Add transition timestamp to AccessibilityWindowInfo

We use a timestamp to know when is the last transition
of the window. With the value, devlopers could define
the meaning of a stable window.

Bug: 215487047
Test: atest AccessibilityWindowQueryTest AccessibilityWindowInfoTest
      manual test
Change-Id: I3ea1c6f4ff135e9ded0a016a6b8a61eb1f754ed7
This commit is contained in:
ryanlwlin
2022-01-20 12:17:22 +08:00
parent 2e96df286e
commit 630a657d98
3 changed files with 48 additions and 2 deletions

View File

@@ -52211,6 +52211,7 @@ package android.view.accessibility {
method public android.view.accessibility.AccessibilityNodeInfo getRoot();
method @Nullable public android.view.accessibility.AccessibilityNodeInfo getRoot(int);
method @Nullable public CharSequence getTitle();
method public long getTransitionTimeMillis();
method public int getType();
method public boolean isAccessibilityFocused();
method public boolean isActive();

View File

@@ -19,11 +19,13 @@ package android.view.accessibility;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
import android.annotation.UptimeMillisLong;
import android.app.ActivityTaskManager;
import android.graphics.Rect;
import android.graphics.Region;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.LongArray;
import android.util.Pools.SynchronizedPool;
@@ -126,6 +128,7 @@ public final class AccessibilityWindowInfo implements Parcelable {
private LongArray mChildIds;
private CharSequence mTitle;
private long mAnchorId = AccessibilityNodeInfo.UNDEFINED_NODE_ID;
private long mTransitionTime;
private int mConnectionId = UNDEFINED_CONNECTION_ID;
@@ -526,6 +529,31 @@ public final class AccessibilityWindowInfo implements Parcelable {
return mDisplayId;
}
/**
* Sets the timestamp of the transition.
*
* @param transitionTime The timestamp from {@link SystemClock#uptimeMillis()} at which the
* transition happens.
*
* @hide
*/
@UptimeMillisLong
public void setTransitionTimeMillis(long transitionTime) {
mTransitionTime = transitionTime;
}
/**
* Return the {@link SystemClock#uptimeMillis()} at which the last transition happens.
* A transition happens when {@link #getBoundsInScreen(Rect)} is changed.
*
* @return The transition timestamp.
*/
@UptimeMillisLong
public long getTransitionTimeMillis() {
return mTransitionTime;
}
/**
* Returns a cached instance if such is available or a new one is
* created.
@@ -634,6 +662,7 @@ public final class AccessibilityWindowInfo implements Parcelable {
mRegionInScreen.writeToParcel(parcel, flags);
parcel.writeCharSequence(mTitle);
parcel.writeLong(mAnchorId);
parcel.writeLong(mTransitionTime);
final LongArray childIds = mChildIds;
if (childIds == null) {
@@ -665,6 +694,7 @@ public final class AccessibilityWindowInfo implements Parcelable {
mRegionInScreen.set(other.mRegionInScreen);
mTitle = other.mTitle;
mAnchorId = other.mAnchorId;
mTransitionTime = other.mTransitionTime;
if (mChildIds != null) mChildIds.clear();
if (other.mChildIds != null && other.mChildIds.size() > 0) {
@@ -689,6 +719,7 @@ public final class AccessibilityWindowInfo implements Parcelable {
mRegionInScreen = Region.CREATOR.createFromParcel(parcel);
mTitle = parcel.readCharSequence();
mAnchorId = parcel.readLong();
mTransitionTime = parcel.readLong();
final int childCount = parcel.readInt();
if (childCount > 0) {
@@ -739,6 +770,7 @@ public final class AccessibilityWindowInfo implements Parcelable {
builder.append(", focused=").append(isFocused());
builder.append(", active=").append(isActive());
builder.append(", pictureInPicture=").append(isInPictureInPictureMode());
builder.append(", transitionTime=").append(mTransitionTime);
if (DEBUG) {
builder.append(", parent=").append(mParentId);
builder.append(", children=[");

View File

@@ -31,6 +31,7 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.ArrayMap;
@@ -564,7 +565,7 @@ public class AccessibilityWindowManager {
final WindowInfo windowInfo = windows.get(i);
final AccessibilityWindowInfo window;
if (mTrackingWindows) {
window = populateReportedWindowLocked(userId, windowInfo);
window = populateReportedWindowLocked(userId, windowInfo, oldWindowsById);
if (window == null) {
hasWindowIgnore = true;
}
@@ -677,7 +678,7 @@ public class AccessibilityWindowManager {
}
private AccessibilityWindowInfo populateReportedWindowLocked(int userId,
WindowInfo window) {
WindowInfo window, SparseArray<AccessibilityWindowInfo> oldWindowsById) {
final int windowId = findWindowIdLocked(userId, window.token);
if (windowId < 0) {
return null;
@@ -716,6 +717,18 @@ public class AccessibilityWindowManager {
}
}
final AccessibilityWindowInfo oldWindowInfo = oldWindowsById.get(windowId);
if (oldWindowInfo == null) {
reportedWindow.setTransitionTimeMillis(SystemClock.uptimeMillis());
} else {
final Region oldTouchRegion = new Region();
oldWindowInfo.getRegionInScreen(oldTouchRegion);
if (oldTouchRegion.equals(window.regionInScreen)) {
reportedWindow.setTransitionTimeMillis(oldWindowInfo.getTransitionTimeMillis());
} else {
reportedWindow.setTransitionTimeMillis(SystemClock.uptimeMillis());
}
}
return reportedWindow;
}