blob: 4e44ac7323a9b5082abb4670d5125dff07e1e1cc [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
Devin Moore5e4c2f12021-09-09 22:36:33 +0000124static std::optional<ConnectionInfo> getVintfConnectionInfo(const std::string& name) {
125 AidlName aname;
126 if (!AidlName::fill(name, &aname)) return std::nullopt;
127
128 std::optional<std::string> ip;
129 std::optional<uint64_t> port;
130 forEachManifest([&](const ManifestWithDescription& mwd) {
131 mwd.manifest->forEachInstance([&](const auto& manifestInstance) {
132 if (manifestInstance.format() != vintf::HalFormat::AIDL) return true;
133 if (manifestInstance.package() != aname.package) return true;
134 if (manifestInstance.interface() != aname.iface) return true;
135 if (manifestInstance.instance() != aname.instance) return true;
136 ip = manifestInstance.ip();
137 port = manifestInstance.port();
138 return false; // break (libvintf uses opposite convention)
139 });
140 return false; // continue
141 });
142
143 if (ip.has_value() && port.has_value()) {
144 ConnectionInfo info;
145 info.ipAddress = *ip;
146 info.port = *port;
147 return std::make_optional<ConnectionInfo>(info);
148 } else {
149 return std::nullopt;
150 }
151}
152
Steven Moreland2e293aa2020-09-23 00:25:16 +0000153static std::vector<std::string> getVintfInstances(const std::string& interface) {
154 size_t lastDot = interface.rfind('.');
155 if (lastDot == std::string::npos) {
156 LOG(ERROR) << "VINTF interfaces require names in Java package format (e.g. some.package.foo.IFoo) but got: " << interface;
157 return {};
158 }
159 const std::string package = interface.substr(0, lastDot);
160 const std::string iface = interface.substr(lastDot+1);
161
162 std::vector<std::string> ret;
163 (void)forEachManifest([&](const ManifestWithDescription& mwd) {
164 auto instances = mwd.manifest->getAidlInstances(package, iface);
165 ret.insert(ret.end(), instances.begin(), instances.end());
166 return false; // continue
167 });
168
169 return ret;
Steven Moreland86a17f82019-09-10 10:18:00 -0700170}
Steven Morelandb82b8f82019-10-28 10:52:34 -0700171
172static bool meetsDeclarationRequirements(const sp<IBinder>& binder, const std::string& name) {
173 if (!Stability::requiresVintfDeclaration(binder)) {
174 return true;
175 }
176
177 return isVintfDeclared(name);
178}
Steven Moreland86a17f82019-09-10 10:18:00 -0700179#endif // !VENDORSERVICEMANAGER
180
Steven Morelandd13f08b2019-11-18 14:23:09 -0800181ServiceManager::ServiceManager(std::unique_ptr<Access>&& access) : mAccess(std::move(access)) {
Steven Moreland8d0c9a72020-04-30 16:51:56 -0700182// TODO(b/151696835): reenable performance hack when we solve bug, since with
183// this hack and other fixes, it is unlikely we will see even an ephemeral
184// failure when the manifest parse fails. The goal is that the manifest will
185// be read incorrectly and cause the process trying to register a HAL to
186// fail. If this is in fact an early boot kernel contention issue, then we
187// will get no failure, and by its absence, be signalled to invest more
188// effort in re-adding this performance hack.
189// #ifndef VENDORSERVICEMANAGER
190// // can process these at any times, don't want to delay first VINTF client
191// std::thread([] {
192// vintf::VintfObject::GetDeviceHalManifest();
193// vintf::VintfObject::GetFrameworkHalManifest();
194// }).detach();
195// #endif // !VENDORSERVICEMANAGER
Steven Morelandd13f08b2019-11-18 14:23:09 -0800196}
Steven Moreland130242d2019-08-26 17:41:32 -0700197ServiceManager::~ServiceManager() {
198 // this should only happen in tests
199
Jon Spivackf288b1d2019-12-19 17:15:51 -0800200 for (const auto& [name, callbacks] : mNameToRegistrationCallback) {
Steven Moreland27cfab02019-08-12 14:34:16 -0700201 CHECK(!callbacks.empty()) << name;
202 for (const auto& callback : callbacks) {
203 CHECK(callback != nullptr) << name;
204 }
205 }
206
Steven Moreland130242d2019-08-26 17:41:32 -0700207 for (const auto& [name, service] : mNameToService) {
208 CHECK(service.binder != nullptr) << name;
209 }
210}
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700211
212Status ServiceManager::getService(const std::string& name, sp<IBinder>* outBinder) {
Jon Spivack0d844302019-07-22 18:40:34 -0700213 *outBinder = tryGetService(name, true);
214 // returns ok regardless of result for legacy reasons
215 return Status::ok();
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700216}
217
218Status ServiceManager::checkService(const std::string& name, sp<IBinder>* outBinder) {
Jon Spivack0d844302019-07-22 18:40:34 -0700219 *outBinder = tryGetService(name, false);
220 // returns ok regardless of result for legacy reasons
221 return Status::ok();
222}
223
224sp<IBinder> ServiceManager::tryGetService(const std::string& name, bool startIfNotFound) {
Steven Morelanda9fe4742019-07-18 14:45:20 -0700225 auto ctx = mAccess->getCallingContext();
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700226
Jon Spivack0d844302019-07-22 18:40:34 -0700227 sp<IBinder> out;
Jon Spivack9f503a42019-10-22 16:49:19 -0700228 Service* service = nullptr;
Jon Spivack0d844302019-07-22 18:40:34 -0700229 if (auto it = mNameToService.find(name); it != mNameToService.end()) {
Jon Spivack9f503a42019-10-22 16:49:19 -0700230 service = &(it->second);
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700231
Jon Spivack9f503a42019-10-22 16:49:19 -0700232 if (!service->allowIsolated) {
Jon Spivack0d844302019-07-22 18:40:34 -0700233 uid_t appid = multiuser_get_app_id(ctx.uid);
234 bool isIsolated = appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END;
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700235
Jon Spivack0d844302019-07-22 18:40:34 -0700236 if (isIsolated) {
237 return nullptr;
238 }
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700239 }
Jon Spivack9f503a42019-10-22 16:49:19 -0700240 out = service->binder;
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700241 }
242
Steven Morelanda9fe4742019-07-18 14:45:20 -0700243 if (!mAccess->canFind(ctx, name)) {
Jon Spivack0d844302019-07-22 18:40:34 -0700244 return nullptr;
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700245 }
246
Jon Spivack0d844302019-07-22 18:40:34 -0700247 if (!out && startIfNotFound) {
248 tryStartService(name);
249 }
250
Jon Spivack9f503a42019-10-22 16:49:19 -0700251 if (out) {
252 // Setting this guarantee each time we hand out a binder ensures that the client-checking
253 // loop knows about the event even if the client immediately drops the service
254 service->guaranteeClient = true;
255 }
256
Jon Spivack0d844302019-07-22 18:40:34 -0700257 return out;
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700258}
259
Steven Moreland905e2e82019-07-17 11:05:45 -0700260bool isValidServiceName(const std::string& name) {
261 if (name.size() == 0) return false;
262 if (name.size() > 127) return false;
263
264 for (char c : name) {
Steven Morelandbb7951d2019-08-20 16:58:25 -0700265 if (c == '_' || c == '-' || c == '.' || c == '/') continue;
Steven Moreland905e2e82019-07-17 11:05:45 -0700266 if (c >= 'a' && c <= 'z') continue;
267 if (c >= 'A' && c <= 'Z') continue;
268 if (c >= '0' && c <= '9') continue;
269 return false;
270 }
271
272 return true;
273}
274
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700275Status ServiceManager::addService(const std::string& name, const sp<IBinder>& binder, bool allowIsolated, int32_t dumpPriority) {
Steven Morelanda9fe4742019-07-18 14:45:20 -0700276 auto ctx = mAccess->getCallingContext();
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700277
278 // apps cannot add services
279 if (multiuser_get_app_id(ctx.uid) >= AID_APP) {
280 return Status::fromExceptionCode(Status::EX_SECURITY);
281 }
282
Steven Morelanda9fe4742019-07-18 14:45:20 -0700283 if (!mAccess->canAdd(ctx, name)) {
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700284 return Status::fromExceptionCode(Status::EX_SECURITY);
285 }
286
287 if (binder == nullptr) {
288 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
289 }
290
Steven Moreland905e2e82019-07-17 11:05:45 -0700291 if (!isValidServiceName(name)) {
292 LOG(ERROR) << "Invalid service name: " << name;
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700293 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
294 }
295
Steven Moreland86a17f82019-09-10 10:18:00 -0700296#ifndef VENDORSERVICEMANAGER
297 if (!meetsDeclarationRequirements(binder, name)) {
298 // already logged
299 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
300 }
301#endif // !VENDORSERVICEMANAGER
302
Steven Moreland88860b02019-08-12 14:24:14 -0700303 // implicitly unlinked when the binder is removed
Steven Morelandb0983182021-04-02 03:14:04 +0000304 if (binder->remoteBinder() != nullptr &&
305 binder->linkToDeath(sp<ServiceManager>::fromExisting(this)) != OK) {
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700306 LOG(ERROR) << "Could not linkToDeath when adding " << name;
307 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
308 }
309
Devin Moore05ffe522020-08-06 13:58:29 -0700310 // Overwrite the old service if it exists
311 mNameToService[name] = Service {
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700312 .binder = binder,
313 .allowIsolated = allowIsolated,
314 .dumpPriority = dumpPriority,
Jon Spivack9f503a42019-10-22 16:49:19 -0700315 .debugPid = ctx.debugPid,
Devin Moore05ffe522020-08-06 13:58:29 -0700316 };
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700317
Jon Spivackf288b1d2019-12-19 17:15:51 -0800318 auto it = mNameToRegistrationCallback.find(name);
319 if (it != mNameToRegistrationCallback.end()) {
Steven Moreland27cfab02019-08-12 14:34:16 -0700320 for (const sp<IServiceCallback>& cb : it->second) {
Devin Moore05ffe522020-08-06 13:58:29 -0700321 mNameToService[name].guaranteeClient = true;
Steven Moreland27cfab02019-08-12 14:34:16 -0700322 // permission checked in registerForNotifications
323 cb->onRegistration(name, binder);
324 }
325 }
326
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700327 return Status::ok();
328}
329
330Status ServiceManager::listServices(int32_t dumpPriority, std::vector<std::string>* outList) {
Steven Morelanda9fe4742019-07-18 14:45:20 -0700331 if (!mAccess->canList(mAccess->getCallingContext())) {
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700332 return Status::fromExceptionCode(Status::EX_SECURITY);
333 }
334
335 size_t toReserve = 0;
336 for (auto const& [name, service] : mNameToService) {
337 (void) name;
338
339 if (service.dumpPriority & dumpPriority) ++toReserve;
340 }
341
342 CHECK(outList->empty());
343
344 outList->reserve(toReserve);
345 for (auto const& [name, service] : mNameToService) {
346 (void) service;
347
348 if (service.dumpPriority & dumpPriority) {
349 outList->push_back(name);
350 }
351 }
352
353 return Status::ok();
354}
355
Steven Moreland27cfab02019-08-12 14:34:16 -0700356Status ServiceManager::registerForNotifications(
357 const std::string& name, const sp<IServiceCallback>& callback) {
358 auto ctx = mAccess->getCallingContext();
359
360 if (!mAccess->canFind(ctx, name)) {
361 return Status::fromExceptionCode(Status::EX_SECURITY);
362 }
363
364 if (!isValidServiceName(name)) {
365 LOG(ERROR) << "Invalid service name: " << name;
366 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
367 }
368
369 if (callback == nullptr) {
370 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
371 }
372
Steven Morelandb0983182021-04-02 03:14:04 +0000373 if (OK !=
374 IInterface::asBinder(callback)->linkToDeath(
375 sp<ServiceManager>::fromExisting(this))) {
Steven Moreland27cfab02019-08-12 14:34:16 -0700376 LOG(ERROR) << "Could not linkToDeath when adding " << name;
377 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
378 }
379
Jon Spivackf288b1d2019-12-19 17:15:51 -0800380 mNameToRegistrationCallback[name].push_back(callback);
Steven Moreland27cfab02019-08-12 14:34:16 -0700381
382 if (auto it = mNameToService.find(name); it != mNameToService.end()) {
383 const sp<IBinder>& binder = it->second.binder;
384
385 // never null if an entry exists
386 CHECK(binder != nullptr) << name;
387 callback->onRegistration(name, binder);
388 }
389
390 return Status::ok();
391}
392Status ServiceManager::unregisterForNotifications(
393 const std::string& name, const sp<IServiceCallback>& callback) {
394 auto ctx = mAccess->getCallingContext();
395
396 if (!mAccess->canFind(ctx, name)) {
397 return Status::fromExceptionCode(Status::EX_SECURITY);
398 }
399
400 bool found = false;
401
Jon Spivackf288b1d2019-12-19 17:15:51 -0800402 auto it = mNameToRegistrationCallback.find(name);
403 if (it != mNameToRegistrationCallback.end()) {
404 removeRegistrationCallback(IInterface::asBinder(callback), &it, &found);
Steven Moreland27cfab02019-08-12 14:34:16 -0700405 }
406
407 if (!found) {
408 LOG(ERROR) << "Trying to unregister callback, but none exists " << name;
409 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
410 }
411
412 return Status::ok();
413}
414
Steven Morelandb82b8f82019-10-28 10:52:34 -0700415Status ServiceManager::isDeclared(const std::string& name, bool* outReturn) {
416 auto ctx = mAccess->getCallingContext();
417
418 if (!mAccess->canFind(ctx, name)) {
419 return Status::fromExceptionCode(Status::EX_SECURITY);
420 }
421
422 *outReturn = false;
423
424#ifndef VENDORSERVICEMANAGER
425 *outReturn = isVintfDeclared(name);
426#endif
427 return Status::ok();
428}
429
Steven Moreland2e293aa2020-09-23 00:25:16 +0000430binder::Status ServiceManager::getDeclaredInstances(const std::string& interface, std::vector<std::string>* outReturn) {
431 auto ctx = mAccess->getCallingContext();
432
433 std::vector<std::string> allInstances;
434#ifndef VENDORSERVICEMANAGER
435 allInstances = getVintfInstances(interface);
436#endif
437
438 outReturn->clear();
439
440 for (const std::string& instance : allInstances) {
Steven Moreland2e293aa2020-09-23 00:25:16 +0000441 if (mAccess->canFind(ctx, interface + "/" + instance)) {
442 outReturn->push_back(instance);
443 }
444 }
445
446 if (outReturn->size() == 0 && allInstances.size() != 0) {
447 return Status::fromExceptionCode(Status::EX_SECURITY);
448 }
449
450 return Status::ok();
451}
452
Steven Morelandedd4e072021-04-21 00:27:29 +0000453Status ServiceManager::updatableViaApex(const std::string& name,
454 std::optional<std::string>* outReturn) {
455 auto ctx = mAccess->getCallingContext();
456
457 if (!mAccess->canFind(ctx, name)) {
458 return Status::fromExceptionCode(Status::EX_SECURITY);
459 }
460
461 *outReturn = std::nullopt;
462
463#ifndef VENDORSERVICEMANAGER
464 *outReturn = getVintfUpdatableApex(name);
465#endif
466 return Status::ok();
467}
468
Devin Moore5e4c2f12021-09-09 22:36:33 +0000469Status ServiceManager::getConnectionInfo(const std::string& name,
470 std::optional<ConnectionInfo>* outReturn) {
471 auto ctx = mAccess->getCallingContext();
472
473 if (!mAccess->canFind(ctx, name)) {
474 return Status::fromExceptionCode(Status::EX_SECURITY);
475 }
476
477 *outReturn = std::nullopt;
478
479#ifndef VENDORSERVICEMANAGER
480 *outReturn = getVintfConnectionInfo(name);
481#endif
482 return Status::ok();
483}
484
Jon Spivackf288b1d2019-12-19 17:15:51 -0800485void ServiceManager::removeRegistrationCallback(const wp<IBinder>& who,
486 ServiceCallbackMap::iterator* it,
Steven Moreland27cfab02019-08-12 14:34:16 -0700487 bool* found) {
488 std::vector<sp<IServiceCallback>>& listeners = (*it)->second;
489
490 for (auto lit = listeners.begin(); lit != listeners.end();) {
491 if (IInterface::asBinder(*lit) == who) {
492 if(found) *found = true;
493 lit = listeners.erase(lit);
494 } else {
495 ++lit;
496 }
497 }
498
499 if (listeners.empty()) {
Jon Spivackf288b1d2019-12-19 17:15:51 -0800500 *it = mNameToRegistrationCallback.erase(*it);
Steven Moreland27cfab02019-08-12 14:34:16 -0700501 } else {
Jon Spivacke223f082019-11-19 16:21:20 -0800502 (*it)++;
Steven Moreland27cfab02019-08-12 14:34:16 -0700503 }
504}
505
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700506void ServiceManager::binderDied(const wp<IBinder>& who) {
507 for (auto it = mNameToService.begin(); it != mNameToService.end();) {
508 if (who == it->second.binder) {
509 it = mNameToService.erase(it);
510 } else {
511 ++it;
512 }
513 }
Steven Moreland27cfab02019-08-12 14:34:16 -0700514
Jon Spivackf288b1d2019-12-19 17:15:51 -0800515 for (auto it = mNameToRegistrationCallback.begin(); it != mNameToRegistrationCallback.end();) {
516 removeRegistrationCallback(who, &it, nullptr /*found*/);
Steven Moreland27cfab02019-08-12 14:34:16 -0700517 }
Jon Spivack9f503a42019-10-22 16:49:19 -0700518
519 for (auto it = mNameToClientCallback.begin(); it != mNameToClientCallback.end();) {
520 removeClientCallback(who, &it);
521 }
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700522}
523
Jon Spivack0d844302019-07-22 18:40:34 -0700524void ServiceManager::tryStartService(const std::string& name) {
525 ALOGI("Since '%s' could not be found, trying to start it as a lazy AIDL service",
526 name.c_str());
527
528 std::thread([=] {
Steven Morelandbfe9fba2021-04-27 18:39:57 +0000529 if (!base::SetProperty("ctl.interface_start", "aidl/" + name)) {
530 LOG(INFO) << "Tried to start aidl service " << name
531 << " as a lazy service, but was unable to. Usually this happens when a "
532 "service is not installed, but if the service is intended to be used as a "
533 "lazy service, then it may be configured incorrectly.";
534 }
Jon Spivack0d844302019-07-22 18:40:34 -0700535 }).detach();
536}
537
Jon Spivack9f503a42019-10-22 16:49:19 -0700538Status ServiceManager::registerClientCallback(const std::string& name, const sp<IBinder>& service,
539 const sp<IClientCallback>& cb) {
540 if (cb == nullptr) {
541 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
542 }
543
544 auto ctx = mAccess->getCallingContext();
545 if (!mAccess->canAdd(ctx, name)) {
546 return Status::fromExceptionCode(Status::EX_SECURITY);
547 }
548
549 auto serviceIt = mNameToService.find(name);
550 if (serviceIt == mNameToService.end()) {
551 LOG(ERROR) << "Could not add callback for nonexistent service: " << name;
552 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
553 }
554
555 if (serviceIt->second.debugPid != IPCThreadState::self()->getCallingPid()) {
556 LOG(WARNING) << "Only a server can register for client callbacks (for " << name << ")";
557 return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION);
558 }
559
560 if (serviceIt->second.binder != service) {
561 LOG(WARNING) << "Tried to register client callback for " << name
562 << " but a different service is registered under this name.";
563 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
564 }
565
Steven Morelandb0983182021-04-02 03:14:04 +0000566 if (OK !=
567 IInterface::asBinder(cb)->linkToDeath(sp<ServiceManager>::fromExisting(this))) {
Jon Spivack9f503a42019-10-22 16:49:19 -0700568 LOG(ERROR) << "Could not linkToDeath when adding client callback for " << name;
569 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
570 }
571
572 mNameToClientCallback[name].push_back(cb);
573
574 return Status::ok();
575}
576
577void ServiceManager::removeClientCallback(const wp<IBinder>& who,
578 ClientCallbackMap::iterator* it) {
579 std::vector<sp<IClientCallback>>& listeners = (*it)->second;
580
581 for (auto lit = listeners.begin(); lit != listeners.end();) {
582 if (IInterface::asBinder(*lit) == who) {
583 lit = listeners.erase(lit);
584 } else {
585 ++lit;
586 }
587 }
588
589 if (listeners.empty()) {
590 *it = mNameToClientCallback.erase(*it);
591 } else {
592 (*it)++;
593 }
594}
595
596ssize_t ServiceManager::Service::getNodeStrongRefCount() {
Steven Morelandb0983182021-04-02 03:14:04 +0000597 sp<BpBinder> bpBinder = sp<BpBinder>::fromExisting(binder->remoteBinder());
Jon Spivack9f503a42019-10-22 16:49:19 -0700598 if (bpBinder == nullptr) return -1;
599
Steven Morelande8393882020-12-18 02:27:20 +0000600 return ProcessState::self()->getStrongRefCountForNode(bpBinder);
Jon Spivack9f503a42019-10-22 16:49:19 -0700601}
602
603void ServiceManager::handleClientCallbacks() {
604 for (const auto& [name, service] : mNameToService) {
Jon Spivackd9533c22020-01-27 22:19:22 +0000605 handleServiceClientCallback(name, true);
Jon Spivack9f503a42019-10-22 16:49:19 -0700606 }
607}
608
Jon Spivackd9533c22020-01-27 22:19:22 +0000609ssize_t ServiceManager::handleServiceClientCallback(const std::string& serviceName,
610 bool isCalledOnInterval) {
Jon Spivack9f503a42019-10-22 16:49:19 -0700611 auto serviceIt = mNameToService.find(serviceName);
612 if (serviceIt == mNameToService.end() || mNameToClientCallback.count(serviceName) < 1) {
613 return -1;
614 }
615
616 Service& service = serviceIt->second;
617 ssize_t count = service.getNodeStrongRefCount();
618
619 // binder driver doesn't support this feature
620 if (count == -1) return count;
621
622 bool hasClients = count > 1; // this process holds a strong count
623
624 if (service.guaranteeClient) {
625 // we have no record of this client
626 if (!service.hasClients && !hasClients) {
627 sendClientCallbackNotifications(serviceName, true);
628 }
629
630 // guarantee is temporary
631 service.guaranteeClient = false;
632 }
633
Jon Spivackd9533c22020-01-27 22:19:22 +0000634 // only send notifications if this was called via the interval checking workflow
635 if (isCalledOnInterval) {
636 if (hasClients && !service.hasClients) {
637 // client was retrieved in some other way
638 sendClientCallbackNotifications(serviceName, true);
639 }
Jon Spivack9f503a42019-10-22 16:49:19 -0700640
Jon Spivackd9533c22020-01-27 22:19:22 +0000641 // there are no more clients, but the callback has not been called yet
642 if (!hasClients && service.hasClients) {
643 sendClientCallbackNotifications(serviceName, false);
644 }
Jon Spivack9f503a42019-10-22 16:49:19 -0700645 }
646
647 return count;
648}
649
650void ServiceManager::sendClientCallbackNotifications(const std::string& serviceName, bool hasClients) {
651 auto serviceIt = mNameToService.find(serviceName);
652 if (serviceIt == mNameToService.end()) {
653 LOG(WARNING) << "sendClientCallbackNotifications could not find service " << serviceName;
654 return;
655 }
656 Service& service = serviceIt->second;
657
658 CHECK(hasClients != service.hasClients) << "Record shows: " << service.hasClients
659 << " so we can't tell clients again that we have client: " << hasClients;
660
661 LOG(INFO) << "Notifying " << serviceName << " they have clients: " << hasClients;
662
663 auto ccIt = mNameToClientCallback.find(serviceName);
664 CHECK(ccIt != mNameToClientCallback.end())
665 << "sendClientCallbackNotifications could not find callbacks for service ";
666
667 for (const auto& callback : ccIt->second) {
668 callback->onClients(service.binder, hasClients);
669 }
670
671 service.hasClients = hasClients;
672}
673
674Status ServiceManager::tryUnregisterService(const std::string& name, const sp<IBinder>& binder) {
675 if (binder == nullptr) {
676 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
677 }
678
679 auto ctx = mAccess->getCallingContext();
680 if (!mAccess->canAdd(ctx, name)) {
681 return Status::fromExceptionCode(Status::EX_SECURITY);
682 }
683
684 auto serviceIt = mNameToService.find(name);
685 if (serviceIt == mNameToService.end()) {
686 LOG(WARNING) << "Tried to unregister " << name
687 << ", but that service wasn't registered to begin with.";
688 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
689 }
690
691 if (serviceIt->second.debugPid != IPCThreadState::self()->getCallingPid()) {
692 LOG(WARNING) << "Only a server can unregister itself (for " << name << ")";
693 return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION);
694 }
695
696 sp<IBinder> storedBinder = serviceIt->second.binder;
697
698 if (binder != storedBinder) {
699 LOG(WARNING) << "Tried to unregister " << name
700 << ", but a different service is registered under this name.";
701 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
702 }
703
Jon Spivack0f18f2c2020-03-13 20:45:18 -0700704 if (serviceIt->second.guaranteeClient) {
705 LOG(INFO) << "Tried to unregister " << name << ", but there is about to be a client.";
706 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
707 }
708
Jon Spivackd9533c22020-01-27 22:19:22 +0000709 int clients = handleServiceClientCallback(name, false);
Jon Spivack9f503a42019-10-22 16:49:19 -0700710
711 // clients < 0: feature not implemented or other error. Assume clients.
712 // Otherwise:
713 // - kernel driver will hold onto one refcount (during this transaction)
714 // - servicemanager has a refcount (guaranteed by this transaction)
715 // So, if clients > 2, then at least one other service on the system must hold a refcount.
716 if (clients < 0 || clients > 2) {
717 // client callbacks are either disabled or there are other clients
Jon Spivackd9533c22020-01-27 22:19:22 +0000718 LOG(INFO) << "Tried to unregister " << name << ", but there are clients: " << clients;
Jon Spivack620d2dc2020-03-06 13:58:01 -0800719 // Set this flag to ensure the clients are acknowledged in the next callback
720 serviceIt->second.guaranteeClient = true;
Jon Spivack9f503a42019-10-22 16:49:19 -0700721 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
722 }
723
724 mNameToService.erase(name);
725
726 return Status::ok();
727}
728
Steven Moreland3ea43272021-01-28 22:49:28 +0000729Status ServiceManager::getServiceDebugInfo(std::vector<ServiceDebugInfo>* outReturn) {
730 if (!mAccess->canList(mAccess->getCallingContext())) {
731 return Status::fromExceptionCode(Status::EX_SECURITY);
732 }
733
734 outReturn->reserve(mNameToService.size());
735 for (auto const& [name, service] : mNameToService) {
736 ServiceDebugInfo info;
737 info.name = name;
738 info.debugPid = service.debugPid;
739
740 outReturn->push_back(std::move(info));
741 }
742
743 return Status::ok();
744}
745
Steven Moreland8d0c9a72020-04-30 16:51:56 -0700746} // namespace android