• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "rdb/starting_window_rdb_manager.h"
17 
18 #include <hitrace_meter.h>
19 
20 #include "ability_info.h"
21 #include "rdb/scope_guard.h"
22 #include "resource_manager.h"
23 #include "window_manager_hilog.h"
24 
25 namespace OHOS {
26 namespace Rosen {
27 namespace {
28 const std::string DB_PRIMARY_KEY = "ID";
29 const std::string DB_BUNDLE_NAME = "BUNDLE_NAME";
30 const std::string DB_MODULE_NAME = "MODULE_NAME";
31 const std::string DB_ABILITY_NAME = "ABILITY_NAME";
32 const std::string DB_DARK_MODE = "DARK_MODE";
33 const std::string DB_BACKGROUND_COLOR_EARLY_VERSION = "BACKGROUND_COLOR_EARLY_VERSION";
34 const std::string DB_ICON_PATH_EARLY_VERSION = "ICON_PATH_EARLY_VERSION";
35 const std::string DB_CONFIG_FILE_ENABLED = "CONFIG_FILE_ENABLED";
36 const std::string DB_BACKGROUND_COLOR = "BACKGROUND_COLOR";
37 const std::string DB_ICON_PATH = "ICON_PATH";
38 const std::string DB_ILLUSTRATION_PATH = "ILLUSTRATION_PATH";
39 const std::string DB_BRANDING_PATH = "BRANDING_PATH";
40 const std::string DB_BACKGROUND_IMAGE_PATH = "BACKGROUND_IMAGE_PATH";
41 const std::string DB_BACKGROUND_IMAGE_FIT = "BACKGROUND_IMAGE_FIT";
42 const std::string DB_STARTWINDOW_TYPE = "STARTWINDOW_TYPE";
43 constexpr int32_t DB_PRIMARY_KEY_INDEX = 0;
44 constexpr int32_t DB_BUNDLE_NAME_INDEX = 1;
45 constexpr int32_t DB_MODULE_NAME_INDEX = 2;
46 constexpr int32_t DB_ABILITY_NAME_INDEX = 3;
47 constexpr int32_t DB_DARK_MODE_INDEX = 4;
48 constexpr int32_t DB_BACKGROUND_COLOR_EARLY_VERSION_INDEX = 5;
49 constexpr int32_t DB_ICON_PATH_EARLY_VERSION_INDEX = 6;
50 constexpr int32_t DB_CONFIG_FILE_ENABLED_INDEX = 7;
51 constexpr int32_t DB_BACKGROUND_COLOR_INDEX = 8;
52 constexpr int32_t DB_ICON_PATH_INDEX = 9;
53 constexpr int32_t DB_ILLUSTRATION_PATH_INDEX = 10;
54 constexpr int32_t DB_BRANDING_PATH_INDEX = 11;
55 constexpr int32_t DB_BACKGROUND_IMAGE_PATH_INDEX = 12;
56 constexpr int32_t DB_BACKGROUND_IMAGE_FIT_INDEX = 13;
57 constexpr int32_t DB_STARTWINDOW_TYPE_INDEX = 14;
58 constexpr const char* PROFILE_PREFIX = "$profile:";
59 constexpr uint16_t MAX_JSON_STRING_LENGTH = 4096;
60 constexpr int32_t DEFAULT_ROW_COUNT = -1;
61 
BuildValuesBucket(const StartingWindowRdbItemKey & key,const StartingWindowInfo & value)62 NativeRdb::ValuesBucket BuildValuesBucket(const StartingWindowRdbItemKey& key, const StartingWindowInfo& value)
63 {
64     NativeRdb::ValuesBucket valuesBucket;
65     valuesBucket.PutString(DB_BUNDLE_NAME, key.bundleName);
66     valuesBucket.PutString(DB_MODULE_NAME, key.moduleName);
67     valuesBucket.PutString(DB_ABILITY_NAME, key.abilityName);
68     valuesBucket.PutBool(DB_DARK_MODE, key.darkMode);
69     valuesBucket.PutInt(DB_BACKGROUND_COLOR_EARLY_VERSION, value.backgroundColorEarlyVersion_);
70     valuesBucket.PutString(DB_ICON_PATH_EARLY_VERSION, value.iconPathEarlyVersion_);
71     valuesBucket.PutBool(DB_CONFIG_FILE_ENABLED, value.configFileEnabled_);
72     valuesBucket.PutInt(DB_BACKGROUND_COLOR, value.backgroundColor_);
73     valuesBucket.PutString(DB_ICON_PATH, value.iconPath_);
74     valuesBucket.PutString(DB_ILLUSTRATION_PATH, value.illustrationPath_);
75     valuesBucket.PutString(DB_BRANDING_PATH, value.brandingPath_);
76     valuesBucket.PutString(DB_BACKGROUND_IMAGE_PATH, value.backgroundImagePath_);
77     valuesBucket.PutString(DB_BACKGROUND_IMAGE_FIT, value.backgroundImageFit_);
78     valuesBucket.PutString(DB_STARTWINDOW_TYPE, value.startWindowType_);
79     return valuesBucket;
80 }
81 
BuildPredicates(const std::string tableName,const StartingWindowRdbItemKey & key)82 NativeRdb::AbsRdbPredicates BuildPredicates(const std::string tableName, const StartingWindowRdbItemKey& key)
83 {
84     NativeRdb::AbsRdbPredicates absRdbPredicates(tableName);
85     absRdbPredicates.EqualTo(DB_BUNDLE_NAME, key.bundleName)->And()->
86                      EqualTo(DB_MODULE_NAME, key.moduleName)->And()->
87                      EqualTo(DB_ABILITY_NAME, key.abilityName)->And()->
88                      EqualTo(DB_DARK_MODE, key.darkMode);
89     return absRdbPredicates;
90 }
91 
CheckRdbResult(int resCode)92 bool CheckRdbResult(int resCode)
93 {
94     if (resCode != NativeRdb::E_OK) {
95         TLOGE(WmsLogTag::WMS_PATTERN, "rdb failed, ret:%{public}d", resCode);
96         return false;
97     }
98     return true;
99 }
100 } // namespace
101 
StartingWindowRdbManager(const WmsRdbConfig & wmsRdbConfig)102 StartingWindowRdbManager::StartingWindowRdbManager(const WmsRdbConfig& wmsRdbConfig)
103     : wmsRdbConfig_(wmsRdbConfig)
104 {
105     std::string uniqueConstraint = std::string("CONSTRAINT uniqueConstraint UNIQUE (" +
106         DB_BUNDLE_NAME + ", " + DB_MODULE_NAME + ", " + DB_ABILITY_NAME + ", " + DB_DARK_MODE + ")");
107     wmsRdbConfig_.createTableSql = std::string("CREATE TABLE IF NOT EXISTS " + wmsRdbConfig_.tableName +
108         "(" + DB_PRIMARY_KEY + " INTEGER PRIMARY KEY AUTOINCREMENT, " + DB_BUNDLE_NAME + " TEXT NOT NULL, " +
109         DB_MODULE_NAME + " TEXT NOT NULL, " + DB_ABILITY_NAME + " TEXT NOT NULL, " + DB_DARK_MODE + " BOOLEAN, " +
110         DB_BACKGROUND_COLOR_EARLY_VERSION + " INTEGER, " + DB_ICON_PATH_EARLY_VERSION + " TEXT, " +
111         DB_CONFIG_FILE_ENABLED + " BOOLEAN, " + DB_BACKGROUND_COLOR + " INTEGER, " + DB_ICON_PATH + " TEXT, " +
112         DB_ILLUSTRATION_PATH + " TEXT, " + DB_BRANDING_PATH + " TEXT, " +
113         DB_BACKGROUND_IMAGE_PATH + " TEXT, " + DB_BACKGROUND_IMAGE_FIT + " TEXT, " +
114         DB_STARTWINDOW_TYPE + " TEXT, " + uniqueConstraint + ");");
115 }
116 
~StartingWindowRdbManager()117 StartingWindowRdbManager::~StartingWindowRdbManager()
118 {
119     ClearRdbStore();
120 }
121 
ClearRdbStore()122 void StartingWindowRdbManager::ClearRdbStore()
123 {
124     std::lock_guard<std::mutex> lock(rdbMutex_);
125     rdbStore_ = nullptr;
126 }
127 
GetRdbStore()128 std::shared_ptr<NativeRdb::RdbStore> StartingWindowRdbManager::GetRdbStore()
129 {
130     std::lock_guard<std::mutex> lock(rdbMutex_);
131     if (rdbStore_ != nullptr) {
132         return rdbStore_;
133     }
134     NativeRdb::RdbStoreConfig rdbStoreConfig(wmsRdbConfig_.dbPath + wmsRdbConfig_.dbName);
135     rdbStoreConfig.SetSecurityLevel(NativeRdb::SecurityLevel::S1);
136     int32_t resCode = NativeRdb::E_OK;
137     WmsRdbOpenCallback wmsCallback(wmsRdbConfig_);
138     rdbStore_ = NativeRdb::RdbHelper::GetRdbStore(
139         rdbStoreConfig, wmsRdbConfig_.version, wmsCallback, resCode);
140     TLOGI(WmsLogTag::WMS_PATTERN, "resCode: %{public}d, version: %{public}d",
141         resCode, wmsRdbConfig_.version);
142     return rdbStore_;
143 }
144 
Init()145 bool StartingWindowRdbManager::Init()
146 {
147     auto rdbStore = GetRdbStore();
148     if (rdbStore == nullptr) {
149         TLOGE(WmsLogTag::WMS_PATTERN, "failed");
150         return false;
151     }
152     return true;
153 }
154 
InsertData(const StartingWindowRdbItemKey & key,const StartingWindowInfo & value)155 bool StartingWindowRdbManager::InsertData(const StartingWindowRdbItemKey& key, const StartingWindowInfo& value)
156 {
157     auto rdbStore = GetRdbStore();
158     if (rdbStore == nullptr) {
159         TLOGE(WmsLogTag::WMS_PATTERN, "RdbStore is null");
160         return false;
161     }
162     int64_t rowId = -1;
163     auto valuesBucket = BuildValuesBucket(key, value);
164     auto ret = rdbStore->InsertWithConflictResolution(
165         rowId, wmsRdbConfig_.tableName, valuesBucket, NativeRdb::ConflictResolution::ON_CONFLICT_REPLACE);
166     return CheckRdbResult(ret);
167 }
168 
BatchInsert(int64_t & outInsertNum,const std::vector<std::pair<StartingWindowRdbItemKey,StartingWindowInfo>> & inputValues)169 bool StartingWindowRdbManager::BatchInsert(int64_t& outInsertNum,
170     const std::vector<std::pair<StartingWindowRdbItemKey, StartingWindowInfo>>& inputValues)
171 {
172     auto rdbStore = GetRdbStore();
173     if (rdbStore == nullptr) {
174         TLOGE(WmsLogTag::WMS_PATTERN, "RdbStore is null");
175         return false;
176     }
177     std::vector<NativeRdb::ValuesBucket> valuesBuckets;
178     for (const auto& pair : inputValues) {
179         auto valuesBucket = BuildValuesBucket(pair.first, pair.second);
180         valuesBuckets.emplace_back(valuesBucket);
181     }
182     auto ret = rdbStore->BatchInsert(outInsertNum, wmsRdbConfig_.tableName, valuesBuckets);
183     return CheckRdbResult(ret);
184 }
185 
DeleteDataByBundleName(const std::string & bundleName)186 bool StartingWindowRdbManager::DeleteDataByBundleName(const std::string& bundleName)
187 {
188     auto rdbStore = GetRdbStore();
189     if (rdbStore == nullptr) {
190         TLOGE(WmsLogTag::WMS_PATTERN, "RdbStore is null");
191         return false;
192     }
193     int32_t deletedRows = DEFAULT_ROW_COUNT;
194     NativeRdb::AbsRdbPredicates absRdbPredicates(wmsRdbConfig_.tableName);
195     absRdbPredicates.EqualTo(DB_BUNDLE_NAME, bundleName);
196     auto ret = rdbStore->Delete(deletedRows, absRdbPredicates);
197     return CheckRdbResult(ret);
198 }
199 
DeleteAllData()200 bool StartingWindowRdbManager::DeleteAllData()
201 {
202     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:DeleteAllData");
203     auto rdbStore = GetRdbStore();
204     if (rdbStore == nullptr) {
205         TLOGE(WmsLogTag::WMS_PATTERN, "RdbStore is null");
206         return false;
207     }
208     int32_t deletedRows = DEFAULT_ROW_COUNT;
209     NativeRdb::AbsRdbPredicates absRdbPredicates(wmsRdbConfig_.tableName);
210     auto ret = rdbStore->Delete(deletedRows, absRdbPredicates);
211     return CheckRdbResult(ret);
212 }
213 
QueryData(const StartingWindowRdbItemKey & key,StartingWindowInfo & value)214 bool StartingWindowRdbManager::QueryData(const StartingWindowRdbItemKey& key, StartingWindowInfo& value)
215 {
216     auto rdbStore = GetRdbStore();
217     if (rdbStore == nullptr) {
218         TLOGE(WmsLogTag::WMS_PATTERN, "RdbStore is null");
219         return false;
220     }
221     auto absRdbPredicates = BuildPredicates(wmsRdbConfig_.tableName, key);
222     auto absSharedResultSet = rdbStore->QueryByStep(absRdbPredicates, std::vector<std::string>());
223     if (absSharedResultSet == nullptr) {
224         TLOGE(WmsLogTag::WMS_PATTERN, "absSharedResultSet failed");
225         return false;
226     }
227     ScopeGuard stateGuard([&] { absSharedResultSet->Close(); });
228     auto ret = absSharedResultSet->GoToFirstRow();
229     if (ret != NativeRdb::E_OK) {
230         TLOGE(WmsLogTag::WMS_PATTERN, "GoToFirstRow failed, ret:%{public}d", ret);
231         return false;
232     }
233     int backgroundColorEarlyVersion = 0;
234     int backgroundColor = 0;
235     int configFileEnabled = 0;
236     if (!CheckRdbResult(absSharedResultSet->GetInt(
237             DB_BACKGROUND_COLOR_EARLY_VERSION_INDEX, backgroundColorEarlyVersion)) ||
238         !CheckRdbResult(absSharedResultSet->GetString(
239             DB_ICON_PATH_EARLY_VERSION_INDEX, value.iconPathEarlyVersion_)) ||
240         !CheckRdbResult(absSharedResultSet->GetInt(DB_BACKGROUND_COLOR_INDEX, backgroundColor)) ||
241         !CheckRdbResult(absSharedResultSet->GetString(DB_ICON_PATH_INDEX, value.iconPath_)) ||
242         !CheckRdbResult(absSharedResultSet->GetInt(DB_CONFIG_FILE_ENABLED_INDEX, configFileEnabled)) ||
243         !CheckRdbResult(absSharedResultSet->GetString(DB_ILLUSTRATION_PATH_INDEX, value.illustrationPath_)) ||
244         !CheckRdbResult(absSharedResultSet->GetString(DB_BRANDING_PATH_INDEX, value.brandingPath_)) ||
245         !CheckRdbResult(absSharedResultSet->GetString(DB_BACKGROUND_IMAGE_PATH_INDEX, value.backgroundImagePath_)) ||
246         !CheckRdbResult(absSharedResultSet->GetString(DB_BACKGROUND_IMAGE_FIT_INDEX, value.backgroundImageFit_)) ||
247         !CheckRdbResult(absSharedResultSet->GetString(DB_STARTWINDOW_TYPE_INDEX, value.startWindowType_))) {
248         return false;
249     }
250     value.backgroundColorEarlyVersion_ = static_cast<uint32_t>(backgroundColorEarlyVersion);
251     value.backgroundColor_ = static_cast<uint32_t>(backgroundColor);
252     value.configFileEnabled_ = configFileEnabled;
253     return true;
254 }
255 
GetStartWindowValFromProfile(const AppExecFwk::AbilityInfo & abilityInfo,const std::shared_ptr<Global::Resource::ResourceManager> & resourceMgr,const std::string & key,const std::string & defaultVal)256 std::string StartingWindowRdbManager::GetStartWindowValFromProfile(const AppExecFwk::AbilityInfo& abilityInfo,
257     const std::shared_ptr<Global::Resource::ResourceManager>& resourceMgr,
258     const std::string& key, const std::string& defaultVal)
259 {
260     auto pos = abilityInfo.startWindow.find(PROFILE_PREFIX);
261     if (pos == std::string::npos) {
262         TLOGD(WmsLogTag::WMS_PATTERN, "invalid profile");
263         return defaultVal;
264     }
265     std::string startWindowName = abilityInfo.startWindow.substr(pos + strlen(PROFILE_PREFIX));
266     std::unique_ptr<uint8_t[]> fileContentPtr = nullptr;
267     size_t len = 0;
268     if (resourceMgr->GetProfileDataByName(startWindowName.c_str(), len, fileContentPtr) !=
269         Global::Resource::RState::SUCCESS) {
270         TLOGE(WmsLogTag::WMS_PATTERN, "getProfileData failed");
271         return defaultVal;
272     }
273     if (fileContentPtr == nullptr || len == 0) {
274         TLOGE(WmsLogTag::WMS_PATTERN, "invalid data");
275         return defaultVal;
276     }
277     std::string rawData(fileContentPtr.get(), fileContentPtr.get() + len);
278     if (!nlohmann::json::accept(rawData)) {
279         TLOGE(WmsLogTag::WMS_PATTERN, "rawData failed");
280         return defaultVal;
281     }
282     nlohmann::json profileJson = nlohmann::json::parse(rawData);
283     if (profileJson.is_discarded()) {
284         TLOGE(WmsLogTag::WMS_PATTERN, "bad profile file");
285         return defaultVal;
286     }
287     if (profileJson.find(key) == profileJson.end()) {
288         TLOGE(WmsLogTag::WMS_PATTERN, "the default value is %{public}s", defaultVal.c_str());
289         return defaultVal;
290     }
291     if (!profileJson.at(key).is_string()) {
292         TLOGE(WmsLogTag::WMS_PATTERN, "the default value is not string");
293         return defaultVal;
294     }
295     std::string res = profileJson.at(key).get<std::string>();
296     if (res.empty() || res.length() > MAX_JSON_STRING_LENGTH) {
297         TLOGE(WmsLogTag::WMS_PATTERN, "exceeding the maximum string length");
298         return defaultVal;
299     }
300     TLOGI(WmsLogTag::WMS_PATTERN, "startWindowType: %{public}s", res.c_str());
301     return res;
302 }
303 } // namespace Rosen
304 } // namespace OHOS