Merge "Binder: enable/fix some warnings" into main
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index 80720b0..55161a5 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -100,7 +100,6 @@
     prebuilts: [
         // to enable arm64 host support, build with musl - e.g. on aosp_cf_arm64_phone
         "aidl",
-        "libc++",
     ],
     include_sources: true,
     cflags: [
diff --git a/libs/binder/TEST_MAPPING b/libs/binder/TEST_MAPPING
index 2b3ff44..1256173 100644
--- a/libs/binder/TEST_MAPPING
+++ b/libs/binder/TEST_MAPPING
@@ -129,6 +129,12 @@
       "name": "memunreachable_binder_test"
     }
   ],
+  "postsubmit": [
+    {
+      "name": "binder_sdk_test",
+      "host": true
+    }
+  ],
   "imports": [
     {
       "path": "packages/modules/Virtualization"
diff --git a/libs/binder/include/binder/Functional.h b/libs/binder/include/binder/Functional.h
index bb0e5f4..e153969 100644
--- a/libs/binder/include/binder/Functional.h
+++ b/libs/binder/include/binder/Functional.h
@@ -36,7 +36,7 @@
     inline void release() { f_.reset(); }
 
 private:
-    friend scope_guard<F> android::binder::impl::make_scope_guard(F);
+    friend scope_guard<F> android::binder::impl::make_scope_guard<>(F);
 
     inline scope_guard(F&& f) : f_(std::move(f)) {}
 
diff --git a/libs/binder/include/binder/ProcessState.h b/libs/binder/include/binder/ProcessState.h
index 8908cb8..021bd58 100644
--- a/libs/binder/include/binder/ProcessState.h
+++ b/libs/binder/include/binder/ProcessState.h
@@ -25,6 +25,7 @@
 
 #include <atomic>
 #include <chrono>
+#include <condition_variable>
 #include <mutex>
 
 // ---------------------------------------------------------------------------
diff --git a/libs/binder/rust/src/binder.rs b/libs/binder/rust/src/binder.rs
index e34d31e..9a252b8 100644
--- a/libs/binder/rust/src/binder.rs
+++ b/libs/binder/rust/src/binder.rs
@@ -768,14 +768,14 @@
         $interface:path[$descriptor:expr] {
             native: $native:ident($on_transact:path),
             proxy: $proxy:ident,
-            $(async: $async_interface:ident,)?
+            $(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
         }
     } => {
         $crate::declare_binder_interface! {
             $interface[$descriptor] {
                 native: $native($on_transact),
                 proxy: $proxy {},
-                $(async: $async_interface,)?
+                $(async: $async_interface $(($try_into_local_async))?,)?
                 stability: $crate::binder_impl::Stability::default(),
             }
         }
@@ -785,7 +785,7 @@
         $interface:path[$descriptor:expr] {
             native: $native:ident($on_transact:path),
             proxy: $proxy:ident,
-            $(async: $async_interface:ident,)?
+            $(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
             stability: $stability:expr,
         }
     } => {
@@ -793,7 +793,7 @@
             $interface[$descriptor] {
                 native: $native($on_transact),
                 proxy: $proxy {},
-                $(async: $async_interface,)?
+                $(async: $async_interface $(($try_into_local_async))?,)?
                 stability: $stability,
             }
         }
@@ -805,7 +805,7 @@
             proxy: $proxy:ident {
                 $($fname:ident: $fty:ty = $finit:expr),*
             },
-            $(async: $async_interface:ident,)?
+            $(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
         }
     } => {
         $crate::declare_binder_interface! {
@@ -814,7 +814,7 @@
                 proxy: $proxy {
                     $($fname: $fty = $finit),*
                 },
-                $(async: $async_interface,)?
+                $(async: $async_interface $(($try_into_local_async))?,)?
                 stability: $crate::binder_impl::Stability::default(),
             }
         }
@@ -826,7 +826,7 @@
             proxy: $proxy:ident {
                 $($fname:ident: $fty:ty = $finit:expr),*
             },
-            $(async: $async_interface:ident,)?
+            $(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
             stability: $stability:expr,
         }
     } => {
@@ -838,7 +838,7 @@
                 proxy: $proxy {
                     $($fname: $fty = $finit),*
                 },
-                $(async: $async_interface,)?
+                $(async: $async_interface $(($try_into_local_async))?,)?
                 stability: $stability,
             }
         }
@@ -854,7 +854,7 @@
                 $($fname:ident: $fty:ty = $finit:expr),*
             },
 
-            $( async: $async_interface:ident, )?
+            $(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
 
             stability: $stability:expr,
         }
@@ -1043,6 +1043,24 @@
                 }
 
                 if ibinder.associate_class(<$native as $crate::binder_impl::Remotable>::get_class()) {
+                    let service: std::result::Result<$crate::binder_impl::Binder<$native>, $crate::StatusCode> =
+                        std::convert::TryFrom::try_from(ibinder.clone());
+                    $(
+                    // This part is only generated if the user of the macro specifies that the
+                    // trait has an `try_into_local_async` implementation.
+                    if let Ok(service) = service {
+                        if let Some(async_service) = $native::$try_into_local_async(service) {
+                            // We were able to associate with our expected class,
+                            // the service is local, and the local service is async.
+                            return Ok(async_service);
+                        }
+                        // The service is local but not async. Fall back to treating it as a
+                        // remote service. This means that calls to this local service have an
+                        // extra performance cost due to serialization, but async handle to
+                        // non-async server is considered a rare case, so this is okay.
+                    }
+                    )?
+                    // Treat service as remote.
                     return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?)));
                 }
 
diff --git a/libs/binder/rust/tests/integration.rs b/libs/binder/rust/tests/integration.rs
index 15ae56f..5359832 100644
--- a/libs/binder/rust/tests/integration.rs
+++ b/libs/binder/rust/tests/integration.rs
@@ -182,7 +182,7 @@
         proxy: BpTest {
             x: i32 = 100
         },
-        async: IATest,
+        async: IATest(try_into_local_async),
     }
 }
 
@@ -323,6 +323,14 @@
     }
 }
 
+impl BnTest {
+    fn try_into_local_async<P: binder::BinderAsyncPool + 'static>(
+        me: Binder<BnTest>,
+    ) -> Option<binder::Strong<dyn IATest<P>>> {
+        Some(binder::Strong::new(Box::new(me) as _))
+    }
+}
+
 /// Trivial testing binder interface
 pub trait ITestSameDescriptor: Interface {}
 
@@ -900,6 +908,19 @@
         assert_eq!(service.test().unwrap(), service_name);
     }
 
+    #[tokio::test]
+    async fn reassociate_rust_binder_async() {
+        let service_name = "testing_service";
+        let service_ibinder =
+            BnTest::new_binder(TestService::new(service_name), BinderFeatures::default())
+                .as_binder();
+
+        let service: Strong<dyn IATest<Tokio>> =
+            service_ibinder.into_interface().expect("Could not reassociate the generic ibinder");
+
+        assert_eq!(service.test().await.unwrap(), service_name);
+    }
+
     #[test]
     fn weak_binder_upgrade() {
         let service_name = "testing_service";
diff --git a/libs/binder/tests/binder_sdk/binder_sdk_docker_test.sh b/libs/binder/tests/binder_sdk/binder_sdk_docker_test.sh
index 0eca846..9ea8cb3 100755
--- a/libs/binder/tests/binder_sdk/binder_sdk_docker_test.sh
+++ b/libs/binder/tests/binder_sdk/binder_sdk_docker_test.sh
@@ -57,7 +57,7 @@
         exit 1
     fi
     ${ANDROID_BUILD_TOP}/build/soong/soong_ui.bash --make-mode binder_sdk
-    BINDER_SDK_ZIP="${ANDROID_BUILD_TOP}/out/soong/.intermediates/frameworks/native/libs/binder/binder_sdk/linux_glibc_x86_64/*/binder_sdk.zip"
+    BINDER_SDK_ZIP="${ANDROID_BUILD_TOP}/out/soong/.intermediates/frameworks/native/libs/binder/binder_sdk/linux_glibc_x86_64/binder_sdk.zip"
     DOCKER_PATH="$(dirname $(ls -1 ${BINDER_SDK_ZIP} | head --lines=1))"
 fi