blob: f66993f9266e9285aa6b2d242d8ba489c17b35d0 [file] [log] [blame]
Jon Spivack9f503a42019-10-22 16:49:19 -07001/*
2 * Copyright (C) 2019 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
Amos Bianchi844e19b2020-12-23 09:57:02 -080017#include "log/log_main.h"
Jon Spivack9f503a42019-10-22 16:49:19 -070018#define LOG_TAG "AidlLazyServiceRegistrar"
19
20#include <binder/LazyServiceRegistrar.h>
21#include <binder/IPCThreadState.h>
22#include <binder/IServiceManager.h>
23#include <android/os/BnClientCallback.h>
24#include <android/os/IServiceManager.h>
25#include <utils/Log.h>
26
27namespace android {
28namespace binder {
29namespace internal {
30
31using AidlServiceManager = android::os::IServiceManager;
32
Jon Spivackdc6cb052020-10-27 19:29:14 -070033class ClientCounterCallbackImpl : public ::android::os::BnClientCallback {
Jon Spivack9f503a42019-10-22 16:49:19 -070034public:
Jon Spivackdc6cb052020-10-27 19:29:14 -070035 ClientCounterCallbackImpl() : mNumConnectedServices(0), mForcePersist(false) {}
Jon Spivack9f503a42019-10-22 16:49:19 -070036
37 bool registerService(const sp<IBinder>& service, const std::string& name,
38 bool allowIsolated, int dumpFlags);
Jon Spivacke17055a2020-03-06 13:58:01 -080039 void forcePersist(bool persist);
40
Amos Bianchi3f796942021-01-20 16:06:56 -080041 void setActiveServicesCallback(const std::function<bool(bool)>& activeServicesCallback);
Amos Bianchi844e19b2020-12-23 09:57:02 -080042
Steven Moreland7a5889c2021-06-22 19:18:28 +000043 bool tryUnregisterLocked();
Amos Bianchi844e19b2020-12-23 09:57:02 -080044
Steven Moreland7a5889c2021-06-22 19:18:28 +000045 void reRegisterLocked();
Amos Bianchi844e19b2020-12-23 09:57:02 -080046
Jon Spivack9f503a42019-10-22 16:49:19 -070047protected:
48 Status onClients(const sp<IBinder>& service, bool clients) override;
49
50private:
Steven Morelanddd20e7c2020-04-10 11:51:14 -070051 struct Service {
52 sp<IBinder> service;
53 bool allowIsolated;
54 int dumpFlags;
55
56 // whether, based on onClients calls, we know we have a client for this
57 // service or not
58 bool clients = false;
Xin Lica3e5792021-02-21 09:43:11 -080059 bool registered = true;
Steven Morelanddd20e7c2020-04-10 11:51:14 -070060 };
61
Steven Moreland7a5889c2021-06-22 19:18:28 +000062 bool registerServiceLocked(const sp<IBinder>& service, const std::string& name,
63 bool allowIsolated, int dumpFlags);
64
Steven Morelanddd20e7c2020-04-10 11:51:14 -070065 /**
66 * Looks up a service guaranteed to be registered (service from onClients).
67 */
68 std::map<std::string, Service>::iterator assertRegisteredService(const sp<IBinder>& service);
69
Jon Spivack9f503a42019-10-22 16:49:19 -070070 /**
71 * Unregisters all services that we can. If we can't unregister all, re-register other
72 * services.
73 */
Steven Moreland7a5889c2021-06-22 19:18:28 +000074 void tryShutdownLocked();
Jon Spivack9f503a42019-10-22 16:49:19 -070075
76 /**
Amos Bianchi844e19b2020-12-23 09:57:02 -080077 * Try to shutdown the process, unless:
78 * - 'forcePersist' is 'true', or
79 * - The active services count callback returns 'true', or
80 * - Some services have clients.
81 */
Steven Moreland7a5889c2021-06-22 19:18:28 +000082 void maybeTryShutdownLocked();
83
84 // for below
85 std::mutex mMutex;
Amos Bianchi844e19b2020-12-23 09:57:02 -080086
Steven Morelanddd20e7c2020-04-10 11:51:14 -070087 // count of services with clients
Jon Spivack9f503a42019-10-22 16:49:19 -070088 size_t mNumConnectedServices;
89
Amos Bianchi3f796942021-01-20 16:06:56 -080090 // previous value passed to the active services callback
91 std::optional<bool> mPreviousHasClients;
92
Steven Morelanddd20e7c2020-04-10 11:51:14 -070093 // map of registered names and services
Jon Spivackd9533c22020-01-27 22:19:22 +000094 std::map<std::string, Service> mRegisteredServices;
Jon Spivacke17055a2020-03-06 13:58:01 -080095
96 bool mForcePersist;
Amos Bianchi844e19b2020-12-23 09:57:02 -080097
Amos Bianchi3f796942021-01-20 16:06:56 -080098 // Callback used to report if there are services with clients
99 std::function<bool(bool)> mActiveServicesCallback;
Jon Spivack9f503a42019-10-22 16:49:19 -0700100};
101
Jon Spivackdc6cb052020-10-27 19:29:14 -0700102class ClientCounterCallback {
103public:
104 ClientCounterCallback();
105
106 bool registerService(const sp<IBinder>& service, const std::string& name,
107 bool allowIsolated, int dumpFlags);
108
109 /**
110 * Set a flag to prevent services from automatically shutting down
111 */
112 void forcePersist(bool persist);
113
Amos Bianchi3f796942021-01-20 16:06:56 -0800114 void setActiveServicesCallback(const std::function<bool(bool)>& activeServicesCallback);
Amos Bianchi844e19b2020-12-23 09:57:02 -0800115
116 bool tryUnregister();
117
118 void reRegister();
119
Jon Spivackdc6cb052020-10-27 19:29:14 -0700120private:
121 sp<ClientCounterCallbackImpl> mImpl;
122};
123
124bool ClientCounterCallbackImpl::registerService(const sp<IBinder>& service, const std::string& name,
Jon Spivack9f503a42019-10-22 16:49:19 -0700125 bool allowIsolated, int dumpFlags) {
Steven Moreland7a5889c2021-06-22 19:18:28 +0000126 std::lock_guard<std::mutex> lock(mMutex);
127 return registerServiceLocked(service, name, allowIsolated, dumpFlags);
128}
129
130bool ClientCounterCallbackImpl::registerServiceLocked(const sp<IBinder>& service,
131 const std::string& name, bool allowIsolated,
132 int dumpFlags) {
Jon Spivack718470e2020-02-19 19:18:21 -0800133 auto manager = interface_cast<AidlServiceManager>(asBinder(defaultServiceManager()));
Jon Spivack9f503a42019-10-22 16:49:19 -0700134
Jon Spivackd9533c22020-01-27 22:19:22 +0000135 bool reRegister = mRegisteredServices.count(name) > 0;
136 std::string regStr = (reRegister) ? "Re-registering" : "Registering";
137 ALOGI("%s service %s", regStr.c_str(), name.c_str());
Jon Spivack9f503a42019-10-22 16:49:19 -0700138
Steven Moreland48c73e02021-05-10 18:31:34 +0000139 if (Status status = manager->addService(name.c_str(), service, allowIsolated, dumpFlags);
140 !status.isOk()) {
141 ALOGE("Failed to register service %s (%s)", name.c_str(), status.toString8().c_str());
Jon Spivack9f503a42019-10-22 16:49:19 -0700142 return false;
143 }
144
Jon Spivackd9533c22020-01-27 22:19:22 +0000145 if (!reRegister) {
Steven Moreland48c73e02021-05-10 18:31:34 +0000146 if (Status status =
147 manager->registerClientCallback(name, service,
148 sp<android::os::IClientCallback>::fromExisting(
149 this));
150 !status.isOk()) {
151 ALOGE("Failed to add client callback for service %s (%s)", name.c_str(),
152 status.toString8().c_str());
Steven Moreland60774252020-04-10 15:25:01 -0700153 return false;
154 }
155
Jon Spivackd9533c22020-01-27 22:19:22 +0000156 // Only add this when a service is added for the first time, as it is not removed
Steven Morelanddd20e7c2020-04-10 11:51:14 -0700157 mRegisteredServices[name] = {
158 .service = service,
159 .allowIsolated = allowIsolated,
160 .dumpFlags = dumpFlags
161 };
Jon Spivackd9533c22020-01-27 22:19:22 +0000162 }
Jon Spivack9f503a42019-10-22 16:49:19 -0700163
164 return true;
165}
166
Jon Spivack143a10d2020-10-27 19:29:14 -0700167std::map<std::string, ClientCounterCallbackImpl::Service>::iterator ClientCounterCallbackImpl::assertRegisteredService(const sp<IBinder>& service) {
Steven Morelanddd20e7c2020-04-10 11:51:14 -0700168 LOG_ALWAYS_FATAL_IF(service == nullptr, "Got onClients callback for null service");
169 for (auto it = mRegisteredServices.begin(); it != mRegisteredServices.end(); ++it) {
170 auto const& [name, registered] = *it;
171 (void) name;
172 if (registered.service != service) continue;
173 return it;
174 }
175 LOG_ALWAYS_FATAL("Got callback on service which we did not register: %s", String8(service->getInterfaceDescriptor()).c_str());
176 __builtin_unreachable();
177}
178
Jon Spivackdc6cb052020-10-27 19:29:14 -0700179void ClientCounterCallbackImpl::forcePersist(bool persist) {
Steven Moreland7a5889c2021-06-22 19:18:28 +0000180 std::lock_guard<std::mutex> lock(mMutex);
Jon Spivacke17055a2020-03-06 13:58:01 -0800181 mForcePersist = persist;
Amos Bianchi3f796942021-01-20 16:06:56 -0800182 if (!mForcePersist) {
Jon Spivacke17055a2020-03-06 13:58:01 -0800183 // Attempt a shutdown in case the number of clients hit 0 while the flag was on
Steven Moreland7a5889c2021-06-22 19:18:28 +0000184 maybeTryShutdownLocked();
Amos Bianchi844e19b2020-12-23 09:57:02 -0800185 }
186}
187
Steven Moreland7a5889c2021-06-22 19:18:28 +0000188bool ClientCounterCallbackImpl::tryUnregisterLocked() {
Amos Bianchi844e19b2020-12-23 09:57:02 -0800189 auto manager = interface_cast<AidlServiceManager>(asBinder(defaultServiceManager()));
190
191 for (auto& [name, entry] : mRegisteredServices) {
Steven Moreland48c73e02021-05-10 18:31:34 +0000192 Status status = manager->tryUnregisterService(name, entry.service);
Amos Bianchi844e19b2020-12-23 09:57:02 -0800193
Steven Moreland48c73e02021-05-10 18:31:34 +0000194 if (!status.isOk()) {
195 ALOGI("Failed to unregister service %s (%s)", name.c_str(), status.toString8().c_str());
Amos Bianchi844e19b2020-12-23 09:57:02 -0800196 return false;
197 }
198 entry.registered = false;
199 }
200
201 return true;
202}
203
Steven Moreland7a5889c2021-06-22 19:18:28 +0000204void ClientCounterCallbackImpl::reRegisterLocked() {
Amos Bianchi844e19b2020-12-23 09:57:02 -0800205 for (auto& [name, entry] : mRegisteredServices) {
206 // re-register entry if not already registered
207 if (entry.registered) {
208 continue;
209 }
210
Steven Moreland7a5889c2021-06-22 19:18:28 +0000211 if (!registerServiceLocked(entry.service, name, entry.allowIsolated, entry.dumpFlags)) {
Amos Bianchi844e19b2020-12-23 09:57:02 -0800212 // Must restart. Otherwise, clients will never be able to get a hold of this service.
213 LOG_ALWAYS_FATAL("Bad state: could not re-register services");
214 }
215
216 entry.registered = true;
217 }
218}
219
Steven Moreland7a5889c2021-06-22 19:18:28 +0000220void ClientCounterCallbackImpl::maybeTryShutdownLocked() {
Amos Bianchi844e19b2020-12-23 09:57:02 -0800221 if (mForcePersist) {
222 ALOGI("Shutdown prevented by forcePersist override flag.");
223 return;
224 }
225
226 bool handledInCallback = false;
Amos Bianchi3f796942021-01-20 16:06:56 -0800227 if (mActiveServicesCallback != nullptr) {
228 bool hasClients = mNumConnectedServices != 0;
229 if (hasClients != mPreviousHasClients) {
230 handledInCallback = mActiveServicesCallback(hasClients);
231 mPreviousHasClients = hasClients;
232 }
Amos Bianchi844e19b2020-12-23 09:57:02 -0800233 }
234
235 // If there is no callback defined or the callback did not handle this
236 // client count change event, try to shutdown the process if its services
237 // have no clients.
238 if (!handledInCallback && mNumConnectedServices == 0) {
Steven Moreland7a5889c2021-06-22 19:18:28 +0000239 tryShutdownLocked();
Jon Spivacke17055a2020-03-06 13:58:01 -0800240 }
241}
242
Jon Spivackdc6cb052020-10-27 19:29:14 -0700243Status ClientCounterCallbackImpl::onClients(const sp<IBinder>& service, bool clients) {
Steven Moreland7a5889c2021-06-22 19:18:28 +0000244 std::lock_guard<std::mutex> lock(mMutex);
Steven Morelanddd20e7c2020-04-10 11:51:14 -0700245 auto & [name, registered] = *assertRegisteredService(service);
246 if (registered.clients == clients) {
247 LOG_ALWAYS_FATAL("Process already thought %s had clients: %d but servicemanager has "
248 "notified has clients: %d", name.c_str(), registered.clients, clients);
249 }
250 registered.clients = clients;
251
252 // update cache count of clients
253 {
254 size_t numWithClients = 0;
255 for (const auto& [name, registered] : mRegisteredServices) {
256 (void) name;
257 if (registered.clients) numWithClients++;
258 }
259 mNumConnectedServices = numWithClients;
Jon Spivack9f503a42019-10-22 16:49:19 -0700260 }
261
262 ALOGI("Process has %zu (of %zu available) client(s) in use after notification %s has clients: %d",
Steven Morelanddd20e7c2020-04-10 11:51:14 -0700263 mNumConnectedServices, mRegisteredServices.size(), name.c_str(), clients);
Jon Spivack9f503a42019-10-22 16:49:19 -0700264
Steven Moreland7a5889c2021-06-22 19:18:28 +0000265 maybeTryShutdownLocked();
Jon Spivack9f503a42019-10-22 16:49:19 -0700266 return Status::ok();
267}
268
Steven Moreland7a5889c2021-06-22 19:18:28 +0000269void ClientCounterCallbackImpl::tryShutdownLocked() {
270 ALOGI("Trying to shut down the service. No clients in use for any service in process.");
Jon Spivacke17055a2020-03-06 13:58:01 -0800271
Steven Moreland7a5889c2021-06-22 19:18:28 +0000272 if (tryUnregisterLocked()) {
273 ALOGI("Unregistered all clients and exiting");
274 exit(EXIT_SUCCESS);
275 }
Jon Spivacke17055a2020-03-06 13:58:01 -0800276
Steven Moreland7a5889c2021-06-22 19:18:28 +0000277 reRegisterLocked();
Amos Bianchi844e19b2020-12-23 09:57:02 -0800278}
Jon Spivack9f503a42019-10-22 16:49:19 -0700279
Amos Bianchi3f796942021-01-20 16:06:56 -0800280void ClientCounterCallbackImpl::setActiveServicesCallback(const std::function<bool(bool)>&
281 activeServicesCallback) {
Steven Moreland7a5889c2021-06-22 19:18:28 +0000282 std::lock_guard<std::mutex> lock(mMutex);
Amos Bianchi3f796942021-01-20 16:06:56 -0800283 mActiveServicesCallback = activeServicesCallback;
Jon Spivack9f503a42019-10-22 16:49:19 -0700284}
285
Jon Spivackdc6cb052020-10-27 19:29:14 -0700286ClientCounterCallback::ClientCounterCallback() {
Jon Spivack143a10d2020-10-27 19:29:14 -0700287 mImpl = sp<ClientCounterCallbackImpl>::make();
Jon Spivackdc6cb052020-10-27 19:29:14 -0700288}
289
290bool ClientCounterCallback::registerService(const sp<IBinder>& service, const std::string& name,
291 bool allowIsolated, int dumpFlags) {
292 return mImpl->registerService(service, name, allowIsolated, dumpFlags);
293}
294
295void ClientCounterCallback::forcePersist(bool persist) {
296 mImpl->forcePersist(persist);
297}
298
Amos Bianchi3f796942021-01-20 16:06:56 -0800299void ClientCounterCallback::setActiveServicesCallback(const std::function<bool(bool)>&
300 activeServicesCallback) {
301 mImpl->setActiveServicesCallback(activeServicesCallback);
Amos Bianchi844e19b2020-12-23 09:57:02 -0800302}
303
304bool ClientCounterCallback::tryUnregister() {
Steven Moreland7a5889c2021-06-22 19:18:28 +0000305 // see comments in header, this should only be called from the active
306 // services callback, see also b/191781736
307 return mImpl->tryUnregisterLocked();
Amos Bianchi844e19b2020-12-23 09:57:02 -0800308}
309
310void ClientCounterCallback::reRegister() {
Steven Moreland7a5889c2021-06-22 19:18:28 +0000311 // see comments in header, this should only be called from the active
312 // services callback, see also b/191781736
313 mImpl->reRegisterLocked();
Amos Bianchi844e19b2020-12-23 09:57:02 -0800314}
315
Jon Spivack9f503a42019-10-22 16:49:19 -0700316} // namespace internal
317
318LazyServiceRegistrar::LazyServiceRegistrar() {
319 mClientCC = std::make_shared<internal::ClientCounterCallback>();
320}
321
322LazyServiceRegistrar& LazyServiceRegistrar::getInstance() {
323 static auto registrarInstance = new LazyServiceRegistrar();
324 return *registrarInstance;
325}
326
327status_t LazyServiceRegistrar::registerService(const sp<IBinder>& service, const std::string& name,
328 bool allowIsolated, int dumpFlags) {
329 if (!mClientCC->registerService(service, name, allowIsolated, dumpFlags)) {
330 return UNKNOWN_ERROR;
331 }
332 return OK;
333}
334
Jon Spivacke17055a2020-03-06 13:58:01 -0800335void LazyServiceRegistrar::forcePersist(bool persist) {
336 mClientCC->forcePersist(persist);
337}
338
Amos Bianchi3f796942021-01-20 16:06:56 -0800339void LazyServiceRegistrar::setActiveServicesCallback(const std::function<bool(bool)>&
340 activeServicesCallback) {
341 mClientCC->setActiveServicesCallback(activeServicesCallback);
Amos Bianchi844e19b2020-12-23 09:57:02 -0800342}
343
344bool LazyServiceRegistrar::tryUnregister() {
345 return mClientCC->tryUnregister();
346}
347
348void LazyServiceRegistrar::reRegister() {
349 mClientCC->reRegister();
350}
351
Jon Spivack9f503a42019-10-22 16:49:19 -0700352} // namespace hardware
Amos Bianchi844e19b2020-12-23 09:57:02 -0800353} // namespace android