Merge changes from topic "add-runtime-blur-disabling" into sc-dev

* changes:
  Create listener for dynamic blurEnabled changes
  Make WM.LP.blurBehindRadius a setter+getter
This commit is contained in:
Galia Peycheva
2021-03-02 04:45:06 +00:00
committed by Android (Google) Code Review
15 changed files with 497 additions and 68 deletions

View File

@@ -49724,9 +49724,12 @@ package android.view {
}
public interface WindowManager extends android.view.ViewManager {
method public default void addCrossWindowBlurEnabledListener(@NonNull java.util.function.Consumer<java.lang.Boolean>);
method @NonNull public default android.view.WindowMetrics getCurrentWindowMetrics();
method @Deprecated public android.view.Display getDefaultDisplay();
method @NonNull public default android.view.WindowMetrics getMaximumWindowMetrics();
method public default boolean isCrossWindowBlurEnabled();
method public default void removeCrossWindowBlurEnabledListener(@NonNull java.util.function.Consumer<java.lang.Boolean>);
method public void removeViewImmediate(android.view.View);
}
@@ -49751,12 +49754,14 @@ package android.view {
method public final int copyFrom(android.view.WindowManager.LayoutParams);
method public String debug(String);
method public int describeContents();
method public int getBlurBehindRadius();
method public int getColorMode();
method public int getFitInsetsSides();
method public int getFitInsetsTypes();
method public final CharSequence getTitle();
method public boolean isFitInsetsIgnoringVisibility();
method public static boolean mayUseInputMethod(int);
method public void setBlurBehindRadius(@IntRange(from=0) int);
method public void setColorMode(int);
method public void setFitInsetsIgnoringVisibility(boolean);
method public void setFitInsetsSides(int);
@@ -49867,7 +49872,6 @@ package android.view {
field @Deprecated public static final int TYPE_TOAST = 2005; // 0x7d5
field public static final int TYPE_WALLPAPER = 2013; // 0x7dd
field public float alpha;
field public int blurBehindRadius;
field public float buttonBrightness;
field public float dimAmount;
field public int flags;

View File

@@ -2549,7 +2549,6 @@ package android.content.pm {
field public static final String FEATURE_BROADCAST_RADIO = "android.hardware.broadcastradio";
field public static final String FEATURE_CAMERA_TOGGLE = "android.hardware.camera.toggle";
field public static final String FEATURE_CONTEXT_HUB = "android.hardware.context_hub";
field public static final String FEATURE_CROSS_LAYER_BLUR = "android.software.cross_layer_blur";
field @Deprecated public static final String FEATURE_INCREMENTAL_DELIVERY = "android.software.incremental_delivery";
field public static final String FEATURE_INCREMENTAL_DELIVERY_VERSION = "android.software.incremental_delivery_version";
field public static final String FEATURE_MICROPHONE_TOGGLE = "android.hardware.microphone.toggle";

View File

@@ -3655,17 +3655,6 @@ public abstract class PackageManager {
@SdkConstant(SdkConstantType.FEATURE)
public static final String FEATURE_APP_ENUMERATION = "android.software.app_enumeration";
/**
* Feature for {@link android.view.WindowManager.LayoutParams.backgroundBlurRedius} and
* {@link android.graphics.drawable.BackgroundBlurDrawable}: the device supports cross-layer
* blurring.
*
* @hide
*/
@SystemApi
@SdkConstant(SdkConstantType.FEATURE)
public static final String FEATURE_CROSS_LAYER_BLUR = "android.software.cross_layer_blur";
/**
* Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: The device has
* a Keystore implementation that can only enforce limited use key in hardware with max usage

View File

@@ -0,0 +1,137 @@
/**
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.view;
import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.util.ArraySet;
import android.util.Log;
import java.util.function.Consumer;
/**
* Class that holds all registered {@link CrossWindowBlurEnabledListener}s. It listens
* for updates from the WindowManagerService and updates all registered listeners.
* @hide
*/
public final class CrossWindowBlurListeners {
private static final String TAG = "CrossWindowBlurListeners";
// property for background blur support in surface flinger
private static final String BLUR_PROPERTY = "ro.surface_flinger.supports_background_blur";
public static final boolean CROSS_WINDOW_BLUR_SUPPORTED =
SystemProperties.get(BLUR_PROPERTY, "default").equals("1");
private static volatile CrossWindowBlurListeners sInstance;
private static final Object sLock = new Object();
private final BlurEnabledListenerInternal mListenerInternal = new BlurEnabledListenerInternal();
private final ArraySet<Consumer<Boolean>> mListeners = new ArraySet();
private final Handler mMainHandler = new Handler(Looper.getMainLooper());
private boolean mInternalListenerAttached = false;
private boolean mCrossWindowBlurEnabled;
private CrossWindowBlurListeners() {}
/**
* Returns a CrossWindowBlurListeners instance
*/
public static CrossWindowBlurListeners getInstance() {
CrossWindowBlurListeners instance = sInstance;
if (instance == null) {
synchronized (sLock) {
instance = sInstance;
if (instance == null) {
instance = new CrossWindowBlurListeners();
sInstance = instance;
}
}
}
return instance;
}
boolean isCrossWindowBlurEnabled() {
synchronized (sLock) {
attachInternalListenerIfNeededLocked();
return mCrossWindowBlurEnabled;
}
}
void addListener(Consumer<Boolean> listener) {
if (listener == null) return;
synchronized (sLock) {
attachInternalListenerIfNeededLocked();
mListeners.add(listener);
notifyListenerOnMain(listener, mCrossWindowBlurEnabled);
}
}
void removeListener(Consumer<Boolean> listener) {
if (listener == null) return;
synchronized (sLock) {
mListeners.remove(listener);
if (mInternalListenerAttached && mListeners.size() == 0) {
try {
WindowManagerGlobal.getWindowManagerService()
.unregisterCrossWindowBlurEnabledListener(mListenerInternal);
mInternalListenerAttached = false;
} catch (RemoteException e) {
Log.d(TAG, "Could not unregister ICrossWindowBlurEnabledListener");
}
}
}
}
private void attachInternalListenerIfNeededLocked() {
if (!mInternalListenerAttached) {
try {
mCrossWindowBlurEnabled = WindowManagerGlobal.getWindowManagerService()
.registerCrossWindowBlurEnabledListener(mListenerInternal);
mInternalListenerAttached = true;
} catch (RemoteException e) {
Log.d(TAG, "Could not register ICrossWindowBlurEnabledListener");
}
}
}
private void notifyListenerOnMain(Consumer<Boolean> listener, boolean enabled) {
mMainHandler.post(() -> {
listener.accept(enabled);
});
}
private final class BlurEnabledListenerInternal extends ICrossWindowBlurEnabledListener.Stub {
@Override
public void onCrossWindowBlurEnabledChanged(boolean enabled) {
synchronized (sLock) {
mCrossWindowBlurEnabled = enabled;
for (int i = 0; i < mListeners.size(); i++) {
notifyListenerOnMain(mListeners.valueAt(i), enabled);
}
}
}
}
}

View File

@@ -0,0 +1,29 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.view;
/**
* Listener to be invoked when cross-window blur is enabled or disabled.
* {@hide}
*/
oneway interface ICrossWindowBlurEnabledListener {
/**
* Method that will be invoked when cross-window blur is enabled or disabled.
* @param enabled True if cross-window blur is enabled.
*/
void onCrossWindowBlurEnabledChanged(boolean enabled);
}

View File

@@ -35,6 +35,7 @@ import android.os.ParcelFileDescriptor;
import android.view.DisplayCutout;
import android.view.IApplicationToken;
import android.view.IAppTransitionAnimationSpecsFuture;
import android.view.ICrossWindowBlurEnabledListener;
import android.view.IDisplayWindowInsetsController;
import android.view.IDisplayWindowListener;
import android.view.IDisplayFoldListener;
@@ -730,7 +731,7 @@ interface IWindowManager
void showGlobalActions();
/**
* Sets layer tracing flags for SurfaceFlingerTrace.
* Sets layer tracing flags for SurfaceFlingerTrace.
*
* @param flags see definition in SurfaceTracing.cpp
*/
@@ -799,4 +800,20 @@ interface IWindowManager
* @param clientToken the window context's token
*/
void unregisterWindowContextListener(IBinder clientToken);
/**
* Registers a listener, which is to be called whenever cross-window blur is enabled/disabled.
*
* @param listener the listener to be registered
* @return true if cross-window blur is currently enabled; false otherwise
*/
boolean registerCrossWindowBlurEnabledListener(ICrossWindowBlurEnabledListener listener);
/**
* Unregisters a listener which was registered with
* {@link #registerCrossWindowBlurEnabledListener()}.
*
* @param listener the listener to be unregistered
*/
void unregisterCrossWindowBlurEnabledListener(ICrossWindowBlurEnabledListener listener);
}

View File

@@ -1716,13 +1716,22 @@ public abstract class Window {
* For the blur region to be visible, the window has to be translucent. See
* {@link android.R.styleable#Window_windowIsTranslucent}.
*
* Note the difference with {@link android.view.WindowManager.LayoutParams#blurBehindRadius},
* Note the difference with {@link WindowManager.LayoutParams#setBlurBehindRadius},
* which blurs the whole screen behind the window. Background blur blurs the screen behind
* only within the bounds of the window.
*
* Some devices might not support cross-window blur due to GPU limitations. It can also be
* disabled at runtime, e.g. during battery saving mode, when multimedia tunneling is used or
* when minimal post processing is requested. In such situations, no blur will be computed or
* drawn, resulting in a transparent window background. To avoid this, the app might want to
* change its theme to one that does not use blurs. To listen for cross-window blur
* enabled/disabled events, use {@link WindowManager#addCrossWindowBlurEnabledListener}.
*
* @param blurRadius The blur radius to use for window background blur in pixels
*
* @see android.R.styleable#Window_windowBackgroundBlurRadius
* @see WindowManager.LayoutParams#setBlurBehindRadius
* @see WindowManager#addCrossWindowBlurEnabledListener
*/
public void setBackgroundBlurRadius(int blurRadius) {}

View File

@@ -82,6 +82,7 @@ import static android.view.WindowLayoutParamsProto.Y;
import android.Manifest.permission;
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -120,6 +121,7 @@ import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
/**
* The interface that apps use to talk to the window manager.
@@ -808,6 +810,64 @@ public interface WindowManager extends ViewManager {
return DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
}
/**
* Returns whether cross-window blur is currently enabled. This affects both window blur behind
* (see {@link LayoutParams#setBlurBehindRadius}) and window background blur (see
* {@link Window#setBackgroundBlurRadius}).
*
* Cross-window blur might not be supported by some devices due to GPU limitations. It can also
* be disabled at runtime, e.g. during battery saving mode, when multimedia tunneling is used or
* when minimal post processing is requested. In such situations, no blur will be computed or
* drawn, so the blur target area will not be blurred. To handle this, the app might want to
* change its theme to one that does not use blurs. To listen for cross-window blur
* enabled/disabled events, use {@link #addCrossWindowBlurEnabledListener}.
*
* @see #addCrossWindowBlurEnabledListener
* @see LayoutParams#setBlurBehindRadius
* @see Window#setBackgroundBlurRadius
*/
default boolean isCrossWindowBlurEnabled() {
return false;
}
/**
* Adds a listener, which will be called when cross-window blurs are enabled/disabled at
* runtime. This affects both window blur behind (see {@link LayoutParams#setBlurBehindRadius})
* and window background blur (see {@link Window#setBackgroundBlurRadius}).
*
* Cross-window blur might not be supported by some devices due to GPU limitations. It can also
* be disabled at runtime, e.g. during battery saving mode, when multimedia tunneling is used or
* when minimal post processing is requested. In such situations, no blur will be computed or
* drawn, so the blur target area will not be blurred. To handle this, the app might want to
* change its theme to one that does not use blurs.
*
* The listener will be called on the main thread.
*
* If the listener is added successfully, it will be called immediately with the current
* cross-window blur enabled state.
*
*
* @param listener the listener to be added. It will be called back with a boolean parameter,
* which is true if cross-window blur is enabled and false if it is disabled
*
* @see #removeCrossWindowBlurEnabledListener
* @see #isCrossWindowBlurEnabled
* @see LayoutParams#setBlurBehindRadius
* @see Window#setBackgroundBlurRadius
*/
default void addCrossWindowBlurEnabledListener(@NonNull Consumer<Boolean> listener) {
}
/**
* Removes a listener, previously added with {@link #addCrossWindowBlurEnabledListener}
*
* @param listener the listener to be removed
*
* @see #addCrossWindowBlurEnabledListener
*/
default void removeCrossWindowBlurEnabledListener(@NonNull Consumer<Boolean> listener) {
}
public static class LayoutParams extends ViewGroup.LayoutParams implements Parcelable {
/**
* X position for this window. With the default gravity it is ignored.
@@ -3238,9 +3298,9 @@ public interface WindowManager extends ViewManager {
* The blur behind radius range starts at 0, which means no blur, and increases until 150
* for the densest blur.
*
* @see #FLAG_BLUR_BEHIND
* @see #setBlurBehindRadius
*/
public int blurBehindRadius = 0;
private int mBlurBehindRadius = 0;
/**
* The color mode requested by this window. The target display may
@@ -3534,6 +3594,50 @@ public interface WindowManager extends ViewManager {
return mColorMode;
}
/**
* Blurs the screen behind the window. The effect is similar to that of {@link #dimAmount},
* but instead of dimmed, the content behind the window will be blurred (or combined with
* the dim amount, if such is specified).
*
* The density of the blur is set by the blur radius. The radius defines the size
* of the neighbouring area, from which pixels will be averaged to form the final
* color for each pixel. The operation approximates a Gaussian blur.
* A radius of 0 means no blur. The higher the radius, the denser the blur.
*
* Note the difference with {@link android.view.Window#setBackgroundBlurRadius},
* which blurs only within the bounds of the window. Blur behind blurs the whole screen
* behind the window.
*
* Requires {@link #FLAG_BLUR_BEHIND} to be set.
*
* Cross-window blur might not be supported by some devices due to GPU limitations. It can
* also be disabled at runtime, e.g. during battery saving mode, when multimedia tunneling
* is used or when minimal post processing is requested. In such situations, no blur will
* be computed or drawn, resulting in there being no depth separation between the window
* and the content behind it. To avoid this, the app might want to use more
* {@link #dimAmount} on its window. To listen for cross-window blur enabled/disabled
* events, use {@link #addCrossWindowBlurEnabledListener}.
*
* @param blurBehindRadius The blur radius to use for blur behind in pixels
*
* @see #FLAG_BLUR_BEHIND
* @see #getBlurBehindRadius
* @see WindowManager#addCrossWindowBlurEnabledListener
* @see Window#setBackgroundBlurRadius
*/
public void setBlurBehindRadius(@IntRange(from = 0) int blurBehindRadius) {
mBlurBehindRadius = blurBehindRadius;
}
/**
* Returns the blur behind radius of the window.
*
* @see #setBlurBehindRadius
*/
public int getBlurBehindRadius() {
return mBlurBehindRadius;
}
/** @hide */
@SystemApi
public final void setUserActivityTimeout(long timeout) {
@@ -3629,7 +3733,7 @@ public interface WindowManager extends ViewManager {
out.writeInt(mFitInsetsSides);
out.writeBoolean(mFitInsetsIgnoringVisibility);
out.writeBoolean(preferMinimalPostProcessing);
out.writeInt(blurBehindRadius);
out.writeInt(mBlurBehindRadius);
if (providesInsetsTypes != null) {
out.writeInt(providesInsetsTypes.length);
out.writeIntArray(providesInsetsTypes);
@@ -3698,7 +3802,7 @@ public interface WindowManager extends ViewManager {
mFitInsetsSides = in.readInt();
mFitInsetsIgnoringVisibility = in.readBoolean();
preferMinimalPostProcessing = in.readBoolean();
blurBehindRadius = in.readInt();
mBlurBehindRadius = in.readInt();
int insetsTypesLength = in.readInt();
if (insetsTypesLength > 0) {
providesInsetsTypes = new int[insetsTypesLength];
@@ -3752,7 +3856,7 @@ public interface WindowManager extends ViewManager {
/** {@hide} */
public static final int MINIMAL_POST_PROCESSING_PREFERENCE_CHANGED = 1 << 28;
/** {@hide} */
public static final int BACKGROUND_BLUR_RADIUS_CHANGED = 1 << 29;
public static final int BLUR_BEHIND_RADIUS_CHANGED = 1 << 29;
// internal buffer to backup/restore parameters under compatibility mode.
private int[] mCompatibilityParamsBackup = null;
@@ -3943,9 +4047,9 @@ public interface WindowManager extends ViewManager {
changes |= MINIMAL_POST_PROCESSING_PREFERENCE_CHANGED;
}
if (blurBehindRadius != o.blurBehindRadius) {
blurBehindRadius = o.blurBehindRadius;
changes |= BACKGROUND_BLUR_RADIUS_CHANGED;
if (mBlurBehindRadius != o.mBlurBehindRadius) {
mBlurBehindRadius = o.mBlurBehindRadius;
changes |= BLUR_BEHIND_RADIUS_CHANGED;
}
// This can't change, it's only set at window creation time.
@@ -4111,9 +4215,9 @@ public interface WindowManager extends ViewManager {
sb.append(" preferMinimalPostProcessing=");
sb.append(preferMinimalPostProcessing);
}
if (blurBehindRadius != 0) {
if (mBlurBehindRadius != 0) {
sb.append(" blurBehindRadius=");
sb.append(blurBehindRadius);
sb.append(mBlurBehindRadius);
}
sb.append(System.lineSeparator());
sb.append(prefix).append(" fl=").append(

View File

@@ -40,6 +40,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.IResultReceiver;
import java.util.List;
import java.util.function.Consumer;
/**
* Provides low-level communication with the system window manager for
@@ -301,4 +302,19 @@ public final class WindowManagerImpl implements WindowManager {
throw e.rethrowFromSystemServer();
}
}
@Override
public boolean isCrossWindowBlurEnabled() {
return CrossWindowBlurListeners.getInstance().isCrossWindowBlurEnabled();
}
@Override
public void addCrossWindowBlurEnabledListener(@NonNull Consumer<Boolean> listener) {
CrossWindowBlurListeners.getInstance().addListener(listener);
}
@Override
public void removeCrossWindowBlurEnabledListener(@NonNull Consumer<Boolean> listener) {
CrossWindowBlurListeners.getInstance().removeListener(listener);
}
}

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);
}
}
}
@@ -2556,8 +2559,8 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
params.flags |= WindowManager.LayoutParams.FLAG_BLUR_BEHIND;
}
params.blurBehindRadius = a.getDimensionPixelSize(
android.R.styleable.Window_windowBlurBehindRadius, 0);
params.setBlurBehindRadius(a.getDimensionPixelSize(
android.R.styleable.Window_windowBlurBehindRadius, 0));
}
setBackgroundBlurRadius(a.getDimensionPixelSize(

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);
}

View File

@@ -0,0 +1,76 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.wm;
import static android.view.CrossWindowBlurListeners.CROSS_WINDOW_BLUR_SUPPORTED;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.view.ICrossWindowBlurEnabledListener;
final class BlurController {
private final RemoteCallbackList<ICrossWindowBlurEnabledListener>
mBlurEnabledListeners = new RemoteCallbackList<>();
private final Object mLock = new Object();
boolean mBlurEnabled;
BlurController() {
mBlurEnabled = CROSS_WINDOW_BLUR_SUPPORTED;
}
boolean registerCrossWindowBlurEnabledListener(ICrossWindowBlurEnabledListener listener) {
if (listener == null) return false;
mBlurEnabledListeners.register(listener);
synchronized (mLock) {
return mBlurEnabled;
}
}
void unregisterCrossWindowBlurEnabledListener(ICrossWindowBlurEnabledListener listener) {
if (listener == null) return;
mBlurEnabledListeners.unregister(listener);
}
private void updateBlurEnabled() {
// TODO: add other factors disabling blurs
final boolean newEnabled = CROSS_WINDOW_BLUR_SUPPORTED;
synchronized (mLock) {
if (mBlurEnabled == newEnabled) {
return;
}
mBlurEnabled = newEnabled;
notifyBlurEnabledChanged(newEnabled);
}
}
private void notifyBlurEnabledChanged(boolean enabled) {
int i = mBlurEnabledListeners.beginBroadcast();
while (i > 0) {
i--;
ICrossWindowBlurEnabledListener listener =
mBlurEnabledListeners.getBroadcastItem(i);
try {
listener.onCrossWindowBlurEnabledChanged(enabled);
} catch (RemoteException e) {
}
}
mBlurEnabledListeners.finishBroadcast();
}
}

View File

@@ -223,6 +223,7 @@ import android.view.Display;
import android.view.DisplayInfo;
import android.view.Gravity;
import android.view.IAppTransitionAnimationSpecsFuture;
import android.view.ICrossWindowBlurEnabledListener;
import android.view.IDisplayFoldListener;
import android.view.IDisplayWindowInsetsController;
import android.view.IDisplayWindowListener;
@@ -756,6 +757,8 @@ public class WindowManagerService extends IWindowManager.Stub
final TaskSnapshotController mTaskSnapshotController;
final BlurController mBlurController = new BlurController();
boolean mIsTouchDevice;
boolean mIsFakeTouchDevice;
@@ -5672,6 +5675,18 @@ public class WindowManagerService extends IWindowManager.Stub
return mWindowTracing.isEnabled();
}
@Override
public boolean registerCrossWindowBlurEnabledListener(
ICrossWindowBlurEnabledListener listener) {
return mBlurController.registerCrossWindowBlurEnabledListener(listener);
}
@Override
public void unregisterCrossWindowBlurEnabledListener(
ICrossWindowBlurEnabledListener listener) {
mBlurController.unregisterCrossWindowBlurEnabledListener(listener);
}
// -------------------------------------------------------------
// Internals
// -------------------------------------------------------------
@@ -6411,6 +6426,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
});
pw.print(" mInTouchMode="); pw.println(mInTouchMode);
pw.print(" mBlurEnabled="); pw.println(mBlurController.mBlurEnabled);
pw.print(" mLastDisplayFreezeDuration=");
TimeUtils.formatDuration(mLastDisplayFreezeDuration, pw);
if ( mLastFinishedFreezeSource != null) {

View File

@@ -5273,22 +5273,24 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
if (!mAnimatingExit && mAppDied) {
mIsDimming = true;
getDimmer().dimAbove(getSyncTransaction(), this, DEFAULT_DIM_AMOUNT_DEAD_WINDOW);
} else if (((mAttrs.flags & FLAG_DIM_BEHIND) != 0 || (mAttrs.flags & FLAG_BLUR_BEHIND) != 0)
} else if (((mAttrs.flags & FLAG_DIM_BEHIND) != 0 || shouldDrawBlurBehind())
&& isVisibleNow() && !mHidden) {
// Only show the Dimmer when the following is satisfied:
// 1. The window has the flag FLAG_DIM_BEHIND or background blur is requested
// 1. The window has the flag FLAG_DIM_BEHIND or blur behind is requested
// 2. The WindowToken is not hidden so dims aren't shown when the window is exiting.
// 3. The WS is considered visible according to the isVisible() method
// 4. The WS is not hidden.
mIsDimming = true;
final float dimAmount = (mAttrs.flags & FLAG_DIM_BEHIND) != 0 ? mAttrs.dimAmount : 0;
final int blurRadius =
(mAttrs.flags & FLAG_BLUR_BEHIND) != 0 ? mAttrs.blurBehindRadius : 0;
getDimmer().dimBelow(
getSyncTransaction(), this, mAttrs.dimAmount, mAttrs.blurBehindRadius);
final int blurRadius = shouldDrawBlurBehind() ? mAttrs.getBlurBehindRadius() : 0;
getDimmer().dimBelow(getSyncTransaction(), this, mAttrs.dimAmount, blurRadius);
}
}
private boolean shouldDrawBlurBehind() {
return (mAttrs.flags & FLAG_BLUR_BEHIND) != 0 && mWmService.mBlurController.mBlurEnabled;
}
/**
* Notifies SF about the priority of the window, if it changed. SF then uses this information
* to decide which window's desired rendering rate should have a priority when deciding about