• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024-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 "local_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 "task_executor.h"
27 #include "task_factory.h"
28 
29 namespace OHOS {
30 namespace DistributedHardware {
31 #undef DH_LOG_TAG
32 #define DH_LOG_TAG "LocalCapabilityInfoManager"
33 
34 constexpr const char *LOCAL_CAPABILITY_INFO_KEY = "local_capability_info";
35 
LocalCapabilityInfoManager()36 LocalCapabilityInfoManager::LocalCapabilityInfoManager() : dbAdapterPtr_(nullptr)
37 {
38     DHLOGI("LocalCapabilityInfoManager construction!");
39 }
40 
~LocalCapabilityInfoManager()41 LocalCapabilityInfoManager::~LocalCapabilityInfoManager()
42 {
43     DHLOGI("LocalCapabilityInfoManager destruction!");
44 }
45 
GetInstance()46 std::shared_ptr<LocalCapabilityInfoManager> LocalCapabilityInfoManager::GetInstance()
47 {
48     static std::shared_ptr<LocalCapabilityInfoManager> instance = std::make_shared<LocalCapabilityInfoManager>();
49     return instance;
50 }
51 
Init()52 int32_t LocalCapabilityInfoManager::Init()
53 {
54     DHLOGI("LocalCapabilityInfoManager instance init!");
55     std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
56     dbAdapterPtr_ = std::make_shared<DBAdapter>(APP_ID, LOCAL_CAPABILITY_INFO_KEY, shared_from_this());
57     if (dbAdapterPtr_ == nullptr) {
58         DHLOGE("dbAdapterPtr_ is null");
59         return ERR_DH_FWK_RESOURCE_DB_ADAPTER_POINTER_NULL;
60     }
61     if (dbAdapterPtr_->InitLocal() != DH_FWK_SUCCESS) {
62         DHLOGE("Init dbAdapterPtr_ failed");
63         return ERR_DH_FWK_RESOURCE_INIT_DB_FAILED;
64     }
65     DHLOGI("LocalCapabilityInfoManager instance init success");
66     return DH_FWK_SUCCESS;
67 }
68 
UnInit()69 int32_t LocalCapabilityInfoManager::UnInit()
70 {
71     DHLOGI("LocalCapabilityInfoManager UnInit");
72     std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
73     if (dbAdapterPtr_ == nullptr) {
74         DHLOGE("dbAdapterPtr_ is null");
75         return ERR_DH_FWK_RESOURCE_UNINIT_DB_FAILED;
76     }
77     dbAdapterPtr_->UnInit();
78     dbAdapterPtr_.reset();
79     return DH_FWK_SUCCESS;
80 }
81 
SyncDeviceInfoFromDB(const std::string & deviceId)82 int32_t LocalCapabilityInfoManager::SyncDeviceInfoFromDB(const std::string &deviceId)
83 {
84     if (!IsIdLengthValid(deviceId)) {
85         return ERR_DH_FWK_PARA_INVALID;
86     }
87     DHLOGI("Sync DeviceInfo from DB, deviceId: %{public}s", GetAnonyString(deviceId).c_str());
88     std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
89     if (dbAdapterPtr_ == nullptr) {
90         DHLOGE("dbAdapterPtr_ is null");
91         return ERR_DH_FWK_RESOURCE_DB_ADAPTER_POINTER_NULL;
92     }
93     std::vector<std::string> dataVector;
94     if (dbAdapterPtr_->GetDataByKeyPrefix(deviceId, dataVector) != DH_FWK_SUCCESS) {
95         DHLOGE("Query data from DB by deviceId failed, id: %{public}s", GetAnonyString(deviceId).c_str());
96         return ERR_DH_FWK_RESOURCE_DB_ADAPTER_OPERATION_FAIL;
97     }
98     if (dataVector.empty() || dataVector.size() > MAX_DB_RECORD_SIZE) {
99         DHLOGE("On dataVector error, maybe empty or too large.");
100         return ERR_DH_FWK_RESOURCE_RES_DB_DATA_INVALID;
101     }
102     for (const auto &data : dataVector) {
103         std::shared_ptr<CapabilityInfo> capabilityInfo;
104         if (GetCapabilityByValue<CapabilityInfo>(data, capabilityInfo) != DH_FWK_SUCCESS) {
105             DHLOGE("Get capability ptr by value failed");
106             continue;
107         }
108         globalCapInfoMap_[capabilityInfo->GetKey()] = capabilityInfo;
109     }
110     return DH_FWK_SUCCESS;
111 }
112 
AddCapability(const std::vector<std::shared_ptr<CapabilityInfo>> & resInfos)113 int32_t LocalCapabilityInfoManager::AddCapability(const std::vector<std::shared_ptr<CapabilityInfo>> &resInfos)
114 {
115     if (resInfos.empty() || resInfos.size() > MAX_DB_RECORD_SIZE) {
116         DHLOGE("resInfo is empty or too large!");
117         return ERR_DH_FWK_RESOURCE_RES_DB_DATA_INVALID;
118     }
119     std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
120     if (dbAdapterPtr_ == nullptr) {
121         DHLOGE("dbAdapterPtr_ is null");
122         return ERR_DH_FWK_RESOURCE_DB_ADAPTER_POINTER_NULL;
123     }
124     std::vector<std::string> keys;
125     std::vector<std::string> values;
126     std::string key;
127     for (auto &resInfo : resInfos) {
128         if (resInfo == nullptr) {
129             continue;
130         }
131         key = resInfo->GetKey();
132         globalCapInfoMap_[key] = resInfo;
133         DHLOGI("AddCapability, Key: %{public}s", resInfo->GetAnonymousKey().c_str());
134         keys.push_back(key);
135         values.push_back(resInfo->ToJsonString());
136     }
137     if (keys.empty() || values.empty()) {
138         DHLOGD("Records are empty, No need add data to db!");
139         return DH_FWK_SUCCESS;
140     }
141     if (dbAdapterPtr_->PutDataBatch(keys, values) != DH_FWK_SUCCESS) {
142         DHLOGE("Fail to storage batch to kv");
143         return ERR_DH_FWK_RESOURCE_DB_ADAPTER_OPERATION_FAIL;
144     }
145     return DH_FWK_SUCCESS;
146 }
147 
RemoveCapabilityInfoByKey(const std::string & key)148 int32_t LocalCapabilityInfoManager::RemoveCapabilityInfoByKey(const std::string &key)
149 {
150     if (!IsKeySizeValid(key)) {
151         return ERR_DH_FWK_PARA_INVALID;
152     }
153     DHLOGI("Remove capability device info, key: %{public}s", GetAnonyString(key).c_str());
154     std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
155     if (dbAdapterPtr_ == nullptr) {
156         DHLOGE("dbAdapterPtr_ is null");
157         return ERR_DH_FWK_RESOURCE_DB_ADAPTER_POINTER_NULL;
158     }
159     // 1. Clear the cache in the memory.
160     globalCapInfoMap_.erase(key);
161 
162     // 2. Delete the corresponding record from the database.(use key)
163     if (dbAdapterPtr_->RemoveDataByKey(key) != DH_FWK_SUCCESS) {
164         DHLOGE("Remove capability Device Data failed, key: %{public}s", GetAnonyString(key).c_str());
165         return ERR_DH_FWK_RESOURCE_DB_ADAPTER_OPERATION_FAIL;
166     }
167     return DH_FWK_SUCCESS;
168 }
169 
GetCapabilitiesByDeviceId(const std::string & deviceId,std::vector<std::shared_ptr<CapabilityInfo>> & resInfos)170 void LocalCapabilityInfoManager::GetCapabilitiesByDeviceId(const std::string &deviceId,
171     std::vector<std::shared_ptr<CapabilityInfo>> &resInfos)
172 {
173     if (!IsIdLengthValid(deviceId)) {
174         return;
175     }
176     std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
177     for (auto &capabilityInfo : globalCapInfoMap_) {
178         if (IsCapKeyMatchDeviceId(capabilityInfo.first, deviceId)) {
179             resInfos.emplace_back(capabilityInfo.second);
180         }
181     }
182 }
183 
GetCapability(const std::string & deviceId,const std::string & dhId,std::shared_ptr<CapabilityInfo> & capPtr)184 int32_t LocalCapabilityInfoManager::GetCapability(const std::string &deviceId, const std::string &dhId,
185     std::shared_ptr<CapabilityInfo> &capPtr)
186 {
187     if (!IsIdLengthValid(deviceId) || !IsIdLengthValid(dhId)) {
188         return ERR_DH_FWK_PARA_INVALID;
189     }
190     std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
191     std::string key = GetCapabilityKey(deviceId, dhId);
192     if (globalCapInfoMap_.find(key) == globalCapInfoMap_.end()) {
193         DHLOGE("Can not find capability In globalCapInfoMap_: %{public}s", GetAnonyString(deviceId).c_str());
194         return ERR_DH_FWK_RESOURCE_CAPABILITY_MAP_NOT_FOUND;
195     }
196     capPtr = globalCapInfoMap_[key];
197     return DH_FWK_SUCCESS;
198 }
199 
GetDataByKey(const std::string & key,std::shared_ptr<CapabilityInfo> & capInfoPtr)200 int32_t LocalCapabilityInfoManager::GetDataByKey(const std::string &key, std::shared_ptr<CapabilityInfo> &capInfoPtr)
201 {
202     if (!IsIdLengthValid(key)) {
203         return ERR_DH_FWK_PARA_INVALID;
204     }
205     std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
206     if (dbAdapterPtr_ == nullptr) {
207         DHLOGI("dbAdapterPtr_ is null");
208         return ERR_DH_FWK_RESOURCE_DB_ADAPTER_POINTER_NULL;
209     }
210     std::string data;
211     if (dbAdapterPtr_->GetDataByKey(key, data) != DH_FWK_SUCCESS) {
212         DHLOGE("Query capability info from db failed, key: %{public}s", GetAnonyString(key).c_str());
213         return ERR_DH_FWK_RESOURCE_DB_ADAPTER_OPERATION_FAIL;
214     }
215     return GetCapabilityByValue<CapabilityInfo>(data, capInfoPtr);
216 }
217 
GetDataByDHType(const DHType dhType,CapabilityInfoMap & capabilityMap)218 int32_t LocalCapabilityInfoManager::GetDataByDHType(const DHType dhType, CapabilityInfoMap &capabilityMap)
219 {
220     std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
221     for (const auto &capInfo : globalCapInfoMap_) {
222         if (capInfo.second->GetDHType() != dhType) {
223             continue;
224         }
225         capabilityMap[capInfo.first] = capInfo.second;
226     }
227     return DH_FWK_SUCCESS;
228 }
229 
GetDataByKeyPrefix(const std::string & keyPrefix,CapabilityInfoMap & capabilityMap)230 int32_t LocalCapabilityInfoManager::GetDataByKeyPrefix(const std::string &keyPrefix, CapabilityInfoMap &capabilityMap)
231 {
232     if (!IsKeySizeValid(keyPrefix)) {
233         return ERR_DH_FWK_PARA_INVALID;
234     }
235     std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
236     if (dbAdapterPtr_ == nullptr) {
237         DHLOGE("dbAdapterPtr is null");
238         return ERR_DH_FWK_RESOURCE_DB_ADAPTER_POINTER_NULL;
239     }
240     std::vector<std::string> dataVector;
241     if (dbAdapterPtr_->GetDataByKeyPrefix(keyPrefix, dataVector) != DH_FWK_SUCCESS) {
242         DHLOGE("Query capability info from db failed, key: %{public}s", GetAnonyString(keyPrefix).c_str());
243         return ERR_DH_FWK_RESOURCE_DB_ADAPTER_OPERATION_FAIL;
244     }
245     if (dataVector.empty() || dataVector.size() > MAX_DB_RECORD_SIZE) {
246         DHLOGE("On dataVector error, maybe empty or too large!");
247         return ERR_DH_FWK_RESOURCE_RES_DB_DATA_INVALID;
248     }
249     for (const auto &data : dataVector) {
250         std::shared_ptr<CapabilityInfo> capabilityInfo;
251         if (GetCapabilityByValue<CapabilityInfo>(data, capabilityInfo) != DH_FWK_SUCCESS) {
252             DHLOGE("Get capability ptr by value failed");
253             continue;
254         }
255         if (capabilityInfo->FromJsonString(data) != DH_FWK_SUCCESS) {
256             DHLOGE("Wrong data: %{public}s", GetAnonyString(data).c_str());
257             continue;
258         }
259         capabilityMap[capabilityInfo->GetKey()] = capabilityInfo;
260     }
261     return DH_FWK_SUCCESS;
262 }
263 
RemoveLocalInfoInMemByUuid(const std::string & peeruuid)264 int32_t LocalCapabilityInfoManager::RemoveLocalInfoInMemByUuid(const std::string &peeruuid)
265 {
266     DHLOGI("remove device localinfo in memory, peerudid: %{public}s", GetAnonyString(peeruuid).c_str());
267     std::string deviceId = Sha256(peeruuid);
268     for (auto iter = globalCapInfoMap_.begin(); iter != globalCapInfoMap_.end();) {
269         if (!IsCapKeyMatchDeviceId(iter->first, deviceId)) {
270             DHLOGI("not find deviceId: %{public}s", GetAnonyString(deviceId).c_str());
271             iter++;
272             continue;
273         }
274         globalCapInfoMap_.erase(iter++);
275     }
276     return DH_FWK_SUCCESS;
277 }
278 
ClearRemoteDeviceLocalInfoData(const std::string & peeruuid)279 int32_t LocalCapabilityInfoManager::ClearRemoteDeviceLocalInfoData(const std::string &peeruuid)
280 {
281     std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
282     if (dbAdapterPtr_ == nullptr) {
283         DHLOGE("dbAdapterPtr is null");
284         return ERR_DH_FWK_RESOURCE_DB_ADAPTER_POINTER_NULL;
285     }
286     dbAdapterPtr_->ClearDataByPrefix(peeruuid);
287     RemoveLocalInfoInMemByUuid(peeruuid);
288     return DH_FWK_SUCCESS;
289 }
290 } // namespace DistributedHardware
291 } // namespace OHOS
292