binder_rs: add OwnedParcel

This adds a new binder::OwnedParcel type that exclusively
contains an owned parcel, and implements Send so it
can be sent between threads. Parcel cannot implement Send
because Parcel::Borrowed could point to thread-local
C++ values, e.g., a Parcel stored on the stack.
This change is a prerequisite for both async and
thread-safe ParcelableHolder.

Bug: 200676345
Test: atest aidl_integration_test
Change-Id: I1a7b965d26cb5350576450debd7d058a6451b1f0
diff --git a/libs/binder/rust/src/binder.rs b/libs/binder/rust/src/binder.rs
index 854b1f9..cc5dd06 100644
--- a/libs/binder/rust/src/binder.rs
+++ b/libs/binder/rust/src/binder.rs
@@ -17,7 +17,7 @@
 //! Trait definitions for binder objects
 
 use crate::error::{status_t, Result, StatusCode};
-use crate::parcel::Parcel;
+use crate::parcel::{OwnedParcel, Parcel};
 use crate::proxy::{DeathRecipient, SpIBinder, WpIBinder};
 use crate::sys;
 
@@ -177,25 +177,25 @@
     fn get_extension(&mut self) -> Result<Option<SpIBinder>>;
 
     /// Create a Parcel that can be used with `submit_transact`.
-    fn prepare_transact(&self) -> Result<Parcel>;
+    fn prepare_transact(&self) -> Result<OwnedParcel>;
 
     /// Perform a generic operation with the object.
     ///
-    /// The provided [`Parcel`] must have been created by a call to
+    /// The provided [`OwnedParcel`] 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.
+    /// * `data` - [`OwnedParcel`] 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,
+        data: OwnedParcel,
         flags: TransactionFlags,
-    ) -> Result<Parcel>;
+    ) -> Result<OwnedParcel>;
 
     /// Perform a generic operation with the object. This is a convenience
     /// method that internally calls `prepare_transact` followed by
@@ -213,8 +213,8 @@
         input_callback: F,
     ) -> Result<Parcel> {
         let mut parcel = self.prepare_transact()?;
-        input_callback(&mut parcel)?;
-        self.submit_transact(code, parcel, flags)
+        input_callback(&mut parcel.borrowed())?;
+        self.submit_transact(code, parcel, flags).map(OwnedParcel::into_parcel)
     }
 }
 
diff --git a/libs/binder/rust/src/lib.rs b/libs/binder/rust/src/lib.rs
index d1d37d7..81b620e 100644
--- a/libs/binder/rust/src/lib.rs
+++ b/libs/binder/rust/src/lib.rs
@@ -113,7 +113,7 @@
 };
 pub use error::{status_t, ExceptionCode, Result, Status, StatusCode};
 pub use native::{add_service, force_lazy_services_persist, register_lazy_service, Binder};
-pub use parcel::Parcel;
+pub use parcel::{OwnedParcel, Parcel};
 pub use proxy::{get_interface, get_service, wait_for_interface, wait_for_service};
 pub use proxy::{AssociateClass, DeathRecipient, Proxy, SpIBinder, WpIBinder};
 pub use state::{ProcessState, ThreadState};
diff --git a/libs/binder/rust/src/parcel.rs b/libs/binder/rust/src/parcel.rs
index 7391561..9dba950 100644
--- a/libs/binder/rust/src/parcel.rs
+++ b/libs/binder/rust/src/parcel.rs
@@ -23,6 +23,7 @@
 
 use std::cell::RefCell;
 use std::convert::TryInto;
+use std::marker::PhantomData;
 use std::mem::ManuallyDrop;
 use std::ptr;
 use std::fmt;
@@ -52,6 +53,106 @@
     Borrowed(*mut sys::AParcel),
 }
 
+/// A variant of Parcel that is known to be owned.
+pub struct OwnedParcel {
+    ptr: *mut sys::AParcel,
+}
+
+/// # Safety
+///
+/// This type guarantees that it owns the AParcel and that all access to
+/// the AParcel happens through the OwnedParcel, so it is ok to send across
+/// threads.
+unsafe impl Send for OwnedParcel {}
+
+/// A variant of Parcel that is known to be borrowed.
+pub struct BorrowedParcel<'a> {
+    inner: Parcel,
+    _lifetime: PhantomData<&'a mut Parcel>,
+}
+
+impl OwnedParcel {
+    /// Create a new empty `OwnedParcel`.
+    pub fn new() -> OwnedParcel {
+        let ptr = unsafe {
+            // Safety: If `AParcel_create` succeeds, it always returns
+            // a valid pointer. If it fails, the process will crash.
+            sys::AParcel_create()
+        };
+        assert!(!ptr.is_null());
+        Self { ptr }
+    }
+
+    /// Create an owned reference to a parcel object from a raw pointer.
+    ///
+    /// # Safety
+    ///
+    /// This constructor is safe if the raw pointer parameter is either null
+    /// (resulting in `None`), or a valid pointer to an `AParcel` object. The
+    /// parcel object must be owned by the caller prior to this call, as this
+    /// constructor takes ownership of the parcel and will destroy it on drop.
+    ///
+    /// Additionally, the caller must guarantee that it is valid to take
+    /// ownership of the AParcel object. All future access to the AParcel
+    /// must happen through this `OwnedParcel`.
+    ///
+    /// Because `OwnedParcel` implements `Send`, the pointer must never point
+    /// to any thread-local data, e.g., a variable on the stack, either directly
+    /// or indirectly.
+    pub unsafe fn from_raw(ptr: *mut sys::AParcel) -> Option<OwnedParcel> {
+        ptr.as_mut().map(|ptr| Self { ptr })
+    }
+
+    /// Consume the parcel, transferring ownership to the caller.
+    pub(crate) fn into_raw(self) -> *mut sys::AParcel {
+        let ptr = self.ptr;
+        let _ = ManuallyDrop::new(self);
+        ptr
+    }
+
+    /// Convert this `OwnedParcel` into an owned `Parcel`.
+    pub fn into_parcel(self) -> Parcel {
+        Parcel::Owned(self.into_raw())
+    }
+
+    /// Get a borrowed view into the contents of this `Parcel`.
+    pub fn borrowed(&mut self) -> BorrowedParcel<'_> {
+        BorrowedParcel {
+            inner: Parcel::Borrowed(self.ptr),
+            _lifetime: PhantomData,
+        }
+    }
+}
+
+impl Default for OwnedParcel {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+impl Clone for OwnedParcel {
+    fn clone(&self) -> Self {
+        let mut new_parcel = Self::new();
+        new_parcel
+            .borrowed()
+            .append_all_from(&Parcel::Borrowed(self.ptr))
+            .expect("Failed to append from Parcel");
+        new_parcel
+    }
+}
+
+impl<'a> std::ops::Deref for BorrowedParcel<'a> {
+    type Target = Parcel;
+    fn deref(&self) -> &Parcel {
+        &self.inner
+    }
+}
+impl<'a> std::ops::DerefMut for BorrowedParcel<'a> {
+    fn deref_mut(&mut self) -> &mut Parcel {
+        &mut self.inner
+    }
+}
+
 /// # Safety
 ///
 /// The `Parcel` constructors guarantee that a `Parcel` object will always
@@ -95,33 +196,6 @@
     pub(crate) unsafe fn borrowed(ptr: *mut sys::AParcel) -> Option<Parcel> {
         ptr.as_mut().map(|ptr| Self::Borrowed(ptr))
     }
-
-    /// Create an owned reference to a parcel object from a raw pointer.
-    ///
-    /// # Safety
-    ///
-    /// This constructor is safe if the raw pointer parameter is either null
-    /// (resulting in `None`), or a valid pointer to an `AParcel` object. The
-    /// parcel object must be owned by the caller prior to this call, as this
-    /// constructor takes ownership of the parcel and will destroy it on drop.
-    pub(crate) unsafe fn owned(ptr: *mut sys::AParcel) -> Option<Parcel> {
-        ptr.as_mut().map(|ptr| Self::Owned(ptr))
-    }
-
-    /// Consume the parcel, transferring ownership to the caller if the parcel
-    /// was owned.
-    pub(crate) fn into_raw(mut self) -> *mut sys::AParcel {
-        let ptr = self.as_native_mut();
-        let _ = ManuallyDrop::new(self);
-        ptr
-    }
-
-    pub(crate) fn is_owned(&self) -> bool {
-        match *self {
-            Self::Owned(_) => true,
-            Self::Borrowed(_) => false,
-        }
-    }
 }
 
 impl Default for Parcel {
@@ -478,6 +552,18 @@
     }
 }
 
+impl Drop for OwnedParcel {
+    fn drop(&mut self) {
+        // Run the C++ Parcel complete object destructor
+        unsafe {
+            // Safety: `OwnedParcel` always contains a valid pointer to an
+            // `AParcel`. Since we own the parcel, we can safely delete it
+            // here.
+            sys::AParcel_delete(self.ptr)
+        }
+    }
+}
+
 impl fmt::Debug for Parcel {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("Parcel")
@@ -485,6 +571,13 @@
     }
 }
 
+impl fmt::Debug for OwnedParcel {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("OwnedParcel")
+            .finish()
+    }
+}
+
 #[test]
 fn test_read_write() {
     let mut parcel = Parcel::new();
diff --git a/libs/binder/rust/src/proxy.rs b/libs/binder/rust/src/proxy.rs
index 68fa34b..a7a3fb2 100644
--- a/libs/binder/rust/src/proxy.rs
+++ b/libs/binder/rust/src/proxy.rs
@@ -22,7 +22,7 @@
 };
 use crate::error::{status_result, Result, StatusCode};
 use crate::parcel::{
-    Deserialize, DeserializeArray, DeserializeOption, Parcel, Serialize, SerializeArray,
+    Deserialize, DeserializeArray, DeserializeOption, OwnedParcel, Parcel, Serialize, SerializeArray,
     SerializeOption,
 };
 use crate::sys;
@@ -235,7 +235,7 @@
 }
 
 impl<T: AsNative<sys::AIBinder>> IBinderInternal for T {
-    fn prepare_transact(&self) -> Result<Parcel> {
+    fn prepare_transact(&self) -> Result<OwnedParcel> {
         let mut input = ptr::null_mut();
         let status = unsafe {
             // Safety: `SpIBinder` guarantees that `self` always contains a
@@ -253,20 +253,19 @@
 
         unsafe {
             // Safety: At this point, `input` is either a valid, owned `AParcel`
-            // pointer, or null. `Parcel::owned` safely handles both cases,
+            // pointer, or null. `OwnedParcel::from_raw` safely handles both cases,
             // taking ownership of the parcel.
-            Parcel::owned(input).ok_or(StatusCode::UNEXPECTED_NULL)
+            OwnedParcel::from_raw(input).ok_or(StatusCode::UNEXPECTED_NULL)
         }
     }
 
     fn submit_transact(
         &self,
         code: TransactionCode,
-        data: Parcel,
+        data: OwnedParcel,
         flags: TransactionFlags,
-    ) -> Result<Parcel> {
+    ) -> Result<OwnedParcel> {
         let mut reply = ptr::null_mut();
-        assert!(data.is_owned());
         let status = unsafe {
             // Safety: `SpIBinder` guarantees that `self` always contains a
             // valid pointer to an `AIBinder`. Although `IBinder::transact` is
@@ -299,9 +298,8 @@
             // after the call to `AIBinder_transact` above, so we can
             // construct a `Parcel` out of it. `AIBinder_transact` passes
             // ownership of the `reply` parcel to Rust, so we need to
-            // construct an owned variant. `Parcel::owned` takes ownership
-            // of the parcel pointer.
-            Parcel::owned(reply).ok_or(StatusCode::UNEXPECTED_NULL)
+            // construct an owned variant.
+            OwnedParcel::from_raw(reply).ok_or(StatusCode::UNEXPECTED_NULL)
         }
     }