1 /*
2 * Copyright (c) 2021 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 <cstdio>
17 #include "animation_label.h"
18 #include "frame.h"
19 #include "input_event.h"
20 #include "log/log.h"
21 #include "progress_bar.h"
22 #include "securec.h"
23 #include "surface_dev.h"
24 #include "updater_main.h"
25 #include "updater_ui_const.h"
26 #include "utils.h"
27 #include "view.h"
28
29 namespace updater {
30 using utils::String2Int;
31
32 constexpr int LABEL_HEIGHT = 13;
33 constexpr int MAX_IMGS = 62;
34 constexpr int DIALIG_COLOR_A = 0xAA;
35 constexpr int DIALOG_COLOR = 0x00;
36
37 int g_updateFlag = 0;
38 int g_textLabelNum = 0;
39
40 Frame *g_menuFrame;
41 Frame *g_updateFrame;
42 TextLabel *g_textLabel0;
43 TextLabel *g_textLabel2;
44 TextLabel *g_textLabel3;
45 TextLabel *g_logLabel;
46 TextLabel *g_logResultLabel;
47 TextLabel *g_updateInfoLabel;
48 AnimationLable *g_anmimationLabel;
49 ProgressBar *g_progressBar;
50
51 TextLabel *g_dialogTitle;
52 TextLabel *g_dialogNote;
53 TextLabel *g_dialogNoteNext;
54 TextLabel *g_dialogCancalBtn;
55 TextLabel *g_dialogOkBtn;
56 SurfaceDev *g_sfDev;
57
ClearText()58 static void ClearText()
59 {
60 if (g_logLabel != nullptr) {
61 g_logLabel->SetText("");
62 }
63 if (g_logResultLabel != nullptr) {
64 g_logResultLabel->SetText("");
65 }
66 if (g_updateInfoLabel != nullptr) {
67 g_updateInfoLabel->SetText("");
68 }
69 }
70
ShowText(TextLabel * label,std::string text)71 void ShowText(TextLabel *label, std::string text)
72 {
73 if (label != nullptr) {
74 ClearText();
75 label->SetText(text.c_str());
76 }
77 }
78
HideDialog()79 static void HideDialog()
80 {
81 if (!g_menuFrame->IsVisiable()) {
82 return;
83 }
84 if (g_dialogTitle != nullptr) {
85 g_dialogTitle->Hide();
86 }
87 if (g_dialogNote != nullptr) {
88 g_dialogNote->Hide();
89 }
90 if (g_dialogNoteNext != nullptr) {
91 g_dialogNoteNext->Hide();
92 }
93 if (g_dialogCancalBtn != nullptr) {
94 g_dialogCancalBtn->Hide();
95 }
96 if (g_dialogOkBtn != nullptr) {
97 g_dialogOkBtn->Hide();
98 }
99 }
100
ShowDialog()101 static void ShowDialog()
102 {
103 if (!g_menuFrame->IsVisiable()) {
104 return;
105 }
106 if (g_dialogTitle != nullptr) {
107 g_dialogTitle->Show();
108 }
109 if (g_dialogNote != nullptr) {
110 g_dialogNote->Show();
111 }
112 if (g_dialogNoteNext != nullptr) {
113 g_dialogNoteNext->Show();
114 }
115 if (g_dialogCancalBtn != nullptr) {
116 g_dialogCancalBtn->Show();
117 }
118 if (g_dialogOkBtn != nullptr) {
119 g_dialogOkBtn->Show();
120 }
121 }
122
ShowMenu()123 static void ShowMenu()
124 {
125 if (g_menuFrame == nullptr) {
126 return;
127 }
128 if (g_textLabel0 != nullptr) {
129 g_textLabel0->Show();
130 }
131 if (g_textLabel2 != nullptr) {
132 g_textLabel2->Show();
133 }
134 if (g_textLabel3 != nullptr) {
135 g_textLabel3->Show();
136 }
137 g_menuFrame->Show();
138 }
139
HideMenu()140 static void HideMenu()
141 {
142 if (g_menuFrame == nullptr) {
143 return;
144 }
145 if (g_textLabel0 != nullptr) {
146 g_textLabel0->Hide();
147 }
148 if (g_textLabel2 != nullptr) {
149 g_textLabel2->Hide();
150 }
151 if (g_textLabel3 != nullptr) {
152 g_textLabel3->Hide();
153 }
154 g_menuFrame->Hide();
155 }
156
OnKeyEvent(int viewId)157 void OnKeyEvent(int viewId)
158 {
159 if (!g_menuFrame->IsVisiable()) {
160 return;
161 }
162 ClearText();
163 if (viewId == g_textLabel0->GetViewId() && g_textLabel0->IsVisiable()) {
164 HideDialog();
165 PostUpdater(true);
166 utils::DoReboot("");
167 } else if (viewId == g_textLabel2->GetViewId() && g_textLabel2->IsVisiable()) {
168 ShowDialog();
169 } else if (viewId == g_textLabel3->GetViewId() && g_textLabel3->IsVisiable()) {
170 HideDialog();
171 UpdaterStatus status = UpdaterFromSdcard();
172 if (status != UPDATE_SUCCESS) {
173 ShowUpdateFrame(false);
174 ShowMenu();
175 return;
176 }
177 PostUpdater(true);
178 utils::DoReboot("");
179 } else if (viewId == g_dialogCancalBtn->GetViewId() && g_dialogCancalBtn->IsVisiable()) {
180 HideDialog();
181 } else if (viewId == g_dialogOkBtn->GetViewId() && g_dialogOkBtn->IsVisiable()) {
182 HideDialog();
183 HideMenu();
184 g_logLabel->SetText("Wipe data");
185 g_updateFlag = 1;
186 ShowUpdateFrame(true);
187 DoProgress();
188 int ret = FactoryReset(USER_WIPE_DATA, "/data");
189 if (ret != 0) {
190 g_logLabel->SetText("Wipe data failed");
191 } else {
192 g_logLabel->SetText("Wipe data done");
193 }
194 ShowUpdateFrame(false);
195 ShowMenu();
196 }
197 }
198
LoadImgs()199 void LoadImgs()
200 {
201 for (int i = 0; i < MAX_IMGS; i++) {
202 std::string nameBuf;
203 if (i < LOOP_TOP_PICTURES) {
204 nameBuf = "/resources/loop0000";
205 nameBuf.append(std::to_string(i)).append(".png");
206 } else {
207 nameBuf = "/resources/loop000";
208 nameBuf.append(std::to_string(i)).append(".png");
209 }
210 g_anmimationLabel->AddImg(nameBuf);
211 }
212 }
213
ShowUpdateFrame(bool isShow)214 void ShowUpdateFrame(bool isShow)
215 {
216 const int sleepMs = 300 * 100;
217 if (isShow) {
218 g_menuFrame->Hide();
219 g_updateInfoLabel->SetText("");
220 g_updateFrame->Show();
221 g_anmimationLabel->Start();
222 return;
223 }
224 usleep(sleepMs);
225 g_anmimationLabel->Stop();
226 g_progressBar->Show();
227 g_updateFrame->Hide();
228 g_menuFrame->Show();
229 g_updateFlag = 0;
230 }
231
DoProgress()232 void DoProgress()
233 {
234 const int sleepMs = 300 * 1000;
235 const int maxSleepMs = 1000 * 1000;
236 const int progressValueStep = 10;
237 const int maxProgressValue = 100;
238 std::string progressValue;
239 int progressvalueTmp = 0;
240 if (!g_updateFlag) {
241 return;
242 }
243 g_progressBar->SetProgressValue(0);
244 while (progressvalueTmp <= maxProgressValue) {
245 if (!(g_updateInfoLabel->IsVisiable()) || !(g_progressBar->IsVisiable()) ||
246 !(g_updateFrame->IsVisiable())) {
247 LOG(INFO) <<"is not visable in updater_frame";
248 }
249 usleep(sleepMs);
250 if (g_updateFlag == 1) {
251 progressvalueTmp = progressvalueTmp + progressValueStep;
252 g_progressBar->SetProgressValue(progressvalueTmp);
253 if (progressvalueTmp >= maxProgressValue) {
254 usleep(maxSleepMs);
255 return;
256 }
257 }
258 }
259 }
260
261 struct FocusInfo {
262 bool focus;
263 bool focusable;
264 };
265
266 struct Bold {
267 bool top;
268 bool bottom;
269 };
270
TextLabelInit(TextLabel * t,const std::string & text,struct Bold bold,struct FocusInfo focus,View::BRGA888Pixel color)271 static void TextLabelInit(TextLabel *t, const std::string &text, struct Bold bold,
272 struct FocusInfo focus, View::BRGA888Pixel color)
273 {
274 if (t != nullptr) {
275 t->SetText(text.c_str());
276 t->SetOutLineBold(bold.top, bold.bottom);
277 t->OnFocus(focus.focus);
278 t->SetBackgroundColor(&color);
279 t->SetFocusAble(focus.focusable);
280 }
281 }
282
InitDialogButton(int height,int width,View::BRGA888Pixel bgColor)283 static void InitDialogButton(int height, int width, View::BRGA888Pixel bgColor)
284 {
285 const int okStartY = 450;
286 const int cancelNextStartY = 451;
287 g_dialogOkBtn = new TextLabel(0, okStartY, width, DIALOG_OK_WIDTH, g_menuFrame);
288 g_dialogOkBtn->Hide();
289 struct FocusInfo info {false, false};
290 struct Bold bold {false, false};
291 g_dialogOkBtn->SetViewId(DIALOG_OK_ID);
292 info = {false, false};
293 bold = {false, false};
294 TextLabelInit(g_dialogOkBtn, "Continue", bold, info, bgColor);
295 if (!g_dialogOkBtn) {
296 LOG(ERROR) << "g_dialogOkBtn is null";
297 return;
298 }
299 g_dialogOkBtn->SetOnClickCallback(OnKeyEvent);
300
301 g_dialogCancalBtn = new TextLabel(DIALOG_CANCEL_X, cancelNextStartY, DIALOG_OK_WIDTH, DIALOG_OK_WIDTH, g_menuFrame);
302 g_dialogCancalBtn->Hide();
303 info = {false, false};
304 bold = {false, false};
305 TextLabelInit(g_dialogCancalBtn, "Cancel", bold, info, bgColor);
306 if (!g_dialogCancalBtn) {
307 LOG(ERROR) << "g_dialogCancalBtn is null";
308 return;
309 }
310 g_dialogCancalBtn->SetViewId(DIALOG_CANCEL_ID);
311 g_dialogCancalBtn->SetOnClickCallback(OnKeyEvent);
312 }
313
DialogInit(int height,int width)314 static void DialogInit(int height, int width)
315 {
316 if (g_menuFrame == nullptr) {
317 LOG(ERROR) << "Frame is null";
318 return;
319 }
320 const int titleHeight = 100;
321 const int titleStartX = 250;
322 const int noteStartY = 350;
323 const int noteNextStartY = 400;
324 View::BRGA888Pixel color;
325 color.r = DIALOG_COLOR;
326 color.g = DIALOG_COLOR;
327 color.b = DIALOG_COLOR;
328 color.a = DIALIG_COLOR_A;
329 g_dialogTitle = new TextLabel(0, titleStartX, width, titleHeight, g_menuFrame);
330 g_dialogTitle->SetTextAlignmentMethod(TextLabel::AlignmentMethod::ALIGN_CENTER,
331 TextLabel::AlignmentMethod::ALIGN_CENTER);
332 g_dialogTitle->Hide();
333 struct FocusInfo info {false, false};
334 struct Bold bold {false, false};
335 TextLabelInit(g_dialogTitle, "Tip", bold, info, color);
336 if (!g_dialogTitle) {
337 LOG(ERROR) << "g_dialogTitle is null";
338 return;
339 }
340
341 g_dialogNote = new TextLabel(0, noteStartY, width, HEIGHT4, g_menuFrame);
342 g_dialogNote->Hide();
343 info = {false, false};
344 bold = {false, false};
345 TextLabelInit(g_dialogNote, "Delete user date now...", bold, info, color);
346 if (!g_dialogNote) {
347 LOG(ERROR) << "g_dialogNote is null";
348 return;
349 }
350
351 g_dialogNoteNext = new TextLabel(0, noteNextStartY, width, HEIGHT4, g_menuFrame);
352 g_dialogNoteNext->Hide();
353 info = {false, false};
354 bold = {false, false};
355 TextLabelInit(g_dialogNoteNext, "Do you want to continue?", bold, info, color);
356 if (!g_dialogNoteNext) {
357 LOG(ERROR) << "g_dialogNoteNext is null";
358 return;
359 }
360 InitDialogButton(width, height, color);
361 }
362
MenuItemInit(int height,int width,View::BRGA888Pixel bgColor)363 static void MenuItemInit(int height, int width, View::BRGA888Pixel bgColor)
364 {
365 if (g_menuFrame == nullptr) {
366 LOG(ERROR) << "Frame is null";
367 return;
368 }
369 g_textLabel0 = new TextLabel(0, height * LABEL0_OFFSET / LABEL_HEIGHT, width, height /
370 LABEL_HEIGHT, g_menuFrame);
371 struct FocusInfo info {false, true};
372 struct Bold bold {true, false};
373 TextLabelInit(g_textLabel0, "Reboot to normal system", bold, info, bgColor);
374 if (!g_textLabel0) {
375 LOG(ERROR) << "g_textLabel0 is null";
376 return;
377 }
378 g_textLabel0->SetOnClickCallback(OnKeyEvent);
379 g_textLabelNum++;
380
381 g_textLabel2 = new TextLabel(0, height * LABEL1_OFFSET / LABEL_HEIGHT, width, height /
382 LABEL_HEIGHT, g_menuFrame);
383 info = {false, true};
384 bold = {false, false};
385 TextLabelInit(g_textLabel2, "Userdata reset", bold, info, bgColor);
386 if (!g_textLabel2) {
387 LOG(ERROR) << "g_textLabel2 is null";
388 return;
389 }
390 g_textLabel2->SetOnClickCallback(OnKeyEvent);
391 g_textLabelNum++;
392
393 g_textLabel3 = new TextLabel(0, height * LABEL2_OFFSET / LABEL_HEIGHT, width, height /
394 LABEL_HEIGHT, g_menuFrame);
395 info = {false, true};
396 bold = {false, true};
397 TextLabelInit(g_textLabel3, "Update from SD Card", bold, info, bgColor);
398 if (!g_textLabel3) {
399 LOG(ERROR) << "g_textLabel3 is null";
400 return;
401 }
402 g_textLabel3->SetOnClickCallback(OnKeyEvent);
403 g_textLabelNum++;
404 g_textLabel0->SetViewId(LABEL_ID_0);
405 g_textLabel2->SetViewId(LABEL_ID_1);
406 g_textLabel3->SetViewId(LABEL_ID_2);
407 }
408
UpdaterUiInit()409 void UpdaterUiInit()
410 {
411 constexpr char alpha = 0xff;
412 int screenH = 0;
413 int screenW = 0;
414 g_sfDev = new SurfaceDev(SurfaceDev::DevType::DRM_DEVICE);
415 g_sfDev->GetScreenSize(screenW, screenH);
416 View::BRGA888Pixel bgColor {0x00, 0x00, 0x00, alpha};
417
418 g_menuFrame = new Frame(screenW, screenH, View::PixelFormat::BGRA888, g_sfDev);
419 g_menuFrame->SetBackgroundColor(&bgColor);
420 g_menuFrame->Hide();
421
422 MenuItemInit(screenH, screenW, bgColor);
423 DialogInit(screenH, screenW);
424
425 g_logLabel = new TextLabel(START_X1, START_Y1, WIDTH1, HEIGHT1, g_menuFrame);
426 struct FocusInfo info {false, false};
427 struct Bold bold {false, false};
428 TextLabelInit(g_logLabel, "", bold, info, bgColor);
429
430 g_logResultLabel = new TextLabel(START_X2, START_Y2, WIDTH2, HEIGHT2, g_menuFrame);
431 TextLabelInit(g_logResultLabel, "", bold, info, bgColor);
432
433 g_updateFrame = new Frame(screenW, screenH, View::PixelFormat::BGRA888, g_sfDev);
434 g_updateFrame->SetBackgroundColor(&bgColor);
435 g_updateFrame->Hide();
436
437 g_anmimationLabel = new AnimationLable(START_X_SCALE, START_Y_SCALE,
438 screenW * WIDTH_SCALE1 / WIDTH_SCALE2, screenH / MEDIAN_NUMBER, g_updateFrame);
439 g_anmimationLabel->SetBackgroundColor(&bgColor);
440 LoadImgs();
441 g_progressBar = new ProgressBar(START_X3, START_Y3, WIDTH3, HEIGHT3, g_updateFrame);
442 g_progressBar->Hide();
443
444 g_updateInfoLabel = new TextLabel(START_X5, START_Y5, screenW, HEIGHT5, g_updateFrame);
445 g_updateInfoLabel->SetOutLineBold(false, false);
446 g_updateInfoLabel->SetBackgroundColor(&bgColor);
447 HdfInit();
448 }
449
DeleteOtherView()450 static void DeleteOtherView()
451 {
452 if (g_updateInfoLabel != nullptr) {
453 delete g_updateInfoLabel;
454 g_updateInfoLabel = nullptr;
455 }
456 if (g_anmimationLabel != nullptr) {
457 delete g_anmimationLabel;
458 g_anmimationLabel = nullptr;
459 }
460 if (g_progressBar != nullptr) {
461 delete g_progressBar;
462 g_progressBar = nullptr;
463 }
464 if (g_dialogTitle != nullptr) {
465 delete g_dialogTitle;
466 g_dialogTitle = nullptr;
467 }
468 if (g_dialogNote != nullptr) {
469 delete g_dialogNote;
470 g_dialogNote = nullptr;
471 }
472 if (g_dialogNoteNext != nullptr) {
473 delete g_dialogNoteNext;
474 g_dialogNoteNext = nullptr;
475 }
476 if (g_dialogCancalBtn != nullptr) {
477 delete g_dialogCancalBtn;
478 g_dialogCancalBtn = nullptr;
479 }
480 if (g_dialogOkBtn != nullptr) {
481 delete g_dialogOkBtn;
482 g_dialogOkBtn = nullptr;
483 }
484 if (g_logResultLabel != nullptr) {
485 delete g_logResultLabel;
486 g_logResultLabel = nullptr;
487 }
488 }
489
DeleteView()490 void DeleteView()
491 {
492 DeleteOtherView();
493 if (g_textLabel0 != nullptr) {
494 delete g_textLabel0;
495 g_textLabel0 = nullptr;
496 }
497 if (g_textLabel2 != nullptr) {
498 delete g_textLabel2;
499 g_textLabel2 = nullptr;
500 }
501 if (g_textLabel3 != nullptr) {
502 delete g_textLabel3;
503 g_textLabel3 = nullptr;
504 }
505 if (g_logLabel == nullptr) {
506 delete g_logLabel;
507 g_logLabel = nullptr;
508 }
509 if (g_updateFrame != nullptr) {
510 delete g_updateFrame;
511 g_updateFrame = nullptr;
512 }
513 if (g_menuFrame != nullptr) {
514 delete g_menuFrame;
515 g_menuFrame = nullptr;
516 }
517 if (g_sfDev != nullptr) {
518 delete g_sfDev;
519 g_sfDev = nullptr;
520 }
521 }
522
GetUpdateInfoLabel()523 TextLabel *GetUpdateInfoLabel()
524 {
525 return g_updateInfoLabel;
526 }
527
GetProgressBar()528 ProgressBar *GetProgressBar()
529 {
530 return g_progressBar;
531 }
532
SetUpdateFlag(int updateFlag)533 void SetUpdateFlag(int updateFlag)
534 {
535 g_updateFlag = updateFlag;
536 }
537 } // namespace updater
538