Use magiskboot to repack the boot partition

Set TW_INCLUDE_REPACKTOOLS := true

Must also have:
AB_OTA_UPDATER := true

Use magiskboot and provide GUI options to allow users to repack
their existing boot image to install TWRP (or kernels) so we can
stop having to provide installation zips for AB devices. There is
also an option to try to fix a recovery bootloop if the kernel
has been patched to always boot the ramdisk for root, etc.

You will need to pull the below repo into external/magisk-prebuilt
https://github.com/TeamWin/external_magisk-prebuilt

Change-Id: I74196cc6f095a7576d61886dc96cbc18deba9b04
diff --git a/gui/action.cpp b/gui/action.cpp
index 4b644a9..c4e78cf 100755
--- a/gui/action.cpp
+++ b/gui/action.cpp
@@ -231,6 +231,8 @@
 		ADD_ACTION(twcmd);
 		ADD_ACTION(setbootslot);
 		ADD_ACTION(installapp);
+		ADD_ACTION(repackimage);
+		ADD_ACTION(fixabrecoverybootloop);
 	}
 
 	// First, get the action
@@ -1196,7 +1198,7 @@
 			string Backup_Name;
 			DataManager::GetValue(TW_BACKUP_NAME, Backup_Name);
 			string auto_gen = gui_lookup("auto_generate", "(Auto Generate)");
-			if (Backup_Name == auto_gen || Backup_Name == gui_lookup("curr_date", "(Current Date)") || Backup_Name == "0" || Backup_Name == "(" || PartitionManager.Check_Backup_Name(true) == 0) {
+			if (Backup_Name == auto_gen || Backup_Name == gui_lookup("curr_date", "(Current Date)") || Backup_Name == "0" || Backup_Name == "(" || PartitionManager.Check_Backup_Name(Backup_Name, true, true) == 0) {
 				ret = PartitionManager.Run_Backup(false);
 				DataManager::SetValue("tw_encrypt_backup", 0); // reset value so we don't encrypt every subsequent backup
 				if (!PartitionManager.stop_backup.get_value()) {
@@ -1472,7 +1474,9 @@
 	if (simulate) {
 		simulate_progress_bar();
 	} else {
-		op_status = PartitionManager.Check_Backup_Name(true);
+		string Backup_Name;
+		DataManager::GetValue(TW_BACKUP_NAME, Backup_Name);
+		op_status = PartitionManager.Check_Backup_Name(Backup_Name, true, true);
 		if (op_status != 0)
 			op_status = 1;
 	}
@@ -2053,3 +2057,89 @@
 	operation_end(0);
 	return 0;
 }
+
+int GUIAction::repackimage(std::string arg __unused)
+{
+	int op_status = 1;
+	operation_start("Repack Image");
+	if (!simulate)
+	{
+		std::string path = DataManager::GetStrValue("tw_filename");
+		Repack_Options_struct Repack_Options;
+		Repack_Options.Disable_Verity = false;
+		Repack_Options.Disable_Force_Encrypt = false;
+		Repack_Options.Backup_First = DataManager::GetIntValue("tw_repack_backup_first") != 0;
+		if (DataManager::GetIntValue("tw_repack_kernel") == 1)
+			Repack_Options.Type = REPLACE_KERNEL;
+		else
+			Repack_Options.Type = REPLACE_RAMDISK;
+		if (!PartitionManager.Repack_Images(path, Repack_Options))
+			goto exit;
+	} else
+		simulate_progress_bar();
+	op_status = 0;
+exit:
+	operation_end(op_status);
+	return 0;
+}
+
+int GUIAction::fixabrecoverybootloop(std::string arg __unused)
+{
+	int op_status = 1;
+	operation_start("Repack Image");
+	if (!simulate)
+	{
+		if (!TWFunc::Path_Exists("/sbin/magiskboot")) {
+			LOGERR("Image repacking tool not present in this TWRP build!");
+			goto exit;
+		}
+		DataManager::SetProgress(0);
+		TWPartition* part = PartitionManager.Find_Partition_By_Path("/boot");
+		if (part)
+			gui_msg(Msg("unpacking_image=Unpacking {1}...")(part->Display_Name));
+		else {
+			gui_msg(Msg(msg::kError, "unable_to_locate=Unable to locate {1}.")("/boot"));
+			goto exit;
+		}
+		if (!PartitionManager.Prepare_Repack(part, REPACK_ORIG_DIR, DataManager::GetIntValue("tw_repack_backup_first") != 0, gui_lookup("repack", "Repack")))
+			goto exit;
+		DataManager::SetProgress(.25);
+		gui_msg("fixing_recovery_loop_patch=Patching kernel...");
+		std::string command = "cd " REPACK_ORIG_DIR " && /sbin/magiskboot --hexpatch kernel 77616E745F696E697472616D667300 736B69705F696E697472616D667300";
+		if (TWFunc::Exec_Cmd(command) != 0) {
+			gui_msg(Msg(msg::kError, "fix_recovery_loop_patch_error=Error patching kernel."));
+			goto exit;
+		}
+		std::string header_path = REPACK_ORIG_DIR;
+		header_path += "header";
+		if (TWFunc::Path_Exists(header_path)) {
+			command = "cd " REPACK_ORIG_DIR " && sed -i \"s|$(grep '^cmdline=' header | cut -d= -f2-)|$(grep '^cmdline=' header | cut -d= -f2- | sed -e 's/skip_override//' -e 's/  */ /g' -e 's/[ \t]*$//')|\" header";
+			if (TWFunc::Exec_Cmd(command) != 0) {
+				gui_msg(Msg(msg::kError, "fix_recovery_loop_patch_error=Error patching kernel."));
+				goto exit;
+			}
+		}
+		DataManager::SetProgress(.5);
+		gui_msg(Msg("repacking_image=Repacking {1}...")(part->Display_Name));
+		command = "cd " REPACK_ORIG_DIR " && /sbin/magiskboot --repack " REPACK_ORIG_DIR "boot.img";
+		if (TWFunc::Exec_Cmd(command) != 0) {
+			gui_msg(Msg(msg::kError, "repack_error=Error repacking image."));
+			goto exit;
+		}
+		DataManager::SetProgress(.75);
+		std::string path = REPACK_ORIG_DIR;
+		std::string file = "new-boot.img";
+		DataManager::SetValue("tw_flash_partition", "/boot;");
+		if (!PartitionManager.Flash_Image(path, file)) {
+			LOGINFO("Error flashing new image\n");
+			goto exit;
+		}
+		DataManager::SetProgress(1);
+		TWFunc::removeDir(REPACK_ORIG_DIR, false);
+	} else
+		simulate_progress_bar();
+	op_status = 0;
+exit:
+	operation_end(op_status);
+	return 0;
+}
diff --git a/gui/objects.hpp b/gui/objects.hpp
index 630cf71..2e306e0 100644
--- a/gui/objects.hpp
+++ b/gui/objects.hpp
@@ -367,6 +367,8 @@
 	int twcmd(std::string arg);
 	int setbootslot(std::string arg);
 	int installapp(std::string arg);
+	int repackimage(std::string arg);
+	int fixabrecoverybootloop(std::string arg);
 
 	int simulate;
 };
diff --git a/gui/theme/common/landscape.xml b/gui/theme/common/landscape.xml
index a3e6ed8..bb9878f 100755
--- a/gui/theme/common/landscape.xml
+++ b/gui/theme/common/landscape.xml
@@ -3398,6 +3398,41 @@
 						<action function="page">confirm_action</action>
 					</actions>
 				</listitem>
+				<listitem name="{@install_twrp_ramdisk=Install Recovery Ramdisk}">
+					<conditions>
+						<condition var1="tw_has_boot_slots" var2="1"/>
+						<condition var1="tw_has_repack_tools" var2="1"/>
+					</conditions>
+					<actions>
+						<action function="set">tw_repack_kernel=0</action>
+						<action function="page">repackselect</action>
+					</actions>
+				</listitem>
+				<listitem name="{@install_kernel=Install Kernel}">
+					<conditions>
+						<condition var1="tw_has_boot_slots" var2="1"/>
+						<condition var1="tw_has_repack_tools" var2="1"/>
+					</conditions>
+					<actions>
+						<action function="set">tw_repack_kernel=1</action>
+						<action function="page">repackselect</action>
+					</actions>
+				</listitem>
+				<listitem name="{@fix_recovery_loop=Fix Recovery Bootloop}">
+					<conditions>
+						<condition var1="tw_has_boot_slots" var2="1"/>
+						<condition var1="tw_has_repack_tools" var2="1"/>
+					</conditions>
+					<actions>
+						<action function="set">tw_back=advanced</action>
+						<action function="set">tw_action=fixabrecoverybootloop</action>
+						<action function="set">tw_text1={@fix_recovery_loop_confirm=Fix Recovery Bootloop?}</action>
+						<action function="set">tw_action_text1={@fixing_recovery_loop=Fixing Recovery Bootloop...}</action>
+						<action function="set">tw_complete_text1={@fix_recovery_loop_complete=Fix Recovery Bootloop Complete}</action>
+						<action function="set">tw_slider_text={@swipe_to_confirm=Swipe to Confirm}</action>
+						<action function="page">confirm_action</action>
+					</actions>
+				</listitem>
 			</listbox>
 
 			<action>
@@ -3657,6 +3692,140 @@
 			</action>
 		</page>
 
+		<page name="repackselect">
+			<template name="page"/>
+
+			<text style="text_l">
+				<placement x="%col1_x_header%" y="%row3_header_y%"/>
+				<text>{@repack_image_hdr=Select Image}</text>
+			</text>
+
+			<text style="text_m">
+				<placement x="%col1_x_header%" y="%row4_header_y%"/>
+				<text>{@select_file_from_storage=Select File from %tw_storage_display_name% (%tw_storage_free_size% MB)}</text>
+			</text>
+
+			<template name="sort_options"/>
+
+			<fileselector>
+				<placement x="%col1_x_left%" y="%row1a_y%" w="%content_quarter_width%" h="%fileselector_filemanager_height%"/>
+				<text>%tw_zip_location%</text>
+				<filter extn=".img" folders="1" files="1"/>
+				<path name="tw_zip_location" default="/sdcard"/>
+				<data name="tw_filename"/>
+				<selection name="tw_file"/>
+			</fileselector>
+
+			<button style="main_button_half_width_low">
+				<placement x="%col_button_right%" y="%row16a_y%"/>
+				<text>{@select_storage_btn=Select Storage}</text>
+				<actions>
+					<action function="set">tw_back=install</action>
+					<action function="overlay">select_storage</action>
+				</actions>
+			</button>
+
+			<action>
+				<conditions>
+					<condition var1="tw_filename" op="modified"/>
+				</conditions>
+				<action function="page">repackconfirm</action>
+			</action>
+
+			<action>
+				<touch key="back"/>
+				<action function="page">advanced</action>
+			</action>
+
+			<action>
+				<touch key="home"/>
+				<action function="page">main</action>
+			</action>
+		</page>
+
+		<page name="repackconfirm">
+			<template name="page"/>
+
+			<text style="text_l">
+				<condition var1="tw_repack_kernel" var2="1"/>
+				<placement x="%col1_x_header%" y="%row3_header_y%"/>
+				<text>{@repack_kernel_confirm_hdr=Install Kernel}</text>
+			</text>
+
+			<text style="text_l">
+				<condition var1="tw_repack_kernel" var2="0"/>
+				<placement x="%col1_x_header%" y="%row3_header_y%"/>
+				<text>{@repack_ramdisk_confirm_hdr=Install Recovery}</text>
+			</text>
+
+			<text style="text_m">
+				<condition var1="tw_repack_kernel" var2="1"/>
+				<placement x="%col1_x_header%" y="%row4_header_y%"/>
+				<text>{@repack_kernel_confirm=Install Kernel?}</text>
+			</text>
+
+			<text style="text_m">
+				<condition var1="tw_repack_kernel" var2="0"/>
+				<placement x="%col1_x_header%" y="%row4_header_y%"/>
+				<text>{@repack_ramdisk_confirm=Install Recovery?}</text>
+			</text>
+
+			<text style="text_m_accent">
+				<placement x="%indent%" y="%row2_y%"/>
+				<text>{@folder=Folder:}</text>
+			</text>
+
+			<text style="text_m">
+				<placement x="%indent%" y="%row3_y%"/>
+				<text>%tw_zip_location%</text>
+			</text>
+
+			<text style="text_m_accent">
+				<placement x="%indent%" y="%row4_y%"/>
+				<text>{@file=File:}</text>
+			</text>
+
+			<text style="text_m">
+				<placement x="%indent%" y="%row5_y%"/>
+				<text>%tw_file%</text>
+			</text>
+
+			<checkbox>
+				<placement x="%indent%" y="%row7_y%"/>
+				<text>{@repack_backup_first=Back up existing image first}</text>
+				<data variable="tw_repack_backup_first"/>
+			</checkbox>
+
+			<button style="main_button_half_width">
+				<placement x="%col1_x_left%" y="%row15a_y%"/>
+				<text>{@install_cancel=Do not Install}</text>
+				<action function="page">repackselect</action>
+			</button>
+
+			<slider style="slider_centered">
+				<text>{@swipe_to_install=Swipe to Install}</text>
+				<actions>
+					<action function="set">tw_back=advanced</action>
+					<action function="set">tw_action=repackimage</action>
+					<action function="set">tw_action_param=/boot</action>
+					<action function="set">tw_action_text1={@installing=Installing...}</action>
+					<action function="set">tw_action_text2=</action>
+					<action function="set">tw_complete_text1={@install_complete=Install Complete}</action>
+					<action function="page">action_page</action>
+				</actions>
+			</slider>
+
+			<action>
+				<touch key="back"/>
+				<action function="page">repackselect</action>
+			</action>
+
+			<action>
+				<touch key="home"/>
+				<action function="page">main</action>
+			</action>
+		</page>
+
 		<page name="lock">
 			<background color="%semi_transparent%"/>
 
diff --git a/gui/theme/common/languages/en.xml b/gui/theme/common/languages/en.xml
index e61f6c0..7a60120 100755
--- a/gui/theme/common/languages/en.xml
+++ b/gui/theme/common/languages/en.xml
@@ -486,6 +486,28 @@
 		<string name="install_cancel">Do Not Install</string>
 		<string name="sel_storage_list">Select Storage</string>
 		<string name="ok_btn">OK</string>
+		<string name="install_twrp_ramdisk">Install Recovery Ramdisk</string>
+		<string name="install_kernel">Install Kernel</string>
+		<string name="repack_kernel_confirm_hdr">Install Kernel</string>
+		<string name="repack_ramdisk_confirm_hdr">Install Recovery</string>
+		<string name="repack_kernel_confirm">Install Kernel?</string>
+		<string name="repack_ramdisk_confirm">Install Recovery?</string>
+		<string name="repack_backup_first">Back up existing image first</string>
+		<string name="repack">Repack</string>
+		<string name="swipe_to_install">Swipe to Install</string>
+		<string name="installing">Installing...</string>
+		<string name="install_complete">Install Complete</string>
+		<string name="unpack_error">Error unpacking image.</string>
+		<string name="repack_error">Error repacking image.</string>
+		<string name="unpacking_image">Unpacking {1}...</string>
+		<string name="repacking_image">Repacking {1}...</string>
+		<string name="repack_image_hdr">Select Image</string>
+		<string name="fix_recovery_loop">Fix Recovery Bootloop</string>
+		<string name="fix_recovery_loop_confirm">Fix Recovery Bootloop?</string>
+		<string name="fixing_recovery_loop">Fixing Recovery Bootloop...</string>
+		<string name="fix_recovery_loop_complete">Fix Recovery Bootloop Complete</string>
+		<string name="fixing_recovery_loop_patch">Patching kernel...</string>
+		<string name="fix_recovery_loop_patch_error">Error patching kernel.</string>
 
 		<!-- Various console messages - these consist of user displayed messages, oftentimes errors -->
 		<string name="no_kernel_selinux">Kernel does not have support for reading SELinux contexts.</string>
diff --git a/gui/theme/common/portrait.xml b/gui/theme/common/portrait.xml
index c993225..691f149 100755
--- a/gui/theme/common/portrait.xml
+++ b/gui/theme/common/portrait.xml
@@ -3559,6 +3559,41 @@
 						<action function="page">confirm_action</action>
 					</actions>
 				</listitem>
+				<listitem name="{@install_twrp_ramdisk=Install Recovery Ramdisk}">
+					<conditions>
+						<condition var1="tw_has_boot_slots" var2="1"/>
+						<condition var1="tw_has_repack_tools" var2="1"/>
+					</conditions>
+					<actions>
+						<action function="set">tw_repack_kernel=0</action>
+						<action function="page">repackselect</action>
+					</actions>
+				</listitem>
+				<listitem name="{@install_kernel=Install Kernel}">
+					<conditions>
+						<condition var1="tw_has_boot_slots" var2="1"/>
+						<condition var1="tw_has_repack_tools" var2="1"/>
+					</conditions>
+					<actions>
+						<action function="set">tw_repack_kernel=1</action>
+						<action function="page">repackselect</action>
+					</actions>
+				</listitem>
+				<listitem name="{@fix_recovery_loop=Fix Recovery Bootloop}">
+					<conditions>
+						<condition var1="tw_has_boot_slots" var2="1"/>
+						<condition var1="tw_has_repack_tools" var2="1"/>
+					</conditions>
+					<actions>
+						<action function="set">tw_back=advanced</action>
+						<action function="set">tw_action=fixabrecoverybootloop</action>
+						<action function="set">tw_text1={@fix_recovery_loop_confirm=Fix Recovery Bootloop?}</action>
+						<action function="set">tw_action_text1={@fixing_recovery_loop=Fixing Recovery Bootloop...}</action>
+						<action function="set">tw_complete_text1={@fix_recovery_loop_complete=Fix Recovery Bootloop Complete}</action>
+						<action function="set">tw_slider_text={@swipe_to_confirm=Swipe to Confirm}</action>
+						<action function="page">confirm_action</action>
+					</actions>
+				</listitem>
 			</listbox>
 
 			<action>
@@ -3821,6 +3856,140 @@
 			</action>
 		</page>
 
+		<page name="repackselect">
+			<template name="page"/>
+
+			<text style="text_l">
+				<placement x="%col1_x_header%" y="%row3_header_y%"/>
+				<text>{@repack_image_hdr=Select Image}</text>
+			</text>
+
+			<text style="text_m">
+				<placement x="%col1_x_header%" y="%row4_header_y%"/>
+				<text>{@select_file_from_storage=Select File from %tw_storage_display_name% (%tw_storage_free_size% MB)}</text>
+			</text>
+
+			<template name="sort_options"/>
+
+			<fileselector>
+				<placement x="%indent%" y="%row3_y%" w="%content_width%" h="%fileselector_install_height%"/>
+				<text>%tw_zip_location%</text>
+				<filter extn=".img" folders="1" files="1"/>
+				<path name="tw_zip_location" default="/sdcard"/>
+				<data name="tw_filename"/>
+				<selection name="tw_file"/>
+			</fileselector>
+
+			<button style="main_button_half_height">
+				<placement x="%indent%" y="%row21a_y%"/>
+				<text>{@select_storage_btn=Select Storage}</text>
+				<actions>
+					<action function="set">tw_back=repackselect</action>
+					<action function="overlay">select_storage</action>
+				</actions>
+			</button>
+
+			<action>
+				<conditions>
+					<condition var1="tw_filename" op="modified"/>
+				</conditions>
+				<action function="page">repackconfirm</action>
+			</action>
+
+			<action>
+				<touch key="back"/>
+				<action function="page">advanced</action>
+			</action>
+
+			<action>
+				<touch key="home"/>
+				<action function="page">main</action>
+			</action>
+		</page>
+
+		<page name="repackconfirm">
+			<template name="page"/>
+
+			<text style="text_l">
+				<condition var1="tw_repack_kernel" var2="1"/>
+				<placement x="%col1_x_header%" y="%row3_header_y%"/>
+				<text>{@repack_kernel_confirm_hdr=Install Kernel}</text>
+			</text>
+
+			<text style="text_l">
+				<condition var1="tw_repack_kernel" var2="0"/>
+				<placement x="%col1_x_header%" y="%row3_header_y%"/>
+				<text>{@repack_ramdisk_confirm_hdr=Install Recovery}</text>
+			</text>
+
+			<text style="text_m">
+				<condition var1="tw_repack_kernel" var2="1"/>
+				<placement x="%col1_x_header%" y="%row4_header_y%"/>
+				<text>{@repack_kernel_confirm=Install Kernel?}</text>
+			</text>
+
+			<text style="text_m">
+				<condition var1="tw_repack_kernel" var2="0"/>
+				<placement x="%col1_x_header%" y="%row4_header_y%"/>
+				<text>{@repack_ramdisk_confirm=Install Recovery?}</text>
+			</text>
+
+			<text style="text_m_accent">
+				<placement x="%indent%" y="%row2_y%"/>
+				<text>{@folder=Folder:}</text>
+			</text>
+
+			<text style="text_m">
+				<placement x="%indent%" y="%row3_y%"/>
+				<text>%tw_zip_location%</text>
+			</text>
+
+			<text style="text_m_accent">
+				<placement x="%indent%" y="%row4_y%"/>
+				<text>{@file=File:}</text>
+			</text>
+
+			<text style="text_m">
+				<placement x="%indent%" y="%row5_y%"/>
+				<text>%tw_file%</text>
+			</text>
+
+			<checkbox>
+				<placement x="%indent%" y="%row7_y%"/>
+				<text>{@repack_backup_first=Back up existing image first}</text>
+				<data variable="tw_repack_backup_first"/>
+			</checkbox>
+
+			<button style="main_button_half_height">
+				<placement x="%indent%" y="%row16_y%"/>
+				<text>{@install_cancel=Do not Install}</text>
+				<action function="page">repackselect</action>
+			</button>
+
+			<slider>
+				<text>{@swipe_to_install=Swipe to Install}</text>
+				<actions>
+					<action function="set">tw_back=advanced</action>
+					<action function="set">tw_action=repackimage</action>
+					<action function="set">tw_action_param=/boot</action>
+					<action function="set">tw_action_text1={@installing=Installing...}</action>
+					<action function="set">tw_action_text2=</action>
+					<action function="set">tw_complete_text1={@install_complete=Install Complete}</action>
+					<action function="page">action_page</action>
+				</actions>
+			</slider>
+
+			<action>
+				<touch key="back"/>
+				<action function="page">repackselect</action>
+			</action>
+
+			<action>
+				<touch key="home"/>
+				<action function="page">main</action>
+			</action>
+		</page>
+
 		<page name="lock">
 			<background color="%semi_transparent%"/>
 
diff --git a/gui/theme/common/watch.xml b/gui/theme/common/watch.xml
index 79ac5ec..fcb00bc 100755
--- a/gui/theme/common/watch.xml
+++ b/gui/theme/common/watch.xml
@@ -4170,6 +4170,41 @@
 						<action function="page">confirm_action</action>
 					</actions>
 				</listitem>
+				<listitem name="{@install_twrp_ramdisk=Install Recovery Ramdisk}">
+					<conditions>
+						<condition var1="tw_has_boot_slots" var2="1"/>
+						<condition var1="tw_has_repack_tools" var2="1"/>
+					</conditions>
+					<actions>
+						<action function="set">tw_repack_kernel=0</action>
+						<action function="page">repackselect</action>
+					</actions>
+				</listitem>
+				<listitem name="{@install_kernel=Install Kernel}">
+					<conditions>
+						<condition var1="tw_has_boot_slots" var2="1"/>
+						<condition var1="tw_has_repack_tools" var2="1"/>
+					</conditions>
+					<actions>
+						<action function="set">tw_repack_kernel=1</action>
+						<action function="page">repackselect</action>
+					</actions>
+				</listitem>
+				<listitem name="{@fix_recovery_loop=Fix Recovery Bootloop}">
+					<conditions>
+						<condition var1="tw_has_boot_slots" var2="1"/>
+						<condition var1="tw_has_repack_tools" var2="1"/>
+					</conditions>
+					<actions>
+						<action function="set">tw_back=advanced</action>
+						<action function="set">tw_action=fixabrecoverybootloop</action>
+						<action function="set">tw_text1={@fix_recovery_loop_confirm=Fix Recovery Bootloop?}</action>
+						<action function="set">tw_action_text1={@fixing_recovery_loop=Fixing Recovery Bootloop...}</action>
+						<action function="set">tw_complete_text1={@fix_recovery_loop_complete=Fix Recovery Bootloop Complete}</action>
+						<action function="set">tw_slider_text={@swipe_to_confirm=Swipe to Confirm}</action>
+						<action function="page">confirm_action</action>
+					</actions>
+				</listitem>
 			</listbox>
 
 			<button>
@@ -4576,6 +4611,121 @@
 			</action>
 		</page>
 
+		<page name="repackselect">
+			<template name="page"/>
+
+			<template name="statusbar"/>
+
+			<text style="text_m">
+				<placement x="%col1_x_left%" y="%row1_header_y%"/>
+				<text>{@repack_image_hdr=Select Image}</text>
+			</text>
+
+			<fileselector>
+				<placement x="%indent%" y="%row2_header_y%" w="%content_width%" h="%fileselector_install_height%"/>
+				<text>%tw_zip_location%</text>
+				<filter extn=".img" folders="1" files="1"/>
+				<path name="tw_zip_location" default="/sdcard"/>
+				<data name="tw_filename"/>
+				<selection name="tw_file"/>
+			</fileselector>
+
+			<button>
+				<placement x="%btn4_col4_x%" y="%row11_y%"/>
+				<highlight color="%highlight_color%"/>
+				<image resource="q_btn_storage"/>
+				<actions>
+					<action function="set">tw_storagetext={@install_hdr=Install} &gt; {@select_storage_hdr=Select Storage}</action>
+					<action function="set">tw_back=install</action>
+					<action function="page">select_storage</action>
+				</actions>
+			</button>
+
+			<action>
+				<conditions>
+					<condition var1="tw_filename" op="modified"/>
+				</conditions>
+				<action function="page">repackconfirm</action>
+			</action>
+
+			<action>
+				<touch key="back"/>
+				<action function="page">advanced</action>
+			</action>
+
+			<action>
+				<touch key="home"/>
+				<action function="page">main</action>
+			</action>
+		</page>
+
+		<page name="repackconfirm">
+			<template name="page"/>
+
+			<template name="statusbar"/>
+
+			<text style="text_m">
+				<condition var1="tw_repack_kernel" var2="1"/>
+				<placement x="%col1_x_left%" y="%row1_header_y%"/>
+				<text>{@repack_kernel_confirm=Install Kernel?}</text>
+			</text>
+
+			<text style="text_m">
+				<condition var1="tw_repack_kernel" var2="0"/>
+				<placement x="%col1_x_left%" y="%row1_header_y%"/>
+				<text>{@repack_ramdisk_confirm=Install Recovery?}</text>
+			</text>
+
+			<text style="text_m_accent">
+				<placement x="%indent%" y="%row2_y%"/>
+				<text>{@folder=Folder:}</text>
+			</text>
+
+			<text style="text_m">
+				<placement x="%indent%" y="%row3_y%"/>
+				<text>%tw_zip_location%</text>
+			</text>
+
+			<text style="text_m_accent">
+				<placement x="%indent%" y="%row4_y%"/>
+				<text>{@file=File:}</text>
+			</text>
+
+			<text style="text_m">
+				<placement x="%indent%" y="%row5_y%"/>
+				<text>%tw_file%</text>
+			</text>
+
+			<checkbox>
+				<placement x="%indent%" y="%row7_y%"/>
+				<text>{@repack_backup_first=Back up existing image first}</text>
+				<data variable="tw_repack_backup_first"/>
+			</checkbox>
+
+			<slider>
+				<text>{@swipe_to_install=Swipe to Install}</text>
+				<actions>
+					<action function="set">tw_back=advanced</action>
+					<action function="set">tw_action=repackimage</action>
+					<action function="set">tw_action_param=/boot</action>
+					<action function="set">tw_action_text1={@installing=Installing...}</action>
+					<action function="set">tw_action_text2=</action>
+					<action function="set">tw_complete_text1={@install_complete=Install Complete}</action>
+					<action function="page">action_page</action>
+				</actions>
+			</slider>
+
+			<action>
+				<touch key="back"/>
+				<action function="page">repackselect</action>
+			</action>
+
+			<action>
+				<touch key="home"/>
+				<action function="page">main</action>
+			</action>
+		</page>
+
 		<page name="lock">
 			<background color="%semi_transparent%"/>