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

Commit b110f3b2 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add display info to window infos listener test API" into main

parents 521ba6b0 b3d94acf
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -4425,8 +4425,13 @@ package android.window {

  public class WindowInfosListenerForTest {
    ctor public WindowInfosListenerForTest();
    method @RequiresPermission(android.Manifest.permission.ACCESS_SURFACE_FLINGER) public void addWindowInfosListener(@NonNull java.util.function.Consumer<java.util.List<android.window.WindowInfosListenerForTest.WindowInfo>>);
    method public void removeWindowInfosListener(@NonNull java.util.function.Consumer<java.util.List<android.window.WindowInfosListenerForTest.WindowInfo>>);
    method @RequiresPermission(android.Manifest.permission.ACCESS_SURFACE_FLINGER) public void addWindowInfosListener(@NonNull java.util.function.BiConsumer<java.util.List<android.window.WindowInfosListenerForTest.WindowInfo>,java.util.List<android.window.WindowInfosListenerForTest.DisplayInfo>>);
    method public void removeWindowInfosListener(@NonNull java.util.function.BiConsumer<java.util.List<android.window.WindowInfosListenerForTest.WindowInfo>,java.util.List<android.window.WindowInfosListenerForTest.DisplayInfo>>);
  }

  public static class WindowInfosListenerForTest.DisplayInfo {
    field public final int displayId;
    field @NonNull public final android.graphics.Matrix transform;
  }

  public static class WindowInfosListenerForTest.WindowInfo {
+59 −15
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.graphics.Rect;
import android.graphics.RectF;
import android.os.IBinder;
import android.os.InputConfig;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Pair;
@@ -35,7 +36,7 @@ import android.view.InputWindowHandle;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.function.Consumer;
import java.util.function.BiConsumer;

/**
 * Wrapper class to provide access to WindowInfosListener within tests.
@@ -83,7 +84,7 @@ public class WindowInfosListenerForTest {
        public final boolean isVisible;

        /**
         * Return the transform to get the bounds from display space into window space.
         * The transform from display space to window space.
         */
        @NonNull
        public final Matrix transform;
@@ -150,9 +151,41 @@ public class WindowInfosListenerForTest {
        }
    }

    /**
     * Display properties passed to {@code @WindowInfosListenerForTest#onWindowInfosChanged}.
     */
    @SuppressLint("UnflaggedApi") // The API is only used for tests.
    public static class DisplayInfo {

        /**
         * The display's id.
         */
        @SuppressLint("UnflaggedApi") // The API is only used for tests.
        public final int displayId;

        /**
         * The display's transform from physical display space to logical display space.
         */
        @SuppressLint("UnflaggedApi") // The API is only used for tests.
        @NonNull
        public final Matrix transform;

        DisplayInfo(int displayId, @NonNull Matrix transform) {
            this.displayId = displayId;
            this.transform = transform;
        }

        @Override
        public String toString() {
            return TextUtils.formatSimple(
                    "DisplayInfo{displayId=%s, transform=%s}", displayId, transform);
        }
    }

    private static final String TAG = "WindowInfosListenerForTest";

    private ArrayMap<Consumer<List<WindowInfo>>, WindowInfosListener> mListeners;
    private ArrayMap<BiConsumer<List<WindowInfo>, List<DisplayInfo>>, WindowInfosListener>
            mListeners;

    public WindowInfosListenerForTest() {
        mListeners = new ArrayMap<>();
@@ -165,9 +198,10 @@ public class WindowInfosListenerForTest {
     * @param consumer Consumer that is called with reverse Z ordered lists of WindowInfo instances
     *                 where the first value is the topmost window.
     */
    @SuppressLint("UnflaggedApi") // The API is only used for tests.
    @RequiresPermission(Manifest.permission.ACCESS_SURFACE_FLINGER)
    public void addWindowInfosListener(
            @NonNull Consumer<List<WindowInfo>> consumer) {
            @NonNull BiConsumer<List<WindowInfo>, List<DisplayInfo>> consumer) {
        var calledWithInitialState = new CountDownLatch(1);
        var listener = new WindowInfosListener() {
            @Override
@@ -180,20 +214,24 @@ public class WindowInfosListenerForTest {
                            "Exception thrown while waiting for listener to be called with "
                                    + "initial state");
                }
                consumer.accept(buildWindowInfos(windowHandles, displayInfos));
                var params = buildParams(windowHandles, displayInfos);
                consumer.accept(params.first, params.second);
            }
        };
        mListeners.put(consumer, listener);
        Pair<InputWindowHandle[], WindowInfosListener.DisplayInfo[]> initialState =
                listener.register();
        consumer.accept(buildWindowInfos(initialState.first, initialState.second));
        Pair<List<WindowInfo>, List<DisplayInfo>> params =
                buildParams(initialState.first, initialState.second);

        consumer.accept(params.first, params.second);
        calledWithInitialState.countDown();
    }

    /**
     * Unregisters the listener.
     */
    public void removeWindowInfosListener(@NonNull Consumer<List<WindowInfo>> consumer) {
    /** Unregisters the listener. */
    @SuppressLint("UnflaggedApi") // The API is only used for tests.
    public void removeWindowInfosListener(
            @NonNull BiConsumer<List<WindowInfo>, List<DisplayInfo>> consumer) {
        WindowInfosListener listener = mListeners.remove(consumer);
        if (listener == null) {
            return;
@@ -201,15 +239,20 @@ public class WindowInfosListenerForTest {
        listener.unregister();
    }

    private static List<WindowInfo> buildWindowInfos(
    private static Pair<List<WindowInfo>, List<DisplayInfo>> buildParams(
            InputWindowHandle[] windowHandles, WindowInfosListener.DisplayInfo[] displayInfos) {
        var windowInfos = new ArrayList<WindowInfo>(windowHandles.length);
        var outWindowInfos = new ArrayList<WindowInfo>(windowHandles.length);
        var outDisplayInfos = new ArrayList<DisplayInfo>(displayInfos.length);

        var displayInfoById = new SparseArray<WindowInfosListener.DisplayInfo>(displayInfos.length);
        for (var displayInfo : displayInfos) {
            displayInfoById.put(displayInfo.mDisplayId, displayInfo);
        }

        for (var displayInfo : displayInfos) {
            outDisplayInfos.add(new DisplayInfo(displayInfo.mDisplayId, displayInfo.mTransform));
        }

        var tmp = new RectF();
        for (var handle : windowHandles) {
            var bounds = new Rect(handle.frame);
@@ -222,9 +265,10 @@ public class WindowInfosListenerForTest {
                tmp.round(bounds);
            }

            windowInfos.add(new WindowInfo(handle.getWindowToken(), handle.name, handle.displayId,
                    bounds, handle.inputConfig, handle.transform));
            outWindowInfos.add(new WindowInfo(handle.getWindowToken(), handle.name,
                    handle.displayId, bounds, handle.inputConfig, handle.transform));
        }
        return windowInfos;

        return new Pair(outWindowInfos, outDisplayInfos);
    }
}
+12 −9
Original line number Diff line number Diff line
@@ -33,6 +33,8 @@ import android.view.MotionEvent;
import android.view.ViewGroup;
import android.widget.Button;
import android.window.WindowInfosListenerForTest;
import android.window.WindowInfosListenerForTest.DisplayInfo;
import android.window.WindowInfosListenerForTest.WindowInfo;

import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -50,7 +52,7 @@ import org.junit.runner.RunWith;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.BiConsumer;

/**
 * Internal variant of {@link android.server.wm.window.ActivityRecordInputSinkTests}.
@@ -154,9 +156,10 @@ public class ActivityRecordInputSinkTests {
    private void waitForOverlayApp() throws InterruptedException {
        final var listenerHost = new WindowInfosListenerForTest();
        final var latch = new CountDownLatch(1);
        final Consumer<List<WindowInfosListenerForTest.WindowInfo>> listener = windowInfos -> {
            final boolean inputSinkReady = windowInfos.stream().anyMatch(info ->
                    info.isVisible
        final BiConsumer<List<WindowInfo>, List<DisplayInfo>> listener =
            (windowInfos, displayInfos) -> {
                final boolean inputSinkReady = windowInfos.stream().anyMatch(
                    info -> info.isVisible
                        && info.name.contains("ActivityRecordInputSink " + OVERLAY_ACTIVITY));
                if (inputSinkReady) {
                    latch.countDown();