1 /* 2 * Copyright (c) 2021-2024 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 "local_hardware_manager.h" 17 18 #include <unistd.h> 19 20 #include "anonymous_string.h" 21 #include "capability_info_manager.h" 22 #include "component_loader.h" 23 #include "constants.h" 24 #include "device_type.h" 25 #include "dh_context.h" 26 #include "dh_utils_hitrace.h" 27 #include "distributed_hardware_errno.h" 28 #include "distributed_hardware_log.h" 29 #include "dh_utils_tool.h" 30 #include "meta_info_manager.h" 31 #include "plugin_listener_impl.h" 32 #include "version_manager.h" 33 34 namespace OHOS { 35 namespace DistributedHardware { 36 namespace { 37 constexpr int32_t QUERY_INTERVAL_TIME = 1000 * 1000; // 1s 38 constexpr int32_t QUERY_RETRY_MAX_TIMES = 3; 39 } 40 #undef DH_LOG_TAG 41 #define DH_LOG_TAG "LocalHardwareManager" 42 IMPLEMENT_SINGLE_INSTANCE(LocalHardwareManager)43 IMPLEMENT_SINGLE_INSTANCE(LocalHardwareManager) 44 45 LocalHardwareManager::LocalHardwareManager() {} ~LocalHardwareManager()46 LocalHardwareManager::~LocalHardwareManager() {} 47 Init()48 void LocalHardwareManager::Init() 49 { 50 DHLOGI("start"); 51 std::vector<DHType> allCompTypes = ComponentLoader::GetInstance().GetAllCompTypes(); 52 localDHItemsMap_.clear(); 53 int64_t allQueryStartTime = GetCurrentTime(); 54 for (auto dhType : allCompTypes) { 55 int64_t singleQueryStartTime = GetCurrentTime(); 56 IHardwareHandler *hardwareHandler = nullptr; 57 int32_t status = ComponentLoader::GetInstance().GetHardwareHandler(dhType, hardwareHandler); 58 if (status != DH_FWK_SUCCESS || hardwareHandler == nullptr) { 59 DHLOGE("GetHardwareHandler %{public}#X failed", dhType); 60 continue; 61 } 62 if (hardwareHandler->Initialize() != DH_FWK_SUCCESS) { 63 DHLOGE("Initialize %{public}#X failed", dhType); 64 continue; 65 } 66 67 DHQueryTraceStart(dhType); 68 QueryLocalHardware(dhType, hardwareHandler); 69 DHTraceEnd(); 70 if (!hardwareHandler->IsSupportPlugin()) { 71 DHLOGI("hardwareHandler is not support hot swap plugin, release!"); 72 ComponentLoader::GetInstance().ReleaseHardwareHandler(dhType); 73 hardwareHandler = nullptr; 74 } else { 75 compToolFuncsMap_[dhType] = hardwareHandler; 76 std::shared_ptr<PluginListener> listener = std::make_shared<PluginListenerImpl>(dhType); 77 pluginListenerMap_[dhType] = listener; 78 hardwareHandler->RegisterPluginListener(listener); 79 } 80 int64_t singleQueryEndTime = GetCurrentTime(); 81 DHLOGI("query %{public}#X hardware cost time: %{public}" PRIu64 " ms", 82 dhType, singleQueryEndTime - singleQueryStartTime); 83 } 84 int64_t allQueryEndTime = GetCurrentTime(); 85 DHLOGI("query all local hardware cost time: %{public}" PRIu64 " ms", allQueryEndTime - allQueryStartTime); 86 std::vector<std::shared_ptr<CapabilityInfo>> capabilityInfos; 87 std::vector<std::shared_ptr<MetaCapabilityInfo>> metaCapInfos; 88 for (const auto &localDHItems : localDHItemsMap_) { 89 AddLocalCapabilityInfo(localDHItems.second, localDHItems.first, capabilityInfos); 90 AddLocalMetaCapInfo(localDHItems.second, localDHItems.first, metaCapInfos); 91 } 92 CapabilityInfoManager::GetInstance()->AddCapability(capabilityInfos); 93 MetaInfoManager::GetInstance()->AddMetaCapInfos(metaCapInfos); 94 } 95 UnInit()96 void LocalHardwareManager::UnInit() 97 { 98 DHLOGI("start"); 99 compToolFuncsMap_.clear(); 100 pluginListenerMap_.clear(); 101 } 102 QueryLocalHardware(const DHType dhType,IHardwareHandler * hardwareHandler)103 void LocalHardwareManager::QueryLocalHardware(const DHType dhType, IHardwareHandler *hardwareHandler) 104 { 105 std::vector<DHItem> dhItems; 106 int32_t retryTimes = QUERY_RETRY_MAX_TIMES; 107 while (retryTimes > 0) { 108 DHLOGI("Query hardwareHandler retry times left: %{public}d, dhType: %{public}#X", retryTimes, dhType); 109 if (hardwareHandler == nullptr) { 110 DHLOGE("hardwareHandler is null."); 111 return; 112 } 113 dhItems = hardwareHandler->Query(); 114 if (dhItems.empty()) { 115 DHLOGE("Query hardwareHandler and obtain empty, dhType: %{public}#X", dhType); 116 usleep(QUERY_INTERVAL_TIME); 117 } else { 118 DHLOGI("Query hardwareHandler success, dhType: %{public}#X!, size: %{public}zu", dhType, dhItems.size()); 119 /* 120 * Failed to delete data when the device restarts or other exception situation. 121 * So check and remove the non-exist local capabilityInfo. 122 */ 123 CheckNonExistCapabilityInfo(dhItems, dhType); 124 localDHItemsMap_[dhType] = dhItems; 125 break; 126 } 127 retryTimes--; 128 } 129 } 130 AddLocalCapabilityInfo(const std::vector<DHItem> & dhItems,const DHType dhType,std::vector<std::shared_ptr<CapabilityInfo>> & capabilityInfos)131 void LocalHardwareManager::AddLocalCapabilityInfo(const std::vector<DHItem> &dhItems, const DHType dhType, 132 std::vector<std::shared_ptr<CapabilityInfo>> &capabilityInfos) 133 { 134 DHLOGI("start!"); 135 std::string deviceId = DHContext::GetInstance().GetDeviceInfo().deviceId; 136 std::string devName = DHContext::GetInstance().GetDeviceInfo().deviceName; 137 uint16_t devType = DHContext::GetInstance().GetDeviceInfo().deviceType; 138 for (auto dhItem : dhItems) { 139 std::shared_ptr<CapabilityInfo> dhCapabilityInfo = std::make_shared<CapabilityInfo>( 140 dhItem.dhId, deviceId, devName, devType, dhType, dhItem.attrs, dhItem.subtype); 141 capabilityInfos.push_back(dhCapabilityInfo); 142 } 143 } 144 AddLocalMetaCapInfo(const std::vector<DHItem> & dhItems,const DHType dhType,std::vector<std::shared_ptr<MetaCapabilityInfo>> & metaCapInfos)145 void LocalHardwareManager::AddLocalMetaCapInfo(const std::vector<DHItem> &dhItems, const DHType dhType, 146 std::vector<std::shared_ptr<MetaCapabilityInfo>> &metaCapInfos) 147 { 148 DHLOGI("start!"); 149 std::string deviceId = DHContext::GetInstance().GetDeviceInfo().deviceId; 150 std::string udidHash = DHContext::GetInstance().GetDeviceInfo().udidHash; 151 std::string devName = DHContext::GetInstance().GetDeviceInfo().deviceName; 152 uint16_t devType = DHContext::GetInstance().GetDeviceInfo().deviceType; 153 std::string strUUID = DHContext::GetInstance().GetDeviceInfo().uuid; 154 CompVersion compversion; 155 VersionManager::GetInstance().GetCompVersion(strUUID, dhType, compversion); 156 for (auto dhItem : dhItems) { 157 std::shared_ptr<MetaCapabilityInfo> dhMetaCapInfo = std::make_shared<MetaCapabilityInfo>( 158 dhItem.dhId, deviceId, devName, devType, dhType, dhItem.attrs, dhItem.subtype, udidHash, 159 compversion.sinkVersion); 160 metaCapInfos.push_back(dhMetaCapInfo); 161 } 162 } 163 CheckNonExistCapabilityInfo(const std::vector<DHItem> & dhItems,const DHType dhType)164 void LocalHardwareManager::CheckNonExistCapabilityInfo(const std::vector<DHItem> &dhItems, const DHType dhType) 165 { 166 DHLOGI("start"); 167 if (dhType != DHType::INPUT) { 168 DHLOGI("This dhType is not input and no need check!"); 169 return; 170 } 171 CapabilityInfoMap allLocalCapabilityInfos; 172 GetLocalCapabilityMapByPrefix(dhType, allLocalCapabilityInfos); 173 for (auto capabilityInfo : allLocalCapabilityInfos) { 174 std::shared_ptr<CapabilityInfo> capabilityValue = capabilityInfo.second; 175 if (capabilityValue == nullptr) { 176 DHLOGE("capabilityInfo value is nullptr"); 177 continue; 178 } 179 DHLOGI("The key in allLocalCapabilityInfos is %{public}s", capabilityValue->GetAnonymousKey().c_str()); 180 bool isExist = false; 181 for (auto dhItem : dhItems) { 182 DHLOGI("This data key is: %{public}s, dhItem: %{public}s", capabilityValue->GetAnonymousKey().c_str(), 183 GetAnonyString(dhItem.dhId).c_str()); 184 if (capabilityValue->GetDHId() == dhItem.dhId) { 185 DHLOGI("This data is exist, no need removed key: %{public}s", 186 capabilityValue->GetAnonymousKey().c_str()); 187 isExist = true; 188 break; 189 } 190 } 191 if (!isExist) { 192 DHLOGI("This data is non-exist, it should be removed, key: %{public}s", 193 capabilityValue->GetAnonymousKey().c_str()); 194 CapabilityInfoManager::GetInstance()->RemoveCapabilityInfoByKey(capabilityValue->GetKey()); 195 } 196 } 197 DHLOGI("end"); 198 } 199 GetLocalCapabilityMapByPrefix(const DHType dhType,CapabilityInfoMap & capabilityInfoMap)200 void LocalHardwareManager::GetLocalCapabilityMapByPrefix(const DHType dhType, CapabilityInfoMap &capabilityInfoMap) 201 { 202 std::string localDeviceId = DHContext::GetInstance().GetDeviceInfo().deviceId; 203 if (!IsIdLengthValid(localDeviceId)) { 204 return; 205 } 206 if (DHTypePrefixMap.find(dhType) == DHTypePrefixMap.end()) { 207 DHLOGE("DHTypePrefixMap can not find dhType: %{public}#X", dhType); 208 return; 209 } 210 std::string prefix = DHTypePrefixMap.find(dhType)->second; 211 std::string localCapabilityPrefix = localDeviceId + RESOURCE_SEPARATOR + prefix; 212 CapabilityInfoManager::GetInstance()->GetDataByKeyPrefix(localCapabilityPrefix, capabilityInfoMap); 213 } 214 } // namespace DistributedHardware 215 } // namespace OHOS 216