Create listener for dynamic blurEnabled changes

This CL exposes an API to let apps know when the blur has been enabled
or disabled dynamically.

This could be due to battery saving mode turned on, tunnel mode being
used, minimal post processing requested, etc.

This adds a WindowManager.addCrossWindowBlurEnabledListener, which allows
apps to add/remove a listener for blur enabled state changes. The
listeners are registered in a CrossWindowBlurListeners, which receives
updates from WindowManagerService when blurEnabled changes.
CrossWindowBlurListeners only registers a remote listener if the client
initializes it. I.e. if the app is not interested in blurs, the
CrossWindowBlurListeners won't get initialized and won't register a
remote listener.

WindowManagerService holds a RemoteCallbackList, which holds listeners
for each client process and notifies them when there are updates. If any
of the listeners' process dies, the entry is removed from the list.

Bug: 177524486
Test: m
CTS-Coverage-Bug: 179990440
Change-Id: I3fe8f2d2008171d6b069e8ee6f3b47e5b5d60cfa
This commit is contained in:
Galia Peycheva
2021-02-16 16:39:57 +01:00
parent 7fe1a92c60
commit 6e842a730c
15 changed files with 445 additions and 52 deletions

View File

@@ -124,6 +124,7 @@ import com.android.internal.widget.DecorCaptionView;
import com.android.internal.widget.FloatingToolbar;
import java.util.List;
import java.util.function.Consumer;
/** @hide */
public class DecorView extends FrameLayout implements RootViewSurfaceTaker, WindowCallbacks {
@@ -282,14 +283,19 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
private final Paint mLegacyNavigationBarBackgroundPaint = new Paint();
private Insets mBackgroundInsets = Insets.NONE;
private Insets mLastBackgroundInsets = Insets.NONE;
private int mLastBackgroundBlurRadius = 0;
private boolean mDrawLegacyNavigationBarBackground;
private PendingInsetsController mPendingInsetsController = new PendingInsetsController();
private int mOriginalBackgroundBlurRadius = 0;
private int mBackgroundBlurRadius = 0;
private int mLastBackgroundBlurRadius = 0;
private boolean mCrossWindowBlurEnabled;
private final ViewTreeObserver.OnPreDrawListener mBackgroundBlurOnPreDrawListener = () -> {
updateBackgroundBlur();
updateBackgroundBlurCorners();
return true;
};
private Consumer<Boolean> mCrossWindowBlurEnabledListener;
DecorView(Context context, int featureId, PhoneWindow window,
WindowManager.LayoutParams params) {
@@ -1272,23 +1278,17 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
}
if (mBackgroundInsets.equals(mLastBackgroundInsets)
&& mWindow.mBackgroundBlurRadius == mLastBackgroundBlurRadius
&& mBackgroundBlurRadius == mLastBackgroundBlurRadius
&& mLastOriginalBackgroundDrawable == mOriginalBackgroundDrawable) {
return;
}
Drawable destDrawable = mOriginalBackgroundDrawable;
if (mWindow.mBackgroundBlurRadius > 0 && getViewRootImpl() != null
&& mWindow.isTranslucent()) {
if (mBackgroundBlurDrawable == null) {
mBackgroundBlurDrawable = getViewRootImpl().createBackgroundBlurDrawable();
}
if (mBackgroundBlurRadius > 0) {
destDrawable = new LayerDrawable(new Drawable[] {mBackgroundBlurDrawable,
mOriginalBackgroundDrawable});
mLastBackgroundBlurRadius = mWindow.mBackgroundBlurRadius;
}
if (destDrawable != null && !mBackgroundInsets.equals(Insets.NONE)) {
destDrawable = new InsetDrawable(destDrawable,
mBackgroundInsets.left, mBackgroundInsets.top,
@@ -1309,23 +1309,60 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
super.setBackgroundDrawable(destDrawable);
mLastBackgroundInsets = mBackgroundInsets;
mLastBackgroundBlurRadius = mBackgroundBlurRadius;
mLastOriginalBackgroundDrawable = mOriginalBackgroundDrawable;
}
private void updateBackgroundBlur() {
private void updateBackgroundBlurCorners() {
if (mBackgroundBlurDrawable == null) return;
float cornerRadius = 0;
// If the blur radius is 0, the blur region won't be sent to surface flinger, so we don't
// need to calculate the corner radius.
if (mWindow.mBackgroundBlurRadius > 0) {
if (mOriginalBackgroundDrawable != null) {
final Outline outline = new Outline();
mOriginalBackgroundDrawable.getOutline(outline);
mBackgroundBlurDrawable.setCornerRadius(outline.mMode == Outline.MODE_ROUND_RECT
? outline.getRadius() : 0);
}
if (mBackgroundBlurRadius != 0 && mOriginalBackgroundDrawable != null) {
final Outline outline = new Outline();
mOriginalBackgroundDrawable.getOutline(outline);
cornerRadius = outline.mMode == Outline.MODE_ROUND_RECT ? outline.getRadius() : 0;
}
mBackgroundBlurDrawable.setCornerRadius(cornerRadius);
}
private void updateBackgroundBlurRadius() {
if (getViewRootImpl() == null) return;
mBackgroundBlurRadius = mCrossWindowBlurEnabled && mWindow.isTranslucent()
? mOriginalBackgroundBlurRadius : 0;
if (mBackgroundBlurDrawable == null && mBackgroundBlurRadius > 0) {
mBackgroundBlurDrawable = getViewRootImpl().createBackgroundBlurDrawable();
}
if (mBackgroundBlurDrawable != null) {
mBackgroundBlurDrawable.setBlurRadius(mBackgroundBlurRadius);
updateBackgroundDrawable();
}
}
void setBackgroundBlurRadius(int blurRadius) {
mOriginalBackgroundBlurRadius = blurRadius;
if (blurRadius > 0) {
if (mCrossWindowBlurEnabledListener == null) {
mCrossWindowBlurEnabledListener = enabled -> {
mCrossWindowBlurEnabled = enabled;
updateBackgroundBlurRadius();
};
getContext().getSystemService(WindowManager.class)
.addCrossWindowBlurEnabledListener(mCrossWindowBlurEnabledListener);
getViewTreeObserver().addOnPreDrawListener(mBackgroundBlurOnPreDrawListener);
} else {
updateBackgroundBlurRadius();
}
} else if (mCrossWindowBlurEnabledListener != null) {
mCrossWindowBlurEnabledListener = null;
getContext().getSystemService(WindowManager.class)
.removeCrossWindowBlurEnabledListener(mCrossWindowBlurEnabledListener);
getViewTreeObserver().removeOnPreDrawListener(mBackgroundBlurOnPreDrawListener);
updateBackgroundBlurRadius();
}
mBackgroundBlurDrawable.setBlurRadius(mWindow.mBackgroundBlurRadius);
}
@Override
@@ -1758,9 +1795,6 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
cb.onAttachedToWindow();
}
getViewTreeObserver().addOnPreDrawListener(mBackgroundBlurOnPreDrawListener);
updateBackgroundDrawable();
if (mFeatureId == -1) {
/*
* The main window has been attached, try to restore any panels
@@ -1782,6 +1816,9 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
// renderer about it.
mBackdropFrameRenderer.onConfigurationChange();
}
updateBackgroundBlurRadius();
mWindow.onViewRootImplSet(getViewRootImpl());
}
@@ -1794,8 +1831,6 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
cb.onDetachedFromWindow();
}
getViewTreeObserver().removeOnPreDrawListener(mBackgroundBlurOnPreDrawListener);
if (mWindow.mDecorContentParent != null) {
mWindow.mDecorContentParent.dismissPopups();
}

View File

@@ -75,6 +75,7 @@ import android.util.Pair;
import android.util.SparseArray;
import android.util.TypedValue;
import android.view.ContextThemeWrapper;
import android.view.CrossWindowBlurListeners;
import android.view.Gravity;
import android.view.IRotationWatcher.Stub;
import android.view.IScrollCaptureCallbacks;
@@ -258,7 +259,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
Drawable mBackgroundDrawable = null;
Drawable mBackgroundFallbackDrawable = null;
int mBackgroundBlurRadius = 0;
private int mBackgroundBlurRadius = 0;
private boolean mLoadElevation = true;
private float mElevation;
@@ -1527,9 +1528,11 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
@Override
public final void setBackgroundBlurRadius(int blurRadius) {
super.setBackgroundBlurRadius(blurRadius);
if (getContext().getPackageManager().hasSystemFeature(
PackageManager.FEATURE_CROSS_LAYER_BLUR)) {
mBackgroundBlurRadius = Math.max(blurRadius, 0);
if (CrossWindowBlurListeners.CROSS_WINDOW_BLUR_SUPPORTED) {
if (mBackgroundBlurRadius != Math.max(blurRadius, 0)) {
mBackgroundBlurRadius = Math.max(blurRadius, 0);
mDecor.setBackgroundBlurRadius(mBackgroundBlurRadius);
}
}
}

View File

@@ -95,9 +95,6 @@ public class SystemConfig {
// property for runtime configuration differentiation in vendor
private static final String VENDOR_SKU_PROPERTY = "ro.boot.product.vendor.sku";
// property for background blur support in surface flinger
private static final String BLUR_PROPERTY = "ro.surface_flinger.supports_background_blur";
// Group-ids that are given to all packages as read from etc/permissions/*.xml.
int[] mGlobalGids = EmptyArray.INT;
@@ -1249,10 +1246,6 @@ public class SystemConfig {
addFeature(PackageManager.FEATURE_IPSEC_TUNNELS, 0);
}
if (SystemProperties.get(BLUR_PROPERTY, "default").equals("1")) {
addFeature(PackageManager.FEATURE_CROSS_LAYER_BLUR, 0);
}
if (SensorPrivacyManager.USE_MICROPHONE_TOGGLE) {
addFeature(PackageManager.FEATURE_MICROPHONE_TOGGLE, 0);
}