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