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