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