performance profile support

Many device trees support the recovery.perf.mode property to
set various core frequencies and online/offline mode. TWRP is
highly threaded, and support for multiple cores on many operations
dramatically recudes the time, e.g., backups, zip flashes, etc.

p2: removed user notifications

Change-Id: I957b8ca40b241c0af0471327eeb329cce1816017
diff --git a/gui/action.cpp b/gui/action.cpp
index 7e43222..398ef50 100644
--- a/gui/action.cpp
+++ b/gui/action.cpp
@@ -853,7 +853,9 @@
 				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);
+				TWFunc::SetPerformanceMode(false);
 				if (ret_val != 0) {
 					gui_print("Error flashing zip '%s'\n", zip_queue[i].c_str());
 					i = 10; // Error flashing zip - exit queue
@@ -1416,10 +1418,12 @@
 				DataManager::GetValue("tw_restore", Restore_Path);
 				Restore_Path += "/";
 				DataManager::GetValue("tw_restore_password", Password);
+				TWFunc::SetPerformanceMode(true);
 				if (TWFunc::Try_Decrypting_Backup(Restore_Path, Password))
 					op_status = 0; // success
 				else
 					op_status = 1; // fail
+				TWFunc::SetPerformanceMode(false);
 			}
 
 			operation_end(op_status, simulate);
diff --git a/partitionmanager.cpp b/partitionmanager.cpp
index b2d7b4e..7215374 100644
--- a/partitionmanager.cpp
+++ b/partitionmanager.cpp
@@ -651,9 +651,11 @@
 	pos = section_time / (float) total_time;
 	//DataManager::ShowProgress(pos, section_time);
 
+	TWFunc::SetPerformanceMode(true);
 	time(&start);
 
 	if (Part->Backup(Backup_Folder, &total_size, &current_size)) {
+		bool md5Success = false;
 		current_size += Part->Backup_Size;
 		pos = (float)((float)(current_size) / (float)(total_size));
 		DataManager::SetProgress(pos);
@@ -662,12 +664,16 @@
 
 			for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
 				if ((*subpart)->Can_Be_Backed_Up && (*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point) {
-					if (!(*subpart)->Backup(Backup_Folder, &total_size, &current_size))
+					if (!(*subpart)->Backup(Backup_Folder, &total_size, &current_size)) {
+						TWFunc::SetPerformanceMode(false);
 						return false;
+					}
 					sync();
 					sync();
-					if (!Make_MD5(generate_md5, Backup_Folder, (*subpart)->Backup_FileName))
+					if (!Make_MD5(generate_md5, Backup_Folder, (*subpart)->Backup_FileName)) {
+						TWFunc::SetPerformanceMode(false);
 						return false;
+					}
 					if (Part->Backup_Method == 1) {
 						*file_bytes_remaining -= (*subpart)->Backup_Size;
 					} else {
@@ -689,8 +695,12 @@
 			*img_bytes_remaining -= Part->Backup_Size;
 			*img_time += backup_time;
 		}
-		return Make_MD5(generate_md5, Backup_Folder, Part->Backup_FileName);
+
+		md5Success = Make_MD5(generate_md5, Backup_Folder, Part->Backup_FileName);
+		TWFunc::SetPerformanceMode(false);
+		return md5Success;
 	} else {
+		TWFunc::SetPerformanceMode(false);
 		return false;
 	}
 }
@@ -862,21 +872,27 @@
 
 bool TWPartitionManager::Restore_Partition(TWPartition* Part, string Restore_Name, int partition_count, const unsigned long long *total_restore_size, unsigned long long *already_restored_size) {
 	time_t Start, Stop;
+	TWFunc::SetPerformanceMode(true);
 	time(&Start);
 	//DataManager::ShowProgress(1.0 / (float)partition_count, 150);
-	if (!Part->Restore(Restore_Name, total_restore_size, already_restored_size))
+	if (!Part->Restore(Restore_Name, total_restore_size, already_restored_size)) {
+		TWFunc::SetPerformanceMode(false);
 		return false;
+	}
 	if (Part->Has_SubPartition) {
 		std::vector<TWPartition*>::iterator subpart;
 
 		for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
 			if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point) {
-				if (!(*subpart)->Restore(Restore_Name, total_restore_size, already_restored_size))
+				if (!(*subpart)->Restore(Restore_Name, total_restore_size, already_restored_size)) {
+					TWFunc::SetPerformanceMode(false);
 					return false;
+				}
 			}
 		}
 	}
 	time(&Stop);
+	TWFunc::SetPerformanceMode(false);
 	gui_print("[%s done (%d seconds)]\n\n", Part->Backup_Display_Name.c_str(), (int)difftime(Stop, Start));
 	return true;
 }
diff --git a/twrp-functions.cpp b/twrp-functions.cpp
index 1798c49..cd8700f 100644
--- a/twrp-functions.cpp
+++ b/twrp-functions.cpp
@@ -42,6 +42,7 @@
 #include "partitions.hpp"
 #include "variables.h"
 #include "bootloader.h"
+#include "cutils/properties.h"
 #ifdef ANDROID_RB_POWEROFF
 	#include "cutils/android_reboot.h"
 #endif
@@ -1278,4 +1279,14 @@
 #endif
 }
 
+void TWFunc::SetPerformanceMode(bool mode) {
+	if (mode) {
+		property_set("recovery.perf.mode", "1");
+	} else {
+		property_set("recovery.perf.mode", "0");
+	}
+	// Some time for events to catch up to init handlers
+	usleep(500000);
+}
+
 #endif // ndef BUILD_TWRPTAR_MAIN
diff --git a/twrp-functions.hpp b/twrp-functions.hpp
index c46738e..de14d94 100644
--- a/twrp-functions.hpp
+++ b/twrp-functions.hpp
@@ -87,6 +87,8 @@
 	static int Set_Brightness(std::string brightness_value); // Well, you can read, it does what it says, passing return int from TWFunc::Write_File ;)
 	static bool Toggle_MTP(bool enable);                                        // Disables MTP if enable is false and re-enables MTP if enable is true and it was enabled the last time it was toggled off
 
+	static void SetPerformanceMode(bool mode); // support recovery.perf.mode
+
 private:
 	static void Copy_Log(string Source, string Destination);