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