Rewrite FoxCompat to support Notch and remove unused stuff.
parent
afc91645aa
commit
a92d752160
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue