• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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