From d865a6b48bd2f309b5b36c96a590aed63c8aad57 Mon Sep 17 00:00:00 2001 From: BlackMesa123 Date: Mon, 31 Jan 2022 18:16:30 +0100 Subject: [PATCH 1/2] app/PopupMenu: add blur effect support for OUI 4 devices Signed-off-by: BlackMesa123 --- .../androidx/reflect/SeslBaseReflector.java | 10 +++ .../reflect/provider/SeslSystemReflector.java | 9 +++ .../view/SeslSemBlurInfoReflector.java | 70 +++++++++++++++++++ .../reflect/view/SeslViewReflector.java | 15 ++++ .../dlyt/yanndroid/oneui/menu/PopupMenu.java | 32 +++++++++ .../src/main/res/values-night/colors.xml | 1 + .../oneui/src/main/res/values/colors.xml | 1 + 7 files changed, 138 insertions(+) create mode 100644 yanndroid/oneui/src/main/java/androidx/reflect/view/SeslSemBlurInfoReflector.java diff --git a/yanndroid/oneui/src/main/java/androidx/reflect/SeslBaseReflector.java b/yanndroid/oneui/src/main/java/androidx/reflect/SeslBaseReflector.java index 4b6a9849..2f226c3a 100644 --- a/yanndroid/oneui/src/main/java/androidx/reflect/SeslBaseReflector.java +++ b/yanndroid/oneui/src/main/java/androidx/reflect/SeslBaseReflector.java @@ -2,6 +2,7 @@ import android.util.Log; +import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -203,4 +204,13 @@ public static void set(Object obj, Field field, Object obj2) { Log.e(TAG, field.getName() + " IllegalArgumentException", e2); } } + + public static Constructor getConstructor(String str, Class... clsArr) { + try { + return Class.forName(str).getDeclaredConstructor(clsArr); + } catch (ClassNotFoundException | NoSuchMethodException e) { + e.printStackTrace(); + return null; + } + } } diff --git a/yanndroid/oneui/src/main/java/androidx/reflect/provider/SeslSystemReflector.java b/yanndroid/oneui/src/main/java/androidx/reflect/provider/SeslSystemReflector.java index 44573595..edfbe8d2 100644 --- a/yanndroid/oneui/src/main/java/androidx/reflect/provider/SeslSystemReflector.java +++ b/yanndroid/oneui/src/main/java/androidx/reflect/provider/SeslSystemReflector.java @@ -27,4 +27,13 @@ public static String getField_SEM_PEN_HOVERING() { } return obj instanceof String ? (String) obj : "pen_hovering"; } + + public static String getField_SEM_ACCESSIBILITY_REDUCE_TRANSPARENCY() { + Method declaredMethod; + Object obj = null; + if (Build.VERSION.SDK_INT >= 31 && (declaredMethod = SeslBaseReflector.getDeclaredMethod(mClass, "hidden_SEM_ACCESSIBILITY_REDUCE_TRANSPARENCY", new Class[0])) != null) { + obj = SeslBaseReflector.invoke(null, declaredMethod, new Object[0]); + } + return obj instanceof String ? (String) obj : "not_supported"; + } } \ No newline at end of file diff --git a/yanndroid/oneui/src/main/java/androidx/reflect/view/SeslSemBlurInfoReflector.java b/yanndroid/oneui/src/main/java/androidx/reflect/view/SeslSemBlurInfoReflector.java new file mode 100644 index 00000000..df24fec9 --- /dev/null +++ b/yanndroid/oneui/src/main/java/androidx/reflect/view/SeslSemBlurInfoReflector.java @@ -0,0 +1,70 @@ +package androidx.reflect.view; + +import android.os.Build; +import android.util.Log; +import android.view.View; + +import androidx.reflect.SeslBaseReflector; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class SeslSemBlurInfoReflector { + private static final String TAG = "SeslSemBlurInfoReflector"; + private static final String mBuilderClass = "android.view.SemBlurInfo$Builder"; + + private SeslSemBlurInfoReflector() { + } + + public static Object semCreateBlurBuilder(int i) { + Constructor constructor = SeslBaseReflector.getConstructor(mBuilderClass, Integer.TYPE); + if (Build.VERSION.SDK_INT >= 31 && constructor != null) { + try { + return constructor.newInstance(Integer.valueOf(i)); + } catch (IllegalAccessException e) { + Log.e(TAG, "semCreateBlurBuilder IllegalAccessException", e); + } catch (InstantiationException e2) { + Log.e(TAG, "semCreateBlurBuilder InstantiationException", e2); + } catch (InvocationTargetException e3) { + Log.e(TAG, "semCreateBlurBuilder InvocationTargetException", e3); + } + } + return null; + } + + public static Object semSetBuilderBlurRadius(Object obj, int i) { + Method declaredMethod = Build.VERSION.SDK_INT >= 31 ? SeslBaseReflector.getDeclaredMethod(mBuilderClass, "hidden_setRadius", Integer.TYPE) : null; + if (declaredMethod != null) { + declaredMethod.setAccessible(true); + SeslBaseReflector.invoke(obj, declaredMethod, Integer.valueOf(i)); + } + return obj; + } + + public static Object semSetBuilderBlurBackgroundColor(Object obj, int i) { + Method declaredMethod = Build.VERSION.SDK_INT >= 31 ? SeslBaseReflector.getDeclaredMethod(mBuilderClass, "hidden_setBackgroundColor", Integer.TYPE) : null; + if (declaredMethod != null) { + declaredMethod.setAccessible(true); + SeslBaseReflector.invoke(obj, declaredMethod, Integer.valueOf(i)); + } + return obj; + } + + public static Object semSetBuilderBlurBackgroundCornerRadius(Object obj, float f) { + Method declaredMethod = Build.VERSION.SDK_INT >= 31 ? SeslBaseReflector.getDeclaredMethod(mBuilderClass, "hidden_setBackgroundCornerRadius", Float.TYPE) : null; + if (declaredMethod != null) { + declaredMethod.setAccessible(true); + SeslBaseReflector.invoke(obj, declaredMethod, Float.valueOf(f)); + } + return obj; + } + + public static void semBuildSetBlurInfo(Object obj, View view) { + Method declaredMethod = Build.VERSION.SDK_INT >= 31 ? SeslBaseReflector.getDeclaredMethod(mBuilderClass, "hidden_build", new Class[0]) : null; + if (declaredMethod != null) { + declaredMethod.setAccessible(true); + SeslViewReflector.semSetBlurInfo(view, SeslBaseReflector.invoke(obj, declaredMethod, new Object[0])); + } + } +} diff --git a/yanndroid/oneui/src/main/java/androidx/reflect/view/SeslViewReflector.java b/yanndroid/oneui/src/main/java/androidx/reflect/view/SeslViewReflector.java index bce5c7ac..76ee1519 100644 --- a/yanndroid/oneui/src/main/java/androidx/reflect/view/SeslViewReflector.java +++ b/yanndroid/oneui/src/main/java/androidx/reflect/view/SeslViewReflector.java @@ -2,6 +2,7 @@ import android.graphics.Rect; import android.os.Build; +import android.util.Log; import android.view.PointerIcon; import android.view.View; @@ -11,6 +12,7 @@ import java.lang.reflect.Method; public class SeslViewReflector { + private static final String TAG = "SeslViewReflector"; private static final Class mClass = View.class; private SeslViewReflector() { @@ -165,6 +167,19 @@ public static boolean isHoveringUIEnabled(View view) { return false; } + public static void semSetBlurInfo(View view, Object obj) { + if (Build.VERSION.SDK_INT >= 31) { + try { + Method declaredMethod = SeslBaseReflector.getDeclaredMethod(mClass, "hidden_semSetBlurInfo", Class.forName("android.view.SemBlurInfo")); + if (declaredMethod != null) { + SeslBaseReflector.invoke(view, declaredMethod, obj); + } + } catch (ClassNotFoundException e) { + Log.e(TAG, "semSetBlurInfo ClassNotFoundException", e); + } + } + } + public static void semSetPointerIcon(View view, int i, PointerIcon pointerIcon) { Method method; if (Build.VERSION.SDK_INT >= 29) { diff --git a/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/menu/PopupMenu.java b/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/menu/PopupMenu.java index 58ef9fc2..30434034 100644 --- a/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/menu/PopupMenu.java +++ b/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/menu/PopupMenu.java @@ -2,6 +2,7 @@ import android.content.Context; import android.graphics.Typeface; +import android.provider.Settings; import android.util.TypedValue; import android.view.Gravity; import android.view.KeyEvent; @@ -15,6 +16,8 @@ import androidx.annotation.MenuRes; import androidx.core.content.res.ResourcesCompat; +import androidx.reflect.provider.SeslSystemReflector; +import androidx.reflect.view.SeslSemBlurInfoReflector; import java.util.ArrayList; @@ -38,6 +41,7 @@ public class PopupMenu { private CharSequence title; private int mAnimationStyleRes = 0; + private boolean mBlurEffectEnabled = true; private boolean mGroupDividerEnabled; private int lastGroupId = 0; @@ -178,6 +182,29 @@ private TextView createTitleView() { return titleView; } + private boolean isReduceTransparencySettingsEnabled() { + String reduceTransparencyFlag = SeslSystemReflector.getField_SEM_ACCESSIBILITY_REDUCE_TRANSPARENCY(); + return !reduceTransparencyFlag.equals("not_supported") && Settings.System.getInt(context.getContentResolver(), reduceTransparencyFlag, 0) == 1; + } + + private void setupBlurEffect() { + if (mBlurEffectEnabled) { + if (popupWindow.getContentView() != null && context != null) { + Object blurBuilder = SeslSemBlurInfoReflector.semCreateBlurBuilder(0 /* SemBlurInfo.BLUR_MODE_WINDOW */); + + if (blurBuilder != null && !isReduceTransparencySettingsEnabled()) { + SeslSemBlurInfoReflector.semSetBuilderBlurRadius(blurBuilder, 120); + SeslSemBlurInfoReflector.semSetBuilderBlurBackgroundColor(blurBuilder, context.getResources().getColor(R.color.sesl_popup_menu_blur_background)); + SeslSemBlurInfoReflector.semSetBuilderBlurBackgroundCornerRadius(blurBuilder, context.getResources().getDimension(R.dimen.sesl_menu_popup_corner_radius)); + SeslSemBlurInfoReflector.semBuildSetBlurInfo(blurBuilder, popupWindow.getContentView()); + if (listView != null) { + listView.setOverScrollMode(View.OVER_SCROLL_NEVER); + } + } + } + } + } + private boolean shouldShowGroupDivider(MenuItem menuItem) { if (mGroupDividerEnabled) { if (menuItem.getGroupId() == lastGroupId) { @@ -228,6 +255,7 @@ public void show() { public void show(int xoff, int yoff) { this.xoff = xoff; this.yoff = yoff; + setupBlurEffect(); popupWindow.showAsDropDown(anchor, xoff, yoff); updatePopupSize(); ((View) ReflectUtils.genericGetField(popupWindow, "mBackgroundView")).setClipToOutline(true); @@ -240,6 +268,10 @@ public void setAnimationStyle(int animationStyle) { } } + public void setBlurEffectEnabled(boolean enabled) { + mBlurEffectEnabled = enabled; + } + public void setGroupDividerEnabled(boolean enabled) { mGroupDividerEnabled = enabled; diff --git a/yanndroid/oneui/src/main/res/values-night/colors.xml b/yanndroid/oneui/src/main/res/values-night/colors.xml index 2a3b1bf0..fc73c4ee 100644 --- a/yanndroid/oneui/src/main/res/values-night/colors.xml +++ b/yanndroid/oneui/src/main/res/values-night/colors.xml @@ -76,6 +76,7 @@ #ff252525 #ff3a3a3a #ff3a3a3a + #d6252525 #fffafafa #66fafafa #ffd9d9d9 diff --git a/yanndroid/oneui/src/main/res/values/colors.xml b/yanndroid/oneui/src/main/res/values/colors.xml index cba9ab7e..44ed5ae4 100644 --- a/yanndroid/oneui/src/main/res/values/colors.xml +++ b/yanndroid/oneui/src/main/res/values/colors.xml @@ -135,6 +135,7 @@ #fffcfcfc #fffcfcfc #fffcfcfc + #e6fcfcfc ?colorPrimaryDark ?colorPrimaryDark #66000000 From e2d999152430f35fdcb7a49daac0ee73ab70e849 Mon Sep 17 00:00:00 2001 From: BlackMesa123 Date: Mon, 31 Jan 2022 18:21:42 +0100 Subject: [PATCH 2/2] app/PopupMenu: enable blur effect by default only with OUI4 theme set Signed-off-by: BlackMesa123 --- .../src/main/java/de/dlyt/yanndroid/oneui/menu/PopupMenu.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/menu/PopupMenu.java b/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/menu/PopupMenu.java index 30434034..a787ab93 100644 --- a/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/menu/PopupMenu.java +++ b/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/menu/PopupMenu.java @@ -41,7 +41,7 @@ public class PopupMenu { private CharSequence title; private int mAnimationStyleRes = 0; - private boolean mBlurEffectEnabled = true; + private boolean mBlurEffectEnabled; private boolean mGroupDividerEnabled; private int lastGroupId = 0; @@ -52,6 +52,7 @@ public PopupMenu(View anchor) { this.context = anchor.getContext(); this.anchor = anchor; mIsOneUI4 = context.getTheme().obtainStyledAttributes(new int[]{R.attr.isOneUI4}).getBoolean(0, false); + mBlurEffectEnabled = mIsOneUI4; } public interface PopupMenuListener {