diff --git a/Android.mk b/Android.mk
index 2c81be6..527aa1b 100644
--- a/Android.mk
+++ b/Android.mk
@@ -8,7 +8,7 @@
     bootloader.cpp \
     install.cpp \
     roots.cpp \
-    ui.cpp \
+    screen_ui.cpp \
     verifier.cpp
 
 LOCAL_MODULE := recovery
diff --git a/install.cpp b/install.cpp
index 482e0d7..0783433 100644
--- a/install.cpp
+++ b/install.cpp
@@ -34,9 +34,17 @@
 #include "verifier.h"
 #include "ui.h"
 
+extern RecoveryUI* ui;
+
 #define ASSUMED_UPDATE_BINARY_NAME  "META-INF/com/google/android/update-binary"
 #define PUBLIC_KEYS_FILE "/res/keys"
 
+// Default allocation of progress bar segments to operations
+static const int VERIFICATION_PROGRESS_TIME = 60;
+static const float VERIFICATION_PROGRESS_FRACTION = 0.25;
+static const float DEFAULT_FILES_PROGRESS_FRACTION = 0.4;
+static const float DEFAULT_IMAGE_PROGRESS_FRACTION = 0.1;
+
 // 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) {
@@ -134,18 +142,17 @@
             float fraction = strtof(fraction_s, NULL);
             int seconds = strtol(seconds_s, NULL, 10);
 
-            ui_show_progress(fraction * (1-VERIFICATION_PROGRESS_FRACTION),
-                             seconds);
+            ui->ShowProgress(fraction * (1-VERIFICATION_PROGRESS_FRACTION), seconds);
         } else if (strcmp(command, "set_progress") == 0) {
             char* fraction_s = strtok(NULL, " \n");
             float fraction = strtof(fraction_s, NULL);
-            ui_set_progress(fraction);
+            ui->SetProgress(fraction);
         } else if (strcmp(command, "ui_print") == 0) {
             char* str = strtok(NULL, "\n");
             if (str) {
-                ui_print("%s", str);
+                ui->Print("%s", str);
             } else {
-                ui_print("\n");
+                ui->Print("\n");
             }
         } else if (strcmp(command, "wipe_cache") == 0) {
             *wipe_cache = 1;
@@ -244,9 +251,9 @@
 static int
 really_install_package(const char *path, int* wipe_cache)
 {
-    ui_set_background(BACKGROUND_ICON_INSTALLING);
-    ui_print("Finding update package...\n");
-    ui_show_indeterminate_progress();
+    ui->SetBackground(RecoveryUI::INSTALLING);
+    ui->Print("Finding update package...\n");
+    ui->SetProgressType(RecoveryUI::INDETERMINATE);
     LOGI("Update location: %s\n", path);
 
     if (ensure_path_mounted(path) != 0) {
@@ -254,7 +261,7 @@
         return INSTALL_CORRUPT;
     }
 
-    ui_print("Opening update package...\n");
+    ui->Print("Opening update package...\n");
 
     int numKeys;
     RSAPublicKey* loadedKeys = load_keys(PUBLIC_KEYS_FILE, &numKeys);
@@ -265,10 +272,9 @@
     LOGI("%d key(s) loaded from %s\n", numKeys, PUBLIC_KEYS_FILE);
 
     // Give verification half the progress bar...
-    ui_print("Verifying update package...\n");
-    ui_show_progress(
-            VERIFICATION_PROGRESS_FRACTION,
-            VERIFICATION_PROGRESS_TIME);
+    ui->Print("Verifying update package...\n");
+    ui->SetProgressType(RecoveryUI::DETERMINATE);
+    ui->ShowProgress(VERIFICATION_PROGRESS_FRACTION, VERIFICATION_PROGRESS_TIME);
 
     int err;
     err = verify_file(path, loadedKeys, numKeys);
@@ -290,7 +296,7 @@
 
     /* Verify and install the contents of the package.
      */
-    ui_print("Installing update...\n");
+    ui->Print("Installing update...\n");
     return try_update_binary(path, &zip, wipe_cache);
 }
 
diff --git a/recovery.cpp b/recovery.cpp
index 7c1d7fb..d1af3ac 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -39,6 +39,7 @@
 #include "roots.h"
 #include "recovery_ui.h"
 #include "ui.h"
+#include "screen_ui.h"
 
 static const struct option OPTIONS[] = {
   { "send_intent", required_argument, NULL, 's' },
@@ -62,6 +63,8 @@
 
 extern UIParameters ui_parameters;    // from ui.c
 
+RecoveryUI* ui = NULL;
+
 /*
  * The recovery tool communicates with the main system through /cache files.
  *   /cache/recovery/command - INPUT - command line for tool, one arg per line
@@ -291,9 +294,9 @@
 
 static int
 erase_volume(const char *volume) {
-    ui_set_background(BACKGROUND_ICON_INSTALLING);
-    ui_show_indeterminate_progress();
-    ui_print("Formatting %s...\n", volume);
+    ui->SetBackground(RecoveryUI::INSTALLING);
+    ui->SetProgressType(RecoveryUI::INDETERMINATE);
+    ui->Print("Formatting %s...\n", volume);
 
     ensure_path_unmounted(volume);
 
@@ -425,22 +428,22 @@
                    int menu_only, int initial_selection) {
     // throw away keys pressed previously, so user doesn't
     // accidentally trigger menu items.
-    ui_clear_key_queue();
+    ui->FlushKeys();
 
-    ui_start_menu(headers, items, initial_selection);
+    ui->StartMenu(headers, items, initial_selection);
     int selected = initial_selection;
     int chosen_item = -1;
 
     while (chosen_item < 0) {
-        int key = ui_wait_key();
-        int visible = ui_text_visible();
+        int key = ui->WaitKey();
+        int visible = ui->IsTextVisible();
 
         if (key == -1) {   // ui_wait_key() timed out
-            if (ui_text_ever_visible()) {
+            if (ui->WasTextEverVisible()) {
                 continue;
             } else {
                 LOGI("timed out waiting for key input; rebooting.\n");
-                ui_end_menu();
+                ui->EndMenu();
                 return ITEM_REBOOT;
             }
         }
@@ -451,11 +454,11 @@
             switch (action) {
                 case HIGHLIGHT_UP:
                     --selected;
-                    selected = ui_menu_select(selected);
+                    selected = ui->SelectMenu(selected);
                     break;
                 case HIGHLIGHT_DOWN:
                     ++selected;
-                    selected = ui_menu_select(selected);
+                    selected = ui->SelectMenu(selected);
                     break;
                 case SELECT_ITEM:
                     chosen_item = selected;
@@ -468,7 +471,7 @@
         }
     }
 
-    ui_end_menu();
+    ui->EndMenu();
     return chosen_item;
 }
 
@@ -577,7 +580,7 @@
             strlcat(new_path, "/", PATH_MAX);
             strlcat(new_path, item, PATH_MAX);
 
-            ui_print("\n-- Install %s ...\n", path);
+            ui->Print("\n-- Install %s ...\n", path);
             set_sdcard_update_bootloader_message();
             char* copy = copy_sideloaded_package(new_path);
             if (unmount_when_done != NULL) {
@@ -636,11 +639,11 @@
         }
     }
 
-    ui_print("\n-- Wiping data...\n");
+    ui->Print("\n-- Wiping data...\n");
     device_wipe_data();
     erase_volume("/data");
     erase_volume("/cache");
-    ui_print("Data wipe complete.\n");
+    ui->Print("Data wipe complete.\n");
 }
 
 static void
@@ -649,7 +652,7 @@
 
     for (;;) {
         finish_recovery(NULL);
-        ui_reset_progress();
+        ui->SetProgressType(RecoveryUI::EMPTY);
 
         int chosen_item = get_menu_selection(headers, MENU_ITEMS, 0, 0);
 
@@ -665,35 +668,35 @@
                 return;
 
             case ITEM_WIPE_DATA:
-                wipe_data(ui_text_visible());
-                if (!ui_text_visible()) return;
+                wipe_data(ui->IsTextVisible());
+                if (!ui->IsTextVisible()) return;
                 break;
 
             case ITEM_WIPE_CACHE:
-                ui_print("\n-- Wiping cache...\n");
+                ui->Print("\n-- Wiping cache...\n");
                 erase_volume("/cache");
-                ui_print("Cache wipe complete.\n");
-                if (!ui_text_visible()) return;
+                ui->Print("Cache wipe complete.\n");
+                if (!ui->IsTextVisible()) return;
                 break;
 
             case ITEM_APPLY_SDCARD:
                 status = update_directory(SDCARD_ROOT, SDCARD_ROOT, &wipe_cache);
                 if (status == INSTALL_SUCCESS && wipe_cache) {
-                    ui_print("\n-- Wiping cache (at package request)...\n");
+                    ui->Print("\n-- Wiping cache (at package request)...\n");
                     if (erase_volume("/cache")) {
-                        ui_print("Cache wipe failed.\n");
+                        ui->Print("Cache wipe failed.\n");
                     } else {
-                        ui_print("Cache wipe complete.\n");
+                        ui->Print("Cache wipe complete.\n");
                     }
                 }
                 if (status >= 0) {
                     if (status != INSTALL_SUCCESS) {
-                        ui_set_background(BACKGROUND_ICON_ERROR);
-                        ui_print("Installation aborted.\n");
-                    } else if (!ui_text_visible()) {
+                        ui->SetBackground(RecoveryUI::ERROR);
+                        ui->Print("Installation aborted.\n");
+                    } else if (!ui->IsTextVisible()) {
                         return;  // reboot if logs aren't visible
                     } else {
-                        ui_print("\nInstall from sdcard complete.\n");
+                        ui->Print("\nInstall from sdcard complete.\n");
                     }
                 }
                 break;
@@ -701,21 +704,21 @@
                 // Don't unmount cache at the end of this.
                 status = update_directory(CACHE_ROOT, NULL, &wipe_cache);
                 if (status == INSTALL_SUCCESS && wipe_cache) {
-                    ui_print("\n-- Wiping cache (at package request)...\n");
+                    ui->Print("\n-- Wiping cache (at package request)...\n");
                     if (erase_volume("/cache")) {
-                        ui_print("Cache wipe failed.\n");
+                        ui->Print("Cache wipe failed.\n");
                     } else {
-                        ui_print("Cache wipe complete.\n");
+                        ui->Print("Cache wipe complete.\n");
                     }
                 }
                 if (status >= 0) {
                     if (status != INSTALL_SUCCESS) {
-                        ui_set_background(BACKGROUND_ICON_ERROR);
-                        ui_print("Installation aborted.\n");
-                    } else if (!ui_text_visible()) {
+                        ui->SetBackground(RecoveryUI::ERROR);
+                        ui->Print("Installation aborted.\n");
+                    } else if (!ui->IsTextVisible()) {
                         return;  // reboot if logs aren't visible
                     } else {
-                        ui_print("\nInstall from cache complete.\n");
+                        ui->Print("\nInstall from cache complete.\n");
                     }
                 }
                 break;
@@ -738,9 +741,13 @@
     freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL);
     printf("Starting recovery on %s", ctime(&start));
 
+    // TODO: device_* should be a C++ class; init should return the
+    // appropriate UI for the device.
     device_ui_init(&ui_parameters);
-    ui_init();
-    ui_set_background(BACKGROUND_ICON_INSTALLING);
+    ui = new ScreenRecoveryUI();
+
+    ui->Init();
+    ui->SetBackground(RecoveryUI::INSTALLING);
     load_volume_table();
     get_args(&argc, &argv);
 
@@ -757,7 +764,7 @@
         case 'u': update_package = optarg; break;
         case 'w': wipe_data = wipe_cache = 1; break;
         case 'c': wipe_cache = 1; break;
-        case 't': ui_show_text(1); break;
+        case 't': ui->ShowText(true); break;
         case '?':
             LOGE("Invalid command argument\n");
             continue;
@@ -800,27 +807,27 @@
                 LOGE("Cache wipe (requested by package) failed.");
             }
         }
-        if (status != INSTALL_SUCCESS) ui_print("Installation aborted.\n");
+        if (status != INSTALL_SUCCESS) ui->Print("Installation aborted.\n");
     } else if (wipe_data) {
         if (device_wipe_data()) status = INSTALL_ERROR;
         if (erase_volume("/data")) status = INSTALL_ERROR;
         if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
-        if (status != INSTALL_SUCCESS) ui_print("Data wipe failed.\n");
+        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");
+        if (status != INSTALL_SUCCESS) ui->Print("Cache wipe failed.\n");
     } else {
         status = INSTALL_ERROR;  // No command specified
     }
 
-    if (status != INSTALL_SUCCESS) ui_set_background(BACKGROUND_ICON_ERROR);
-    if (status != INSTALL_SUCCESS || ui_text_visible()) {
+    if (status != INSTALL_SUCCESS) ui->SetBackground(RecoveryUI::ERROR);
+    if (status != INSTALL_SUCCESS || ui->IsTextVisible()) {
         prompt_and_wait();
     }
 
     // Otherwise, get ready to boot the main system...
     finish_recovery(send_intent);
-    ui_print("Rebooting...\n");
+    ui->Print("Rebooting...\n");
     android_reboot(ANDROID_RB_RESTART, 0, 0);
     return EXIT_SUCCESS;
 }
diff --git a/screen_ui.cpp b/screen_ui.cpp
new file mode 100644
index 0000000..e6a31db
--- /dev/null
+++ b/screen_ui.cpp
@@ -0,0 +1,633 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/input.h>
+#include <pthread.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "common.h"
+#include <cutils/android_reboot.h>
+#include "minui/minui.h"
+#include "recovery_ui.h"
+#include "ui.h"
+#include "screen_ui.h"
+
+#define CHAR_WIDTH 10
+#define CHAR_HEIGHT 18
+
+#define UI_WAIT_KEY_TIMEOUT_SEC    120
+
+UIParameters ui_parameters = {
+    6,       // indeterminate progress bar frames
+    20,      // fps
+    7,       // installation icon frames (0 == static image)
+    13, 190, // installation icon overlay offset
+};
+
+// There's only (at most) one of these objects, and global callbacks
+// (for pthread_create, and the input event system) need to find it,
+// so use a global variable.
+static ScreenRecoveryUI* self = NULL;
+
+// Return the current time as a double (including fractions of a second).
+static double now() {
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    return tv.tv_sec + tv.tv_usec / 1000000.0;
+}
+
+ScreenRecoveryUI::ScreenRecoveryUI() :
+    currentIcon(NONE),
+    installingFrame(0),
+    progressBarType(EMPTY),
+    progressScopeStart(0),
+    progressScopeSize(0),
+    progress(0),
+    pagesIdentical(false),
+    text_cols(0),
+    text_rows(0),
+    text_col(0),
+    text_row(0),
+    text_top(0),
+    show_text(false),
+    show_text_ever(false),
+    show_menu(false),
+    menu_top(0),
+    menu_items(0),
+    menu_sel(0),
+    key_queue_len(0) {
+    pthread_mutex_init(&updateMutex, NULL);
+    pthread_mutex_init(&key_queue_mutex, NULL);
+    pthread_cond_init(&key_queue_cond, NULL);
+    self = this;
+}
+
+// Draw the given frame over the installation overlay animation.  The
+// background is not cleared or draw with the base icon first; we
+// assume that the frame already contains some other frame of the
+// animation.  Does nothing if no overlay animation is defined.
+// Should only be called with updateMutex locked.
+void ScreenRecoveryUI::draw_install_overlay_locked(int frame) {
+    if (installationOverlay == NULL) return;
+    gr_surface surface = installationOverlay[frame];
+    int iconWidth = gr_get_width(surface);
+    int iconHeight = gr_get_height(surface);
+    gr_blit(surface, 0, 0, iconWidth, iconHeight,
+            ui_parameters.install_overlay_offset_x,
+            ui_parameters.install_overlay_offset_y);
+}
+
+// Clear the screen and draw the currently selected background icon (if any).
+// Should only be called with updateMutex locked.
+void ScreenRecoveryUI::draw_background_locked(Icon icon)
+{
+    pagesIdentical = false;
+    gr_color(0, 0, 0, 255);
+    gr_fill(0, 0, gr_fb_width(), gr_fb_height());
+
+    if (icon) {
+        gr_surface surface = backgroundIcon[icon];
+        int iconWidth = gr_get_width(surface);
+        int iconHeight = gr_get_height(surface);
+        int iconX = (gr_fb_width() - iconWidth) / 2;
+        int iconY = (gr_fb_height() - iconHeight) / 2;
+        gr_blit(surface, 0, 0, iconWidth, iconHeight, iconX, iconY);
+        if (icon == INSTALLING) {
+            draw_install_overlay_locked(installingFrame);
+        }
+    }
+}
+
+// Draw the progress bar (if any) on the screen.  Does not flip pages.
+// Should only be called with updateMutex locked.
+void ScreenRecoveryUI::draw_progress_locked()
+{
+    if (currentIcon == INSTALLING) {
+        draw_install_overlay_locked(installingFrame);
+    }
+
+    if (progressBarType != EMPTY) {
+        int iconHeight = gr_get_height(backgroundIcon[INSTALLING]);
+        int width = gr_get_width(progressBarEmpty);
+        int height = gr_get_height(progressBarEmpty);
+
+        int dx = (gr_fb_width() - width)/2;
+        int dy = (3*gr_fb_height() + iconHeight - 2*height)/4;
+
+        // Erase behind the progress bar (in case this was a progress-only update)
+        gr_color(0, 0, 0, 255);
+        gr_fill(dx, dy, width, height);
+
+        if (progressBarType == DETERMINATE) {
+            float p = progressScopeStart + progress * progressScopeSize;
+            int pos = (int) (p * width);
+
+            if (pos > 0) {
+                gr_blit(progressBarFill, 0, 0, pos, height, dx, dy);
+            }
+            if (pos < width-1) {
+                gr_blit(progressBarEmpty, pos, 0, width-pos, height, dx+pos, dy);
+            }
+        }
+
+        if (progressBarType == INDETERMINATE) {
+            static int frame = 0;
+            gr_blit(progressBarIndeterminate[frame], 0, 0, width, height, dx, dy);
+            frame = (frame + 1) % ui_parameters.indeterminate_frames;
+        }
+    }
+}
+
+void ScreenRecoveryUI::draw_text_line(int row, const char* t) {
+  if (t[0] != '\0') {
+    gr_text(0, (row+1)*CHAR_HEIGHT-1, t);
+  }
+}
+
+// Redraw everything on the screen.  Does not flip pages.
+// Should only be called with updateMutex locked.
+void ScreenRecoveryUI::draw_screen_locked()
+{
+    draw_background_locked(currentIcon);
+    draw_progress_locked();
+
+    if (show_text) {
+        gr_color(0, 0, 0, 160);
+        gr_fill(0, 0, gr_fb_width(), gr_fb_height());
+
+        int i = 0;
+        if (show_menu) {
+            gr_color(64, 96, 255, 255);
+            gr_fill(0, (menu_top+menu_sel) * CHAR_HEIGHT,
+                    gr_fb_width(), (menu_top+menu_sel+1)*CHAR_HEIGHT+1);
+
+            for (; i < menu_top + menu_items; ++i) {
+                if (i == menu_top + menu_sel) {
+                    gr_color(255, 255, 255, 255);
+                    draw_text_line(i, menu[i]);
+                    gr_color(64, 96, 255, 255);
+                } else {
+                    draw_text_line(i, menu[i]);
+                }
+            }
+            gr_fill(0, i*CHAR_HEIGHT+CHAR_HEIGHT/2-1,
+                    gr_fb_width(), i*CHAR_HEIGHT+CHAR_HEIGHT/2+1);
+            ++i;
+        }
+
+        gr_color(255, 255, 0, 255);
+
+        for (; i < text_rows; ++i) {
+            draw_text_line(i, text[(i+text_top) % text_rows]);
+        }
+    }
+}
+
+// Redraw everything on the screen and flip the screen (make it visible).
+// Should only be called with updateMutex locked.
+void ScreenRecoveryUI::update_screen_locked()
+{
+    draw_screen_locked();
+    gr_flip();
+}
+
+// Updates only the progress bar, if possible, otherwise redraws the screen.
+// Should only be called with updateMutex locked.
+void ScreenRecoveryUI::update_progress_locked()
+{
+    if (show_text || !pagesIdentical) {
+        draw_screen_locked();    // Must redraw the whole screen
+        pagesIdentical = true;
+    } else {
+        draw_progress_locked();  // Draw only the progress bar and overlays
+    }
+    gr_flip();
+}
+
+// Keeps the progress bar updated, even when the process is otherwise busy.
+void* ScreenRecoveryUI::progress_thread(void *cookie)
+{
+    double interval = 1.0 / ui_parameters.update_fps;
+    for (;;) {
+        double start = now();
+        pthread_mutex_lock(&self->updateMutex);
+
+        int redraw = 0;
+
+        // update the installation animation, if active
+        // skip this if we have a text overlay (too expensive to update)
+        if (self->currentIcon == INSTALLING &&
+            ui_parameters.installing_frames > 0 &&
+            !self->show_text) {
+            self->installingFrame =
+                (self->installingFrame + 1) % ui_parameters.installing_frames;
+            redraw = 1;
+        }
+
+        // update the progress bar animation, if active
+        // skip this if we have a text overlay (too expensive to update)
+        if (self->progressBarType == INDETERMINATE && !self->show_text) {
+            redraw = 1;
+        }
+
+        // move the progress bar forward on timed intervals, if configured
+        int duration = self->progressScopeDuration;
+        if (self->progressBarType == DETERMINATE && duration > 0) {
+            double elapsed = now() - self->progressScopeTime;
+            float progress = 1.0 * elapsed / duration;
+            if (progress > 1.0) progress = 1.0;
+            if (progress > progress) {
+                progress = progress;
+                redraw = 1;
+            }
+        }
+
+        if (redraw) self->update_progress_locked();
+
+        pthread_mutex_unlock(&self->updateMutex);
+        double end = now();
+        // minimum of 20ms delay between frames
+        double delay = interval - (end-start);
+        if (delay < 0.02) delay = 0.02;
+        usleep((long)(delay * 1000000));
+    }
+    return NULL;
+}
+
+int ScreenRecoveryUI::input_callback(int fd, short revents, void* data)
+{
+    struct input_event ev;
+    int ret;
+    int fake_key = 0;
+
+    ret = ev_get_input(fd, revents, &ev);
+    if (ret)
+        return -1;
+
+    if (ev.type == EV_SYN) {
+        return 0;
+    } else if (ev.type == EV_REL) {
+        if (ev.code == REL_Y) {
+            // accumulate the up or down motion reported by
+            // the trackball.  When it exceeds a threshold
+            // (positive or negative), fake an up/down
+            // key event.
+            self->rel_sum += ev.value;
+            if (self->rel_sum > 3) {
+                fake_key = 1;
+                ev.type = EV_KEY;
+                ev.code = KEY_DOWN;
+                ev.value = 1;
+                self->rel_sum = 0;
+            } else if (self->rel_sum < -3) {
+                fake_key = 1;
+                ev.type = EV_KEY;
+                ev.code = KEY_UP;
+                ev.value = 1;
+                self->rel_sum = 0;
+            }
+        }
+    } else {
+        self->rel_sum = 0;
+    }
+
+    if (ev.type != EV_KEY || ev.code > KEY_MAX)
+        return 0;
+
+    pthread_mutex_lock(&self->key_queue_mutex);
+    if (!fake_key) {
+        // our "fake" keys only report a key-down event (no
+        // key-up), so don't record them in the key_pressed
+        // table.
+        self->key_pressed[ev.code] = ev.value;
+    }
+    const int queue_max = sizeof(self->key_queue) / sizeof(self->key_queue[0]);
+    if (ev.value > 0 && self->key_queue_len < queue_max) {
+        self->key_queue[self->key_queue_len++] = ev.code;
+        pthread_cond_signal(&self->key_queue_cond);
+    }
+    pthread_mutex_unlock(&self->key_queue_mutex);
+
+    if (ev.value > 0 && device_toggle_display(self->key_pressed, ev.code)) {
+        pthread_mutex_lock(&self->updateMutex);
+        self->show_text = !self->show_text;
+        if (self->show_text) self->show_text_ever = true;
+        self->update_screen_locked();
+        pthread_mutex_unlock(&self->updateMutex);
+    }
+
+    if (ev.value > 0 && device_reboot_now(self->key_pressed, ev.code)) {
+        android_reboot(ANDROID_RB_RESTART, 0, 0);
+    }
+
+    return 0;
+}
+
+// Reads input events, handles special hot keys, and adds to the key queue.
+void* ScreenRecoveryUI::input_thread(void *cookie)
+{
+    for (;;) {
+        if (!ev_wait(-1))
+            ev_dispatch();
+    }
+    return NULL;
+}
+
+void ScreenRecoveryUI::LoadBitmap(const char* filename, gr_surface* surface) {
+    int result = res_create_surface(filename, surface);
+    if (result < 0) {
+        LOGE("missing bitmap %s\n(Code %d)\n", filename, result);
+    }
+}
+
+void ScreenRecoveryUI::Init()
+{
+    gr_init();
+    ev_init(input_callback, NULL);
+
+    text_col = text_row = 0;
+    text_rows = gr_fb_height() / CHAR_HEIGHT;
+    if (text_rows > kMaxRows) text_rows = kMaxRows;
+    text_top = 1;
+
+    text_cols = gr_fb_width() / CHAR_WIDTH;
+    if (text_cols > kMaxCols - 1) text_cols = kMaxCols - 1;
+
+    LoadBitmap("icon_installing", &backgroundIcon[INSTALLING]);
+    LoadBitmap("icon_error", &backgroundIcon[ERROR]);
+    LoadBitmap("progress_empty", &progressBarEmpty);
+    LoadBitmap("progress_fill", &progressBarFill);
+
+    int i;
+
+    progressBarIndeterminate = (gr_surface*)malloc(ui_parameters.indeterminate_frames *
+                                                    sizeof(gr_surface));
+    for (i = 0; i < ui_parameters.indeterminate_frames; ++i) {
+        char filename[40];
+        // "indeterminate01.png", "indeterminate02.png", ...
+        sprintf(filename, "indeterminate%02d", i+1);
+        LoadBitmap(filename, progressBarIndeterminate+i);
+    }
+
+    if (ui_parameters.installing_frames > 0) {
+        installationOverlay = (gr_surface*)malloc(ui_parameters.installing_frames *
+                                                   sizeof(gr_surface));
+        for (i = 0; i < ui_parameters.installing_frames; ++i) {
+            char filename[40];
+            // "icon_installing_overlay01.png",
+            // "icon_installing_overlay02.png", ...
+            sprintf(filename, "icon_installing_overlay%02d", i+1);
+            LoadBitmap(filename, installationOverlay+i);
+        }
+
+        // Adjust the offset to account for the positioning of the
+        // base image on the screen.
+        if (backgroundIcon[INSTALLING] != NULL) {
+            gr_surface bg = backgroundIcon[INSTALLING];
+            ui_parameters.install_overlay_offset_x +=
+                (gr_fb_width() - gr_get_width(bg)) / 2;
+            ui_parameters.install_overlay_offset_y +=
+                (gr_fb_height() - gr_get_height(bg)) / 2;
+        }
+    } else {
+        installationOverlay = NULL;
+    }
+
+    pthread_create(&progress_t, NULL, progress_thread, NULL);
+    pthread_create(&input_t, NULL, input_thread, NULL);
+}
+
+void ScreenRecoveryUI::SetBackground(Icon icon)
+{
+    pthread_mutex_lock(&updateMutex);
+    currentIcon = icon;
+    update_screen_locked();
+    pthread_mutex_unlock(&updateMutex);
+}
+
+void ScreenRecoveryUI::SetProgressType(ProgressType type)
+{
+    pthread_mutex_lock(&updateMutex);
+    if (progressBarType != type) {
+        progressBarType = type;
+        update_progress_locked();
+    }
+    pthread_mutex_unlock(&updateMutex);
+}
+
+void ScreenRecoveryUI::ShowProgress(float portion, float seconds)
+{
+    pthread_mutex_lock(&updateMutex);
+    progressBarType = DETERMINATE;
+    progressScopeStart += progressScopeSize;
+    progressScopeSize = portion;
+    progressScopeTime = now();
+    progressScopeDuration = seconds;
+    progress = 0;
+    update_progress_locked();
+    pthread_mutex_unlock(&updateMutex);
+}
+
+void ScreenRecoveryUI::SetProgress(float fraction)
+{
+    pthread_mutex_lock(&updateMutex);
+    if (fraction < 0.0) fraction = 0.0;
+    if (fraction > 1.0) fraction = 1.0;
+    if (progressBarType == DETERMINATE && fraction > progress) {
+        // Skip updates that aren't visibly different.
+        int width = gr_get_width(progressBarIndeterminate[0]);
+        float scale = width * progressScopeSize;
+        if ((int) (progress * scale) != (int) (fraction * scale)) {
+            progress = fraction;
+            update_progress_locked();
+        }
+    }
+    pthread_mutex_unlock(&updateMutex);
+}
+
+void ScreenRecoveryUI::Print(const char *fmt, ...)
+{
+    char buf[256];
+    va_list ap;
+    va_start(ap, fmt);
+    vsnprintf(buf, 256, fmt, ap);
+    va_end(ap);
+
+    fputs(buf, stdout);
+
+    // 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) {
+            if (*ptr == '\n' || text_col >= text_cols) {
+                text[text_row][text_col] = '\0';
+                text_col = 0;
+                text_row = (text_row + 1) % text_rows;
+                if (text_row == text_top) text_top = (text_top + 1) % text_rows;
+            }
+            if (*ptr != '\n') text[text_row][text_col++] = *ptr;
+        }
+        text[text_row][text_col] = '\0';
+        update_screen_locked();
+    }
+    pthread_mutex_unlock(&updateMutex);
+}
+
+void ScreenRecoveryUI::StartMenu(const char* const * headers, const char* const * items,
+                                 int initial_selection) {
+    int i;
+    pthread_mutex_lock(&updateMutex);
+    if (text_rows > 0 && text_cols > 0) {
+        for (i = 0; i < text_rows; ++i) {
+            if (headers[i] == NULL) break;
+            strncpy(menu[i], headers[i], text_cols-1);
+            menu[i][text_cols-1] = '\0';
+        }
+        menu_top = i;
+        for (; i < text_rows; ++i) {
+            if (items[i-menu_top] == NULL) break;
+            strncpy(menu[i], items[i-menu_top], text_cols-1);
+            menu[i][text_cols-1] = '\0';
+        }
+        menu_items = i - menu_top;
+        show_menu = 1;
+        menu_sel = initial_selection;
+        update_screen_locked();
+    }
+    pthread_mutex_unlock(&updateMutex);
+}
+
+int ScreenRecoveryUI::SelectMenu(int sel) {
+    int old_sel;
+    pthread_mutex_lock(&updateMutex);
+    if (show_menu > 0) {
+        old_sel = menu_sel;
+        menu_sel = sel;
+        if (menu_sel < 0) menu_sel = 0;
+        if (menu_sel >= menu_items) menu_sel = menu_items-1;
+        sel = menu_sel;
+        if (menu_sel != old_sel) update_screen_locked();
+    }
+    pthread_mutex_unlock(&updateMutex);
+    return sel;
+}
+
+void ScreenRecoveryUI::EndMenu() {
+    int i;
+    pthread_mutex_lock(&updateMutex);
+    if (show_menu > 0 && text_rows > 0 && text_cols > 0) {
+        show_menu = 0;
+        update_screen_locked();
+    }
+    pthread_mutex_unlock(&updateMutex);
+}
+
+bool ScreenRecoveryUI::IsTextVisible()
+{
+    pthread_mutex_lock(&updateMutex);
+    int visible = show_text;
+    pthread_mutex_unlock(&updateMutex);
+    return visible;
+}
+
+bool ScreenRecoveryUI::WasTextEverVisible()
+{
+    pthread_mutex_lock(&updateMutex);
+    int ever_visible = show_text_ever;
+    pthread_mutex_unlock(&updateMutex);
+    return ever_visible;
+}
+
+void ScreenRecoveryUI::ShowText(bool visible)
+{
+    pthread_mutex_lock(&updateMutex);
+    show_text = visible;
+    if (show_text) show_text_ever = 1;
+    update_screen_locked();
+    pthread_mutex_unlock(&updateMutex);
+}
+
+// Return true if USB is connected.
+bool ScreenRecoveryUI::usb_connected() {
+    int fd = open("/sys/class/android_usb/android0/state", O_RDONLY);
+    if (fd < 0) {
+        printf("failed to open /sys/class/android_usb/android0/state: %s\n",
+               strerror(errno));
+        return 0;
+    }
+
+    char buf;
+    /* USB is connected if android_usb state is CONNECTED or CONFIGURED */
+    int connected = (read(fd, &buf, 1) == 1) && (buf == 'C');
+    if (close(fd) < 0) {
+        printf("failed to close /sys/class/android_usb/android0/state: %s\n",
+               strerror(errno));
+    }
+    return connected;
+}
+
+int ScreenRecoveryUI::WaitKey()
+{
+    pthread_mutex_lock(&key_queue_mutex);
+
+    // Time out after UI_WAIT_KEY_TIMEOUT_SEC, unless a USB cable is
+    // plugged in.
+    do {
+        struct timeval now;
+        struct timespec timeout;
+        gettimeofday(&now, NULL);
+        timeout.tv_sec = now.tv_sec;
+        timeout.tv_nsec = now.tv_usec * 1000;
+        timeout.tv_sec += UI_WAIT_KEY_TIMEOUT_SEC;
+
+        int rc = 0;
+        while (key_queue_len == 0 && rc != ETIMEDOUT) {
+            rc = pthread_cond_timedwait(&key_queue_cond, &key_queue_mutex,
+                                        &timeout);
+        }
+    } while (usb_connected() && key_queue_len == 0);
+
+    int key = -1;
+    if (key_queue_len > 0) {
+        key = key_queue[0];
+        memcpy(&key_queue[0], &key_queue[1], sizeof(int) * --key_queue_len);
+    }
+    pthread_mutex_unlock(&key_queue_mutex);
+    return key;
+}
+
+bool ScreenRecoveryUI::IsKeyPressed(int key)
+{
+    // This is a volatile static array, don't bother locking
+    return key_pressed[key];
+}
+
+void ScreenRecoveryUI::FlushKeys() {
+    pthread_mutex_lock(&key_queue_mutex);
+    key_queue_len = 0;
+    pthread_mutex_unlock(&key_queue_mutex);
+}
diff --git a/screen_ui.h b/screen_ui.h
new file mode 100644
index 0000000..544f154
--- /dev/null
+++ b/screen_ui.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RECOVERY_SCREEN_UI_H
+#define RECOVERY_SCREEN_UI_H
+
+#include <pthread.h>
+
+#include "ui.h"
+#include "minui/minui.h"
+
+// Implementation of RecoveryUI appropriate for devices with a screen
+// (shows an icon + a progress bar, text logging, menu, etc.)
+class ScreenRecoveryUI : public RecoveryUI {
+  public:
+    ScreenRecoveryUI();
+
+    void Init();
+
+    // overall recovery state ("background image")
+    void SetBackground(Icon icon);
+
+    // progress indicator
+    void SetProgressType(ProgressType type);
+    void ShowProgress(float portion, float seconds);
+    void SetProgress(float fraction);
+
+    // text log
+    void ShowText(bool visible);
+    bool IsTextVisible();
+    bool WasTextEverVisible();
+
+    // key handling
+    int WaitKey();
+    bool IsKeyPressed(int key);
+    void FlushKeys();
+
+    // printing messages
+    void Print(const char* fmt, ...); // __attribute__((format(printf, 1, 2)));
+
+    // menu display
+    void StartMenu(const char* const * headers, const char* const * items,
+                           int initial_selection);
+    int SelectMenu(int sel);
+    void EndMenu();
+
+  private:
+    Icon currentIcon;
+    int installingFrame;
+
+    pthread_mutex_t updateMutex;
+    gr_surface backgroundIcon[3];
+    gr_surface *installationOverlay;
+    gr_surface *progressBarIndeterminate;
+    gr_surface progressBarEmpty;
+    gr_surface progressBarFill;
+
+    ProgressType progressBarType;
+
+    float progressScopeStart, progressScopeSize, progress;
+    double progressScopeTime, progressScopeDuration;
+
+    // true when both graphics pages are the same (except for the
+    // progress bar)
+    bool pagesIdentical;
+
+    static const int kMaxCols = 96;
+    static const int kMaxRows = 32;
+
+    // Log text overlay, displayed when a magic key is pressed
+    char text[kMaxRows][kMaxCols];
+    int text_cols, text_rows;
+    int text_col, text_row, text_top;
+    bool show_text;
+    bool show_text_ever;   // has show_text ever been true?
+
+    char menu[kMaxRows][kMaxCols];
+    bool show_menu;
+    int menu_top, menu_items, menu_sel;
+
+    // Key event input queue
+    pthread_mutex_t key_queue_mutex;
+    pthread_cond_t key_queue_cond;
+    int key_queue[256], key_queue_len;
+    volatile char key_pressed[KEY_MAX + 1];
+    int rel_sum;
+
+    pthread_t progress_t;
+    pthread_t input_t;
+
+    void draw_install_overlay_locked(int frame);
+    void draw_background_locked(Icon icon);
+    void draw_progress_locked();
+    void draw_text_line(int row, const char* t);
+    void draw_screen_locked();
+    void update_screen_locked();
+    void update_progress_locked();
+    static void* progress_thread(void* cookie);
+    static int input_callback(int fd, short revents, void* data);
+    static void* input_thread(void* cookie);
+
+    bool usb_connected();
+
+    void LoadBitmap(const char* filename, gr_surface* surface);
+
+};
+
+#endif  // RECOVERY_UI_H
diff --git a/ui.cpp b/ui.cpp
deleted file mode 100644
index 657a01e..0000000
--- a/ui.cpp
+++ /dev/null
@@ -1,666 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <linux/input.h>
-#include <pthread.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <time.h>
-#include <unistd.h>
-
-#include "common.h"
-#include <cutils/android_reboot.h>
-#include "minui/minui.h"
-#include "recovery_ui.h"
-#include "ui.h"
-
-#define MAX_COLS 96
-#define MAX_ROWS 32
-
-#define CHAR_WIDTH 10
-#define CHAR_HEIGHT 18
-
-#define UI_WAIT_KEY_TIMEOUT_SEC    120
-
-UIParameters ui_parameters = {
-    6,       // indeterminate progress bar frames
-    20,      // fps
-    7,       // installation icon frames (0 == static image)
-    13, 190, // installation icon overlay offset
-};
-
-static pthread_mutex_t gUpdateMutex = PTHREAD_MUTEX_INITIALIZER;
-static gr_surface gBackgroundIcon[NUM_BACKGROUND_ICONS];
-static gr_surface *gInstallationOverlay;
-static gr_surface *gProgressBarIndeterminate;
-static gr_surface gProgressBarEmpty;
-static gr_surface gProgressBarFill;
-
-static const struct { gr_surface* surface; const char *name; } BITMAPS[] = {
-    { &gBackgroundIcon[BACKGROUND_ICON_INSTALLING], "icon_installing" },
-    { &gBackgroundIcon[BACKGROUND_ICON_ERROR],      "icon_error" },
-    { &gProgressBarEmpty,               "progress_empty" },
-    { &gProgressBarFill,                "progress_fill" },
-    { NULL,                             NULL },
-};
-
-static int gCurrentIcon = 0;
-static int gInstallingFrame = 0;
-
-static enum ProgressBarType {
-    PROGRESSBAR_TYPE_NONE,
-    PROGRESSBAR_TYPE_INDETERMINATE,
-    PROGRESSBAR_TYPE_NORMAL,
-} gProgressBarType = PROGRESSBAR_TYPE_NONE;
-
-// Progress bar scope of current operation
-static float gProgressScopeStart = 0, gProgressScopeSize = 0, gProgress = 0;
-static double gProgressScopeTime, gProgressScopeDuration;
-
-// Set to 1 when both graphics pages are the same (except for the progress bar)
-static int gPagesIdentical = 0;
-
-// Log text overlay, displayed when a magic key is pressed
-static char text[MAX_ROWS][MAX_COLS];
-static int text_cols = 0, text_rows = 0;
-static int text_col = 0, text_row = 0, text_top = 0;
-static int show_text = 0;
-static int show_text_ever = 0;   // has show_text ever been 1?
-
-static char menu[MAX_ROWS][MAX_COLS];
-static int show_menu = 0;
-static int menu_top = 0, menu_items = 0, menu_sel = 0;
-
-// Key event input queue
-static pthread_mutex_t key_queue_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t key_queue_cond = PTHREAD_COND_INITIALIZER;
-static int key_queue[256], key_queue_len = 0;
-static volatile char key_pressed[KEY_MAX + 1];
-
-// Return the current time as a double (including fractions of a second).
-static double now() {
-    struct timeval tv;
-    gettimeofday(&tv, NULL);
-    return tv.tv_sec + tv.tv_usec / 1000000.0;
-}
-
-// Draw the given frame over the installation overlay animation.  The
-// background is not cleared or draw with the base icon first; we
-// assume that the frame already contains some other frame of the
-// animation.  Does nothing if no overlay animation is defined.
-// Should only be called with gUpdateMutex locked.
-static void draw_install_overlay_locked(int frame) {
-    if (gInstallationOverlay == NULL) return;
-    gr_surface surface = gInstallationOverlay[frame];
-    int iconWidth = gr_get_width(surface);
-    int iconHeight = gr_get_height(surface);
-    gr_blit(surface, 0, 0, iconWidth, iconHeight,
-            ui_parameters.install_overlay_offset_x,
-            ui_parameters.install_overlay_offset_y);
-}
-
-// Clear the screen and draw the currently selected background icon (if any).
-// Should only be called with gUpdateMutex locked.
-static void draw_background_locked(int icon)
-{
-    gPagesIdentical = 0;
-    gr_color(0, 0, 0, 255);
-    gr_fill(0, 0, gr_fb_width(), gr_fb_height());
-
-    if (icon) {
-        gr_surface surface = gBackgroundIcon[icon];
-        int iconWidth = gr_get_width(surface);
-        int iconHeight = gr_get_height(surface);
-        int iconX = (gr_fb_width() - iconWidth) / 2;
-        int iconY = (gr_fb_height() - iconHeight) / 2;
-        gr_blit(surface, 0, 0, iconWidth, iconHeight, iconX, iconY);
-        if (icon == BACKGROUND_ICON_INSTALLING) {
-            draw_install_overlay_locked(gInstallingFrame);
-        }
-    }
-}
-
-// Draw the progress bar (if any) on the screen.  Does not flip pages.
-// Should only be called with gUpdateMutex locked.
-static void draw_progress_locked()
-{
-    if (gCurrentIcon == BACKGROUND_ICON_INSTALLING) {
-        draw_install_overlay_locked(gInstallingFrame);
-    }
-
-    if (gProgressBarType != PROGRESSBAR_TYPE_NONE) {
-        int iconHeight = gr_get_height(gBackgroundIcon[BACKGROUND_ICON_INSTALLING]);
-        int width = gr_get_width(gProgressBarEmpty);
-        int height = gr_get_height(gProgressBarEmpty);
-
-        int dx = (gr_fb_width() - width)/2;
-        int dy = (3*gr_fb_height() + iconHeight - 2*height)/4;
-
-        // Erase behind the progress bar (in case this was a progress-only update)
-        gr_color(0, 0, 0, 255);
-        gr_fill(dx, dy, width, height);
-
-        if (gProgressBarType == PROGRESSBAR_TYPE_NORMAL) {
-            float progress = gProgressScopeStart + gProgress * gProgressScopeSize;
-            int pos = (int) (progress * width);
-
-            if (pos > 0) {
-                gr_blit(gProgressBarFill, 0, 0, pos, height, dx, dy);
-            }
-            if (pos < width-1) {
-                gr_blit(gProgressBarEmpty, pos, 0, width-pos, height, dx+pos, dy);
-            }
-        }
-
-        if (gProgressBarType == PROGRESSBAR_TYPE_INDETERMINATE) {
-            static int frame = 0;
-            gr_blit(gProgressBarIndeterminate[frame], 0, 0, width, height, dx, dy);
-            frame = (frame + 1) % ui_parameters.indeterminate_frames;
-        }
-    }
-}
-
-static void draw_text_line(int row, const char* t) {
-  if (t[0] != '\0') {
-    gr_text(0, (row+1)*CHAR_HEIGHT-1, t);
-  }
-}
-
-// Redraw everything on the screen.  Does not flip pages.
-// Should only be called with gUpdateMutex locked.
-static void draw_screen_locked(void)
-{
-    draw_background_locked(gCurrentIcon);
-    draw_progress_locked();
-
-    if (show_text) {
-        gr_color(0, 0, 0, 160);
-        gr_fill(0, 0, gr_fb_width(), gr_fb_height());
-
-        int i = 0;
-        if (show_menu) {
-            gr_color(64, 96, 255, 255);
-            gr_fill(0, (menu_top+menu_sel) * CHAR_HEIGHT,
-                    gr_fb_width(), (menu_top+menu_sel+1)*CHAR_HEIGHT+1);
-
-            for (; i < menu_top + menu_items; ++i) {
-                if (i == menu_top + menu_sel) {
-                    gr_color(255, 255, 255, 255);
-                    draw_text_line(i, menu[i]);
-                    gr_color(64, 96, 255, 255);
-                } else {
-                    draw_text_line(i, menu[i]);
-                }
-            }
-            gr_fill(0, i*CHAR_HEIGHT+CHAR_HEIGHT/2-1,
-                    gr_fb_width(), i*CHAR_HEIGHT+CHAR_HEIGHT/2+1);
-            ++i;
-        }
-
-        gr_color(255, 255, 0, 255);
-
-        for (; i < text_rows; ++i) {
-            draw_text_line(i, text[(i+text_top) % text_rows]);
-        }
-    }
-}
-
-// Redraw everything on the screen and flip the screen (make it visible).
-// Should only be called with gUpdateMutex locked.
-static void update_screen_locked(void)
-{
-    draw_screen_locked();
-    gr_flip();
-}
-
-// Updates only the progress bar, if possible, otherwise redraws the screen.
-// Should only be called with gUpdateMutex locked.
-static void update_progress_locked(void)
-{
-    if (show_text || !gPagesIdentical) {
-        draw_screen_locked();    // Must redraw the whole screen
-        gPagesIdentical = 1;
-    } else {
-        draw_progress_locked();  // Draw only the progress bar and overlays
-    }
-    gr_flip();
-}
-
-// Keeps the progress bar updated, even when the process is otherwise busy.
-static void *progress_thread(void *cookie)
-{
-    double interval = 1.0 / ui_parameters.update_fps;
-    for (;;) {
-        double start = now();
-        pthread_mutex_lock(&gUpdateMutex);
-
-        int redraw = 0;
-
-        // update the installation animation, if active
-        // skip this if we have a text overlay (too expensive to update)
-        if (gCurrentIcon == BACKGROUND_ICON_INSTALLING &&
-            ui_parameters.installing_frames > 0 &&
-            !show_text) {
-            gInstallingFrame =
-                (gInstallingFrame + 1) % ui_parameters.installing_frames;
-            redraw = 1;
-        }
-
-        // update the progress bar animation, if active
-        // skip this if we have a text overlay (too expensive to update)
-        if (gProgressBarType == PROGRESSBAR_TYPE_INDETERMINATE && !show_text) {
-            redraw = 1;
-        }
-
-        // move the progress bar forward on timed intervals, if configured
-        int duration = gProgressScopeDuration;
-        if (gProgressBarType == PROGRESSBAR_TYPE_NORMAL && duration > 0) {
-            double elapsed = now() - gProgressScopeTime;
-            float progress = 1.0 * elapsed / duration;
-            if (progress > 1.0) progress = 1.0;
-            if (progress > gProgress) {
-                gProgress = progress;
-                redraw = 1;
-            }
-        }
-
-        if (redraw) update_progress_locked();
-
-        pthread_mutex_unlock(&gUpdateMutex);
-        double end = now();
-        // minimum of 20ms delay between frames
-        double delay = interval - (end-start);
-        if (delay < 0.02) delay = 0.02;
-        usleep((long)(delay * 1000000));
-    }
-    return NULL;
-}
-
-static int rel_sum = 0;
-
-static int input_callback(int fd, short revents, void *data)
-{
-    struct input_event ev;
-    int ret;
-    int fake_key = 0;
-
-    ret = ev_get_input(fd, revents, &ev);
-    if (ret)
-        return -1;
-
-    if (ev.type == EV_SYN) {
-        return 0;
-    } else if (ev.type == EV_REL) {
-        if (ev.code == REL_Y) {
-            // accumulate the up or down motion reported by
-            // the trackball.  When it exceeds a threshold
-            // (positive or negative), fake an up/down
-            // key event.
-            rel_sum += ev.value;
-            if (rel_sum > 3) {
-                fake_key = 1;
-                ev.type = EV_KEY;
-                ev.code = KEY_DOWN;
-                ev.value = 1;
-                rel_sum = 0;
-            } else if (rel_sum < -3) {
-                fake_key = 1;
-                ev.type = EV_KEY;
-                ev.code = KEY_UP;
-                ev.value = 1;
-                rel_sum = 0;
-            }
-        }
-    } else {
-        rel_sum = 0;
-    }
-
-    if (ev.type != EV_KEY || ev.code > KEY_MAX)
-        return 0;
-
-    pthread_mutex_lock(&key_queue_mutex);
-    if (!fake_key) {
-        // our "fake" keys only report a key-down event (no
-        // key-up), so don't record them in the key_pressed
-        // table.
-        key_pressed[ev.code] = ev.value;
-    }
-    const int queue_max = sizeof(key_queue) / sizeof(key_queue[0]);
-    if (ev.value > 0 && key_queue_len < queue_max) {
-        key_queue[key_queue_len++] = ev.code;
-        pthread_cond_signal(&key_queue_cond);
-    }
-    pthread_mutex_unlock(&key_queue_mutex);
-
-    if (ev.value > 0 && device_toggle_display(key_pressed, ev.code)) {
-        pthread_mutex_lock(&gUpdateMutex);
-        show_text = !show_text;
-        if (show_text) show_text_ever = 1;
-        update_screen_locked();
-        pthread_mutex_unlock(&gUpdateMutex);
-    }
-
-    if (ev.value > 0 && device_reboot_now(key_pressed, ev.code)) {
-        android_reboot(ANDROID_RB_RESTART, 0, 0);
-    }
-
-    return 0;
-}
-
-// Reads input events, handles special hot keys, and adds to the key queue.
-static void *input_thread(void *cookie)
-{
-    for (;;) {
-        if (!ev_wait(-1))
-            ev_dispatch();
-    }
-    return NULL;
-}
-
-void ui_init(void)
-{
-    gr_init();
-    ev_init(input_callback, NULL);
-
-    text_col = text_row = 0;
-    text_rows = gr_fb_height() / CHAR_HEIGHT;
-    if (text_rows > MAX_ROWS) text_rows = MAX_ROWS;
-    text_top = 1;
-
-    text_cols = gr_fb_width() / CHAR_WIDTH;
-    if (text_cols > MAX_COLS - 1) text_cols = MAX_COLS - 1;
-
-    int i;
-    for (i = 0; BITMAPS[i].name != NULL; ++i) {
-        int result = res_create_surface(BITMAPS[i].name, BITMAPS[i].surface);
-        if (result < 0) {
-            LOGE("Missing bitmap %s\n(Code %d)\n", BITMAPS[i].name, result);
-        }
-    }
-
-    gProgressBarIndeterminate = (gr_surface*)malloc(ui_parameters.indeterminate_frames *
-                                                    sizeof(gr_surface));
-    for (i = 0; i < ui_parameters.indeterminate_frames; ++i) {
-        char filename[40];
-        // "indeterminate01.png", "indeterminate02.png", ...
-        sprintf(filename, "indeterminate%02d", i+1);
-        int result = res_create_surface(filename, gProgressBarIndeterminate+i);
-        if (result < 0) {
-            LOGE("Missing bitmap %s\n(Code %d)\n", filename, result);
-        }
-    }
-
-    if (ui_parameters.installing_frames > 0) {
-        gInstallationOverlay = (gr_surface*)malloc(ui_parameters.installing_frames *
-                                                   sizeof(gr_surface));
-        for (i = 0; i < ui_parameters.installing_frames; ++i) {
-            char filename[40];
-            // "icon_installing_overlay01.png",
-            // "icon_installing_overlay02.png", ...
-            sprintf(filename, "icon_installing_overlay%02d", i+1);
-            int result = res_create_surface(filename, gInstallationOverlay+i);
-            if (result < 0) {
-                LOGE("Missing bitmap %s\n(Code %d)\n", filename, result);
-            }
-        }
-
-        // Adjust the offset to account for the positioning of the
-        // base image on the screen.
-        if (gBackgroundIcon[BACKGROUND_ICON_INSTALLING] != NULL) {
-            gr_surface bg = gBackgroundIcon[BACKGROUND_ICON_INSTALLING];
-            ui_parameters.install_overlay_offset_x +=
-                (gr_fb_width() - gr_get_width(bg)) / 2;
-            ui_parameters.install_overlay_offset_y +=
-                (gr_fb_height() - gr_get_height(bg)) / 2;
-        }
-    } else {
-        gInstallationOverlay = NULL;
-    }
-
-    pthread_t t;
-    pthread_create(&t, NULL, progress_thread, NULL);
-    pthread_create(&t, NULL, input_thread, NULL);
-}
-
-void ui_set_background(int icon)
-{
-    pthread_mutex_lock(&gUpdateMutex);
-    gCurrentIcon = icon;
-    update_screen_locked();
-    pthread_mutex_unlock(&gUpdateMutex);
-}
-
-void ui_show_indeterminate_progress()
-{
-    pthread_mutex_lock(&gUpdateMutex);
-    if (gProgressBarType != PROGRESSBAR_TYPE_INDETERMINATE) {
-        gProgressBarType = PROGRESSBAR_TYPE_INDETERMINATE;
-        update_progress_locked();
-    }
-    pthread_mutex_unlock(&gUpdateMutex);
-}
-
-void ui_show_progress(float portion, int seconds)
-{
-    pthread_mutex_lock(&gUpdateMutex);
-    gProgressBarType = PROGRESSBAR_TYPE_NORMAL;
-    gProgressScopeStart += gProgressScopeSize;
-    gProgressScopeSize = portion;
-    gProgressScopeTime = now();
-    gProgressScopeDuration = seconds;
-    gProgress = 0;
-    update_progress_locked();
-    pthread_mutex_unlock(&gUpdateMutex);
-}
-
-void ui_set_progress(float fraction)
-{
-    pthread_mutex_lock(&gUpdateMutex);
-    if (fraction < 0.0) fraction = 0.0;
-    if (fraction > 1.0) fraction = 1.0;
-    if (gProgressBarType == PROGRESSBAR_TYPE_NORMAL && fraction > gProgress) {
-        // Skip updates that aren't visibly different.
-        int width = gr_get_width(gProgressBarIndeterminate[0]);
-        float scale = width * gProgressScopeSize;
-        if ((int) (gProgress * scale) != (int) (fraction * scale)) {
-            gProgress = fraction;
-            update_progress_locked();
-        }
-    }
-    pthread_mutex_unlock(&gUpdateMutex);
-}
-
-void ui_reset_progress()
-{
-    pthread_mutex_lock(&gUpdateMutex);
-    gProgressBarType = PROGRESSBAR_TYPE_NONE;
-    gProgressScopeStart = gProgressScopeSize = 0;
-    gProgressScopeTime = gProgressScopeDuration = 0;
-    gProgress = 0;
-    update_screen_locked();
-    pthread_mutex_unlock(&gUpdateMutex);
-}
-
-void ui_print(const char *fmt, ...)
-{
-    char buf[256];
-    va_list ap;
-    va_start(ap, fmt);
-    vsnprintf(buf, 256, fmt, ap);
-    va_end(ap);
-
-    fputs(buf, stdout);
-
-    // This can get called before ui_init(), so be careful.
-    pthread_mutex_lock(&gUpdateMutex);
-    if (text_rows > 0 && text_cols > 0) {
-        char *ptr;
-        for (ptr = buf; *ptr != '\0'; ++ptr) {
-            if (*ptr == '\n' || text_col >= text_cols) {
-                text[text_row][text_col] = '\0';
-                text_col = 0;
-                text_row = (text_row + 1) % text_rows;
-                if (text_row == text_top) text_top = (text_top + 1) % text_rows;
-            }
-            if (*ptr != '\n') text[text_row][text_col++] = *ptr;
-        }
-        text[text_row][text_col] = '\0';
-        update_screen_locked();
-    }
-    pthread_mutex_unlock(&gUpdateMutex);
-}
-
-void ui_start_menu(const char* const * headers, const char* const * items,
-                   int initial_selection) {
-    int i;
-    pthread_mutex_lock(&gUpdateMutex);
-    if (text_rows > 0 && text_cols > 0) {
-        for (i = 0; i < text_rows; ++i) {
-            if (headers[i] == NULL) break;
-            strncpy(menu[i], headers[i], text_cols-1);
-            menu[i][text_cols-1] = '\0';
-        }
-        menu_top = i;
-        for (; i < text_rows; ++i) {
-            if (items[i-menu_top] == NULL) break;
-            strncpy(menu[i], items[i-menu_top], text_cols-1);
-            menu[i][text_cols-1] = '\0';
-        }
-        menu_items = i - menu_top;
-        show_menu = 1;
-        menu_sel = initial_selection;
-        update_screen_locked();
-    }
-    pthread_mutex_unlock(&gUpdateMutex);
-}
-
-int ui_menu_select(int sel) {
-    int old_sel;
-    pthread_mutex_lock(&gUpdateMutex);
-    if (show_menu > 0) {
-        old_sel = menu_sel;
-        menu_sel = sel;
-        if (menu_sel < 0) menu_sel = 0;
-        if (menu_sel >= menu_items) menu_sel = menu_items-1;
-        sel = menu_sel;
-        if (menu_sel != old_sel) update_screen_locked();
-    }
-    pthread_mutex_unlock(&gUpdateMutex);
-    return sel;
-}
-
-void ui_end_menu() {
-    int i;
-    pthread_mutex_lock(&gUpdateMutex);
-    if (show_menu > 0 && text_rows > 0 && text_cols > 0) {
-        show_menu = 0;
-        update_screen_locked();
-    }
-    pthread_mutex_unlock(&gUpdateMutex);
-}
-
-int ui_text_visible()
-{
-    pthread_mutex_lock(&gUpdateMutex);
-    int visible = show_text;
-    pthread_mutex_unlock(&gUpdateMutex);
-    return visible;
-}
-
-int ui_text_ever_visible()
-{
-    pthread_mutex_lock(&gUpdateMutex);
-    int ever_visible = show_text_ever;
-    pthread_mutex_unlock(&gUpdateMutex);
-    return ever_visible;
-}
-
-void ui_show_text(int visible)
-{
-    pthread_mutex_lock(&gUpdateMutex);
-    show_text = visible;
-    if (show_text) show_text_ever = 1;
-    update_screen_locked();
-    pthread_mutex_unlock(&gUpdateMutex);
-}
-
-// Return true if USB is connected.
-static int usb_connected() {
-    int fd = open("/sys/class/android_usb/android0/state", O_RDONLY);
-    if (fd < 0) {
-        printf("failed to open /sys/class/android_usb/android0/state: %s\n",
-               strerror(errno));
-        return 0;
-    }
-
-    char buf;
-    /* USB is connected if android_usb state is CONNECTED or CONFIGURED */
-    int connected = (read(fd, &buf, 1) == 1) && (buf == 'C');
-    if (close(fd) < 0) {
-        printf("failed to close /sys/class/android_usb/android0/state: %s\n",
-               strerror(errno));
-    }
-    return connected;
-}
-
-int ui_wait_key()
-{
-    pthread_mutex_lock(&key_queue_mutex);
-
-    // Time out after UI_WAIT_KEY_TIMEOUT_SEC, unless a USB cable is
-    // plugged in.
-    do {
-        struct timeval now;
-        struct timespec timeout;
-        gettimeofday(&now, NULL);
-        timeout.tv_sec = now.tv_sec;
-        timeout.tv_nsec = now.tv_usec * 1000;
-        timeout.tv_sec += UI_WAIT_KEY_TIMEOUT_SEC;
-
-        int rc = 0;
-        while (key_queue_len == 0 && rc != ETIMEDOUT) {
-            rc = pthread_cond_timedwait(&key_queue_cond, &key_queue_mutex,
-                                        &timeout);
-        }
-    } while (usb_connected() && key_queue_len == 0);
-
-    int key = -1;
-    if (key_queue_len > 0) {
-        key = key_queue[0];
-        memcpy(&key_queue[0], &key_queue[1], sizeof(int) * --key_queue_len);
-    }
-    pthread_mutex_unlock(&key_queue_mutex);
-    return key;
-}
-
-int ui_key_pressed(int key)
-{
-    // This is a volatile static array, don't bother locking
-    return key_pressed[key];
-}
-
-void ui_clear_key_queue() {
-    pthread_mutex_lock(&key_queue_mutex);
-    key_queue_len = 0;
-    pthread_mutex_unlock(&key_queue_mutex);
-}
diff --git a/ui.h b/ui.h
index fa7a53c..6150bfd 100644
--- a/ui.h
+++ b/ui.h
@@ -17,59 +17,68 @@
 #ifndef RECOVERY_UI_H
 #define RECOVERY_UI_H
 
-// Initialize the graphics system.
-void ui_init();
+// Abstract class for controlling the user interface during recovery.
+class RecoveryUI {
+  public:
+    virtual ~RecoveryUI() { }
 
-// Use KEY_* codes from <linux/input.h> or KEY_DREAM_* from "minui/minui.h".
-int ui_wait_key();            // waits for a key/button press, returns the code
-int ui_key_pressed(int key);  // returns >0 if the code is currently pressed
-int ui_text_visible();        // returns >0 if text log is currently visible
-int ui_text_ever_visible();   // returns >0 if text log was ever visible
-void ui_show_text(int visible);
-void ui_clear_key_queue();
+    // Initialize the object; called before anything else.
+    virtual void Init() = 0;
 
-// Write a message to the on-screen log shown with Alt-L (also to stderr).
-// The screen is small, and users may need to report these messages to support,
-// so keep the output short and not too cryptic.
-void ui_print(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
+    // Set the overall recovery state ("background image").
+    enum Icon { NONE, INSTALLING, ERROR };
+    virtual void SetBackground(Icon icon) = 0;
 
-// Display some header text followed by a menu of items, which appears
-// at the top of the screen (in place of any scrolling ui_print()
-// output, if necessary).
-void ui_start_menu(const char* const * headers, const char* const * items,
-                   int initial_selection);
-// Set the menu highlight to the given index, and return it (capped to
-// the range [0..numitems).
-int ui_menu_select(int sel);
-// End menu mode, resetting the text overlay so that ui_print()
-// statements will be displayed.
-void ui_end_menu();
+    // --- progress indicator ---
+    enum ProgressType { EMPTY, INDETERMINATE, DETERMINATE };
+    virtual void SetProgressType(ProgressType determinate) = 0;
 
-// Set the icon (normally the only thing visible besides the progress bar).
-enum {
-  BACKGROUND_ICON_NONE,
-  BACKGROUND_ICON_INSTALLING,
-  BACKGROUND_ICON_ERROR,
-  NUM_BACKGROUND_ICONS
+    // Show a progress bar and define the scope of the next operation:
+    //   portion - fraction of the progress bar the next operation will use
+    //   seconds - expected time interval (progress bar moves at this minimum rate)
+    virtual void ShowProgress(float portion, float seconds) = 0;
+
+    // Set progress bar position (0.0 - 1.0 within the scope defined
+    // by the last call to ShowProgress).
+    virtual void SetProgress(float fraction) = 0;
+
+    // --- text log ---
+
+    virtual void ShowText(bool visible) = 0;
+
+    virtual bool IsTextVisible() = 0;
+
+    virtual bool WasTextEverVisible() = 0;
+
+    // Write a message to the on-screen log (shown if the user has
+    // toggled on the text display).
+    virtual void Print(const char* fmt, ...) = 0; // __attribute__((format(printf, 1, 2))) = 0;
+
+    // --- key handling ---
+
+    // Wait for keypress and return it.  May return -1 after timeout.
+    virtual int WaitKey() = 0;
+
+    virtual bool IsKeyPressed(int key) = 0;
+
+    // Erase any queued-up keys.
+    virtual void FlushKeys() = 0;
+
+    // --- menu display ---
+
+    // Display some header text followed by a menu of items, which appears
+    // at the top of the screen (in place of any scrolling ui_print()
+    // output, if necessary).
+    virtual void StartMenu(const char* const * headers, const char* const * items,
+                           int initial_selection) = 0;
+
+    // Set the menu highlight to the given index, and return it (capped to
+    // the range [0..numitems).
+    virtual int SelectMenu(int sel) = 0;
+
+    // End menu mode, resetting the text overlay so that ui_print()
+    // statements will be displayed.
+    virtual void EndMenu() = 0;
 };
-void ui_set_background(int icon);
-
-// Show a progress bar and define the scope of the next operation:
-//   portion - fraction of the progress bar the next operation will use
-//   seconds - expected time interval (progress bar moves at this minimum rate)
-void ui_show_progress(float portion, int seconds);
-void ui_set_progress(float fraction);  // 0.0 - 1.0 within the defined scope
-
-// Default allocation of progress bar segments to operations
-static const int VERIFICATION_PROGRESS_TIME = 60;
-static const float VERIFICATION_PROGRESS_FRACTION = 0.25;
-static const float DEFAULT_FILES_PROGRESS_FRACTION = 0.4;
-static const float DEFAULT_IMAGE_PROGRESS_FRACTION = 0.1;
-
-// Show a rotating "barberpole" for ongoing operations.  Updates automatically.
-void ui_show_indeterminate_progress();
-
-// Hide and reset the progress bar.
-void ui_reset_progress();
 
 #endif  // RECOVERY_UI_H
diff --git a/verifier.cpp b/verifier.cpp
index 58ca723..1c5a41d 100644
--- a/verifier.cpp
+++ b/verifier.cpp
@@ -25,6 +25,8 @@
 #include <stdio.h>
 #include <errno.h>
 
+extern RecoveryUI* ui;
+
 // Look for an RSA signature embedded in the .ZIP file comment given
 // the path to the zip.  Verify it matches one of the given public
 // keys.
@@ -33,7 +35,7 @@
 // or no key matches the signature).
 
 int verify_file(const char* path, const RSAPublicKey *pKeys, unsigned int numKeys) {
-    ui_set_progress(0.0);
+    ui->SetProgress(0.0);
 
     FILE* f = fopen(path, "rb");
     if (f == NULL) {
@@ -161,7 +163,7 @@
         so_far += size;
         double f = so_far / (double)signed_len;
         if (f > frac + 0.02 || size == so_far) {
-            ui_set_progress(f);
+            ui->SetProgress(f);
             frac = f;
         }
     }
