int ui_wait_key()
{
    if (boardEnableKeyRepeat) return ui_wait_key_with_repeat();
    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;
}
Example #2
0
int ui_wait_key()
{
    if (boardEnableKeyRepeat.value) return ui_wait_key_with_repeat();
    pthread_mutex_lock(&key_queue_mutex);
    int timeouts = UI_WAIT_KEY_TIMEOUT_SEC;
#ifdef PHILZ_TOUCH_RECOVERY
    int display_state = 0;
#endif
    // Time out after REFRESH_TIME_USB_INTERVAL seconds to catch volume changes, refresh clock, and loop for
    // UI_WAIT_KEY_TIMEOUT_SEC to restart a device not connected to USB
    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 += REFRESH_TIME_USB_INTERVAL;

        int rc = 0;
        while (key_queue_len == 0 && rc != ETIMEDOUT) {
            rc = pthread_cond_timedwait(&key_queue_cond, &key_queue_mutex,
                                        &timeout);
            if (volumes_changed()) {
                pthread_mutex_unlock(&key_queue_mutex);
                return REFRESH;
            }
        }
        timeouts -= REFRESH_TIME_USB_INTERVAL;
#ifdef PHILZ_TOUCH_RECOVERY
        ui_refresh_display_state(&display_state);
#endif
    } while ((timeouts > 0 || 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_wait_key_with_repeat()
{
    int key = -1;

    // Loop to wait for more keys.
    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;
        pthread_mutex_lock(&key_queue_mutex);
        while (key_queue_len == 0 && rc != ETIMEDOUT) {
            rc = pthread_cond_timedwait(&key_queue_cond, &key_queue_mutex,
                                        &timeout);
        }
        pthread_mutex_unlock(&key_queue_mutex);
        if (rc == ETIMEDOUT && !usb_connected()) {
            return -1;
        }

        // Loop to wait wait for more keys, or repeated keys to be ready.
        while (1) {
            unsigned long now_msec;

            gettimeofday(&now, NULL);
            now_msec = (now.tv_sec * 1000) + (now.tv_usec / 1000);

            pthread_mutex_lock(&key_queue_mutex);

            // Replacement for the while conditional, so we don't have to lock the entire
            // loop, because that prevents the input system from touching the variables while
            // the loop is running which causes problems.
            if (key_queue_len == 0) {
                pthread_mutex_unlock(&key_queue_mutex);
                break;
            }

            key = key_queue[0];
            memcpy(&key_queue[0], &key_queue[1], sizeof(int) * --key_queue_len);

            // sanity check the returned key.
            if (key < 0) {
                pthread_mutex_unlock(&key_queue_mutex);
                return key;
            }

            // Check for already released keys and drop them if they've repeated.
            if (!key_pressed[key] && key_last_repeat[key] > 0) {
                pthread_mutex_unlock(&key_queue_mutex);
                continue;
            }

            if (key_can_repeat(key)) {
                // Re-add the key if a repeat is expected, since we just popped it. The
                // if below will determine when the key is actually repeated (returned)
                // in the mean time, the key will be passed through the queue over and
                // over and re-evaluated each time.
                if (key_pressed[key]) {
                    key_queue[key_queue_len] = key;
                    key_queue_len++;
                }
                if ((now_msec > key_press_time[key] + UI_KEY_WAIT_REPEAT && now_msec > key_last_repeat[key] + UI_KEY_REPEAT_INTERVAL) ||
                        key_last_repeat[key] == 0) {
                    key_last_repeat[key] = now_msec;
                } else {
                    // Not ready
                    pthread_mutex_unlock(&key_queue_mutex);
                    continue;
                }
            }
            pthread_mutex_unlock(&key_queue_mutex);
            return key;
        }
    } while (1);

    return key;
}
Example #4
0
/**
 * run_bootmenu()
 *
 */
static int run_bootmenu(void) {
  int defmode, mode, status = BUTTON_ERROR;
  int adb_started = 0;
  time_t start = time(NULL);

  LOGI("Starting bootmenu on %s", ctime(&start));

  if (bypass_check()) {

    // init rootfs and mount cache
    exec_script(FILE_PRE_MENU, DISABLE);

    led_alert("blue", ENABLE);

    defmode = get_default_bootmode();

    // get and clean one shot bootmode (or default)
    mode = get_bootmode(1,1);

    if (mode == int_mode("bootmenu")
     || mode == int_mode("recovery")
     || mode == int_mode("shell")) {
        // dont wait if these modes are asked
    } else {
        status = (wait_key(KEY_VOLUMEDOWN) ? BUTTON_PRESSED : BUTTON_TIMEOUT);
    }

    // only start adb if usb is connected
    if (usb_connected()) {
      if (mode == int_mode("2nd-init-adb")
       || mode == int_mode("2nd-boot-adb")
       || mode == int_mode("2nd-system-adb")) {
         exec_script(FILE_ADBD, DISABLE);
         adb_started = 1;
      }
    }

    // on timeout
    if (status != BUTTON_PRESSED) {

      if (mode == int_mode("bootmenu")) {
          led_alert("blue", DISABLE);
          status = BUTTON_PRESSED;
      }
      else if (mode == int_mode("2nd-init") || mode == int_mode("2nd-init-adb")) {
          led_alert("blue", DISABLE);
          led_alert("green", ENABLE);
          snd_init(DISABLE);
          led_alert("green", DISABLE);
          status = BUTTON_TIMEOUT;
      }
      else if (mode == int_mode("2nd-boot") || mode == int_mode("2nd-boot-adb")) {
          led_alert("blue", DISABLE);
          led_alert("red", ENABLE);
          snd_boot(DISABLE);
          led_alert("red", DISABLE);
          status = BUTTON_TIMEOUT;
      }
      else if (mode == int_mode("2nd-system") || mode == int_mode("2nd-system-adb")) {
          led_alert("blue", DISABLE);
          led_alert("red", ENABLE);
          led_alert("green", ENABLE);
          snd_system(DISABLE);
          led_alert("red", DISABLE);
          led_alert("green", DISABLE);
          status = BUTTON_TIMEOUT;
      }
      else if (mode == int_mode("recovery-dev")) {
          led_alert("blue", DISABLE);
          exec_script(FILE_CUSTOMRECOVERY, DISABLE);
          status = BUTTON_TIMEOUT;
      }
      else if (mode == int_mode("recovery")) {
          led_alert("blue", DISABLE);
          exec_script(FILE_STABLERECOVERY, DISABLE);
          status = BUTTON_TIMEOUT;
      }
      else if (mode == int_mode("shell")) {
          led_alert("blue", DISABLE);
          exec_script(FILE_ADBD, DISABLE);
          status = BUTTON_PRESSED;
      }
      else if (mode == int_mode("normal") || mode == int_mode("normal-adb")) {
          led_alert("blue", DISABLE);
          stk_boot(DISABLE);
          status = BUTTON_TIMEOUT;
      }

    }

    if (status == BUTTON_PRESSED ) {

        ui_init();
        ui_set_background(BACKGROUND_DEFAULT);
        ui_show_text(ENABLE);
        led_alert("button-backlight", ENABLE);

        LOGI("Start Android BootMenu....\n");

        main_headers = prepend_title((const char**)MENU_HEADERS);

        /* can be buggy, adb could lock filesystem
        if (!adb_started && usb_connected()) {
            ui_print("Usb connected, starting adb...\n\n");
            exec_script(FILE_ADBD, DISABLE);
        }
        */

        ui_print("Default mode: %s\n", str_mode(defmode));

        if (mode == int_mode("shell")) {
            ui_print("\n");
            ui_print("Current mode: %s\n", str_mode(mode));
            if (!usb_connected()) {
                ui_print(" But USB is not connected !\n");
            }
        }

        checkup_report();
        ui_reset_progress();

        prompt_and_wait();
        free_menu_headers(main_headers);

        ui_finish();
    }

  }
  return EXIT_SUCCESS;
}