Merge "always use volume mount option when mounting a partition"
diff --git a/adb_install.cpp b/adb_install.cpp
index e328960..6d6dbb1 100644
--- a/adb_install.cpp
+++ b/adb_install.cpp
@@ -73,7 +73,7 @@
 #define ADB_INSTALL_TIMEOUT 300
 
 int
-apply_from_adb(RecoveryUI* ui_, int* wipe_cache, const char* install_file) {
+apply_from_adb(RecoveryUI* ui_, bool* wipe_cache, const char* install_file) {
     ui = ui_;
 
     stop_adbd();
diff --git a/adb_install.h b/adb_install.h
index a18b712..efad436 100644
--- a/adb_install.h
+++ b/adb_install.h
@@ -19,6 +19,6 @@
 
 class RecoveryUI;
 
-int apply_from_adb(RecoveryUI* h, int* wipe_cache, const char* install_file);
+int apply_from_adb(RecoveryUI* h, bool* wipe_cache, const char* install_file);
 
 #endif
diff --git a/install.cpp b/install.cpp
index 31606bb..63b1d38 100644
--- a/install.cpp
+++ b/install.cpp
@@ -48,7 +48,7 @@
 
 // If the package contains an update binary, extract it and run it.
 static int
-try_update_binary(const char *path, ZipArchive *zip, int* wipe_cache) {
+try_update_binary(const char* path, ZipArchive* zip, bool* wipe_cache) {
     const ZipEntry* binary_entry =
             mzFindZipEntry(zip, ASSUMED_UPDATE_BINARY_NAME);
     if (binary_entry == NULL) {
@@ -129,7 +129,7 @@
     }
     close(pipefd[1]);
 
-    *wipe_cache = 0;
+    *wipe_cache = false;
 
     char buffer[1024];
     FILE* from_child = fdopen(pipefd[0], "r");
@@ -158,7 +158,7 @@
             }
             fflush(stdout);
         } else if (strcmp(command, "wipe_cache") == 0) {
-            *wipe_cache = 1;
+            *wipe_cache = true;
         } else if (strcmp(command, "clear_display") == 0) {
             ui->SetBackground(RecoveryUI::NONE);
         } else if (strcmp(command, "enable_reboot") == 0) {
@@ -183,7 +183,7 @@
 }
 
 static int
-really_install_package(const char *path, int* wipe_cache, bool needs_mount)
+really_install_package(const char *path, bool* wipe_cache, bool needs_mount)
 {
     ui->SetBackground(RecoveryUI::INSTALLING_UPDATE);
     ui->Print("Finding update package...\n");
@@ -253,7 +253,7 @@
 }
 
 int
-install_package(const char* path, int* wipe_cache, const char* install_file,
+install_package(const char* path, bool* wipe_cache, const char* install_file,
                 bool needs_mount)
 {
     FILE* install_log = fopen_path(install_file, "w");
diff --git a/install.h b/install.h
index 53c0d31..680499d 100644
--- a/install.h
+++ b/install.h
@@ -27,7 +27,7 @@
 // Install the package specified by root_path.  If INSTALL_SUCCESS is
 // returned and *wipe_cache is true on exit, caller should wipe the
 // cache partition.
-int install_package(const char *root_path, int* wipe_cache,
+int install_package(const char* root_path, bool* wipe_cache,
                     const char* install_file, bool needs_mount);
 
 #ifdef __cplusplus
diff --git a/minui/Android.mk b/minui/Android.mk
index 9b2e09b..53d072f 100644
--- a/minui/Android.mk
+++ b/minui/Android.mk
@@ -1,14 +1,15 @@
 LOCAL_PATH := $(call my-dir)
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES := graphics.c graphics_adf.c graphics_fbdev.c events.c \
-	resources.c
+LOCAL_SRC_FILES := graphics.c graphics_adf.c graphics_fbdev.c events.c resources.c
 
 LOCAL_WHOLE_STATIC_LIBRARIES += libadf
 LOCAL_STATIC_LIBRARIES += libpng
 
 LOCAL_MODULE := libminui
 
+LOCAL_CFLAGS := -std=gnu11
+
 # This used to compare against values in double-quotes (which are just
 # ordinary characters in this context).  Strip double-quotes from the
 # value so that either will work.
diff --git a/minui/graphics.c b/minui/graphics.c
index 870ffa0..9d1e1b4 100644
--- a/minui/graphics.c
+++ b/minui/graphics.c
@@ -48,8 +48,6 @@
 static int overscan_offset_x = 0;
 static int overscan_offset_y = 0;
 
-static int gr_vt_fd = -1;
-
 static unsigned char gr_current_r = 255;
 static unsigned char gr_current_g = 255;
 static unsigned char gr_current_b = 255;
@@ -77,11 +75,10 @@
                        unsigned char* dst_p, int dst_row_bytes,
                        int width, int height)
 {
-    int i, j;
-    for (j = 0; j < height; ++j) {
+    for (int j = 0; j < height; ++j) {
         unsigned char* sx = src_p;
         unsigned char* px = dst_p;
-        for (i = 0; i < width; ++i) {
+        for (int i = 0; i < width; ++i) {
             unsigned char a = *sx++;
             if (gr_current_a < 255) a = ((int)a * gr_current_a) / 255;
             if (a == 255) {
@@ -106,34 +103,33 @@
     }
 }
 
-
 void gr_text(int x, int y, const char *s, int bold)
 {
-    GRFont *font = gr_font;
-    unsigned off;
+    GRFont* font = gr_font;
 
-    if (!font->texture) return;
-    if (gr_current_a == 0) return;
+    if (!font->texture || gr_current_a == 0) return;
 
     bold = bold && (font->texture->height != font->cheight);
 
     x += overscan_offset_x;
     y += overscan_offset_y;
 
-    while((off = *s++)) {
-        off -= 32;
+    unsigned char ch;
+    while ((ch = *s++)) {
         if (outside(x, y) || outside(x+font->cwidth-1, y+font->cheight-1)) break;
-        if (off < 96) {
 
-            unsigned char* src_p = font->texture->data + (off * font->cwidth) +
-                (bold ? font->cheight * font->texture->row_bytes : 0);
-            unsigned char* dst_p = gr_draw->data + y*gr_draw->row_bytes + x*gr_draw->pixel_bytes;
-
-            text_blend(src_p, font->texture->row_bytes,
-                       dst_p, gr_draw->row_bytes,
-                       font->cwidth, font->cheight);
-
+        if (ch < ' ' || ch > '~') {
+            ch = '?';
         }
+
+        unsigned char* src_p = font->texture->data + ((ch - ' ') * font->cwidth) +
+                               (bold ? font->cheight * font->texture->row_bytes : 0);
+        unsigned char* dst_p = gr_draw->data + y*gr_draw->row_bytes + x*gr_draw->pixel_bytes;
+
+        text_blend(src_p, font->texture->row_bytes,
+                   dst_p, gr_draw->row_bytes,
+                   font->cwidth, font->cheight);
+
         x += font->cwidth;
     }
 }
@@ -176,14 +172,12 @@
 
 void gr_clear()
 {
-    if (gr_current_r == gr_current_g &&
-        gr_current_r == gr_current_b) {
+    if (gr_current_r == gr_current_g && gr_current_r == gr_current_b) {
         memset(gr_draw->data, gr_current_r, gr_draw->height * gr_draw->row_bytes);
     } else {
-        int x, y;
         unsigned char* px = gr_draw->data;
-        for (y = 0; y < gr_draw->height; ++y) {
-            for (x = 0; x < gr_draw->width; ++x) {
+        for (int y = 0; y < gr_draw->height; ++y) {
+            for (int x = 0; x < gr_draw->width; ++x) {
                 *px++ = gr_current_r;
                 *px++ = gr_current_g;
                 *px++ = gr_current_b;
@@ -366,17 +360,6 @@
 {
     gr_init_font();
 
-    gr_vt_fd = open("/dev/tty0", O_RDWR | O_SYNC);
-    if (gr_vt_fd < 0) {
-        // This is non-fatal; post-Cupcake kernels don't have tty0.
-        perror("can't open /dev/tty0");
-    } else if (ioctl(gr_vt_fd, KDSETMODE, (void*) KD_GRAPHICS)) {
-        // However, if we do open tty0, we expect the ioctl to work.
-        perror("failed KDSETMODE to KD_GRAPHICS on tty0");
-        gr_exit();
-        return -1;
-    }
-
     gr_backend = open_adf();
     if (gr_backend) {
         gr_draw = gr_backend->init(gr_backend);
@@ -405,10 +388,6 @@
 void gr_exit(void)
 {
     gr_backend->exit(gr_backend);
-
-    ioctl(gr_vt_fd, KDSETMODE, (void*) KD_TEXT);
-    close(gr_vt_fd);
-    gr_vt_fd = -1;
 }
 
 int gr_fb_width(void)
diff --git a/recovery.cpp b/recovery.cpp
index 641f36f..0ba4d1e 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -52,11 +52,13 @@
 struct selabel_handle *sehandle;
 
 static const struct option OPTIONS[] = {
-  { "send_intent", required_argument, NULL, 's' },
+  { "send_intent", required_argument, NULL, 'i' },
   { "update_package", required_argument, NULL, 'u' },
   { "wipe_data", no_argument, NULL, 'w' },
   { "wipe_cache", no_argument, NULL, 'c' },
   { "show_text", no_argument, NULL, 't' },
+  { "sideload", no_argument, NULL, 's' },
+  { "sideload_auto_reboot", no_argument, NULL, 'a' },
   { "just_exit", no_argument, NULL, 'x' },
   { "locale", required_argument, NULL, 'l' },
   { "stages", required_argument, NULL, 'g' },
@@ -502,8 +504,7 @@
     return result;
 }
 
-static const char**
-prepend_title(const char* const* headers) {
+static const char** prepend_title(const char* const* headers) {
     // count the number of lines in our title, plus the
     // caller-provided headers.
     int count = 3;   // our title has 3 lines
@@ -578,24 +579,15 @@
 }
 
 // Returns a malloc'd path, or NULL.
-static char*
-browse_directory(const char* path, Device* device) {
+static char* browse_directory(const char* path, Device* device) {
     ensure_path_mounted(path);
 
-    const char* MENU_HEADERS[] = { "Choose a package to install:",
-                                   path,
-                                   "",
-                                   NULL };
-    DIR* d;
-    struct dirent* de;
-    d = opendir(path);
+    DIR* d = opendir(path);
     if (d == NULL) {
         LOGE("error opening %s: %s\n", path, strerror(errno));
         return NULL;
     }
 
-    const char** headers = prepend_title(MENU_HEADERS);
-
     int d_size = 0;
     int d_alloc = 10;
     char** dirs = (char**)malloc(d_alloc * sizeof(char*));
@@ -604,6 +596,7 @@
     char** zips = (char**)malloc(z_alloc * sizeof(char*));
     zips[0] = strdup("../");
 
+    struct dirent* de;
     while ((de = readdir(d)) != NULL) {
         int name_len = strlen(de->d_name);
 
@@ -647,6 +640,8 @@
     z_size += d_size;
     zips[z_size] = NULL;
 
+    const char* headers[] = { "Choose a package to install:", path, "", NULL };
+
     char* result;
     int chosen_item = 0;
     while (true) {
@@ -677,52 +672,50 @@
         }
     }
 
-    int i;
-    for (i = 0; i < z_size; ++i) free(zips[i]);
+    for (int i = 0; i < z_size; ++i) free(zips[i]);
     free(zips);
-    free(headers);
 
     return result;
 }
 
-static void
-wipe_data(int confirm, Device* device) {
-    if (confirm) {
-        static const char** title_headers = NULL;
+static bool yes_no(Device* device, const char* question1, const char* question2) {
+    const char* headers[] = { question1, question2, "", NULL };
+    const char* items[] = { " No", " Yes", NULL };
 
-        if (title_headers == NULL) {
-            const char* headers[] = { "Confirm wipe of all user data?",
-                                      "  THIS CAN NOT BE UNDONE.",
-                                      "",
-                                      NULL };
-            title_headers = prepend_title((const char**)headers);
-        }
+    int chosen_item = get_menu_selection(headers, items, 1, 0, device);
+    return (chosen_item == 1);
+}
 
-        const char* items[] = { " No",
-                                " No",
-                                " No",
-                                " No",
-                                " No",
-                                " No",
-                                " No",
-                                " Yes -- delete all user data",   // [7]
-                                " No",
-                                " No",
-                                " No",
-                                NULL };
-
-        int chosen_item = get_menu_selection(title_headers, items, 1, 0, device);
-        if (chosen_item != 7) {
-            return;
-        }
+// Return true on success.
+static bool wipe_data(int should_confirm, Device* device) {
+    if (should_confirm && !yes_no(device, "Wipe all user data?", "  THIS CAN NOT BE UNDONE!")) {
+        return false;
     }
 
     ui->Print("\n-- Wiping data...\n");
-    device->WipeData();
-    erase_volume("/data");
-    erase_volume("/cache");
-    erase_persistent_partition();
-    ui->Print("Data wipe complete.\n");
+    if (device->WipeData() == 0 && erase_volume("/data") == 0 && erase_volume("/cache") == 0) {
+        ui->Print("Data wipe complete.\n");
+        return true;
+    } else {
+        ui->Print("Data wipe failed.\n");
+        return false;
+    }
+}
+
+// Return true on success.
+static bool wipe_cache(bool should_confirm, Device* device) {
+    if (should_confirm && !yes_no(device, "Wipe cache?", "  THIS CAN NOT BE UNDONE!")) {
+        return false;
+    }
+
+    ui->Print("\n-- Wiping cache...\n");
+    if (erase_volume("/cache") == 0) {
+        ui->Print("Cache wipe complete.\n");
+        return true;
+    } else {
+        ui->Print("Cache wipe failed.\n");
+        return false;
+    }
 }
 
 static void file_to_ui(const char* fn) {
@@ -782,9 +775,6 @@
     unsigned int n;
     static const char** title_headers = NULL;
     char *filename;
-    const char* headers[] = { "Select file to view",
-                              "",
-                              NULL };
     // "Go back" + LAST_KMSG_FILE + KEEP_LOG_COUNT + terminating NULL entry
     char* entries[KEEP_LOG_COUNT + 3];
     memset(entries, 0, sizeof(entries));
@@ -812,10 +802,10 @@
         entries[n++] = filename;
     }
 
-    title_headers = prepend_title((const char**)headers);
+    const char* headers[] = { "Select file to view", "", NULL };
 
     while(1) {
-        int chosen_item = get_menu_selection(title_headers, entries, 1, 0, device);
+        int chosen_item = get_menu_selection(headers, entries, 1, 0, device);
         if (chosen_item == 0) break;
         file_to_ui(entries[chosen_item]);
     }
@@ -825,6 +815,30 @@
     }
 }
 
+static int apply_from_sdcard(Device* device, bool* wipe_cache) {
+    if (ensure_path_mounted(SDCARD_ROOT) != 0) {
+        ui->Print("\n-- Couldn't mount %s.\n", SDCARD_ROOT);
+        return INSTALL_ERROR;
+    }
+
+    char* path = browse_directory(SDCARD_ROOT, device);
+    if (path == NULL) {
+        ui->Print("\n-- No package file selected.\n", path);
+        return INSTALL_ERROR;
+    }
+
+    ui->Print("\n-- Install %s ...\n", path);
+    set_sdcard_update_bootloader_message();
+    void* token = start_sdcard_fuse(path);
+
+    int status = install_package(FUSE_SIDELOAD_HOST_PATHNAME, wipe_cache,
+                                 TEMPORARY_INSTALL_FILE, false);
+
+    finish_sdcard_fuse(token);
+    ensure_path_unmounted(SDCARD_ROOT);
+    return status;
+}
+
 // Return REBOOT, SHUTDOWN, or REBOOT_BOOTLOADER.  Returning NO_ACTION
 // means to take the default, which is to reboot or shutdown depending
 // on if the --shutdown_after flag was passed to recovery.
@@ -854,7 +868,7 @@
         // statement below.
         Device::BuiltinAction chosen_action = device->InvokeMenuItem(chosen_item);
 
-        int wipe_cache = 0;
+        bool should_wipe_cache = false;
         switch (chosen_action) {
             case Device::NO_ACTION:
                 break;
@@ -870,67 +884,26 @@
                 break;
 
             case Device::WIPE_CACHE:
-                ui->Print("\n-- Wiping cache...\n");
-                erase_volume("/cache");
-                ui->Print("Cache wipe complete.\n");
+                wipe_cache(ui->IsTextVisible(), device);
                 if (!ui->IsTextVisible()) return Device::NO_ACTION;
                 break;
 
-            case Device::APPLY_EXT: {
-                if (ensure_path_mounted(SDCARD_ROOT) != 0) {
-                    ui->Print("\n-- Couldn't mount %s.\n", SDCARD_ROOT);
-                    break;
-                }
-
-                char* path = browse_directory(SDCARD_ROOT, device);
-                if (path == NULL) {
-                    ui->Print("\n-- No package file selected.\n", path);
-                    break;
-                }
-
-                ui->Print("\n-- Install %s ...\n", path);
-                set_sdcard_update_bootloader_message();
-                void* token = start_sdcard_fuse(path);
-
-                int status = install_package(FUSE_SIDELOAD_HOST_PATHNAME, &wipe_cache,
-                                             TEMPORARY_INSTALL_FILE, false);
-
-                finish_sdcard_fuse(token);
-                ensure_path_unmounted(SDCARD_ROOT);
-
-                if (status == INSTALL_SUCCESS && wipe_cache) {
-                    ui->Print("\n-- Wiping cache (at package request)...\n");
-                    if (erase_volume("/cache")) {
-                        ui->Print("Cache wipe failed.\n");
-                    } else {
-                        ui->Print("Cache wipe complete.\n");
-                    }
-                }
-
-                if (status >= 0) {
-                    if (status != INSTALL_SUCCESS) {
-                        ui->SetBackground(RecoveryUI::ERROR);
-                        ui->Print("Installation aborted.\n");
-                    } else if (!ui->IsTextVisible()) {
-                        return Device::NO_ACTION;  // reboot if logs aren't visible
-                    } else {
-                        ui->Print("\nInstall from SD card complete.\n");
-                    }
-                }
-                break;
-            }
-
-            case Device::APPLY_CACHE:
-                ui->Print("\nAPPLY_CACHE is deprecated.\n");
-                break;
-
-            case Device::READ_RECOVERY_LASTLOG:
-                choose_recovery_file(device);
-                break;
-
             case Device::APPLY_ADB_SIDELOAD:
-                status = apply_from_adb(ui, &wipe_cache, TEMPORARY_INSTALL_FILE);
-                if (status >= 0) {
+            case Device::APPLY_EXT:
+                {
+                    bool adb = (chosen_action == Device::APPLY_ADB_SIDELOAD);
+                    if (adb) {
+                        status = apply_from_adb(ui, &should_wipe_cache, TEMPORARY_INSTALL_FILE);
+                    } else {
+                        status = apply_from_sdcard(device, &should_wipe_cache);
+                    }
+
+                    if (status == INSTALL_SUCCESS && should_wipe_cache) {
+                        if (!wipe_cache(false, device)) {
+                            status = INSTALL_ERROR;
+                        }
+                    }
+
                     if (status != INSTALL_SUCCESS) {
                         ui->SetBackground(RecoveryUI::ERROR);
                         ui->Print("Installation aborted.\n");
@@ -938,10 +911,18 @@
                     } else if (!ui->IsTextVisible()) {
                         return Device::NO_ACTION;  // reboot if logs aren't visible
                     } else {
-                        ui->Print("\nInstall from ADB complete.\n");
+                        ui->Print("\nInstall from %s complete.\n", adb ? "ADB" : "SD card");
                     }
                 }
                 break;
+
+            case Device::APPLY_CACHE:
+                ui->Print("\nAPPLY_CACHE is deprecated.\n");
+                break;
+
+            case Device::READ_RECOVERY_LASTLOG:
+                choose_recovery_file(device);
+                break;
         }
     }
 }
@@ -1015,18 +996,24 @@
 
     const char *send_intent = NULL;
     const char *update_package = NULL;
-    int wipe_data = 0, wipe_cache = 0, show_text = 0;
+    bool should_wipe_data = false;
+    bool should_wipe_cache = false;
+    bool show_text = false;
+    bool sideload = false;
+    bool sideload_auto_reboot = false;
     bool just_exit = false;
     bool shutdown_after = false;
 
     int arg;
     while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) {
         switch (arg) {
-        case 's': send_intent = optarg; break;
+        case 'i': send_intent = optarg; break;
         case 'u': update_package = optarg; break;
-        case 'w': wipe_data = wipe_cache = 1; break;
-        case 'c': wipe_cache = 1; break;
-        case 't': show_text = 1; break;
+        case 'w': should_wipe_data = true; break;
+        case 'c': should_wipe_cache = true; break;
+        case 't': show_text = true; break;
+        case 's': sideload = true; break;
+        case 'a': sideload = true; sideload_auto_reboot = true; break;
         case 'x': just_exit = true; break;
         case 'l': locale = optarg; break;
         case 'g': {
@@ -1108,11 +1095,9 @@
     int status = INSTALL_SUCCESS;
 
     if (update_package != NULL) {
-        status = install_package(update_package, &wipe_cache, TEMPORARY_INSTALL_FILE, true);
-        if (status == INSTALL_SUCCESS && wipe_cache) {
-            if (erase_volume("/cache")) {
-                LOGE("Cache wipe (requested by package) failed.");
-            }
+        status = install_package(update_package, &should_wipe_cache, TEMPORARY_INSTALL_FILE, true);
+        if (status == INSTALL_SUCCESS && should_wipe_cache) {
+            wipe_cache(false, device);
         }
         if (status != INSTALL_SUCCESS) {
             ui->Print("Installation aborted.\n");
@@ -1124,28 +1109,50 @@
                 ui->ShowText(true);
             }
         }
-    } else if (wipe_data) {
-        if (device->WipeData()) status = INSTALL_ERROR;
-        if (erase_volume("/data")) status = INSTALL_ERROR;
-        if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
-        if (erase_persistent_partition() == -1 ) status = INSTALL_ERROR;
-        if (status != INSTALL_SUCCESS) ui->Print("Data wipe failed.\n");
-    } else if (wipe_cache) {
-        if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
-        if (status != INSTALL_SUCCESS) ui->Print("Cache wipe failed.\n");
+    } else if (should_wipe_data) {
+        if (!wipe_data(false, device)) {
+            status = INSTALL_ERROR;
+        }
+    } else if (should_wipe_cache) {
+        if (!wipe_cache(false, 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
+        // display will NOT be turned on by default. And it will reboot after
+        // sideload finishes even if there are errors. Unless one turns on the
+        // text display during the installation. This is to enable automated
+        // testing.
+        if (!sideload_auto_reboot) {
+            ui->ShowText(true);
+        }
+        status = apply_from_adb(ui, &should_wipe_cache, TEMPORARY_INSTALL_FILE);
+        if (status == INSTALL_SUCCESS && should_wipe_cache) {
+            if (!wipe_cache(false, device)) {
+                status = INSTALL_ERROR;
+            }
+        }
+        ui->Print("\nInstall from ADB complete (status: %d).\n", status);
+        if (sideload_auto_reboot) {
+            ui->Print("Rebooting automatically.\n");
+        }
     } else if (!just_exit) {
         status = INSTALL_NONE;  // No command specified
         ui->SetBackground(RecoveryUI::NO_COMMAND);
     }
 
-    if (status == INSTALL_ERROR || status == INSTALL_CORRUPT) {
+    if (!sideload_auto_reboot && (status == INSTALL_ERROR || status == INSTALL_CORRUPT)) {
         copy_logs();
         ui->SetBackground(RecoveryUI::ERROR);
     }
+
     Device::BuiltinAction after = shutdown_after ? Device::SHUTDOWN : Device::REBOOT;
-    if (status != INSTALL_SUCCESS || ui->IsTextVisible()) {
+    if ((status != INSTALL_SUCCESS && !sideload_auto_reboot) || ui->IsTextVisible()) {
         Device::BuiltinAction temp = prompt_and_wait(device, status);
-        if (temp != Device::NO_ACTION) after = temp;
+        if (temp != Device::NO_ACTION) {
+            after = temp;
+        }
     }
 
     // Save logs and clean up before rebooting or shutting down.
diff --git a/roots.cpp b/roots.cpp
index c067bcc..f863cb2 100644
--- a/roots.cpp
+++ b/roots.cpp
@@ -39,8 +39,6 @@
 
 extern struct selabel_handle *sehandle;
 
-static const char* PERSISTENT_PATH = "/persistent";
-
 void load_volume_table()
 {
     int i;
@@ -266,41 +264,6 @@
     return -1;
 }
 
-int erase_persistent_partition() {
-    Volume *v = volume_for_path(PERSISTENT_PATH);
-    if (v == NULL) {
-        // most devices won't have /persistent, so this is not an error.
-        return 0;
-    }
-
-    int fd = open(v->blk_device, O_RDWR);
-    uint64_t size = get_file_size(fd);
-    if (size == 0) {
-        LOGE("failed to stat size of /persistent\n");
-        close(fd);
-        return -1;
-    }
-
-    char oem_unlock_enabled;
-    lseek(fd, size - 1, SEEK_SET);
-    read(fd, &oem_unlock_enabled, 1);
-
-    if (oem_unlock_enabled) {
-        if (wipe_block_device(fd, size)) {
-           LOGE("error wiping /persistent: %s\n", strerror(errno));
-           close(fd);
-           return -1;
-        }
-
-        lseek(fd, size - 1, SEEK_SET);
-        write(fd, &oem_unlock_enabled, 1);
-    }
-
-    close(fd);
-
-    return (int) oem_unlock_enabled;
-}
-
 int setup_install_mounts() {
     if (fstab == NULL) {
         LOGE("can't set up install mounts: no fstab loaded\n");
diff --git a/roots.h b/roots.h
index b62a5b1..230d9de 100644
--- a/roots.h
+++ b/roots.h
@@ -46,11 +46,6 @@
 // mounted (/tmp and /cache) are mounted.  Returns 0 on success.
 int setup_install_mounts();
 
-// Conditionally wipes the /persistent partition if it's marked
-// to wipe. Returns -1 on failure, 1 if the partition was wiped
-// and 0 if the partition was not wiped.
-int erase_persistent_partition();
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/screen_ui.cpp b/screen_ui.cpp
index 5e3a24f..edc41ab 100644
--- a/screen_ui.cpp
+++ b/screen_ui.cpp
@@ -246,12 +246,11 @@
         // display from the bottom up, until we hit the top of the
         // screen, the bottom of the menu, or we've displayed the
         // entire text buffer.
-        int ty;
         int row = (text_top+text_rows-1) % text_rows;
         for (int ty = gr_fb_height() - char_height, count = 0;
              ty > y+2 && count < text_rows;
              ty -= char_height, ++count) {
-            gr_text(4, ty, text[row], 0);
+            gr_text(0, ty, text[row], 0);
             --row;
             if (row < 0) row = text_rows-1;
         }
@@ -480,8 +479,7 @@
     // This can get called before ui_init(), so be careful.
     pthread_mutex_lock(&updateMutex);
     if (text_rows > 0 && text_cols > 0) {
-        char *ptr;
-        for (ptr = buf; *ptr != '\0'; ++ptr) {
+        for (char* ptr = buf; *ptr != '\0'; ++ptr) {
             if (*ptr == '\n' || text_col >= text_cols) {
                 text[text_row][text_col] = '\0';
                 text_col = 0;
@@ -521,10 +519,9 @@
 }
 
 int ScreenRecoveryUI::SelectMenu(int sel) {
-    int old_sel;
     pthread_mutex_lock(&updateMutex);
     if (show_menu > 0) {
-        old_sel = menu_sel;
+        int old_sel = menu_sel;
         menu_sel = sel;
 
         // Wrap at top and bottom.
@@ -539,7 +536,6 @@
 }
 
 void ScreenRecoveryUI::EndMenu() {
-    int i;
     pthread_mutex_lock(&updateMutex);
     if (show_menu > 0 && text_rows > 0 && text_cols > 0) {
         show_menu = 0;