blob: ea97136a72076720b868094d4d1a6cf0bfd0e06b [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;
Steven Morelandd8536202018-09-26 10:56:19 -070016using ::android::hardware::interfacesEqual;
Steven Morelandcdf94722017-03-21 12:16:31 -070017
Steven Morelandd83d1102016-10-25 15:01:47 -070018namespace android {
19namespace hidl {
20namespace manager {
Steven Morelandd83d1102016-10-25 15:01:47 -070021namespace implementation {
22
Martijn Coenen7fafc142017-03-06 16:17:51 +010023static constexpr uint64_t kServiceDiedCookie = 0;
24static constexpr uint64_t kPackageListenerDiedCookie = 1;
25static constexpr uint64_t kServiceListenerDiedCookie = 2;
Steven Morelandd8536202018-09-26 10:56:19 -070026static constexpr uint64_t kClientCallbackDiedCookie = 3;
Martijn Coenen7fafc142017-03-06 16:17:51 +010027
Yifan Hong83c49f62017-01-25 14:16:34 -080028size_t ServiceManager::countExistingService() const {
29 size_t total = 0;
30 forEachExistingService([&] (const HidlService *) {
31 ++total;
Steven Morelandd8536202018-09-26 10:56:19 -070032 return true; // continue
Yifan Hong83c49f62017-01-25 14:16:34 -080033 });
34 return total;
35}
36
Steven Morelandd8536202018-09-26 10:56:19 -070037void ServiceManager::forEachExistingService(std::function<bool(const HidlService *)> f) const {
38 forEachServiceEntry([&] (const HidlService *service) {
Yifan Hongee531a82017-02-03 15:10:18 -080039 if (service->getService() == nullptr) {
Steven Morelandd8536202018-09-26 10:56:19 -070040 return true; // continue
Yifan Hongee531a82017-02-03 15:10:18 -080041 }
Steven Morelandd8536202018-09-26 10:56:19 -070042 return f(service);
Yifan Hongee531a82017-02-03 15:10:18 -080043 });
44}
45
Steven Morelandd8536202018-09-26 10:56:19 -070046void ServiceManager::forEachExistingService(std::function<bool(HidlService *)> f) {
47 forEachServiceEntry([&] (HidlService *service) {
48 if (service->getService() == nullptr) {
49 return true; // continue
50 }
51 return f(service);
52 });
53}
Yifan Hong83c49f62017-01-25 14:16:34 -080054
Steven Morelandd8536202018-09-26 10:56:19 -070055void ServiceManager::forEachServiceEntry(std::function<bool(const HidlService *)> f) const {
56 for (const auto& interfaceMapping : mServiceMap) {
57 const auto& instanceMap = interfaceMapping.second.getInstanceMap();
58
59 for (const auto& instanceMapping : instanceMap) {
60 if (!f(instanceMapping.second.get())) {
61 return;
62 }
63 }
64 }
65}
66
67void ServiceManager::forEachServiceEntry(std::function<bool(HidlService *)> f) {
68 for (auto& interfaceMapping : mServiceMap) {
69 auto& instanceMap = interfaceMapping.second.getInstanceMap();
70
71 for (auto& instanceMapping : instanceMap) {
72 if (!f(instanceMapping.second.get())) {
73 return;
74 }
Yifan Hong83c49f62017-01-25 14:16:34 -080075 }
76 }
77}
78
Martijn Coenen7fafc142017-03-06 16:17:51 +010079void ServiceManager::serviceDied(uint64_t cookie, const wp<IBase>& who) {
Steven Moreland3af80b92018-05-09 15:31:18 -070080 bool serviceRemoved = false;
Martijn Coenen7fafc142017-03-06 16:17:51 +010081 switch (cookie) {
82 case kServiceDiedCookie:
Steven Moreland3af80b92018-05-09 15:31:18 -070083 serviceRemoved = removeService(who, nullptr /* restrictToInstanceName */);
Martijn Coenen7fafc142017-03-06 16:17:51 +010084 break;
85 case kPackageListenerDiedCookie:
Steven Moreland3af80b92018-05-09 15:31:18 -070086 serviceRemoved = removePackageListener(who);
Martijn Coenen7fafc142017-03-06 16:17:51 +010087 break;
88 case kServiceListenerDiedCookie:
Steven Moreland3af80b92018-05-09 15:31:18 -070089 serviceRemoved = removeServiceListener(who);
Martijn Coenen7fafc142017-03-06 16:17:51 +010090 break;
Steven Morelandd8536202018-09-26 10:56:19 -070091 case kClientCallbackDiedCookie: {
92 sp<IBase> base = who.promote();
93 IClientCallback* callback = static_cast<IClientCallback*>(base.get());
94 serviceRemoved = unregisterClientCallback(nullptr /*service*/,
95 sp<IClientCallback>(callback));
96 } break;
Martijn Coenen7fafc142017-03-06 16:17:51 +010097 }
Steven Moreland3af80b92018-05-09 15:31:18 -070098
99 if (!serviceRemoved) {
Steven Morelandd8536202018-09-26 10:56:19 -0700100 LOG(ERROR) << "Received death notification but interface instance not removed. Cookie: "
101 << cookie << " Service pointer: " << who.promote().get();
Steven Moreland3af80b92018-05-09 15:31:18 -0700102 }
Martijn Coenen46847a62016-12-19 05:36:12 +0100103}
104
Steven Moreland2173d3c2016-11-09 15:00:58 -0800105ServiceManager::InstanceMap &ServiceManager::PackageInterfaceMap::getInstanceMap() {
106 return mInstanceMap;
Steven Moreland5fb3d652016-11-03 13:45:18 -0700107}
108
Steven Moreland2173d3c2016-11-09 15:00:58 -0800109const ServiceManager::InstanceMap &ServiceManager::PackageInterfaceMap::getInstanceMap() const {
110 return mInstanceMap;
Steven Moreland5fb3d652016-11-03 13:45:18 -0700111}
112
Steven Morelandd544cf62017-01-04 15:24:32 -0800113const HidlService *ServiceManager::PackageInterfaceMap::lookup(
114 const std::string &name) const {
115 auto it = mInstanceMap.find(name);
Steven Moreland76237812016-11-08 15:59:04 -0800116
Steven Morelandd544cf62017-01-04 15:24:32 -0800117 if (it == mInstanceMap.end()) {
118 return nullptr;
Steven Moreland5fb3d652016-11-03 13:45:18 -0700119 }
120
Steven Morelandd544cf62017-01-04 15:24:32 -0800121 return it->second.get();
Steven Moreland2173d3c2016-11-09 15:00:58 -0800122}
Steven Moreland5fb3d652016-11-03 13:45:18 -0700123
Steven Morelandd544cf62017-01-04 15:24:32 -0800124HidlService *ServiceManager::PackageInterfaceMap::lookup(
125 const std::string &name) {
Steven Moreland5fb3d652016-11-03 13:45:18 -0700126
Steven Moreland2173d3c2016-11-09 15:00:58 -0800127 return const_cast<HidlService*>(
Steven Morelandd544cf62017-01-04 15:24:32 -0800128 const_cast<const PackageInterfaceMap*>(this)->lookup(name));
Steven Moreland2173d3c2016-11-09 15:00:58 -0800129}
130
131void ServiceManager::PackageInterfaceMap::insertService(
132 std::unique_ptr<HidlService> &&service) {
Steven Morelandd544cf62017-01-04 15:24:32 -0800133 mInstanceMap.insert({service->getInstanceName(), std::move(service)});
Steven Moreland2173d3c2016-11-09 15:00:58 -0800134}
135
136void ServiceManager::PackageInterfaceMap::sendPackageRegistrationNotification(
137 const hidl_string &fqName,
Martijn Coenen7fafc142017-03-06 16:17:51 +0100138 const hidl_string &instanceName) {
Steven Moreland2173d3c2016-11-09 15:00:58 -0800139
Martijn Coenen7fafc142017-03-06 16:17:51 +0100140 for (auto it = mPackageListeners.begin(); it != mPackageListeners.end();) {
141 auto ret = (*it)->onRegistration(fqName, instanceName, false /* preexisting */);
142 if (ret.isOk()) {
143 ++it;
144 } else {
145 LOG(ERROR) << "Dropping registration callback for " << fqName << "/" << instanceName
146 << ": transport error.";
147 it = mPackageListeners.erase(it);
148 }
Steven Moreland2173d3c2016-11-09 15:00:58 -0800149 }
150}
Steven Moreland2173d3c2016-11-09 15:00:58 -0800151
Martijn Coenen7fafc142017-03-06 16:17:51 +0100152void ServiceManager::PackageInterfaceMap::addPackageListener(sp<IServiceNotification> listener) {
Steven Moreland2173d3c2016-11-09 15:00:58 -0800153 for (const auto &instanceMapping : mInstanceMap) {
154 const std::unique_ptr<HidlService> &service = instanceMapping.second;
155
156 if (service->getService() == nullptr) {
157 continue;
158 }
159
Steven Moreland30acc222017-01-26 11:44:38 -0800160 auto ret = listener->onRegistration(
Steven Morelandd544cf62017-01-04 15:24:32 -0800161 service->getInterfaceName(),
162 service->getInstanceName(),
163 true /* preexisting */);
Martijn Coenen7fafc142017-03-06 16:17:51 +0100164 if (!ret.isOk()) {
165 LOG(ERROR) << "Not adding package listener for " << service->getInterfaceName()
166 << "/" << service->getInstanceName() << ": transport error "
167 << "when sending notification for already registered instance.";
168 return;
169 }
Steven Moreland2173d3c2016-11-09 15:00:58 -0800170 }
Martijn Coenen7fafc142017-03-06 16:17:51 +0100171 mPackageListeners.push_back(listener);
172}
173
174bool ServiceManager::PackageInterfaceMap::removePackageListener(const wp<IBase>& who) {
175 bool found = false;
176
177 for (auto it = mPackageListeners.begin(); it != mPackageListeners.end();) {
Steven Moreland6f4fbe12017-07-21 18:07:42 -0700178 if (interfacesEqual(*it, who.promote())) {
Martijn Coenen7fafc142017-03-06 16:17:51 +0100179 it = mPackageListeners.erase(it);
180 found = true;
181 } else {
182 ++it;
183 }
184 }
185
186 return found;
Steven Moreland5fb3d652016-11-03 13:45:18 -0700187}
188
Steven Moreland6f4fbe12017-07-21 18:07:42 -0700189bool ServiceManager::PackageInterfaceMap::removeServiceListener(const wp<IBase>& who) {
Steven Moreland6f4fbe12017-07-21 18:07:42 -0700190 bool found = false;
191
192 for (auto &servicePair : getInstanceMap()) {
193 const std::unique_ptr<HidlService> &service = servicePair.second;
194 found |= service->removeListener(who);
195 }
196
197 return found;
198}
199
Steven Moreland5a317452017-10-05 18:49:48 -0700200static void tryStartService(const std::string& fqName, const std::string& name) {
201 using ::android::base::SetProperty;
202
Steven Moreland58cef2c2018-01-24 16:41:38 -0800203 std::thread([=] {
204 bool success = SetProperty("ctl.interface_start", fqName + "/" + name);
Steven Moreland5a317452017-10-05 18:49:48 -0700205
Steven Moreland58cef2c2018-01-24 16:41:38 -0800206 if (!success) {
207 LOG(ERROR) << "Failed to set property for starting " << fqName << "/" << name;
208 }
209 }).detach();
Steven Moreland5a317452017-10-05 18:49:48 -0700210}
211
Steven Morelandd83d1102016-10-25 15:01:47 -0700212// Methods from ::android::hidl::manager::V1_0::IServiceManager follow.
Steven Moreland5a317452017-10-05 18:49:48 -0700213Return<sp<IBase>> ServiceManager::get(const hidl_string& hidlFqName,
214 const hidl_string& hidlName) {
215 const std::string fqName = hidlFqName;
216 const std::string name = hidlName;
217
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700218 pid_t pid = IPCThreadState::self()->getCallingPid();
219 if (!mAcl.canGet(fqName, pid)) {
220 return nullptr;
221 }
222
Steven Morelandd544cf62017-01-04 15:24:32 -0800223 auto ifaceIt = mServiceMap.find(fqName);
Steven Moreland5fb3d652016-11-03 13:45:18 -0700224 if (ifaceIt == mServiceMap.end()) {
Steven Moreland5a317452017-10-05 18:49:48 -0700225 tryStartService(fqName, hidlName);
Martijn Coenen7b02bf92017-01-02 15:17:58 +0100226 return nullptr;
Steven Moreland5fb3d652016-11-03 13:45:18 -0700227 }
228
Steven Morelandc06af8d2018-10-22 16:35:07 -0700229 PackageInterfaceMap &ifaceMap = ifaceIt->second;
230
231 // may be modified in post-command task
232 HidlService *hidlService = ifaceMap.lookup(name);
Steven Moreland5fb3d652016-11-03 13:45:18 -0700233
Steven Morelandd544cf62017-01-04 15:24:32 -0800234 if (hidlService == nullptr) {
Steven Moreland5a317452017-10-05 18:49:48 -0700235 tryStartService(fqName, hidlName);
Martijn Coenen7b02bf92017-01-02 15:17:58 +0100236 return nullptr;
Steven Morelandd83d1102016-10-25 15:01:47 -0700237 }
Steven Morelandd544cf62017-01-04 15:24:32 -0800238
Steven Moreland5a317452017-10-05 18:49:48 -0700239 sp<IBase> service = hidlService->getService();
240 if (service == nullptr) {
241 tryStartService(fqName, hidlName);
242 return nullptr;
243 }
244
Steven Moreland98db8292018-12-07 13:08:25 -0800245 // Let HidlService know that we handed out a client. If the client drops the service before the
246 // next time handleClientCallbacks is called, it will still know that the service had been handed out.
247 hidlService->guaranteeClient();
248
Steven Morelandc06af8d2018-10-22 16:35:07 -0700249 // This is executed immediately after the binder driver confirms the transaction. The driver
250 // will update the appropriate data structures to reflect the fact that the client now has the
251 // service this function is returning. Nothing else can update the HidlService at the same
252 // time. This will run before anything else can modify the HidlService which is owned by this
253 // object, so it will be in the same state that it was when this function returns.
254 hardware::addPostCommandTask([hidlService] {
Peter Kalauskas3b27ec52019-01-17 14:47:24 -0800255 hidlService->handleClientCallbacks(false /* isCalledOnInterval */);
Steven Morelandc06af8d2018-10-22 16:35:07 -0700256 });
257
Steven Moreland5a317452017-10-05 18:49:48 -0700258 return service;
Steven Morelandd83d1102016-10-25 15:01:47 -0700259}
260
Martijn Coenen1a5da1c2017-03-06 13:05:39 +0100261Return<bool> ServiceManager::add(const hidl_string& name, const sp<IBase>& service) {
Steven Moreland707f22c2018-10-11 12:09:34 -0700262 bool addSuccess = false;
Steven Morelandd83d1102016-10-25 15:01:47 -0700263
Martijn Coenen1a5da1c2017-03-06 13:05:39 +0100264 if (service == nullptr) {
Steven Moreland5fb3d652016-11-03 13:45:18 -0700265 return false;
Steven Morelandd83d1102016-10-25 15:01:47 -0700266 }
Steven Moreland5fb3d652016-11-03 13:45:18 -0700267
Steven Morelandcdf94722017-03-21 12:16:31 -0700268 pid_t pid = IPCThreadState::self()->getCallingPid();
Steven Moreland4034c1c2017-11-03 17:42:27 -0700269 auto context = mAcl.getContext(pid);
Steven Morelandcdf94722017-03-21 12:16:31 -0700270
Martijn Coenen1a5da1c2017-03-06 13:05:39 +0100271 auto ret = service->interfaceChain([&](const auto &interfaceChain) {
Steven Moreland707f22c2018-10-11 12:09:34 -0700272 addSuccess = addImpl(name, service, interfaceChain, context, pid);
Martijn Coenen1a5da1c2017-03-06 13:05:39 +0100273 });
274
275 if (!ret.isOk()) {
Steven Moreland707f22c2018-10-11 12:09:34 -0700276 LOG(ERROR) << "Failed to retrieve interface chain: " << ret.description();
Martijn Coenen1a5da1c2017-03-06 13:05:39 +0100277 return false;
Steven Morelandd83d1102016-10-25 15:01:47 -0700278 }
Steven Morelandd544cf62017-01-04 15:24:32 -0800279
Steven Moreland707f22c2018-10-11 12:09:34 -0700280 return addSuccess;
281}
282
283bool ServiceManager::addImpl(const hidl_string& name,
284 const sp<IBase>& service,
285 const hidl_vec<hidl_string>& interfaceChain,
286 const AccessControl::Context &context,
287 pid_t pid) {
288 if (interfaceChain.size() == 0) {
289 LOG(WARNING) << "Empty interface chain for " << name;
290 return false;
291 }
292
293 // First, verify you're allowed to add() the whole interface hierarchy
294 for(size_t i = 0; i < interfaceChain.size(); i++) {
295 const std::string fqName = interfaceChain[i];
296
297 if (!mAcl.canAdd(fqName, context, pid)) {
298 return false;
299 }
300 }
301
302 {
303 // For IBar extends IFoo if IFoo/default is being registered, remove
304 // IBar/default. This makes sure the following two things are equivalent
305 // 1). IBar::castFrom(IFoo::getService(X))
306 // 2). IBar::getService(X)
307 // assuming that IBar is declared in the device manifest and there
308 // is also not an IBaz extends IFoo.
309 const std::string childFqName = interfaceChain[0];
310 const PackageInterfaceMap &ifaceMap = mServiceMap[childFqName];
311 const HidlService *hidlService = ifaceMap.lookup(name);
312 if (hidlService != nullptr) {
313 const sp<IBase> remove = hidlService->getService();
314
315 if (remove != nullptr) {
316 const std::string instanceName = name;
317 removeService(remove, &instanceName /* restrictToInstanceName */);
318 }
319 }
320 }
321
322 for(size_t i = 0; i < interfaceChain.size(); i++) {
323 const std::string fqName = interfaceChain[i];
324
325 PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
326 HidlService *hidlService = ifaceMap.lookup(name);
327
328 if (hidlService == nullptr) {
329 ifaceMap.insertService(
330 std::make_unique<HidlService>(fqName, name, service, pid));
331 } else {
332 hidlService->setService(service, pid);
333 }
334
335 ifaceMap.sendPackageRegistrationNotification(fqName, name);
336 }
337
338 bool linkRet = service->linkToDeath(this, kServiceDiedCookie).withDefault(false);
339 if (!linkRet) {
340 LOG(ERROR) << "Could not link to death for " << interfaceChain[0] << "/" << name;
341 }
342
343 return true;
Steven Morelandd83d1102016-10-25 15:01:47 -0700344}
345
Steven Moreland37aed802017-04-06 09:16:42 -0700346Return<ServiceManager::Transport> ServiceManager::getTransport(const hidl_string& fqName,
347 const hidl_string& name) {
348 using ::android::hardware::getTransport;
349
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700350 pid_t pid = IPCThreadState::self()->getCallingPid();
351 if (!mAcl.canGet(fqName, pid)) {
352 return Transport::EMPTY;
353 }
354
Steven Moreland37aed802017-04-06 09:16:42 -0700355 switch (getTransport(fqName, name)) {
356 case vintf::Transport::HWBINDER:
357 return Transport::HWBINDER;
358 case vintf::Transport::PASSTHROUGH:
359 return Transport::PASSTHROUGH;
360 case vintf::Transport::EMPTY:
361 default:
362 return Transport::EMPTY;
363 }
364}
365
Steven Moreland76237812016-11-08 15:59:04 -0800366Return<void> ServiceManager::list(list_cb _hidl_cb) {
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700367 pid_t pid = IPCThreadState::self()->getCallingPid();
368 if (!mAcl.canList(pid)) {
369 _hidl_cb({});
370 return Void();
371 }
Steven Moreland76237812016-11-08 15:59:04 -0800372
373 hidl_vec<hidl_string> list;
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700374
Yifan Hong83c49f62017-01-25 14:16:34 -0800375 list.resize(countExistingService());
Steven Moreland76237812016-11-08 15:59:04 -0800376
377 size_t idx = 0;
Yifan Hong83c49f62017-01-25 14:16:34 -0800378 forEachExistingService([&] (const HidlService *service) {
379 list[idx++] = service->string();
Steven Morelandd8536202018-09-26 10:56:19 -0700380 return true; // continue
Yifan Hong83c49f62017-01-25 14:16:34 -0800381 });
Steven Moreland76237812016-11-08 15:59:04 -0800382
383 _hidl_cb(list);
384 return Void();
385}
386
Steven Moreland2173d3c2016-11-09 15:00:58 -0800387Return<void> ServiceManager::listByInterface(const hidl_string& fqName,
388 listByInterface_cb _hidl_cb) {
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700389 pid_t pid = IPCThreadState::self()->getCallingPid();
390 if (!mAcl.canGet(fqName, pid)) {
391 _hidl_cb({});
392 return Void();
393 }
394
Steven Morelandd544cf62017-01-04 15:24:32 -0800395 auto ifaceIt = mServiceMap.find(fqName);
Steven Moreland76237812016-11-08 15:59:04 -0800396 if (ifaceIt == mServiceMap.end()) {
397 _hidl_cb(hidl_vec<hidl_string>());
398 return Void();
399 }
400
Steven Moreland2173d3c2016-11-09 15:00:58 -0800401 const auto &instanceMap = ifaceIt->second.getInstanceMap();
Steven Moreland76237812016-11-08 15:59:04 -0800402
403 hidl_vec<hidl_string> list;
Steven Morelandfc56b612017-01-23 20:10:45 -0800404
405 size_t total = 0;
406 for (const auto &serviceMapping : instanceMap) {
407 const std::unique_ptr<HidlService> &service = serviceMapping.second;
408 if (service->getService() == nullptr) continue;
409
410 ++total;
411 }
412 list.resize(total);
Steven Moreland76237812016-11-08 15:59:04 -0800413
414 size_t idx = 0;
Steven Moreland2173d3c2016-11-09 15:00:58 -0800415 for (const auto &serviceMapping : instanceMap) {
Steven Moreland76237812016-11-08 15:59:04 -0800416 const std::unique_ptr<HidlService> &service = serviceMapping.second;
Steven Morelandfc56b612017-01-23 20:10:45 -0800417 if (service->getService() == nullptr) continue;
Steven Moreland76237812016-11-08 15:59:04 -0800418
Steven Morelandd544cf62017-01-04 15:24:32 -0800419 list[idx++] = service->getInstanceName();
Steven Moreland76237812016-11-08 15:59:04 -0800420 }
421
422 _hidl_cb(list);
423 return Void();
424}
425
Steven Moreland2173d3c2016-11-09 15:00:58 -0800426Return<bool> ServiceManager::registerForNotifications(const hidl_string& fqName,
427 const hidl_string& name,
428 const sp<IServiceNotification>& callback) {
429 if (callback == nullptr) {
430 return false;
431 }
432
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700433 pid_t pid = IPCThreadState::self()->getCallingPid();
434 if (!mAcl.canGet(fqName, pid)) {
435 return false;
436 }
437
Steven Morelandd544cf62017-01-04 15:24:32 -0800438 PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
Steven Moreland2173d3c2016-11-09 15:00:58 -0800439
440 if (name.empty()) {
Steven Moreland78c899e2018-09-27 16:45:18 -0700441 bool ret = callback->linkToDeath(this, kPackageListenerDiedCookie).withDefault(false);
442 if (!ret) {
Martijn Coenen7fafc142017-03-06 16:17:51 +0100443 LOG(ERROR) << "Failed to register death recipient for " << fqName << "/" << name;
444 return false;
445 }
Steven Moreland2173d3c2016-11-09 15:00:58 -0800446 ifaceMap.addPackageListener(callback);
447 return true;
448 }
449
Steven Morelandd544cf62017-01-04 15:24:32 -0800450 HidlService *service = ifaceMap.lookup(name);
Steven Moreland2173d3c2016-11-09 15:00:58 -0800451
Steven Moreland78c899e2018-09-27 16:45:18 -0700452 bool ret = callback->linkToDeath(this, kServiceListenerDiedCookie).withDefault(false);
453 if (!ret) {
Martijn Coenen7fafc142017-03-06 16:17:51 +0100454 LOG(ERROR) << "Failed to register death recipient for " << fqName << "/" << name;
455 return false;
456 }
457
Steven Moreland2173d3c2016-11-09 15:00:58 -0800458 if (service == nullptr) {
Steven Morelandcdf94722017-03-21 12:16:31 -0700459 auto adding = std::make_unique<HidlService>(fqName, name);
Steven Morelandd544cf62017-01-04 15:24:32 -0800460 adding->addListener(callback);
461 ifaceMap.insertService(std::move(adding));
Steven Moreland2173d3c2016-11-09 15:00:58 -0800462 } else {
463 service->addListener(callback);
464 }
465
466 return true;
467}
468
Steven Moreland6f4fbe12017-07-21 18:07:42 -0700469Return<bool> ServiceManager::unregisterForNotifications(const hidl_string& fqName,
470 const hidl_string& name,
471 const sp<IServiceNotification>& callback) {
472 if (callback == nullptr) {
473 LOG(ERROR) << "Cannot unregister null callback for " << fqName << "/" << name;
474 return false;
475 }
476
477 // NOTE: don't need ACL since callback is binder token, and if someone has gotten it,
478 // then they already have access to it.
479
480 if (fqName.empty()) {
481 bool success = false;
482 success |= removePackageListener(callback);
483 success |= removeServiceListener(callback);
484 return success;
485 }
486
487 PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
488
489 if (name.empty()) {
490 bool success = false;
491 success |= ifaceMap.removePackageListener(callback);
492 success |= ifaceMap.removeServiceListener(callback);
493 return success;
494 }
495
496 HidlService *service = ifaceMap.lookup(name);
497
498 if (service == nullptr) {
499 return false;
500 }
501
502 return service->removeListener(callback);
503}
504
Steven Morelandd8536202018-09-26 10:56:19 -0700505Return<bool> ServiceManager::registerClientCallback(const sp<IBase>& server,
506 const sp<IClientCallback>& cb) {
507 if (server == nullptr || cb == nullptr) return false;
508
509 // only the server of the interface can register a client callback
510 pid_t pid = IPCThreadState::self()->getCallingPid();
511
512 HidlService* registered = nullptr;
513
514 forEachExistingService([&] (HidlService *service) {
515 if (service->getPid() != pid) {
516 return true; // continue
517 }
518
519 if (interfacesEqual(service->getService(), server)) {
520 service->addClientCallback(cb);
521 registered = service;
522 return false; // break
523 }
524 return true; // continue
525 });
526
527 if (registered != nullptr) {
528 bool linkRet = cb->linkToDeath(this, kClientCallbackDiedCookie).withDefault(false);
529 if (!linkRet) {
530 LOG(ERROR) << "Could not link to death for registerClientCallback";
531 unregisterClientCallback(server, cb);
532 registered = nullptr;
533 }
534 }
535
536 if (registered != nullptr) {
Peter Kalauskas3b27ec52019-01-17 14:47:24 -0800537 registered->handleClientCallbacks(false /* isCalledOnInterval */);
Steven Morelandd8536202018-09-26 10:56:19 -0700538 }
539
540 return registered != nullptr;
541}
542
543Return<bool> ServiceManager::unregisterClientCallback(const sp<IBase>& server,
544 const sp<IClientCallback>& cb) {
545 if (cb == nullptr) return false;
546
547 bool removed = false;
548
549 forEachExistingService([&] (HidlService *service) {
550 if (server == nullptr || interfacesEqual(service->getService(), server)) {
551 removed |= service->removeClientCallback(cb);
552 }
553 return true; // continue
554 });
555
556 return removed;
557}
558
559void ServiceManager::handleClientCallbacks() {
560 forEachServiceEntry([&] (HidlService *service) {
Peter Kalauskas3b27ec52019-01-17 14:47:24 -0800561 service->handleClientCallbacks(true /* isCalledOnInterval */);
Steven Morelandd8536202018-09-26 10:56:19 -0700562 return true; // continue
563 });
564}
565
Steven Moreland707f22c2018-10-11 12:09:34 -0700566Return<bool> ServiceManager::addWithChain(const hidl_string& name,
567 const sp<IBase>& service,
568 const hidl_vec<hidl_string>& chain) {
569 if (service == nullptr) {
570 return false;
571 }
572
573 pid_t pid = IPCThreadState::self()->getCallingPid();
574 auto context = mAcl.getContext(pid);
575
576 return addImpl(name, service, chain, context, pid);
577}
578
Steven Morelandaae4eab2018-10-29 13:00:31 -0700579Return<void> ServiceManager::listManifestByInterface(const hidl_string& fqName,
580 listManifestByInterface_cb _hidl_cb) {
581 pid_t pid = IPCThreadState::self()->getCallingPid();
582 if (!mAcl.canGet(fqName, pid)) {
583 _hidl_cb({});
584 return Void();
585 }
586
587 std::set<std::string> instances = getInstances(fqName);
588 hidl_vec<hidl_string> ret(instances.begin(), instances.end());
589
590 _hidl_cb(ret);
591 return Void();
592}
593
Yifan Hong83c49f62017-01-25 14:16:34 -0800594Return<void> ServiceManager::debugDump(debugDump_cb _cb) {
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700595 pid_t pid = IPCThreadState::self()->getCallingPid();
596 if (!mAcl.canList(pid)) {
597 _cb({});
598 return Void();
599 }
600
Yifan Hongee531a82017-02-03 15:10:18 -0800601 std::vector<IServiceManager::InstanceDebugInfo> list;
602 forEachServiceEntry([&] (const HidlService *service) {
Yifan Hongee531a82017-02-03 15:10:18 -0800603 hidl_vec<int32_t> clientPids;
604 clientPids.resize(service->getPassthroughClients().size());
605
606 size_t i = 0;
607 for (pid_t p : service->getPassthroughClients()) {
608 clientPids[i++] = p;
609 }
610
611 list.push_back({
Steven Morelandcdf94722017-03-21 12:16:31 -0700612 .pid = service->getPid(),
Yifan Hong83c49f62017-01-25 14:16:34 -0800613 .interfaceName = service->getInterfaceName(),
614 .instanceName = service->getInstanceName(),
Yifan Hong1d2deb12017-03-02 16:58:22 -0800615 .clientPids = clientPids,
616 .arch = ::android::hidl::base::V1_0::DebugInfo::Architecture::UNKNOWN
Yifan Hongee531a82017-02-03 15:10:18 -0800617 });
Steven Morelandd8536202018-09-26 10:56:19 -0700618
619 return true; // continue
Yifan Hong83c49f62017-01-25 14:16:34 -0800620 });
621
622 _cb(list);
623 return Void();
624}
625
Yifan Hongee531a82017-02-03 15:10:18 -0800626
627Return<void> ServiceManager::registerPassthroughClient(const hidl_string &fqName,
Martijn Coenen737de1b2017-04-27 09:29:43 -0700628 const hidl_string &name) {
629 pid_t pid = IPCThreadState::self()->getCallingPid();
630 if (!mAcl.canGet(fqName, pid)) {
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700631 /* We guard this function with "get", because it's typically used in
632 * the getService() path, albeit for a passthrough service in this
633 * case
634 */
635 return Void();
636 }
Yifan Hongee531a82017-02-03 15:10:18 -0800637
638 PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
639
640 if (name.empty()) {
641 LOG(WARNING) << "registerPassthroughClient encounters empty instance name for "
642 << fqName.c_str();
643 return Void();
644 }
645
646 HidlService *service = ifaceMap.lookup(name);
647
648 if (service == nullptr) {
Steven Morelandcdf94722017-03-21 12:16:31 -0700649 auto adding = std::make_unique<HidlService>(fqName, name);
Yifan Hongee531a82017-02-03 15:10:18 -0800650 adding->registerPassthroughClient(pid);
651 ifaceMap.insertService(std::move(adding));
652 } else {
653 service->registerPassthroughClient(pid);
654 }
655 return Void();
656}
657
Steven Moreland76936fe2017-09-19 12:18:30 -0700658bool ServiceManager::removeService(const wp<IBase>& who, const std::string* restrictToInstanceName) {
Steven Moreland76936fe2017-09-19 12:18:30 -0700659 bool keepInstance = false;
660 bool removed = false;
Martijn Coenen46847a62016-12-19 05:36:12 +0100661 for (auto &interfaceMapping : mServiceMap) {
662 auto &instanceMap = interfaceMapping.second.getInstanceMap();
663
Steven Morelandd544cf62017-01-04 15:24:32 -0800664 for (auto &servicePair : instanceMap) {
Steven Moreland76936fe2017-09-19 12:18:30 -0700665 const std::string &instanceName = servicePair.first;
Steven Morelandd544cf62017-01-04 15:24:32 -0800666 const std::unique_ptr<HidlService> &service = servicePair.second;
Steven Moreland76936fe2017-09-19 12:18:30 -0700667
Steven Moreland6f4fbe12017-07-21 18:07:42 -0700668 if (interfacesEqual(service->getService(), who.promote())) {
Steven Moreland76936fe2017-09-19 12:18:30 -0700669 if (restrictToInstanceName != nullptr && *restrictToInstanceName != instanceName) {
670 // We cannot remove all instances of this service, so we don't return that it
671 // has been entirely removed.
672 keepInstance = true;
673 continue;
674 }
675
Steven Morelandcdf94722017-03-21 12:16:31 -0700676 service->setService(nullptr, static_cast<pid_t>(IServiceManager::PidConstant::NO_PID));
Steven Moreland76936fe2017-09-19 12:18:30 -0700677 removed = true;
Martijn Coenen46847a62016-12-19 05:36:12 +0100678 }
679 }
680 }
Steven Moreland76936fe2017-09-19 12:18:30 -0700681
682 return !keepInstance && removed;
Martijn Coenen46847a62016-12-19 05:36:12 +0100683}
Yifan Hong83c49f62017-01-25 14:16:34 -0800684
Martijn Coenen7fafc142017-03-06 16:17:51 +0100685bool ServiceManager::removePackageListener(const wp<IBase>& who) {
686 bool found = false;
687
688 for (auto &interfaceMapping : mServiceMap) {
689 found |= interfaceMapping.second.removePackageListener(who);
690 }
691
692 return found;
693}
694
695bool ServiceManager::removeServiceListener(const wp<IBase>& who) {
696 bool found = false;
697 for (auto &interfaceMapping : mServiceMap) {
Steven Moreland6f4fbe12017-07-21 18:07:42 -0700698 auto &packageInterfaceMap = interfaceMapping.second;
Martijn Coenen7fafc142017-03-06 16:17:51 +0100699
Steven Moreland6f4fbe12017-07-21 18:07:42 -0700700 found |= packageInterfaceMap.removeServiceListener(who);
Martijn Coenen7fafc142017-03-06 16:17:51 +0100701 }
702 return found;
703}
Steven Moreland6f4fbe12017-07-21 18:07:42 -0700704} // namespace implementation
Steven Morelandd83d1102016-10-25 15:01:47 -0700705} // namespace manager
706} // namespace hidl
707} // namespace android