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 #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     // start ability
92     int32_t ret = device->Connect();
93     if (ret != EDM_OK) {
94         EDM_LOGE(MODULE_DEV_MGR,
95             "deviceId[%{public}016" PRIX64 "] connect driver extension ability[%{public}s] failed[%{public}d]",
96             deviceId, Device::GetAbilityName(bundleInfo).c_str(), ret);
97         return EDM_NOK;
98     }
99     PrintMatchDriverMap();
100     return EDM_OK;
101 }
102 
RemoveDevIdOfBundleInfoMap(shared_ptr<Device> device,string & bundleInfo)103 int32_t ExtDeviceManager::RemoveDevIdOfBundleInfoMap(shared_ptr<Device> device, string &bundleInfo)
104 {
105     if (bundleInfo.empty() || device == nullptr) {
106         EDM_LOGE(MODULE_DEV_MGR, "bundleInfo or device is null");
107         return EDM_ERR_INVALID_PARAM;
108     }
109 
110     // update bundle info
111     lock_guard<mutex> lock(bundleMatchMapMutex_);
112     auto pos = bundleMatchMap_.find(bundleInfo);
113     if (pos == bundleMatchMap_.end()) {
114         EDM_LOGI(MODULE_DEV_MGR, "not find bundleInfo from map");
115         return EDM_OK;
116     }
117 
118     // If the number of devices is greater than one, only the device erase
119     uint64_t deviceId = device->GetDeviceInfo()->GetDeviceId();
120     if (pos->second.size() > 1) {
121         pos->second.erase(deviceId);
122         EDM_LOGD(MODULE_DEV_MGR, "bundleMap existed driver, remove deviceId %{public}016" PRIX64 "", deviceId);
123         PrintMatchDriverMap();
124         return EDM_OK;
125     }
126 
127     EDM_LOGD(MODULE_DEV_MGR, "bundleMap remove bundleInfo[%{public}s]", bundleInfo.c_str());
128     bundleMatchMap_.erase(pos);
129 
130     // stop ability and destory sa
131     int32_t ret = device->Disconnect();
132     if (ret != EDM_OK) {
133         EDM_LOGE(MODULE_DEV_MGR,
134             "deviceId[%{public}016" PRIX64 "] disconnect driver extension ability[%{public}s] failed[%{public}d]",
135             deviceId, Device::GetAbilityName(bundleInfo).c_str(), ret);
136         return ret;
137     }
138     PrintMatchDriverMap();
139     return EDM_OK;
140 }
141 
RemoveDeviceOfDeviceMap(shared_ptr<Device> device)142 void ExtDeviceManager::RemoveDeviceOfDeviceMap(shared_ptr<Device> device)
143 {
144     EDM_LOGI(MODULE_DEV_MGR, "RemoveDeviceOfDeviceMap enter");
145     shared_ptr<DeviceInfo> deviceInfo = device->GetDeviceInfo();
146     if (deviceInfo == nullptr) {
147         EDM_LOGE(MODULE_DEV_MGR, "device info is null");
148         return;
149     }
150     BusType type = deviceInfo->GetBusType();
151     uint64_t deviceId = deviceInfo->GetDeviceId();
152 
153     lock_guard<mutex> lock(deviceMapMutex_);
154     if (deviceMap_.find(type) != deviceMap_.end()) {
155         unordered_map<uint64_t, shared_ptr<Device>> &map = deviceMap_[type];
156         map.erase(deviceId);
157         EDM_LOGI(MODULE_DEV_MGR, "success RemoveDeviceOfDeviceMap, deviceId:%{public}016" PRIx64 "", deviceId);
158     }
159 }
160 
DeleteBundlesOfBundleInfoMap(const std::string & bundleName)161 std::unordered_set<uint64_t> ExtDeviceManager::DeleteBundlesOfBundleInfoMap(const std::string &bundleName)
162 {
163     EDM_LOGD(MODULE_DEV_MGR, "DeleteBundlesOfBundleInfoMap enter");
164     std::unordered_set<uint64_t> deviceIds;
165     lock_guard<mutex> lock(bundleMatchMapMutex_);
166     if (bundleName.empty()) {
167         bundleMatchMap_.clear();
168     } else {
169         std::string startStr = bundleName + Device::GetStiching();
170         for (auto iter = bundleMatchMap_.begin(); iter != bundleMatchMap_.end();) {
171             if (startStr.compare(iter->first.substr(0, startStr.size())) == 0) {
172                 deviceIds.insert(iter->second.begin(), iter->second.end());
173                 iter = bundleMatchMap_.erase(iter);
174             } else {
175                 iter++;
176             }
177         }
178     }
179     return deviceIds;
180 }
181 
MatchDriverInfos(std::unordered_set<uint64_t> deviceIds,bool isDriversReset)182 void ExtDeviceManager::MatchDriverInfos(std::unordered_set<uint64_t> deviceIds, bool isDriversReset)
183 {
184     EDM_LOGI(MODULE_DEV_MGR, "MatchDriverInfos enter");
185     lock_guard<mutex> lock(deviceMapMutex_);
186     for (auto &m : deviceMap_) {
187         for (auto &[deviceId, device] : m.second) {
188             if (isDriversReset) {
189                 device->RemoveBundleInfo();
190                 device->ClearDrvExtRemote();
191             }
192             if (deviceIds.find(deviceId) != deviceIds.end()) {
193                 device->RemoveBundleInfo();
194             }
195             if (device->IsUnRegisted() || device->GetDrvExtRemote() != nullptr) {
196                 continue;
197             }
198             auto bundleInfoNames = DriverPkgManager::GetInstance().QueryMatchDriver(device->GetDeviceInfo());
199             if (bundleInfoNames == nullptr) {
200                 EDM_LOGD(MODULE_DEV_MGR, "deviceId[%{public}016" PRIX64 "], not find driver", deviceId);
201                 continue;
202             }
203             std::string bundleInfo = bundleInfoNames->bundleName + Device::GetStiching() + bundleInfoNames->abilityName;
204             EDM_LOGI(MODULE_DEV_MGR, "MatchDriverInfo success, bundleInfo: %{public}s", bundleInfo.c_str());
205             device->AddBundleInfo(bundleInfo, bundleInfoNames->driverUid);
206             int32_t ret = AddDevIdOfBundleInfoMap(device, bundleInfo);
207             if (ret != EDM_OK) {
208                 EDM_LOGD(MODULE_DEV_MGR,
209                     "deviceId[%{public}016" PRIX64 "] AddDevIdOfBundleInfoMap failed, ret=%{public}d", deviceId, ret);
210             }
211         }
212     }
213 }
214 
ClearMatchedDrivers(const int32_t userId)215 void ExtDeviceManager::ClearMatchedDrivers(const int32_t userId)
216 {
217     EDM_LOGI(MODULE_DEV_MGR, "ClearMatchedDrivers start");
218     lock_guard<mutex> lock(bundleMatchMapMutex_);
219     for (auto iter : bundleMatchMap_) {
220         std::string bundleInfo = iter.first;
221         (void)DriverExtensionController::GetInstance().StopDriverExtension(Device::GetBundleName(bundleInfo),
222             Device::GetAbilityName(bundleInfo), userId);
223     }
224     bundleMatchMap_.clear();
225 }
226 
RegisterDevice(shared_ptr<DeviceInfo> devInfo)227 int32_t ExtDeviceManager::RegisterDevice(shared_ptr<DeviceInfo> devInfo)
228 {
229     BusType type = devInfo->GetBusType();
230     uint64_t deviceId = devInfo->GetDeviceId();
231     shared_ptr<Device> device;
232     lock_guard<mutex> lock(deviceMapMutex_);
233     if (deviceMap_.find(type) != deviceMap_.end()) {
234         unordered_map<uint64_t, shared_ptr<Device>> &map = deviceMap_[type];
235         if (map.find(deviceId) != map.end() && map[deviceId] != nullptr) {
236             device = map.find(deviceId)->second;
237             // device has been registered and do not need to connect again
238             if (device->GetDrvExtRemote() != nullptr) {
239                 EDM_LOGI(MODULE_DEV_MGR, "device has been registered, deviceId is %{public}016" PRIx64 "", deviceId);
240                 return EDM_OK;
241             }
242             // device has been registered and need to connect
243             EDM_LOGI(MODULE_DEV_MGR, "device has been registered, deviceId is %{public}016" PRIx64 "", deviceId);
244         }
245     } else {
246         EDM_LOGI(MODULE_DEV_MGR, "emplace Type of deviceMap_");
247         deviceMap_.emplace(type, unordered_map<uint64_t, shared_ptr<Device>>());
248     }
249     EDM_LOGD(MODULE_DEV_MGR, "begin to register device, deviceId is %{public}016" PRIx64 "", deviceId);
250     // device need to register
251     if (device == nullptr) {
252         device = make_shared<Device>(devInfo);
253         deviceMap_[type].emplace(deviceId, device);
254         EDM_LOGI(MODULE_DEV_MGR, "successfully registered device, deviceId = %{public}016" PRIx64 "", deviceId);
255     }
256     // driver match
257     std::string bundleInfo = device->GetBundleInfo();
258     // if device does not have a matching driver, match driver here
259     if (bundleInfo.empty()) {
260         auto bundleInfoNames = DriverPkgManager::GetInstance().QueryMatchDriver(devInfo);
261         if (bundleInfoNames != nullptr) {
262             bundleInfo = bundleInfoNames->bundleName + Device::GetStiching() + bundleInfoNames->abilityName;
263             device->AddBundleInfo(bundleInfo, bundleInfoNames->driverUid);
264         }
265     }
266     unloadSelftimer_.Unregister(unloadSelftimerId_);
267 
268     // match driver failed, waitting to install driver package
269     if (bundleInfo.empty()) {
270         EDM_LOGD(MODULE_DEV_MGR,
271             "deviceId %{public}016" PRIX64 "match driver failed, waitting to install ext driver package", deviceId);
272         return EDM_OK;
273     }
274 
275     int32_t ret = AddDevIdOfBundleInfoMap(device, bundleInfo);
276     if (ret != EDM_OK) {
277         EDM_LOGE(MODULE_DEV_MGR, "deviceId[%{public}016" PRIX64 "] update bundle info map failed[%{public}d]", deviceId,
278             ret);
279         return EDM_NOK;
280     }
281     EDM_LOGI(MODULE_DEV_MGR, "successfully match driver[%{public}s], deviceId is %{public}016" PRIx64 "",
282         bundleInfo.c_str(), deviceId);
283 
284     return ret;
285 }
286 
UnRegisterDevice(const shared_ptr<DeviceInfo> devInfo)287 int32_t ExtDeviceManager::UnRegisterDevice(const shared_ptr<DeviceInfo> devInfo)
288 {
289     BusType type = devInfo->GetBusType();
290     uint64_t deviceId = devInfo->GetDeviceId();
291     shared_ptr<Device> device;
292     string bundleInfo;
293 
294     lock_guard<mutex> lock(deviceMapMutex_);
295     if (deviceMap_.find(type) != deviceMap_.end()) {
296         unordered_map<uint64_t, shared_ptr<Device>> &map = deviceMap_[type];
297         if (map.find(deviceId) != map.end()) {
298             device = map[deviceId];
299             bundleInfo = map[deviceId]->GetBundleInfo();
300             if (device != nullptr && device->GetDrvExtRemote() != nullptr) {
301                 device->UnRegist();
302             } else {
303                 map.erase(deviceId);
304             }
305             EDM_LOGI(MODULE_DEV_MGR, "successfully unregistered device, deviceId is %{public}016" PRIx64 "", deviceId);
306             UnLoadSelf();
307         }
308     }
309 
310     if (bundleInfo.empty()) {
311         EDM_LOGI(MODULE_DEV_MGR, "deviceId %{public}016" PRIX64 " bundleInfo is empty", deviceId);
312         return EDM_OK;
313     }
314 
315     int32_t ret = RemoveDevIdOfBundleInfoMap(device, bundleInfo);
316     if (ret != EDM_OK) {
317         EDM_LOGE(
318             MODULE_DEV_MGR, "deviceId[%{public}016" PRIX64 "] remove bundleInfo map failed[%{public}d]", deviceId, ret);
319         return ret;
320     }
321 
322     EDM_LOGI(MODULE_DEV_MGR, "successfully remove bundleInfo, deviceId %{public}016" PRIx64 ", bundleInfo[%{public}s]",
323         deviceId, bundleInfo.c_str());
324 
325     return EDM_OK;
326 }
327 
QueryDevice(const BusType busType)328 vector<shared_ptr<DeviceInfo>> ExtDeviceManager::QueryDevice(const BusType busType)
329 {
330     vector<shared_ptr<DeviceInfo>> devInfoVec;
331 
332     lock_guard<mutex> lock(deviceMapMutex_);
333     if (deviceMap_.find(busType) == deviceMap_.end()) {
334         EDM_LOGE(MODULE_DEV_MGR, "no device is found and busType %{public}d is invalid", busType);
335         return devInfoVec;
336     }
337 
338     unordered_map<uint64_t, shared_ptr<Device>> map = deviceMap_[busType];
339     for (auto &[_, device] : map) {
340         if (device != nullptr && !device->IsUnRegisted()) {
341             devInfoVec.emplace_back(device->GetDeviceInfo());
342         }
343     }
344     EDM_LOGD(MODULE_DEV_MGR, "find %{public}zu device of busType %{public}d", devInfoVec.size(), busType);
345 
346     return devInfoVec;
347 }
348 
QueryAllDevices()349 vector<shared_ptr<Device>> ExtDeviceManager::QueryAllDevices()
350 {
351     vector<shared_ptr<Device>> devices;
352     lock_guard<mutex> lock(deviceMapMutex_);
353 
354     for (auto &m : deviceMap_) {
355         for (auto &[_, device] : m.second) {
356             if (device != nullptr && !device->IsUnRegisted()) {
357                 devices.emplace_back(device);
358             }
359         }
360     }
361 
362     return devices;
363 }
364 
QueryDevicesById(const uint64_t deviceId)365 vector<shared_ptr<Device>> ExtDeviceManager::QueryDevicesById(const uint64_t deviceId)
366 {
367     vector<shared_ptr<Device>> devices;
368     lock_guard<mutex> lock(deviceMapMutex_);
369 
370     for (auto &m : deviceMap_) {
371         for (auto &[id, device] : m.second) {
372             if (deviceId == id && device != nullptr && !device->IsUnRegisted()) {
373                 devices.emplace_back(device);
374             }
375         }
376     }
377 
378     return devices;
379 }
380 
381 
GetTotalDeviceNum(void) const382 size_t ExtDeviceManager::GetTotalDeviceNum(void) const
383 {
384     // Please do not add lock. This will be called in the UnRegisterDevice.
385     size_t totalNum = 0;
386     for (auto &m : deviceMap_) {
387         for (auto &[_, device] : m.second) {
388             if (!device->IsUnRegisted()) {
389                 totalNum++;
390             }
391         }
392     }
393     EDM_LOGD(MODULE_DEV_MGR, "total device num is %{public}zu", totalNum);
394     return totalNum;
395 }
396 
UnLoadSA(void)397 void ExtDeviceManager::UnLoadSA(void)
398 {
399     EDM_LOGI(MODULE_DEV_MGR, "UnLoadSA enter");
400     if (GetTotalDeviceNum() != 0) {
401         EDM_LOGI(MODULE_DEV_MGR, "not need unload");
402         return;
403     }
404     auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
405     if (samgrProxy == nullptr) {
406         EDM_LOGE(MODULE_DEV_MGR, "get samgr failed");
407         return;
408     }
409 
410     auto saObj = samgrProxy->CheckSystemAbility(HDF_EXTERNAL_DEVICE_MANAGER_SA_ID);
411     if (saObj == nullptr) {
412         EDM_LOGE(MODULE_DEV_MGR, "sa has unloaded");
413         return;
414     }
415 
416     auto ret = samgrProxy->UnloadSystemAbility(HDF_EXTERNAL_DEVICE_MANAGER_SA_ID);
417     if (ret != EDM_OK) {
418         EDM_LOGE(MODULE_DEV_MGR, "unload failed");
419     }
420 }
421 
UnLoadSelf(void)422 void ExtDeviceManager::UnLoadSelf(void)
423 {
424     unloadSelftimer_.Unregister(unloadSelftimerId_);
425     unloadSelftimer_.Shutdown();
426     if (GetTotalDeviceNum() != 0) {
427         EDM_LOGI(MODULE_DEV_MGR, "not need unload");
428         return;
429     }
430 
431     if (auto ret = unloadSelftimer_.Setup(); ret != Utils::TIMER_ERR_OK) {
432         EDM_LOGE(MODULE_DEV_MGR, "set up timer failed %{public}u", ret);
433         return;
434     }
435 
436     auto task = []() {
437         auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
438         if (samgrProxy == nullptr) {
439             EDM_LOGE(MODULE_DEV_MGR, "get samgr failed");
440             return;
441         }
442 
443         auto saObj = samgrProxy->CheckSystemAbility(HDF_EXTERNAL_DEVICE_MANAGER_SA_ID);
444         if (saObj == nullptr) {
445             EDM_LOGE(MODULE_DEV_MGR, "sa has unloaded");
446             return;
447         }
448 
449         auto ret = samgrProxy->UnloadSystemAbility(HDF_EXTERNAL_DEVICE_MANAGER_SA_ID);
450         if (ret != EDM_OK) {
451             EDM_LOGE(MODULE_DEV_MGR, "unload failed");
452         }
453     };
454     unloadSelftimerId_ = unloadSelftimer_.Register(task, UNLOAD_SA_TIMER_INTERVAL, true);
455 }
456 
QueryDeviceByDeviceID(uint64_t deviceId)457 std::shared_ptr<Device> ExtDeviceManager::QueryDeviceByDeviceID(uint64_t deviceId)
458 {
459     BusType busType = *reinterpret_cast<BusType *>(&deviceId);
460     EDM_LOGI(MODULE_DEV_MGR, "the busType: %{public}d", static_cast<uint32_t>(busType));
461     auto deviceMapIter = deviceMap_.find(busType);
462     if (deviceMapIter == deviceMap_.end()) {
463         EDM_LOGE(MODULE_DEV_MGR, "can not find device by %{public}d busType", static_cast<uint32_t>(busType));
464         return nullptr;
465     }
466 
467     const auto &devices = deviceMapIter->second;
468     auto deviceIter = devices.find(deviceId);
469     if (deviceIter == devices.end()) {
470         EDM_LOGE(MODULE_DEV_MGR, "can not find device by %{public}016" PRIX64 " deviceId", deviceId);
471         return nullptr;
472     }
473 
474     EDM_LOGI(MODULE_DEV_MGR, "find device by %{public}016" PRIX64 " deviceId sucessfully", deviceId);
475     return deviceIter->second;
476 }
477 
ConnectDevice(uint64_t deviceId,const sptr<IDriverExtMgrCallback> & connectCallback)478 int32_t ExtDeviceManager::ConnectDevice(uint64_t deviceId, const sptr<IDriverExtMgrCallback> &connectCallback)
479 {
480     // find device by deviceId
481     lock_guard<mutex> lock(deviceMapMutex_);
482     std::shared_ptr<Device> device = QueryDeviceByDeviceID(deviceId);
483     if (device == nullptr) {
484         EDM_LOGI(MODULE_DEV_MGR, "failed to find device with %{public}016" PRIX64 " deviceId", deviceId);
485         return EDM_NOK;
486     }
487     return device->Connect(connectCallback);
488 }
489 
DisConnectDevice(uint64_t deviceId)490 int32_t ExtDeviceManager::DisConnectDevice(uint64_t deviceId)
491 {
492     lock_guard<mutex> lock(deviceMapMutex_);
493     std::shared_ptr<Device> device = QueryDeviceByDeviceID(deviceId);
494     if (device == nullptr) {
495         EDM_LOGI(MODULE_DEV_MGR, "failed to find device with %{public}016" PRIX64 " deviceId", deviceId);
496         return EDM_NOK;
497     }
498 
499     return device->Disconnect();
500 }
501 } // namespace ExternalDeviceManager
502 } // namespace OHOS