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