blob: 4e6f60735057d8533745e2f0312dd0275846567b [file] [log] [blame]
Steven Moreland80e1e6d2019-06-21 12:35:59 -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
17#include "ServiceManager.h"
18
19#include <android-base/logging.h>
Jon Spivack0d844302019-07-22 18:40:34 -070020#include <android-base/properties.h>
Jon Spivack9f503a42019-10-22 16:49:19 -070021#include <binder/BpBinder.h>
22#include <binder/IPCThreadState.h>
23#include <binder/ProcessState.h>
Steven Moreland86a17f82019-09-10 10:18:00 -070024#include <binder/Stability.h>
Steven Moreland80e1e6d2019-06-21 12:35:59 -070025#include <cutils/android_filesystem_config.h>
26#include <cutils/multiuser.h>
Jon Spivack0d844302019-07-22 18:40:34 -070027#include <thread>
Steven Moreland80e1e6d2019-06-21 12:35:59 -070028
Steven Moreland86a17f82019-09-10 10:18:00 -070029#ifndef VENDORSERVICEMANAGER
30#include <vintf/VintfObject.h>
31#include <vintf/constants.h>
32#endif // !VENDORSERVICEMANAGER
33
Steven Moreland80e1e6d2019-06-21 12:35:59 -070034using ::android::binder::Status;
Steven Moreland86a17f82019-09-10 10:18:00 -070035using ::android::internal::Stability;
Steven Moreland80e1e6d2019-06-21 12:35:59 -070036
37namespace android {
38
Steven Moreland86a17f82019-09-10 10:18:00 -070039#ifndef VENDORSERVICEMANAGER
Steven Morelandb82b8f82019-10-28 10:52:34 -070040static bool isVintfDeclared(const std::string& name) {
Steven Moreland86a17f82019-09-10 10:18:00 -070041 size_t firstSlash = name.find('/');
42 size_t lastDot = name.rfind('.', firstSlash);
43 if (firstSlash == std::string::npos || lastDot == std::string::npos) {
44 LOG(ERROR) << "VINTF HALs require names in the format type/instance (e.g. "
45 << "some.package.foo.IFoo/default) but got: " << name;
46 return false;
47 }
48 const std::string package = name.substr(0, lastDot);
49 const std::string iface = name.substr(lastDot+1, firstSlash-lastDot-1);
50 const std::string instance = name.substr(firstSlash+1);
51
52 for (const auto& manifest : {
53 vintf::VintfObject::GetDeviceHalManifest(),
54 vintf::VintfObject::GetFrameworkHalManifest()
55 }) {
Steven Moreland97d1d452019-11-01 10:08:34 -070056 if (manifest != nullptr && manifest->hasAidlInstance(package, iface, instance)) {
Steven Moreland86a17f82019-09-10 10:18:00 -070057 return true;
58 }
59 }
60 LOG(ERROR) << "Could not find " << package << "." << iface << "/" << instance
61 << " in the VINTF manifest.";
62 return false;
63}
Steven Morelandb82b8f82019-10-28 10:52:34 -070064
65static bool meetsDeclarationRequirements(const sp<IBinder>& binder, const std::string& name) {
66 if (!Stability::requiresVintfDeclaration(binder)) {
67 return true;
68 }
69
70 return isVintfDeclared(name);
71}
Steven Moreland86a17f82019-09-10 10:18:00 -070072#endif // !VENDORSERVICEMANAGER
73
Steven Morelandd13f08b2019-11-18 14:23:09 -080074ServiceManager::ServiceManager(std::unique_ptr<Access>&& access) : mAccess(std::move(access)) {
Steven Moreland8d0c9a72020-04-30 16:51:56 -070075// TODO(b/151696835): reenable performance hack when we solve bug, since with
76// this hack and other fixes, it is unlikely we will see even an ephemeral
77// failure when the manifest parse fails. The goal is that the manifest will
78// be read incorrectly and cause the process trying to register a HAL to
79// fail. If this is in fact an early boot kernel contention issue, then we
80// will get no failure, and by its absence, be signalled to invest more
81// effort in re-adding this performance hack.
82// #ifndef VENDORSERVICEMANAGER
83// // can process these at any times, don't want to delay first VINTF client
84// std::thread([] {
85// vintf::VintfObject::GetDeviceHalManifest();
86// vintf::VintfObject::GetFrameworkHalManifest();
87// }).detach();
88// #endif // !VENDORSERVICEMANAGER
Steven Morelandd13f08b2019-11-18 14:23:09 -080089}
Steven Moreland130242d2019-08-26 17:41:32 -070090ServiceManager::~ServiceManager() {
91 // this should only happen in tests
92
Jon Spivackf288b1d2019-12-19 17:15:51 -080093 for (const auto& [name, callbacks] : mNameToRegistrationCallback) {
Steven Moreland27cfab02019-08-12 14:34:16 -070094 CHECK(!callbacks.empty()) << name;
95 for (const auto& callback : callbacks) {
96 CHECK(callback != nullptr) << name;
97 }
98 }
99
Steven Moreland130242d2019-08-26 17:41:32 -0700100 for (const auto& [name, service] : mNameToService) {
101 CHECK(service.binder != nullptr) << name;
102 }
103}
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700104
105Status ServiceManager::getService(const std::string& name, sp<IBinder>* outBinder) {
Jon Spivack0d844302019-07-22 18:40:34 -0700106 *outBinder = tryGetService(name, true);
107 // returns ok regardless of result for legacy reasons
108 return Status::ok();
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700109}
110
111Status ServiceManager::checkService(const std::string& name, sp<IBinder>* outBinder) {
Jon Spivack0d844302019-07-22 18:40:34 -0700112 *outBinder = tryGetService(name, false);
113 // returns ok regardless of result for legacy reasons
114 return Status::ok();
115}
116
117sp<IBinder> ServiceManager::tryGetService(const std::string& name, bool startIfNotFound) {
Steven Morelanda9fe4742019-07-18 14:45:20 -0700118 auto ctx = mAccess->getCallingContext();
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700119
Jon Spivack0d844302019-07-22 18:40:34 -0700120 sp<IBinder> out;
Jon Spivack9f503a42019-10-22 16:49:19 -0700121 Service* service = nullptr;
Jon Spivack0d844302019-07-22 18:40:34 -0700122 if (auto it = mNameToService.find(name); it != mNameToService.end()) {
Jon Spivack9f503a42019-10-22 16:49:19 -0700123 service = &(it->second);
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700124
Jon Spivack9f503a42019-10-22 16:49:19 -0700125 if (!service->allowIsolated) {
Jon Spivack0d844302019-07-22 18:40:34 -0700126 uid_t appid = multiuser_get_app_id(ctx.uid);
127 bool isIsolated = appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END;
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700128
Jon Spivack0d844302019-07-22 18:40:34 -0700129 if (isIsolated) {
130 return nullptr;
131 }
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700132 }
Jon Spivack9f503a42019-10-22 16:49:19 -0700133 out = service->binder;
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700134 }
135
Steven Morelanda9fe4742019-07-18 14:45:20 -0700136 if (!mAccess->canFind(ctx, name)) {
Jon Spivack0d844302019-07-22 18:40:34 -0700137 return nullptr;
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700138 }
139
Jon Spivack0d844302019-07-22 18:40:34 -0700140 if (!out && startIfNotFound) {
141 tryStartService(name);
142 }
143
Jon Spivack9f503a42019-10-22 16:49:19 -0700144 if (out) {
145 // Setting this guarantee each time we hand out a binder ensures that the client-checking
146 // loop knows about the event even if the client immediately drops the service
147 service->guaranteeClient = true;
148 }
149
Jon Spivack0d844302019-07-22 18:40:34 -0700150 return out;
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700151}
152
Steven Moreland905e2e82019-07-17 11:05:45 -0700153bool isValidServiceName(const std::string& name) {
154 if (name.size() == 0) return false;
155 if (name.size() > 127) return false;
156
157 for (char c : name) {
Steven Morelandbb7951d2019-08-20 16:58:25 -0700158 if (c == '_' || c == '-' || c == '.' || c == '/') continue;
Steven Moreland905e2e82019-07-17 11:05:45 -0700159 if (c >= 'a' && c <= 'z') continue;
160 if (c >= 'A' && c <= 'Z') continue;
161 if (c >= '0' && c <= '9') continue;
162 return false;
163 }
164
165 return true;
166}
167
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700168Status ServiceManager::addService(const std::string& name, const sp<IBinder>& binder, bool allowIsolated, int32_t dumpPriority) {
Steven Morelanda9fe4742019-07-18 14:45:20 -0700169 auto ctx = mAccess->getCallingContext();
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700170
171 // apps cannot add services
172 if (multiuser_get_app_id(ctx.uid) >= AID_APP) {
173 return Status::fromExceptionCode(Status::EX_SECURITY);
174 }
175
Steven Morelanda9fe4742019-07-18 14:45:20 -0700176 if (!mAccess->canAdd(ctx, name)) {
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700177 return Status::fromExceptionCode(Status::EX_SECURITY);
178 }
179
180 if (binder == nullptr) {
181 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
182 }
183
Steven Moreland905e2e82019-07-17 11:05:45 -0700184 if (!isValidServiceName(name)) {
185 LOG(ERROR) << "Invalid service name: " << name;
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700186 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
187 }
188
Steven Moreland86a17f82019-09-10 10:18:00 -0700189#ifndef VENDORSERVICEMANAGER
190 if (!meetsDeclarationRequirements(binder, name)) {
191 // already logged
192 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
193 }
194#endif // !VENDORSERVICEMANAGER
195
Steven Moreland88860b02019-08-12 14:24:14 -0700196 // implicitly unlinked when the binder is removed
Steven Moreland46f380b2019-10-16 16:28:21 -0700197 if (binder->remoteBinder() != nullptr && binder->linkToDeath(this) != OK) {
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700198 LOG(ERROR) << "Could not linkToDeath when adding " << name;
199 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
200 }
201
Jon Spivack9f503a42019-10-22 16:49:19 -0700202 auto entry = mNameToService.emplace(name, Service {
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700203 .binder = binder,
204 .allowIsolated = allowIsolated,
205 .dumpPriority = dumpPriority,
Jon Spivack9f503a42019-10-22 16:49:19 -0700206 .debugPid = ctx.debugPid,
207 });
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700208
Jon Spivackf288b1d2019-12-19 17:15:51 -0800209 auto it = mNameToRegistrationCallback.find(name);
210 if (it != mNameToRegistrationCallback.end()) {
Steven Moreland27cfab02019-08-12 14:34:16 -0700211 for (const sp<IServiceCallback>& cb : it->second) {
Jon Spivack9f503a42019-10-22 16:49:19 -0700212 entry.first->second.guaranteeClient = true;
Steven Moreland27cfab02019-08-12 14:34:16 -0700213 // permission checked in registerForNotifications
214 cb->onRegistration(name, binder);
215 }
216 }
217
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700218 return Status::ok();
219}
220
221Status ServiceManager::listServices(int32_t dumpPriority, std::vector<std::string>* outList) {
Steven Morelanda9fe4742019-07-18 14:45:20 -0700222 if (!mAccess->canList(mAccess->getCallingContext())) {
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700223 return Status::fromExceptionCode(Status::EX_SECURITY);
224 }
225
226 size_t toReserve = 0;
227 for (auto const& [name, service] : mNameToService) {
228 (void) name;
229
230 if (service.dumpPriority & dumpPriority) ++toReserve;
231 }
232
233 CHECK(outList->empty());
234
235 outList->reserve(toReserve);
236 for (auto const& [name, service] : mNameToService) {
237 (void) service;
238
239 if (service.dumpPriority & dumpPriority) {
240 outList->push_back(name);
241 }
242 }
243
244 return Status::ok();
245}
246
Steven Moreland27cfab02019-08-12 14:34:16 -0700247Status ServiceManager::registerForNotifications(
248 const std::string& name, const sp<IServiceCallback>& callback) {
249 auto ctx = mAccess->getCallingContext();
250
251 if (!mAccess->canFind(ctx, name)) {
252 return Status::fromExceptionCode(Status::EX_SECURITY);
253 }
254
255 if (!isValidServiceName(name)) {
256 LOG(ERROR) << "Invalid service name: " << name;
257 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
258 }
259
260 if (callback == nullptr) {
261 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
262 }
263
264 if (OK != IInterface::asBinder(callback)->linkToDeath(this)) {
265 LOG(ERROR) << "Could not linkToDeath when adding " << name;
266 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
267 }
268
Jon Spivackf288b1d2019-12-19 17:15:51 -0800269 mNameToRegistrationCallback[name].push_back(callback);
Steven Moreland27cfab02019-08-12 14:34:16 -0700270
271 if (auto it = mNameToService.find(name); it != mNameToService.end()) {
272 const sp<IBinder>& binder = it->second.binder;
273
274 // never null if an entry exists
275 CHECK(binder != nullptr) << name;
276 callback->onRegistration(name, binder);
277 }
278
279 return Status::ok();
280}
281Status ServiceManager::unregisterForNotifications(
282 const std::string& name, const sp<IServiceCallback>& callback) {
283 auto ctx = mAccess->getCallingContext();
284
285 if (!mAccess->canFind(ctx, name)) {
286 return Status::fromExceptionCode(Status::EX_SECURITY);
287 }
288
289 bool found = false;
290
Jon Spivackf288b1d2019-12-19 17:15:51 -0800291 auto it = mNameToRegistrationCallback.find(name);
292 if (it != mNameToRegistrationCallback.end()) {
293 removeRegistrationCallback(IInterface::asBinder(callback), &it, &found);
Steven Moreland27cfab02019-08-12 14:34:16 -0700294 }
295
296 if (!found) {
297 LOG(ERROR) << "Trying to unregister callback, but none exists " << name;
298 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
299 }
300
301 return Status::ok();
302}
303
Steven Morelandb82b8f82019-10-28 10:52:34 -0700304Status ServiceManager::isDeclared(const std::string& name, bool* outReturn) {
305 auto ctx = mAccess->getCallingContext();
306
307 if (!mAccess->canFind(ctx, name)) {
308 return Status::fromExceptionCode(Status::EX_SECURITY);
309 }
310
311 *outReturn = false;
312
313#ifndef VENDORSERVICEMANAGER
314 *outReturn = isVintfDeclared(name);
315#endif
316 return Status::ok();
317}
318
Jon Spivackf288b1d2019-12-19 17:15:51 -0800319void ServiceManager::removeRegistrationCallback(const wp<IBinder>& who,
320 ServiceCallbackMap::iterator* it,
Steven Moreland27cfab02019-08-12 14:34:16 -0700321 bool* found) {
322 std::vector<sp<IServiceCallback>>& listeners = (*it)->second;
323
324 for (auto lit = listeners.begin(); lit != listeners.end();) {
325 if (IInterface::asBinder(*lit) == who) {
326 if(found) *found = true;
327 lit = listeners.erase(lit);
328 } else {
329 ++lit;
330 }
331 }
332
333 if (listeners.empty()) {
Jon Spivackf288b1d2019-12-19 17:15:51 -0800334 *it = mNameToRegistrationCallback.erase(*it);
Steven Moreland27cfab02019-08-12 14:34:16 -0700335 } else {
Jon Spivacke223f082019-11-19 16:21:20 -0800336 (*it)++;
Steven Moreland27cfab02019-08-12 14:34:16 -0700337 }
338}
339
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700340void ServiceManager::binderDied(const wp<IBinder>& who) {
341 for (auto it = mNameToService.begin(); it != mNameToService.end();) {
342 if (who == it->second.binder) {
343 it = mNameToService.erase(it);
344 } else {
345 ++it;
346 }
347 }
Steven Moreland27cfab02019-08-12 14:34:16 -0700348
Jon Spivackf288b1d2019-12-19 17:15:51 -0800349 for (auto it = mNameToRegistrationCallback.begin(); it != mNameToRegistrationCallback.end();) {
350 removeRegistrationCallback(who, &it, nullptr /*found*/);
Steven Moreland27cfab02019-08-12 14:34:16 -0700351 }
Jon Spivack9f503a42019-10-22 16:49:19 -0700352
353 for (auto it = mNameToClientCallback.begin(); it != mNameToClientCallback.end();) {
354 removeClientCallback(who, &it);
355 }
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700356}
357
Jon Spivack0d844302019-07-22 18:40:34 -0700358void ServiceManager::tryStartService(const std::string& name) {
359 ALOGI("Since '%s' could not be found, trying to start it as a lazy AIDL service",
360 name.c_str());
361
362 std::thread([=] {
363 (void)base::SetProperty("ctl.interface_start", "aidl/" + name);
364 }).detach();
365}
366
Jon Spivack9f503a42019-10-22 16:49:19 -0700367Status ServiceManager::registerClientCallback(const std::string& name, const sp<IBinder>& service,
368 const sp<IClientCallback>& cb) {
369 if (cb == nullptr) {
370 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
371 }
372
373 auto ctx = mAccess->getCallingContext();
374 if (!mAccess->canAdd(ctx, name)) {
375 return Status::fromExceptionCode(Status::EX_SECURITY);
376 }
377
378 auto serviceIt = mNameToService.find(name);
379 if (serviceIt == mNameToService.end()) {
380 LOG(ERROR) << "Could not add callback for nonexistent service: " << name;
381 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
382 }
383
384 if (serviceIt->second.debugPid != IPCThreadState::self()->getCallingPid()) {
385 LOG(WARNING) << "Only a server can register for client callbacks (for " << name << ")";
386 return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION);
387 }
388
389 if (serviceIt->second.binder != service) {
390 LOG(WARNING) << "Tried to register client callback for " << name
391 << " but a different service is registered under this name.";
392 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
393 }
394
395 if (OK != IInterface::asBinder(cb)->linkToDeath(this)) {
396 LOG(ERROR) << "Could not linkToDeath when adding client callback for " << name;
397 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
398 }
399
400 mNameToClientCallback[name].push_back(cb);
401
402 return Status::ok();
403}
404
405void ServiceManager::removeClientCallback(const wp<IBinder>& who,
406 ClientCallbackMap::iterator* it) {
407 std::vector<sp<IClientCallback>>& listeners = (*it)->second;
408
409 for (auto lit = listeners.begin(); lit != listeners.end();) {
410 if (IInterface::asBinder(*lit) == who) {
411 lit = listeners.erase(lit);
412 } else {
413 ++lit;
414 }
415 }
416
417 if (listeners.empty()) {
418 *it = mNameToClientCallback.erase(*it);
419 } else {
420 (*it)++;
421 }
422}
423
424ssize_t ServiceManager::Service::getNodeStrongRefCount() {
425 sp<BpBinder> bpBinder = binder->remoteBinder();
426 if (bpBinder == nullptr) return -1;
427
428 return ProcessState::self()->getStrongRefCountForNodeByHandle(bpBinder->handle());
429}
430
431void ServiceManager::handleClientCallbacks() {
432 for (const auto& [name, service] : mNameToService) {
Jon Spivackd9533c22020-01-27 22:19:22 +0000433 handleServiceClientCallback(name, true);
Jon Spivack9f503a42019-10-22 16:49:19 -0700434 }
435}
436
Jon Spivackd9533c22020-01-27 22:19:22 +0000437ssize_t ServiceManager::handleServiceClientCallback(const std::string& serviceName,
438 bool isCalledOnInterval) {
Jon Spivack9f503a42019-10-22 16:49:19 -0700439 auto serviceIt = mNameToService.find(serviceName);
440 if (serviceIt == mNameToService.end() || mNameToClientCallback.count(serviceName) < 1) {
441 return -1;
442 }
443
444 Service& service = serviceIt->second;
445 ssize_t count = service.getNodeStrongRefCount();
446
447 // binder driver doesn't support this feature
448 if (count == -1) return count;
449
450 bool hasClients = count > 1; // this process holds a strong count
451
452 if (service.guaranteeClient) {
453 // we have no record of this client
454 if (!service.hasClients && !hasClients) {
455 sendClientCallbackNotifications(serviceName, true);
456 }
457
458 // guarantee is temporary
459 service.guaranteeClient = false;
460 }
461
Jon Spivackd9533c22020-01-27 22:19:22 +0000462 // only send notifications if this was called via the interval checking workflow
463 if (isCalledOnInterval) {
464 if (hasClients && !service.hasClients) {
465 // client was retrieved in some other way
466 sendClientCallbackNotifications(serviceName, true);
467 }
Jon Spivack9f503a42019-10-22 16:49:19 -0700468
Jon Spivackd9533c22020-01-27 22:19:22 +0000469 // there are no more clients, but the callback has not been called yet
470 if (!hasClients && service.hasClients) {
471 sendClientCallbackNotifications(serviceName, false);
472 }
Jon Spivack9f503a42019-10-22 16:49:19 -0700473 }
474
475 return count;
476}
477
478void ServiceManager::sendClientCallbackNotifications(const std::string& serviceName, bool hasClients) {
479 auto serviceIt = mNameToService.find(serviceName);
480 if (serviceIt == mNameToService.end()) {
481 LOG(WARNING) << "sendClientCallbackNotifications could not find service " << serviceName;
482 return;
483 }
484 Service& service = serviceIt->second;
485
486 CHECK(hasClients != service.hasClients) << "Record shows: " << service.hasClients
487 << " so we can't tell clients again that we have client: " << hasClients;
488
489 LOG(INFO) << "Notifying " << serviceName << " they have clients: " << hasClients;
490
491 auto ccIt = mNameToClientCallback.find(serviceName);
492 CHECK(ccIt != mNameToClientCallback.end())
493 << "sendClientCallbackNotifications could not find callbacks for service ";
494
495 for (const auto& callback : ccIt->second) {
496 callback->onClients(service.binder, hasClients);
497 }
498
499 service.hasClients = hasClients;
500}
501
502Status ServiceManager::tryUnregisterService(const std::string& name, const sp<IBinder>& binder) {
503 if (binder == nullptr) {
504 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
505 }
506
507 auto ctx = mAccess->getCallingContext();
508 if (!mAccess->canAdd(ctx, name)) {
509 return Status::fromExceptionCode(Status::EX_SECURITY);
510 }
511
512 auto serviceIt = mNameToService.find(name);
513 if (serviceIt == mNameToService.end()) {
514 LOG(WARNING) << "Tried to unregister " << name
515 << ", but that service wasn't registered to begin with.";
516 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
517 }
518
519 if (serviceIt->second.debugPid != IPCThreadState::self()->getCallingPid()) {
520 LOG(WARNING) << "Only a server can unregister itself (for " << name << ")";
521 return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION);
522 }
523
524 sp<IBinder> storedBinder = serviceIt->second.binder;
525
526 if (binder != storedBinder) {
527 LOG(WARNING) << "Tried to unregister " << name
528 << ", but a different service is registered under this name.";
529 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
530 }
531
Jon Spivack0f18f2c2020-03-13 20:45:18 -0700532 if (serviceIt->second.guaranteeClient) {
533 LOG(INFO) << "Tried to unregister " << name << ", but there is about to be a client.";
534 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
535 }
536
Jon Spivackd9533c22020-01-27 22:19:22 +0000537 int clients = handleServiceClientCallback(name, false);
Jon Spivack9f503a42019-10-22 16:49:19 -0700538
539 // clients < 0: feature not implemented or other error. Assume clients.
540 // Otherwise:
541 // - kernel driver will hold onto one refcount (during this transaction)
542 // - servicemanager has a refcount (guaranteed by this transaction)
543 // So, if clients > 2, then at least one other service on the system must hold a refcount.
544 if (clients < 0 || clients > 2) {
545 // client callbacks are either disabled or there are other clients
Jon Spivackd9533c22020-01-27 22:19:22 +0000546 LOG(INFO) << "Tried to unregister " << name << ", but there are clients: " << clients;
Jon Spivack620d2dc2020-03-06 13:58:01 -0800547 // Set this flag to ensure the clients are acknowledged in the next callback
548 serviceIt->second.guaranteeClient = true;
Jon Spivack9f503a42019-10-22 16:49:19 -0700549 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
550 }
551
552 mNameToService.erase(name);
553
554 return Status::ok();
555}
556
Steven Moreland8d0c9a72020-04-30 16:51:56 -0700557} // namespace android