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 "app_log_wrapper.h"
19 #include "bundle_mgr_service.h"
20 #include "json_util.h"
21
22 namespace OHOS {
23 namespace AppExecFwk {
24 namespace {
25 const std::string PREINSTALL_EXCEPTION = "PreInstallExceptionMgr";
26 const std::string EXCEPTION_PATHS = "ExceptionPaths";
27 const std::string EXCEPTION_BUNDLENAMES = "ExceptionBundleNames";
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)37 bool PreInstallExceptionMgr::GetAllPreInstallExceptionInfo(
38 std::set<std::string> &exceptionPaths, std::set<std::string> &exceptionBundleNames)
39 {
40 std::lock_guard<std::mutex> lock(preInstallExceptionMutex_);
41 if (!hasInit_) {
42 APP_LOGI("LoadPreInstallExceptionInfosFromDb");
43 if (!LoadPreInstallExceptionInfosFromDb()) {
44 return false;
45 }
46 }
47
48 exceptionPaths = exceptionPaths_;
49 exceptionBundleNames = exceptionBundleNames_;
50 return !exceptionPaths_.empty() || !exceptionBundleNames_.empty();
51 }
52
LoadPreInstallExceptionInfosFromDb()53 bool PreInstallExceptionMgr::LoadPreInstallExceptionInfosFromDb()
54 {
55 auto bmsPara = DelayedSingleton<BundleMgrService>::GetInstance()->GetBmsParam();
56 if (bmsPara == nullptr) {
57 APP_LOGE("bmsPara is nullptr");
58 return false;
59 }
60
61 std::string preInstallExceptionStr;
62 bmsPara->GetBmsParam(PREINSTALL_EXCEPTION, preInstallExceptionStr);
63 if (preInstallExceptionStr.empty()) {
64 APP_LOGI("preInstallExceptionStr is empty");
65 return false;
66 }
67
68 nlohmann::json jsonObject = nlohmann::json::parse(preInstallExceptionStr, nullptr, false);
69 if (jsonObject.is_discarded() || !jsonObject.is_object()) {
70 APP_LOGE("jsonObject is invalid");
71 return false;
72 }
73
74 const auto &jsonObjectEnd = jsonObject.end();
75 int32_t parseResult = ERR_OK;
76 GetValueIfFindKey<std::set<std::string>>(jsonObject,
77 jsonObjectEnd,
78 EXCEPTION_PATHS,
79 exceptionPaths_,
80 JsonType::ARRAY,
81 false,
82 parseResult,
83 ArrayType::STRING);
84 GetValueIfFindKey<std::set<std::string>>(jsonObject,
85 jsonObjectEnd,
86 EXCEPTION_BUNDLENAMES,
87 exceptionBundleNames_,
88 JsonType::ARRAY,
89 false,
90 parseResult,
91 ArrayType::STRING);
92 if (parseResult != ERR_OK) {
93 APP_LOGE("from_json error, error code : %{public}d", parseResult);
94 exceptionPaths_.clear();
95 exceptionBundleNames_.clear();
96 return false;
97 }
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 bmsPara->DeleteBmsParam(PREINSTALL_EXCEPTION);
136 } else {
137 bmsPara->SaveBmsParam(PREINSTALL_EXCEPTION, jsonObject.dump());
138 }
139 }
140
SavePreInstallExceptionPath(const std::string & bundleDir)141 void PreInstallExceptionMgr::SavePreInstallExceptionPath(
142 const std::string &bundleDir)
143 {
144 std::lock_guard<std::mutex> lock(preInstallExceptionMutex_);
145 if (bundleDir.empty()) {
146 APP_LOGE("bundleDir is empty");
147 return;
148 }
149
150 if (exceptionPaths_.find(bundleDir) != exceptionPaths_.end()) {
151 APP_LOGE("bundleDir %{public}s has saved", bundleDir.c_str());
152 return;
153 }
154
155 exceptionPaths_.insert(bundleDir);
156 SavePreInstallExceptionInfosToDb();
157 }
158
DeletePreInstallExceptionPath(const std::string & bundleDir)159 void PreInstallExceptionMgr::DeletePreInstallExceptionPath(const std::string &bundleDir)
160 {
161 std::lock_guard<std::mutex> lock(preInstallExceptionMutex_);
162 if (bundleDir.empty()) {
163 APP_LOGE("bundleDir is empty");
164 return;
165 }
166
167 if (exceptionPaths_.find(bundleDir) == exceptionPaths_.end()) {
168 APP_LOGE("bundleDir %{public}s has deleted", bundleDir.c_str());
169 return;
170 }
171
172 auto bmsPara = DelayedSingleton<BundleMgrService>::GetInstance()->GetBmsParam();
173 if (bmsPara == nullptr) {
174 APP_LOGE("bmsPara is nullptr");
175 return;
176 }
177
178 exceptionPaths_.erase(bundleDir);
179 DeletePreInstallExceptionInfosFromDb();
180 }
181
SavePreInstallExceptionBundleName(const std::string & bundleName)182 void PreInstallExceptionMgr::SavePreInstallExceptionBundleName(const std::string &bundleName)
183 {
184 std::lock_guard<std::mutex> lock(preInstallExceptionMutex_);
185 if (bundleName.empty()) {
186 APP_LOGE("bundleName is empty");
187 return;
188 }
189
190 if (exceptionBundleNames_.find(bundleName) != exceptionBundleNames_.end()) {
191 APP_LOGE("bundleName %{public}s has saved", bundleName.c_str());
192 return;
193 }
194
195 exceptionBundleNames_.insert(bundleName);
196 SavePreInstallExceptionInfosToDb();
197 }
198
DeletePreInstallExceptionBundleName(const std::string & bundleName)199 void PreInstallExceptionMgr::DeletePreInstallExceptionBundleName(const std::string &bundleName)
200 {
201 std::lock_guard<std::mutex> lock(preInstallExceptionMutex_);
202 if (bundleName.empty()) {
203 APP_LOGE("bundleName is empty");
204 return;
205 }
206
207 if (exceptionBundleNames_.find(bundleName) == exceptionBundleNames_.end()) {
208 APP_LOGE("bundleName %{public}s has deleted", bundleName.c_str());
209 return;
210 }
211
212 exceptionBundleNames_.erase(bundleName);
213 DeletePreInstallExceptionInfosFromDb();
214 }
215
ClearAll()216 void PreInstallExceptionMgr::ClearAll()
217 {
218 std::lock_guard<std::mutex> lock(preInstallExceptionMutex_);
219 auto bmsPara = DelayedSingleton<BundleMgrService>::GetInstance()->GetBmsParam();
220 if (bmsPara == nullptr) {
221 APP_LOGE("bmsPara is nullptr");
222 return;
223 }
224
225 bmsPara->DeleteBmsParam(PREINSTALL_EXCEPTION);
226 exceptionPaths_.clear();
227 exceptionBundleNames_.clear();
228 hasInit_ = false;
229 }
230 } // namespace AppExecFwk
231 } // namespace OHOS