diff options
-rw-r--r-- | Android.mk | 4 | ||||
-rw-r--r-- | device.cpp | 54 | ||||
-rw-r--r-- | recovery.cpp | 92 | ||||
-rw-r--r-- | tools/recovery_l10n/res/values-b+sr+Latn/strings.xml | 8 | ||||
-rw-r--r-- | tools/recovery_l10n/res/values-be-rBY/strings.xml | 8 | ||||
-rw-r--r-- | tools/recovery_l10n/res/values-bs-rBA/strings.xml | 8 |
6 files changed, 147 insertions, 27 deletions
diff --git a/Android.mk b/Android.mk index 65d123a86..9a064f236 100644 --- a/Android.mk +++ b/Android.mk @@ -93,6 +93,10 @@ ifeq ($(TARGET_USERIMAGES_USE_EXT4), true) LOCAL_STATIC_LIBRARIES += libext4_utils_static libz endif +ifeq ($(AB_OTA_UPDATER),true) + LOCAL_CFLAGS += -DAB_OTA_UPDATER=1 +endif + LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin ifeq ($(TARGET_RECOVERY_UI_LIB),) diff --git a/device.cpp b/device.cpp index 2465b0778..f8fbb8a49 100644 --- a/device.cpp +++ b/device.cpp @@ -16,6 +16,29 @@ #include "device.h" +#if defined(AB_OTA_UPDATER) + +static const char* MENU_ITEMS[] = { + "Reboot system now", + "Reboot to bootloader", + "Wipe data/factory reset", + "Mount /system", + "Run graphics test", + "Power off", + NULL, +}; + +static const Device::BuiltinAction MENU_ACTIONS[] = { + Device::REBOOT, + Device::REBOOT_BOOTLOADER, + Device::WIPE_DATA, + Device::MOUNT_SYSTEM, + Device::RUN_GRAPHICS_TEST, + Device::SHUTDOWN, +}; + +#else + static const char* MENU_ITEMS[] = { "Reboot system now", "Reboot to bootloader", @@ -27,27 +50,30 @@ static const char* MENU_ITEMS[] = { "View recovery logs", "Run graphics test", "Power off", - NULL + NULL, }; +static const Device::BuiltinAction MENU_ACTIONS[] = { + Device::REBOOT, + Device::REBOOT_BOOTLOADER, + Device::APPLY_ADB_SIDELOAD, + Device::APPLY_SDCARD, + Device::WIPE_DATA, + Device::WIPE_CACHE, + Device::MOUNT_SYSTEM, + Device::VIEW_RECOVERY_LOGS, + Device::RUN_GRAPHICS_TEST, + Device::SHUTDOWN, +}; + +#endif + const char* const* Device::GetMenuItems() { return MENU_ITEMS; } Device::BuiltinAction Device::InvokeMenuItem(int menu_position) { - switch (menu_position) { - case 0: return REBOOT; - case 1: return REBOOT_BOOTLOADER; - case 2: return APPLY_ADB_SIDELOAD; - case 3: return APPLY_SDCARD; - case 4: return WIPE_DATA; - case 5: return WIPE_CACHE; - case 6: return MOUNT_SYSTEM; - case 7: return VIEW_RECOVERY_LOGS; - case 8: return RUN_GRAPHICS_TEST; - case 9: return SHUTDOWN; - default: return NO_ACTION; - } + return menu_position < 0 ? NO_ACTION : MENU_ACTIONS[menu_position]; } int Device::HandleMenuKey(int key, int visible) { diff --git a/recovery.cpp b/recovery.cpp index 6b6643fab..65e1a7bba 100644 --- a/recovery.cpp +++ b/recovery.cpp @@ -19,7 +19,9 @@ #include <errno.h> #include <fcntl.h> #include <getopt.h> +#include <inttypes.h> #include <limits.h> +#include <linux/fs.h> #include <linux/input.h> #include <stdarg.h> #include <stdio.h> @@ -33,12 +35,15 @@ #include <unistd.h> #include <chrono> +#include <string> +#include <vector> #include <adb.h> #include <android/log.h> /* Android Log Priority Tags */ #include <android-base/file.h> #include <android-base/parseint.h> #include <android-base/stringprintf.h> +#include <android-base/strings.h> #include <cutils/android_reboot.h> #include <cutils/properties.h> #include <log/logger.h> /* Android Log packet format */ @@ -58,6 +63,7 @@ #include "minzip/DirUtil.h" #include "roots.h" #include "ui.h" +#include "unique_fd.h" #include "screen_ui.h" struct selabel_handle *sehandle; @@ -77,6 +83,7 @@ static const struct option OPTIONS[] = { { "shutdown_after", no_argument, NULL, 'p' }, { "reason", required_argument, NULL, 'r' }, { "security", no_argument, NULL, 'e'}, + { "wipe_ab", no_argument, NULL, 0 }, { NULL, 0, NULL, 0 }, }; @@ -103,6 +110,7 @@ static const int BATTERY_READ_TIMEOUT_IN_SEC = 10; // So we should check battery with a slightly lower limitation. static const int BATTERY_OK_PERCENTAGE = 20; static const int BATTERY_WITH_CHARGER_OK_PERCENTAGE = 15; +constexpr const char* RECOVERY_WIPE = "/etc/recovery.wipe"; RecoveryUI* ui = NULL; static const char* locale = "en_US"; @@ -853,6 +861,75 @@ static bool wipe_cache(bool should_confirm, Device* device) { return success; } +// Secure-wipe a given partition. It uses BLKSECDISCARD, if supported. +// Otherwise, it goes with BLKDISCARD (if device supports BLKDISCARDZEROES) or +// BLKZEROOUT. +static bool secure_wipe_partition(const std::string& partition) { + unique_fd fd(TEMP_FAILURE_RETRY(open(partition.c_str(), O_WRONLY))); + if (fd.get() == -1) { + LOGE("failed to open \"%s\": %s\n", partition.c_str(), strerror(errno)); + return false; + } + + uint64_t range[2] = {0, 0}; + if (ioctl(fd.get(), BLKGETSIZE64, &range[1]) == -1 || range[1] == 0) { + LOGE("failed to get partition size: %s\n", strerror(errno)); + return false; + } + printf("Secure-wiping \"%s\" from %" PRIu64 " to %" PRIu64 ".\n", + partition.c_str(), range[0], range[1]); + + printf("Trying BLKSECDISCARD...\t"); + if (ioctl(fd.get(), BLKSECDISCARD, &range) == -1) { + printf("failed: %s\n", strerror(errno)); + + // Use BLKDISCARD if it zeroes out blocks, otherwise use BLKZEROOUT. + unsigned int zeroes; + if (ioctl(fd.get(), BLKDISCARDZEROES, &zeroes) == 0 && zeroes != 0) { + printf("Trying BLKDISCARD...\t"); + if (ioctl(fd.get(), BLKDISCARD, &range) == -1) { + printf("failed: %s\n", strerror(errno)); + return false; + } + } else { + printf("Trying BLKZEROOUT...\t"); + if (ioctl(fd.get(), BLKZEROOUT, &range) == -1) { + printf("failed: %s\n", strerror(errno)); + return false; + } + } + } + + printf("done\n"); + return true; +} + +// Wipe the current A/B device, with a secure wipe of all the partitions in +// RECOVERY_WIPE. +static bool wipe_ab_device() { + ui->SetBackground(RecoveryUI::ERASING); + ui->SetProgressType(RecoveryUI::INDETERMINATE); + + std::string partition_list; + if (!android::base::ReadFileToString(RECOVERY_WIPE, &partition_list)) { + LOGE("failed to read \"%s\".\n", RECOVERY_WIPE); + return false; + } + + std::vector<std::string> lines = android::base::Split(partition_list, "\n"); + for (const std::string& line : lines) { + std::string partition = android::base::Trim(line); + // Ignore '#' comment or empty lines. + if (android::base::StartsWith(partition, "#") || partition.empty()) { + continue; + } + + // Proceed anyway even if it fails to wipe some partition. + secure_wipe_partition(partition); + } + return true; +} + static void choose_recovery_file(Device* device) { if (!has_cache) { ui->Print("No /cache partition found.\n"); @@ -1340,6 +1417,7 @@ int main(int argc, char **argv) { const char *update_package = NULL; bool should_wipe_data = false; bool should_wipe_cache = false; + bool should_wipe_ab = false; bool show_text = false; bool sideload = false; bool sideload_auto_reboot = false; @@ -1349,7 +1427,8 @@ int main(int argc, char **argv) { bool security_update = false; int arg; - while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) { + int option_index; + while ((arg = getopt_long(argc, argv, "", OPTIONS, &option_index)) != -1) { switch (arg) { case 'i': send_intent = optarg; break; case 'n': android::base::ParseInt(optarg, &retry_count, 0); break; @@ -1372,6 +1451,13 @@ int main(int argc, char **argv) { case 'p': shutdown_after = true; break; case 'r': reason = optarg; break; case 'e': security_update = true; break; + case 0: { + if (strcmp(OPTIONS[option_index].name, "wipe_ab") == 0) { + should_wipe_ab = true; + break; + } + break; + } case '?': LOGE("Invalid command argument\n"); continue; @@ -1510,6 +1596,10 @@ int main(int argc, char **argv) { if (!wipe_cache(false, device)) { status = INSTALL_ERROR; } + } else if (should_wipe_ab) { + if (!wipe_ab_device()) { + status = INSTALL_ERROR; + } } else if (sideload) { // 'adb reboot sideload' acts the same as user presses key combinations // to enter the sideload mode. When 'sideload-auto-reboot' is used, text diff --git a/tools/recovery_l10n/res/values-b+sr+Latn/strings.xml b/tools/recovery_l10n/res/values-b+sr+Latn/strings.xml index c2d8f2239..6f433e39d 100644 --- a/tools/recovery_l10n/res/values-b+sr+Latn/strings.xml +++ b/tools/recovery_l10n/res/values-b+sr+Latn/strings.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="recovery_installing" msgid="2013591905463558223">"Ažuriranje sistema se instalira"</string> - <string name="recovery_erasing" msgid="7334826894904037088">"Briše se"</string> - <string name="recovery_no_command" msgid="4465476568623024327">"Nema komande"</string> + <string name="recovery_installing" msgid="4995089002339765600">"Instaliranje ažuriranja sistema..."</string> + <string name="recovery_erasing" msgid="3454811999717520920">"Brisanje..."</string> + <string name="recovery_no_command" msgid="3005798864326873414">"Nema komande."</string> <string name="recovery_error" msgid="5748178989622716736">"Greška!"</string> - <string name="recovery_installing_security" msgid="9184031299717114342">"Instalira se bezbednosno ažuriranje"</string> + <string name="recovery_installing_security" msgid="241961948312007086">"Instalira se bezbednosno ažuriranje…"</string> </resources> diff --git a/tools/recovery_l10n/res/values-be-rBY/strings.xml b/tools/recovery_l10n/res/values-be-rBY/strings.xml index 7c0954d31..5decf8130 100644 --- a/tools/recovery_l10n/res/values-be-rBY/strings.xml +++ b/tools/recovery_l10n/res/values-be-rBY/strings.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="recovery_installing" msgid="2013591905463558223">"Усталёўка абнаўлення сістэмы"</string> - <string name="recovery_erasing" msgid="7334826894904037088">"Сціранне"</string> - <string name="recovery_no_command" msgid="4465476568623024327">"Няма каманды"</string> + <string name="recovery_installing" msgid="4995089002339765600">"Усталёўка абнаўлення сістэмы..."</string> + <string name="recovery_erasing" msgid="3454811999717520920">"Выдаленне..."</string> + <string name="recovery_no_command" msgid="3005798864326873414">"Няма каманды"</string> <string name="recovery_error" msgid="5748178989622716736">"Памылка"</string> - <string name="recovery_installing_security" msgid="9184031299717114342">"Усталёўка абнаўлення сістэмы бяспекі"</string> + <string name="recovery_installing_security" msgid="241961948312007086">"Усталёўка абнаўлення сістэмы бяспекі..."</string> </resources> diff --git a/tools/recovery_l10n/res/values-bs-rBA/strings.xml b/tools/recovery_l10n/res/values-bs-rBA/strings.xml index 412cf0276..8b6202a1e 100644 --- a/tools/recovery_l10n/res/values-bs-rBA/strings.xml +++ b/tools/recovery_l10n/res/values-bs-rBA/strings.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="recovery_installing" msgid="2013591905463558223">"Ažuriranje sistema…"</string> - <string name="recovery_erasing" msgid="7334826894904037088">"Brisanje u toku"</string> - <string name="recovery_no_command" msgid="4465476568623024327">"Nema komande"</string> + <string name="recovery_installing" msgid="4995089002339765600">"Sistem se ažurira…"</string> + <string name="recovery_erasing" msgid="3454811999717520920">"Briše se…"</string> + <string name="recovery_no_command" msgid="3005798864326873414">"Nema komande."</string> <string name="recovery_error" msgid="5748178989622716736">"Greška!"</string> - <string name="recovery_installing_security" msgid="9184031299717114342">"Instaliranje sigurnosnog ažuriranja…"</string> + <string name="recovery_installing_security" msgid="241961948312007086">"Instaliranje sigurnosnog ažuriranja…"</string> </resources> |