diff --git a/bundle.json b/bundle.json index 6791f166847bf51c4eebf54eb00942d4f0f6d2d0..d05e8acb2bd64d6f2c3c3bcde837daf98af4a414 100644 --- a/bundle.json +++ b/bundle.json @@ -61,7 +61,7 @@ ], "inner_kits": [], "test": [ - "//drivers/external_device_manager/test/unittest:external_device_manager_test", + "//drivers/external_device_manager/test/unittest:external_device_manager_ut", "//drivers/external_device_manager/test/unittest/driver_extension_context_test:driver_extension_context_test", "//drivers/external_device_manager/test/fuzztest:fuzztest", "//drivers/external_device_manager/test//moduletest/:external_device_manager_mt" diff --git a/services/native/driver_extension_manager/include/device_manager/etx_device_mgr.h b/services/native/driver_extension_manager/include/device_manager/etx_device_mgr.h index e044c86ec02b27a921b2cd937662fa4bc09ac0c8..0369cf71e28388e21cc25151d24853f073a0fae9 100644 --- a/services/native/driver_extension_manager/include/device_manager/etx_device_mgr.h +++ b/services/native/driver_extension_manager/include/device_manager/etx_device_mgr.h @@ -18,24 +18,46 @@ #include #include #include +#include + #include "ext_object.h" #include "single_instance.h" namespace OHOS { namespace ExternalDeviceManager { +using namespace std; + class Device final { public: - Device(std::shared_ptr info) : info_(info) {}; + Device(shared_ptr info) : info_(info) {}; + bool HasDriver() const + { + return !bundleInfo_.empty(); + }; - bool HasDriver() const; - std::shared_ptr GetDeviceInfo() const + shared_ptr GetDeviceInfo() const { return info_; } + void AddBundleInfo(const string &bundleInfo) + { + bundleInfo_ = bundleInfo; + } + + void RemoveBundleInfo() + { + bundleInfo_.clear(); + } + + string GetBundleInfo() const + { + return bundleInfo_; + } private: - std::shared_ptr driver_; - std::shared_ptr info_; + string bundleInfo_; + shared_ptr driver_; + shared_ptr info_; }; class ExtDeviceManager final { @@ -43,14 +65,27 @@ class ExtDeviceManager final { public: ~ExtDeviceManager() = default; int32_t Init(); - int32_t RegisterDevice(std::shared_ptr devInfo); - int32_t UnRegisterDevice(const std::shared_ptr devInfo); - std::vector> QueryDevice(const BusType busType); - + int32_t RegisterDevice(shared_ptr devInfo); + int32_t UnRegisterDevice(const shared_ptr devInfo); + vector> QueryDevice(const BusType busType); + static int32_t UpdateBundleStatusCallback(int32_t bundleStatus, int32_t busType, + const string &bundleName, const string &abilityName); private: ExtDeviceManager() = default; - std::unordered_map>> deviceMap_; - std::mutex deviceMapMutex_; + void PrintMatchDriverMap(); + string GetBundleName(string &bundleInfo) const; + string GetAbilityName(string &bundleInfo) const; + int32_t AddDevIdOfBundleInfoMap(uint64_t deviceId, string &bundleInfo); + int32_t RemoveDevIdOfBundleInfoMap(uint64_t deviceId, string &bundleInfo); + int32_t RemoveAllDevIdOfBundleInfoMap(string &bundleInfo); + int32_t AddBundleInfo(enum BusType busType, const string &bundleName, const string &abilityName); + int32_t RemoveBundleInfo(enum BusType busType, const string &bundleName, const string &abilityName); + int32_t UpdateBundleInfo(enum BusType busType, const string &bundleName, const string &abilityName); + string stiching_ = "_stiching_"; + unordered_map>> deviceMap_; + unordered_map> bundleMatchMap_; // driver matching table + mutex deviceMapMutex_; + mutex bundleMatchMapMutex_; }; } // namespace ExternalDeviceManager } // namespace OHOS diff --git a/services/native/driver_extension_manager/src/device_manager/BUILD.gn b/services/native/driver_extension_manager/src/device_manager/BUILD.gn index 587a9e0b7dd7829f282d58e405ce00f3ebce20d6..43f070dfd19f1c069806d558d0a59757f295114f 100644 --- a/services/native/driver_extension_manager/src/device_manager/BUILD.gn +++ b/services/native/driver_extension_manager/src/device_manager/BUILD.gn @@ -38,7 +38,10 @@ ohos_shared_library("driver_extension_device_manager") { "${ext_mgr_path}/services/native/driver_extension_manager/include/drivers_pkg_manager", ] configs = [ "${utils_path}:utils_config" ] - deps = [ "${ext_mgr_path}/services/native/driver_extension_manager/src/drivers_pkg_manager:drivers_pkg_manager" ] + deps = [ + "${ext_mgr_path}/services/native/driver_extension_manager/src/driver_controller:driver_extension_controller", + "${ext_mgr_path}/services/native/driver_extension_manager/src/drivers_pkg_manager:drivers_pkg_manager", + ] external_deps = [ "bundle_framework:appexecfwk_core", "c_utils:utils", diff --git a/services/native/driver_extension_manager/src/device_manager/etx_device_mgr.cpp b/services/native/driver_extension_manager/src/device_manager/etx_device_mgr.cpp index 86c9f4390b725c047269ce7bb700b6b1134066c8..c95896f399ce414db5384836033388227eb7fdff 100644 --- a/services/native/driver_extension_manager/src/device_manager/etx_device_mgr.cpp +++ b/services/native/driver_extension_manager/src/device_manager/etx_device_mgr.cpp @@ -15,68 +15,374 @@ #include "etx_device_mgr.h" #include "cinttypes" +#include "driver_extension_controller.h" #include "driver_pkg_manager.h" #include "edm_errors.h" #include "hilog_wrapper.h" + namespace OHOS { namespace ExternalDeviceManager { IMPLEMENT_SINGLE_INSTANCE(ExtDeviceManager); +void ExtDeviceManager::PrintMatchDriverMap() +{ + if (!bundleMatchMap_.empty()) { + EDM_LOGD(MODULE_DEV_MGR, " bundleInfo map size[%{public}zu]", bundleMatchMap_.size()); + for (auto iter : bundleMatchMap_) { + for (auto iterId = iter.second.begin(); iterId != iter.second.end(); ++iterId) { + uint64_t deviceId = *iterId; + EDM_LOGD(MODULE_DEV_MGR, "print match map info[%{public}s], deviceId %{public}016" PRIX64 "", + iter.first.c_str(), deviceId); + } + } + EDM_LOGD(MODULE_DEV_MGR, "ExtDeviceManager print driver match map success"); + } +} + int32_t ExtDeviceManager::Init() { - EDM_LOGD(MODULE_DEV_MGR, "ExtDeviceManager Init start"); + EDM_LOGD(MODULE_DEV_MGR, "ExtDeviceManager Init success"); + return EDM_OK; +} + +string ExtDeviceManager::GetBundleName(string &bundleInfo) const +{ + string::size_type pos = bundleInfo.find(stiching_); + if (pos == string::npos) { + EDM_LOGI(MODULE_DEV_MGR, "bundleInfo not find stiching name"); + return ""; + } + + return bundleInfo.substr(0, pos); +} + +string ExtDeviceManager::GetAbilityName(string &bundleInfo) const +{ + string::size_type pos = bundleInfo.find(stiching_); + if (pos == string::npos) { + EDM_LOGI(MODULE_DEV_MGR, "bundleInfo not find stiching name"); + return ""; + } + + return bundleInfo.substr(pos + stiching_.length()); +} + +int32_t ExtDeviceManager::AddDevIdOfBundleInfoMap(uint64_t deviceId, string &bundleInfo) +{ + if (bundleInfo.empty()) { + EDM_LOGE(MODULE_DEV_MGR, "bundleInfo is null"); + return EDM_NOK; + } + + // update bundle info + lock_guard lock(bundleMatchMapMutex_); + auto pos = bundleMatchMap_.find(bundleInfo); + if (pos == bundleMatchMap_.end()) { + unordered_set tmpSet; + tmpSet.emplace(deviceId); + bundleMatchMap_.emplace(bundleInfo, tmpSet); + EDM_LOGD(MODULE_DEV_MGR, "bundleMap emplace New driver, add deviceId %{public}016" PRIX64 "", deviceId); + } else { + auto pairRet = pos->second.emplace(deviceId); + // Check whether the deviceId matches the driver + if (!pairRet.second || pos->second.size() > 1) { + EDM_LOGD(MODULE_DEV_MGR, "bundleMap had existed driver, add deviceId %{public}016" PRIX64 "", deviceId); + PrintMatchDriverMap(); + return EDM_OK; + } + } + + PrintMatchDriverMap(); + return EDM_OK; +} + +int32_t ExtDeviceManager::RemoveDevIdOfBundleInfoMap(uint64_t deviceId, string &bundleInfo) +{ + if (bundleInfo.empty()) { + EDM_LOGE(MODULE_DEV_MGR, "bundleInfo is null"); + return EDM_NOK; + } + + // update bundle info + lock_guard lock(bundleMatchMapMutex_); + auto pos = bundleMatchMap_.find(bundleInfo); + if (pos == bundleMatchMap_.end()) { + EDM_LOGI(MODULE_DEV_MGR, "not find bundleInfo from map"); + return EDM_OK; + } + + // If the number of devices is greater than one, only the device erase + if (pos->second.size() > 1) { + pos->second.erase(deviceId); + EDM_LOGD(MODULE_DEV_MGR, "bundleMap existed driver, remove deviceId %{public}016" PRIX64 "", deviceId); + PrintMatchDriverMap(); + return EDM_OK; + } + + EDM_LOGD(MODULE_DEV_MGR, "bundleMap remove bundleInfo[%{public}s]", bundleInfo.c_str()); + bundleMatchMap_.erase(pos); + + PrintMatchDriverMap(); return EDM_OK; } -int32_t ExtDeviceManager::RegisterDevice(std::shared_ptr devInfo) +int32_t ExtDeviceManager::RemoveAllDevIdOfBundleInfoMap(string &bundleInfo) +{ + // update bundle info + lock_guard lock(bundleMatchMapMutex_); + auto pos = bundleMatchMap_.find(bundleInfo); + if (pos == bundleMatchMap_.end()) { + return EDM_OK; + } + + bundleMatchMap_.erase(pos); + + return EDM_OK; +} + +int32_t ExtDeviceManager::AddBundleInfo(enum BusType busType, const string &bundleName, const string &abilityName) +{ + if (busType <= BUS_TYPE_INVALID || busType > BUS_TYPE_TEST) { + EDM_LOGE(MODULE_DEV_MGR, "busType para invalid"); + return EDM_ERR_INVALID_PARAM; + } + + if (bundleName.empty() || abilityName.empty()) { + EDM_LOGE(MODULE_DEV_MGR, "BundleInfo para invalid"); + return EDM_ERR_INVALID_PARAM; + } + + // iterate over device, find bundleInfo and ability status + lock_guard lock(deviceMapMutex_); + + // find device + if (deviceMap_.count(busType) == 0) { + EDM_LOGD(MODULE_DEV_MGR, "deviceMap_ not bustype[%{public}d], wait to plug device", busType); + return EDM_OK; + } + + string bundleInfo = bundleName + stiching_ + abilityName; + unordered_map> &map = deviceMap_[busType]; + + for (auto iter : map) { + shared_ptr device = iter.second; + + // iterate over device by bustype + shared_ptr bundleInfoNames = make_shared(); + bundleInfoNames->bundleName = "bundle_name_test"; + bundleInfoNames->abilityName = "ability_name_test"; + + if (bundleName.compare(bundleInfoNames->bundleName) == 0 && + abilityName.compare(bundleInfoNames->abilityName) == 0) { + device->AddBundleInfo(bundleInfo); + int32_t ret = AddDevIdOfBundleInfoMap(device->GetDeviceInfo()->GetDeviceId(), bundleInfo); + if (ret != EDM_OK) { + EDM_LOGE(MODULE_DEV_MGR, + "deviceId[%{public}016" PRIX64 "] start driver extension ability[%{public}s] fail[%{public}d]", + device->GetDeviceInfo()->GetDeviceId(), GetAbilityName(bundleInfo).c_str(), ret); + } + } + } + + return EDM_OK; +} + +int32_t ExtDeviceManager::RemoveBundleInfo(enum BusType busType, const string &bundleName, const string &abilityName) +{ + if (busType <= BUS_TYPE_INVALID || busType >= BUS_TYPE_TEST) { + EDM_LOGE(MODULE_DEV_MGR, "busType para invalid"); + return EDM_ERR_INVALID_PARAM; + } + + if (bundleName.empty() || abilityName.empty()) { + EDM_LOGE(MODULE_DEV_MGR, "BundleInfo para invalid"); + return EDM_ERR_INVALID_PARAM; + } + + lock_guard lock(deviceMapMutex_); + if (deviceMap_.count(busType) == 0) { + EDM_LOGD(MODULE_DEV_MGR, "deviceMap_ not bustype[%{public}d], wait to plug device", busType); + return EDM_OK; + } + + // iterate over device, remove bundleInfo + string bundleInfo = bundleName + stiching_ + abilityName; + unordered_map> &deviceMap = deviceMap_[busType]; + + for (auto iter : deviceMap) { + shared_ptr device = iter.second; + + // iterate over device by bustype + if (bundleInfo.compare(device->GetBundleInfo()) == 0) { + device->RemoveBundleInfo(); // update device + int32_t ret = RemoveAllDevIdOfBundleInfoMap(bundleInfo); + if (ret != EDM_OK) { + EDM_LOGE(MODULE_DEV_MGR, + "deviceId[%{public}016" PRIX64 "] stop driver extension ability[%{public}s] fail[%{public}d]", + device->GetDeviceInfo()->GetDeviceId(), GetAbilityName(bundleInfo).c_str(), ret); + } + } + } + return EDM_OK; +} + +int32_t ExtDeviceManager::UpdateBundleInfo(enum BusType busType, const string &bundleName, const string &abilityName) +{ + // stop ability of device and reset bundleInfo of device + int32_t ret = RemoveBundleInfo(busType, bundleName, abilityName); + if (ret != EDM_OK) { + EDM_LOGE(MODULE_DEV_MGR, "remove bundle info fail"); + return EDM_NOK; + } + + // iterate over device, add bundleInfo and start ability + ret = AddBundleInfo(busType, bundleName, abilityName); + if (ret != EDM_OK) { + EDM_LOGE(MODULE_DEV_MGR, "add bundle info fail"); + return EDM_NOK; + } + + return EDM_OK; +} + +int32_t ExtDeviceManager::UpdateBundleStatusCallback(int32_t bundleStatus, int32_t busType, + const string &bundleName, const string &abilityName) +{ + int32_t ret = EDM_NOK; + if (bundleStatus < BUNDLE_ADDED || bundleStatus > BUNDLE_REMOVED) { + EDM_LOGE(MODULE_DEV_MGR, "bundleStatus para invalid"); + return EDM_ERR_INVALID_PARAM; + } + + // add bundle + if (bundleStatus == BUNDLE_ADDED) { + ret = ExtDeviceManager::GetInstance().AddBundleInfo((enum BusType)busType, bundleName, abilityName); + if (ret != EDM_OK) { + EDM_LOGE(MODULE_DEV_MGR, "callback add bundle info fail"); + } + return ret; + } + + // update bundle + if (bundleStatus == BUNDLE_UPDATED) { + ret = ExtDeviceManager::GetInstance().UpdateBundleInfo((enum BusType)busType, bundleName, abilityName); + if (ret != EDM_OK) { + EDM_LOGE(MODULE_DEV_MGR, "callback update bundle info fail"); + } + return ret; + } + + // remove bundle + ret = ExtDeviceManager::GetInstance().RemoveBundleInfo((enum BusType)busType, bundleName, abilityName); + if (ret != EDM_OK) { + EDM_LOGE(MODULE_DEV_MGR, "callback update bundle info fail"); + } + + return ret; +} + +int32_t ExtDeviceManager::RegisterDevice(shared_ptr devInfo) { BusType type = devInfo->GetBusType(); uint64_t deviceId = devInfo->GetDeviceId(); - std::lock_guard lock(deviceMapMutex_); + + lock_guard lock(deviceMapMutex_); if (deviceMap_.find(type) != deviceMap_.end()) { - std::unordered_map> &map = deviceMap_[type]; + unordered_map> &map = deviceMap_[type]; if (map.find(deviceId) != map.end()) { EDM_LOGI(MODULE_DEV_MGR, "device has been registered, deviceId is %{public}016" PRIx64 "", deviceId); return EDM_OK; } } - std::shared_ptr device = std::make_shared(devInfo); + EDM_LOGD(MODULE_DEV_MGR, "device begin register deviceId is %{public}016" PRIx64 "", deviceId); + + // driver match + shared_ptr bundleInfoNames = make_shared(); + bundleInfoNames->bundleName = "bundle_name_test"; + bundleInfoNames->abilityName = "ability_name_test"; + + // add device + shared_ptr device = make_shared(devInfo); + string bundleInfo; + + // add bundle info + if (bundleInfoNames != nullptr) { + bundleInfo = bundleInfoNames->bundleName + stiching_ + bundleInfoNames->abilityName; + device->AddBundleInfo(bundleInfo); + } + deviceMap_[type].emplace(deviceId, device); - EDM_LOGD(MODULE_DEV_MGR, "successfully registered device, deviceId is %{public}016" PRIx64 "", deviceId); - DriverPkgManager::GetInstance(); - return EDM_OK; + EDM_LOGD(MODULE_DEV_MGR, "successfully registered device, deviceId = %{public}016" PRIx64 "", deviceId); + + // not match driver, waitting install driver + if (bundleInfo.empty()) { + EDM_LOGD(MODULE_DEV_MGR, "deviceId %{public}016" PRIX64 "not match driver, waitting for install ext driver", + deviceId); + return EDM_OK; + } + + int32_t ret = AddDevIdOfBundleInfoMap(deviceId, bundleInfo); + if (ret != EDM_OK) { + EDM_LOGE(MODULE_DEV_MGR, "deviceId[%{public}016" PRIX64 "] update bundle info map failed[%{public}d]", + deviceId, ret); + return EDM_NOK; + } + EDM_LOGD(MODULE_DEV_MGR, "successfully match driver[%{public}s], deviceId is %{public}016" PRIx64 "", + bundleInfo.c_str(), deviceId); + + return ret; } -int32_t ExtDeviceManager::UnRegisterDevice(const std::shared_ptr devInfo) +int32_t ExtDeviceManager::UnRegisterDevice(const shared_ptr devInfo) { BusType type = devInfo->GetBusType(); uint64_t deviceId = devInfo->GetDeviceId(); - std::lock_guard lock(deviceMapMutex_); + string bundleInfo; + + lock_guard lock(deviceMapMutex_); if (deviceMap_.find(type) != deviceMap_.end()) { - std::unordered_map> &map = deviceMap_[type]; + unordered_map> &map = deviceMap_[type]; if (map.find(deviceId) != map.end()) { + bundleInfo = map[deviceId]->GetBundleInfo(); map.erase(deviceId); EDM_LOGI(MODULE_DEV_MGR, "successfully unregistered device, deviceId is %{public}016" PRIx64 "", deviceId); - return EDM_OK; } } - EDM_LOGD(MODULE_DEV_MGR, "device has been unregistered, deviceId is %{public}016" PRIx64 "", deviceId); + + if (bundleInfo.empty()) { + EDM_LOGD(MODULE_DEV_MGR, "deviceId %{public}016" PRIX64 "not find device", deviceId); + return EDM_OK; + } + + int32_t ret = RemoveDevIdOfBundleInfoMap(deviceId, bundleInfo); + if (ret != EDM_OK) { + EDM_LOGE(MODULE_DEV_MGR, "deviceId[%{public}016" PRIX64 "] remove bundleInfo map failed[%{public}d]", + deviceId, ret); + return ret; + } + + EDM_LOGI(MODULE_DEV_MGR, "successfully remove bundleInfo, deviceId %{public}016" PRIx64 ", bundleInfo[%{public}s]", + deviceId, bundleInfo.c_str()); + return EDM_OK; } -std::vector> ExtDeviceManager::QueryDevice(const BusType busType) +vector> ExtDeviceManager::QueryDevice(const BusType busType) { - std::vector> devInfoVec; - std::lock_guard lock(deviceMapMutex_); + vector> devInfoVec; + + lock_guard lock(deviceMapMutex_); if (deviceMap_.find(busType) == deviceMap_.end()) { - EDM_LOGE(MODULE_DEV_MGR, "no device is found or busType %{public}d is invalid", busType); + EDM_LOGE(MODULE_DEV_MGR, "no device is found and busType %{public}d is invalid", busType); return devInfoVec; } - std::unordered_map> map = deviceMap_[busType]; + + unordered_map> map = deviceMap_[busType]; for (auto device : map) { - devInfoVec.push_back(device.second->GetDeviceInfo()); + devInfoVec.emplace_back(device.second->GetDeviceInfo()); } EDM_LOGD(MODULE_DEV_MGR, "find %{public}zu device of busType %{public}d", devInfoVec.size(), busType); + return devInfoVec; } } // namespace ExternalDeviceManager diff --git a/services/native/driver_extension_manager/src/driver_etx_mgr.cpp b/services/native/driver_extension_manager/src/driver_etx_mgr.cpp index 7b0272b28c29771edc271bbf1c2e344eae74c850..8f413cf09ff47bb4f621826751e771eabf1557c5 100644 --- a/services/native/driver_extension_manager/src/driver_etx_mgr.cpp +++ b/services/native/driver_extension_manager/src/driver_etx_mgr.cpp @@ -33,11 +33,21 @@ DriverExtMgr::~DriverExtMgr() {} void DriverExtMgr::OnStart() { + int32_t ret; EDM_LOGI(MODULE_SERVICE, "hdf_ext_devmgr OnStart"); - DriverPkgManager::GetInstance().Init(); - ExtDeviceManager::GetInstance().Init(); + ret = DriverPkgManager::GetInstance().Init(); + if (ret != EDM_OK) { + EDM_LOGE(MODULE_SERVICE, "DriverPkgManager Init failed %{public}d", ret); + } + ret = ExtDeviceManager::GetInstance().Init(); + if (ret != EDM_OK) { + EDM_LOGE(MODULE_SERVICE, "ExtDeviceManager Init failed %{public}d", ret); + } std::shared_ptr callback = std::make_shared(); - BusExtensionCore::GetInstance().Init(callback); + ret = BusExtensionCore::GetInstance().Init(callback); + if (ret != EDM_OK) { + EDM_LOGE(MODULE_SERVICE, "BusExtensionCore Init failed %{public}d", ret); + } } void DriverExtMgr::OnStop() diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index ca3210379cc78a23fdb2aea9f69380f3062d613f..ec9f6f7c70bc908dd16b0d9eeb8cf6de55f0135b 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -97,7 +97,7 @@ ohos_unittest("drivers_pkg_manager_test") { configs = [ "${utils_path}:utils_config" ] } -group("external_device_manager_test") { +group("external_device_manager_ut") { testonly = true deps = [ ":bus_extension_test",