diff --git a/app/build.gradle b/app/build.gradle index 3a3abb3..569854f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -97,7 +97,7 @@ dependencies { // Utils implementation 'com.squareup.okhttp3:okhttp-dnsoverhttps:4.9.3' implementation 'com.squareup.okhttp3:okhttp-brotli:4.9.3' - implementation 'com.github.topjohnwu.libsu:io:4.0.3' + implementation 'com.github.topjohnwu.libsu:io:5.0.0' // Markdown implementation "io.noties.markwon:core:4.6.2" diff --git a/app/src/main/java/com/fox2code/mmm/ActionButtonType.java b/app/src/main/java/com/fox2code/mmm/ActionButtonType.java index 73a104c..4315b80 100644 --- a/app/src/main/java/com/fox2code/mmm/ActionButtonType.java +++ b/app/src/main/java/com/fox2code/mmm/ActionButtonType.java @@ -18,6 +18,7 @@ import com.fox2code.mmm.installer.InstallerInitializer; import com.fox2code.mmm.manager.LocalModuleInfo; import com.fox2code.mmm.manager.ModuleInfo; import com.fox2code.mmm.manager.ModuleManager; +import com.fox2code.mmm.module.ModuleHolder; import com.fox2code.mmm.utils.IntentHelper; import com.google.android.material.dialog.MaterialAlertDialogBuilder; diff --git a/app/src/main/java/com/fox2code/mmm/MainActivity.java b/app/src/main/java/com/fox2code/mmm/MainActivity.java index 17bf080..3afe7cf 100644 --- a/app/src/main/java/com/fox2code/mmm/MainActivity.java +++ b/app/src/main/java/com/fox2code/mmm/MainActivity.java @@ -20,17 +20,22 @@ import android.view.View; import android.view.WindowManager; import android.view.inputmethod.EditorInfo; import android.widget.TextView; +import android.widget.Toast; import com.fox2code.mmm.compat.CompatActivity; import com.fox2code.mmm.compat.CompatDisplay; import com.fox2code.mmm.installer.InstallerInitializer; import com.fox2code.mmm.manager.LocalModuleInfo; import com.fox2code.mmm.manager.ModuleManager; +import com.fox2code.mmm.module.ModuleViewAdapter; +import com.fox2code.mmm.module.ModuleViewListBuilder; import com.fox2code.mmm.repo.RepoManager; import com.fox2code.mmm.settings.SettingsActivity; import com.fox2code.mmm.utils.Http; import com.fox2code.mmm.utils.IntentHelper; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.progressindicator.LinearProgressIndicator; +import com.topjohnwu.superuser.Shell; import eightbitlab.com.blurview.BlurView; import eightbitlab.com.blurview.RenderScriptBlur; @@ -133,6 +138,7 @@ public class MainActivity extends CompatActivity implements SwipeRefreshLayout.O this.searchView.setEnabled(false); // Enabled later this.cardIconifyUpdate(); this.updateScreenInsets(this.getResources().getConfiguration()); + InstallerInitializer.tryGetMagiskPathAsync(new InstallerInitializer.Callback() { @Override public void onPathReceived(String path) { @@ -378,9 +384,7 @@ public class MainActivity extends CompatActivity implements SwipeRefreshLayout.O this.searchView.clearFocus(); if (this.initMode) return false; if (this.moduleViewListBuilder.setQueryChange(query)) { - new Thread(() -> { - this.moduleViewListBuilder.applyTo(moduleList, moduleViewAdapter); - }, "Query update thread").start(); + new Thread(() -> this.moduleViewListBuilder.applyTo(moduleList, moduleViewAdapter), "Query update thread").start(); } return true; } @@ -389,9 +393,7 @@ public class MainActivity extends CompatActivity implements SwipeRefreshLayout.O public boolean onQueryTextChange(String query) { if (this.initMode) return false; if (this.moduleViewListBuilder.setQueryChange(query)) { - new Thread(() -> { - this.moduleViewListBuilder.applyTo(moduleList, moduleViewAdapter); - }, "Query update thread").start(); + new Thread(() -> this.moduleViewListBuilder.applyTo(moduleList, moduleViewAdapter), "Query update thread").start(); } return false; } @@ -400,9 +402,7 @@ public class MainActivity extends CompatActivity implements SwipeRefreshLayout.O public boolean onClose() { if (this.initMode) return false; if (this.moduleViewListBuilder.setQueryChange(null)) { - new Thread(() -> { - this.moduleViewListBuilder.applyTo(moduleList, moduleViewAdapter); - }, "Query update thread").start(); + new Thread(() -> this.moduleViewListBuilder.applyTo(moduleList, moduleViewAdapter), "Query update thread").start(); } return false; } diff --git a/app/src/main/java/com/fox2code/mmm/MainApplication.java b/app/src/main/java/com/fox2code/mmm/MainApplication.java index d2c2443..059fefe 100644 --- a/app/src/main/java/com/fox2code/mmm/MainApplication.java +++ b/app/src/main/java/com/fox2code/mmm/MainApplication.java @@ -91,6 +91,10 @@ public class MainApplication extends CompatApplication { return getSharedPreferences().getBoolean("pref_showcase_mode", false); } + public static boolean shouldPreventReboot() { + return getSharedPreferences().getBoolean("pref_prevent_reboot", false); + } + public static boolean isShowIncompatibleModules() { return getSharedPreferences().getBoolean("pref_show_incompatible", false); } diff --git a/app/src/main/java/com/fox2code/mmm/NotificationType.java b/app/src/main/java/com/fox2code/mmm/NotificationType.java index 4059681..a92a784 100644 --- a/app/src/main/java/com/fox2code/mmm/NotificationType.java +++ b/app/src/main/java/com/fox2code/mmm/NotificationType.java @@ -33,7 +33,7 @@ public enum NotificationType implements NotificationTypeCst { } }, NO_ROOT(R.string.fail_root_magisk, R.drawable.ic_baseline_numbers_24, v -> { - IntentHelper.openUrl(v.getContext(), "https://github.com/topjohnwu/Magisk"); + IntentHelper.openUrl(v.getContext(), "https://github.com/topjohnwu/Magisk/blob/master/docs/install.md"); }) { @Override public boolean shouldRemove() { @@ -41,7 +41,7 @@ public enum NotificationType implements NotificationTypeCst { } }, MAGISK_OUTDATED(R.string.magisk_outdated, R.drawable.ic_baseline_update_24, v -> { - IntentHelper.openUrl(v.getContext(), "https://github.com/topjohnwu/Magisk"); + IntentHelper.openUrl(v.getContext(), "https://github.com/topjohnwu/Magisk/releases"); }) { @Override public boolean shouldRemove() { @@ -120,7 +120,7 @@ public enum NotificationType implements NotificationTypeCst { InstallerInitializer.peekMagiskPath() == null); } }); - }, true) { + }, false) { @Override public boolean shouldRemove() { return !BuildConfig.DEBUG && 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 2e85c05..7304acb 100644 --- a/app/src/main/java/com/fox2code/mmm/installer/InstallerActivity.java +++ b/app/src/main/java/com/fox2code/mmm/installer/InstallerActivity.java @@ -29,6 +29,8 @@ import com.fox2code.mmm.utils.Hashes; import com.fox2code.mmm.utils.Http; import com.fox2code.mmm.utils.IntentHelper; import com.fox2code.mmm.utils.PropUtils; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton; import com.google.android.material.progressindicator.LinearProgressIndicator; import com.topjohnwu.superuser.CallbackList; import com.topjohnwu.superuser.Shell; @@ -50,6 +52,7 @@ import java.util.zip.ZipInputStream; public class InstallerActivity extends CompatActivity { private static final String TAG = "InstallerActivity"; public LinearProgressIndicator progressIndicator; + public ExtendedFloatingActionButton rebootFloatingButton; public InstallerTerminal installerTerminal; private File moduleCache; private File toDelete; @@ -113,6 +116,7 @@ public class InstallerActivity extends CompatActivity { View horizontalScroller = findViewById(R.id.install_horizontal_scroller); RecyclerView installTerminal; this.progressIndicator = findViewById(R.id.progress_bar); + this.rebootFloatingButton = findViewById(R.id.install_terminal_reboot_fab); this.installerTerminal = new InstallerTerminal( installTerminal = findViewById(R.id.install_terminal), foreground); (horizontalScroller != null ? horizontalScroller : installTerminal) @@ -225,7 +229,7 @@ public class InstallerActivity extends CompatActivity { } - private void doInstall(File file,boolean noExtensions,boolean rootless) { + private void doInstall(File file, boolean noExtensions, boolean rootless) { if (this.canceled) return; UiThreadHandler.runAndWait(() -> { this.setOnBackPressedCallback(DISABLE_BACK_BUTTON); @@ -310,8 +314,9 @@ public class InstallerActivity extends CompatActivity { ZipEntry moduleProp = zipFile.getEntry("module.prop"); magiskModule = moduleProp != null; moduleId = PropUtils.readModuleId(zipFile - .getInputStream(moduleProp)); - } catch (IOException ignored) {} + .getInputStream(zipFile.getEntry("module.prop"))); + } catch (IOException ignored) { + } int compatFlags = AppUpdateManager.getFlagsForModule(moduleId); if ((compatFlags & AppUpdateManager.FLAG_COMPAT_NEED_32BIT) != 0) needs32bit = true; @@ -396,7 +401,8 @@ public class InstallerActivity extends CompatActivity { } boolean success = installJob.exec().isSuccess(); // Wait one UI cycle before disabling controller or processing results - UiThreadHandler.runAndWait(() -> {}); // to avoid race conditions + UiThreadHandler.runAndWait(() -> { + }); // to avoid race conditions installerController.disable(); String message = "- Install successful"; if (!success) { @@ -420,7 +426,7 @@ public class InstallerActivity extends CompatActivity { private String supportLink = ""; private InstallerController(LinearProgressIndicator progressIndicator, - InstallerTerminal terminal,File moduleFile, + InstallerTerminal terminal, File moduleFile, boolean noExtension) { this.progressIndicator = progressIndicator; this.terminal = terminal; @@ -503,7 +509,8 @@ public class InstallerActivity extends CompatActivity { try { this.progressIndicator.setProgressCompat( Short.parseShort(arg), true); - } catch (Exception ignored) {} + } catch (Exception ignored) { + } break; case "hideLoading": this.progressIndicator.setVisibility(View.GONE); @@ -596,7 +603,7 @@ public class InstallerActivity extends CompatActivity { } @SuppressWarnings("SameParameterValue") - private void setInstallStateFinished(boolean success, String message,String optionalLink) { + private void setInstallStateFinished(boolean success, String message, String optionalLink) { if (success && toDelete != null && !toDelete.delete()) { SuFile suFile = new SuFile(toDelete.getAbsolutePath()); if (suFile.exists() && !suFile.delete()) @@ -608,14 +615,37 @@ public class InstallerActivity extends CompatActivity { this.setOnBackPressedCallback(null); this.setDisplayHomeAsUpEnabled(true); this.progressIndicator.setVisibility(View.GONE); + + // This should be improved ? + String reboot_cmd = "/system/bin/svc power reboot || /system/bin/reboot"; + rebootFloatingButton.setOnClickListener(_view -> { + if (MainApplication.shouldPreventReboot()) { + MaterialAlertDialogBuilder builder = + new MaterialAlertDialogBuilder(this); + + builder + .setTitle(R.string.install_terminal_reboot_now) + .setCancelable(false) + .setIcon(R.drawable.ic_reboot_24) + .setPositiveButton(R.string.yes, (x, y) -> { + Shell.cmd(reboot_cmd).submit(); + }) + .setNegativeButton(R.string.no, (x, y) -> { + x.dismiss(); + }).show(); + } else { + Shell.cmd(reboot_cmd).submit(); + } + }); + if (message != null && !message.isEmpty()) this.installerTerminal.addLine(message); if (!optionalLink.isEmpty()) { this.setActionBarExtraMenuButton(ActionButtonType.supportIconForUrl(optionalLink), menu -> { - IntentHelper.openUrl(this, optionalLink); - return true; - }); + IntentHelper.openUrl(this, optionalLink); + return true; + }); } else if (success) { final Intent intent = this.getIntent(); final String config = MainApplication.checkSecret(intent) ? @@ -628,6 +658,7 @@ public class InstallerActivity extends CompatActivity { IntentHelper.openConfig(this, config); return true; }); + this.rebootFloatingButton.setVisibility(View.VISIBLE); } catch (PackageManager.NameNotFoundException e) { Log.w(TAG, "Config package \"" + configPkg + "\" missing for installer view"); diff --git a/app/src/main/java/com/fox2code/mmm/ModuleHolder.java b/app/src/main/java/com/fox2code/mmm/module/ModuleHolder.java similarity index 98% rename from app/src/main/java/com/fox2code/mmm/ModuleHolder.java rename to app/src/main/java/com/fox2code/mmm/module/ModuleHolder.java index 416115b..2f841fe 100644 --- a/app/src/main/java/com/fox2code/mmm/ModuleHolder.java +++ b/app/src/main/java/com/fox2code/mmm/module/ModuleHolder.java @@ -1,4 +1,4 @@ -package com.fox2code.mmm; +package com.fox2code.mmm.module; import android.content.Context; import android.content.pm.PackageManager; @@ -8,6 +8,11 @@ import android.view.View; import androidx.annotation.NonNull; import androidx.annotation.StringRes; +import com.fox2code.mmm.ActionButtonType; +import com.fox2code.mmm.MainApplication; +import com.fox2code.mmm.NotificationType; +import com.fox2code.mmm.R; +import com.fox2code.mmm.XHooks; import com.fox2code.mmm.manager.LocalModuleInfo; import com.fox2code.mmm.manager.ModuleInfo; import com.fox2code.mmm.repo.RepoModule; diff --git a/app/src/main/java/com/fox2code/mmm/ModuleSorter.java b/app/src/main/java/com/fox2code/mmm/module/ModuleSorter.java similarity index 95% rename from app/src/main/java/com/fox2code/mmm/ModuleSorter.java rename to app/src/main/java/com/fox2code/mmm/module/ModuleSorter.java index 193576d..b353a2a 100644 --- a/app/src/main/java/com/fox2code/mmm/ModuleSorter.java +++ b/app/src/main/java/com/fox2code/mmm/module/ModuleSorter.java @@ -1,7 +1,9 @@ -package com.fox2code.mmm; +package com.fox2code.mmm.module; import androidx.annotation.DrawableRes; +import com.fox2code.mmm.R; + import java.util.Comparator; public enum ModuleSorter implements Comparator { diff --git a/app/src/main/java/com/fox2code/mmm/ModuleViewAdapter.java b/app/src/main/java/com/fox2code/mmm/module/ModuleViewAdapter.java similarity index 97% rename from app/src/main/java/com/fox2code/mmm/ModuleViewAdapter.java rename to app/src/main/java/com/fox2code/mmm/module/ModuleViewAdapter.java index 5c70f9d..ec47cb6 100644 --- a/app/src/main/java/com/fox2code/mmm/ModuleViewAdapter.java +++ b/app/src/main/java/com/fox2code/mmm/module/ModuleViewAdapter.java @@ -1,4 +1,4 @@ -package com.fox2code.mmm; +package com.fox2code.mmm.module; import android.annotation.SuppressLint; import android.content.res.Resources; @@ -18,6 +18,10 @@ import androidx.annotation.StringRes; import androidx.cardview.widget.CardView; import androidx.recyclerview.widget.RecyclerView; +import com.fox2code.mmm.ActionButtonType; +import com.fox2code.mmm.MainApplication; +import com.fox2code.mmm.NotificationType; +import com.fox2code.mmm.R; import com.fox2code.mmm.manager.LocalModuleInfo; import com.fox2code.mmm.manager.ModuleInfo; import com.fox2code.mmm.manager.ModuleManager; @@ -269,7 +273,7 @@ public final class ModuleViewAdapter extends RecyclerView.Adapter + + diff --git a/app/src/main/res/layout/installer.xml b/app/src/main/res/layout/installer.xml index 236d9b2..61e0e7f 100644 --- a/app/src/main/res/layout/installer.xml +++ b/app/src/main/res/layout/installer.xml @@ -33,4 +33,17 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> + + \ No newline at end of file diff --git a/app/src/main/res/layout/markdown_view.xml b/app/src/main/res/layout/markdown_view.xml index a7616e7..81e1391 100644 --- a/app/src/main/res/layout/markdown_view.xml +++ b/app/src/main/res/layout/markdown_view.xml @@ -1,37 +1,28 @@ - - - + - + + - - - - - - + android:text="" /> + + \ No newline at end of file diff --git a/app/src/main/res/layout/module_entry.xml b/app/src/main/res/layout/module_entry.xml index 43e2ad6..49e04d7 100644 --- a/app/src/main/res/layout/module_entry.xml +++ b/app/src/main/res/layout/module_entry.xml @@ -8,8 +8,7 @@ android:layout_marginRight="8dp" android:layout_marginTop="2dp" android:layout_marginBottom="2dp" - android:gravity="center_vertical" - android:background="@null"> + android:gravity="center_vertical"> + android:layout_margin="8dp"> + Fox\'s Magisk Module Manager Fox\'s Mmm Could not access either Root or Magisk @@ -24,6 +24,9 @@ Donate Submit a module Requires Android 6.0+ + Reboot + Yes + No Last version: @@ -37,6 +40,8 @@ Manage repos Lockdown mode Lockdown mode prevents the manager from carrying out actions on modules + Prevent reboot + Prevents unexpected reboots Settings Info Show licenses @@ -45,6 +50,9 @@ Show modules unlikely to work on your device based on their metadata There is a new version of Magisk to install! Repos + Security + Appearance + General The repository hosting Magisk modules An alternative to the Magisk-Modules-Repo with fewer restrictions. Delete the module files? @@ -64,7 +72,7 @@ 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 + 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.\nTurn this on at your own risk! diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 0e8aa5b..86439aa 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -1,8 +1,8 @@ + + - -