1 /*
2 * Copyright (c) 2022-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 "quick_fix_manager_service.h"
17
18 #include "hilog_wrapper.h"
19 #include "hitrace_meter.h"
20 #include "permission_verification.h"
21 #include "quick_fix_error_utils.h"
22 #include "quick_fix_utils.h"
23
24 namespace OHOS {
25 namespace AAFwk {
26 std::mutex QuickFixManagerService::mutex_;
27 sptr<QuickFixManagerService> QuickFixManagerService::instance_;
28
GetInstance()29 sptr<QuickFixManagerService> QuickFixManagerService::GetInstance()
30 {
31 std::lock_guard<std::mutex> lock(mutex_);
32
33 if (instance_ == nullptr) {
34 instance_ = new QuickFixManagerService();
35 }
36 return instance_;
37 }
38
Init()39 bool QuickFixManagerService::Init()
40 {
41 std::lock_guard<std::mutex> lock(mutex_);
42 eventRunner_ = AppExecFwk::EventRunner::Create("QuickFixMgrSvrMain");
43 if (eventRunner_ == nullptr) {
44 HILOG_ERROR("Create event runner failed.");
45 return false;
46 }
47
48 eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(eventRunner_);
49 if (eventHandler_ == nullptr) {
50 HILOG_ERROR("Create event handler failed.");
51 return false;
52 }
53
54 return true;
55 }
56
ApplyQuickFix(const std::vector<std::string> & quickFixFiles)57 int32_t QuickFixManagerService::ApplyQuickFix(const std::vector<std::string> &quickFixFiles)
58 {
59 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
60 HILOG_DEBUG("function called.");
61 if (!AAFwk::PermissionVerification::GetInstance()->JudgeCallerIsAllowedToUseSystemAPI()) {
62 HILOG_ERROR("The caller is not system-app, can not use system-api");
63 return QUICK_FIX_NOT_SYSTEM_APP;
64 }
65 if (!AAFwk::PermissionVerification::GetInstance()->VerifyInstallBundlePermission()) {
66 return QUICK_FIX_VERIFY_PERMISSION_FAILED;
67 }
68
69 auto bundleQfMgr = QuickFixUtil::GetBundleQuickFixMgrProxy();
70 if (bundleQfMgr == nullptr) {
71 HILOG_ERROR("Bundle quick fix manager is nullptr.");
72 return QUICK_FIX_CONNECT_FAILED;
73 }
74
75 auto appMgr = QuickFixUtil::GetAppManagerProxy();
76 if (appMgr == nullptr) {
77 HILOG_ERROR("App manager is nullptr.");
78 return QUICK_FIX_CONNECT_FAILED;
79 }
80
81 auto applyTask = std::make_shared<QuickFixManagerApplyTask>(bundleQfMgr, appMgr, eventHandler_, this);
82 AddApplyTask(applyTask);
83 applyTask->Run(quickFixFiles);
84
85 HILOG_DEBUG("function finished.");
86 return QUICK_FIX_OK;
87 }
88
GetApplyedQuickFixInfo(const std::string & bundleName,ApplicationQuickFixInfo & quickFixInfo)89 int32_t QuickFixManagerService::GetApplyedQuickFixInfo(const std::string &bundleName,
90 ApplicationQuickFixInfo &quickFixInfo)
91 {
92 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
93 HILOG_DEBUG("function called.");
94 if (!AAFwk::PermissionVerification::GetInstance()->JudgeCallerIsAllowedToUseSystemAPI()) {
95 HILOG_ERROR("The caller is not system-app, can not use system-api");
96 return QUICK_FIX_NOT_SYSTEM_APP;
97 }
98 if (!AAFwk::PermissionVerification::GetInstance()->VerifyGetBundleInfoPrivilegedPermission()) {
99 return QUICK_FIX_VERIFY_PERMISSION_FAILED;
100 }
101
102 auto bundleMgr = QuickFixUtil::GetBundleManagerProxy();
103 if (bundleMgr == nullptr) {
104 HILOG_ERROR("Failed to get bundle manager.");
105 return QUICK_FIX_CONNECT_FAILED;
106 }
107
108 AppExecFwk::BundleInfo bundleInfo;
109 if (!bundleMgr->GetBundleInfo(bundleName, AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, bundleInfo,
110 AppExecFwk::Constants::ANY_USERID)) {
111 HILOG_ERROR("Get bundle info failed.");
112 return QUICK_FIX_GET_BUNDLE_INFO_FAILED;
113 }
114
115 quickFixInfo.bundleName = bundleName;
116 quickFixInfo.bundleVersionCode = bundleInfo.versionCode;
117 quickFixInfo.bundleVersionName = bundleInfo.versionName;
118 quickFixInfo.appqfInfo = bundleInfo.applicationInfo.appQuickFix.deployedAppqfInfo;
119
120 HILOG_DEBUG("function finished.");
121 return QUICK_FIX_OK;
122 }
123
RevokeQuickFix(const std::string & bundleName)124 int32_t QuickFixManagerService::RevokeQuickFix(const std::string &bundleName)
125 {
126 HILOG_DEBUG("Function called.");
127 if (!AAFwk::PermissionVerification::GetInstance()->JudgeCallerIsAllowedToUseSystemAPI()) {
128 HILOG_ERROR("The caller is not system-app, can not use system-api");
129 return QUICK_FIX_NOT_SYSTEM_APP;
130 }
131
132 if (!AAFwk::PermissionVerification::GetInstance()->VerifyGetBundleInfoPrivilegedPermission() ||
133 !AAFwk::PermissionVerification::GetInstance()->VerifyInstallBundlePermission()) {
134 HILOG_ERROR("Permission verification failed");
135 return QUICK_FIX_VERIFY_PERMISSION_FAILED;
136 }
137
138 if (CheckTaskRunningState(bundleName)) {
139 HILOG_ERROR("Has a apply quick fix task");
140 return QUICK_FIX_DEPLOYING_TASK;
141 }
142
143 auto bundleMgr = QuickFixUtil::GetBundleManagerProxy();
144 if (bundleMgr == nullptr) {
145 HILOG_ERROR("Failed to get bundle manager.");
146 return QUICK_FIX_CONNECT_FAILED;
147 }
148
149 AppExecFwk::BundleInfo bundleInfo;
150 if (!bundleMgr->GetBundleInfo(bundleName, AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, bundleInfo,
151 AppExecFwk::Constants::ANY_USERID)) {
152 HILOG_ERROR("Get bundle info failed.");
153 return QUICK_FIX_GET_BUNDLE_INFO_FAILED;
154 }
155
156 auto isSoContained = !bundleInfo.applicationInfo.appQuickFix.deployedAppqfInfo.nativeLibraryPath.empty();
157 auto patchExists = true;
158 for (auto &item : bundleInfo.hapModuleInfos) {
159 if (!item.hqfInfo.moduleName.empty()) {
160 patchExists = false;
161 break;
162 }
163 }
164
165 if (patchExists) {
166 HILOG_ERROR("Patch does not exist.");
167 return QUICK_FIX_GET_BUNDLE_INFO_FAILED;
168 }
169
170 auto appMgr = QuickFixUtil::GetAppManagerProxy();
171 if (appMgr == nullptr) {
172 HILOG_ERROR("App manager is nullptr.");
173 return QUICK_FIX_CONNECT_FAILED;
174 }
175
176 auto bundleQfMgr = QuickFixUtil::GetBundleQuickFixMgrProxy();
177 if (bundleQfMgr == nullptr) {
178 HILOG_ERROR("Bundle quick fix manager is nullptr.");
179 return QUICK_FIX_CONNECT_FAILED;
180 }
181
182 auto applyTask = std::make_shared<QuickFixManagerApplyTask>(bundleQfMgr, appMgr, eventHandler_, this);
183 if (applyTask == nullptr) {
184 HILOG_ERROR("Task connect failed.");
185 return QUICK_FIX_CONNECT_FAILED;
186 }
187
188 applyTask->InitRevokeTask(bundleName, isSoContained);
189 AddApplyTask(applyTask);
190 applyTask->RunRevoke();
191 HILOG_DEBUG("Function finished.");
192 return QUICK_FIX_OK;
193 }
194
AddApplyTask(std::shared_ptr<QuickFixManagerApplyTask> applyTask)195 void QuickFixManagerService::AddApplyTask(std::shared_ptr<QuickFixManagerApplyTask> applyTask)
196 {
197 std::lock_guard<std::mutex> lock(mutex_);
198 applyTasks_.emplace_back(applyTask);
199 }
200
RemoveApplyTask(std::shared_ptr<QuickFixManagerApplyTask> applyTask)201 void QuickFixManagerService::RemoveApplyTask(std::shared_ptr<QuickFixManagerApplyTask> applyTask)
202 {
203 std::lock_guard<std::mutex> lock(mutex_);
204 for (auto it = applyTasks_.begin(); it != applyTasks_.end();) {
205 if (*it == applyTask) {
206 it = applyTasks_.erase(it);
207 } else {
208 it++;
209 }
210 }
211 }
212
CheckTaskRunningState(const std::string & bundleName)213 bool QuickFixManagerService::CheckTaskRunningState(const std::string &bundleName)
214 {
215 std::lock_guard<std::mutex> lock(mutex_);
216 for (auto &item : applyTasks_) {
217 if (item != nullptr && item->GetBundleName() == bundleName) {
218 return true;
219 }
220 }
221
222 HILOG_DEBUG("bundleName %{public}s not found in tasks.", bundleName.c_str());
223 return false;
224 }
225 } // namespace AAFwk
226 } // namespace OHOS
227