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