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