Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 191c35b9 authored by Galia Peycheva's avatar Galia Peycheva
Browse files

Add executor to window blur api

Bug: 181593110
Test: atest BlurTests
CTS-Coverage-Bug: 179990440
Change-Id: Ifc15afd100d5e75c63ded524f43b0d7442dc815d
parent 07fedbce
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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();
+24 −13
Original line number Diff line number Diff line
@@ -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;

/**
@@ -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;
@@ -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);
@@ -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 {
@@ -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);
                }
            }
        }
+29 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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;

/**
@@ -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}
     *
+9 −1
Original line number Diff line number Diff line
@@ -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;
@@ -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;

/**
@@ -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