From fd0439ed590f4c12b29d6392c9022c21cc44b997 Mon Sep 17 00:00:00 2001 From: Ethan Yonker Date: Wed, 14 Jan 2015 11:08:13 -0600 Subject: Move ORS command line into main thread Also eliminate the mostly similar runPage function in favor of using a single runPages function to avoid code duplication. Change-Id: I46ef414beb4009fee16d4de13d8a5ab2b9678409 --- gui/gui.cpp | 249 ++++++++++++++++++++++--------------------------- gui/gui.h | 2 +- openrecoveryscript.cpp | 2 +- twrp.cpp | 4 +- 4 files changed, 114 insertions(+), 143 deletions(-) diff --git a/gui/gui.cpp b/gui/gui.cpp index 61e5de1fb..9b918f0e7 100644 --- a/gui/gui.cpp +++ b/gui/gui.cpp @@ -68,8 +68,8 @@ static int gForceRender = 0; pthread_mutex_t gForceRendermutex; static int gNoAnimation = 1; static int gGuiInputRunning = 0; -static int gCmdLineRunning = 0; blanktimer blankTimer; +int ors_read_fd = -1; // Needed by pages.cpp too int gGuiRunning = 0; @@ -407,83 +407,97 @@ static void * input_thread(void *cookie) return NULL; } -static void * command_thread(void *cookie) +static void setup_ors_command() { - int read_fd; - FILE* orsout; - char command[1024], result[512]; - - LOGINFO("Starting command line thread\n"); + ors_read_fd = -1; unlink(ORS_INPUT_FILE); if (mkfifo(ORS_INPUT_FILE, 06660) != 0) { LOGINFO("Unable to mkfifo %s\n", ORS_INPUT_FILE); - return 0; + return; } unlink(ORS_OUTPUT_FILE); if (mkfifo(ORS_OUTPUT_FILE, 06666) != 0) { LOGINFO("Unable to mkfifo %s\n", ORS_OUTPUT_FILE); unlink(ORS_INPUT_FILE); - return 0; + return; } - read_fd = open(ORS_INPUT_FILE, O_RDONLY); - if (read_fd < 0) { + ors_read_fd = open(ORS_INPUT_FILE, O_RDONLY | O_NONBLOCK); + if (ors_read_fd < 0) { LOGINFO("Unable to open %s\n", ORS_INPUT_FILE); unlink(ORS_INPUT_FILE); unlink(ORS_OUTPUT_FILE); - return 0; } +} - while (!gGuiRunning) - sleep(1); - - for (;;) { - while (read(read_fd, &command, sizeof(command)) > 0) { - command[1022] = '\n'; - command[1023] = '\0'; - LOGINFO("Command '%s' received\n", command); - orsout = fopen(ORS_OUTPUT_FILE, "w"); - if (!orsout) { - close(read_fd); - LOGINFO("Unable to fopen %s\n", ORS_OUTPUT_FILE); - unlink(ORS_INPUT_FILE); - unlink(ORS_OUTPUT_FILE); - return 0; - } - if (DataManager::GetIntValue("tw_busy") != 0) { - strcpy(result, "Failed, operation in progress\n"); - fprintf(orsout, "%s", result); - LOGINFO("Command cannot be performed, operation in progress.\n"); - } else { - if (gui_console_only() == 0) { - LOGINFO("Console started successfully\n"); - gui_set_FILE(orsout); - if (strlen(command) > 11 && strncmp(command, "runscript", 9) == 0) { - char* filename = command + 11; - if (OpenRecoveryScript::copy_script_file(filename) == 0) { - LOGERR("Unable to copy script file\n"); - } else { - OpenRecoveryScript::run_script_file(); - } - } else if (strlen(command) > 5 && strncmp(command, "get", 3) == 0) { - char* varname = command + 4; - string temp; - DataManager::GetValue(varname, temp); - gui_print("%s = %s\n", varname, temp.c_str()); - } else if (OpenRecoveryScript::Insert_ORS_Command(command)) { +static void ors_command_read() +{ + FILE* orsout; + char command[1024], result[512]; + int set_page_done = 0, read_ret = 0; + + if ((read_ret = read(ors_read_fd, &command, sizeof(command))) > 0) { + command[1022] = '\n'; + command[1023] = '\0'; + LOGINFO("Command '%s' received\n", command); + orsout = fopen(ORS_OUTPUT_FILE, "w"); + if (!orsout) { + close(ors_read_fd); + ors_read_fd = -1; + LOGINFO("Unable to fopen %s\n", ORS_OUTPUT_FILE); + unlink(ORS_INPUT_FILE); + unlink(ORS_OUTPUT_FILE); + return; + } + if (DataManager::GetIntValue("tw_busy") != 0) { + strcpy(result, "Failed, operation in progress\n"); + fprintf(orsout, "%s", result); + LOGINFO("Command cannot be performed, operation in progress.\n"); + } else { + if (gui_console_only() == 0) { + LOGINFO("Console started successfully\n"); + gui_set_FILE(orsout); + if (strlen(command) > 11 && strncmp(command, "runscript", 9) == 0) { + char* filename = command + 11; + if (OpenRecoveryScript::copy_script_file(filename) == 0) { + LOGERR("Unable to copy script file\n"); + } else { OpenRecoveryScript::run_script_file(); } - gui_set_FILE(NULL); - gGuiConsoleTerminate = 1; + } else if (strlen(command) > 5 && strncmp(command, "get", 3) == 0) { + char* varname = command + 4; + string temp; + DataManager::GetValue(varname, temp); + gui_print("%s = %s\n", varname, temp.c_str()); + } else if (strlen(command) > 9 && strncmp(command, "decrypt", 7) == 0) { + char* pass = command + 8; + gui_print("Attempting to decrypt data partition via command line.\n"); + if (PartitionManager.Decrypt_Device(pass) == 0) { + set_page_done = 1; + } + } else if (OpenRecoveryScript::Insert_ORS_Command(command)) { + OpenRecoveryScript::run_script_file(); } + gui_set_FILE(NULL); + gGuiConsoleTerminate = 1; } - fclose(orsout); } + fclose(orsout); + LOGINFO("Done reading ORS command from command line\n"); + if (set_page_done) { + DataManager::SetValue("tw_page_done", 1); + } else { + // The select function will return ready to read and the + // read function will return errno 19 no such device unless + // we set everything up all over again. + close(ors_read_fd); + setup_ors_command(); + } + } else { + LOGINFO("ORS command line read returned an error: %i, %i, %s\n", read_ret, errno, strerror(errno)); } - close(read_fd); - LOGINFO("Command thread exiting\n"); - return 0; + return; } // This special function will return immediately the first time, but then @@ -521,8 +535,11 @@ static void loopTimer(void) } while (1); } -static int runPages(void) +static int runPages(const char *page_name, const int stop_on_page_done) { + if (page_name) + gui_changePage(page_name); + // Raise the curtain if (gCurtain != NULL) { @@ -542,10 +559,27 @@ static int runPages(void) timespec start, end; int32_t render_t, flip_t; #endif +#ifndef TW_OEM_BUILD + struct timeval timeout; + fd_set fdset; + int has_data = 0; +#endif for (;;) { loopTimer(); +#ifndef TW_OEM_BUILD + if (ors_read_fd > 0) { + FD_ZERO(&fdset); + FD_SET(ors_read_fd, &fdset); + timeout.tv_sec = 0; + timeout.tv_usec = 1; + has_data = select(ors_read_fd+1, &fdset, NULL, NULL, &timeout); + if (has_data > 0) { + ors_command_read(); + } + } +#endif if (gGuiConsoleRunning) { continue; @@ -591,64 +625,17 @@ static int runPages(void) } blankTimer.checkForTimeout(); - if (DataManager::GetIntValue("tw_gui_done") != 0) - break; - } - - gGuiRunning = 0; - return 0; -} - -static int runPage(const char *page_name) -{ - gui_changePage(page_name); - - // Raise the curtain - if (gCurtain != NULL) - { - gr_surface surface; - - PageManager::Render(); - gr_get_surface(&surface); - curtainRaise(surface); - gr_free_surface(surface); - } - - gGuiRunning = 1; - - DataManager::SetValue("tw_loaded", 1); - - for (;;) - { - loopTimer(); - - if (!gForceRender) - { - int ret; - - ret = PageManager::Update(); - if (ret > 1) - PageManager::Render(); - - if (ret > 0) - flip(); - } - else - { - pthread_mutex_lock(&gForceRendermutex); - gForceRender = 0; - pthread_mutex_unlock(&gForceRendermutex); - PageManager::Render(); - flip(); - } - blankTimer.checkForTimeout(); - if (DataManager::GetIntValue("tw_page_done") != 0) + if (stop_on_page_done && DataManager::GetIntValue("tw_page_done") != 0) { gui_changePage("main"); break; } + if (DataManager::GetIntValue("tw_gui_done") != 0) + break; } - + if (ors_read_fd > 0) + close(ors_read_fd); + ors_read_fd = -1; gGuiRunning = 0; return 0; } @@ -838,6 +825,11 @@ error: } extern "C" int gui_start(void) +{ + return gui_startPage(NULL, 1, 0); +} + +extern "C" int gui_startPage(const char *page_name, const int allow_commands, int stop_on_page_done) { if (!gGuiInitialized) return -1; @@ -858,40 +850,19 @@ extern "C" int gui_start(void) gGuiInputRunning = 1; } #ifndef TW_OEM_BUILD - if (!gCmdLineRunning) + if (allow_commands) { - // Start by spinning off an input handler. - pthread_t t; - pthread_create(&t, NULL, command_thread, NULL); - gCmdLineRunning = 1; + if (ors_read_fd < 0) + setup_ors_command(); + } else { + if (ors_read_fd >= 0) { + close(ors_read_fd); + ors_read_fd = -1; + } } #endif - return runPages(); -} - -extern "C" int gui_startPage(const char *page_name) -{ - if (!gGuiInitialized) - return -1; - - gGuiConsoleTerminate = 1; - - while (gGuiConsoleRunning) - loopTimer(); - - // Set the default package - PageManager::SelectPackage("TWRP"); - - if (!gGuiInputRunning) - { - // Start by spinning off an input handler. - pthread_t t; - pthread_create(&t, NULL, input_thread, NULL); - gGuiInputRunning = 1; - } - DataManager::SetValue("tw_page_done", 0); - return runPage(page_name); + return runPages(page_name, stop_on_page_done); } static void * console_thread(void *cookie) diff --git a/gui/gui.h b/gui/gui.h index 21c460ebe..5b2cdec18 100644 --- a/gui/gui.h +++ b/gui/gui.h @@ -26,7 +26,7 @@ int gui_init(); int gui_loadResources(); int gui_loadCustomResources(); int gui_start(); -int gui_startPage(const char* page_name); +int gui_startPage(const char* page_name, const int allow_comands, int stop_on_page_done); void gui_print(const char *fmt, ...); void gui_print_color(const char *color, const char *fmt, ...); void gui_set_FILE(FILE* f); diff --git a/openrecoveryscript.cpp b/openrecoveryscript.cpp index 96383931b..d28f76202 100644 --- a/openrecoveryscript.cpp +++ b/openrecoveryscript.cpp @@ -566,7 +566,7 @@ void OpenRecoveryScript::Run_OpenRecoveryScript(void) { DataManager::SetValue("tw_complete_text1", "OpenRecoveryScript Complete"); DataManager::SetValue("tw_has_cancel", 0); DataManager::SetValue("tw_show_reboot", 0); - if (gui_startPage("action_page") != 0) { + if (gui_startPage("action_page", 0, 1) != 0) { LOGERR("Failed to load OpenRecoveryScript GUI page.\n"); } } diff --git a/twrp.cpp b/twrp.cpp index 3489f8cfc..b6d3d79fd 100644 --- a/twrp.cpp +++ b/twrp.cpp @@ -276,7 +276,7 @@ int main(int argc, char **argv) { // Offer to decrypt if the device is encrypted if (DataManager::GetIntValue(TW_IS_ENCRYPTED) != 0) { LOGINFO("Is encrypted, do decrypt page first\n"); - if (gui_startPage("decrypt") != 0) { + if (gui_startPage("decrypt", 1, 1) != 0) { LOGERR("Failed to start decrypt GUI page.\n"); } else { // Check for and load custom theme if present @@ -347,7 +347,7 @@ int main(int argc, char **argv) { if (TWFunc::Path_Exists("/supersu/su") && !TWFunc::Path_Exists("/system/bin/su") && !TWFunc::Path_Exists("/system/xbin/su") && !TWFunc::Path_Exists("/system/bin/.ext/.su")) { // Device doesn't have su installed DataManager::SetValue("tw_busy", 1); - if (gui_startPage("installsu") != 0) { + if (gui_startPage("installsu", 1, 1) != 0) { LOGERR("Failed to start SuperSU install page.\n"); } } -- cgit v1.2.3