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