1 /*
2 * Copyright (c) 2024 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 "ability_resident_process_rdb.h"
17
18 #include "hilog_tag_wrapper.h"
19 #include "parser_util.h"
20 #include <charconv>
21
22 namespace OHOS {
23 namespace AbilityRuntime {
24 namespace {
25 const std::string ABILITY_RDB_TABLE_NAME = "resident_process_list";
26 const std::string KEY_BUNDLE_NAME = "KEY_BUNDLE_NAME";
27 const std::string KEY_KEEP_ALIVE_ENABLE = "KEEP_ALIVE_ENABLE";
28 const std::string KEY_KEEP_ALIVE_CONFIGURED_LIST = "KEEP_ALIVE_CONFIGURED_LIST";
29
30 const int32_t INDEX_BUNDLE_NAME = 0;
31 const int32_t INDEX_KEEP_ALIVE_ENABLE = 1;
32 const int32_t INDEX_KEEP_ALIVE_CONFIGURED_LIST = 2;
33 } // namespace
34
AmsResidentProcessRdbCallBack(const AmsRdbConfig & rdbConfig)35 AmsResidentProcessRdbCallBack::AmsResidentProcessRdbCallBack(const AmsRdbConfig &rdbConfig) : rdbConfig_(rdbConfig) {}
36
OnCreate(NativeRdb::RdbStore & rdbStore)37 int32_t AmsResidentProcessRdbCallBack::OnCreate(NativeRdb::RdbStore &rdbStore)
38 {
39 TAG_LOGI(AAFwkTag::ABILITYMGR, "OnCreate");
40
41 std::string createTableSql = "CREATE TABLE IF NOT EXISTS " + rdbConfig_.tableName +
42 " (KEY_BUNDLE_NAME TEXT NOT NULL PRIMARY KEY," +
43 "KEEP_ALIVE_ENABLE TEXT NOT NULL, KEEP_ALIVE_CONFIGURED_LIST TEXT NOT NULL);";
44 auto sqlResult = rdbStore.ExecuteSql(createTableSql);
45 if (sqlResult != NativeRdb::E_OK) {
46 TAG_LOGE(AAFwkTag::ABILITYMGR, "Ability mgr rdb execute sql error");
47 return sqlResult;
48 }
49
50 auto &parser = ParserUtil::GetInstance();
51 std::vector<std::tuple<std::string, std::string, std::string>> initList;
52 parser.GetResidentProcessRawData(initList);
53
54 std::vector<NativeRdb::ValuesBucket> valuesBuckets;
55 for (const auto &item : initList) {
56 NativeRdb::ValuesBucket valuesBucket;
57 valuesBucket.PutString(KEY_BUNDLE_NAME, std::get<INDEX_BUNDLE_NAME>(item));
58 valuesBucket.PutString(KEY_KEEP_ALIVE_ENABLE, std::get<INDEX_KEEP_ALIVE_ENABLE>(item));
59 valuesBucket.PutString(KEY_KEEP_ALIVE_CONFIGURED_LIST, std::get<INDEX_KEEP_ALIVE_CONFIGURED_LIST>(item));
60
61 valuesBuckets.emplace_back(valuesBucket);
62 }
63
64 int64_t rowId = -1;
65 int64_t insertNum = 0;
66 int32_t ret = rdbStore.BatchInsert(insertNum, rdbConfig_.tableName, valuesBuckets);
67 if (ret != NativeRdb::E_OK) {
68 TAG_LOGE(AAFwkTag::ABILITYMGR, "Ability mgr rdb batch insert error[%{public}d]", ret);
69 return ret;
70 }
71 return NativeRdb::E_OK;
72 }
73
OnUpgrade(NativeRdb::RdbStore & rdbStore,int currentVersion,int targetVersion)74 int32_t AmsResidentProcessRdbCallBack::OnUpgrade(NativeRdb::RdbStore &rdbStore, int currentVersion, int targetVersion)
75 {
76 TAG_LOGI(AAFwkTag::ABILITYMGR, "OnUpgrade currentVersion: %{plubic}d, targetVersion: %{plubic}d", currentVersion,
77 targetVersion);
78 return NativeRdb::E_OK;
79 }
80
OnDowngrade(NativeRdb::RdbStore & rdbStore,int currentVersion,int targetVersion)81 int32_t AmsResidentProcessRdbCallBack::OnDowngrade(NativeRdb::RdbStore &rdbStore, int currentVersion, int targetVersion)
82 {
83 TAG_LOGI(AAFwkTag::ABILITYMGR, "OnDowngrade currentVersion: %{plubic}d, targetVersion: %{plubic}d", currentVersion,
84 targetVersion);
85 return NativeRdb::E_OK;
86 }
87
OnOpen(NativeRdb::RdbStore & rdbStore)88 int32_t AmsResidentProcessRdbCallBack::OnOpen(NativeRdb::RdbStore &rdbStore)
89 {
90 TAG_LOGI(AAFwkTag::ABILITYMGR, "OnOpen");
91 return NativeRdb::E_OK;
92 }
93
onCorruption(std::string databaseFile)94 int32_t AmsResidentProcessRdbCallBack::onCorruption(std::string databaseFile)
95 {
96 TAG_LOGI(AAFwkTag::ABILITYMGR, "onCorruption");
97 return NativeRdb::E_OK;
98 }
99
Init()100 int32_t AmsResidentProcessRdb::Init()
101 {
102 if (rdbMgr_ != nullptr) {
103 TAG_LOGD(AAFwkTag::ABILITYMGR, "Rdb mgr existed.");
104 return Rdb_OK;
105 }
106
107 AmsRdbConfig config;
108 config.tableName = ABILITY_RDB_TABLE_NAME;
109 rdbMgr_ = std::make_unique<RdbDataManager>(config);
110 if (rdbMgr_ == nullptr) {
111 TAG_LOGE(AAFwkTag::ABILITYMGR, "Failed to create database mgr object.");
112 return Rdb_Init_Err;
113 }
114
115 AmsResidentProcessRdbCallBack amsCallback(config);
116 if (rdbMgr_->Init(amsCallback) != Rdb_OK) {
117 return Rdb_Init_Err;
118 }
119
120 return Rdb_OK;
121 }
122
GetInstance()123 AmsResidentProcessRdb &AmsResidentProcessRdb::GetInstance()
124 {
125 static AmsResidentProcessRdb instance;
126 return instance;
127 }
128
VerifyConfigurationPermissions(const std::string & bundleName,const std::string & callerBundleName)129 int32_t AmsResidentProcessRdb::VerifyConfigurationPermissions(
130 const std::string &bundleName, const std::string &callerBundleName)
131 {
132 if (bundleName.empty() || callerBundleName.empty()) {
133 TAG_LOGE(AAFwkTag::ABILITYMGR, "Bundle name is null.");
134 return Rdb_Parameter_Err;
135 }
136
137 if (bundleName == callerBundleName) {
138 TAG_LOGD(AAFwkTag::ABILITYMGR, "The caller and the called are the same.");
139 return Rdb_OK;
140 }
141
142 if (rdbMgr_ == nullptr) {
143 TAG_LOGE(AAFwkTag::ABILITYMGR, "Rdb mgr error.");
144 return Rdb_Parameter_Err;
145 }
146
147 NativeRdb::AbsRdbPredicates absRdbPredicates(ABILITY_RDB_TABLE_NAME);
148 absRdbPredicates.EqualTo(KEY_BUNDLE_NAME, bundleName);
149 auto absSharedResultSet = rdbMgr_->QueryData(absRdbPredicates);
150 if (absSharedResultSet == nullptr) {
151 TAG_LOGE(AAFwkTag::ABILITYMGR, "Ability mgr rdb query data failed.");
152 return Rdb_Permissions_Err;
153 }
154
155 ScopeGuard stateGuard([absSharedResultSet] { absSharedResultSet->Close(); });
156 auto ret = absSharedResultSet->GoToFirstRow();
157 if (ret != NativeRdb::E_OK) {
158 TAG_LOGE(AAFwkTag::ABILITYMGR, "Go to first row failed, ret: %{public}d", ret);
159 return Rdb_Search_Record_Err;
160 }
161
162 std::string KeepAliveConfiguredList;
163 ret = absSharedResultSet->GetString(INDEX_KEEP_ALIVE_CONFIGURED_LIST, KeepAliveConfiguredList);
164 if (ret != NativeRdb::E_OK) {
165 TAG_LOGE(AAFwkTag::ABILITYMGR, "Get configured list failed, ret: %{public}d", ret);
166 return Rdb_Search_Record_Err;
167 }
168
169 if (KeepAliveConfiguredList.find(callerBundleName) != std::string::npos) {
170 return Rdb_OK;
171 }
172
173 return Rdb_Permissions_Err;
174 }
175
GetResidentProcessEnable(const std::string & bundleName,bool & enable)176 int32_t AmsResidentProcessRdb::GetResidentProcessEnable(const std::string &bundleName, bool &enable)
177 {
178 if (bundleName.empty()) {
179 TAG_LOGE(AAFwkTag::ABILITYMGR, "Bundle name is null.");
180 return Rdb_Parameter_Err;
181 }
182
183 if (rdbMgr_ == nullptr) {
184 TAG_LOGE(AAFwkTag::ABILITYMGR, "Rdb mgr error.");
185 return Rdb_Parameter_Err;
186 }
187
188 NativeRdb::AbsRdbPredicates absRdbPredicates(ABILITY_RDB_TABLE_NAME);
189 absRdbPredicates.EqualTo(KEY_BUNDLE_NAME, bundleName);
190 auto absSharedResultSet = rdbMgr_->QueryData(absRdbPredicates);
191 if (absSharedResultSet == nullptr) {
192 TAG_LOGE(AAFwkTag::ABILITYMGR, "Ability mgr rdb query data failed.");
193 return Rdb_Permissions_Err;
194 }
195
196 ScopeGuard stateGuard([absSharedResultSet] { absSharedResultSet->Close(); });
197 auto ret = absSharedResultSet->GoToFirstRow();
198 if (ret != NativeRdb::E_OK) {
199 TAG_LOGD(AAFwkTag::ABILITYMGR, "Go to first row failed, ret: %{public}d", ret);
200 return Rdb_Search_Record_Err;
201 }
202
203 std::string flag;
204 ret = absSharedResultSet->GetString(INDEX_KEEP_ALIVE_ENABLE, flag);
205 if (ret != NativeRdb::E_OK) {
206 TAG_LOGE(AAFwkTag::ABILITYMGR, "Get enable status failed, ret: %{public}d", ret);
207 return Rdb_Search_Record_Err;
208 }
209 unsigned long value = 0;
210 auto res = std::from_chars(flag.c_str(), flag.c_str() + flag.size(), value);
211 if (res.ec != std::errc()) {
212 TAG_LOGE(AAFwkTag::ABILITYMGR, "from_chars error flag:%{public}s", flag.c_str());
213 return Rdb_Search_Record_Err;
214 }
215 enable = static_cast<bool>(value);
216
217 return Rdb_OK;
218 }
219
UpdateResidentProcessEnable(const std::string & bundleName,bool enable)220 int32_t AmsResidentProcessRdb::UpdateResidentProcessEnable(const std::string &bundleName, bool enable)
221 {
222 if (bundleName.empty()) {
223 TAG_LOGE(AAFwkTag::ABILITYMGR, "Bundle name is null.");
224 return Rdb_Parameter_Err;
225 }
226
227 if (rdbMgr_ == nullptr) {
228 TAG_LOGE(AAFwkTag::ABILITYMGR, "Rdb mgr error.");
229 return Rdb_Parameter_Err;
230 }
231
232 NativeRdb::ValuesBucket valuesBucket;
233 valuesBucket.PutString(KEY_KEEP_ALIVE_ENABLE, std::to_string(enable));
234 NativeRdb::AbsRdbPredicates absRdbPredicates(ABILITY_RDB_TABLE_NAME);
235 absRdbPredicates.EqualTo(KEY_BUNDLE_NAME, bundleName);
236 return rdbMgr_->UpdateData(valuesBucket, absRdbPredicates);
237 }
238
RemoveData(std::string & bundleName)239 int32_t AmsResidentProcessRdb::RemoveData(std::string &bundleName)
240 {
241 if (bundleName.empty()) {
242 TAG_LOGE(AAFwkTag::ABILITYMGR, "Bundle name is null.");
243 return Rdb_Parameter_Err;
244 }
245
246 if (rdbMgr_ == nullptr) {
247 TAG_LOGE(AAFwkTag::ABILITYMGR, "Rdb mgr error.");
248 return Rdb_Parameter_Err;
249 }
250 NativeRdb::AbsRdbPredicates absRdbPredicates(ABILITY_RDB_TABLE_NAME);
251 absRdbPredicates.EqualTo(KEY_BUNDLE_NAME, bundleName);
252 return rdbMgr_->DeleteData(absRdbPredicates);
253 }
254 } // namespace AbilityRuntime
255 } // namespace OHOS
256