diff --git a/core/api/current.txt b/core/api/current.txt index ba92ba03f69cc..3f985d0804353 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -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(); diff --git a/core/java/android/view/accessibility/AccessibilityWindowInfo.java b/core/java/android/view/accessibility/AccessibilityWindowInfo.java index f155badc218f2..9be999053fa69 100644 --- a/core/java/android/view/accessibility/AccessibilityWindowInfo.java +++ b/core/java/android/view/accessibility/AccessibilityWindowInfo.java @@ -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=["); diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java index 87bfef78bb00e..e7ade3dbe4a43 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java @@ -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 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; }