Loading media/utils/include/mediautils/BinderGenericUtils.h +18 −0 Original line number Diff line number Diff line Loading @@ -58,6 +58,24 @@ template<typename Interface> return interface->asBinder(); } /** * Returns true if two interfaces pointer-match, or represent identical binder objects. * * C++ with C++ and NDK with NDK interfaces may be compared. * * It currently isn't possible through the NDK public interface to extract * the underlying C++ binder object, so we don't allow NDK and C++ interfaces to * be cross-checked even though they might be backed by the same binder object. */ static inline bool isSameInterface(const sp<IInterface>& a, const sp<IInterface>& b) { return a == b || (a && b && IInterface::asBinder(a) == IInterface::asBinder(b)); } static inline bool isSameInterface(const std::shared_ptr<::ndk::ICInterface>& a, const std::shared_ptr<::ndk::ICInterface>& b) { return a == b || (a && b && a->asBinder() == b->asBinder()); } /** * Returns either a sp<Interface> or a std::shared_ptr<Interface> from a Binder object. * Loading media/utils/include/mediautils/ServiceSingleton.h +5 −1 Original line number Diff line number Diff line Loading @@ -318,7 +318,9 @@ private: [traits, this](const InterfaceType<Service>& service) { audio_utils::unique_lock ul(mMutex); auto originalService = std::get<BaseInterfaceType<Service>>(mService); if (originalService != service) { // we suppress equivalent services from being set // where either the pointers match or the binder objects match. if (!mediautils::isSameInterface(originalService, service)) { if (originalService != nullptr) { invalidateService_l<Service>(); } Loading Loading @@ -346,6 +348,8 @@ private: // sets the death notifier for mService (mService must be non-null). template <typename Service> void setDeathNotifier_l(const BaseInterfaceType<Service>& base) REQUIRES(mMutex) { // here the pointer match should be identical to binder object match // since we use a cached service. if (base != std::get<BaseInterfaceType<Service>>(mService)) { ALOGW("%s: service has changed for %s, skipping death notification registration", __func__, toString(Service::descriptor).c_str()); Loading media/utils/tests/service_singleton_tests.cpp +26 −0 Original line number Diff line number Diff line Loading @@ -251,9 +251,35 @@ TEST(service_singleton_tests, one_and_only) { auto service = mediautils::getService<IServiceSingletonTest>(); EXPECT_TRUE(service); // mediautils::getService<> is a cached service. // pointer equality is preserved for subsequent requests. auto service_equal = mediautils::getService<IServiceSingletonTest>(); EXPECT_EQ(service, service_equal); EXPECT_TRUE(mediautils::isSameInterface(service, service_equal)); // we can create an alias to the service by requesting it outside of the cache. // this is a different pointer, but same underlying binder object. auto service_equivalent = mediautils::checkServicePassThrough<IServiceSingletonTest>(); EXPECT_NE(service, service_equivalent); EXPECT_TRUE(mediautils::isSameInterface(service, service_equivalent)); auto service2 = mediautils::getService<aidl::IServiceSingletonTest>(); EXPECT_TRUE(service2); // mediautils::getService<> is a cached service. // pointer equality is preserved for subsequent requests. auto service2_equal = mediautils::getService<aidl::IServiceSingletonTest>(); EXPECT_EQ(service2, service2_equal); EXPECT_TRUE(mediautils::isSameInterface(service2, service2_equal)); // we can create an alias to the service by requesting it outside of the cache. // this is a different pointer, but same underlying binder object. auto service2_equivalent = mediautils::checkServicePassThrough<aidl::IServiceSingletonTest>(); EXPECT_NE(service2, service2_equivalent); EXPECT_TRUE(mediautils::isSameInterface(service2, service2_equivalent)); keepAlive = service2; // we can also request our own death notifications (outside of the service traits). Loading Loading
media/utils/include/mediautils/BinderGenericUtils.h +18 −0 Original line number Diff line number Diff line Loading @@ -58,6 +58,24 @@ template<typename Interface> return interface->asBinder(); } /** * Returns true if two interfaces pointer-match, or represent identical binder objects. * * C++ with C++ and NDK with NDK interfaces may be compared. * * It currently isn't possible through the NDK public interface to extract * the underlying C++ binder object, so we don't allow NDK and C++ interfaces to * be cross-checked even though they might be backed by the same binder object. */ static inline bool isSameInterface(const sp<IInterface>& a, const sp<IInterface>& b) { return a == b || (a && b && IInterface::asBinder(a) == IInterface::asBinder(b)); } static inline bool isSameInterface(const std::shared_ptr<::ndk::ICInterface>& a, const std::shared_ptr<::ndk::ICInterface>& b) { return a == b || (a && b && a->asBinder() == b->asBinder()); } /** * Returns either a sp<Interface> or a std::shared_ptr<Interface> from a Binder object. * Loading
media/utils/include/mediautils/ServiceSingleton.h +5 −1 Original line number Diff line number Diff line Loading @@ -318,7 +318,9 @@ private: [traits, this](const InterfaceType<Service>& service) { audio_utils::unique_lock ul(mMutex); auto originalService = std::get<BaseInterfaceType<Service>>(mService); if (originalService != service) { // we suppress equivalent services from being set // where either the pointers match or the binder objects match. if (!mediautils::isSameInterface(originalService, service)) { if (originalService != nullptr) { invalidateService_l<Service>(); } Loading Loading @@ -346,6 +348,8 @@ private: // sets the death notifier for mService (mService must be non-null). template <typename Service> void setDeathNotifier_l(const BaseInterfaceType<Service>& base) REQUIRES(mMutex) { // here the pointer match should be identical to binder object match // since we use a cached service. if (base != std::get<BaseInterfaceType<Service>>(mService)) { ALOGW("%s: service has changed for %s, skipping death notification registration", __func__, toString(Service::descriptor).c_str()); Loading
media/utils/tests/service_singleton_tests.cpp +26 −0 Original line number Diff line number Diff line Loading @@ -251,9 +251,35 @@ TEST(service_singleton_tests, one_and_only) { auto service = mediautils::getService<IServiceSingletonTest>(); EXPECT_TRUE(service); // mediautils::getService<> is a cached service. // pointer equality is preserved for subsequent requests. auto service_equal = mediautils::getService<IServiceSingletonTest>(); EXPECT_EQ(service, service_equal); EXPECT_TRUE(mediautils::isSameInterface(service, service_equal)); // we can create an alias to the service by requesting it outside of the cache. // this is a different pointer, but same underlying binder object. auto service_equivalent = mediautils::checkServicePassThrough<IServiceSingletonTest>(); EXPECT_NE(service, service_equivalent); EXPECT_TRUE(mediautils::isSameInterface(service, service_equivalent)); auto service2 = mediautils::getService<aidl::IServiceSingletonTest>(); EXPECT_TRUE(service2); // mediautils::getService<> is a cached service. // pointer equality is preserved for subsequent requests. auto service2_equal = mediautils::getService<aidl::IServiceSingletonTest>(); EXPECT_EQ(service2, service2_equal); EXPECT_TRUE(mediautils::isSameInterface(service2, service2_equal)); // we can create an alias to the service by requesting it outside of the cache. // this is a different pointer, but same underlying binder object. auto service2_equivalent = mediautils::checkServicePassThrough<aidl::IServiceSingletonTest>(); EXPECT_NE(service2, service2_equivalent); EXPECT_TRUE(mediautils::isSameInterface(service2, service2_equivalent)); keepAlive = service2; // we can also request our own death notifications (outside of the service traits). Loading