1 /*
2 * Copyright (c) 2022 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_command.h"
17
18 #include "app_log_wrapper.h"
19 #include "common_event_data.h"
20 #include "common_event_manager.h"
21 #include "common_event_support.h"
22 #include "quick_fix_manager_client.h"
23 #include "status_receiver_impl.h"
24 #include "want.h"
25
26 namespace OHOS {
27 namespace AppExecFwk {
28 class ApplyQuickFixMonitor : public EventFwk::CommonEventSubscriber,
29 public std::enable_shared_from_this<ApplyQuickFixMonitor> {
30 public:
ApplyQuickFixMonitor(const EventFwk::CommonEventSubscribeInfo & subscribeInfo,sptr<StatusReceiverImpl> receiver)31 ApplyQuickFixMonitor(const EventFwk::CommonEventSubscribeInfo &subscribeInfo, sptr<StatusReceiverImpl> receiver)
32 : EventFwk::CommonEventSubscriber(subscribeInfo), statusReceiver_(receiver)
33 {}
34
35 virtual ~ApplyQuickFixMonitor() = default;
36
OnReceiveEvent(const EventFwk::CommonEventData & eventData)37 void OnReceiveEvent(const EventFwk::CommonEventData &eventData)
38 {
39 APP_LOGD("function called.");
40 AAFwk::Want want = eventData.GetWant();
41 int32_t applyResult = want.GetIntParam("applyResult", -1);
42 std::string resultInfo = want.GetStringParam("applyResultInfo");
43 std::string bundleName = want.GetStringParam("bundleName");
44 APP_LOGD("bundleName: %{public}s, applyResult: %{public}d, resultInfo: %{public}s.",
45 bundleName.c_str(), applyResult, resultInfo.c_str());
46 resultInfo_ = resultInfo;
47 statusReceiver_->OnFinished(applyResult, resultInfo);
48 }
49
GetResultInfo()50 std::string GetResultInfo()
51 {
52 return resultInfo_;
53 }
54
55 private:
56 sptr<StatusReceiverImpl> statusReceiver_ = nullptr;
57 std::string resultInfo_;
58 };
59
ApplyQuickFix(const std::vector<std::string> & quickFixFiles,std::string & resultInfo)60 int32_t QuickFixCommand::ApplyQuickFix(const std::vector<std::string> &quickFixFiles, std::string &resultInfo)
61 {
62 if (quickFixFiles.empty()) {
63 resultInfo.append("quick fix file is empty.\n");
64 return ERR_INVALID_VALUE;
65 }
66
67 for (auto file : quickFixFiles) {
68 APP_LOGI("apply hqf file %{private}s.", file.c_str());
69 }
70
71 sptr<StatusReceiverImpl> statusReceiver(new (std::nothrow) StatusReceiverImpl());
72 if (statusReceiver == nullptr) {
73 resultInfo.append("Create status receiver failed.\n");
74 return ERR_INVALID_VALUE;
75 }
76
77 EventFwk::MatchingSkills matchingSkills;
78 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_QUICK_FIX_APPLY_RESULT);
79 EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
80 auto applyMonitor = std::make_shared<ApplyQuickFixMonitor>(subscribeInfo, statusReceiver);
81 EventFwk::CommonEventManager::SubscribeCommonEvent(applyMonitor);
82
83 auto result = DelayedSingleton<AAFwk::QuickFixManagerClient>::GetInstance()->ApplyQuickFix(quickFixFiles);
84 if (result == ERR_OK) {
85 APP_LOGD("Waiting apply finished.");
86 result = statusReceiver->GetResultCode();
87 }
88
89 if (result == ERR_OK) {
90 resultInfo.append("apply quickfix succeed.\n");
91 } else {
92 if (applyMonitor->GetResultInfo().empty()) {
93 resultInfo.append("apply quickfix failed with errno: " + std::to_string(result) + ".\n");
94 } else {
95 resultInfo.append("apply quickfix failed with error: " + applyMonitor->GetResultInfo() + ".\n");
96 }
97 }
98
99 return result;
100 }
101
GetApplyedQuickFixInfo(const std::string & bundleName,std::string & resultInfo)102 int32_t QuickFixCommand::GetApplyedQuickFixInfo(const std::string &bundleName, std::string &resultInfo)
103 {
104 if (bundleName.empty()) {
105 resultInfo.append("bundle name is empty.\n");
106 return ERR_INVALID_VALUE;
107 }
108
109 AAFwk::ApplicationQuickFixInfo quickFixInfo;
110 auto result = AAFwk::QuickFixManagerClient::GetInstance()->GetApplyedQuickFixInfo(bundleName, quickFixInfo);
111 if (result == ERR_OK) {
112 resultInfo.append("Information as follows:\n");
113 resultInfo.append(GetQuickFixInfoString(quickFixInfo));
114 } else {
115 resultInfo.append("Get quick fix info failed with errno " + std::to_string(result) + ".\n");
116 }
117
118 return result;
119 }
120
GetQuickFixInfoString(const AAFwk::ApplicationQuickFixInfo & quickFixInfo)121 std::string QuickFixCommand::GetQuickFixInfoString(const AAFwk::ApplicationQuickFixInfo &quickFixInfo)
122 {
123 std::string info;
124 info = "ApplicationQuickFixInfo:\n";
125 info.append(" bundle name: " + quickFixInfo.bundleName + "\n");
126 info.append(" bundle version code: " + std::to_string(quickFixInfo.bundleVersionCode) + "\n");
127 info.append(" bundle version name: " + quickFixInfo.bundleVersionName + "\n");
128 AppqfInfo appqfInfo = quickFixInfo.appqfInfo;
129 info.append(" patch version code: " + std::to_string(appqfInfo.versionCode) + "\n");
130 info.append(" patch version name: " + appqfInfo.versionName + "\n");
131 info.append(" cpu abi: " + appqfInfo.cpuAbi + "\n");
132 info.append(" native library path: " + appqfInfo.nativeLibraryPath + "\n");
133 std::string type;
134 if (appqfInfo.type == AppExecFwk::QuickFixType::PATCH) {
135 type = "patch";
136 } else if (appqfInfo.type == AppExecFwk::QuickFixType::HOT_RELOAD) {
137 type = "hotreload";
138 }
139 info.append(" type: " + type + "\n");
140 for (auto hqfInfo : appqfInfo.hqfInfos) {
141 info.append(" ModuelQuickFixInfo:\n");
142 info.append(" module name: " + hqfInfo.moduleName + "\n");
143 info.append(" module sha256: " + hqfInfo.hapSha256 + "\n");
144 info.append(" file path: " + hqfInfo.hqfFilePath + "\n");
145 }
146
147 return info;
148 }
149 } // namespace AppExecFwk
150 } // namespace OHOS