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