Loading core/api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -49895,6 +49895,7 @@ package android.view { public interface WindowManager extends android.view.ViewManager { method public default void addCrossWindowBlurEnabledListener(@NonNull java.util.function.Consumer<java.lang.Boolean>); method public default void addCrossWindowBlurEnabledListener(@NonNull java.util.concurrent.Executor, @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(); core/java/android/view/CrossWindowBlurListeners.java +24 −13 Original line number Diff line number Diff line Loading @@ -16,13 +16,19 @@ package android.view; import android.annotation.CallbackExecutor; import android.annotation.NonNull; import android.os.Binder; import android.os.Handler; import android.os.Looper; import android.os.RemoteException; import android.os.SystemProperties; import android.util.ArraySet; import android.util.ArrayMap; import android.util.Log; import com.android.internal.util.Preconditions; import java.util.concurrent.Executor; import java.util.function.Consumer; /** Loading @@ -42,7 +48,7 @@ public final class CrossWindowBlurListeners { private static final Object sLock = new Object(); private final BlurEnabledListenerInternal mListenerInternal = new BlurEnabledListenerInternal(); private final ArraySet<Consumer<Boolean>> mListeners = new ArraySet(); private final ArrayMap<Consumer<Boolean>, Executor> mListeners = new ArrayMap(); private final Handler mMainHandler = new Handler(Looper.getMainLooper()); private boolean mInternalListenerAttached = false; private boolean mCrossWindowBlurEnabled; Loading Loading @@ -74,20 +80,22 @@ public final class CrossWindowBlurListeners { } } void addListener(Consumer<Boolean> listener) { if (listener == null) return; void addListener(@NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> listener) { Preconditions.checkNotNull(listener, "listener cannot be null"); Preconditions.checkNotNull(executor, "executor cannot be null"); synchronized (sLock) { attachInternalListenerIfNeededLocked(); mListeners.add(listener); notifyListenerOnMain(listener, mCrossWindowBlurEnabled); mListeners.put(listener, executor); notifyListener(listener, executor, mCrossWindowBlurEnabled); } } void removeListener(Consumer<Boolean> listener) { if (listener == null) return; Preconditions.checkNotNull(listener, "listener cannot be null"); synchronized (sLock) { mListeners.remove(listener); Loading Loading @@ -116,10 +124,8 @@ public final class CrossWindowBlurListeners { } } private void notifyListenerOnMain(Consumer<Boolean> listener, boolean enabled) { mMainHandler.post(() -> { listener.accept(enabled); }); private void notifyListener(Consumer<Boolean> listener, Executor executor, boolean enabled) { executor.execute(() -> listener.accept(enabled)); } private final class BlurEnabledListenerInternal extends ICrossWindowBlurEnabledListener.Stub { Loading @@ -128,8 +134,13 @@ public final class CrossWindowBlurListeners { synchronized (sLock) { mCrossWindowBlurEnabled = enabled; final long token = Binder.clearCallingIdentity(); try { for (int i = 0; i < mListeners.size(); i++) { notifyListenerOnMain(mListeners.valueAt(i), enabled); notifyListener(mListeners.keyAt(i), mListeners.valueAt(i), enabled); } } finally { Binder.restoreCallingIdentity(token); } } } Loading core/java/android/view/WindowManager.java +29 −0 Original line number Diff line number Diff line Loading @@ -81,6 +81,7 @@ import static android.view.WindowLayoutParamsProto.X; import static android.view.WindowLayoutParamsProto.Y; import android.Manifest.permission; import android.annotation.CallbackExecutor; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; Loading Loading @@ -121,6 +122,7 @@ import java.lang.annotation.RetentionPolicy; import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.concurrent.Executor; import java.util.function.Consumer; /** Loading Loading @@ -863,6 +865,33 @@ public interface WindowManager extends ViewManager { default void addCrossWindowBlurEnabledListener(@NonNull Consumer<Boolean> listener) { } /** * 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. * * If the listener is added successfully, it will be called immediately with the current * cross-window blur enabled state. * * @param executor {@link Executor} to handle the listener callback * @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 @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> listener) { } /** * Removes a listener, previously added with {@link #addCrossWindowBlurEnabledListener} * Loading core/java/android/view/WindowManagerImpl.java +9 −1 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; import android.annotation.CallbackExecutor; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UiContext; Loading @@ -40,6 +41,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.IResultReceiver; import java.util.List; import java.util.concurrent.Executor; import java.util.function.Consumer; /** Loading Loading @@ -310,7 +312,13 @@ public final class WindowManagerImpl implements WindowManager { @Override public void addCrossWindowBlurEnabledListener(@NonNull Consumer<Boolean> listener) { CrossWindowBlurListeners.getInstance().addListener(listener); addCrossWindowBlurEnabledListener(mContext.getMainExecutor(), listener); } @Override public void addCrossWindowBlurEnabledListener(@NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> listener) { CrossWindowBlurListeners.getInstance().addListener(executor, listener); } @Override Loading Loading
core/api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -49895,6 +49895,7 @@ package android.view { public interface WindowManager extends android.view.ViewManager { method public default void addCrossWindowBlurEnabledListener(@NonNull java.util.function.Consumer<java.lang.Boolean>); method public default void addCrossWindowBlurEnabledListener(@NonNull java.util.concurrent.Executor, @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();
core/java/android/view/CrossWindowBlurListeners.java +24 −13 Original line number Diff line number Diff line Loading @@ -16,13 +16,19 @@ package android.view; import android.annotation.CallbackExecutor; import android.annotation.NonNull; import android.os.Binder; import android.os.Handler; import android.os.Looper; import android.os.RemoteException; import android.os.SystemProperties; import android.util.ArraySet; import android.util.ArrayMap; import android.util.Log; import com.android.internal.util.Preconditions; import java.util.concurrent.Executor; import java.util.function.Consumer; /** Loading @@ -42,7 +48,7 @@ public final class CrossWindowBlurListeners { private static final Object sLock = new Object(); private final BlurEnabledListenerInternal mListenerInternal = new BlurEnabledListenerInternal(); private final ArraySet<Consumer<Boolean>> mListeners = new ArraySet(); private final ArrayMap<Consumer<Boolean>, Executor> mListeners = new ArrayMap(); private final Handler mMainHandler = new Handler(Looper.getMainLooper()); private boolean mInternalListenerAttached = false; private boolean mCrossWindowBlurEnabled; Loading Loading @@ -74,20 +80,22 @@ public final class CrossWindowBlurListeners { } } void addListener(Consumer<Boolean> listener) { if (listener == null) return; void addListener(@NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> listener) { Preconditions.checkNotNull(listener, "listener cannot be null"); Preconditions.checkNotNull(executor, "executor cannot be null"); synchronized (sLock) { attachInternalListenerIfNeededLocked(); mListeners.add(listener); notifyListenerOnMain(listener, mCrossWindowBlurEnabled); mListeners.put(listener, executor); notifyListener(listener, executor, mCrossWindowBlurEnabled); } } void removeListener(Consumer<Boolean> listener) { if (listener == null) return; Preconditions.checkNotNull(listener, "listener cannot be null"); synchronized (sLock) { mListeners.remove(listener); Loading Loading @@ -116,10 +124,8 @@ public final class CrossWindowBlurListeners { } } private void notifyListenerOnMain(Consumer<Boolean> listener, boolean enabled) { mMainHandler.post(() -> { listener.accept(enabled); }); private void notifyListener(Consumer<Boolean> listener, Executor executor, boolean enabled) { executor.execute(() -> listener.accept(enabled)); } private final class BlurEnabledListenerInternal extends ICrossWindowBlurEnabledListener.Stub { Loading @@ -128,8 +134,13 @@ public final class CrossWindowBlurListeners { synchronized (sLock) { mCrossWindowBlurEnabled = enabled; final long token = Binder.clearCallingIdentity(); try { for (int i = 0; i < mListeners.size(); i++) { notifyListenerOnMain(mListeners.valueAt(i), enabled); notifyListener(mListeners.keyAt(i), mListeners.valueAt(i), enabled); } } finally { Binder.restoreCallingIdentity(token); } } } Loading
core/java/android/view/WindowManager.java +29 −0 Original line number Diff line number Diff line Loading @@ -81,6 +81,7 @@ import static android.view.WindowLayoutParamsProto.X; import static android.view.WindowLayoutParamsProto.Y; import android.Manifest.permission; import android.annotation.CallbackExecutor; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; Loading Loading @@ -121,6 +122,7 @@ import java.lang.annotation.RetentionPolicy; import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.concurrent.Executor; import java.util.function.Consumer; /** Loading Loading @@ -863,6 +865,33 @@ public interface WindowManager extends ViewManager { default void addCrossWindowBlurEnabledListener(@NonNull Consumer<Boolean> listener) { } /** * 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. * * If the listener is added successfully, it will be called immediately with the current * cross-window blur enabled state. * * @param executor {@link Executor} to handle the listener callback * @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 @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> listener) { } /** * Removes a listener, previously added with {@link #addCrossWindowBlurEnabledListener} * Loading
core/java/android/view/WindowManagerImpl.java +9 −1 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; import android.annotation.CallbackExecutor; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UiContext; Loading @@ -40,6 +41,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.IResultReceiver; import java.util.List; import java.util.concurrent.Executor; import java.util.function.Consumer; /** Loading Loading @@ -310,7 +312,13 @@ public final class WindowManagerImpl implements WindowManager { @Override public void addCrossWindowBlurEnabledListener(@NonNull Consumer<Boolean> listener) { CrossWindowBlurListeners.getInstance().addListener(listener); addCrossWindowBlurEnabledListener(mContext.getMainExecutor(), listener); } @Override public void addCrossWindowBlurEnabledListener(@NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> listener) { CrossWindowBlurListeners.getInstance().addListener(executor, listener); } @Override Loading