mirror of
https://github.com/Fox2Code/FoxMagiskModuleManager
synced 2024-10-30 15:20:15 +00:00
Rewrite FoxCompat to support Notch and remove unused stuff.
This commit is contained in:
parent
afc91645aa
commit
a92d752160
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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<CompatActivity> 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 {}
|
||||
}
|
||||
|
@ -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<CompatActivity> 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<CompatActivity> 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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
93
app/src/main/java/com/fox2code/mmm/compat/CompatNotch.java
Normal file
93
app/src/main/java/com/fox2code/mmm/compat/CompatNotch.java
Normal file
@ -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;
|
||||
}
|
||||
}
|
@ -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() {
|
||||
|
@ -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() ?
|
||||
|
Loading…
Reference in New Issue
Block a user