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