1545fdf9bSopenharmony_ci/*
2545fdf9bSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
3545fdf9bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4545fdf9bSopenharmony_ci * you may not use this file except in compliance with the License.
5545fdf9bSopenharmony_ci * You may obtain a copy of the License at
6545fdf9bSopenharmony_ci *
7545fdf9bSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8545fdf9bSopenharmony_ci *
9545fdf9bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10545fdf9bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11545fdf9bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12545fdf9bSopenharmony_ci * See the License for the specific language governing permissions and
13545fdf9bSopenharmony_ci * limitations under the License.
14545fdf9bSopenharmony_ci */
15545fdf9bSopenharmony_ci
16545fdf9bSopenharmony_ci#include "quick_fix_command.h"
17545fdf9bSopenharmony_ci
18545fdf9bSopenharmony_ci#include "app_log_wrapper.h"
19545fdf9bSopenharmony_ci#include "common_event_data.h"
20545fdf9bSopenharmony_ci#include "common_event_manager.h"
21545fdf9bSopenharmony_ci#include "common_event_support.h"
22545fdf9bSopenharmony_ci#include "quick_fix_manager_client.h"
23545fdf9bSopenharmony_ci#include "status_receiver_impl.h"
24545fdf9bSopenharmony_ci#include "want.h"
25545fdf9bSopenharmony_ci
26545fdf9bSopenharmony_cinamespace OHOS {
27545fdf9bSopenharmony_cinamespace AppExecFwk {
28545fdf9bSopenharmony_ciclass ApplyQuickFixMonitor : public EventFwk::CommonEventSubscriber,
29545fdf9bSopenharmony_ci                             public std::enable_shared_from_this<ApplyQuickFixMonitor> {
30545fdf9bSopenharmony_cipublic:
31545fdf9bSopenharmony_ci    ApplyQuickFixMonitor(const EventFwk::CommonEventSubscribeInfo &subscribeInfo, sptr<StatusReceiverImpl> receiver)
32545fdf9bSopenharmony_ci        : EventFwk::CommonEventSubscriber(subscribeInfo), statusReceiver_(receiver)
33545fdf9bSopenharmony_ci    {}
34545fdf9bSopenharmony_ci
35545fdf9bSopenharmony_ci    virtual ~ApplyQuickFixMonitor() = default;
36545fdf9bSopenharmony_ci
37545fdf9bSopenharmony_ci    void OnReceiveEvent(const EventFwk::CommonEventData &eventData)
38545fdf9bSopenharmony_ci    {
39545fdf9bSopenharmony_ci        APP_LOGD("function called.");
40545fdf9bSopenharmony_ci        AAFwk::Want want = eventData.GetWant();
41545fdf9bSopenharmony_ci        int32_t applyResult = want.GetIntParam("applyResult", -1);
42545fdf9bSopenharmony_ci        std::string resultInfo = want.GetStringParam("applyResultInfo");
43545fdf9bSopenharmony_ci        std::string bundleName = want.GetStringParam("bundleName");
44545fdf9bSopenharmony_ci        APP_LOGD("bundleName: %{public}s, applyResult: %{public}d, resultInfo: %{public}s.",
45545fdf9bSopenharmony_ci            bundleName.c_str(), applyResult, resultInfo.c_str());
46545fdf9bSopenharmony_ci        resultInfo_ = resultInfo;
47545fdf9bSopenharmony_ci        statusReceiver_->OnFinished(applyResult, resultInfo);
48545fdf9bSopenharmony_ci    }
49545fdf9bSopenharmony_ci
50545fdf9bSopenharmony_ci    std::string GetResultInfo()
51545fdf9bSopenharmony_ci    {
52545fdf9bSopenharmony_ci        return resultInfo_;
53545fdf9bSopenharmony_ci    }
54545fdf9bSopenharmony_ci
55545fdf9bSopenharmony_ciprivate:
56545fdf9bSopenharmony_ci    sptr<StatusReceiverImpl> statusReceiver_ = nullptr;
57545fdf9bSopenharmony_ci    std::string resultInfo_;
58545fdf9bSopenharmony_ci};
59545fdf9bSopenharmony_ci
60545fdf9bSopenharmony_ciint32_t QuickFixCommand::ApplyQuickFix(const std::vector<std::string> &quickFixFiles, std::string &resultInfo,
61545fdf9bSopenharmony_ci    bool isDebug)
62545fdf9bSopenharmony_ci{
63545fdf9bSopenharmony_ci    if (quickFixFiles.empty()) {
64545fdf9bSopenharmony_ci        resultInfo.append("quick fix file is empty.\n");
65545fdf9bSopenharmony_ci        return ERR_INVALID_VALUE;
66545fdf9bSopenharmony_ci    }
67545fdf9bSopenharmony_ci
68545fdf9bSopenharmony_ci    for (auto file : quickFixFiles) {
69545fdf9bSopenharmony_ci        APP_LOGI("apply hqf file %{private}s.", file.c_str());
70545fdf9bSopenharmony_ci    }
71545fdf9bSopenharmony_ci
72545fdf9bSopenharmony_ci    APP_LOGI("IsDEBUG is %d", isDebug);
73545fdf9bSopenharmony_ci
74545fdf9bSopenharmony_ci    sptr<StatusReceiverImpl> statusReceiver(new (std::nothrow) StatusReceiverImpl());
75545fdf9bSopenharmony_ci    if (statusReceiver == nullptr) {
76545fdf9bSopenharmony_ci        resultInfo.append("Create status receiver failed.\n");
77545fdf9bSopenharmony_ci        return ERR_INVALID_VALUE;
78545fdf9bSopenharmony_ci    }
79545fdf9bSopenharmony_ci
80545fdf9bSopenharmony_ci    EventFwk::MatchingSkills matchingSkills;
81545fdf9bSopenharmony_ci    matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_QUICK_FIX_APPLY_RESULT);
82545fdf9bSopenharmony_ci    EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
83545fdf9bSopenharmony_ci    auto applyMonitor = std::make_shared<ApplyQuickFixMonitor>(subscribeInfo, statusReceiver);
84545fdf9bSopenharmony_ci    EventFwk::CommonEventManager::SubscribeCommonEvent(applyMonitor);
85545fdf9bSopenharmony_ci
86545fdf9bSopenharmony_ci    auto result = DelayedSingleton<AAFwk::QuickFixManagerClient>::GetInstance()->ApplyQuickFix(quickFixFiles, isDebug);
87545fdf9bSopenharmony_ci    if (result == ERR_OK) {
88545fdf9bSopenharmony_ci        APP_LOGD("Waiting apply finished.");
89545fdf9bSopenharmony_ci        result = statusReceiver->GetResultCode();
90545fdf9bSopenharmony_ci    }
91545fdf9bSopenharmony_ci
92545fdf9bSopenharmony_ci    if (result == ERR_OK) {
93545fdf9bSopenharmony_ci        resultInfo.append("apply quickfix succeed.\n");
94545fdf9bSopenharmony_ci    } else {
95545fdf9bSopenharmony_ci        if (applyMonitor->GetResultInfo().empty()) {
96545fdf9bSopenharmony_ci            resultInfo.append("apply quickfix failed with errno: " + std::to_string(result) + ".\n");
97545fdf9bSopenharmony_ci        } else {
98545fdf9bSopenharmony_ci            resultInfo.append("apply quickfix failed with error: " + applyMonitor->GetResultInfo() + ".\n");
99545fdf9bSopenharmony_ci        }
100545fdf9bSopenharmony_ci    }
101545fdf9bSopenharmony_ci
102545fdf9bSopenharmony_ci    return result;
103545fdf9bSopenharmony_ci}
104545fdf9bSopenharmony_ci
105545fdf9bSopenharmony_ciint32_t QuickFixCommand::GetApplyedQuickFixInfo(const std::string &bundleName, std::string &resultInfo)
106545fdf9bSopenharmony_ci{
107545fdf9bSopenharmony_ci    if (bundleName.empty()) {
108545fdf9bSopenharmony_ci        resultInfo.append("bundle name is empty.\n");
109545fdf9bSopenharmony_ci        return ERR_INVALID_VALUE;
110545fdf9bSopenharmony_ci    }
111545fdf9bSopenharmony_ci
112545fdf9bSopenharmony_ci    AAFwk::ApplicationQuickFixInfo quickFixInfo;
113545fdf9bSopenharmony_ci    auto result = AAFwk::QuickFixManagerClient::GetInstance()->GetApplyedQuickFixInfo(bundleName, quickFixInfo);
114545fdf9bSopenharmony_ci    if (result == ERR_OK) {
115545fdf9bSopenharmony_ci        resultInfo.append("Information as follows:\n");
116545fdf9bSopenharmony_ci        resultInfo.append(GetQuickFixInfoString(quickFixInfo));
117545fdf9bSopenharmony_ci    } else {
118545fdf9bSopenharmony_ci        resultInfo.append("Get quick fix info failed with errno " + std::to_string(result) + ".\n");
119545fdf9bSopenharmony_ci    }
120545fdf9bSopenharmony_ci
121545fdf9bSopenharmony_ci    return result;
122545fdf9bSopenharmony_ci}
123545fdf9bSopenharmony_ci
124545fdf9bSopenharmony_cistd::string QuickFixCommand::GetQuickFixInfoString(const AAFwk::ApplicationQuickFixInfo &quickFixInfo)
125545fdf9bSopenharmony_ci{
126545fdf9bSopenharmony_ci    std::string info = "ApplicationQuickFixInfo:\n";
127545fdf9bSopenharmony_ci    info.append("  bundle name: " + quickFixInfo.bundleName + "\n");
128545fdf9bSopenharmony_ci    info.append("  bundle version code: " + std::to_string(quickFixInfo.bundleVersionCode) + "\n");
129545fdf9bSopenharmony_ci    info.append("  bundle version name: " + quickFixInfo.bundleVersionName + "\n");
130545fdf9bSopenharmony_ci    AppqfInfo appqfInfo = quickFixInfo.appqfInfo;
131545fdf9bSopenharmony_ci    info.append("  patch version code: " + std::to_string(appqfInfo.versionCode) + "\n");
132545fdf9bSopenharmony_ci    info.append("  patch version name: " + appqfInfo.versionName + "\n");
133545fdf9bSopenharmony_ci    info.append("  cpu abi: " + appqfInfo.cpuAbi + "\n");
134545fdf9bSopenharmony_ci    info.append("  native library path: " + appqfInfo.nativeLibraryPath + "\n");
135545fdf9bSopenharmony_ci    std::string type;
136545fdf9bSopenharmony_ci    if (appqfInfo.type == AppExecFwk::QuickFixType::PATCH) {
137545fdf9bSopenharmony_ci        type = "patch";
138545fdf9bSopenharmony_ci    } else if (appqfInfo.type == AppExecFwk::QuickFixType::HOT_RELOAD) {
139545fdf9bSopenharmony_ci        type = "hotreload";
140545fdf9bSopenharmony_ci    }
141545fdf9bSopenharmony_ci    info.append("  type: " + type + "\n");
142545fdf9bSopenharmony_ci    for (auto hqfInfo : appqfInfo.hqfInfos) {
143545fdf9bSopenharmony_ci        info.append("  ModuelQuickFixInfo:\n");
144545fdf9bSopenharmony_ci        info.append("    module name: " + hqfInfo.moduleName + "\n");
145545fdf9bSopenharmony_ci        info.append("    module sha256: " + hqfInfo.hapSha256 + "\n");
146545fdf9bSopenharmony_ci        info.append("    file path: " + hqfInfo.hqfFilePath + "\n");
147545fdf9bSopenharmony_ci    }
148545fdf9bSopenharmony_ci
149545fdf9bSopenharmony_ci    return info;
150545fdf9bSopenharmony_ci}
151545fdf9bSopenharmony_ci} // namespace AppExecFwk
152545fdf9bSopenharmony_ci} // namespace OHOS