• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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