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 "preinstall_data_storage_rdb.h"
17 
18 namespace OHOS {
19 namespace AppExecFwk {
20 namespace {
21 constexpr const char* PRE_BUNDLE_RDB_TABLE_NAME = "preinstalled_bundle";
22 }
PreInstallDataStorageRdb()23 PreInstallDataStorageRdb::PreInstallDataStorageRdb()
24 {
25     APP_LOGI("PreInstallDataStorageRdb instance is created");
26     BmsRdbConfig bmsRdbConfig;
27     bmsRdbConfig.dbName = ServiceConstants::BUNDLE_RDB_NAME;
28     bmsRdbConfig.tableName = PRE_BUNDLE_RDB_TABLE_NAME;
29     rdbDataManager_ = std::make_shared<RdbDataManager>(bmsRdbConfig);
30     rdbDataManager_->CreateTable();
31 }
32 
~PreInstallDataStorageRdb()33 PreInstallDataStorageRdb::~PreInstallDataStorageRdb()
34 {
35     APP_LOGI("PreInstallDataStorageRdb instance is destroyed");
36 }
37 
LoadAllPreInstallBundleInfos(std::vector<PreInstallBundleInfo> & preInstallBundleInfos)38 bool PreInstallDataStorageRdb::LoadAllPreInstallBundleInfos(
39     std::vector<PreInstallBundleInfo> &preInstallBundleInfos)
40 {
41     APP_LOGI("Load all prebundle data to vector");
42     if (rdbDataManager_ == nullptr) {
43         APP_LOGE("rdbDataManager is null");
44         return false;
45     }
46 
47     std::map<std::string, std::string> datas;
48     if (!rdbDataManager_->QueryAllData(datas)) {
49         APP_LOGE("QueryAllData failed");
50         return false;
51     }
52 
53     TransformStrToInfo(datas, preInstallBundleInfos);
54     return !preInstallBundleInfos.empty();
55 }
56 
TransformStrToInfo(const std::map<std::string,std::string> & datas,std::vector<PreInstallBundleInfo> & preInstallBundleInfos)57 void PreInstallDataStorageRdb::TransformStrToInfo(
58     const std::map<std::string, std::string> &datas,
59     std::vector<PreInstallBundleInfo> &preInstallBundleInfos)
60 {
61     APP_LOGD("TransformStrToInfo start");
62     if (rdbDataManager_ == nullptr || datas.empty()) {
63         APP_LOGE("data is null");
64         return;
65     }
66 
67     std::map<std::string, PreInstallBundleInfo> updateInfos;
68     for (const auto &data : datas) {
69         PreInstallBundleInfo preInstallBundleInfo;
70         nlohmann::json jsonObject = nlohmann::json::parse(data.second, nullptr, false);
71         if (jsonObject.is_discarded()) {
72             APP_LOGE("Error key: %{plublic}s", data.first.c_str());
73             rdbDataManager_->DeleteData(data.first);
74             continue;
75         }
76 
77         if (preInstallBundleInfo.FromJson(jsonObject) != ERR_OK) {
78             APP_LOGE("Error key: %{plublic}s", data.first.c_str());
79             rdbDataManager_->DeleteData(data.first);
80             continue;
81         }
82 
83         preInstallBundleInfos.emplace_back(preInstallBundleInfo);
84         // database update
85         std::string key = data.first;
86         if (key != preInstallBundleInfo.GetBundleName()) {
87             updateInfos.emplace(key, preInstallBundleInfo);
88         }
89     }
90 
91     if (updateInfos.size() > 0) {
92         UpdateDataBase(updateInfos);
93     }
94 }
95 
UpdateDataBase(std::map<std::string,PreInstallBundleInfo> & infos)96 void PreInstallDataStorageRdb::UpdateDataBase(
97     std::map<std::string, PreInstallBundleInfo> &infos)
98 {
99     APP_LOGD("Begin to update preInstall database");
100     if (rdbDataManager_ == nullptr) {
101         APP_LOGE("rdbDataManager is null");
102         return;
103     }
104 
105     for (const auto& item : infos) {
106         if (!SavePreInstallStorageBundleInfo(item.second)) {
107             rdbDataManager_->DeleteData(item.first);
108         }
109     }
110     APP_LOGD("Update preInstall database done");
111 }
112 
SavePreInstallStorageBundleInfo(const PreInstallBundleInfo & preInstallBundleInfo)113 bool PreInstallDataStorageRdb::SavePreInstallStorageBundleInfo(
114     const PreInstallBundleInfo &preInstallBundleInfo)
115 {
116     if (rdbDataManager_ == nullptr) {
117         APP_LOGE("rdbDataManager is null");
118         return false;
119     }
120 
121     if (preInstallBundleInfo.GetBundleName().empty()) {
122         APP_LOGE("Save failed due to key is empty");
123         return false;
124     }
125 
126     bool ret = rdbDataManager_->InsertData(
127         preInstallBundleInfo.GetBundleName(), preInstallBundleInfo.ToString());
128     APP_LOGD("SavePreInstallStorageBundleInfo %{public}d", ret);
129     return ret;
130 }
131 
DeletePreInstallStorageBundleInfo(const PreInstallBundleInfo & preInstallBundleInfo)132 bool PreInstallDataStorageRdb::DeletePreInstallStorageBundleInfo(
133     const PreInstallBundleInfo &preInstallBundleInfo)
134 {
135     if (rdbDataManager_ == nullptr) {
136         APP_LOGE("rdbDataManager is null");
137         return false;
138     }
139 
140     if (preInstallBundleInfo.GetBundleName().empty()) {
141         APP_LOGE("Delete failed due to key is empty");
142         return false;
143     }
144 
145     bool ret = rdbDataManager_->DeleteData(preInstallBundleInfo.GetBundleName());
146     APP_LOGD("DeletePreInstallStorageBundleInfo %{public}d", ret);
147     return ret;
148 }
149 
LoadPreInstallBundleInfo(const std::string & bundleName,PreInstallBundleInfo & preInstallBundleInfo)150 bool PreInstallDataStorageRdb::LoadPreInstallBundleInfo(const std::string &bundleName,
151     PreInstallBundleInfo &preInstallBundleInfo)
152 {
153     if (rdbDataManager_ == nullptr) {
154         APP_LOGE("rdbDataManager is null");
155         return false;
156     }
157 
158     if (bundleName.empty()) {
159         APP_LOGE("Query failed due to key is empty");
160         return false;
161     }
162 
163     std::string value;
164     bool ret = rdbDataManager_->QueryData(bundleName, value);
165     if (!ret) {
166         APP_LOGE("LoadPreInstallBundleInfo QueryData failed");
167         return ret;
168     }
169     nlohmann::json jsonObject = nlohmann::json::parse(value, nullptr, false);
170     if (jsonObject.is_discarded() || (preInstallBundleInfo.FromJson(jsonObject) != ERR_OK)) {
171         APP_LOGE("error key : %{public}s", bundleName.c_str());
172         return false;
173     }
174     return ret;
175 }
176 }  // namespace AppExecFwk
177 }  // namespace OHOS