Allow set_requesting_sid to be enabled when AIDL Binder is created.

Bug: 181869875
Bug: 178852354
Test: mm
Change-Id: Iff84df4ee4eed2f24d02fd8156b575a443bbb0c6
diff --git a/libs/binder/rust/src/binder.rs b/libs/binder/rust/src/binder.rs
index 321b422..695a83e 100644
--- a/libs/binder/rust/src/binder.rs
+++ b/libs/binder/rust/src/binder.rs
@@ -548,6 +548,28 @@
     }
 }
 
+/// The features to enable when creating a native Binder.
+///
+/// This should always be initialised with a default value, e.g.:
+/// ```
+/// # use binder::BinderFeatures;
+/// BinderFeatures {
+///   set_requesting_sid: true,
+///   ..BinderFeatures::default(),
+/// }
+/// ```
+#[derive(Clone, Debug, Default, Eq, PartialEq)]
+pub struct BinderFeatures {
+    /// Indicates that the service intends to receive caller security contexts. This must be true
+    /// for `ThreadState::with_calling_sid` to work.
+    pub set_requesting_sid: bool,
+    // Ensure that clients include a ..BinderFeatures::default() to preserve backwards compatibility
+    // when new fields are added. #[non_exhaustive] doesn't work because it prevents struct
+    // expressions entirely.
+    #[doc(hidden)]
+    pub _non_exhaustive: (),
+}
+
 /// Declare typed interfaces for a binder object.
 ///
 /// Given an interface trait and descriptor string, create a native and remote
@@ -730,8 +752,9 @@
 
         impl $native {
             /// Create a new binder service.
-            pub fn new_binder<T: $interface + Sync + Send + 'static>(inner: T) -> $crate::Strong<dyn $interface> {
-                let binder = $crate::Binder::new_with_stability($native(Box::new(inner)), $stability);
+            pub fn new_binder<T: $interface + Sync + Send + 'static>(inner: T, features: $crate::BinderFeatures) -> $crate::Strong<dyn $interface> {
+                let mut binder = $crate::Binder::new_with_stability($native(Box::new(inner)), $stability);
+                $crate::IBinderInternal::set_requesting_sid(&mut binder, features.set_requesting_sid);
                 $crate::Strong::new(Box::new(binder))
             }
         }
diff --git a/libs/binder/rust/src/lib.rs b/libs/binder/rust/src/lib.rs
index 30928a5..2694cba 100644
--- a/libs/binder/rust/src/lib.rs
+++ b/libs/binder/rust/src/lib.rs
@@ -107,10 +107,9 @@
 pub mod parcel;
 
 pub use crate::binder::{
-    FromIBinder, IBinder, IBinderInternal, Interface, InterfaceClass, Remotable,
-    Stability, Strong, TransactionCode, TransactionFlags, Weak,
-    FIRST_CALL_TRANSACTION, FLAG_CLEAR_BUF, FLAG_ONEWAY, FLAG_PRIVATE_LOCAL,
-    LAST_CALL_TRANSACTION,
+    BinderFeatures, FromIBinder, IBinder, IBinderInternal, Interface, InterfaceClass, Remotable,
+    Stability, Strong, TransactionCode, TransactionFlags, Weak, FIRST_CALL_TRANSACTION,
+    FLAG_CLEAR_BUF, FLAG_ONEWAY, FLAG_PRIVATE_LOCAL, LAST_CALL_TRANSACTION,
 };
 pub use error::{status_t, ExceptionCode, Result, Status, StatusCode};
 pub use native::add_service;
@@ -125,8 +124,8 @@
     pub use super::parcel::ParcelFileDescriptor;
     pub use super::{add_service, get_interface};
     pub use super::{
-        DeathRecipient, ExceptionCode, IBinder, Interface, ProcessState, SpIBinder, Status,
-        StatusCode, Strong, ThreadState, Weak, WpIBinder,
+        BinderFeatures, DeathRecipient, ExceptionCode, IBinder, Interface, ProcessState, SpIBinder,
+        Status, StatusCode, Strong, ThreadState, Weak, WpIBinder,
     };
 
     /// Binder result containing a [`Status`] on error.
diff --git a/libs/binder/rust/tests/integration.rs b/libs/binder/rust/tests/integration.rs
index 60e3502..0332007 100644
--- a/libs/binder/rust/tests/integration.rs
+++ b/libs/binder/rust/tests/integration.rs
@@ -19,7 +19,7 @@
 use binder::declare_binder_interface;
 use binder::parcel::Parcel;
 use binder::{
-    Binder, IBinderInternal, Interface, StatusCode, ThreadState, TransactionCode,
+    Binder, BinderFeatures, IBinderInternal, Interface, StatusCode, ThreadState, TransactionCode,
     FIRST_CALL_TRANSACTION,
 };
 use std::convert::{TryFrom, TryInto};
@@ -55,7 +55,8 @@
         })));
         service.set_requesting_sid(true);
         if let Some(extension_name) = extension_name {
-            let extension = BnTest::new_binder(TestService { s: extension_name });
+            let extension =
+                BnTest::new_binder(TestService { s: extension_name }, BinderFeatures::default());
             service
                 .set_extension(&mut extension.as_binder())
                 .expect("Could not add extension");
@@ -212,8 +213,8 @@
     use std::time::Duration;
 
     use binder::{
-        Binder, DeathRecipient, FromIBinder, IBinder, IBinderInternal, Interface, SpIBinder,
-        StatusCode, Strong,
+        Binder, BinderFeatures, DeathRecipient, FromIBinder, IBinder, IBinderInternal, Interface,
+        SpIBinder, StatusCode, Strong,
     };
 
     use super::{BnTest, ITest, ITestSameDescriptor, TestService, RUST_SERVICE_BINARY};
@@ -495,9 +496,12 @@
     #[test]
     fn reassociate_rust_binder() {
         let service_name = "testing_service";
-        let service_ibinder = BnTest::new_binder(TestService {
-            s: service_name.to_string(),
-        })
+        let service_ibinder = BnTest::new_binder(
+            TestService {
+                s: service_name.to_string(),
+            },
+            BinderFeatures::default(),
+        )
         .as_binder();
 
         let service: Strong<dyn ITest> = service_ibinder
@@ -510,9 +514,12 @@
     #[test]
     fn weak_binder_upgrade() {
         let service_name = "testing_service";
-        let service = BnTest::new_binder(TestService {
-            s: service_name.to_string(),
-        });
+        let service = BnTest::new_binder(
+            TestService {
+                s: service_name.to_string(),
+            },
+            BinderFeatures::default(),
+        );
 
         let weak = Strong::downgrade(&service);
 
@@ -525,9 +532,12 @@
     fn weak_binder_upgrade_dead() {
         let service_name = "testing_service";
         let weak = {
-            let service = BnTest::new_binder(TestService {
-                s: service_name.to_string(),
-            });
+            let service = BnTest::new_binder(
+                TestService {
+                    s: service_name.to_string(),
+                },
+                BinderFeatures::default(),
+            );
 
             Strong::downgrade(&service)
         };
@@ -538,9 +548,12 @@
     #[test]
     fn weak_binder_clone() {
         let service_name = "testing_service";
-        let service = BnTest::new_binder(TestService {
-            s: service_name.to_string(),
-        });
+        let service = BnTest::new_binder(
+            TestService {
+                s: service_name.to_string(),
+            },
+            BinderFeatures::default(),
+        );
 
         let weak = Strong::downgrade(&service);
         let cloned = weak.clone();
@@ -556,12 +569,18 @@
     #[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(),
-        });
+        let service1 = BnTest::new_binder(
+            TestService {
+                s: "testing_service1".to_string(),
+            },
+            BinderFeatures::default(),
+        );
+        let service2 = BnTest::new_binder(
+            TestService {
+                s: "testing_service2".to_string(),
+            },
+            BinderFeatures::default(),
+        );
 
         assert!(!(service1 < service1));
         assert!(!(service1 > service1));
diff --git a/libs/binder/rust/tests/ndk_rust_interop.rs b/libs/binder/rust/tests/ndk_rust_interop.rs
index ce75ab7..4702e45 100644
--- a/libs/binder/rust/tests/ndk_rust_interop.rs
+++ b/libs/binder/rust/tests/ndk_rust_interop.rs
@@ -16,15 +16,13 @@
 
 //! Rust Binder NDK interop tests
 
-use std::ffi::CStr;
-use std::os::raw::{c_char, c_int};
-use ::IBinderRustNdkInteropTest::binder::{self, Interface, StatusCode};
 use ::IBinderRustNdkInteropTest::aidl::IBinderRustNdkInteropTest::{
     BnBinderRustNdkInteropTest, IBinderRustNdkInteropTest,
 };
-use ::IBinderRustNdkInteropTest::aidl::IBinderRustNdkInteropTestOther::{
-    IBinderRustNdkInteropTestOther,
-};
+use ::IBinderRustNdkInteropTest::aidl::IBinderRustNdkInteropTestOther::IBinderRustNdkInteropTestOther;
+use ::IBinderRustNdkInteropTest::binder::{self, BinderFeatures, Interface, StatusCode};
+use std::ffi::CStr;
+use std::os::raw::{c_char, c_int};
 
 /// Look up the provided AIDL service and call its echo method.
 ///
@@ -37,18 +35,21 @@
 
     // The Rust class descriptor pointer will not match the NDK one, but the
     // descriptor strings match so this needs to still associate.
-    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;
-        }
-        Ok(service) => service,
-    };
+    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;
+            }
+            Ok(service) => service,
+        };
 
     match service.echo("testing") {
-        Ok(s) => if s != "testing" {
-            return StatusCode::BAD_VALUE as c_int;
-        },
+        Ok(s) => {
+            if s != "testing" {
+                return StatusCode::BAD_VALUE as c_int;
+            }
+        }
         Err(e) => return e.into(),
     }
 
@@ -88,7 +89,7 @@
 #[no_mangle]
 pub unsafe extern "C" fn rust_start_service(service_name: *const c_char) -> c_int {
     let service_name = CStr::from_ptr(service_name).to_str().unwrap();
-    let service = BnBinderRustNdkInteropTest::new_binder(Service);
+    let service = BnBinderRustNdkInteropTest::new_binder(Service, BinderFeatures::default());
     match binder::add_service(&service_name, service.as_binder()) {
         Ok(_) => StatusCode::OK as c_int,
         Err(e) => e as c_int,
diff --git a/libs/binder/rust/tests/serialization.rs b/libs/binder/rust/tests/serialization.rs
index f1b068e..66ba846 100644
--- a/libs/binder/rust/tests/serialization.rs
+++ b/libs/binder/rust/tests/serialization.rs
@@ -18,11 +18,11 @@
 //! access.
 
 use binder::declare_binder_interface;
+use binder::parcel::ParcelFileDescriptor;
 use binder::{
-    Binder, ExceptionCode, Interface, Parcel, Result, SpIBinder, Status,
+    Binder, BinderFeatures, ExceptionCode, Interface, Parcel, Result, SpIBinder, Status,
     StatusCode, TransactionCode,
 };
-use binder::parcel::ParcelFileDescriptor;
 
 use std::ffi::{c_void, CStr, CString};
 use std::sync::Once;
@@ -85,7 +85,7 @@
 pub extern "C" fn rust_service() -> *mut c_void {
     unsafe {
         SERVICE_ONCE.call_once(|| {
-            SERVICE = Some(BnReadParcelTest::new_binder(()).as_binder());
+            SERVICE = Some(BnReadParcelTest::new_binder((), BinderFeatures::default()).as_binder());
         });
         SERVICE.as_ref().unwrap().as_raw().cast()
     }
@@ -108,8 +108,12 @@
 impl ReadParcelTest for () {}
 
 #[allow(clippy::float_cmp)]
-fn on_transact(_service: &dyn ReadParcelTest, code: TransactionCode,
-               parcel: &Parcel, reply: &mut Parcel) -> Result<()> {
+fn on_transact(
+    _service: &dyn ReadParcelTest,
+    code: TransactionCode,
+    parcel: &Parcel,
+    reply: &mut Parcel,
+) -> Result<()> {
     match code {
         bindings::Transaction_TEST_BOOL => {
             assert_eq!(parcel.read::<bool>()?, true);