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:
committed by
Android (Google) Code Review
commit
fd98c576c7
@@ -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;
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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
|
||||
|
||||
137
core/java/android/view/CrossWindowBlurListeners.java
Normal file
137
core/java/android/view/CrossWindowBlurListeners.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
29
core/java/android/view/ICrossWindowBlurEnabledListener.aidl
Normal file
29
core/java/android/view/ICrossWindowBlurEnabledListener.aidl
Normal 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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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) {}
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
76
services/core/java/com/android/server/wm/BlurController.java
Normal file
76
services/core/java/com/android/server/wm/BlurController.java
Normal 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();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user