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 const std::string PREINSTALL_EXCEPTION = "PreInstallExceptionMgr";
24 const std::string EXCEPTION_PATHS = "ExceptionPaths";
25 const std::string EXCEPTION_BUNDLENAMES = "ExceptionBundleNames";
26 }
PreInstallExceptionMgr()27 PreInstallExceptionMgr::PreInstallExceptionMgr()
28 {}
29
~PreInstallExceptionMgr()30 PreInstallExceptionMgr::~PreInstallExceptionMgr()
31 {
32 APP_LOGD("PreInstallExceptionMgr instance is destroyed");
33 }
34
GetAllPreInstallExceptionInfo(std::set<std::string> & exceptionPaths,std::set<std::string> & exceptionBundleNames)35 bool PreInstallExceptionMgr::GetAllPreInstallExceptionInfo(
36 std::set<std::string> &exceptionPaths, std::set<std::string> &exceptionBundleNames)
37 {
38 std::lock_guard<std::mutex> lock(preInstallExceptionMutex_);
39 if (!hasInit_) {
40 APP_LOGI("LoadPreInstallExceptionInfosFromDb");
41 if (!LoadPreInstallExceptionInfosFromDb()) {
42 APP_LOGE("Load PreInstall Exception Infos FromDb error");
43 return false;
44 }
45 }
46
47 exceptionPaths = exceptionPaths_;
48 exceptionBundleNames = exceptionBundleNames_;
49 return !exceptionPaths_.empty() || !exceptionBundleNames_.empty();
50 }
51
LoadPreInstallExceptionInfosFromDb()52 bool PreInstallExceptionMgr::LoadPreInstallExceptionInfosFromDb()
53 {
54 auto bmsPara = DelayedSingleton<BundleMgrService>::GetInstance()->GetBmsParam();
55 if (bmsPara == nullptr) {
56 APP_LOGE("bmsPara is nullptr");
57 return false;
58 }
59
60 std::string preInstallExceptionStr;
61 bmsPara->GetBmsParam(PREINSTALL_EXCEPTION, preInstallExceptionStr);
62 if (preInstallExceptionStr.empty()) {
63 APP_LOGI("preInstallExceptionStr is empty");
64 return false;
65 }
66
67 nlohmann::json jsonObject = nlohmann::json::parse(preInstallExceptionStr, nullptr, false);
68 if (jsonObject.is_discarded() || !jsonObject.is_object()) {
69 APP_LOGE("jsonObject is invalid");
70 return false;
71 }
72
73 const auto &jsonObjectEnd = jsonObject.end();
74 int32_t parseResult = ERR_OK;
75 GetValueIfFindKey<std::set<std::string>>(jsonObject,
76 jsonObjectEnd,
77 EXCEPTION_PATHS,
78 exceptionPaths_,
79 JsonType::ARRAY,
80 false,
81 parseResult,
82 ArrayType::STRING);
83 GetValueIfFindKey<std::set<std::string>>(jsonObject,
84 jsonObjectEnd,
85 EXCEPTION_BUNDLENAMES,
86 exceptionBundleNames_,
87 JsonType::ARRAY,
88 false,
89 parseResult,
90 ArrayType::STRING);
91 if (parseResult != ERR_OK) {
92 APP_LOGE("from_json error code : %{public}d", parseResult);
93 exceptionPaths_.clear();
94 exceptionBundleNames_.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 bmsPara->SaveBmsParam(PREINSTALL_EXCEPTION, jsonObject.dump());
115 }
116
DeletePreInstallExceptionInfosFromDb()117 void PreInstallExceptionMgr::DeletePreInstallExceptionInfosFromDb()
118 {
119 auto bmsPara = DelayedSingleton<BundleMgrService>::GetInstance()->GetBmsParam();
120 if (bmsPara == nullptr) {
121 APP_LOGE("bmsPara is nullptr");
122 return;
123 }
124
125 nlohmann::json jsonObject;
126 if (!exceptionPaths_.empty()) {
127 jsonObject[EXCEPTION_PATHS] = exceptionPaths_;
128 }
129
130 if (!exceptionBundleNames_.empty()) {
131 jsonObject[EXCEPTION_BUNDLENAMES] = exceptionBundleNames_;
132 }
133
134 if (jsonObject.empty()) {
135 APP_LOGI_NOFUNC("Exception information is empty, Deleting pre-install exception information from database");
136 bmsPara->DeleteBmsParam(PREINSTALL_EXCEPTION);
137 } else {
138 APP_LOGI_NOFUNC("Updating pre-install exception in database");
139 bmsPara->SaveBmsParam(PREINSTALL_EXCEPTION, jsonObject.dump());
140 }
141 }
142
SavePreInstallExceptionPath(const std::string & bundleDir)143 void PreInstallExceptionMgr::SavePreInstallExceptionPath(
144 const std::string &bundleDir)
145 {
146 std::lock_guard<std::mutex> lock(preInstallExceptionMutex_);
147 if (bundleDir.empty()) {
148 APP_LOGE("bundleDir is empty");
149 return;
150 }
151
152 if (exceptionPaths_.find(bundleDir) != exceptionPaths_.end()) {
153 APP_LOGE("bundleDir %{public}s saved", bundleDir.c_str());
154 return;
155 }
156
157 exceptionPaths_.insert(bundleDir);
158 SavePreInstallExceptionInfosToDb();
159 APP_LOGI_NOFUNC("Pre-install exception save success");
160 }
161
DeletePreInstallExceptionPath(const std::string & bundleDir)162 void PreInstallExceptionMgr::DeletePreInstallExceptionPath(const std::string &bundleDir)
163 {
164 std::lock_guard<std::mutex> lock(preInstallExceptionMutex_);
165 if (bundleDir.empty()) {
166 APP_LOGE("bundleDir is empty");
167 return;
168 }
169
170 if (exceptionPaths_.find(bundleDir) == exceptionPaths_.end()) {
171 APP_LOGE("bundleDir %{public}s deleted", bundleDir.c_str());
172 return;
173 }
174
175 auto bmsPara = DelayedSingleton<BundleMgrService>::GetInstance()->GetBmsParam();
176 if (bmsPara == nullptr) {
177 APP_LOGE("bmsPara is nullptr");
178 return;
179 }
180
181 exceptionPaths_.erase(bundleDir);
182 APP_LOGI_NOFUNC("exceptionPaths erase dir:%{public}s", bundleDir.c_str());
183 DeletePreInstallExceptionInfosFromDb();
184 }
185
SavePreInstallExceptionBundleName(const std::string & bundleName)186 void PreInstallExceptionMgr::SavePreInstallExceptionBundleName(const std::string &bundleName)
187 {
188 std::lock_guard<std::mutex> lock(preInstallExceptionMutex_);
189 if (bundleName.empty()) {
190 APP_LOGE("bundleName is empty");
191 return;
192 }
193
194 if (exceptionBundleNames_.find(bundleName) != exceptionBundleNames_.end()) {
195 APP_LOGE("bundleName %{public}s saved", bundleName.c_str());
196 return;
197 }
198
199 exceptionBundleNames_.insert(bundleName);
200 SavePreInstallExceptionInfosToDb();
201 APP_LOGI_NOFUNC("Pre-install exception save success -n %{public}s", bundleName.c_str());
202 }
203
DeletePreInstallExceptionBundleName(const std::string & bundleName)204 void PreInstallExceptionMgr::DeletePreInstallExceptionBundleName(const std::string &bundleName)
205 {
206 std::lock_guard<std::mutex> lock(preInstallExceptionMutex_);
207 if (bundleName.empty()) {
208 APP_LOGE("bundleName is empty");
209 return;
210 }
211
212 if (exceptionBundleNames_.find(bundleName) == exceptionBundleNames_.end()) {
213 APP_LOGE("bundleName %{public}s deleted", bundleName.c_str());
214 return;
215 }
216
217 exceptionBundleNames_.erase(bundleName);
218 APP_LOGI_NOFUNC("exceptionBundleNames erase -n %{public}s", bundleName.c_str());
219 DeletePreInstallExceptionInfosFromDb();
220 }
221
ClearAll()222 void PreInstallExceptionMgr::ClearAll()
223 {
224 std::lock_guard<std::mutex> lock(preInstallExceptionMutex_);
225 auto bmsPara = DelayedSingleton<BundleMgrService>::GetInstance()->GetBmsParam();
226 if (bmsPara == nullptr) {
227 APP_LOGE("bmsPara is nullptr");
228 return;
229 }
230
231 bmsPara->DeleteBmsParam(PREINSTALL_EXCEPTION);
232 exceptionPaths_.clear();
233 exceptionBundleNames_.clear();
234 hasInit_ = false;
235 APP_LOGI_NOFUNC("Pre-install exception cleare success");
236 }
237 } // namespace AppExecFwk
238 } // namespace OHOS