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