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