1 /*
2 * Copyright (c) 2023-2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "etx_device_mgr.h"
17 #include "cinttypes"
18 #include "common_timer_errors.h"
19 #include "driver_extension_controller.h"
20 #include "driver_pkg_manager.h"
21 #include "edm_errors.h"
22 #include "hilog_wrapper.h"
23 #include "iservice_registry.h"
24 #include "system_ability_definition.h"
25 #include "bundle_update_callback.h"
26
27 namespace OHOS {
28 namespace ExternalDeviceManager {
29 constexpr uint32_t UNLOAD_SA_TIMER_INTERVAL = 30 * 1000;
30 std::string Device::stiching_ = "-";
31 IMPLEMENT_SINGLE_INSTANCE(ExtDeviceManager);
32
~ExtDeviceManager()33 ExtDeviceManager::~ExtDeviceManager()
34 {
35 unloadSelftimer_.Unregister(unloadSelftimerId_);
36 unloadSelftimer_.Shutdown();
37 }
38
PrintMatchDriverMap()39 void ExtDeviceManager::PrintMatchDriverMap()
40 {
41 if (!bundleMatchMap_.empty()) {
42 EDM_LOGD(MODULE_DEV_MGR, " bundleInfo map size[%{public}zu]", bundleMatchMap_.size());
43 for (auto iter : bundleMatchMap_) {
44 for (auto iterId = iter.second.begin(); iterId != iter.second.end(); ++iterId) {
45 uint64_t deviceId = *iterId;
46 EDM_LOGD(MODULE_DEV_MGR, "print match map info[%{public}s], deviceId %{public}016" PRIX64 "",
47 iter.first.c_str(), deviceId);
48 }
49 }
50 EDM_LOGD(MODULE_DEV_MGR, "ExtDeviceManager print driver match map success");
51 }
52 }
53
Init()54 int32_t ExtDeviceManager::Init()
55 {
56 EDM_LOGD(MODULE_DEV_MGR, "ExtDeviceManager Init success");
57 auto callback = make_shared<BundleUpdateCallback>();
58 int32_t ret = DriverPkgManager::GetInstance().RegisterBundleCallback(callback);
59 if (ret != EDM_OK) {
60 EDM_LOGE(MODULE_DEV_MGR, "Register bundle update callback fail");
61 return EDM_NOK;
62 }
63 return EDM_OK;
64 }
65
AddDevIdOfBundleInfoMap(shared_ptr<Device> device,string & bundleInfo)66 int32_t ExtDeviceManager::AddDevIdOfBundleInfoMap(shared_ptr<Device> device, string &bundleInfo)
67 {
68 if (bundleInfo.empty() || device == nullptr) {
69 EDM_LOGE(MODULE_DEV_MGR, "bundleInfo or device is null");
70 return EDM_ERR_INVALID_PARAM;
71 }
72
73 // update bundle info
74 lock_guard<mutex> lock(bundleMatchMapMutex_);
75 auto pos = bundleMatchMap_.find(bundleInfo);
76 uint64_t deviceId = device->GetDeviceInfo()->GetDeviceId();
77 if (pos == bundleMatchMap_.end()) {
78 unordered_set<uint64_t> tmpSet;
79 tmpSet.emplace(deviceId);
80 bundleMatchMap_.emplace(bundleInfo, tmpSet);
81 EDM_LOGI(MODULE_DEV_MGR, "bundleMap emplace New driver, add deviceId %{public}016" PRIX64 "", deviceId);
82 } else {
83 auto pairRet = pos->second.emplace(deviceId);
84 // Check whether the deviceId matches the driver
85 if (!pairRet.second || pos->second.size() > 1) {
86 EDM_LOGI(MODULE_DEV_MGR, "bundleMap had existed driver, add deviceId %{public}016" PRIX64 "", deviceId);
87 PrintMatchDriverMap();
88 }
89 }
90
91 auto driverInfo = device->GetDriverInfo();
92 if (driverInfo == nullptr) {
93 EDM_LOGE(MODULE_DEV_MGR, "driverInfo is nullptr");
94 return EDM_NOK;
95 }
96
97 UpdateDriverInfo(device);
98
99 if (driverInfo->GetLaunchOnBind()) {
100 EDM_LOGI(MODULE_DEV_MGR, "driver is set to launch on client bind");
101 return EDM_OK;
102 }
103 // start ability
104 int32_t ret = device->Connect();
105 if (ret != EDM_OK) {
106 EDM_LOGE(MODULE_DEV_MGR,
107 "deviceId[%{public}016" PRIX64 "] connect driver extension ability[%{public}s] failed[%{public}d]",
108 deviceId, Device::GetAbilityName(bundleInfo).c_str(), ret);
109 return EDM_NOK;
110 }
111 PrintMatchDriverMap();
112 return EDM_OK;
113 }
114
RemoveDevIdOfBundleInfoMap(shared_ptr<Device> device,string & bundleInfo)115 int32_t ExtDeviceManager::RemoveDevIdOfBundleInfoMap(shared_ptr<Device> device, string &bundleInfo)
116 {
117 if (bundleInfo.empty() || device == nullptr) {
118 EDM_LOGE(MODULE_DEV_MGR, "bundleInfo or device is null");
119 return EDM_ERR_INVALID_PARAM;
120 }
121
122 // update bundle info
123 lock_guard<mutex> lock(bundleMatchMapMutex_);
124 auto pos = bundleMatchMap_.find(bundleInfo);
125 if (pos == bundleMatchMap_.end()) {
126 EDM_LOGI(MODULE_DEV_MGR, "not find bundleInfo from map");
127 return EDM_OK;
128 }
129
130 // If the number of devices is greater than one, only the device erase
131 uint64_t deviceId = device->GetDeviceInfo()->GetDeviceId();
132 if (pos->second.size() > 1) {
133 pos->second.erase(deviceId);
134 EDM_LOGD(MODULE_DEV_MGR, "bundleMap existed driver, remove deviceId %{public}016" PRIX64 "", deviceId);
135 PrintMatchDriverMap();
136 return EDM_OK;
137 }
138
139 EDM_LOGD(MODULE_DEV_MGR, "bundleMap remove bundleInfo[%{public}s]", bundleInfo.c_str());
140 bundleMatchMap_.erase(pos);
141
142 // stop ability and destory sa
143 int32_t ret = device->Disconnect();
144 if (ret != EDM_OK) {
145 EDM_LOGE(MODULE_DEV_MGR,
146 "deviceId[%{public}016" PRIX64 "] disconnect driver extension ability[%{public}s] failed[%{public}d]",
147 deviceId, Device::GetAbilityName(bundleInfo).c_str(), ret);
148 return ret;
149 }
150
151 RemoveDriverInfo(device);
152 PrintMatchDriverMap();
153 return EDM_OK;
154 }
155
UpdateDriverInfo(const shared_ptr<Device> & device)156 void ExtDeviceManager::UpdateDriverInfo(const shared_ptr<Device> &device)
157 {
158 if (device == nullptr) {
159 EDM_LOGE(MODULE_DEV_MGR, "device is null");
160 return;
161 }
162
163 auto driverInfo = device->GetDriverInfo();
164 if (driverInfo == nullptr) {
165 EDM_LOGE(MODULE_DEV_MGR, "update driver info with null");
166 return;
167 }
168
169 if (driverChangeCallback_ == nullptr) {
170 EDM_LOGE(MODULE_DEV_MGR, "updated driverChangeCallback is null");
171 return;
172 }
173
174 driverChangeCallback_->OnDriverMatched(driverInfo);
175 }
176
RemoveDriverInfo(const shared_ptr<Device> & device)177 void ExtDeviceManager::RemoveDriverInfo(const shared_ptr<Device> &device)
178 {
179 if (device == nullptr) {
180 EDM_LOGE(MODULE_DEV_MGR, "device is null");
181 return;
182 }
183
184 auto driverInfo = device->GetDriverInfo();
185 if (driverInfo == nullptr) {
186 EDM_LOGE(MODULE_DEV_MGR, "remove driver info with null");
187 return;
188 }
189
190 if (driverChangeCallback_ == nullptr) {
191 EDM_LOGE(MODULE_DEV_MGR, "removed driverChangeCallback is null");
192 return;
193 }
194
195 driverChangeCallback_->OnDriverRemoved(driverInfo);
196 device->RemoveDriverInfo();
197 }
198
RemoveDeviceOfDeviceMap(shared_ptr<Device> device)199 void ExtDeviceManager::RemoveDeviceOfDeviceMap(shared_ptr<Device> device)
200 {
201 EDM_LOGI(MODULE_DEV_MGR, "RemoveDeviceOfDeviceMap enter");
202 shared_ptr<DeviceInfo> deviceInfo = device->GetDeviceInfo();
203 if (deviceInfo == nullptr) {
204 EDM_LOGE(MODULE_DEV_MGR, "device info is null");
205 return;
206 }
207 BusType type = deviceInfo->GetBusType();
208 uint64_t deviceId = deviceInfo->GetDeviceId();
209
210 lock_guard<mutex> lock(deviceMapMutex_);
211 if (deviceMap_.find(type) != deviceMap_.end()) {
212 unordered_map<uint64_t, shared_ptr<Device>> &map = deviceMap_[type];
213 map.erase(deviceId);
214 EDM_LOGI(MODULE_DEV_MGR, "success RemoveDeviceOfDeviceMap, deviceId:%{public}016" PRIx64 "", deviceId);
215 }
216 }
217
DeleteBundlesOfBundleInfoMap(const std::string & bundleName)218 std::unordered_set<uint64_t> ExtDeviceManager::DeleteBundlesOfBundleInfoMap(const std::string &bundleName)
219 {
220 EDM_LOGD(MODULE_DEV_MGR, "DeleteBundlesOfBundleInfoMap enter");
221 std::unordered_set<uint64_t> deviceIds;
222 lock_guard<mutex> lock(bundleMatchMapMutex_);
223 if (bundleName.empty()) {
224 bundleMatchMap_.clear();
225 } else {
226 std::string startStr = bundleName + Device::GetStiching();
227 for (auto iter = bundleMatchMap_.begin(); iter != bundleMatchMap_.end();) {
228 if (startStr.compare(iter->first.substr(0, startStr.size())) == 0) {
229 deviceIds.insert(iter->second.begin(), iter->second.end());
230 iter = bundleMatchMap_.erase(iter);
231 } else {
232 iter++;
233 }
234 }
235 }
236 return deviceIds;
237 }
238
MatchDriverInfos(std::unordered_set<uint64_t> deviceIds)239 void ExtDeviceManager::MatchDriverInfos(std::unordered_set<uint64_t> deviceIds)
240 {
241 EDM_LOGI(MODULE_DEV_MGR, "MatchDriverInfos enter");
242 lock_guard<mutex> lock(deviceMapMutex_);
243 for (auto &m : deviceMap_) {
244 for (auto &[deviceId, device] : m.second) {
245 if (deviceIds.find(deviceId) != deviceIds.end()) {
246 device->RemoveBundleInfo();
247 device->ClearDrvExtRemote();
248 RemoveDriverInfo(device);
249 }
250 if (device->IsUnRegisted() || device->GetDrvExtRemote() != nullptr) {
251 continue;
252 }
253 auto matchedDriverInfo = DriverPkgManager::GetInstance().QueryMatchDriver(device->GetDeviceInfo());
254 if (matchedDriverInfo == nullptr) {
255 EDM_LOGD(MODULE_DEV_MGR, "deviceId[%{public}016" PRIX64 "], not find driver", deviceId);
256 continue;
257 }
258 std::string bundleInfo = matchedDriverInfo->GetBundleName() + Device::GetStiching() +
259 matchedDriverInfo->GetDriverName();
260 EDM_LOGI(MODULE_DEV_MGR, "MatchDriverInfo success, bundleInfo: %{public}s", bundleInfo.c_str());
261 device->AddBundleInfo(bundleInfo, matchedDriverInfo);
262 int32_t ret = AddDevIdOfBundleInfoMap(device, bundleInfo);
263 if (ret != EDM_OK) {
264 EDM_LOGD(MODULE_DEV_MGR,
265 "deviceId[%{public}016" PRIX64 "] AddDevIdOfBundleInfoMap failed, ret=%{public}d", deviceId, ret);
266 }
267 }
268 }
269 }
270
ClearMatchedDrivers(const int32_t userId)271 void ExtDeviceManager::ClearMatchedDrivers(const int32_t userId)
272 {
273 EDM_LOGI(MODULE_DEV_MGR, "ClearMatchedDrivers start");
274 lock_guard<mutex> lock(bundleMatchMapMutex_);
275 for (auto iter : bundleMatchMap_) {
276 std::string bundleInfo = iter.first;
277 (void)DriverExtensionController::GetInstance().StopDriverExtension(Device::GetBundleName(bundleInfo),
278 Device::GetAbilityName(bundleInfo), userId);
279 }
280 bundleMatchMap_.clear();
281
282 lock_guard<mutex> deviceMapLock(deviceMapMutex_);
283 for (auto &m : deviceMap_) {
284 for (auto &[_, device] : m.second) {
285 if (device != nullptr && !device->IsUnRegisted()) {
286 device->RemoveBundleInfo();
287 device->ClearDrvExtRemote();
288 RemoveDriverInfo(device);
289 }
290 }
291 }
292 }
293
RegisterDevice(shared_ptr<DeviceInfo> devInfo)294 int32_t ExtDeviceManager::RegisterDevice(shared_ptr<DeviceInfo> devInfo)
295 {
296 BusType type = devInfo->GetBusType();
297 uint64_t deviceId = devInfo->GetDeviceId();
298 shared_ptr<Device> device;
299 lock_guard<mutex> lock(deviceMapMutex_);
300 if (deviceMap_.find(type) != deviceMap_.end()) {
301 unordered_map<uint64_t, shared_ptr<Device>> &map = deviceMap_[type];
302 if (map.find(deviceId) != map.end() && map[deviceId] != nullptr) {
303 device = map.find(deviceId)->second;
304 // device has been registered and do not need to connect again
305 if (device->GetDrvExtRemote() != nullptr) {
306 EDM_LOGI(MODULE_DEV_MGR, "device has been registered, deviceId is %{public}016" PRIx64 "", deviceId);
307 return EDM_OK;
308 }
309 // device has been registered and need to connect
310 EDM_LOGI(MODULE_DEV_MGR, "device has been registered, deviceId is %{public}016" PRIx64 "", deviceId);
311 }
312 } else {
313 EDM_LOGI(MODULE_DEV_MGR, "emplace Type of deviceMap_");
314 deviceMap_.emplace(type, unordered_map<uint64_t, shared_ptr<Device>>());
315 }
316 EDM_LOGD(MODULE_DEV_MGR, "begin to register device, deviceId is %{public}016" PRIx64 "", deviceId);
317 // device need to register
318 if (device == nullptr) {
319 device = make_shared<Device>(devInfo);
320 deviceMap_[type].emplace(deviceId, device);
321 EDM_LOGI(MODULE_DEV_MGR, "successfully registered device, deviceId = %{public}016" PRIx64 "", deviceId);
322 }
323 // driver match
324 std::string bundleInfo = device->GetBundleInfo();
325 // if device does not have a matching driver, match driver here
326 if (bundleInfo.empty()) {
327 auto matchedDriverInfo = DriverPkgManager::GetInstance().QueryMatchDriver(devInfo);
328 if (matchedDriverInfo != nullptr) {
329 bundleInfo = matchedDriverInfo->GetBundleName() + Device::GetStiching() +
330 matchedDriverInfo->GetDriverName();
331 device->AddBundleInfo(bundleInfo, matchedDriverInfo);
332 }
333 }
334 unloadSelftimer_.Unregister(unloadSelftimerId_);
335
336 // match driver failed, waitting to install driver package
337 if (bundleInfo.empty()) {
338 EDM_LOGD(MODULE_DEV_MGR,
339 "deviceId %{public}016" PRIX64 "match driver failed, waitting to install ext driver package", deviceId);
340 return EDM_OK;
341 }
342
343 int32_t ret = AddDevIdOfBundleInfoMap(device, bundleInfo);
344 if (ret != EDM_OK) {
345 EDM_LOGE(MODULE_DEV_MGR, "deviceId[%{public}016" PRIX64 "] update bundle info map failed[%{public}d]", deviceId,
346 ret);
347 return EDM_NOK;
348 }
349 EDM_LOGI(MODULE_DEV_MGR, "successfully match driver[%{public}s], deviceId is %{public}016" PRIx64 "",
350 bundleInfo.c_str(), deviceId);
351
352 return ret;
353 }
354
UnRegisterDevice(const shared_ptr<DeviceInfo> devInfo)355 int32_t ExtDeviceManager::UnRegisterDevice(const shared_ptr<DeviceInfo> devInfo)
356 {
357 BusType type = devInfo->GetBusType();
358 uint64_t deviceId = devInfo->GetDeviceId();
359 shared_ptr<Device> device;
360 string bundleInfo;
361
362 lock_guard<mutex> lock(deviceMapMutex_);
363 if (deviceMap_.find(type) != deviceMap_.end()) {
364 unordered_map<uint64_t, shared_ptr<Device>> &map = deviceMap_[type];
365 if (map.find(deviceId) != map.end()) {
366 device = map[deviceId];
367 bundleInfo = map[deviceId]->GetBundleInfo();
368 if (device != nullptr && device->GetDrvExtRemote() != nullptr) {
369 device->UnRegist();
370 } else {
371 map.erase(deviceId);
372 }
373 EDM_LOGI(MODULE_DEV_MGR, "successfully unregistered device, deviceId is %{public}016" PRIx64 "", deviceId);
374 UnLoadSelf();
375 }
376 }
377
378 if (bundleInfo.empty()) {
379 EDM_LOGI(MODULE_DEV_MGR, "deviceId %{public}016" PRIX64 " bundleInfo is empty", deviceId);
380 return EDM_OK;
381 }
382
383 int32_t ret = RemoveDevIdOfBundleInfoMap(device, bundleInfo);
384 if (ret != EDM_OK) {
385 EDM_LOGE(
386 MODULE_DEV_MGR, "deviceId[%{public}016" PRIX64 "] remove bundleInfo map failed[%{public}d]", deviceId, ret);
387 return ret;
388 }
389
390 EDM_LOGI(MODULE_DEV_MGR, "successfully remove bundleInfo, deviceId %{public}016" PRIx64 ", bundleInfo[%{public}s]",
391 deviceId, bundleInfo.c_str());
392
393 return EDM_OK;
394 }
395
QueryDevice(const BusType busType)396 vector<shared_ptr<DeviceInfo>> ExtDeviceManager::QueryDevice(const BusType busType)
397 {
398 vector<shared_ptr<DeviceInfo>> devInfoVec;
399
400 lock_guard<mutex> lock(deviceMapMutex_);
401 if (deviceMap_.find(busType) == deviceMap_.end()) {
402 EDM_LOGE(MODULE_DEV_MGR, "no device is found and busType %{public}d is invalid", busType);
403 return devInfoVec;
404 }
405
406 unordered_map<uint64_t, shared_ptr<Device>> map = deviceMap_[busType];
407 for (auto &[_, device] : map) {
408 if (device != nullptr && !device->IsUnRegisted()) {
409 devInfoVec.emplace_back(device->GetDeviceInfo());
410 }
411 }
412 EDM_LOGD(MODULE_DEV_MGR, "find %{public}zu device of busType %{public}d", devInfoVec.size(), busType);
413
414 return devInfoVec;
415 }
416
QueryAllDevices()417 vector<shared_ptr<Device>> ExtDeviceManager::QueryAllDevices()
418 {
419 vector<shared_ptr<Device>> devices;
420 lock_guard<mutex> lock(deviceMapMutex_);
421
422 for (auto &m : deviceMap_) {
423 for (auto &[_, device] : m.second) {
424 if (device != nullptr && !device->IsUnRegisted()) {
425 devices.emplace_back(device);
426 }
427 }
428 }
429
430 return devices;
431 }
432
QueryDevicesById(const uint64_t deviceId)433 vector<shared_ptr<Device>> ExtDeviceManager::QueryDevicesById(const uint64_t deviceId)
434 {
435 vector<shared_ptr<Device>> devices;
436 lock_guard<mutex> lock(deviceMapMutex_);
437
438 for (auto &m : deviceMap_) {
439 for (auto &[id, device] : m.second) {
440 if (deviceId == id && device != nullptr && !device->IsUnRegisted()) {
441 devices.emplace_back(device);
442 }
443 }
444 }
445
446 return devices;
447 }
448
449
GetTotalDeviceNum(void) const450 size_t ExtDeviceManager::GetTotalDeviceNum(void) const
451 {
452 // Please do not add lock. This will be called in the UnRegisterDevice.
453 size_t totalNum = 0;
454 for (auto &m : deviceMap_) {
455 for (auto &[_, device] : m.second) {
456 if (!device->IsUnRegisted()) {
457 totalNum++;
458 }
459 }
460 }
461 EDM_LOGD(MODULE_DEV_MGR, "total device num is %{public}zu", totalNum);
462 return totalNum;
463 }
464
UnLoadSelf(void)465 void ExtDeviceManager::UnLoadSelf(void)
466 {
467 unloadSelftimer_.Unregister(unloadSelftimerId_);
468 unloadSelftimer_.Shutdown();
469 if (GetTotalDeviceNum() != 0) {
470 EDM_LOGI(MODULE_DEV_MGR, "not need unload");
471 return;
472 }
473
474 if (auto ret = unloadSelftimer_.Setup(); ret != Utils::TIMER_ERR_OK) {
475 EDM_LOGE(MODULE_DEV_MGR, "set up timer failed %{public}u", ret);
476 return;
477 }
478
479 auto task = []() {
480 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
481 if (samgrProxy == nullptr) {
482 EDM_LOGE(MODULE_DEV_MGR, "get samgr failed");
483 return;
484 }
485
486 auto saObj = samgrProxy->CheckSystemAbility(HDF_EXTERNAL_DEVICE_MANAGER_SA_ID);
487 if (saObj == nullptr) {
488 EDM_LOGE(MODULE_DEV_MGR, "sa has unloaded");
489 return;
490 }
491
492 auto ret = samgrProxy->UnloadSystemAbility(HDF_EXTERNAL_DEVICE_MANAGER_SA_ID);
493 if (ret != EDM_OK) {
494 EDM_LOGE(MODULE_DEV_MGR, "unload failed");
495 }
496 };
497 unloadSelftimerId_ = unloadSelftimer_.Register(task, UNLOAD_SA_TIMER_INTERVAL, true);
498 }
499
QueryDeviceByDeviceID(uint64_t deviceId)500 std::shared_ptr<Device> ExtDeviceManager::QueryDeviceByDeviceID(uint64_t deviceId)
501 {
502 BusType busType = *reinterpret_cast<BusType *>(&deviceId);
503 EDM_LOGI(MODULE_DEV_MGR, "the busType: %{public}d", static_cast<uint32_t>(busType));
504 auto deviceMapIter = deviceMap_.find(busType);
505 if (deviceMapIter == deviceMap_.end()) {
506 EDM_LOGE(MODULE_DEV_MGR, "can not find device by %{public}d busType", static_cast<uint32_t>(busType));
507 return nullptr;
508 }
509
510 const auto &devices = deviceMapIter->second;
511 auto deviceIter = devices.find(deviceId);
512 if (deviceIter == devices.end()) {
513 EDM_LOGE(MODULE_DEV_MGR, "can not find device by %{public}016" PRIX64 " deviceId", deviceId);
514 return nullptr;
515 }
516
517 EDM_LOGI(MODULE_DEV_MGR, "find device by %{public}016" PRIX64 " deviceId sucessfully", deviceId);
518 return deviceIter->second;
519 }
520
ConnectDevice(uint64_t deviceId,uint32_t callingTokenId,const sptr<IDriverExtMgrCallback> & connectCallback)521 int32_t ExtDeviceManager::ConnectDevice(uint64_t deviceId, uint32_t callingTokenId,
522 const sptr<IDriverExtMgrCallback> &connectCallback)
523 {
524 // find device by deviceId
525 lock_guard<mutex> lock(deviceMapMutex_);
526 std::shared_ptr<Device> device = QueryDeviceByDeviceID(deviceId);
527 if (device == nullptr) {
528 EDM_LOGI(MODULE_DEV_MGR, "failed to find device with %{public}016" PRIX64 " deviceId", deviceId);
529 return EDM_NOK;
530 }
531
532 return device->Connect(connectCallback, callingTokenId);
533 }
534
DisConnectDevice(uint64_t deviceId,uint32_t callingTokenId)535 int32_t ExtDeviceManager::DisConnectDevice(uint64_t deviceId, uint32_t callingTokenId)
536 {
537 lock_guard<mutex> lock(deviceMapMutex_);
538 std::shared_ptr<Device> device = QueryDeviceByDeviceID(deviceId);
539 if (device == nullptr) {
540 EDM_LOGI(MODULE_DEV_MGR, "failed to find device with %{public}016" PRIX64 " deviceId", deviceId);
541 return EDM_NOK;
542 }
543
544 std::shared_ptr<DriverInfo> driverInfo = device->GetDriverInfo();
545 if (driverInfo == nullptr) {
546 EDM_LOGE(MODULE_DEV_MGR, "failed to find driverInfo for device with %{public}016" PRIX64 " deviceId", deviceId);
547 return EDM_NOK;
548 }
549
550 if (!driverInfo->GetLaunchOnBind() || !device->IsLastCaller(callingTokenId)) {
551 device->RemoveCaller(callingTokenId);
552 EDM_LOGI(MODULE_DEV_MGR, "driver not launching on bind or other client bound. Removing caller ID: %{public}u",
553 callingTokenId);
554 return EDM_OK;
555 }
556 return device->Disconnect();
557 }
558
ConnectDriverWithDeviceId(uint64_t deviceId,uint32_t callingTokenId,const unordered_set<std::string> & accessibleBundles,const sptr<IDriverExtMgrCallback> & connectCallback)559 int32_t ExtDeviceManager::ConnectDriverWithDeviceId(uint64_t deviceId, uint32_t callingTokenId,
560 const unordered_set<std::string> &accessibleBundles, const sptr<IDriverExtMgrCallback> &connectCallback)
561 {
562 // find device by deviceId
563 lock_guard<mutex> lock(deviceMapMutex_);
564 std::shared_ptr<Device> device = QueryDeviceByDeviceID(deviceId);
565 if (device == nullptr) {
566 EDM_LOGI(MODULE_DEV_MGR, "failed to find device with %{public}016" PRIX64 " deviceId", deviceId);
567 return EDM_NOK;
568 }
569
570 int32_t ret = CheckAccessPermission(device->GetDriverInfo(), accessibleBundles);
571 if (ret != EDM_OK) {
572 EDM_LOGE(MODULE_DEV_MGR, "failed to bind device verification with %{public}016" PRIX64 " deviceId", deviceId);
573 return ret;
574 }
575 return device->Connect(connectCallback, callingTokenId);
576 }
577
DisConnectDriverWithDeviceId(uint64_t deviceId,uint32_t callingTokenId)578 int32_t ExtDeviceManager::DisConnectDriverWithDeviceId(uint64_t deviceId, uint32_t callingTokenId)
579 {
580 lock_guard<mutex> lock(deviceMapMutex_);
581 std::shared_ptr<Device> device = QueryDeviceByDeviceID(deviceId);
582 if (device == nullptr) {
583 EDM_LOGI(MODULE_DEV_MGR, "failed to find device with %{public}016" PRIX64 " deviceId", deviceId);
584 return EDM_NOK;
585 }
586
587 if (!device->IsBindCaller(callingTokenId)) {
588 EDM_LOGE(MODULE_DEV_MGR, "can not find binding relationship by %{public}u callerTokenId", callingTokenId);
589 return EDM_ERR_SERVICE_NOT_BOUND;
590 }
591
592 std::shared_ptr<DriverInfo> driverInfo = device->GetDriverInfo();
593 if (driverInfo == nullptr) {
594 EDM_LOGE(MODULE_DEV_MGR, "failed to find driverInfo for device with %{public}016" PRIX64 " deviceId", deviceId);
595 return EDM_NOK;
596 }
597
598 if (!driverInfo->GetLaunchOnBind() || !device->IsLastCaller(callingTokenId)) {
599 device->RemoveCaller(callingTokenId);
600 EDM_LOGI(MODULE_DEV_MGR, "driver not launching on bind or other client bound. Removing caller ID: %{public}u",
601 callingTokenId);
602 return EDM_OK;
603 }
604 return device->Disconnect();
605 }
606
SetDriverChangeCallback(shared_ptr<IDriverChangeCallback> & driverChangeCallback)607 void ExtDeviceManager::SetDriverChangeCallback(shared_ptr<IDriverChangeCallback> &driverChangeCallback)
608 {
609 driverChangeCallback_ = driverChangeCallback;
610 }
611
CheckAccessPermission(const std::shared_ptr<DriverInfo> & driverInfo,const unordered_set<std::string> & accessibleBundles) const612 int32_t ExtDeviceManager::CheckAccessPermission(const std::shared_ptr<DriverInfo> &driverInfo,
613 const unordered_set<std::string> &accessibleBundles) const
614 {
615 if (driverInfo == nullptr) {
616 EDM_LOGE(MODULE_DEV_MGR, "the device does not have a matching driver");
617 return EDM_NOK;
618 }
619 if (!driverInfo->IsAccessAllowed()) {
620 EDM_LOGE(MODULE_DEV_MGR, "the driver service does not allow access");
621 return EDM_ERR_SERVICE_NOT_ALLOW_ACCESS;
622 }
623
624 std::string bundleName = driverInfo->GetBundleName();
625 auto driverIter = accessibleBundles.find(bundleName);
626 if (driverIter == accessibleBundles.end()) {
627 EDM_LOGE(MODULE_DEV_MGR, "%{public}s does not exist in ohos.permission.ACCESS_DDK_DRIVERS configuration",
628 bundleName.c_str());
629 return EDM_ERR_NO_PERM;
630 }
631 return EDM_OK;
632 }
633 } // namespace ExternalDeviceManager
634 } // namespace OHOS