From a92d7521602cbe43e07cec6e7018b4963c12d77d Mon Sep 17 00:00:00 2001 From: Fox2Code Date: Sat, 2 Jul 2022 18:00:58 +0200 Subject: [PATCH] Rewrite FoxCompat to support Notch and remove unused stuff. --- .../java/android/os/SystemProperties.java | 14 ++ .../com/fox2code/mmm/MainApplication.java | 15 +- .../fox2code/mmm/compat/CompatActivity.java | 145 ++++++++++-------- .../mmm/compat/CompatApplication.java | 76 +-------- .../mmm/compat/CompatConfigHelper.java | 94 ------------ .../com/fox2code/mmm/compat/CompatNotch.java | 93 +++++++++++ .../mmm/compat/CompatThemeWrapper.java | 28 ---- .../mmm/installer/InstallerActivity.java | 8 +- 8 files changed, 207 insertions(+), 266 deletions(-) delete mode 100644 app/src/main/java/com/fox2code/mmm/compat/CompatConfigHelper.java create mode 100644 app/src/main/java/com/fox2code/mmm/compat/CompatNotch.java diff --git a/app/src/main/java/android/os/SystemProperties.java b/app/src/main/java/android/os/SystemProperties.java index 1017039..87d9705 100644 --- a/app/src/main/java/android/os/SystemProperties.java +++ b/app/src/main/java/android/os/SystemProperties.java @@ -4,6 +4,9 @@ import androidx.annotation.Keep; import com.topjohnwu.superuser.ShellUtils; +/** + * I will probably outsource this to a separate library later + */ @Keep public class SystemProperties { @Keep @@ -13,4 +16,15 @@ public class SystemProperties { prop = prop.substring(0, prop.length() - 1).trim(); return prop; } + + @Keep + public static int getInt(String key, int def) { + try { + String value = get(key); + if (value.isEmpty()) return def; + return Integer.parseInt(value); + } catch (Exception e) { + return def; + } + } } diff --git a/app/src/main/java/com/fox2code/mmm/MainApplication.java b/app/src/main/java/com/fox2code/mmm/MainApplication.java index 8333d37..91ac726 100644 --- a/app/src/main/java/com/fox2code/mmm/MainApplication.java +++ b/app/src/main/java/com/fox2code/mmm/MainApplication.java @@ -1,6 +1,7 @@ package com.fox2code.mmm; import android.annotation.SuppressLint; +import android.content.ComponentName; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.Configuration; @@ -78,6 +79,13 @@ public class MainApplication extends CompatApplication { } public static void addSecret(Intent intent) { + ComponentName componentName = intent.getComponent(); + String packageName = componentName != null ? + componentName.getPackageName() : intent.getPackage(); + if (!BuildConfig.APPLICATION_ID.equalsIgnoreCase(packageName)) { + // Code safeguard, we should never reach here. + throw new IllegalArgumentException("Can't add secret to outbound Intent"); + } intent.putExtra("secret", secret); } @@ -101,10 +109,6 @@ public class MainApplication extends CompatApplication { return getSharedPreferences().getBoolean("pref_show_incompatible", false); } - public static boolean isForceEnglish() { - return getSharedPreferences().getBoolean("pref_force_english", false); - } - public static boolean isForceDarkTerminal() { return getSharedPreferences().getBoolean("pref_force_dark_terminal", false); } @@ -190,7 +194,6 @@ public class MainApplication extends CompatApplication { if (contextThemeWrapper == null) { contextThemeWrapper = this.markwonThemeContext = new CompatThemeWrapper(this, this.managerThemeResId); - contextThemeWrapper.setForceEnglish(isForceEnglish()); } Markwon markwon = Markwon.builder(contextThemeWrapper).usePlugin(HtmlPlugin.create()) .usePlugin(SyntaxHighlightPlugin.create( @@ -327,14 +330,12 @@ public class MainApplication extends CompatApplication { @Override public void onCreateCompatActivity(CompatActivity compatActivity) { - this.setForceEnglish(isForceEnglish()); super.onCreateCompatActivity(compatActivity); compatActivity.setTheme(this.managerThemeResId); } @Override public void onRefreshUI(CompatActivity compatActivity) { - this.setForceEnglish(isForceEnglish()); super.onRefreshUI(compatActivity); compatActivity.setThemeRecreate(this.managerThemeResId); } diff --git a/app/src/main/java/com/fox2code/mmm/compat/CompatActivity.java b/app/src/main/java/com/fox2code/mmm/compat/CompatActivity.java index 29b0489..3ca6b77 100644 --- a/app/src/main/java/com/fox2code/mmm/compat/CompatActivity.java +++ b/app/src/main/java/com/fox2code/mmm/compat/CompatActivity.java @@ -12,16 +12,16 @@ import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Bundle; import android.os.SystemProperties; -import android.util.AttributeSet; import android.util.Log; import android.util.TypedValue; +import android.view.Display; import android.view.KeyCharacterMap; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; +import android.view.Surface; import android.view.View; import android.view.ViewConfiguration; -import android.widget.ScrollView; import androidx.annotation.AttrRes; import androidx.annotation.CallSuper; @@ -29,6 +29,7 @@ import androidx.annotation.ColorInt; import androidx.annotation.ColorRes; import androidx.annotation.Dimension; import androidx.annotation.DrawableRes; +import androidx.annotation.IntDef; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.Px; @@ -37,6 +38,7 @@ import androidx.annotation.StyleRes; import androidx.appcompat.app.AppCompatActivity; import androidx.core.content.ContextCompat; import androidx.core.graphics.ColorUtils; +import androidx.core.graphics.Insets; import androidx.core.view.WindowInsetsCompat; import androidx.core.widget.NestedScrollView; import androidx.fragment.app.Fragment; @@ -44,12 +46,12 @@ import androidx.recyclerview.widget.RecyclerView; import com.fox2code.mmm.Constants; import com.fox2code.mmm.R; -import com.kieronquinn.monetcompat.app.MonetCompatActivity; import com.kieronquinn.monetcompat.extensions.views.ViewExtensions_RecyclerViewKt; import com.kieronquinn.monetcompat.extensions.views.ViewExtensions_ScrollViewKt; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; -import java.util.Locale; import java.util.Objects; import rikka.insets.WindowInsetsHelper; @@ -71,13 +73,13 @@ public class CompatActivity extends AppCompatActivity { }; final WeakReference selfReference; - private final CompatConfigHelper compatConfigHelper = new CompatConfigHelper(this); private CompatActivity.OnActivityResultCallback onActivityResultCallback; private CompatActivity.OnBackPressedCallback onBackPressedCallback; private MenuItem.OnMenuItemClickListener menuClickListener; private CharSequence menuContentDescription; - @StyleRes - private int setThemeDynamic = 0; + private int displayCutoutHeight = 0; + @Rotation private int cachedRotation = 0; + @StyleRes private int setThemeDynamic = 0; private boolean onCreateCalledOnce = false; private boolean onCreateCalled = false; private boolean isRefreshUi = false; @@ -107,6 +109,8 @@ public class CompatActivity extends AppCompatActivity { } })); this.hasHardwareNavBar = this.hasHardwareNavBar0(); + this.displayCutoutHeight = CompatNotch.getNotchHeight(this); + this.cachedRotation = this.getRotation(); this.onCreateCalledOnce = true; } Application application = this.getApplication(); @@ -115,17 +119,28 @@ public class CompatActivity extends AppCompatActivity { } super.onCreate(savedInstanceState); this.onCreateCalled = true; - this.checkResourcesOverrides( - this.forceEnglish, this.nightModeOverride); } + @Override protected void onResume() { this.hasHardwareNavBar = this.hasHardwareNavBar0(); + this.displayCutoutHeight = CompatNotch.getNotchHeight(this); + this.cachedRotation = this.getRotation(); super.onResume(); this.refreshUI(); } + @Override + public void onConfigurationChanged(@NonNull Configuration newConfig) { + super.onConfigurationChanged(newConfig); + if (this.cachedRotation != this.getRotation() && + this.onCreateCalledOnce) { + this.cachedRotation = this.getRotation(); + this.displayCutoutHeight = CompatNotch.getNotchHeight(this); + } + } + @Override public void finish() { this.onActivityResultCallback = null; @@ -151,8 +166,6 @@ public class CompatActivity extends AppCompatActivity { } finally { this.isRefreshUi = false; } - this.checkResourcesOverrides( - this.forceEnglish, this.nightModeOverride); } } @@ -239,8 +252,7 @@ public class CompatActivity extends AppCompatActivity { } } - @Dimension - @Px + @Dimension @Px public int getActionBarHeight() { androidx.appcompat.app.ActionBar compatActionBar; try { @@ -266,15 +278,6 @@ public class CompatActivity extends AppCompatActivity { } } - public int getActionBarHeight(Activity activity) { - TypedValue tv = new TypedValue(); - int actionBarHeight = 0; - if (activity.getTheme().resolveAttribute(R.attr.actionBarSize, tv, true)) { - actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics()); - } - return actionBarHeight; - } - public void setActionBarBackground(Drawable drawable) { androidx.appcompat.app.ActionBar compatActionBar; try { @@ -295,8 +298,17 @@ public class CompatActivity extends AppCompatActivity { @Dimension @Px @SuppressLint("InternalInsetResource") public int getStatusBarHeight() { - int height = WindowInsetsCompat.CONSUMED.getInsets( - WindowInsetsCompat.Type.statusBars()).top; + // Check display cutout height + int height = this.getRotation() == 0 ? + this.displayCutoutHeight : 0; + // Check consumed insets + if (WindowInsetsCompat.CONSUMED.isConsumed()) { + Insets insets = WindowInsetsCompat.CONSUMED.getInsets( + WindowInsetsCompat.Type.statusBars()); + if (insets.top == 0) { + height = Math.max(height, insets.bottom); + } + } // Check system resources int id = Resources.getSystem().getIdentifier( "status_bar_height", "dimen", "android"); @@ -307,8 +319,16 @@ public class CompatActivity extends AppCompatActivity { @Dimension @Px @SuppressLint("InternalInsetResource") public int getNavigationBarHeight() { - int height = WindowInsetsCompat.CONSUMED.getInsets( - WindowInsetsCompat.Type.navigationBars()).bottom; + int height = 0; + // Check consumed insets + if (WindowInsetsCompat.CONSUMED.isConsumed()) { + Insets insets = WindowInsetsCompat.CONSUMED.getInsets( + WindowInsetsCompat.Type.statusBars()); + if (insets.top != 0) { + height = Math.max(height, + insets.bottom - insets.top); + } + } // Check system resources int id = Resources.getSystem().getIdentifier( "config_showNavigationBar", "bool", "android"); @@ -408,19 +428,10 @@ public class CompatActivity extends AppCompatActivity { super.overridePendingTransition( android.R.anim.fade_in, android.R.anim.fade_out); } else { - this.compatConfigHelper.checkResourcesOverrides(theme, - this.forceEnglish, this.nightModeOverride); super.onApplyThemeResource(theme, resid, first); } } - @Override - public void onConfigurationChanged(@NonNull Configuration newConfig) { - this.compatConfigHelper.checkResourcesOverrides(newConfig, - this.forceEnglish, this.nightModeOverride); - super.onConfigurationChanged(newConfig); - } - public void setOnBackPressedCallback(OnBackPressedCallback onBackPressedCallback) { this.onBackPressedCallback = onBackPressedCallback; } @@ -487,31 +498,6 @@ public class CompatActivity extends AppCompatActivity { } } - public void setForceEnglish(boolean forceEnglish) { - if (this.forceEnglish == forceEnglish) return; - this.forceEnglish = forceEnglish; - this.checkResourcesOverrides(forceEnglish, this.nightModeOverride); - } - - public void setNightModeOverride(Boolean nightModeOverride) { - if (this.nightModeOverride == nightModeOverride) return; - this.nightModeOverride = nightModeOverride; - this.checkResourcesOverrides(this.forceEnglish, nightModeOverride); - } - - void propagateResourcesOverride(boolean forceEnglish, Boolean nightModeOverride) { - if (this.forceEnglish == forceEnglish && - this.nightModeOverride == nightModeOverride) return; - this.forceEnglish = forceEnglish; - this.nightModeOverride = nightModeOverride; - this.checkResourcesOverrides(forceEnglish, nightModeOverride); - } - - private void checkResourcesOverrides(boolean forceEnglish, Boolean nightModeOverride) { - if (this.isRefreshUi || !this.onCreateCalled) return; // Wait before reload - this.compatConfigHelper.checkResourcesOverrides(forceEnglish, nightModeOverride); - } - public boolean isLightTheme() { Resources.Theme theme = this.getTheme(); TypedValue typedValue = new TypedValue(); @@ -544,8 +530,34 @@ public class CompatActivity extends AppCompatActivity { return ContextCompat.getColor(this, color); } - public Locale getUserLocale() { - return this.compatConfigHelper.getUserLocale(); + /** + * Note: This value can change at runtime on some devices, + * and return true if DisplayCutout is simulated. + * */ + public boolean hasNotch() { + if (!this.onCreateCalledOnce) { + Log.w(TAG, "hasNotch() called before onCreate()"); + return CompatNotch.getNotchHeight(this) != 0; + } + return this.displayCutoutHeight != 0; + } + + @SuppressWarnings("deprecation") + @Nullable @Override + public Display getDisplay() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + return super.getDisplay(); + } + return this.getWindowManager().getDefaultDisplay(); + } + + @Rotation + public int getRotation() { + Display display = this.getDisplay(); + return display != null ? display.getRotation() : + this.getResources().getConfiguration().orientation == + Configuration.ORIENTATION_LANDSCAPE ? + Surface.ROTATION_90 : Surface.ROTATION_0; } public static CompatActivity getCompatActivity(View view) { @@ -584,4 +596,13 @@ public class CompatActivity extends AppCompatActivity { void onRefreshUI(CompatActivity compatActivity); } + + @IntDef(open = true, value = { + Surface.ROTATION_0, + Surface.ROTATION_90, + Surface.ROTATION_180, + Surface.ROTATION_270 + }) + @Retention(RetentionPolicy.SOURCE) + private @interface Rotation {} } diff --git a/app/src/main/java/com/fox2code/mmm/compat/CompatApplication.java b/app/src/main/java/com/fox2code/mmm/compat/CompatApplication.java index 1e937f7..18f439c 100644 --- a/app/src/main/java/com/fox2code/mmm/compat/CompatApplication.java +++ b/app/src/main/java/com/fox2code/mmm/compat/CompatApplication.java @@ -1,17 +1,15 @@ package com.fox2code.mmm.compat; import android.app.Application; -import android.content.res.Configuration; import android.content.res.Resources; import android.os.Build; -import android.util.Log; import android.util.TypedValue; import androidx.annotation.AttrRes; import androidx.annotation.CallSuper; import androidx.annotation.ColorInt; import androidx.annotation.ColorRes; -import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; import androidx.core.graphics.ColorUtils; @@ -24,69 +22,10 @@ import java.lang.ref.WeakReference; */ public class CompatApplication extends Application implements CompatActivity.ApplicationCallbacks { private static final String TAG = "CompatApplication"; - private final CompatConfigHelper compatConfigHelper = new CompatConfigHelper(this); private WeakReference lastCompatActivity; - // CompatConfigHelper - private boolean forceEnglish; - private Boolean nightModeOverride; - private boolean propagateOverrides; public CompatApplication() {} - @Override - public void onConfigurationChanged(@NonNull Configuration newConfig) { - this.compatConfigHelper.checkResourcesOverrides(newConfig, - this.forceEnglish, this.nightModeOverride); - super.onConfigurationChanged(newConfig); - } - - public void setForceEnglish(boolean forceEnglish) { - if (this.forceEnglish != forceEnglish) { - this.forceEnglish = forceEnglish; - this.checkResourcesOverrides(forceEnglish, this.nightModeOverride); - } - // Propagate even if local value didn't changed - if (this.propagateOverrides && this.lastCompatActivity != null) { - CompatActivity compatActivity = this.lastCompatActivity.get(); - if (compatActivity != null) - compatActivity.setForceEnglish(forceEnglish); - } - } - - public void setNightModeOverride(Boolean nightModeOverride) { - if (this.nightModeOverride != nightModeOverride) { - this.nightModeOverride = nightModeOverride; - this.checkResourcesOverrides(this.forceEnglish, nightModeOverride); - } - // Propagate even if local value didn't changed - if (this.propagateOverrides && this.lastCompatActivity != null) { - CompatActivity compatActivity = this.lastCompatActivity.get(); - if (compatActivity != null) - compatActivity.setNightModeOverride(nightModeOverride); - } - } - - public boolean isPropagateOverrides() { - return propagateOverrides; - } - - public void setPropagateOverrides(boolean propagateOverrides) { - this.propagateOverrides = propagateOverrides; - WeakReference lastCompatActivity = this.lastCompatActivity; - if (lastCompatActivity != null) { - Log.d(TAG, "setPropagateOverrides(" + // This should be avoided - propagateOverrides + ") called after first activity created!"); - CompatActivity compatActivity = lastCompatActivity.get(); - if (compatActivity != null && propagateOverrides) { - this.propagateOverrides(compatActivity); - } - } - } - - private void checkResourcesOverrides(boolean forceEnglish, Boolean nightModeOverride) { - this.compatConfigHelper.checkResourcesOverrides(forceEnglish, nightModeOverride); - } - public boolean isLightTheme() { Resources.Theme theme = this.getTheme(); TypedValue typedValue = new TypedValue(); @@ -123,22 +62,17 @@ public class CompatApplication extends Application implements CompatActivity.App @CallSuper public void onCreateCompatActivity(CompatActivity compatActivity) { this.lastCompatActivity = compatActivity.selfReference; - if (this.propagateOverrides) { - this.propagateOverrides(compatActivity); - } } @Override @CallSuper public void onRefreshUI(CompatActivity compatActivity) { this.lastCompatActivity = compatActivity.selfReference; - if (this.propagateOverrides) { - this.propagateOverrides(compatActivity); - } } - private void propagateOverrides(CompatActivity compatActivity) { - compatActivity.propagateResourcesOverride( - this.forceEnglish, this.nightModeOverride); + @Nullable + public CompatActivity getLastCompatActivity() { + return this.lastCompatActivity == null ? + null : this.lastCompatActivity.get(); } } diff --git a/app/src/main/java/com/fox2code/mmm/compat/CompatConfigHelper.java b/app/src/main/java/com/fox2code/mmm/compat/CompatConfigHelper.java deleted file mode 100644 index e9655dc..0000000 --- a/app/src/main/java/com/fox2code/mmm/compat/CompatConfigHelper.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.fox2code.mmm.compat; - -import android.content.Context; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.os.Build; -import android.os.LocaleList; - -import java.util.Locale; - -/** - * I will probably outsource this to a separate library later - */ -final class CompatConfigHelper { - // ENGLISH like this is an unnatural local, as it doesn't precise the country - // All english locales settable by the user precise the country (Ex: en-US) - private static final Locale englishLocale = Locale.ENGLISH; - private static final Object englishLocales = - Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ? - new LocaleList(englishLocale) : null; - - private final Context context; - private Object userLocales; - private Locale userLocale; - - CompatConfigHelper(Context context) { - this.context = context; - } - - void checkResourcesOverrides(boolean forceEnglish, - Boolean nightModeOverride) { - this.checkResourcesOverrides( - this.context.getTheme(), - forceEnglish, nightModeOverride); - } - - void checkResourcesOverrides(Resources.Theme theme, boolean forceEnglish, - Boolean nightModeOverride) { - Resources res = theme.getResources(); - if (this.checkResourcesOverrides(res.getConfiguration(), - forceEnglish, nightModeOverride)) { - res.updateConfiguration( - res.getConfiguration(), - res.getDisplayMetrics()); - } - } - - boolean checkResourcesOverrides(Configuration conf, boolean forceEnglish, - Boolean nightModeOverride) { - Locale current = conf.locale; - boolean didChange = false; - boolean wasForceEnglish = englishLocale.equals(current); - if (forceEnglish != wasForceEnglish) { - didChange = true; - if (forceEnglish) { - this.userLocale = conf.locale; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - this.userLocales = conf.getLocales(); - } - conf.locale = englishLocale; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - conf.setLocales((LocaleList) englishLocales); - } - } else { - conf.locale = this.userLocale; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - conf.setLocales((LocaleList) this.userLocales); - } - } - } - int nightMode = conf.uiMode & Configuration.UI_MODE_NIGHT_MASK; - int sysNightMode = Resources.getSystem() - .getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; - if (nightModeOverride == null ? sysNightMode != nightMode : - nightMode != (nightModeOverride ? - Configuration.UI_MODE_NIGHT_YES : Configuration.UI_MODE_NIGHT_NO)) { - didChange = true; - nightMode = nightModeOverride == null ? sysNightMode : nightModeOverride ? - Configuration.UI_MODE_NIGHT_YES : Configuration.UI_MODE_NIGHT_NO; - conf.uiMode = nightMode | (conf.uiMode & ~Configuration.UI_MODE_NIGHT_MASK); - } - if (!forceEnglish && !wasForceEnglish) { - this.userLocale = null; - this.userLocales = null; - } - return didChange; - } - - public Locale getUserLocale() { - // Only use cached value if force english - Locale locale = this.context.getResources().getConfiguration().locale; - return englishLocale.equals(locale) ? this.userLocale : locale; - } -} diff --git a/app/src/main/java/com/fox2code/mmm/compat/CompatNotch.java b/app/src/main/java/com/fox2code/mmm/compat/CompatNotch.java new file mode 100644 index 0000000..a83b557 --- /dev/null +++ b/app/src/main/java/com/fox2code/mmm/compat/CompatNotch.java @@ -0,0 +1,93 @@ +package com.fox2code.mmm.compat; + +import android.annotation.SuppressLint; +import android.content.res.Resources; +import android.os.Build; +import android.os.SystemProperties; +import android.util.Log; +import android.view.Display; +import android.view.DisplayCutout; + +import androidx.annotation.RequiresApi; +import androidx.core.view.DisplayCutoutCompat; +import androidx.core.view.WindowInsetsCompat; + +import java.lang.reflect.Method; +import java.util.Objects; + +/** + * Get notch information from any Android devices. + */ +final class CompatNotch { + private static final String TAG = "CompatNotch"; + + static int getNotchHeight(CompatActivity compatActivity) { + // Android 9.0 still need legacy check for notch detection. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + return getNotchHeightModern(compatActivity); + } else { + int notch = getNotchHeightLegacy(compatActivity); + DisplayCutoutCompat displayCutoutCompat = + WindowInsetsCompat.CONSUMED.getDisplayCutout(); + return displayCutoutCompat == null ? notch : + Math.max(displayCutoutCompat.getSafeInsetTop(), notch); + } + } + + @RequiresApi(Build.VERSION_CODES.Q) + private static int getNotchHeightModern(CompatActivity compatActivity) { + Display display = compatActivity.getDisplay(); + DisplayCutout displayCutout = display == null ? null : display.getCutout(); + if (displayCutout != null) return Math.max(displayCutout.getSafeInsetTop(), 1); + DisplayCutoutCompat displayCutoutCompat = WindowInsetsCompat.CONSUMED.getDisplayCutout(); + return displayCutoutCompat == null ? 0 : Math.max(displayCutoutCompat.getSafeInsetTop(), 1); + } + + private static final int VIVO_NOTCH = 0x00000020; + + @SuppressLint({"InternalInsetResource", "PrivateApi"}) + private static int getNotchHeightLegacy(CompatActivity compatActivity) { + ClassLoader classLoader = compatActivity.getClassLoader(); + int id = Resources.getSystem().getIdentifier("status_bar_height", "dimen", "android"); + int height = id <= 0 ? 1 : Resources.getSystem().getDimensionPixelSize(id); + try { // Huawei Notch + Class HwNotchSizeUtil = classLoader.loadClass("com.huawei.android.util.HwNotchSizeUtil"); + Method get = HwNotchSizeUtil.getMethod("hasNotchInScreen"); + if ((boolean) Objects.requireNonNull( + get.invoke(HwNotchSizeUtil))) { + try { + get = HwNotchSizeUtil.getMethod("getNotchSize"); + return Math.max(((int[]) Objects.requireNonNull( + get.invoke(HwNotchSizeUtil)))[1], height); + } catch (Exception e) { + Log.e(TAG, "Failed to get Huawei notch on Huawei device", e); + return height; + } + } + } catch (Exception e) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && + "Huawei".equalsIgnoreCase(Build.MANUFACTURER)) { + Log.e(TAG, "Failed to get Huawei notch on Huawei device", e); + } + } + if (compatActivity.getPackageManager() // Oppo & MIUI Notch + .hasSystemFeature("com.oppo.feature.screen.heteromorphism") || + SystemProperties.getInt("ro.miui.notch", -1) == 1) { + return height; + } + try { // Vivo Notch + Class FtFeature = classLoader.loadClass("android.util.FtFeature"); + Method method = FtFeature.getMethod("isFeatureSupport", int.class); + if ((boolean) Objects.requireNonNull( + method.invoke(FtFeature, VIVO_NOTCH))) { + return height; + } + } catch (Exception e) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && + "Vivo".equalsIgnoreCase(Build.MANUFACTURER)) { + Log.e(TAG, "Failed to get Vivo notch on Vivo device", e); + } + } + return 0; + } +} diff --git a/app/src/main/java/com/fox2code/mmm/compat/CompatThemeWrapper.java b/app/src/main/java/com/fox2code/mmm/compat/CompatThemeWrapper.java index d192ce9..0a58479 100644 --- a/app/src/main/java/com/fox2code/mmm/compat/CompatThemeWrapper.java +++ b/app/src/main/java/com/fox2code/mmm/compat/CompatThemeWrapper.java @@ -19,47 +19,19 @@ import com.fox2code.mmm.R; * I will probably outsource this to a separate library later */ public class CompatThemeWrapper extends ContextThemeWrapper { - private final CompatConfigHelper compatConfigHelper = new CompatConfigHelper(this); private boolean canReload; - // CompatConfigHelper - private boolean forceEnglish; - private Boolean nightModeOverride; public CompatThemeWrapper(Context base, @StyleRes int themeResId) { super(base, themeResId); this.canReload = true; - this.checkResourcesOverrides( - this.forceEnglish, this.nightModeOverride); } @Override protected void onApplyThemeResource(Resources.Theme theme, int resid, boolean first) { boolean couldReload = this.canReload; if (couldReload) this.canReload = false; - this.compatConfigHelper.checkResourcesOverrides(theme, - this.forceEnglish, this.nightModeOverride); super.onApplyThemeResource(theme, resid, first); if (couldReload) this.canReload = true; - // In case value change while reload, should have no effect - this.compatConfigHelper.checkResourcesOverrides(theme, - this.forceEnglish, this.nightModeOverride); - } - - public void setForceEnglish(boolean forceEnglish) { - if (this.forceEnglish == forceEnglish) return; - this.forceEnglish = forceEnglish; - this.checkResourcesOverrides(forceEnglish, this.nightModeOverride); - } - - public void setNightModeOverride(Boolean nightModeOverride) { - if (this.nightModeOverride == nightModeOverride) return; - this.nightModeOverride = nightModeOverride; - this.checkResourcesOverrides(this.forceEnglish, nightModeOverride); - } - - private void checkResourcesOverrides(boolean forceEnglish,Boolean nightModeOverride) { - if (!this.canReload) return; // Do not reload during theme reload - this.compatConfigHelper.checkResourcesOverrides(forceEnglish, nightModeOverride); } public boolean isLightTheme() { 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 e9b0d27..c1a7929 100644 --- a/app/src/main/java/com/fox2code/mmm/installer/InstallerActivity.java +++ b/app/src/main/java/com/fox2code/mmm/installer/InstallerActivity.java @@ -267,8 +267,8 @@ public class InstallerActivity extends CompatActivity { } installerMonitor = new InstallerMonitor(installScript); installJob = Shell.cmd("export MMM_EXT_SUPPORT=1", - "export MMM_USER_LANGUAGE=" + (MainApplication.isForceEnglish() ? "en-US" : - Resources.getSystem().getConfiguration().locale.toLanguageTag()), + "export MMM_USER_LANGUAGE=" + this.getResources() + .getConfiguration().locale.toLanguageTag(), "export MMM_APP_VERSION=" + BuildConfig.VERSION_NAME, "export MMM_TEXT_WRAP=" + (this.textWrap ? "1" : "0"), AnsiConstants.ANSI_CMD_SUPPORT, @@ -406,8 +406,8 @@ public class InstallerActivity extends CompatActivity { this.installerTerminal.disableAnsi(); else this.installerTerminal.enableAnsi(); installJob = Shell.cmd(arch32, "export MMM_EXT_SUPPORT=1", - "export MMM_USER_LANGUAGE=" + (MainApplication.isForceEnglish() ? "en-US" : - Resources.getSystem().getConfiguration().locale.toLanguageTag()), + "export MMM_USER_LANGUAGE=" + this.getResources() + .getConfiguration().locale.toLanguageTag(), "export MMM_APP_VERSION=" + BuildConfig.VERSION_NAME, "export MMM_TEXT_WRAP=" + (this.textWrap ? "1" : "0"), this.installerTerminal.isAnsiEnabled() ?