Merge "libbinder_rs: Add Strong<> and Weak<> Binder references"
diff --git a/libs/binder/rust/src/binder.rs b/libs/binder/rust/src/binder.rs
index 42c1e0a..d53a88f 100644
--- a/libs/binder/rust/src/binder.rs
+++ b/libs/binder/rust/src/binder.rs
@@ -16,12 +16,17 @@
 
 //! Trait definitions for binder objects
 
-use crate::error::{status_t, Result};
+use crate::error::{status_t, Result, StatusCode};
 use crate::parcel::Parcel;
-use crate::proxy::{DeathRecipient, SpIBinder};
+use crate::proxy::{DeathRecipient, SpIBinder, WpIBinder};
 use crate::sys;
 
+use std::borrow::Borrow;
+use std::cmp::Ordering;
 use std::ffi::{c_void, CStr, CString};
+use std::fmt;
+use std::marker::PhantomData;
+use std::ops::Deref;
 use std::os::raw::c_char;
 use std::os::unix::io::AsRawFd;
 use std::ptr;
@@ -44,7 +49,7 @@
 /// interfaces) must implement this trait.
 ///
 /// This is equivalent `IInterface` in C++.
-pub trait Interface {
+pub trait Interface: Send {
     /// Convert this binder object into a generic [`SpIBinder`] reference.
     fn as_binder(&self) -> SpIBinder {
         panic!("This object was not a Binder object and cannot be converted into an SpIBinder.")
@@ -230,6 +235,132 @@
     }
 }
 
+/// Strong reference to a binder object
+pub struct Strong<I: FromIBinder + ?Sized>(Box<I>);
+
+impl<I: FromIBinder + ?Sized> Strong<I> {
+    /// Create a new strong reference to the provided binder object
+    pub fn new(binder: Box<I>) -> Self {
+        Self(binder)
+    }
+
+    /// Construct a new weak reference to this binder
+    pub fn downgrade(this: &Strong<I>) -> Weak<I> {
+        Weak::new(this)
+    }
+}
+
+impl<I: FromIBinder + ?Sized> Clone for Strong<I> {
+    fn clone(&self) -> Self {
+        // Since we hold a strong reference, we should always be able to create
+        // a new strong reference to the same interface type, so try_from()
+        // should never fail here.
+        FromIBinder::try_from(self.0.as_binder()).unwrap()
+    }
+}
+
+impl<I: FromIBinder + ?Sized> Borrow<I> for Strong<I> {
+    fn borrow(&self) -> &I {
+        &self.0
+    }
+}
+
+impl<I: FromIBinder + ?Sized> AsRef<I> for Strong<I> {
+    fn as_ref(&self) -> &I {
+        &self.0
+    }
+}
+
+impl<I: FromIBinder + ?Sized> Deref for Strong<I> {
+    type Target = I;
+
+    fn deref(&self) -> &Self::Target {
+        &self.0
+    }
+}
+
+impl<I: FromIBinder + fmt::Debug + ?Sized> fmt::Debug for Strong<I> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Debug::fmt(&**self, f)
+    }
+}
+
+impl<I: FromIBinder + ?Sized> Ord for Strong<I> {
+    fn cmp(&self, other: &Self) -> Ordering {
+        self.0.as_binder().cmp(&other.0.as_binder())
+    }
+}
+
+impl<I: FromIBinder + ?Sized> PartialOrd for Strong<I> {
+    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+        self.0.as_binder().partial_cmp(&other.0.as_binder())
+    }
+}
+
+impl<I: FromIBinder + ?Sized> PartialEq for Strong<I> {
+    fn eq(&self, other: &Self) -> bool {
+        self.0.as_binder().eq(&other.0.as_binder())
+    }
+}
+
+impl<I: FromIBinder + ?Sized> Eq for Strong<I> {}
+
+/// Weak reference to a binder object
+#[derive(Debug)]
+pub struct Weak<I: FromIBinder + ?Sized> {
+    weak_binder: WpIBinder,
+    interface_type: PhantomData<I>,
+}
+
+impl<I: FromIBinder + ?Sized> Weak<I> {
+    /// Construct a new weak reference from a strong reference
+    fn new(binder: &Strong<I>) -> Self {
+        let weak_binder = binder.as_binder().downgrade();
+        Weak {
+            weak_binder,
+            interface_type: PhantomData,
+        }
+    }
+
+    /// Upgrade this weak reference to a strong reference if the binder object
+    /// is still alive
+    pub fn upgrade(&self) -> Result<Strong<I>> {
+        self.weak_binder
+            .promote()
+            .ok_or(StatusCode::DEAD_OBJECT)
+            .and_then(FromIBinder::try_from)
+    }
+}
+
+impl<I: FromIBinder + ?Sized> Clone for Weak<I> {
+    fn clone(&self) -> Self {
+        Self {
+            weak_binder: self.weak_binder.clone(),
+            interface_type: PhantomData,
+        }
+    }
+}
+
+impl<I: FromIBinder + ?Sized> Ord for Weak<I> {
+    fn cmp(&self, other: &Self) -> Ordering {
+        self.weak_binder.cmp(&other.weak_binder)
+    }
+}
+
+impl<I: FromIBinder + ?Sized> PartialOrd for Weak<I> {
+    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+        self.weak_binder.partial_cmp(&other.weak_binder)
+    }
+}
+
+impl<I: FromIBinder + ?Sized> PartialEq for Weak<I> {
+    fn eq(&self, other: &Self) -> bool {
+        self.weak_binder == other.weak_binder
+    }
+}
+
+impl<I: FromIBinder + ?Sized> Eq for Weak<I> {}
+
 /// Create a function implementing a static getter for an interface class.
 ///
 /// Each binder interface (i.e. local [`Remotable`] service or remote proxy
@@ -354,12 +485,12 @@
 ///     }
 /// }
 /// ```
-pub trait FromIBinder {
+pub trait FromIBinder: Interface {
     /// Try to interpret a generic Binder object as this interface.
     ///
     /// Returns a trait object for the `Self` interface if this object
     /// implements that interface.
-    fn try_from(ibinder: SpIBinder) -> Result<Box<Self>>;
+    fn try_from(ibinder: SpIBinder) -> Result<Strong<Self>>;
 }
 
 /// Trait for transparent Rust wrappers around android C++ native types.
@@ -534,8 +665,9 @@
 
         impl $native {
             /// Create a new binder service.
-            pub fn new_binder<T: $interface + Sync + Send + 'static>(inner: T) -> impl $interface {
-                $crate::Binder::new($native(Box::new(inner)))
+            pub fn new_binder<T: $interface + Sync + Send + 'static>(inner: T) -> $crate::Strong<dyn $interface> {
+                let binder = $crate::Binder::new($native(Box::new(inner)));
+                $crate::Strong::new(Box::new(binder))
             }
         }
 
@@ -577,7 +709,7 @@
         }
 
         impl $crate::FromIBinder for dyn $interface {
-            fn try_from(mut ibinder: $crate::SpIBinder) -> $crate::Result<Box<dyn $interface>> {
+            fn try_from(mut ibinder: $crate::SpIBinder) -> $crate::Result<$crate::Strong<dyn $interface>> {
                 use $crate::AssociateClass;
 
                 let existing_class = ibinder.get_class();
@@ -590,7 +722,7 @@
                         // associated object as remote, because we can't cast it
                         // into a Rust service object without a matching class
                         // pointer.
-                        return Ok(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?));
+                        return Ok($crate::Strong::new(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?)));
                     }
                 }
 
@@ -600,10 +732,10 @@
                     if let Ok(service) = service {
                         // We were able to associate with our expected class and
                         // the service is local.
-                        return Ok(Box::new(service));
+                        return Ok($crate::Strong::new(Box::new(service)));
                     } else {
                         // Service is remote
-                        return Ok(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?));
+                        return Ok($crate::Strong::new(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?)));
                     }
                 }
 
@@ -633,9 +765,9 @@
             }
         }
 
-        // Convert a &dyn $interface to Box<dyn $interface>
+        /// Convert a &dyn $interface to Strong<dyn $interface>
         impl std::borrow::ToOwned for dyn $interface {
-            type Owned = Box<dyn $interface>;
+            type Owned = $crate::Strong<dyn $interface>;
             fn to_owned(&self) -> Self::Owned {
                 self.as_binder().into_interface()
                     .expect(concat!("Error cloning interface ", stringify!($interface)))
diff --git a/libs/binder/rust/src/lib.rs b/libs/binder/rust/src/lib.rs
index edfb56a..43a237a 100644
--- a/libs/binder/rust/src/lib.rs
+++ b/libs/binder/rust/src/lib.rs
@@ -107,7 +107,8 @@
 pub mod parcel;
 
 pub use crate::binder::{
-    FromIBinder, IBinder, Interface, InterfaceClass, Remotable, TransactionCode, TransactionFlags,
+    FromIBinder, IBinder, Interface, InterfaceClass, Remotable, Strong, TransactionCode,
+    TransactionFlags, Weak,
 };
 pub use error::{status_t, ExceptionCode, Result, Status, StatusCode};
 pub use native::add_service;
@@ -122,7 +123,8 @@
     pub use super::parcel::ParcelFileDescriptor;
     pub use super::{add_service, get_interface};
     pub use super::{
-        ExceptionCode, Interface, ProcessState, SpIBinder, Status, StatusCode, WpIBinder,
+        ExceptionCode, Interface, ProcessState, SpIBinder, Status, StatusCode, Strong, ThreadState,
+        Weak, WpIBinder,
     };
 
     /// Binder result containing a [`Status`] on error.
diff --git a/libs/binder/rust/src/parcel/parcelable.rs b/libs/binder/rust/src/parcel/parcelable.rs
index 8d18fb4..f57788b 100644
--- a/libs/binder/rust/src/parcel/parcelable.rs
+++ b/libs/binder/rust/src/parcel/parcelable.rs
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-use crate::binder::{AsNative, FromIBinder};
+use crate::binder::{AsNative, FromIBinder, Strong};
 use crate::error::{status_result, status_t, Result, Status, StatusCode};
 use crate::parcel::Parcel;
 use crate::proxy::SpIBinder;
@@ -628,26 +628,26 @@
     }
 }
 
-impl<T: Serialize + ?Sized> Serialize for Box<T> {
+impl<T: Serialize + FromIBinder + ?Sized> Serialize for Strong<T> {
     fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
         Serialize::serialize(&**self, parcel)
     }
 }
 
-impl<T: SerializeOption + ?Sized> SerializeOption for Box<T> {
+impl<T: SerializeOption + FromIBinder + ?Sized> SerializeOption for Strong<T> {
     fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
         SerializeOption::serialize_option(this.map(|b| &**b), parcel)
     }
 }
 
-impl<T: FromIBinder + ?Sized> Deserialize for Box<T> {
+impl<T: FromIBinder + ?Sized> Deserialize for Strong<T> {
     fn deserialize(parcel: &Parcel) -> Result<Self> {
         let ibinder: SpIBinder = parcel.read()?;
         FromIBinder::try_from(ibinder)
     }
 }
 
-impl<T: FromIBinder + ?Sized> DeserializeOption for Box<T> {
+impl<T: FromIBinder + ?Sized> DeserializeOption for Strong<T> {
     fn deserialize_option(parcel: &Parcel) -> Result<Option<Self>> {
         let ibinder: Option<SpIBinder> = parcel.read()?;
         ibinder.map(FromIBinder::try_from).transpose()
diff --git a/libs/binder/rust/src/proxy.rs b/libs/binder/rust/src/proxy.rs
index e9e74c0..132e075 100644
--- a/libs/binder/rust/src/proxy.rs
+++ b/libs/binder/rust/src/proxy.rs
@@ -17,7 +17,7 @@
 //! Rust API for interacting with a remote binder service.
 
 use crate::binder::{
-    AsNative, FromIBinder, IBinder, Interface, InterfaceClass, TransactionCode, TransactionFlags,
+    AsNative, FromIBinder, IBinder, Interface, InterfaceClass, Strong, TransactionCode, TransactionFlags,
 };
 use crate::error::{status_result, Result, StatusCode};
 use crate::parcel::{
@@ -27,6 +27,7 @@
 use crate::sys;
 
 use std::convert::TryInto;
+use std::cmp::Ordering;
 use std::ffi::{c_void, CString};
 use std::fmt;
 use std::os::unix::io::AsRawFd;
@@ -99,7 +100,7 @@
     ///
     /// If this object does not implement the expected interface, the error
     /// `StatusCode::BAD_TYPE` is returned.
-    pub fn into_interface<I: FromIBinder + ?Sized>(self) -> Result<Box<I>> {
+    pub fn into_interface<I: FromIBinder + Interface + ?Sized>(self) -> Result<Strong<I>> {
         FromIBinder::try_from(self)
     }
 
@@ -148,6 +149,36 @@
     }
 }
 
+impl Ord for SpIBinder {
+    fn cmp(&self, other: &Self) -> Ordering {
+        let less_than = unsafe {
+            // Safety: SpIBinder always holds a valid `AIBinder` pointer, so
+            // this pointer is always safe to pass to `AIBinder_lt` (null is
+            // also safe to pass to this function, but we should never do that).
+            sys::AIBinder_lt(self.0, other.0)
+        };
+        let greater_than = unsafe {
+            // Safety: SpIBinder always holds a valid `AIBinder` pointer, so
+            // this pointer is always safe to pass to `AIBinder_lt` (null is
+            // also safe to pass to this function, but we should never do that).
+            sys::AIBinder_lt(other.0, self.0)
+        };
+        if !less_than && !greater_than {
+            Ordering::Equal
+        } else if less_than {
+            Ordering::Less
+        } else {
+            Ordering::Greater
+        }
+    }
+}
+
+impl PartialOrd for SpIBinder {
+    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+        Some(self.cmp(other))
+    }
+}
+
 impl PartialEq for SpIBinder {
     fn eq(&self, other: &Self) -> bool {
         ptr::eq(self.0, other.0)
@@ -326,7 +357,7 @@
             // Safety: `SpIBinder` guarantees that `self` always contains a
             // valid pointer to an `AIBinder`. `recipient` can always be
             // converted into a valid pointer to an
-            // `AIBinder_DeatRecipient`. Any value is safe to pass as the
+            // `AIBinder_DeathRecipient`. Any value is safe to pass as the
             // cookie, although we depend on this value being set by
             // `get_cookie` when the death recipient callback is called.
             sys::AIBinder_linkToDeath(
@@ -342,7 +373,7 @@
             // Safety: `SpIBinder` guarantees that `self` always contains a
             // valid pointer to an `AIBinder`. `recipient` can always be
             // converted into a valid pointer to an
-            // `AIBinder_DeatRecipient`. Any value is safe to pass as the
+            // `AIBinder_DeathRecipient`. Any value is safe to pass as the
             // cookie, although we depend on this value being set by
             // `get_cookie` when the death recipient callback is called.
             sys::AIBinder_unlinkToDeath(
@@ -430,6 +461,62 @@
     }
 }
 
+impl Clone for WpIBinder {
+    fn clone(&self) -> Self {
+        let ptr = unsafe {
+            // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer,
+            // so this pointer is always safe to pass to `AIBinder_Weak_clone`
+            // (although null is also a safe value to pass to this API).
+            //
+            // We get ownership of the returned pointer, so can construct a new
+            // WpIBinder object from it.
+            sys::AIBinder_Weak_clone(self.0)
+        };
+        assert!(!ptr.is_null(), "Unexpected null pointer from AIBinder_Weak_clone");
+        Self(ptr)
+    }
+}
+
+impl Ord for WpIBinder {
+    fn cmp(&self, other: &Self) -> Ordering {
+        let less_than = unsafe {
+            // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer,
+            // so this pointer is always safe to pass to `AIBinder_Weak_lt`
+            // (null is also safe to pass to this function, but we should never
+            // do that).
+            sys::AIBinder_Weak_lt(self.0, other.0)
+        };
+        let greater_than = unsafe {
+            // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer,
+            // so this pointer is always safe to pass to `AIBinder_Weak_lt`
+            // (null is also safe to pass to this function, but we should never
+            // do that).
+            sys::AIBinder_Weak_lt(other.0, self.0)
+        };
+        if !less_than && !greater_than {
+            Ordering::Equal
+        } else if less_than {
+            Ordering::Less
+        } else {
+            Ordering::Greater
+        }
+    }
+}
+
+impl PartialOrd for WpIBinder {
+    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+        Some(self.cmp(other))
+    }
+}
+
+impl PartialEq for WpIBinder {
+    fn eq(&self, other: &Self) -> bool {
+        self.cmp(other) == Ordering::Equal
+    }
+}
+
+impl Eq for WpIBinder {}
+
 impl Drop for WpIBinder {
     fn drop(&mut self) {
         unsafe {
@@ -564,7 +651,7 @@
 
 /// Retrieve an existing service for a particular interface, blocking for a few
 /// seconds if it doesn't yet exist.
-pub fn get_interface<T: FromIBinder + ?Sized>(name: &str) -> Result<Box<T>> {
+pub fn get_interface<T: FromIBinder + ?Sized>(name: &str) -> Result<Strong<T>> {
     let service = get_service(name);
     match service {
         Some(service) => FromIBinder::try_from(service),
diff --git a/libs/binder/rust/tests/integration.rs b/libs/binder/rust/tests/integration.rs
index bb8c492..719229c 100644
--- a/libs/binder/rust/tests/integration.rs
+++ b/libs/binder/rust/tests/integration.rs
@@ -209,7 +209,7 @@
     use std::thread;
     use std::time::Duration;
 
-    use binder::{Binder, DeathRecipient, FromIBinder, IBinder, Interface, SpIBinder, StatusCode};
+    use binder::{Binder, DeathRecipient, FromIBinder, IBinder, Interface, SpIBinder, StatusCode, Strong};
 
     use super::{BnTest, ITest, ITestSameDescriptor, RUST_SERVICE_BINARY, TestService};
 
@@ -271,7 +271,7 @@
     fn trivial_client() {
         let service_name = "trivial_client_test";
         let _process = ScopedServiceProcess::new(service_name);
-        let test_client: Box<dyn ITest> =
+        let test_client: Strong<dyn ITest> =
             binder::get_interface(service_name).expect("Did not get manager binder service");
         assert_eq!(test_client.test().unwrap(), "trivial_client_test");
     }
@@ -280,7 +280,7 @@
     fn get_selinux_context() {
         let service_name = "get_selinux_context";
         let _process = ScopedServiceProcess::new(service_name);
-        let test_client: Box<dyn ITest> =
+        let test_client: Strong<dyn ITest> =
             binder::get_interface(service_name).expect("Did not get manager binder service");
         let expected_context = unsafe {
             let mut out_ptr = ptr::null_mut();
@@ -453,7 +453,7 @@
 
             let extension = maybe_extension.expect("Remote binder did not have an extension");
 
-            let extension: Box<dyn ITest> = FromIBinder::try_from(extension)
+            let extension: Strong<dyn ITest> = FromIBinder::try_from(extension)
                 .expect("Extension could not be converted to the expected interface");
 
             assert_eq!(extension.test().unwrap(), extension_name);
@@ -479,7 +479,7 @@
 
         // This should succeed although we will have to treat the service as
         // remote.
-        let _interface: Box<dyn ITestSameDescriptor> = FromIBinder::try_from(service.as_binder())
+        let _interface: Strong<dyn ITestSameDescriptor> = FromIBinder::try_from(service.as_binder())
             .expect("Could not re-interpret service as the ITestSameDescriptor interface");
     }
 
@@ -490,9 +490,60 @@
         let service_ibinder = BnTest::new_binder(TestService { s: service_name.to_string() })
             .as_binder();
 
-        let service: Box<dyn ITest> = service_ibinder.into_interface()
+        let service: Strong<dyn ITest> = service_ibinder.into_interface()
             .expect("Could not reassociate the generic ibinder");
 
         assert_eq!(service.test().unwrap(), service_name);
     }
+
+    #[test]
+    fn weak_binder_upgrade() {
+        let service_name = "testing_service";
+        let service = BnTest::new_binder(TestService { s: service_name.to_string() });
+
+        let weak = Strong::downgrade(&service);
+
+        let upgraded = weak.upgrade().expect("Could not upgrade weak binder");
+
+        assert_eq!(service, upgraded);
+    }
+
+    #[test]
+    fn weak_binder_upgrade_dead() {
+        let service_name = "testing_service";
+        let weak = {
+            let service = BnTest::new_binder(TestService { s: service_name.to_string() });
+
+            Strong::downgrade(&service)
+        };
+
+        assert_eq!(weak.upgrade(), Err(StatusCode::DEAD_OBJECT));
+    }
+
+    #[test]
+    fn weak_binder_clone() {
+        let service_name = "testing_service";
+        let service = BnTest::new_binder(TestService { s: service_name.to_string() });
+
+        let weak = Strong::downgrade(&service);
+        let cloned = weak.clone();
+        assert_eq!(weak, cloned);
+
+        let upgraded = weak.upgrade().expect("Could not upgrade weak binder");
+        let clone_upgraded = cloned.upgrade().expect("Could not upgrade weak binder");
+
+        assert_eq!(service, upgraded);
+        assert_eq!(service, clone_upgraded);
+    }
+
+    #[test]
+    #[allow(clippy::eq_op)]
+    fn binder_ord() {
+        let service1 = BnTest::new_binder(TestService { s: "testing_service1".to_string() });
+        let service2 = BnTest::new_binder(TestService { s: "testing_service2".to_string() });
+
+        assert!(!(service1 < service1));
+        assert!(!(service1 > service1));
+        assert_eq!(service1 < service2, !(service2 < service1));
+    }
 }
diff --git a/libs/binder/rust/tests/ndk_rust_interop.rs b/libs/binder/rust/tests/ndk_rust_interop.rs
index 70a6dc0..ce75ab7 100644
--- a/libs/binder/rust/tests/ndk_rust_interop.rs
+++ b/libs/binder/rust/tests/ndk_rust_interop.rs
@@ -37,7 +37,7 @@
 
     // The Rust class descriptor pointer will not match the NDK one, but the
     // descriptor strings match so this needs to still associate.
-    let service: Box<dyn IBinderRustNdkInteropTest> = match binder::get_interface(service_name) {
+    let service: binder::Strong<dyn IBinderRustNdkInteropTest> = match binder::get_interface(service_name) {
         Err(e) => {
             eprintln!("Could not find Ndk service {}: {:?}", service_name, e);
             return StatusCode::NAME_NOT_FOUND as c_int;
@@ -53,7 +53,7 @@
     }
 
     // Try using the binder service through the wrong interface type
-    let wrong_service: Result<Box<dyn IBinderRustNdkInteropTestOther>, StatusCode> =
+    let wrong_service: Result<binder::Strong<dyn IBinderRustNdkInteropTestOther>, StatusCode> =
         binder::get_interface(service_name);
     match wrong_service {
         Err(e) if e == StatusCode::BAD_TYPE => {}