diff options
| -rw-r--r-- | libs/binder/ndk/ibinder.cpp | 11 | ||||
| -rw-r--r-- | libs/binder/ndk/include_platform/android/binder_ibinder_platform.h | 34 | ||||
| -rw-r--r-- | libs/binder/ndk/libbinder_ndk.map.txt | 12 | ||||
| -rw-r--r-- | libs/binder/ndk/tests/IBinderNdkUnitTest.aidl | 2 | ||||
| -rw-r--r-- | libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp | 28 |
5 files changed, 81 insertions, 6 deletions
diff --git a/libs/binder/ndk/ibinder.cpp b/libs/binder/ndk/ibinder.cpp index 7540cae391..d287290a8d 100644 --- a/libs/binder/ndk/ibinder.cpp +++ b/libs/binder/ndk/ibinder.cpp @@ -698,3 +698,14 @@ void AIBinder_setRequestingSid(AIBinder* binder, bool requestingSid) { const char* AIBinder_getCallingSid() { return ::android::IPCThreadState::self()->getCallingSid(); } + +android::sp<android::IBinder> AIBinder_toPlatformBinder(AIBinder* binder) { + if (binder == nullptr) return nullptr; + return binder->getBinder(); +} + +AIBinder* AIBinder_fromPlatformBinder(const android::sp<android::IBinder>& binder) { + sp<AIBinder> ndkBinder = ABpBinder::lookupOrCreateFromBinder(binder); + AIBinder_incStrong(ndkBinder.get()); + return ndkBinder.get(); +} diff --git a/libs/binder/ndk/include_platform/android/binder_ibinder_platform.h b/libs/binder/ndk/include_platform/android/binder_ibinder_platform.h index 1f5a2373a2..d4feabac8a 100644 --- a/libs/binder/ndk/include_platform/android/binder_ibinder_platform.h +++ b/libs/binder/ndk/include_platform/android/binder_ibinder_platform.h @@ -18,6 +18,10 @@ #include <android/binder_ibinder.h> +#if !defined(__ANDROID_APEX__) && !defined(__ANDROID_VNDK__) +#include <binder/IBinder.h> +#endif + __BEGIN_DECLS /** @@ -44,3 +48,33 @@ void AIBinder_setRequestingSid(AIBinder* binder, bool requestingSid) __INTRODUCE __attribute__((warn_unused_result)) const char* AIBinder_getCallingSid() __INTRODUCED_IN(31); __END_DECLS + +#if !defined(__ANDROID_APEX__) && !defined(__ANDROID_VNDK__) + +/** + * Get libbinder version of binder from AIBinder. + * + * WARNING: function calls to a local object on the other side of this function + * will parcel. When converting between binders, keep in mind it is not as + * efficient as a direct function call. + * + * \param binder binder with ownership retained by the client + * \return platform binder object + */ +android::sp<android::IBinder> AIBinder_toPlatformBinder(AIBinder* binder); + +/** + * Get libbinder_ndk version of binder from platform binder. + * + * WARNING: function calls to a local object on the other side of this function + * will parcel. When converting between binders, keep in mind it is not as + * efficient as a direct function call. + * + * \param binder platform binder which may be from anywhere (doesn't have to be + * created with libbinder_ndK) + * \return binder with one reference count of ownership given to the client. See + * AIBinder_decStrong + */ +AIBinder* AIBinder_fromPlatformBinder(const android::sp<android::IBinder>& binder); + +#endif diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt index d58b75c2d2..9b5fa26303 100644 --- a/libs/binder/ndk/libbinder_ndk.map.txt +++ b/libs/binder/ndk/libbinder_ndk.map.txt @@ -95,8 +95,6 @@ LIBBINDER_NDK { # introduced=29 AServiceManager_addService; # apex llndk AServiceManager_checkService; # apex llndk AServiceManager_getService; # apex llndk - local: - *; }; LIBBINDER_NDK30 { # introduced=30 @@ -111,19 +109,21 @@ LIBBINDER_NDK30 { # introduced=30 AIBinder_markVendorStability; # llndk AIBinder_markVintfStability; # apex llndk AIBinder_Class_setHandleShellCommand; # apex llndk - local: - *; }; LIBBINDER_NDK31 { # introduced=31 global: AIBinder_getCallingSid; # apex AIBinder_setRequestingSid; # apex - local: - *; }; LIBBINDER_NDK_PLATFORM { global: AParcel_getAllowFds; + extern "C++" { + AIBinder_fromPlatformBinder*; + AIBinder_toPlatformBinder*; + }; + local: + *; }; diff --git a/libs/binder/ndk/tests/IBinderNdkUnitTest.aidl b/libs/binder/ndk/tests/IBinderNdkUnitTest.aidl index 4bba9e4317..dc77467d8c 100644 --- a/libs/binder/ndk/tests/IBinderNdkUnitTest.aidl +++ b/libs/binder/ndk/tests/IBinderNdkUnitTest.aidl @@ -22,6 +22,8 @@ import IEmpty; interface IBinderNdkUnitTest { + int repeatInt(int a); + void takeInterface(IEmpty test); void forceFlushCommands(); diff --git a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp index 6869220727..e3fdb4bab3 100644 --- a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp +++ b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp @@ -44,6 +44,10 @@ constexpr char kExistingNonNdkService[] = "SurfaceFlinger"; constexpr char kBinderNdkUnitTestService[] = "BinderNdkUnitTest"; class MyBinderNdkUnitTest : public aidl::BnBinderNdkUnitTest { + ndk::ScopedAStatus repeatInt(int32_t in, int32_t* out) { + *out = in; + return ndk::ScopedAStatus::ok(); + } ndk::ScopedAStatus takeInterface(const std::shared_ptr<aidl::IEmpty>& empty) { (void)empty; return ndk::ScopedAStatus::ok(); @@ -329,6 +333,30 @@ TEST(NdkBinder, SentAidlBinderCanBeDestroyed) { EXPECT_TRUE(destroyed); } +TEST(NdkBinder, ConvertToPlatformBinder) { + for (const ndk::SpAIBinder& binder : + {// remote + ndk::SpAIBinder(AServiceManager_getService(kBinderNdkUnitTestService)), + // local + ndk::SharedRefBase::make<MyBinderNdkUnitTest>()->asBinder()}) { + // convert to platform binder + EXPECT_NE(binder.get(), nullptr); + sp<IBinder> platformBinder = AIBinder_toPlatformBinder(binder.get()); + EXPECT_NE(platformBinder.get(), nullptr); + auto proxy = interface_cast<IBinderNdkUnitTest>(platformBinder); + EXPECT_NE(proxy, nullptr); + + // use platform binder + int out; + EXPECT_TRUE(proxy->repeatInt(4, &out).isOk()); + EXPECT_EQ(out, 4); + + // convert back + ndk::SpAIBinder backBinder = ndk::SpAIBinder(AIBinder_fromPlatformBinder(platformBinder)); + EXPECT_EQ(backBinder.get(), binder.get()); + } +} + class MyResultReceiver : public BnResultReceiver { public: Mutex mMutex; |