summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jooyung Han <jooyung@google.com> 2022-10-25 17:02:45 +0900
committer Jooyung Han <jooyung@google.com> 2022-10-26 09:42:59 +0900
commit76944fee1a642cdfbabaa72ef7d29e53af1d50db (patch)
tree3b0d45fa894dc8b3d9f7d2677e6a74d99323ba25
parent4e84148059c54ccbf64740c6841fdae46ce64b30 (diff)
servicemanager: getUpdatableNames()
This new method is a reverse of updatableViaApex(). It returns the list of declared instances which can be updated via the passed APEX. Updatable vendor apexes are supposed to be used only to update HAL services. APEXd can use this method to see if the target APEX is actually to updating HALs. It's not exposed to NDK/Java yet because there's no clients. Bug: 254201177 Test: TBD Change-Id: I7b5aa7d00a3ddeb13855816006a9561dfa601529
-rw-r--r--cmds/dumpsys/tests/dumpsys_test.cpp1
-rw-r--r--cmds/servicemanager/ServiceManager.cpp44
-rw-r--r--cmds/servicemanager/ServiceManager.h2
-rw-r--r--libs/binder/IServiceManager.cpp18
-rw-r--r--libs/binder/aidl/android/os/IServiceManager.aidl6
-rw-r--r--libs/binder/include/binder/IServiceManager.h6
-rw-r--r--libs/binder/servicedispatcher.cpp4
-rw-r--r--libs/fakeservicemanager/ServiceManager.cpp5
-rw-r--r--libs/fakeservicemanager/include/fakeservicemanager/ServiceManager.h2
9 files changed, 88 insertions, 0 deletions
diff --git a/cmds/dumpsys/tests/dumpsys_test.cpp b/cmds/dumpsys/tests/dumpsys_test.cpp
index f0c19b93ec..b8e5ce1a63 100644
--- a/cmds/dumpsys/tests/dumpsys_test.cpp
+++ b/cmds/dumpsys/tests/dumpsys_test.cpp
@@ -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>&));
diff --git a/cmds/servicemanager/ServiceManager.cpp b/cmds/servicemanager/ServiceManager.cpp
index 3681d5b8b9..2684f048f8 100644
--- a/cmds/servicemanager/ServiceManager.cpp
+++ b/cmds/servicemanager/ServiceManager.cpp
@@ -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;
@@ -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();
diff --git a/cmds/servicemanager/ServiceManager.h b/cmds/servicemanager/ServiceManager.h
index 07b79f80ac..b24c11c161 100644
--- a/cmds/servicemanager/ServiceManager.h
+++ b/cmds/servicemanager/ServiceManager.h
@@ -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,
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 05db7743f2..a0c43349a7 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -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:
@@ -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;
diff --git a/libs/binder/aidl/android/os/IServiceManager.aidl b/libs/binder/aidl/android/os/IServiceManager.aidl
index 5880c0a1bd..0fb1615391 100644
--- a/libs/binder/aidl/android/os/IServiceManager.aidl
+++ b/libs/binder/aidl/android/os/IServiceManager.aidl
@@ -114,6 +114,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
*/
@nullable ConnectionInfo getConnectionInfo(@utf8InCpp String name);
diff --git a/libs/binder/include/binder/IServiceManager.h b/libs/binder/include/binder/IServiceManager.h
index 413c97f349..79e771f092 100644
--- a/libs/binder/include/binder/IServiceManager.h
+++ b/libs/binder/include/binder/IServiceManager.h
@@ -115,6 +115,12 @@ public:
virtual std::optional<String16> updatableViaApex(const String16& name) = 0;
/**
+ * Returns all instances which are updatable via the APEX. Instance names are fully qualified
+ * like `pack.age.IFoo/default`.
+ */
+ virtual Vector<String16> getUpdatableNames(const String16& apexName) = 0;
+
+ /**
* If this instance has declared remote connection information, returns
* the ConnectionInfo.
*/
diff --git a/libs/binder/servicedispatcher.cpp b/libs/binder/servicedispatcher.cpp
index 777f3c9354..692cc95e3b 100644
--- a/libs/binder/servicedispatcher.cpp
+++ b/libs/binder/servicedispatcher.cpp
@@ -156,6 +156,10 @@ public:
std::optional<std::string>* _aidl_return) override {
return mImpl->updatableViaApex(name, _aidl_return);
}
+ android::binder::Status getUpdatableNames(const std::string& apexName,
+ std::vector<std::string>* _aidl_return) override {
+ return mImpl->getUpdatableNames(apexName, _aidl_return);
+ }
android::binder::Status getConnectionInfo(
const std::string& name,
std::optional<android::os::ConnectionInfo>* _aidl_return) override {
diff --git a/libs/fakeservicemanager/ServiceManager.cpp b/libs/fakeservicemanager/ServiceManager.cpp
index 6c6d7f3641..480ec79725 100644
--- a/libs/fakeservicemanager/ServiceManager.cpp
+++ b/libs/fakeservicemanager/ServiceManager.cpp
@@ -78,6 +78,11 @@ std::optional<String16> ServiceManager::updatableViaApex(const String16& name) {
return std::nullopt;
}
+Vector<String16> ServiceManager::getUpdatableNames(const String16& apexName) {
+ (void)apexName;
+ return {};
+}
+
std::optional<IServiceManager::ConnectionInfo> ServiceManager::getConnectionInfo(
const String16& name) {
(void)name;
diff --git a/libs/fakeservicemanager/include/fakeservicemanager/ServiceManager.h b/libs/fakeservicemanager/include/fakeservicemanager/ServiceManager.h
index e0af5d4ba8..ee0637eb7e 100644
--- a/libs/fakeservicemanager/include/fakeservicemanager/ServiceManager.h
+++ b/libs/fakeservicemanager/include/fakeservicemanager/ServiceManager.h
@@ -52,6 +52,8 @@ public:
std::optional<String16> updatableViaApex(const String16& name) override;
+ Vector<String16> getUpdatableNames(const String16& apexName) override;
+
std::optional<IServiceManager::ConnectionInfo> getConnectionInfo(const String16& name) override;
status_t registerForNotifications(const String16& name,