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  #include "form_event_report.h"
24  
25  namespace OHOS {
26  namespace AppExecFwk {
27  namespace {
28  constexpr int32_t MAX_TIMES = 600; // 600 * 100ms = 1min
29  constexpr int32_t SLEEP_INTERVAL = 100 * 1000; // 100ms
30  const std::string FORM_INFO_PREFIX = "formInfo_";
31  const std::string FORM_ID_PREFIX = "formId_";
32  const std::string STATUS_DATA_PREFIX = "statusData_";
33  } // namespace
34  
FormInfoRdbStorageMgr()35  FormInfoRdbStorageMgr::FormInfoRdbStorageMgr()
36  {
37      HILOG_DEBUG("FormInfoRdbStorageMgr is created");
38      FormRdbTableConfig formRdbTableConfig;
39      if (FormRdbDataMgr::GetInstance().InitFormRdbTable(formRdbTableConfig) != ERR_OK) {
40          HILOG_ERROR("Form info rdb storage mgr init form rdb table fail");
41          FormEventReport::SendFormFailedEvent(FormEventName::INIT_FMS_FAILED, HiSysEventType::FAULT,
42              static_cast<int64_t>(InitFmsFiledErrorType::LOAD_FORM_DB_FAILED));
43      }
44  }
45  
~FormInfoRdbStorageMgr()46  FormInfoRdbStorageMgr::~FormInfoRdbStorageMgr()
47  {
48      HILOG_DEBUG("FormInfoRdbStorageMgr is deleted");
49  }
50  
LoadFormInfos(std::vector<std::pair<std::string,std::string>> & formInfoStorages)51  ErrCode FormInfoRdbStorageMgr::LoadFormInfos(std::vector<std::pair<std::string, std::string>> &formInfoStorages)
52  {
53      HILOG_DEBUG("FormInfoAllRdbStorageMgr load all form infos");
54      std::unordered_map<std::string, std::string> value;
55      ErrCode result = FormRdbDataMgr::GetInstance().QueryData(Constants::FORM_RDB_TABLE_NAME,
56          FORM_INFO_PREFIX, value);
57      if (result != ERR_OK) {
58          HILOG_ERROR("get entries error");
59          FormEventReport::SendFormFailedEvent(FormEventName::CALLEN_DB_FAILED, HiSysEventType::FAULT,
60              static_cast<int64_t>(CallDbFiledErrorType::LOAD_DATABASE_FAILED));
61          return ERR_APPEXECFWK_FORM_COMMON_CODE;
62      }
63  
64      for (const auto &item: value) {
65          formInfoStorages.emplace_back(item.first.substr(FORM_INFO_PREFIX.length()), item.second);
66      }
67  
68      return ERR_OK;
69  }
70  
RemoveBundleFormInfos(const std::string & bundleName)71  ErrCode FormInfoRdbStorageMgr::RemoveBundleFormInfos(const std::string &bundleName)
72  {
73      if (bundleName.empty()) {
74          HILOG_ERROR("empty bundleName");
75          return ERR_APPEXECFWK_FORM_INVALID_PARAM;
76      }
77  
78      HILOG_DEBUG("FormInfoRdbStorageMgr remove form info, bundleName=%{public}s", bundleName.c_str());
79  
80      std::string key = std::string().append(FORM_INFO_PREFIX).append(bundleName);
81      ErrCode result;
82      {
83          std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
84          result = FormRdbDataMgr::GetInstance().DeleteData(Constants::FORM_RDB_TABLE_NAME, key);
85      }
86  
87      if (result != ERR_OK) {
88          HILOG_ERROR("remove formInfoStorages from rdbStore error");
89          return ERR_APPEXECFWK_FORM_COMMON_CODE;
90      }
91      return ERR_OK;
92  }
93  
UpdateBundleFormInfos(const std::string & bundleName,const std::string & formInfoStorages)94  ErrCode FormInfoRdbStorageMgr::UpdateBundleFormInfos(const std::string &bundleName, const std::string &formInfoStorages)
95  {
96      if (bundleName.empty()) {
97          HILOG_ERROR("empty bundleName");
98          return ERR_APPEXECFWK_FORM_INVALID_PARAM;
99      }
100  
101      HILOG_DEBUG("FormInfoRdbStorageMgr update form info, bundleName=%{public}s", bundleName.c_str());
102      std::string key = std::string().append(FORM_INFO_PREFIX).append(bundleName);
103      std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
104      std::string value = formInfoStorages;
105      ErrCode result = FormRdbDataMgr::GetInstance().InsertData(Constants::FORM_RDB_TABLE_NAME, key, value);
106      if (result != ERR_OK) {
107          HILOG_ERROR("update formInfoStorages to rdbStore error");
108          return ERR_APPEXECFWK_FORM_COMMON_CODE;
109      }
110      return ERR_OK;
111  }
112  
SaveEntries(const std::unordered_map<std::string,std::string> & value,std::vector<InnerFormInfo> & innerFormInfos)113  void FormInfoRdbStorageMgr::SaveEntries(
114      const std::unordered_map<std::string, std::string> &value, std::vector<InnerFormInfo> &innerFormInfos)
115  {
116      for (const auto &item : value) {
117          InnerFormInfo innerFormInfo;
118          nlohmann::json jsonObject = nlohmann::json::parse(item.second, nullptr, false);
119          if (jsonObject.is_discarded() || innerFormInfo.FromJson(jsonObject) != true) {
120              HILOG_ERROR("error key: %{private}s", item.first.c_str());
121              FormRdbDataMgr::GetInstance().DeleteData(Constants::FORM_RDB_TABLE_NAME, item.first);
122              continue;
123          }
124  
125          if (std::find(innerFormInfos.begin(), innerFormInfos.end(), innerFormInfo) == innerFormInfos.end()) {
126              innerFormInfos.emplace_back(innerFormInfo);
127          }
128      }
129      HILOG_DEBUG("SaveEntries end");
130  }
131  
LoadFormData(std::vector<InnerFormInfo> & innerFormInfos)132  ErrCode FormInfoRdbStorageMgr::LoadFormData(std::vector<InnerFormInfo> &innerFormInfos)
133  {
134      HILOG_DEBUG("call");
135      ErrCode result;
136      std::unordered_map<std::string, std::string> value;
137      {
138          std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
139          result = FormRdbDataMgr::GetInstance().QueryData(Constants::FORM_RDB_TABLE_NAME, FORM_ID_PREFIX, value);
140      }
141      if (result != ERR_OK) {
142          HILOG_ERROR("get entries error");
143          FormEventReport::SendFormFailedEvent(FormEventName::CALLEN_DB_FAILED, HiSysEventType::FAULT,
144              static_cast<int64_t>(CallDbFiledErrorType::LOAD_DATABASE_FAILED));
145          return ERR_APPEXECFWK_FORM_COMMON_CODE;
146      }
147      SaveEntries(value, innerFormInfos);
148  
149      HILOG_DEBUG("end");
150      return ERR_OK;
151  }
152  
SaveStorageFormData(const InnerFormInfo & innerFormInfo)153  ErrCode FormInfoRdbStorageMgr::SaveStorageFormData(const InnerFormInfo &innerFormInfo)
154  {
155      HILOG_DEBUG("formId[%{public}" PRId64 "]", innerFormInfo.GetFormId());
156      std::string formId = std::to_string(innerFormInfo.GetFormId());
157      std::string key = std::string().append(FORM_ID_PREFIX).append(formId);
158      std::string value = innerFormInfo.ToString();
159      ErrCode result;
160      {
161          std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
162          result = FormRdbDataMgr::GetInstance().InsertData(Constants::FORM_RDB_TABLE_NAME, key, value);
163      }
164      if (result != ERR_OK) {
165          HILOG_ERROR("put innerFormInfo to RdbStore error");
166          FormEventReport::SendFormFailedEvent(FormEventName::CALLEN_DB_FAILED, HiSysEventType::FAULT,
167              static_cast<int64_t>(CallDbFiledErrorType::DATABASE_SAVE_FORMID_FAILED));
168          return ERR_APPEXECFWK_FORM_COMMON_CODE;
169      }
170      return ERR_OK;
171  }
172  
ModifyStorageFormData(const InnerFormInfo & innerFormInfo)173  ErrCode FormInfoRdbStorageMgr::ModifyStorageFormData(const InnerFormInfo &innerFormInfo)
174  {
175      HILOG_DEBUG("formId[%{public}" PRId64 "]", innerFormInfo.GetFormId());
176      std::string formId = std::to_string(innerFormInfo.GetFormId());
177      ErrCode ret = DeleteStorageFormData(formId);
178      if (ret == ERR_OK) {
179          SaveStorageFormData(innerFormInfo);
180      }
181  
182      return ret;
183  }
184  
DeleteStorageFormData(const std::string & formId)185  ErrCode FormInfoRdbStorageMgr::DeleteStorageFormData(const std::string &formId)
186  {
187      HILOG_DEBUG("formId[%{public}s]", formId.c_str());
188      std::string key = std::string().append(FORM_ID_PREFIX).append(formId);
189      ErrCode result;
190      {
191          std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
192          result = FormRdbDataMgr::GetInstance().DeleteData(Constants::FORM_RDB_TABLE_NAME, key);
193      }
194  
195      if (result != ERR_OK) {
196          HILOG_ERROR("delete key error");
197          FormEventReport::SendFormFailedEvent(FormEventName::CALLEN_DB_FAILED, HiSysEventType::FAULT,
198              static_cast<int64_t>(CallDbFiledErrorType::DATABASE_DELETE_FORMID_FAILED));
199          return ERR_APPEXECFWK_FORM_COMMON_CODE;
200      }
201  
202      key = std::string().append(STATUS_DATA_PREFIX).append(formId);
203      {
204          std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
205          result = FormRdbDataMgr::GetInstance().DeleteData(Constants::FORM_RDB_TABLE_NAME, key);
206      }
207      if (result != ERR_OK) {
208          HILOG_ERROR("delete status data of %{public}s failed", formId.c_str());
209          FormEventReport::SendFormFailedEvent(FormEventName::CALLEN_DB_FAILED, HiSysEventType::FAULT,
210              static_cast<int64_t>(CallDbFiledErrorType::DATABASE_DELETE_FORMID_FAILED));
211          return ERR_APPEXECFWK_FORM_COMMON_CODE;
212      }
213  
214      HILOG_DEBUG("delete value to RdbStore success");
215      return ERR_OK;
216  }
217  
LoadStatusData(const std::string & formId,std::string & statusData)218  ErrCode FormInfoRdbStorageMgr::LoadStatusData(const std::string &formId, std::string &statusData)
219  {
220      HILOG_DEBUG("formId is %{public}s", formId.c_str());
221      if (formId.empty()) {
222          HILOG_ERROR("empty formId");
223          return ERR_APPEXECFWK_FORM_INVALID_PARAM;
224      }
225  
226      ErrCode result;
227      std::string key = std::string().append(STATUS_DATA_PREFIX).append(formId);
228      result = FormRdbDataMgr::GetInstance().QueryData(Constants::FORM_RDB_TABLE_NAME, key, statusData);
229      if (result != ERR_OK) {
230          HILOG_ERROR("load status data of %{public}s failed, code is %{public}d", formId.c_str(), result);
231          FormEventReport::SendFormFailedEvent(FormEventName::CALLEN_DB_FAILED, HiSysEventType::FAULT,
232              static_cast<int64_t>(CallDbFiledErrorType::DATABASE_QUERY_FORMID_FAILED));
233          return ERR_APPEXECFWK_FORM_COMMON_CODE;
234      }
235  
236      return ERR_OK;
237  }
238  
UpdateStatusData(const std::string & formId,const std::string & statusData)239  ErrCode FormInfoRdbStorageMgr::UpdateStatusData(const std::string &formId, const std::string &statusData)
240  {
241      HILOG_DEBUG("formId is %{public}s", formId.c_str());
242      if (formId.empty() || statusData.empty()) {
243          HILOG_ERROR("empty formId or statusData");
244          return ERR_APPEXECFWK_FORM_INVALID_PARAM;
245      }
246  
247      ErrCode result;
248      std::string key = std::string().append(STATUS_DATA_PREFIX).append(formId);
249      result = FormRdbDataMgr::GetInstance().InsertData(Constants::FORM_RDB_TABLE_NAME, key, statusData);
250      if (result != ERR_OK) {
251          HILOG_ERROR("update status data of %{public}s to rdbstore failed, code is %{public}d", formId.c_str(), result);
252          return ERR_APPEXECFWK_FORM_COMMON_CODE;
253      }
254  
255      return ERR_OK;
256  }
257  } // namespace AppExecFwk
258  } // namespace OHOS
259