1 /*
2 * Copyright (c) 2021-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 #include "updater_main.h"
16 #include <chrono>
17 #include <dirent.h>
18 #include <fcntl.h>
19 #include <getopt.h>
20 #include <libgen.h>
21 #include <string>
22 #include <sys/mount.h>
23 #include <sys/reboot.h>
24 #include <sys/stat.h>
25 #include <sys/statvfs.h>
26 #include <sys/syscall.h>
27 #include <thread>
28 #include <unistd.h>
29 #include <vector>
30 #include "applypatch/partition_record.h"
31 #include "cert_verify.h"
32 #include "flashd/flashd.h"
33 #include "fs_manager/mount.h"
34 #include "include/updater/updater.h"
35 #include "json_node.h"
36 #include "language/language_ui.h"
37 #include "log/dump.h"
38 #include "log/log.h"
39 #include "misc_info/misc_info.h"
40 #include "package/pkg_manager.h"
41 #include "pkg_manager.h"
42 #include "pkg_utils.h"
43 #include "ptable_parse/ptable_process.h"
44 #include "sdcard_update/sdcard_update.h"
45 #include "securec.h"
46 #include "updater/updater_const.h"
47 #include "updater/updater_preprocess.h"
48 #include "updater_ui_stub.h"
49 #include "utils.h"
50
51 namespace Updater {
52 using Utils::String2Int;
53 using namespace Hpackage;
54 using namespace Updater::Utils;
55 using namespace std::literals::chrono_literals;
56
57 [[maybe_unused]] constexpr int DISPLAY_TIME = 1000 * 1000;
58 constexpr struct option OPTIONS[] = {
59 { "update_package", required_argument, nullptr, 0 },
60 { "retry_count", required_argument, nullptr, 0 },
61 { "factory_wipe_data", no_argument, nullptr, 0 },
62 { "user_wipe_data", no_argument, nullptr, 0 },
63 { "sdcard_update", no_argument, nullptr, 0 },
64 { "upgraded_pkg_num", required_argument, nullptr, 0 },
65 { "force_update_action", required_argument, nullptr, 0 },
66 { nullptr, 0, nullptr, 0 },
67 };
68 constexpr float VERIFY_PERCENT = 0.05;
69
DoFactoryReset(FactoryResetMode mode,const std::string & path)70 static int DoFactoryReset(FactoryResetMode mode, const std::string &path)
71 {
72 if (mode == USER_WIPE_DATA) {
73 STAGE(UPDATE_STAGE_BEGIN) << "User FactoryReset";
74 LOG(INFO) << "Begin erasing /data";
75 if (FormatPartition(path, true) != 0) {
76 LOG(ERROR) << "User level FactoryReset failed";
77 STAGE(UPDATE_STAGE_FAIL) << "User FactoryReset";
78 ERROR_CODE(CODE_FACTORY_RESET_FAIL);
79 return 1;
80 }
81 LOG(INFO) << "User level FactoryReset success";
82 STAGE(UPDATE_STAGE_SUCCESS) << "User FactoryReset";
83 }
84 return 0;
85 }
86
FactoryReset(FactoryResetMode mode,const std::string & path)87 int FactoryReset(FactoryResetMode mode, const std::string &path)
88 {
89 return DoFactoryReset(mode, path);
90 }
91
OtaUpdatePreCheck(PkgManager::PkgManagerPtr pkgManager,const std::string & packagePath)92 static int OtaUpdatePreCheck(PkgManager::PkgManagerPtr pkgManager, const std::string &packagePath)
93 {
94 UPDATER_INIT_RECORD;
95 if (pkgManager == nullptr) {
96 LOG(ERROR) << "pkgManager is nullptr";
97 UPDATER_LAST_WORD(PKG_INVALID_FILE);
98 return UPDATE_CORRUPT;
99 }
100 char realPath[PATH_MAX + 1] = {0};
101 if (realpath(packagePath.c_str(), realPath) == nullptr) {
102 LOG(ERROR) << "realpath error";
103 UPDATER_LAST_WORD(PKG_INVALID_FILE);
104 return PKG_INVALID_FILE;
105 }
106 if (access(realPath, F_OK) != 0) {
107 LOG(ERROR) << "package does not exist!";
108 UPDATER_LAST_WORD(PKG_INVALID_FILE);
109 return PKG_INVALID_FILE;
110 }
111
112 int32_t ret = pkgManager->VerifyOtaPackage(packagePath);
113 if (ret != PKG_SUCCESS) {
114 LOG(INFO) << "VerifyOtaPackage fail ret :"<< ret;
115 UPDATER_LAST_WORD(ret);
116 return ret;
117 }
118
119 return PKG_SUCCESS;
120 }
121
UpdatePreCheck(UpdaterParams & upParams,const std::string pkgPath)122 static UpdaterStatus UpdatePreCheck(UpdaterParams &upParams, const std::string pkgPath)
123 {
124 if (PreProcess::GetInstance().DoUpdateAuth(pkgPath) != 0) {
125 UPDATER_LAST_WORD(UPDATE_ERROR);
126 return UPDATE_ERROR;
127 }
128
129 PkgManager::PkgManagerPtr pkgManager = PkgManager::CreatePackageInstance();
130 if (GetUpdatePackageInfo(pkgManager, pkgPath) != PKG_SUCCESS) {
131 PkgManager::ReleasePackageInstance(pkgManager);
132 LOG(ERROR) << "Verify update bin file Fail!";
133 UPDATER_LAST_WORD(UPDATE_ERROR);
134 return UPDATE_ERROR;
135 }
136 if (PreProcess::GetInstance().DoUpdatePreProcess(pkgManager) != PKG_SUCCESS) {
137 PkgManager::ReleasePackageInstance(pkgManager);
138 LOG(ERROR) << "Version Check Fail!";
139 UPDATER_LAST_WORD(UPDATE_ERROR);
140 return UPDATE_ERROR;
141 }
142 PkgManager::ReleasePackageInstance(pkgManager);
143 return UPDATE_SUCCESS;
144 }
145
VerifyPackages(UpdaterParams & upParams)146 static UpdaterStatus VerifyPackages(UpdaterParams &upParams)
147 {
148 LOG(INFO) << "Verify packages start...";
149 UPDATER_UI_INSTANCE.ShowProgressPage();
150 UPDATER_UI_INSTANCE.ShowUpdInfo(TR(UPD_VERIFYPKG));
151
152 if (upParams.callbackProgress == nullptr) {
153 UPDATER_UI_INSTANCE.ShowUpdInfo(TR(UPD_VERIFYPKGFAIL), true);
154 UPDATER_LAST_WORD(UPDATE_CORRUPT);
155 return UPDATE_CORRUPT;
156 }
157 upParams.callbackProgress(0.0);
158 for (unsigned int i = upParams.pkgLocation; i < upParams.updatePackage.size(); i++) {
159 LOG(INFO) << "Verify package:" << upParams.updatePackage[i];
160 auto startTime = std::chrono::system_clock::now();
161 PkgManager::PkgManagerPtr manager = PkgManager::CreatePackageInstance();
162 int32_t verifyret = OtaUpdatePreCheck(manager, upParams.updatePackage[i]);
163 PkgManager::ReleasePackageInstance(manager);
164
165 if (verifyret != PKG_SUCCESS || UpdatePreCheck(upParams, upParams.updatePackage[i]) != UPDATE_SUCCESS) {
166 upParams.pkgLocation = i;
167 UPDATER_UI_INSTANCE.ShowUpdInfo(TR(UPD_VERIFYPKGFAIL), true);
168 auto endTime = std::chrono::system_clock::now();
169 upParams.installTime.push_back(endTime - startTime);
170 UPDATER_LAST_WORD(UPDATE_CORRUPT);
171 return UPDATE_CORRUPT;
172 }
173 auto endTime = std::chrono::system_clock::now();
174 upParams.installTime.push_back(endTime - startTime);
175 }
176
177 ProgressSmoothHandler(0, static_cast<int>(VERIFY_PERCENT * FULL_PERCENT_PROGRESS));
178 LOG(INFO) << "Verify packages successfull...";
179 return UPDATE_SUCCESS;
180 }
181
GetBatteryCapacity(int & capacity)182 bool GetBatteryCapacity(int &capacity)
183 {
184 const static std::vector<const char *> vec = {
185 "/sys/class/power_supply/battery/capacity",
186 "/sys/class/power_supply/Battery/capacity"
187 };
188 for (auto &it : vec) {
189 std::ifstream ifs { it };
190 if (!ifs.is_open()) {
191 continue;
192 }
193
194 int tmpCapacity = 0;
195 ifs >> tmpCapacity;
196 if ((ifs.fail()) || (ifs.bad())) {
197 continue;
198 }
199
200 capacity = tmpCapacity;
201 return true;
202 }
203
204 return false;
205 }
206
IsBatteryCapacitySufficient()207 bool IsBatteryCapacitySufficient()
208 {
209 if (Utils::CheckUpdateMode(OTA_MODE)) {
210 LOG(INFO) << "this is OTA update, on need to determine the battery";
211 return true;
212 }
213 static constexpr auto levelIdx = "lowBatteryLevel";
214 static constexpr auto jsonPath = "/etc/product_cfg.json";
215
216 int capacity = 0;
217 bool ret = GetBatteryCapacity(capacity);
218 if (!ret) {
219 return true; /* maybe no battery or err value return default true */
220 }
221
222 JsonNode node { Fs::path { jsonPath }};
223 auto item = node[levelIdx].As<int>();
224 if (!item.has_value()) {
225 return true; /* maybe no value return default true */
226 }
227
228 int lowLevel = *item;
229 if (lowLevel > 100 || lowLevel < 0) { /* full percent is 100 */
230 LOG(ERROR) << "load battery level error:" << lowLevel;
231 return false; /* config err not allow to update */
232 }
233
234 LOG(INFO) << "current capacity:" << capacity << ", low level:" << lowLevel;
235
236 return capacity > lowLevel;
237 }
238
InstallUpdaterPackage(UpdaterParams & upParams,PkgManager::PkgManagerPtr manager)239 static UpdaterStatus InstallUpdaterPackage(UpdaterParams &upParams, PkgManager::PkgManagerPtr manager)
240 {
241 UpdaterStatus status = UPDATE_UNKNOWN;
242 STAGE(UPDATE_STAGE_BEGIN) << "Install package";
243 if (upParams.retryCount == 0) {
244 // First time enter updater, record retryCount in case of abnormal reset.
245 if (!PartitionRecord::GetInstance().ClearRecordPartitionOffset()) {
246 LOG(ERROR) << "ClearRecordPartitionOffset failed";
247 UPDATER_LAST_WORD(UPDATE_ERROR);
248 return UPDATE_ERROR;
249 }
250 SetMessageToMisc(upParams.miscCmd, upParams.retryCount + 1, "retry_count");
251 }
252 if (upParams.sdcardUpdate) {
253 status = DoInstallUpdaterPackage(manager, upParams, SDCARD_UPDATE);
254 } else {
255 status = DoInstallUpdaterPackage(manager, upParams, HOTA_UPDATE);
256 }
257 if (status != UPDATE_SUCCESS) {
258 UPDATER_UI_INSTANCE.Sleep(UI_SHOW_DURATION);
259 UPDATER_UI_INSTANCE.ShowLog(TR(LOG_UPDFAIL));
260 STAGE(UPDATE_STAGE_FAIL) << "Install failed";
261 if (status == UPDATE_RETRY && upParams.retryCount < MAX_RETRY_COUNT) {
262 upParams.retryCount += 1;
263 UPDATER_UI_INSTANCE.ShowFailedPage();
264 SetMessageToMisc(upParams.miscCmd, upParams.retryCount, "retry_count");
265 Utils::UpdaterDoReboot("updater");
266 }
267 } else {
268 LOG(INFO) << "Install package success.";
269 STAGE(UPDATE_STAGE_SUCCESS) << "Install package";
270 }
271 return status;
272 }
273
CalcProgress(const UpdaterParams & upParams,std::vector<double> & pkgStartPosition,double & updateStartPosition)274 static UpdaterStatus CalcProgress(const UpdaterParams &upParams,
275 std::vector<double> &pkgStartPosition, double &updateStartPosition)
276 {
277 UPDATER_INIT_RECORD;
278 int64_t allPkgSize = 0;
279 std::vector<int64_t> everyPkgSize;
280 for (const auto &path : upParams.updatePackage) {
281 char realPath[PATH_MAX + 1] = {0};
282 if (realpath(path.c_str(), realPath) == nullptr) {
283 LOG(ERROR) << "Can not find updatePackage : " << path;
284 UPDATER_LAST_WORD(UPDATE_ERROR);
285 return UPDATE_ERROR;
286 }
287 struct stat st {};
288 if (stat(realPath, &st) == 0) {
289 everyPkgSize.push_back(st.st_size);
290 allPkgSize += st.st_size;
291 LOG(INFO) << "pkg " << path << " size is:" << st.st_size;
292 }
293 }
294 pkgStartPosition.push_back(VERIFY_PERCENT);
295 if (allPkgSize == 0) {
296 LOG(ERROR) << "All packages's size is 0.";
297 UPDATER_LAST_WORD(UPDATE_ERROR);
298 return UPDATE_ERROR;
299 }
300 int64_t startSize = 0;
301 for (auto size : everyPkgSize) {
302 startSize += size;
303 float percent = static_cast<double>(startSize) / static_cast<double>(allPkgSize) + VERIFY_PERCENT;
304 percent = (percent > 1.0) ? 1.0 : percent; // 1.0 : 100%
305 LOG(INFO) << "percent is:" << percent;
306 pkgStartPosition.push_back(percent);
307 }
308
309 updateStartPosition = pkgStartPosition[upParams.pkgLocation];
310 return UPDATE_SUCCESS;
311 }
312
PreUpdatePackages(UpdaterParams & upParams)313 static UpdaterStatus PreUpdatePackages(UpdaterParams &upParams)
314 {
315 UPDATER_INIT_RECORD;
316 LOG(INFO) << "start to update packages, start index:" << upParams.pkgLocation;
317
318 UpdaterStatus status = UPDATE_UNKNOWN;
319 if (SetupPartitions() != 0) {
320 UPDATER_UI_INSTANCE.ShowUpdInfo(TR(UPD_SETPART_FAIL), true);
321 UPDATER_LAST_WORD(UPDATE_ERROR);
322 return UPDATE_ERROR;
323 }
324 const std::string resultPath = std::string(UPDATER_PATH) + "/" + std::string(UPDATER_RESULT_FILE);
325 if (access(resultPath.c_str(), F_OK) != -1) {
326 (void)DeleteFile(resultPath);
327 LOG(INFO) << "deleate last upgrade file";
328 }
329
330 // verify packages first
331 if (VerifyPackages(upParams) != UPDATE_SUCCESS) {
332 UPDATER_LAST_WORD(UPDATE_ERROR);
333 return UPDATE_ERROR;
334 }
335
336 // Only handle UPATE_ERROR and UPDATE_SUCCESS here.Let package verify handle others.
337 if (IsSpaceCapacitySufficient(upParams.updatePackage) == UPDATE_ERROR) {
338 UPDATER_LAST_WORD(status);
339 return status;
340 }
341 if (upParams.retryCount == 0 && !IsBatteryCapacitySufficient()) {
342 UPDATER_UI_INSTANCE.ShowUpdInfo(TR(LOG_LOWPOWER));
343 UPDATER_UI_INSTANCE.Sleep(UI_SHOW_DURATION);
344 UPDATER_LAST_WORD(UPDATE_ERROR);
345 LOG(ERROR) << "Battery is not sufficient for install package.";
346 return UPDATE_SKIP;
347 }
348
349 #ifdef UPDATER_USE_PTABLE
350 if (!PtablePreProcess::GetInstance().DoPtableProcess(upParams)) {
351 LOG(ERROR) << "DoPtableProcess failed";
352 UPDATER_LAST_WORD(UPDATE_ERROR);
353 return UPDATE_ERROR;
354 }
355 #endif
356 return UPDATE_SUCCESS;
357 }
358
DoUpdatePackages(UpdaterParams & upParams)359 static UpdaterStatus DoUpdatePackages(UpdaterParams &upParams)
360 {
361 UPDATER_INIT_RECORD;
362 UpdaterStatus status = UPDATE_UNKNOWN;
363 std::vector<double> pkgStartPosition {};
364 double updateStartPosition;
365 status = CalcProgress(upParams, pkgStartPosition, updateStartPosition);
366 if (status != UPDATE_SUCCESS) {
367 UPDATER_LAST_WORD(status);
368 return status;
369 }
370 for (unsigned int i = 0; i < upParams.updatePackage.size(); i++) {
371 LOG(INFO) << "package " << i << ":" << upParams.updatePackage[i] <<
372 " precent:" << upParams.currentPercentage;
373 }
374 if (upParams.callbackProgress == nullptr) {
375 LOG(ERROR) << "CallbackProgress is nullptr";
376 return UPDATE_CORRUPT;
377 }
378 upParams.callbackProgress(updateStartPosition * FULL_PERCENT_PROGRESS);
379 for (; upParams.pkgLocation < upParams.updatePackage.size(); upParams.pkgLocation++) {
380 PkgManager::PkgManagerPtr manager = PkgManager::CreatePackageInstance();
381 auto startTime = std::chrono::system_clock::now();
382 upParams.currentPercentage = pkgStartPosition[upParams.pkgLocation + 1] -
383 pkgStartPosition[upParams.pkgLocation];
384 upParams.initialProgress = pkgStartPosition[upParams.pkgLocation];
385 LOG(INFO) << "InstallUpdaterPackage pkg is " << upParams.updatePackage[upParams.pkgLocation] <<
386 " percent:" << upParams.initialProgress << "~" << pkgStartPosition[upParams.pkgLocation + 1];
387
388 status = InstallUpdaterPackage(upParams, manager);
389 SetMessageToMisc(upParams.miscCmd, upParams.pkgLocation + 1, "upgraded_pkg_num");
390 auto endTime = std::chrono::system_clock::now();
391 upParams.installTime[upParams.pkgLocation] = upParams.installTime[upParams.pkgLocation] + endTime - startTime;
392 ProgressSmoothHandler(
393 static_cast<int>(upParams.initialProgress * FULL_PERCENT_PROGRESS +
394 upParams.currentPercentage * GetTmpProgressValue()),
395 static_cast<int>(pkgStartPosition[upParams.pkgLocation + 1] * FULL_PERCENT_PROGRESS));
396 if (status != UPDATE_SUCCESS) {
397 LOG(ERROR) << "InstallUpdaterPackage failed! Pkg is " << upParams.updatePackage[upParams.pkgLocation];
398 if (!CheckDumpResult()) {
399 UPDATER_LAST_WORD(status);
400 }
401 PkgManager::ReleasePackageInstance(manager);
402 return status;
403 }
404 PkgManager::ReleasePackageInstance(manager);
405 }
406 if (upParams.forceUpdate) {
407 UPDATER_UI_INSTANCE.ShowLogRes(TR(LABEL_UPD_OK_SHUTDOWN));
408 }
409 UPDATER_UI_INSTANCE.ShowSuccessPage();
410 return status;
411 }
412
PostUpdatePackages(UpdaterParams & upParams,bool updateResult)413 static void PostUpdatePackages(UpdaterParams &upParams, bool updateResult)
414 {
415 std::string writeBuffer;
416 std::string buf;
417 std::string time;
418 if (!updateResult) {
419 const std::string resultPath = std::string(UPDATER_PATH) + "/" + std::string(UPDATER_RESULT_FILE);
420 std::ifstream fin {resultPath};
421 if (!fin.is_open() || !std::getline(fin, buf)) {
422 LOG(ERROR) << "read result file error " << resultPath;
423 buf = "fail";
424 }
425 } else {
426 buf = "pass";
427 upParams.pkgLocation = upParams.pkgLocation == 0 ? upParams.pkgLocation : (upParams.pkgLocation - 1);
428 }
429
430 for (unsigned int i = 0; i < upParams.pkgLocation; i++) {
431 time = DurationToString(upParams.installTime[i]);
432 writeBuffer += upParams.updatePackage[i] + "|pass|install_time=" + time + "\n";
433 }
434 time = DurationToString(upParams.installTime[upParams.pkgLocation]);
435
436 writeBuffer += upParams.updatePackage[upParams.pkgLocation] + "|" + buf + "|install_time=" + time + "\n";
437 for (unsigned int i = upParams.pkgLocation + 1; i < upParams.updatePackage.size(); i++) {
438 writeBuffer += upParams.updatePackage[i] + "\n";
439 }
440 if (writeBuffer != "") {
441 writeBuffer.pop_back();
442 }
443 LOG(INFO) << "post over, writeBuffer = " << writeBuffer;
444 WriteDumpResult(writeBuffer);
445 }
446
UpdaterFromSdcard(UpdaterParams & upParams)447 UpdaterStatus UpdaterFromSdcard(UpdaterParams &upParams)
448 {
449 upParams.callbackProgress = [] (float value) { UPDATER_UI_INSTANCE.ShowProgress(value); };
450 SetMessageToMisc(upParams.miscCmd, 0, "sdcard_update");
451 if (CheckSdcardPkgs(upParams) != UPDATE_SUCCESS) {
452 LOG(ERROR) << "can not find sdcard packages";
453 return UPDATE_ERROR;
454 }
455 // verify packages first
456 if (upParams.retryCount == 0 && !IsBatteryCapacitySufficient()) {
457 UPDATER_UI_INSTANCE.ShowUpdInfo(TR(LOG_LOWPOWER));
458 UPDATER_UI_INSTANCE.Sleep(UI_SHOW_DURATION);
459 LOG(ERROR) << "Battery is not sufficient for install package.";
460 return UPDATE_SKIP;
461 }
462
463 if (upParams.pkgLocation == 0 && VerifyPackages(upParams) != UPDATE_SUCCESS) {
464 return UPDATE_ERROR;
465 }
466 #ifdef UPDATER_USE_PTABLE
467 if (!PtablePreProcess::GetInstance().DoPtableProcess(upParams)) {
468 LOG(ERROR) << "DoPtableProcess failed";
469 return UPDATE_ERROR;
470 }
471 #endif
472 upParams.initialProgress += VERIFY_PERCENT;
473 upParams.currentPercentage -= VERIFY_PERCENT;
474
475 STAGE(UPDATE_STAGE_BEGIN) << "UpdaterFromSdcard";
476 LOG(INFO) << "UpdaterFromSdcard start, sdcard updaterPath : " << upParams.updatePackage[upParams.pkgLocation];
477 UPDATER_UI_INSTANCE.ShowLog(TR(LOG_SDCARD_NOTMOVE));
478 return DoUpdatePackages(upParams);
479 }
480
InstallUpdaterPackages(UpdaterParams & upParams)481 UpdaterStatus InstallUpdaterPackages(UpdaterParams &upParams)
482 {
483 UpdaterStatus status = PreUpdatePackages(upParams);
484 if (status == UPDATE_SUCCESS) {
485 status = DoUpdatePackages(upParams);
486 }
487 PostUpdatePackages(upParams, status == UPDATE_SUCCESS);
488 return status;
489 }
490
StartUpdaterEntry(UpdaterParams & upParams)491 static UpdaterStatus StartUpdaterEntry(UpdaterParams &upParams)
492 {
493 UpdaterStatus status = UPDATE_UNKNOWN;
494 if (upParams.sdcardUpdate) {
495 LOG(INFO) << "start sdcard update";
496 UPDATER_UI_INSTANCE.ShowProgressPage();
497 status = UpdaterFromSdcard(upParams);
498 return status;
499 } else if (upParams.updatePackage.size() > 0) {
500 UPDATER_UI_INSTANCE.ShowProgressPage();
501 status = InstallUpdaterPackages(upParams);
502 } else if (upParams.factoryWipeData) {
503 UPDATER_UI_INSTANCE.ShowProgressPage();
504 LOG(INFO) << "Factory level FactoryReset begin";
505 status = UPDATE_SUCCESS;
506 #if !defined(UPDATER_UT) && defined(UPDATER_UI_SUPPORT)
507 DoProgress();
508 #endif
509 if (FactoryReset(FACTORY_WIPE_DATA, "/data") != 0) {
510 LOG(ERROR) << "FactoryReset factory level failed";
511 status = UPDATE_ERROR;
512 }
513 UPDATER_UI_INSTANCE.ShowLogRes(
514 (status != UPDATE_SUCCESS) ? TR(LOGRES_FACTORY_FAIL) : TR(LOGRES_FACTORY_DONE));
515 UpdaterInit::GetInstance().InvokeEvent(UPDATER_RPMB_DATA_CLEAR_EVENT);
516 } else if (upParams.userWipeData) {
517 UPDATER_UI_INSTANCE.ShowProgressPage();
518 LOG(INFO) << "User level FactoryReset begin";
519 status = UPDATE_SUCCESS;
520 #if !defined(UPDATER_UT) && defined(UPDATER_UI_SUPPORT)
521 DoProgress();
522 #endif
523 if (FactoryReset(USER_WIPE_DATA, "/data") != 0) {
524 LOG(ERROR) << "FactoryReset user level failed";
525 status = UPDATE_ERROR;
526 }
527 if (status != UPDATE_SUCCESS) {
528 UPDATER_UI_INSTANCE.ShowLogRes(TR(LOGRES_WIPE_FAIL));
529 } else {
530 UpdaterInit::GetInstance().InvokeEvent(UPDATER_RPMB_DATA_CLEAR_EVENT);
531 UPDATER_UI_INSTANCE.ShowSuccessPage();
532 UPDATER_UI_INSTANCE.ShowLogRes(TR(LOGRES_WIPE_FINISH));
533 PostUpdater(true);
534 std::this_thread::sleep_for(std::chrono::milliseconds(UI_SHOW_DURATION));
535 }
536 }
537 return status;
538 }
539
StartUpdater(const std::vector<std::string> & args,char ** argv,PackageUpdateMode & mode,UpdaterParams & upParams)540 static UpdaterStatus StartUpdater(const std::vector<std::string> &args,
541 char **argv, PackageUpdateMode &mode, UpdaterParams &upParams)
542 {
543 std::vector<char *> extractedArgs;
544 int rc;
545 int optionIndex;
546
547 for (const auto &arg : args) {
548 extractedArgs.push_back(const_cast<char *>(arg.c_str()));
549 }
550 extractedArgs.push_back(nullptr);
551 extractedArgs.insert(extractedArgs.begin(), argv[0]);
552 while ((rc = getopt_long(extractedArgs.size() - 1, extractedArgs.data(), "", OPTIONS, &optionIndex)) != -1) {
553 switch (rc) {
554 case 0: {
555 std::string option = OPTIONS[optionIndex].name;
556 if (option == "update_package") {
557 upParams.updatePackage.push_back(optarg);
558 (void)UPDATER_UI_INSTANCE.SetMode(UpdaterMode::OTA);
559 mode = HOTA_UPDATE;
560 } else if (option == "retry_count") {
561 upParams.retryCount = atoi(optarg);
562 } else if (option == "factory_wipe_data") {
563 (void)UPDATER_UI_INSTANCE.SetMode(UpdaterMode::REBOOTFACTORYRST);
564 upParams.factoryWipeData = true;
565 } else if (option == "user_wipe_data") {
566 (void)UPDATER_UI_INSTANCE.SetMode(UpdaterMode::REBOOTFACTORYRST);
567 upParams.userWipeData = true;
568 } else if (option == "upgraded_pkg_num") {
569 upParams.pkgLocation = static_cast<unsigned int>(atoi(optarg));
570 } else if (option == "sdcard_update") {
571 upParams.sdcardUpdate = true;
572 } else if (option == "force_update_action" && std::string(optarg) == POWEROFF) { /* Only for OTA. */
573 upParams.forceUpdate = true;
574 }
575 break;
576 }
577 default:
578 LOG(ERROR) << "Invalid argument.";
579 break;
580 }
581 }
582 optind = 1;
583 // Sanity checks
584 if (upParams.sdcardUpdate) {
585 (void)UPDATER_UI_INSTANCE.SetMode(UpdaterMode::SDCARD);
586 mode = SDCARD_UPDATE;
587 }
588 if (upParams.factoryWipeData && upParams.userWipeData) {
589 LOG(WARNING) << "Factory level reset and user level reset both set. use user level reset.";
590 upParams.factoryWipeData = false;
591 }
592 return StartUpdaterEntry(upParams);
593 }
594
595 // add updater mode
596 REGISTER_MODE(Updater, "updater.hdc.configfs");
597
UpdaterMain(int argc,char ** argv)598 int UpdaterMain(int argc, char **argv)
599 {
600 [[maybe_unused]] UpdaterStatus status = UPDATE_UNKNOWN;
601 UpdaterParams upParams;
602 upParams.callbackProgress = [] (float value) { UPDATER_UI_INSTANCE.ShowProgress(value); };
603 UpdaterInit::GetInstance().InvokeEvent(UPDATER_PRE_INIT_EVENT);
604 std::vector<std::string> args = ParseParams(argc, argv);
605
606 LOG(INFO) << "Ready to start";
607 #if !defined(UPDATER_UT) && defined(UPDATER_UI_SUPPORT)
608 UPDATER_UI_INSTANCE.InitEnv();
609 #endif
610 UpdaterInit::GetInstance().InvokeEvent(UPDATER_INIT_EVENT);
611 PackageUpdateMode mode = UNKNOWN_UPDATE;
612 status = StartUpdater(args, argv, mode, upParams);
613 #if !defined(UPDATER_UT) && defined(UPDATER_UI_SUPPORT)
614 UPDATER_UI_INSTANCE.Sleep(UI_SHOW_DURATION);
615 if (status != UPDATE_SUCCESS && status != UPDATE_SKIP) {
616 if (mode == HOTA_UPDATE) {
617 UPDATER_UI_INSTANCE.ShowFailedPage();
618 } else if (mode == SDCARD_UPDATE) {
619 UPDATER_UI_INSTANCE.ShowLogRes(
620 status == UPDATE_CORRUPT ? TR(LOGRES_VERIFY_FAILED) : TR(LOGRES_UPDATE_FAILED));
621 UPDATER_UI_INSTANCE.ShowFailedPage();
622 Utils::UsSleep(5 * DISPLAY_TIME); // 5 : 5s
623 UPDATER_UI_INSTANCE.ShowMainpage();
624 } else {
625 UPDATER_UI_INSTANCE.ShowMainpage();
626 UPDATER_UI_INSTANCE.Sleep(50); /* wait for page flush 50ms */
627 UPDATER_UI_INSTANCE.SaveScreen();
628 }
629 // Wait for user input
630 while (true) {
631 Utils::UsSleep(DISPLAY_TIME);
632 }
633 return 0;
634 }
635 #endif
636 PostUpdater(true);
637 upParams.forceUpdate ? Utils::DoShutdown() : Utils::UpdaterDoReboot("");
638 return 0;
639 }
640 } // Updater
641