ADB Backup: add ability for TWRP GUI to restore

Restore adb backup files that TWRP made to your PC.
Put files in your backup directory to see them.

e.g. /sdcard/TWRP/BACKUPS/<sn>

Change-Id: I2c57970d77b64c39a302159041456e761c185259
diff --git a/partitionmanager.cpp b/partitionmanager.cpp
index 9b1c1c9..e896cee 100644
--- a/partitionmanager.cpp
+++ b/partitionmanager.cpp
@@ -1,5 +1,5 @@
 /*
-	Copyright 2014 to 2016 TeamWin
+	Copyright 2014 to 2017 TeamWin
 	This file is part of TWRP/TeamWin Recovery Project.
 
 	TWRP is free software: you can redistribute it and/or modify
@@ -667,10 +667,6 @@
 	part_settings.file_bytes = 0;
 	part_settings.PM_Method = PM_BACKUP;
 
-	DataManager::GetValue("tw_enable_adb_backup", gui_adb_backup);
-	if (gui_adb_backup == true)
-		adbbackup = true;
-
 	part_settings.adbbackup = adbbackup;
 	time(&total_start);
 
@@ -865,6 +861,8 @@
 	time_t Start, Stop;
 
 	if (part_settings->adbbackup) {
+		std::string partName = part_settings->Part->Backup_Name + "." + part_settings->Part->Current_File_System + ".win";
+		LOGINFO("setting backup name: %s\n", partName.c_str());
 		part_settings->Part->Set_Backup_FileName(part_settings->Part->Backup_Name + "." + part_settings->Part->Current_File_System + ".win");
 	}
 
@@ -876,7 +874,7 @@
 		TWFunc::SetPerformanceMode(false);
 		return false;
 	}
-	if (part_settings->Part->Has_SubPartition) {
+	if (part_settings->Part->Has_SubPartition && !part_settings->adbbackup) {
 		std::vector<TWPartition*>::iterator subpart;
 		TWPartition *parentPart = part_settings->Part;
 
@@ -884,6 +882,7 @@
 			part_settings->Part = *subpart;
 			if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == parentPart->Mount_Point) {
 				part_settings->Part = (*subpart);
+				part_settings->Part->Set_Backup_FileName(part_settings->Part->Backup_Name + "." + part_settings->Part->Current_File_System + ".win");
 				if (!(*subpart)->Restore(part_settings)) {
 					TWFunc::SetPerformanceMode(false);
 					return false;
@@ -1013,93 +1012,114 @@
 	// Start with the default values
 	string Restore_List;
 	bool get_date = true, check_encryption = true;
+	bool adbbackup = false;
 
 	DataManager::SetValue("tw_restore_encrypted", 0);
-
-	DIR* d;
-	d = opendir(Restore_Name.c_str());
-	if (d == NULL)
-	{
-		gui_msg(Msg(msg::kError, "error_opening_strerr=Error opening: '{1}' ({2})")(Restore_Name)(strerror(errno)));
-		return;
+	if (twadbbu::Check_ADB_Backup_File(Restore_Name)) {
+		vector<string> adb_files;
+		adb_files = twadbbu::Get_ADB_Backup_Files(Restore_Name);
+		for (unsigned int i = 0; i < adb_files.size(); ++i) {
+			string adb_restore_file = adb_files.at(i);
+			std::size_t pos = adb_restore_file.find_first_of(".");
+			std::string path = "/" + adb_restore_file.substr(0, pos);
+			Restore_List = path + ";";
+			TWPartition* Part = Find_Partition_By_Path(path);
+			Part->Backup_FileName = TWFunc::Get_Filename(adb_restore_file);
+			adbbackup = true;
+		}
+		DataManager::SetValue("tw_enable_adb_backup", 1);
 	}
-
-	struct dirent* de;
-	while ((de = readdir(d)) != NULL)
-	{
-		// Strip off three components
-		char str[256];
-		char* label;
-		char* fstype = NULL;
-		char* extn = NULL;
-		char* ptr;
-
-		strcpy(str, de->d_name);
-		if (strlen(str) <= 2)
-			continue;
-
-		if (get_date) {
-			char file_path[255];
-			struct stat st;
-
-			strcpy(file_path, Restore_Name.c_str());
-			strcat(file_path, "/");
-			strcat(file_path, str);
-			stat(file_path, &st);
-			string backup_date = ctime((const time_t*)(&st.st_mtime));
-			DataManager::SetValue(TW_RESTORE_FILE_DATE, backup_date);
-			get_date = false;
-		}
-
-		label = str;
-		ptr = label;
-		while (*ptr && *ptr != '.')	 ptr++;
-		if (*ptr == '.')
+	else {
+		DIR* d;
+		d = opendir(Restore_Name.c_str());
+		if (d == NULL)
 		{
-			*ptr = 0x00;
-			ptr++;
-			fstype = ptr;
+			gui_msg(Msg(msg::kError, "error_opening_strerr=Error opening: '{1}' ({2})")(Restore_Name)(strerror(errno)));
+			return;
 		}
-		while (*ptr && *ptr != '.')	 ptr++;
-		if (*ptr == '.')
+
+		struct dirent* de;
+		while ((de = readdir(d)) != NULL)
 		{
-			*ptr = 0x00;
-			ptr++;
-			extn = ptr;
-		}
+			// Strip off three components
+			char str[256];
+			char* label;
+			char* fstype = NULL;
+			char* extn = NULL;
+			char* ptr;
 
-		if (fstype == NULL || extn == NULL || strcmp(fstype, "log") == 0) continue;
-		int extnlength = strlen(extn);
-		if (extnlength != 3 && extnlength != 6) continue;
-		if (extnlength >= 3 && strncmp(extn, "win", 3) != 0) continue;
-		//if (extnlength == 6 && strncmp(extn, "win000", 6) != 0) continue;
+			strcpy(str, de->d_name);
+			if (strlen(str) <= 2)
+				continue;
 
-		if (check_encryption) {
-			string filename = Restore_Name + "/";
-			filename += de->d_name;
-			if (TWFunc::Get_File_Type(filename) == 2) {
-				LOGINFO("'%s' is encrypted\n", filename.c_str());
-				DataManager::SetValue("tw_restore_encrypted", 1);
+			if (get_date) {
+				char file_path[255];
+				struct stat st;
+
+				strcpy(file_path, Restore_Name.c_str());
+				strcat(file_path, "/");
+				strcat(file_path, str);
+				stat(file_path, &st);
+				string backup_date = ctime((const time_t*)(&st.st_mtime));
+				DataManager::SetValue(TW_RESTORE_FILE_DATE, backup_date);
+				get_date = false;
 			}
-		}
-		if (extnlength == 6 && strncmp(extn, "win000", 6) != 0) continue;
 
-		TWPartition* Part = Find_Partition_By_Path(label);
-		if (Part == NULL)
-		{
-			gui_msg(Msg(msg::kError, "unable_locate_part_backup_name=Unable to locate partition by backup name: '{1}'")(label));
-			continue;
-		}
+			label = str;
+			ptr = label;
+			while (*ptr && *ptr != '.')	 ptr++;
+			if (*ptr == '.')
+			{
+				*ptr = 0x00;
+				ptr++;
+				fstype = ptr;
+			}
+			while (*ptr && *ptr != '.')	 ptr++;
+			if (*ptr == '.')
+			{
+				*ptr = 0x00;
+				ptr++;
+				extn = ptr;
+			}
 
-		Part->Backup_FileName = de->d_name;
-		if (strlen(extn) > 3) {
-			Part->Backup_FileName.resize(Part->Backup_FileName.size() - strlen(extn) + 3);
-		}
+			if (fstype == NULL || extn == NULL || strcmp(fstype, "log") == 0) continue;
+			int extnlength = strlen(extn);
+			if (extnlength != 3 && extnlength != 6) continue;
+			if (extnlength >= 3 && strncmp(extn, "win", 3) != 0) continue;
+			//if (extnlength == 6 && strncmp(extn, "win000", 6) != 0) continue;
 
-		if (!Part->Is_SubPartition)
-			Restore_List += Part->Backup_Path + ";";
+			if (check_encryption) {
+				string filename = Restore_Name + "/";
+				filename += de->d_name;
+				if (TWFunc::Get_File_Type(filename) == 2) {
+					LOGINFO("'%s' is encrypted\n", filename.c_str());
+					DataManager::SetValue("tw_restore_encrypted", 1);
+				}
+			}
+			if (extnlength == 6 && strncmp(extn, "win000", 6) != 0) continue;
+
+			TWPartition* Part = Find_Partition_By_Path(label);
+			if (Part == NULL)
+			{
+				gui_msg(Msg(msg::kError, "unable_locate_part_backup_name=Unable to locate partition by backup name: '{1}'")(label));
+				continue;
+			}
+
+			Part->Backup_FileName = de->d_name;
+			if (strlen(extn) > 3) {
+				Part->Backup_FileName.resize(Part->Backup_FileName.size() - strlen(extn) + 3);
+			}
+
+			if (!Part->Is_SubPartition)
+				Restore_List += Part->Backup_Path + ";";
+		}
+		closedir(d);
 	}
-	closedir(d);
+
+	if (adbbackup) {
+		Restore_List = "ADB_Backup;";
+		adbbackup = false;
+	}
 
 	// Set the final value
 	DataManager::SetValue("tw_restore_list", Restore_List);
@@ -1953,12 +1973,19 @@
 			size_t start_pos = 0, end_pos = Restore_List.find(";", start_pos);
 			while (end_pos != string::npos && start_pos < Restore_List.size()) {
 				restore_path = Restore_List.substr(start_pos, end_pos - start_pos);
+				struct PartitionList part;
+				if (restore_path.compare("ADB_Backup") == 0) {
+					part.Display_Name = "ADB Backup";
+					part.Mount_Point = "ADB Backup";
+					part.selected = 1;
+					Partition_List->push_back(part);
+					break;
+				}
 				if ((restore_part = Find_Partition_By_Path(restore_path)) != NULL) {
 					if ((restore_part->Backup_Name == "recovery" && !restore_part->Can_Be_Backed_Up) || restore_part->Is_SubPartition) {
 						// Don't allow restore of recovery (causes problems on some devices)
 						// Don't add subpartitions to the list of items
 					} else {
-						struct PartitionList part;
 						part.Display_Name = restore_part->Backup_Display_Name;
 						part.Mount_Point = restore_part->Backup_Path;
 						part.selected = 1;