1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
// Copyright 2022 Jeff Kim <hiking90@gmail.com>
// SPDX-License-Identifier: Apache-2.0
//! A pure Rust implementation of Android Binder IPC mechanism.
//!
//! This library provides a complete implementation of the Android Binder protocol
//! for inter-process communication (IPC) on Linux and Android systems. It enables
//! services to communicate across process boundaries with type safety and efficiency.
//!
//! # Core Components
//!
//! - **Binder**: Core binder object and transaction handling
//! - **Parcel**: Serialization/deserialization for IPC data
//! - **Proxy**: Client-side interface for remote services
//! - **Native**: Server-side service implementation utilities
//! - **ProcessState**: Process-level binder state management
//! - **ServiceManager**: Service discovery and registration
//!
//! # Basic Usage
//!
//! This library works with AIDL (Android Interface Definition Language) files to generate
//! type-safe Rust bindings for IPC services.
//!
//! ## Setting up an AIDL-based Service
//!
//! First, create an AIDL interface file (`aidl/hello/IHello.aidl`):
//!
//! ```aidl
//! package hello;
//!
//! interface IHello {
//! String echo(in String message);
//! }
//! ```
//!
//! Add a `build.rs` file to generate Rust bindings:
//!
//! ```rust,ignore
//! # use std::path::PathBuf;
//! rsbinder_aidl::Builder::new()
//! .source(PathBuf::from("aidl/hello/IHello.aidl"))
//! .output(PathBuf::from("hello.rs"))
//! .generate()
//! .unwrap();
//! ```
//!
//! In your `Cargo.toml`, add the build dependency:
//!
//! ```toml
//! [build-dependencies]
//! rsbinder-aidl = "*" # Check crates.io for the latest version
//! ```
//!
//! ## Implementing the Service
//!
//! ```rust,ignore
//! use rsbinder::*;
//!
//! // Include the generated code
//! include!(concat!(env!("OUT_DIR"), "/hello.rs"));
//! pub use crate::hello::IHello::*;
//!
//! // Implement the service
//! struct HelloService;
//!
//! impl Interface for HelloService {}
//!
//! impl IHello for HelloService {
//! fn echo(&self, message: &str) -> rsbinder::status::Result<String> {
//! Ok(format!("Echo: {}", message))
//! }
//! }
//!
//! # fn main() -> Result<()> {
//! // Initialize the process state
//! ProcessState::init_default()?;
//!
//! // Start the thread pool
//! ProcessState::start_thread_pool();
//!
//! // Register your service
//! let service = BnHello::new_binder(HelloService);
//! hub::add_service("hello_service", service.as_binder())?;
//!
//! println!("Hello service started");
//!
//! // Join the thread pool to handle requests
//! ProcessState::join_thread_pool();
//! # Ok(())
//! # }
//! ```
//!
//! ## Creating a Client
//!
//! ```rust,ignore
//! use rsbinder::*;
//!
//! // Include the same generated code
//! include!(concat!(env!("OUT_DIR"), "/hello.rs"));
//! pub use crate::hello::IHello::*;
//!
//! # fn main() -> Result<()> {
//! // Initialize the process state
//! ProcessState::init_default()?;
//!
//! // Get service from service manager
//! let service = hub::get_service("hello_service")?;
//! let hello_service = BpHello::new(service)?;
//!
//! // Call remote method
//! let result = hello_service.echo("Hello, World!")?;
//! println!("Service response: {}", result);
//! # Ok(())
//! # }
//! ```
//!
//! ## Opting into kernel-level features
//!
//! Native binders can opt into per-binder kernel features (for example,
//! receiving the caller's SELinux security context) via [`BinderFeatures`]
//! and the `*_with_features` constructor variants. See [`BinderFeatures`]
//! for the available opt-ins.
//!
//! # License
//!
//! Licensed under Apache License, Version 2.0.
//!
//! # References
//!
//! * [AIDL](https://source.android.com/docs/core/architecture/aidl)
//! * [Binder](https://source.android.com/docs/core/architecture/hidl/binder-ipc)
//!
// Core binder functionality
/// Async binder runtime support
/// BinderFS filesystem utilities
/// Error types and result handling
/// File descriptor wrapper for IPC
/// Native service implementation helpers
/// Data serialization for IPC
/// Parcelable trait for serializable types
/// Holder for parcelable objects
/// Client proxy for remote services
/// Status and exception handling
/// Thread-local binder state
/// Service hub and manager implementations
/// Async runtime implementations
pub use *;
pub use ;
pub use ;
pub use ParcelFileDescriptor;
pub use *;
pub use Parcel;
pub use *;
pub use ParcelableHolder;
pub use ProcessState;
pub use *;
pub use *;
pub use ;
/// Default path to the binder control device
pub const DEFAULT_BINDER_CONTROL_PATH: &str = "/dev/binderfs/binder-control";
/// Default path to the binder device (binderfs, used on Android 11+).
pub const DEFAULT_BINDER_PATH: &str = "/dev/binderfs/binder";
/// Default path to the binderfs mount point
pub const DEFAULT_BINDERFS_PATH: &str = "/dev/binderfs";
/// Legacy binder device path used on Android 10 and earlier.
pub const LEGACY_BINDER_PATH: &str = "/dev/binder";
/// Returns `true` when the runtime Android SDK version is at least `version`.
/// On non-Android platforms this always returns `true`.
static ANDROID_SDK_VERSION: OnceLock = new;
/// Get the Android SDK version from system properties.
///
/// Returns the Android SDK version number, or 0 if not available.