summaryrefslogtreecommitdiff
path: root/cmds/servicemanager/ServiceManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cmds/servicemanager/ServiceManager.cpp')
-rw-r--r--cmds/servicemanager/ServiceManager.cpp194
1 files changed, 32 insertions, 162 deletions
diff --git a/cmds/servicemanager/ServiceManager.cpp b/cmds/servicemanager/ServiceManager.cpp
index 90db5091e1..1f9892a262 100644
--- a/cmds/servicemanager/ServiceManager.cpp
+++ b/cmds/servicemanager/ServiceManager.cpp
@@ -37,12 +37,22 @@ using ::android::internal::Stability;
namespace android {
#ifndef VENDORSERVICEMANAGER
-struct ManifestWithDescription {
- std::shared_ptr<const vintf::HalManifest> manifest;
- const char* description;
-};
-// func true -> stop search and forEachManifest will return true
-static bool forEachManifest(const std::function<bool(const ManifestWithDescription&)>& func) {
+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) {
+ LOG(ERROR) << "VINTF HALs require names in the format type/instance (e.g. "
+ << "some.package.foo.IFoo/default) but got: " << name;
+ return false;
+ }
+ const std::string package = name.substr(0, lastDot);
+ const std::string iface = name.substr(lastDot+1, firstSlash-lastDot-1);
+ const std::string instance = name.substr(firstSlash+1);
+
+ struct ManifestWithDescription {
+ std::shared_ptr<const vintf::HalManifest> manifest;
+ const char* description;
+ };
for (const ManifestWithDescription& mwd : {
ManifestWithDescription{ vintf::VintfObject::GetDeviceHalManifest(), "device" },
ManifestWithDescription{ vintf::VintfObject::GetFrameworkHalManifest(), "framework" },
@@ -53,91 +63,17 @@ static bool forEachManifest(const std::function<bool(const ManifestWithDescripti
// or other bugs (b/151696835)
continue;
}
- if (func(mwd)) return true;
- }
- return false;
-}
-
-struct AidlName {
- std::string package;
- std::string iface;
- std::string instance;
-
- static bool fill(const std::string& name, AidlName* aname) {
- size_t firstSlash = name.find('/');
- size_t lastDot = name.rfind('.', firstSlash);
- if (firstSlash == std::string::npos || lastDot == std::string::npos) {
- LOG(ERROR) << "VINTF HALs require names in the format type/instance (e.g. "
- << "some.package.foo.IFoo/default) but got: " << name;
- return false;
- }
- aname->package = name.substr(0, lastDot);
- aname->iface = name.substr(lastDot + 1, firstSlash - lastDot - 1);
- aname->instance = name.substr(firstSlash + 1);
- return true;
- }
-};
-
-static bool isVintfDeclared(const std::string& name) {
- AidlName aname;
- if (!AidlName::fill(name, &aname)) return false;
-
- bool found = forEachManifest([&](const ManifestWithDescription& mwd) {
- if (mwd.manifest->hasAidlInstance(aname.package, aname.iface, aname.instance)) {
+ if (mwd.manifest->hasAidlInstance(package, iface, instance)) {
LOG(INFO) << "Found " << name << " in " << mwd.description << " VINTF manifest.";
- return true; // break
+ return true;
}
- return false; // continue
- });
-
- if (!found) {
- // Although it is tested, explicitly rebuilding qualified name, in case it
- // becomes something unexpected.
- LOG(ERROR) << "Could not find " << aname.package << "." << aname.iface << "/"
- << aname.instance << " in the VINTF manifest.";
}
- return found;
-}
-
-static std::optional<std::string> getVintfUpdatableApex(const std::string& name) {
- AidlName aname;
- if (!AidlName::fill(name, &aname)) return std::nullopt;
-
- std::optional<std::string> updatableViaApex;
-
- forEachManifest([&](const ManifestWithDescription& mwd) {
- mwd.manifest->forEachInstance([&](const auto& manifestInstance) {
- if (manifestInstance.format() != vintf::HalFormat::AIDL) return true;
- if (manifestInstance.package() != aname.package) return true;
- if (manifestInstance.interface() != aname.iface) return true;
- if (manifestInstance.instance() != aname.instance) return true;
- updatableViaApex = manifestInstance.updatableViaApex();
- return false; // break (libvintf uses opposite convention)
- });
- return false; // continue
- });
-
- return updatableViaApex;
-}
-
-static std::vector<std::string> getVintfInstances(const std::string& interface) {
- size_t lastDot = interface.rfind('.');
- if (lastDot == std::string::npos) {
- LOG(ERROR) << "VINTF interfaces require names in Java package format (e.g. some.package.foo.IFoo) but got: " << interface;
- return {};
- }
- const std::string package = interface.substr(0, lastDot);
- const std::string iface = interface.substr(lastDot+1);
-
- std::vector<std::string> ret;
- (void)forEachManifest([&](const ManifestWithDescription& mwd) {
- auto instances = mwd.manifest->getAidlInstances(package, iface);
- ret.insert(ret.end(), instances.begin(), instances.end());
- return false; // continue
- });
-
- return ret;
+ // Although it is tested, explicitly rebuilding qualified name, in case it
+ // becomes something unexpected.
+ LOG(ERROR) << "Could not find " << package << "." << iface << "/" << instance
+ << " in the VINTF manifest.";
+ return false;
}
static bool meetsDeclarationRequirements(const sp<IBinder>& binder, const std::string& name) {
@@ -272,24 +208,22 @@ Status ServiceManager::addService(const std::string& name, const sp<IBinder>& bi
#endif // !VENDORSERVICEMANAGER
// implicitly unlinked when the binder is removed
- if (binder->remoteBinder() != nullptr &&
- binder->linkToDeath(sp<ServiceManager>::fromExisting(this)) != OK) {
+ if (binder->remoteBinder() != nullptr && binder->linkToDeath(this) != OK) {
LOG(ERROR) << "Could not linkToDeath when adding " << name;
return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
}
- // Overwrite the old service if it exists
- mNameToService[name] = Service {
+ auto entry = mNameToService.emplace(name, Service {
.binder = binder,
.allowIsolated = allowIsolated,
.dumpPriority = dumpPriority,
.debugPid = ctx.debugPid,
- };
+ });
auto it = mNameToRegistrationCallback.find(name);
if (it != mNameToRegistrationCallback.end()) {
for (const sp<IServiceCallback>& cb : it->second) {
- mNameToService[name].guaranteeClient = true;
+ entry.first->second.guaranteeClient = true;
// permission checked in registerForNotifications
cb->onRegistration(name, binder);
}
@@ -341,9 +275,7 @@ Status ServiceManager::registerForNotifications(
return Status::fromExceptionCode(Status::EX_NULL_POINTER);
}
- if (OK !=
- IInterface::asBinder(callback)->linkToDeath(
- sp<ServiceManager>::fromExisting(this))) {
+ if (OK != IInterface::asBinder(callback)->linkToDeath(this)) {
LOG(ERROR) << "Could not linkToDeath when adding " << name;
return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
}
@@ -398,45 +330,6 @@ Status ServiceManager::isDeclared(const std::string& name, bool* outReturn) {
return Status::ok();
}
-binder::Status ServiceManager::getDeclaredInstances(const std::string& interface, std::vector<std::string>* outReturn) {
- auto ctx = mAccess->getCallingContext();
-
- std::vector<std::string> allInstances;
-#ifndef VENDORSERVICEMANAGER
- allInstances = getVintfInstances(interface);
-#endif
-
- outReturn->clear();
-
- for (const std::string& instance : allInstances) {
- if (mAccess->canFind(ctx, interface + "/" + instance)) {
- outReturn->push_back(instance);
- }
- }
-
- if (outReturn->size() == 0 && allInstances.size() != 0) {
- return Status::fromExceptionCode(Status::EX_SECURITY);
- }
-
- return Status::ok();
-}
-
-Status ServiceManager::updatableViaApex(const std::string& name,
- std::optional<std::string>* outReturn) {
- auto ctx = mAccess->getCallingContext();
-
- if (!mAccess->canFind(ctx, name)) {
- return Status::fromExceptionCode(Status::EX_SECURITY);
- }
-
- *outReturn = std::nullopt;
-
-#ifndef VENDORSERVICEMANAGER
- *outReturn = getVintfUpdatableApex(name);
-#endif
- return Status::ok();
-}
-
void ServiceManager::removeRegistrationCallback(const wp<IBinder>& who,
ServiceCallbackMap::iterator* it,
bool* found) {
@@ -481,12 +374,7 @@ void ServiceManager::tryStartService(const std::string& name) {
name.c_str());
std::thread([=] {
- if (!base::SetProperty("ctl.interface_start", "aidl/" + name)) {
- LOG(INFO) << "Tried to start aidl service " << name
- << " as a lazy service, but was unable to. Usually this happens when a "
- "service is not installed, but if the service is intended to be used as a "
- "lazy service, then it may be configured incorrectly.";
- }
+ (void)base::SetProperty("ctl.interface_start", "aidl/" + name);
}).detach();
}
@@ -518,8 +406,7 @@ Status ServiceManager::registerClientCallback(const std::string& name, const sp<
return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
}
- if (OK !=
- IInterface::asBinder(cb)->linkToDeath(sp<ServiceManager>::fromExisting(this))) {
+ if (OK != IInterface::asBinder(cb)->linkToDeath(this)) {
LOG(ERROR) << "Could not linkToDeath when adding client callback for " << name;
return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
}
@@ -549,10 +436,10 @@ void ServiceManager::removeClientCallback(const wp<IBinder>& who,
}
ssize_t ServiceManager::Service::getNodeStrongRefCount() {
- sp<BpBinder> bpBinder = sp<BpBinder>::fromExisting(binder->remoteBinder());
+ sp<BpBinder> bpBinder = binder->remoteBinder();
if (bpBinder == nullptr) return -1;
- return ProcessState::self()->getStrongRefCountForNode(bpBinder);
+ return ProcessState::self()->getStrongRefCountForNodeByHandle(bpBinder->handle());
}
void ServiceManager::handleClientCallbacks() {
@@ -681,21 +568,4 @@ Status ServiceManager::tryUnregisterService(const std::string& name, const sp<IB
return Status::ok();
}
-Status ServiceManager::getServiceDebugInfo(std::vector<ServiceDebugInfo>* outReturn) {
- if (!mAccess->canList(mAccess->getCallingContext())) {
- return Status::fromExceptionCode(Status::EX_SECURITY);
- }
-
- outReturn->reserve(mNameToService.size());
- for (auto const& [name, service] : mNameToService) {
- ServiceDebugInfo info;
- info.name = name;
- info.debugPid = service.debugPid;
-
- outReturn->push_back(std::move(info));
- }
-
- return Status::ok();
-}
-
} // namespace android