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