• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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_stream_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 UpdateService {
34 
IsComponentLegal(const std::vector<FirmwareComponent> & componentList)35 bool StreamInstallerInstall::IsComponentLegal(const std::vector<FirmwareComponent> &componentList)
36 {
37     return true;
38 }
39 
PerformInstall(const std::vector<FirmwareComponent> & componentList,UpgradeStatus & status)40 bool StreamInstallerInstall::PerformInstall(const std::vector<FirmwareComponent> &componentList, UpgradeStatus &status)
41 {
42     FIRMWARE_LOGI("StreamInstallerInstall::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("StreamInstallerInstall PerformInstall onFirmwareStatus is null");
50             continue;
51         }
52         onInstallCallback_.onFirmwareStatus(UpgradeStatus::INSTALLING);
53         if (InstallComponentWithRetry(component)) {
54             successCount++;
55         }
56     }
57     if (sysInstallProgress_.status != UpgradeStatus::INSTALL_FAIL) {
58         status = downloadProgress_.status;
59     }
60 
61     return successCount == static_cast<uint32_t>(componentList.size());
62 }
63 
InstallComponentWithRetry(const FirmwareComponent & component)64 bool StreamInstallerInstall::InstallComponentWithRetry(const FirmwareComponent &component)
65 {
66     int16_t retry = 0;
67     while (retry < MAX_RETRY_COUNT) {
68         FIRMWARE_LOGI("InstallComponentWithRetry PerformInstall retry = %{public}d", retry);
69 
70         FirmwareComponent refreshComponent;
71         FirmwareComponentOperator().QueryByUrl(component.url, refreshComponent);
72 
73         if (DoSysInstall(refreshComponent) == OHOS_SUCCESS) {
74             return true;
75         } else {
76             if (downloadProgress_.status == UpgradeStatus::DOWNLOAD_CANCEL) {
77                 return false;
78             }
79         }
80 
81         retry++;
82         usleep(RETRY_INTERVAL_TIME);
83     }
84 
85     return false;
86 }
87 
DoSysInstall(const FirmwareComponent & component)88 int32_t StreamInstallerInstall::DoSysInstall(const FirmwareComponent &component)
89 {
90     #ifndef UPDATER_UT
91     SysInstaller::SysInstallerKitsImpl::GetInstance().StopStreamUpdate();
92     #endif
93     downloadProgress_.status = UpgradeStatus::INIT;
94     sysInstallProgress_.status = UpgradeStatus::INIT;
95     FIRMWARE_LOGI("DoSysInstall, status=%{public}d", component.status);
96     FirmwareComponent firmwareComponent = component;
97 
98     int32_t ret = InitSysInstaller(firmwareComponent.versionId);
99     if (ret != OHOS_SUCCESS) {
100         return ret;
101     }
102 
103     // Set the callback for the installer
104     ret = SetInstallerCallback(firmwareComponent);
105     if (ret != OHOS_SUCCESS) {
106         return ret;
107     }
108 
109     ret = StartInstallProcess(firmwareComponent);
110     if (ret != OHOS_SUCCESS) {
111         return ret;
112     }
113     return WaitInstallResult();
114 }
115 
InitSysInstaller(const std::string & versionId)116 int32_t StreamInstallerInstall::InitSysInstaller(const std::string &versionId)
117 {
118     #ifndef UPDATER_UT
119     int32_t ret = SysInstaller::SysInstallerKitsImpl::GetInstance().SysInstallerInit(versionId, true);
120     if (ret != OHOS_SUCCESS) {
121         FIRMWARE_LOGE("sys installer init failed");
122         errMsg_.errorMessage = "sys installer init failed";
123         errMsg_.errorCode = DUPDATE_ERR_IPC_ERROR;
124         return OHOS_FAILURE;
125     }
126     int32_t updateStatus = SysInstaller::SysInstallerKitsImpl::GetInstance().GetUpdateStatus(versionId);
127     if (updateStatus != CAST_INT(SysInstaller::UpdateStatus::UPDATE_STATE_INIT)) {
128         FIRMWARE_LOGE("StartUnpack status: %{public}d , system busy", updateStatus);
129         errMsg_.errorMessage = "sys installer is busy";
130         errMsg_.errorCode = ret;
131         return OHOS_FAILURE;
132     }
133     #endif
134     return OHOS_SUCCESS;
135 }
136 
SetInstallerCallback(FirmwareComponent & component)137 int32_t StreamInstallerInstall::SetInstallerCallback(FirmwareComponent &component)
138 {
139     #ifndef UPDATER_UT
140     SysInstallerExecutorCallback callback{[&](const InstallProgress &installProgress) {
141         component.status = installProgress.progress.status;
142         component.recordPoint += installProgress.dealLen;
143         if (component.size > 0) {
144             component.progress = static_cast<double>(component.recordPoint) / component.size * Firmware::ONE_HUNDRED;
145         }
146         if (onInstallCallback_.onFirmwareProgress == nullptr) {
147             FIRMWARE_LOGE("SysInstallerExecutorCallback onFirmwareProgress is null");
148             return;
149         }
150         onInstallCallback_.onFirmwareProgress(component);
151         sysInstallProgress_ = installProgress.progress;
152         if (Firmware::ONE_HUNDRED == component.progress) {
153             sysInstallProgress_.status = UpgradeStatus::INSTALL_SUCCESS;
154         }
155         errMsg_ = installProgress.errMsg;
156         if (component.status == UpgradeStatus::INSTALL_FAIL ||
157             component.status == UpgradeStatus::INSTALL_SUCCESS) {
158             NotifyCondition();
159         }
160     }};
161 
162     sptr<SysInstaller::ISysInstallerCallbackFunc> cb = new SysInstallerCallback(callback);
163     if (cb == nullptr) {
164         FIRMWARE_LOGE("sys installer callback is nullptr");
165         errMsg_.errorMessage = "sys installer callback is nullptr";
166         errMsg_.errorCode = DUPDATE_ERR_IPC_ERROR;
167         return OHOS_FAILURE;
168     }
169 
170     int32_t ret = SysInstaller::SysInstallerKitsImpl::GetInstance().SetUpdateCallback(component.versionId, cb);
171     if (ret != OHOS_SUCCESS) {
172         FIRMWARE_LOGE("set sys installer callback failed");
173         errMsg_.errorMessage = "set sys installer callback failed";
174         errMsg_.errorCode = ret;
175     }
176     return ret;
177     #else
178     return OHOS_SUCCESS;
179     #endif
180 }
181 
StartInstallProcess(FirmwareComponent & component)182 int32_t StreamInstallerInstall::StartInstallProcess(FirmwareComponent &component)
183 {
184     #ifndef UPDATER_UT
185     auto ret = SysInstaller::SysInstallerKitsImpl::GetInstance().StartStreamUpdate();
186     if (ret != OHOS_SUCCESS) {
187         errMsg_.errorMessage = "sys installer StartStreamUpdate failed";
188         errMsg_.errorCode = ret;
189         FIRMWARE_LOGE("sys installer StartStreamUpdate failed ret = %{public}d", ret);
190         return OHOS_FAILURE;
191     }
192     downloadThread_ = std::make_shared<StreamProgressThread>([&](const Progress &progress) -> void {
193         downloadProgress_ = progress;
194         if (downloadProgress_.status == UpgradeStatus::DOWNLOAD_FAIL) {
195             errMsg_.errorMessage = "download fail";
196             errMsg_.errorCode = -1;
197             NotifyCondition();
198         } else if (downloadProgress_.status == UpgradeStatus::DOWNLOAD_CANCEL) {
199             NotifyCondition();
200         } else {
201         }
202     });
203     ret = downloadThread_->StartDownload(component.url, component.size, component.recordPoint);
204     if (ret != OHOS_SUCCESS) {
205         errMsg_.errorMessage = "StartDownload failed";
206         errMsg_.errorCode = ret;
207         FIRMWARE_LOGE("StartDownload failed ret = %{public}d", ret);
208         return OHOS_FAILURE;
209     }
210     #endif
211     return OHOS_SUCCESS;
212 }
213 
NotifyCondition()214 void StreamInstallerInstall::NotifyCondition()
215 {
216     std::lock_guard<std::mutex> lock(installMutex_);
217     installCond_.notify_all();
218 }
219 
WaitInstallResult()220 int32_t StreamInstallerInstall::WaitInstallResult()
221 {
222     #ifndef UPDATER_UT
223     std::unique_lock<std::mutex> lock(installMutex_);
224     int32_t ret = OHOS_SUCCESS;
225     uint32_t configTime = DelayedSingleton<ConfigParse>::GetInstance()->GetStreamInstallerTimeout();
226     FIRMWARE_LOGI("sysinstaller wait result, max wait time=%{public}u", configTime);
227     if (!installCond_.wait_for(lock, std::chrono::seconds(configTime), [this] {
228         return (sysInstallProgress_.status == UpgradeStatus::INSTALL_SUCCESS) ||
229         (sysInstallProgress_.status == UpgradeStatus::INSTALL_FAIL) ||
230         (downloadProgress_.status == UpgradeStatus::DOWNLOAD_FAIL) ||
231         (downloadProgress_.status == UpgradeStatus::DOWNLOAD_CANCEL);
232     })) {
233         FIRMWARE_LOGE("WaitInstallResult time out");
234         ret = OHOS_FAILURE;
235     } else {
236         if (sysInstallProgress_.status == UpgradeStatus::INSTALL_SUCCESS) {
237             FIRMWARE_LOGI("WaitInstallResult INSTALL_SUCCESS");
238             ret =  OHOS_SUCCESS;
239         } else {
240             FIRMWARE_LOGE("WaitInstallResult fail, sysInstallProgress_.status=%{public}d, "
241                 "downloadProgress_.status=%{public}d", CAST_INT(sysInstallProgress_.status),
242                 CAST_INT(downloadProgress_.status));
243             ret = OHOS_FAILURE;
244         }
245     }
246     // 停止下载线程
247     downloadThread_->StopDownload();
248     // 停止数据处理线程
249     SysInstaller::SysInstallerKitsImpl::GetInstance().StopStreamUpdate();
250     return ret;
251     #else
252     return OHOS_SUCCESS;
253     #endif
254 }
255 } // namespace UpdateService
256 } // namespace OHOS
257