Merge "Add WindowInfosListenerForTest" into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
a3decbe174
@@ -3939,6 +3939,18 @@ package android.window {
|
||||
method public abstract void onTransactionReady(int, @NonNull android.view.SurfaceControl.Transaction);
|
||||
}
|
||||
|
||||
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>>);
|
||||
}
|
||||
|
||||
public static class WindowInfosListenerForTest.WindowInfo {
|
||||
field @NonNull public final android.graphics.Rect bounds;
|
||||
field @NonNull public final String name;
|
||||
field @NonNull public final android.os.IBinder windowToken;
|
||||
}
|
||||
|
||||
public class WindowOrganizer {
|
||||
ctor public WindowOrganizer();
|
||||
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public int applySyncTransaction(@NonNull android.window.WindowContainerTransaction, @NonNull android.window.WindowContainerTransactionCallback);
|
||||
|
||||
@@ -244,6 +244,10 @@ public final class InputWindowHandle {
|
||||
window = iwindow;
|
||||
}
|
||||
|
||||
public @Nullable IBinder getWindowToken() {
|
||||
return windowToken;
|
||||
}
|
||||
|
||||
public IWindow getWindow() {
|
||||
if (window != null) {
|
||||
return window;
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package android.window;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.graphics.Matrix;
|
||||
import android.util.Pair;
|
||||
import android.util.Size;
|
||||
@@ -49,10 +51,13 @@ public abstract class WindowInfosListener {
|
||||
/**
|
||||
* Register the WindowInfosListener.
|
||||
*
|
||||
* Registering WindowInfosListeners should only be done within system_server and shell.
|
||||
*
|
||||
* @return The cached values for InputWindowHandles and DisplayInfos. This is the last updated
|
||||
* value that was sent from SurfaceFlinger to this particular process. If there was nothing
|
||||
* registered previously, then the data can be empty.
|
||||
*/
|
||||
@RequiresPermission(Manifest.permission.ACCESS_SURFACE_FLINGER)
|
||||
public Pair<InputWindowHandle[], DisplayInfo[]> register() {
|
||||
return nativeRegister(mNativeListener);
|
||||
}
|
||||
@@ -65,8 +70,12 @@ public abstract class WindowInfosListener {
|
||||
}
|
||||
|
||||
private static native long nativeCreate(WindowInfosListener thiz);
|
||||
|
||||
@RequiresPermission(Manifest.permission.ACCESS_SURFACE_FLINGER)
|
||||
private static native Pair<InputWindowHandle[], DisplayInfo[]> nativeRegister(long ptr);
|
||||
|
||||
private static native void nativeUnregister(long ptr);
|
||||
|
||||
private static native long nativeGetFinalizer();
|
||||
|
||||
/**
|
||||
|
||||
136
core/java/android/window/WindowInfosListenerForTest.java
Normal file
136
core/java/android/window/WindowInfosListenerForTest.java
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.window;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.annotation.TestApi;
|
||||
import android.graphics.Rect;
|
||||
import android.os.IBinder;
|
||||
import android.os.InputConfig;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.view.InputWindowHandle;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Wrapper class to provide access to WindowInfosListener within tests.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
public class WindowInfosListenerForTest {
|
||||
|
||||
/**
|
||||
* Window properties passed to {@code @WindowInfosListenerForTest#onWindowInfosChanged}.
|
||||
*/
|
||||
public static class WindowInfo {
|
||||
/**
|
||||
* The window's token.
|
||||
*/
|
||||
@NonNull
|
||||
public final IBinder windowToken;
|
||||
|
||||
/**
|
||||
* The window's name.
|
||||
*/
|
||||
@NonNull
|
||||
public final String name;
|
||||
|
||||
/**
|
||||
* The window's position and size in display space.
|
||||
*/
|
||||
@NonNull
|
||||
public final Rect bounds;
|
||||
|
||||
WindowInfo(@NonNull IBinder windowToken, @NonNull String name, @NonNull Rect bounds) {
|
||||
this.windowToken = windowToken;
|
||||
this.name = name;
|
||||
this.bounds = bounds;
|
||||
}
|
||||
}
|
||||
|
||||
private static final String TAG = "WindowInfosListenerForTest";
|
||||
|
||||
private ArrayMap<Consumer<List<WindowInfo>>, WindowInfosListener> mListeners;
|
||||
|
||||
public WindowInfosListenerForTest() {
|
||||
mListeners = new ArrayMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a listener that is called when the system's list of visible windows has changes in
|
||||
* position or visibility.
|
||||
*
|
||||
* @param consumer Consumer that is called with reverse Z ordered lists of WindowInfo instances
|
||||
* where the first value is the topmost window.
|
||||
*/
|
||||
@RequiresPermission(Manifest.permission.ACCESS_SURFACE_FLINGER)
|
||||
public void addWindowInfosListener(
|
||||
@NonNull Consumer<List<WindowInfo>> consumer) {
|
||||
var calledWithInitialState = new CountDownLatch(1);
|
||||
var listener = new WindowInfosListener() {
|
||||
@Override
|
||||
public void onWindowInfosChanged(InputWindowHandle[] windowHandles,
|
||||
DisplayInfo[] displayInfos) {
|
||||
try {
|
||||
calledWithInitialState.await();
|
||||
} catch (InterruptedException exception) {
|
||||
Log.e(TAG,
|
||||
"Exception thrown while waiting for listener to be called with "
|
||||
+ "initial state");
|
||||
}
|
||||
consumer.accept(buildWindowInfos(windowHandles));
|
||||
}
|
||||
};
|
||||
mListeners.put(consumer, listener);
|
||||
Pair<InputWindowHandle[], WindowInfosListener.DisplayInfo[]> initialState =
|
||||
listener.register();
|
||||
consumer.accept(buildWindowInfos(initialState.first));
|
||||
calledWithInitialState.countDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters the listener.
|
||||
*/
|
||||
public void removeWindowInfosListener(@NonNull Consumer<List<WindowInfo>> consumer) {
|
||||
WindowInfosListener listener = mListeners.remove(consumer);
|
||||
if (listener == null) {
|
||||
return;
|
||||
}
|
||||
listener.unregister();
|
||||
}
|
||||
|
||||
private static List<WindowInfo> buildWindowInfos(InputWindowHandle[] windowHandles) {
|
||||
var windowInfos = new ArrayList<WindowInfo>(windowHandles.length);
|
||||
for (var handle : windowHandles) {
|
||||
if ((handle.inputConfig & InputConfig.NOT_VISIBLE) != 0) {
|
||||
continue;
|
||||
}
|
||||
var bounds = new Rect(handle.frameLeft, handle.frameTop, handle.frameRight,
|
||||
handle.frameBottom);
|
||||
windowInfos.add(new WindowInfo(handle.getWindowToken(), handle.name, bounds));
|
||||
}
|
||||
return windowInfos;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user