1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 //! Safe Rust interface to Android `libbinder`.
18 //!
19 //! This crate is primarily designed as an target for a Rust AIDL compiler
20 //! backend, and should generally not be used directly by users. It is built on
21 //! top of the binder NDK library to be usable by APEX modules, and therefore
22 //! only exposes functionality available in the NDK interface.
23 //!
24 //! # Example
25 //!
26 //! The following example illustrates how the AIDL backend will use this crate.
27 //!
28 //! ```
29 //! use binder::{
30 //!     declare_binder_interface, Binder, IBinder, Interface, Remotable, Parcel, SpIBinder,
31 //!     StatusCode, TransactionCode,
32 //! };
33 //!
34 //! // Generated by AIDL compiler
35 //! pub trait ITest: Interface {
36 //!     fn test(&self) -> binder::Result<String>;
37 //! }
38 //!
39 //! // Creates a new local (native) service object, BnTest, and a remote proxy
40 //! // object, BpTest, that are the typed interfaces for their respective ends
41 //! // of the binder transaction. Generated by AIDL compiler.
42 //! declare_binder_interface! {
43 //!     ITest["android.os.ITest"] {
44 //!         native: BnTest(on_transact),
45 //!         proxy: BpTest,
46 //!     }
47 //! }
48 //!
49 //! // Generated by AIDL compiler
50 //! fn on_transact(
51 //!     service: &dyn ITest,
52 //!     code: TransactionCode,
53 //!     _data: &Parcel,
54 //!     reply: &mut Parcel,
55 //! ) -> binder::Result<()> {
56 //!     match code {
57 //!         SpIBinder::FIRST_CALL_TRANSACTION => {
58 //!             reply.write(&service.test()?)?;
59 //!             Ok(())
60 //!         }
61 //!         _ => Err(StatusCode::UNKNOWN_TRANSACTION),
62 //!     }
63 //! }
64 //!
65 //! // Generated by AIDL compiler
66 //! impl ITest for Binder<BnTest> {
67 //!     fn test(&self) -> binder::Result<String> {
68 //!         self.0.test()
69 //!     }
70 //! }
71 //!
72 //! // Generated by AIDL compiler
73 //! impl ITest for BpTest {
74 //!     fn test(&self) -> binder::Result<String> {
75 //!        let reply = self
76 //!            .as_binder()
77 //!            .transact(SpIBinder::FIRST_CALL_TRANSACTION, 0, |_| Ok(()))?;
78 //!        reply.read()
79 //!     }
80 //! }
81 //!
82 //! // User implemented:
83 //!
84 //! // Local implementation of the ITest remotable interface.
85 //! struct TestService;
86 //!
87 //! impl Interface for TestService {}
88 //!
89 //! impl ITest for TestService {
90 //!     fn test(&self) -> binder::Result<String> {
91 //!        Ok("testing service".to_string())
92 //!     }
93 //! }
94 //! ```
95 
96 #[macro_use]
97 mod proxy;
98 
99 #[macro_use]
100 mod binder;
101 mod error;
102 mod native;
103 mod state;
104 
105 use binder_ndk_sys as sys;
106 
107 pub mod parcel;
108 
109 pub use crate::binder::{
110     BinderFeatures, FromIBinder, IBinder, IBinderInternal, Interface, InterfaceClass, Remotable,
111     Stability, Strong, TransactionCode, TransactionFlags, Weak, FIRST_CALL_TRANSACTION,
112     FLAG_CLEAR_BUF, FLAG_ONEWAY, FLAG_PRIVATE_LOCAL, LAST_CALL_TRANSACTION,
113 };
114 pub use error::{status_t, ExceptionCode, Result, Status, StatusCode};
115 pub use native::add_service;
116 pub use native::Binder;
117 pub use parcel::Parcel;
118 pub use proxy::{get_interface, get_service};
119 pub use proxy::{AssociateClass, DeathRecipient, Proxy, SpIBinder, WpIBinder};
120 pub use state::{ProcessState, ThreadState};
121 
122 /// The public API usable outside AIDL-generated interface crates.
123 pub mod public_api {
124     pub use super::parcel::ParcelFileDescriptor;
125     pub use super::{add_service, get_interface};
126     pub use super::{
127         BinderFeatures, DeathRecipient, ExceptionCode, IBinder, Interface, ProcessState, SpIBinder,
128         Status, StatusCode, Strong, ThreadState, Weak, WpIBinder,
129     };
130 
131     /// Binder result containing a [`Status`] on error.
132     pub type Result<T> = std::result::Result<T, Status>;
133 }
134