1 /*
2 * Copyright (c) 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 "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) || resInfos.empty() || resInfos.size() > MAX_DB_RECORD_SIZE) {
172 DHLOGE("On parameter error, maybe empty or too large!");
173 return;
174 }
175 std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
176 for (auto &capabilityInfo : globalCapInfoMap_) {
177 if (IsCapKeyMatchDeviceId(capabilityInfo.first, deviceId)) {
178 resInfos.emplace_back(capabilityInfo.second);
179 }
180 }
181 }
182
GetCapability(const std::string & deviceId,const std::string & dhId,std::shared_ptr<CapabilityInfo> & capPtr)183 int32_t LocalCapabilityInfoManager::GetCapability(const std::string &deviceId, const std::string &dhId,
184 std::shared_ptr<CapabilityInfo> &capPtr)
185 {
186 if (!IsIdLengthValid(deviceId) || !IsIdLengthValid(dhId)) {
187 return ERR_DH_FWK_PARA_INVALID;
188 }
189 std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
190 std::string key = GetCapabilityKey(deviceId, dhId);
191 if (globalCapInfoMap_.find(key) == globalCapInfoMap_.end()) {
192 DHLOGE("Can not find capability In globalCapInfoMap_: %{public}s", GetAnonyString(deviceId).c_str());
193 return ERR_DH_FWK_RESOURCE_CAPABILITY_MAP_NOT_FOUND;
194 }
195 capPtr = globalCapInfoMap_[key];
196 return DH_FWK_SUCCESS;
197 }
198
GetDataByKey(const std::string & key,std::shared_ptr<CapabilityInfo> & capInfoPtr)199 int32_t LocalCapabilityInfoManager::GetDataByKey(const std::string &key, std::shared_ptr<CapabilityInfo> &capInfoPtr)
200 {
201 if (!IsIdLengthValid(key)) {
202 return ERR_DH_FWK_PARA_INVALID;
203 }
204 std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
205 if (dbAdapterPtr_ == nullptr) {
206 DHLOGI("dbAdapterPtr_ is null");
207 return ERR_DH_FWK_RESOURCE_DB_ADAPTER_POINTER_NULL;
208 }
209 std::string data;
210 if (dbAdapterPtr_->GetDataByKey(key, data) != DH_FWK_SUCCESS) {
211 DHLOGE("Query capability info from db failed, key: %{public}s", GetAnonyString(key).c_str());
212 return ERR_DH_FWK_RESOURCE_DB_ADAPTER_OPERATION_FAIL;
213 }
214 return GetCapabilityByValue<CapabilityInfo>(data, capInfoPtr);
215 }
216
GetDataByDHType(const DHType dhType,CapabilityInfoMap & capabilityMap)217 int32_t LocalCapabilityInfoManager::GetDataByDHType(const DHType dhType, CapabilityInfoMap &capabilityMap)
218 {
219 std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
220 for (const auto &capInfo : globalCapInfoMap_) {
221 if (capInfo.second->GetDHType() != dhType) {
222 continue;
223 }
224 capabilityMap[capInfo.first] = capInfo.second;
225 }
226 return DH_FWK_SUCCESS;
227 }
228
GetDataByKeyPrefix(const std::string & keyPrefix,CapabilityInfoMap & capabilityMap)229 int32_t LocalCapabilityInfoManager::GetDataByKeyPrefix(const std::string &keyPrefix, CapabilityInfoMap &capabilityMap)
230 {
231 if (!IsKeySizeValid(keyPrefix)) {
232 return ERR_DH_FWK_PARA_INVALID;
233 }
234 std::lock_guard<std::mutex> lock(capInfoMgrMutex_);
235 if (dbAdapterPtr_ == nullptr) {
236 DHLOGE("dbAdapterPtr is null");
237 return ERR_DH_FWK_RESOURCE_DB_ADAPTER_POINTER_NULL;
238 }
239 std::vector<std::string> dataVector;
240 if (dbAdapterPtr_->GetDataByKeyPrefix(keyPrefix, dataVector) != DH_FWK_SUCCESS) {
241 DHLOGE("Query capability info from db failed, key: %{public}s", GetAnonyString(keyPrefix).c_str());
242 return ERR_DH_FWK_RESOURCE_DB_ADAPTER_OPERATION_FAIL;
243 }
244 if (dataVector.empty() || dataVector.size() > MAX_DB_RECORD_SIZE) {
245 DHLOGE("On dataVector error, maybe empty or too large!");
246 return ERR_DH_FWK_RESOURCE_RES_DB_DATA_INVALID;
247 }
248 for (const auto &data : dataVector) {
249 std::shared_ptr<CapabilityInfo> capabilityInfo;
250 if (GetCapabilityByValue<CapabilityInfo>(data, capabilityInfo) != DH_FWK_SUCCESS) {
251 DHLOGE("Get capability ptr by value failed");
252 continue;
253 }
254 if (capabilityInfo->FromJsonString(data) != DH_FWK_SUCCESS) {
255 DHLOGE("Wrong data: %{public}s", GetAnonyString(data).c_str());
256 continue;
257 }
258 capabilityMap[capabilityInfo->GetKey()] = capabilityInfo;
259 }
260 return DH_FWK_SUCCESS;
261 }
262 } // namespace DistributedHardware
263 } // namespace OHOS
264