diff options
author | 2024-04-22 14:21:07 +0000 | |
---|---|---|
committer | 2024-06-20 10:17:34 +0000 | |
commit | 56a0471ed60e551925dfc8d76cb061ffa8d10122 (patch) | |
tree | 33fcbf6d48abc9d08351b130c8a6371ba3e942c0 | |
parent | 9f0a7d383bfa8fae53d9e362179b38d8be3f8d13 (diff) |
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
-rw-r--r-- | libs/binder/Android.bp | 3 | ||||
-rw-r--r-- | libs/binder/BackendUnifiedServiceManager.cpp | 119 | ||||
-rw-r--r-- | libs/binder/BackendUnifiedServiceManager.h | 68 | ||||
-rw-r--r-- | libs/binder/IServiceManager.cpp | 70 | ||||
-rw-r--r-- | libs/binder/IServiceManagerFFI.cpp | 27 | ||||
-rw-r--r-- | libs/binder/include/binder/IServiceManagerFFI.h | 25 |
6 files changed, 265 insertions, 47 deletions
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp index f31f8d3993..1abde5cb92 100644 --- a/libs/binder/Android.bp +++ b/libs/binder/Android.bp @@ -442,8 +442,10 @@ cc_defaults { 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 @@ cc_library { "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 0000000000..496c5ef788 --- /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 0000000000..a67d5bae2d --- /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 fbcf823045..5844c85d21 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 @@ public: std::vector<IServiceManager::ServiceDebugInfo> getServiceDebugInfo() override; // for legacy ABI const String16& getInterfaceDescriptor() const override { - return mTheRealServiceManager->getInterfaceDescriptor(); - } - IBinder* onAsBinder() override { - return IInterface::asBinder(mTheRealServiceManager).get(); + return mUnifiedServiceManager->getInterfaceDescriptor(); } + 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 @@ protected: // 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 @@ protected: 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 @@ void* openDeclaredPassthroughHal(const String16& interface, const String16& inst // ---------------------------------------------------------------------- -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::getService(const String16& name) const 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 @@ sp<IBinder> ServiceManagerShim::checkService(const String16& name) const 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 @@ sp<IBinder> ServiceManagerShim::waitForService(const String16& name16) 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 @@ sp<IBinder> ServiceManagerShim::waitForService(const String16& name16) 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 @@ bool ServiceManagerShim::isDeclared(const String16& name) { 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 @@ Vector<String16> ServiceManagerShim::getDeclaredInstances(const String16& interf 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 @@ std::optional<String16> ServiceManagerShim::updatableViaApex(const String16& nam 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 @@ std::optional<IServiceManager::ConnectionInfo> ServiceManagerShim::getConnection 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 @@ status_t ServiceManagerShim::registerForNotifications(const String16& name, 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 @@ status_t ServiceManagerShim::unregisterForNotifications(const String16& name, 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 @@ status_t ServiceManagerShim::unregisterForNotifications(const String16& name, 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 0000000000..7d4d7dc063 --- /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 0000000000..753735506c --- /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 |