Parth Sane | 56a0471 | 2024-04-22 14:21:07 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2024 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | #include "BackendUnifiedServiceManager.h" |
| 17 | |
Alice Wang | 8578f13 | 2024-05-03 09:01:56 +0000 | [diff] [blame] | 18 | #include <android/os/IAccessor.h> |
| 19 | #include <binder/RpcSession.h> |
| 20 | |
Tomasz Wasilczyk | fe25f12 | 2024-06-26 12:45:57 -0700 | [diff] [blame] | 21 | #if defined(__BIONIC__) && !defined(__ANDROID_VNDK__) |
| 22 | #include <android-base/properties.h> |
| 23 | #endif |
| 24 | |
Parth Sane | 56a0471 | 2024-04-22 14:21:07 +0000 | [diff] [blame] | 25 | namespace android { |
| 26 | |
| 27 | using AidlServiceManager = android::os::IServiceManager; |
Alice Wang | 8578f13 | 2024-05-03 09:01:56 +0000 | [diff] [blame] | 28 | using IAccessor = android::os::IAccessor; |
Parth Sane | 56a0471 | 2024-04-22 14:21:07 +0000 | [diff] [blame] | 29 | |
| 30 | BackendUnifiedServiceManager::BackendUnifiedServiceManager(const sp<AidlServiceManager>& impl) |
| 31 | : mTheRealServiceManager(impl) {} |
| 32 | |
| 33 | sp<AidlServiceManager> BackendUnifiedServiceManager::getImpl() { |
| 34 | return mTheRealServiceManager; |
| 35 | } |
Alice Wang | 11da150 | 2024-07-25 12:03:22 +0000 | [diff] [blame] | 36 | |
Parth Sane | 56a0471 | 2024-04-22 14:21:07 +0000 | [diff] [blame] | 37 | binder::Status BackendUnifiedServiceManager::getService(const ::std::string& name, |
Alice Wang | 11da150 | 2024-07-25 12:03:22 +0000 | [diff] [blame] | 38 | sp<IBinder>* _aidl_return) { |
Alice Wang | 8578f13 | 2024-05-03 09:01:56 +0000 | [diff] [blame] | 39 | os::Service service; |
Alice Wang | 11da150 | 2024-07-25 12:03:22 +0000 | [diff] [blame] | 40 | binder::Status status = getService2(name, &service); |
| 41 | *_aidl_return = service.get<os::Service::Tag::binder>(); |
| 42 | return status; |
| 43 | } |
| 44 | |
| 45 | binder::Status BackendUnifiedServiceManager::getService2(const ::std::string& name, |
| 46 | os::Service* _out) { |
| 47 | os::Service service; |
| 48 | binder::Status status = mTheRealServiceManager->getService2(name, &service); |
Devin Moore | 18f6375 | 2024-08-08 21:01:24 +0000 | [diff] [blame^] | 49 | if (status.isOk()) { |
| 50 | return toBinderService(name, service, _out); |
| 51 | } |
Alice Wang | 8578f13 | 2024-05-03 09:01:56 +0000 | [diff] [blame] | 52 | return status; |
Parth Sane | 56a0471 | 2024-04-22 14:21:07 +0000 | [diff] [blame] | 53 | } |
Alice Wang | 8578f13 | 2024-05-03 09:01:56 +0000 | [diff] [blame] | 54 | |
Parth Sane | 56a0471 | 2024-04-22 14:21:07 +0000 | [diff] [blame] | 55 | binder::Status BackendUnifiedServiceManager::checkService(const ::std::string& name, |
Alice Wang | 8578f13 | 2024-05-03 09:01:56 +0000 | [diff] [blame] | 56 | os::Service* _out) { |
| 57 | os::Service service; |
| 58 | binder::Status status = mTheRealServiceManager->checkService(name, &service); |
Devin Moore | 18f6375 | 2024-08-08 21:01:24 +0000 | [diff] [blame^] | 59 | if (status.isOk()) { |
| 60 | return toBinderService(name, service, _out); |
| 61 | } |
Alice Wang | 8578f13 | 2024-05-03 09:01:56 +0000 | [diff] [blame] | 62 | return status; |
Parth Sane | 56a0471 | 2024-04-22 14:21:07 +0000 | [diff] [blame] | 63 | } |
Alice Wang | 8578f13 | 2024-05-03 09:01:56 +0000 | [diff] [blame] | 64 | |
Devin Moore | 18f6375 | 2024-08-08 21:01:24 +0000 | [diff] [blame^] | 65 | binder::Status BackendUnifiedServiceManager::toBinderService(const ::std::string& name, |
| 66 | const os::Service& in, |
| 67 | os::Service* _out) { |
Alice Wang | 8578f13 | 2024-05-03 09:01:56 +0000 | [diff] [blame] | 68 | switch (in.getTag()) { |
| 69 | case os::Service::Tag::binder: { |
Devin Moore | 18f6375 | 2024-08-08 21:01:24 +0000 | [diff] [blame^] | 70 | if (in.get<os::Service::Tag::binder>() == nullptr) { |
| 71 | // failed to find a service. Check to see if we have any local |
| 72 | // injected Accessors for this service. |
| 73 | os::Service accessor; |
| 74 | binder::Status status = getInjectedAccessor(name, &accessor); |
| 75 | if (!status.isOk()) { |
| 76 | *_out = os::Service::make<os::Service::Tag::binder>(nullptr); |
| 77 | return status; |
| 78 | } |
| 79 | if (accessor.getTag() == os::Service::Tag::accessor && |
| 80 | accessor.get<os::Service::Tag::accessor>() != nullptr) { |
| 81 | ALOGI("Found local injected service for %s, will attempt to create connection", |
| 82 | name.c_str()); |
| 83 | // Call this again using the accessor Service to get the real |
| 84 | // service's binder into _out |
| 85 | return toBinderService(name, accessor, _out); |
| 86 | } |
| 87 | } |
| 88 | |
Alice Wang | 8578f13 | 2024-05-03 09:01:56 +0000 | [diff] [blame] | 89 | *_out = in; |
Devin Moore | 18f6375 | 2024-08-08 21:01:24 +0000 | [diff] [blame^] | 90 | return binder::Status::ok(); |
Alice Wang | 8578f13 | 2024-05-03 09:01:56 +0000 | [diff] [blame] | 91 | } |
| 92 | case os::Service::Tag::accessor: { |
| 93 | sp<IBinder> accessorBinder = in.get<os::Service::Tag::accessor>(); |
| 94 | sp<IAccessor> accessor = interface_cast<IAccessor>(accessorBinder); |
| 95 | if (accessor == nullptr) { |
| 96 | ALOGE("Service#accessor doesn't have accessor. VM is maybe starting..."); |
| 97 | *_out = os::Service::make<os::Service::Tag::binder>(nullptr); |
Devin Moore | 18f6375 | 2024-08-08 21:01:24 +0000 | [diff] [blame^] | 98 | return binder::Status::ok(); |
Alice Wang | 8578f13 | 2024-05-03 09:01:56 +0000 | [diff] [blame] | 99 | } |
| 100 | auto request = [=] { |
| 101 | os::ParcelFileDescriptor fd; |
| 102 | binder::Status ret = accessor->addConnection(&fd); |
| 103 | if (ret.isOk()) { |
| 104 | return base::unique_fd(fd.release()); |
| 105 | } else { |
| 106 | ALOGE("Failed to connect to RpcSession: %s", ret.toString8().c_str()); |
| 107 | return base::unique_fd(-1); |
| 108 | } |
| 109 | }; |
| 110 | auto session = RpcSession::make(); |
Devin Moore | 18f6375 | 2024-08-08 21:01:24 +0000 | [diff] [blame^] | 111 | status_t status = session->setupPreconnectedClient(base::unique_fd{}, request); |
| 112 | if (status != OK) { |
| 113 | ALOGE("Failed to set up preconnected binder RPC client: %s", |
| 114 | statusToString(status).c_str()); |
| 115 | return binder::Status::fromStatusT(status); |
| 116 | } |
Alice Wang | 8578f13 | 2024-05-03 09:01:56 +0000 | [diff] [blame] | 117 | session->setSessionSpecificRoot(accessorBinder); |
| 118 | *_out = os::Service::make<os::Service::Tag::binder>(session->getRootObject()); |
Devin Moore | 18f6375 | 2024-08-08 21:01:24 +0000 | [diff] [blame^] | 119 | return binder::Status::ok(); |
Alice Wang | 8578f13 | 2024-05-03 09:01:56 +0000 | [diff] [blame] | 120 | } |
| 121 | default: { |
| 122 | LOG_ALWAYS_FATAL("Unknown service type: %d", in.getTag()); |
| 123 | } |
| 124 | } |
| 125 | } |
| 126 | |
Parth Sane | 56a0471 | 2024-04-22 14:21:07 +0000 | [diff] [blame] | 127 | binder::Status BackendUnifiedServiceManager::addService(const ::std::string& name, |
| 128 | const sp<IBinder>& service, |
| 129 | bool allowIsolated, int32_t dumpPriority) { |
| 130 | return mTheRealServiceManager->addService(name, service, allowIsolated, dumpPriority); |
| 131 | } |
| 132 | binder::Status BackendUnifiedServiceManager::listServices( |
| 133 | int32_t dumpPriority, ::std::vector<::std::string>* _aidl_return) { |
| 134 | return mTheRealServiceManager->listServices(dumpPriority, _aidl_return); |
| 135 | } |
| 136 | binder::Status BackendUnifiedServiceManager::registerForNotifications( |
| 137 | const ::std::string& name, const sp<os::IServiceCallback>& callback) { |
| 138 | return mTheRealServiceManager->registerForNotifications(name, callback); |
| 139 | } |
| 140 | binder::Status BackendUnifiedServiceManager::unregisterForNotifications( |
| 141 | const ::std::string& name, const sp<os::IServiceCallback>& callback) { |
| 142 | return mTheRealServiceManager->unregisterForNotifications(name, callback); |
| 143 | } |
| 144 | binder::Status BackendUnifiedServiceManager::isDeclared(const ::std::string& name, |
| 145 | bool* _aidl_return) { |
| 146 | return mTheRealServiceManager->isDeclared(name, _aidl_return); |
| 147 | } |
| 148 | binder::Status BackendUnifiedServiceManager::getDeclaredInstances( |
| 149 | const ::std::string& iface, ::std::vector<::std::string>* _aidl_return) { |
| 150 | return mTheRealServiceManager->getDeclaredInstances(iface, _aidl_return); |
| 151 | } |
| 152 | binder::Status BackendUnifiedServiceManager::updatableViaApex( |
| 153 | const ::std::string& name, ::std::optional<::std::string>* _aidl_return) { |
| 154 | return mTheRealServiceManager->updatableViaApex(name, _aidl_return); |
| 155 | } |
| 156 | binder::Status BackendUnifiedServiceManager::getUpdatableNames( |
| 157 | const ::std::string& apexName, ::std::vector<::std::string>* _aidl_return) { |
| 158 | return mTheRealServiceManager->getUpdatableNames(apexName, _aidl_return); |
| 159 | } |
| 160 | binder::Status BackendUnifiedServiceManager::getConnectionInfo( |
| 161 | const ::std::string& name, ::std::optional<os::ConnectionInfo>* _aidl_return) { |
| 162 | return mTheRealServiceManager->getConnectionInfo(name, _aidl_return); |
| 163 | } |
| 164 | binder::Status BackendUnifiedServiceManager::registerClientCallback( |
| 165 | const ::std::string& name, const sp<IBinder>& service, |
| 166 | const sp<os::IClientCallback>& callback) { |
| 167 | return mTheRealServiceManager->registerClientCallback(name, service, callback); |
| 168 | } |
| 169 | binder::Status BackendUnifiedServiceManager::tryUnregisterService(const ::std::string& name, |
| 170 | const sp<IBinder>& service) { |
| 171 | return mTheRealServiceManager->tryUnregisterService(name, service); |
| 172 | } |
| 173 | binder::Status BackendUnifiedServiceManager::getServiceDebugInfo( |
| 174 | ::std::vector<os::ServiceDebugInfo>* _aidl_return) { |
| 175 | return mTheRealServiceManager->getServiceDebugInfo(_aidl_return); |
| 176 | } |
| 177 | |
| 178 | [[clang::no_destroy]] static std::once_flag gUSmOnce; |
| 179 | [[clang::no_destroy]] static sp<BackendUnifiedServiceManager> gUnifiedServiceManager; |
| 180 | |
| 181 | sp<BackendUnifiedServiceManager> getBackendUnifiedServiceManager() { |
| 182 | std::call_once(gUSmOnce, []() { |
| 183 | #if defined(__BIONIC__) && !defined(__ANDROID_VNDK__) |
| 184 | /* wait for service manager */ { |
| 185 | using std::literals::chrono_literals::operator""s; |
| 186 | using android::base::WaitForProperty; |
| 187 | while (!WaitForProperty("servicemanager.ready", "true", 1s)) { |
| 188 | ALOGE("Waited for servicemanager.ready for a second, waiting another..."); |
| 189 | } |
| 190 | } |
| 191 | #endif |
| 192 | |
| 193 | sp<AidlServiceManager> sm = nullptr; |
| 194 | while (sm == nullptr) { |
| 195 | sm = interface_cast<AidlServiceManager>( |
| 196 | ProcessState::self()->getContextObject(nullptr)); |
| 197 | if (sm == nullptr) { |
| 198 | ALOGE("Waiting 1s on context object on %s.", |
| 199 | ProcessState::self()->getDriverName().c_str()); |
| 200 | sleep(1); |
| 201 | } |
| 202 | } |
| 203 | |
| 204 | gUnifiedServiceManager = sp<BackendUnifiedServiceManager>::make(sm); |
| 205 | }); |
| 206 | |
| 207 | return gUnifiedServiceManager; |
| 208 | } |
| 209 | |
Devin Moore | 18f6375 | 2024-08-08 21:01:24 +0000 | [diff] [blame^] | 210 | } // namespace android |