blob: a858f7f1ad7778e7f1902062fcf68467e1e1ba44 [file] [log] [blame]
Steven Moreland5fb3d652016-11-03 13:45:18 -07001#define LOG_TAG "hwservicemanager"
2
Steven Morelandd83d1102016-10-25 15:01:47 -07003#include "ServiceManager.h"
Steven Moreland37aed802017-04-06 09:16:42 -07004#include "Vintf.h"
Steven Morelandd83d1102016-10-25 15:01:47 -07005
Steven Moreland5fb3d652016-11-03 13:45:18 -07006#include <android-base/logging.h>
Steven Moreland5a317452017-10-05 18:49:48 -07007#include <android-base/properties.h>
Steven Morelandcdf94722017-03-21 12:16:31 -07008#include <hwbinder/IPCThreadState.h>
Steven Morelandd83d1102016-10-25 15:01:47 -07009#include <hidl/HidlSupport.h>
Steven Moreland6f4fbe12017-07-21 18:07:42 -070010#include <hidl/HidlTransportSupport.h>
Steven Moreland5fb3d652016-11-03 13:45:18 -070011#include <regex>
Steven Moreland76237812016-11-08 15:59:04 -080012#include <sstream>
Steven Moreland58cef2c2018-01-24 16:41:38 -080013#include <thread>
Steven Morelandd83d1102016-10-25 15:01:47 -070014
Steven Morelandcdf94722017-03-21 12:16:31 -070015using android::hardware::IPCThreadState;
16
Steven Morelandd83d1102016-10-25 15:01:47 -070017namespace android {
18namespace hidl {
19namespace manager {
Steven Morelandd83d1102016-10-25 15:01:47 -070020namespace implementation {
21
Martijn Coenen7fafc142017-03-06 16:17:51 +010022static constexpr uint64_t kServiceDiedCookie = 0;
23static constexpr uint64_t kPackageListenerDiedCookie = 1;
24static constexpr uint64_t kServiceListenerDiedCookie = 2;
25
Yifan Hong83c49f62017-01-25 14:16:34 -080026size_t ServiceManager::countExistingService() const {
27 size_t total = 0;
28 forEachExistingService([&] (const HidlService *) {
29 ++total;
30 });
31 return total;
32}
33
34void ServiceManager::forEachExistingService(std::function<void(const HidlService *)> f) const {
Yifan Hongee531a82017-02-03 15:10:18 -080035 forEachServiceEntry([f] (const HidlService *service) {
36 if (service->getService() == nullptr) {
37 return;
38 }
39 f(service);
40 });
41}
42
43void ServiceManager::forEachServiceEntry(std::function<void(const HidlService *)> f) const {
Yifan Hong83c49f62017-01-25 14:16:34 -080044 for (const auto &interfaceMapping : mServiceMap) {
45 const auto &instanceMap = interfaceMapping.second.getInstanceMap();
46
47 for (const auto &instanceMapping : instanceMap) {
Yifan Hongee531a82017-02-03 15:10:18 -080048 f(instanceMapping.second.get());
Yifan Hong83c49f62017-01-25 14:16:34 -080049 }
50 }
51}
52
Martijn Coenen7fafc142017-03-06 16:17:51 +010053void ServiceManager::serviceDied(uint64_t cookie, const wp<IBase>& who) {
Steven Moreland3af80b92018-05-09 15:31:18 -070054 bool serviceRemoved = false;
Martijn Coenen7fafc142017-03-06 16:17:51 +010055 switch (cookie) {
56 case kServiceDiedCookie:
Steven Moreland3af80b92018-05-09 15:31:18 -070057 serviceRemoved = removeService(who, nullptr /* restrictToInstanceName */);
Martijn Coenen7fafc142017-03-06 16:17:51 +010058 break;
59 case kPackageListenerDiedCookie:
Steven Moreland3af80b92018-05-09 15:31:18 -070060 serviceRemoved = removePackageListener(who);
Martijn Coenen7fafc142017-03-06 16:17:51 +010061 break;
62 case kServiceListenerDiedCookie:
Steven Moreland3af80b92018-05-09 15:31:18 -070063 serviceRemoved = removeServiceListener(who);
Martijn Coenen7fafc142017-03-06 16:17:51 +010064 break;
65 }
Steven Moreland3af80b92018-05-09 15:31:18 -070066
67 if (!serviceRemoved) {
68 LOG(ERROR) << "Received death notification but serivce not removed. Cookie: " << cookie
69 << " Service pointer: " << who.promote().get();
70 }
Martijn Coenen46847a62016-12-19 05:36:12 +010071}
72
Steven Moreland2173d3c2016-11-09 15:00:58 -080073ServiceManager::InstanceMap &ServiceManager::PackageInterfaceMap::getInstanceMap() {
74 return mInstanceMap;
Steven Moreland5fb3d652016-11-03 13:45:18 -070075}
76
Steven Moreland2173d3c2016-11-09 15:00:58 -080077const ServiceManager::InstanceMap &ServiceManager::PackageInterfaceMap::getInstanceMap() const {
78 return mInstanceMap;
Steven Moreland5fb3d652016-11-03 13:45:18 -070079}
80
Steven Morelandd544cf62017-01-04 15:24:32 -080081const HidlService *ServiceManager::PackageInterfaceMap::lookup(
82 const std::string &name) const {
83 auto it = mInstanceMap.find(name);
Steven Moreland76237812016-11-08 15:59:04 -080084
Steven Morelandd544cf62017-01-04 15:24:32 -080085 if (it == mInstanceMap.end()) {
86 return nullptr;
Steven Moreland5fb3d652016-11-03 13:45:18 -070087 }
88
Steven Morelandd544cf62017-01-04 15:24:32 -080089 return it->second.get();
Steven Moreland2173d3c2016-11-09 15:00:58 -080090}
Steven Moreland5fb3d652016-11-03 13:45:18 -070091
Steven Morelandd544cf62017-01-04 15:24:32 -080092HidlService *ServiceManager::PackageInterfaceMap::lookup(
93 const std::string &name) {
Steven Moreland5fb3d652016-11-03 13:45:18 -070094
Steven Moreland2173d3c2016-11-09 15:00:58 -080095 return const_cast<HidlService*>(
Steven Morelandd544cf62017-01-04 15:24:32 -080096 const_cast<const PackageInterfaceMap*>(this)->lookup(name));
Steven Moreland2173d3c2016-11-09 15:00:58 -080097}
98
99void ServiceManager::PackageInterfaceMap::insertService(
100 std::unique_ptr<HidlService> &&service) {
Steven Morelandd544cf62017-01-04 15:24:32 -0800101 mInstanceMap.insert({service->getInstanceName(), std::move(service)});
Steven Moreland2173d3c2016-11-09 15:00:58 -0800102}
103
104void ServiceManager::PackageInterfaceMap::sendPackageRegistrationNotification(
105 const hidl_string &fqName,
Martijn Coenen7fafc142017-03-06 16:17:51 +0100106 const hidl_string &instanceName) {
Steven Moreland2173d3c2016-11-09 15:00:58 -0800107
Martijn Coenen7fafc142017-03-06 16:17:51 +0100108 for (auto it = mPackageListeners.begin(); it != mPackageListeners.end();) {
109 auto ret = (*it)->onRegistration(fqName, instanceName, false /* preexisting */);
110 if (ret.isOk()) {
111 ++it;
112 } else {
113 LOG(ERROR) << "Dropping registration callback for " << fqName << "/" << instanceName
114 << ": transport error.";
115 it = mPackageListeners.erase(it);
116 }
Steven Moreland2173d3c2016-11-09 15:00:58 -0800117 }
118}
Steven Moreland2173d3c2016-11-09 15:00:58 -0800119
Martijn Coenen7fafc142017-03-06 16:17:51 +0100120void ServiceManager::PackageInterfaceMap::addPackageListener(sp<IServiceNotification> listener) {
Steven Moreland2173d3c2016-11-09 15:00:58 -0800121 for (const auto &instanceMapping : mInstanceMap) {
122 const std::unique_ptr<HidlService> &service = instanceMapping.second;
123
124 if (service->getService() == nullptr) {
125 continue;
126 }
127
Steven Moreland30acc222017-01-26 11:44:38 -0800128 auto ret = listener->onRegistration(
Steven Morelandd544cf62017-01-04 15:24:32 -0800129 service->getInterfaceName(),
130 service->getInstanceName(),
131 true /* preexisting */);
Martijn Coenen7fafc142017-03-06 16:17:51 +0100132 if (!ret.isOk()) {
133 LOG(ERROR) << "Not adding package listener for " << service->getInterfaceName()
134 << "/" << service->getInstanceName() << ": transport error "
135 << "when sending notification for already registered instance.";
136 return;
137 }
Steven Moreland2173d3c2016-11-09 15:00:58 -0800138 }
Martijn Coenen7fafc142017-03-06 16:17:51 +0100139 mPackageListeners.push_back(listener);
140}
141
142bool ServiceManager::PackageInterfaceMap::removePackageListener(const wp<IBase>& who) {
Steven Moreland6f4fbe12017-07-21 18:07:42 -0700143 using ::android::hardware::interfacesEqual;
144
Martijn Coenen7fafc142017-03-06 16:17:51 +0100145 bool found = false;
146
147 for (auto it = mPackageListeners.begin(); it != mPackageListeners.end();) {
Steven Moreland6f4fbe12017-07-21 18:07:42 -0700148 if (interfacesEqual(*it, who.promote())) {
Martijn Coenen7fafc142017-03-06 16:17:51 +0100149 it = mPackageListeners.erase(it);
150 found = true;
151 } else {
152 ++it;
153 }
154 }
155
156 return found;
Steven Moreland5fb3d652016-11-03 13:45:18 -0700157}
158
Steven Moreland6f4fbe12017-07-21 18:07:42 -0700159bool ServiceManager::PackageInterfaceMap::removeServiceListener(const wp<IBase>& who) {
160 using ::android::hardware::interfacesEqual;
161
162 bool found = false;
163
164 for (auto &servicePair : getInstanceMap()) {
165 const std::unique_ptr<HidlService> &service = servicePair.second;
166 found |= service->removeListener(who);
167 }
168
169 return found;
170}
171
Steven Moreland5a317452017-10-05 18:49:48 -0700172static void tryStartService(const std::string& fqName, const std::string& name) {
173 using ::android::base::SetProperty;
174
Steven Moreland58cef2c2018-01-24 16:41:38 -0800175 std::thread([=] {
176 bool success = SetProperty("ctl.interface_start", fqName + "/" + name);
Steven Moreland5a317452017-10-05 18:49:48 -0700177
Steven Moreland58cef2c2018-01-24 16:41:38 -0800178 if (!success) {
179 LOG(ERROR) << "Failed to set property for starting " << fqName << "/" << name;
180 }
181 }).detach();
Steven Moreland5a317452017-10-05 18:49:48 -0700182}
183
Steven Morelandd83d1102016-10-25 15:01:47 -0700184// Methods from ::android::hidl::manager::V1_0::IServiceManager follow.
Steven Moreland5a317452017-10-05 18:49:48 -0700185Return<sp<IBase>> ServiceManager::get(const hidl_string& hidlFqName,
186 const hidl_string& hidlName) {
187 const std::string fqName = hidlFqName;
188 const std::string name = hidlName;
189
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700190 pid_t pid = IPCThreadState::self()->getCallingPid();
191 if (!mAcl.canGet(fqName, pid)) {
192 return nullptr;
193 }
194
Steven Morelandd544cf62017-01-04 15:24:32 -0800195 auto ifaceIt = mServiceMap.find(fqName);
Steven Moreland5fb3d652016-11-03 13:45:18 -0700196 if (ifaceIt == mServiceMap.end()) {
Steven Moreland5a317452017-10-05 18:49:48 -0700197 tryStartService(fqName, hidlName);
Martijn Coenen7b02bf92017-01-02 15:17:58 +0100198 return nullptr;
Steven Moreland5fb3d652016-11-03 13:45:18 -0700199 }
200
Steven Moreland2173d3c2016-11-09 15:00:58 -0800201 const PackageInterfaceMap &ifaceMap = ifaceIt->second;
Steven Morelandd544cf62017-01-04 15:24:32 -0800202 const HidlService *hidlService = ifaceMap.lookup(name);
Steven Moreland5fb3d652016-11-03 13:45:18 -0700203
Steven Morelandd544cf62017-01-04 15:24:32 -0800204 if (hidlService == nullptr) {
Steven Moreland5a317452017-10-05 18:49:48 -0700205 tryStartService(fqName, hidlName);
Martijn Coenen7b02bf92017-01-02 15:17:58 +0100206 return nullptr;
Steven Morelandd83d1102016-10-25 15:01:47 -0700207 }
Steven Morelandd544cf62017-01-04 15:24:32 -0800208
Steven Moreland5a317452017-10-05 18:49:48 -0700209 sp<IBase> service = hidlService->getService();
210 if (service == nullptr) {
211 tryStartService(fqName, hidlName);
212 return nullptr;
213 }
214
215 return service;
Steven Morelandd83d1102016-10-25 15:01:47 -0700216}
217
Martijn Coenen1a5da1c2017-03-06 13:05:39 +0100218Return<bool> ServiceManager::add(const hidl_string& name, const sp<IBase>& service) {
219 bool isValidService = false;
Steven Morelandd83d1102016-10-25 15:01:47 -0700220
Martijn Coenen1a5da1c2017-03-06 13:05:39 +0100221 if (service == nullptr) {
Steven Moreland5fb3d652016-11-03 13:45:18 -0700222 return false;
Steven Morelandd83d1102016-10-25 15:01:47 -0700223 }
Steven Moreland5fb3d652016-11-03 13:45:18 -0700224
Steven Morelandcdf94722017-03-21 12:16:31 -0700225 // TODO(b/34235311): use HIDL way to determine this
226 // also, this assumes that the PID that is registering is the pid that is the service
227 pid_t pid = IPCThreadState::self()->getCallingPid();
Steven Moreland4034c1c2017-11-03 17:42:27 -0700228 auto context = mAcl.getContext(pid);
Steven Morelandcdf94722017-03-21 12:16:31 -0700229
Martijn Coenen1a5da1c2017-03-06 13:05:39 +0100230 auto ret = service->interfaceChain([&](const auto &interfaceChain) {
231 if (interfaceChain.size() == 0) {
232 return;
Steven Moreland5fb3d652016-11-03 13:45:18 -0700233 }
Steven Moreland978473f2016-11-28 14:51:07 -0800234
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700235 // First, verify you're allowed to add() the whole interface hierarchy
236 for(size_t i = 0; i < interfaceChain.size(); i++) {
Steven Moreland76936fe2017-09-19 12:18:30 -0700237 const std::string fqName = interfaceChain[i];
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700238
Steven Moreland4034c1c2017-11-03 17:42:27 -0700239 if (!mAcl.canAdd(fqName, context, pid)) {
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700240 return;
241 }
242 }
243
Steven Moreland76936fe2017-09-19 12:18:30 -0700244 {
245 // For IBar extends IFoo if IFoo/default is being registered, remove
246 // IBar/default. This makes sure the following two things are equivalent
247 // 1). IBar::castFrom(IFoo::getService(X))
248 // 2). IBar::getService(X)
249 // assuming that IBar is declared in the device manifest and there
250 // is also not an IBaz extends IFoo.
251 const std::string childFqName = interfaceChain[0];
252 const PackageInterfaceMap &ifaceMap = mServiceMap[childFqName];
253 const HidlService *hidlService = ifaceMap.lookup(name);
254 if (hidlService != nullptr) {
255 const sp<IBase> remove = hidlService->getService();
256
257 if (remove != nullptr) {
258 const std::string instanceName = name;
Steven Moreland1ac63d92017-10-06 12:48:14 -0700259 removeService(remove, &instanceName /* restrictToInstanceName */);
Steven Moreland76936fe2017-09-19 12:18:30 -0700260 }
261 }
262 }
263
Martijn Coenen1a5da1c2017-03-06 13:05:39 +0100264 for(size_t i = 0; i < interfaceChain.size(); i++) {
Steven Moreland76936fe2017-09-19 12:18:30 -0700265 const std::string fqName = interfaceChain[i];
Martijn Coenen1a5da1c2017-03-06 13:05:39 +0100266
267 PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
268 HidlService *hidlService = ifaceMap.lookup(name);
269
270 if (hidlService == nullptr) {
271 ifaceMap.insertService(
Steven Morelandcdf94722017-03-21 12:16:31 -0700272 std::make_unique<HidlService>(fqName, name, service, pid));
Martijn Coenen1a5da1c2017-03-06 13:05:39 +0100273 } else {
Steven Morelandcdf94722017-03-21 12:16:31 -0700274 hidlService->setService(service, pid);
Martijn Coenen1a5da1c2017-03-06 13:05:39 +0100275 }
276
277 ifaceMap.sendPackageRegistrationNotification(fqName, name);
278 }
279
Steven Moreland3505c382017-10-06 09:58:57 -0700280 bool linkRet = service->linkToDeath(this, kServiceDiedCookie).withDefault(false);
281 if (!linkRet) {
282 LOG(ERROR) << "Could not link to death for " << interfaceChain[0] << "/" << name;
283 }
Martijn Coenen1a5da1c2017-03-06 13:05:39 +0100284
285 isValidService = true;
286 });
287
288 if (!ret.isOk()) {
289 LOG(ERROR) << "Failed to retrieve interface chain.";
290 return false;
Steven Morelandd83d1102016-10-25 15:01:47 -0700291 }
Steven Morelandd544cf62017-01-04 15:24:32 -0800292
Martijn Coenen1a5da1c2017-03-06 13:05:39 +0100293 return isValidService;
Steven Morelandd83d1102016-10-25 15:01:47 -0700294}
295
Steven Moreland37aed802017-04-06 09:16:42 -0700296Return<ServiceManager::Transport> ServiceManager::getTransport(const hidl_string& fqName,
297 const hidl_string& name) {
298 using ::android::hardware::getTransport;
299
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700300 pid_t pid = IPCThreadState::self()->getCallingPid();
301 if (!mAcl.canGet(fqName, pid)) {
302 return Transport::EMPTY;
303 }
304
Steven Moreland37aed802017-04-06 09:16:42 -0700305 switch (getTransport(fqName, name)) {
306 case vintf::Transport::HWBINDER:
307 return Transport::HWBINDER;
308 case vintf::Transport::PASSTHROUGH:
309 return Transport::PASSTHROUGH;
310 case vintf::Transport::EMPTY:
311 default:
312 return Transport::EMPTY;
313 }
314}
315
Steven Moreland76237812016-11-08 15:59:04 -0800316Return<void> ServiceManager::list(list_cb _hidl_cb) {
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700317 pid_t pid = IPCThreadState::self()->getCallingPid();
318 if (!mAcl.canList(pid)) {
319 _hidl_cb({});
320 return Void();
321 }
Steven Moreland76237812016-11-08 15:59:04 -0800322
323 hidl_vec<hidl_string> list;
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700324
Yifan Hong83c49f62017-01-25 14:16:34 -0800325 list.resize(countExistingService());
Steven Moreland76237812016-11-08 15:59:04 -0800326
327 size_t idx = 0;
Yifan Hong83c49f62017-01-25 14:16:34 -0800328 forEachExistingService([&] (const HidlService *service) {
329 list[idx++] = service->string();
330 });
Steven Moreland76237812016-11-08 15:59:04 -0800331
332 _hidl_cb(list);
333 return Void();
334}
335
Steven Moreland2173d3c2016-11-09 15:00:58 -0800336Return<void> ServiceManager::listByInterface(const hidl_string& fqName,
337 listByInterface_cb _hidl_cb) {
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700338 pid_t pid = IPCThreadState::self()->getCallingPid();
339 if (!mAcl.canGet(fqName, pid)) {
340 _hidl_cb({});
341 return Void();
342 }
343
Steven Morelandd544cf62017-01-04 15:24:32 -0800344 auto ifaceIt = mServiceMap.find(fqName);
Steven Moreland76237812016-11-08 15:59:04 -0800345 if (ifaceIt == mServiceMap.end()) {
346 _hidl_cb(hidl_vec<hidl_string>());
347 return Void();
348 }
349
Steven Moreland2173d3c2016-11-09 15:00:58 -0800350 const auto &instanceMap = ifaceIt->second.getInstanceMap();
Steven Moreland76237812016-11-08 15:59:04 -0800351
352 hidl_vec<hidl_string> list;
Steven Morelandfc56b612017-01-23 20:10:45 -0800353
354 size_t total = 0;
355 for (const auto &serviceMapping : instanceMap) {
356 const std::unique_ptr<HidlService> &service = serviceMapping.second;
357 if (service->getService() == nullptr) continue;
358
359 ++total;
360 }
361 list.resize(total);
Steven Moreland76237812016-11-08 15:59:04 -0800362
363 size_t idx = 0;
Steven Moreland2173d3c2016-11-09 15:00:58 -0800364 for (const auto &serviceMapping : instanceMap) {
Steven Moreland76237812016-11-08 15:59:04 -0800365 const std::unique_ptr<HidlService> &service = serviceMapping.second;
Steven Morelandfc56b612017-01-23 20:10:45 -0800366 if (service->getService() == nullptr) continue;
Steven Moreland76237812016-11-08 15:59:04 -0800367
Steven Morelandd544cf62017-01-04 15:24:32 -0800368 list[idx++] = service->getInstanceName();
Steven Moreland76237812016-11-08 15:59:04 -0800369 }
370
371 _hidl_cb(list);
372 return Void();
373}
374
Steven Moreland2173d3c2016-11-09 15:00:58 -0800375Return<bool> ServiceManager::registerForNotifications(const hidl_string& fqName,
376 const hidl_string& name,
377 const sp<IServiceNotification>& callback) {
378 if (callback == nullptr) {
379 return false;
380 }
381
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700382 pid_t pid = IPCThreadState::self()->getCallingPid();
383 if (!mAcl.canGet(fqName, pid)) {
384 return false;
385 }
386
Steven Morelandd544cf62017-01-04 15:24:32 -0800387 PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
Steven Moreland2173d3c2016-11-09 15:00:58 -0800388
389 if (name.empty()) {
Steven Moreland78c899e2018-09-27 16:45:18 -0700390 bool ret = callback->linkToDeath(this, kPackageListenerDiedCookie).withDefault(false);
391 if (!ret) {
Martijn Coenen7fafc142017-03-06 16:17:51 +0100392 LOG(ERROR) << "Failed to register death recipient for " << fqName << "/" << name;
393 return false;
394 }
Steven Moreland2173d3c2016-11-09 15:00:58 -0800395 ifaceMap.addPackageListener(callback);
396 return true;
397 }
398
Steven Morelandd544cf62017-01-04 15:24:32 -0800399 HidlService *service = ifaceMap.lookup(name);
Steven Moreland2173d3c2016-11-09 15:00:58 -0800400
Steven Moreland78c899e2018-09-27 16:45:18 -0700401 bool ret = callback->linkToDeath(this, kServiceListenerDiedCookie).withDefault(false);
402 if (!ret) {
Martijn Coenen7fafc142017-03-06 16:17:51 +0100403 LOG(ERROR) << "Failed to register death recipient for " << fqName << "/" << name;
404 return false;
405 }
406
Steven Moreland2173d3c2016-11-09 15:00:58 -0800407 if (service == nullptr) {
Steven Morelandcdf94722017-03-21 12:16:31 -0700408 auto adding = std::make_unique<HidlService>(fqName, name);
Steven Morelandd544cf62017-01-04 15:24:32 -0800409 adding->addListener(callback);
410 ifaceMap.insertService(std::move(adding));
Steven Moreland2173d3c2016-11-09 15:00:58 -0800411 } else {
412 service->addListener(callback);
413 }
414
415 return true;
416}
417
Steven Moreland6f4fbe12017-07-21 18:07:42 -0700418Return<bool> ServiceManager::unregisterForNotifications(const hidl_string& fqName,
419 const hidl_string& name,
420 const sp<IServiceNotification>& callback) {
421 if (callback == nullptr) {
422 LOG(ERROR) << "Cannot unregister null callback for " << fqName << "/" << name;
423 return false;
424 }
425
426 // NOTE: don't need ACL since callback is binder token, and if someone has gotten it,
427 // then they already have access to it.
428
429 if (fqName.empty()) {
430 bool success = false;
431 success |= removePackageListener(callback);
432 success |= removeServiceListener(callback);
433 return success;
434 }
435
436 PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
437
438 if (name.empty()) {
439 bool success = false;
440 success |= ifaceMap.removePackageListener(callback);
441 success |= ifaceMap.removeServiceListener(callback);
442 return success;
443 }
444
445 HidlService *service = ifaceMap.lookup(name);
446
447 if (service == nullptr) {
448 return false;
449 }
450
451 return service->removeListener(callback);
452}
453
Yifan Hong83c49f62017-01-25 14:16:34 -0800454Return<void> ServiceManager::debugDump(debugDump_cb _cb) {
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700455 pid_t pid = IPCThreadState::self()->getCallingPid();
456 if (!mAcl.canList(pid)) {
457 _cb({});
458 return Void();
459 }
460
Yifan Hongee531a82017-02-03 15:10:18 -0800461 std::vector<IServiceManager::InstanceDebugInfo> list;
462 forEachServiceEntry([&] (const HidlService *service) {
Yifan Hongee531a82017-02-03 15:10:18 -0800463 hidl_vec<int32_t> clientPids;
464 clientPids.resize(service->getPassthroughClients().size());
465
466 size_t i = 0;
467 for (pid_t p : service->getPassthroughClients()) {
468 clientPids[i++] = p;
469 }
470
471 list.push_back({
Steven Morelandcdf94722017-03-21 12:16:31 -0700472 .pid = service->getPid(),
Yifan Hong83c49f62017-01-25 14:16:34 -0800473 .interfaceName = service->getInterfaceName(),
474 .instanceName = service->getInstanceName(),
Yifan Hong1d2deb12017-03-02 16:58:22 -0800475 .clientPids = clientPids,
476 .arch = ::android::hidl::base::V1_0::DebugInfo::Architecture::UNKNOWN
Yifan Hongee531a82017-02-03 15:10:18 -0800477 });
Yifan Hong83c49f62017-01-25 14:16:34 -0800478 });
479
480 _cb(list);
481 return Void();
482}
483
Yifan Hongee531a82017-02-03 15:10:18 -0800484
485Return<void> ServiceManager::registerPassthroughClient(const hidl_string &fqName,
Martijn Coenen737de1b2017-04-27 09:29:43 -0700486 const hidl_string &name) {
487 pid_t pid = IPCThreadState::self()->getCallingPid();
488 if (!mAcl.canGet(fqName, pid)) {
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700489 /* We guard this function with "get", because it's typically used in
490 * the getService() path, albeit for a passthrough service in this
491 * case
492 */
493 return Void();
494 }
Yifan Hongee531a82017-02-03 15:10:18 -0800495
496 PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
497
498 if (name.empty()) {
499 LOG(WARNING) << "registerPassthroughClient encounters empty instance name for "
500 << fqName.c_str();
501 return Void();
502 }
503
504 HidlService *service = ifaceMap.lookup(name);
505
506 if (service == nullptr) {
Steven Morelandcdf94722017-03-21 12:16:31 -0700507 auto adding = std::make_unique<HidlService>(fqName, name);
Yifan Hongee531a82017-02-03 15:10:18 -0800508 adding->registerPassthroughClient(pid);
509 ifaceMap.insertService(std::move(adding));
510 } else {
511 service->registerPassthroughClient(pid);
512 }
513 return Void();
514}
515
Steven Moreland76936fe2017-09-19 12:18:30 -0700516bool ServiceManager::removeService(const wp<IBase>& who, const std::string* restrictToInstanceName) {
Steven Moreland6f4fbe12017-07-21 18:07:42 -0700517 using ::android::hardware::interfacesEqual;
518
Steven Moreland76936fe2017-09-19 12:18:30 -0700519 bool keepInstance = false;
520 bool removed = false;
Martijn Coenen46847a62016-12-19 05:36:12 +0100521 for (auto &interfaceMapping : mServiceMap) {
522 auto &instanceMap = interfaceMapping.second.getInstanceMap();
523
Steven Morelandd544cf62017-01-04 15:24:32 -0800524 for (auto &servicePair : instanceMap) {
Steven Moreland76936fe2017-09-19 12:18:30 -0700525 const std::string &instanceName = servicePair.first;
Steven Morelandd544cf62017-01-04 15:24:32 -0800526 const std::unique_ptr<HidlService> &service = servicePair.second;
Steven Moreland76936fe2017-09-19 12:18:30 -0700527
Steven Moreland6f4fbe12017-07-21 18:07:42 -0700528 if (interfacesEqual(service->getService(), who.promote())) {
Steven Moreland76936fe2017-09-19 12:18:30 -0700529 if (restrictToInstanceName != nullptr && *restrictToInstanceName != instanceName) {
530 // We cannot remove all instances of this service, so we don't return that it
531 // has been entirely removed.
532 keepInstance = true;
533 continue;
534 }
535
Steven Morelandcdf94722017-03-21 12:16:31 -0700536 service->setService(nullptr, static_cast<pid_t>(IServiceManager::PidConstant::NO_PID));
Steven Moreland76936fe2017-09-19 12:18:30 -0700537 removed = true;
Martijn Coenen46847a62016-12-19 05:36:12 +0100538 }
539 }
540 }
Steven Moreland76936fe2017-09-19 12:18:30 -0700541
542 return !keepInstance && removed;
Martijn Coenen46847a62016-12-19 05:36:12 +0100543}
Yifan Hong83c49f62017-01-25 14:16:34 -0800544
Martijn Coenen7fafc142017-03-06 16:17:51 +0100545bool ServiceManager::removePackageListener(const wp<IBase>& who) {
546 bool found = false;
547
548 for (auto &interfaceMapping : mServiceMap) {
549 found |= interfaceMapping.second.removePackageListener(who);
550 }
551
552 return found;
553}
554
555bool ServiceManager::removeServiceListener(const wp<IBase>& who) {
556 bool found = false;
557 for (auto &interfaceMapping : mServiceMap) {
Steven Moreland6f4fbe12017-07-21 18:07:42 -0700558 auto &packageInterfaceMap = interfaceMapping.second;
Martijn Coenen7fafc142017-03-06 16:17:51 +0100559
Steven Moreland6f4fbe12017-07-21 18:07:42 -0700560 found |= packageInterfaceMap.removeServiceListener(who);
Martijn Coenen7fafc142017-03-06 16:17:51 +0100561 }
562 return found;
563}
Steven Moreland6f4fbe12017-07-21 18:07:42 -0700564} // namespace implementation
Steven Morelandd83d1102016-10-25 15:01:47 -0700565} // namespace manager
566} // namespace hidl
567} // namespace android