Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f8ec3975 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Add a BackendUnifiedServiceManager wrapper" into main

parents dae812b1 56a0471e
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -457,8 +457,10 @@ cc_defaults {
    name: "libbinder_kernel_defaults",
    srcs: [
        "BufferedTextOutput.cpp",
        "BackendUnifiedServiceManager.cpp",
        "IPCThreadState.cpp",
        "IServiceManager.cpp",
        "IServiceManagerFFI.cpp",
        "ProcessState.cpp",
        "Static.cpp",
        ":libbinder_aidl",
@@ -534,7 +536,6 @@ cc_library {
        "ParcelableHolder.cpp",
        "PersistableBundle.cpp",
    ],

    target: {
        android: {
            // NOT static to keep the wire protocol unfrozen
+119 −0
Original line number Diff line number Diff line
/*
 * 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
+68 −0
Original line number Diff line number Diff line
/*
 * 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
+24 −46
Original line number Diff line number Diff line
@@ -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;
+27 −0
Original line number Diff line number Diff line
/*
 * 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
Loading