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