Loading cmds/dumpsys/tests/dumpsys_test.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ class ServiceManagerMock : public IServiceManager { MOCK_METHOD4(addService, status_t(const String16&, const sp<IBinder>&, bool, int)); MOCK_METHOD1(listServices, Vector<String16>(int)); MOCK_METHOD1(waitForService, sp<IBinder>(const String16&)); MOCK_METHOD1(isDeclared, bool(const String16&)); protected: MOCK_METHOD0(onAsBinder, IBinder*()); }; Loading cmds/servicemanager/ServiceManager.cpp +24 −5 Original line number Diff line number Diff line Loading @@ -34,11 +34,7 @@ using ::android::internal::Stability; namespace android { #ifndef VENDORSERVICEMANAGER static bool meetsDeclarationRequirements(const sp<IBinder>& binder, const std::string& name) { if (!Stability::requiresVintfDeclaration(binder)) { return true; } static bool isVintfDeclared(const std::string& name) { size_t firstSlash = name.find('/'); size_t lastDot = name.rfind('.', firstSlash); if (firstSlash == std::string::npos || lastDot == std::string::npos) { Loading @@ -62,6 +58,14 @@ static bool meetsDeclarationRequirements(const sp<IBinder>& binder, const std::s << " in the VINTF manifest."; return false; } static bool meetsDeclarationRequirements(const sp<IBinder>& binder, const std::string& name) { if (!Stability::requiresVintfDeclaration(binder)) { return true; } return isVintfDeclared(name); } #endif // !VENDORSERVICEMANAGER ServiceManager::ServiceManager(std::unique_ptr<Access>&& access) : mAccess(std::move(access)) {} Loading Loading @@ -270,6 +274,21 @@ Status ServiceManager::unregisterForNotifications( return Status::ok(); } Status ServiceManager::isDeclared(const std::string& name, bool* outReturn) { auto ctx = mAccess->getCallingContext(); if (!mAccess->canFind(ctx, name)) { return Status::fromExceptionCode(Status::EX_SECURITY); } *outReturn = false; #ifndef VENDORSERVICEMANAGER *outReturn = isVintfDeclared(name); #endif return Status::ok(); } void ServiceManager::removeCallback(const wp<IBinder>& who, CallbackMap::iterator* it, bool* found) { Loading cmds/servicemanager/ServiceManager.h +1 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ public: const sp<IServiceCallback>& callback) override; binder::Status unregisterForNotifications(const std::string& name, const sp<IServiceCallback>& callback) override; binder::Status isDeclared(const std::string& name, bool* outReturn) override; void binderDied(const wp<IBinder>& who) override; Loading libs/binder/IServiceManager.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,7 @@ public: bool allowIsolated, int dumpsysPriority) override; Vector<String16> listServices(int dumpsysPriority) override; sp<IBinder> waitForService(const String16& name16) override; bool isDeclared(const String16& name) override; // for legacy ABI const String16& getInterfaceDescriptor() const override { Loading Loading @@ -321,4 +322,12 @@ sp<IBinder> ServiceManagerShim::waitForService(const String16& name16) } } bool ServiceManagerShim::isDeclared(const String16& name) { bool declared; if (!mTheRealServiceManager->isDeclared(String8(name).c_str(), &declared).isOk()) { return false; } return declared; } } // namespace android libs/binder/aidl/android/os/IServiceManager.aidl +7 −0 Original line number Diff line number Diff line Loading @@ -89,4 +89,11 @@ interface IServiceManager { * Unregisters all requests for notifications for a specific callback. */ void unregisterForNotifications(@utf8InCpp String name, IServiceCallback callback); /** * Returns whether a given interface is declared on the device, even if it * is not started yet. For instance, this could be a service declared in the VINTF * manifest. */ boolean isDeclared(@utf8InCpp String name); } Loading
cmds/dumpsys/tests/dumpsys_test.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ class ServiceManagerMock : public IServiceManager { MOCK_METHOD4(addService, status_t(const String16&, const sp<IBinder>&, bool, int)); MOCK_METHOD1(listServices, Vector<String16>(int)); MOCK_METHOD1(waitForService, sp<IBinder>(const String16&)); MOCK_METHOD1(isDeclared, bool(const String16&)); protected: MOCK_METHOD0(onAsBinder, IBinder*()); }; Loading
cmds/servicemanager/ServiceManager.cpp +24 −5 Original line number Diff line number Diff line Loading @@ -34,11 +34,7 @@ using ::android::internal::Stability; namespace android { #ifndef VENDORSERVICEMANAGER static bool meetsDeclarationRequirements(const sp<IBinder>& binder, const std::string& name) { if (!Stability::requiresVintfDeclaration(binder)) { return true; } static bool isVintfDeclared(const std::string& name) { size_t firstSlash = name.find('/'); size_t lastDot = name.rfind('.', firstSlash); if (firstSlash == std::string::npos || lastDot == std::string::npos) { Loading @@ -62,6 +58,14 @@ static bool meetsDeclarationRequirements(const sp<IBinder>& binder, const std::s << " in the VINTF manifest."; return false; } static bool meetsDeclarationRequirements(const sp<IBinder>& binder, const std::string& name) { if (!Stability::requiresVintfDeclaration(binder)) { return true; } return isVintfDeclared(name); } #endif // !VENDORSERVICEMANAGER ServiceManager::ServiceManager(std::unique_ptr<Access>&& access) : mAccess(std::move(access)) {} Loading Loading @@ -270,6 +274,21 @@ Status ServiceManager::unregisterForNotifications( return Status::ok(); } Status ServiceManager::isDeclared(const std::string& name, bool* outReturn) { auto ctx = mAccess->getCallingContext(); if (!mAccess->canFind(ctx, name)) { return Status::fromExceptionCode(Status::EX_SECURITY); } *outReturn = false; #ifndef VENDORSERVICEMANAGER *outReturn = isVintfDeclared(name); #endif return Status::ok(); } void ServiceManager::removeCallback(const wp<IBinder>& who, CallbackMap::iterator* it, bool* found) { Loading
cmds/servicemanager/ServiceManager.h +1 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ public: const sp<IServiceCallback>& callback) override; binder::Status unregisterForNotifications(const std::string& name, const sp<IServiceCallback>& callback) override; binder::Status isDeclared(const std::string& name, bool* outReturn) override; void binderDied(const wp<IBinder>& who) override; Loading
libs/binder/IServiceManager.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,7 @@ public: bool allowIsolated, int dumpsysPriority) override; Vector<String16> listServices(int dumpsysPriority) override; sp<IBinder> waitForService(const String16& name16) override; bool isDeclared(const String16& name) override; // for legacy ABI const String16& getInterfaceDescriptor() const override { Loading Loading @@ -321,4 +322,12 @@ sp<IBinder> ServiceManagerShim::waitForService(const String16& name16) } } bool ServiceManagerShim::isDeclared(const String16& name) { bool declared; if (!mTheRealServiceManager->isDeclared(String8(name).c_str(), &declared).isOk()) { return false; } return declared; } } // namespace android
libs/binder/aidl/android/os/IServiceManager.aidl +7 −0 Original line number Diff line number Diff line Loading @@ -89,4 +89,11 @@ interface IServiceManager { * Unregisters all requests for notifications for a specific callback. */ void unregisterForNotifications(@utf8InCpp String name, IServiceCallback callback); /** * Returns whether a given interface is declared on the device, even if it * is not started yet. For instance, this could be a service declared in the VINTF * manifest. */ boolean isDeclared(@utf8InCpp String name); }