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_client.h"
17
18 #include "appexecfwk_errors.h"
19 #include "hilog_tag_wrapper.h"
20 #include "hitrace_meter.h"
21 #include "if_system_ability_manager.h"
22 #include "iservice_registry.h"
23 #include "quick_fix_error_utils.h"
24 #include "quick_fix_load_callback.h"
25 #include "quick_fix_manager_proxy.h"
26 #include "quick_fix_utils.h"
27 #include "system_ability_definition.h"
28
29 namespace OHOS {
30 namespace AAFwk {
31 namespace {
32 const int LOAD_SA_TIMEOUT_MS = 4 * 1000;
33 } // namespace
34
ApplyQuickFix(const std::vector<std::string> & quickFixFiles,bool isDebug,bool isReplace)35 int32_t QuickFixManagerClient::ApplyQuickFix(const std::vector<std::string> &quickFixFiles, bool isDebug,
36 bool isReplace)
37 {
38 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
39 TAG_LOGD(AAFwkTag::QUICKFIX, "called");
40
41 auto quickFixMgr = GetQuickFixMgrProxy();
42 if (quickFixMgr == nullptr) {
43 TAG_LOGE(AAFwkTag::QUICKFIX, "Get quick fix manager service failed");
44 return QUICK_FIX_CONNECT_FAILED;
45 }
46
47 auto bundleQuickFixMgr = QuickFixUtil::GetBundleQuickFixMgrProxy();
48 if (bundleQuickFixMgr == nullptr) {
49 return QUICK_FIX_CONNECT_FAILED;
50 }
51
52 TAG_LOGD(AAFwkTag::QUICKFIX, "hqf file number need to apply: %{public}zu", quickFixFiles.size());
53 std::vector<std::string> destFiles;
54 auto copyRet = bundleQuickFixMgr->CopyFiles(quickFixFiles, destFiles);
55 if (copyRet != 0) {
56 TAG_LOGE(AAFwkTag::QUICKFIX, "Copy files failed.");
57 return (copyRet == ERR_BUNDLEMANAGER_QUICK_FIX_PERMISSION_DENIED) ? QUICK_FIX_VERIFY_PERMISSION_FAILED :
58 QUICK_FIX_COPY_FILES_FAILED;
59 }
60
61 return quickFixMgr->ApplyQuickFix(destFiles, isDebug, isReplace);
62 }
63
GetApplyedQuickFixInfo(const std::string & bundleName,ApplicationQuickFixInfo & quickFixInfo)64 int32_t QuickFixManagerClient::GetApplyedQuickFixInfo(const std::string &bundleName,
65 ApplicationQuickFixInfo &quickFixInfo)
66 {
67 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
68 TAG_LOGD(AAFwkTag::QUICKFIX, "called");
69
70 auto quickFixMgr = GetQuickFixMgrProxy();
71 if (quickFixMgr == nullptr) {
72 TAG_LOGE(AAFwkTag::QUICKFIX, "Get quick fix manager service failed");
73 return QUICK_FIX_CONNECT_FAILED;
74 }
75
76 return quickFixMgr->GetApplyedQuickFixInfo(bundleName, quickFixInfo);
77 }
78
GetQuickFixMgrProxy()79 sptr<IQuickFixManager> QuickFixManagerClient::GetQuickFixMgrProxy()
80 {
81 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
82 TAG_LOGD(AAFwkTag::QUICKFIX, "called");
83 auto quickFixMgr = GetQuickFixMgr();
84 if (quickFixMgr != nullptr) {
85 TAG_LOGD(AAFwkTag::QUICKFIX, "Quick fix manager has been started");
86 return quickFixMgr;
87 }
88
89 if (!LoadQuickFixMgrService()) {
90 TAG_LOGE(AAFwkTag::QUICKFIX, "Load quick fix manager service failed");
91 return nullptr;
92 }
93
94 quickFixMgr = GetQuickFixMgr();
95 if (quickFixMgr == nullptr || quickFixMgr->AsObject() == nullptr) {
96 TAG_LOGE(AAFwkTag::QUICKFIX, "Failed to get quick fix manager");
97 return nullptr;
98 }
99
100 auto self = weak_from_this();
101 const auto &onClearProxyCallback = [self](const wptr<IRemoteObject> &remote) {
102 auto impl = self.lock();
103 if (impl && impl->quickFixMgr_ == remote) {
104 impl->ClearProxy();
105 }
106 };
107
108 sptr<QfmsDeathRecipient> recipient(new (std::nothrow) QfmsDeathRecipient(onClearProxyCallback));
109 quickFixMgr->AsObject()->AddDeathRecipient(recipient);
110
111 return quickFixMgr;
112 }
113
RevokeQuickFix(const std::string & bundleName)114 int32_t QuickFixManagerClient::RevokeQuickFix(const std::string &bundleName)
115 {
116 TAG_LOGD(AAFwkTag::QUICKFIX, "called");
117
118 auto quickFixMgr = GetQuickFixMgrProxy();
119 if (quickFixMgr == nullptr) {
120 TAG_LOGE(AAFwkTag::QUICKFIX, "Get quick fix manager service failed");
121 return QUICK_FIX_CONNECT_FAILED;
122 }
123
124 auto retval = quickFixMgr->RevokeQuickFix(bundleName);
125 TAG_LOGD(AAFwkTag::QUICKFIX, "Function call end, retval is %{public}d", retval);
126 return retval;
127 }
128
ClearProxy()129 void QuickFixManagerClient::ClearProxy()
130 {
131 TAG_LOGD(AAFwkTag::QUICKFIX, "called");
132 std::lock_guard<std::mutex> lock(mutex_);
133 quickFixMgr_ = nullptr;
134 }
135
OnRemoteDied(const wptr<IRemoteObject> & remote)136 void QuickFixManagerClient::QfmsDeathRecipient::OnRemoteDied([[maybe_unused]] const wptr<IRemoteObject> &remote)
137 {
138 if (proxy_ != nullptr) {
139 TAG_LOGE(AAFwkTag::QUICKFIX, "quick fix manager service died");
140 proxy_(remote);
141 }
142 }
143
LoadQuickFixMgrService()144 bool QuickFixManagerClient::LoadQuickFixMgrService()
145 {
146 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
147 {
148 std::unique_lock<std::mutex> lock(loadSaMutex_);
149 loadSaFinished_ = false;
150 }
151
152 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, "GetSystemAbilityManager");
153 auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
154 if (systemAbilityMgr == nullptr) {
155 TAG_LOGE(AAFwkTag::QUICKFIX, "Failed to get SystemAbilityManager");
156 return false;
157 }
158
159 sptr<QuickFixLoadCallback> loadCallback = new (std::nothrow) QuickFixLoadCallback();
160 if (loadCallback == nullptr) {
161 TAG_LOGE(AAFwkTag::QUICKFIX, "Create load callback failed");
162 return false;
163 }
164
165 auto ret = systemAbilityMgr->LoadSystemAbility(QUICK_FIX_MGR_SERVICE_ID, loadCallback);
166 if (ret != 0) {
167 TAG_LOGE(AAFwkTag::QUICKFIX, "Load system ability %{public}d failed with %{public}d", QUICK_FIX_MGR_SERVICE_ID,
168 ret);
169 return false;
170 }
171
172 {
173 std::unique_lock<std::mutex> lock(loadSaMutex_);
174 auto waitStatus = loadSaCondation_.wait_for(lock, std::chrono::milliseconds(LOAD_SA_TIMEOUT_MS),
175 [this]() {
176 return loadSaFinished_;
177 });
178 if (!waitStatus) {
179 TAG_LOGE(AAFwkTag::QUICKFIX, "Wait for load sa timeout");
180 return false;
181 }
182 }
183
184 return true;
185 }
186
SetQuickFixMgr(const sptr<IRemoteObject> & remoteObject)187 void QuickFixManagerClient::SetQuickFixMgr(const sptr<IRemoteObject> &remoteObject)
188 {
189 std::lock_guard<std::mutex> lock(mutex_);
190 quickFixMgr_ = iface_cast<IQuickFixManager>(remoteObject);
191 }
192
GetQuickFixMgr()193 sptr<IQuickFixManager> QuickFixManagerClient::GetQuickFixMgr()
194 {
195 std::lock_guard<std::mutex> lock(mutex_);
196 return quickFixMgr_;
197 }
198
OnLoadSystemAbilitySuccess(const sptr<IRemoteObject> & remoteObject)199 void QuickFixManagerClient::OnLoadSystemAbilitySuccess(const sptr<IRemoteObject> &remoteObject)
200 {
201 SetQuickFixMgr(remoteObject);
202 std::unique_lock<std::mutex> lock(loadSaMutex_);
203 loadSaFinished_ = true;
204 loadSaCondation_.notify_one();
205 }
206
OnLoadSystemAbilityFail()207 void QuickFixManagerClient::OnLoadSystemAbilityFail()
208 {
209 SetQuickFixMgr(nullptr);
210 std::unique_lock<std::mutex> lock(loadSaMutex_);
211 loadSaFinished_ = true;
212 loadSaCondation_.notify_one();
213 }
214 } // namespace AAFwk
215 } // namespace OHOS
216