Query methods for VINTF native instances
isDeclared(name), getDeclaredInstances(interface),
updatableViaApex(name), and getUpdatableNames(apexName) are extended to
support native instances when
- "name" is formatted as e.g. "mapper/minigbm",
- "interface" is formatted as e.g. "mapper"
Bug: 316051788
Test: atest servicemanager_test
Test: atest --host servicemanager_unittest
Change-Id: I0520888dbf5d30c66b97058f45cd6828731ca8bc
diff --git a/cmds/servicemanager/ServiceManager.cpp b/cmds/servicemanager/ServiceManager.cpp
index f2f0a0f..bf85e61 100644
--- a/cmds/servicemanager/ServiceManager.cpp
+++ b/cmds/servicemanager/ServiceManager.cpp
@@ -35,6 +35,8 @@
#include <vintf/constants.h>
#endif // !VENDORSERVICEMANAGER
+#include "NameUtil.h"
+
using ::android::binder::Status;
using ::android::internal::Stability;
@@ -84,6 +86,10 @@
return false;
}
+static std::string getNativeInstanceName(const vintf::ManifestInstance& instance) {
+ return instance.package() + "/" + instance.instance();
+}
+
struct AidlName {
std::string package;
std::string iface;
@@ -105,7 +111,26 @@
}
};
+static std::string getAidlInstanceName(const vintf::ManifestInstance& instance) {
+ return instance.package() + "." + instance.interface() + "/" + instance.instance();
+}
+
static bool isVintfDeclared(const std::string& name) {
+ NativeName nname;
+ if (NativeName::fill(name, &nname)) {
+ bool found = forEachManifest([&](const ManifestWithDescription& mwd) {
+ if (mwd.manifest->hasNativeInstance(nname.package, nname.instance)) {
+ ALOGI("Found %s in %s VINTF manifest.", name.c_str(), mwd.description);
+ return true; // break
+ }
+ return false; // continue
+ });
+ if (!found) {
+ ALOGI("Could not find %s in the VINTF manifest.", name.c_str());
+ }
+ return found;
+ }
+
AidlName aname;
if (!AidlName::fill(name, &aname)) return false;
@@ -144,6 +169,24 @@
}
static std::optional<std::string> getVintfUpdatableApex(const std::string& name) {
+ NativeName nname;
+ if (NativeName::fill(name, &nname)) {
+ std::optional<std::string> updatableViaApex;
+
+ forEachManifest([&](const ManifestWithDescription& mwd) {
+ bool cont = mwd.manifest->forEachInstance([&](const auto& manifestInstance) {
+ if (manifestInstance.format() != vintf::HalFormat::NATIVE) return true;
+ if (manifestInstance.package() != nname.package) return true;
+ if (manifestInstance.instance() != nname.instance) return true;
+ updatableViaApex = manifestInstance.updatableViaApex();
+ return false; // break (libvintf uses opposite convention)
+ });
+ return !cont;
+ });
+
+ return updatableViaApex;
+ }
+
AidlName aname;
if (!AidlName::fill(name, &aname)) return std::nullopt;
@@ -164,24 +207,25 @@
return updatableViaApex;
}
-static std::vector<std::string> getVintfUpdatableInstances(const std::string& apexName) {
- std::vector<std::string> instances;
+static std::vector<std::string> getVintfUpdatableNames(const std::string& apexName) {
+ std::vector<std::string> names;
forEachManifest([&](const ManifestWithDescription& mwd) {
mwd.manifest->forEachInstance([&](const auto& manifestInstance) {
- if (manifestInstance.format() == vintf::HalFormat::AIDL &&
- manifestInstance.updatableViaApex().has_value() &&
+ if (manifestInstance.updatableViaApex().has_value() &&
manifestInstance.updatableViaApex().value() == apexName) {
- std::string aname = manifestInstance.package() + "." +
- manifestInstance.interface() + "/" + manifestInstance.instance();
- instances.push_back(aname);
+ if (manifestInstance.format() == vintf::HalFormat::NATIVE) {
+ names.push_back(getNativeInstanceName(manifestInstance));
+ } else if (manifestInstance.format() == vintf::HalFormat::AIDL) {
+ names.push_back(getAidlInstanceName(manifestInstance));
+ }
}
return true; // continue (libvintf uses opposite convention)
});
return false; // continue
});
- return instances;
+ return names;
}
static std::optional<ConnectionInfo> getVintfConnectionInfo(const std::string& name) {
@@ -216,6 +260,18 @@
static std::vector<std::string> getVintfInstances(const std::string& interface) {
size_t lastDot = interface.rfind('.');
if (lastDot == std::string::npos) {
+ // This might be a package for native instance.
+ std::vector<std::string> ret;
+ (void)forEachManifest([&](const ManifestWithDescription& mwd) {
+ auto instances = mwd.manifest->getNativeInstances(interface);
+ ret.insert(ret.end(), instances.begin(), instances.end());
+ return false; // continue
+ });
+ // If found, return it without error log.
+ if (!ret.empty()) {
+ return ret;
+ }
+
ALOGE("VINTF interfaces require names in Java package format (e.g. some.package.foo.IFoo) "
"but got: %s",
interface.c_str());
@@ -593,20 +649,20 @@
std::vector<std::string>* outReturn) {
auto ctx = mAccess->getCallingContext();
- std::vector<std::string> apexUpdatableInstances;
+ std::vector<std::string> apexUpdatableNames;
#ifndef VENDORSERVICEMANAGER
- apexUpdatableInstances = getVintfUpdatableInstances(apexName);
+ apexUpdatableNames = getVintfUpdatableNames(apexName);
#endif
outReturn->clear();
- for (const std::string& instance : apexUpdatableInstances) {
- if (mAccess->canFind(ctx, instance)) {
- outReturn->push_back(instance);
+ for (const std::string& name : apexUpdatableNames) {
+ if (mAccess->canFind(ctx, name)) {
+ outReturn->push_back(name);
}
}
- if (outReturn->size() == 0 && apexUpdatableInstances.size() != 0) {
+ if (outReturn->size() == 0 && apexUpdatableNames.size() != 0) {
return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied.");
}