• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 
26 namespace OHOS {
27 namespace ExternalDeviceManager {
28 constexpr uint32_t UNLOAD_SA_TIMER_INTERVAL = 30 * 1000;
29 std::string Device::stiching_ = "_stiching_";
30 IMPLEMENT_SINGLE_INSTANCE(ExtDeviceManager);
31 
~ExtDeviceManager()32 ExtDeviceManager::~ExtDeviceManager()
33 {
34     unloadSelftimer_.Unregister(unloadSelftimerId_);
35     unloadSelftimer_.Shutdown();
36 }
37 
PrintMatchDriverMap()38 void ExtDeviceManager::PrintMatchDriverMap()
39 {
40     if (!bundleMatchMap_.empty()) {
41         EDM_LOGD(MODULE_DEV_MGR, " bundleInfo map size[%{public}zu]", bundleMatchMap_.size());
42         for (auto iter : bundleMatchMap_) {
43             for (auto iterId = iter.second.begin(); iterId != iter.second.end(); ++iterId) {
44                 uint64_t deviceId = *iterId;
45                 EDM_LOGD(MODULE_DEV_MGR, "print match map info[%{public}s], deviceId %{public}016" PRIX64 "",
46                     iter.first.c_str(), deviceId);
47             }
48         }
49         EDM_LOGD(MODULE_DEV_MGR, "ExtDeviceManager print driver match map success");
50     }
51 }
52 
Init()53 int32_t ExtDeviceManager::Init()
54 {
55     EDM_LOGD(MODULE_DEV_MGR, "ExtDeviceManager Init success");
56     int32_t ret = DriverPkgManager::GetInstance().RegisterOnBundleUpdate(UpdateBundleStatusCallback);
57     if (ret != EDM_OK) {
58         EDM_LOGE(MODULE_DEV_MGR, "register bundle status callback fail");
59         return EDM_NOK;
60     }
61     return EDM_OK;
62 }
63 
AddDevIdOfBundleInfoMap(shared_ptr<Device> device,string & bundleInfo)64 int32_t ExtDeviceManager::AddDevIdOfBundleInfoMap(shared_ptr<Device> device, string &bundleInfo)
65 {
66     if (bundleInfo.empty() || device == nullptr) {
67         EDM_LOGE(MODULE_DEV_MGR, "bundleInfo or device is null");
68         return EDM_ERR_INVALID_PARAM;
69     }
70 
71     // update bundle info
72     lock_guard<mutex> lock(bundleMatchMapMutex_);
73     auto pos = bundleMatchMap_.find(bundleInfo);
74     uint64_t deviceId = device->GetDeviceInfo()->GetDeviceId();
75     if (pos == bundleMatchMap_.end()) {
76         unordered_set<uint64_t> tmpSet;
77         tmpSet.emplace(deviceId);
78         bundleMatchMap_.emplace(bundleInfo, tmpSet);
79         EDM_LOGI(MODULE_DEV_MGR, "bundleMap emplace New driver, add deviceId %{public}016" PRIX64 "", deviceId);
80     } else {
81         auto pairRet = pos->second.emplace(deviceId);
82         // Check whether the deviceId matches the driver
83         if (!pairRet.second || pos->second.size() > 1) {
84             EDM_LOGI(MODULE_DEV_MGR, "bundleMap had existed driver, add deviceId %{public}016" PRIX64 "", deviceId);
85             PrintMatchDriverMap();
86         }
87     }
88 
89     // start ability
90     int32_t ret = device->Connect();
91     if (ret != EDM_OK) {
92         EDM_LOGE(MODULE_DEV_MGR,
93             "deviceId[%{public}016" PRIX64 "] connect driver extension ability[%{public}s] failed[%{public}d]",
94             deviceId, Device::GetAbilityName(bundleInfo).c_str(), ret);
95         return EDM_NOK;
96     }
97     PrintMatchDriverMap();
98     return EDM_OK;
99 }
100 
RemoveDevIdOfBundleInfoMap(shared_ptr<Device> device,string & bundleInfo)101 int32_t ExtDeviceManager::RemoveDevIdOfBundleInfoMap(shared_ptr<Device> device, string &bundleInfo)
102 {
103     if (bundleInfo.empty() || device == nullptr) {
104         EDM_LOGE(MODULE_DEV_MGR, "bundleInfo or device is null");
105         return EDM_ERR_INVALID_PARAM;
106     }
107 
108     // update bundle info
109     lock_guard<mutex> lock(bundleMatchMapMutex_);
110     auto pos = bundleMatchMap_.find(bundleInfo);
111     if (pos == bundleMatchMap_.end()) {
112         EDM_LOGI(MODULE_DEV_MGR, "not find bundleInfo from map");
113         return EDM_OK;
114     }
115 
116     // If the number of devices is greater than one, only the device erase
117     uint64_t deviceId = device->GetDeviceInfo()->GetDeviceId();
118     if (pos->second.size() > 1) {
119         pos->second.erase(deviceId);
120         EDM_LOGD(MODULE_DEV_MGR, "bundleMap existed driver, remove deviceId %{public}016" PRIX64 "", deviceId);
121         PrintMatchDriverMap();
122         return EDM_OK;
123     }
124 
125     EDM_LOGD(MODULE_DEV_MGR, "bundleMap remove bundleInfo[%{public}s]", bundleInfo.c_str());
126     bundleMatchMap_.erase(pos);
127 
128     // stop ability and destory sa
129     int32_t ret = device->Disconnect();
130     if (ret != EDM_OK) {
131         EDM_LOGE(MODULE_DEV_MGR,
132             "deviceId[%{public}016" PRIX64 "] disconnect driver extension ability[%{public}s] failed[%{public}d]",
133             deviceId, Device::GetAbilityName(bundleInfo).c_str(), ret);
134         return ret;
135     }
136     PrintMatchDriverMap();
137     return EDM_OK;
138 }
139 
RemoveAllDevIdOfBundleInfoMap(shared_ptr<Device> device,string & bundleInfo)140 int32_t ExtDeviceManager::RemoveAllDevIdOfBundleInfoMap(shared_ptr<Device> device, string &bundleInfo)
141 {
142     if (device == nullptr) {
143         EDM_LOGE(MODULE_DEV_MGR, "device is null");
144         return EDM_ERR_INVALID_PARAM;
145     }
146     // update bundle info
147     lock_guard<mutex> lock(bundleMatchMapMutex_);
148     auto pos = bundleMatchMap_.find(bundleInfo);
149     if (pos == bundleMatchMap_.end()) {
150         return EDM_OK;
151     }
152 
153     bundleMatchMap_.erase(pos);
154     // stop ability and destory sa
155     int32_t ret = device->Disconnect();
156     if (ret != EDM_OK) {
157         EDM_LOGE(MODULE_DEV_MGR, "disconnect driver extension ability[%{public}s] failed[%{public}d]",
158             Device::GetAbilityName(bundleInfo).c_str(), ret);
159         return ret;
160     }
161     return EDM_OK;
162 }
163 
RemoveDeviceOfDeviceMap(shared_ptr<Device> device)164 void ExtDeviceManager::RemoveDeviceOfDeviceMap(shared_ptr<Device> device)
165 {
166     EDM_LOGI(MODULE_DEV_MGR, "RemoveDeviceOfDeviceMap enter");
167     shared_ptr<DeviceInfo> deviceInfo = device->GetDeviceInfo();
168     if (deviceInfo == nullptr) {
169         EDM_LOGE(MODULE_DEV_MGR, "device info is null");
170         return;
171     }
172     BusType type = deviceInfo->GetBusType();
173     uint64_t deviceId = deviceInfo->GetDeviceId();
174 
175     lock_guard<mutex> lock(deviceMapMutex_);
176     if (deviceMap_.find(type) != deviceMap_.end()) {
177         unordered_map<uint64_t, shared_ptr<Device>> &map = deviceMap_[type];
178         map.erase(deviceId);
179         EDM_LOGI(MODULE_DEV_MGR, "success RemoveDeviceOfDeviceMap, deviceId:%{public}016" PRIx64 "", deviceId);
180     }
181 }
182 
AddBundleInfo(enum BusType busType,const string & bundleName,const string & abilityName)183 int32_t ExtDeviceManager::AddBundleInfo(enum BusType busType, const string &bundleName, const string &abilityName)
184 {
185     EDM_LOGI(MODULE_DEV_MGR, "%{public}s enter", __func__);
186     if (busType <= BUS_TYPE_INVALID || busType > BUS_TYPE_TEST) {
187         EDM_LOGE(MODULE_DEV_MGR, "busType para invalid");
188         return EDM_ERR_INVALID_PARAM;
189     }
190 
191     if (bundleName.empty() || abilityName.empty()) {
192         EDM_LOGE(MODULE_DEV_MGR, "BundleInfo para invalid");
193         return EDM_ERR_INVALID_PARAM;
194     }
195 
196     // iterate over device, find bundleInfo and ability status
197     lock_guard<mutex> lock(deviceMapMutex_);
198 
199     // find device
200     if (deviceMap_.count(busType) == 0) {
201         EDM_LOGD(MODULE_DEV_MGR, "deviceMap_ not bustype[%{public}d], wait to plug device", busType);
202         return EDM_OK;
203     }
204 
205     string bundleInfo = bundleName + Device::GetStiching() + abilityName;
206     unordered_map<uint64_t, shared_ptr<Device>> &map = deviceMap_[busType];
207 
208     for (auto iter : map) {
209         shared_ptr<Device> device = iter.second;
210 
211         // iterate over device by bustype
212         auto bundleInfoNames = DriverPkgManager::GetInstance().QueryMatchDriver(device->GetDeviceInfo());
213         if (bundleInfoNames == nullptr) {
214             EDM_LOGD(MODULE_DEV_MGR, "deviceId[%{public}016" PRIX64 "], not find driver",
215                 device->GetDeviceInfo()->GetDeviceId());
216             continue;
217         }
218 
219         if (bundleName.compare(bundleInfoNames->bundleName) == 0 &&
220             abilityName.compare(bundleInfoNames->abilityName) == 0) {
221             device->AddBundleInfo(bundleInfo);
222             int32_t ret = AddDevIdOfBundleInfoMap(device, bundleInfo);
223             if (ret != EDM_OK) {
224                 EDM_LOGE(MODULE_DEV_MGR,
225                     "deviceId[%{public}016" PRIX64 "] start driver extension ability[%{public}s] fail[%{public}d]",
226                     device->GetDeviceInfo()->GetDeviceId(), Device::GetAbilityName(bundleInfo).c_str(), ret);
227             }
228         }
229     }
230 
231     return EDM_OK;
232 }
233 
RemoveBundleInfo(enum BusType busType,const string & bundleName,const string & abilityName)234 int32_t ExtDeviceManager::RemoveBundleInfo(enum BusType busType, const string &bundleName, const string &abilityName)
235 {
236     EDM_LOGI(MODULE_DEV_MGR, "%{public}s enter", __func__);
237     if (busType <= BUS_TYPE_INVALID || busType >= BUS_TYPE_TEST) {
238         EDM_LOGE(MODULE_DEV_MGR, "busType para invalid");
239         return EDM_ERR_INVALID_PARAM;
240     }
241 
242     if (bundleName.empty() || abilityName.empty()) {
243         EDM_LOGE(MODULE_DEV_MGR, "BundleInfo para invalid");
244         return EDM_ERR_INVALID_PARAM;
245     }
246 
247     lock_guard<mutex> lock(deviceMapMutex_);
248     if (deviceMap_.count(busType) == 0) {
249         EDM_LOGD(MODULE_DEV_MGR, "deviceMap_ not bustype[%{public}d], wait to plug device", busType);
250         return EDM_OK;
251     }
252 
253     // iterate over device, remove bundleInfo
254     string bundleInfo = bundleName + Device::GetStiching() + abilityName;
255     unordered_map<uint64_t, shared_ptr<Device>> &deviceMap = deviceMap_[busType];
256 
257     for (auto iter : deviceMap) {
258         shared_ptr<Device> device = iter.second;
259 
260         // iterate over device by bustype
261         if (bundleInfo.compare(device->GetBundleInfo()) == 0) {
262             int32_t ret = RemoveAllDevIdOfBundleInfoMap(device, bundleInfo);
263             device->RemoveBundleInfo(); // update device
264             if (ret != EDM_OK) {
265                 EDM_LOGE(MODULE_DEV_MGR,
266                     "deviceId[%{public}016" PRIX64 "] stop driver extension ability[%{public}s] fail[%{public}d]",
267                     device->GetDeviceInfo()->GetDeviceId(), Device::GetAbilityName(bundleInfo).c_str(), ret);
268             }
269         }
270     }
271     return EDM_OK;
272 }
273 
UpdateBundleInfo(enum BusType busType,const string & bundleName,const string & abilityName)274 int32_t ExtDeviceManager::UpdateBundleInfo(enum BusType busType, const string &bundleName, const string &abilityName)
275 {
276     EDM_LOGI(MODULE_DEV_MGR, "%{public}s enter", __func__);
277     // stop ability of device and reset bundleInfo of device
278     int32_t ret = RemoveBundleInfo(busType, bundleName, abilityName);
279     if (ret != EDM_OK) {
280         EDM_LOGE(MODULE_DEV_MGR, "remove bundle info fail");
281         return EDM_NOK;
282     }
283 
284     // iterate over device, add bundleInfo and start ability
285     ret = AddBundleInfo(busType, bundleName, abilityName);
286     if (ret != EDM_OK) {
287         EDM_LOGE(MODULE_DEV_MGR, "add bundle info fail");
288         return EDM_NOK;
289     }
290 
291     return EDM_OK;
292 }
293 
UpdateBundleStatusCallback(int32_t bundleStatus,int32_t busType,const string & bundleName,const string & abilityName)294 int32_t ExtDeviceManager::UpdateBundleStatusCallback(
295     int32_t bundleStatus, int32_t busType, const string &bundleName, const string &abilityName)
296 {
297     int32_t ret = EDM_NOK;
298     if (bundleStatus < BUNDLE_ADDED || bundleStatus > BUNDLE_REMOVED) {
299         EDM_LOGE(MODULE_DEV_MGR, "bundleStatus para invalid");
300         return EDM_ERR_INVALID_PARAM;
301     }
302 
303     // add bundle
304     if (bundleStatus == BUNDLE_ADDED) {
305         ret = ExtDeviceManager::GetInstance().AddBundleInfo((enum BusType)busType, bundleName, abilityName);
306         if (ret != EDM_OK) {
307             EDM_LOGE(MODULE_DEV_MGR, "callback add bundle info fail");
308         }
309         return ret;
310     }
311 
312     // update bundle
313     if (bundleStatus == BUNDLE_UPDATED) {
314         ret = ExtDeviceManager::GetInstance().UpdateBundleInfo((enum BusType)busType, bundleName, abilityName);
315         if (ret != EDM_OK) {
316             EDM_LOGE(MODULE_DEV_MGR, "callback update bundle info fail");
317         }
318         return ret;
319     }
320 
321     // remove bundle
322     ret = ExtDeviceManager::GetInstance().RemoveBundleInfo((enum BusType)busType, bundleName, abilityName);
323     if (ret != EDM_OK) {
324         EDM_LOGE(MODULE_DEV_MGR, "callback remove bundle info fail");
325     }
326 
327     return ret;
328 }
329 
RegisterDevice(shared_ptr<DeviceInfo> devInfo)330 int32_t ExtDeviceManager::RegisterDevice(shared_ptr<DeviceInfo> devInfo)
331 {
332     BusType type = devInfo->GetBusType();
333     uint64_t deviceId = devInfo->GetDeviceId();
334     shared_ptr<Device> device;
335     lock_guard<mutex> lock(deviceMapMutex_);
336     if (deviceMap_.find(type) != deviceMap_.end()) {
337         unordered_map<uint64_t, shared_ptr<Device>> &map = deviceMap_[type];
338         if (map.find(deviceId) != map.end() && map[deviceId] != nullptr) {
339             device = map.find(deviceId)->second;
340             // device has been registered and do not need to connect again
341             if (device->GetDrvExtRemote() != nullptr) {
342                 EDM_LOGI(MODULE_DEV_MGR, "device has been registered, deviceId is %{public}016" PRIx64 "", deviceId);
343                 return EDM_OK;
344             }
345             // device has been registered and need to connect
346             EDM_LOGI(MODULE_DEV_MGR, "device has been registered, deviceId is %{public}016" PRIx64 "", deviceId);
347         }
348     } else {
349         EDM_LOGI(MODULE_DEV_MGR, "emplace Type of deviceMap_");
350         deviceMap_.emplace(type, unordered_map<uint64_t, shared_ptr<Device>>());
351     }
352     EDM_LOGD(MODULE_DEV_MGR, "begin to register device, deviceId is %{public}016" PRIx64 "", deviceId);
353     // device need to register
354     if (device == nullptr) {
355         device = make_shared<Device>(devInfo);
356         deviceMap_[type].emplace(deviceId, device);
357         EDM_LOGI(MODULE_DEV_MGR, "successfully registered device, deviceId = %{public}016" PRIx64 "", deviceId);
358     }
359     // driver match
360     std::string bundleInfo = device->GetBundleInfo();
361     // if device does not have a matching driver, match driver here
362     if (bundleInfo.empty()) {
363         auto bundleInfoNames = DriverPkgManager::GetInstance().QueryMatchDriver(devInfo);
364         if (bundleInfoNames != nullptr) {
365             bundleInfo = bundleInfoNames->bundleName + Device::GetStiching() + bundleInfoNames->abilityName;
366             device->AddBundleInfo(bundleInfo);
367         }
368     }
369     unloadSelftimer_.Unregister(unloadSelftimerId_);
370 
371     // match driver failed, waitting to install driver package
372     if (bundleInfo.empty()) {
373         EDM_LOGD(MODULE_DEV_MGR,
374             "deviceId %{public}016" PRIX64 "match driver failed, waitting to install ext driver package", deviceId);
375         return EDM_OK;
376     }
377 
378     int32_t ret = AddDevIdOfBundleInfoMap(device, bundleInfo);
379     if (ret != EDM_OK) {
380         EDM_LOGE(MODULE_DEV_MGR, "deviceId[%{public}016" PRIX64 "] update bundle info map failed[%{public}d]", deviceId,
381             ret);
382         return EDM_NOK;
383     }
384     EDM_LOGI(MODULE_DEV_MGR, "successfully match driver[%{public}s], deviceId is %{public}016" PRIx64 "",
385         bundleInfo.c_str(), deviceId);
386 
387     return ret;
388 }
389 
UnRegisterDevice(const shared_ptr<DeviceInfo> devInfo)390 int32_t ExtDeviceManager::UnRegisterDevice(const shared_ptr<DeviceInfo> devInfo)
391 {
392     BusType type = devInfo->GetBusType();
393     uint64_t deviceId = devInfo->GetDeviceId();
394     shared_ptr<Device> device;
395     string bundleInfo;
396 
397     lock_guard<mutex> lock(deviceMapMutex_);
398     if (deviceMap_.find(type) != deviceMap_.end()) {
399         unordered_map<uint64_t, shared_ptr<Device>> &map = deviceMap_[type];
400         if (map.find(deviceId) != map.end()) {
401             device = map[deviceId];
402             bundleInfo = map[deviceId]->GetBundleInfo();
403             if (device != nullptr) {
404                 device->UnRegist();
405             }
406             EDM_LOGI(MODULE_DEV_MGR, "successfully unregistered device, deviceId is %{public}016" PRIx64 "", deviceId);
407             UnLoadSelf();
408         }
409     }
410 
411     if (bundleInfo.empty()) {
412         EDM_LOGI(MODULE_DEV_MGR, "deviceId %{public}016" PRIX64 " bundleInfo is empty", deviceId);
413         return EDM_OK;
414     }
415 
416     int32_t ret = RemoveDevIdOfBundleInfoMap(device, bundleInfo);
417     if (ret != EDM_OK) {
418         EDM_LOGE(
419             MODULE_DEV_MGR, "deviceId[%{public}016" PRIX64 "] remove bundleInfo map failed[%{public}d]", deviceId, ret);
420         return ret;
421     }
422 
423     EDM_LOGI(MODULE_DEV_MGR, "successfully remove bundleInfo, deviceId %{public}016" PRIx64 ", bundleInfo[%{public}s]",
424         deviceId, bundleInfo.c_str());
425 
426     return EDM_OK;
427 }
428 
QueryDevice(const BusType busType)429 vector<shared_ptr<DeviceInfo>> ExtDeviceManager::QueryDevice(const BusType busType)
430 {
431     vector<shared_ptr<DeviceInfo>> devInfoVec;
432 
433     lock_guard<mutex> lock(deviceMapMutex_);
434     if (deviceMap_.find(busType) == deviceMap_.end()) {
435         EDM_LOGE(MODULE_DEV_MGR, "no device is found and busType %{public}d is invalid", busType);
436         return devInfoVec;
437     }
438 
439     unordered_map<uint64_t, shared_ptr<Device>> map = deviceMap_[busType];
440     for (auto device : map) {
441         devInfoVec.emplace_back(device.second->GetDeviceInfo());
442     }
443     EDM_LOGD(MODULE_DEV_MGR, "find %{public}zu device of busType %{public}d", devInfoVec.size(), busType);
444 
445     return devInfoVec;
446 }
447 
GetTotalDeviceNum(void) const448 size_t ExtDeviceManager::GetTotalDeviceNum(void) const
449 {
450     // Please do not add lock. This will be called in the UnRegisterDevice.
451     size_t totalNum = 0;
452     for (auto &m : deviceMap_) {
453         for (auto &[_, device] : m.second) {
454             if (!device->IsUnRegisted()) {
455                 totalNum++;
456             }
457         }
458     }
459     EDM_LOGD(MODULE_DEV_MGR, "total device num is %{public}zu", totalNum);
460     return totalNum;
461 }
462 
UnLoadSA(void)463 void ExtDeviceManager::UnLoadSA(void)
464 {
465     EDM_LOGI(MODULE_DEV_MGR, "UnLoadSA enter");
466     if (GetTotalDeviceNum() != 0) {
467         EDM_LOGI(MODULE_DEV_MGR, "not need unload");
468         return;
469     }
470     auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
471     if (samgrProxy == nullptr) {
472         EDM_LOGE(MODULE_DEV_MGR, "get samgr failed");
473         return;
474     }
475 
476     auto saObj = samgrProxy->CheckSystemAbility(HDF_EXTERNAL_DEVICE_MANAGER_SA_ID);
477     if (saObj == nullptr) {
478         EDM_LOGE(MODULE_DEV_MGR, "sa has unloaded");
479         return;
480     }
481 
482     auto ret = samgrProxy->UnloadSystemAbility(HDF_EXTERNAL_DEVICE_MANAGER_SA_ID);
483     if (ret != EDM_OK) {
484         EDM_LOGE(MODULE_DEV_MGR, "unload failed");
485     }
486 }
487 
UnLoadSelf(void)488 void ExtDeviceManager::UnLoadSelf(void)
489 {
490     unloadSelftimer_.Unregister(unloadSelftimerId_);
491     unloadSelftimer_.Shutdown();
492     if (GetTotalDeviceNum() != 0) {
493         EDM_LOGI(MODULE_DEV_MGR, "not need unload");
494         return;
495     }
496 
497     if (auto ret = unloadSelftimer_.Setup(); ret != Utils::TIMER_ERR_OK) {
498         EDM_LOGE(MODULE_DEV_MGR, "set up timer failed %{public}u", ret);
499         return;
500     }
501 
502     auto task = []() {
503         auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
504         if (samgrProxy == nullptr) {
505             EDM_LOGE(MODULE_DEV_MGR, "get samgr failed");
506             return;
507         }
508 
509         auto saObj = samgrProxy->CheckSystemAbility(HDF_EXTERNAL_DEVICE_MANAGER_SA_ID);
510         if (saObj == nullptr) {
511             EDM_LOGE(MODULE_DEV_MGR, "sa has unloaded");
512             return;
513         }
514 
515         auto ret = samgrProxy->UnloadSystemAbility(HDF_EXTERNAL_DEVICE_MANAGER_SA_ID);
516         if (ret != EDM_OK) {
517             EDM_LOGE(MODULE_DEV_MGR, "unload failed");
518         }
519     };
520     unloadSelftimerId_ = unloadSelftimer_.Register(task, UNLOAD_SA_TIMER_INTERVAL, true);
521 }
522 
QueryDeviceByDeviceID(uint64_t deviceId)523 std::shared_ptr<Device> ExtDeviceManager::QueryDeviceByDeviceID(uint64_t deviceId)
524 {
525     BusType busType = *reinterpret_cast<BusType *>(&deviceId);
526     EDM_LOGI(MODULE_DEV_MGR, "the busType: %{public}d", static_cast<uint32_t>(busType));
527     auto deviceMapIter = deviceMap_.find(busType);
528     if (deviceMapIter == deviceMap_.end()) {
529         EDM_LOGE(MODULE_DEV_MGR, "can not find device by %{public}d busType", static_cast<uint32_t>(busType));
530         return nullptr;
531     }
532 
533     const auto &devices = deviceMapIter->second;
534     auto deviceIter = devices.find(deviceId);
535     if (deviceIter == devices.end()) {
536         EDM_LOGE(MODULE_DEV_MGR, "can not find device by %{public}016" PRIX64 " deviceId", deviceId);
537         return nullptr;
538     }
539 
540     EDM_LOGI(MODULE_DEV_MGR, "find device by %{public}016" PRIX64 " deviceId sucessfully", deviceId);
541     return deviceIter->second;
542 }
543 
ConnectDevice(uint64_t deviceId,const sptr<IDriverExtMgrCallback> & connectCallback)544 int32_t ExtDeviceManager::ConnectDevice(uint64_t deviceId, const sptr<IDriverExtMgrCallback> &connectCallback)
545 {
546     // find device by deviceId
547     lock_guard<mutex> lock(deviceMapMutex_);
548     std::shared_ptr<Device> device = QueryDeviceByDeviceID(deviceId);
549     if (device == nullptr) {
550         EDM_LOGI(MODULE_DEV_MGR, "failed to find device with %{public}016" PRIX64 " deviceId", deviceId);
551         return EDM_NOK;
552     }
553     return device->Connect(connectCallback);
554 }
555 
DisConnectDevice(uint64_t deviceId)556 int32_t ExtDeviceManager::DisConnectDevice(uint64_t deviceId)
557 {
558     lock_guard<mutex> lock(deviceMapMutex_);
559     std::shared_ptr<Device> device = QueryDeviceByDeviceID(deviceId);
560     if (device == nullptr) {
561         EDM_LOGI(MODULE_DEV_MGR, "failed to find device with %{public}016" PRIX64 " deviceId", deviceId);
562         return EDM_NOK;
563     }
564 
565     return device->Disconnect();
566 }
567 } // namespace ExternalDeviceManager
568 } // namespace OHOS