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