rust: split transact into prepare and submit
The async Rust binder interface will want to prepare and build the
Parcel on one thread, and submit the transaction from another thread.
Doing this will reduce the amount of `: 'static` bounds necessary in the
async binder interface.
Such a workflow where `AIBinder_prepareTransaction` and
`AIBinder_transact` are called on two different threads is not possible
with the current API.
Test: m
Change-Id: Iaf13b070e69faf8658a202c6e05f0a2aeaa4a904
diff --git a/libs/binder/rust/src/binder.rs b/libs/binder/rust/src/binder.rs
index dd0c7b8..41ceee5 100644
--- a/libs/binder/rust/src/binder.rs
+++ b/libs/binder/rust/src/binder.rs
@@ -152,20 +152,46 @@
/// available.
fn get_extension(&mut self) -> Result<Option<SpIBinder>>;
+ /// Create a Parcel that can be used with `submit_transact`.
+ fn prepare_transact(&self) -> Result<Parcel>;
+
/// Perform a generic operation with the object.
///
+ /// The provided [`Parcel`] must have been created by a call to
+ /// `prepare_transact` on the same binder.
+ ///
+ /// # Arguments
+ ///
+ /// * `code` - Transaction code for the operation.
+ /// * `data` - [`Parcel`] with input data.
+ /// * `flags` - Transaction flags, e.g. marking the transaction as
+ /// asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY)).
+ fn submit_transact(
+ &self,
+ code: TransactionCode,
+ data: Parcel,
+ flags: TransactionFlags,
+ ) -> Result<Parcel>;
+
+ /// Perform a generic operation with the object. This is a convenience
+ /// method that internally calls `prepare_transact` followed by
+ /// `submit_transact.
+ ///
/// # Arguments
/// * `code` - Transaction code for the operation
- /// * `data` - [`Parcel`] with input data
- /// * `reply` - Optional [`Parcel`] for reply data
/// * `flags` - Transaction flags, e.g. marking the transaction as
/// asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY))
+ /// * `input_callback` A callback for building the `Parcel`.
fn transact<F: FnOnce(&mut Parcel) -> Result<()>>(
&self,
code: TransactionCode,
flags: TransactionFlags,
input_callback: F,
- ) -> Result<Parcel>;
+ ) -> Result<Parcel> {
+ let mut parcel = self.prepare_transact()?;
+ input_callback(&mut parcel)?;
+ self.submit_transact(code, parcel, flags)
+ }
}
/// Interface of binder local or remote objects.