1 /*
2  * Copyright (c) 2023 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 "firmware_sys_installer_install.h"
17 
18 #include <dirent.h>
19 #include <iostream>
20 #include <unistd.h>
21 
22 #include "isys_installer.h"
23 #include "sys_installer_kits_impl.h"
24 
25 #include "config_parse.h"
26 #include "dupdate_errno.h"
27 #include "firmware_constant.h"
28 #include "firmware_log.h"
29 #include "firmware_sys_installer_callback.h"
30 #include "firmware_update_helper.h"
31 
32 namespace OHOS {
33 namespace UpdateEngine {
34 
IsComponentLegal(const std::vector<FirmwareComponent> & componentList)35 bool SysInstallerInstall::IsComponentLegal(const std::vector<FirmwareComponent> &componentList)
36 {
37     return FirmwareUpdateHelper::IsUpgradePackagesReady(componentList);
38 }
39 
PerformInstall(const std::vector<FirmwareComponent> & componentList)40 bool SysInstallerInstall::PerformInstall(const std::vector<FirmwareComponent> &componentList)
41 {
42     FIRMWARE_LOGI("SysInstallerInstall::PerformInstall");
43     if (componentList.empty()) {
44         return false;
45     }
46     uint32_t successCount = 0;
47     for (const auto &component : componentList) {
48         if (onInstallCallback_.onFirmwareStatus == nullptr) {
49             FIRMWARE_LOGE("SysInstallerInstall PerformInstall onFirmwareStatus is null");
50             continue;
51         }
52         onInstallCallback_.onFirmwareStatus(UpgradeStatus::INSTALLING);
53         if (DoSysInstall(component) == OHOS_SUCCESS) {
54             successCount ++;
55         }
56     }
57     return successCount == static_cast<uint32_t>(componentList.size());
58 }
59 
DoSysInstall(const FirmwareComponent & firmwareComponent)60 int32_t SysInstallerInstall::DoSysInstall(const FirmwareComponent &firmwareComponent)
61 {
62     FIRMWARE_LOGI("DoSysInstall, status=%{public}d", firmwareComponent.status);
63     FirmwareComponent sysComponent = firmwareComponent;
64     InitInstallProgress();
65     int32_t ret = SysInstaller::SysInstallerKitsImpl::GetInstance().SysInstallerInit();
66     if (ret != OHOS_SUCCESS) {
67         FIRMWARE_LOGE("sys installer init failed");
68         errMsg_.errorMessage = "sys installer init failed";
69         errMsg_.errorCode = DUPDATE_ERR_IPC_ERROR;
70         return OHOS_FAILURE;
71     }
72 
73     int32_t updateStatus = SysInstaller::SysInstallerKitsImpl::GetInstance().GetUpdateStatus();
74     if (updateStatus != CAST_INT(SysInstaller::UpdateStatus::UPDATE_STATE_INIT)) {
75         FIRMWARE_LOGE("StartUnpack status: %{public}d , system busy", updateStatus);
76         errMsg_.errorMessage = "sys installer is busy";
77         errMsg_.errorCode = ret;
78         return OHOS_FAILURE;
79     }
80 
81     SysInstallerExecutorCallback callback { [&](const InstallProgress &installProgress) {
82         sysInstallProgress_ = installProgress.progress;
83         errMsg_ = installProgress.errMsg;
84         sysComponent.status = installProgress.progress.status;
85         sysComponent.progress = installProgress.progress.percent;
86         FIRMWARE_LOGI("SysInstallerExecutorCallback status=%{public}d , progress=%{public}d",
87             sysComponent.status, sysComponent.progress);
88         if (onInstallCallback_.onFirmwareProgress == nullptr) {
89             FIRMWARE_LOGE("SysInstallerExecutorCallback onFirmwareProgress is null");
90             return;
91         }
92         onInstallCallback_.onFirmwareProgress(sysComponent);
93     } };
94     sptr<SysInstaller::ISysInstallerCallbackFunc> cb = new SysInstallerCallback(callback);
95     if (cb == nullptr) {
96         FIRMWARE_LOGE("sys installer callback is nullptr");
97         errMsg_.errorMessage = "sys installer callback is nullptr";
98         errMsg_.errorCode = DUPDATE_ERR_IPC_ERROR;
99         return OHOS_FAILURE;
100     }
101 
102     ret = SysInstaller::SysInstallerKitsImpl::GetInstance().SetUpdateCallback(cb);
103     if (ret != OHOS_SUCCESS) {
104         FIRMWARE_LOGE("set sys installer callback failed");
105         errMsg_.errorMessage = "set sys installer callback failed";
106         errMsg_.errorCode = ret;
107         return OHOS_FAILURE;
108     }
109 
110     if (StartUpdatePackageZip(sysComponent.spath) != OHOS_SUCCESS) {
111         return OHOS_FAILURE;
112     }
113     return WaitInstallResult();
114 }
115 
StartUpdatePackageZip(std::string & path)116 int32_t SysInstallerInstall::StartUpdatePackageZip(std::string &path)
117 {
118     auto ret = SysInstaller::SysInstallerKitsImpl::GetInstance().StartUpdatePackageZip(path);
119     if (ret != OHOS_SUCCESS) {
120         errMsg_.errorMessage = "sys installer StartUpdatePackageZip failed";
121         errMsg_.errorCode = ret;
122         FIRMWARE_LOGE("sys installer StartUpdatePackageZip failed ret = %{public}d", ret);
123         return OHOS_FAILURE;
124     }
125     return ret;
126 }
127 
InitInstallProgress()128 void SysInstallerInstall::InitInstallProgress()
129 {
130     sysInstallProgress_.status = UpgradeStatus::INSTALLING;
131     sysInstallProgress_.percent = 0;
132     sysInstallProgress_.endReason = "";
133     errMsg_.errorCode = 0;
134     errMsg_.errorMessage = "";
135 }
136 
WaitInstallResult()137 int32_t SysInstallerInstall::WaitInstallResult()
138 {
139     uint32_t timeout = 0;
140     uint32_t configTime = DelayedSingleton<ConfigParse>::GetInstance()->GetAbInstallerTimeout();
141     FIRMWARE_LOGI("sysinstaller wait result, max wait time=%{public}u", configTime);
142     while (timeout <= configTime) {
143         if (sysInstallProgress_.status == UpgradeStatus::INSTALL_FAIL) {
144             FIRMWARE_LOGE("WaitInstallResult sysinstaller fail");
145             return OHOS_FAILURE;
146         }
147         if (sysInstallProgress_.status == UpgradeStatus::INSTALL_SUCCESS &&
148             sysInstallProgress_.percent == Firmware::ONE_HUNDRED) {
149             return OHOS_SUCCESS;
150         }
151         timeout++;
152         sleep(SLEEP_INSTALL);
153     }
154     FIRMWARE_LOGI("WaitInstallResult time out, sysInstallProgress_.status=%{public}d",
155         CAST_INT(sysInstallProgress_.status));
156     return OHOS_FAILURE;
157 }
158 } // namespace UpdateEngine
159 } // namespace OHOS
160