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 "pre_install_exception_mgr.h"
17
18 #include "bundle_mgr_service.h"
19
20 namespace OHOS {
21 namespace AppExecFwk {
22 namespace {
23 constexpr const char* PREINSTALL_EXCEPTION = "PreInstallExceptionMgr";
24 constexpr const char* EXCEPTION_PATHS = "ExceptionPaths";
25 constexpr const char* EXCEPTION_BUNDLENAMES = "ExceptionBundleNames";
26 constexpr const char* EXCEPTION_APP_SERVICE_PATHS = "ExceptionAppServicePaths";
27 constexpr const char* EXCEPTION_APP_SERVICE_BUNDLENAMES = "ExceptionAppServiceBundleNames";
28 }
PreInstallExceptionMgr()29 PreInstallExceptionMgr::PreInstallExceptionMgr()
30 {}
31
~PreInstallExceptionMgr()32 PreInstallExceptionMgr::~PreInstallExceptionMgr()
33 {
34 APP_LOGD("PreInstallExceptionMgr instance is destroyed");
35 }
36
GetAllPreInstallExceptionInfo( std::set<std::string> &exceptionPaths, std::set<std::string> &exceptionBundleNames, std::set<std::string> &exceptionAppServicePaths, std::set<std::string> &exceptionAppServiceBundleNames)37 bool PreInstallExceptionMgr::GetAllPreInstallExceptionInfo(
38 std::set<std::string> &exceptionPaths, std::set<std::string> &exceptionBundleNames,
39 std::set<std::string> &exceptionAppServicePaths, std::set<std::string> &exceptionAppServiceBundleNames)
40 {
41 std::lock_guard<std::mutex> lock(preInstallExceptionMutex_);
42 if (!hasInit_) {
43 APP_LOGI("LoadPreInstallExceptionInfosFromDb");
44 if (!LoadPreInstallExceptionInfosFromDb()) {
45 APP_LOGE("Load PreInstall Exception Infos FromDb error");
46 return false;
47 }
48 }
49
50 exceptionPaths = exceptionPaths_;
51 exceptionBundleNames = exceptionBundleNames_;
52 exceptionAppServicePaths = exceptionAppServicePaths_;
53 exceptionAppServiceBundleNames = exceptionAppServiceBundleNames_;
54 return !exceptionPaths_.empty() || !exceptionBundleNames_.empty() ||
55 !exceptionAppServicePaths_.empty() || !exceptionAppServiceBundleNames_.empty();
56 }
57
LoadPreInstallExceptionInfosFromDb()58 bool PreInstallExceptionMgr::LoadPreInstallExceptionInfosFromDb()
59 {
60 auto bmsPara = DelayedSingleton<BundleMgrService>::GetInstance()->GetBmsParam();
61 if (bmsPara == nullptr) {
62 APP_LOGE("bmsPara is nullptr");
63 return false;
64 }
65
66 std::string preInstallExceptionStr;
67 bmsPara->GetBmsParam(PREINSTALL_EXCEPTION, preInstallExceptionStr);
68 if (preInstallExceptionStr.empty()) {
69 APP_LOGI("preInstallExceptionStr is empty");
70 return false;
71 }
72
73 nlohmann::json jsonObject = nlohmann::json::parse(preInstallExceptionStr, nullptr, false);
74 if (jsonObject.is_discarded() || !jsonObject.is_object()) {
75 APP_LOGE("jsonObject is invalid");
76 return false;
77 }
78
79 const auto &jsonObjectEnd = jsonObject.end();
80 int32_t parseResult = ERR_OK;
81 GetValueIfFindKey<std::set<std::string>>(jsonObject, jsonObjectEnd, EXCEPTION_PATHS, exceptionPaths_,
82 JsonType::ARRAY, false, parseResult, ArrayType::STRING);
83 GetValueIfFindKey<std::set<std::string>>(jsonObject, jsonObjectEnd, EXCEPTION_BUNDLENAMES, exceptionBundleNames_,
84 JsonType::ARRAY, false, parseResult, ArrayType::STRING);
85 GetValueIfFindKey<std::set<std::string>>(jsonObject, jsonObjectEnd, EXCEPTION_APP_SERVICE_PATHS,
86 exceptionAppServicePaths_, JsonType::ARRAY, false, parseResult, ArrayType::STRING);
87 GetValueIfFindKey<std::set<std::string>>(jsonObject, jsonObjectEnd, EXCEPTION_APP_SERVICE_BUNDLENAMES,
88 exceptionAppServiceBundleNames_, JsonType::ARRAY, false, parseResult, ArrayType::STRING);
89 if (parseResult != ERR_OK) {
90 APP_LOGE("from_json error code : %{public}d", parseResult);
91 exceptionPaths_.clear();
92 exceptionBundleNames_.clear();
93 exceptionAppServicePaths_.clear();
94 exceptionAppServiceBundleNames_.clear();
95 return false;
96 }
97 APP_LOGI("Successfully loaded pre-install exception information");
98
99 hasInit_ = true;
100 return true;
101 }
102
SavePreInstallExceptionInfosToDb()103 void PreInstallExceptionMgr::SavePreInstallExceptionInfosToDb()
104 {
105 auto bmsPara = DelayedSingleton<BundleMgrService>::GetInstance()->GetBmsParam();
106 if (bmsPara == nullptr) {
107 APP_LOGE("bmsPara is nullptr");
108 return;
109 }
110
111 nlohmann::json jsonObject;
112 jsonObject[EXCEPTION_PATHS] = exceptionPaths_;
113 jsonObject[EXCEPTION_BUNDLENAMES] = exceptionBundleNames_;
114 jsonObject[EXCEPTION_APP_SERVICE_PATHS] = exceptionAppServicePaths_;
115 jsonObject[EXCEPTION_APP_SERVICE_BUNDLENAMES] = exceptionAppServiceBundleNames_;
116 bmsPara->SaveBmsParam(PREINSTALL_EXCEPTION, jsonObject.dump());
117 }
118
DeletePreInstallExceptionInfosFromDb()119 void PreInstallExceptionMgr::DeletePreInstallExceptionInfosFromDb()
120 {
121 auto bmsPara = DelayedSingleton<BundleMgrService>::GetInstance()->GetBmsParam();
122 if (bmsPara == nullptr) {
123 APP_LOGE("bmsPara is nullptr");
124 return;
125 }
126
127 nlohmann::json jsonObject;
128 if (!exceptionPaths_.empty()) {
129 jsonObject[EXCEPTION_PATHS] = exceptionPaths_;
130 }
131
132 if (!exceptionBundleNames_.empty()) {
133 jsonObject[EXCEPTION_BUNDLENAMES] = exceptionBundleNames_;
134 }
135
136 if (!exceptionAppServiceBundleNames_.empty()) {
137 jsonObject[EXCEPTION_APP_SERVICE_BUNDLENAMES] = exceptionAppServiceBundleNames_;
138 }
139
140 if (!exceptionAppServicePaths_.empty()) {
141 jsonObject[EXCEPTION_APP_SERVICE_PATHS] = exceptionAppServicePaths_;
142 }
143
144 if (jsonObject.empty()) {
145 APP_LOGI_NOFUNC("Exception information is empty, Deleting pre-install exception information from database");
146 bmsPara->DeleteBmsParam(PREINSTALL_EXCEPTION);
147 } else {
148 APP_LOGI_NOFUNC("Updating pre-install exception in database");
149 bmsPara->SaveBmsParam(PREINSTALL_EXCEPTION, jsonObject.dump());
150 }
151 }
152
SavePreInstallExceptionPath( const std::string &bundleDir)153 void PreInstallExceptionMgr::SavePreInstallExceptionPath(
154 const std::string &bundleDir)
155 {
156 std::lock_guard<std::mutex> lock(preInstallExceptionMutex_);
157 if (bundleDir.empty()) {
158 APP_LOGE("bundleDir is empty");
159 return;
160 }
161
162 if (exceptionPaths_.find(bundleDir) != exceptionPaths_.end()) {
163 APP_LOGE("bundleDir %{public}s saved", bundleDir.c_str());
164 return;
165 }
166
167 exceptionPaths_.insert(bundleDir);
168 SavePreInstallExceptionInfosToDb();
169 APP_LOGI_NOFUNC("Pre-install exception save success");
170 }
171
DeletePreInstallExceptionPath(const std::string &bundleDir)172 void PreInstallExceptionMgr::DeletePreInstallExceptionPath(const std::string &bundleDir)
173 {
174 std::lock_guard<std::mutex> lock(preInstallExceptionMutex_);
175 if (bundleDir.empty()) {
176 APP_LOGE("bundleDir is empty");
177 return;
178 }
179
180 if (exceptionPaths_.find(bundleDir) == exceptionPaths_.end()) {
181 APP_LOGE("bundleDir %{public}s deleted", bundleDir.c_str());
182 return;
183 }
184
185 auto bmsPara = DelayedSingleton<BundleMgrService>::GetInstance()->GetBmsParam();
186 if (bmsPara == nullptr) {
187 APP_LOGE("bmsPara is nullptr");
188 return;
189 }
190
191 exceptionPaths_.erase(bundleDir);
192 DeletePreInstallExceptionInfosFromDb();
193 APP_LOGI_NOFUNC("Pre-install exception delete success bundleDir:%{public}s", bundleDir.c_str());
194 }
195
SavePreInstallExceptionBundleName(const std::string &bundleName)196 void PreInstallExceptionMgr::SavePreInstallExceptionBundleName(const std::string &bundleName)
197 {
198 std::lock_guard<std::mutex> lock(preInstallExceptionMutex_);
199 if (bundleName.empty()) {
200 APP_LOGE("bundleName is empty");
201 return;
202 }
203
204 if (exceptionBundleNames_.find(bundleName) != exceptionBundleNames_.end()) {
205 APP_LOGE("bundleName %{public}s saved", bundleName.c_str());
206 return;
207 }
208
209 exceptionBundleNames_.insert(bundleName);
210 SavePreInstallExceptionInfosToDb();
211 APP_LOGI_NOFUNC("Pre-install exception save success -n %{public}s", bundleName.c_str());
212 }
213
DeletePreInstallExceptionBundleName(const std::string &bundleName)214 void PreInstallExceptionMgr::DeletePreInstallExceptionBundleName(const std::string &bundleName)
215 {
216 std::lock_guard<std::mutex> lock(preInstallExceptionMutex_);
217 if (bundleName.empty()) {
218 APP_LOGE("bundleName is empty");
219 return;
220 }
221
222 if (exceptionBundleNames_.find(bundleName) == exceptionBundleNames_.end()) {
223 APP_LOGE("bundleName %{public}s deleted", bundleName.c_str());
224 return;
225 }
226
227 exceptionBundleNames_.erase(bundleName);
228 DeletePreInstallExceptionInfosFromDb();
229 APP_LOGI_NOFUNC("Pre-install exception delete success -n %{public}s", bundleName.c_str());
230 }
231
SavePreInstallExceptionAppServiceBundleName(const std::string &bundleName)232 void PreInstallExceptionMgr::SavePreInstallExceptionAppServiceBundleName(const std::string &bundleName)
233 {
234 std::lock_guard<std::mutex> lock(preInstallExceptionMutex_);
235 if (bundleName.empty()) {
236 APP_LOGE("bundleName is empty");
237 return;
238 }
239
240 if (exceptionAppServiceBundleNames_.find(bundleName) != exceptionAppServiceBundleNames_.end()) {
241 APP_LOGE("bundleName %{public}s saved", bundleName.c_str());
242 return;
243 }
244
245 exceptionAppServiceBundleNames_.insert(bundleName);
246 SavePreInstallExceptionInfosToDb();
247 APP_LOGI_NOFUNC("Pre-install exception app service save success -n %{public}s", bundleName.c_str());
248 }
249
DeletePreInstallExceptionAppServiceBundleName(const std::string &bundleName)250 void PreInstallExceptionMgr::DeletePreInstallExceptionAppServiceBundleName(const std::string &bundleName)
251 {
252 std::lock_guard<std::mutex> lock(preInstallExceptionMutex_);
253 if (bundleName.empty()) {
254 APP_LOGE("bundleName is empty");
255 return;
256 }
257
258 if (exceptionAppServiceBundleNames_.find(bundleName) == exceptionAppServiceBundleNames_.end()) {
259 APP_LOGE("bundleName %{public}s deleted", bundleName.c_str());
260 return;
261 }
262
263 exceptionAppServiceBundleNames_.erase(bundleName);
264 DeletePreInstallExceptionInfosFromDb();
265 APP_LOGI_NOFUNC("Pre-install exception app service delete success -n %{public}s", bundleName.c_str());
266 }
267
SavePreInstallExceptionAppServicePath( const std::string &bundleDir)268 void PreInstallExceptionMgr::SavePreInstallExceptionAppServicePath(
269 const std::string &bundleDir)
270 {
271 std::lock_guard<std::mutex> lock(preInstallExceptionMutex_);
272 if (bundleDir.empty()) {
273 APP_LOGE("bundleDir is empty");
274 return;
275 }
276
277 if (exceptionAppServicePaths_.find(bundleDir) != exceptionAppServicePaths_.end()) {
278 APP_LOGE("bundleDir %{public}s saved", bundleDir.c_str());
279 return;
280 }
281
282 exceptionAppServicePaths_.insert(bundleDir);
283 SavePreInstallExceptionInfosToDb();
284 APP_LOGI_NOFUNC("Pre-install exception app service save success");
285 }
286
DeletePreInstallExceptionAppServicePath(const std::string &bundleDir)287 void PreInstallExceptionMgr::DeletePreInstallExceptionAppServicePath(const std::string &bundleDir)
288 {
289 std::lock_guard<std::mutex> lock(preInstallExceptionMutex_);
290 if (bundleDir.empty()) {
291 APP_LOGE("bundleDir is empty");
292 return;
293 }
294
295 if (exceptionAppServicePaths_.find(bundleDir) == exceptionAppServicePaths_.end()) {
296 APP_LOGE("bundleDir %{public}s deleted", bundleDir.c_str());
297 return;
298 }
299
300 auto bmsPara = DelayedSingleton<BundleMgrService>::GetInstance()->GetBmsParam();
301 if (bmsPara == nullptr) {
302 APP_LOGE("bmsPara is nullptr");
303 return;
304 }
305
306 exceptionAppServicePaths_.erase(bundleDir);
307 DeletePreInstallExceptionInfosFromDb();
308 APP_LOGI_NOFUNC("Pre-install exception app service delete success bundleDir:%{public}s", bundleDir.c_str());
309 }
310
ClearAll()311 void PreInstallExceptionMgr::ClearAll()
312 {
313 std::lock_guard<std::mutex> lock(preInstallExceptionMutex_);
314 auto bmsPara = DelayedSingleton<BundleMgrService>::GetInstance()->GetBmsParam();
315 if (bmsPara == nullptr) {
316 APP_LOGE("bmsPara is nullptr");
317 return;
318 }
319
320 bmsPara->DeleteBmsParam(PREINSTALL_EXCEPTION);
321 exceptionPaths_.clear();
322 exceptionBundleNames_.clear();
323 exceptionAppServicePaths_.clear();
324 exceptionAppServiceBundleNames_.clear();
325 hasInit_ = false;
326 APP_LOGI_NOFUNC("Pre-install exception cleare success");
327 }
328 } // namespace AppExecFwk
329 } // namespace OHOS