diff --git a/app/src/main/java/com/fox2code/mmm/MainApplication.java b/app/src/main/java/com/fox2code/mmm/MainApplication.java index 1a9abd9..5fb3281 100644 --- a/app/src/main/java/com/fox2code/mmm/MainApplication.java +++ b/app/src/main/java/com/fox2code/mmm/MainApplication.java @@ -47,37 +47,33 @@ import io.noties.markwon.syntax.SyntaxHighlightPlugin; import io.noties.prism4j.Prism4j; import io.noties.prism4j.annotations.PrismBundle; -@PrismBundle( - includeAll = true, - grammarLocatorClassName = ".Prism4jGrammarLocator" -) -public class MainApplication extends FoxApplication - implements androidx.work.Configuration.Provider { +@PrismBundle(includeAll = true, grammarLocatorClassName = ".Prism4jGrammarLocator") +public class MainApplication extends FoxApplication implements androidx.work.Configuration.Provider { private static final String TAG = "MainApplication"; private static final String timeFormatString = "dd MMM yyyy"; // Example: 13 july 2001 - private static Locale timeFormatLocale = - Resources.getSystem().getConfiguration().locale; - private static SimpleDateFormat timeFormat = - new SimpleDateFormat(timeFormatString, timeFormatLocale); private static final Shell.Builder shellBuilder; private static final long secret; @SuppressLint("RestrictedApi") // Use FoxProcess wrapper helper. private static final boolean wrapped = !FoxProcessExt.isRootLoader(); + private static Locale timeFormatLocale = Resources.getSystem().getConfiguration().locale; + private static SimpleDateFormat timeFormat = new SimpleDateFormat(timeFormatString, timeFormatLocale); private static SharedPreferences bootSharedPreferences; private static String relPackageName = BuildConfig.APPLICATION_ID; private static MainApplication INSTANCE; private static boolean firstBoot; - // Provides the Context for the base application - public Context FoxApplication = this; static { - Shell.setDefaultBuilder(shellBuilder = Shell.Builder.create() - .setFlags(Shell.FLAG_REDIRECT_STDERR) - .setTimeout(10).setInitializers(InstallerInitializer.class) - ); + Shell.setDefaultBuilder(shellBuilder = Shell.Builder.create().setFlags(Shell.FLAG_REDIRECT_STDERR).setTimeout(10).setInitializers(InstallerInitializer.class)); secret = new Random().nextLong(); } + // Provides the Context for the base application + public Context FoxApplication = this; + @StyleRes + private int managerThemeResId = R.style.Theme_MagiskModuleManager; + private FoxThemeWrapper markwonThemeContext; + private Markwon markwon; + public MainApplication() { if (INSTANCE != null && INSTANCE != this) throw new IllegalStateException("Duplicate application instance!"); @@ -90,10 +86,8 @@ public class MainApplication extends FoxApplication public static void addSecret(Intent intent) { ComponentName componentName = intent.getComponent(); - String packageName = componentName != null ? - componentName.getPackageName() : intent.getPackage(); - if (!BuildConfig.APPLICATION_ID.equalsIgnoreCase(packageName) && - !relPackageName.equals(packageName)) { + String packageName = componentName != null ? componentName.getPackageName() : intent.getPackage(); + if (!BuildConfig.APPLICATION_ID.equalsIgnoreCase(packageName) && !relPackageName.equals(packageName)) { // Code safeguard, we should never reach here. throw new IllegalArgumentException("Can't add secret to outbound Intent"); } @@ -139,29 +133,23 @@ public class MainApplication extends FoxApplication } public static boolean isMonetEnabled() { - return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && - getSharedPreferences().getBoolean("pref_enable_monet", true); + return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && getSharedPreferences().getBoolean("pref_enable_monet", true); } public static boolean isBlurEnabled() { - return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && - getSharedPreferences().getBoolean("pref_enable_blur", false); + return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && getSharedPreferences().getBoolean("pref_enable_blur", false); } public static boolean isDeveloper() { - return BuildConfig.DEBUG || - getSharedPreferences().getBoolean("developer", false); + return BuildConfig.DEBUG || getSharedPreferences().getBoolean("developer", false); } public static boolean isDisableLowQualityModuleFilter() { - return getSharedPreferences().getBoolean("pref_disable_low_quality_module_filter", - false) && isDeveloper(); + return getSharedPreferences().getBoolean("pref_disable_low_quality_module_filter", false) && isDeveloper(); } public static boolean isUsingMagiskCommand() { - return InstallerInitializer.peekMagiskVersion() >= Constants.MAGISK_VER_CODE_INSTALL_COMMAND - && getSharedPreferences().getBoolean("pref_use_magisk_install_command", false) - && isDeveloper(); + return InstallerInitializer.peekMagiskVersion() >= Constants.MAGISK_VER_CODE_INSTALL_COMMAND && getSharedPreferences().getBoolean("pref_use_magisk_install_command", false) && isDeveloper(); } public static boolean isBackgroundUpdateCheckEnabled() { @@ -169,8 +157,7 @@ public class MainApplication extends FoxApplication } public static boolean isAndroidacyTestMode() { - return isDeveloper() && - getSharedPreferences().getBoolean("pref_androidacy_test_mode", false); + return isDeveloper() && getSharedPreferences().getBoolean("pref_androidacy_test_mode", false); } public static boolean isFirstBoot() { @@ -186,8 +173,7 @@ public class MainApplication extends FoxApplication } public static boolean isCrashReportingEnabled() { - return getSharedPreferences().getBoolean("pref_crash_reporting", - BuildConfig.DEFAULT_ENABLE_CRASH_REPORTING && !BuildConfig.DEBUG); + return getSharedPreferences().getBoolean("pref_crash_reporting", BuildConfig.DEFAULT_ENABLE_CRASH_REPORTING && !BuildConfig.DEBUG); } public static SharedPreferences getBootSharedPreferences() { @@ -203,28 +189,17 @@ public class MainApplication extends FoxApplication return timeFormat.format(new Date(timeStamp)); } - @StyleRes - private int managerThemeResId = R.style.Theme_MagiskModuleManager; - private FoxThemeWrapper markwonThemeContext; - private Markwon markwon; - public static boolean isNotificationPermissionGranted() { return NotificationManagerCompat.from(INSTANCE).areNotificationsEnabled(); } public Markwon getMarkwon() { - if (this.markwon != null) - return this.markwon; + if (this.markwon != null) return this.markwon; FoxThemeWrapper contextThemeWrapper = this.markwonThemeContext; if (contextThemeWrapper == null) { - contextThemeWrapper = this.markwonThemeContext = - new FoxThemeWrapper(this, this.managerThemeResId); + contextThemeWrapper = this.markwonThemeContext = new FoxThemeWrapper(this, this.managerThemeResId); } - Markwon markwon = Markwon.builder(contextThemeWrapper).usePlugin(HtmlPlugin.create()) - .usePlugin(SyntaxHighlightPlugin.create( - new Prism4j(new Prism4jGrammarLocator()), new Prism4jSwitchTheme())) - .usePlugin(ImagesPlugin.create().addSchemeHandler( - OkHttpNetworkSchemeHandler.create(Http.getHttpClientWithCache()))).build(); + Markwon markwon = Markwon.builder(contextThemeWrapper).usePlugin(HtmlPlugin.create()).usePlugin(SyntaxHighlightPlugin.create(new Prism4j(new Prism4jGrammarLocator()), new Prism4jSwitchTheme())).usePlugin(ImagesPlugin.create().addSchemeHandler(OkHttpNetworkSchemeHandler.create(Http.getHttpClientWithCache()))).build(); return this.markwon = markwon; } @@ -238,43 +213,6 @@ public class MainApplication extends FoxApplication return new androidx.work.Configuration.Builder().build(); } - private class Prism4jSwitchTheme implements Prism4jTheme { - private final Prism4jTheme light = new Prism4jThemeDefault(Color.TRANSPARENT); - private final Prism4jTheme dark = new Prism4jThemeDarkula(Color.TRANSPARENT); - // Black theme - private final Prism4jTheme black = new Prism4jThemeDefault(Color.BLACK); - - private Prism4jTheme getTheme() { - // isLightTheme() means light, isDarkTheme() means dark, and isBlackTheme() means black - return isLightTheme() ? light : isDarkTheme() ? dark : black; - } - - @Override - public int background() { - return this.getTheme().background(); - } - - @Override - public int textColor() { - return this.getTheme().textColor(); - } - - @Override - public void apply(@NonNull String language, @NonNull Prism4j.Syntax syntax, - @NonNull SpannableStringBuilder builder, int start, int end) { - this.getTheme().apply(language, syntax, builder, start, end); - } - } - - @SuppressLint("NonConstantResourceId") - public void setManagerThemeResId(@StyleRes int resId) { - this.managerThemeResId = resId; - if (this.markwonThemeContext != null) { - this.markwonThemeContext.setTheme(resId); - } - this.markwon = null; - } - public void updateTheme() { @StyleRes int themeResId; String theme; @@ -283,27 +221,22 @@ public class MainApplication extends FoxApplication default: Log.w("MainApplication", "Unknown theme id: " + theme); case "system": - themeResId = monet ? - R.style.Theme_MagiskModuleManager_Monet : - R.style.Theme_MagiskModuleManager; + themeResId = monet ? R.style.Theme_MagiskModuleManager_Monet : R.style.Theme_MagiskModuleManager; break; case "dark": - themeResId = monet ? - R.style.Theme_MagiskModuleManager_Monet_Dark : - R.style.Theme_MagiskModuleManager_Dark; + themeResId = monet ? R.style.Theme_MagiskModuleManager_Monet_Dark : R.style.Theme_MagiskModuleManager_Dark; + break; + case "black": + themeResId = monet ? R.style.Theme_MagiskModuleManager_Monet_Black : R.style.Theme_MagiskModuleManager_Black; break; case "light": - themeResId = monet ? - R.style.Theme_MagiskModuleManager_Monet_Light : - R.style.Theme_MagiskModuleManager_Light; + themeResId = monet ? R.style.Theme_MagiskModuleManager_Monet_Light : R.style.Theme_MagiskModuleManager_Light; break; } // Handle force black theme if (theme.equals("dark") && isForceBlackThemeEnabled()) { // just black background - themeResId = monet ? - R.style.Theme_MagiskModuleManager_Monet_Black : - R.style.Theme_MagiskModuleManager_Black; + themeResId = monet ? R.style.Theme_MagiskModuleManager_Monet_Black : R.style.Theme_MagiskModuleManager_Black; } this.setManagerThemeResId(themeResId); } @@ -317,14 +250,21 @@ public class MainApplication extends FoxApplication return managerThemeResId; } + @SuppressLint("NonConstantResourceId") + public void setManagerThemeResId(@StyleRes int resId) { + this.managerThemeResId = resId; + if (this.markwonThemeContext != null) { + this.markwonThemeContext.setTheme(resId); + } + this.markwon = null; + } + @SuppressLint("NonConstantResourceId") public boolean isLightTheme() { switch (this.managerThemeResId) { case R.style.Theme_MagiskModuleManager: case R.style.Theme_MagiskModuleManager_Monet: - return (this.getResources().getConfiguration().uiMode - & Configuration.UI_MODE_NIGHT_MASK) - != Configuration.UI_MODE_NIGHT_YES; + return (this.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) != Configuration.UI_MODE_NIGHT_YES; case R.style.Theme_MagiskModuleManager_Monet_Light: case R.style.Theme_MagiskModuleManager_Light: return true; @@ -353,14 +293,12 @@ public class MainApplication extends FoxApplication }*/ SharedPreferences sharedPreferences = MainApplication.getSharedPreferences(); // We are only one process so it's ok to do this - SharedPreferences bootPrefs = MainApplication.bootSharedPreferences = - this.getSharedPreferences("mmm_boot", MODE_PRIVATE); + SharedPreferences bootPrefs = MainApplication.bootSharedPreferences = this.getSharedPreferences("mmm_boot", MODE_PRIVATE); long lastBoot = System.currentTimeMillis() - SystemClock.elapsedRealtime(); long lastBootPrefs = bootPrefs.getLong("last_boot", 0); if (lastBootPrefs == 0 || Math.abs(lastBoot - lastBootPrefs) > 100) { boolean firstBoot = sharedPreferences.getBoolean("first_boot", true); - bootPrefs.edit().clear().putLong("last_boot", lastBoot) - .putBoolean("first_boot", firstBoot).apply(); + bootPrefs.edit().clear().putLong("last_boot", lastBoot).putBoolean("first_boot", firstBoot).apply(); if (firstBoot) { sharedPreferences.edit().putBoolean("first_boot", false).apply(); } @@ -374,12 +312,10 @@ public class MainApplication extends FoxApplication // Update SSL Ciphers if update is possible GMSProviderInstaller.installIfNeeded(this); // Update emoji config - FontRequestEmojiCompatConfig fontRequestEmojiCompatConfig = - DefaultEmojiCompatConfig.create(this); + FontRequestEmojiCompatConfig fontRequestEmojiCompatConfig = DefaultEmojiCompatConfig.create(this); if (fontRequestEmojiCompatConfig != null) { fontRequestEmojiCompatConfig.setReplaceAll(true); - fontRequestEmojiCompatConfig - .setMetadataLoadStrategy(EmojiCompat.LOAD_STRATEGY_MANUAL); + fontRequestEmojiCompatConfig.setMetadataLoadStrategy(EmojiCompat.LOAD_STRATEGY_MANUAL); EmojiCompat emojiCompat = EmojiCompat.init(fontRequestEmojiCompatConfig); new Thread(() -> { Log.d("MainApplication", "Loading emoji compat..."); @@ -408,9 +344,35 @@ public class MainApplication extends FoxApplication Locale newTimeFormatLocale = newConfig.locale; if (timeFormatLocale != newTimeFormatLocale) { timeFormatLocale = newTimeFormatLocale; - timeFormat = new SimpleDateFormat( - timeFormatString, timeFormatLocale); + timeFormat = new SimpleDateFormat(timeFormatString, timeFormatLocale); } super.onConfigurationChanged(newConfig); } + + private class Prism4jSwitchTheme implements Prism4jTheme { + private final Prism4jTheme light = new Prism4jThemeDefault(Color.TRANSPARENT); + private final Prism4jTheme dark = new Prism4jThemeDarkula(Color.TRANSPARENT); + // Black theme + private final Prism4jTheme black = new Prism4jThemeDefault(Color.BLACK); + + private Prism4jTheme getTheme() { + // isLightTheme() means light, isDarkTheme() means dark, and isBlackTheme() means black + return isLightTheme() ? light : isDarkTheme() ? dark : black; + } + + @Override + public int background() { + return this.getTheme().background(); + } + + @Override + public int textColor() { + return this.getTheme().textColor(); + } + + @Override + public void apply(@NonNull String language, @NonNull Prism4j.Syntax syntax, @NonNull SpannableStringBuilder builder, int start, int end) { + this.getTheme().apply(language, syntax, builder, start, end); + } + } } diff --git a/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java b/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java index 2a16e0b..903cf7b 100644 --- a/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java +++ b/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java @@ -137,20 +137,6 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { }, 1); return true; }); - // Force black theme - depends on themePreference being system or dark - SwitchPreferenceCompat forceBlackPreference = findPreference("pref_force_black_theme"); - // Set invisible if theme is not dark or system - forceBlackPreference.setVisible(themePreference.getValue().equals("dark") || - themePreference.getValue().equals("system")); - forceBlackPreference.setOnPreferenceChangeListener((preference, newValue) -> { - devModeStep = 0; - UiThreadHandler.handler.postDelayed(() -> { - MainApplication.getINSTANCE().updateTheme(); - FoxActivity.getFoxActivity(this).setThemeRecreate( - MainApplication.getINSTANCE().getManagerThemeResId()); - }, 1); - return true; - }); // Crash reporting TwoStatePreference crashReportingPreference = findPreference("pref_crash_reporting"); if (!SentryMain.IS_SENTRY_INSTALLED) crashReportingPreference.setVisible(false); diff --git a/app/src/main/res/values-v31/themes.xml b/app/src/main/res/values-v31/themes.xml index e7fb75b..3476aec 100644 --- a/app/src/main/res/values-v31/themes.xml +++ b/app/src/main/res/values-v31/themes.xml @@ -30,6 +30,9 @@ @color/black @color/black @color/black + + @color/system_accent2_900 + @color/system_accent2_900