aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDoug Zongker2011-10-31 11:34:15 -0500
committerDoug Zongker2011-10-31 17:51:07 -0500
commitdaefc1d442fb421606680feb9aeb59c133f4c427 (patch)
tree71b64ebdd66540aca7a523c73a47626ca519d039 /recovery.cpp
parentb88aea8a89f9d3344022cdfe895397baac6c05e7 (diff)
downloadplatform-bootable-recovery-daefc1d442fb421606680feb9aeb59c133f4c427.tar.gz
platform-bootable-recovery-daefc1d442fb421606680feb9aeb59c133f4c427.tar.xz
platform-bootable-recovery-daefc1d442fb421606680feb9aeb59c133f4c427.zip
C++ class for device-specific code
Replace the device-specific functions with a class. Move some of the key handling (for log visibility toggling and rebooting) into the UI class. Fix up the key handling so there is less crosstalk between the immediate keys and the queued keys (an increasing annoyance on button-limited devices). Change-Id: I698f6fd21c67a1e55429312a0484b6c393cad46f
Diffstat (limited to 'recovery.cpp')
-rw-r--r--recovery.cpp70
1 files changed, 34 insertions, 36 deletions
diff --git a/recovery.cpp b/recovery.cpp
index d1af3ac0..d028cc91 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -37,9 +37,9 @@
37#include "minui/minui.h" 37#include "minui/minui.h"
38#include "minzip/DirUtil.h" 38#include "minzip/DirUtil.h"
39#include "roots.h" 39#include "roots.h"
40#include "recovery_ui.h"
41#include "ui.h" 40#include "ui.h"
42#include "screen_ui.h" 41#include "screen_ui.h"
42#include "device.h"
43 43
44static const struct option OPTIONS[] = { 44static const struct option OPTIONS[] = {
45 { "send_intent", required_argument, NULL, 's' }, 45 { "send_intent", required_argument, NULL, 's' },
@@ -401,7 +401,7 @@ copy_sideloaded_package(const char* original_path) {
401} 401}
402 402
403static const char** 403static const char**
404prepend_title(const char** headers) { 404prepend_title(const char* const* headers) {
405 const char* title[] = { "Android system recovery <" 405 const char* title[] = { "Android system recovery <"
406 EXPAND(RECOVERY_API_VERSION) "e>", 406 EXPAND(RECOVERY_API_VERSION) "e>",
407 "", 407 "",
@@ -410,7 +410,7 @@ prepend_title(const char** headers) {
410 // count the number of lines in our title, plus the 410 // count the number of lines in our title, plus the
411 // caller-provided headers. 411 // caller-provided headers.
412 int count = 0; 412 int count = 0;
413 const char** p; 413 const char* const* p;
414 for (p = title; *p; ++p, ++count); 414 for (p = title; *p; ++p, ++count);
415 for (p = headers; *p; ++p, ++count); 415 for (p = headers; *p; ++p, ++count);
416 416
@@ -425,7 +425,7 @@ prepend_title(const char** headers) {
425 425
426static int 426static int
427get_menu_selection(const char* const * headers, const char* const * items, 427get_menu_selection(const char* const * headers, const char* const * items,
428 int menu_only, int initial_selection) { 428 int menu_only, int initial_selection, Device* device) {
429 // throw away keys pressed previously, so user doesn't 429 // throw away keys pressed previously, so user doesn't
430 // accidentally trigger menu items. 430 // accidentally trigger menu items.
431 ui->FlushKeys(); 431 ui->FlushKeys();
@@ -444,26 +444,26 @@ get_menu_selection(const char* const * headers, const char* const * items,
444 } else { 444 } else {
445 LOGI("timed out waiting for key input; rebooting.\n"); 445 LOGI("timed out waiting for key input; rebooting.\n");
446 ui->EndMenu(); 446 ui->EndMenu();
447 return ITEM_REBOOT; 447 return 0; // XXX fixme
448 } 448 }
449 } 449 }
450 450
451 int action = device_handle_key(key, visible); 451 int action = device->HandleMenuKey(key, visible);
452 452
453 if (action < 0) { 453 if (action < 0) {
454 switch (action) { 454 switch (action) {
455 case HIGHLIGHT_UP: 455 case Device::kHighlightUp:
456 --selected; 456 --selected;
457 selected = ui->SelectMenu(selected); 457 selected = ui->SelectMenu(selected);
458 break; 458 break;
459 case HIGHLIGHT_DOWN: 459 case Device::kHighlightDown:
460 ++selected; 460 ++selected;
461 selected = ui->SelectMenu(selected); 461 selected = ui->SelectMenu(selected);
462 break; 462 break;
463 case SELECT_ITEM: 463 case Device::kInvokeItem:
464 chosen_item = selected; 464 chosen_item = selected;
465 break; 465 break;
466 case NO_ACTION: 466 case Device::kNoAction:
467 break; 467 break;
468 } 468 }
469 } else if (!menu_only) { 469 } else if (!menu_only) {
@@ -481,7 +481,7 @@ static int compare_string(const void* a, const void* b) {
481 481
482static int 482static int
483update_directory(const char* path, const char* unmount_when_done, 483update_directory(const char* path, const char* unmount_when_done,
484 int* wipe_cache) { 484 int* wipe_cache, Device* device) {
485 ensure_path_mounted(path); 485 ensure_path_mounted(path);
486 486
487 const char* MENU_HEADERS[] = { "Choose a package to install:", 487 const char* MENU_HEADERS[] = { "Choose a package to install:",
@@ -555,7 +555,7 @@ update_directory(const char* path, const char* unmount_when_done,
555 int result; 555 int result;
556 int chosen_item = 0; 556 int chosen_item = 0;
557 do { 557 do {
558 chosen_item = get_menu_selection(headers, zips, 1, chosen_item); 558 chosen_item = get_menu_selection(headers, zips, 1, chosen_item, device);
559 559
560 char* item = zips[chosen_item]; 560 char* item = zips[chosen_item];
561 int item_len = strlen(item); 561 int item_len = strlen(item);
@@ -570,7 +570,7 @@ update_directory(const char* path, const char* unmount_when_done,
570 strlcat(new_path, "/", PATH_MAX); 570 strlcat(new_path, "/", PATH_MAX);
571 strlcat(new_path, item, PATH_MAX); 571 strlcat(new_path, item, PATH_MAX);
572 new_path[strlen(new_path)-1] = '\0'; // truncate the trailing '/' 572 new_path[strlen(new_path)-1] = '\0'; // truncate the trailing '/'
573 result = update_directory(new_path, unmount_when_done, wipe_cache); 573 result = update_directory(new_path, unmount_when_done, wipe_cache, device);
574 if (result >= 0) break; 574 if (result >= 0) break;
575 } else { 575 } else {
576 // selected a zip file: attempt to install it, and return 576 // selected a zip file: attempt to install it, and return
@@ -608,7 +608,7 @@ update_directory(const char* path, const char* unmount_when_done,
608} 608}
609 609
610static void 610static void
611wipe_data(int confirm) { 611wipe_data(int confirm, Device* device) {
612 if (confirm) { 612 if (confirm) {
613 static const char** title_headers = NULL; 613 static const char** title_headers = NULL;
614 614
@@ -633,54 +633,54 @@ wipe_data(int confirm) {
633 " No", 633 " No",
634 NULL }; 634 NULL };
635 635
636 int chosen_item = get_menu_selection(title_headers, items, 1, 0); 636 int chosen_item = get_menu_selection(title_headers, items, 1, 0, device);
637 if (chosen_item != 7) { 637 if (chosen_item != 7) {
638 return; 638 return;
639 } 639 }
640 } 640 }
641 641
642 ui->Print("\n-- Wiping data...\n"); 642 ui->Print("\n-- Wiping data...\n");
643 device_wipe_data(); 643 device->WipeData();
644 erase_volume("/data"); 644 erase_volume("/data");
645 erase_volume("/cache"); 645 erase_volume("/cache");
646 ui->Print("Data wipe complete.\n"); 646 ui->Print("Data wipe complete.\n");
647} 647}
648 648
649static void 649static void
650prompt_and_wait() { 650prompt_and_wait(Device* device) {
651 const char** headers = prepend_title((const char**)MENU_HEADERS); 651 const char* const* headers = prepend_title(device->GetMenuHeaders());
652 652
653 for (;;) { 653 for (;;) {
654 finish_recovery(NULL); 654 finish_recovery(NULL);
655 ui->SetProgressType(RecoveryUI::EMPTY); 655 ui->SetProgressType(RecoveryUI::EMPTY);
656 656
657 int chosen_item = get_menu_selection(headers, MENU_ITEMS, 0, 0); 657 int chosen_item = get_menu_selection(headers, device->GetMenuItems(), 0, 0, device);
658 658
659 // device-specific code may take some action here. It may 659 // device-specific code may take some action here. It may
660 // return one of the core actions handled in the switch 660 // return one of the core actions handled in the switch
661 // statement below. 661 // statement below.
662 chosen_item = device_perform_action(chosen_item); 662 chosen_item = device->InvokeMenuItem(chosen_item);
663 663
664 int status; 664 int status;
665 int wipe_cache; 665 int wipe_cache;
666 switch (chosen_item) { 666 switch (chosen_item) {
667 case ITEM_REBOOT: 667 case Device::REBOOT:
668 return; 668 return;
669 669
670 case ITEM_WIPE_DATA: 670 case Device::WIPE_DATA:
671 wipe_data(ui->IsTextVisible()); 671 wipe_data(ui->IsTextVisible(), device);
672 if (!ui->IsTextVisible()) return; 672 if (!ui->IsTextVisible()) return;
673 break; 673 break;
674 674
675 case ITEM_WIPE_CACHE: 675 case Device::WIPE_CACHE:
676 ui->Print("\n-- Wiping cache...\n"); 676 ui->Print("\n-- Wiping cache...\n");
677 erase_volume("/cache"); 677 erase_volume("/cache");
678 ui->Print("Cache wipe complete.\n"); 678 ui->Print("Cache wipe complete.\n");
679 if (!ui->IsTextVisible()) return; 679 if (!ui->IsTextVisible()) return;
680 break; 680 break;
681 681
682 case ITEM_APPLY_SDCARD: 682 case Device::APPLY_EXT:
683 status = update_directory(SDCARD_ROOT, SDCARD_ROOT, &wipe_cache); 683 status = update_directory(SDCARD_ROOT, SDCARD_ROOT, &wipe_cache, device);
684 if (status == INSTALL_SUCCESS && wipe_cache) { 684 if (status == INSTALL_SUCCESS && wipe_cache) {
685 ui->Print("\n-- Wiping cache (at package request)...\n"); 685 ui->Print("\n-- Wiping cache (at package request)...\n");
686 if (erase_volume("/cache")) { 686 if (erase_volume("/cache")) {
@@ -700,9 +700,10 @@ prompt_and_wait() {
700 } 700 }
701 } 701 }
702 break; 702 break;
703 case ITEM_APPLY_CACHE: 703
704 case Device::APPLY_CACHE:
704 // Don't unmount cache at the end of this. 705 // Don't unmount cache at the end of this.
705 status = update_directory(CACHE_ROOT, NULL, &wipe_cache); 706 status = update_directory(CACHE_ROOT, NULL, &wipe_cache, device);
706 if (status == INSTALL_SUCCESS && wipe_cache) { 707 if (status == INSTALL_SUCCESS && wipe_cache) {
707 ui->Print("\n-- Wiping cache (at package request)...\n"); 708 ui->Print("\n-- Wiping cache (at package request)...\n");
708 if (erase_volume("/cache")) { 709 if (erase_volume("/cache")) {
@@ -722,7 +723,6 @@ prompt_and_wait() {
722 } 723 }
723 } 724 }
724 break; 725 break;
725
726 } 726 }
727 } 727 }
728} 728}
@@ -741,10 +741,8 @@ main(int argc, char **argv) {
741 freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL); 741 freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL);
742 printf("Starting recovery on %s", ctime(&start)); 742 printf("Starting recovery on %s", ctime(&start));
743 743
744 // TODO: device_* should be a C++ class; init should return the 744 Device* device = make_device();
745 // appropriate UI for the device. 745 ui = device->GetUI();
746 device_ui_init(&ui_parameters);
747 ui = new ScreenRecoveryUI();
748 746
749 ui->Init(); 747 ui->Init();
750 ui->SetBackground(RecoveryUI::INSTALLING); 748 ui->SetBackground(RecoveryUI::INSTALLING);
@@ -771,7 +769,7 @@ main(int argc, char **argv) {
771 } 769 }
772 } 770 }
773 771
774 device_recovery_start(); 772 device->StartRecovery();
775 773
776 printf("Command:"); 774 printf("Command:");
777 for (arg = 0; arg < argc; arg++) { 775 for (arg = 0; arg < argc; arg++) {
@@ -809,7 +807,7 @@ main(int argc, char **argv) {
809 } 807 }
810 if (status != INSTALL_SUCCESS) ui->Print("Installation aborted.\n"); 808 if (status != INSTALL_SUCCESS) ui->Print("Installation aborted.\n");
811 } else if (wipe_data) { 809 } else if (wipe_data) {
812 if (device_wipe_data()) status = INSTALL_ERROR; 810 if (device->WipeData()) status = INSTALL_ERROR;
813 if (erase_volume("/data")) status = INSTALL_ERROR; 811 if (erase_volume("/data")) status = INSTALL_ERROR;
814 if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; 812 if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
815 if (status != INSTALL_SUCCESS) ui->Print("Data wipe failed.\n"); 813 if (status != INSTALL_SUCCESS) ui->Print("Data wipe failed.\n");
@@ -822,7 +820,7 @@ main(int argc, char **argv) {
822 820
823 if (status != INSTALL_SUCCESS) ui->SetBackground(RecoveryUI::ERROR); 821 if (status != INSTALL_SUCCESS) ui->SetBackground(RecoveryUI::ERROR);
824 if (status != INSTALL_SUCCESS || ui->IsTextVisible()) { 822 if (status != INSTALL_SUCCESS || ui->IsTextVisible()) {
825 prompt_and_wait(); 823 prompt_and_wait(device);
826 } 824 }
827 825
828 // Otherwise, get ready to boot the main system... 826 // Otherwise, get ready to boot the main system...