blob: 3681d5b8b989ce028a30368fb67a45eadbde0d07 [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>
Yifan Hong0a9b56e2021-11-30 16:45:40 -080031#ifdef __ANDROID_RECOVERY__
32#include <vintf/VintfObjectRecovery.h>
33#endif // __ANDROID_RECOVERY__
Steven Moreland86a17f82019-09-10 10:18:00 -070034#include <vintf/constants.h>
35#endif // !VENDORSERVICEMANAGER
36
Steven Moreland80e1e6d2019-06-21 12:35:59 -070037using ::android::binder::Status;
Steven Moreland86a17f82019-09-10 10:18:00 -070038using ::android::internal::Stability;
Steven Moreland80e1e6d2019-06-21 12:35:59 -070039
40namespace android {
41
Steven Moreland86a17f82019-09-10 10:18:00 -070042#ifndef VENDORSERVICEMANAGER
Yifan Hong0a9b56e2021-11-30 16:45:40 -080043
Steven Moreland2e293aa2020-09-23 00:25:16 +000044struct ManifestWithDescription {
45 std::shared_ptr<const vintf::HalManifest> manifest;
46 const char* description;
47};
Yifan Hong0a9b56e2021-11-30 16:45:40 -080048static std::vector<ManifestWithDescription> GetManifestsWithDescription() {
49#ifdef __ANDROID_RECOVERY__
50 auto vintfObject = vintf::VintfObjectRecovery::GetInstance();
51 if (vintfObject == nullptr) {
Pawan Wagh37526162022-09-29 21:55:26 +000052 ALOGE("NULL VintfObjectRecovery!");
Yifan Hong0a9b56e2021-11-30 16:45:40 -080053 return {};
54 }
55 return {ManifestWithDescription{vintfObject->getRecoveryHalManifest(), "recovery"}};
56#else
57 auto vintfObject = vintf::VintfObject::GetInstance();
58 if (vintfObject == nullptr) {
Pawan Wagh37526162022-09-29 21:55:26 +000059 ALOGE("NULL VintfObject!");
Yifan Hong0a9b56e2021-11-30 16:45:40 -080060 return {};
61 }
62 return {ManifestWithDescription{vintfObject->getDeviceHalManifest(), "device"},
63 ManifestWithDescription{vintfObject->getFrameworkHalManifest(), "framework"}};
64#endif
65}
66
Steven Moreland2e293aa2020-09-23 00:25:16 +000067// func true -> stop search and forEachManifest will return true
68static bool forEachManifest(const std::function<bool(const ManifestWithDescription&)>& func) {
Yifan Hong0a9b56e2021-11-30 16:45:40 -080069 for (const ManifestWithDescription& mwd : GetManifestsWithDescription()) {
Steven Moreland2e293aa2020-09-23 00:25:16 +000070 if (mwd.manifest == nullptr) {
Pawan Wagh37526162022-09-29 21:55:26 +000071 ALOGE("NULL VINTF MANIFEST!: %s", mwd.description);
72 // note, we explicitly do not retry here, so that we can detect VINTF
73 // or other bugs (b/151696835)
74 continue;
Steven Moreland2e293aa2020-09-23 00:25:16 +000075 }
76 if (func(mwd)) return true;
77 }
78 return false;
79}
80
Steven Morelandedd4e072021-04-21 00:27:29 +000081struct AidlName {
82 std::string package;
83 std::string iface;
84 std::string instance;
Steven Moreland86a17f82019-09-10 10:18:00 -070085
Steven Morelandedd4e072021-04-21 00:27:29 +000086 static bool fill(const std::string& name, AidlName* aname) {
87 size_t firstSlash = name.find('/');
88 size_t lastDot = name.rfind('.', firstSlash);
89 if (firstSlash == std::string::npos || lastDot == std::string::npos) {
Pawan Wagh37526162022-09-29 21:55:26 +000090 ALOGE("VINTF HALs require names in the format type/instance (e.g. "
91 "some.package.foo.IFoo/default) but got: %s",
92 name.c_str());
Steven Morelandedd4e072021-04-21 00:27:29 +000093 return false;
94 }
95 aname->package = name.substr(0, lastDot);
96 aname->iface = name.substr(lastDot + 1, firstSlash - lastDot - 1);
97 aname->instance = name.substr(firstSlash + 1);
98 return true;
99 }
100};
101
102static bool isVintfDeclared(const std::string& name) {
103 AidlName aname;
104 if (!AidlName::fill(name, &aname)) return false;
105
106 bool found = forEachManifest([&](const ManifestWithDescription& mwd) {
107 if (mwd.manifest->hasAidlInstance(aname.package, aname.iface, aname.instance)) {
Pawan Wagh37526162022-09-29 21:55:26 +0000108 ALOGI("Found %s in %s VINTF manifest.", name.c_str(), mwd.description);
Steven Morelandedd4e072021-04-21 00:27:29 +0000109 return true; // break
Steven Moreland86a17f82019-09-10 10:18:00 -0700110 }
Steven Moreland2e293aa2020-09-23 00:25:16 +0000111 return false; // continue
112 });
113
114 if (!found) {
115 // Although it is tested, explicitly rebuilding qualified name, in case it
116 // becomes something unexpected.
Pawan Wagh37526162022-09-29 21:55:26 +0000117 ALOGI("Could not find %s.%s/%s in the VINTF manifest.", aname.package.c_str(),
118 aname.iface.c_str(), aname.instance.c_str());
Steven Moreland86a17f82019-09-10 10:18:00 -0700119 }
Steven Moreland2edde8e2020-04-30 17:04:54 -0700120
Steven Moreland2e293aa2020-09-23 00:25:16 +0000121 return found;
122}
123
Steven Morelandedd4e072021-04-21 00:27:29 +0000124static std::optional<std::string> getVintfUpdatableApex(const std::string& name) {
125 AidlName aname;
126 if (!AidlName::fill(name, &aname)) return std::nullopt;
127
128 std::optional<std::string> updatableViaApex;
129
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 updatableViaApex = manifestInstance.updatableViaApex();
137 return false; // break (libvintf uses opposite convention)
138 });
139 return false; // continue
140 });
141
142 return updatableViaApex;
143}
144
Devin Moore5e4c2f12021-09-09 22:36:33 +0000145static std::optional<ConnectionInfo> getVintfConnectionInfo(const std::string& name) {
146 AidlName aname;
147 if (!AidlName::fill(name, &aname)) return std::nullopt;
148
149 std::optional<std::string> ip;
150 std::optional<uint64_t> port;
151 forEachManifest([&](const ManifestWithDescription& mwd) {
152 mwd.manifest->forEachInstance([&](const auto& manifestInstance) {
153 if (manifestInstance.format() != vintf::HalFormat::AIDL) return true;
154 if (manifestInstance.package() != aname.package) return true;
155 if (manifestInstance.interface() != aname.iface) return true;
156 if (manifestInstance.instance() != aname.instance) return true;
157 ip = manifestInstance.ip();
158 port = manifestInstance.port();
159 return false; // break (libvintf uses opposite convention)
160 });
161 return false; // continue
162 });
163
164 if (ip.has_value() && port.has_value()) {
165 ConnectionInfo info;
166 info.ipAddress = *ip;
167 info.port = *port;
168 return std::make_optional<ConnectionInfo>(info);
169 } else {
170 return std::nullopt;
171 }
172}
173
Steven Moreland2e293aa2020-09-23 00:25:16 +0000174static std::vector<std::string> getVintfInstances(const std::string& interface) {
175 size_t lastDot = interface.rfind('.');
176 if (lastDot == std::string::npos) {
Pawan Wagh37526162022-09-29 21:55:26 +0000177 ALOGE("VINTF interfaces require names in Java package format (e.g. some.package.foo.IFoo) "
178 "but got: %s",
179 interface.c_str());
Steven Moreland2e293aa2020-09-23 00:25:16 +0000180 return {};
181 }
182 const std::string package = interface.substr(0, lastDot);
183 const std::string iface = interface.substr(lastDot+1);
184
185 std::vector<std::string> ret;
186 (void)forEachManifest([&](const ManifestWithDescription& mwd) {
187 auto instances = mwd.manifest->getAidlInstances(package, iface);
188 ret.insert(ret.end(), instances.begin(), instances.end());
189 return false; // continue
190 });
191
192 return ret;
Steven Moreland86a17f82019-09-10 10:18:00 -0700193}
Steven Morelandb82b8f82019-10-28 10:52:34 -0700194
195static bool meetsDeclarationRequirements(const sp<IBinder>& binder, const std::string& name) {
196 if (!Stability::requiresVintfDeclaration(binder)) {
197 return true;
198 }
199
200 return isVintfDeclared(name);
201}
Steven Moreland86a17f82019-09-10 10:18:00 -0700202#endif // !VENDORSERVICEMANAGER
203
Steven Morelandd13f08b2019-11-18 14:23:09 -0800204ServiceManager::ServiceManager(std::unique_ptr<Access>&& access) : mAccess(std::move(access)) {
Steven Moreland8d0c9a72020-04-30 16:51:56 -0700205// TODO(b/151696835): reenable performance hack when we solve bug, since with
206// this hack and other fixes, it is unlikely we will see even an ephemeral
207// failure when the manifest parse fails. The goal is that the manifest will
208// be read incorrectly and cause the process trying to register a HAL to
209// fail. If this is in fact an early boot kernel contention issue, then we
210// will get no failure, and by its absence, be signalled to invest more
211// effort in re-adding this performance hack.
212// #ifndef VENDORSERVICEMANAGER
213// // can process these at any times, don't want to delay first VINTF client
214// std::thread([] {
215// vintf::VintfObject::GetDeviceHalManifest();
216// vintf::VintfObject::GetFrameworkHalManifest();
217// }).detach();
218// #endif // !VENDORSERVICEMANAGER
Steven Morelandd13f08b2019-11-18 14:23:09 -0800219}
Steven Moreland130242d2019-08-26 17:41:32 -0700220ServiceManager::~ServiceManager() {
221 // this should only happen in tests
222
Jon Spivackf288b1d2019-12-19 17:15:51 -0800223 for (const auto& [name, callbacks] : mNameToRegistrationCallback) {
Steven Moreland27cfab02019-08-12 14:34:16 -0700224 CHECK(!callbacks.empty()) << name;
225 for (const auto& callback : callbacks) {
226 CHECK(callback != nullptr) << name;
227 }
228 }
229
Steven Moreland130242d2019-08-26 17:41:32 -0700230 for (const auto& [name, service] : mNameToService) {
231 CHECK(service.binder != nullptr) << name;
232 }
233}
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700234
235Status ServiceManager::getService(const std::string& name, sp<IBinder>* outBinder) {
Jon Spivack0d844302019-07-22 18:40:34 -0700236 *outBinder = tryGetService(name, true);
237 // returns ok regardless of result for legacy reasons
238 return Status::ok();
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700239}
240
241Status ServiceManager::checkService(const std::string& name, sp<IBinder>* outBinder) {
Jon Spivack0d844302019-07-22 18:40:34 -0700242 *outBinder = tryGetService(name, false);
243 // returns ok regardless of result for legacy reasons
244 return Status::ok();
245}
246
247sp<IBinder> ServiceManager::tryGetService(const std::string& name, bool startIfNotFound) {
Steven Morelanda9fe4742019-07-18 14:45:20 -0700248 auto ctx = mAccess->getCallingContext();
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700249
Jon Spivack0d844302019-07-22 18:40:34 -0700250 sp<IBinder> out;
Jon Spivack9f503a42019-10-22 16:49:19 -0700251 Service* service = nullptr;
Jon Spivack0d844302019-07-22 18:40:34 -0700252 if (auto it = mNameToService.find(name); it != mNameToService.end()) {
Jon Spivack9f503a42019-10-22 16:49:19 -0700253 service = &(it->second);
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700254
Jon Spivack9f503a42019-10-22 16:49:19 -0700255 if (!service->allowIsolated) {
Jon Spivack0d844302019-07-22 18:40:34 -0700256 uid_t appid = multiuser_get_app_id(ctx.uid);
257 bool isIsolated = appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END;
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700258
Jon Spivack0d844302019-07-22 18:40:34 -0700259 if (isIsolated) {
260 return nullptr;
261 }
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700262 }
Jon Spivack9f503a42019-10-22 16:49:19 -0700263 out = service->binder;
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700264 }
265
Steven Morelanda9fe4742019-07-18 14:45:20 -0700266 if (!mAccess->canFind(ctx, name)) {
Jon Spivack0d844302019-07-22 18:40:34 -0700267 return nullptr;
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700268 }
269
Jon Spivack0d844302019-07-22 18:40:34 -0700270 if (!out && startIfNotFound) {
271 tryStartService(name);
272 }
273
Jon Spivack9f503a42019-10-22 16:49:19 -0700274 if (out) {
275 // Setting this guarantee each time we hand out a binder ensures that the client-checking
276 // loop knows about the event even if the client immediately drops the service
277 service->guaranteeClient = true;
278 }
279
Jon Spivack0d844302019-07-22 18:40:34 -0700280 return out;
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700281}
282
Steven Moreland905e2e82019-07-17 11:05:45 -0700283bool isValidServiceName(const std::string& name) {
284 if (name.size() == 0) return false;
285 if (name.size() > 127) return false;
286
287 for (char c : name) {
Steven Morelandbb7951d2019-08-20 16:58:25 -0700288 if (c == '_' || c == '-' || c == '.' || c == '/') continue;
Steven Moreland905e2e82019-07-17 11:05:45 -0700289 if (c >= 'a' && c <= 'z') continue;
290 if (c >= 'A' && c <= 'Z') continue;
291 if (c >= '0' && c <= '9') continue;
292 return false;
293 }
294
295 return true;
296}
297
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700298Status ServiceManager::addService(const std::string& name, const sp<IBinder>& binder, bool allowIsolated, int32_t dumpPriority) {
Steven Morelanda9fe4742019-07-18 14:45:20 -0700299 auto ctx = mAccess->getCallingContext();
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700300
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700301 if (multiuser_get_app_id(ctx.uid) >= AID_APP) {
Steven Morelandac2d2852022-03-18 18:15:20 +0000302 return Status::fromExceptionCode(Status::EX_SECURITY, "App UIDs cannot add services");
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700303 }
304
Steven Morelanda9fe4742019-07-18 14:45:20 -0700305 if (!mAccess->canAdd(ctx, name)) {
Steven Morelandac2d2852022-03-18 18:15:20 +0000306 return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denial");
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700307 }
308
309 if (binder == nullptr) {
Steven Morelandac2d2852022-03-18 18:15:20 +0000310 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, "Null binder");
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700311 }
312
Steven Moreland905e2e82019-07-17 11:05:45 -0700313 if (!isValidServiceName(name)) {
Pawan Wagh37526162022-09-29 21:55:26 +0000314 ALOGE("Invalid service name: %s", name.c_str());
Steven Morelandac2d2852022-03-18 18:15:20 +0000315 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, "Invalid service name");
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700316 }
317
Steven Moreland86a17f82019-09-10 10:18:00 -0700318#ifndef VENDORSERVICEMANAGER
319 if (!meetsDeclarationRequirements(binder, name)) {
320 // already logged
Steven Morelandac2d2852022-03-18 18:15:20 +0000321 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, "VINTF declaration error");
Steven Moreland86a17f82019-09-10 10:18:00 -0700322 }
323#endif // !VENDORSERVICEMANAGER
324
Steven Moreland88860b02019-08-12 14:24:14 -0700325 // implicitly unlinked when the binder is removed
Steven Morelandb0983182021-04-02 03:14:04 +0000326 if (binder->remoteBinder() != nullptr &&
327 binder->linkToDeath(sp<ServiceManager>::fromExisting(this)) != OK) {
Pawan Wagh37526162022-09-29 21:55:26 +0000328 ALOGE("Could not linkToDeath when adding %s", name.c_str());
Steven Morelandac2d2852022-03-18 18:15:20 +0000329 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE, "linkToDeath failure");
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700330 }
331
Steven Moreland7ee423b2022-09-24 03:52:08 +0000332 auto it = mNameToService.find(name);
333 if (it != mNameToService.end()) {
334 const Service& existing = it->second;
335
336 // We could do better than this because if the other service dies, it
337 // may not have an entry here. However, this case is unlikely. We are
338 // only trying to detect when two different services are accidentally installed.
339
340 if (existing.ctx.uid != ctx.uid) {
Pawan Wagh37526162022-09-29 21:55:26 +0000341 ALOGW("Service '%s' originally registered from UID %u but it is now being registered "
342 "from UID %u. Multiple instances installed?",
343 name.c_str(), existing.ctx.uid, ctx.uid);
Steven Moreland7ee423b2022-09-24 03:52:08 +0000344 }
345
346 if (existing.ctx.sid != ctx.sid) {
Pawan Wagh37526162022-09-29 21:55:26 +0000347 ALOGW("Service '%s' originally registered from SID %s but it is now being registered "
348 "from SID %s. Multiple instances installed?",
349 name.c_str(), existing.ctx.sid.c_str(), ctx.sid.c_str());
Steven Moreland7ee423b2022-09-24 03:52:08 +0000350 }
351
Pawan Wagh37526162022-09-29 21:55:26 +0000352 ALOGI("Service '%s' originally registered from PID %d but it is being registered again "
353 "from PID %d. Bad state? Late death notification? Multiple instances installed?",
354 name.c_str(), existing.ctx.debugPid, ctx.debugPid);
Steven Moreland7ee423b2022-09-24 03:52:08 +0000355 }
356
Devin Moore05ffe522020-08-06 13:58:29 -0700357 // Overwrite the old service if it exists
Steven Moreland7ee423b2022-09-24 03:52:08 +0000358 mNameToService[name] = Service{
359 .binder = binder,
360 .allowIsolated = allowIsolated,
361 .dumpPriority = dumpPriority,
362 .ctx = ctx,
Devin Moore05ffe522020-08-06 13:58:29 -0700363 };
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700364
Steven Moreland7ee423b2022-09-24 03:52:08 +0000365 if (auto it = mNameToRegistrationCallback.find(name); it != mNameToRegistrationCallback.end()) {
Steven Moreland27cfab02019-08-12 14:34:16 -0700366 for (const sp<IServiceCallback>& cb : it->second) {
Devin Moore05ffe522020-08-06 13:58:29 -0700367 mNameToService[name].guaranteeClient = true;
Steven Moreland27cfab02019-08-12 14:34:16 -0700368 // permission checked in registerForNotifications
369 cb->onRegistration(name, binder);
370 }
371 }
372
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700373 return Status::ok();
374}
375
376Status ServiceManager::listServices(int32_t dumpPriority, std::vector<std::string>* outList) {
Steven Morelanda9fe4742019-07-18 14:45:20 -0700377 if (!mAccess->canList(mAccess->getCallingContext())) {
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700378 return Status::fromExceptionCode(Status::EX_SECURITY);
379 }
380
381 size_t toReserve = 0;
382 for (auto const& [name, service] : mNameToService) {
383 (void) name;
384
385 if (service.dumpPriority & dumpPriority) ++toReserve;
386 }
387
388 CHECK(outList->empty());
389
390 outList->reserve(toReserve);
391 for (auto const& [name, service] : mNameToService) {
392 (void) service;
393
394 if (service.dumpPriority & dumpPriority) {
395 outList->push_back(name);
396 }
397 }
398
399 return Status::ok();
400}
401
Steven Moreland27cfab02019-08-12 14:34:16 -0700402Status ServiceManager::registerForNotifications(
403 const std::string& name, const sp<IServiceCallback>& callback) {
404 auto ctx = mAccess->getCallingContext();
405
406 if (!mAccess->canFind(ctx, name)) {
407 return Status::fromExceptionCode(Status::EX_SECURITY);
408 }
409
410 if (!isValidServiceName(name)) {
Pawan Wagh37526162022-09-29 21:55:26 +0000411 ALOGE("Invalid service name: %s", name.c_str());
Steven Moreland27cfab02019-08-12 14:34:16 -0700412 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
413 }
414
415 if (callback == nullptr) {
416 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
417 }
418
Steven Morelandb0983182021-04-02 03:14:04 +0000419 if (OK !=
420 IInterface::asBinder(callback)->linkToDeath(
421 sp<ServiceManager>::fromExisting(this))) {
Pawan Wagh37526162022-09-29 21:55:26 +0000422 ALOGE("Could not linkToDeath when adding %s", name.c_str());
Steven Moreland27cfab02019-08-12 14:34:16 -0700423 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
424 }
425
Jon Spivackf288b1d2019-12-19 17:15:51 -0800426 mNameToRegistrationCallback[name].push_back(callback);
Steven Moreland27cfab02019-08-12 14:34:16 -0700427
428 if (auto it = mNameToService.find(name); it != mNameToService.end()) {
429 const sp<IBinder>& binder = it->second.binder;
430
431 // never null if an entry exists
432 CHECK(binder != nullptr) << name;
433 callback->onRegistration(name, binder);
434 }
435
436 return Status::ok();
437}
438Status ServiceManager::unregisterForNotifications(
439 const std::string& name, const sp<IServiceCallback>& callback) {
440 auto ctx = mAccess->getCallingContext();
441
442 if (!mAccess->canFind(ctx, name)) {
443 return Status::fromExceptionCode(Status::EX_SECURITY);
444 }
445
446 bool found = false;
447
Jon Spivackf288b1d2019-12-19 17:15:51 -0800448 auto it = mNameToRegistrationCallback.find(name);
449 if (it != mNameToRegistrationCallback.end()) {
450 removeRegistrationCallback(IInterface::asBinder(callback), &it, &found);
Steven Moreland27cfab02019-08-12 14:34:16 -0700451 }
452
453 if (!found) {
Pawan Wagh37526162022-09-29 21:55:26 +0000454 ALOGE("Trying to unregister callback, but none exists %s", name.c_str());
Steven Moreland27cfab02019-08-12 14:34:16 -0700455 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
456 }
457
458 return Status::ok();
459}
460
Steven Morelandb82b8f82019-10-28 10:52:34 -0700461Status ServiceManager::isDeclared(const std::string& name, bool* outReturn) {
462 auto ctx = mAccess->getCallingContext();
463
464 if (!mAccess->canFind(ctx, name)) {
465 return Status::fromExceptionCode(Status::EX_SECURITY);
466 }
467
468 *outReturn = false;
469
470#ifndef VENDORSERVICEMANAGER
471 *outReturn = isVintfDeclared(name);
472#endif
473 return Status::ok();
474}
475
Steven Moreland2e293aa2020-09-23 00:25:16 +0000476binder::Status ServiceManager::getDeclaredInstances(const std::string& interface, std::vector<std::string>* outReturn) {
477 auto ctx = mAccess->getCallingContext();
478
479 std::vector<std::string> allInstances;
480#ifndef VENDORSERVICEMANAGER
481 allInstances = getVintfInstances(interface);
482#endif
483
484 outReturn->clear();
485
486 for (const std::string& instance : allInstances) {
Steven Moreland2e293aa2020-09-23 00:25:16 +0000487 if (mAccess->canFind(ctx, interface + "/" + instance)) {
488 outReturn->push_back(instance);
489 }
490 }
491
492 if (outReturn->size() == 0 && allInstances.size() != 0) {
493 return Status::fromExceptionCode(Status::EX_SECURITY);
494 }
495
496 return Status::ok();
497}
498
Steven Morelandedd4e072021-04-21 00:27:29 +0000499Status ServiceManager::updatableViaApex(const std::string& name,
500 std::optional<std::string>* outReturn) {
501 auto ctx = mAccess->getCallingContext();
502
503 if (!mAccess->canFind(ctx, name)) {
504 return Status::fromExceptionCode(Status::EX_SECURITY);
505 }
506
507 *outReturn = std::nullopt;
508
509#ifndef VENDORSERVICEMANAGER
510 *outReturn = getVintfUpdatableApex(name);
511#endif
512 return Status::ok();
513}
514
Devin Moore5e4c2f12021-09-09 22:36:33 +0000515Status ServiceManager::getConnectionInfo(const std::string& name,
516 std::optional<ConnectionInfo>* outReturn) {
517 auto ctx = mAccess->getCallingContext();
518
519 if (!mAccess->canFind(ctx, name)) {
520 return Status::fromExceptionCode(Status::EX_SECURITY);
521 }
522
523 *outReturn = std::nullopt;
524
525#ifndef VENDORSERVICEMANAGER
526 *outReturn = getVintfConnectionInfo(name);
527#endif
528 return Status::ok();
529}
530
Jon Spivackf288b1d2019-12-19 17:15:51 -0800531void ServiceManager::removeRegistrationCallback(const wp<IBinder>& who,
532 ServiceCallbackMap::iterator* it,
Steven Moreland27cfab02019-08-12 14:34:16 -0700533 bool* found) {
534 std::vector<sp<IServiceCallback>>& listeners = (*it)->second;
535
536 for (auto lit = listeners.begin(); lit != listeners.end();) {
537 if (IInterface::asBinder(*lit) == who) {
538 if(found) *found = true;
539 lit = listeners.erase(lit);
540 } else {
541 ++lit;
542 }
543 }
544
545 if (listeners.empty()) {
Jon Spivackf288b1d2019-12-19 17:15:51 -0800546 *it = mNameToRegistrationCallback.erase(*it);
Steven Moreland27cfab02019-08-12 14:34:16 -0700547 } else {
Jon Spivacke223f082019-11-19 16:21:20 -0800548 (*it)++;
Steven Moreland27cfab02019-08-12 14:34:16 -0700549 }
550}
551
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700552void ServiceManager::binderDied(const wp<IBinder>& who) {
553 for (auto it = mNameToService.begin(); it != mNameToService.end();) {
554 if (who == it->second.binder) {
555 it = mNameToService.erase(it);
556 } else {
557 ++it;
558 }
559 }
Steven Moreland27cfab02019-08-12 14:34:16 -0700560
Jon Spivackf288b1d2019-12-19 17:15:51 -0800561 for (auto it = mNameToRegistrationCallback.begin(); it != mNameToRegistrationCallback.end();) {
562 removeRegistrationCallback(who, &it, nullptr /*found*/);
Steven Moreland27cfab02019-08-12 14:34:16 -0700563 }
Jon Spivack9f503a42019-10-22 16:49:19 -0700564
565 for (auto it = mNameToClientCallback.begin(); it != mNameToClientCallback.end();) {
566 removeClientCallback(who, &it);
567 }
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700568}
569
Jon Spivack0d844302019-07-22 18:40:34 -0700570void ServiceManager::tryStartService(const std::string& name) {
571 ALOGI("Since '%s' could not be found, trying to start it as a lazy AIDL service",
572 name.c_str());
573
574 std::thread([=] {
Steven Morelandbfe9fba2021-04-27 18:39:57 +0000575 if (!base::SetProperty("ctl.interface_start", "aidl/" + name)) {
Pawan Wagh37526162022-09-29 21:55:26 +0000576 ALOGI("Tried to start aidl service %s as a lazy service, but was unable to. Usually "
577 "this happens when a "
578 "service is not installed, but if the service is intended to be used as a "
579 "lazy service, then it may be configured incorrectly.",
580 name.c_str());
Steven Morelandbfe9fba2021-04-27 18:39:57 +0000581 }
Jon Spivack0d844302019-07-22 18:40:34 -0700582 }).detach();
583}
584
Jon Spivack9f503a42019-10-22 16:49:19 -0700585Status ServiceManager::registerClientCallback(const std::string& name, const sp<IBinder>& service,
586 const sp<IClientCallback>& cb) {
587 if (cb == nullptr) {
588 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
589 }
590
591 auto ctx = mAccess->getCallingContext();
592 if (!mAccess->canAdd(ctx, name)) {
593 return Status::fromExceptionCode(Status::EX_SECURITY);
594 }
595
596 auto serviceIt = mNameToService.find(name);
597 if (serviceIt == mNameToService.end()) {
Pawan Wagh37526162022-09-29 21:55:26 +0000598 ALOGE("Could not add callback for nonexistent service: %s", name.c_str());
Jon Spivack9f503a42019-10-22 16:49:19 -0700599 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
600 }
601
Steven Moreland7ee423b2022-09-24 03:52:08 +0000602 if (serviceIt->second.ctx.debugPid != IPCThreadState::self()->getCallingPid()) {
Pawan Wagh37526162022-09-29 21:55:26 +0000603 ALOGW("Only a server can register for client callbacks (for %s)", name.c_str());
Jon Spivack9f503a42019-10-22 16:49:19 -0700604 return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION);
605 }
606
607 if (serviceIt->second.binder != service) {
Pawan Wagh37526162022-09-29 21:55:26 +0000608 ALOGW("Tried to register client callback for %s but a different service is registered "
609 "under this name.",
610 name.c_str());
Jon Spivack9f503a42019-10-22 16:49:19 -0700611 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
612 }
613
Steven Morelandb0983182021-04-02 03:14:04 +0000614 if (OK !=
615 IInterface::asBinder(cb)->linkToDeath(sp<ServiceManager>::fromExisting(this))) {
Pawan Wagh37526162022-09-29 21:55:26 +0000616 ALOGE("Could not linkToDeath when adding client callback for %s", name.c_str());
Jon Spivack9f503a42019-10-22 16:49:19 -0700617 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
618 }
619
620 mNameToClientCallback[name].push_back(cb);
621
622 return Status::ok();
623}
624
625void ServiceManager::removeClientCallback(const wp<IBinder>& who,
626 ClientCallbackMap::iterator* it) {
627 std::vector<sp<IClientCallback>>& listeners = (*it)->second;
628
629 for (auto lit = listeners.begin(); lit != listeners.end();) {
630 if (IInterface::asBinder(*lit) == who) {
631 lit = listeners.erase(lit);
632 } else {
633 ++lit;
634 }
635 }
636
637 if (listeners.empty()) {
638 *it = mNameToClientCallback.erase(*it);
639 } else {
640 (*it)++;
641 }
642}
643
644ssize_t ServiceManager::Service::getNodeStrongRefCount() {
Steven Morelandb0983182021-04-02 03:14:04 +0000645 sp<BpBinder> bpBinder = sp<BpBinder>::fromExisting(binder->remoteBinder());
Jon Spivack9f503a42019-10-22 16:49:19 -0700646 if (bpBinder == nullptr) return -1;
647
Steven Morelande8393882020-12-18 02:27:20 +0000648 return ProcessState::self()->getStrongRefCountForNode(bpBinder);
Jon Spivack9f503a42019-10-22 16:49:19 -0700649}
650
651void ServiceManager::handleClientCallbacks() {
652 for (const auto& [name, service] : mNameToService) {
Jon Spivackd9533c22020-01-27 22:19:22 +0000653 handleServiceClientCallback(name, true);
Jon Spivack9f503a42019-10-22 16:49:19 -0700654 }
655}
656
Jon Spivackd9533c22020-01-27 22:19:22 +0000657ssize_t ServiceManager::handleServiceClientCallback(const std::string& serviceName,
658 bool isCalledOnInterval) {
Jon Spivack9f503a42019-10-22 16:49:19 -0700659 auto serviceIt = mNameToService.find(serviceName);
660 if (serviceIt == mNameToService.end() || mNameToClientCallback.count(serviceName) < 1) {
661 return -1;
662 }
663
664 Service& service = serviceIt->second;
665 ssize_t count = service.getNodeStrongRefCount();
666
667 // binder driver doesn't support this feature
668 if (count == -1) return count;
669
670 bool hasClients = count > 1; // this process holds a strong count
671
672 if (service.guaranteeClient) {
673 // we have no record of this client
674 if (!service.hasClients && !hasClients) {
675 sendClientCallbackNotifications(serviceName, true);
676 }
677
678 // guarantee is temporary
679 service.guaranteeClient = false;
680 }
681
Jon Spivackd9533c22020-01-27 22:19:22 +0000682 // only send notifications if this was called via the interval checking workflow
683 if (isCalledOnInterval) {
684 if (hasClients && !service.hasClients) {
685 // client was retrieved in some other way
686 sendClientCallbackNotifications(serviceName, true);
687 }
Jon Spivack9f503a42019-10-22 16:49:19 -0700688
Jon Spivackd9533c22020-01-27 22:19:22 +0000689 // there are no more clients, but the callback has not been called yet
690 if (!hasClients && service.hasClients) {
691 sendClientCallbackNotifications(serviceName, false);
692 }
Jon Spivack9f503a42019-10-22 16:49:19 -0700693 }
694
695 return count;
696}
697
698void ServiceManager::sendClientCallbackNotifications(const std::string& serviceName, bool hasClients) {
699 auto serviceIt = mNameToService.find(serviceName);
700 if (serviceIt == mNameToService.end()) {
Pawan Wagh37526162022-09-29 21:55:26 +0000701 ALOGW("sendClientCallbackNotifications could not find service %s", serviceName.c_str());
Jon Spivack9f503a42019-10-22 16:49:19 -0700702 return;
703 }
704 Service& service = serviceIt->second;
705
706 CHECK(hasClients != service.hasClients) << "Record shows: " << service.hasClients
707 << " so we can't tell clients again that we have client: " << hasClients;
708
Pawan Wagh37526162022-09-29 21:55:26 +0000709 ALOGI("Notifying %s they have clients: %d", serviceName.c_str(), hasClients);
Jon Spivack9f503a42019-10-22 16:49:19 -0700710
711 auto ccIt = mNameToClientCallback.find(serviceName);
712 CHECK(ccIt != mNameToClientCallback.end())
713 << "sendClientCallbackNotifications could not find callbacks for service ";
714
715 for (const auto& callback : ccIt->second) {
716 callback->onClients(service.binder, hasClients);
717 }
718
719 service.hasClients = hasClients;
720}
721
722Status ServiceManager::tryUnregisterService(const std::string& name, const sp<IBinder>& binder) {
723 if (binder == nullptr) {
724 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
725 }
726
727 auto ctx = mAccess->getCallingContext();
728 if (!mAccess->canAdd(ctx, name)) {
729 return Status::fromExceptionCode(Status::EX_SECURITY);
730 }
731
732 auto serviceIt = mNameToService.find(name);
733 if (serviceIt == mNameToService.end()) {
Pawan Wagh37526162022-09-29 21:55:26 +0000734 ALOGW("Tried to unregister %s, but that service wasn't registered to begin with.",
735 name.c_str());
Jon Spivack9f503a42019-10-22 16:49:19 -0700736 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
737 }
738
Steven Moreland7ee423b2022-09-24 03:52:08 +0000739 if (serviceIt->second.ctx.debugPid != IPCThreadState::self()->getCallingPid()) {
Pawan Wagh37526162022-09-29 21:55:26 +0000740 ALOGW("Only a server can unregister itself (for %s)", name.c_str());
Jon Spivack9f503a42019-10-22 16:49:19 -0700741 return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION);
742 }
743
744 sp<IBinder> storedBinder = serviceIt->second.binder;
745
746 if (binder != storedBinder) {
Pawan Wagh37526162022-09-29 21:55:26 +0000747 ALOGW("Tried to unregister %s, but a different service is registered under this name.",
748 name.c_str());
Jon Spivack9f503a42019-10-22 16:49:19 -0700749 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
750 }
751
Jon Spivack0f18f2c2020-03-13 20:45:18 -0700752 if (serviceIt->second.guaranteeClient) {
Pawan Wagh37526162022-09-29 21:55:26 +0000753 ALOGI("Tried to unregister %s, but there is about to be a client.", name.c_str());
Jon Spivack0f18f2c2020-03-13 20:45:18 -0700754 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
755 }
756
Jon Spivackd9533c22020-01-27 22:19:22 +0000757 int clients = handleServiceClientCallback(name, false);
Jon Spivack9f503a42019-10-22 16:49:19 -0700758
759 // clients < 0: feature not implemented or other error. Assume clients.
760 // Otherwise:
761 // - kernel driver will hold onto one refcount (during this transaction)
762 // - servicemanager has a refcount (guaranteed by this transaction)
763 // So, if clients > 2, then at least one other service on the system must hold a refcount.
764 if (clients < 0 || clients > 2) {
765 // client callbacks are either disabled or there are other clients
Pawan Wagh37526162022-09-29 21:55:26 +0000766 ALOGI("Tried to unregister %s, but there are clients: %d", name.c_str(), clients);
Jon Spivack620d2dc2020-03-06 13:58:01 -0800767 // Set this flag to ensure the clients are acknowledged in the next callback
768 serviceIt->second.guaranteeClient = true;
Jon Spivack9f503a42019-10-22 16:49:19 -0700769 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
770 }
771
772 mNameToService.erase(name);
773
774 return Status::ok();
775}
776
Steven Moreland3ea43272021-01-28 22:49:28 +0000777Status ServiceManager::getServiceDebugInfo(std::vector<ServiceDebugInfo>* outReturn) {
778 if (!mAccess->canList(mAccess->getCallingContext())) {
779 return Status::fromExceptionCode(Status::EX_SECURITY);
780 }
781
782 outReturn->reserve(mNameToService.size());
783 for (auto const& [name, service] : mNameToService) {
784 ServiceDebugInfo info;
785 info.name = name;
Steven Moreland7ee423b2022-09-24 03:52:08 +0000786 info.debugPid = service.ctx.debugPid;
Steven Moreland3ea43272021-01-28 22:49:28 +0000787
788 outReturn->push_back(std::move(info));
789 }
790
791 return Status::ok();
792}
793
Pawan Wagh243888e2022-09-20 19:37:35 +0000794void ServiceManager::clear() {
795 mNameToService.clear();
796 mNameToRegistrationCallback.clear();
797 mNameToClientCallback.clear();
798}
799
Steven Moreland8d0c9a72020-04-30 16:51:56 -0700800} // namespace android