From 02109b9a7e3e794c48b81e28e743dd8c1407fa19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Allan=20Nordh=C3=B8y?= Date: Sun, 17 Apr 2022 04:34:32 +0000 Subject: [PATCH 1/8] App strings reworked --- app/src/main/res/values/strings.xml | 74 ++++++++++++++--------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 42adfe2..e372c24 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,23 +1,23 @@ Fox\'s Magisk Module Manager Fox\'s Mmm - Failed to get access to Root or Magisk + Could not access either Root or Magisk Loading… - Updatable + Upgradable Installed Online Repo - The application is in lockdown mode - Failed to download file. + The app is in lockdown mode + Could not download the file Modules took too long to boot, consider disabling some modules - Failed to connect to the internet - Failed to get system WebView + Could not connect to the Internet + Could not open system WebView SettingsActivity - Application update available + A new version of the app is available Update No description found. Download module Install module - Update module + Upgrade module Changelog Website Support @@ -26,7 +26,7 @@ Require Android 6.0+ - Last update: + Last version: Repo: by Downloads: @@ -36,63 +36,63 @@ Manage repos Lockdown mode - Lockdown mode prevent manager to do action on modules + Lockdown mode prevents the manager from carrying out actions on modules Settings Info Show licenses Licences Show incompatible modules - Show modules that are incompatible with your device based on their metadata + Show modules unlikely to work on your device based on their metadata Magisk is outdated! Repos - The repository hosting Magisk Modules - An alternative to Magisk-Modules-Repo with fewer restrictions. + The repository hosting Magisk modules + An alternative to the Magisk-Modules-Repo with fewer restrictions. Delete the module files? - Keep files - Delete files - Failed to delete the module files + Keep + Delete + Could not delete the module files Theme Theme mode - Module id: + Module ID: Install module from storage The selected module is in an invalid format Local install Source code - Magisk builtin module - Substratum builtin module - Force dark mode terminal - Your current file picker failed to give access to the file. + Magisk built-in module + Substratum built-in module + Force dark-mode terminal + Your current file picker failed to grant access to the file. Remote install Your file picker returned a non standard response. Use magisk module install command - During test it caused problems to the module install error diagnosis tool, - so I hid this option behind developer mode, enable this at your own risk! + During testing it caused problems to the module install error diagnosis tool, + so this option behind is hidden behind developer mode. Turn this on at your own risk! - Developer mode enabled + Developer mode on Force English language - Disable low quality module filter + Turn off low quality module filter - Some modules do not declare their metadata properly,causing visual glitches, - and/or indicating poor module quality, disable at your own risk! + Some modules do not declare their metadata properly, causing visual glitches, + and/or indicating poor module quality. Turn this off at your own risk! - Dns over https + DNS over HTTPS May fix connections issues in some cases. - (Does not apply to WebView) + (Does not apply to WebView.) - Disable extensions + No Mmm - Disable Fox\'s Mmm extensions, this prevent modules from using - terminal extensions, useful if a module misuse Fox\'s Mmm extensions. + Turn off Fox\'s Mmm extensions, preventing modules from using + terminal extensions. Useful if a module misuses Fox\'s Mmm extensions. Wrap text Wrap text to a new line instead of putting - all text on the same line when installing a module + all text on the same line when installing a module. - Enable blur - Repo enabled - Repo disabled - Androidacy repo uses ads and trackers. + Blur + Repo on + Repo off + The Androidacy repo has ads and trackers. From e5f44b5e088e0a0779d5711515267b7e57fdd78a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Allan=20Nordh=C3=B8y?= Date: Sun, 17 Apr 2022 14:18:20 +0000 Subject: [PATCH 2/8] Suggested changes made --- app/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e372c24..b738d25 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -63,7 +63,7 @@ Force dark-mode terminal Your current file picker failed to grant access to the file. Remote install - Your file picker returned a non standard response. + Your file picker returned a non-standard response. Use magisk module install command During testing it caused problems to the module install error diagnosis tool, From 546f940d4e02eda8a3775d0945c9f3191ad30534 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Allan=20Nordh=C3=B8y?= Date: Sun, 17 Apr 2022 14:18:55 +0000 Subject: [PATCH 3/8] Suggested changes made 2 --- app/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b738d25..97cc2ff 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -64,7 +64,7 @@ Your current file picker failed to grant access to the file. Remote install Your file picker returned a non-standard response. - Use magisk module install command + Use the \"magisk --install-module\" command During testing it caused problems to the module install error diagnosis tool, so this option behind is hidden behind developer mode. Turn this on at your own risk! From 42fe07ba72ab736b6daf08ee9b68a573e6b45986 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Allan=20Nordh=C3=B8y?= Date: Mon, 2 May 2022 10:54:51 +0000 Subject: [PATCH 4/8] Improvements implemented --- app/src/main/res/values/strings.xml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 97cc2ff..9af00c0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -13,7 +13,7 @@ Could not open system WebView SettingsActivity A new version of the app is available - Update + Upgrade No description found. Download module Install module @@ -23,7 +23,7 @@ Support Donate Submit a module - Require Android 6.0+ + Requires Android 6.0+ Last version: @@ -43,7 +43,7 @@ Licences Show incompatible modules Show modules unlikely to work on your device based on their metadata - Magisk is outdated! + There is a new version of Magisk to install! Repos The repository hosting Magisk modules An alternative to the Magisk-Modules-Repo with fewer restrictions. @@ -55,26 +55,26 @@ Theme mode Module ID: Install module from storage - The selected module is in an invalid format + The selected module has an invalid format Local install Source code Magisk built-in module Substratum built-in module - Force dark-mode terminal - Your current file picker failed to grant access to the file. + Dark terminal + Your current file picker could not access the file. Remote install Your file picker returned a non-standard response. Use the \"magisk --install-module\" command During testing it caused problems to the module install error diagnosis tool, - so this option behind is hidden behind developer mode. Turn this on at your own risk! + so this option behind is hidden behind developer mode.\nTurn this on at your own risk! Developer mode on - Force English language - Turn off low quality module filter + English app language + Show low-quality modules Some modules do not declare their metadata properly, causing visual glitches, - and/or indicating poor module quality. Turn this off at your own risk! + and/or indicating poor module quality.\nTurn this off at your own risk! DNS over HTTPS @@ -84,11 +84,11 @@ No Mmm Turn off Fox\'s Mmm extensions, preventing modules from using - terminal extensions. Useful if a module misuses Fox\'s Mmm extensions. + terminal extensions.\nUseful if a module misuses Fox\'s Mmm extensions. - Wrap text + Text wrapping - Wrap text to a new line instead of putting + Show text on multiple lines instead of putting all text on the same line when installing a module. Blur From 0026388f65dc0d859c6762100bb03ee579930413 Mon Sep 17 00:00:00 2001 From: Fox2Code Date: Tue, 3 May 2022 12:57:01 +0200 Subject: [PATCH 5/8] Add system-less AnyKernel module install support. (Experimental) --- .../mmm/installer/InstallerActivity.java | 269 +++++++++++------- .../com/fox2code/mmm/utils/PropUtils.java | 1 + 2 files changed, 161 insertions(+), 109 deletions(-) diff --git a/app/src/main/java/com/fox2code/mmm/installer/InstallerActivity.java b/app/src/main/java/com/fox2code/mmm/installer/InstallerActivity.java index c8a2c0c..288bb53 100644 --- a/app/src/main/java/com/fox2code/mmm/installer/InstallerActivity.java +++ b/app/src/main/java/com/fox2code/mmm/installer/InstallerActivity.java @@ -35,11 +35,14 @@ import com.topjohnwu.superuser.Shell; import com.topjohnwu.superuser.internal.UiThreadHandler; import com.topjohnwu.superuser.io.SuFile; +import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStreamReader; import java.io.OutputStream; +import java.io.PrintStream; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipInputStream; @@ -62,7 +65,8 @@ public class InstallerActivity extends CompatActivity { this.setDisplayHomeAsUpEnabled(true); setActionBarBackground(null); this.setOnBackPressedCallback(a -> { - this.canceled = true; return false; + this.canceled = true; + return false; }); final Intent intent = this.getIntent(); final String target; @@ -95,7 +99,7 @@ public class InstallerActivity extends CompatActivity { setTitle(name); this.textWrap = MainApplication.isTextWrapEnabled(); setContentView(this.textWrap ? - R.layout.installer_wrap :R.layout.installer); + R.layout.installer_wrap : R.layout.installer); int background; int foreground; if (MainApplication.getINSTANCE().isLightTheme() && @@ -118,127 +122,107 @@ public class InstallerActivity extends CompatActivity { this.getWindow().setFlags( // Note: Doesn't require WAKELOCK permission WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - if (urlMode) { - this.progressIndicator.setVisibility(View.VISIBLE); - this.installerTerminal.addLine("- Downloading " + name); - new Thread(() -> { - File moduleCache = this.toDelete = - new File(this.moduleCache, "module.zip"); - if (moduleCache.exists() && !moduleCache.delete() && - !new SuFile(moduleCache.getAbsolutePath()).delete()) - Log.e(TAG, "Failed to delete module cache"); - String errMessage = "Failed to download module zip"; - try { - Log.i(TAG, "Downloading: " + target); - byte[] rawModule = Http.doHttpGet(target,(progress, max, done) -> { - if (max <= 0 && this.progressIndicator.isIndeterminate()) - return; - this.runOnUiThread(() -> { - this.progressIndicator.setIndeterminate(false); - this.progressIndicator.setMax(max); - this.progressIndicator.setProgressCompat(progress, true); - }); + final File moduleFile = urlMode ? null : new File(target); + this.progressIndicator.setVisibility(View.VISIBLE); + this.installerTerminal.addLine("- Downloading " + name); + new Thread(() -> { + File moduleCache = this.toDelete = urlMode ? + new File(this.moduleCache, "module.zip") : moduleFile; + if (moduleCache.exists() && !moduleCache.delete() && + !new SuFile(moduleCache.getAbsolutePath()).delete()) + Log.e(TAG, "Failed to delete module cache"); + String errMessage = "Failed to download module zip"; + try { + Log.i(TAG, "Downloading: " + target); + byte[] rawModule = urlMode ? Http.doHttpGet(target, (progress, max, done) -> { + if (max <= 0 && this.progressIndicator.isIndeterminate()) + return; + this.runOnUiThread(() -> { + this.progressIndicator.setIndeterminate(false); + this.progressIndicator.setMax(max); + this.progressIndicator.setProgressCompat(progress, true); }); + }) : Files.readSU(moduleFile); + this.runOnUiThread(() -> { + this.progressIndicator.setVisibility(View.GONE); + this.progressIndicator.setIndeterminate(true); + }); + if (this.canceled) return; + if (checksum != null && !checksum.isEmpty()) { + Log.d(TAG, "Checking for checksum: " + checksum); this.runOnUiThread(() -> { - this.progressIndicator.setVisibility(View.GONE); - this.progressIndicator.setIndeterminate(true); + this.installerTerminal.addLine("- Checking file integrity"); }); - if (this.canceled) return; - if (checksum != null && !checksum.isEmpty()) { - Log.d(TAG, "Checking for checksum: " + checksum); - this.runOnUiThread(() -> { - this.installerTerminal.addLine("- Checking file integrity"); - }); - if (!Hashes.checkSumMatch(rawModule, checksum)) { - this.setInstallStateFinished(false, - "! File integrity check failed", ""); - return; - } + if (!Hashes.checkSumMatch(rawModule, checksum)) { + this.setInstallStateFinished(false, + "! File integrity check failed", ""); + return; } - if (this.canceled) return; - Files.fixJavaZipHax(rawModule); - boolean noPatch = false; - boolean isModule = false; - boolean isAnyKernel = false; - errMessage = "File is not a valid zip file"; - try (ZipInputStream zipInputStream = new ZipInputStream( - new ByteArrayInputStream(rawModule))) { - ZipEntry zipEntry; - while ((zipEntry = zipInputStream.getNextEntry()) != null) { - String entryName = zipEntry.getName(); - if (entryName.equals("anykernel.sh")) { - isAnyKernel = true; - break; - } else if (entryName.equals("module.prop")) { - noPatch = true; - isModule = true; - break; - } else if (entryName.endsWith("/module.prop")) { - isModule = true; - } + } + if (this.canceled) return; + Files.fixJavaZipHax(rawModule); + boolean noPatch = false; + boolean isModule = false; + boolean isAnyKernel = false; + errMessage = "File is not a valid zip file"; + try (ZipInputStream zipInputStream = new ZipInputStream( + new ByteArrayInputStream(rawModule))) { + ZipEntry zipEntry; + while ((zipEntry = zipInputStream.getNextEntry()) != null) { + String entryName = zipEntry.getName(); + if (entryName.equals("anykernel.sh")) { + noPatch = true; + isAnyKernel = true; + break; + } else if (entryName.equals("module.prop")) { + noPatch = true; + isModule = true; + break; + } else if (entryName.endsWith("/anykernel.sh")) { + isAnyKernel = true; + } else if (entryName.endsWith("/module.prop")) { + isModule = true; } } - if (!isModule) { - this.setInstallStateFinished(false, isAnyKernel ? - "! AnyKernel modules can only be installed on recovery" : - "! File is not a valid magisk module", ""); - return; - } - if (noPatch) { + } + if (!isModule && !isAnyKernel) { + this.setInstallStateFinished(false, + "! File is not a valid magisk module", ""); + return; + } + if (noPatch) { + if (urlMode) { errMessage = "Failed to save module zip"; try (OutputStream outputStream = new FileOutputStream(moduleCache)) { outputStream.write(rawModule); outputStream.flush(); } - } else { - errMessage = "Failed to patch module zip"; - this.runOnUiThread(() -> { - this.installerTerminal.addLine("- Patching " + name); - }); - Log.i(TAG, "Patching: " + moduleCache.getName()); - try (OutputStream outputStream = new FileOutputStream(moduleCache)) { - Files.patchModuleSimple(rawModule, outputStream); - outputStream.flush(); - } } - if (this.canceled) return; - //noinspection UnusedAssignment (Important to avoid OutOfMemoryError) - rawModule = null; // Because reference is kept when calling doInstall + } else { + errMessage = "Failed to patch module zip"; this.runOnUiThread(() -> { - this.installerTerminal.addLine("- Installing " + name); + this.installerTerminal.addLine("- Patching " + name); }); - errMessage = "Failed to install module zip"; - this.doInstall(moduleCache, noExtensions, rootless); - } catch (IOException e) { - Log.e(TAG, errMessage, e); - this.setInstallStateFinished(false, - "! " + errMessage, ""); - } - }, "Module download Thread").start(); - } else { - final File moduleFile = new File(target); - if (checksum != null && !checksum.isEmpty()) { - Log.d(TAG, "Checking for checksum: " + checksum); - this.installerTerminal.addLine("- Checking file integrity"); - try { - if (!Hashes.checkSumMatch(Files.readSU(moduleFile), checksum)) { - this.setInstallStateFinished(false, - "! File integrity check failed", ""); - return; + Log.i(TAG, "Patching: " + moduleCache.getName()); + try (OutputStream outputStream = new FileOutputStream(moduleCache)) { + Files.patchModuleSimple(rawModule, outputStream); + outputStream.flush(); } - } catch (IOException e) { - Log.e(TAG, "Failed to read file for checksum check", e); - this.setInstallStateFinished(false, - "! File integrity check failed", ""); - return; } + //noinspection UnusedAssignment (Important to avoid OutOfMemoryError) + rawModule = null; // Because reference is kept when calling doInstall if (this.canceled) return; + this.runOnUiThread(() -> { + this.installerTerminal.addLine("- Installing " + name); + }); + errMessage = "Failed to install module zip"; + this.doInstall(moduleCache, noExtensions, rootless); + } catch (IOException e) { + Log.e(TAG, errMessage, e); + this.setInstallStateFinished(false, + "! " + errMessage, ""); } - this.installerTerminal.addLine("- Installing " + name); - new Thread(() -> this.doInstall( - this.toDelete = moduleFile, noExtensions, rootless), - "Install Thread").start(); - } + }, "Module install Thread").start(); } @@ -271,15 +255,63 @@ public class InstallerActivity extends CompatActivity { String arch32 = "true"; // Do nothing by default boolean needs32bit = false; String moduleId = null; + boolean anyKernel = false; + boolean magiskModule = false; + boolean anyKernelSystemLess = false; + File anyKernelInstallScript = new File(this.moduleCache, "update-binary"); try (ZipFile zipFile = new ZipFile(file)) { + ZipEntry anyKernelSh = zipFile.getEntry("anykernel.sh"); + if (anyKernelSh != null) { // Check if module is AnyKernel module + BufferedReader bufferedReader = new BufferedReader( + new InputStreamReader(zipFile.getInputStream(anyKernelSh))); + String line; + // Check if AnyKernel module support system-less + while ((line = bufferedReader.readLine()) != null) { + String trimmedLine = line.trim(); + if (trimmedLine.equals("do.modules=1")) + anyKernel = true; + if (trimmedLine.equals("do.systemless=1")) + anyKernelSystemLess = true; + } + bufferedReader.close(); + if (anyKernelSystemLess && anyKernel) { + anyKernelSystemLess = false; + ZipEntry updateBinary = zipFile.getEntry( + "META-INF/com/google/android/update-binary"); + if (updateBinary != null) { + bufferedReader = new BufferedReader( + new InputStreamReader(zipFile.getInputStream(updateBinary))); + PrintStream printStream = new PrintStream( + new FileOutputStream(anyKernelInstallScript)); + while ((line = bufferedReader.readLine()) != null) { + String trimmedLine = line.trim(); + if (trimmedLine.equals("mount_all;") || + trimmedLine.equals("umount_all;")) + continue; // Do not mount anything + line = line.replace("/sbin/sh", "/system/bin/sh"); + int prePatch = line.length(); + line = line.replace("/data/adb/modules/ak3-helper", + "/data/adb/modules-update/ak3-helper"); + if (prePatch != line.length()) anyKernelSystemLess = true; + printStream.println(line); + } + printStream.close(); + bufferedReader.close(); + if (!anyKernelSystemLess) anyKernelInstallScript.delete(); + } + } + anyKernel = true; + } if (zipFile.getEntry( // Check if module hard require 32bit support "common/addon/Volume-Key-Selector/tools/arm64/keycheck") == null && zipFile.getEntry( "common/addon/Volume-Key-Selector/install.sh") != null) { needs32bit = true; } + ZipEntry moduleProp = zipFile.getEntry("module.prop"); + magiskModule = moduleProp != null; moduleId = PropUtils.readModuleId(zipFile - .getInputStream(zipFile.getEntry("module.prop"))); + .getInputStream(moduleProp)); } catch (IOException ignored) {} int compatFlags = AppUpdateManager.getFlagsForModule(moduleId); if ((compatFlags & AppUpdateManager.FLAG_COMPAT_NEED_32BIT) != 0) @@ -294,6 +326,12 @@ public class InstallerActivity extends CompatActivity { null); return; } + if (magiskModule && moduleId == null && !anyKernel) { + // Modules without module Ids are module installed by 3rd party software + this.setInstallStateFinished(false, + "! Magisk modules require a moduleId", null); + return; + } if (Build.SUPPORTED_32_BIT_ABIS.length == 0) { if (needs32bit) { this.setInstallStateFinished(false, @@ -310,14 +348,23 @@ public class InstallerActivity extends CompatActivity { } String installCommand; File installExecutable; - if (InstallerInitializer.peekMagiskVersion() >= + if (anyKernel) { + if (!anyKernelSystemLess) { + this.setInstallStateFinished(false, + "! This AnyKernel module only support recovery install", null); + return; + } + installExecutable = anyKernelInstallScript; + installCommand = "sh \"" + installExecutable.getAbsolutePath() + "\"" + + " /dev/null 0 \"" + file.getAbsolutePath() + "\""; + } else if (InstallerInitializer.peekMagiskVersion() >= Constants.MAGISK_VER_CODE_INSTALL_COMMAND && ((compatFlags & AppUpdateManager.FLAG_COMPAT_MAGISK_CMD) != 0 || noExtensions || MainApplication.isUsingMagiskCommand())) { installCommand = "magisk --install-module \"" + file.getAbsolutePath() + "\""; installExecutable = new File(InstallerInitializer.peekMagiskPath() .equals("/sbin") ? "/sbin/magisk" : "/system/bin/magisk"); - } else { + } else if (moduleId != null) { installExecutable = this.extractInstallScript("module_installer_compat.sh"); if (installExecutable == null) { this.setInstallStateFinished(false, @@ -325,7 +372,11 @@ public class InstallerActivity extends CompatActivity { return; } installCommand = "sh \"" + installExecutable.getAbsolutePath() + "\"" + - " /dev/null 1 \"" + file.getAbsolutePath() + "\""; + " /dev/null 0 \"" + file.getAbsolutePath() + "\""; + } else { + this.setInstallStateFinished(false, + "! Zip file is not a valid Magisk or a AnyKernel module!", null); + return; } installerMonitor = new InstallerMonitor(installExecutable); if (moduleId != null) installerMonitor.setForCleanUp(moduleId); diff --git a/app/src/main/java/com/fox2code/mmm/utils/PropUtils.java b/app/src/main/java/com/fox2code/mmm/utils/PropUtils.java index e680465..63639c2 100644 --- a/app/src/main/java/com/fox2code/mmm/utils/PropUtils.java +++ b/app/src/main/java/com/fox2code/mmm/utils/PropUtils.java @@ -303,6 +303,7 @@ public class PropUtils { } public static String readModuleId(InputStream inputStream) { + if (inputStream == null) return null; String moduleId = null; try (BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(inputStream, StandardCharsets.UTF_8))) { From faf3e3caab0621faf759fa01a9c7a9a56998d357 Mon Sep 17 00:00:00 2001 From: Fox2Code Date: Tue, 3 May 2022 16:18:58 +0200 Subject: [PATCH 6/8] Fix-up previous commit. --- .../main/java/com/fox2code/mmm/NotificationType.java | 6 ++++-- .../com/fox2code/mmm/installer/InstallerActivity.java | 11 +++++------ app/src/main/java/com/fox2code/mmm/utils/Files.java | 6 ++++++ .../java/com/fox2code/mmm/utils/IntentHelper.java | 1 + 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/fox2code/mmm/NotificationType.java b/app/src/main/java/com/fox2code/mmm/NotificationType.java index ab1f86f..4059681 100644 --- a/app/src/main/java/com/fox2code/mmm/NotificationType.java +++ b/app/src/main/java/com/fox2code/mmm/NotificationType.java @@ -83,14 +83,16 @@ public enum NotificationType implements NotificationTypeCst { try { boolean needPatch; try (ZipFile zipFile = new ZipFile(d)) { - needPatch = zipFile.getEntry("module.prop") == null; + needPatch = zipFile.getEntry("module.prop") == null && + zipFile.getEntry("anykernel.sh") == null; } if (needPatch) { Files.patchModuleSimple(Files.read(d), new FileOutputStream(d)); } try (ZipFile zipFile = new ZipFile(d)) { - needPatch = zipFile.getEntry("module.prop") == null; + needPatch = zipFile.getEntry("module.prop") == null && + zipFile.getEntry("anykernel.sh") == null; } if (needPatch) { if (d.exists() && !d.delete()) diff --git a/app/src/main/java/com/fox2code/mmm/installer/InstallerActivity.java b/app/src/main/java/com/fox2code/mmm/installer/InstallerActivity.java index 288bb53..52cb3e2 100644 --- a/app/src/main/java/com/fox2code/mmm/installer/InstallerActivity.java +++ b/app/src/main/java/com/fox2code/mmm/installer/InstallerActivity.java @@ -122,18 +122,17 @@ public class InstallerActivity extends CompatActivity { this.getWindow().setFlags( // Note: Doesn't require WAKELOCK permission WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - final File moduleFile = urlMode ? null : new File(target); this.progressIndicator.setVisibility(View.VISIBLE); - this.installerTerminal.addLine("- Downloading " + name); + if (urlMode) this.installerTerminal.addLine("- Downloading " + name); new Thread(() -> { File moduleCache = this.toDelete = urlMode ? - new File(this.moduleCache, "module.zip") : moduleFile; - if (moduleCache.exists() && !moduleCache.delete() && + new File(this.moduleCache, "module.zip") : new File(target); + if (urlMode && moduleCache.exists() && !moduleCache.delete() && !new SuFile(moduleCache.getAbsolutePath()).delete()) Log.e(TAG, "Failed to delete module cache"); String errMessage = "Failed to download module zip"; try { - Log.i(TAG, "Downloading: " + target); + Log.i(TAG, (urlMode ? "Downloading: " : "Loading: ") + target); byte[] rawModule = urlMode ? Http.doHttpGet(target, (progress, max, done) -> { if (max <= 0 && this.progressIndicator.isIndeterminate()) return; @@ -142,7 +141,7 @@ public class InstallerActivity extends CompatActivity { this.progressIndicator.setMax(max); this.progressIndicator.setProgressCompat(progress, true); }); - }) : Files.readSU(moduleFile); + }) : Files.readSU(moduleCache); this.runOnUiThread(() -> { this.progressIndicator.setVisibility(View.GONE); this.progressIndicator.setIndeterminate(true); diff --git a/app/src/main/java/com/fox2code/mmm/utils/Files.java b/app/src/main/java/com/fox2code/mmm/utils/Files.java index edf6b83..d6d9ae1 100644 --- a/app/src/main/java/com/fox2code/mmm/utils/Files.java +++ b/app/src/main/java/com/fox2code/mmm/utils/Files.java @@ -1,6 +1,7 @@ package com.fox2code.mmm.utils; import android.os.Build; +import android.util.Log; import androidx.annotation.NonNull; @@ -45,6 +46,11 @@ public class Files { } public static byte[] readSU(File file) throws IOException { + if (file.isFile() && file.canRead()) { + try { // Read as app if su not required + return read(file); + } catch (IOException ignored) {} + } try (InputStream inputStream = SuFileInputStream.open(file)) { return readAllBytes(inputStream); } diff --git a/app/src/main/java/com/fox2code/mmm/utils/IntentHelper.java b/app/src/main/java/com/fox2code/mmm/utils/IntentHelper.java index 4d751e0..0026fd1 100644 --- a/app/src/main/java/com/fox2code/mmm/utils/IntentHelper.java +++ b/app/src/main/java/com/fox2code/mmm/utils/IntentHelper.java @@ -371,6 +371,7 @@ public class IntentHelper { } outputStream = new FileOutputStream(destination); Files.copy(inputStream, outputStream); + Log.d(TAG, "File saved at " + destination); success = true; } catch (Exception e) { Log.e(TAG, "failed copy of " + uri, e); From 81143e7d9526f098a9a900ac060e1c6453ec2fb0 Mon Sep 17 00:00:00 2001 From: Fox2Code Date: Tue, 3 May 2022 16:35:17 +0200 Subject: [PATCH 7/8] 0.4.5 Release --- app/build.gradle | 4 ++-- .../java/com/fox2code/mmm/installer/InstallerActivity.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 6b3bf86..3a3abb3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -10,8 +10,8 @@ android { applicationId "com.fox2code.mmm" minSdk 21 targetSdk 32 - versionCode 39 - versionName "0.4.4" + versionCode 40 + versionName "0.4.5" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/app/src/main/java/com/fox2code/mmm/installer/InstallerActivity.java b/app/src/main/java/com/fox2code/mmm/installer/InstallerActivity.java index 52cb3e2..2e85c05 100644 --- a/app/src/main/java/com/fox2code/mmm/installer/InstallerActivity.java +++ b/app/src/main/java/com/fox2code/mmm/installer/InstallerActivity.java @@ -347,7 +347,7 @@ public class InstallerActivity extends CompatActivity { } String installCommand; File installExecutable; - if (anyKernel) { + if (anyKernel && moduleId == null) { // AnyKernel modules don't have a moduleId if (!anyKernelSystemLess) { this.setInstallStateFinished(false, "! This AnyKernel module only support recovery install", null); From dc959ed06f048c70fb6e91d558b3968c304aafda Mon Sep 17 00:00:00 2001 From: Fox2Code Date: Tue, 3 May 2022 17:02:43 +0200 Subject: [PATCH 8/8] Rework code of conduct --- CODE_OF_CONDUCT.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index d638d96..13b3113 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,5 +1,9 @@ # Contributor Covenant Code of Conduct +Note: The code of conduct are the rules that applies to everyone interacting +with the repo, regardless of acceptance, moderators of the repo are not forced +to apply it strictly, so be nice! + ## Our Pledge We as members, contributors, and leaders pledge to make participation in our @@ -24,6 +28,8 @@ community include: and learning from the experience * Focusing on what is best not just for us as individuals, but for the overall community +* Respecting mistakes as something happening to everyone that is useful as + learning material Examples of unacceptable behavior include: @@ -31,8 +37,8 @@ Examples of unacceptable behavior include: advances of any kind * Trolling, insulting or derogatory comments, and personal or political attacks * Public or private harassment -* Publishing others' private information, such as a physical or email - address, without their explicit permission +* Publishing others' private information, such as a physical or email address, + with or without their explicit permission unless widely publicly available * Other conduct which could reasonably be considered inappropriate in a professional setting @@ -73,16 +79,16 @@ the consequences for any action they deem in violation of this Code of Conduct: ### 1. Correction **Community Impact**: Use of inappropriate language or other behavior deemed -unprofessional or unwelcome in the community. +harmful or unwelcome in the community. **Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the -behavior was inappropriate. A public apology may be requested. +behavior was inappropriate. ### 2. Warning **Community Impact**: A violation through a single incident or series -of actions. +of actions, or a behaviour that induce hatred in the community. **Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with