blob: 90db5091e179dfbb28588e322df5c47f49dc3372 [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 Moreland2e293aa2020-09-23 00:25:16 +000040struct ManifestWithDescription {
41 std::shared_ptr<const vintf::HalManifest> manifest;
42 const char* description;
43};
44// func true -> stop search and forEachManifest will return true
45static 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
Steven Morelandedd4e072021-04-21 00:27:29 +000061struct AidlName {
62 std::string package;
63 std::string iface;
64 std::string instance;
Steven Moreland86a17f82019-09-10 10:18:00 -070065
Steven Morelandedd4e072021-04-21 00:27:29 +000066 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
81static 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)) {
Steven Moreland2edde8e2020-04-30 17:04:54 -070087 LOG(INFO) << "Found " << name << " in " << mwd.description << " VINTF manifest.";
Steven Morelandedd4e072021-04-21 00:27:29 +000088 return true; // break
Steven Moreland86a17f82019-09-10 10:18:00 -070089 }
Steven Moreland2e293aa2020-09-23 00:25:16 +000090 return false; // continue
91 });
92
93 if (!found) {
94 // Although it is tested, explicitly rebuilding qualified name, in case it
95 // becomes something unexpected.
Steven Morelandedd4e072021-04-21 00:27:29 +000096 LOG(ERROR) << "Could not find " << aname.package << "." << aname.iface << "/"
97 << aname.instance << " in the VINTF manifest.";
Steven Moreland86a17f82019-09-10 10:18:00 -070098 }
Steven Moreland2edde8e2020-04-30 17:04:54 -070099
Steven Moreland2e293aa2020-09-23 00:25:16 +0000100 return found;
101}
102
Steven Morelandedd4e072021-04-21 00:27:29 +0000103static 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
Steven Moreland2e293aa2020-09-23 00:25:16 +0000124static 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;
Steven Moreland86a17f82019-09-10 10:18:00 -0700141}
Steven Morelandb82b8f82019-10-28 10:52:34 -0700142
143static 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}
Steven Moreland86a17f82019-09-10 10:18:00 -0700150#endif // !VENDORSERVICEMANAGER
151
Steven Morelandd13f08b2019-11-18 14:23:09 -0800152ServiceManager::ServiceManager(std::unique_ptr<Access>&& access) : mAccess(std::move(access)) {
Steven Moreland8d0c9a72020-04-30 16:51:56 -0700153// 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
Steven Morelandd13f08b2019-11-18 14:23:09 -0800167}
Steven Moreland130242d2019-08-26 17:41:32 -0700168ServiceManager::~ServiceManager() {
169 // this should only happen in tests
170
Jon Spivackf288b1d2019-12-19 17:15:51 -0800171 for (const auto& [name, callbacks] : mNameToRegistrationCallback) {
Steven Moreland27cfab02019-08-12 14:34:16 -0700172 CHECK(!callbacks.empty()) << name;
173 for (const auto& callback : callbacks) {
174 CHECK(callback != nullptr) << name;
175 }
176 }
177
Steven Moreland130242d2019-08-26 17:41:32 -0700178 for (const auto& [name, service] : mNameToService) {
179 CHECK(service.binder != nullptr) << name;
180 }
181}
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700182
183Status ServiceManager::getService(const std::string& name, sp<IBinder>* outBinder) {
Jon Spivack0d844302019-07-22 18:40:34 -0700184 *outBinder = tryGetService(name, true);
185 // returns ok regardless of result for legacy reasons
186 return Status::ok();
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700187}
188
189Status ServiceManager::checkService(const std::string& name, sp<IBinder>* outBinder) {
Jon Spivack0d844302019-07-22 18:40:34 -0700190 *outBinder = tryGetService(name, false);
191 // returns ok regardless of result for legacy reasons
192 return Status::ok();
193}
194
195sp<IBinder> ServiceManager::tryGetService(const std::string& name, bool startIfNotFound) {
Steven Morelanda9fe4742019-07-18 14:45:20 -0700196 auto ctx = mAccess->getCallingContext();
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700197
Jon Spivack0d844302019-07-22 18:40:34 -0700198 sp<IBinder> out;
Jon Spivack9f503a42019-10-22 16:49:19 -0700199 Service* service = nullptr;
Jon Spivack0d844302019-07-22 18:40:34 -0700200 if (auto it = mNameToService.find(name); it != mNameToService.end()) {
Jon Spivack9f503a42019-10-22 16:49:19 -0700201 service = &(it->second);
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700202
Jon Spivack9f503a42019-10-22 16:49:19 -0700203 if (!service->allowIsolated) {
Jon Spivack0d844302019-07-22 18:40:34 -0700204 uid_t appid = multiuser_get_app_id(ctx.uid);
205 bool isIsolated = appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END;
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700206
Jon Spivack0d844302019-07-22 18:40:34 -0700207 if (isIsolated) {
208 return nullptr;
209 }
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700210 }
Jon Spivack9f503a42019-10-22 16:49:19 -0700211 out = service->binder;
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700212 }
213
Steven Morelanda9fe4742019-07-18 14:45:20 -0700214 if (!mAccess->canFind(ctx, name)) {
Jon Spivack0d844302019-07-22 18:40:34 -0700215 return nullptr;
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700216 }
217
Jon Spivack0d844302019-07-22 18:40:34 -0700218 if (!out && startIfNotFound) {
219 tryStartService(name);
220 }
221
Jon Spivack9f503a42019-10-22 16:49:19 -0700222 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
Jon Spivack0d844302019-07-22 18:40:34 -0700228 return out;
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700229}
230
Steven Moreland905e2e82019-07-17 11:05:45 -0700231bool 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) {
Steven Morelandbb7951d2019-08-20 16:58:25 -0700236 if (c == '_' || c == '-' || c == '.' || c == '/') continue;
Steven Moreland905e2e82019-07-17 11:05:45 -0700237 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
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700246Status ServiceManager::addService(const std::string& name, const sp<IBinder>& binder, bool allowIsolated, int32_t dumpPriority) {
Steven Morelanda9fe4742019-07-18 14:45:20 -0700247 auto ctx = mAccess->getCallingContext();
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700248
249 // apps cannot add services
250 if (multiuser_get_app_id(ctx.uid) >= AID_APP) {
251 return Status::fromExceptionCode(Status::EX_SECURITY);
252 }
253
Steven Morelanda9fe4742019-07-18 14:45:20 -0700254 if (!mAccess->canAdd(ctx, name)) {
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700255 return Status::fromExceptionCode(Status::EX_SECURITY);
256 }
257
258 if (binder == nullptr) {
259 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
260 }
261
Steven Moreland905e2e82019-07-17 11:05:45 -0700262 if (!isValidServiceName(name)) {
263 LOG(ERROR) << "Invalid service name: " << name;
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700264 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
265 }
266
Steven Moreland86a17f82019-09-10 10:18:00 -0700267#ifndef VENDORSERVICEMANAGER
268 if (!meetsDeclarationRequirements(binder, name)) {
269 // already logged
270 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
271 }
272#endif // !VENDORSERVICEMANAGER
273
Steven Moreland88860b02019-08-12 14:24:14 -0700274 // implicitly unlinked when the binder is removed
Steven Morelandb0983182021-04-02 03:14:04 +0000275 if (binder->remoteBinder() != nullptr &&
276 binder->linkToDeath(sp<ServiceManager>::fromExisting(this)) != OK) {
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700277 LOG(ERROR) << "Could not linkToDeath when adding " << name;
278 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
279 }
280
Devin Moore05ffe522020-08-06 13:58:29 -0700281 // Overwrite the old service if it exists
282 mNameToService[name] = Service {
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700283 .binder = binder,
284 .allowIsolated = allowIsolated,
285 .dumpPriority = dumpPriority,
Jon Spivack9f503a42019-10-22 16:49:19 -0700286 .debugPid = ctx.debugPid,
Devin Moore05ffe522020-08-06 13:58:29 -0700287 };
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700288
Jon Spivackf288b1d2019-12-19 17:15:51 -0800289 auto it = mNameToRegistrationCallback.find(name);
290 if (it != mNameToRegistrationCallback.end()) {
Steven Moreland27cfab02019-08-12 14:34:16 -0700291 for (const sp<IServiceCallback>& cb : it->second) {
Devin Moore05ffe522020-08-06 13:58:29 -0700292 mNameToService[name].guaranteeClient = true;
Steven Moreland27cfab02019-08-12 14:34:16 -0700293 // permission checked in registerForNotifications
294 cb->onRegistration(name, binder);
295 }
296 }
297
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700298 return Status::ok();
299}
300
301Status ServiceManager::listServices(int32_t dumpPriority, std::vector<std::string>* outList) {
Steven Morelanda9fe4742019-07-18 14:45:20 -0700302 if (!mAccess->canList(mAccess->getCallingContext())) {
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700303 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
Steven Moreland27cfab02019-08-12 14:34:16 -0700327Status 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
Steven Morelandb0983182021-04-02 03:14:04 +0000344 if (OK !=
345 IInterface::asBinder(callback)->linkToDeath(
346 sp<ServiceManager>::fromExisting(this))) {
Steven Moreland27cfab02019-08-12 14:34:16 -0700347 LOG(ERROR) << "Could not linkToDeath when adding " << name;
348 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
349 }
350
Jon Spivackf288b1d2019-12-19 17:15:51 -0800351 mNameToRegistrationCallback[name].push_back(callback);
Steven Moreland27cfab02019-08-12 14:34:16 -0700352
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}
363Status 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
Jon Spivackf288b1d2019-12-19 17:15:51 -0800373 auto it = mNameToRegistrationCallback.find(name);
374 if (it != mNameToRegistrationCallback.end()) {
375 removeRegistrationCallback(IInterface::asBinder(callback), &it, &found);
Steven Moreland27cfab02019-08-12 14:34:16 -0700376 }
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
Steven Morelandb82b8f82019-10-28 10:52:34 -0700386Status 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
Steven Moreland2e293aa2020-09-23 00:25:16 +0000401binder::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) {
Steven Moreland2e293aa2020-09-23 00:25:16 +0000412 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
Steven Morelandedd4e072021-04-21 00:27:29 +0000424Status 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
Jon Spivackf288b1d2019-12-19 17:15:51 -0800440void ServiceManager::removeRegistrationCallback(const wp<IBinder>& who,
441 ServiceCallbackMap::iterator* it,
Steven Moreland27cfab02019-08-12 14:34:16 -0700442 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()) {
Jon Spivackf288b1d2019-12-19 17:15:51 -0800455 *it = mNameToRegistrationCallback.erase(*it);
Steven Moreland27cfab02019-08-12 14:34:16 -0700456 } else {
Jon Spivacke223f082019-11-19 16:21:20 -0800457 (*it)++;
Steven Moreland27cfab02019-08-12 14:34:16 -0700458 }
459}
460
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700461void 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 }
Steven Moreland27cfab02019-08-12 14:34:16 -0700469
Jon Spivackf288b1d2019-12-19 17:15:51 -0800470 for (auto it = mNameToRegistrationCallback.begin(); it != mNameToRegistrationCallback.end();) {
471 removeRegistrationCallback(who, &it, nullptr /*found*/);
Steven Moreland27cfab02019-08-12 14:34:16 -0700472 }
Jon Spivack9f503a42019-10-22 16:49:19 -0700473
474 for (auto it = mNameToClientCallback.begin(); it != mNameToClientCallback.end();) {
475 removeClientCallback(who, &it);
476 }
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700477}
478
Jon Spivack0d844302019-07-22 18:40:34 -0700479void 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([=] {
Steven Morelandbfe9fba2021-04-27 18:39:57 +0000484 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 }
Jon Spivack0d844302019-07-22 18:40:34 -0700490 }).detach();
491}
492
Jon Spivack9f503a42019-10-22 16:49:19 -0700493Status 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
Steven Morelandb0983182021-04-02 03:14:04 +0000521 if (OK !=
522 IInterface::asBinder(cb)->linkToDeath(sp<ServiceManager>::fromExisting(this))) {
Jon Spivack9f503a42019-10-22 16:49:19 -0700523 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
532void 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
551ssize_t ServiceManager::Service::getNodeStrongRefCount() {
Steven Morelandb0983182021-04-02 03:14:04 +0000552 sp<BpBinder> bpBinder = sp<BpBinder>::fromExisting(binder->remoteBinder());
Jon Spivack9f503a42019-10-22 16:49:19 -0700553 if (bpBinder == nullptr) return -1;
554
Steven Morelande8393882020-12-18 02:27:20 +0000555 return ProcessState::self()->getStrongRefCountForNode(bpBinder);
Jon Spivack9f503a42019-10-22 16:49:19 -0700556}
557
558void ServiceManager::handleClientCallbacks() {
559 for (const auto& [name, service] : mNameToService) {
Jon Spivackd9533c22020-01-27 22:19:22 +0000560 handleServiceClientCallback(name, true);
Jon Spivack9f503a42019-10-22 16:49:19 -0700561 }
562}
563
Jon Spivackd9533c22020-01-27 22:19:22 +0000564ssize_t ServiceManager::handleServiceClientCallback(const std::string& serviceName,
565 bool isCalledOnInterval) {
Jon Spivack9f503a42019-10-22 16:49:19 -0700566 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
Jon Spivackd9533c22020-01-27 22:19:22 +0000589 // 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 }
Jon Spivack9f503a42019-10-22 16:49:19 -0700595
Jon Spivackd9533c22020-01-27 22:19:22 +0000596 // there are no more clients, but the callback has not been called yet
597 if (!hasClients && service.hasClients) {
598 sendClientCallbackNotifications(serviceName, false);
599 }
Jon Spivack9f503a42019-10-22 16:49:19 -0700600 }
601
602 return count;
603}
604
605void 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
629Status 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
Jon Spivack0f18f2c2020-03-13 20:45:18 -0700659 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
Jon Spivackd9533c22020-01-27 22:19:22 +0000664 int clients = handleServiceClientCallback(name, false);
Jon Spivack9f503a42019-10-22 16:49:19 -0700665
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
Jon Spivackd9533c22020-01-27 22:19:22 +0000673 LOG(INFO) << "Tried to unregister " << name << ", but there are clients: " << clients;
Jon Spivack620d2dc2020-03-06 13:58:01 -0800674 // Set this flag to ensure the clients are acknowledged in the next callback
675 serviceIt->second.guaranteeClient = true;
Jon Spivack9f503a42019-10-22 16:49:19 -0700676 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
677 }
678
679 mNameToService.erase(name);
680
681 return Status::ok();
682}
683
Steven Moreland3ea43272021-01-28 22:49:28 +0000684Status 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
Steven Moreland8d0c9a72020-04-30 16:51:56 -0700701} // namespace android