Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c0441d17 authored by Doug Zongker's avatar Doug Zongker
Browse files

notify about pending long press

Recovery changes:

- add a method to the UI class that is called when a key is held down
  long enough to be a "long press" (but before it is released).
  Device-specific subclasses can override this to indicate a long
  press.

- do color selection for ScreenRecoveryUI's menu-and-log drawing
  function.  Subclasses can override this to customize the colors they
  use for various elements.

- Include the value of ro.build.display.id in the menu headers, so you
  can see on the screen what version of recovery you are running.

Change-Id: I426a6daf892b9011638e2035aebfa2831d4f596d
parent 3c3ee3bc
Loading
Loading
Loading
Loading
+6 −8
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@ static const char *SIDELOAD_TEMP_DIR = "/tmp/sideload";

RecoveryUI* ui = NULL;
char* locale = NULL;
char recovery_version[PROPERTY_VALUE_MAX+1];

/*
 * The recovery tool communicates with the main system through /cache files.
@@ -526,21 +527,17 @@ copy_sideloaded_package(const char* original_path) {

static const char**
prepend_title(const char* const* headers) {
    const char* title[] = { "Android system recovery <"
                            EXPAND(RECOVERY_API_VERSION) "e>",
                            "",
                            NULL };

    // count the number of lines in our title, plus the
    // caller-provided headers.
    int count = 0;
    int count = 3;   // our title has 3 lines
    const char* const* p;
    for (p = title; *p; ++p, ++count);
    for (p = headers; *p; ++p, ++count);

    const char** new_headers = (const char**)malloc((count+1) * sizeof(char*));
    const char** h = new_headers;
    for (p = title; *p; ++p, ++h) *h = *p;
    *(h++) = "Android system recovery <" EXPAND(RECOVERY_API_VERSION) "e>";
    *(h++) = recovery_version;
    *(h++) = "";
    for (p = headers; *p; ++p, ++h) *h = *p;
    *h = NULL;

@@ -1022,6 +1019,7 @@ main(int argc, char **argv) {
    printf("\n");

    property_list(print_property, NULL);
    property_get("ro.build.display.id", recovery_version, "");
    printf("\n");

    int status = INSTALL_SUCCESS;
+38 −10
Original line number Diff line number Diff line
@@ -196,9 +196,29 @@ void ScreenRecoveryUI::draw_progress_locked()
    }
}

#define C_HEADER  247,0,6
#define C_MENU    0,106,157
#define C_LOG     249,194,0
void ScreenRecoveryUI::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;
    }
}

// Redraw everything on the screen.  Does not flip pages.
// Should only be called with updateMutex locked.
@@ -208,37 +228,38 @@ void ScreenRecoveryUI::draw_screen_locked()
    draw_progress_locked();

    if (show_text) {
        gr_color(0, 0, 0, 160);
        SetColor(TEXT_FILL);
        gr_fill(0, 0, gr_fb_width(), gr_fb_height());

        int y = 0;
        int i = 0;
        if (show_menu) {
            gr_color(C_HEADER, 255);
            SetColor(HEADER);

            for (; i < menu_top + menu_items; ++i) {
                if (i == menu_top) gr_color(C_MENU, 255);
                if (i == menu_top) SetColor(MENU);

                if (i == menu_top + menu_sel) {
                    // draw the highlight bar
                    SetColor(MENU_SEL_BG);
                    gr_fill(0, y-2, gr_fb_width(), y+char_height+2);
                    // white text of selected item
                    gr_color(255, 255, 255, 255);
                    SetColor(MENU_SEL_FG);
                    if (menu[i][0]) gr_text(4, y, menu[i], 1);
                    gr_color(C_MENU, 255);
                    SetColor(MENU);
                } else {
                    if (menu[i][0]) gr_text(4, y, menu[i], i < menu_top);
                }
                y += char_height+4;
            }
            gr_color(C_MENU, 255);
            SetColor(MENU);
            y += 4;
            gr_fill(0, y, gr_fb_width(), y+2);
            y += 4;
            ++i;
        }

        gr_color(C_LOG, 255);
        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
@@ -585,3 +606,10 @@ void ScreenRecoveryUI::ShowText(bool visible)
    update_screen_locked();
    pthread_mutex_unlock(&updateMutex);
}

void ScreenRecoveryUI::Redraw()
{
    pthread_mutex_lock(&updateMutex);
    update_screen_locked();
    pthread_mutex_unlock(&updateMutex);
}
+5 −0
Original line number Diff line number Diff line
@@ -53,6 +53,11 @@ class ScreenRecoveryUI : public RecoveryUI {
    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);

  private:
    Icon currentIcon;
    int installingFrame;
+33 −8
Original line number Diff line number Diff line
@@ -46,7 +46,8 @@ static RecoveryUI* self = NULL;
RecoveryUI::RecoveryUI() :
    key_queue_len(0),
    key_last_down(-1),
    key_down_time(0) {
    key_long_press(false),
    key_down_count(0) {
    pthread_mutex_init(&key_queue_mutex, NULL);
    pthread_cond_init(&key_queue_cond, NULL);
    self = this;
@@ -112,19 +113,22 @@ void RecoveryUI::process_key(int key_code, int updown) {
    bool register_key = false;
    bool long_press = false;

    const long long_threshold = CLOCKS_PER_SEC * 750 / 1000;

    pthread_mutex_lock(&key_queue_mutex);
    key_pressed[key_code] = updown;
    if (updown) {
        ++key_down_count;
        key_last_down = key_code;
        key_down_time = clock();
        key_long_press = false;
        pthread_t th;
        key_timer_t* info = new key_timer_t;
        info->ui = this;
        info->key_code = key_code;
        info->count = key_down_count;
        pthread_create(&th, NULL, &RecoveryUI::time_key_helper, info);
        pthread_detach(th);
    } else {
        if (key_last_down == key_code) {
            long duration = clock() - key_down_time;
            if (duration > long_threshold) {
                long_press = true;
            }
            long_press = key_long_press;
            register_key = true;
        }
        key_last_down = -1;
@@ -152,6 +156,24 @@ void RecoveryUI::process_key(int key_code, int updown) {
    }
}

void* RecoveryUI::time_key_helper(void* cookie) {
    key_timer_t* info = (key_timer_t*) cookie;
    info->ui->time_key(info->key_code, info->count);
    delete info;
    return NULL;
}

void RecoveryUI::time_key(int key_code, int count) {
    usleep(750000);  // 750 ms == "long"
    bool long_press = false;
    pthread_mutex_lock(&key_queue_mutex);
    if (key_last_down == key_code && key_down_count == count) {
        long_press = key_long_press = true;
    }
    pthread_mutex_unlock(&key_queue_mutex);
    if (long_press) KeyLongPress(key_code);
}

void RecoveryUI::EnqueueKey(int key_code) {
    pthread_mutex_lock(&key_queue_mutex);
    const int queue_max = sizeof(key_queue) / sizeof(key_queue[0]);
@@ -242,3 +264,6 @@ RecoveryUI::KeyAction RecoveryUI::CheckKey(int key) {

void RecoveryUI::NextCheckKeyIsLong(bool is_long_press) {
}

void RecoveryUI::KeyLongPress(int key) {
}
+20 −1
Original line number Diff line number Diff line
@@ -80,8 +80,17 @@ class RecoveryUI {
    enum KeyAction { ENQUEUE, TOGGLE, REBOOT, IGNORE };
    virtual KeyAction CheckKey(int key);

    // Called immediately before each call to CheckKey(), tell you if
    // the key was long-pressed.
    virtual void NextCheckKeyIsLong(bool is_long_press);

    // Called when a key is held down long enough to have been a
    // long-press (but before the key is released).  This means that
    // if the key is eventually registered (released without any other
    // keys being pressed in the meantime), NextCheckKeyIsLong() will
    // be called with "true".
    virtual void KeyLongPress(int key);

    // --- menu display ---

    // Display some header text followed by a menu of items, which appears
@@ -108,15 +117,25 @@ private:
    int key_queue[256], key_queue_len;
    char key_pressed[KEY_MAX + 1];     // under key_queue_mutex
    int key_last_down;                 // under key_queue_mutex
    clock_t key_down_time;             // under key_queue_mutex
    bool key_long_press;               // under key_queue_mutex
    int key_down_count;                // under key_queue_mutex
    int rel_sum;

    typedef struct {
        RecoveryUI* ui;
        int key_code;
        int count;
    } key_timer_t;

    pthread_t input_t;

    static void* input_thread(void* cookie);
    static int input_callback(int fd, short revents, void* data);
    void process_key(int key_code, int updown);
    bool usb_connected();

    static void* time_key_helper(void* cookie);
    void time_key(int key_code, int count);
};

#endif  // RECOVERY_UI_H