blob: 85d4974d74ab609d2722b442a455e68fece9cc43 [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
Steven Moreland2aefd642019-01-03 17:51:17 -080039AccessControl::CallingContext getBinderCallingContext() {
40 const auto& self = IPCThreadState::self();
41
42 pid_t pid = self->getCallingPid();
43 const char* sid = self->getCallingSid();
44
45 if (sid == nullptr) {
46 if (pid != getpid()) {
47 android_errorWriteLog(0x534e4554, "121035042");
48 }
49
50 return AccessControl::getCallingContext(pid);
51 } else {
52 return { true, sid, pid };
53 }
54}
55
Martijn Coenen7fafc142017-03-06 16:17:51 +010056static constexpr uint64_t kServiceDiedCookie = 0;
57static constexpr uint64_t kPackageListenerDiedCookie = 1;
58static constexpr uint64_t kServiceListenerDiedCookie = 2;
Steven Morelandd8536202018-09-26 10:56:19 -070059static constexpr uint64_t kClientCallbackDiedCookie = 3;
Martijn Coenen7fafc142017-03-06 16:17:51 +010060
Yifan Hong83c49f62017-01-25 14:16:34 -080061size_t ServiceManager::countExistingService() const {
62 size_t total = 0;
63 forEachExistingService([&] (const HidlService *) {
64 ++total;
Steven Morelandd8536202018-09-26 10:56:19 -070065 return true; // continue
Yifan Hong83c49f62017-01-25 14:16:34 -080066 });
67 return total;
68}
69
Steven Morelandd8536202018-09-26 10:56:19 -070070void ServiceManager::forEachExistingService(std::function<bool(const HidlService *)> f) const {
71 forEachServiceEntry([&] (const HidlService *service) {
Yifan Hongee531a82017-02-03 15:10:18 -080072 if (service->getService() == nullptr) {
Steven Morelandd8536202018-09-26 10:56:19 -070073 return true; // continue
Yifan Hongee531a82017-02-03 15:10:18 -080074 }
Steven Morelandd8536202018-09-26 10:56:19 -070075 return f(service);
Yifan Hongee531a82017-02-03 15:10:18 -080076 });
77}
78
Steven Morelandd8536202018-09-26 10:56:19 -070079void ServiceManager::forEachExistingService(std::function<bool(HidlService *)> f) {
80 forEachServiceEntry([&] (HidlService *service) {
81 if (service->getService() == nullptr) {
82 return true; // continue
83 }
84 return f(service);
85 });
86}
Yifan Hong83c49f62017-01-25 14:16:34 -080087
Steven Morelandd8536202018-09-26 10:56:19 -070088void ServiceManager::forEachServiceEntry(std::function<bool(const HidlService *)> f) const {
89 for (const auto& interfaceMapping : mServiceMap) {
90 const auto& instanceMap = interfaceMapping.second.getInstanceMap();
91
92 for (const auto& instanceMapping : instanceMap) {
93 if (!f(instanceMapping.second.get())) {
94 return;
95 }
96 }
97 }
98}
99
100void ServiceManager::forEachServiceEntry(std::function<bool(HidlService *)> f) {
101 for (auto& interfaceMapping : mServiceMap) {
102 auto& instanceMap = interfaceMapping.second.getInstanceMap();
103
104 for (auto& instanceMapping : instanceMap) {
105 if (!f(instanceMapping.second.get())) {
106 return;
107 }
Yifan Hong83c49f62017-01-25 14:16:34 -0800108 }
109 }
110}
111
Steven Morelanddbaab552019-01-24 19:00:04 -0800112HidlService* ServiceManager::lookup(const std::string& fqName, const std::string& name) {
113 auto ifaceIt = mServiceMap.find(fqName);
114 if (ifaceIt == mServiceMap.end()) {
115 return nullptr;
116 }
117
118 PackageInterfaceMap &ifaceMap = ifaceIt->second;
119
120 HidlService *hidlService = ifaceMap.lookup(name);
121
122 return hidlService;
123}
124
Martijn Coenen7fafc142017-03-06 16:17:51 +0100125void ServiceManager::serviceDied(uint64_t cookie, const wp<IBase>& who) {
Steven Moreland3af80b92018-05-09 15:31:18 -0700126 bool serviceRemoved = false;
Martijn Coenen7fafc142017-03-06 16:17:51 +0100127 switch (cookie) {
128 case kServiceDiedCookie:
Steven Moreland3af80b92018-05-09 15:31:18 -0700129 serviceRemoved = removeService(who, nullptr /* restrictToInstanceName */);
Martijn Coenen7fafc142017-03-06 16:17:51 +0100130 break;
131 case kPackageListenerDiedCookie:
Steven Moreland3af80b92018-05-09 15:31:18 -0700132 serviceRemoved = removePackageListener(who);
Martijn Coenen7fafc142017-03-06 16:17:51 +0100133 break;
134 case kServiceListenerDiedCookie:
Steven Moreland3af80b92018-05-09 15:31:18 -0700135 serviceRemoved = removeServiceListener(who);
Martijn Coenen7fafc142017-03-06 16:17:51 +0100136 break;
Steven Morelandd8536202018-09-26 10:56:19 -0700137 case kClientCallbackDiedCookie: {
138 sp<IBase> base = who.promote();
139 IClientCallback* callback = static_cast<IClientCallback*>(base.get());
140 serviceRemoved = unregisterClientCallback(nullptr /*service*/,
141 sp<IClientCallback>(callback));
142 } break;
Martijn Coenen7fafc142017-03-06 16:17:51 +0100143 }
Steven Moreland3af80b92018-05-09 15:31:18 -0700144
145 if (!serviceRemoved) {
Steven Morelandd8536202018-09-26 10:56:19 -0700146 LOG(ERROR) << "Received death notification but interface instance not removed. Cookie: "
147 << cookie << " Service pointer: " << who.promote().get();
Steven Moreland3af80b92018-05-09 15:31:18 -0700148 }
Martijn Coenen46847a62016-12-19 05:36:12 +0100149}
150
Steven Moreland2173d3c2016-11-09 15:00:58 -0800151ServiceManager::InstanceMap &ServiceManager::PackageInterfaceMap::getInstanceMap() {
152 return mInstanceMap;
Steven Moreland5fb3d652016-11-03 13:45:18 -0700153}
154
Steven Moreland2173d3c2016-11-09 15:00:58 -0800155const ServiceManager::InstanceMap &ServiceManager::PackageInterfaceMap::getInstanceMap() const {
156 return mInstanceMap;
Steven Moreland5fb3d652016-11-03 13:45:18 -0700157}
158
Steven Morelandd544cf62017-01-04 15:24:32 -0800159const HidlService *ServiceManager::PackageInterfaceMap::lookup(
160 const std::string &name) const {
161 auto it = mInstanceMap.find(name);
Steven Moreland76237812016-11-08 15:59:04 -0800162
Steven Morelandd544cf62017-01-04 15:24:32 -0800163 if (it == mInstanceMap.end()) {
164 return nullptr;
Steven Moreland5fb3d652016-11-03 13:45:18 -0700165 }
166
Steven Morelandd544cf62017-01-04 15:24:32 -0800167 return it->second.get();
Steven Moreland2173d3c2016-11-09 15:00:58 -0800168}
Steven Moreland5fb3d652016-11-03 13:45:18 -0700169
Steven Morelandd544cf62017-01-04 15:24:32 -0800170HidlService *ServiceManager::PackageInterfaceMap::lookup(
171 const std::string &name) {
Steven Moreland5fb3d652016-11-03 13:45:18 -0700172
Steven Moreland2173d3c2016-11-09 15:00:58 -0800173 return const_cast<HidlService*>(
Steven Morelandd544cf62017-01-04 15:24:32 -0800174 const_cast<const PackageInterfaceMap*>(this)->lookup(name));
Steven Moreland2173d3c2016-11-09 15:00:58 -0800175}
176
177void ServiceManager::PackageInterfaceMap::insertService(
178 std::unique_ptr<HidlService> &&service) {
Steven Morelandd544cf62017-01-04 15:24:32 -0800179 mInstanceMap.insert({service->getInstanceName(), std::move(service)});
Steven Moreland2173d3c2016-11-09 15:00:58 -0800180}
181
182void ServiceManager::PackageInterfaceMap::sendPackageRegistrationNotification(
183 const hidl_string &fqName,
Martijn Coenen7fafc142017-03-06 16:17:51 +0100184 const hidl_string &instanceName) {
Steven Moreland2173d3c2016-11-09 15:00:58 -0800185
Martijn Coenen7fafc142017-03-06 16:17:51 +0100186 for (auto it = mPackageListeners.begin(); it != mPackageListeners.end();) {
187 auto ret = (*it)->onRegistration(fqName, instanceName, false /* preexisting */);
188 if (ret.isOk()) {
189 ++it;
190 } else {
191 LOG(ERROR) << "Dropping registration callback for " << fqName << "/" << instanceName
192 << ": transport error.";
193 it = mPackageListeners.erase(it);
194 }
Steven Moreland2173d3c2016-11-09 15:00:58 -0800195 }
196}
Steven Moreland2173d3c2016-11-09 15:00:58 -0800197
Martijn Coenen7fafc142017-03-06 16:17:51 +0100198void ServiceManager::PackageInterfaceMap::addPackageListener(sp<IServiceNotification> listener) {
Steven Moreland2173d3c2016-11-09 15:00:58 -0800199 for (const auto &instanceMapping : mInstanceMap) {
200 const std::unique_ptr<HidlService> &service = instanceMapping.second;
201
202 if (service->getService() == nullptr) {
203 continue;
204 }
205
Steven Moreland30acc222017-01-26 11:44:38 -0800206 auto ret = listener->onRegistration(
Steven Morelandd544cf62017-01-04 15:24:32 -0800207 service->getInterfaceName(),
208 service->getInstanceName(),
209 true /* preexisting */);
Martijn Coenen7fafc142017-03-06 16:17:51 +0100210 if (!ret.isOk()) {
211 LOG(ERROR) << "Not adding package listener for " << service->getInterfaceName()
212 << "/" << service->getInstanceName() << ": transport error "
213 << "when sending notification for already registered instance.";
214 return;
215 }
Steven Moreland2173d3c2016-11-09 15:00:58 -0800216 }
Martijn Coenen7fafc142017-03-06 16:17:51 +0100217 mPackageListeners.push_back(listener);
218}
219
220bool ServiceManager::PackageInterfaceMap::removePackageListener(const wp<IBase>& who) {
221 bool found = false;
222
223 for (auto it = mPackageListeners.begin(); it != mPackageListeners.end();) {
Steven Moreland6f4fbe12017-07-21 18:07:42 -0700224 if (interfacesEqual(*it, who.promote())) {
Martijn Coenen7fafc142017-03-06 16:17:51 +0100225 it = mPackageListeners.erase(it);
226 found = true;
227 } else {
228 ++it;
229 }
230 }
231
232 return found;
Steven Moreland5fb3d652016-11-03 13:45:18 -0700233}
234
Steven Moreland6f4fbe12017-07-21 18:07:42 -0700235bool ServiceManager::PackageInterfaceMap::removeServiceListener(const wp<IBase>& who) {
Steven Moreland6f4fbe12017-07-21 18:07:42 -0700236 bool found = false;
237
238 for (auto &servicePair : getInstanceMap()) {
239 const std::unique_ptr<HidlService> &service = servicePair.second;
240 found |= service->removeListener(who);
241 }
242
243 return found;
244}
245
Steven Moreland5a317452017-10-05 18:49:48 -0700246static void tryStartService(const std::string& fqName, const std::string& name) {
247 using ::android::base::SetProperty;
248
Steven Morelandcdd252f2019-07-15 15:18:07 -0700249 // The "happy path" here is starting up a service that is configured as a
250 // lazy HAL, but we aren't sure that is the case. If the service doesn't
251 // have an 'interface' entry in its .rc file OR if the service is already
252 // running, then this will be a no-op. So, for instance, if a service is
253 // deadlocked during startup, you will see this message repeatedly.
254 LOG(INFO) << "Since " << fqName << "/" << name
255 << " is not registered, trying to start it as a lazy HAL.";
256
Steven Moreland58cef2c2018-01-24 16:41:38 -0800257 std::thread([=] {
Steven Moreland52fde212019-08-27 14:52:24 -0700258 (void)SetProperty("ctl.interface_start", fqName + "/" + name);
Steven Moreland58cef2c2018-01-24 16:41:38 -0800259 }).detach();
Steven Moreland5a317452017-10-05 18:49:48 -0700260}
261
Steven Morelandd83d1102016-10-25 15:01:47 -0700262// Methods from ::android::hidl::manager::V1_0::IServiceManager follow.
Steven Moreland5a317452017-10-05 18:49:48 -0700263Return<sp<IBase>> ServiceManager::get(const hidl_string& hidlFqName,
264 const hidl_string& hidlName) {
265 const std::string fqName = hidlFqName;
266 const std::string name = hidlName;
267
Steven Moreland2aefd642019-01-03 17:51:17 -0800268 if (!mAcl.canGet(fqName, getBinderCallingContext())) {
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700269 return nullptr;
270 }
271
Steven Morelanddbaab552019-01-24 19:00:04 -0800272 HidlService* hidlService = lookup(fqName, name);
Steven Morelandd544cf62017-01-04 15:24:32 -0800273 if (hidlService == nullptr) {
Steven Morelanddbaab552019-01-24 19:00:04 -0800274 tryStartService(fqName, name);
Martijn Coenen7b02bf92017-01-02 15:17:58 +0100275 return nullptr;
Steven Morelandd83d1102016-10-25 15:01:47 -0700276 }
Steven Morelandd544cf62017-01-04 15:24:32 -0800277
Steven Moreland5a317452017-10-05 18:49:48 -0700278 sp<IBase> service = hidlService->getService();
279 if (service == nullptr) {
Steven Morelanddbaab552019-01-24 19:00:04 -0800280 tryStartService(fqName, name);
Steven Moreland5a317452017-10-05 18:49:48 -0700281 return nullptr;
282 }
283
Steven Moreland98db8292018-12-07 13:08:25 -0800284 // Let HidlService know that we handed out a client. If the client drops the service before the
285 // next time handleClientCallbacks is called, it will still know that the service had been handed out.
286 hidlService->guaranteeClient();
Peter Kalauskas85c2f4e2020-06-17 10:51:14 -0700287 forEachExistingService([&] (HidlService *otherService) {
288 if (otherService != hidlService && interfacesEqual(service, otherService->getService())) {
289 otherService->guaranteeClient();
290 }
291 return true;
292 });
Steven Moreland98db8292018-12-07 13:08:25 -0800293
Steven Morelandc06af8d2018-10-22 16:35:07 -0700294 // This is executed immediately after the binder driver confirms the transaction. The driver
295 // will update the appropriate data structures to reflect the fact that the client now has the
296 // service this function is returning. Nothing else can update the HidlService at the same
297 // time. This will run before anything else can modify the HidlService which is owned by this
298 // object, so it will be in the same state that it was when this function returns.
299 hardware::addPostCommandTask([hidlService] {
Steven Moreland105c58b2020-04-06 16:18:50 -0700300 hidlService->handleClientCallbacks(false /* isCalledOnInterval */, 1 /*knownClientCount*/);
Steven Morelandc06af8d2018-10-22 16:35:07 -0700301 });
302
Steven Moreland5a317452017-10-05 18:49:48 -0700303 return service;
Steven Morelandd83d1102016-10-25 15:01:47 -0700304}
305
Martijn Coenen1a5da1c2017-03-06 13:05:39 +0100306Return<bool> ServiceManager::add(const hidl_string& name, const sp<IBase>& service) {
Steven Moreland707f22c2018-10-11 12:09:34 -0700307 bool addSuccess = false;
Steven Morelandd83d1102016-10-25 15:01:47 -0700308
Martijn Coenen1a5da1c2017-03-06 13:05:39 +0100309 if (service == nullptr) {
Steven Moreland5fb3d652016-11-03 13:45:18 -0700310 return false;
Steven Morelandd83d1102016-10-25 15:01:47 -0700311 }
Steven Moreland5fb3d652016-11-03 13:45:18 -0700312
Xin Libf44d5a2019-03-11 17:50:47 -0700313 auto pidcon = getBinderCallingContext();
Steven Morelandcdf94722017-03-21 12:16:31 -0700314
Steven Morelandc86f1172019-05-14 13:19:21 -0700315 if (!mAcl.canAdd(IBase::descriptor, pidcon)) {
316 LOG(ERROR) << "Missing permissions to add IBase";
317 return false;
318 }
319
Martijn Coenen1a5da1c2017-03-06 13:05:39 +0100320 auto ret = service->interfaceChain([&](const auto &interfaceChain) {
Xin Libf44d5a2019-03-11 17:50:47 -0700321 addSuccess = addImpl(name, service, interfaceChain, pidcon);
Martijn Coenen1a5da1c2017-03-06 13:05:39 +0100322 });
323
324 if (!ret.isOk()) {
Steven Moreland707f22c2018-10-11 12:09:34 -0700325 LOG(ERROR) << "Failed to retrieve interface chain: " << ret.description();
Martijn Coenen1a5da1c2017-03-06 13:05:39 +0100326 return false;
Steven Morelandd83d1102016-10-25 15:01:47 -0700327 }
Steven Morelandd544cf62017-01-04 15:24:32 -0800328
Steven Moreland707f22c2018-10-11 12:09:34 -0700329 return addSuccess;
330}
331
Steven Morelandd90d9f22019-03-20 13:47:30 -0700332bool ServiceManager::addImpl(const std::string& name,
Steven Moreland707f22c2018-10-11 12:09:34 -0700333 const sp<IBase>& service,
334 const hidl_vec<hidl_string>& interfaceChain,
Xin Libf44d5a2019-03-11 17:50:47 -0700335 const AccessControl::CallingContext& callingContext) {
Steven Moreland707f22c2018-10-11 12:09:34 -0700336 if (interfaceChain.size() == 0) {
337 LOG(WARNING) << "Empty interface chain for " << name;
338 return false;
339 }
340
341 // First, verify you're allowed to add() the whole interface hierarchy
342 for(size_t i = 0; i < interfaceChain.size(); i++) {
343 const std::string fqName = interfaceChain[i];
344
Xin Libf44d5a2019-03-11 17:50:47 -0700345 if (!mAcl.canAdd(fqName, callingContext)) {
Steven Moreland707f22c2018-10-11 12:09:34 -0700346 return false;
347 }
348 }
349
Steven Morelandd90d9f22019-03-20 13:47:30 -0700350 // Detect duplicate registration
351 if (interfaceChain.size() > 1) {
352 // second to last entry should be the highest base class other than IBase.
353 const std::string baseFqName = interfaceChain[interfaceChain.size() - 2];
354 const HidlService *hidlService = lookup(baseFqName, name);
355 if (hidlService != nullptr && hidlService->getService() != nullptr) {
356 // This shouldn't occur during normal operation. Here are some cases where
357 // it might get hit:
358 // - bad configuration (service installed on device multiple times)
359 // - race between death notification and a new service being registered
360 // (previous logs should indicate a separate problem)
361 const std::string childFqName = interfaceChain[0];
362 pid_t newServicePid = IPCThreadState::self()->getCallingPid();
363 pid_t oldServicePid = hidlService->getDebugPid();
364 LOG(WARNING) << "Detected instance of " << childFqName << " (pid: " << newServicePid
365 << ") registering over instance of or with base of " << baseFqName << " (pid: "
366 << oldServicePid << ").";
367 }
368 }
369
370 // Unregister superclass if subclass is registered over it
Steven Moreland707f22c2018-10-11 12:09:34 -0700371 {
372 // For IBar extends IFoo if IFoo/default is being registered, remove
373 // IBar/default. This makes sure the following two things are equivalent
374 // 1). IBar::castFrom(IFoo::getService(X))
375 // 2). IBar::getService(X)
376 // assuming that IBar is declared in the device manifest and there
Steven Morelandd90d9f22019-03-20 13:47:30 -0700377 // is also not an IBaz extends IFoo and there is no race.
Steven Moreland707f22c2018-10-11 12:09:34 -0700378 const std::string childFqName = interfaceChain[0];
Steven Morelandd90d9f22019-03-20 13:47:30 -0700379 const HidlService *hidlService = lookup(childFqName, name);
Steven Moreland707f22c2018-10-11 12:09:34 -0700380 if (hidlService != nullptr) {
381 const sp<IBase> remove = hidlService->getService();
382
383 if (remove != nullptr) {
384 const std::string instanceName = name;
385 removeService(remove, &instanceName /* restrictToInstanceName */);
386 }
387 }
388 }
389
390 for(size_t i = 0; i < interfaceChain.size(); i++) {
391 const std::string fqName = interfaceChain[i];
392
393 PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
394 HidlService *hidlService = ifaceMap.lookup(name);
395
396 if (hidlService == nullptr) {
397 ifaceMap.insertService(
Xin Libf44d5a2019-03-11 17:50:47 -0700398 std::make_unique<HidlService>(fqName, name, service, callingContext.pid));
Steven Moreland707f22c2018-10-11 12:09:34 -0700399 } else {
Xin Libf44d5a2019-03-11 17:50:47 -0700400 hidlService->setService(service, callingContext.pid);
Steven Moreland707f22c2018-10-11 12:09:34 -0700401 }
402
403 ifaceMap.sendPackageRegistrationNotification(fqName, name);
404 }
405
406 bool linkRet = service->linkToDeath(this, kServiceDiedCookie).withDefault(false);
407 if (!linkRet) {
408 LOG(ERROR) << "Could not link to death for " << interfaceChain[0] << "/" << name;
409 }
410
411 return true;
Steven Morelandd83d1102016-10-25 15:01:47 -0700412}
413
Steven Moreland37aed802017-04-06 09:16:42 -0700414Return<ServiceManager::Transport> ServiceManager::getTransport(const hidl_string& fqName,
415 const hidl_string& name) {
416 using ::android::hardware::getTransport;
417
Steven Moreland2aefd642019-01-03 17:51:17 -0800418 if (!mAcl.canGet(fqName, getBinderCallingContext())) {
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700419 return Transport::EMPTY;
420 }
421
Steven Moreland37aed802017-04-06 09:16:42 -0700422 switch (getTransport(fqName, name)) {
423 case vintf::Transport::HWBINDER:
424 return Transport::HWBINDER;
425 case vintf::Transport::PASSTHROUGH:
426 return Transport::PASSTHROUGH;
427 case vintf::Transport::EMPTY:
428 default:
429 return Transport::EMPTY;
430 }
431}
432
Steven Moreland76237812016-11-08 15:59:04 -0800433Return<void> ServiceManager::list(list_cb _hidl_cb) {
Steven Moreland2aefd642019-01-03 17:51:17 -0800434 if (!mAcl.canList(getBinderCallingContext())) {
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700435 _hidl_cb({});
436 return Void();
437 }
Steven Moreland76237812016-11-08 15:59:04 -0800438
439 hidl_vec<hidl_string> list;
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700440
Yifan Hong83c49f62017-01-25 14:16:34 -0800441 list.resize(countExistingService());
Steven Moreland76237812016-11-08 15:59:04 -0800442
443 size_t idx = 0;
Yifan Hong83c49f62017-01-25 14:16:34 -0800444 forEachExistingService([&] (const HidlService *service) {
445 list[idx++] = service->string();
Steven Morelandd8536202018-09-26 10:56:19 -0700446 return true; // continue
Yifan Hong83c49f62017-01-25 14:16:34 -0800447 });
Steven Moreland76237812016-11-08 15:59:04 -0800448
449 _hidl_cb(list);
450 return Void();
451}
452
Steven Moreland2173d3c2016-11-09 15:00:58 -0800453Return<void> ServiceManager::listByInterface(const hidl_string& fqName,
454 listByInterface_cb _hidl_cb) {
Steven Moreland2aefd642019-01-03 17:51:17 -0800455 if (!mAcl.canGet(fqName, getBinderCallingContext())) {
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700456 _hidl_cb({});
457 return Void();
458 }
459
Steven Morelandd544cf62017-01-04 15:24:32 -0800460 auto ifaceIt = mServiceMap.find(fqName);
Steven Moreland76237812016-11-08 15:59:04 -0800461 if (ifaceIt == mServiceMap.end()) {
462 _hidl_cb(hidl_vec<hidl_string>());
463 return Void();
464 }
465
Steven Moreland2173d3c2016-11-09 15:00:58 -0800466 const auto &instanceMap = ifaceIt->second.getInstanceMap();
Steven Moreland76237812016-11-08 15:59:04 -0800467
468 hidl_vec<hidl_string> list;
Steven Morelandfc56b612017-01-23 20:10:45 -0800469
470 size_t total = 0;
471 for (const auto &serviceMapping : instanceMap) {
472 const std::unique_ptr<HidlService> &service = serviceMapping.second;
473 if (service->getService() == nullptr) continue;
474
475 ++total;
476 }
477 list.resize(total);
Steven Moreland76237812016-11-08 15:59:04 -0800478
479 size_t idx = 0;
Steven Moreland2173d3c2016-11-09 15:00:58 -0800480 for (const auto &serviceMapping : instanceMap) {
Steven Moreland76237812016-11-08 15:59:04 -0800481 const std::unique_ptr<HidlService> &service = serviceMapping.second;
Steven Morelandfc56b612017-01-23 20:10:45 -0800482 if (service->getService() == nullptr) continue;
Steven Moreland76237812016-11-08 15:59:04 -0800483
Steven Morelandd544cf62017-01-04 15:24:32 -0800484 list[idx++] = service->getInstanceName();
Steven Moreland76237812016-11-08 15:59:04 -0800485 }
486
487 _hidl_cb(list);
488 return Void();
489}
490
Steven Moreland2173d3c2016-11-09 15:00:58 -0800491Return<bool> ServiceManager::registerForNotifications(const hidl_string& fqName,
492 const hidl_string& name,
493 const sp<IServiceNotification>& callback) {
494 if (callback == nullptr) {
495 return false;
496 }
497
Steven Moreland2aefd642019-01-03 17:51:17 -0800498 if (!mAcl.canGet(fqName, getBinderCallingContext())) {
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700499 return false;
500 }
501
Steven Morelandd544cf62017-01-04 15:24:32 -0800502 PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
Steven Moreland2173d3c2016-11-09 15:00:58 -0800503
504 if (name.empty()) {
Steven Moreland78c899e2018-09-27 16:45:18 -0700505 bool ret = callback->linkToDeath(this, kPackageListenerDiedCookie).withDefault(false);
506 if (!ret) {
Martijn Coenen7fafc142017-03-06 16:17:51 +0100507 LOG(ERROR) << "Failed to register death recipient for " << fqName << "/" << name;
508 return false;
509 }
Steven Moreland2173d3c2016-11-09 15:00:58 -0800510 ifaceMap.addPackageListener(callback);
511 return true;
512 }
513
Steven Morelandd544cf62017-01-04 15:24:32 -0800514 HidlService *service = ifaceMap.lookup(name);
Steven Moreland2173d3c2016-11-09 15:00:58 -0800515
Steven Moreland78c899e2018-09-27 16:45:18 -0700516 bool ret = callback->linkToDeath(this, kServiceListenerDiedCookie).withDefault(false);
517 if (!ret) {
Martijn Coenen7fafc142017-03-06 16:17:51 +0100518 LOG(ERROR) << "Failed to register death recipient for " << fqName << "/" << name;
519 return false;
520 }
521
Steven Moreland2173d3c2016-11-09 15:00:58 -0800522 if (service == nullptr) {
Steven Morelandcdf94722017-03-21 12:16:31 -0700523 auto adding = std::make_unique<HidlService>(fqName, name);
Steven Morelandd544cf62017-01-04 15:24:32 -0800524 adding->addListener(callback);
525 ifaceMap.insertService(std::move(adding));
Steven Moreland2173d3c2016-11-09 15:00:58 -0800526 } else {
527 service->addListener(callback);
528 }
529
530 return true;
531}
532
Steven Moreland6f4fbe12017-07-21 18:07:42 -0700533Return<bool> ServiceManager::unregisterForNotifications(const hidl_string& fqName,
534 const hidl_string& name,
535 const sp<IServiceNotification>& callback) {
536 if (callback == nullptr) {
537 LOG(ERROR) << "Cannot unregister null callback for " << fqName << "/" << name;
538 return false;
539 }
540
541 // NOTE: don't need ACL since callback is binder token, and if someone has gotten it,
542 // then they already have access to it.
543
544 if (fqName.empty()) {
545 bool success = false;
546 success |= removePackageListener(callback);
547 success |= removeServiceListener(callback);
548 return success;
549 }
550
551 PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
552
553 if (name.empty()) {
554 bool success = false;
555 success |= ifaceMap.removePackageListener(callback);
556 success |= ifaceMap.removeServiceListener(callback);
557 return success;
558 }
559
560 HidlService *service = ifaceMap.lookup(name);
561
562 if (service == nullptr) {
563 return false;
564 }
565
566 return service->removeListener(callback);
567}
568
Steven Morelanddbaab552019-01-24 19:00:04 -0800569Return<bool> ServiceManager::registerClientCallback(const hidl_string& hidlFqName,
570 const hidl_string& hidlName,
571 const sp<IBase>& server,
Steven Morelandd8536202018-09-26 10:56:19 -0700572 const sp<IClientCallback>& cb) {
573 if (server == nullptr || cb == nullptr) return false;
574
Steven Morelanddbaab552019-01-24 19:00:04 -0800575 const std::string fqName = hidlFqName;
576 const std::string name = hidlName;
577
Steven Morelandd8536202018-09-26 10:56:19 -0700578 // only the server of the interface can register a client callback
579 pid_t pid = IPCThreadState::self()->getCallingPid();
Xin Libf44d5a2019-03-11 17:50:47 -0700580 if (!mAcl.canAdd(fqName, getBinderCallingContext())) {
Steven Morelanddbaab552019-01-24 19:00:04 -0800581 return false;
Steven Morelandd8536202018-09-26 10:56:19 -0700582 }
583
Steven Morelanddbaab552019-01-24 19:00:04 -0800584 HidlService* registered = lookup(fqName, name);
585
586 if (registered == nullptr) {
587 return false;
Steven Morelandd8536202018-09-26 10:56:19 -0700588 }
589
Steven Morelanddbaab552019-01-24 19:00:04 -0800590 // sanity
Xin Libf44d5a2019-03-11 17:50:47 -0700591 if (registered->getDebugPid() != pid) {
Steven Morelanddbaab552019-01-24 19:00:04 -0800592 LOG(WARNING) << "Only a server can register for client callbacks (for " << fqName
593 << "/" << name << ")";
594 return false;
595 }
596
597 sp<IBase> service = registered->getService();
598
599 if (!interfacesEqual(service, server)) {
600 LOG(WARNING) << "Tried to register client callback for " << fqName << "/" << name
601 << " but a different service is registered under this name.";
602 return false;
603 }
604
605 bool linkRet = cb->linkToDeath(this, kClientCallbackDiedCookie).withDefault(false);
606 if (!linkRet) {
607 LOG(ERROR) << "Could not link to death for registerClientCallback";
608 return false;
609 }
610
Steven Moreland105c58b2020-04-06 16:18:50 -0700611 // knownClientCount
612 // - one from binder transaction (base here)
613 // - one from hwservicemanager
614 registered->addClientCallback(cb, 2 /*knownClientCount*/);
Steven Morelanddbaab552019-01-24 19:00:04 -0800615
616 return true;
Steven Morelandd8536202018-09-26 10:56:19 -0700617}
618
619Return<bool> ServiceManager::unregisterClientCallback(const sp<IBase>& server,
620 const sp<IClientCallback>& cb) {
621 if (cb == nullptr) return false;
622
623 bool removed = false;
624
625 forEachExistingService([&] (HidlService *service) {
626 if (server == nullptr || interfacesEqual(service->getService(), server)) {
627 removed |= service->removeClientCallback(cb);
628 }
629 return true; // continue
630 });
631
632 return removed;
633}
634
635void ServiceManager::handleClientCallbacks() {
636 forEachServiceEntry([&] (HidlService *service) {
Steven Moreland105c58b2020-04-06 16:18:50 -0700637 // hwservicemanager will hold one reference, so knownClientCount is 1.
638 service->handleClientCallbacks(true /* isCalledOnInterval */, 1 /*knownClientCount*/);
Steven Morelandd8536202018-09-26 10:56:19 -0700639 return true; // continue
640 });
641}
642
Steven Moreland707f22c2018-10-11 12:09:34 -0700643Return<bool> ServiceManager::addWithChain(const hidl_string& name,
644 const sp<IBase>& service,
645 const hidl_vec<hidl_string>& chain) {
646 if (service == nullptr) {
647 return false;
648 }
649
Xin Libf44d5a2019-03-11 17:50:47 -0700650 auto callingContext = getBinderCallingContext();
Steven Moreland707f22c2018-10-11 12:09:34 -0700651
Xin Libf44d5a2019-03-11 17:50:47 -0700652 return addImpl(name, service, chain, callingContext);
Steven Moreland707f22c2018-10-11 12:09:34 -0700653}
654
Steven Morelandaae4eab2018-10-29 13:00:31 -0700655Return<void> ServiceManager::listManifestByInterface(const hidl_string& fqName,
656 listManifestByInterface_cb _hidl_cb) {
Xin Libf44d5a2019-03-11 17:50:47 -0700657 if (!mAcl.canGet(fqName, getBinderCallingContext())) {
Steven Morelandaae4eab2018-10-29 13:00:31 -0700658 _hidl_cb({});
659 return Void();
660 }
661
662 std::set<std::string> instances = getInstances(fqName);
663 hidl_vec<hidl_string> ret(instances.begin(), instances.end());
664
665 _hidl_cb(ret);
666 return Void();
667}
668
Steven Morelanddbaab552019-01-24 19:00:04 -0800669Return<bool> ServiceManager::tryUnregister(const hidl_string& hidlFqName,
670 const hidl_string& hidlName,
671 const sp<IBase>& service) {
672 const std::string fqName = hidlFqName;
673 const std::string name = hidlName;
674
675 if (service == nullptr) {
676 return false;
677 }
678
Xin Libf44d5a2019-03-11 17:50:47 -0700679 if (!mAcl.canAdd(fqName, getBinderCallingContext())) {
Steven Morelanddbaab552019-01-24 19:00:04 -0800680 return false;
681 }
682
683 HidlService* registered = lookup(fqName, name);
684
685 // sanity
Xin Libf44d5a2019-03-11 17:50:47 -0700686 pid_t pid = IPCThreadState::self()->getCallingPid();
687 if (registered->getDebugPid() != pid) {
Steven Morelanddbaab552019-01-24 19:00:04 -0800688 LOG(WARNING) << "Only a server can unregister itself (for " << fqName
689 << "/" << name << ")";
690 return false;
691 }
692
693 sp<IBase> server = registered->getService();
694
695 if (!interfacesEqual(service, server)) {
696 LOG(WARNING) << "Tried to unregister for " << fqName << "/" << name
697 << " but a different service is registered under this name.";
698 return false;
699 }
700
Steven Moreland105c58b2020-04-06 16:18:50 -0700701 // knownClientCount
702 // - one from binder transaction (base here)
703 // - one from hwservicemanager
704 bool clients = registered->forceHandleClientCallbacks(false /*isCalledOnInterval*/, 2 /*knownClientCount*/);
Steven Morelanddbaab552019-01-24 19:00:04 -0800705
Steven Moreland105c58b2020-04-06 16:18:50 -0700706 if (clients) {
Steven Morelanddbaab552019-01-24 19:00:04 -0800707 // client callbacks are either disabled or there are other clients
708 LOG(INFO) << "Tried to unregister for " << fqName << "/" << name
709 << " but there are clients: " << clients;
710 return false;
711 }
712
713 // will remove entire parent hierarchy
714 bool success = removeService(service, &name /*restrictToInstanceName*/);
715
716 if (registered->getService() != nullptr) {
717 LOG(ERROR) << "Bad state. Unregistration failed for " << fqName << "/" << name << ".";
718 return false;
719 }
720
721 return success;
722}
723
Yifan Hong83c49f62017-01-25 14:16:34 -0800724Return<void> ServiceManager::debugDump(debugDump_cb _cb) {
Steven Moreland2aefd642019-01-03 17:51:17 -0800725 if (!mAcl.canList(getBinderCallingContext())) {
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700726 _cb({});
727 return Void();
728 }
729
Yifan Hongee531a82017-02-03 15:10:18 -0800730 std::vector<IServiceManager::InstanceDebugInfo> list;
731 forEachServiceEntry([&] (const HidlService *service) {
Yifan Hongee531a82017-02-03 15:10:18 -0800732 hidl_vec<int32_t> clientPids;
733 clientPids.resize(service->getPassthroughClients().size());
734
735 size_t i = 0;
736 for (pid_t p : service->getPassthroughClients()) {
737 clientPids[i++] = p;
738 }
739
740 list.push_back({
Yifan Hong83c49f62017-01-25 14:16:34 -0800741 .interfaceName = service->getInterfaceName(),
742 .instanceName = service->getInstanceName(),
Nick Desaulniers1c48f2f2019-10-15 19:20:40 -0700743 .pid = service->getDebugPid(),
Yifan Hong1d2deb12017-03-02 16:58:22 -0800744 .clientPids = clientPids,
745 .arch = ::android::hidl::base::V1_0::DebugInfo::Architecture::UNKNOWN
Yifan Hongee531a82017-02-03 15:10:18 -0800746 });
Steven Morelandd8536202018-09-26 10:56:19 -0700747
748 return true; // continue
Yifan Hong83c49f62017-01-25 14:16:34 -0800749 });
750
751 _cb(list);
752 return Void();
753}
754
Yifan Hongee531a82017-02-03 15:10:18 -0800755
756Return<void> ServiceManager::registerPassthroughClient(const hidl_string &fqName,
Martijn Coenen737de1b2017-04-27 09:29:43 -0700757 const hidl_string &name) {
Steven Moreland2aefd642019-01-03 17:51:17 -0800758 auto callingContext = getBinderCallingContext();
759
760 if (!mAcl.canGet(fqName, callingContext)) {
Martijn Coenen7ce83be2017-04-07 16:19:32 -0700761 /* We guard this function with "get", because it's typically used in
762 * the getService() path, albeit for a passthrough service in this
763 * case
764 */
765 return Void();
766 }
Yifan Hongee531a82017-02-03 15:10:18 -0800767
768 PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
769
770 if (name.empty()) {
771 LOG(WARNING) << "registerPassthroughClient encounters empty instance name for "
772 << fqName.c_str();
773 return Void();
774 }
775
776 HidlService *service = ifaceMap.lookup(name);
777
778 if (service == nullptr) {
Steven Morelandcdf94722017-03-21 12:16:31 -0700779 auto adding = std::make_unique<HidlService>(fqName, name);
Steven Moreland2aefd642019-01-03 17:51:17 -0800780 adding->registerPassthroughClient(callingContext.pid);
Yifan Hongee531a82017-02-03 15:10:18 -0800781 ifaceMap.insertService(std::move(adding));
782 } else {
Steven Moreland2aefd642019-01-03 17:51:17 -0800783 service->registerPassthroughClient(callingContext.pid);
Yifan Hongee531a82017-02-03 15:10:18 -0800784 }
785 return Void();
786}
787
Steven Moreland76936fe2017-09-19 12:18:30 -0700788bool ServiceManager::removeService(const wp<IBase>& who, const std::string* restrictToInstanceName) {
Steven Moreland76936fe2017-09-19 12:18:30 -0700789 bool keepInstance = false;
790 bool removed = false;
Martijn Coenen46847a62016-12-19 05:36:12 +0100791 for (auto &interfaceMapping : mServiceMap) {
792 auto &instanceMap = interfaceMapping.second.getInstanceMap();
793
Steven Morelandd544cf62017-01-04 15:24:32 -0800794 for (auto &servicePair : instanceMap) {
Steven Moreland76936fe2017-09-19 12:18:30 -0700795 const std::string &instanceName = servicePair.first;
Steven Morelandd544cf62017-01-04 15:24:32 -0800796 const std::unique_ptr<HidlService> &service = servicePair.second;
Steven Moreland76936fe2017-09-19 12:18:30 -0700797
Steven Moreland6f4fbe12017-07-21 18:07:42 -0700798 if (interfacesEqual(service->getService(), who.promote())) {
Steven Moreland76936fe2017-09-19 12:18:30 -0700799 if (restrictToInstanceName != nullptr && *restrictToInstanceName != instanceName) {
800 // We cannot remove all instances of this service, so we don't return that it
801 // has been entirely removed.
802 keepInstance = true;
803 continue;
804 }
805
Steven Morelandcdf94722017-03-21 12:16:31 -0700806 service->setService(nullptr, static_cast<pid_t>(IServiceManager::PidConstant::NO_PID));
Steven Moreland76936fe2017-09-19 12:18:30 -0700807 removed = true;
Martijn Coenen46847a62016-12-19 05:36:12 +0100808 }
809 }
810 }
Steven Moreland76936fe2017-09-19 12:18:30 -0700811
812 return !keepInstance && removed;
Martijn Coenen46847a62016-12-19 05:36:12 +0100813}
Yifan Hong83c49f62017-01-25 14:16:34 -0800814
Martijn Coenen7fafc142017-03-06 16:17:51 +0100815bool ServiceManager::removePackageListener(const wp<IBase>& who) {
816 bool found = false;
817
818 for (auto &interfaceMapping : mServiceMap) {
819 found |= interfaceMapping.second.removePackageListener(who);
820 }
821
822 return found;
823}
824
825bool ServiceManager::removeServiceListener(const wp<IBase>& who) {
826 bool found = false;
827 for (auto &interfaceMapping : mServiceMap) {
Steven Moreland6f4fbe12017-07-21 18:07:42 -0700828 auto &packageInterfaceMap = interfaceMapping.second;
Martijn Coenen7fafc142017-03-06 16:17:51 +0100829
Steven Moreland6f4fbe12017-07-21 18:07:42 -0700830 found |= packageInterfaceMap.removeServiceListener(who);
Martijn Coenen7fafc142017-03-06 16:17:51 +0100831 }
832 return found;
833}
Steven Moreland6f4fbe12017-07-21 18:07:42 -0700834} // namespace implementation
Steven Morelandd83d1102016-10-25 15:01:47 -0700835} // namespace manager
836} // namespace hidl
837} // namespace android