Include common names for Magisk app in list of flashable zip files.

We introduce a new XML element prfxfilter for file name prefix
filtering, e.g. Magisk- .

The file is first matched against the list of extensions and, if there's
no match, then matched against the list of prefixes. An extension or
prefix may be equal to the whole filename.

Change-Id: I46a985c7298799793911948bc74296bebb306d9e
diff --git a/gui/fileselector.cpp b/gui/fileselector.cpp
index 2778f96..a32743a 100644
--- a/gui/fileselector.cpp
+++ b/gui/fileselector.cpp
@@ -69,6 +69,12 @@
 		if (attr)
 			mShowNavFolders = atoi(attr->value());
 	}
+	child = FindNode(node, "prfxfilter");
+	if (child) {
+		attr = child->first_attribute("prfx");
+		if (attr)
+			mPrfx = attr->value();
+	}
 
 	// Handle the path variable
 	child = FindNode(node, "path");
@@ -261,6 +267,7 @@
 
 	while ((de = readdir(d)) != NULL) {
 		FileData data;
+		bool match = false;
 
 		data.fileName = de->d_name;
 		if (data.fileName == ".")
@@ -292,26 +299,52 @@
 			for (const std::string& mExtnElement : mExtnResults)
 			{
 				std::string mExtnName = android::base::Trim(mExtnElement);
-				if (mExtnName.empty() || (data.fileName.length() > mExtnName.length() && data.fileName.substr(data.fileName.length() - mExtnName.length()) == mExtnName)) {
+				if (mExtnName.empty() || (data.fileName.length() >= mExtnName.length() && data.fileName.substr(data.fileName.length() - mExtnName.length()) == mExtnName)) {
 					if (mExtnName == ".ab" && twadbbu::Check_ADB_Backup_File(path))
 						mFolderList.push_back(data);
 					else
 						mFileList.push_back(data);
+					match = true;
+					break;
+				}
 			}
+
+			if (!match) {
+				std::vector<std::string> mPrfxResults = android::base::Split(mPrfx, ";");
+				for (const std::string& mPrfxElement : mPrfxResults)
+				{
+					std::string mPrfxName = android::base::Trim(mPrfxElement);
+					if (!mPrfxName.empty() && data.fileName.length() >= mPrfxName.length() && data.fileName.substr(0, mPrfxName.length()) == mPrfxName) {
+						mFileList.push_back(data);
+					}
 #else //On android 5.1 we can't use android::base::Trim and Split so just use the first extension written in the list
 			std::size_t seppos = mExtn.find_first_of(";");
 			std::string mExtnf;
 			if (seppos!=std::string::npos){
 				mExtnf = mExtn.substr(0, seppos);
 			} else {
-			mExtnf = mExtn;
+				mExtnf = mExtn;
 			}
-			if (mExtnf.empty() || (data.fileName.length() > mExtnf.length() && data.fileName.substr(data.fileName.length() - mExtnf.length()) == mExtnf)) {
+			if (mExtnf.empty() || (data.fileName.length() >= mExtnf.length() && data.fileName.substr(data.fileName.length() - mExtnf.length()) == mExtnf)) {
 				if (mExtnf == ".ab" && twadbbu::Check_ADB_Backup_File(path))
 					mFolderList.push_back(data);
 				else
 					mFileList.push_back(data);
+				match = true;
+			}
+
+			if (!match) {
+				std::size_t seppos = mPrfx.find_first_of(";");
+				std::string mPrfxf;
+				if (seppos!=std::string::npos){
+					mPrfxf = mPrfx.substr(0, seppos);
+				} else {
+					mPrfxf = mPrfx;
+				}
+				if (!mPrfxf.empty() && data.fileName.length() >= mPrfxf.length() && data.fileName.substr(0, mPrfxf.length()) == mPrfxf) {
+					mFileList.push_back(data);
 #endif
+				}
 			}
 		}
 	}
diff --git a/gui/objects.hpp b/gui/objects.hpp
index ccfc522..02f9e54 100755
--- a/gui/objects.hpp
+++ b/gui/objects.hpp
@@ -608,6 +608,7 @@
 	std::string mPathVar; // current path displayed, saved in the data manager
 	std::string mPathDefault; // default value for the path if none is set in mPathVar
 	std::string mExtn; // used for filtering the file list, for example, *.zip
+	std::string mPrfx; // used for filtering the file list, for example, Magisk-
 	std::string mVariable; // set when the user selects an item, pull path like /path/to/foo
 	std::string mSortVariable; // data manager variable used to change the sorting of files
 	std::string mSelection; // set when the user selects an item without the full path like selecting /path/to/foo would just be set to foo
diff --git a/gui/theme/common/landscape.xml b/gui/theme/common/landscape.xml
index babf5b4..65850c0 100755
--- a/gui/theme/common/landscape.xml
+++ b/gui/theme/common/landscape.xml
@@ -311,6 +311,7 @@
 				<placement x="%col2_x_left%" y="%row1a_y%" w="%fileselector_install_width%" h="%fileselector_install_height%"/>
 				<text>%tw_zip_location%</text>
 				<filter extn=".zip;.ozip;.ZIP;.OZIP" folders="0" files="1"/>
+				<prfxfilter prfx="Magisk-;Magisk.apk;app-release.apk;app-debug.apk" folders="1" files="1"/>
 				<path name="tw_zip_location" default="/sdcard"/>
 				<data name="tw_filename"/>
 				<selection name="tw_file"/>
diff --git a/gui/theme/common/portrait.xml b/gui/theme/common/portrait.xml
index 36356fb..b669693 100755
--- a/gui/theme/common/portrait.xml
+++ b/gui/theme/common/portrait.xml
@@ -268,6 +268,7 @@
 				<placement x="%indent%" y="%row3_y%" w="%content_width%" h="%fileselector_install_height%"/>
 				<text>%tw_zip_location%</text>
 				<filter extn=".zip;.ozip;.ZIP;.OZIP" folders="1" files="1"/>
+				<prfxfilter prfx="Magisk-;Magisk.apk;app-release.apk;app-debug.apk" folders="1" files="1"/>
 				<path name="tw_zip_location" default="/sdcard"/>
 				<data name="tw_filename"/>
 				<selection name="tw_file"/>
diff --git a/gui/theme/common/watch.xml b/gui/theme/common/watch.xml
index 05438a6..50f3c2b 100755
--- a/gui/theme/common/watch.xml
+++ b/gui/theme/common/watch.xml
@@ -399,6 +399,7 @@
 				<placement x="%indent%" y="%row2_header_y%" w="%content_width%" h="%fileselector_install_height%"/>
 				<text>%tw_zip_location%</text>
 				<filter extn=".zip;.ozip;.ZIP;.OZIP" folders="1" files="1"/>
+				<prfxfilter prfx="Magisk-;Magisk.apk;app-release.apk;app-debug.apk" folders="1" files="1"/>
 				<path name="tw_zip_location" default="/sdcard"/>
 				<data name="tw_filename"/>
 				<selection name="tw_file"/>