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