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

Commit 3f7b1ace authored by that's avatar that
Browse files

gui: Move action functions to function pointer map.

This allows the functions to be more readable and make
doActions readable.

Patch set 5: gui: remove threading in GUIAction

Multiple actions were started in another thread that was joined
immediately after starting it, so the input thread was blocked anyway.

Selected single actions were started in their own thread, but this
caused bugs like being able to install the same package twice in
parallel by quickly swiping the slider twice.

Change-Id: I28adadaedd032efc7bff3aaa48e659627aa3a3b3
parent fcdb76dd
Loading
Loading
Loading
Loading
+1082 −1056
Original line number Diff line number Diff line
@@ -53,11 +53,6 @@ extern "C" {
#include "../minadbd/adb.h"
#include "../adb_install.h"
#include "../set_metadata.h"

int TWinstall_zip(const char* path, int* wipe_cache);
void run_script(const char *str1, const char *str2, const char *str3, const char *str4, const char *str5, const char *str6, const char *str7, int request_confirm);
int gui_console_only();
int gui_start();
};

#include "rapidxml.hpp"
@@ -69,6 +64,11 @@ extern blanktimer blankTimer;

void curtainClose(void);

GUIAction::mapFunc GUIAction::mf;
static string zip_queue[10];
static int zip_queue_index;
static pthread_t terminal_command;

GUIAction::GUIAction(xml_node<>* node)
	: GUIObject(node)
{
@@ -78,6 +78,65 @@ GUIAction::GUIAction(xml_node<>* node)

	if (!node)  return;

	if (mf.empty()) {
		mf["reboot"] = &GUIAction::reboot;
		mf["home"] = &GUIAction::home;
		mf["key"] = &GUIAction::key;
		mf["page"] = &GUIAction::page;
		mf["reload"] = &GUIAction::reload;
		mf["readBackup"] = &GUIAction::readBackup;
		mf["set"] = &GUIAction::set;
		mf["clear"] = &GUIAction::clear;
		mf["mount"] = &GUIAction::mount;
		mf["unmount"] = &GUIAction::unmount;
		mf["umount"] = &GUIAction::unmount;
		mf["restoredefaultsettings"] = &GUIAction::restoredefaultsettings;
		mf["copylog"] = &GUIAction::copylog;
		mf["compute"] = &GUIAction::compute;
		mf["addsubtract"] = &GUIAction::compute;
		mf["setguitimezone"] = &GUIAction::setguitimezone;
		mf["overlay"] = &GUIAction::overlay;
		mf["queuezip"] = &GUIAction::queuezip;
		mf["cancelzip"] = &GUIAction::cancelzip;
		mf["queueclear"] = &GUIAction::queueclear;
		mf["sleep"] = &GUIAction::sleep;
		mf["appenddatetobackupname"] = &GUIAction::appenddatetobackupname;
		mf["generatebackupname"] = &GUIAction::generatebackupname;
		mf["checkpartitionlist"] = &GUIAction::checkpartitionlist;
		mf["getpartitiondetails"] = &GUIAction::getpartitiondetails;
		mf["screenshot"] = &GUIAction::screenshot;
		mf["setbrightness"] = &GUIAction::setbrightness;

		// threaded actions
		mf["fileexists"] = &GUIAction::fileexists;
		mf["flash"] = &GUIAction::flash;
		mf["wipe"] = &GUIAction::wipe;
		mf["refreshsizes"] = &GUIAction::refreshsizes;
		mf["nandroid"] = &GUIAction::nandroid;
		mf["fixpermissions"] = &GUIAction::fixpermissions;
		mf["dd"] = &GUIAction::dd;
		mf["partitionsd"] = &GUIAction::partitionsd;
		mf["installhtcdumlock"] = &GUIAction::installhtcdumlock;
		mf["htcdumlockrestoreboot"] = &GUIAction::htcdumlockrestoreboot;
		mf["htcdumlockreflashrecovery"] = &GUIAction::htcdumlockreflashrecovery;
		mf["cmd"] = &GUIAction::cmd;
		mf["terminalcommand"] = &GUIAction::terminalcommand;
		mf["killterminal"] = &GUIAction::killterminal;
		mf["reinjecttwrp"] = &GUIAction::reinjecttwrp;
		mf["checkbackupname"] = &GUIAction::checkbackupname;
		mf["decrypt"] = &GUIAction::decrypt;
		mf["adbsideload"] = &GUIAction::adbsideload;
		mf["adbsideloadcancel"] = &GUIAction::adbsideloadcancel;
		mf["openrecoveryscript"] = &GUIAction::openrecoveryscript;
		mf["installsu"] = &GUIAction::installsu;
		mf["fixsu"] = &GUIAction::fixsu;
		mf["decrypt_backup"] = &GUIAction::decrypt_backup;
		mf["repair"] = &GUIAction::repair;
		mf["changefilesystem"] = &GUIAction::changefilesystem;
		mf["startmtp"] = &GUIAction::startmtp;
		mf["stopmtp"] = &GUIAction::stopmtp;
	}

	// First, get the action
	actions = node->first_node("actions");
	if (actions)	child = actions->first_node("action");
@@ -199,7 +258,7 @@ void GUIAction::simulate_progress_bar(void)
	}
}

int GUIAction::flash_zip(std::string filename, std::string pageName, const int simulate, int* wipe_cache)
int GUIAction::flash_zip(std::string filename, std::string pageName, int* wipe_cache)
{
	int ret_val = 0;

@@ -214,17 +273,12 @@ int GUIAction::flash_zip(std::string filename, std::string pageName, const int s
	// We're going to jump to this page first, like a loading page
	gui_changePage(pageName);

	int fd = -1;
	ZipArchive zip;

	if (!PartitionManager.Mount_By_Path(filename, true))
		return -1;

	// TODO: why again?
	gui_changePage(pageName);

	if (fd >= 0)
		close(fd);

	if (simulate) {
		simulate_progress_bar();
	} else {
@@ -252,73 +306,35 @@ int GUIAction::flash_zip(std::string filename, std::string pageName, const int s

int GUIAction::doActions()
{
	if (mActions.size() < 1)	return -1;
	if (mActions.size() == 1)
		return doAction(mActions.at(0), 0);

	// For multi-action, we always use a thread
	pthread_t t;
	pthread_attr_t tattr;

	if (pthread_attr_init(&tattr)) {
		LOGERR("Unable to pthread_attr_init\n");
	if (mActions.size() < 1)
		return -1;
	}
	if (pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_JOINABLE)) {
		LOGERR("Error setting pthread_attr_setdetachstate\n");
		return -1;
	}
	if (pthread_attr_setscope(&tattr, PTHREAD_SCOPE_SYSTEM)) {
		LOGERR("Error setting pthread_attr_setscope\n");
		return -1;
	}
	/*if (pthread_attr_setstacksize(&tattr, 524288)) {
		LOGERR("Error setting pthread_attr_setstacksize\n");
		return -1;
	}
	*/
	int ret = pthread_create(&t, &tattr, thread_start, this);
	if (ret) {
		LOGERR("Unable to create more threads for actions... continuing in same thread! %i\n", ret);
		thread_start(this);
	} else {
		if (pthread_join(t, NULL)) {
			LOGERR("Error joining threads\n");
		}
	}
	if (pthread_attr_destroy(&tattr)) {
		LOGERR("Failed to pthread_attr_destroy\n");
		return -1;
	}

	std::vector<Action>::iterator it;
	for (it = mActions.begin(); it != mActions.end(); ++it)
		doAction(*it);

	return 0;
}

void* GUIAction::thread_start(void *cookie)
int GUIAction::doAction(Action action)
{
	GUIAction* ourThis = (GUIAction*) cookie;
	DataManager::GetValue(TW_SIMULATE_ACTIONS, simulate);

	DataManager::SetValue(TW_ACTION_BUSY, 1);
	std::string function = gui_parse_text(action.mFunction);
	std::string arg = gui_parse_text(action.mArg);

	if (ourThis->mActions.size() > 1)
	{
		std::vector<Action>::iterator iter;
		for (iter = ourThis->mActions.begin(); iter != ourThis->mActions.end(); iter++)
			ourThis->doAction(*iter, 1);
	}
	else
	{
		ourThis->doAction(ourThis->mActions.at(0), 1);
	}
	int check = 0;
	DataManager::GetValue("tw_background_thread_running", check);
	if (check == 0)
		DataManager::SetValue(TW_ACTION_BUSY, 0);
	return NULL;
	// find function and execute it
	mapFunc::const_iterator funcitr = mf.find(function);
	if (funcitr != mf.end())
		return (this->*funcitr->second)(arg);

	LOGERR("Unknown action '%s'\n", function.c_str());
	return -1;
}

void GUIAction::operation_start(const string operation_name)
{
	LOGINFO("operation_start: '%s'\n", operation_name.c_str());
	time(&Start);
	DataManager::SetValue(TW_ACTION_BUSY, 1);
	DataManager::SetValue("ui_progress", 0);
@@ -327,7 +343,7 @@ void GUIAction::operation_start(const string operation_name)
	DataManager::SetValue("tw_operation_state", 0);
}

void GUIAction::operation_end(const int operation_status, const int simulate)
void GUIAction::operation_end(const int operation_status)
{
	time_t Stop;
	int simulate_fail;
@@ -354,22 +370,10 @@ void GUIAction::operation_end(const int operation_status, const int simulate)
	time(&Stop);
	if ((int) difftime(Stop, Start) > 10)
		DataManager::Vibrate("tw_action_vibrate");
	LOGINFO("operation_end - status=%d\n", operation_status);
}

int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
{
	static string zip_queue[10];
	static int zip_queue_index;
	static pthread_t terminal_command;
	int simulate;

	std::string arg = gui_parse_text(action.mArg);

	std::string function = gui_parse_text(action.mFunction);

	DataManager::GetValue(TW_SIMULATE_ACTIONS, simulate);

	if (function == "reboot")
int GUIAction::reboot(std::string arg)
{
	//curtainClose(); this sometimes causes a crash

@@ -379,14 +383,15 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)

	return 0;
}
	if (function == "home")

int GUIAction::home(std::string arg)
{
	PageManager::SelectPackage("TWRP");
	gui_changePage("main");
	return 0;
}

	if (function == "key")
int GUIAction::key(std::string arg)
{
	const int key = getKeyByName(arg);
	PageManager::NotifyKey(key, true);
@@ -394,12 +399,14 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
	return 0;
}

	if (function == "page") {
int GUIAction::page(std::string arg)
{
	std::string page_name = gui_parse_text(arg);
	return gui_changePage(page_name);
}

	if (function == "reload") {
int GUIAction::reload(std::string arg)
{
	int check = 0, ret_val = 0;
	std::string theme_path;

@@ -421,11 +428,11 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
			ret_val = 1;
		}
	}
		operation_end(ret_val, simulate);
	operation_end(ret_val);
	return 0;
}

	if (function == "readBackup")
int GUIAction::readBackup(std::string arg)
{
	string Restore_Name;
	DataManager::GetValue("tw_restore", Restore_Name);
@@ -433,7 +440,7 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
	return 0;
}

	if (function == "set")
int GUIAction::set(std::string arg)
{
	if (arg.find('=') != string::npos)
	{
@@ -447,13 +454,15 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
		DataManager::SetValue(arg, "1");
	return 0;
}
	if (function == "clear")

int GUIAction::clear(std::string arg)
{
	DataManager::SetValue(arg, "0");
	return 0;
}

	if (function == "mount") {
int GUIAction::mount(std::string arg)
{
	if (arg == "usb") {
		DataManager::SetValue(TW_ACTION_BUSY, 1);
		if (!simulate)
@@ -468,7 +477,8 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
	return 0;
}

	if (function == "umount" || function == "unmount") {
int GUIAction::unmount(std::string arg)
{
	if (arg == "usb") {
		if (!simulate)
			PartitionManager.usb_storage_disable();
@@ -482,7 +492,7 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
	return 0;
}

	if (function == "restoredefaultsettings")
int GUIAction::restoredefaultsettings(std::string arg)
{
	operation_start("Restore Defaults");
	if (simulate) // Simulated so that people don't accidently wipe out the "simulation is on" setting
@@ -492,11 +502,11 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
		PartitionManager.Update_System_Details();
		PartitionManager.Mount_Current_Storage(true);
	}
		operation_end(0, simulate);
	operation_end(0);
	return 0;
}

	if (function == "copylog")
int GUIAction::copylog(std::string arg)
{
	operation_start("Copy Log");
	if (!simulate)
@@ -510,11 +520,12 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
		gui_print("Copied recovery log to %s.\n", DataManager::GetCurrentStoragePath().c_str());
	} else
		simulate_progress_bar();
		operation_end(0, simulate);
	operation_end(0);
	return 0;
}

	if (function == "compute" || function == "addsubtract")

int GUIAction::compute(std::string arg)
{
	if (arg.find("+") != string::npos)
	{
@@ -570,7 +581,7 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
	return -1;
}

	if (function == "setguitimezone")
int GUIAction::setguitimezone(std::string arg)
{
	string SelectedZone;
	DataManager::GetValue(TW_TIME_ZONE_GUISEL, SelectedZone); // read the selected time zone into SelectedZone
@@ -595,15 +606,12 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
	return 0;
}

	if (function == "togglestorage") {
		LOGERR("togglestorage action was deprecated from TWRP\n");
		return 0;
	}

	if (function == "overlay")
int GUIAction::overlay(std::string arg)
{
	return gui_changeOverlay(arg);
}

	if (function == "queuezip")
int GUIAction::queuezip(std::string arg)
{
	if (zip_queue_index >= 10) {
		gui_print("Maximum zip queue reached!\n");
@@ -617,7 +625,7 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
	return 0;
}

	if (function == "cancelzip")
int GUIAction::cancelzip(std::string arg)
{
	if (zip_queue_index <= 0) {
		gui_print("Minimum zip queue reached!\n");
@@ -629,22 +637,22 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
	return 0;
}

	if (function == "queueclear")
int GUIAction::queueclear(std::string arg)
{
	zip_queue_index = 0;
	DataManager::SetValue(TW_ZIP_QUEUE_COUNT, zip_queue_index);
	return 0;
}

	if (function == "sleep")
int GUIAction::sleep(std::string arg)
{
	operation_start("Sleep");
	usleep(atoi(arg.c_str()));
		operation_end(0, simulate);
	operation_end(0);
	return 0;
}

	if (function == "appenddatetobackupname")
int GUIAction::appenddatetobackupname(std::string arg)
{
	operation_start("AppendDateToBackupName");
	string Backup_Name;
@@ -653,18 +661,20 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
	if (Backup_Name.size() > MAX_BACKUP_NAME_LEN)
		Backup_Name.resize(MAX_BACKUP_NAME_LEN);
	DataManager::SetValue(TW_BACKUP_NAME, Backup_Name);
		operation_end(0, simulate);
	operation_end(0);
	return 0;
}

	if (function == "generatebackupname")
int GUIAction::generatebackupname(std::string arg)
{
	operation_start("GenerateBackupName");
	TWFunc::Auto_Generate_Backup_Name();
		operation_end(0, simulate);
	operation_end(0);
	return 0;
}
	if (function == "checkpartitionlist") {

int GUIAction::checkpartitionlist(std::string arg)
{
	string Wipe_List, wipe_path;
	int count = 0;

@@ -689,7 +699,9 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
	}
		return 0;
}
	if (function == "getpartitiondetails") {

int GUIAction::getpartitiondetails(std::string arg)
{
	string Wipe_List, wipe_path;
	int count = 0;

@@ -755,7 +767,7 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
	return 0;
}

	if (function == "screenshot")
int GUIAction::screenshot(std::string arg)
{
	time_t tm;
	char path[256];
@@ -803,37 +815,34 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
	return 0;
}

	if (function == "setbrightness")
int GUIAction::setbrightness(std::string arg)
{
	return TWFunc::Set_Brightness(arg);
}

	if (isThreaded)
	{
		if (function == "fileexists")
int GUIAction::fileexists(std::string arg)
{
	struct stat st;
	string newpath = arg + "/.";

	operation_start("FileExists");
	if (stat(arg.c_str(), &st) == 0 || stat(newpath.c_str(), &st) == 0)
				operation_end(0, simulate);
		operation_end(0);
	else
				operation_end(1, simulate);
		operation_end(1);
	return 0;
}

		if (function == "flash")
int GUIAction::flash(std::string arg)
{
	int i, ret_val = 0, wipe_cache = 0;

	for (i=0; i<zip_queue_index; i++) {
		operation_start("Flashing");
		DataManager::SetValue("tw_filename", zip_queue[i]);
		DataManager::SetValue(TW_ZIP_INDEX, (i + 1));

		TWFunc::SetPerformanceMode(true);
				ret_val = flash_zip(zip_queue[i], arg, simulate, &wipe_cache);
		ret_val = flash_zip(zip_queue[i], arg, &wipe_cache);
		TWFunc::SetPerformanceMode(false);
		if (ret_val != 0) {
			gui_print("Error flashing zip '%s'\n", zip_queue[i].c_str());
@@ -864,10 +873,11 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
		}
	}
	PartitionManager.Update_System_Details();
			operation_end(ret_val, simulate);
	operation_end(ret_val);
	return 0;
}
		if (function == "wipe")

int GUIAction::wipe(std::string arg)
{
	operation_start("Format");
	DataManager::SetValue("tw_partition", arg);
@@ -978,20 +988,22 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
		ret_val = 0; // 0 is success
	else
		ret_val = 1; // 1 is failure
			operation_end(ret_val, simulate);
	operation_end(ret_val);
	return 0;
}
		if (function == "refreshsizes")

int GUIAction::refreshsizes(std::string arg)
{
	operation_start("Refreshing Sizes");
	if (simulate) {
		simulate_progress_bar();
	} else
		PartitionManager.Update_System_Details();
			operation_end(0, simulate);
	operation_end(0);
	return 0;
}
		if (function == "nandroid")

int GUIAction::nandroid(std::string arg)
{
	operation_start("Nandroid");
	int ret = 0;
@@ -1007,7 +1019,7 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
				ret = PartitionManager.Run_Backup();
			}
			else {
						operation_end(1, simulate);
				operation_end(1);
				return -1;

			}
@@ -1017,7 +1029,7 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
			DataManager::GetValue("tw_restore", Restore_Name);
			ret = PartitionManager.Run_Restore(Restore_Name);
		} else {
					operation_end(1, simulate);
			operation_end(1);
					return -1;
				}
			}
@@ -1026,10 +1038,11 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
				ret = 1; // 1 for failure
			else
				ret = 0; // 0 for success
			operation_end(ret, simulate);
			operation_end(ret);
			return 0;
}
		if (function == "fixpermissions")

int GUIAction::fixpermissions(std::string arg)
{
	operation_start("Fix Permissions");
	LOGINFO("fix permissions started!\n");
@@ -1039,11 +1052,12 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
		int op_status = PartitionManager.Fix_Permissions();
		if (op_status != 0)
			op_status = 1; // failure
				operation_end(op_status, simulate);
		operation_end(op_status);
	}
	return 0;
}
		if (function == "dd")

int GUIAction::dd(std::string arg)
{
	operation_start("imaging");

@@ -1053,10 +1067,11 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
		string cmd = "dd " + arg;
		TWFunc::Exec_Cmd(cmd);
	}
			operation_end(0, simulate);
	operation_end(0);
	return 0;
}
		if (function == "partitionsd")

int GUIAction::partitionsd(std::string arg)
{
	operation_start("Partition SD Card");
	int ret_val = 0;
@@ -1073,10 +1088,12 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
				ret_val = 1; // failed
		}
	}
			operation_end(ret_val, simulate);
	operation_end(ret_val);
	return 0;

}
		if (function == "installhtcdumlock")

int GUIAction::installhtcdumlock(std::string arg)
{
	operation_start("Install HTC Dumlock");
	if (simulate) {
@@ -1084,10 +1101,11 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
	} else
		TWFunc::install_htc_dumlock();

			operation_end(0, simulate);
	operation_end(0);
	return 0;
}
		if (function == "htcdumlockrestoreboot")

int GUIAction::htcdumlockrestoreboot(std::string arg)
{
	operation_start("HTC Dumlock Restore Boot");
	if (simulate) {
@@ -1095,10 +1113,11 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
	} else
		TWFunc::htc_dumlock_restore_original_boot();

			operation_end(0, simulate);
	operation_end(0);
	return 0;
}
		if (function == "htcdumlockreflashrecovery")

int GUIAction::htcdumlockreflashrecovery(std::string arg)
{
	operation_start("HTC Dumlock Reflash Recovery");
	if (simulate) {
@@ -1106,10 +1125,11 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
	} else
		TWFunc::htc_dumlock_reflash_recovery_to_boot();

			operation_end(0, simulate);
	operation_end(0);
	return 0;
}
		if (function == "cmd")

int GUIAction::cmd(std::string arg)
{
	int op_status = 0;

@@ -1123,10 +1143,11 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
			op_status = 1;
	}

			operation_end(op_status, simulate);
	operation_end(op_status);
	return 0;
}
		if (function == "terminalcommand")

int GUIAction::terminalcommand(std::string arg)
{
	int op_status = 0;
	string cmdpath, command;
@@ -1136,7 +1157,7 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
	gui_print("%s # %s\n", cmdpath.c_str(), arg.c_str());
	if (simulate) {
		simulate_progress_bar();
				operation_end(op_status, simulate);
		operation_end(op_status);
	} else {
		command = "cd \"" + cmdpath + "\" && " + arg + " 2>&1";;
		LOGINFO("Actual command is: '%s'\n", command.c_str());
@@ -1148,12 +1169,13 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
			LOGERR("Error starting terminal command thread, %i.\n", op_status);
			DataManager::SetValue("tw_terminal_state", 0);
			DataManager::SetValue("tw_background_thread_running", 0);
					operation_end(1, simulate);
			operation_end(1);
		}
	}
	return 0;
}
		if (function == "killterminal")

int GUIAction::killterminal(std::string arg)
{
	int op_status = 0;

@@ -1166,7 +1188,8 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
	DataManager::SetValue(TW_ACTION_BUSY, 0);
	return 0;
}
		if (function == "reinjecttwrp")

int GUIAction::reinjecttwrp(std::string arg)
{
	int op_status = 0;
	operation_start("ReinjectTWRP");
@@ -1178,10 +1201,11 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
		gui_print("TWRP injection complete.\n");
	}

			operation_end(op_status, simulate);
	operation_end(op_status);
	return 0;
}
		if (function == "checkbackupname")

int GUIAction::checkbackupname(std::string arg)
{
	int op_status = 0;

@@ -1194,10 +1218,11 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
			op_status = 1;
	}

			operation_end(op_status, simulate);
	operation_end(op_status);
	return 0;
}
		if (function == "decrypt")

int GUIAction::decrypt(std::string arg)
{
	int op_status = 0;

@@ -1254,10 +1279,11 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
		}
	}

			operation_end(op_status, simulate);
	operation_end(op_status);
	return 0;
}
		if (function == "adbsideload")

int GUIAction::adbsideload(std::string arg)
{
	int ret = 0;

@@ -1323,18 +1349,19 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
			}
		}
	}
			operation_end(ret, simulate);
	operation_end(ret);
	return 0;
}
		if (function == "adbsideloadcancel")

int GUIAction::adbsideloadcancel(std::string arg)
{
			int child_pid, status;
	int child_pid;
	char child_prop[PROPERTY_VALUE_MAX];
	struct stat st;
	DataManager::SetValue("tw_has_cancel", 0); // Remove cancel button from gui
	gui_print("Cancelling ADB sideload...\n");
	stat("/sideload/exit", &st);
			sleep(1);
	::sleep(1);
	property_get("tw_child_pid", child_prop, "error");
	if (strcmp(child_prop, "error") == 0) {
		LOGERR("Unable to get child ID from prop\n");
@@ -1345,7 +1372,9 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
	DataManager::SetValue("tw_page_done", "1"); // For OpenRecoveryScript support
	return 0;
}
		if (function == "openrecoveryscript") {

int GUIAction::openrecoveryscript(std::string arg)
{
	operation_start("OpenRecoveryScript");
	if (simulate) {
		simulate_progress_bar();
@@ -1376,7 +1405,8 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
	}
	return 0;
}
		if (function == "installsu")

int GUIAction::installsu(std::string arg)
{
	int op_status = 0;

@@ -1388,10 +1418,11 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
			op_status = 1;
	}

			operation_end(op_status, simulate);
	operation_end(op_status);
	return 0;
}
		if (function == "fixsu")

int GUIAction::fixsu(std::string arg)
{
	int op_status = 0;

@@ -1403,10 +1434,11 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
		LOGERR("4.3+ ROMs with SELinux will always lose su perms.\n");
	}

			operation_end(op_status, simulate);
	operation_end(op_status);
	return 0;
}
		if (function == "decrypt_backup")

int GUIAction::decrypt_backup(std::string arg)
{
	int op_status = 0;

@@ -1426,10 +1458,11 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
		TWFunc::SetPerformanceMode(false);
	}

			operation_end(op_status, simulate);
	operation_end(op_status);
	return 0;
}
		if (function == "repair")

int GUIAction::repair(std::string arg)
{
	int op_status = 0;

@@ -1447,10 +1480,11 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
		}
	}

			operation_end(op_status, simulate);
	operation_end(op_status);
	return 0;
}
		if (function == "changefilesystem")

int GUIAction::changefilesystem(std::string arg)
{
	int op_status = 0;

@@ -1469,10 +1503,11 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
		}
	}
	PartitionManager.Update_System_Details();
			operation_end(op_status, simulate);
	operation_end(op_status);
	return 0;
}
		if (function == "startmtp")

int GUIAction::startmtp(std::string arg)
{
	int op_status = 0;

@@ -1482,10 +1517,11 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
	else
		op_status = 1; // fail

			operation_end(op_status, simulate);
	operation_end(op_status);
	return 0;
}
		if (function == "stopmtp")

int GUIAction::stopmtp(std::string arg)
{
	int op_status = 0;

@@ -1495,19 +1531,9 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
	else
		op_status = 1; // fail

			operation_end(op_status, simulate);
	operation_end(op_status);
	return 0;
}
	}
	else
	{
		pthread_t t;
		pthread_create(&t, NULL, thread_start, this);
		return 0;
	}
	LOGERR("Unknown action '%s'\n", function.c_str());
	return -1;
}

int GUIAction::getKeyByName(std::string key)
{
+68 −5
Original line number Diff line number Diff line
@@ -264,7 +264,8 @@ public:
	virtual int NotifyTouch(TOUCH_STATE state, int x, int y);
	virtual int NotifyKey(int key, bool down);
	virtual int NotifyVarChange(const std::string& varName, const std::string& value);
	virtual int doActions();

	int doActions();

protected:
	class Action
@@ -279,14 +280,76 @@ protected:

protected:
	int getKeyByName(std::string key);
	virtual int doAction(Action action, int isThreaded = 0);
	static void* thread_start(void *cookie);
	int doAction(Action action);
	void simulate_progress_bar(void);
	int flash_zip(std::string filename, std::string pageName, const int simulate, int* wipe_cache);
	int flash_zip(std::string filename, std::string pageName, int* wipe_cache);
	void operation_start(const string operation_name);
	void operation_end(const int operation_status, const int simulate);
	void operation_end(const int operation_status);
	static void* command_thread(void *cookie);
	time_t Start;

	// map action name to function pointer
	typedef int (GUIAction::*execFunction)(std::string);
	typedef std::map<std::string, execFunction> mapFunc;
	static mapFunc mf;

	// GUI actions
	int reboot(std::string arg);
	int home(std::string arg);
	int key(std::string arg);
	int page(std::string arg);
	int reload(std::string arg);
	int readBackup(std::string arg);
	int set(std::string arg);
	int clear(std::string arg);
	int mount(std::string arg);
	int unmount(std::string arg);
	int restoredefaultsettings(std::string arg);
	int copylog(std::string arg);
	int compute(std::string arg);
	int setguitimezone(std::string arg);
	int overlay(std::string arg);
	int queuezip(std::string arg);
	int cancelzip(std::string arg);
	int queueclear(std::string arg);
	int sleep(std::string arg);
	int appenddatetobackupname(std::string arg);
	int generatebackupname(std::string arg);
	int checkpartitionlist(std::string arg);
	int getpartitiondetails(std::string arg);
	int screenshot(std::string arg);
	int setbrightness(std::string arg);

	// threaded actions
	int fileexists(std::string arg);
	int flash(std::string arg);
	int wipe(std::string arg);
	int refreshsizes(std::string arg);
	int nandroid(std::string arg);
	int fixpermissions(std::string arg);
	int dd(std::string arg);
	int partitionsd(std::string arg);
	int installhtcdumlock(std::string arg);
	int htcdumlockrestoreboot(std::string arg);
	int htcdumlockreflashrecovery(std::string arg);
	int cmd(std::string arg);
	int terminalcommand(std::string arg);
	int killterminal(std::string arg);
	int reinjecttwrp(std::string arg);
	int checkbackupname(std::string arg);
	int decrypt(std::string arg);
	int adbsideload(std::string arg);
	int adbsideloadcancel(std::string arg);
	int openrecoveryscript(std::string arg);
	int installsu(std::string arg);
	int fixsu(std::string arg);
	int decrypt_backup(std::string arg);
	int repair(std::string arg);
	int changefilesystem(std::string arg);
	int startmtp(std::string arg);
	int stopmtp(std::string arg);

	int simulate;
};

class GUIConsole : public GUIObject, public RenderObject, public ActionObject