get rid of console thread for OpenRecoveryScript
- CLI commands run in a threaded action "twcmd" - Console is displayed via "singleaction_page" - move ORS execution code from GUI action to OpenRecoveryScript class - remove unused function gui_changePackage - don't change PageManager package in home action - fix that /tmp/openrecoveryscript was not deleted after execution Change-Id: Ic688c0b04647ce09e9db979b0bc5123f47cf4f70
This commit is contained in:
+13
-31
@@ -226,6 +226,7 @@ GUIAction::GUIAction(xml_node<>* node)
|
||||
ADD_ACTION(resize);
|
||||
ADD_ACTION(changefilesystem);
|
||||
ADD_ACTION(flashimage);
|
||||
ADD_ACTION(twcmd);
|
||||
}
|
||||
|
||||
// First, get the action
|
||||
@@ -522,7 +523,6 @@ int GUIAction::reboot(std::string arg)
|
||||
|
||||
int GUIAction::home(std::string arg __unused)
|
||||
{
|
||||
PageManager::SelectPackage("TWRP");
|
||||
gui_changePage("main");
|
||||
return 0;
|
||||
}
|
||||
@@ -1536,41 +1536,12 @@ int GUIAction::adbsideloadcancel(std::string arg __unused)
|
||||
|
||||
int GUIAction::openrecoveryscript(std::string arg __unused)
|
||||
{
|
||||
int op_status = 1;
|
||||
|
||||
operation_start("OpenRecoveryScript");
|
||||
if (simulate) {
|
||||
simulate_progress_bar();
|
||||
operation_end(0);
|
||||
} else {
|
||||
// Check for the SCRIPT_FILE_TMP first as these are AOSP recovery commands
|
||||
// that we converted to ORS commands during boot in recovery.cpp.
|
||||
// Run those first.
|
||||
int reboot = 0;
|
||||
if (TWFunc::Path_Exists(SCRIPT_FILE_TMP)) {
|
||||
gui_msg("running_recovery_commands=Running Recovery Commands");
|
||||
if (OpenRecoveryScript::run_script_file() == 0) {
|
||||
reboot = 1;
|
||||
op_status = 0;
|
||||
}
|
||||
}
|
||||
// Check for the ORS file in /cache and attempt to run those commands.
|
||||
if (OpenRecoveryScript::check_for_script_file()) {
|
||||
gui_msg("running_ors=Running OpenRecoveryScript");
|
||||
if (OpenRecoveryScript::run_script_file() == 0) {
|
||||
reboot = 1;
|
||||
op_status = 0;
|
||||
}
|
||||
}
|
||||
if (reboot) {
|
||||
// Disable stock recovery reflashing
|
||||
TWFunc::Disable_Stock_Recovery_Replace();
|
||||
usleep(2000000); // Sleep for 2 seconds before rebooting
|
||||
TWFunc::tw_reboot(rb_system);
|
||||
usleep(5000000); // Sleep for 5 seconds to allow reboot to occur
|
||||
} else {
|
||||
DataManager::SetValue("tw_page_done", 1);
|
||||
}
|
||||
int op_status = OpenRecoveryScript::Run_OpenRecoveryScript_Action();
|
||||
operation_end(op_status);
|
||||
}
|
||||
return 0;
|
||||
@@ -1743,6 +1714,17 @@ int GUIAction::flashimage(std::string arg __unused)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GUIAction::twcmd(std::string arg)
|
||||
{
|
||||
operation_start("TWRP CLI Command");
|
||||
if (simulate)
|
||||
simulate_progress_bar();
|
||||
else
|
||||
OpenRecoveryScript::Run_CLI_Command(arg.c_str());
|
||||
operation_end(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GUIAction::getKeyByName(std::string key)
|
||||
{
|
||||
if (key == "home") return KEY_HOME;
|
||||
|
||||
+42
-119
@@ -69,12 +69,11 @@ using namespace rapidxml;
|
||||
// Global values
|
||||
static gr_surface gCurtain = NULL;
|
||||
static int gGuiInitialized = 0;
|
||||
static TWAtomicInt gGuiConsoleRunning;
|
||||
static TWAtomicInt gGuiConsoleTerminate;
|
||||
static TWAtomicInt gForceRender;
|
||||
const int gNoAnimation = 1;
|
||||
blanktimer blankTimer;
|
||||
int ors_read_fd = -1;
|
||||
static FILE* orsout = NULL;
|
||||
static float scale_theme_w = 1;
|
||||
static float scale_theme_h = 1;
|
||||
|
||||
@@ -493,13 +492,28 @@ static void setup_ors_command()
|
||||
}
|
||||
}
|
||||
|
||||
// callback called after a CLI command was executed
|
||||
static void ors_command_done()
|
||||
{
|
||||
gui_set_FILE(NULL);
|
||||
fclose(orsout);
|
||||
orsout = NULL;
|
||||
|
||||
if (DataManager::GetIntValue("tw_page_done") == 0) {
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
|
||||
static void ors_command_read()
|
||||
{
|
||||
FILE* orsout;
|
||||
char command[1024], result[512];
|
||||
int set_page_done = 0, read_ret = 0;
|
||||
char command[1024];
|
||||
int read_ret = read(ors_read_fd, &command, sizeof(command));
|
||||
|
||||
if ((read_ret = read(ors_read_fd, &command, sizeof(command))) > 0) {
|
||||
if (read_ret > 0) {
|
||||
command[1022] = '\n';
|
||||
command[1023] = '\0';
|
||||
LOGINFO("Command '%s' received\n", command);
|
||||
@@ -513,61 +527,40 @@ static void ors_command_read()
|
||||
return;
|
||||
}
|
||||
if (DataManager::GetIntValue("tw_busy") != 0) {
|
||||
strcpy(result, "Failed, operation in progress\n");
|
||||
fprintf(orsout, "%s", result);
|
||||
fputs("Failed, operation in progress\n", orsout);
|
||||
LOGINFO("Command cannot be performed, operation in progress.\n");
|
||||
fclose(orsout);
|
||||
} else {
|
||||
if (strlen(command) == 11 && strncmp(command, "dumpstrings", 11) == 0) {
|
||||
// This cannot be done safely with gui_console_only because gui_console_only updates mCurrentSet
|
||||
// which makes the resources that we are trying to read unreachable.
|
||||
gui_set_FILE(orsout);
|
||||
PageManager::GetResources()->DumpStrings();
|
||||
gui_set_FILE(NULL);
|
||||
} else if (gui_console_only() == 0) {
|
||||
LOGINFO("Console started successfully\n");
|
||||
ors_command_done();
|
||||
} else {
|
||||
// mirror output messages
|
||||
gui_set_FILE(orsout);
|
||||
if (strlen(command) > 11 && strncmp(command, "runscript", 9) == 0) {
|
||||
char* filename = command + 11;
|
||||
if (OpenRecoveryScript::copy_script_file(filename) == 0) {
|
||||
LOGINFO("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 (strlen(command) > 9 && strncmp(command, "decrypt", 7) == 0) {
|
||||
char* pass = command + 8;
|
||||
gui_msg("decrypt_cmd=Attempting to decrypt data partition via command line.");
|
||||
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.set_value(1);
|
||||
// close orsout and restart listener after command is done
|
||||
OpenRecoveryScript::Call_After_CLI_Command(ors_command_done);
|
||||
// run the command in a threaded action...
|
||||
DataManager::SetValue("tw_action", "twcmd");
|
||||
DataManager::SetValue("tw_action_param", command);
|
||||
// ...and switch back to the current page when finished
|
||||
std::string currentPage = PageManager::GetCurrentPage();
|
||||
DataManager::SetValue("tw_has_action2", "1");
|
||||
DataManager::SetValue("tw_action2", "page");
|
||||
DataManager::SetValue("tw_action2_param", currentPage);
|
||||
DataManager::SetValue("tw_action_text1", gui_lookup("running_recovery_commands", "Running Recovery Commands"));
|
||||
DataManager::SetValue("tw_action_text2", "");
|
||||
gui_changePage("singleaction_page");
|
||||
// now immediately return to the GUI main loop (the action runs in the background thread)
|
||||
// put all things that need to be done after the command is finished into ors_command_done, not here
|
||||
}
|
||||
}
|
||||
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));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Get and dispatch input events until it's time to draw the next frame
|
||||
// This special function will return immediately the first time, but then
|
||||
// always returns 1/30th of a second (or immediately if called later) from
|
||||
// the last time it was called
|
||||
@@ -648,7 +641,7 @@ static int runPages(const char *page_name, const int stop_on_page_done)
|
||||
{
|
||||
loopTimer(input_timeout_ms);
|
||||
#ifndef TW_OEM_BUILD
|
||||
if (ors_read_fd > 0) {
|
||||
if (ors_read_fd > 0 && !orsout) { // orsout is non-NULL if a command is still running
|
||||
FD_ZERO(&fdset);
|
||||
FD_SET(ors_read_fd, &fdset);
|
||||
timeout.tv_sec = 0;
|
||||
@@ -660,10 +653,6 @@ static int runPages(const char *page_name, const int stop_on_page_done)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (gGuiConsoleRunning.get_value()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!gForceRender.get_value())
|
||||
{
|
||||
int ret = PageManager::Update();
|
||||
@@ -748,13 +737,6 @@ int gui_changeOverlay(std::string overlay)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gui_changePackage(std::string newPackage)
|
||||
{
|
||||
PageManager::SelectPackage(newPackage);
|
||||
gForceRender.set_value(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string gui_parse_text(std::string str)
|
||||
{
|
||||
// This function parses text for DataManager values encompassed by %value% in the XML
|
||||
@@ -957,11 +939,6 @@ extern "C" int gui_startPage(const char *page_name, const int allow_commands, in
|
||||
if (!gGuiInitialized)
|
||||
return -1;
|
||||
|
||||
gGuiConsoleTerminate.set_value(1);
|
||||
|
||||
while (gGuiConsoleRunning.get_value())
|
||||
usleep(10000);
|
||||
|
||||
// Set the default package
|
||||
PageManager::SelectPackage("TWRP");
|
||||
|
||||
@@ -981,60 +958,6 @@ extern "C" int gui_startPage(const char *page_name, const int allow_commands, in
|
||||
return runPages(page_name, stop_on_page_done);
|
||||
}
|
||||
|
||||
static void * console_thread(void *cookie __unused)
|
||||
{
|
||||
PageManager::SwitchToConsole();
|
||||
|
||||
while (!gGuiConsoleTerminate.get_value())
|
||||
{
|
||||
loopTimer(0);
|
||||
|
||||
if (!gForceRender.get_value())
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = PageManager::Update();
|
||||
if (ret > 1)
|
||||
PageManager::Render();
|
||||
|
||||
if (ret > 0)
|
||||
flip();
|
||||
|
||||
if (ret < 0)
|
||||
LOGERR("An update request has failed.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
gForceRender.set_value(0);
|
||||
PageManager::Render();
|
||||
flip();
|
||||
}
|
||||
}
|
||||
gGuiConsoleRunning.set_value(0);
|
||||
gForceRender.set_value(1); // this will kickstart the GUI to render again
|
||||
PageManager::EndConsole();
|
||||
LOGINFO("Console stopping\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
extern "C" int gui_console_only(void)
|
||||
{
|
||||
if (!gGuiInitialized)
|
||||
return -1;
|
||||
|
||||
gGuiConsoleTerminate.set_value(0);
|
||||
|
||||
if (gGuiConsoleRunning.get_value())
|
||||
return 0;
|
||||
|
||||
gGuiConsoleRunning.set_value(1);
|
||||
|
||||
// Start by spinning off an input handler.
|
||||
pthread_t t;
|
||||
pthread_create(&t, NULL, console_thread, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" void set_scale_values(float w, float h)
|
||||
{
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int gui_console_only();
|
||||
int gui_init();
|
||||
int gui_loadResources();
|
||||
int gui_loadCustomResources();
|
||||
|
||||
@@ -366,6 +366,7 @@ protected:
|
||||
int checkpartitionlifetimewrites(std::string arg);
|
||||
int mountsystemtoggle(std::string arg);
|
||||
int setlanguage(std::string arg);
|
||||
int twcmd(std::string arg);
|
||||
|
||||
int simulate;
|
||||
};
|
||||
|
||||
+10
-18
@@ -1098,6 +1098,11 @@ int PageSet::IsCurrentPage(Page* page)
|
||||
return ((mCurrentPage && mCurrentPage == page) ? 1 : 0);
|
||||
}
|
||||
|
||||
std::string PageSet::GetCurrentPage() const
|
||||
{
|
||||
return mCurrentPage ? mCurrentPage->GetName() : "";
|
||||
}
|
||||
|
||||
int PageSet::Render(void)
|
||||
{
|
||||
int ret;
|
||||
@@ -1544,6 +1549,11 @@ int PageManager::ChangePage(std::string name)
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string PageManager::GetCurrentPage()
|
||||
{
|
||||
return mCurrentSet ? mCurrentSet->GetCurrentPage() : "";
|
||||
}
|
||||
|
||||
int PageManager::ChangeOverlay(std::string name)
|
||||
{
|
||||
if (name.empty())
|
||||
@@ -1560,24 +1570,6 @@ const ResourceManager* PageManager::GetResources()
|
||||
return (mCurrentSet ? mCurrentSet->GetResources() : NULL);
|
||||
}
|
||||
|
||||
int PageManager::SwitchToConsole(void)
|
||||
{
|
||||
PageSet* console = new PageSet(NULL);
|
||||
|
||||
mCurrentSet = console;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PageManager::EndConsole(void)
|
||||
{
|
||||
if (mCurrentSet && mBaseSet) {
|
||||
delete mCurrentSet;
|
||||
mCurrentSet = mBaseSet;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int PageManager::IsCurrentPage(Page* page)
|
||||
{
|
||||
return (mCurrentSet ? mCurrentSet->IsCurrentPage(page) : 0);
|
||||
|
||||
+2
-4
@@ -101,6 +101,7 @@ public:
|
||||
|
||||
// Helper routine for identifing if we're the current page
|
||||
int IsCurrentPage(Page* page);
|
||||
std::string GetCurrentPage() const;
|
||||
|
||||
// These are routing routines
|
||||
int Render(void);
|
||||
@@ -144,10 +145,7 @@ public:
|
||||
static int ChangePage(std::string name);
|
||||
static int ChangeOverlay(std::string name);
|
||||
static const ResourceManager* GetResources();
|
||||
|
||||
// Used for console-only mode
|
||||
static int SwitchToConsole(void);
|
||||
static int EndConsole(void);
|
||||
static std::string GetCurrentPage();
|
||||
|
||||
// Helper to identify if a particular page is the active page
|
||||
static int IsCurrentPage(Page* page);
|
||||
|
||||
@@ -48,6 +48,8 @@ extern "C" {
|
||||
int TWinstall_zip(const char* path, int* wipe_cache);
|
||||
}
|
||||
|
||||
OpenRecoveryScript::VoidFunction OpenRecoveryScript::call_after_cli_command;
|
||||
|
||||
#define SCRIPT_COMMAND_SIZE 512
|
||||
|
||||
int OpenRecoveryScript::check_for_script_file(void) {
|
||||
@@ -398,6 +400,7 @@ int OpenRecoveryScript::run_script_file(void) {
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
unlink(SCRIPT_FILE_TMP);
|
||||
gui_msg("done_ors=Done processing script file");
|
||||
} else {
|
||||
gui_msg(Msg(msg::kError, "error_opening_strerr=Error opening: '{1}' ({2})")(SCRIPT_FILE_TMP)(strerror(errno)));
|
||||
@@ -569,9 +572,11 @@ int OpenRecoveryScript::Backup_Command(string Options) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// this is called by main()
|
||||
void OpenRecoveryScript::Run_OpenRecoveryScript(void) {
|
||||
DataManager::SetValue("tw_back", "main");
|
||||
DataManager::SetValue("tw_action", "openrecoveryscript");
|
||||
DataManager::SetValue("tw_action_param", "");
|
||||
DataManager::SetValue("tw_has_action2", "0");
|
||||
DataManager::SetValue("tw_action2", "");
|
||||
DataManager::SetValue("tw_action2_param", "");
|
||||
@@ -589,3 +594,66 @@ void OpenRecoveryScript::Run_OpenRecoveryScript(void) {
|
||||
LOGERR("Failed to load OpenRecoveryScript GUI page.\n");
|
||||
}
|
||||
}
|
||||
|
||||
// this is called by the "openrecoveryscript" GUI action called via action page from Run_OpenRecoveryScript
|
||||
int OpenRecoveryScript::Run_OpenRecoveryScript_Action() {
|
||||
int op_status = 1;
|
||||
// Check for the SCRIPT_FILE_TMP first as these are AOSP recovery commands
|
||||
// that we converted to ORS commands during boot in recovery.cpp.
|
||||
// Run those first.
|
||||
int reboot = 0;
|
||||
if (TWFunc::Path_Exists(SCRIPT_FILE_TMP)) {
|
||||
gui_msg("running_recovery_commands=Running Recovery Commands");
|
||||
if (OpenRecoveryScript::run_script_file() == 0) {
|
||||
reboot = 1;
|
||||
op_status = 0;
|
||||
}
|
||||
}
|
||||
// Check for the ORS file in /cache and attempt to run those commands.
|
||||
if (OpenRecoveryScript::check_for_script_file()) {
|
||||
gui_msg("running_ors=Running OpenRecoveryScript");
|
||||
if (OpenRecoveryScript::run_script_file() == 0) {
|
||||
reboot = 1;
|
||||
op_status = 0;
|
||||
}
|
||||
}
|
||||
if (reboot) {
|
||||
// Disable stock recovery reflashing
|
||||
TWFunc::Disable_Stock_Recovery_Replace();
|
||||
usleep(2000000); // Sleep for 2 seconds before rebooting
|
||||
TWFunc::tw_reboot(rb_system);
|
||||
usleep(5000000); // Sleep for 5 seconds to allow reboot to occur
|
||||
} else {
|
||||
DataManager::SetValue("tw_page_done", 1);
|
||||
}
|
||||
return op_status;
|
||||
}
|
||||
|
||||
// this is called by the "twcmd" GUI action when a command is received via FIFO from the "twrp" command line tool
|
||||
void OpenRecoveryScript::Run_CLI_Command(const char* command) {
|
||||
if (strlen(command) > 11 && strncmp(command, "runscript", 9) == 0) {
|
||||
const char* filename = command + 10;
|
||||
if (OpenRecoveryScript::copy_script_file(filename) == 0) {
|
||||
LOGINFO("Unable to copy script file\n");
|
||||
} else {
|
||||
OpenRecoveryScript::run_script_file();
|
||||
}
|
||||
} else if (strlen(command) > 5 && strncmp(command, "get", 3) == 0) {
|
||||
const char* varname = command + 4;
|
||||
string value;
|
||||
DataManager::GetValue(varname, value);
|
||||
gui_print("%s = %s\n", varname, value.c_str());
|
||||
} else if (strlen(command) > 9 && strncmp(command, "decrypt", 7) == 0) {
|
||||
const char* pass = command + 8;
|
||||
gui_msg("decrypt_cmd=Attempting to decrypt data partition via command line.");
|
||||
if (PartitionManager.Decrypt_Device(pass) == 0) {
|
||||
// set_page_done = 1; // done by singleaction_page anyway
|
||||
}
|
||||
} else if (OpenRecoveryScript::Insert_ORS_Command(command)) {
|
||||
OpenRecoveryScript::run_script_file();
|
||||
}
|
||||
|
||||
// let the GUI close the output fd and restart the command listener
|
||||
call_after_cli_command();
|
||||
LOGINFO("Done reading ORS command from command line\n");
|
||||
}
|
||||
|
||||
@@ -23,18 +23,23 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
// Partition class
|
||||
class OpenRecoveryScript
|
||||
{
|
||||
public:
|
||||
typedef void (*VoidFunction)();
|
||||
static VoidFunction call_after_cli_command; // callback to GUI after Run_CLI_Command
|
||||
|
||||
static int check_for_script_file(); // Checks to see if the ORS file is present in /cache
|
||||
static int copy_script_file(string filename); // Copies a script file to the temp folder
|
||||
static int run_script_file(); // Executes the commands in the ORS file
|
||||
static int Insert_ORS_Command(string Command); // Inserts the Command into the SCRIPT_FILE_TMP file
|
||||
static int Install_Command(string Zip); // Installs a zip
|
||||
static string Locate_Zip_File(string Path, string File); // Attempts to locate the zip file in storage
|
||||
static int Backup_Command(string Options); // Runs a backup
|
||||
public:
|
||||
static int Insert_ORS_Command(string Command); // Inserts the Command into the SCRIPT_FILE_TMP file
|
||||
static void Run_OpenRecoveryScript(); // Starts the GUI Page for running OpenRecoveryScript
|
||||
static int Run_OpenRecoveryScript_Action(); // Actually runs the ORS scripts for the GUI action
|
||||
static void Call_After_CLI_Command(VoidFunction fn) { call_after_cli_command = fn; }
|
||||
static void Run_CLI_Command(const char* command); // Runs a command for orscmd (twrp binary)
|
||||
};
|
||||
|
||||
#endif // _OPENRECOVERYSCRIPT_HPP
|
||||
|
||||
Reference in New Issue
Block a user