1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker * Copyright (C) 2019 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker *
4*38e8c45fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker *
8*38e8c45fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker *
10*38e8c45fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker */
16*38e8c45fSAndroid Build Coastguard Worker
17*38e8c45fSAndroid Build Coastguard Worker #define LOG_TAG "AidlLazyServiceRegistrar"
18*38e8c45fSAndroid Build Coastguard Worker
19*38e8c45fSAndroid Build Coastguard Worker #include <android/os/BnClientCallback.h>
20*38e8c45fSAndroid Build Coastguard Worker #include <android/os/IServiceManager.h>
21*38e8c45fSAndroid Build Coastguard Worker #include <binder/IPCThreadState.h>
22*38e8c45fSAndroid Build Coastguard Worker #include <binder/LazyServiceRegistrar.h>
23*38e8c45fSAndroid Build Coastguard Worker
24*38e8c45fSAndroid Build Coastguard Worker namespace android {
25*38e8c45fSAndroid Build Coastguard Worker namespace binder {
26*38e8c45fSAndroid Build Coastguard Worker namespace internal {
27*38e8c45fSAndroid Build Coastguard Worker
28*38e8c45fSAndroid Build Coastguard Worker using AidlServiceManager = android::os::IServiceManager;
29*38e8c45fSAndroid Build Coastguard Worker
30*38e8c45fSAndroid Build Coastguard Worker class ClientCounterCallbackImpl : public ::android::os::BnClientCallback {
31*38e8c45fSAndroid Build Coastguard Worker public:
ClientCounterCallbackImpl()32*38e8c45fSAndroid Build Coastguard Worker ClientCounterCallbackImpl() : mNumConnectedServices(0), mForcePersist(false) {}
33*38e8c45fSAndroid Build Coastguard Worker
34*38e8c45fSAndroid Build Coastguard Worker bool registerService(const sp<IBinder>& service, const std::string& name,
35*38e8c45fSAndroid Build Coastguard Worker bool allowIsolated, int dumpFlags);
36*38e8c45fSAndroid Build Coastguard Worker void forcePersist(bool persist);
37*38e8c45fSAndroid Build Coastguard Worker
38*38e8c45fSAndroid Build Coastguard Worker void setActiveServicesCallback(const std::function<bool(bool)>& activeServicesCallback);
39*38e8c45fSAndroid Build Coastguard Worker
40*38e8c45fSAndroid Build Coastguard Worker bool tryUnregisterLocked();
41*38e8c45fSAndroid Build Coastguard Worker
42*38e8c45fSAndroid Build Coastguard Worker void reRegisterLocked();
43*38e8c45fSAndroid Build Coastguard Worker
44*38e8c45fSAndroid Build Coastguard Worker protected:
45*38e8c45fSAndroid Build Coastguard Worker Status onClients(const sp<IBinder>& service, bool clients) override;
46*38e8c45fSAndroid Build Coastguard Worker
47*38e8c45fSAndroid Build Coastguard Worker private:
48*38e8c45fSAndroid Build Coastguard Worker struct Service {
49*38e8c45fSAndroid Build Coastguard Worker sp<IBinder> service;
50*38e8c45fSAndroid Build Coastguard Worker bool allowIsolated;
51*38e8c45fSAndroid Build Coastguard Worker int dumpFlags;
52*38e8c45fSAndroid Build Coastguard Worker
53*38e8c45fSAndroid Build Coastguard Worker // whether, based on onClients calls, we know we have a client for this
54*38e8c45fSAndroid Build Coastguard Worker // service or not
55*38e8c45fSAndroid Build Coastguard Worker bool clients = false;
56*38e8c45fSAndroid Build Coastguard Worker bool registered = true;
57*38e8c45fSAndroid Build Coastguard Worker };
58*38e8c45fSAndroid Build Coastguard Worker
59*38e8c45fSAndroid Build Coastguard Worker bool registerServiceLocked(const sp<IBinder>& service, const std::string& name,
60*38e8c45fSAndroid Build Coastguard Worker bool allowIsolated, int dumpFlags);
61*38e8c45fSAndroid Build Coastguard Worker
62*38e8c45fSAndroid Build Coastguard Worker /**
63*38e8c45fSAndroid Build Coastguard Worker * Looks up a service guaranteed to be registered (service from onClients).
64*38e8c45fSAndroid Build Coastguard Worker */
65*38e8c45fSAndroid Build Coastguard Worker std::map<std::string, Service>::iterator assertRegisteredService(const sp<IBinder>& service);
66*38e8c45fSAndroid Build Coastguard Worker
67*38e8c45fSAndroid Build Coastguard Worker /**
68*38e8c45fSAndroid Build Coastguard Worker * Unregisters all services that we can. If we can't unregister all, re-register other
69*38e8c45fSAndroid Build Coastguard Worker * services.
70*38e8c45fSAndroid Build Coastguard Worker */
71*38e8c45fSAndroid Build Coastguard Worker void tryShutdownLocked();
72*38e8c45fSAndroid Build Coastguard Worker
73*38e8c45fSAndroid Build Coastguard Worker /**
74*38e8c45fSAndroid Build Coastguard Worker * Try to shutdown the process, unless:
75*38e8c45fSAndroid Build Coastguard Worker * - 'forcePersist' is 'true', or
76*38e8c45fSAndroid Build Coastguard Worker * - The active services count callback returns 'true', or
77*38e8c45fSAndroid Build Coastguard Worker * - Some services have clients.
78*38e8c45fSAndroid Build Coastguard Worker */
79*38e8c45fSAndroid Build Coastguard Worker void maybeTryShutdownLocked();
80*38e8c45fSAndroid Build Coastguard Worker
81*38e8c45fSAndroid Build Coastguard Worker // for below
82*38e8c45fSAndroid Build Coastguard Worker std::mutex mMutex;
83*38e8c45fSAndroid Build Coastguard Worker
84*38e8c45fSAndroid Build Coastguard Worker // count of services with clients
85*38e8c45fSAndroid Build Coastguard Worker size_t mNumConnectedServices;
86*38e8c45fSAndroid Build Coastguard Worker
87*38e8c45fSAndroid Build Coastguard Worker // previous value passed to the active services callback
88*38e8c45fSAndroid Build Coastguard Worker std::optional<bool> mPreviousHasClients;
89*38e8c45fSAndroid Build Coastguard Worker
90*38e8c45fSAndroid Build Coastguard Worker // map of registered names and services
91*38e8c45fSAndroid Build Coastguard Worker std::map<std::string, Service> mRegisteredServices;
92*38e8c45fSAndroid Build Coastguard Worker
93*38e8c45fSAndroid Build Coastguard Worker bool mForcePersist;
94*38e8c45fSAndroid Build Coastguard Worker
95*38e8c45fSAndroid Build Coastguard Worker // Callback used to report if there are services with clients
96*38e8c45fSAndroid Build Coastguard Worker std::function<bool(bool)> mActiveServicesCallback;
97*38e8c45fSAndroid Build Coastguard Worker };
98*38e8c45fSAndroid Build Coastguard Worker
99*38e8c45fSAndroid Build Coastguard Worker class ClientCounterCallback {
100*38e8c45fSAndroid Build Coastguard Worker public:
101*38e8c45fSAndroid Build Coastguard Worker ClientCounterCallback();
102*38e8c45fSAndroid Build Coastguard Worker
103*38e8c45fSAndroid Build Coastguard Worker bool registerService(const sp<IBinder>& service, const std::string& name,
104*38e8c45fSAndroid Build Coastguard Worker bool allowIsolated, int dumpFlags);
105*38e8c45fSAndroid Build Coastguard Worker
106*38e8c45fSAndroid Build Coastguard Worker /**
107*38e8c45fSAndroid Build Coastguard Worker * Set a flag to prevent services from automatically shutting down
108*38e8c45fSAndroid Build Coastguard Worker */
109*38e8c45fSAndroid Build Coastguard Worker void forcePersist(bool persist);
110*38e8c45fSAndroid Build Coastguard Worker
111*38e8c45fSAndroid Build Coastguard Worker void setActiveServicesCallback(const std::function<bool(bool)>& activeServicesCallback);
112*38e8c45fSAndroid Build Coastguard Worker
113*38e8c45fSAndroid Build Coastguard Worker bool tryUnregister();
114*38e8c45fSAndroid Build Coastguard Worker
115*38e8c45fSAndroid Build Coastguard Worker void reRegister();
116*38e8c45fSAndroid Build Coastguard Worker
117*38e8c45fSAndroid Build Coastguard Worker private:
118*38e8c45fSAndroid Build Coastguard Worker sp<ClientCounterCallbackImpl> mImpl;
119*38e8c45fSAndroid Build Coastguard Worker };
120*38e8c45fSAndroid Build Coastguard Worker
registerService(const sp<IBinder> & service,const std::string & name,bool allowIsolated,int dumpFlags)121*38e8c45fSAndroid Build Coastguard Worker bool ClientCounterCallbackImpl::registerService(const sp<IBinder>& service, const std::string& name,
122*38e8c45fSAndroid Build Coastguard Worker bool allowIsolated, int dumpFlags) {
123*38e8c45fSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mMutex);
124*38e8c45fSAndroid Build Coastguard Worker return registerServiceLocked(service, name, allowIsolated, dumpFlags);
125*38e8c45fSAndroid Build Coastguard Worker }
126*38e8c45fSAndroid Build Coastguard Worker
registerServiceLocked(const sp<IBinder> & service,const std::string & name,bool allowIsolated,int dumpFlags)127*38e8c45fSAndroid Build Coastguard Worker bool ClientCounterCallbackImpl::registerServiceLocked(const sp<IBinder>& service,
128*38e8c45fSAndroid Build Coastguard Worker const std::string& name, bool allowIsolated,
129*38e8c45fSAndroid Build Coastguard Worker int dumpFlags) {
130*38e8c45fSAndroid Build Coastguard Worker auto manager = interface_cast<AidlServiceManager>(asBinder(defaultServiceManager()));
131*38e8c45fSAndroid Build Coastguard Worker
132*38e8c45fSAndroid Build Coastguard Worker bool reRegister = mRegisteredServices.count(name) > 0;
133*38e8c45fSAndroid Build Coastguard Worker std::string regStr = (reRegister) ? "Re-registering" : "Registering";
134*38e8c45fSAndroid Build Coastguard Worker ALOGI("%s service %s", regStr.c_str(), name.c_str());
135*38e8c45fSAndroid Build Coastguard Worker
136*38e8c45fSAndroid Build Coastguard Worker if (dumpFlags & android::os::IServiceManager::FLAG_IS_LAZY_SERVICE) {
137*38e8c45fSAndroid Build Coastguard Worker ALOGW("FLAG_IS_LAZY_SERVICE flag already set. This should only be set by "
138*38e8c45fSAndroid Build Coastguard Worker "ClientCounterCallbackImpl in LazyServiceRegistrar");
139*38e8c45fSAndroid Build Coastguard Worker }
140*38e8c45fSAndroid Build Coastguard Worker dumpFlags |= android::os::IServiceManager::FLAG_IS_LAZY_SERVICE;
141*38e8c45fSAndroid Build Coastguard Worker
142*38e8c45fSAndroid Build Coastguard Worker if (Status status = manager->addService(name.c_str(), service, allowIsolated, dumpFlags);
143*38e8c45fSAndroid Build Coastguard Worker !status.isOk()) {
144*38e8c45fSAndroid Build Coastguard Worker ALOGE("Failed to register service %s (%s)", name.c_str(), status.toString8().c_str());
145*38e8c45fSAndroid Build Coastguard Worker return false;
146*38e8c45fSAndroid Build Coastguard Worker }
147*38e8c45fSAndroid Build Coastguard Worker
148*38e8c45fSAndroid Build Coastguard Worker if (!reRegister) {
149*38e8c45fSAndroid Build Coastguard Worker if (Status status =
150*38e8c45fSAndroid Build Coastguard Worker manager->registerClientCallback(name, service,
151*38e8c45fSAndroid Build Coastguard Worker sp<android::os::IClientCallback>::fromExisting(
152*38e8c45fSAndroid Build Coastguard Worker this));
153*38e8c45fSAndroid Build Coastguard Worker !status.isOk()) {
154*38e8c45fSAndroid Build Coastguard Worker ALOGE("Failed to add client callback for service %s (%s)", name.c_str(),
155*38e8c45fSAndroid Build Coastguard Worker status.toString8().c_str());
156*38e8c45fSAndroid Build Coastguard Worker return false;
157*38e8c45fSAndroid Build Coastguard Worker }
158*38e8c45fSAndroid Build Coastguard Worker
159*38e8c45fSAndroid Build Coastguard Worker // Only add this when a service is added for the first time, as it is not removed
160*38e8c45fSAndroid Build Coastguard Worker mRegisteredServices[name] = {
161*38e8c45fSAndroid Build Coastguard Worker .service = service,
162*38e8c45fSAndroid Build Coastguard Worker .allowIsolated = allowIsolated,
163*38e8c45fSAndroid Build Coastguard Worker .dumpFlags = dumpFlags
164*38e8c45fSAndroid Build Coastguard Worker };
165*38e8c45fSAndroid Build Coastguard Worker }
166*38e8c45fSAndroid Build Coastguard Worker
167*38e8c45fSAndroid Build Coastguard Worker return true;
168*38e8c45fSAndroid Build Coastguard Worker }
169*38e8c45fSAndroid Build Coastguard Worker
assertRegisteredService(const sp<IBinder> & service)170*38e8c45fSAndroid Build Coastguard Worker std::map<std::string, ClientCounterCallbackImpl::Service>::iterator ClientCounterCallbackImpl::assertRegisteredService(const sp<IBinder>& service) {
171*38e8c45fSAndroid Build Coastguard Worker LOG_ALWAYS_FATAL_IF(service == nullptr, "Got onClients callback for null service");
172*38e8c45fSAndroid Build Coastguard Worker for (auto it = mRegisteredServices.begin(); it != mRegisteredServices.end(); ++it) {
173*38e8c45fSAndroid Build Coastguard Worker auto const& [name, registered] = *it;
174*38e8c45fSAndroid Build Coastguard Worker (void) name;
175*38e8c45fSAndroid Build Coastguard Worker if (registered.service != service) continue;
176*38e8c45fSAndroid Build Coastguard Worker return it;
177*38e8c45fSAndroid Build Coastguard Worker }
178*38e8c45fSAndroid Build Coastguard Worker LOG_ALWAYS_FATAL("Got callback on service which we did not register: %s", String8(service->getInterfaceDescriptor()).c_str());
179*38e8c45fSAndroid Build Coastguard Worker __builtin_unreachable();
180*38e8c45fSAndroid Build Coastguard Worker }
181*38e8c45fSAndroid Build Coastguard Worker
forcePersist(bool persist)182*38e8c45fSAndroid Build Coastguard Worker void ClientCounterCallbackImpl::forcePersist(bool persist) {
183*38e8c45fSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mMutex);
184*38e8c45fSAndroid Build Coastguard Worker mForcePersist = persist;
185*38e8c45fSAndroid Build Coastguard Worker if (!mForcePersist) {
186*38e8c45fSAndroid Build Coastguard Worker // Attempt a shutdown in case the number of clients hit 0 while the flag was on
187*38e8c45fSAndroid Build Coastguard Worker maybeTryShutdownLocked();
188*38e8c45fSAndroid Build Coastguard Worker }
189*38e8c45fSAndroid Build Coastguard Worker }
190*38e8c45fSAndroid Build Coastguard Worker
tryUnregisterLocked()191*38e8c45fSAndroid Build Coastguard Worker bool ClientCounterCallbackImpl::tryUnregisterLocked() {
192*38e8c45fSAndroid Build Coastguard Worker auto manager = interface_cast<AidlServiceManager>(asBinder(defaultServiceManager()));
193*38e8c45fSAndroid Build Coastguard Worker
194*38e8c45fSAndroid Build Coastguard Worker for (auto& [name, entry] : mRegisteredServices) {
195*38e8c45fSAndroid Build Coastguard Worker Status status = manager->tryUnregisterService(name, entry.service);
196*38e8c45fSAndroid Build Coastguard Worker
197*38e8c45fSAndroid Build Coastguard Worker if (!status.isOk()) {
198*38e8c45fSAndroid Build Coastguard Worker ALOGI("Failed to unregister service %s (%s)", name.c_str(), status.toString8().c_str());
199*38e8c45fSAndroid Build Coastguard Worker return false;
200*38e8c45fSAndroid Build Coastguard Worker }
201*38e8c45fSAndroid Build Coastguard Worker entry.registered = false;
202*38e8c45fSAndroid Build Coastguard Worker }
203*38e8c45fSAndroid Build Coastguard Worker
204*38e8c45fSAndroid Build Coastguard Worker return true;
205*38e8c45fSAndroid Build Coastguard Worker }
206*38e8c45fSAndroid Build Coastguard Worker
reRegisterLocked()207*38e8c45fSAndroid Build Coastguard Worker void ClientCounterCallbackImpl::reRegisterLocked() {
208*38e8c45fSAndroid Build Coastguard Worker for (auto& [name, entry] : mRegisteredServices) {
209*38e8c45fSAndroid Build Coastguard Worker // re-register entry if not already registered
210*38e8c45fSAndroid Build Coastguard Worker if (entry.registered) {
211*38e8c45fSAndroid Build Coastguard Worker continue;
212*38e8c45fSAndroid Build Coastguard Worker }
213*38e8c45fSAndroid Build Coastguard Worker
214*38e8c45fSAndroid Build Coastguard Worker if (!registerServiceLocked(entry.service, name, entry.allowIsolated, entry.dumpFlags)) {
215*38e8c45fSAndroid Build Coastguard Worker // Must restart. Otherwise, clients will never be able to get a hold of this service.
216*38e8c45fSAndroid Build Coastguard Worker LOG_ALWAYS_FATAL("Bad state: could not re-register services");
217*38e8c45fSAndroid Build Coastguard Worker }
218*38e8c45fSAndroid Build Coastguard Worker
219*38e8c45fSAndroid Build Coastguard Worker entry.registered = true;
220*38e8c45fSAndroid Build Coastguard Worker }
221*38e8c45fSAndroid Build Coastguard Worker }
222*38e8c45fSAndroid Build Coastguard Worker
maybeTryShutdownLocked()223*38e8c45fSAndroid Build Coastguard Worker void ClientCounterCallbackImpl::maybeTryShutdownLocked() {
224*38e8c45fSAndroid Build Coastguard Worker if (mForcePersist) {
225*38e8c45fSAndroid Build Coastguard Worker ALOGI("Shutdown prevented by forcePersist override flag.");
226*38e8c45fSAndroid Build Coastguard Worker return;
227*38e8c45fSAndroid Build Coastguard Worker }
228*38e8c45fSAndroid Build Coastguard Worker
229*38e8c45fSAndroid Build Coastguard Worker bool handledInCallback = false;
230*38e8c45fSAndroid Build Coastguard Worker if (mActiveServicesCallback != nullptr) {
231*38e8c45fSAndroid Build Coastguard Worker bool hasClients = mNumConnectedServices != 0;
232*38e8c45fSAndroid Build Coastguard Worker if (hasClients != mPreviousHasClients) {
233*38e8c45fSAndroid Build Coastguard Worker handledInCallback = mActiveServicesCallback(hasClients);
234*38e8c45fSAndroid Build Coastguard Worker mPreviousHasClients = hasClients;
235*38e8c45fSAndroid Build Coastguard Worker }
236*38e8c45fSAndroid Build Coastguard Worker }
237*38e8c45fSAndroid Build Coastguard Worker
238*38e8c45fSAndroid Build Coastguard Worker // If there is no callback defined or the callback did not handle this
239*38e8c45fSAndroid Build Coastguard Worker // client count change event, try to shutdown the process if its services
240*38e8c45fSAndroid Build Coastguard Worker // have no clients.
241*38e8c45fSAndroid Build Coastguard Worker if (!handledInCallback && mNumConnectedServices == 0) {
242*38e8c45fSAndroid Build Coastguard Worker tryShutdownLocked();
243*38e8c45fSAndroid Build Coastguard Worker }
244*38e8c45fSAndroid Build Coastguard Worker }
245*38e8c45fSAndroid Build Coastguard Worker
onClients(const sp<IBinder> & service,bool clients)246*38e8c45fSAndroid Build Coastguard Worker Status ClientCounterCallbackImpl::onClients(const sp<IBinder>& service, bool clients) {
247*38e8c45fSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mMutex);
248*38e8c45fSAndroid Build Coastguard Worker auto & [name, registered] = *assertRegisteredService(service);
249*38e8c45fSAndroid Build Coastguard Worker if (registered.clients == clients) {
250*38e8c45fSAndroid Build Coastguard Worker LOG_ALWAYS_FATAL("Process already thought %s had clients: %d but servicemanager has "
251*38e8c45fSAndroid Build Coastguard Worker "notified has clients: %d", name.c_str(), registered.clients, clients);
252*38e8c45fSAndroid Build Coastguard Worker }
253*38e8c45fSAndroid Build Coastguard Worker registered.clients = clients;
254*38e8c45fSAndroid Build Coastguard Worker
255*38e8c45fSAndroid Build Coastguard Worker // update cache count of clients
256*38e8c45fSAndroid Build Coastguard Worker {
257*38e8c45fSAndroid Build Coastguard Worker size_t numWithClients = 0;
258*38e8c45fSAndroid Build Coastguard Worker for (const auto& [name, registered] : mRegisteredServices) {
259*38e8c45fSAndroid Build Coastguard Worker (void) name;
260*38e8c45fSAndroid Build Coastguard Worker if (registered.clients) numWithClients++;
261*38e8c45fSAndroid Build Coastguard Worker }
262*38e8c45fSAndroid Build Coastguard Worker mNumConnectedServices = numWithClients;
263*38e8c45fSAndroid Build Coastguard Worker }
264*38e8c45fSAndroid Build Coastguard Worker
265*38e8c45fSAndroid Build Coastguard Worker ALOGI("Process has %zu (of %zu available) client(s) in use after notification %s has clients: %d",
266*38e8c45fSAndroid Build Coastguard Worker mNumConnectedServices, mRegisteredServices.size(), name.c_str(), clients);
267*38e8c45fSAndroid Build Coastguard Worker
268*38e8c45fSAndroid Build Coastguard Worker maybeTryShutdownLocked();
269*38e8c45fSAndroid Build Coastguard Worker return Status::ok();
270*38e8c45fSAndroid Build Coastguard Worker }
271*38e8c45fSAndroid Build Coastguard Worker
tryShutdownLocked()272*38e8c45fSAndroid Build Coastguard Worker void ClientCounterCallbackImpl::tryShutdownLocked() {
273*38e8c45fSAndroid Build Coastguard Worker ALOGI("Trying to shut down the service. No clients in use for any service in process.");
274*38e8c45fSAndroid Build Coastguard Worker
275*38e8c45fSAndroid Build Coastguard Worker if (tryUnregisterLocked()) {
276*38e8c45fSAndroid Build Coastguard Worker ALOGI("Unregistered all clients and exiting");
277*38e8c45fSAndroid Build Coastguard Worker exit(EXIT_SUCCESS);
278*38e8c45fSAndroid Build Coastguard Worker }
279*38e8c45fSAndroid Build Coastguard Worker
280*38e8c45fSAndroid Build Coastguard Worker reRegisterLocked();
281*38e8c45fSAndroid Build Coastguard Worker }
282*38e8c45fSAndroid Build Coastguard Worker
setActiveServicesCallback(const std::function<bool (bool)> & activeServicesCallback)283*38e8c45fSAndroid Build Coastguard Worker void ClientCounterCallbackImpl::setActiveServicesCallback(const std::function<bool(bool)>&
284*38e8c45fSAndroid Build Coastguard Worker activeServicesCallback) {
285*38e8c45fSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mMutex);
286*38e8c45fSAndroid Build Coastguard Worker mActiveServicesCallback = activeServicesCallback;
287*38e8c45fSAndroid Build Coastguard Worker }
288*38e8c45fSAndroid Build Coastguard Worker
ClientCounterCallback()289*38e8c45fSAndroid Build Coastguard Worker ClientCounterCallback::ClientCounterCallback() {
290*38e8c45fSAndroid Build Coastguard Worker mImpl = sp<ClientCounterCallbackImpl>::make();
291*38e8c45fSAndroid Build Coastguard Worker }
292*38e8c45fSAndroid Build Coastguard Worker
registerService(const sp<IBinder> & service,const std::string & name,bool allowIsolated,int dumpFlags)293*38e8c45fSAndroid Build Coastguard Worker bool ClientCounterCallback::registerService(const sp<IBinder>& service, const std::string& name,
294*38e8c45fSAndroid Build Coastguard Worker bool allowIsolated, int dumpFlags) {
295*38e8c45fSAndroid Build Coastguard Worker return mImpl->registerService(service, name, allowIsolated, dumpFlags);
296*38e8c45fSAndroid Build Coastguard Worker }
297*38e8c45fSAndroid Build Coastguard Worker
forcePersist(bool persist)298*38e8c45fSAndroid Build Coastguard Worker void ClientCounterCallback::forcePersist(bool persist) {
299*38e8c45fSAndroid Build Coastguard Worker mImpl->forcePersist(persist);
300*38e8c45fSAndroid Build Coastguard Worker }
301*38e8c45fSAndroid Build Coastguard Worker
setActiveServicesCallback(const std::function<bool (bool)> & activeServicesCallback)302*38e8c45fSAndroid Build Coastguard Worker void ClientCounterCallback::setActiveServicesCallback(const std::function<bool(bool)>&
303*38e8c45fSAndroid Build Coastguard Worker activeServicesCallback) {
304*38e8c45fSAndroid Build Coastguard Worker mImpl->setActiveServicesCallback(activeServicesCallback);
305*38e8c45fSAndroid Build Coastguard Worker }
306*38e8c45fSAndroid Build Coastguard Worker
tryUnregister()307*38e8c45fSAndroid Build Coastguard Worker bool ClientCounterCallback::tryUnregister() {
308*38e8c45fSAndroid Build Coastguard Worker // see comments in header, this should only be called from the active
309*38e8c45fSAndroid Build Coastguard Worker // services callback, see also b/191781736
310*38e8c45fSAndroid Build Coastguard Worker return mImpl->tryUnregisterLocked();
311*38e8c45fSAndroid Build Coastguard Worker }
312*38e8c45fSAndroid Build Coastguard Worker
reRegister()313*38e8c45fSAndroid Build Coastguard Worker void ClientCounterCallback::reRegister() {
314*38e8c45fSAndroid Build Coastguard Worker // see comments in header, this should only be called from the active
315*38e8c45fSAndroid Build Coastguard Worker // services callback, see also b/191781736
316*38e8c45fSAndroid Build Coastguard Worker mImpl->reRegisterLocked();
317*38e8c45fSAndroid Build Coastguard Worker }
318*38e8c45fSAndroid Build Coastguard Worker
319*38e8c45fSAndroid Build Coastguard Worker } // namespace internal
320*38e8c45fSAndroid Build Coastguard Worker
LazyServiceRegistrar()321*38e8c45fSAndroid Build Coastguard Worker LazyServiceRegistrar::LazyServiceRegistrar() {
322*38e8c45fSAndroid Build Coastguard Worker mClientCC = std::make_shared<internal::ClientCounterCallback>();
323*38e8c45fSAndroid Build Coastguard Worker }
324*38e8c45fSAndroid Build Coastguard Worker
getInstance()325*38e8c45fSAndroid Build Coastguard Worker LazyServiceRegistrar& LazyServiceRegistrar::getInstance() {
326*38e8c45fSAndroid Build Coastguard Worker static auto registrarInstance = new LazyServiceRegistrar();
327*38e8c45fSAndroid Build Coastguard Worker return *registrarInstance;
328*38e8c45fSAndroid Build Coastguard Worker }
329*38e8c45fSAndroid Build Coastguard Worker
createExtraTestInstance()330*38e8c45fSAndroid Build Coastguard Worker LazyServiceRegistrar LazyServiceRegistrar::createExtraTestInstance() {
331*38e8c45fSAndroid Build Coastguard Worker return LazyServiceRegistrar();
332*38e8c45fSAndroid Build Coastguard Worker }
333*38e8c45fSAndroid Build Coastguard Worker
registerService(const sp<IBinder> & service,const std::string & name,bool allowIsolated,int dumpFlags)334*38e8c45fSAndroid Build Coastguard Worker status_t LazyServiceRegistrar::registerService(const sp<IBinder>& service, const std::string& name,
335*38e8c45fSAndroid Build Coastguard Worker bool allowIsolated, int dumpFlags) {
336*38e8c45fSAndroid Build Coastguard Worker if (!mClientCC->registerService(service, name, allowIsolated, dumpFlags)) {
337*38e8c45fSAndroid Build Coastguard Worker return UNKNOWN_ERROR;
338*38e8c45fSAndroid Build Coastguard Worker }
339*38e8c45fSAndroid Build Coastguard Worker return OK;
340*38e8c45fSAndroid Build Coastguard Worker }
341*38e8c45fSAndroid Build Coastguard Worker
forcePersist(bool persist)342*38e8c45fSAndroid Build Coastguard Worker void LazyServiceRegistrar::forcePersist(bool persist) {
343*38e8c45fSAndroid Build Coastguard Worker mClientCC->forcePersist(persist);
344*38e8c45fSAndroid Build Coastguard Worker }
345*38e8c45fSAndroid Build Coastguard Worker
setActiveServicesCallback(const std::function<bool (bool)> & activeServicesCallback)346*38e8c45fSAndroid Build Coastguard Worker void LazyServiceRegistrar::setActiveServicesCallback(const std::function<bool(bool)>&
347*38e8c45fSAndroid Build Coastguard Worker activeServicesCallback) {
348*38e8c45fSAndroid Build Coastguard Worker mClientCC->setActiveServicesCallback(activeServicesCallback);
349*38e8c45fSAndroid Build Coastguard Worker }
350*38e8c45fSAndroid Build Coastguard Worker
tryUnregister()351*38e8c45fSAndroid Build Coastguard Worker bool LazyServiceRegistrar::tryUnregister() {
352*38e8c45fSAndroid Build Coastguard Worker return mClientCC->tryUnregister();
353*38e8c45fSAndroid Build Coastguard Worker }
354*38e8c45fSAndroid Build Coastguard Worker
reRegister()355*38e8c45fSAndroid Build Coastguard Worker void LazyServiceRegistrar::reRegister() {
356*38e8c45fSAndroid Build Coastguard Worker mClientCC->reRegister();
357*38e8c45fSAndroid Build Coastguard Worker }
358*38e8c45fSAndroid Build Coastguard Worker
359*38e8c45fSAndroid Build Coastguard Worker } // namespace hardware
360*38e8c45fSAndroid Build Coastguard Worker } // namespace android
361