blob: 9f458018a8f8658d73f1903f1b1fcc21efb35ffa [file] [log] [blame]
Steven Morelandfe66b732019-02-01 14:29:45 -08001/*
2 * Copyright (C) 2016 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
Steven Moreland5fb3d652016-11-03 13:45:18 -070017#define LOG_TAG "hwservicemanager"
18
Steven Morelandd83d1102016-10-25 15:01:47 -070019#include "ServiceManager.h"
Steven Moreland37aed802017-04-06 09:16:42 -070020#include "Vintf.h"
Steven Morelandd83d1102016-10-25 15:01:47 -070021
Steven Moreland5fb3d652016-11-03 13:45:18 -070022#include <android-base/logging.h>
Steven Moreland5a317452017-10-05 18:49:48 -070023#include <android-base/properties.h>
Steven Morelandcdf94722017-03-21 12:16:31 -070024#include <hwbinder/IPCThreadState.h>
Steven Morelandd83d1102016-10-25 15:01:47 -070025#include <hidl/HidlSupport.h>
Steven Moreland6f4fbe12017-07-21 18:07:42 -070026#include <hidl/HidlTransportSupport.h>
Steven Moreland5fb3d652016-11-03 13:45:18 -070027#include <regex>
Steven Moreland76237812016-11-08 15:59:04 -080028#include <sstream>
Steven Moreland58cef2c2018-01-24 16:41:38 -080029#include <thread>
Steven Morelandd83d1102016-10-25 15:01:47 -070030
Steven Morelandcdf94722017-03-21 12:16:31 -070031using android::hardware::IPCThreadState;
Steven Morelandd8536202018-09-26 10:56:19 -070032using ::android::hardware::interfacesEqual;
Steven Morelandcdf94722017-03-21 12:16:31 -070033
Steven Morelandd83d1102016-10-25 15:01:47 -070034namespace android {
35namespace hidl {
36namespace manager {
Steven Morelandd83d1102016-10-25 15:01:47 -070037namespace implementation {
38
Martijn Coenen7fafc142017-03-06 16:17:51 +010039static constexpr uint64_t kServiceDiedCookie = 0;
40static constexpr uint64_t kPackageListenerDiedCookie = 1;
41static constexpr uint64_t kServiceListenerDiedCookie = 2;
Steven Morelandd8536202018-09-26 10:56:19 -070042static constexpr uint64_t kClientCallbackDiedCookie = 3;
Martijn Coenen7fafc142017-03-06 16:17:51 +010043
Yifan Hong83c49f62017-01-25 14:16:34 -080044size_t ServiceManager::countExistingService() const {
45 size_t total = 0;
46 forEachExistingService([&] (const HidlService *) {
47 ++total;
Steven Morelandd8536202018-09-26 10:56:19 -070048 return true; // continue
Yifan Hong83c49f62017-01-25 14:16:34 -080049 });
50 return total;
51}
52
Steven Morelandd8536202018-09-26 10:56:19 -070053void ServiceManager::forEachExistingService(std::function<bool(const HidlService *)> f) const {
54 forEachServiceEntry([&] (const HidlService *service) {
Yifan Hongee531a82017-02-03 15:10:18 -080055 if (service->getService() == nullptr) {
Steven Morelandd8536202018-09-26 10:56:19 -070056 return true; // continue
Yifan Hongee531a82017-02-03 15:10:18 -080057 }
Steven Morelandd8536202018-09-26 10:56:19 -070058 return f(service);
Yifan Hongee531a82017-02-03 15:10:18 -080059 });
60}
61
Steven Morelandd8536202018-09-26 10:56:19 -070062void ServiceManager::forEachExistingService(std::function<bool(HidlService *)> f) {
63 forEachServiceEntry([&] (HidlService *service) {
64 if (service->getService() == nullptr) {
65 return true; // continue
66 }
67 return f(service);
68 });
69}
Yifan Hong83c49f62017-01-25 14:16:34 -080070
Steven Morelandd8536202018-09-26 10:56:19 -070071void ServiceManager::forEachServiceEntry(std::function<bool(const HidlService *)> f) const {
72 for (const auto& interfaceMapping : mServiceMap) {
73 const auto& instanceMap = interfaceMapping.second.getInstanceMap();
74
75 for (const auto& instanceMapping : instanceMap) {
76 if (!f(instanceMapping.second.get())) {
77 return;
78 }
79 }
80 }
81}
82
83void ServiceManager::forEachServiceEntry(std::function<bool(HidlService *)> f) {
84 for (auto& interfaceMapping : mServiceMap) {
85 auto& instanceMap = interfaceMapping.second.getInstanceMap();
86
87 for (auto& instanceMapping : instanceMap) {
88 if (!f(instanceMapping.second.get())) {
89 return;
90 }
Yifan Hong83c49f62017-01-25 14:16:34 -080091 }
92 }
93}
94
Steven Morelanddbaab552019-01-24 19:00:04 -080095HidlService* ServiceManager::lookup(const std::string& fqName, const std::string& name) {
96 auto ifaceIt = mServiceMap.find(fqName);
97 if (ifaceIt == mServiceMap.end()) {
98 return nullptr;
99 }
100
101 PackageInterfaceMap &ifaceMap = ifaceIt->second;
102
103 HidlService *hidlService = ifaceMap.lookup(name);
104
105 return hidlService;
106}
107
Martijn Coenen7fafc142017-03-06 16:17:51 +0100108void ServiceManager::serviceDied(uint64_t cookie, const wp<IBase>& who) {
Steven Moreland3af80b92018-05-09 15:31:18 -0700109 bool serviceRemoved = false;
Martijn Coenen7fafc142017-03-06 16:17:51 +0100110 switch (cookie) {
111 case kServiceDiedCookie:
Steven Moreland3af80b92018-05-09 15:31:18 -0700112 serviceRemoved = removeService(who, nullptr /* restrictToInstanceName */);
Martijn Coenen7fafc142017-03-06 16:17:51 +0100113 break;
114 case kPackageListenerDiedCookie:
Steven Moreland3af80b92018-05-09 15:31:18 -0700115 serviceRemoved = removePackageListener(who);
Martijn Coenen7fafc142017-03-06 16:17:51 +0100116 break;
117 case kServiceListenerDiedCookie:
Steven Moreland3af80b92018-05-09 15:31:18 -0700118 serviceRemoved = removeServiceListener(who);
Martijn Coenen7fafc142017-03-06 16:17:51 +0100119 break;
Steven Morelandd8536202018-09-26 10:56:19 -0700120 case kClientCallbackDiedCookie: {
121 sp<IBase> base = who.promote();
122 IClientCallback* callback = static_cast<IClientCallback*>(base.get());
123 serviceRemoved = unregisterClientCallback(nullptr /*service*/,
124 sp<IClientCallback>(callback));
125 } break;
Martijn Coenen7fafc142017-03-06 16:17:51 +0100126 }
Steven Moreland3af80b92018-05-09 15:31:18 -0700127
128 if (!serviceRemoved) {
Steven Morelandd8536202018-09-26 10:56:19 -0700129 LOG(ERROR) << "Received death notification but interface instance not removed. Cookie: "
130 << cookie << " Service pointer: " << who.promote().get();
Steven Moreland3af80b92018-05-09 15:31:18 -0700131 }
Martijn Coenen46847a62016-12-19 05:36:12 +0100132}
133
Steven Moreland2173d3c2016-11-09 15:00:58 -0800134ServiceManager::InstanceMap &ServiceManager::PackageInterfaceMap::getInstanceMap() {
135 return mInstanceMap;
Steven Moreland5fb3d652016-11-03 13:45:18 -0700136}
137
Steven Moreland2173d3c2016-11-09 15:00:58 -0800138const ServiceManager::InstanceMap &ServiceManager::PackageInterfaceMap::getInstanceMap() const {
139 return mInstanceMap;
Steven Moreland5fb3d652016-11-03 13:45:18 -0700140}
141
Steven Morelandd544cf62017-01-04 15:24:32 -0800142const HidlService *ServiceManager::PackageInterfaceMap::lookup(
143 const std::string &name) const {
144 auto it = mInstanceMap.find(name);
Steven Moreland76237812016-11-08 15:59:04 -0800145
Steven Morelandd544cf62017-01-04 15:24:32 -0800146 if (it == mInstanceMap.end()) {
147 return nullptr;
Steven Moreland5fb3d652016-11-03 13:45:18 -0700148 }
149
Steven Morelandd544cf62017-01-04 15:24:32 -0800150 return it->second.get();
Steven Moreland2173d3c2016-11-09 15:00:58 -0800151}
Steven Moreland5fb3d652016-11-03 13:45:18 -0700152
Steven Morelandd544cf62017-01-04 15:24:32 -0800153HidlService *ServiceManager::PackageInterfaceMap::lookup(
154 const std::string &name) {
Steven Moreland5fb3d652016-11-03 13:45:18 -0700155
Steven Moreland2173d3c2016-11-09 15:00:58 -0800156 return const_cast<HidlService*>(
Steven Morelandd544cf62017-01-04 15:24:32 -0800157 const_cast<const PackageInterfaceMap*>(this)->lookup(name));
Steven Moreland2173d3c2016-11-09 15:00:58 -0800158}
159
160void ServiceManager::PackageInterfaceMap::insertService(
161 std::unique_ptr<HidlService> &&service) {
Steven Morelandd544cf62017-01-04 15:24:32 -0800162 mInstanceMap.insert({service->getInstanceName(), std::move(service)});
Steven Moreland2173d3c2016-11-09 15:00:58 -0800163}
164
165void ServiceManager::PackageInterfaceMap::sendPackageRegistrationNotification(
166 const hidl_string &fqName,
Martijn Coenen7fafc142017-03-06 16:17:51 +0100167 const hidl_string &instanceName) {
Steven Moreland2173d3c2016-11-09 15:00:58 -0800168
Martijn Coenen7fafc142017-03-06 16:17:51 +0100169 for (auto it = mPackageListeners.begin(); it != mPackageListeners.end();) {
170 auto ret = (*it)->onRegistration(fqName, instanceName, false /* preexisting */);
171 if (ret.isOk()) {
172 ++it;
173 } else {
174 LOG(ERROR) << "Dropping registration callback for " << fqName << "/" << instanceName
175 << ": transport error.";
176 it = mPackageListeners.erase(it);
177 }
Steven Moreland2173d3c2016-11-09 15:00:58 -0800178 }
179}
Steven Moreland2173d3c2016-11-09 15:00:58 -0800180
Martijn Coenen7fafc142017-03-06 16:17:51 +0100181void ServiceManager::PackageInterfaceMap::addPackageListener(sp<IServiceNotification> listener) {
Steven Moreland2173d3c2016-11-09 15:00:58 -0800182 for (const auto &instanceMapping : mInstanceMap) {
183 const std::unique_ptr<HidlService> &service = instanceMapping.second;
184
185 if (service->getService() == nullptr) {
186 continue;
187 }
188
Steven Moreland30acc222017-01-26 11:44:38 -0800189 auto ret = listener->onRegistration(
Steven Morelandd544cf62017-01-04 15:24:32 -0800190 service->getInterfaceName(),
191 service->getInstanceName(),
192 true /* preexisting */);
Martijn Coenen7fafc142017-03-06 16:17:51 +0100193 if (!ret.isOk()) {
194 LOG(ERROR) << "Not adding package listener for " << service->getInterfaceName()
195 << "/" << service->getInstanceName() << ": transport error "
196 << "when sending notification for already registered instance.";
197 return;
198 }
Steven Moreland2173d3c2016-11-09 15:00:58 -0800199 }
Martijn Coenen7fafc142017-03-06 16:17:51 +0100200 mPackageListeners.push_back(listener);
201}
202
203bool ServiceManager::PackageInterfaceMap::removePackageListener(const wp<IBase>& who) {
204 bool found = false;
205
206 for (auto it = mPackageListeners.begin(); it != mPackageListeners.end();) {
Steven Moreland6f4fbe12017-07-21 18:07:42 -0700207 if (interfacesEqual(*it, who.promote())) {
Martijn Coenen7fafc142017-03-06 16:17:51 +0100208 it = mPackageListeners.erase(it);
209 found = true;
210 } else {
211 ++it;
212 }
213 }
214
215 return found;
Steven Moreland5fb3d652016-11-03 13:45:18 -0700216}
217
Steven Moreland6f4fbe12017-07-21 18:07:42 -0700218bool ServiceManager::PackageInterfaceMap::removeServiceListener(const wp<IBase>& who) {
Steven Moreland6f4fbe12017-07-21 18:07:42 -0700219 bool found = false;
220
221 for (auto &servicePair : getInstanceMap()) {
222 const std::unique_ptr<HidlService> &service = servicePair.second;
223 found |= service->removeListener(who);
224 }
225
226 return found;
227}
228
Steven Moreland5a317452017-10-05 18:49:48 -0700229static void tryStartService(const std::string& fqName, const std::string& name) {
230 using ::android::base::SetProperty;
231
Steven Moreland58cef2c2018-01-24 16:41:38 -0800232 std::thread([=] {
233 bool success = SetProperty("ctl.interface_start", fqName + "/" + name);
Steven Moreland5a317452017-10-05 18:49:48 -0700234
Steven Moreland58cef2c2018-01-24 16:41:38 -0800235 if (!success) {
236 LOG(ERROR) << "Failed to set property for starting " << fqName << "/" << name;
237 }
238 }).detach();
Steven Moreland5a317452017-10-05 18:49:48 -0700239}
240
Steven Morelandd83d1102016-10-25 15:01:47 -0700241// Methods from ::android::hidl::manager::V1_0::IServiceManager follow.
Steven Moreland5a317452017-10-05 18:49:48 -0700242Return<sp<IBase>> ServiceManager::get(const hidl_string& hidlFqName,
243 const hidl_string& hidlName) {
244 const std::string fqName = hidlFqName;
245 const std::string name = hidlName;
246
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700247 pid_t pid = IPCThreadState::self()->getCallingPid();
248 if (!mAcl.canGet(fqName, pid)) {
249 return nullptr;
250 }
251
Steven Morelanddbaab552019-01-24 19:00:04 -0800252 HidlService* hidlService = lookup(fqName, name);
Steven Morelandd544cf62017-01-04 15:24:32 -0800253 if (hidlService == nullptr) {
Steven Morelanddbaab552019-01-24 19:00:04 -0800254 tryStartService(fqName, name);
Martijn Coenen7b02bf92017-01-02 15:17:58 +0100255 return nullptr;
Steven Morelandd83d1102016-10-25 15:01:47 -0700256 }
Steven Morelandd544cf62017-01-04 15:24:32 -0800257
Steven Moreland5a317452017-10-05 18:49:48 -0700258 sp<IBase> service = hidlService->getService();
259 if (service == nullptr) {
Steven Morelanddbaab552019-01-24 19:00:04 -0800260 tryStartService(fqName, name);
Steven Moreland5a317452017-10-05 18:49:48 -0700261 return nullptr;
262 }
263
Steven Moreland98db8292018-12-07 13:08:25 -0800264 // Let HidlService know that we handed out a client. If the client drops the service before the
265 // next time handleClientCallbacks is called, it will still know that the service had been handed out.
266 hidlService->guaranteeClient();
267
Steven Morelandc06af8d2018-10-22 16:35:07 -0700268 // This is executed immediately after the binder driver confirms the transaction. The driver
269 // will update the appropriate data structures to reflect the fact that the client now has the
270 // service this function is returning. Nothing else can update the HidlService at the same
271 // time. This will run before anything else can modify the HidlService which is owned by this
272 // object, so it will be in the same state that it was when this function returns.
273 hardware::addPostCommandTask([hidlService] {
Peter Kalauskas3b27ec52019-01-17 14:47:24 -0800274 hidlService->handleClientCallbacks(false /* isCalledOnInterval */);
Steven Morelandc06af8d2018-10-22 16:35:07 -0700275 });
276
Steven Moreland5a317452017-10-05 18:49:48 -0700277 return service;
Steven Morelandd83d1102016-10-25 15:01:47 -0700278}
279
Martijn Coenen1a5da1c2017-03-06 13:05:39 +0100280Return<bool> ServiceManager::add(const hidl_string& name, const sp<IBase>& service) {
Steven Moreland707f22c2018-10-11 12:09:34 -0700281 bool addSuccess = false;
Steven Morelandd83d1102016-10-25 15:01:47 -0700282
Martijn Coenen1a5da1c2017-03-06 13:05:39 +0100283 if (service == nullptr) {
Steven Moreland5fb3d652016-11-03 13:45:18 -0700284 return false;
Steven Morelandd83d1102016-10-25 15:01:47 -0700285 }
Steven Moreland5fb3d652016-11-03 13:45:18 -0700286
Steven Morelandcdf94722017-03-21 12:16:31 -0700287 pid_t pid = IPCThreadState::self()->getCallingPid();
Steven Moreland4034c1c2017-11-03 17:42:27 -0700288 auto context = mAcl.getContext(pid);
Steven Morelandcdf94722017-03-21 12:16:31 -0700289
Martijn Coenen1a5da1c2017-03-06 13:05:39 +0100290 auto ret = service->interfaceChain([&](const auto &interfaceChain) {
Steven Moreland707f22c2018-10-11 12:09:34 -0700291 addSuccess = addImpl(name, service, interfaceChain, context, pid);
Martijn Coenen1a5da1c2017-03-06 13:05:39 +0100292 });
293
294 if (!ret.isOk()) {
Steven Moreland707f22c2018-10-11 12:09:34 -0700295 LOG(ERROR) << "Failed to retrieve interface chain: " << ret.description();
Martijn Coenen1a5da1c2017-03-06 13:05:39 +0100296 return false;
Steven Morelandd83d1102016-10-25 15:01:47 -0700297 }
Steven Morelandd544cf62017-01-04 15:24:32 -0800298
Steven Moreland707f22c2018-10-11 12:09:34 -0700299 return addSuccess;
300}
301
302bool ServiceManager::addImpl(const hidl_string& name,
303 const sp<IBase>& service,
304 const hidl_vec<hidl_string>& interfaceChain,
305 const AccessControl::Context &context,
306 pid_t pid) {
307 if (interfaceChain.size() == 0) {
308 LOG(WARNING) << "Empty interface chain for " << name;
309 return false;
310 }
311
312 // First, verify you're allowed to add() the whole interface hierarchy
313 for(size_t i = 0; i < interfaceChain.size(); i++) {
314 const std::string fqName = interfaceChain[i];
315
316 if (!mAcl.canAdd(fqName, context, pid)) {
317 return false;
318 }
319 }
320
321 {
322 // For IBar extends IFoo if IFoo/default is being registered, remove
323 // IBar/default. This makes sure the following two things are equivalent
324 // 1). IBar::castFrom(IFoo::getService(X))
325 // 2). IBar::getService(X)
326 // assuming that IBar is declared in the device manifest and there
327 // is also not an IBaz extends IFoo.
328 const std::string childFqName = interfaceChain[0];
329 const PackageInterfaceMap &ifaceMap = mServiceMap[childFqName];
330 const HidlService *hidlService = ifaceMap.lookup(name);
331 if (hidlService != nullptr) {
332 const sp<IBase> remove = hidlService->getService();
333
334 if (remove != nullptr) {
335 const std::string instanceName = name;
336 removeService(remove, &instanceName /* restrictToInstanceName */);
337 }
338 }
339 }
340
341 for(size_t i = 0; i < interfaceChain.size(); i++) {
342 const std::string fqName = interfaceChain[i];
343
344 PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
345 HidlService *hidlService = ifaceMap.lookup(name);
346
347 if (hidlService == nullptr) {
348 ifaceMap.insertService(
349 std::make_unique<HidlService>(fqName, name, service, pid));
350 } else {
351 hidlService->setService(service, pid);
352 }
353
354 ifaceMap.sendPackageRegistrationNotification(fqName, name);
355 }
356
357 bool linkRet = service->linkToDeath(this, kServiceDiedCookie).withDefault(false);
358 if (!linkRet) {
359 LOG(ERROR) << "Could not link to death for " << interfaceChain[0] << "/" << name;
360 }
361
362 return true;
Steven Morelandd83d1102016-10-25 15:01:47 -0700363}
364
Steven Moreland37aed802017-04-06 09:16:42 -0700365Return<ServiceManager::Transport> ServiceManager::getTransport(const hidl_string& fqName,
366 const hidl_string& name) {
367 using ::android::hardware::getTransport;
368
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700369 pid_t pid = IPCThreadState::self()->getCallingPid();
370 if (!mAcl.canGet(fqName, pid)) {
371 return Transport::EMPTY;
372 }
373
Steven Moreland37aed802017-04-06 09:16:42 -0700374 switch (getTransport(fqName, name)) {
375 case vintf::Transport::HWBINDER:
376 return Transport::HWBINDER;
377 case vintf::Transport::PASSTHROUGH:
378 return Transport::PASSTHROUGH;
379 case vintf::Transport::EMPTY:
380 default:
381 return Transport::EMPTY;
382 }
383}
384
Steven Moreland76237812016-11-08 15:59:04 -0800385Return<void> ServiceManager::list(list_cb _hidl_cb) {
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700386 pid_t pid = IPCThreadState::self()->getCallingPid();
387 if (!mAcl.canList(pid)) {
388 _hidl_cb({});
389 return Void();
390 }
Steven Moreland76237812016-11-08 15:59:04 -0800391
392 hidl_vec<hidl_string> list;
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700393
Yifan Hong83c49f62017-01-25 14:16:34 -0800394 list.resize(countExistingService());
Steven Moreland76237812016-11-08 15:59:04 -0800395
396 size_t idx = 0;
Yifan Hong83c49f62017-01-25 14:16:34 -0800397 forEachExistingService([&] (const HidlService *service) {
398 list[idx++] = service->string();
Steven Morelandd8536202018-09-26 10:56:19 -0700399 return true; // continue
Yifan Hong83c49f62017-01-25 14:16:34 -0800400 });
Steven Moreland76237812016-11-08 15:59:04 -0800401
402 _hidl_cb(list);
403 return Void();
404}
405
Steven Moreland2173d3c2016-11-09 15:00:58 -0800406Return<void> ServiceManager::listByInterface(const hidl_string& fqName,
407 listByInterface_cb _hidl_cb) {
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700408 pid_t pid = IPCThreadState::self()->getCallingPid();
409 if (!mAcl.canGet(fqName, pid)) {
410 _hidl_cb({});
411 return Void();
412 }
413
Steven Morelandd544cf62017-01-04 15:24:32 -0800414 auto ifaceIt = mServiceMap.find(fqName);
Steven Moreland76237812016-11-08 15:59:04 -0800415 if (ifaceIt == mServiceMap.end()) {
416 _hidl_cb(hidl_vec<hidl_string>());
417 return Void();
418 }
419
Steven Moreland2173d3c2016-11-09 15:00:58 -0800420 const auto &instanceMap = ifaceIt->second.getInstanceMap();
Steven Moreland76237812016-11-08 15:59:04 -0800421
422 hidl_vec<hidl_string> list;
Steven Morelandfc56b612017-01-23 20:10:45 -0800423
424 size_t total = 0;
425 for (const auto &serviceMapping : instanceMap) {
426 const std::unique_ptr<HidlService> &service = serviceMapping.second;
427 if (service->getService() == nullptr) continue;
428
429 ++total;
430 }
431 list.resize(total);
Steven Moreland76237812016-11-08 15:59:04 -0800432
433 size_t idx = 0;
Steven Moreland2173d3c2016-11-09 15:00:58 -0800434 for (const auto &serviceMapping : instanceMap) {
Steven Moreland76237812016-11-08 15:59:04 -0800435 const std::unique_ptr<HidlService> &service = serviceMapping.second;
Steven Morelandfc56b612017-01-23 20:10:45 -0800436 if (service->getService() == nullptr) continue;
Steven Moreland76237812016-11-08 15:59:04 -0800437
Steven Morelandd544cf62017-01-04 15:24:32 -0800438 list[idx++] = service->getInstanceName();
Steven Moreland76237812016-11-08 15:59:04 -0800439 }
440
441 _hidl_cb(list);
442 return Void();
443}
444
Steven Moreland2173d3c2016-11-09 15:00:58 -0800445Return<bool> ServiceManager::registerForNotifications(const hidl_string& fqName,
446 const hidl_string& name,
447 const sp<IServiceNotification>& callback) {
448 if (callback == nullptr) {
449 return false;
450 }
451
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700452 pid_t pid = IPCThreadState::self()->getCallingPid();
453 if (!mAcl.canGet(fqName, pid)) {
454 return false;
455 }
456
Steven Morelandd544cf62017-01-04 15:24:32 -0800457 PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
Steven Moreland2173d3c2016-11-09 15:00:58 -0800458
459 if (name.empty()) {
Steven Moreland78c899e2018-09-27 16:45:18 -0700460 bool ret = callback->linkToDeath(this, kPackageListenerDiedCookie).withDefault(false);
461 if (!ret) {
Martijn Coenen7fafc142017-03-06 16:17:51 +0100462 LOG(ERROR) << "Failed to register death recipient for " << fqName << "/" << name;
463 return false;
464 }
Steven Moreland2173d3c2016-11-09 15:00:58 -0800465 ifaceMap.addPackageListener(callback);
466 return true;
467 }
468
Steven Morelandd544cf62017-01-04 15:24:32 -0800469 HidlService *service = ifaceMap.lookup(name);
Steven Moreland2173d3c2016-11-09 15:00:58 -0800470
Steven Moreland78c899e2018-09-27 16:45:18 -0700471 bool ret = callback->linkToDeath(this, kServiceListenerDiedCookie).withDefault(false);
472 if (!ret) {
Martijn Coenen7fafc142017-03-06 16:17:51 +0100473 LOG(ERROR) << "Failed to register death recipient for " << fqName << "/" << name;
474 return false;
475 }
476
Steven Moreland2173d3c2016-11-09 15:00:58 -0800477 if (service == nullptr) {
Steven Morelandcdf94722017-03-21 12:16:31 -0700478 auto adding = std::make_unique<HidlService>(fqName, name);
Steven Morelandd544cf62017-01-04 15:24:32 -0800479 adding->addListener(callback);
480 ifaceMap.insertService(std::move(adding));
Steven Moreland2173d3c2016-11-09 15:00:58 -0800481 } else {
482 service->addListener(callback);
483 }
484
485 return true;
486}
487
Steven Moreland6f4fbe12017-07-21 18:07:42 -0700488Return<bool> ServiceManager::unregisterForNotifications(const hidl_string& fqName,
489 const hidl_string& name,
490 const sp<IServiceNotification>& callback) {
491 if (callback == nullptr) {
492 LOG(ERROR) << "Cannot unregister null callback for " << fqName << "/" << name;
493 return false;
494 }
495
496 // NOTE: don't need ACL since callback is binder token, and if someone has gotten it,
497 // then they already have access to it.
498
499 if (fqName.empty()) {
500 bool success = false;
501 success |= removePackageListener(callback);
502 success |= removeServiceListener(callback);
503 return success;
504 }
505
506 PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
507
508 if (name.empty()) {
509 bool success = false;
510 success |= ifaceMap.removePackageListener(callback);
511 success |= ifaceMap.removeServiceListener(callback);
512 return success;
513 }
514
515 HidlService *service = ifaceMap.lookup(name);
516
517 if (service == nullptr) {
518 return false;
519 }
520
521 return service->removeListener(callback);
522}
523
Steven Morelanddbaab552019-01-24 19:00:04 -0800524Return<bool> ServiceManager::registerClientCallback(const hidl_string& hidlFqName,
525 const hidl_string& hidlName,
526 const sp<IBase>& server,
Steven Morelandd8536202018-09-26 10:56:19 -0700527 const sp<IClientCallback>& cb) {
528 if (server == nullptr || cb == nullptr) return false;
529
Steven Morelanddbaab552019-01-24 19:00:04 -0800530 const std::string fqName = hidlFqName;
531 const std::string name = hidlName;
532
Steven Morelandd8536202018-09-26 10:56:19 -0700533 // only the server of the interface can register a client callback
534 pid_t pid = IPCThreadState::self()->getCallingPid();
Steven Morelanddbaab552019-01-24 19:00:04 -0800535 auto context = mAcl.getContext(pid);
536 if (!mAcl.canAdd(fqName, context, pid)) {
537 return false;
Steven Morelandd8536202018-09-26 10:56:19 -0700538 }
539
Steven Morelanddbaab552019-01-24 19:00:04 -0800540 HidlService* registered = lookup(fqName, name);
541
542 if (registered == nullptr) {
543 return false;
Steven Morelandd8536202018-09-26 10:56:19 -0700544 }
545
Steven Morelanddbaab552019-01-24 19:00:04 -0800546 // sanity
547 if (registered->getPid() != pid) {
548 LOG(WARNING) << "Only a server can register for client callbacks (for " << fqName
549 << "/" << name << ")";
550 return false;
551 }
552
553 sp<IBase> service = registered->getService();
554
555 if (!interfacesEqual(service, server)) {
556 LOG(WARNING) << "Tried to register client callback for " << fqName << "/" << name
557 << " but a different service is registered under this name.";
558 return false;
559 }
560
561 bool linkRet = cb->linkToDeath(this, kClientCallbackDiedCookie).withDefault(false);
562 if (!linkRet) {
563 LOG(ERROR) << "Could not link to death for registerClientCallback";
564 return false;
565 }
566
567 registered->addClientCallback(cb);
Steven Morelanddbaab552019-01-24 19:00:04 -0800568
569 return true;
Steven Morelandd8536202018-09-26 10:56:19 -0700570}
571
572Return<bool> ServiceManager::unregisterClientCallback(const sp<IBase>& server,
573 const sp<IClientCallback>& cb) {
574 if (cb == nullptr) return false;
575
576 bool removed = false;
577
578 forEachExistingService([&] (HidlService *service) {
579 if (server == nullptr || interfacesEqual(service->getService(), server)) {
580 removed |= service->removeClientCallback(cb);
581 }
582 return true; // continue
583 });
584
585 return removed;
586}
587
588void ServiceManager::handleClientCallbacks() {
589 forEachServiceEntry([&] (HidlService *service) {
Peter Kalauskas3b27ec52019-01-17 14:47:24 -0800590 service->handleClientCallbacks(true /* isCalledOnInterval */);
Steven Morelandd8536202018-09-26 10:56:19 -0700591 return true; // continue
592 });
593}
594
Steven Moreland707f22c2018-10-11 12:09:34 -0700595Return<bool> ServiceManager::addWithChain(const hidl_string& name,
596 const sp<IBase>& service,
597 const hidl_vec<hidl_string>& chain) {
598 if (service == nullptr) {
599 return false;
600 }
601
602 pid_t pid = IPCThreadState::self()->getCallingPid();
603 auto context = mAcl.getContext(pid);
604
605 return addImpl(name, service, chain, context, pid);
606}
607
Steven Morelandaae4eab2018-10-29 13:00:31 -0700608Return<void> ServiceManager::listManifestByInterface(const hidl_string& fqName,
609 listManifestByInterface_cb _hidl_cb) {
610 pid_t pid = IPCThreadState::self()->getCallingPid();
611 if (!mAcl.canGet(fqName, pid)) {
612 _hidl_cb({});
613 return Void();
614 }
615
616 std::set<std::string> instances = getInstances(fqName);
617 hidl_vec<hidl_string> ret(instances.begin(), instances.end());
618
619 _hidl_cb(ret);
620 return Void();
621}
622
Steven Morelanddbaab552019-01-24 19:00:04 -0800623Return<bool> ServiceManager::tryUnregister(const hidl_string& hidlFqName,
624 const hidl_string& hidlName,
625 const sp<IBase>& service) {
626 const std::string fqName = hidlFqName;
627 const std::string name = hidlName;
628
629 if (service == nullptr) {
630 return false;
631 }
632
633 pid_t pid = IPCThreadState::self()->getCallingPid();
634 auto context = mAcl.getContext(pid);
635
636 if (!mAcl.canAdd(fqName, context, pid)) {
637 return false;
638 }
639
640 HidlService* registered = lookup(fqName, name);
641
642 // sanity
643 if (registered->getPid() != pid) {
644 LOG(WARNING) << "Only a server can unregister itself (for " << fqName
645 << "/" << name << ")";
646 return false;
647 }
648
649 sp<IBase> server = registered->getService();
650
651 if (!interfacesEqual(service, server)) {
652 LOG(WARNING) << "Tried to unregister for " << fqName << "/" << name
653 << " but a different service is registered under this name.";
654 return false;
655 }
656
Steven Morelande7cf1422019-02-01 20:17:25 -0800657 int clients = registered->forceHandleClientCallbacks(false /* isCalledOnInterval */);
Steven Morelanddbaab552019-01-24 19:00:04 -0800658
659 // clients < 0: feature not implemented or other error. Assume clients.
660 // Otherwise:
661 // - kernel driver will hold onto one refcount (during this transaction)
662 // - hwservicemanager has a refcount (guaranteed by this transaction)
663 // So, if clients > 2, then at least one other service on the system must hold a refcount.
664 if (clients < 0 || clients > 2) {
665 // client callbacks are either disabled or there are other clients
666 LOG(INFO) << "Tried to unregister for " << fqName << "/" << name
667 << " but there are clients: " << clients;
668 return false;
669 }
670
671 // will remove entire parent hierarchy
672 bool success = removeService(service, &name /*restrictToInstanceName*/);
673
674 if (registered->getService() != nullptr) {
675 LOG(ERROR) << "Bad state. Unregistration failed for " << fqName << "/" << name << ".";
676 return false;
677 }
678
679 return success;
680}
681
Yifan Hong83c49f62017-01-25 14:16:34 -0800682Return<void> ServiceManager::debugDump(debugDump_cb _cb) {
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700683 pid_t pid = IPCThreadState::self()->getCallingPid();
684 if (!mAcl.canList(pid)) {
685 _cb({});
686 return Void();
687 }
688
Yifan Hongee531a82017-02-03 15:10:18 -0800689 std::vector<IServiceManager::InstanceDebugInfo> list;
690 forEachServiceEntry([&] (const HidlService *service) {
Yifan Hongee531a82017-02-03 15:10:18 -0800691 hidl_vec<int32_t> clientPids;
692 clientPids.resize(service->getPassthroughClients().size());
693
694 size_t i = 0;
695 for (pid_t p : service->getPassthroughClients()) {
696 clientPids[i++] = p;
697 }
698
699 list.push_back({
Steven Morelandcdf94722017-03-21 12:16:31 -0700700 .pid = service->getPid(),
Yifan Hong83c49f62017-01-25 14:16:34 -0800701 .interfaceName = service->getInterfaceName(),
702 .instanceName = service->getInstanceName(),
Yifan Hong1d2deb12017-03-02 16:58:22 -0800703 .clientPids = clientPids,
704 .arch = ::android::hidl::base::V1_0::DebugInfo::Architecture::UNKNOWN
Yifan Hongee531a82017-02-03 15:10:18 -0800705 });
Steven Morelandd8536202018-09-26 10:56:19 -0700706
707 return true; // continue
Yifan Hong83c49f62017-01-25 14:16:34 -0800708 });
709
710 _cb(list);
711 return Void();
712}
713
Yifan Hongee531a82017-02-03 15:10:18 -0800714
715Return<void> ServiceManager::registerPassthroughClient(const hidl_string &fqName,
Martijn Coenen737de1b2017-04-27 09:29:43 -0700716 const hidl_string &name) {
717 pid_t pid = IPCThreadState::self()->getCallingPid();
718 if (!mAcl.canGet(fqName, pid)) {
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700719 /* We guard this function with "get", because it's typically used in
720 * the getService() path, albeit for a passthrough service in this
721 * case
722 */
723 return Void();
724 }
Yifan Hongee531a82017-02-03 15:10:18 -0800725
726 PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
727
728 if (name.empty()) {
729 LOG(WARNING) << "registerPassthroughClient encounters empty instance name for "
730 << fqName.c_str();
731 return Void();
732 }
733
734 HidlService *service = ifaceMap.lookup(name);
735
736 if (service == nullptr) {
Steven Morelandcdf94722017-03-21 12:16:31 -0700737 auto adding = std::make_unique<HidlService>(fqName, name);
Yifan Hongee531a82017-02-03 15:10:18 -0800738 adding->registerPassthroughClient(pid);
739 ifaceMap.insertService(std::move(adding));
740 } else {
741 service->registerPassthroughClient(pid);
742 }
743 return Void();
744}
745
Steven Moreland76936fe2017-09-19 12:18:30 -0700746bool ServiceManager::removeService(const wp<IBase>& who, const std::string* restrictToInstanceName) {
Steven Moreland76936fe2017-09-19 12:18:30 -0700747 bool keepInstance = false;
748 bool removed = false;
Martijn Coenen46847a62016-12-19 05:36:12 +0100749 for (auto &interfaceMapping : mServiceMap) {
750 auto &instanceMap = interfaceMapping.second.getInstanceMap();
751
Steven Morelandd544cf62017-01-04 15:24:32 -0800752 for (auto &servicePair : instanceMap) {
Steven Moreland76936fe2017-09-19 12:18:30 -0700753 const std::string &instanceName = servicePair.first;
Steven Morelandd544cf62017-01-04 15:24:32 -0800754 const std::unique_ptr<HidlService> &service = servicePair.second;
Steven Moreland76936fe2017-09-19 12:18:30 -0700755
Steven Moreland6f4fbe12017-07-21 18:07:42 -0700756 if (interfacesEqual(service->getService(), who.promote())) {
Steven Moreland76936fe2017-09-19 12:18:30 -0700757 if (restrictToInstanceName != nullptr && *restrictToInstanceName != instanceName) {
758 // We cannot remove all instances of this service, so we don't return that it
759 // has been entirely removed.
760 keepInstance = true;
761 continue;
762 }
763
Steven Morelandcdf94722017-03-21 12:16:31 -0700764 service->setService(nullptr, static_cast<pid_t>(IServiceManager::PidConstant::NO_PID));
Steven Moreland76936fe2017-09-19 12:18:30 -0700765 removed = true;
Martijn Coenen46847a62016-12-19 05:36:12 +0100766 }
767 }
768 }
Steven Moreland76936fe2017-09-19 12:18:30 -0700769
770 return !keepInstance && removed;
Martijn Coenen46847a62016-12-19 05:36:12 +0100771}
Yifan Hong83c49f62017-01-25 14:16:34 -0800772
Martijn Coenen7fafc142017-03-06 16:17:51 +0100773bool ServiceManager::removePackageListener(const wp<IBase>& who) {
774 bool found = false;
775
776 for (auto &interfaceMapping : mServiceMap) {
777 found |= interfaceMapping.second.removePackageListener(who);
778 }
779
780 return found;
781}
782
783bool ServiceManager::removeServiceListener(const wp<IBase>& who) {
784 bool found = false;
785 for (auto &interfaceMapping : mServiceMap) {
Steven Moreland6f4fbe12017-07-21 18:07:42 -0700786 auto &packageInterfaceMap = interfaceMapping.second;
Martijn Coenen7fafc142017-03-06 16:17:51 +0100787
Steven Moreland6f4fbe12017-07-21 18:07:42 -0700788 found |= packageInterfaceMap.removeServiceListener(who);
Martijn Coenen7fafc142017-03-06 16:17:51 +0100789 }
790 return found;
791}
Steven Moreland6f4fbe12017-07-21 18:07:42 -0700792} // namespace implementation
Steven Morelandd83d1102016-10-25 15:01:47 -0700793} // namespace manager
794} // namespace hidl
795} // namespace android