1 /*
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
17 #include "ServiceManager.h"
18
19 #include <android-base/logging.h>
20 #include <android-base/properties.h>
21 #include <binder/BpBinder.h>
22 #include <binder/IPCThreadState.h>
23 #include <binder/ProcessState.h>
24 #include <binder/Stability.h>
25 #include <cutils/android_filesystem_config.h>
26 #include <cutils/multiuser.h>
27 #include <thread>
28
29 #ifndef VENDORSERVICEMANAGER
30 #include <vintf/VintfObject.h>
31 #include <vintf/constants.h>
32 #endif // !VENDORSERVICEMANAGER
33
34 using ::android::binder::Status;
35 using ::android::internal::Stability;
36
37 namespace android {
38
39 #ifndef VENDORSERVICEMANAGER
40 struct ManifestWithDescription {
41 std::shared_ptr<const vintf::HalManifest> manifest;
42 const char* description;
43 };
44 // func true -> stop search and forEachManifest will return true
forEachManifest(const std::function<bool (const ManifestWithDescription &)> & func)45 static bool forEachManifest(const std::function<bool(const ManifestWithDescription&)>& func) {
46 for (const ManifestWithDescription& mwd : {
47 ManifestWithDescription{ vintf::VintfObject::GetDeviceHalManifest(), "device" },
48 ManifestWithDescription{ vintf::VintfObject::GetFrameworkHalManifest(), "framework" },
49 }) {
50 if (mwd.manifest == nullptr) {
51 LOG(ERROR) << "NULL VINTF MANIFEST!: " << mwd.description;
52 // note, we explicitly do not retry here, so that we can detect VINTF
53 // or other bugs (b/151696835)
54 continue;
55 }
56 if (func(mwd)) return true;
57 }
58 return false;
59 }
60
61 struct AidlName {
62 std::string package;
63 std::string iface;
64 std::string instance;
65
fillandroid::AidlName66 static bool fill(const std::string& name, AidlName* aname) {
67 size_t firstSlash = name.find('/');
68 size_t lastDot = name.rfind('.', firstSlash);
69 if (firstSlash == std::string::npos || lastDot == std::string::npos) {
70 LOG(ERROR) << "VINTF HALs require names in the format type/instance (e.g. "
71 << "some.package.foo.IFoo/default) but got: " << name;
72 return false;
73 }
74 aname->package = name.substr(0, lastDot);
75 aname->iface = name.substr(lastDot + 1, firstSlash - lastDot - 1);
76 aname->instance = name.substr(firstSlash + 1);
77 return true;
78 }
79 };
80
isVintfDeclared(const std::string & name)81 static bool isVintfDeclared(const std::string& name) {
82 AidlName aname;
83 if (!AidlName::fill(name, &aname)) return false;
84
85 bool found = forEachManifest([&](const ManifestWithDescription& mwd) {
86 if (mwd.manifest->hasAidlInstance(aname.package, aname.iface, aname.instance)) {
87 LOG(INFO) << "Found " << name << " in " << mwd.description << " VINTF manifest.";
88 return true; // break
89 }
90 return false; // continue
91 });
92
93 if (!found) {
94 // Although it is tested, explicitly rebuilding qualified name, in case it
95 // becomes something unexpected.
96 LOG(ERROR) << "Could not find " << aname.package << "." << aname.iface << "/"
97 << aname.instance << " in the VINTF manifest.";
98 }
99
100 return found;
101 }
102
getVintfUpdatableApex(const std::string & name)103 static std::optional<std::string> getVintfUpdatableApex(const std::string& name) {
104 AidlName aname;
105 if (!AidlName::fill(name, &aname)) return std::nullopt;
106
107 std::optional<std::string> updatableViaApex;
108
109 forEachManifest([&](const ManifestWithDescription& mwd) {
110 mwd.manifest->forEachInstance([&](const auto& manifestInstance) {
111 if (manifestInstance.format() != vintf::HalFormat::AIDL) return true;
112 if (manifestInstance.package() != aname.package) return true;
113 if (manifestInstance.interface() != aname.iface) return true;
114 if (manifestInstance.instance() != aname.instance) return true;
115 updatableViaApex = manifestInstance.updatableViaApex();
116 return false; // break (libvintf uses opposite convention)
117 });
118 return false; // continue
119 });
120
121 return updatableViaApex;
122 }
123
getVintfInstances(const std::string & interface)124 static std::vector<std::string> getVintfInstances(const std::string& interface) {
125 size_t lastDot = interface.rfind('.');
126 if (lastDot == std::string::npos) {
127 LOG(ERROR) << "VINTF interfaces require names in Java package format (e.g. some.package.foo.IFoo) but got: " << interface;
128 return {};
129 }
130 const std::string package = interface.substr(0, lastDot);
131 const std::string iface = interface.substr(lastDot+1);
132
133 std::vector<std::string> ret;
134 (void)forEachManifest([&](const ManifestWithDescription& mwd) {
135 auto instances = mwd.manifest->getAidlInstances(package, iface);
136 ret.insert(ret.end(), instances.begin(), instances.end());
137 return false; // continue
138 });
139
140 return ret;
141 }
142
meetsDeclarationRequirements(const sp<IBinder> & binder,const std::string & name)143 static bool meetsDeclarationRequirements(const sp<IBinder>& binder, const std::string& name) {
144 if (!Stability::requiresVintfDeclaration(binder)) {
145 return true;
146 }
147
148 return isVintfDeclared(name);
149 }
150 #endif // !VENDORSERVICEMANAGER
151
ServiceManager(std::unique_ptr<Access> && access)152 ServiceManager::ServiceManager(std::unique_ptr<Access>&& access) : mAccess(std::move(access)) {
153 // TODO(b/151696835): reenable performance hack when we solve bug, since with
154 // this hack and other fixes, it is unlikely we will see even an ephemeral
155 // failure when the manifest parse fails. The goal is that the manifest will
156 // be read incorrectly and cause the process trying to register a HAL to
157 // fail. If this is in fact an early boot kernel contention issue, then we
158 // will get no failure, and by its absence, be signalled to invest more
159 // effort in re-adding this performance hack.
160 // #ifndef VENDORSERVICEMANAGER
161 // // can process these at any times, don't want to delay first VINTF client
162 // std::thread([] {
163 // vintf::VintfObject::GetDeviceHalManifest();
164 // vintf::VintfObject::GetFrameworkHalManifest();
165 // }).detach();
166 // #endif // !VENDORSERVICEMANAGER
167 }
~ServiceManager()168 ServiceManager::~ServiceManager() {
169 // this should only happen in tests
170
171 for (const auto& [name, callbacks] : mNameToRegistrationCallback) {
172 CHECK(!callbacks.empty()) << name;
173 for (const auto& callback : callbacks) {
174 CHECK(callback != nullptr) << name;
175 }
176 }
177
178 for (const auto& [name, service] : mNameToService) {
179 CHECK(service.binder != nullptr) << name;
180 }
181 }
182
getService(const std::string & name,sp<IBinder> * outBinder)183 Status ServiceManager::getService(const std::string& name, sp<IBinder>* outBinder) {
184 *outBinder = tryGetService(name, true);
185 // returns ok regardless of result for legacy reasons
186 return Status::ok();
187 }
188
checkService(const std::string & name,sp<IBinder> * outBinder)189 Status ServiceManager::checkService(const std::string& name, sp<IBinder>* outBinder) {
190 *outBinder = tryGetService(name, false);
191 // returns ok regardless of result for legacy reasons
192 return Status::ok();
193 }
194
tryGetService(const std::string & name,bool startIfNotFound)195 sp<IBinder> ServiceManager::tryGetService(const std::string& name, bool startIfNotFound) {
196 auto ctx = mAccess->getCallingContext();
197
198 sp<IBinder> out;
199 Service* service = nullptr;
200 if (auto it = mNameToService.find(name); it != mNameToService.end()) {
201 service = &(it->second);
202
203 if (!service->allowIsolated) {
204 uid_t appid = multiuser_get_app_id(ctx.uid);
205 bool isIsolated = appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END;
206
207 if (isIsolated) {
208 return nullptr;
209 }
210 }
211 out = service->binder;
212 }
213
214 if (!mAccess->canFind(ctx, name)) {
215 return nullptr;
216 }
217
218 if (!out && startIfNotFound) {
219 tryStartService(name);
220 }
221
222 if (out) {
223 // Setting this guarantee each time we hand out a binder ensures that the client-checking
224 // loop knows about the event even if the client immediately drops the service
225 service->guaranteeClient = true;
226 }
227
228 return out;
229 }
230
isValidServiceName(const std::string & name)231 bool isValidServiceName(const std::string& name) {
232 if (name.size() == 0) return false;
233 if (name.size() > 127) return false;
234
235 for (char c : name) {
236 if (c == '_' || c == '-' || c == '.' || c == '/') continue;
237 if (c >= 'a' && c <= 'z') continue;
238 if (c >= 'A' && c <= 'Z') continue;
239 if (c >= '0' && c <= '9') continue;
240 return false;
241 }
242
243 return true;
244 }
245
addService(const std::string & name,const sp<IBinder> & binder,bool allowIsolated,int32_t dumpPriority)246 Status ServiceManager::addService(const std::string& name, const sp<IBinder>& binder, bool allowIsolated, int32_t dumpPriority) {
247 auto ctx = mAccess->getCallingContext();
248
249 // apps cannot add services
250 if (multiuser_get_app_id(ctx.uid) >= AID_APP) {
251 return Status::fromExceptionCode(Status::EX_SECURITY);
252 }
253
254 if (!mAccess->canAdd(ctx, name)) {
255 return Status::fromExceptionCode(Status::EX_SECURITY);
256 }
257
258 if (binder == nullptr) {
259 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
260 }
261
262 if (!isValidServiceName(name)) {
263 LOG(ERROR) << "Invalid service name: " << name;
264 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
265 }
266
267 #ifndef VENDORSERVICEMANAGER
268 if (!meetsDeclarationRequirements(binder, name)) {
269 // already logged
270 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
271 }
272 #endif // !VENDORSERVICEMANAGER
273
274 // implicitly unlinked when the binder is removed
275 if (binder->remoteBinder() != nullptr &&
276 binder->linkToDeath(sp<ServiceManager>::fromExisting(this)) != OK) {
277 LOG(ERROR) << "Could not linkToDeath when adding " << name;
278 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
279 }
280
281 // Overwrite the old service if it exists
282 mNameToService[name] = Service {
283 .binder = binder,
284 .allowIsolated = allowIsolated,
285 .dumpPriority = dumpPriority,
286 .debugPid = ctx.debugPid,
287 };
288
289 auto it = mNameToRegistrationCallback.find(name);
290 if (it != mNameToRegistrationCallback.end()) {
291 for (const sp<IServiceCallback>& cb : it->second) {
292 mNameToService[name].guaranteeClient = true;
293 // permission checked in registerForNotifications
294 cb->onRegistration(name, binder);
295 }
296 }
297
298 return Status::ok();
299 }
300
listServices(int32_t dumpPriority,std::vector<std::string> * outList)301 Status ServiceManager::listServices(int32_t dumpPriority, std::vector<std::string>* outList) {
302 if (!mAccess->canList(mAccess->getCallingContext())) {
303 return Status::fromExceptionCode(Status::EX_SECURITY);
304 }
305
306 size_t toReserve = 0;
307 for (auto const& [name, service] : mNameToService) {
308 (void) name;
309
310 if (service.dumpPriority & dumpPriority) ++toReserve;
311 }
312
313 CHECK(outList->empty());
314
315 outList->reserve(toReserve);
316 for (auto const& [name, service] : mNameToService) {
317 (void) service;
318
319 if (service.dumpPriority & dumpPriority) {
320 outList->push_back(name);
321 }
322 }
323
324 return Status::ok();
325 }
326
registerForNotifications(const std::string & name,const sp<IServiceCallback> & callback)327 Status ServiceManager::registerForNotifications(
328 const std::string& name, const sp<IServiceCallback>& callback) {
329 auto ctx = mAccess->getCallingContext();
330
331 if (!mAccess->canFind(ctx, name)) {
332 return Status::fromExceptionCode(Status::EX_SECURITY);
333 }
334
335 if (!isValidServiceName(name)) {
336 LOG(ERROR) << "Invalid service name: " << name;
337 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
338 }
339
340 if (callback == nullptr) {
341 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
342 }
343
344 if (OK !=
345 IInterface::asBinder(callback)->linkToDeath(
346 sp<ServiceManager>::fromExisting(this))) {
347 LOG(ERROR) << "Could not linkToDeath when adding " << name;
348 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
349 }
350
351 mNameToRegistrationCallback[name].push_back(callback);
352
353 if (auto it = mNameToService.find(name); it != mNameToService.end()) {
354 const sp<IBinder>& binder = it->second.binder;
355
356 // never null if an entry exists
357 CHECK(binder != nullptr) << name;
358 callback->onRegistration(name, binder);
359 }
360
361 return Status::ok();
362 }
unregisterForNotifications(const std::string & name,const sp<IServiceCallback> & callback)363 Status ServiceManager::unregisterForNotifications(
364 const std::string& name, const sp<IServiceCallback>& callback) {
365 auto ctx = mAccess->getCallingContext();
366
367 if (!mAccess->canFind(ctx, name)) {
368 return Status::fromExceptionCode(Status::EX_SECURITY);
369 }
370
371 bool found = false;
372
373 auto it = mNameToRegistrationCallback.find(name);
374 if (it != mNameToRegistrationCallback.end()) {
375 removeRegistrationCallback(IInterface::asBinder(callback), &it, &found);
376 }
377
378 if (!found) {
379 LOG(ERROR) << "Trying to unregister callback, but none exists " << name;
380 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
381 }
382
383 return Status::ok();
384 }
385
isDeclared(const std::string & name,bool * outReturn)386 Status ServiceManager::isDeclared(const std::string& name, bool* outReturn) {
387 auto ctx = mAccess->getCallingContext();
388
389 if (!mAccess->canFind(ctx, name)) {
390 return Status::fromExceptionCode(Status::EX_SECURITY);
391 }
392
393 *outReturn = false;
394
395 #ifndef VENDORSERVICEMANAGER
396 *outReturn = isVintfDeclared(name);
397 #endif
398 return Status::ok();
399 }
400
getDeclaredInstances(const std::string & interface,std::vector<std::string> * outReturn)401 binder::Status ServiceManager::getDeclaredInstances(const std::string& interface, std::vector<std::string>* outReturn) {
402 auto ctx = mAccess->getCallingContext();
403
404 std::vector<std::string> allInstances;
405 #ifndef VENDORSERVICEMANAGER
406 allInstances = getVintfInstances(interface);
407 #endif
408
409 outReturn->clear();
410
411 for (const std::string& instance : allInstances) {
412 if (mAccess->canFind(ctx, interface + "/" + instance)) {
413 outReturn->push_back(instance);
414 }
415 }
416
417 if (outReturn->size() == 0 && allInstances.size() != 0) {
418 return Status::fromExceptionCode(Status::EX_SECURITY);
419 }
420
421 return Status::ok();
422 }
423
updatableViaApex(const std::string & name,std::optional<std::string> * outReturn)424 Status ServiceManager::updatableViaApex(const std::string& name,
425 std::optional<std::string>* outReturn) {
426 auto ctx = mAccess->getCallingContext();
427
428 if (!mAccess->canFind(ctx, name)) {
429 return Status::fromExceptionCode(Status::EX_SECURITY);
430 }
431
432 *outReturn = std::nullopt;
433
434 #ifndef VENDORSERVICEMANAGER
435 *outReturn = getVintfUpdatableApex(name);
436 #endif
437 return Status::ok();
438 }
439
removeRegistrationCallback(const wp<IBinder> & who,ServiceCallbackMap::iterator * it,bool * found)440 void ServiceManager::removeRegistrationCallback(const wp<IBinder>& who,
441 ServiceCallbackMap::iterator* it,
442 bool* found) {
443 std::vector<sp<IServiceCallback>>& listeners = (*it)->second;
444
445 for (auto lit = listeners.begin(); lit != listeners.end();) {
446 if (IInterface::asBinder(*lit) == who) {
447 if(found) *found = true;
448 lit = listeners.erase(lit);
449 } else {
450 ++lit;
451 }
452 }
453
454 if (listeners.empty()) {
455 *it = mNameToRegistrationCallback.erase(*it);
456 } else {
457 (*it)++;
458 }
459 }
460
binderDied(const wp<IBinder> & who)461 void ServiceManager::binderDied(const wp<IBinder>& who) {
462 for (auto it = mNameToService.begin(); it != mNameToService.end();) {
463 if (who == it->second.binder) {
464 it = mNameToService.erase(it);
465 } else {
466 ++it;
467 }
468 }
469
470 for (auto it = mNameToRegistrationCallback.begin(); it != mNameToRegistrationCallback.end();) {
471 removeRegistrationCallback(who, &it, nullptr /*found*/);
472 }
473
474 for (auto it = mNameToClientCallback.begin(); it != mNameToClientCallback.end();) {
475 removeClientCallback(who, &it);
476 }
477 }
478
tryStartService(const std::string & name)479 void ServiceManager::tryStartService(const std::string& name) {
480 ALOGI("Since '%s' could not be found, trying to start it as a lazy AIDL service",
481 name.c_str());
482
483 std::thread([=] {
484 if (!base::SetProperty("ctl.interface_start", "aidl/" + name)) {
485 LOG(INFO) << "Tried to start aidl service " << name
486 << " as a lazy service, but was unable to. Usually this happens when a "
487 "service is not installed, but if the service is intended to be used as a "
488 "lazy service, then it may be configured incorrectly.";
489 }
490 }).detach();
491 }
492
registerClientCallback(const std::string & name,const sp<IBinder> & service,const sp<IClientCallback> & cb)493 Status ServiceManager::registerClientCallback(const std::string& name, const sp<IBinder>& service,
494 const sp<IClientCallback>& cb) {
495 if (cb == nullptr) {
496 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
497 }
498
499 auto ctx = mAccess->getCallingContext();
500 if (!mAccess->canAdd(ctx, name)) {
501 return Status::fromExceptionCode(Status::EX_SECURITY);
502 }
503
504 auto serviceIt = mNameToService.find(name);
505 if (serviceIt == mNameToService.end()) {
506 LOG(ERROR) << "Could not add callback for nonexistent service: " << name;
507 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
508 }
509
510 if (serviceIt->second.debugPid != IPCThreadState::self()->getCallingPid()) {
511 LOG(WARNING) << "Only a server can register for client callbacks (for " << name << ")";
512 return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION);
513 }
514
515 if (serviceIt->second.binder != service) {
516 LOG(WARNING) << "Tried to register client callback for " << name
517 << " but a different service is registered under this name.";
518 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
519 }
520
521 if (OK !=
522 IInterface::asBinder(cb)->linkToDeath(sp<ServiceManager>::fromExisting(this))) {
523 LOG(ERROR) << "Could not linkToDeath when adding client callback for " << name;
524 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
525 }
526
527 mNameToClientCallback[name].push_back(cb);
528
529 return Status::ok();
530 }
531
removeClientCallback(const wp<IBinder> & who,ClientCallbackMap::iterator * it)532 void ServiceManager::removeClientCallback(const wp<IBinder>& who,
533 ClientCallbackMap::iterator* it) {
534 std::vector<sp<IClientCallback>>& listeners = (*it)->second;
535
536 for (auto lit = listeners.begin(); lit != listeners.end();) {
537 if (IInterface::asBinder(*lit) == who) {
538 lit = listeners.erase(lit);
539 } else {
540 ++lit;
541 }
542 }
543
544 if (listeners.empty()) {
545 *it = mNameToClientCallback.erase(*it);
546 } else {
547 (*it)++;
548 }
549 }
550
getNodeStrongRefCount()551 ssize_t ServiceManager::Service::getNodeStrongRefCount() {
552 sp<BpBinder> bpBinder = sp<BpBinder>::fromExisting(binder->remoteBinder());
553 if (bpBinder == nullptr) return -1;
554
555 return ProcessState::self()->getStrongRefCountForNode(bpBinder);
556 }
557
handleClientCallbacks()558 void ServiceManager::handleClientCallbacks() {
559 for (const auto& [name, service] : mNameToService) {
560 handleServiceClientCallback(name, true);
561 }
562 }
563
handleServiceClientCallback(const std::string & serviceName,bool isCalledOnInterval)564 ssize_t ServiceManager::handleServiceClientCallback(const std::string& serviceName,
565 bool isCalledOnInterval) {
566 auto serviceIt = mNameToService.find(serviceName);
567 if (serviceIt == mNameToService.end() || mNameToClientCallback.count(serviceName) < 1) {
568 return -1;
569 }
570
571 Service& service = serviceIt->second;
572 ssize_t count = service.getNodeStrongRefCount();
573
574 // binder driver doesn't support this feature
575 if (count == -1) return count;
576
577 bool hasClients = count > 1; // this process holds a strong count
578
579 if (service.guaranteeClient) {
580 // we have no record of this client
581 if (!service.hasClients && !hasClients) {
582 sendClientCallbackNotifications(serviceName, true);
583 }
584
585 // guarantee is temporary
586 service.guaranteeClient = false;
587 }
588
589 // only send notifications if this was called via the interval checking workflow
590 if (isCalledOnInterval) {
591 if (hasClients && !service.hasClients) {
592 // client was retrieved in some other way
593 sendClientCallbackNotifications(serviceName, true);
594 }
595
596 // there are no more clients, but the callback has not been called yet
597 if (!hasClients && service.hasClients) {
598 sendClientCallbackNotifications(serviceName, false);
599 }
600 }
601
602 return count;
603 }
604
sendClientCallbackNotifications(const std::string & serviceName,bool hasClients)605 void ServiceManager::sendClientCallbackNotifications(const std::string& serviceName, bool hasClients) {
606 auto serviceIt = mNameToService.find(serviceName);
607 if (serviceIt == mNameToService.end()) {
608 LOG(WARNING) << "sendClientCallbackNotifications could not find service " << serviceName;
609 return;
610 }
611 Service& service = serviceIt->second;
612
613 CHECK(hasClients != service.hasClients) << "Record shows: " << service.hasClients
614 << " so we can't tell clients again that we have client: " << hasClients;
615
616 LOG(INFO) << "Notifying " << serviceName << " they have clients: " << hasClients;
617
618 auto ccIt = mNameToClientCallback.find(serviceName);
619 CHECK(ccIt != mNameToClientCallback.end())
620 << "sendClientCallbackNotifications could not find callbacks for service ";
621
622 for (const auto& callback : ccIt->second) {
623 callback->onClients(service.binder, hasClients);
624 }
625
626 service.hasClients = hasClients;
627 }
628
tryUnregisterService(const std::string & name,const sp<IBinder> & binder)629 Status ServiceManager::tryUnregisterService(const std::string& name, const sp<IBinder>& binder) {
630 if (binder == nullptr) {
631 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
632 }
633
634 auto ctx = mAccess->getCallingContext();
635 if (!mAccess->canAdd(ctx, name)) {
636 return Status::fromExceptionCode(Status::EX_SECURITY);
637 }
638
639 auto serviceIt = mNameToService.find(name);
640 if (serviceIt == mNameToService.end()) {
641 LOG(WARNING) << "Tried to unregister " << name
642 << ", but that service wasn't registered to begin with.";
643 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
644 }
645
646 if (serviceIt->second.debugPid != IPCThreadState::self()->getCallingPid()) {
647 LOG(WARNING) << "Only a server can unregister itself (for " << name << ")";
648 return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION);
649 }
650
651 sp<IBinder> storedBinder = serviceIt->second.binder;
652
653 if (binder != storedBinder) {
654 LOG(WARNING) << "Tried to unregister " << name
655 << ", but a different service is registered under this name.";
656 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
657 }
658
659 if (serviceIt->second.guaranteeClient) {
660 LOG(INFO) << "Tried to unregister " << name << ", but there is about to be a client.";
661 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
662 }
663
664 int clients = handleServiceClientCallback(name, false);
665
666 // clients < 0: feature not implemented or other error. Assume clients.
667 // Otherwise:
668 // - kernel driver will hold onto one refcount (during this transaction)
669 // - servicemanager has a refcount (guaranteed by this transaction)
670 // So, if clients > 2, then at least one other service on the system must hold a refcount.
671 if (clients < 0 || clients > 2) {
672 // client callbacks are either disabled or there are other clients
673 LOG(INFO) << "Tried to unregister " << name << ", but there are clients: " << clients;
674 // Set this flag to ensure the clients are acknowledged in the next callback
675 serviceIt->second.guaranteeClient = true;
676 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
677 }
678
679 mNameToService.erase(name);
680
681 return Status::ok();
682 }
683
getServiceDebugInfo(std::vector<ServiceDebugInfo> * outReturn)684 Status ServiceManager::getServiceDebugInfo(std::vector<ServiceDebugInfo>* outReturn) {
685 if (!mAccess->canList(mAccess->getCallingContext())) {
686 return Status::fromExceptionCode(Status::EX_SECURITY);
687 }
688
689 outReturn->reserve(mNameToService.size());
690 for (auto const& [name, service] : mNameToService) {
691 ServiceDebugInfo info;
692 info.name = name;
693 info.debugPid = service.debugPid;
694
695 outReturn->push_back(std::move(info));
696 }
697
698 return Status::ok();
699 }
700
701 } // namespace android
702