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 "form_info_rdb_storage_mgr.h"
17
18 #include <cinttypes>
19 #include <thread>
20 #include <unistd.h>
21 #include "fms_log_wrapper.h"
22 #include "form_constants.h"
23
24 namespace OHOS {
25 namespace AppExecFwk {
26 namespace {
27 constexpr int32_t MAX_TIMES = 600; // 600 * 100ms = 1min
28 constexpr int32_t SLEEP_INTERVAL = 100 * 1000; // 100ms
29 const std::string FORM_INFO_PREFIX = "formInfo_";
30 const std::string FORM_ID_PREFIX = "formId_";
31 const std::string STATUS_DATA_PREFIX = "statusData_";
32 } // namespace
33
FormInfoRdbStorageMgr()34 FormInfoRdbStorageMgr::FormInfoRdbStorageMgr()
35 {
36 FormRdbConfig formRdbConfig;
37 rdbDataManager_ = std::make_shared<FormRdbDataMgr>(formRdbConfig);
38 rdbDataManager_->Init();
39 HILOG_DEBUG("FormInfoRdbStorageMgr is created");
40 }
41
~FormInfoRdbStorageMgr()42 FormInfoRdbStorageMgr::~FormInfoRdbStorageMgr()
43 {
44 HILOG_DEBUG("FormInfoRdbStorageMgr is deleted");
45 }
46
LoadFormInfos(std::vector<std::pair<std::string,std::string>> & formInfoStorages)47 ErrCode FormInfoRdbStorageMgr::LoadFormInfos(std::vector<std::pair<std::string, std::string>> &formInfoStorages)
48 {
49 HILOG_DEBUG("FormInfoAllRdbStorageMgr load all form infos");
50 {
51 std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
52 if (!CheckRdbStore()) {
53 HILOG_ERROR("RdbStore is nullptr");
54 return ERR_APPEXECFWK_FORM_COMMON_CODE;
55 }
56 }
57
58 std::unordered_map<std::string, std::string> value;
59 ErrCode result = rdbDataManager_->QueryData(FORM_INFO_PREFIX, value);
60 if (result != ERR_OK) {
61 HILOG_ERROR("get entries error");
62 return ERR_APPEXECFWK_FORM_COMMON_CODE;
63 }
64
65 for (const auto &item: value) {
66 formInfoStorages.emplace_back(item.first.substr(FORM_INFO_PREFIX.length()), item.second);
67 }
68
69 return ERR_OK;
70 }
71
RemoveBundleFormInfos(const std::string & bundleName)72 ErrCode FormInfoRdbStorageMgr::RemoveBundleFormInfos(const std::string &bundleName)
73 {
74 if (bundleName.empty()) {
75 HILOG_ERROR("bundleName is empty.");
76 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
77 }
78
79 HILOG_DEBUG("FormInfoRdbStorageMgr remove form info, bundleName=%{public}s", bundleName.c_str());
80 {
81 std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
82 if (!CheckRdbStore()) {
83 HILOG_ERROR("RdbStore is nullptr");
84 return ERR_APPEXECFWK_FORM_COMMON_CODE;
85 }
86 }
87
88 std::string key = std::string().append(FORM_INFO_PREFIX).append(bundleName);
89 ErrCode result;
90 {
91 std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
92 result = rdbDataManager_->DeleteData(key);
93 }
94
95 if (result != ERR_OK) {
96 HILOG_ERROR("remove formInfoStorages from rdbStore error");
97 return ERR_APPEXECFWK_FORM_COMMON_CODE;
98 }
99 return ERR_OK;
100 }
101
UpdateBundleFormInfos(const std::string & bundleName,const std::string & formInfoStorages)102 ErrCode FormInfoRdbStorageMgr::UpdateBundleFormInfos(const std::string &bundleName, const std::string &formInfoStorages)
103 {
104 if (bundleName.empty()) {
105 HILOG_ERROR("bundleName is empty.");
106 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
107 }
108
109 HILOG_DEBUG("FormInfoRdbStorageMgr update form info, bundleName=%{public}s", bundleName.c_str());
110 {
111 std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
112 if (!CheckRdbStore()) {
113 HILOG_ERROR("RdbStore is nullptr");
114 return ERR_APPEXECFWK_FORM_COMMON_CODE;
115 }
116 }
117 std::string key = std::string().append(FORM_INFO_PREFIX).append(bundleName);
118 ErrCode result;
119 std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
120 std::string value = formInfoStorages;
121 result = rdbDataManager_->InsertData(key, value);
122 if (result != ERR_OK) {
123 HILOG_ERROR("update formInfoStorages to rdbStore error");
124 return ERR_APPEXECFWK_FORM_COMMON_CODE;
125 }
126 return ERR_OK;
127 }
128
CheckRdbStore()129 bool FormInfoRdbStorageMgr::CheckRdbStore()
130 {
131 if (rdbDataManager_ == nullptr) {
132 HILOG_ERROR("rdbDataManager is null");
133 return false;
134 }
135 int32_t tryTimes = MAX_TIMES;
136 while (tryTimes > 0) {
137 ErrCode result = rdbDataManager_->Init();
138 if (result == ERR_OK) {
139 return true;
140 }
141 HILOG_DEBUG("CheckRdbStore, Times: %{public}d", tryTimes);
142 usleep(SLEEP_INTERVAL);
143 tryTimes--;
144 }
145 return false;
146 }
147
SaveEntries(const std::unordered_map<std::string,std::string> & value,std::vector<InnerFormInfo> & innerFormInfos)148 void FormInfoRdbStorageMgr::SaveEntries(
149 const std::unordered_map<std::string, std::string> &value, std::vector<InnerFormInfo> &innerFormInfos)
150 {
151 for (const auto &item : value) {
152 InnerFormInfo innerFormInfo;
153 nlohmann::json jsonObject = nlohmann::json::parse(item.second, nullptr, false);
154 if (jsonObject.is_discarded() || innerFormInfo.FromJson(jsonObject) != true) {
155 HILOG_ERROR("error key: %{private}s", item.first.c_str());
156 {
157 std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
158 if (!CheckRdbStore()) {
159 HILOG_ERROR("RdbStore is nullptr");
160 return;
161 }
162 rdbDataManager_->DeleteData(item.first);
163 }
164 continue;
165 }
166
167 if (std::find(innerFormInfos.begin(), innerFormInfos.end(), innerFormInfo) == innerFormInfos.end()) {
168 innerFormInfos.emplace_back(innerFormInfo);
169 }
170 }
171 HILOG_DEBUG("SaveEntries end");
172 }
173
LoadFormData(std::vector<InnerFormInfo> & innerFormInfos)174 ErrCode FormInfoRdbStorageMgr::LoadFormData(std::vector<InnerFormInfo> &innerFormInfos)
175 {
176 HILOG_DEBUG("%{public}s called.", __func__);
177 {
178 std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
179 if (!CheckRdbStore()) {
180 HILOG_ERROR("RdbStore is nullptr");
181 return ERR_APPEXECFWK_FORM_COMMON_CODE;
182 }
183 }
184 ErrCode result;
185 std::unordered_map<std::string, std::string> value;
186 {
187 std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
188 result = rdbDataManager_->QueryData(FORM_ID_PREFIX, value);
189 }
190 if (result != ERR_OK) {
191 HILOG_ERROR("get entries error");
192 return ERR_APPEXECFWK_FORM_COMMON_CODE;
193 }
194 SaveEntries(value, innerFormInfos);
195
196 HILOG_DEBUG("%{public}s end", __func__);
197 return ERR_OK;
198 }
199
SaveStorageFormData(const InnerFormInfo & innerFormInfo)200 ErrCode FormInfoRdbStorageMgr::SaveStorageFormData(const InnerFormInfo &innerFormInfo)
201 {
202 HILOG_DEBUG("%{public}s called, formId[%{public}" PRId64 "]", __func__, innerFormInfo.GetFormId());
203 {
204 std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
205 if (!CheckRdbStore()) {
206 HILOG_ERROR("RdbStore is nullptr");
207 return ERR_APPEXECFWK_FORM_COMMON_CODE;
208 }
209 }
210
211 std::string formId = std::to_string(innerFormInfo.GetFormId());
212 std::string key = std::string().append(FORM_ID_PREFIX).append(formId);
213 std::string value = innerFormInfo.ToString();
214 ErrCode result;
215 {
216 std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
217 result = rdbDataManager_->InsertData(key, value);
218 }
219 if (result != ERR_OK) {
220 HILOG_ERROR("put innerFormInfo to RdbStore error");
221 return ERR_APPEXECFWK_FORM_COMMON_CODE;
222 }
223 return ERR_OK;
224 }
225
ModifyStorageFormData(const InnerFormInfo & innerFormInfo)226 ErrCode FormInfoRdbStorageMgr::ModifyStorageFormData(const InnerFormInfo &innerFormInfo)
227 {
228 HILOG_DEBUG("%{public}s called, formId[%{public}" PRId64 "]", __func__, innerFormInfo.GetFormId());
229 std::string formId = std::to_string(innerFormInfo.GetFormId());
230 ErrCode ret = DeleteStorageFormData(formId);
231 if (ret == ERR_OK) {
232 SaveStorageFormData(innerFormInfo);
233 }
234
235 return ret;
236 }
237
DeleteStorageFormData(const std::string & formId)238 ErrCode FormInfoRdbStorageMgr::DeleteStorageFormData(const std::string &formId)
239 {
240 HILOG_DEBUG("%{public}s called, formId[%{public}s]", __func__, formId.c_str());
241 {
242 std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
243 if (!CheckRdbStore()) {
244 HILOG_ERROR("RdbStore is nullptr");
245 return ERR_APPEXECFWK_FORM_COMMON_CODE;
246 }
247 }
248 std::string key = std::string().append(FORM_ID_PREFIX).append(formId);
249 ErrCode result;
250 {
251 std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
252 result = rdbDataManager_->DeleteData(key);
253 }
254
255 if (result != ERR_OK) {
256 HILOG_ERROR("delete key error");
257 return ERR_APPEXECFWK_FORM_COMMON_CODE;
258 }
259
260 key = std::string().append(STATUS_DATA_PREFIX).append(formId);
261 {
262 std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
263 result = rdbDataManager_->DeleteData(key);
264 }
265 if (result != ERR_OK) {
266 HILOG_ERROR("delete status data of %{public}s failed", formId.c_str());
267 return ERR_APPEXECFWK_FORM_COMMON_CODE;
268 }
269
270 HILOG_DEBUG("delete value to RdbStore success");
271 return ERR_OK;
272 }
273
LoadStatusData(const std::string & formId,std::string & statusData)274 ErrCode FormInfoRdbStorageMgr::LoadStatusData(const std::string &formId, std::string &statusData)
275 {
276 HILOG_DEBUG("formId is %{public}s", formId.c_str());
277 if (formId.empty()) {
278 HILOG_ERROR("formId is empty");
279 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
280 }
281
282 ErrCode result;
283 std::string key = std::string().append(STATUS_DATA_PREFIX).append(formId);
284 {
285 std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
286 if (!CheckRdbStore()) {
287 HILOG_ERROR("RdbStore is nullptr");
288 return ERR_APPEXECFWK_FORM_COMMON_CODE;
289 }
290 result = rdbDataManager_->QueryData(key, statusData);
291 }
292 if (result != ERR_OK) {
293 HILOG_ERROR("load status data of %{public}s failed, code is %{public}d", formId.c_str(), result);
294 return ERR_APPEXECFWK_FORM_COMMON_CODE;
295 }
296
297 return ERR_OK;
298 }
299
UpdateStatusData(const std::string & formId,const std::string & statusData)300 ErrCode FormInfoRdbStorageMgr::UpdateStatusData(const std::string &formId, const std::string &statusData)
301 {
302 HILOG_DEBUG("formId is %{public}s", formId.c_str());
303 if (formId.empty() || statusData.empty()) {
304 HILOG_ERROR("formId or statusData is empty");
305 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
306 }
307
308 ErrCode result;
309 std::string key = std::string().append(STATUS_DATA_PREFIX).append(formId);
310 {
311 std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
312 if (!CheckRdbStore()) {
313 HILOG_ERROR("RdbStore is nullptr");
314 return ERR_APPEXECFWK_FORM_COMMON_CODE;
315 }
316 result = rdbDataManager_->InsertData(key, statusData);
317 }
318 if (result != ERR_OK) {
319 HILOG_ERROR("update status data of %{public}s to rdbstore failed, code is %{public}d", formId.c_str(), result);
320 return ERR_APPEXECFWK_FORM_COMMON_CODE;
321 }
322
323 return ERR_OK;
324 }
325 } // namespace AppExecFwk
326 } // namespace OHOS
327