Loading cmds/dumpsys/tests/dumpsys_test.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ class ServiceManagerMock : public IServiceManager { MOCK_METHOD1(isDeclared, bool(const String16&)); MOCK_METHOD1(getDeclaredInstances, Vector<String16>(const String16&)); MOCK_METHOD1(updatableViaApex, std::optional<String16>(const String16&)); MOCK_METHOD1(getUpdatableNames, Vector<String16>(const String16&)); MOCK_METHOD1(getConnectionInfo, std::optional<ConnectionInfo>(const String16&)); MOCK_METHOD2(registerForNotifications, status_t(const String16&, const sp<LocalRegistrationCallback>&)); Loading cmds/servicemanager/ServiceManager.cpp +44 −0 Original line number Diff line number Diff line Loading @@ -142,6 +142,26 @@ static std::optional<std::string> getVintfUpdatableApex(const std::string& name) return updatableViaApex; } static std::vector<std::string> getVintfUpdatableInstances(const std::string& apexName) { std::vector<std::string> instances; forEachManifest([&](const ManifestWithDescription& mwd) { mwd.manifest->forEachInstance([&](const auto& manifestInstance) { if (manifestInstance.format() == vintf::HalFormat::AIDL && manifestInstance.updatableViaApex().has_value() && manifestInstance.updatableViaApex().value() == apexName) { std::string aname = manifestInstance.package() + "." + manifestInstance.interface() + "/" + manifestInstance.instance(); instances.push_back(aname); } return false; // continue }); return false; // continue }); return instances; } static std::optional<ConnectionInfo> getVintfConnectionInfo(const std::string& name) { AidlName aname; if (!AidlName::fill(name, &aname)) return std::nullopt; Loading Loading @@ -512,6 +532,30 @@ Status ServiceManager::updatableViaApex(const std::string& name, return Status::ok(); } Status ServiceManager::getUpdatableNames([[maybe_unused]] const std::string& apexName, std::vector<std::string>* outReturn) { auto ctx = mAccess->getCallingContext(); std::vector<std::string> apexUpdatableInstances; #ifndef VENDORSERVICEMANAGER apexUpdatableInstances = getVintfUpdatableInstances(apexName); #endif outReturn->clear(); for (const std::string& instance : apexUpdatableInstances) { if (mAccess->canFind(ctx, instance)) { outReturn->push_back(instance); } } if (outReturn->size() == 0 && apexUpdatableInstances.size() != 0) { return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denial"); } return Status::ok(); } Status ServiceManager::getConnectionInfo(const std::string& name, std::optional<ConnectionInfo>* outReturn) { auto ctx = mAccess->getCallingContext(); Loading cmds/servicemanager/ServiceManager.h +2 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,8 @@ public: binder::Status getDeclaredInstances(const std::string& interface, std::vector<std::string>* outReturn) override; binder::Status updatableViaApex(const std::string& name, std::optional<std::string>* outReturn) override; binder::Status getUpdatableNames(const std::string& apexName, std::vector<std::string>* outReturn) override; binder::Status getConnectionInfo(const std::string& name, std::optional<ConnectionInfo>* outReturn) override; binder::Status registerClientCallback(const std::string& name, const sp<IBinder>& service, Loading libs/binder/IServiceManager.cpp +18 −0 Original line number Diff line number Diff line Loading @@ -81,6 +81,7 @@ public: bool isDeclared(const String16& name) override; Vector<String16> getDeclaredInstances(const String16& interface) override; std::optional<String16> updatableViaApex(const String16& name) override; Vector<String16> getUpdatableNames(const String16& apexName) override; std::optional<IServiceManager::ConnectionInfo> getConnectionInfo(const String16& name) override; class RegistrationWaiter : public android::os::BnServiceCallback { public: Loading Loading @@ -479,6 +480,23 @@ std::optional<String16> ServiceManagerShim::updatableViaApex(const String16& nam return declared ? std::optional<String16>(String16(declared.value().c_str())) : std::nullopt; } Vector<String16> ServiceManagerShim::getUpdatableNames(const String16& apexName) { std::vector<std::string> out; if (Status status = mTheRealServiceManager->getUpdatableNames(String8(apexName).c_str(), &out); !status.isOk()) { ALOGW("Failed to getUpdatableNames for %s: %s", String8(apexName).c_str(), status.toString8().c_str()); return {}; } Vector<String16> res; res.setCapacity(out.size()); for (const std::string& instance : out) { res.push(String16(instance.c_str())); } return res; } std::optional<IServiceManager::ConnectionInfo> ServiceManagerShim::getConnectionInfo( const String16& name) { std::optional<os::ConnectionInfo> connectionInfo; Loading libs/binder/aidl/android/os/IServiceManager.aidl +6 −0 Original line number Diff line number Diff line Loading @@ -113,6 +113,12 @@ interface IServiceManager { */ @nullable @utf8InCpp String updatableViaApex(@utf8InCpp String name); /** * Returns all instances which are updatable via the APEX. Instance names are fully qualified * like `pack.age.IFoo/default`. */ @utf8InCpp String[] getUpdatableNames(@utf8InCpp String apexName); /** * If connection info is available for the given instance, returns the ConnectionInfo */ Loading Loading
cmds/dumpsys/tests/dumpsys_test.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ class ServiceManagerMock : public IServiceManager { MOCK_METHOD1(isDeclared, bool(const String16&)); MOCK_METHOD1(getDeclaredInstances, Vector<String16>(const String16&)); MOCK_METHOD1(updatableViaApex, std::optional<String16>(const String16&)); MOCK_METHOD1(getUpdatableNames, Vector<String16>(const String16&)); MOCK_METHOD1(getConnectionInfo, std::optional<ConnectionInfo>(const String16&)); MOCK_METHOD2(registerForNotifications, status_t(const String16&, const sp<LocalRegistrationCallback>&)); Loading
cmds/servicemanager/ServiceManager.cpp +44 −0 Original line number Diff line number Diff line Loading @@ -142,6 +142,26 @@ static std::optional<std::string> getVintfUpdatableApex(const std::string& name) return updatableViaApex; } static std::vector<std::string> getVintfUpdatableInstances(const std::string& apexName) { std::vector<std::string> instances; forEachManifest([&](const ManifestWithDescription& mwd) { mwd.manifest->forEachInstance([&](const auto& manifestInstance) { if (manifestInstance.format() == vintf::HalFormat::AIDL && manifestInstance.updatableViaApex().has_value() && manifestInstance.updatableViaApex().value() == apexName) { std::string aname = manifestInstance.package() + "." + manifestInstance.interface() + "/" + manifestInstance.instance(); instances.push_back(aname); } return false; // continue }); return false; // continue }); return instances; } static std::optional<ConnectionInfo> getVintfConnectionInfo(const std::string& name) { AidlName aname; if (!AidlName::fill(name, &aname)) return std::nullopt; Loading Loading @@ -512,6 +532,30 @@ Status ServiceManager::updatableViaApex(const std::string& name, return Status::ok(); } Status ServiceManager::getUpdatableNames([[maybe_unused]] const std::string& apexName, std::vector<std::string>* outReturn) { auto ctx = mAccess->getCallingContext(); std::vector<std::string> apexUpdatableInstances; #ifndef VENDORSERVICEMANAGER apexUpdatableInstances = getVintfUpdatableInstances(apexName); #endif outReturn->clear(); for (const std::string& instance : apexUpdatableInstances) { if (mAccess->canFind(ctx, instance)) { outReturn->push_back(instance); } } if (outReturn->size() == 0 && apexUpdatableInstances.size() != 0) { return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denial"); } return Status::ok(); } Status ServiceManager::getConnectionInfo(const std::string& name, std::optional<ConnectionInfo>* outReturn) { auto ctx = mAccess->getCallingContext(); Loading
cmds/servicemanager/ServiceManager.h +2 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,8 @@ public: binder::Status getDeclaredInstances(const std::string& interface, std::vector<std::string>* outReturn) override; binder::Status updatableViaApex(const std::string& name, std::optional<std::string>* outReturn) override; binder::Status getUpdatableNames(const std::string& apexName, std::vector<std::string>* outReturn) override; binder::Status getConnectionInfo(const std::string& name, std::optional<ConnectionInfo>* outReturn) override; binder::Status registerClientCallback(const std::string& name, const sp<IBinder>& service, Loading
libs/binder/IServiceManager.cpp +18 −0 Original line number Diff line number Diff line Loading @@ -81,6 +81,7 @@ public: bool isDeclared(const String16& name) override; Vector<String16> getDeclaredInstances(const String16& interface) override; std::optional<String16> updatableViaApex(const String16& name) override; Vector<String16> getUpdatableNames(const String16& apexName) override; std::optional<IServiceManager::ConnectionInfo> getConnectionInfo(const String16& name) override; class RegistrationWaiter : public android::os::BnServiceCallback { public: Loading Loading @@ -479,6 +480,23 @@ std::optional<String16> ServiceManagerShim::updatableViaApex(const String16& nam return declared ? std::optional<String16>(String16(declared.value().c_str())) : std::nullopt; } Vector<String16> ServiceManagerShim::getUpdatableNames(const String16& apexName) { std::vector<std::string> out; if (Status status = mTheRealServiceManager->getUpdatableNames(String8(apexName).c_str(), &out); !status.isOk()) { ALOGW("Failed to getUpdatableNames for %s: %s", String8(apexName).c_str(), status.toString8().c_str()); return {}; } Vector<String16> res; res.setCapacity(out.size()); for (const std::string& instance : out) { res.push(String16(instance.c_str())); } return res; } std::optional<IServiceManager::ConnectionInfo> ServiceManagerShim::getConnectionInfo( const String16& name) { std::optional<os::ConnectionInfo> connectionInfo; Loading
libs/binder/aidl/android/os/IServiceManager.aidl +6 −0 Original line number Diff line number Diff line Loading @@ -113,6 +113,12 @@ interface IServiceManager { */ @nullable @utf8InCpp String updatableViaApex(@utf8InCpp String name); /** * Returns all instances which are updatable via the APEX. Instance names are fully qualified * like `pack.age.IFoo/default`. */ @utf8InCpp String[] getUpdatableNames(@utf8InCpp String apexName); /** * If connection info is available for the given instance, returns the ConnectionInfo */ Loading