1 /*
2  * Copyright (c) 2023 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 "bundle_resource_rdb.h"
17 
18 #include "app_log_wrapper.h"
19 #include "bundle_resource_constants.h"
20 #include "bundle_util.h"
21 #include "scope_guard.h"
22 
23 namespace OHOS {
24 namespace AppExecFwk {
25 namespace {
26 constexpr const char* SYSTEM_RESOURCES_APP = "ohos.global.systemres";
27 const int8_t CLOSE_TIME = 60; // delay 60s to backup
28 }
29 
BundleResourceRdb()30 BundleResourceRdb::BundleResourceRdb()
31 {
32     APP_LOGI("create");
33     BmsRdbConfig bmsRdbConfig;
34     bmsRdbConfig.dbName = BundleResourceConstants::BUNDLE_RESOURCE_RDB_NAME;
35     bmsRdbConfig.dbPath = BundleResourceConstants::BUNDLE_RESOURCE_RDB_PATH;
36     bmsRdbConfig.tableName = BundleResourceConstants::BUNDLE_RESOURCE_RDB_TABLE_NAME;
37     bmsRdbConfig.createTableSql = std::string(
38         "CREATE TABLE IF NOT EXISTS "
39         + std::string(BundleResourceConstants::BUNDLE_RESOURCE_RDB_TABLE_NAME)
40         + "(NAME TEXT NOT NULL, UPDATE_TIME INTEGER, LABEL TEXT, ICON TEXT, "
41         + "SYSTEM_STATE TEXT NOT NULL, PRIMARY KEY (NAME));");
42     bmsRdbConfig.insertColumnSql.push_back(std::string("ALTER TABLE " +
43         std::string(BundleResourceConstants::BUNDLE_RESOURCE_RDB_TABLE_NAME) +
44         " ADD FOREGROUND BLOB;"));
45     bmsRdbConfig.insertColumnSql.push_back(std::string("ALTER TABLE " +
46         std::string(BundleResourceConstants::BUNDLE_RESOURCE_RDB_TABLE_NAME) +
47         " ADD BACKGROUND BLOB;"));
48     rdbDataManager_ = std::make_shared<RdbDataManager>(bmsRdbConfig);
49     rdbDataManager_->CreateTable();
50 }
51 
~BundleResourceRdb()52 BundleResourceRdb::~BundleResourceRdb()
53 {
54 }
55 
AddResourceInfo(const ResourceInfo & resourceInfo)56 bool BundleResourceRdb::AddResourceInfo(const ResourceInfo &resourceInfo)
57 {
58     if (resourceInfo.bundleName_.empty()) {
59         APP_LOGE("failed, bundleName is empty");
60         return false;
61     }
62     APP_LOGD("insert resource key:%{public}s", resourceInfo.GetKey().c_str());
63     int64_t timeStamp = BundleUtil::GetCurrentTimeMs();
64     NativeRdb::ValuesBucket valuesBucket;
65     valuesBucket.PutString(BundleResourceConstants::NAME, resourceInfo.GetKey());
66     valuesBucket.PutLong(BundleResourceConstants::UPDATE_TIME, timeStamp);
67     valuesBucket.PutString(BundleResourceConstants::LABEL, resourceInfo.label_);
68     valuesBucket.PutString(BundleResourceConstants::ICON, resourceInfo.icon_);
69     valuesBucket.PutString(BundleResourceConstants::SYSTEM_STATE, BundleSystemState::GetInstance().ToString());
70     // used for layered icons
71     valuesBucket.PutBlob(BundleResourceConstants::FOREGROUND, resourceInfo.foreground_);
72     valuesBucket.PutBlob(BundleResourceConstants::BACKGROUND, resourceInfo.background_);
73     APP_LOGD("key:%{public}s foreground: %{public}zu, background: %{public}zu", resourceInfo.GetKey().c_str(),
74         resourceInfo.foreground_.size(), resourceInfo.background_.size());
75 
76     return rdbDataManager_->InsertData(valuesBucket);
77 }
78 
AddResourceInfos(const std::vector<ResourceInfo> & resourceInfos)79 bool BundleResourceRdb::AddResourceInfos(const std::vector<ResourceInfo> &resourceInfos)
80 {
81     if (resourceInfos.empty()) {
82         APP_LOGE("failed, resourceInfos is empty");
83         return false;
84     }
85     int64_t timeStamp = BundleUtil::GetCurrentTimeMs();
86     bool ret = true;
87     std::vector<NativeRdb::ValuesBucket> valuesBuckets;
88     for (const auto &info : resourceInfos) {
89         if (info.bundleName_.empty()) {
90             APP_LOGE("failed, bundleName is empty");
91             ret = false;
92             continue;
93         }
94         NativeRdb::ValuesBucket valuesBucket;
95         valuesBucket.PutString(BundleResourceConstants::NAME, info.GetKey());
96         valuesBucket.PutLong(BundleResourceConstants::UPDATE_TIME, timeStamp);
97         valuesBucket.PutString(BundleResourceConstants::SYSTEM_STATE, BundleSystemState::GetInstance().ToString());
98 
99         if (!info.label_.empty()) {
100             valuesBucket.PutString(BundleResourceConstants::LABEL, info.label_);
101         } else {
102             valuesBucket.PutString(BundleResourceConstants::LABEL, resourceInfos[0].label_);
103         }
104 
105         if (!info.icon_.empty()) {
106             valuesBucket.PutString(BundleResourceConstants::ICON, info.icon_);
107             // used for layered icons
108             valuesBucket.PutBlob(BundleResourceConstants::FOREGROUND, info.foreground_);
109             valuesBucket.PutBlob(BundleResourceConstants::BACKGROUND, info.background_);
110         } else {
111             valuesBucket.PutString(BundleResourceConstants::ICON, resourceInfos[0].icon_);
112             // used for layered icons
113             valuesBucket.PutBlob(BundleResourceConstants::FOREGROUND, resourceInfos[0].foreground_);
114             valuesBucket.PutBlob(BundleResourceConstants::BACKGROUND, resourceInfos[0].background_);
115         }
116         APP_LOGD("key:%{public}s foreground: %{public}zu, background: %{public}zu", info.GetKey().c_str(),
117             info.foreground_.size(), info.background_.size());
118         valuesBuckets.emplace_back(valuesBucket);
119     }
120     int64_t insertNum = 0;
121     bool insertRet = rdbDataManager_->BatchInsert(insertNum, valuesBuckets);
122     if (!insertRet) {
123         APP_LOGE("BatchInsert failed");
124         return false;
125     }
126     if (valuesBuckets.size() != static_cast<uint64_t>(insertNum)) {
127         APP_LOGE("BatchInsert size not expected");
128         return false;
129     }
130     BackupRdb();
131     return ret;
132 }
133 
DeleteResourceInfo(const std::string & key)134 bool BundleResourceRdb::DeleteResourceInfo(const std::string &key)
135 {
136     if (key.empty()) {
137         APP_LOGE("failed, key is empty");
138         return false;
139     }
140     APP_LOGD("need delete resource info, key: %{public}s", key.c_str());
141     /**
142      * begin with bundle name, like:
143      * 1. bundleName
144      * 2. bundleName/moduleName/abilityName
145      */
146     if (key.find(ServiceConstants::PATH_SEPARATOR) == std::string::npos) {
147         NativeRdb::AbsRdbPredicates absRdbPredicates(BundleResourceConstants::BUNDLE_RESOURCE_RDB_TABLE_NAME);
148         // need delete both bundle resource and launcher ability resource
149         absRdbPredicates.BeginsWith(BundleResourceConstants::NAME, key + ServiceConstants::PATH_SEPARATOR);
150         if (!rdbDataManager_->DeleteData(absRdbPredicates)) {
151             APP_LOGW("delete key:%{public}s failed", key.c_str());
152         }
153     }
154     NativeRdb::AbsRdbPredicates absRdbPredicates(BundleResourceConstants::BUNDLE_RESOURCE_RDB_TABLE_NAME);
155     absRdbPredicates.EqualTo(BundleResourceConstants::NAME, key);
156     return rdbDataManager_->DeleteData(absRdbPredicates);
157 }
158 
GetAllResourceName(std::vector<std::string> & keyNames)159 bool BundleResourceRdb::GetAllResourceName(std::vector<std::string> &keyNames)
160 {
161     NativeRdb::AbsRdbPredicates absRdbPredicates(BundleResourceConstants::BUNDLE_RESOURCE_RDB_TABLE_NAME);
162     std::string systemState = BundleSystemState::GetInstance().ToString();
163     APP_LOGI("start get all resource name:%{public}s", systemState.c_str());
164     auto absSharedResultSet = rdbDataManager_->QueryByStep(absRdbPredicates);
165     if (absSharedResultSet == nullptr) {
166         APP_LOGE("QueryByStep failed, systemState:%{public}s", systemState.c_str());
167         return false;
168     }
169     ScopeGuard stateGuard([absSharedResultSet] { absSharedResultSet->Close(); });
170 
171     auto ret = absSharedResultSet->GoToFirstRow();
172     if (ret != NativeRdb::E_OK) {
173         APP_LOGE("GoToFirstRow failed, ret %{public}d, systemState %{public}s", ret, systemState.c_str());
174         return false;
175     }
176     do {
177         std::string name;
178         ret = absSharedResultSet->GetString(BundleResourceConstants::INDEX_NAME, name);
179         if (ret != NativeRdb::E_OK) {
180             APP_LOGE("GetString name failed, ret %{public}d, systemState %{public}s", ret, systemState.c_str());
181             return false;
182         }
183         if (name.find("/") != std::string::npos) {
184             continue;
185         }
186         // icon is invalid, need add again
187         std::vector<uint8_t> foreground;
188         ret = absSharedResultSet->GetBlob(BundleResourceConstants::INDEX_FOREGROUND, foreground);
189         if (ret != NativeRdb::E_OK) {
190             APP_LOGE("GetString foreground failed, ret %{public}d, systemState %{public}s", ret, systemState.c_str());
191             return false;
192         }
193         if (foreground.empty()) {
194             APP_LOGW("keyName %{public}s foreground invalid", name.c_str());
195             continue;
196         }
197         // label is invalid, need add again
198         std::string label;
199         ret = absSharedResultSet->GetString(BundleResourceConstants::INDEX_LABEL, label);
200         if (ret != NativeRdb::E_OK) {
201             APP_LOGE("GetString label failed, ret %{public}d, systemState:%{public}s", ret, systemState.c_str());
202             return false;
203         }
204         if ((label.find('$') == 0) || (label == name) || label.empty()) {
205             APP_LOGW("keyName %{public}s label invalid", name.c_str());
206             continue;
207         }
208         keyNames.push_back(name);
209     } while (absSharedResultSet->GoToNextRow() == NativeRdb::E_OK);
210     return true;
211 }
212 
GetResourceNameByBundleName(const std::string & bundleName,const int32_t appIndex,std::vector<std::string> & keyName)213 bool BundleResourceRdb::GetResourceNameByBundleName(
214     const std::string &bundleName,
215     const int32_t appIndex,
216     std::vector<std::string> &keyName)
217 {
218     APP_LOGI("start, bundleName:%{public}s appIndex:%{public}d", bundleName.c_str(), appIndex);
219     if (bundleName.empty()) {
220         APP_LOGE("bundleName is empty");
221         return false;
222     }
223     ResourceInfo resourceInfo;
224     resourceInfo.bundleName_ = bundleName;
225     resourceInfo.appIndex_ = appIndex;
226     NativeRdb::AbsRdbPredicates absRdbPredicates(BundleResourceConstants::BUNDLE_RESOURCE_RDB_TABLE_NAME);
227     absRdbPredicates.BeginsWith(BundleResourceConstants::NAME, resourceInfo.GetKey() +
228         BundleResourceConstants::SEPARATOR);
229     std::string systemState = BundleSystemState::GetInstance().ToString();
230 
231     auto absSharedResultSet = rdbDataManager_->QueryByStep(absRdbPredicates);
232     if (absSharedResultSet == nullptr) {
233         APP_LOGE("bundleName:%{public}s failed due rdb QueryByStep failed, systemState:%{public}s",
234             bundleName.c_str(), systemState.c_str());
235         return false;
236     }
237     ScopeGuard stateGuard([absSharedResultSet] { absSharedResultSet->Close(); });
238     auto ret = absSharedResultSet->GoToFirstRow();
239     if (ret != NativeRdb::E_OK) {
240         APP_LOGD("bundleName:%{public}s not exist, ret: %{public}d, systemState:%{public}s",
241             bundleName.c_str(), ret, systemState.c_str());
242         return false;
243     }
244 
245     do {
246         std::string key;
247         auto ret = absSharedResultSet->GetString(BundleResourceConstants::INDEX_NAME, key);
248         CHECK_RDB_RESULT_RETURN_IF_FAIL(ret, "GetString name failed, ret: %{public}d");
249         keyName.emplace_back(key);
250     } while (absSharedResultSet->GoToNextRow() == NativeRdb::E_OK);
251     return true;
252 }
253 
DeleteAllResourceInfo()254 bool BundleResourceRdb::DeleteAllResourceInfo()
255 {
256     NativeRdb::AbsRdbPredicates absRdbPredicates(BundleResourceConstants::BUNDLE_RESOURCE_RDB_TABLE_NAME);
257     // delete all resource info
258     return rdbDataManager_->DeleteData(absRdbPredicates);
259 }
260 
GetBundleResourceInfo(const std::string & bundleName,const uint32_t flags,BundleResourceInfo & bundleResourceInfo,int32_t appIndex)261 bool BundleResourceRdb::GetBundleResourceInfo(
262     const std::string &bundleName,
263     const uint32_t flags,
264     BundleResourceInfo &bundleResourceInfo,
265     int32_t appIndex)
266 {
267     APP_LOGI_NOFUNC("rdb GetBundleResourceInfo -n %{public}s -i %{public}d", bundleName.c_str(), appIndex);
268     if (bundleName.empty()) {
269         APP_LOGE("bundleName is empty");
270         return false;
271     }
272     NativeRdb::AbsRdbPredicates absRdbPredicates(BundleResourceConstants::BUNDLE_RESOURCE_RDB_TABLE_NAME);
273     ResourceInfo resourceInfo;
274     resourceInfo.bundleName_ = bundleName;
275     resourceInfo.appIndex_ = appIndex;
276     absRdbPredicates.EqualTo(BundleResourceConstants::NAME, resourceInfo.GetKey());
277     std::string systemState = BundleSystemState::GetInstance().ToString();
278 
279     auto absSharedResultSet = rdbDataManager_->QueryByStep(absRdbPredicates);
280     if (absSharedResultSet == nullptr) {
281         APP_LOGE("rdb QueryByStep failed, bundleName %{public}s appIndex %{public}d, %{public}s",
282             bundleName.c_str(), appIndex, systemState.c_str());
283         return false;
284     }
285 
286     ScopeGuard stateGuard([absSharedResultSet] { absSharedResultSet->Close(); });
287     auto ret = absSharedResultSet->GoToFirstRow();
288     if (ret != NativeRdb::E_OK) {
289         APP_LOGE_NOFUNC("rdb GetBundleResourceInfo -n %{public}s failed:%{public}d systemState:%{public}s",
290             bundleName.c_str(), ret, systemState.c_str());
291         return false;
292     }
293     return ConvertToBundleResourceInfo(absSharedResultSet, flags, bundleResourceInfo);
294 }
295 
GetLauncherAbilityResourceInfo(const std::string & bundleName,const uint32_t flags,std::vector<LauncherAbilityResourceInfo> & launcherAbilityResourceInfos,const int32_t appIndex)296 bool BundleResourceRdb::GetLauncherAbilityResourceInfo(
297     const std::string &bundleName,
298     const uint32_t flags,
299     std::vector<LauncherAbilityResourceInfo> &launcherAbilityResourceInfos,
300     const int32_t appIndex)
301 {
302     APP_LOGI_NOFUNC("rdb GetLauncherAbilityResourceInfo -n %{public}s -i %{public}d", bundleName.c_str(), appIndex);
303     if (bundleName.empty()) {
304         APP_LOGE("bundleName is empty");
305         return false;
306     }
307     ResourceInfo resourceInfo;
308     resourceInfo.bundleName_ = bundleName;
309     resourceInfo.appIndex_ = appIndex;
310     NativeRdb::AbsRdbPredicates absRdbPredicates(BundleResourceConstants::BUNDLE_RESOURCE_RDB_TABLE_NAME);
311     absRdbPredicates.BeginsWith(BundleResourceConstants::NAME, resourceInfo.GetKey() +
312         BundleResourceConstants::SEPARATOR);
313     std::string systemState = BundleSystemState::GetInstance().ToString();
314 
315     auto absSharedResultSet = rdbDataManager_->QueryByStep(absRdbPredicates);
316     if (absSharedResultSet == nullptr) {
317         APP_LOGE("QueryByStep failed bundleName %{public}s failed, systemState %{public}s",
318             bundleName.c_str(), systemState.c_str());
319         return false;
320     }
321     ScopeGuard stateGuard([absSharedResultSet] { absSharedResultSet->Close(); });
322     auto ret = absSharedResultSet->GoToFirstRow();
323     if (ret != NativeRdb::E_OK) {
324         APP_LOGE("bundleName %{public}s GoToFirstRow failed, ret %{public}d, systemState:%{public}s",
325             bundleName.c_str(), ret, systemState.c_str());
326         return false;
327     }
328 
329     do {
330         LauncherAbilityResourceInfo resourceInfo;
331         if (ConvertToLauncherAbilityResourceInfo(absSharedResultSet, flags, resourceInfo)) {
332             launcherAbilityResourceInfos.push_back(resourceInfo);
333         }
334     } while (absSharedResultSet->GoToNextRow() == NativeRdb::E_OK);
335 
336     if ((flags & static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_SORTED_BY_LABEL)) ==
337         static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_SORTED_BY_LABEL)) {
338         APP_LOGD("need sort by label");
339         std::sort(launcherAbilityResourceInfos.begin(), launcherAbilityResourceInfos.end(),
340             [](LauncherAbilityResourceInfo &resourceA, LauncherAbilityResourceInfo &resourceB) {
341                 return resourceA.label < resourceB.label;
342             });
343     }
344     return !launcherAbilityResourceInfos.empty();
345 }
346 
GetAllBundleResourceInfo(const uint32_t flags,std::vector<BundleResourceInfo> & bundleResourceInfos)347 bool BundleResourceRdb::GetAllBundleResourceInfo(const uint32_t flags,
348     std::vector<BundleResourceInfo> &bundleResourceInfos)
349 {
350     APP_LOGI("start get all bundle resource");
351     NativeRdb::AbsRdbPredicates absRdbPredicates(BundleResourceConstants::BUNDLE_RESOURCE_RDB_TABLE_NAME);
352     std::string systemState = BundleSystemState::GetInstance().ToString();
353 
354     auto absSharedResultSet = rdbDataManager_->QueryByStep(absRdbPredicates);
355     if (absSharedResultSet == nullptr) {
356         APP_LOGE("absSharedResultSet nullptr, systemState %{public}s", systemState.c_str());
357         return false;
358     }
359     ScopeGuard stateGuard([absSharedResultSet] { absSharedResultSet->Close(); });
360     auto ret = absSharedResultSet->GoToFirstRow();
361     if (ret != NativeRdb::E_OK) {
362         APP_LOGE("GoToFirstRow failed, ret %{public}d, systemState %{public}s", ret, systemState.c_str());
363         return false;
364     }
365 
366     do {
367         BundleResourceInfo resourceInfo;
368         if (ConvertToBundleResourceInfo(absSharedResultSet, flags, resourceInfo)) {
369             bundleResourceInfos.push_back(resourceInfo);
370         }
371     } while (absSharedResultSet->GoToNextRow() == NativeRdb::E_OK);
372 
373     if ((flags & static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_SORTED_BY_LABEL)) ==
374         static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_SORTED_BY_LABEL)) {
375         APP_LOGD("need sort by label");
376         std::sort(bundleResourceInfos.begin(), bundleResourceInfos.end(),
377             [](BundleResourceInfo &resourceA, BundleResourceInfo &resourceB) {
378                 return resourceA.label < resourceB.label;
379             });
380     }
381     return !bundleResourceInfos.empty();
382 }
383 
GetAllLauncherAbilityResourceInfo(const uint32_t flags,std::vector<LauncherAbilityResourceInfo> & launcherAbilityResourceInfos)384 bool BundleResourceRdb::GetAllLauncherAbilityResourceInfo(const uint32_t flags,
385     std::vector<LauncherAbilityResourceInfo> &launcherAbilityResourceInfos)
386 {
387     APP_LOGI("start get all launcher resource");
388     NativeRdb::AbsRdbPredicates absRdbPredicates(BundleResourceConstants::BUNDLE_RESOURCE_RDB_TABLE_NAME);
389     absRdbPredicates.Contains(BundleResourceConstants::NAME, BundleResourceConstants::SEPARATOR);
390     std::string systemState = BundleSystemState::GetInstance().ToString();
391 
392     auto absSharedResultSet = rdbDataManager_->QueryByStep(absRdbPredicates);
393     if (absSharedResultSet == nullptr) {
394         APP_LOGE("absSharedResultSet nullptr, systemState %{public}s", systemState.c_str());
395         return false;
396     }
397 
398     ScopeGuard stateGuard([absSharedResultSet] { absSharedResultSet->Close(); });
399     auto ret = absSharedResultSet->GoToFirstRow();
400     if (ret != NativeRdb::E_OK) {
401         APP_LOGE("GoToFirstRow failed, ret %{public}d, systemState %{public}s", ret, systemState.c_str());
402         return false;
403     }
404 
405     do {
406         LauncherAbilityResourceInfo resourceInfo;
407         if (ConvertToLauncherAbilityResourceInfo(absSharedResultSet, flags, resourceInfo)) {
408             launcherAbilityResourceInfos.push_back(resourceInfo);
409         }
410     } while (absSharedResultSet->GoToNextRow() == NativeRdb::E_OK);
411 
412     if ((flags & static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_SORTED_BY_LABEL)) ==
413         static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_SORTED_BY_LABEL)) {
414         std::sort(launcherAbilityResourceInfos.begin(), launcherAbilityResourceInfos.end(),
415             [](LauncherAbilityResourceInfo &resourceA, LauncherAbilityResourceInfo &resourceB) {
416                 return resourceA.label < resourceB.label;
417             });
418     }
419     return !launcherAbilityResourceInfos.empty();
420 }
421 
ConvertToBundleResourceInfo(const std::shared_ptr<NativeRdb::ResultSet> & absSharedResultSet,const uint32_t flags,BundleResourceInfo & bundleResourceInfo)422 bool BundleResourceRdb::ConvertToBundleResourceInfo(
423     const std::shared_ptr<NativeRdb::ResultSet> &absSharedResultSet,
424     const uint32_t flags,
425     BundleResourceInfo &bundleResourceInfo)
426 {
427     if (absSharedResultSet == nullptr) {
428         APP_LOGE("absSharedResultSet is nullptr");
429         return false;
430     }
431     auto ret = absSharedResultSet->GetString(BundleResourceConstants::INDEX_NAME, bundleResourceInfo.bundleName);
432     CHECK_RDB_RESULT_RETURN_IF_FAIL(ret, "GetString name failed, ret: %{public}d");
433     if (bundleResourceInfo.bundleName.find_first_of(BundleResourceConstants::SEPARATOR) != std::string::npos) {
434         APP_LOGD("key:%{public}s not bundle resource info, continue", bundleResourceInfo.bundleName.c_str());
435         return false;
436     }
437     ParseKey(bundleResourceInfo.bundleName, bundleResourceInfo);
438 
439     bool getAll = (flags & static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_ALL)) ==
440         static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_ALL);
441 
442     bool getLabel = (flags & static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_LABEL)) ==
443         static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_LABEL);
444     if (getAll || getLabel) {
445         ret = absSharedResultSet->GetString(BundleResourceConstants::INDEX_LABEL, bundleResourceInfo.label);
446         CHECK_RDB_RESULT_RETURN_IF_FAIL(ret, "GetString label failed, ret: %{public}d");
447     }
448 
449     bool getIcon = (flags & static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_ICON)) ==
450         static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_ICON);
451     if (getAll || getIcon) {
452         ret = absSharedResultSet->GetString(BundleResourceConstants::INDEX_ICON, bundleResourceInfo.icon);
453         CHECK_RDB_RESULT_RETURN_IF_FAIL(ret, "GetString label icon, ret: %{public}d");
454     }
455 
456     bool getDrawable = (flags & static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_DRAWABLE_DESCRIPTOR)) ==
457         static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_DRAWABLE_DESCRIPTOR);
458     if (getDrawable) {
459         ret = absSharedResultSet->GetBlob(BundleResourceConstants::INDEX_FOREGROUND, bundleResourceInfo.foreground);
460         CHECK_RDB_RESULT_RETURN_IF_FAIL(ret, "GetBlob foreground, ret: %{public}d");
461 
462         ret = absSharedResultSet->GetBlob(BundleResourceConstants::INDEX_BACKGROUND, bundleResourceInfo.background);
463         CHECK_RDB_RESULT_RETURN_IF_FAIL(ret, "GetBlob background, ret: %{public}d");
464     }
465     return true;
466 }
467 
ConvertToLauncherAbilityResourceInfo(const std::shared_ptr<NativeRdb::ResultSet> & absSharedResultSet,const uint32_t flags,LauncherAbilityResourceInfo & launcherAbilityResourceInfo)468 bool BundleResourceRdb::ConvertToLauncherAbilityResourceInfo(
469     const std::shared_ptr<NativeRdb::ResultSet> &absSharedResultSet,
470     const uint32_t flags,
471     LauncherAbilityResourceInfo &launcherAbilityResourceInfo)
472 {
473     if (absSharedResultSet == nullptr) {
474         APP_LOGE("absSharedResultSet is nullptr");
475         return false;
476     }
477     std::string key;
478     auto ret = absSharedResultSet->GetString(BundleResourceConstants::INDEX_NAME, key);
479     CHECK_RDB_RESULT_RETURN_IF_FAIL(ret, "GetString name failed, ret: %{public}d");
480     ParseKey(key, launcherAbilityResourceInfo);
481     if (launcherAbilityResourceInfo.moduleName.empty() || launcherAbilityResourceInfo.abilityName.empty()) {
482         APP_LOGW("key:%{public}s not launcher ability resource info", key.c_str());
483         return false;
484     }
485     bool getAll = (flags & static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_ALL)) ==
486         static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_ALL);
487     bool getLabel = (flags & static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_LABEL)) ==
488         static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_LABEL);
489     if (getAll || getLabel) {
490         ret = absSharedResultSet->GetString(BundleResourceConstants::INDEX_LABEL, launcherAbilityResourceInfo.label);
491         CHECK_RDB_RESULT_RETURN_IF_FAIL(ret, "GetString label failed, ret: %{public}d");
492     }
493 
494     bool getIcon = (flags & static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_ICON)) ==
495         static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_ICON);
496     if (getAll || getIcon) {
497         ret = absSharedResultSet->GetString(BundleResourceConstants::INDEX_ICON, launcherAbilityResourceInfo.icon);
498         CHECK_RDB_RESULT_RETURN_IF_FAIL(ret, "GetString label icon, ret: %{public}d");
499     }
500 
501     bool getDrawable = (flags & static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_DRAWABLE_DESCRIPTOR)) ==
502         static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_DRAWABLE_DESCRIPTOR);
503     if (getDrawable) {
504         ret = absSharedResultSet->GetBlob(BundleResourceConstants::INDEX_FOREGROUND,
505             launcherAbilityResourceInfo.foreground);
506         CHECK_RDB_RESULT_RETURN_IF_FAIL(ret, "GetBlob foreground, ret: %{public}d");
507 
508         ret = absSharedResultSet->GetBlob(BundleResourceConstants::INDEX_BACKGROUND,
509             launcherAbilityResourceInfo.background);
510         CHECK_RDB_RESULT_RETURN_IF_FAIL(ret, "GetBlob background, ret: %{public}d");
511     }
512     return true;
513 }
514 
UpdateResourceForSystemStateChanged(const std::vector<ResourceInfo> & resourceInfos)515 bool BundleResourceRdb::UpdateResourceForSystemStateChanged(const std::vector<ResourceInfo> &resourceInfos)
516 {
517     if (resourceInfos.empty()) {
518         APP_LOGE("resourceInfos is empty");
519         return false;
520     }
521     std::string systemState = BundleSystemState::GetInstance().ToString();
522     int64_t timeStamp = BundleUtil::GetCurrentTimeMs();
523     bool ret = true;
524     NativeRdb::AbsRdbPredicates absRdbPredicates(BundleResourceConstants::BUNDLE_RESOURCE_RDB_TABLE_NAME);
525     for (const auto &resourceInfo : resourceInfos) {
526         NativeRdb::ValuesBucket valuesBucket;
527         valuesBucket.PutString(BundleResourceConstants::NAME, resourceInfo.GetKey());
528         valuesBucket.PutString(BundleResourceConstants::SYSTEM_STATE, systemState);
529         // process label
530         if (!resourceInfo.label_.empty()) {
531             valuesBucket.PutString(BundleResourceConstants::LABEL, resourceInfo.label_);
532         } else if (!resourceInfos[0].label_.empty()) {
533             valuesBucket.PutString(BundleResourceConstants::LABEL, resourceInfos[0].label_);
534         }
535         // process icon
536         if (!resourceInfo.icon_.empty()) {
537             valuesBucket.PutString(BundleResourceConstants::ICON, resourceInfo.icon_);
538             valuesBucket.PutBlob(BundleResourceConstants::FOREGROUND, resourceInfo.foreground_);
539             valuesBucket.PutBlob(BundleResourceConstants::BACKGROUND, resourceInfo.background_);
540         } else if (!resourceInfos[0].icon_.empty()) {
541             valuesBucket.PutString(BundleResourceConstants::ICON, resourceInfos[0].icon_);
542             valuesBucket.PutBlob(BundleResourceConstants::FOREGROUND, resourceInfos[0].foreground_);
543             valuesBucket.PutBlob(BundleResourceConstants::BACKGROUND, resourceInfos[0].background_);
544         }
545         valuesBucket.PutLong(BundleResourceConstants::UPDATE_TIME, timeStamp);
546         absRdbPredicates.EqualTo(BundleResourceConstants::NAME, resourceInfo.GetKey());
547         if (!rdbDataManager_->UpdateOrInsertData(valuesBucket, absRdbPredicates)) {
548             APP_LOGE("bundleName: %{public}s UpdateData failed", resourceInfo.GetKey().c_str());
549             ret = false;
550         }
551         absRdbPredicates.Clear();
552     }
553     BackupRdb();
554     return ret;
555 }
556 
GetCurrentSystemState(std::string & systemState)557 bool BundleResourceRdb::GetCurrentSystemState(std::string &systemState)
558 {
559     NativeRdb::AbsRdbPredicates absRdbPredicates(BundleResourceConstants::BUNDLE_RESOURCE_RDB_TABLE_NAME);
560     absRdbPredicates.EqualTo(BundleResourceConstants::NAME, SYSTEM_RESOURCES_APP);
561     auto absSharedResultSet = rdbDataManager_->QueryByStep(absRdbPredicates);
562     if (absSharedResultSet == nullptr) {
563         APP_LOGW("bundleName:%{public}s failed due rdb QueryByStep failed", SYSTEM_RESOURCES_APP);
564         return false;
565     }
566 
567     ScopeGuard stateGuard([absSharedResultSet] { absSharedResultSet->Close(); });
568     auto ret = absSharedResultSet->GoToFirstRow();
569     if (ret != NativeRdb::E_OK) {
570         APP_LOGW("bundleName:%{public}s GoToFirstRow failed, ret: %{public}d", SYSTEM_RESOURCES_APP, ret);
571         return false;
572     }
573     ret = absSharedResultSet->GetString(BundleResourceConstants::INDEX_SYSTEM_STATE, systemState);
574     CHECK_RDB_RESULT_RETURN_IF_FAIL(ret, "GetString name failed, ret: %{public}d");
575     APP_LOGI("current resource rdb systemState:%{public}s", systemState.c_str());
576     return true;
577 }
578 
DeleteNotExistResourceInfo()579 bool BundleResourceRdb::DeleteNotExistResourceInfo()
580 {
581     // need delete not current systemState resource
582     std::string systemState = BundleSystemState::GetInstance().ToString();
583     APP_LOGI("current systemState:%{public}s", systemState.c_str());
584     NativeRdb::AbsRdbPredicates absRdbPredicates(BundleResourceConstants::BUNDLE_RESOURCE_RDB_TABLE_NAME);
585     absRdbPredicates.NotEqualTo(BundleResourceConstants::SYSTEM_STATE, systemState);
586     return rdbDataManager_->DeleteData(absRdbPredicates);
587 }
588 
ParseKey(const std::string & key,LauncherAbilityResourceInfo & launcherAbilityResourceInfo)589 void BundleResourceRdb::ParseKey(const std::string &key,
590     LauncherAbilityResourceInfo &launcherAbilityResourceInfo)
591 {
592     ResourceInfo info;
593     info.ParseKey(key);
594     launcherAbilityResourceInfo.bundleName = info.bundleName_;
595     launcherAbilityResourceInfo.moduleName = info.moduleName_;
596     launcherAbilityResourceInfo.abilityName = info.abilityName_;
597     launcherAbilityResourceInfo.appIndex = info.appIndex_;
598 }
599 
ParseKey(const std::string & key,BundleResourceInfo & bundleResourceInfo)600 void BundleResourceRdb::ParseKey(const std::string &key,
601     BundleResourceInfo &bundleResourceInfo)
602 {
603     ResourceInfo info;
604     info.ParseKey(key);
605     bundleResourceInfo.bundleName = info.bundleName_;
606     bundleResourceInfo.appIndex = info.appIndex_;
607 }
608 
BackupRdb()609 void BundleResourceRdb::BackupRdb()
610 {
611     if (isBackingUp_) {
612         return;
613     }
614     isBackingUp_ = true;
615     std::weak_ptr<BundleResourceRdb> weakPtr = weak_from_this();
616     auto task = [weakPtr] {
617         APP_LOGI("bundleResource.db backup start");
618         std::this_thread::sleep_for(std::chrono::seconds(CLOSE_TIME));
619         auto sharedPtr = weakPtr.lock();
620         if (sharedPtr == nullptr) {
621             APP_LOGE("sharedPtr is null");
622             return;
623         }
624         if (sharedPtr->rdbDataManager_ != nullptr) {
625             sharedPtr->rdbDataManager_->BackupRdb();
626         } else {
627             APP_LOGE("rdbDataManager_ is null");
628         }
629         sharedPtr->isBackingUp_ = false;
630         APP_LOGI("bundleResource.db backup end");
631     };
632     std::thread backUpThread(task);
633     backUpThread.detach();
634 }
635 } // AppExecFwk
636 } // OHOS
637