Add a BackendUnifiedServiceManager wrapper
This can be directly used by java and rust ffi
Test: atest aidl_integration_test
Bug: 333854840
Flag: EXEMPT refactor
Change-Id: I12c3730a89422bf08ab723a82888431f291bd7b3
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index f31f8d3..1abde5c 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -442,8 +442,10 @@
name: "libbinder_kernel_defaults",
srcs: [
"BufferedTextOutput.cpp",
+ "BackendUnifiedServiceManager.cpp",
"IPCThreadState.cpp",
"IServiceManager.cpp",
+ "IServiceManagerFFI.cpp",
"ProcessState.cpp",
"Static.cpp",
":libbinder_aidl",
@@ -519,7 +521,6 @@
"ParcelableHolder.cpp",
"PersistableBundle.cpp",
],
-
target: {
android: {
// NOT static to keep the wire protocol unfrozen
diff --git a/libs/binder/BackendUnifiedServiceManager.cpp b/libs/binder/BackendUnifiedServiceManager.cpp
new file mode 100644
index 0000000..496c5ef
--- /dev/null
+++ b/libs/binder/BackendUnifiedServiceManager.cpp
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "BackendUnifiedServiceManager.h"
+
+namespace android {
+
+using AidlServiceManager = android::os::IServiceManager;
+
+BackendUnifiedServiceManager::BackendUnifiedServiceManager(const sp<AidlServiceManager>& impl)
+ : mTheRealServiceManager(impl) {}
+
+sp<AidlServiceManager> BackendUnifiedServiceManager::getImpl() {
+ return mTheRealServiceManager;
+}
+binder::Status BackendUnifiedServiceManager::getService(const ::std::string& name,
+ sp<IBinder>* _aidl_return) {
+ return mTheRealServiceManager->getService(name, _aidl_return);
+}
+binder::Status BackendUnifiedServiceManager::checkService(const ::std::string& name,
+ sp<IBinder>* _aidl_return) {
+ return mTheRealServiceManager->checkService(name, _aidl_return);
+}
+binder::Status BackendUnifiedServiceManager::addService(const ::std::string& name,
+ const sp<IBinder>& service,
+ bool allowIsolated, int32_t dumpPriority) {
+ return mTheRealServiceManager->addService(name, service, allowIsolated, dumpPriority);
+}
+binder::Status BackendUnifiedServiceManager::listServices(
+ int32_t dumpPriority, ::std::vector<::std::string>* _aidl_return) {
+ return mTheRealServiceManager->listServices(dumpPriority, _aidl_return);
+}
+binder::Status BackendUnifiedServiceManager::registerForNotifications(
+ const ::std::string& name, const sp<os::IServiceCallback>& callback) {
+ return mTheRealServiceManager->registerForNotifications(name, callback);
+}
+binder::Status BackendUnifiedServiceManager::unregisterForNotifications(
+ const ::std::string& name, const sp<os::IServiceCallback>& callback) {
+ return mTheRealServiceManager->unregisterForNotifications(name, callback);
+}
+binder::Status BackendUnifiedServiceManager::isDeclared(const ::std::string& name,
+ bool* _aidl_return) {
+ return mTheRealServiceManager->isDeclared(name, _aidl_return);
+}
+binder::Status BackendUnifiedServiceManager::getDeclaredInstances(
+ const ::std::string& iface, ::std::vector<::std::string>* _aidl_return) {
+ return mTheRealServiceManager->getDeclaredInstances(iface, _aidl_return);
+}
+binder::Status BackendUnifiedServiceManager::updatableViaApex(
+ const ::std::string& name, ::std::optional<::std::string>* _aidl_return) {
+ return mTheRealServiceManager->updatableViaApex(name, _aidl_return);
+}
+binder::Status BackendUnifiedServiceManager::getUpdatableNames(
+ const ::std::string& apexName, ::std::vector<::std::string>* _aidl_return) {
+ return mTheRealServiceManager->getUpdatableNames(apexName, _aidl_return);
+}
+binder::Status BackendUnifiedServiceManager::getConnectionInfo(
+ const ::std::string& name, ::std::optional<os::ConnectionInfo>* _aidl_return) {
+ return mTheRealServiceManager->getConnectionInfo(name, _aidl_return);
+}
+binder::Status BackendUnifiedServiceManager::registerClientCallback(
+ const ::std::string& name, const sp<IBinder>& service,
+ const sp<os::IClientCallback>& callback) {
+ return mTheRealServiceManager->registerClientCallback(name, service, callback);
+}
+binder::Status BackendUnifiedServiceManager::tryUnregisterService(const ::std::string& name,
+ const sp<IBinder>& service) {
+ return mTheRealServiceManager->tryUnregisterService(name, service);
+}
+binder::Status BackendUnifiedServiceManager::getServiceDebugInfo(
+ ::std::vector<os::ServiceDebugInfo>* _aidl_return) {
+ return mTheRealServiceManager->getServiceDebugInfo(_aidl_return);
+}
+
+[[clang::no_destroy]] static std::once_flag gUSmOnce;
+[[clang::no_destroy]] static sp<BackendUnifiedServiceManager> gUnifiedServiceManager;
+
+sp<BackendUnifiedServiceManager> getBackendUnifiedServiceManager() {
+ std::call_once(gUSmOnce, []() {
+#if defined(__BIONIC__) && !defined(__ANDROID_VNDK__)
+ /* wait for service manager */ {
+ using std::literals::chrono_literals::operator""s;
+ using android::base::WaitForProperty;
+ while (!WaitForProperty("servicemanager.ready", "true", 1s)) {
+ ALOGE("Waited for servicemanager.ready for a second, waiting another...");
+ }
+ }
+#endif
+
+ sp<AidlServiceManager> sm = nullptr;
+ while (sm == nullptr) {
+ sm = interface_cast<AidlServiceManager>(
+ ProcessState::self()->getContextObject(nullptr));
+ if (sm == nullptr) {
+ ALOGE("Waiting 1s on context object on %s.",
+ ProcessState::self()->getDriverName().c_str());
+ sleep(1);
+ }
+ }
+
+ gUnifiedServiceManager = sp<BackendUnifiedServiceManager>::make(sm);
+ });
+
+ return gUnifiedServiceManager;
+}
+
+} // namespace android
\ No newline at end of file
diff --git a/libs/binder/BackendUnifiedServiceManager.h b/libs/binder/BackendUnifiedServiceManager.h
new file mode 100644
index 0000000..a67d5ba
--- /dev/null
+++ b/libs/binder/BackendUnifiedServiceManager.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <android-base/properties.h>
+#include <android/os/BnServiceManager.h>
+#include <android/os/IServiceManager.h>
+#include <binder/IPCThreadState.h>
+
+namespace android {
+
+class BackendUnifiedServiceManager : public android::os::BnServiceManager {
+public:
+ explicit BackendUnifiedServiceManager(const sp<os::IServiceManager>& impl);
+
+ sp<os::IServiceManager> getImpl();
+ binder::Status getService(const ::std::string& name, sp<IBinder>* _aidl_return) override;
+ binder::Status checkService(const ::std::string& name, sp<IBinder>* _aidl_return) override;
+ binder::Status addService(const ::std::string& name, const sp<IBinder>& service,
+ bool allowIsolated, int32_t dumpPriority) override;
+ binder::Status listServices(int32_t dumpPriority,
+ ::std::vector<::std::string>* _aidl_return) override;
+ binder::Status registerForNotifications(const ::std::string& name,
+ const sp<os::IServiceCallback>& callback) override;
+ binder::Status unregisterForNotifications(const ::std::string& name,
+ const sp<os::IServiceCallback>& callback) override;
+ binder::Status isDeclared(const ::std::string& name, bool* _aidl_return) override;
+ binder::Status getDeclaredInstances(const ::std::string& iface,
+ ::std::vector<::std::string>* _aidl_return) override;
+ binder::Status updatableViaApex(const ::std::string& name,
+ ::std::optional<::std::string>* _aidl_return) override;
+ binder::Status getUpdatableNames(const ::std::string& apexName,
+ ::std::vector<::std::string>* _aidl_return) override;
+ binder::Status getConnectionInfo(const ::std::string& name,
+ ::std::optional<os::ConnectionInfo>* _aidl_return) override;
+ binder::Status registerClientCallback(const ::std::string& name, const sp<IBinder>& service,
+ const sp<os::IClientCallback>& callback) override;
+ binder::Status tryUnregisterService(const ::std::string& name,
+ const sp<IBinder>& service) override;
+ binder::Status getServiceDebugInfo(::std::vector<os::ServiceDebugInfo>* _aidl_return) override;
+
+ // for legacy ABI
+ const String16& getInterfaceDescriptor() const override {
+ return mTheRealServiceManager->getInterfaceDescriptor();
+ }
+
+ IBinder* onAsBinder() override { return IInterface::asBinder(mTheRealServiceManager).get(); }
+
+private:
+ sp<os::IServiceManager> mTheRealServiceManager;
+};
+
+sp<BackendUnifiedServiceManager> getBackendUnifiedServiceManager();
+
+} // namespace android
\ No newline at end of file
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index fbcf823..5844c85 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -16,6 +16,7 @@
#define LOG_TAG "ServiceManagerCppClient"
+#include <BackendUnifiedServiceManager.h>
#include <binder/IServiceManager.h>
#include <inttypes.h>
@@ -111,14 +112,12 @@
std::vector<IServiceManager::ServiceDebugInfo> getServiceDebugInfo() override;
// for legacy ABI
const String16& getInterfaceDescriptor() const override {
- return mTheRealServiceManager->getInterfaceDescriptor();
+ return mUnifiedServiceManager->getInterfaceDescriptor();
}
- IBinder* onAsBinder() override {
- return IInterface::asBinder(mTheRealServiceManager).get();
- }
+ IBinder* onAsBinder() override { return IInterface::asBinder(mUnifiedServiceManager).get(); }
protected:
- sp<AidlServiceManager> mTheRealServiceManager;
+ sp<BackendUnifiedServiceManager> mUnifiedServiceManager;
// AidlRegistrationCallback -> services that its been registered for
// notifications.
using LocalRegistrationAndWaiter =
@@ -136,9 +135,9 @@
// will still have the 5s delay that is expected by a large amount of Android code.
//
// When implementing ServiceManagerShim, use realGetService instead of
- // mTheRealServiceManager->getService so that it can be overridden in ServiceManagerHostShim.
+ // mUnifiedServiceManager->getService so that it can be overridden in ServiceManagerHostShim.
virtual Status realGetService(const std::string& name, sp<IBinder>* _aidl_return) {
- return mTheRealServiceManager->getService(name, _aidl_return);
+ return mUnifiedServiceManager->getService(name, _aidl_return);
}
};
@@ -148,26 +147,7 @@
sp<IServiceManager> defaultServiceManager()
{
std::call_once(gSmOnce, []() {
-#if defined(__BIONIC__) && !defined(__ANDROID_VNDK__)
- /* wait for service manager */ {
- using std::literals::chrono_literals::operator""s;
- using android::base::WaitForProperty;
- while (!WaitForProperty("servicemanager.ready", "true", 1s)) {
- ALOGE("Waited for servicemanager.ready for a second, waiting another...");
- }
- }
-#endif
-
- sp<AidlServiceManager> sm = nullptr;
- while (sm == nullptr) {
- sm = interface_cast<AidlServiceManager>(ProcessState::self()->getContextObject(nullptr));
- if (sm == nullptr) {
- ALOGE("Waiting 1s on context object on %s.", ProcessState::self()->getDriverName().c_str());
- sleep(1);
- }
- }
-
- gDefaultServiceManager = sp<ServiceManagerShim>::make(sm);
+ gDefaultServiceManager = sp<ServiceManagerShim>::make(getBackendUnifiedServiceManager());
});
return gDefaultServiceManager;
@@ -290,9 +270,9 @@
// ----------------------------------------------------------------------
-ServiceManagerShim::ServiceManagerShim(const sp<AidlServiceManager>& impl)
- : mTheRealServiceManager(impl)
-{}
+ServiceManagerShim::ServiceManagerShim(const sp<AidlServiceManager>& impl) {
+ mUnifiedServiceManager = sp<BackendUnifiedServiceManager>::make(impl);
+}
// This implementation could be simplified and made more efficient by delegating
// to waitForService. However, this changes the threading structure in some
@@ -345,7 +325,7 @@
sp<IBinder> ServiceManagerShim::checkService(const String16& name) const
{
sp<IBinder> ret;
- if (!mTheRealServiceManager->checkService(String8(name).c_str(), &ret).isOk()) {
+ if (!mUnifiedServiceManager->checkService(String8(name).c_str(), &ret).isOk()) {
return nullptr;
}
return ret;
@@ -354,15 +334,15 @@
status_t ServiceManagerShim::addService(const String16& name, const sp<IBinder>& service,
bool allowIsolated, int dumpsysPriority)
{
- Status status = mTheRealServiceManager->addService(
- String8(name).c_str(), service, allowIsolated, dumpsysPriority);
+ Status status = mUnifiedServiceManager->addService(String8(name).c_str(), service,
+ allowIsolated, dumpsysPriority);
return status.exceptionCode();
}
Vector<String16> ServiceManagerShim::listServices(int dumpsysPriority)
{
std::vector<std::string> ret;
- if (!mTheRealServiceManager->listServices(dumpsysPriority, &ret).isOk()) {
+ if (!mUnifiedServiceManager->listServices(dumpsysPriority, &ret).isOk()) {
return {};
}
@@ -420,15 +400,13 @@
if (out != nullptr) return out;
sp<Waiter> waiter = sp<Waiter>::make();
- if (Status status = mTheRealServiceManager->registerForNotifications(name, waiter);
+ if (Status status = mUnifiedServiceManager->registerForNotifications(name, waiter);
!status.isOk()) {
ALOGW("Failed to registerForNotifications in waitForService for %s: %s", name.c_str(),
status.toString8().c_str());
return nullptr;
}
- Defer unregister ([&] {
- mTheRealServiceManager->unregisterForNotifications(name, waiter);
- });
+ Defer unregister([&] { mUnifiedServiceManager->unregisterForNotifications(name, waiter); });
while(true) {
{
@@ -469,7 +447,7 @@
bool ServiceManagerShim::isDeclared(const String16& name) {
bool declared;
- if (Status status = mTheRealServiceManager->isDeclared(String8(name).c_str(), &declared);
+ if (Status status = mUnifiedServiceManager->isDeclared(String8(name).c_str(), &declared);
!status.isOk()) {
ALOGW("Failed to get isDeclared for %s: %s", String8(name).c_str(),
status.toString8().c_str());
@@ -481,7 +459,7 @@
Vector<String16> ServiceManagerShim::getDeclaredInstances(const String16& interface) {
std::vector<std::string> out;
if (Status status =
- mTheRealServiceManager->getDeclaredInstances(String8(interface).c_str(), &out);
+ mUnifiedServiceManager->getDeclaredInstances(String8(interface).c_str(), &out);
!status.isOk()) {
ALOGW("Failed to getDeclaredInstances for %s: %s", String8(interface).c_str(),
status.toString8().c_str());
@@ -498,7 +476,7 @@
std::optional<String16> ServiceManagerShim::updatableViaApex(const String16& name) {
std::optional<std::string> declared;
- if (Status status = mTheRealServiceManager->updatableViaApex(String8(name).c_str(), &declared);
+ if (Status status = mUnifiedServiceManager->updatableViaApex(String8(name).c_str(), &declared);
!status.isOk()) {
ALOGW("Failed to get updatableViaApex for %s: %s", String8(name).c_str(),
status.toString8().c_str());
@@ -509,7 +487,7 @@
Vector<String16> ServiceManagerShim::getUpdatableNames(const String16& apexName) {
std::vector<std::string> out;
- if (Status status = mTheRealServiceManager->getUpdatableNames(String8(apexName).c_str(), &out);
+ if (Status status = mUnifiedServiceManager->getUpdatableNames(String8(apexName).c_str(), &out);
!status.isOk()) {
ALOGW("Failed to getUpdatableNames for %s: %s", String8(apexName).c_str(),
status.toString8().c_str());
@@ -528,7 +506,7 @@
const String16& name) {
std::optional<os::ConnectionInfo> connectionInfo;
if (Status status =
- mTheRealServiceManager->getConnectionInfo(String8(name).c_str(), &connectionInfo);
+ mUnifiedServiceManager->getConnectionInfo(String8(name).c_str(), &connectionInfo);
!status.isOk()) {
ALOGW("Failed to get ConnectionInfo for %s: %s", String8(name).c_str(),
status.toString8().c_str());
@@ -549,7 +527,7 @@
sp<RegistrationWaiter> registrationWaiter = sp<RegistrationWaiter>::make(cb);
std::lock_guard<std::mutex> lock(mNameToRegistrationLock);
if (Status status =
- mTheRealServiceManager->registerForNotifications(nameStr, registrationWaiter);
+ mUnifiedServiceManager->registerForNotifications(nameStr, registrationWaiter);
!status.isOk()) {
ALOGW("Failed to registerForNotifications for %s: %s", nameStr.c_str(),
status.toString8().c_str());
@@ -600,7 +578,7 @@
ALOGE("%s Callback passed wasn't used to register for notifications", __FUNCTION__);
return BAD_VALUE;
}
- if (Status status = mTheRealServiceManager->unregisterForNotifications(String8(name).c_str(),
+ if (Status status = mUnifiedServiceManager->unregisterForNotifications(String8(name).c_str(),
registrationWaiter);
!status.isOk()) {
ALOGW("Failed to get service manager to unregisterForNotifications for %s: %s",
@@ -613,7 +591,7 @@
std::vector<IServiceManager::ServiceDebugInfo> ServiceManagerShim::getServiceDebugInfo() {
std::vector<os::ServiceDebugInfo> serviceDebugInfos;
std::vector<IServiceManager::ServiceDebugInfo> ret;
- if (Status status = mTheRealServiceManager->getServiceDebugInfo(&serviceDebugInfos);
+ if (Status status = mUnifiedServiceManager->getServiceDebugInfo(&serviceDebugInfos);
!status.isOk()) {
ALOGW("%s Failed to get ServiceDebugInfo", __FUNCTION__);
return ret;
diff --git a/libs/binder/IServiceManagerFFI.cpp b/libs/binder/IServiceManagerFFI.cpp
new file mode 100644
index 0000000..7d4d7dc
--- /dev/null
+++ b/libs/binder/IServiceManagerFFI.cpp
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <android/os/IServiceManager.h>
+
+#include <BackendUnifiedServiceManager.h>
+#include <binder/IServiceManagerFFI.h>
+
+namespace android::impl {
+sp<android::os::IServiceManager>
+getJavaServicemanagerImplPrivateDoNotUseExceptInTheOnePlaceItIsUsed() {
+ return getBackendUnifiedServiceManager();
+}
+
+} // namespace android::impl
diff --git a/libs/binder/include/binder/IServiceManagerFFI.h b/libs/binder/include/binder/IServiceManagerFFI.h
new file mode 100644
index 0000000..7537355
--- /dev/null
+++ b/libs/binder/include/binder/IServiceManagerFFI.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <android/os/IServiceManager.h>
+
+namespace android::impl {
+
+LIBBINDER_EXPORTED sp<android::os::IServiceManager>
+getJavaServicemanagerImplPrivateDoNotUseExceptInTheOnePlaceItIsUsed();
+
+} // namespace android::impl