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_download_executor.h"
17
18 #include <cinttypes>
19 #include <unistd.h>
20 #include <sys/stat.h>
21 #include <thread>
22
23 #include "constant.h"
24 #include "dupdate_errno.h"
25 #include "download_info.h"
26 #include "firmware_callback_utils.h"
27 #include "firmware_component_operator.h"
28 #include "firmware_log.h"
29 #include "firmware_task_operator.h"
30 #include "firmware_update_helper.h"
31 #include "progress_thread.h"
32 #include "string_utils.h"
33
34 namespace OHOS {
35 namespace UpdateEngine {
36 const mode_t MKDIR_MODE = 0777;
Execute()37 void FirmwareDownloadExecutor::Execute()
38 {
39 FIRMWARE_LOGI("FirmwareDownloadExecutor::Execute");
40 std::thread downloadThread([this] { this->DoDownload(); });
41 downloadThread.detach();
42 }
43
DoDownload()44 void FirmwareDownloadExecutor::DoDownload()
45 {
46 FirmwareComponentOperator().QueryAll(components_);
47 FIRMWARE_LOGI("Execute size %{public}d", CAST_INT(components_.size()));
48 if (components_.size() == 0) {
49 Progress progress;
50 progress.status = UpgradeStatus::DOWNLOAD_FAIL;
51 progress.endReason = "no task";
52 firmwareProgressCallback_.progressCallback(progress);
53 return;
54 }
55
56 GetTask();
57 if (tasks_.downloadTaskId.empty()) {
58 // 首次触发下载
59 PerformDownload();
60 } else {
61 // 恢复下载
62 Progress progress;
63 progress.status = UpgradeStatus::DOWNLOAD_FAIL;
64 progress.endReason = "not support";
65 firmwareProgressCallback_.progressCallback(progress);
66 return;
67 }
68 }
69
PerformDownload()70 void FirmwareDownloadExecutor::PerformDownload()
71 {
72 std::vector<DownloadInfo> downLoadInfos;
73 for (const auto &component : components_) {
74 DownloadInfo downloadInfo;
75 downloadInfo.versionId = component.url;
76 downloadInfo.url = component.url;
77 downloadInfo.path = component.spath;
78 downloadInfo.packageSize = component.size;
79 downloadInfo.veriftInfo = component.verifyInfo;
80 downloadInfo.isNeedAutoResume = false;
81 downLoadInfos.push_back(downloadInfo);
82 FIRMWARE_LOGD("downloadInfo %s", downloadInfo.ToString().c_str());
83
84 if (access(Constant::DUPDATE_ENGINE_PACKAGE_ROOT_PATH.c_str(), 0) == -1) {
85 mkdir(Constant::DUPDATE_ENGINE_PACKAGE_ROOT_PATH.c_str(), MKDIR_MODE);
86 }
87
88 Progress progress0 = {0, UpgradeStatus::DOWNLOADING, ""};
89
90 std::string downloadFileName = downloadInfo.path;
91 int64_t localFileLength = static_cast<int64_t>(DownloadThread::GetLocalFileLength(downloadFileName));
92 ENGINE_LOGI("Download %{public}" PRId64 ", %{public}s", localFileLength, downloadFileName.c_str());
93 if (localFileLength == downloadInfo.packageSize && downloadInfo.packageSize != 0) {
94 progress0.percent = DOWNLOAD_FINISH_PERCENT;
95 progress0.status = UpgradeStatus::DOWNLOAD_SUCCESS;
96 DownloadCallback(downloadInfo.url, downloadFileName, progress0);
97 }
98 upgradeStatus_ = UpgradeStatus::DOWNLOADING;
99 downloadThread_ = std::make_shared<DownloadThread>(
100 [&](const std::string serverUrl, const std::string &fileName,
101 const Progress &progress) -> void {
102 DownloadCallback(serverUrl, fileName, progress);
103 });
104 int32_t ret = downloadThread_->StartDownload(downloadFileName, downloadInfo.url);
105 if (ret != 0) {
106 progress0 = {};
107 progress0.status = UpgradeStatus::DOWNLOAD_FAIL;
108 progress0.endReason = std::to_string(CAST_INT(DownloadEndReason::FAIL));
109 firmwareProgressCallback_.progressCallback(progress0);
110 }
111 }
112
113 DelayedSingleton<FirmwareCallbackUtils>::GetInstance()->NotifyEvent(
114 tasks_.taskId, EventId::EVENT_DOWNLOAD_START, UpgradeStatus::DOWNLOADING);
115 }
116
GetTask()117 void FirmwareDownloadExecutor::GetTask()
118 {
119 FirmwareTaskOperator().QueryTask(tasks_);
120 }
121
DownloadCallback(std::string serverUrl,std::string packageName,Progress progress)122 void FirmwareDownloadExecutor::DownloadCallback(std::string serverUrl, std::string packageName, Progress progress)
123 {
124 ENGINE_LOGD("FirmwareDownloadExecutor::DownloadCallback progress.status = %{public}d,"
125 " progress.percent = %{public}d", progress.status, progress.percent);
126 Progress downloadProgress {};
127 upgradeStatus_ = UpgradeStatus::DOWNLOADING;
128 if (progress.status == UpgradeStatus::DOWNLOAD_FAIL ||
129 progress.status == UpgradeStatus::DOWNLOAD_SUCCESS) {
130 upgradeStatus_ = progress.status;
131 }
132 downloadProgress.percent = progress.percent;
133 downloadProgress.status = progress.status;
134 downloadProgress.endReason = progress.endReason;
135
136 #ifdef UPDATER_UT
137 upgradeStatus_ = UpgradeStatus::DOWNLOAD_SUCCESS;
138 #endif
139 std::string fileName = packageName;
140 ENGINE_LOGI("DownloadCallback status: %{public}d progress: %{public}d", progress.status, progress.percent);
141
142 if (upgradeStatus_ == UpgradeStatus::DOWNLOAD_SUCCESS) {
143 ENGINE_LOGI("DownloadCallback fileName %{public}s", fileName.c_str());
144 if (!VerifyDownloadPkg(fileName, downloadProgress)) {
145 // If the verification fails, delete the corresponding package.
146 remove(fileName.c_str());
147 downloadProgress.status = UpgradeStatus::DOWNLOAD_FAIL;
148 downloadProgress.endReason = std::to_string(DUpdateErrno::DUPDATE_ERR_VERIFY_PACKAGE_FAIL);
149 }
150 }
151
152 FirmwareComponentOperator firmwareComponentOperator;
153 // 单包进度插入到 component 表
154 ENGINE_LOGI("DownloadCallback serverUrl %s, status %{public}d %{public}d", serverUrl.c_str(),
155 progress.status, progress.percent);
156 firmwareComponentOperator.UpdateProgressByUrl(serverUrl, progress.status, progress.percent);
157 // 整体进度插入到 task 表
158 FirmwareTaskOperator().UpdateProgressByTaskId(tasks_.taskId, downloadProgress.status, downloadProgress.percent);
159 firmwareProgressCallback_.progressCallback(downloadProgress);
160 }
161
VerifyDownloadPkg(const std::string & pkgName,Progress & progress)162 bool FirmwareDownloadExecutor::VerifyDownloadPkg(const std::string &pkgName, Progress &progress)
163 {
164 std::string verifyInfo = "";
165 for (const auto &component : components_) {
166 if (component.spath == pkgName) {
167 verifyInfo = component.verifyInfo;
168 break;
169 }
170 }
171 ENGINE_LOGI("Start Checking file Sha256 %{public}s, verifyInfo %{public}s", pkgName.c_str(), verifyInfo.c_str());
172 if (!verifyInfo.empty() && !Sha256Utils::CheckFileSha256String(pkgName, verifyInfo)) {
173 ENGINE_LOGE("file sha256 check error, fileName:%{public}s", pkgName.c_str());
174 return false;
175 }
176 return true;
177 }
178 } // namespace UpdateEngine
179 } // namespace OHOS
180