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