1 /*
2  * Copyright (c) 2022-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 "default_app_rdb.h"
17 
18 #include "app_log_tag_wrapper.h"
19 #include "bundle_mgr_service.h"
20 #include "bundle_parser.h"
21 
22 namespace OHOS {
23 namespace AppExecFwk {
24 namespace {
25 constexpr int32_t INITIAL_USER_ID = -1;
26 const std::string DEFAULT_APP_JSON_PATH = "/etc/app/default_app.json";
27 const std::string BACK_UP_DEFAULT_APP_JSON_PATH = "/etc/app/backup_default_app.json";
28 constexpr const char* DEFAULT_APP_RDB_TABLE_NAME = "default_app";
29 }
DefaultAppRdb()30 DefaultAppRdb::DefaultAppRdb()
31 {
32     LOG_D(BMS_TAG_DEFAULT, "create DefaultAppRdb");
33     BmsRdbConfig bmsRdbConfig;
34     bmsRdbConfig.dbName = ServiceConstants::BUNDLE_RDB_NAME;
35     bmsRdbConfig.tableName = DEFAULT_APP_RDB_TABLE_NAME;
36     rdbDataManager_ = std::make_shared<RdbDataManager>(bmsRdbConfig);
37     rdbDataManager_->CreateTable();
38     ConvertMimeTypeToUtd();
39     LoadDefaultApplicationConfig();
40     LoadBackUpDefaultApplicationConfig();
41 }
42 
~DefaultAppRdb()43 DefaultAppRdb::~DefaultAppRdb()
44 {
45     LOG_D(BMS_TAG_DEFAULT, "destroy DefaultAppRdb");
46 }
47 
GetDefaultApplicationInfos(int32_t userId,std::map<std::string,Element> & infos)48 bool DefaultAppRdb::GetDefaultApplicationInfos(int32_t userId, std::map<std::string, Element>& infos)
49 {
50     LOG_D(BMS_TAG_DEFAULT, "begin to GetDefaultApplicationInfos, userId : %{public}d", userId);
51     bool ret = GetDataFromDb(userId, infos);
52     if (!ret) {
53         LOG_E(BMS_TAG_DEFAULT, "GetDataFromDb failed");
54         return false;
55     }
56 
57     LOG_D(BMS_TAG_DEFAULT, "GetDefaultApplicationInfos success");
58     return true;
59 }
60 
GetDefaultApplicationInfo(int32_t userId,const std::string & type,Element & element)61 bool DefaultAppRdb::GetDefaultApplicationInfo(int32_t userId, const std::string& type, Element& element)
62 {
63     LOG_D(BMS_TAG_DEFAULT, "begin to GetDefaultApplicationInfo, userId : %{public}d, type : %{public}s",
64         userId, type.c_str());
65     std::map<std::string, Element> infos;
66     bool ret = GetDefaultApplicationInfos(userId, infos);
67     if (!ret) {
68         LOG_E(BMS_TAG_DEFAULT, "GetDefaultApplicationInfos failed");
69         return false;
70     }
71 
72     if (infos.find(type) == infos.end()) {
73         LOG_D(BMS_TAG_DEFAULT, "type is not saved in db");
74         return false;
75     }
76 
77     element = infos.find(type)->second;
78     LOG_D(BMS_TAG_DEFAULT, "GetDefaultApplicationInfo success");
79     return true;
80 }
81 
SetDefaultApplicationInfos(int32_t userId,const std::map<std::string,Element> & infos)82 bool DefaultAppRdb::SetDefaultApplicationInfos(int32_t userId, const std::map<std::string, Element>& infos)
83 {
84     LOG_D(BMS_TAG_DEFAULT, "begin to SetDefaultApplicationInfos, userId : %{public}d", userId);
85     bool ret = SaveDataToDb(userId, infos);
86     if (!ret) {
87         LOG_E(BMS_TAG_DEFAULT, "SaveDataToDb failed");
88         return false;
89     }
90 
91     LOG_D(BMS_TAG_DEFAULT, "SetDefaultApplicationInfos success");
92     return true;
93 }
94 
SetDefaultApplicationInfo(int32_t userId,const std::string & type,const Element & element)95 bool DefaultAppRdb::SetDefaultApplicationInfo(int32_t userId, const std::string& type, const Element& element)
96 {
97     LOG_D(BMS_TAG_DEFAULT, "SetDefaultApplicationInfo userId:%{public}d type:%{public}s", userId, type.c_str());
98     std::map<std::string, Element> infos;
99     GetDefaultApplicationInfos(userId, infos);
100     if (infos.find(type) == infos.end()) {
101         LOG_D(BMS_TAG_DEFAULT, "add default app info");
102         infos.emplace(type, element);
103     } else {
104         LOG_D(BMS_TAG_DEFAULT, "modify default app info");
105         infos[type] = element;
106     }
107 
108     bool ret = SaveDataToDb(userId, infos);
109     if (!ret) {
110         LOG_E(BMS_TAG_DEFAULT, "SaveDataToDb failed");
111         return false;
112     }
113 
114     LOG_D(BMS_TAG_DEFAULT, "SetDefaultApplicationInfo success");
115     return true;
116 }
117 
DeleteDefaultApplicationInfos(int32_t userId)118 bool DefaultAppRdb::DeleteDefaultApplicationInfos(int32_t userId)
119 {
120     LOG_D(BMS_TAG_DEFAULT, "begin to DeleteDefaultApplicationInfos, userId : %{public}d", userId);
121     bool ret = DeleteDataFromDb(userId);
122     if (!ret) {
123         LOG_E(BMS_TAG_DEFAULT, "DeleteDataFromDb failed");
124         return false;
125     }
126 
127     LOG_D(BMS_TAG_DEFAULT, "DeleteDefaultApplicationInfos success");
128     return true;
129 }
130 
DeleteDefaultApplicationInfo(int32_t userId,const std::string & type)131 bool DefaultAppRdb::DeleteDefaultApplicationInfo(int32_t userId, const std::string& type)
132 {
133     LOG_D(BMS_TAG_DEFAULT, "begin to delete userId: %{public}d, type: %{public}s", userId, type.c_str());
134     std::map<std::string, Element> infos;
135     bool ret = GetDataFromDb(userId, infos);
136     if (!ret) {
137         LOG_E(BMS_TAG_DEFAULT, "GetDataFromDb failed");
138         return true;
139     }
140 
141     if (infos.find(type) == infos.end()) {
142         LOG_D(BMS_TAG_DEFAULT, "type doesn't exists in db");
143         return true;
144     }
145 
146     infos.erase(type);
147     ret = SaveDataToDb(userId, infos);
148     if (!ret) {
149         LOG_E(BMS_TAG_DEFAULT, "SaveDataToDb failed");
150         return false;
151     }
152 
153     LOG_D(BMS_TAG_DEFAULT, "DeleteDefaultApplicationInfo success");
154     return true;
155 }
156 
ConvertMimeTypeToUtd()157 void DefaultAppRdb::ConvertMimeTypeToUtd()
158 {
159     std::shared_ptr<BundleDataMgr> dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
160     if (dataMgr == nullptr) {
161         LOG_W(BMS_TAG_DEFAULT, "dataMgr is null");
162         return;
163     }
164     std::set<int32_t> allUsers = dataMgr->GetAllUser();
165     allUsers.insert(INITIAL_USER_ID);
166     allUsers.insert(ServiceConstants::BACKUP_DEFAULT_APP_KEY);
167 
168     for (int32_t userId : allUsers) {
169         std::map<std::string, Element> infos;
170         if (!GetDefaultApplicationInfos(userId, infos)) {
171             continue;
172         }
173         std::map<std::string, Element> newInfos;
174         for (auto& item : infos) {
175             std::vector<std::string> normalizedTypeVector = DefaultAppMgr::Normalize(item.first);
176             if (normalizedTypeVector.empty()) {
177                 LOG_W(BMS_TAG_DEFAULT, "normalize %{public}s failed", item.first.c_str());
178                 continue;
179             }
180             for (const std::string& normalizedType : normalizedTypeVector) {
181                 item.second.type = normalizedType;
182                 newInfos.emplace(normalizedType, item.second);
183             }
184         }
185         (void)SetDefaultApplicationInfos(userId, newInfos);
186     }
187 }
188 
ParseConfig(const std::string & relativePath,DefaultAppData & defaultAppData)189 bool DefaultAppRdb::ParseConfig(const std::string& relativePath, DefaultAppData& defaultAppData)
190 {
191     // load default app config from json file
192     std::vector<std::string> rootDirs;
193     BMSEventHandler::GetPreInstallRootDirList(rootDirs);
194     if (rootDirs.empty()) {
195         LOG_W(BMS_TAG_DEFAULT, "rootDirs empty");
196         return false;
197     }
198     std::for_each(rootDirs.cbegin(), rootDirs.cend(), [&relativePath, &defaultAppData](const auto& rootDir) {
199         std::string path = rootDir + relativePath;
200         LOG_D(BMS_TAG_DEFAULT, "default app json path : %{public}s", path.c_str());
201         nlohmann::json jsonObject;
202         if (!BundleParser::ReadFileIntoJson(path, jsonObject)) {
203             LOG_W(BMS_TAG_DEFAULT, "read default app json failed");
204             return;
205         }
206         defaultAppData.ParseDefaultApplicationConfig(jsonObject);
207     });
208     return !defaultAppData.infos.empty();
209 }
210 
LoadDefaultApplicationConfig()211 void DefaultAppRdb::LoadDefaultApplicationConfig()
212 {
213     LOG_D(BMS_TAG_DEFAULT, "begin to LoadDefaultApplicationConfig");
214     DefaultAppData defaultAppData;
215     if (!ParseConfig(DEFAULT_APP_JSON_PATH, defaultAppData)) {
216         LOG_D(BMS_TAG_DEFAULT, "default app config empty");
217         return;
218     }
219     // get pre default app config
220     std::map<std::string, Element> preInfos;
221     GetDefaultApplicationInfos(INITIAL_USER_ID, preInfos);
222     // save to each user
223     std::shared_ptr<BundleDataMgr> dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
224     if (dataMgr == nullptr) {
225         LOG_W(BMS_TAG_DEFAULT, "get BundleDataMgr failed");
226         return;
227     }
228 
229     std::set<int32_t> allUsers = dataMgr->GetAllUser();
230     for (int32_t userId : allUsers) {
231         std::map<std::string, Element> infos;
232         GetDefaultApplicationInfos(userId, infos);
233         for (const auto& item : defaultAppData.infos) {
234             const std::string& type = item.first;
235             const Element& element = item.second;
236             if (infos.find(type) != infos.end() && preInfos.find(type) != preInfos.end()
237                 && infos.find(type)->second == preInfos.find(type)->second) {
238                 infos[type] = element;
239             } else {
240                 infos.try_emplace(type, element);
241             }
242         }
243 
244         SetDefaultApplicationInfos(userId, infos);
245     }
246 
247     // save default app config to db
248     SetDefaultApplicationInfos(INITIAL_USER_ID, defaultAppData.infos);
249     LOG_D(BMS_TAG_DEFAULT, "LoadDefaultApplicationConfig done");
250 }
251 
LoadBackUpDefaultApplicationConfig()252 void DefaultAppRdb::LoadBackUpDefaultApplicationConfig()
253 {
254     LOG_D(BMS_TAG_DEFAULT, "begin");
255     DefaultAppData defaultAppData;
256     if (!ParseConfig(BACK_UP_DEFAULT_APP_JSON_PATH, defaultAppData)) {
257         LOG_D(BMS_TAG_DEFAULT, "backup default app config empty");
258         return;
259     }
260     // save default app config to db
261     SetDefaultApplicationInfos(ServiceConstants::BACKUP_DEFAULT_APP_KEY, defaultAppData.infos);
262     LOG_D(BMS_TAG_DEFAULT, "end");
263 }
264 
GetDataFromDb(int32_t userId,std::map<std::string,Element> & infos)265 bool DefaultAppRdb::GetDataFromDb(int32_t userId, std::map<std::string, Element>& infos)
266 {
267     if (rdbDataManager_ == nullptr) {
268         LOG_E(BMS_TAG_DEFAULT, "rdbDataManager is null");
269         return false;
270     }
271 
272     std::string key = std::to_string(userId);
273     std::string value;
274     bool result = rdbDataManager_->QueryData(key, value);
275     if (!result) {
276         LOG_E(BMS_TAG_DEFAULT, "QueryData failed by key %{public}d", userId);
277         return false;
278     }
279 
280     DefaultAppData defaultAppData;
281     nlohmann::json jsonObject = nlohmann::json::parse(value, nullptr, false);
282     if (jsonObject.is_discarded() || defaultAppData.FromJson(jsonObject) != ERR_OK) {
283         LOG_E(BMS_TAG_DEFAULT, "error key : %{public}s", key.c_str());
284         rdbDataManager_->DeleteData(key);
285         return false;
286     }
287 
288     infos = defaultAppData.infos;
289     return true;
290 }
291 
SaveDataToDb(int32_t userId,const std::map<std::string,Element> & infos)292 bool DefaultAppRdb::SaveDataToDb(int32_t userId, const std::map<std::string, Element>& infos)
293 {
294     if (rdbDataManager_ == nullptr) {
295         LOG_E(BMS_TAG_DEFAULT, "rdbDataManager is null");
296         return false;
297     }
298 
299     DefaultAppData defaultAppData;
300     defaultAppData.infos = infos;
301     return rdbDataManager_->InsertData(std::to_string(userId), defaultAppData.ToString());
302 }
303 
DeleteDataFromDb(int32_t userId)304 bool DefaultAppRdb::DeleteDataFromDb(int32_t userId)
305 {
306     if (rdbDataManager_ == nullptr) {
307         LOG_E(BMS_TAG_DEFAULT, "rdbDataManager is null");
308         return false;
309     }
310 
311     return rdbDataManager_->DeleteData(std::to_string(userId));
312 }
313 
RegisterDeathListener()314 void DefaultAppRdb::RegisterDeathListener()
315 {
316     LOG_D(BMS_TAG_DEFAULT, "RegisterDeathListener");
317 }
318 
UnRegisterDeathListener()319 void DefaultAppRdb::UnRegisterDeathListener()
320 {
321     LOG_D(BMS_TAG_DEFAULT, "UnRegisterDeathListener");
322 }
323 }
324 }
325