diff --git a/Android.mk b/Android.mk
index 74e7b1d..d96849f 100644
--- a/Android.mk
+++ b/Android.mk
@@ -40,6 +40,7 @@
     screen_ui.cpp \
     ui.cpp \
     verifier.cpp \
+    wear_ui.cpp \
 
 LOCAL_MODULE := recovery
 
diff --git a/wear_ui.cpp b/wear_ui.cpp
new file mode 100644
index 0000000..4ae42c4
--- /dev/null
+++ b/wear_ui.cpp
@@ -0,0 +1,650 @@
+/*
+ * Copyright (C) 2014 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 <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 <vector>
+
+#include "common.h"
+#include "device.h"
+#include "minui/minui.h"
+#include "wear_ui.h"
+#include "ui.h"
+#include "cutils/properties.h"
+#include "base/strings.h"
+
+static int char_width;
+static int char_height;
+
+// 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 WearRecoveryUI* 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;
+}
+
+WearRecoveryUI::WearRecoveryUI() :
+    progress_bar_height(3),
+    progress_bar_width(200),
+    progress_bar_y(259),
+    outer_height(0),
+    outer_width(0),
+    menu_unusable_rows(0),
+    intro_frames(22),
+    loop_frames(60),
+    currentIcon(NONE),
+    intro_done(false),
+    current_frame(0),
+    animation_fps(30),
+    rtl_locale(false),
+    progressBarType(EMPTY),
+    progressScopeStart(0),
+    progressScopeSize(0),
+    progress(0),
+    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_items(0),
+    menu_sel(0) {
+
+    for (size_t i = 0; i < 5; i++)
+        backgroundIcon[i] = NULL;
+
+    pthread_mutex_init(&updateMutex, NULL);
+    self = this;
+}
+
+// Draw background frame on the screen.  Does not flip pages.
+// Should only be called with updateMutex locked.
+void WearRecoveryUI::draw_background_locked(Icon icon)
+{
+    gr_color(0, 0, 0, 255);
+    gr_fill(0, 0, gr_fb_width(), gr_fb_height());
+
+    if (icon) {
+        GRSurface* surface;
+        if (icon == INSTALLING_UPDATE || icon == ERASING) {
+            if (!intro_done) {
+                surface = introFrames[current_frame];
+            } else {
+                surface = loopFrames[current_frame];
+            }
+        }
+        else {
+            surface = backgroundIcon[icon];
+        }
+
+        int width = gr_get_width(surface);
+        int height = gr_get_height(surface);
+
+        int x = (gr_fb_width() - width) / 2;
+        int y = (gr_fb_height() - height) / 2;
+
+        gr_blit(surface, 0, 0, width, height, x, y);
+    }
+}
+
+// Draw the progress bar (if any) on the screen.  Does not flip pages.
+// Should only be called with updateMutex locked.
+void WearRecoveryUI::draw_progress_locked()
+{
+    if (currentIcon == ERROR) return;
+    if (progressBarType != DETERMINATE) return;
+
+    int width = progress_bar_width;
+    int height = progress_bar_height;
+    int dx = (gr_fb_width() - width)/2;
+    int dy = progress_bar_y;
+
+    float p = progressScopeStart + progress * progressScopeSize;
+    int pos = (int) (p * width);
+
+    gr_color(0x43, 0x43, 0x43, 0xff);
+    gr_fill(dx, dy, dx + width, dy + height);
+
+    if (pos > 0) {
+        gr_color(0x02, 0xa8, 0xf3, 255);
+        if (rtl_locale) {
+            // Fill the progress bar from right to left.
+            gr_fill(dx + width - pos, dy, dx + width, dy + height);
+        } else {
+            // Fill the progress bar from left to right.
+            gr_fill(dx, dy, dx + pos, dy + height);
+        }
+    }
+}
+
+void WearRecoveryUI::SetColor(UIElement e) {
+    switch (e) {
+        case HEADER:
+            gr_color(247, 0, 6, 255);
+            break;
+        case MENU:
+        case MENU_SEL_BG:
+            gr_color(0, 106, 157, 255);
+            break;
+        case MENU_SEL_FG:
+            gr_color(255, 255, 255, 255);
+            break;
+        case LOG:
+            gr_color(249, 194, 0, 255);
+            break;
+        case TEXT_FILL:
+            gr_color(0, 0, 0, 160);
+            break;
+        default:
+            gr_color(255, 255, 255, 255);
+            break;
+    }
+}
+
+void WearRecoveryUI::DrawTextLine(int x, int* y, const char* line, bool bold) {
+    gr_text(x, *y, line, bold);
+    *y += char_height + 4;
+}
+
+void WearRecoveryUI::DrawTextLines(int x, int* y, const char* const* lines) {
+    for (size_t i = 0; lines != nullptr && lines[i] != nullptr; ++i) {
+        DrawTextLine(x, y, lines[i], false);
+    }
+}
+
+static const char* HEADERS[] = {
+    "Swipe up/down to move.",
+    "Swipe left/right to select.",
+    "",
+    NULL
+};
+
+void WearRecoveryUI::draw_screen_locked()
+{
+    draw_background_locked(currentIcon);
+    draw_progress_locked();
+    char cur_selection_str[50];
+
+    if (show_text) {
+        SetColor(TEXT_FILL);
+        gr_fill(0, 0, gr_fb_width(), gr_fb_height());
+
+        int y = outer_height;
+        int x = outer_width;
+        if (show_menu) {
+            char recovery_fingerprint[PROPERTY_VALUE_MAX];
+            property_get("ro.bootimage.build.fingerprint", recovery_fingerprint, "");
+            SetColor(HEADER);
+            DrawTextLine(x + 4, &y, "Android Recovery", true);
+            for (auto& chunk: android::base::Split(recovery_fingerprint, ":")) {
+                DrawTextLine(x +4, &y, chunk.c_str(), false);
+            }
+
+            // This is actually the help strings.
+            DrawTextLines(x + 4, &y, HEADERS);
+            SetColor(HEADER);
+            DrawTextLines(x + 4, &y, menu_headers_);
+
+            // Show the current menu item number in relation to total number if
+            // items don't fit on the screen.
+            if (menu_items > menu_end - menu_start) {
+                sprintf(cur_selection_str, "Current item: %d/%d", menu_sel + 1, menu_items);
+                gr_text(x+4, y, cur_selection_str, 1);
+                y += char_height+4;
+            }
+
+            // Menu begins here
+            SetColor(MENU);
+
+            for (int i = menu_start; i < menu_end; ++i) {
+
+                if (i == menu_sel) {
+                    // draw the highlight bar
+                    SetColor(MENU_SEL_BG);
+                    gr_fill(x, y-2, gr_fb_width()-x, y+char_height+2);
+                    // white text of selected item
+                    SetColor(MENU_SEL_FG);
+                    if (menu[i][0]) gr_text(x+4, y, menu[i], 1);
+                    SetColor(MENU);
+                } else {
+                    if (menu[i][0]) gr_text(x+4, y, menu[i], 0);
+                }
+                y += char_height+4;
+            }
+            SetColor(MENU);
+            y += 4;
+            gr_fill(0, y, gr_fb_width(), y+2);
+            y += 4;
+        }
+
+        SetColor(LOG);
+
+        // 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;
+        size_t count = 0;
+        for (int ty = gr_fb_height() - char_height - outer_height;
+             ty > y+2 && count < text_rows;
+             ty -= char_height, ++count) {
+            gr_text(x+4, ty, text[row], 0);
+            --row;
+            if (row < 0) row = text_rows-1;
+        }
+    }
+}
+
+void WearRecoveryUI::update_screen_locked()
+{
+    draw_screen_locked();
+    gr_flip();
+}
+
+// Keeps the progress bar updated, even when the process is otherwise busy.
+void* WearRecoveryUI::progress_thread(void *cookie) {
+    self->progress_loop();
+    return NULL;
+}
+
+void WearRecoveryUI::progress_loop() {
+    double interval = 1.0 / animation_fps;
+    for (;;) {
+        double start = now();
+        pthread_mutex_lock(&updateMutex);
+        int redraw = 0;
+
+        if ((currentIcon == INSTALLING_UPDATE || currentIcon == ERASING)
+                                                            && !show_text) {
+            if (!intro_done) {
+                if (current_frame == intro_frames - 1) {
+                    intro_done = true;
+                    current_frame = 0;
+                } else {
+                    current_frame++;
+                }
+            } else {
+                current_frame = (current_frame + 1) % loop_frames;
+            }
+            redraw = 1;
+        }
+
+        // move the progress bar forward on timed intervals, if configured
+        int duration = progressScopeDuration;
+        if (progressBarType == DETERMINATE && duration > 0) {
+            double elapsed = now() - progressScopeTime;
+            float p = 1.0 * elapsed / duration;
+            if (p > 1.0) p = 1.0;
+            if (p > progress) {
+                progress = p;
+                redraw = 1;
+            }
+        }
+
+        if (redraw)
+            update_screen_locked();
+
+        pthread_mutex_unlock(&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));
+    }
+}
+
+void WearRecoveryUI::LoadBitmap(const char* filename, GRSurface** surface) {
+    int result = res_create_display_surface(filename, surface);
+    if (result < 0) {
+        LOGE("missing bitmap %s\n(Code %d)\n", filename, result);
+    }
+}
+
+void WearRecoveryUI::Init()
+{
+    gr_init();
+
+    gr_font_size(&char_width, &char_height);
+
+    text_col = text_row = 0;
+    text_rows = (gr_fb_height()) / char_height;
+    visible_text_rows = (gr_fb_height() - (outer_height * 2)) / char_height;
+    if (text_rows > kMaxRows) text_rows = kMaxRows;
+    text_top = 1;
+
+    text_cols = (gr_fb_width() - (outer_width * 2)) / char_width;
+    if (text_cols > kMaxCols - 1) text_cols = kMaxCols - 1;
+
+    LoadBitmap("icon_installing", &backgroundIcon[INSTALLING_UPDATE]);
+    backgroundIcon[ERASING] = backgroundIcon[INSTALLING_UPDATE];
+    LoadBitmap("icon_error", &backgroundIcon[ERROR]);
+    backgroundIcon[NO_COMMAND] = backgroundIcon[ERROR];
+
+    introFrames = (GRSurface**)malloc(intro_frames * sizeof(GRSurface*));
+    for (int i = 0; i < intro_frames; ++i) {
+        char filename[40];
+        sprintf(filename, "intro%02d", i);
+        LoadBitmap(filename, introFrames + i);
+    }
+
+    loopFrames = (GRSurface**)malloc(loop_frames * sizeof(GRSurface*));
+    for (int i = 0; i < loop_frames; ++i) {
+        char filename[40];
+        sprintf(filename, "loop%02d", i);
+        LoadBitmap(filename, loopFrames + i);
+    }
+
+    pthread_create(&progress_t, NULL, progress_thread, NULL);
+    RecoveryUI::Init();
+}
+
+void WearRecoveryUI::SetLocale(const char* locale) {
+    if (locale) {
+        char* lang = strdup(locale);
+        for (char* p = lang; *p; ++p) {
+            if (*p == '_') {
+                *p = '\0';
+                break;
+            }
+        }
+
+        // A bit cheesy: keep an explicit list of supported languages
+        // that are RTL.
+        if (strcmp(lang, "ar") == 0 ||   // Arabic
+            strcmp(lang, "fa") == 0 ||   // Persian (Farsi)
+            strcmp(lang, "he") == 0 ||   // Hebrew (new language code)
+            strcmp(lang, "iw") == 0 ||   // Hebrew (old language code)
+            strcmp(lang, "ur") == 0) {   // Urdu
+            rtl_locale = true;
+        }
+        free(lang);
+    }
+}
+
+void WearRecoveryUI::SetBackground(Icon icon)
+{
+    pthread_mutex_lock(&updateMutex);
+    currentIcon = icon;
+    update_screen_locked();
+    pthread_mutex_unlock(&updateMutex);
+}
+
+void WearRecoveryUI::SetProgressType(ProgressType type)
+{
+    pthread_mutex_lock(&updateMutex);
+    if (progressBarType != type) {
+        progressBarType = type;
+    }
+    progressScopeStart = 0;
+    progressScopeSize = 0;
+    progress = 0;
+    update_screen_locked();
+    pthread_mutex_unlock(&updateMutex);
+}
+
+void WearRecoveryUI::ShowProgress(float portion, float seconds)
+{
+    pthread_mutex_lock(&updateMutex);
+    progressBarType = DETERMINATE;
+    progressScopeStart += progressScopeSize;
+    progressScopeSize = portion;
+    progressScopeTime = now();
+    progressScopeDuration = seconds;
+    progress = 0;
+    update_screen_locked();
+    pthread_mutex_unlock(&updateMutex);
+}
+
+void WearRecoveryUI::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 = progress_bar_width;
+        float scale = width * progressScopeSize;
+        if ((int) (progress * scale) != (int) (fraction * scale)) {
+            progress = fraction;
+            update_screen_locked();
+        }
+    }
+    pthread_mutex_unlock(&updateMutex);
+}
+
+void WearRecoveryUI::SetStage(int current, int max)
+{
+}
+
+void WearRecoveryUI::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 WearRecoveryUI::StartMenu(const char* const * headers, const char* const * items,
+                                 int initial_selection) {
+    pthread_mutex_lock(&updateMutex);
+    if (text_rows > 0 && text_cols > 0) {
+        menu_headers_ = headers;
+        size_t i = 0;
+        for (; i < text_rows && items[i] != nullptr; i++) {
+            strncpy(menu[i], items[i], text_cols - 1);
+            menu[i][text_cols - 1] = '\0';
+        }
+        menu_items = i;
+        show_menu = 1;
+        menu_sel = initial_selection;
+        menu_start = 0;
+        menu_end = visible_text_rows - 1 - menu_unusable_rows;
+        if (menu_items <= menu_end)
+          menu_end = menu_items;
+        update_screen_locked();
+    }
+    pthread_mutex_unlock(&updateMutex);
+}
+
+int WearRecoveryUI::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;
+        if (menu_sel < menu_start) {
+          menu_start--;
+          menu_end--;
+        } else if (menu_sel >= menu_end && menu_sel < menu_items) {
+          menu_end++;
+          menu_start++;
+        }
+        sel = menu_sel;
+        if (menu_sel != old_sel) update_screen_locked();
+    }
+    pthread_mutex_unlock(&updateMutex);
+    return sel;
+}
+
+void WearRecoveryUI::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 WearRecoveryUI::IsTextVisible()
+{
+    pthread_mutex_lock(&updateMutex);
+    int visible = show_text;
+    pthread_mutex_unlock(&updateMutex);
+    return visible;
+}
+
+bool WearRecoveryUI::WasTextEverVisible()
+{
+    pthread_mutex_lock(&updateMutex);
+    int ever_visible = show_text_ever;
+    pthread_mutex_unlock(&updateMutex);
+    return ever_visible;
+}
+
+void WearRecoveryUI::ShowText(bool visible)
+{
+    pthread_mutex_lock(&updateMutex);
+    // Don't show text during ota install or factory reset
+    if (currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) {
+        pthread_mutex_unlock(&updateMutex);
+        return;
+    }
+    show_text = visible;
+    if (show_text) show_text_ever = 1;
+    update_screen_locked();
+    pthread_mutex_unlock(&updateMutex);
+}
+
+void WearRecoveryUI::Redraw()
+{
+    pthread_mutex_lock(&updateMutex);
+    update_screen_locked();
+    pthread_mutex_unlock(&updateMutex);
+}
+
+void WearRecoveryUI::ShowFile(FILE* fp) {
+    std::vector<long> offsets;
+    offsets.push_back(ftell(fp));
+    ClearText();
+
+    struct stat sb;
+    fstat(fileno(fp), &sb);
+
+    bool show_prompt = false;
+    while (true) {
+        if (show_prompt) {
+            Print("--(%d%% of %d bytes)--",
+                  static_cast<int>(100 * (double(ftell(fp)) / double(sb.st_size))),
+                  static_cast<int>(sb.st_size));
+            Redraw();
+            while (show_prompt) {
+                show_prompt = false;
+                int key = WaitKey();
+                if (key == KEY_POWER || key == KEY_ENTER) {
+                    return;
+                } else if (key == KEY_UP || key == KEY_VOLUMEUP) {
+                    if (offsets.size() <= 1) {
+                        show_prompt = true;
+                    } else {
+                        offsets.pop_back();
+                        fseek(fp, offsets.back(), SEEK_SET);
+                    }
+                } else {
+                    if (feof(fp)) {
+                        return;
+                    }
+                    offsets.push_back(ftell(fp));
+                }
+            }
+            ClearText();
+        }
+
+        int ch = getc(fp);
+        if (ch == EOF) {
+            text_row = text_top = text_rows - 2;
+            show_prompt = true;
+        } else {
+            PutChar(ch);
+            if (text_col == 0 && text_row >= text_rows - 2) {
+                text_top = text_row;
+                show_prompt = true;
+            }
+        }
+    }
+}
+
+void WearRecoveryUI::PutChar(char ch) {
+    pthread_mutex_lock(&updateMutex);
+    if (ch != '\n') text[text_row][text_col++] = ch;
+    if (ch == '\n' || text_col >= text_cols) {
+        text_col = 0;
+        ++text_row;
+    }
+    pthread_mutex_unlock(&updateMutex);
+}
+
+void WearRecoveryUI::ShowFile(const char* filename) {
+    FILE* fp = fopen_path(filename, "re");
+    if (fp == nullptr) {
+        Print("  Unable to open %s: %s\n", filename, strerror(errno));
+        return;
+    }
+    ShowFile(fp);
+    fclose(fp);
+}
+
+void WearRecoveryUI::ClearText() {
+    pthread_mutex_lock(&updateMutex);
+    text_col = 0;
+    text_row = 0;
+    text_top = 1;
+    for (size_t i = 0; i < text_rows; ++i) {
+        memset(text[i], 0, text_cols + 1);
+    }
+    pthread_mutex_unlock(&updateMutex);
+}
diff --git a/wear_ui.h b/wear_ui.h
new file mode 100644
index 0000000..839a264
--- /dev/null
+++ b/wear_ui.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2014 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_WEAR_UI_H
+#define RECOVERY_WEAR_UI_H
+
+#include <pthread.h>
+#include <stdio.h>
+
+#include "ui.h"
+#include "minui/minui.h"
+
+class WearRecoveryUI : public RecoveryUI {
+  public:
+    WearRecoveryUI();
+
+    void Init();
+    void SetLocale(const char* locale);
+
+    // 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);
+
+    void SetStage(int current, int max);
+
+    // text log
+    void ShowText(bool visible);
+    bool IsTextVisible();
+    bool WasTextEverVisible();
+
+    // printing messages
+    void Print(const char* fmt, ...);
+    void ShowFile(const char* filename);
+    void ShowFile(FILE* fp);
+
+    // menu display
+    void StartMenu(const char* const * headers, const char* const * items,
+                           int initial_selection);
+    int SelectMenu(int sel);
+    void EndMenu();
+
+    void Redraw();
+
+    enum UIElement { HEADER, MENU, MENU_SEL_BG, MENU_SEL_FG, LOG, TEXT_FILL };
+    virtual void SetColor(UIElement e);
+
+  protected:
+    int progress_bar_height, progress_bar_width;
+
+    // progress bar vertical position, it's centered horizontally
+    int progress_bar_y;
+
+    // outer of window
+    int outer_height, outer_width;
+
+    // Unusable rows when displaying the recovery menu, including the lines
+    // for headers (Android Recovery, build id and etc) and the bottom lines
+    // that may otherwise go out of the screen.
+    int menu_unusable_rows;
+
+    // number of intro frames (default: 22) and loop frames (default: 60)
+    int intro_frames;
+    int loop_frames;
+
+  private:
+    Icon currentIcon;
+
+    bool intro_done;
+
+    int current_frame;
+
+    int animation_fps;
+
+    bool rtl_locale;
+
+    pthread_mutex_t updateMutex;
+    GRSurface* backgroundIcon[5];
+    GRSurface* *introFrames;
+    GRSurface* *loopFrames;
+
+    ProgressType progressBarType;
+
+    float progressScopeStart, progressScopeSize, progress;
+    double progressScopeTime, progressScopeDuration;
+
+    static const int kMaxCols = 96;
+    static const int kMaxRows = 96;
+
+    // Log text overlay, displayed when a magic key is pressed
+    char text[kMaxRows][kMaxCols];
+    size_t text_cols, text_rows;
+    // Number of text rows seen on screen
+    int visible_text_rows;
+    size_t 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;
+    const char* const* menu_headers_;
+    int menu_items, menu_sel;
+    int menu_start, menu_end;
+
+    pthread_t progress_t;
+
+  private:
+    void draw_background_locked(Icon icon);
+    void draw_progress_locked();
+    void draw_screen_locked();
+    void update_screen_locked();
+    static void* progress_thread(void* cookie);
+    void progress_loop();
+    void LoadBitmap(const char* filename, GRSurface** surface);
+    void PutChar(char);
+    void ClearText();
+    void DrawTextLine(int x, int* y, const char* line, bool bold);
+    void DrawTextLines(int x, int* y, const char* const* lines);
+};
+
+#endif  // RECOVERY_WEAR_UI_H
