• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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