• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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