summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/binder/BackendUnifiedServiceManager.cpp113
-rw-r--r--libs/binder/include/binder/IServiceManager.h8
-rw-r--r--libs/binder/tests/binderLibTest.cpp57
3 files changed, 145 insertions, 33 deletions
diff --git a/libs/binder/BackendUnifiedServiceManager.cpp b/libs/binder/BackendUnifiedServiceManager.cpp
index 34d5a09948..9d0a557f4e 100644
--- a/libs/binder/BackendUnifiedServiceManager.cpp
+++ b/libs/binder/BackendUnifiedServiceManager.cpp
@@ -47,6 +47,9 @@ using AidlServiceManager = android::os::IServiceManager;
using android::os::IAccessor;
using binder::Status;
+static const char* kUnsupportedOpNoServiceManager =
+ "Unsupported operation without a kernel binder servicemanager process";
+
static const char* kStaticCachableList[] = {
// go/keep-sorted start
"accessibility",
@@ -220,7 +223,10 @@ Status BackendUnifiedServiceManager::getService2(const ::std::string& name, os::
return Status::ok();
}
os::Service service;
- Status status = mTheRealServiceManager->getService2(name, &service);
+ Status status = Status::ok();
+ if (mTheRealServiceManager) {
+ status = mTheRealServiceManager->getService2(name, &service);
+ }
if (status.isOk()) {
status = toBinderService(name, service, _out);
@@ -237,7 +243,10 @@ Status BackendUnifiedServiceManager::checkService(const ::std::string& name, os:
return Status::ok();
}
- Status status = mTheRealServiceManager->checkService(name, &service);
+ Status status = Status::ok();
+ if (mTheRealServiceManager) {
+ status = mTheRealServiceManager->checkService(name, &service);
+ }
if (status.isOk()) {
status = toBinderService(name, service, _out);
if (status.isOk()) {
@@ -315,66 +324,128 @@ Status BackendUnifiedServiceManager::toBinderService(const ::std::string& name,
Status BackendUnifiedServiceManager::addService(const ::std::string& name,
const sp<IBinder>& service, bool allowIsolated,
int32_t dumpPriority) {
- Status status = mTheRealServiceManager->addService(name, service, allowIsolated, dumpPriority);
- // mEnableAddServiceCache is true by default.
- if (kUseCacheInAddService && mEnableAddServiceCache && status.isOk()) {
- return updateCache(name, service,
- dumpPriority & android::os::IServiceManager::FLAG_IS_LAZY_SERVICE);
+ if (mTheRealServiceManager) {
+ Status status =
+ mTheRealServiceManager->addService(name, service, allowIsolated, dumpPriority);
+ // mEnableAddServiceCache is true by default.
+ if (kUseCacheInAddService && mEnableAddServiceCache && status.isOk()) {
+ return updateCache(name, service,
+ dumpPriority & android::os::IServiceManager::FLAG_IS_LAZY_SERVICE);
+ }
+ return status;
}
- return status;
+ return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION,
+ kUnsupportedOpNoServiceManager);
}
Status BackendUnifiedServiceManager::listServices(int32_t dumpPriority,
::std::vector<::std::string>* _aidl_return) {
- return mTheRealServiceManager->listServices(dumpPriority, _aidl_return);
+ if (mTheRealServiceManager) {
+ return mTheRealServiceManager->listServices(dumpPriority, _aidl_return);
+ }
+ return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION,
+ kUnsupportedOpNoServiceManager);
}
Status BackendUnifiedServiceManager::registerForNotifications(
const ::std::string& name, const sp<os::IServiceCallback>& callback) {
- return mTheRealServiceManager->registerForNotifications(name, callback);
+ if (mTheRealServiceManager) {
+ return mTheRealServiceManager->registerForNotifications(name, callback);
+ }
+ return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION,
+ kUnsupportedOpNoServiceManager);
}
Status BackendUnifiedServiceManager::unregisterForNotifications(
const ::std::string& name, const sp<os::IServiceCallback>& callback) {
- return mTheRealServiceManager->unregisterForNotifications(name, callback);
+ if (mTheRealServiceManager) {
+ return mTheRealServiceManager->unregisterForNotifications(name, callback);
+ }
+ return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION,
+ kUnsupportedOpNoServiceManager);
}
Status BackendUnifiedServiceManager::isDeclared(const ::std::string& name, bool* _aidl_return) {
- return mTheRealServiceManager->isDeclared(name, _aidl_return);
+ if (mTheRealServiceManager) {
+ return mTheRealServiceManager->isDeclared(name, _aidl_return);
+ }
+ return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION,
+ kUnsupportedOpNoServiceManager);
}
Status BackendUnifiedServiceManager::getDeclaredInstances(
const ::std::string& iface, ::std::vector<::std::string>* _aidl_return) {
- return mTheRealServiceManager->getDeclaredInstances(iface, _aidl_return);
+ if (mTheRealServiceManager) {
+ return mTheRealServiceManager->getDeclaredInstances(iface, _aidl_return);
+ }
+ return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION,
+ kUnsupportedOpNoServiceManager);
}
Status BackendUnifiedServiceManager::updatableViaApex(
const ::std::string& name, ::std::optional<::std::string>* _aidl_return) {
- return mTheRealServiceManager->updatableViaApex(name, _aidl_return);
+ if (mTheRealServiceManager) {
+ return mTheRealServiceManager->updatableViaApex(name, _aidl_return);
+ }
+ return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION,
+ kUnsupportedOpNoServiceManager);
}
Status BackendUnifiedServiceManager::getUpdatableNames(const ::std::string& apexName,
::std::vector<::std::string>* _aidl_return) {
- return mTheRealServiceManager->getUpdatableNames(apexName, _aidl_return);
+ if (mTheRealServiceManager) {
+ return mTheRealServiceManager->getUpdatableNames(apexName, _aidl_return);
+ }
+ return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION,
+ kUnsupportedOpNoServiceManager);
}
Status BackendUnifiedServiceManager::getConnectionInfo(
const ::std::string& name, ::std::optional<os::ConnectionInfo>* _aidl_return) {
- return mTheRealServiceManager->getConnectionInfo(name, _aidl_return);
+ if (mTheRealServiceManager) {
+ return mTheRealServiceManager->getConnectionInfo(name, _aidl_return);
+ }
+ return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION,
+ kUnsupportedOpNoServiceManager);
}
Status BackendUnifiedServiceManager::registerClientCallback(
const ::std::string& name, const sp<IBinder>& service,
const sp<os::IClientCallback>& callback) {
- return mTheRealServiceManager->registerClientCallback(name, service, callback);
+ if (mTheRealServiceManager) {
+ return mTheRealServiceManager->registerClientCallback(name, service, callback);
+ }
+ return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION,
+ kUnsupportedOpNoServiceManager);
}
Status BackendUnifiedServiceManager::tryUnregisterService(const ::std::string& name,
const sp<IBinder>& service) {
- return mTheRealServiceManager->tryUnregisterService(name, service);
+ if (mTheRealServiceManager) {
+ return mTheRealServiceManager->tryUnregisterService(name, service);
+ }
+ return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION,
+ kUnsupportedOpNoServiceManager);
}
Status BackendUnifiedServiceManager::getServiceDebugInfo(
::std::vector<os::ServiceDebugInfo>* _aidl_return) {
- return mTheRealServiceManager->getServiceDebugInfo(_aidl_return);
+ if (mTheRealServiceManager) {
+ return mTheRealServiceManager->getServiceDebugInfo(_aidl_return);
+ }
+ return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION,
+ kUnsupportedOpNoServiceManager);
}
[[clang::no_destroy]] static std::once_flag gUSmOnce;
[[clang::no_destroy]] static sp<BackendUnifiedServiceManager> gUnifiedServiceManager;
+static bool hasOutOfProcessServiceManager() {
+#ifndef BINDER_WITH_KERNEL_IPC
+ return false;
+#else
+#if defined(__BIONIC__) && !defined(__ANDROID_VNDK__)
+ return android::base::GetBoolProperty("servicemanager.installed", true);
+#else
+ return true;
+#endif
+#endif // BINDER_WITH_KERNEL_IPC
+}
+
sp<BackendUnifiedServiceManager> getBackendUnifiedServiceManager() {
std::call_once(gUSmOnce, []() {
#if defined(__BIONIC__) && !defined(__ANDROID_VNDK__)
- /* wait for service manager */ {
+ /* wait for service manager */
+ if (hasOutOfProcessServiceManager()) {
using std::literals::chrono_literals::operator""s;
using android::base::WaitForProperty;
while (!WaitForProperty("servicemanager.ready", "true", 1s)) {
@@ -384,7 +455,7 @@ sp<BackendUnifiedServiceManager> getBackendUnifiedServiceManager() {
#endif
sp<AidlServiceManager> sm = nullptr;
- while (sm == nullptr) {
+ while (hasOutOfProcessServiceManager() && sm == nullptr) {
sm = interface_cast<AidlServiceManager>(
ProcessState::self()->getContextObject(nullptr));
if (sm == nullptr) {
diff --git a/libs/binder/include/binder/IServiceManager.h b/libs/binder/include/binder/IServiceManager.h
index 7d79baa34d..d248f22e89 100644
--- a/libs/binder/include/binder/IServiceManager.h
+++ b/libs/binder/include/binder/IServiceManager.h
@@ -80,6 +80,14 @@ public:
/**
* Register a service.
+ *
+ * Note:
+ * This status_t return value may be an exception code from an underlying
+ * Status type that doesn't have a representive error code in
+ * utils/Errors.h.
+ * One example of this is a return value of -7
+ * (Status::Exception::EX_UNSUPPORTED_OPERATION) when the service manager
+ * process is not installed on the device when addService is called.
*/
// NOLINTNEXTLINE(google-default-arguments)
virtual status_t addService(const String16& name, const sp<IBinder>& service,
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index d6cb508d7f..391a57010a 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -44,6 +44,7 @@
#include <processgroup/processgroup.h>
#include <utils/Flattenable.h>
#include <utils/SystemClock.h>
+#include "binder/IServiceManagerUnitTestHelper.h"
#include <linux/sched.h>
#include <sys/epoll.h>
@@ -558,14 +559,14 @@ TEST_F(BinderLibTest, AddManagerToManager) {
EXPECT_EQ(NO_ERROR, sm->addService(String16("binderLibTest-manager"), binder));
}
+class LocalRegistrationCallbackImpl : public virtual IServiceManager::LocalRegistrationCallback {
+ void onServiceRegistration(const String16&, const sp<IBinder>&) override {}
+ virtual ~LocalRegistrationCallbackImpl() {}
+};
+
TEST_F(BinderLibTest, RegisterForNotificationsFailure) {
auto sm = defaultServiceManager();
- using LocalRegistrationCallback = IServiceManager::LocalRegistrationCallback;
- class LocalRegistrationCallbackImpl : public virtual LocalRegistrationCallback {
- void onServiceRegistration(const String16&, const sp<IBinder>&) override {}
- virtual ~LocalRegistrationCallbackImpl() {}
- };
- sp<LocalRegistrationCallback> cb = sp<LocalRegistrationCallbackImpl>::make();
+ sp<IServiceManager::LocalRegistrationCallback> cb = sp<LocalRegistrationCallbackImpl>::make();
EXPECT_EQ(BAD_VALUE, sm->registerForNotifications(String16("ValidName"), nullptr));
EXPECT_EQ(UNKNOWN_ERROR, sm->registerForNotifications(String16("InvalidName!$"), cb));
@@ -573,12 +574,7 @@ TEST_F(BinderLibTest, RegisterForNotificationsFailure) {
TEST_F(BinderLibTest, UnregisterForNotificationsFailure) {
auto sm = defaultServiceManager();
- using LocalRegistrationCallback = IServiceManager::LocalRegistrationCallback;
- class LocalRegistrationCallbackImpl : public virtual LocalRegistrationCallback {
- void onServiceRegistration(const String16&, const sp<IBinder>&) override {}
- virtual ~LocalRegistrationCallbackImpl() {}
- };
- sp<LocalRegistrationCallback> cb = sp<LocalRegistrationCallbackImpl>::make();
+ sp<IServiceManager::LocalRegistrationCallback> cb = sp<LocalRegistrationCallbackImpl>::make();
EXPECT_EQ(OK, sm->registerForNotifications(String16("ValidName"), cb));
@@ -1667,6 +1663,43 @@ TEST(ServiceNotifications, Unregister) {
EXPECT_EQ(sm->unregisterForNotifications(String16("RogerRafa"), cb), OK);
}
+// Make sure all IServiceManager APIs will function without an AIDL service
+// manager registered on the device.
+TEST(ServiceManagerNoAidlServer, SanityCheck) {
+ String16 kServiceName("no_services_exist");
+ // This is what clients will see when there is no servicemanager process
+ // that registers itself as context object 0.
+ // Can't use setDefaultServiceManager() here because these test cases run in
+ // the same process and will abort when called twice or before/after
+ // defaultServiceManager().
+ sp<IServiceManager> sm = getServiceManagerShimFromAidlServiceManagerForTests(nullptr);
+ auto status = sm->addService(kServiceName, sp<BBinder>::make());
+ // CppBackendShim returns Status::exceptionCode as the status_t
+ EXPECT_EQ(status, Status::Exception::EX_UNSUPPORTED_OPERATION) << statusToString(status);
+ auto service = sm->checkService(String16("no_services_exist"));
+ EXPECT_TRUE(service == nullptr);
+ auto list = sm->listServices(android::IServiceManager::DUMP_FLAG_PRIORITY_ALL);
+ EXPECT_TRUE(list.isEmpty());
+ bool declared = sm->isDeclared(kServiceName);
+ EXPECT_FALSE(declared);
+ list = sm->getDeclaredInstances(kServiceName);
+ EXPECT_TRUE(list.isEmpty());
+ auto updatable = sm->updatableViaApex(kServiceName);
+ EXPECT_EQ(updatable, std::nullopt);
+ list = sm->getUpdatableNames(kServiceName);
+ EXPECT_TRUE(list.isEmpty());
+ auto conInfo = sm->getConnectionInfo(kServiceName);
+ EXPECT_EQ(conInfo, std::nullopt);
+ auto cb = sp<LocalRegistrationCallbackImpl>::make();
+ status = sm->registerForNotifications(kServiceName, cb);
+ EXPECT_EQ(status, UNKNOWN_ERROR) << statusToString(status);
+ status = sm->unregisterForNotifications(kServiceName, cb);
+ EXPECT_EQ(status, BAD_VALUE) << statusToString(status);
+ auto dbgInfos = sm->getServiceDebugInfo();
+ EXPECT_TRUE(dbgInfos.empty());
+ sm->enableAddServiceCache(true);
+}
+
TEST_F(BinderLibTest, ThreadPoolAvailableThreads) {
Parcel data, reply;
sp<IBinder> server = addServer();