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 #include "updater_ui.h"
16 #include <mutex>
17 #include <thread>
18 #include "language/language_ui.h"
19 #include "log/log.h"
20 #include "page/page_manager.h"
21 #include "scope_guard.h"
22 #include "updater_main.h"
23 #include "updater_ui_facade.h"
24 #include "utils.h"
25
26 namespace Updater {
27 namespace {
28 constexpr uint32_t DISPLAY_TIME = 1 * 1000 * 1000; /* 1s */
29 constexpr uint32_t FAIL_DELAY = 5 * 1000 * 1000;
30 constexpr uint32_t SUCCESS_DELAY = 3 * 1000 * 1000;
31 constexpr int CALLBACK_DELAY = 20 * 1000; /* 20ms */
32 std::mutex g_mtx;
33 bool g_isInCallback { false };
34 bool g_timerStopped { false };
IsAlreadyInCallback()35 bool IsAlreadyInCallback()
36 {
37 std::lock_guard<std::mutex> lck(g_mtx);
38 if (!g_isInCallback) {
39 return false;
40 }
41 g_isInCallback = true;
42 return true;
43 }
44
ExitCallback()45 void ExitCallback()
46 {
47 std::lock_guard<std::mutex> lck(g_mtx);
48 g_isInCallback = false;
49 }
50
GetFacade()51 inline auto &GetFacade()
52 {
53 return UpdaterUiFacade::GetInstance();
54 }
55
56 /**
57 * avoid calling multipule callback simultaneously.
58 * When defining a new callback, should place a
59 * CALLBACK_GUARD_RETURN at the beginning of callback function
60 */
61 #define CALLBACK_GUARD_RETURN \
62 if (IsAlreadyInCallback()) { \
63 return; \
64 } \
65 ON_SCOPE_EXIT(exitCallback) \
66 { \
67 ExitCallback(); \
68 }
69 } // namespace
70
operator <<(std::ostream & os,const ComInfo & com)71 std::ostream &operator<<(std::ostream &os, const ComInfo &com)
72 {
73 os << "pageId: " << com.pageId << " comId: " << com.comId;
74 return os;
75 }
76
DoProgress()77 void DoProgress()
78 {
79 constexpr int maxSleepMs = 1000 * 1000;
80 constexpr int minSleepMs = 3000;
81 constexpr float ratio = 10.0;
82 // if 100 as fullpercent, then 0.3 per step
83 constexpr int progressValueStep = static_cast<int>(0.3 * ratio);
84 constexpr int maxProgressValue = static_cast<int>(100 * ratio);
85 int progressvalueTmp = 0;
86 if (GetFacade().GetMode() != UpdaterMode::FACTORYRST && GetFacade().GetMode() != UpdaterMode::REBOOTFACTORYRST) {
87 return;
88 }
89 GetFacade().ShowProgress(0);
90 while (progressvalueTmp <= maxProgressValue) {
91 progressvalueTmp = progressvalueTmp + progressValueStep;
92 GetFacade().ShowProgress(progressvalueTmp / ratio);
93 Utils::UsSleep(minSleepMs);
94 if (progressvalueTmp >= maxProgressValue) {
95 Utils::UsSleep(maxSleepMs);
96 return;
97 }
98 }
99 }
100
OnRebootEvt()101 void OnRebootEvt()
102 {
103 LOG(INFO) << "On Label Reboot";
104 std::thread {
105 [] () {
106 CALLBACK_GUARD_RETURN;
107 PostUpdater(false);
108 Utils::DoReboot("");
109 }
110 }.detach();
111 }
112
OnLabelResetEvt()113 void OnLabelResetEvt()
114 {
115 LOG(INFO) << "On Label Reset";
116 CALLBACK_GUARD_RETURN;
117 if (!GetFacade().SetMode(UpdaterMode::FACTORYRST)) {
118 return;
119 }
120 GetFacade().ShowFactoryConfirmPage();
121 }
122
OnLabelSDCardEvt()123 void OnLabelSDCardEvt()
124 {
125 LOG(INFO) << "On Label SDCard";
126 std::thread {
127 [] () {
128 CALLBACK_GUARD_RETURN;
129 if (!GetFacade().SetMode(UpdaterMode::SDCARD)) {
130 return;
131 }
132 Utils::UsSleep(CALLBACK_DELAY);
133 GetFacade().ClearText();
134 GetFacade().ShowProgress(0);
135 GetFacade().ShowLog(TR(LOG_SDCARD_NOTMOVE));
136 Utils::UsSleep(DISPLAY_TIME);
137 if (UpdaterFromSdcard() != UPDATE_SUCCESS) {
138 GetFacade().ShowMainpage();
139 return;
140 }
141 PostUpdater(false);
142 Utils::DoReboot("");
143 }
144 }.detach();
145 }
146
OnLabelSDCardNoDelayEvt()147 void OnLabelSDCardNoDelayEvt()
148 {
149 LOG(INFO) << "On Label SDCard";
150 std::thread {
151 [] () {
152 CALLBACK_GUARD_RETURN;
153 if (!GetFacade().SetMode(UpdaterMode::SDCARD)) {
154 return;
155 }
156 Utils::UsSleep(CALLBACK_DELAY);
157 if (auto res = UpdaterFromSdcard(); res != UPDATE_SUCCESS) {
158 GetFacade().ShowLogRes(res == UPDATE_CORRUPT ? TR(LOGRES_VERIFY_FAILED) : TR(LOGRES_UPDATE_FAILED));
159 GetFacade().ShowFailedPage();
160 Utils::UsSleep(FAIL_DELAY);
161 GetFacade().ShowMainpage();
162 return;
163 }
164 GetFacade().ShowLogRes(TR(LABEL_UPD_OK_DONE));
165 GetFacade().ShowSuccessPage();
166 Utils::UsSleep(SUCCESS_DELAY);
167 PostUpdater(false);
168 Utils::DoReboot("");
169 }
170 }.detach();
171 }
172
OnLabelCancelEvt()173 void OnLabelCancelEvt()
174 {
175 CALLBACK_GUARD_RETURN;
176 LOG(INFO) << "On Label Cancel";
177 PageManager::GetInstance().GoBack();
178 }
179
OnLabelOkEvt()180 void OnLabelOkEvt()
181 {
182 LOG(INFO) << "On Label Ok";
183 std::thread {
184 [] () {
185 CALLBACK_GUARD_RETURN;
186 Utils::UsSleep(CALLBACK_DELAY);
187 GetFacade().ShowMainpage();
188 GetFacade().ClearText();
189 GetFacade().ShowLog(TR(LOG_WIPE_DATA));
190 if (!GetFacade().SetMode(UpdaterMode::FACTORYRST)) {
191 return;
192 }
193 GetFacade().ShowProgress(0);
194 GetFacade().ShowProgressPage();
195 DoProgress();
196 if (FactoryReset(USER_WIPE_DATA, "/data") == 0) {
197 GetFacade().ShowLog(TR(LOG_WIPE_DONE));
198 GetFacade().ShowSuccessPage();
199 } else {
200 GetFacade().ShowLog(TR(LOG_WIPE_FAIL));
201 GetFacade().ShowFailedPage();
202 }
203 }
204 }.detach();
205 }
206
OnConfirmRstEvt()207 void OnConfirmRstEvt()
208 {
209 LOG(INFO) << "On Label Ok";
210 std::thread {
211 [] () {
212 CALLBACK_GUARD_RETURN;
213 if (!GetFacade().SetMode(UpdaterMode::FACTORYRST)) {
214 return;
215 }
216 GetFacade().ShowUpdInfo(TR(LABEL_RESET_PROGRESS_INFO));
217 GetFacade().ShowProgressPage();
218 DoProgress();
219 if (FactoryReset(USER_WIPE_DATA, "/data") != 0) {
220 GetFacade().ShowLogRes(TR(LOG_WIPE_FAIL));
221 GetFacade().ShowFailedPage();
222 Utils::UsSleep(FAIL_DELAY);
223 GetFacade().ShowMainpage();
224 } else {
225 GetFacade().ShowUpdInfo(TR(LOGRES_WIPE_FINISH));
226 Utils::UsSleep(DISPLAY_TIME);
227 GetFacade().ShowSuccessPage();
228 }
229 }
230 }.detach();
231 }
232
OnMenuShutdownEvt()233 void OnMenuShutdownEvt()
234 {
235 LOG(INFO) << "On btn shutdown";
236 std::thread {
237 [] () {
238 CALLBACK_GUARD_RETURN;
239 LOG(DEBUG) << "shutdown";
240 Utils::DoShutdown();
241 }
242 }.detach();
243 }
244
OnMenuClearCacheEvt()245 void OnMenuClearCacheEvt()
246 {
247 LOG(INFO) << "On clear cache";
248 std::thread {
249 [] () {
250 CALLBACK_GUARD_RETURN;
251 GetFacade().ClearText();
252 if (!GetFacade().SetMode(UpdaterMode::FACTORYRST)) {
253 return;
254 }
255 Utils::UsSleep(CALLBACK_DELAY);
256 GetFacade().ShowUpdInfo(TR(LOG_CLEAR_CAHCE));
257 GetFacade().ShowProgressPage();
258 ClearMisc();
259 DoProgress();
260 GetFacade().ShowMainpage();
261 }
262 }.detach();
263 }
264
StartLongPressTimer()265 void StartLongPressTimer()
266 {
267 static int downCount { 0 };
268 if (!GetFacade().IsInProgress()) {
269 return;
270 }
271 ++downCount;
272 g_timerStopped = false;
273 using namespace std::literals::chrono_literals;
274 std::thread t { [lastdownCount = downCount] () {
275 constexpr auto threshold = 2s;
276 std::this_thread::sleep_for(threshold);
277 /**
278 * When the downCount of the last power key press changes,
279 * it means that the last press has been released before
280 * the timeout, then you can exit the callback directly
281 */
282 if (g_timerStopped || lastdownCount != downCount) {
283 return;
284 }
285 // show warning
286 GetFacade().ShowProgressWarning(true);
287 }};
288 t.detach();
289 }
290
StopLongPressTimer()291 void StopLongPressTimer()
292 {
293 // no need to judge whether in progress page,
294 // because may press power key in progress
295 // page and release power key in other page
296 g_timerStopped = true;
297 // hide warning
298 GetFacade().ShowProgressWarning(false);
299 }
300 } // namespace Updater
301