xref: /aosp_15_r20/frameworks/native/libs/binder/LazyServiceRegistrar.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
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