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; }
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; }
/** * 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; }