libbinder_rs: Add Strong<> and Weak<> Binder references

Adds Strong<dyn Interface> and Weak<dyn Interface> references for Binder
interfaces. These structs are equivalent to sp<Interface> and
wp<Interface> in C++.

Bug: 175584883
Test: atest -p frameworks/native/libs/binder/TEST_MAPPING
Change-Id: Icf1b3acf0d8c82d541281a5aae9814372a5ab800
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),