• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 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 "capability_info_manager.h"
17 
18 #include "anonymous_string.h"
19 #include "capability_utils.h"
20 #include "constants.h"
21 #include "dh_context.h"
22 #include "dh_utils_tool.h"
23 #include "distributed_hardware_errno.h"
24 #include "distributed_hardware_log.h"
25 #include "distributed_hardware_manager.h"
26 #include "distributed_hardware_manager_factory.h"
27 #include "task_executor.h"
28 #include "task_factory.h"
29 #include "task_board.h"
30 
31 namespace OHOS {
32 namespace DistributedHardware {
33 #undef DH_LOG_TAG
34 #define DH_LOG_TAG "CapabilityInfoManager"
35 
36 constexpr int32_t SYNC_DATA_TIMEOUT_MS = 1000 * 10;
37 constexpr const char *GLOBAL_CAPABILITY_INFO_KEY = "global_capability_info";
38 
CapabilityInfoManager()39 CapabilityInfoManager::CapabilityInfoManager() : dbAdapterPtr_(nullptr)
40 {
41     DHLOGI("CapabilityInfoManager construction!");
42 }
43 
~CapabilityInfoManager()44 CapabilityInfoManager::~CapabilityInfoManager()
45 {
46     DHLOGI("CapabilityInfoManager destruction!");
47 }
48 
GetInstance()49 std::shared_ptr<CapabilityInfoManager> CapabilityInfoManager::GetInstance()
50 {
51     static std::shared_ptr<CapabilityInfoManager> instance = std::make_shared<CapabilityInfoManager>();
52     return instance;
53 }
54 
CapabilityInfoManagerEventHandler(const std::shared_ptr<AppExecFwk::EventRunner> runner,std::shared_ptr<CapabilityInfoManager> capabilityInfoMgrPtr)55 CapabilityInfoManager::CapabilityInfoManagerEventHandler::CapabilityInfoManagerEventHandler(
56     const std::shared_ptr<AppExecFwk::EventRunner> runner,
57     std::shared_ptr<CapabilityInfoManager> capabilityInfoMgrPtr)
58     : AppExecFwk::EventHandler(runner)
59 {
60     DHLOGI("Ctor CapabilityInfoManagerEventHandler");
61     capabilityInfoMgrWPtr_ = capabilityInfoMgrPtr;
62 }
63 
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)64 void CapabilityInfoManager::CapabilityInfoManagerEventHandler::ProcessEvent(
65     const AppExecFwk::InnerEvent::Pointer &event)
66 {
67     if (event == nullptr) {
68         DHLOGE("event is null.");
69         return;
70     }
71     uint32_t eventId = event->GetInnerEventId();
72     auto selfPtr = capabilityInfoMgrWPtr_.lock();
73     if (!selfPtr) {
74         DHLOGE("Can not get strong self ptr");
75         return;
76     }
77     switch (eventId) {
78         case EVENT_CAPABILITY_INFO_DB_RECOVER:
79             selfPtr->SyncRemoteCapabilityInfos();
80             break;
81         default:
82             DHLOGE("event is undefined, id is %{public}d", eventId);
83             break;
84     }
85 }
86 
GetEventHandler()87 std::shared_ptr<CapabilityInfoManager::CapabilityInfoManagerEventHandler> CapabilityInfoManager::GetEventHandler()
88 {
89     return this->eventHandler_;
90 }
91 
Init()92 int32_t CapabilityInfoManager::Init()
93 {
94     DHLOGI("CapabilityInfoManager instance init!");
95     std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
96     dbAdapterPtr_ = std::make_shared<DBAdapter>(APP_ID, GLOBAL_CAPABILITY_INFO_KEY, shared_from_this());
97     if (dbAdapterPtr_ == nullptr) {
98         DHLOGE("dbAdapterPtr_ is null");
99         return ERR_DH_FWK_RESOURCE_DB_ADAPTER_POINTER_NULL;
100     }
101     if (dbAdapterPtr_->Init(false, DistributedKv::DataType::TYPE_DYNAMICAL) != DH_FWK_SUCCESS) {
102         DHLOGE("Init dbAdapterPtr_ failed");
103         return ERR_DH_FWK_RESOURCE_INIT_DB_FAILED;
104     }
105     std::shared_ptr<AppExecFwk::EventRunner> runner = AppExecFwk::EventRunner::Create(true);
106     eventHandler_ = std::make_shared<CapabilityInfoManager::CapabilityInfoManagerEventHandler>(
107         runner, shared_from_this());
108     DHLOGI("CapabilityInfoManager instance init success");
109     return DH_FWK_SUCCESS;
110 }
111 
UnInit()112 int32_t CapabilityInfoManager::UnInit()
113 {
114     DHLOGI("CapabilityInfoManager UnInit");
115     std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
116     if (dbAdapterPtr_ == nullptr) {
117         DHLOGE("dbAdapterPtr_ is null");
118         return ERR_DH_FWK_RESOURCE_UNINIT_DB_FAILED;
119     }
120     dbAdapterPtr_->UnInit();
121     dbAdapterPtr_.reset();
122     return DH_FWK_SUCCESS;
123 }
124 
SyncDeviceInfoFromDB(const std::string & deviceId)125 int32_t CapabilityInfoManager::SyncDeviceInfoFromDB(const std::string &deviceId)
126 {
127     if (!IsIdLengthValid(deviceId)) {
128         return ERR_DH_FWK_PARA_INVALID;
129     }
130     DHLOGI("Sync DeviceInfo from DB, deviceId: %{public}s", GetAnonyString(deviceId).c_str());
131     std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
132     if (dbAdapterPtr_ == nullptr) {
133         DHLOGE("dbAdapterPtr_ is null");
134         return ERR_DH_FWK_RESOURCE_DB_ADAPTER_POINTER_NULL;
135     }
136     std::vector<std::string> dataVector;
137     if (dbAdapterPtr_->GetDataByKeyPrefix(deviceId, dataVector) != DH_FWK_SUCCESS) {
138         DHLOGE("Query data from DB by deviceId failed, id: %{public}s", GetAnonyString(deviceId).c_str());
139         return ERR_DH_FWK_RESOURCE_DB_ADAPTER_OPERATION_FAIL;
140     }
141     if (dataVector.empty() || dataVector.size() > MAX_DB_RECORD_SIZE) {
142         DHLOGE("dataVector size: %{public}zu is invalid, maybe empty or too large.", dataVector.size());
143         return ERR_DH_FWK_RESOURCE_RES_DB_DATA_INVALID;
144     }
145     for (const auto &data : dataVector) {
146         std::shared_ptr<CapabilityInfo> capabilityInfo;
147         if (GetCapabilityByValue<CapabilityInfo>(data, capabilityInfo) != DH_FWK_SUCCESS) {
148             DHLOGE("Get capability ptr by value failed");
149             continue;
150         }
151         globalCapInfoMap_[capabilityInfo->GetKey()] = capabilityInfo;
152     }
153     return DH_FWK_SUCCESS;
154 }
155 
SyncRemoteCapabilityInfos()156 int32_t CapabilityInfoManager::SyncRemoteCapabilityInfos()
157 {
158     DHLOGI("Sync full remote device info from DB");
159     std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
160     if (dbAdapterPtr_ == nullptr) {
161         DHLOGE("dbAdapterPtr_ is null");
162         return ERR_DH_FWK_RESOURCE_DB_ADAPTER_POINTER_NULL;
163     }
164     std::vector<std::string> deviceIdVec;
165     DHContext::GetInstance().GetOnlineDeviceDeviceId(deviceIdVec);
166     for (const auto &deviceId : deviceIdVec) {
167         std::vector<std::string> dataVector;
168         if (dbAdapterPtr_->GetDataByKeyPrefix(deviceId, dataVector) != DH_FWK_SUCCESS) {
169             DHLOGE("Query the deviceId: %{public}s data from DB failed", GetAnonyString(deviceId).c_str());
170             continue;
171         }
172         if (dataVector.empty() || dataVector.size() > MAX_DB_RECORD_SIZE) {
173             DHLOGE("dataVector size: %{public}zu is invalid, maybe empty or too large.", dataVector.size());
174             continue;
175         }
176         for (const auto &data : dataVector) {
177             std::shared_ptr<CapabilityInfo> capabilityInfo;
178             if (GetCapabilityByValue<CapabilityInfo>(data, capabilityInfo) != DH_FWK_SUCCESS) {
179                 DHLOGE("Get capability ptr by value failed");
180                 continue;
181             }
182             const std::string deviceId = capabilityInfo->GetDeviceId();
183             const std::string localDeviceId = DHContext::GetInstance().GetDeviceInfo().deviceId;
184             if (deviceId.compare(localDeviceId) == 0) {
185                 DHLOGE("local device info not need sync from db");
186                 continue;
187             }
188             globalCapInfoMap_[capabilityInfo->GetKey()] = capabilityInfo;
189         }
190     }
191     return DH_FWK_SUCCESS;
192 }
193 
AddCapability(const std::vector<std::shared_ptr<CapabilityInfo>> & resInfos)194 int32_t CapabilityInfoManager::AddCapability(const std::vector<std::shared_ptr<CapabilityInfo>> &resInfos)
195 {
196     if (resInfos.empty() || resInfos.size() > MAX_DB_RECORD_SIZE) {
197         DHLOGE("ResInfo is empty or too large!");
198         return ERR_DH_FWK_RESOURCE_RES_DB_DATA_INVALID;
199     }
200     std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
201     if (dbAdapterPtr_ == nullptr) {
202         DHLOGE("dbAdapterPtr_ is null");
203         return ERR_DH_FWK_RESOURCE_DB_ADAPTER_POINTER_NULL;
204     }
205     std::vector<std::string> keys;
206     std::vector<std::string> values;
207     std::string key;
208     std::string data;
209     for (auto &resInfo : resInfos) {
210         if (resInfo == nullptr) {
211             continue;
212         }
213         key = resInfo->GetKey();
214         globalCapInfoMap_[key] = resInfo;
215         if (dbAdapterPtr_->GetDataByKey(key, data) == DH_FWK_SUCCESS &&
216             IsCapInfoJsonEqual<CapabilityInfo>(data, resInfo->ToJsonString())) {
217             DHLOGD("this record is exist, Key: %{public}s", resInfo->GetAnonymousKey().c_str());
218             continue;
219         }
220         DHLOGI("AddCapability, Key: %{public}s", resInfo->GetAnonymousKey().c_str());
221         keys.push_back(key);
222         values.push_back(resInfo->ToJsonString());
223     }
224     if (keys.empty() || values.empty()) {
225         DHLOGD("Records are empty, No need add data to db!");
226         return DH_FWK_SUCCESS;
227     }
228     if (dbAdapterPtr_->PutDataBatch(keys, values) != DH_FWK_SUCCESS) {
229         DHLOGE("Fail to storage batch to kv");
230         return ERR_DH_FWK_RESOURCE_DB_ADAPTER_OPERATION_FAIL;
231     }
232     return DH_FWK_SUCCESS;
233 }
234 
AddCapabilityInMem(const std::vector<std::shared_ptr<CapabilityInfo>> & resInfos)235 int32_t CapabilityInfoManager::AddCapabilityInMem(const std::vector<std::shared_ptr<CapabilityInfo>> &resInfos)
236 {
237     if (resInfos.empty() || resInfos.size() > MAX_DB_RECORD_SIZE) {
238         DHLOGE("ResInfo is empty or too large!");
239         return ERR_DH_FWK_RESOURCE_RES_DB_DATA_INVALID;
240     }
241     std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
242     for (auto &resInfo : resInfos) {
243         if (resInfo == nullptr) {
244             continue;
245         }
246         const std::string key = resInfo->GetKey();
247         DHLOGI("AddCapabilityInMem, Key: %{public}s", resInfo->GetAnonymousKey().c_str());
248         globalCapInfoMap_[key] = resInfo;
249     }
250     return DH_FWK_SUCCESS;
251 }
252 
RemoveCapabilityInfoInDB(const std::string & deviceId)253 int32_t CapabilityInfoManager::RemoveCapabilityInfoInDB(const std::string &deviceId)
254 {
255     if (!IsIdLengthValid(deviceId)) {
256         return ERR_DH_FWK_PARA_INVALID;
257     }
258     DHLOGI("Remove capability device info, deviceId: %{public}s", GetAnonyString(deviceId).c_str());
259     std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
260     if (dbAdapterPtr_ == nullptr) {
261         DHLOGE("dbAdapterPtr_ is null");
262         return ERR_DH_FWK_RESOURCE_DB_ADAPTER_POINTER_NULL;
263     }
264     // 1. Clear the cache in the memory.
265     for (auto iter = globalCapInfoMap_.begin(); iter != globalCapInfoMap_.end();) {
266         if (!IsCapKeyMatchDeviceId(iter->first, deviceId)) {
267             iter++;
268             continue;
269         }
270         DHLOGI("Clear globalCapInfoMap_ iter: %{public}s", GetAnonyString(iter->first).c_str());
271         globalCapInfoMap_.erase(iter++);
272     }
273     // 2. Delete the corresponding record from the database(use UUID).
274     if (dbAdapterPtr_->RemoveDeviceData(deviceId) != DH_FWK_SUCCESS) {
275         DHLOGE("Remove capability Device Data failed, deviceId: %{public}s", GetAnonyString(deviceId).c_str());
276         return ERR_DH_FWK_RESOURCE_DB_ADAPTER_OPERATION_FAIL;
277     }
278     return DH_FWK_SUCCESS;
279 }
280 
RemoveCapabilityInfoByKey(const std::string & key)281 int32_t CapabilityInfoManager::RemoveCapabilityInfoByKey(const std::string &key)
282 {
283     if (!IsIdLengthValid(key)) {
284         return ERR_DH_FWK_PARA_INVALID;
285     }
286     DHLOGI("Remove capability device info, key: %{public}s", GetAnonyString(key).c_str());
287     std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
288     if (dbAdapterPtr_ == nullptr) {
289         DHLOGE("dbAdapterPtr_ is null");
290         return ERR_DH_FWK_RESOURCE_DB_ADAPTER_POINTER_NULL;
291     }
292     // 1. Clear the cache in the memory.
293     globalCapInfoMap_.erase(key);
294 
295     // 2. Delete the corresponding record from the database.(use key)
296     if (dbAdapterPtr_->RemoveDataByKey(key) != DH_FWK_SUCCESS) {
297         DHLOGE("Remove capability Device Data failed, key: %{public}s", GetAnonyString(key).c_str());
298         return ERR_DH_FWK_RESOURCE_DB_ADAPTER_OPERATION_FAIL;
299     }
300     return DH_FWK_SUCCESS;
301 }
302 
RemoveCapabilityInfoInMem(const std::string & deviceId)303 int32_t CapabilityInfoManager::RemoveCapabilityInfoInMem(const std::string &deviceId)
304 {
305     if (!IsIdLengthValid(deviceId)) {
306         return ERR_DH_FWK_PARA_INVALID;
307     }
308     DHLOGI("remove capability device info in memory, deviceId: %{public}s", GetAnonyString(deviceId).c_str());
309     std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
310     for (auto iter = globalCapInfoMap_.begin(); iter != globalCapInfoMap_.end();) {
311         if (!IsCapKeyMatchDeviceId(iter->first, deviceId)) {
312             iter++;
313             continue;
314         }
315         globalCapInfoMap_.erase(iter++);
316     }
317     return DH_FWK_SUCCESS;
318 }
319 
OnChange(const DistributedKv::ChangeNotification & changeNotification)320 void CapabilityInfoManager::OnChange(const DistributedKv::ChangeNotification &changeNotification)
321 {
322     DHLOGI("CapabilityInfoManager: DB data OnChange");
323     if (!changeNotification.GetInsertEntries().empty() &&
324         changeNotification.GetInsertEntries().size() <= MAX_DB_RECORD_SIZE) {
325         DHLOGI("Handle capability data add change");
326         HandleCapabilityAddChange(changeNotification.GetInsertEntries());
327     }
328     if (!changeNotification.GetUpdateEntries().empty() &&
329         changeNotification.GetUpdateEntries().size() <= MAX_DB_RECORD_SIZE) {
330         DHLOGI("Handle capability data update change");
331         HandleCapabilityUpdateChange(changeNotification.GetUpdateEntries());
332     }
333     if (!changeNotification.GetDeleteEntries().empty() &&
334         changeNotification.GetDeleteEntries().size() <= MAX_DB_RECORD_SIZE) {
335         DHLOGI("Handle capability data delete change");
336         HandleCapabilityDeleteChange(changeNotification.GetDeleteEntries());
337     }
338 }
339 
OnChange(const DistributedKv::DataOrigin & origin,Keys && keys)340 void CapabilityInfoManager::OnChange(const DistributedKv::DataOrigin &origin, Keys &&keys)
341 {
342     DHLOGI("CapabilityInfoManager: Cloud data OnChange.");
343     std::vector<DistributedKv::Entry> insertRecords = GetEntriesByKeys(keys[ChangeOp::OP_INSERT]);
344     if (!insertRecords.empty() && insertRecords.size() <= MAX_DB_RECORD_SIZE) {
345         DHLOGI("Handle capability data add change");
346         HandleCapabilityAddChange(insertRecords);
347     }
348     std::vector<DistributedKv::Entry> updateRecords = GetEntriesByKeys(keys[ChangeOp::OP_UPDATE]);
349     if (!updateRecords.empty() && updateRecords.size() <= MAX_DB_RECORD_SIZE) {
350         DHLOGI("Handle capability data update change");
351         HandleCapabilityUpdateChange(updateRecords);
352     }
353     std::vector<std::string> delKeys = keys[ChangeOp::OP_DELETE];
354     if (!delKeys.empty() && delKeys.size() <= MAX_DB_RECORD_SIZE) {
355         std::vector<DistributedKv::Entry> deleteRecords;
356         for (const auto &key : delKeys) {
357             DistributedKv::Entry entry;
358             DistributedKv::Key kvKey(key);
359             entry.key = kvKey;
360             deleteRecords.emplace_back(entry);
361         }
362         DHLOGI("Handle capability data delete change");
363         HandleCapabilityDeleteChange(deleteRecords);
364     }
365 }
366 
HandleCapabilityAddChange(const std::vector<DistributedKv::Entry> & insertRecords)367 void CapabilityInfoManager::HandleCapabilityAddChange(const std::vector<DistributedKv::Entry> &insertRecords)
368 {
369     std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
370     for (const auto &item : insertRecords) {
371         const std::string value = item.value.ToString();
372         std::shared_ptr<CapabilityInfo> capPtr;
373         if (GetCapabilityByValue<CapabilityInfo>(value, capPtr) != DH_FWK_SUCCESS) {
374             DHLOGE("Get capability by value failed");
375             continue;
376         }
377         std::string uuid = DHContext::GetInstance().GetUUIDByDeviceId(capPtr->GetDeviceId());
378         if (uuid.empty()) {
379             DHLOGE("Find uuid failed and never enable, deviceId: %{public}s",
380                 GetAnonyString(capPtr->GetDeviceId()).c_str());
381             continue;
382         }
383         std::string networkId = DHContext::GetInstance().GetNetworkIdByUUID(uuid);
384         if (networkId.empty()) {
385             DHLOGE("Find network failed and never enable, uuid: %{public}s", GetAnonyString(uuid).c_str());
386             continue;
387         }
388 
389         const auto keyString = capPtr->GetKey();
390         DHLOGI("Add capability key: %{public}s", capPtr->GetAnonymousKey().c_str());
391         globalCapInfoMap_[keyString] = capPtr;
392         TaskParam taskParam = {
393             .networkId = networkId,
394             .uuid = uuid,
395             .dhId = capPtr->GetDHId(),
396             .dhType = capPtr->GetDHType()
397         };
398         auto task = TaskFactory::GetInstance().CreateTask(TaskType::ENABLE, taskParam, nullptr);
399         TaskExecutor::GetInstance().PushTask(task);
400     }
401     DHLOGI("HandleCapabilityAddChange success");
402     std::unique_lock<std::mutex> condition(syncDataMutex_);
403     syncDataCondVar_.notify_all();
404 }
405 
HandleCapabilityUpdateChange(const std::vector<DistributedKv::Entry> & updateRecords)406 void CapabilityInfoManager::HandleCapabilityUpdateChange(const std::vector<DistributedKv::Entry> &updateRecords)
407 {
408     if (DistributedHardwareManagerFactory::GetInstance().GetUnInitFlag()) {
409         DHLOGE("no need Update, is in uniniting.");
410         return;
411     }
412     std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
413     for (const auto &item : updateRecords) {
414         const std::string value = item.value.ToString();
415         std::shared_ptr<CapabilityInfo> capPtr;
416         if (GetCapabilityByValue<CapabilityInfo>(value, capPtr) != DH_FWK_SUCCESS) {
417             DHLOGE("Get capability by value failed");
418             continue;
419         }
420         std::string uuid = DHContext::GetInstance().GetUUIDByDeviceId(capPtr->GetDeviceId());
421         if (uuid.empty()) {
422             DHLOGE("Find uuid failed and never enable, deviceId: %{public}s",
423                 GetAnonyString(capPtr->GetDeviceId()).c_str());
424             continue;
425         }
426         std::string networkId = DHContext::GetInstance().GetNetworkIdByUUID(uuid);
427         if (networkId.empty()) {
428             DHLOGE("Find network failed and never enable, uuid: %{public}s", GetAnonyString(uuid).c_str());
429             continue;
430         }
431         std::string enabledDeviceKey = GetCapabilityKey(capPtr->GetDeviceId(), capPtr->GetDHId());
432         if (TaskBoard::GetInstance().IsEnabledDevice(enabledDeviceKey)) {
433             DHLOGI("The deviceKey: %{public}s is enabled.", GetAnonyString(enabledDeviceKey).c_str());
434             continue;
435         }
436         const auto keyString = capPtr->GetKey();
437         DHLOGI("Update capability key: %{public}s", capPtr->GetAnonymousKey().c_str());
438         globalCapInfoMap_[keyString] = capPtr;
439         TaskParam taskParam = {
440             .networkId = networkId,
441             .uuid = uuid,
442             .dhId = capPtr->GetDHId(),
443             .dhType = capPtr->GetDHType()
444         };
445         auto task = TaskFactory::GetInstance().CreateTask(TaskType::ENABLE, taskParam, nullptr);
446         TaskExecutor::GetInstance().PushTask(task);
447     }
448     DHLOGI("HandleCapabilityUpdateChange success");
449     std::unique_lock<std::mutex> condition(syncDataMutex_);
450     syncDataCondVar_.notify_all();
451 }
452 
HandleCapabilityDeleteChange(const std::vector<DistributedKv::Entry> & deleteRecords)453 void CapabilityInfoManager::HandleCapabilityDeleteChange(const std::vector<DistributedKv::Entry> &deleteRecords)
454 {
455     if (DistributedHardwareManagerFactory::GetInstance().GetUnInitFlag()) {
456         DHLOGE("no need Update, is in uniniting.");
457         return;
458     }
459     std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
460     for (const auto &item : deleteRecords) {
461         const std::string value = item.value.ToString();
462         std::shared_ptr<CapabilityInfo> capPtr;
463         if (GetCapabilityByValue<CapabilityInfo>(value, capPtr) != DH_FWK_SUCCESS) {
464             DHLOGE("Get capability by value failed");
465             continue;
466         }
467         const auto keyString = capPtr->GetKey();
468         std::string uuid = DHContext::GetInstance().GetUUIDByDeviceId(capPtr->GetDeviceId());
469         if (uuid.empty()) {
470             DHLOGI("Find uuid failed and never disable");
471             continue;
472         }
473         std::string networkId = DHContext::GetInstance().GetNetworkIdByUUID(uuid);
474         if (networkId.empty()) {
475             DHLOGI("Find network failed and never disable, uuid: %{public}s", GetAnonyString(uuid).c_str());
476             continue;
477         }
478         TaskParam taskParam = {
479             .networkId = networkId,
480             .uuid = uuid,
481             .dhId = capPtr->GetDHId(),
482             .dhType = capPtr->GetDHType()
483         };
484         auto task = TaskFactory::GetInstance().CreateTask(TaskType::DISABLE, taskParam, nullptr);
485         TaskExecutor::GetInstance().PushTask(task);
486         DHLOGI("Delete capability key: %{public}s", capPtr->GetAnonymousKey().c_str());
487         globalCapInfoMap_.erase(keyString);
488     }
489 }
490 
GetCapabilitiesByDeviceId(const std::string & deviceId,std::vector<std::shared_ptr<CapabilityInfo>> & resInfos)491 void CapabilityInfoManager::GetCapabilitiesByDeviceId(const std::string &deviceId,
492     std::vector<std::shared_ptr<CapabilityInfo>> &resInfos)
493 {
494     if (!IsIdLengthValid(deviceId)) {
495         return;
496     }
497     std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
498     for (auto &capabilityInfo : globalCapInfoMap_) {
499         if (IsCapKeyMatchDeviceId(capabilityInfo.first, deviceId)) {
500             resInfos.emplace_back(capabilityInfo.second);
501         }
502     }
503 }
504 
HasCapability(const std::string & deviceId,const std::string & dhId)505 bool CapabilityInfoManager::HasCapability(const std::string &deviceId, const std::string &dhId)
506 {
507     if (!IsIdLengthValid(deviceId) || !IsIdLengthValid(dhId)) {
508         return false;
509     }
510     std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
511     std::string kvKey = GetCapabilityKey(deviceId, dhId);
512     if (globalCapInfoMap_.find(kvKey) == globalCapInfoMap_.end()) {
513         return false;
514     }
515     return true;
516 }
517 
GetCapability(const std::string & deviceId,const std::string & dhId,std::shared_ptr<CapabilityInfo> & capPtr)518 int32_t CapabilityInfoManager::GetCapability(const std::string &deviceId, const std::string &dhId,
519     std::shared_ptr<CapabilityInfo> &capPtr)
520 {
521     if (!IsIdLengthValid(deviceId) || !IsIdLengthValid(dhId)) {
522         return ERR_DH_FWK_PARA_INVALID;
523     }
524     std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
525     std::string key = GetCapabilityKey(deviceId, dhId);
526     if (globalCapInfoMap_.find(key) == globalCapInfoMap_.end()) {
527         DHLOGE("Can not find capability In globalCapInfoMap_: %{public}s", GetAnonyString(deviceId).c_str());
528         return ERR_DH_FWK_RESOURCE_CAPABILITY_MAP_NOT_FOUND;
529     }
530     capPtr = globalCapInfoMap_[key];
531     return DH_FWK_SUCCESS;
532 }
533 
GetDataByKey(const std::string & key,std::shared_ptr<CapabilityInfo> & capInfoPtr)534 int32_t CapabilityInfoManager::GetDataByKey(const std::string &key, std::shared_ptr<CapabilityInfo> &capInfoPtr)
535 {
536     if (!IsIdLengthValid(key)) {
537         return ERR_DH_FWK_PARA_INVALID;
538     }
539     std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
540     if (dbAdapterPtr_ == nullptr) {
541         DHLOGI("dbAdapterPtr_ is null");
542         return ERR_DH_FWK_RESOURCE_DB_ADAPTER_POINTER_NULL;
543     }
544     std::string data;
545     if (dbAdapterPtr_->GetDataByKey(key, data) != DH_FWK_SUCCESS) {
546         DHLOGE("Query capability info from db failed, key: %{public}s", GetAnonyString(key).c_str());
547         return ERR_DH_FWK_RESOURCE_DB_ADAPTER_OPERATION_FAIL;
548     }
549     return GetCapabilityByValue<CapabilityInfo>(data, capInfoPtr);
550 }
551 
GetDataByDHType(const DHType dhType,CapabilityInfoMap & capabilityMap)552 int32_t CapabilityInfoManager::GetDataByDHType(const DHType dhType, CapabilityInfoMap &capabilityMap)
553 {
554     std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
555     for (const auto &capInfo : globalCapInfoMap_) {
556         if (capInfo.second->GetDHType() != dhType) {
557             continue;
558         }
559         capabilityMap[capInfo.first] = capInfo.second;
560     }
561     return DH_FWK_SUCCESS;
562 }
563 
GetDataByKeyPrefix(const std::string & keyPrefix,CapabilityInfoMap & capabilityMap)564 int32_t CapabilityInfoManager::GetDataByKeyPrefix(const std::string &keyPrefix, CapabilityInfoMap &capabilityMap)
565 {
566     if (!IsIdLengthValid(keyPrefix)) {
567         return ERR_DH_FWK_PARA_INVALID;
568     }
569     std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
570     if (dbAdapterPtr_ == nullptr) {
571         DHLOGE("dbAdapterPtr is null");
572         return ERR_DH_FWK_RESOURCE_DB_ADAPTER_POINTER_NULL;
573     }
574     std::vector<std::string> dataVector;
575     if (dbAdapterPtr_->GetDataByKeyPrefix(keyPrefix, dataVector) != DH_FWK_SUCCESS) {
576         DHLOGE("Query capability info from db failed, key: %{public}s", GetAnonyString(keyPrefix).c_str());
577         return ERR_DH_FWK_RESOURCE_DB_ADAPTER_OPERATION_FAIL;
578     }
579     if (dataVector.empty() || dataVector.size() > MAX_DB_RECORD_SIZE) {
580         DHLOGE("On dataVector error, maybe empty or too large.");
581         return ERR_DH_FWK_RESOURCE_RES_DB_DATA_INVALID;
582     }
583     for (const auto &data : dataVector) {
584         std::shared_ptr<CapabilityInfo> capabilityInfo;
585         if (GetCapabilityByValue<CapabilityInfo>(data, capabilityInfo) != DH_FWK_SUCCESS) {
586             DHLOGE("Get capability ptr by value failed");
587             continue;
588         }
589         capabilityMap[capabilityInfo->GetKey()] = capabilityInfo;
590     }
591     return DH_FWK_SUCCESS;
592 }
593 
DumpCapabilityInfos(std::vector<CapabilityInfo> & capInfos)594 void CapabilityInfoManager::DumpCapabilityInfos(std::vector<CapabilityInfo> &capInfos)
595 {
596     std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
597     for (auto info : globalCapInfoMap_) {
598         CapabilityInfo capInfo = *(info.second);
599         capInfos.emplace_back(capInfo);
600     }
601 }
602 
AsyncGetDistributedHardware(const std::string & networkId,EnableStep enableStep,const sptr<IGetDhDescriptorsCallback> callback)603 void CapabilityInfoManager::AsyncGetDistributedHardware(const std::string &networkId, EnableStep enableStep,
604     const sptr<IGetDhDescriptorsCallback> callback)
605 {
606     DHLOGI("AsyncGetDistributedHardware networkId: %{public}s.", GetAnonyString(networkId).c_str());
607     if (callback == nullptr) {
608         DHLOGE("callback ptr is null");
609         return;
610     }
611     int32_t waitTimeMill = SYNC_DATA_TIMEOUT_MS;
612     while (waitTimeMill > 0) {
613         auto beginTime = std::chrono::steady_clock::now();
614         std::unique_lock<std::mutex> locker(syncDataMutex_);
615         syncDataCondVar_.wait_for(locker, std::chrono::milliseconds(waitTimeMill));
616 
617         std::vector<DHDescriptor> descriptors;
618         std::vector<std::shared_ptr<CapabilityInfo>> capabilities;
619         std::string deviceId = GetDeviceIdByUUID(DHContext::GetInstance().GetUUIDByNetworkId(networkId));
620         CapabilityInfoManager::GetInstance()->GetCapabilitiesByDeviceId(deviceId, capabilities);
621         for (const auto &capabilitie : capabilities) {
622             DHDescriptor descriptor;
623             descriptor.id = capabilitie->GetDHId();
624             descriptor.dhType = capabilitie->GetDHType();
625             descriptors.push_back(descriptor);
626         }
627         if (descriptors.size()) {
628             DHLOGI("AsyncGetDistributedHardware call OnSuccess, networkId: %{public}s.",
629                 GetAnonyString(networkId).c_str());
630             callback->OnSuccess(networkId, descriptors, enableStep);
631             return;
632         }
633 
634         auto endTime = std::chrono::steady_clock::now();
635         auto costTime = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - beginTime);
636         waitTimeMill -= costTime.count();
637         DHLOGI("AsyncGetDistributedHardware do retry, networkId: %{public}s.", GetAnonyString(networkId).c_str());
638     }
639     callback->OnError(networkId, ERR_DH_FWK_GETDISTRIBUTEDHARDWARE_TIMEOUT);
640     DHLOGI("AsyncGetDistributedHardware call OnError, networkId: %{public}s.", GetAnonyString(networkId).c_str());
641 }
642 
DoAsyncGetDistributedHardware(const std::string & networkId,EnableStep enableStep,const sptr<IGetDhDescriptorsCallback> callback)643 void CapabilityInfoManager::DoAsyncGetDistributedHardware(const std::string &networkId, EnableStep enableStep,
644     const sptr<IGetDhDescriptorsCallback> callback)
645 {
646     DHLOGI("DoAsyncGetDistributedHardware networkId: %{public}s.", GetAnonyString(networkId).c_str());
647     std::thread([this, networkId, enableStep, callback]() {
648         this->AsyncGetDistributedHardware(networkId, enableStep, callback);
649     }).detach();
650 }
651 
GetEntriesByKeys(const std::vector<std::string> & keys)652 std::vector<DistributedKv::Entry> CapabilityInfoManager::GetEntriesByKeys(const std::vector<std::string> &keys)
653 {
654     if (!IsArrayLengthValid(keys)) {
655         return {};
656     }
657     DHLOGI("call");
658     std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
659     if (dbAdapterPtr_ == nullptr) {
660         DHLOGE("dbAdapterPtr_ is null");
661         return {};
662     }
663     return dbAdapterPtr_->GetEntriesByKeys(keys);
664 }
665 } // namespace DistributedHardware
666 } // namespace OHOS
667