1 /*
2 * Copyright (c) 2022 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 "version_info_manager.h"
17
18 #include "anonymous_string.h"
19 #include "constants.h"
20 #include "dh_context.h"
21 #include "dh_utils_tool.h"
22 #include "distributed_hardware_errno.h"
23 #include "distributed_hardware_log.h"
24 #include "task_executor.h"
25 #include "task_factory.h"
26 #include "version_info_event.h"
27 #include "version_manager.h"
28
29 class DBAdapter;
30 namespace OHOS {
31 namespace DistributedHardware {
32 #undef DH_LOG_TAG
33 #define DH_LOG_TAG "VersionInfoManager"
34
VersionInfoManager()35 VersionInfoManager::VersionInfoManager() : dbAdapterPtr_(nullptr)
36 {}
37
~VersionInfoManager()38 VersionInfoManager::~VersionInfoManager()
39 {
40 DHLOGI("VersionInfoManager Destruction!");
41 }
42
VersionInfoManagerEventHandler(const std::shared_ptr<AppExecFwk::EventRunner> & runner,std::shared_ptr<VersionInfoManager> versionInfoMgrPtr)43 VersionInfoManager::VersionInfoManagerEventHandler::VersionInfoManagerEventHandler(
44 const std::shared_ptr<AppExecFwk::EventRunner> &runner, std::shared_ptr<VersionInfoManager> versionInfoMgrPtr)
45 : AppExecFwk::EventHandler(runner)
46 {
47 DHLOGI("Ctor VersionInfoManagerEventHandler");
48 versionInfoMgrWPtr_ = versionInfoMgrPtr;
49 }
50
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)51 void VersionInfoManager::VersionInfoManagerEventHandler::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
52 {
53 uint32_t eventId = event->GetInnerEventId();
54 auto selfPtr = versionInfoMgrWPtr_.lock();
55 if (!selfPtr) {
56 DHLOGE("Can not get strong self ptr");
57 return;
58 }
59 switch (eventId) {
60 case EVENT_VERSION_INFO_DB_RECOVER:
61 selfPtr->SyncRemoteVersionInfos();
62 break;
63 default:
64 DHLOGE("event is undefined, id is %d", eventId);
65 break;
66 }
67 }
68
GetEventHandler()69 std::shared_ptr<VersionInfoManager::VersionInfoManagerEventHandler> VersionInfoManager::GetEventHandler()
70 {
71 return this->eventHandler_;
72 }
73
GetInstance()74 std::shared_ptr<VersionInfoManager> VersionInfoManager::GetInstance()
75 {
76 static std::shared_ptr<VersionInfoManager> instance(new(std::nothrow) VersionInfoManager);
77 if (instance == nullptr) {
78 DHLOGE("instance is nullptr, because applying memory fail!");
79 return nullptr;
80 }
81 return instance;
82 }
83
Init()84 int32_t VersionInfoManager::Init()
85 {
86 DHLOGI("VersionInfoManager instance init!");
87 std::lock_guard<std::mutex> lock(verInfoMgrMutex_);
88 dbAdapterPtr_ = std::make_shared<DBAdapter>(APP_ID, GLOBAL_VERSION_ID, shared_from_this());
89 if (dbAdapterPtr_->Init() != DH_FWK_SUCCESS) {
90 DHLOGE("Init dbAdapterPtr_ failed");
91 return ERR_DH_FWK_RESOURCE_INIT_DB_FAILED;
92 }
93
94 std::shared_ptr<AppExecFwk::EventRunner> runner = AppExecFwk::EventRunner::Create(true);
95 eventHandler_ = std::make_shared<VersionInfoManager::VersionInfoManagerEventHandler>(
96 runner, shared_from_this());
97 DHLOGI("VersionInfoManager instance init success");
98 return DH_FWK_SUCCESS;
99 }
100
UnInit()101 int32_t VersionInfoManager::UnInit()
102 {
103 DHLOGI("VersionInfoManager UnInit");
104 std::lock_guard<std::mutex> lock(verInfoMgrMutex_);
105 if (dbAdapterPtr_ == nullptr) {
106 DHLOGE("dbAdapterPtr_ is null");
107 return ERR_DH_FWK_RESOURCE_UNINIT_DB_FAILED;
108 }
109 dbAdapterPtr_->UnInit();
110 dbAdapterPtr_.reset();
111 return DH_FWK_SUCCESS;
112 }
113
AddVersion(const VersionInfo & versionInfo)114 int32_t VersionInfoManager::AddVersion(const VersionInfo &versionInfo)
115 {
116 std::lock_guard<std::mutex> lock(verInfoMgrMutex_);
117 if (dbAdapterPtr_ == nullptr) {
118 DHLOGE("dbAdapterPtr_ is null");
119 return ERR_DH_FWK_RESOURCE_DB_ADAPTER_POINTER_NULL;
120 }
121
122 std::string data("");
123 dbAdapterPtr_->GetDataByKey(versionInfo.deviceId, data);
124 if (data.compare(versionInfo.ToJsonString()) == 0) {
125 DHLOGI("dhversion already stored, Key: %s", GetAnonyString(versionInfo.deviceId).c_str());
126 return DH_FWK_SUCCESS;
127 }
128
129 std::string key = versionInfo.deviceId;
130 std::string value = versionInfo.ToJsonString();
131 DHLOGI("AddVersion, Key: %s", GetAnonyString(versionInfo.deviceId).c_str());
132 if (dbAdapterPtr_->PutData(key, value) != DH_FWK_SUCCESS) {
133 DHLOGE("Fail to storage to kv");
134 return ERR_DH_FWK_RESOURCE_DB_ADAPTER_OPERATION_FAIL;
135 }
136 return DH_FWK_SUCCESS;
137 }
138
GetVersionInfoByDeviceId(const std::string & deviceId,VersionInfo & versionInfo)139 int32_t VersionInfoManager::GetVersionInfoByDeviceId(const std::string &deviceId, VersionInfo &versionInfo)
140 {
141 std::lock_guard<std::mutex> lock(verInfoMgrMutex_);
142 if (dbAdapterPtr_ == nullptr) {
143 DHLOGE("dbAdapterPtr_ is null");
144 return ERR_DH_FWK_RESOURCE_DB_ADAPTER_POINTER_NULL;
145 }
146 std::string data("");
147 if (dbAdapterPtr_->GetDataByKey(deviceId, data) != DH_FWK_SUCCESS) {
148 DHLOGE("Query data from DB by deviceId failed, deviceId: %s", GetAnonyString(deviceId).c_str());
149 return ERR_DH_FWK_RESOURCE_DB_ADAPTER_OPERATION_FAIL;
150 }
151 return versionInfo.FromJsonString(data);
152 }
153
UpdateVersionCache(const VersionInfo & versionInfo)154 void VersionInfoManager::UpdateVersionCache(const VersionInfo &versionInfo)
155 {
156 std::string uuid = DHContext::GetInstance().GetUUIDByDeviceId(versionInfo.deviceId);
157 if (uuid.empty()) {
158 DHLOGI("Find uuid failed, deviceId: %s", GetAnonyString(versionInfo.deviceId).c_str());
159 return;
160 }
161 DHVersion dhVersion;
162 dhVersion.uuid = uuid;
163 dhVersion.dhVersion = versionInfo.dhVersion;
164 dhVersion.compVersions = versionInfo.compVersions;
165 VersionManager::GetInstance().AddDHVersion(uuid, dhVersion);
166 }
167
RemoveVersionInfoByDeviceId(const std::string & deviceId)168 int32_t VersionInfoManager::RemoveVersionInfoByDeviceId(const std::string &deviceId)
169 {
170 DHLOGI("Remove version device info, key: %s", GetAnonyString(deviceId).c_str());
171 std::lock_guard<std::mutex> lock(verInfoMgrMutex_);
172 if (dbAdapterPtr_ == nullptr) {
173 DHLOGE("dbAdapterPtr_ is null");
174 return ERR_DH_FWK_RESOURCE_DB_ADAPTER_POINTER_NULL;
175 }
176
177 if (dbAdapterPtr_->RemoveDataByKey(deviceId) != DH_FWK_SUCCESS) {
178 DHLOGE("Remove version info failed, key: %s", GetAnonyString(deviceId).c_str());
179 return ERR_DH_FWK_RESOURCE_DB_ADAPTER_OPERATION_FAIL;
180 }
181
182 std::string uuid = DHContext::GetInstance().GetUUIDByDeviceId(deviceId);
183 if (uuid.empty()) {
184 DHLOGI("Find uuid failed, deviceId: %s", GetAnonyString(deviceId).c_str());
185 return ERR_DH_FWK_RESOURCE_UUID_NOT_FOUND;
186 }
187 DHLOGI("Delete version ,uuid: %s", GetAnonyString(uuid).c_str());
188 VersionManager::GetInstance().RemoveDHVersion(uuid);
189
190 return DH_FWK_SUCCESS;
191 }
192
SyncVersionInfoFromDB(const std::string & deviceId)193 int32_t VersionInfoManager::SyncVersionInfoFromDB(const std::string &deviceId)
194 {
195 DHLOGI("Sync versionInfo from DB, deviceId: %s", GetAnonyString(deviceId).c_str());
196 std::lock_guard<std::mutex> lock(verInfoMgrMutex_);
197 if (dbAdapterPtr_ == nullptr) {
198 DHLOGE("dbAdapterPtr_ is null");
199 return ERR_DH_FWK_RESOURCE_DB_ADAPTER_POINTER_NULL;
200 }
201 std::string data("");
202 if (dbAdapterPtr_->GetDataByKey(deviceId, data) != DH_FWK_SUCCESS) {
203 DHLOGE("Query data from DB by deviceId failed, deviceId: %s", GetAnonyString(deviceId).c_str());
204 return ERR_DH_FWK_RESOURCE_DB_ADAPTER_OPERATION_FAIL;
205 }
206
207 DHLOGI("Query data from DB by deviceId success, deviceId: %s", GetAnonyString(deviceId).c_str());
208 VersionInfo versionInfo;
209 int32_t ret = versionInfo.FromJsonString(data);
210 if (ret != DH_FWK_SUCCESS) {
211 return ret;
212 }
213 UpdateVersionCache(versionInfo);
214 return DH_FWK_SUCCESS;
215 }
216
SyncRemoteVersionInfos()217 int32_t VersionInfoManager::SyncRemoteVersionInfos()
218 {
219 DHLOGI("Sync full remote version info from DB");
220 std::lock_guard<std::mutex> lock(verInfoMgrMutex_);
221 if (dbAdapterPtr_ == nullptr) {
222 DHLOGE("dbAdapterPtr_ is null");
223 return ERR_DH_FWK_RESOURCE_DB_ADAPTER_POINTER_NULL;
224 }
225 std::vector<std::string> dataVector;
226 if (dbAdapterPtr_->GetDataByKeyPrefix("", dataVector) != DH_FWK_SUCCESS) {
227 DHLOGE("Query all data from DB failed");
228 return ERR_DH_FWK_RESOURCE_DB_ADAPTER_OPERATION_FAIL;
229 }
230 if (dataVector.size() == 0 || dataVector.size() > MAX_DB_RECORD_SIZE) {
231 DHLOGE("DataVector Size is invalid!");
232 return ERR_DH_FWK_RESOURCE_RES_DB_DATA_INVALID;
233 }
234 for (const auto &data : dataVector) {
235 VersionInfo versionInfo;
236 if (versionInfo.FromJsonString(data) != DH_FWK_SUCCESS) {
237 continue;
238 }
239 const std::string &deviceId = versionInfo.deviceId;
240 const std::string &localDeviceId = DHContext::GetInstance().GetDeviceInfo().deviceId;
241 if (deviceId.compare(localDeviceId) == 0) {
242 DHLOGE("Local device info not need sync from db");
243 continue;
244 }
245 if (!DHContext::GetInstance().IsDeviceOnline(deviceId)) {
246 DHLOGE("Offline device, no need sync to memory, deviceId : %s ",
247 GetAnonyString(deviceId).c_str());
248 continue;
249 }
250 UpdateVersionCache(versionInfo);
251 }
252 return DH_FWK_SUCCESS;
253 }
254
OnChange(const DistributedKv::ChangeNotification & changeNotification)255 void VersionInfoManager::OnChange(const DistributedKv::ChangeNotification &changeNotification)
256 {
257 DHLOGI("DB data OnChange");
258 if (!changeNotification.GetInsertEntries().empty() &&
259 changeNotification.GetInsertEntries().size() <= MAX_DB_RECORD_SIZE) {
260 DHLOGI("Handle version data add change");
261 HandleVersionAddChange(changeNotification.GetInsertEntries());
262 }
263 if (!changeNotification.GetUpdateEntries().empty() &&
264 changeNotification.GetUpdateEntries().size() <= MAX_DB_RECORD_SIZE) {
265 DHLOGI("Handle version data update change");
266 HandleVersionUpdateChange(changeNotification.GetUpdateEntries());
267 }
268 if (!changeNotification.GetDeleteEntries().empty() &&
269 changeNotification.GetDeleteEntries().size() <= MAX_DB_RECORD_SIZE) {
270 DHLOGI("Handle version data delete change");
271 HandleVersionDeleteChange(changeNotification.GetDeleteEntries());
272 }
273 }
274
HandleVersionAddChange(const std::vector<DistributedKv::Entry> & insertRecords)275 void VersionInfoManager::HandleVersionAddChange(const std::vector<DistributedKv::Entry> &insertRecords)
276 {
277 DHLOGI("Version add change");
278 for (const auto &item : insertRecords) {
279 const std::string value = item.value.ToString();
280 VersionInfo versionInfo;
281 if (versionInfo.FromJsonString(value) != DH_FWK_SUCCESS) {
282 continue;
283 }
284 UpdateVersionCache(versionInfo);
285 }
286 }
287
HandleVersionUpdateChange(const std::vector<DistributedKv::Entry> & updateRecords)288 void VersionInfoManager::HandleVersionUpdateChange(const std::vector<DistributedKv::Entry> &updateRecords)
289 {
290 DHLOGI("Version update change");
291 for (const auto &item : updateRecords) {
292 const std::string value = item.value.ToString();
293 VersionInfo versionInfo;
294 if (versionInfo.FromJsonString(value) != DH_FWK_SUCCESS) {
295 continue;
296 }
297 UpdateVersionCache(versionInfo);
298 }
299 }
300
HandleVersionDeleteChange(const std::vector<DistributedKv::Entry> & deleteRecords)301 void VersionInfoManager::HandleVersionDeleteChange(const std::vector<DistributedKv::Entry> &deleteRecords)
302 {
303 DHLOGI("Version delete change");
304 for (const auto &item : deleteRecords) {
305 const std::string value = item.value.ToString();
306 VersionInfo versionInfo;
307 if (versionInfo.FromJsonString(value) != DH_FWK_SUCCESS) {
308 continue;
309 }
310 std::string uuid = DHContext::GetInstance().GetUUIDByDeviceId(versionInfo.deviceId);
311 if (uuid.empty()) {
312 DHLOGI("Find uuid failed, deviceId: %s", GetAnonyString(versionInfo.deviceId).c_str());
313 continue;
314 }
315 DHLOGI("Delete version ,uuid: %s", GetAnonyString(uuid).c_str());
316 VersionManager::GetInstance().RemoveDHVersion(uuid);
317 }
318 }
319 } // namespace DistributedHardware
320 } // namespace OHOS
321