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 "update_service_impl_firmware.h"
17
18 #include <string>
19
20 #include "firmware_check_data_processor.h"
21 #include "firmware_constant.h"
22 #include "firmware_component_operator.h"
23 #include "firmware_log.h"
24 #include "firmware_manager.h"
25 #include "firmware_status_cache.h"
26 #include "firmware_task_operator.h"
27 #include "device_adapter.h"
28 #include "firmware_update_helper.h"
29 #include "string_utils.h"
30 #include "update_service_cache.h"
31 #include "update_service_util.h"
32
33 namespace OHOS {
34 namespace UpdateEngine {
35 const std::string LANGUAGE_CHINESE = "<language name=\"zh-cn\" code=\"2052\">";
36 const std::string LANGUAGE_ENGLISH = "<language name=\"en-us\" code=\"1033\">";
37 const std::string LANGUAGE_END = "</language>";
38
CheckNewVersion(const UpgradeInfo & info,BusinessError & businessError,CheckResult & checkResult)39 int32_t UpdateServiceImplFirmware::CheckNewVersion(const UpgradeInfo &info, BusinessError &businessError,
40 CheckResult &checkResult)
41 {
42 wptr<UpdateServiceImplFirmware> weakPtr(this);
43 FirmwareManager::GetInstance()->DoCheck(
44 [&, weakPtr](const BusinessError &error, const CheckResult &result) {
45 sptr<UpdateServiceImplFirmware> firmwareSptr = weakPtr.promote();
46 if (firmwareSptr == nullptr) {
47 FIRMWARE_LOGE("UpdateServiceImplFirmware has been destructed, CheckNewVersion is TimeOut");
48 return;
49 }
50 businessError = error;
51 checkResult = result;
52 firmwareSptr->checkComplete_ = true;
53 firmwareSptr->conditionVariable_.notify_all();
54 });
55 std::unique_lock<std::mutex> lock(checkNewVersionMutex_);
56 constexpr int32_t waitTime = 40;
57 conditionVariable_.wait_for(lock, std::chrono::seconds(waitTime), [&] { return checkComplete_; });
58 if (!checkComplete_) {
59 FIRMWARE_LOGE("CheckNewVersion is time out");
60 businessError.errorNum = CallResult::TIME_OUT;
61 businessError.message = "CheckNewVersion TimeOut";
62 }
63 weakPtr->checkComplete_ = false;
64 return INT_CALL_SUCCESS;
65 }
66
Download(const UpgradeInfo & info,const VersionDigestInfo & versionDigestInfo,const DownloadOptions & downloadOptions,BusinessError & businessError)67 int32_t UpdateServiceImplFirmware::Download(const UpgradeInfo &info, const VersionDigestInfo &versionDigestInfo,
68 const DownloadOptions &downloadOptions, BusinessError &businessError)
69 {
70 FIRMWARE_LOGI("Download allowNetwork:%{public}d order:%{public}d", CAST_INT(downloadOptions.allowNetwork),
71 CAST_INT(downloadOptions.order));
72 //控制1秒内重复点击下载
73 if (DelayedSingleton<FirmwareStatusCache>::GetInstance()->IsDownloadTriggered()) {
74 FIRMWARE_LOGI("on downloading, not perrmit repeat submmit");
75 businessError.Build(CallResult::FAIL, "repeat download error");
76 return INT_CALL_SUCCESS;
77 }
78
79 FirmwareTask task;
80 FirmwareTaskOperator firmwareTaskOperator;
81 firmwareTaskOperator.QueryTask(task);
82 if (task.status != UpgradeStatus::CHECK_VERSION_SUCCESS) {
83 FIRMWARE_LOGI("download fail current status: %{public}d", CAST_INT(task.status));
84 businessError.Build(CallResult::FAIL, "download error");
85 return INT_CALL_SUCCESS;
86 }
87
88 firmwareTaskOperator.UpdateDownloadOptionByTaskId(task.taskId,
89 DownloadMode::MANUAL, downloadOptions.allowNetwork, downloadOptions.order);
90 DelayedSingleton<FirmwareManager>::GetInstance()->DoDownload(downloadOptions, businessError);
91 return INT_CALL_SUCCESS;
92 }
93
PauseDownload(const UpgradeInfo & info,const VersionDigestInfo & versionDigestInfo,const PauseDownloadOptions & pauseDownloadOptions,BusinessError & businessError)94 int32_t UpdateServiceImplFirmware::PauseDownload(const UpgradeInfo &info,
95 const VersionDigestInfo &versionDigestInfo, const PauseDownloadOptions &pauseDownloadOptions,
96 BusinessError &businessError)
97 {
98 FIRMWARE_LOGI("PauseDownload isAllowAutoResume:%{public}s",
99 StringUtils::GetBoolStr(pauseDownloadOptions.isAllowAutoResume).c_str());
100 businessError.Build(CallResult::UN_SUPPORT, "pause download not support");
101 return INT_CALL_SUCCESS;
102 }
103
ResumeDownload(const UpgradeInfo & info,const VersionDigestInfo & versionDigestInfo,const ResumeDownloadOptions & resumeDownloadOptions,BusinessError & businessError)104 int32_t UpdateServiceImplFirmware::ResumeDownload(const UpgradeInfo &info,
105 const VersionDigestInfo &versionDigestInfo, const ResumeDownloadOptions &resumeDownloadOptions,
106 BusinessError &businessError)
107 {
108 FIRMWARE_LOGI("ResumeDownload allowNetwork:%{public}d", CAST_INT(resumeDownloadOptions.allowNetwork));
109 businessError.Build(CallResult::UN_SUPPORT, "resume download not support");
110 return INT_CALL_SUCCESS;
111 }
112
113
Upgrade(const UpgradeInfo & info,const VersionDigestInfo & versionDigestInfo,const UpgradeOptions & upgradeOptions,BusinessError & businessError)114 int32_t UpdateServiceImplFirmware::Upgrade(const UpgradeInfo &info, const VersionDigestInfo &versionDigestInfo,
115 const UpgradeOptions &upgradeOptions, BusinessError &businessError)
116 {
117 FIRMWARE_LOGI("Upgrade order = %{public}d", CAST_INT(upgradeOptions.order));
118 FirmwareTask task;
119 FirmwareTaskOperator firmwareTaskOperator;
120 firmwareTaskOperator.QueryTask(task);
121 firmwareTaskOperator.UpdateUpgradeModeByTaskId(task.taskId, UpgradeMode::MANUAL);
122 DelayedSingleton<FirmwareManager>::GetInstance()->DoInstall(upgradeOptions, businessError,
123 FirmwareUpdateHelper::GetInstallType());
124 return INT_CALL_SUCCESS;
125 }
126
ClearError(const UpgradeInfo & info,const VersionDigestInfo & versionDigestInfo,const ClearOptions & clearOptions,BusinessError & businessError)127 int32_t UpdateServiceImplFirmware::ClearError(const UpgradeInfo &info, const VersionDigestInfo &versionDigestInfo,
128 const ClearOptions &clearOptions, BusinessError &businessError)
129 {
130 FIRMWARE_LOGI("ClearError, versionDigestInfo %{public}s ClearOptions %{public}d",
131 versionDigestInfo.versionDigest.c_str(),
132 CAST_INT(clearOptions.status));
133 DelayedSingleton<FirmwareManager>::GetInstance()->DoClearError(businessError);
134 return INT_CALL_SUCCESS;
135 }
136
TerminateUpgrade(const UpgradeInfo & info,BusinessError & businessError)137 int32_t UpdateServiceImplFirmware::TerminateUpgrade(const UpgradeInfo &info, BusinessError &businessError)
138 {
139 FIRMWARE_LOGI("TerminateUpgrade");
140 DelayedSingleton<FirmwareManager>::GetInstance()->DoTerminateUpgrade(businessError);
141 return INT_CALL_SUCCESS;
142 }
143
GetNewVersionInfo(const UpgradeInfo & info,NewVersionInfo & newVersionInfo,BusinessError & businessError)144 int32_t UpdateServiceImplFirmware::GetNewVersionInfo(
145 const UpgradeInfo &info, NewVersionInfo &newVersionInfo, BusinessError &businessError)
146 {
147 FIRMWARE_LOGI("GetNewVersionInfo");
148 FirmwareTask task;
149 FirmwareTaskOperator().QueryTask(task);
150 std::vector<FirmwareComponent> components;
151 FirmwareComponentOperator().QueryAll(components);
152 FirmwareUpdateHelper::BuildNewVersionInfo(components, newVersionInfo.versionComponents);
153 newVersionInfo.versionDigestInfo.versionDigest = task.taskId;
154 return INT_CALL_SUCCESS;
155 }
156
GetNewVersionDescription(const UpgradeInfo & info,const VersionDigestInfo & versionDigestInfo,const DescriptionOptions & descriptionOptions,VersionDescriptionInfo & newVersionDescriptionInfo,BusinessError & businessError)157 int32_t UpdateServiceImplFirmware::GetNewVersionDescription(const UpgradeInfo &info,
158 const VersionDigestInfo &versionDigestInfo, const DescriptionOptions &descriptionOptions,
159 VersionDescriptionInfo &newVersionDescriptionInfo, BusinessError &businessError)
160 {
161 FIRMWARE_LOGI("GetNewVersionDescription versionDigestInfo %{public}s format %{public}d language %{public}s",
162 versionDigestInfo.versionDigest.c_str(),
163 CAST_INT(descriptionOptions.format),
164 descriptionOptions.language.c_str());
165
166 businessError.Build(CallResult::SUCCESS, "start GetNewVersionDescription");
167 std::vector<FirmwareComponent> components;
168 FirmwareComponentOperator().QueryAll(components);
169 if (components.size() == 0) {
170 FIRMWARE_LOGI("GetNewVersionDescription: no data");
171 businessError.Build(CallResult::FAIL, "GetNewVersionDescription failed");
172 return INT_CALL_SUCCESS;
173 }
174
175 for (auto const &component : components) {
176 ComponentDescription componentDescription;
177 componentDescription.componentId = component.componentId;
178 std::string changelogFilePath = Firmware::CHANGELOG_PATH + "/" + component.componentId + ".xml";
179 if (!FileUtils::IsFileExist(changelogFilePath)) {
180 FIRMWARE_LOGE("changelog file [%{public}s] is not exist!", changelogFilePath.c_str());
181 businessError.Build(CallResult::FAIL, "GetNewVersionDescription failed");
182 return INT_CALL_SUCCESS;
183 }
184 std::string dataXml = FileUtils::ReadDataFromFile(changelogFilePath);
185 size_t startIndex = dataXml.find_first_of("|");
186 if (startIndex == std::string::npos) {
187 FIRMWARE_LOGE("dataXml not found |");
188 businessError.Build(CallResult::FAIL, "GetNewVersionDescription failed");
189 return INT_CALL_SUCCESS;
190 }
191 std::string dataXmlFinal = dataXml.substr(startIndex + 1, dataXml.size());
192 GetChangelogContent(dataXmlFinal, descriptionOptions.language);
193 componentDescription.descriptionInfo.content = dataXmlFinal;
194 componentDescription.descriptionInfo.descriptionType =
195 static_cast<DescriptionType>(atoi(dataXml.substr(0, dataXml.find_first_of("|")).c_str()));
196 newVersionDescriptionInfo.componentDescriptions.push_back(componentDescription);
197 }
198 return INT_CALL_SUCCESS;
199 }
200
GetCurrentVersionInfo(const UpgradeInfo & info,CurrentVersionInfo & currentVersionInfo,BusinessError & businessError)201 int32_t UpdateServiceImplFirmware::GetCurrentVersionInfo(const UpgradeInfo &info,
202 CurrentVersionInfo ¤tVersionInfo, BusinessError &businessError)
203 {
204 FIRMWARE_LOGI("UpdateServiceImplFirmware::GetCurrentVersionInfo");
205 businessError.errorNum = CallResult::SUCCESS;
206 FirmwareUpdateHelper::BuildCurrentVersionInfo(currentVersionInfo);
207 return INT_CALL_SUCCESS;
208 }
209
GetCurrentVersionDescription(const UpgradeInfo & info,const DescriptionOptions & descriptionOptions,VersionDescriptionInfo & currentVersionDescriptionInfo,BusinessError & businessError)210 int32_t UpdateServiceImplFirmware::GetCurrentVersionDescription(const UpgradeInfo &info,
211 const DescriptionOptions &descriptionOptions, VersionDescriptionInfo ¤tVersionDescriptionInfo,
212 BusinessError &businessError)
213 {
214 FIRMWARE_LOGI("GetCurrentVersionDescription format %{public}d language %{public}s",
215 CAST_INT(descriptionOptions.format),
216 descriptionOptions.language.c_str());
217
218 ComponentDescription descriptionContent;
219 descriptionContent.componentId =
220 DelayedSingleton<FirmwarePreferencesUtil>::GetInstance()->ObtainString(Firmware::HOTA_CURRENT_COMPONENT_ID, "");
221 if (descriptionContent.componentId.empty()) {
222 businessError.Build(CallResult::FAIL, "GetCurrentVersionDescription failed");
223 FIRMWARE_LOGE("componentId is null");
224 return INT_CALL_SUCCESS;
225 }
226
227 std::string changelogFilePath = Firmware::CHANGELOG_PATH + "/" + descriptionContent.componentId + ".xml";
228 if (!FileUtils::IsFileExist(changelogFilePath)) {
229 FIRMWARE_LOGE("current changelog file [%{public}s] is not exist!", changelogFilePath.c_str());
230 businessError.Build(CallResult::FAIL, "GetCurrentVersionDescription failed");
231 return INT_CALL_SUCCESS;
232 }
233 std::string dataXml = FileUtils::ReadDataFromFile(changelogFilePath);
234 size_t startIndex = dataXml.find_first_of("|");
235 if (startIndex == std::string::npos) {
236 FIRMWARE_LOGE("dataXml not found |");
237 businessError.Build(CallResult::FAIL, "GetCurrentVersionDescription failed");
238 return INT_CALL_SUCCESS;
239 }
240 std::string dataXmlFinal = dataXml.substr(startIndex + 1, dataXml.size());
241 GetChangelogContent(dataXmlFinal, descriptionOptions.language);
242 descriptionContent.descriptionInfo.content = dataXmlFinal;
243 descriptionContent.descriptionInfo.descriptionType =
244 static_cast<DescriptionType>(atoi(dataXml.substr(0, dataXml.find_first_of("|")).c_str()));
245 currentVersionDescriptionInfo.componentDescriptions.push_back(descriptionContent);
246 businessError.Build(CallResult::SUCCESS, "GetCurrentVersionDescription ok");
247 return INT_CALL_SUCCESS;
248 }
249
GetTaskInfo(const UpgradeInfo & info,TaskInfo & taskInfo,BusinessError & businessError)250 int32_t UpdateServiceImplFirmware::GetTaskInfo(const UpgradeInfo &info, TaskInfo &taskInfo,
251 BusinessError &businessError)
252 {
253 FIRMWARE_LOGI("GetTaskInfo");
254 businessError.errorNum = CallResult::SUCCESS;
255 FirmwareTask task;
256 FirmwareTaskOperator().QueryTask(task);
257 if (task.isExistTask) {
258 taskInfo.existTask = true;
259 taskInfo.taskBody.status = static_cast<UpgradeStatus>(task.status);
260 taskInfo.taskBody.progress = task.progress;
261 taskInfo.taskBody.versionDigestInfo.versionDigest = task.taskId;
262 }
263 FIRMWARE_LOGI("GetTaskInfo existTask %{public}s status %{public}d , progress %{public}d",
264 StringUtils::GetBoolStr(taskInfo.existTask).c_str(), CAST_INT(taskInfo.taskBody.status),
265 taskInfo.taskBody.progress);
266 return INT_CALL_SUCCESS;
267 }
268
SetUpgradePolicy(const UpgradeInfo & info,const UpgradePolicy & policy,BusinessError & businessError)269 int32_t UpdateServiceImplFirmware::SetUpgradePolicy(const UpgradeInfo &info, const UpgradePolicy &policy,
270 BusinessError &businessError)
271 {
272 FIRMWARE_LOGI(
273 "SetUpgradePolicy autoDownload %{public}d installmode %{public}d startTime %{public}d endTime %{public}d",
274 policy.downloadStrategy, policy.autoUpgradeStrategy, policy.autoUpgradePeriods[0].start,
275 policy.autoUpgradePeriods[1].end);
276 businessError.errorNum = CallResult::SUCCESS;
277 bool isAutoDownloadSwitchOn = preferencesUtil_->ObtainBool(Firmware::AUTO_DOWNLOAD_SWITCH, false);
278 FIRMWARE_LOGI("SetUpgradePolicy isAutoDownloadSwitchOn %{public}s",
279 StringUtils::GetBoolStr(isAutoDownloadSwitchOn).c_str());
280 if (isAutoDownloadSwitchOn != policy.downloadStrategy) {
281 DelayedSingleton<FirmwareManager>::GetInstance()->DoAutoDownloadSwitchChanged(policy.downloadStrategy);
282 }
283 return INT_CALL_SUCCESS;
284 }
285
GetUpgradePolicy(const UpgradeInfo & info,UpgradePolicy & policy,BusinessError & businessError)286 int32_t UpdateServiceImplFirmware::GetUpgradePolicy(const UpgradeInfo &info, UpgradePolicy &policy,
287 BusinessError &businessError)
288 {
289 FIRMWARE_LOGI("GetUpgradePolicy");
290 bool isAutoDownloadSwitchOn = preferencesUtil_->ObtainBool(Firmware::AUTO_DOWNLOAD_SWITCH, false);
291 FIRMWARE_LOGI("GetUpgradePolicy isAutoDownloadSwitchOn %{public}s",
292 StringUtils::GetBoolStr(isAutoDownloadSwitchOn).c_str());
293 policy.downloadStrategy = isAutoDownloadSwitchOn;
294 policy.autoUpgradePeriods[0].start =
295 static_cast<uint32_t>(Constant::ONE_HOUR_MINUTES * Firmware::NIGHT_UPGRADE_START_HOUR);
296 policy.autoUpgradePeriods[0].end =
297 static_cast<uint32_t>(Constant::ONE_HOUR_MINUTES * Firmware::NIGHT_UPGRADE_END_HOUR);
298 return INT_CALL_SUCCESS;
299 }
300
Cancel(const UpgradeInfo & info,int32_t service,BusinessError & businessError)301 int32_t UpdateServiceImplFirmware::Cancel(const UpgradeInfo &info, int32_t service, BusinessError &businessError)
302 {
303 FIRMWARE_LOGI("Cancel %{public}d", service);
304 businessError.errorNum = CallResult::SUCCESS;
305 FirmwareTask task;
306 FirmwareTaskOperator().QueryTask(task);
307 if (task.status != UpgradeStatus::DOWNLOADING && task.status != UpgradeStatus::DOWNLOAD_PAUSE) {
308 FIRMWARE_LOGI("Cancel fail current status: %{public}d", CAST_INT(task.status));
309 businessError.Build(CallResult::FAIL, "Cancel download error");
310 } else {
311 DelayedSingleton<FirmwareManager>::GetInstance()->DoCancelDownload(businessError);
312 }
313 return INT_CALL_SUCCESS;
314 }
315
GetChangelogContent(std::string & dataXml,const std::string & language)316 void UpdateServiceImplFirmware::GetChangelogContent(std::string &dataXml, const std::string &language)
317 {
318 std::string languageStart = LANGUAGE_ENGLISH;
319 if (language.compare("zh-cn") != 0) {
320 languageStart = LANGUAGE_CHINESE;
321 }
322 StringUtils::StringRemove(dataXml, languageStart, LANGUAGE_END);
323 }
324 } // namespace UpdateEngine
325 } // namespace OHOS
326