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 #include "factory_reset.h"
16 #include <string>
17 #include "log/dump.h"
18 #include "log/log.h"
19 #include "fs_manager/mount.h"
20 #include "scope_guard.h"
21 
22 namespace Updater {
GetInstance()23 FactoryResetProcess &FactoryResetProcess::GetInstance()
24 {
25     static FactoryResetProcess resetProcessor;
26     return resetProcessor;
27 }
28 
FactoryResetProcess()29 FactoryResetProcess::FactoryResetProcess()
30 {
31     RegisterFunc(USER_WIPE_DATA, [this](const std::string &path) { return DoUserReset(path); });
32     RegisterFunc(FACTORY_WIPE_DATA, [this](const std::string &path) { return DoFactoryReset(path); });
33     RegisterFunc(MENU_WIPE_DATA, [this](const std::string &path) { return DoUserReset(path); });
34 }
35 
RegisterFunc(FactoryResetMode mode,ResetFunc func)36 void FactoryResetProcess::RegisterFunc(FactoryResetMode mode, ResetFunc func)
37 {
38     if (!resetTab_.emplace(mode, func).second) {
39         LOG(ERROR) << "emplace: " << mode << " fail";
40     }
41 }
42 
FactoryResetFunc(FactoryResetMode mode,const std::string & path)43 int FactoryResetProcess::FactoryResetFunc(FactoryResetMode mode, const std::string &path)
44 {
45     auto iter = resetTab_.find(mode);
46     if (iter == resetTab_.end() || iter->second == nullptr) {
47         LOG(ERROR) << "Invalid factory reset tag: " << mode;
48         return 1;
49     }
50     int resetStatus = iter->second(path);
51     ON_SCOPE_EXIT(factoryResetPost) {
52         if (mode == FACTORY_WIPE_DATA &&
53             (FactoryResetPostFunc_ == nullptr || FactoryResetPostFunc_(resetStatus) != 0)) {
54             LOG(ERROR) << "FactoryResetPostFunc_ fail";
55         }
56     };
57     if (resetStatus != 0) {
58         LOG(ERROR) << "Do factory reset failed! tag: " << mode;
59         return 1;
60     }
61     if (CommonResetPostFunc_ == nullptr ||
62         CommonResetPostFunc_(mode == MENU_WIPE_DATA || mode == FACTORY_WIPE_DATA) != 0) {
63         resetStatus = 1;
64         LOG(ERROR) << "CommonResetPostFunc_ fail";
65         return -1;
66     }
67     return 0;
68 }
69 
CommonResetPost(bool flag)70 static int CommonResetPost(bool flag)
71 {
72     LOG(INFO) << "CommonResetPost";
73     return 0;
74 }
75 
RegisterCommonResetPostFunc(CommonResetPostFunc ptr)76 void FactoryResetProcess::RegisterCommonResetPostFunc(CommonResetPostFunc ptr)
77 {
78     CommonResetPostFunc_ = std::move(ptr);
79 }
80 
FactoryResetPre()81 static int FactoryResetPre()
82 {
83     LOG(INFO) << "FactoryResetPre";
84     return 0;
85 }
86 
RegisterFactoryResetPreFunc(FactoryResetPreFunc ptr)87 void FactoryResetProcess::RegisterFactoryResetPreFunc(FactoryResetPreFunc ptr)
88 {
89     FactoryResetPreFunc_ = std::move(ptr);
90 }
91 
FactoryResetPost(int status)92 static int FactoryResetPost(int status)
93 {
94     LOG(INFO) << "FactoryResetPost";
95     return 0;
96 }
97 
RegisterFactoryResetPostFunc(FactoryResetPostFunc ptr)98 void FactoryResetProcess::RegisterFactoryResetPostFunc(FactoryResetPostFunc ptr)
99 {
100     FactoryResetPostFunc_ = std::move(ptr);
101 }
102 
DoUserReset(const std::string & path)103 int FactoryResetProcess::DoUserReset(const std::string &path)
104 {
105     STAGE(UPDATE_STAGE_BEGIN) << "User FactoryReset";
106     LOG(INFO) << "Begin erasing data";
107     if (FormatPartition(path, true) != 0) {
108         LOG(ERROR) << "User level FactoryReset failed";
109         STAGE(UPDATE_STAGE_FAIL) << "User FactoryReset";
110         ERROR_CODE(CODE_FACTORY_RESET_FAIL);
111         return 1;
112     }
113     LOG(INFO) << "User level FactoryReset success";
114     STAGE(UPDATE_STAGE_SUCCESS) << "User FactoryReset";
115 
116     return 0;
117 }
118 
DoFactoryReset(const std::string & path)119 int FactoryResetProcess::DoFactoryReset(const std::string &path)
120 {
121     int resetStatus = 0;
122     STAGE(UPDATE_STAGE_BEGIN) << "Factory FactoryReset";
123     if (FactoryResetPreFunc_ == nullptr || FactoryResetPreFunc_() != 0) {
124         LOG(ERROR) << "FactoryResetPreFunc_ fail";
125     }
126     LOG(INFO) << "Begin erasing data";
127     if (FormatPartition(path, true) != 0) {
128         STAGE(UPDATE_STAGE_FAIL) << "Factory FactoryReset";
129         ERROR_CODE(CODE_FACTORY_RESET_FAIL);
130         resetStatus = 1;
131     }
132 
133     LOG(INFO) << "Factory level FactoryReset status:" << resetStatus;
134     return resetStatus;
135 }
136 
RegisterCommonResetPostFunc(void)137 extern "C" __attribute__((constructor)) void RegisterCommonResetPostFunc(void)
138 {
139     FactoryResetProcess::GetInstance().RegisterCommonResetPostFunc(CommonResetPost);
140 }
141 
RegisterFactoryResetPreFunc(void)142 extern "C" __attribute__((constructor)) void RegisterFactoryResetPreFunc(void)
143 {
144     FactoryResetProcess::GetInstance().RegisterFactoryResetPreFunc(FactoryResetPre);
145 }
146 
RegisterFactoryResetPostFunc(void)147 extern "C" __attribute__((constructor)) void RegisterFactoryResetPostFunc(void)
148 {
149     FactoryResetProcess::GetInstance().RegisterFactoryResetPostFunc(FactoryResetPost);
150 }
151 } // Updater