From 9ae9ed24aa252acbc2e6288068b991dd5291967b Mon Sep 17 00:00:00 2001 From: Svetoslav Date: Tue, 2 Sep 2014 16:36:35 -0700 Subject: [PATCH] Fix AccessibilityNode's isVisibleToUser behavior. The isVisibleToUser property of an AccessibilityNodeInfo specifies whether the user can see the source view. It is used by accessibility services to figure out whether to focus on a view. This property was giving a wrong value if the view is covered by another window such as the keyboard. As a result the user hears one thing but when double taps interacts with the overlaid window which is another thing. bug:15938254 Change-Id: Ib9feb20ea422a24a512c47ed1234961ae0386a7f --- .../AccessibilityInteractionController.java | 58 +++++++++++-- core/java/android/view/ViewRootImpl.java | 38 +++++---- .../IAccessibilityInteractionConnection.aidl | 23 ++--- .../AccessibilityManagerService.java | 84 ++++++++++++++++--- 4 files changed, 158 insertions(+), 45 deletions(-) diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java index 477c9941825c8..a10dda3a55209 100644 --- a/core/java/android/view/AccessibilityInteractionController.java +++ b/core/java/android/view/AccessibilityInteractionController.java @@ -18,6 +18,7 @@ package android.view; import android.graphics.Point; import android.graphics.Rect; +import android.graphics.Region; import android.os.Build; import android.os.Bundle; import android.os.Handler; @@ -96,7 +97,7 @@ final class AccessibilityInteractionController { } public void findAccessibilityNodeInfoByAccessibilityIdClientThread( - long accessibilityNodeId, int interactionId, + long accessibilityNodeId, Region interactiveRegion, int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid, long interrogatingTid, MagnificationSpec spec) { Message message = mHandler.obtainMessage(); @@ -109,6 +110,7 @@ final class AccessibilityInteractionController { args.argi3 = interactionId; args.arg1 = callback; args.arg2 = spec; + args.arg3 = interactiveRegion; message.obj = args; // If the interrogation is performed by the same thread as the main UI @@ -133,6 +135,7 @@ final class AccessibilityInteractionController { final IAccessibilityInteractionConnectionCallback callback = (IAccessibilityInteractionConnectionCallback) args.arg1; final MagnificationSpec spec = (MagnificationSpec) args.arg2; + final Region interactiveRegion = (Region) args.arg3; args.recycle(); @@ -159,6 +162,7 @@ final class AccessibilityInteractionController { if (spec != null) { spec.recycle(); } + adjustIsVisibleToUserIfNeeded(infos, interactiveRegion); callback.setFindAccessibilityNodeInfosResult(infos, interactionId); infos.clear(); } catch (RemoteException re) { @@ -168,8 +172,9 @@ final class AccessibilityInteractionController { } public void findAccessibilityNodeInfosByViewIdClientThread(long accessibilityNodeId, - String viewId, int interactionId, IAccessibilityInteractionConnectionCallback callback, - int flags, int interrogatingPid, long interrogatingTid, MagnificationSpec spec) { + String viewId, Region interactiveRegion, int interactionId, + IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid, + long interrogatingTid, MagnificationSpec spec) { Message message = mHandler.obtainMessage(); message.what = PrivateHandler.MSG_FIND_ACCESSIBLITY_NODE_INFOS_BY_VIEW_ID; message.arg1 = flags; @@ -180,6 +185,7 @@ final class AccessibilityInteractionController { args.arg1 = callback; args.arg2 = spec; args.arg3 = viewId; + args.arg4 = interactiveRegion; message.obj = args; @@ -205,6 +211,7 @@ final class AccessibilityInteractionController { (IAccessibilityInteractionConnectionCallback) args.arg1; final MagnificationSpec spec = (MagnificationSpec) args.arg2; final String viewId = (String) args.arg3; + final Region interactiveRegion = (Region) args.arg4; args.recycle(); @@ -241,6 +248,7 @@ final class AccessibilityInteractionController { if (spec != null) { spec.recycle(); } + adjustIsVisibleToUserIfNeeded(infos, interactiveRegion); callback.setFindAccessibilityNodeInfosResult(infos, interactionId); } catch (RemoteException re) { /* ignore - the other side will time out */ @@ -249,8 +257,9 @@ final class AccessibilityInteractionController { } public void findAccessibilityNodeInfosByTextClientThread(long accessibilityNodeId, - String text, int interactionId, IAccessibilityInteractionConnectionCallback callback, - int flags, int interrogatingPid, long interrogatingTid, MagnificationSpec spec) { + String text, Region interactiveRegion, int interactionId, + IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid, + long interrogatingTid, MagnificationSpec spec) { Message message = mHandler.obtainMessage(); message.what = PrivateHandler.MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT; message.arg1 = flags; @@ -262,6 +271,7 @@ final class AccessibilityInteractionController { args.argi1 = AccessibilityNodeInfo.getAccessibilityViewId(accessibilityNodeId); args.argi2 = AccessibilityNodeInfo.getVirtualDescendantId(accessibilityNodeId); args.argi3 = interactionId; + args.arg4 = interactiveRegion; message.obj = args; // If the interrogation is performed by the same thread as the main UI @@ -287,6 +297,7 @@ final class AccessibilityInteractionController { final int accessibilityViewId = args.argi1; final int virtualDescendantId = args.argi2; final int interactionId = args.argi3; + final Region interactiveRegion = (Region) args.arg4; args.recycle(); List infos = null; @@ -347,6 +358,7 @@ final class AccessibilityInteractionController { if (spec != null) { spec.recycle(); } + adjustIsVisibleToUserIfNeeded(infos, interactiveRegion); callback.setFindAccessibilityNodeInfosResult(infos, interactionId); } catch (RemoteException re) { /* ignore - the other side will time out */ @@ -354,7 +366,8 @@ final class AccessibilityInteractionController { } } - public void findFocusClientThread(long accessibilityNodeId, int focusType, int interactionId, + public void findFocusClientThread(long accessibilityNodeId, int focusType, + Region interactiveRegion, int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags, int interogatingPid, long interrogatingTid, MagnificationSpec spec) { Message message = mHandler.obtainMessage(); @@ -368,6 +381,7 @@ final class AccessibilityInteractionController { args.argi3 = AccessibilityNodeInfo.getVirtualDescendantId(accessibilityNodeId); args.arg1 = callback; args.arg2 = spec; + args.arg3 = interactiveRegion; message.obj = args; @@ -394,6 +408,7 @@ final class AccessibilityInteractionController { final IAccessibilityInteractionConnectionCallback callback = (IAccessibilityInteractionConnectionCallback) args.arg1; final MagnificationSpec spec = (MagnificationSpec) args.arg2; + final Region interactiveRegion = (Region) args.arg3; args.recycle(); AccessibilityNodeInfo focused = null; @@ -457,6 +472,7 @@ final class AccessibilityInteractionController { if (spec != null) { spec.recycle(); } + adjustIsVisibleToUserIfNeeded(focused, interactiveRegion); callback.setFindAccessibilityNodeInfoResult(focused, interactionId); } catch (RemoteException re) { /* ignore - the other side will time out */ @@ -464,7 +480,8 @@ final class AccessibilityInteractionController { } } - public void focusSearchClientThread(long accessibilityNodeId, int direction, int interactionId, + public void focusSearchClientThread(long accessibilityNodeId, int direction, + Region interactiveRegion, int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags, int interogatingPid, long interrogatingTid, MagnificationSpec spec) { Message message = mHandler.obtainMessage(); @@ -477,6 +494,7 @@ final class AccessibilityInteractionController { args.argi3 = interactionId; args.arg1 = callback; args.arg2 = spec; + args.arg3 = interactiveRegion; message.obj = args; @@ -502,6 +520,7 @@ final class AccessibilityInteractionController { final IAccessibilityInteractionConnectionCallback callback = (IAccessibilityInteractionConnectionCallback) args.arg1; final MagnificationSpec spec = (MagnificationSpec) args.arg2; + final Region interactiveRegion = (Region) args.arg3; args.recycle(); @@ -530,6 +549,7 @@ final class AccessibilityInteractionController { if (spec != null) { spec.recycle(); } + adjustIsVisibleToUserIfNeeded(next, interactiveRegion); callback.setFindAccessibilityNodeInfoResult(next, interactionId); } catch (RemoteException re) { /* ignore - the other side will time out */ @@ -644,6 +664,30 @@ final class AccessibilityInteractionController { } } + private void adjustIsVisibleToUserIfNeeded(List infos, + Region interactiveRegion) { + if (interactiveRegion == null || infos == null) { + return; + } + final int infoCount = infos.size(); + for (int i = 0; i < infoCount; i++) { + AccessibilityNodeInfo info = infos.get(i); + adjustIsVisibleToUserIfNeeded(info, interactiveRegion); + } + } + + private void adjustIsVisibleToUserIfNeeded(AccessibilityNodeInfo info, + Region interactiveRegion) { + if (interactiveRegion == null || info == null) { + return; + } + Rect boundsInScreen = mTempRect; + info.getBoundsInScreen(boundsInScreen); + if (interactiveRegion.quickReject(boundsInScreen)) { + info.setVisibleToUser(false); + } + } + private void applyAppScaleAndMagnificationSpecIfNeeded(AccessibilityNodeInfo info, MagnificationSpec spec) { if (info == null) { diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 49d925feeca1a..dd1cbc936b171 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -6629,14 +6629,15 @@ public final class ViewRootImpl implements ViewParent, @Override public void findAccessibilityNodeInfoByAccessibilityId(long accessibilityNodeId, - int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags, + Region interactiveRegion, int interactionId, + IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid, long interrogatingTid, MagnificationSpec spec) { ViewRootImpl viewRootImpl = mViewRootImpl.get(); if (viewRootImpl != null && viewRootImpl.mView != null) { viewRootImpl.getAccessibilityInteractionController() .findAccessibilityNodeInfoByAccessibilityIdClientThread(accessibilityNodeId, - interactionId, callback, flags, interrogatingPid, interrogatingTid, - spec); + interactiveRegion, interactionId, callback, flags, interrogatingPid, + interrogatingTid, spec); } else { // We cannot make the call and notify the caller so it does not wait. try { @@ -6669,15 +6670,15 @@ public final class ViewRootImpl implements ViewParent, @Override public void findAccessibilityNodeInfosByViewId(long accessibilityNodeId, - String viewId, int interactionId, + String viewId, Region interactiveRegion, int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid, long interrogatingTid, MagnificationSpec spec) { ViewRootImpl viewRootImpl = mViewRootImpl.get(); if (viewRootImpl != null && viewRootImpl.mView != null) { viewRootImpl.getAccessibilityInteractionController() .findAccessibilityNodeInfosByViewIdClientThread(accessibilityNodeId, - viewId, interactionId, callback, flags, interrogatingPid, - interrogatingTid, spec); + viewId, interactiveRegion, interactionId, callback, flags, + interrogatingPid, interrogatingTid, spec); } else { // We cannot make the call and notify the caller so it does not wait. try { @@ -6690,14 +6691,15 @@ public final class ViewRootImpl implements ViewParent, @Override public void findAccessibilityNodeInfosByText(long accessibilityNodeId, String text, - int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags, + Region interactiveRegion, int interactionId, + IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid, long interrogatingTid, MagnificationSpec spec) { ViewRootImpl viewRootImpl = mViewRootImpl.get(); if (viewRootImpl != null && viewRootImpl.mView != null) { viewRootImpl.getAccessibilityInteractionController() .findAccessibilityNodeInfosByTextClientThread(accessibilityNodeId, text, - interactionId, callback, flags, interrogatingPid, interrogatingTid, - spec); + interactiveRegion, interactionId, callback, flags, interrogatingPid, + interrogatingTid, spec); } else { // We cannot make the call and notify the caller so it does not wait. try { @@ -6709,14 +6711,15 @@ public final class ViewRootImpl implements ViewParent, } @Override - public void findFocus(long accessibilityNodeId, int focusType, int interactionId, - IAccessibilityInteractionConnectionCallback callback, int flags, + public void findFocus(long accessibilityNodeId, int focusType, Region interactiveRegion, + int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid, long interrogatingTid, MagnificationSpec spec) { ViewRootImpl viewRootImpl = mViewRootImpl.get(); if (viewRootImpl != null && viewRootImpl.mView != null) { viewRootImpl.getAccessibilityInteractionController() - .findFocusClientThread(accessibilityNodeId, focusType, interactionId, callback, - flags, interrogatingPid, interrogatingTid, spec); + .findFocusClientThread(accessibilityNodeId, focusType, interactiveRegion, + interactionId, callback, flags, interrogatingPid, interrogatingTid, + spec); } else { // We cannot make the call and notify the caller so it does not wait. try { @@ -6728,14 +6731,15 @@ public final class ViewRootImpl implements ViewParent, } @Override - public void focusSearch(long accessibilityNodeId, int direction, int interactionId, - IAccessibilityInteractionConnectionCallback callback, int flags, + public void focusSearch(long accessibilityNodeId, int direction, Region interactiveRegion, + int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid, long interrogatingTid, MagnificationSpec spec) { ViewRootImpl viewRootImpl = mViewRootImpl.get(); if (viewRootImpl != null && viewRootImpl.mView != null) { viewRootImpl.getAccessibilityInteractionController() - .focusSearchClientThread(accessibilityNodeId, direction, interactionId, - callback, flags, interrogatingPid, interrogatingTid, spec); + .focusSearchClientThread(accessibilityNodeId, direction, interactiveRegion, + interactionId, callback, flags, interrogatingPid, interrogatingTid, + spec); } else { // We cannot make the call and notify the caller so it does not wait. try { diff --git a/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl b/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl index 8d15472f09990..faf7789dca730 100644 --- a/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl +++ b/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl @@ -16,6 +16,7 @@ package android.view.accessibility; +import android.graphics.Region; import android.os.Bundle; import android.view.MagnificationSpec; import android.view.accessibility.AccessibilityNodeInfo; @@ -29,23 +30,23 @@ import android.view.accessibility.IAccessibilityInteractionConnectionCallback; */ oneway interface IAccessibilityInteractionConnection { - void findAccessibilityNodeInfoByAccessibilityId(long accessibilityNodeId, int interactionId, - IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid, - long interrogatingTid, in MagnificationSpec spec); - - void findAccessibilityNodeInfosByViewId(long accessibilityNodeId, String viewId, + void findAccessibilityNodeInfoByAccessibilityId(long accessibilityNodeId, in Region bounds, int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid, long interrogatingTid, in MagnificationSpec spec); - void findAccessibilityNodeInfosByText(long accessibilityNodeId, String text, int interactionId, + void findAccessibilityNodeInfosByViewId(long accessibilityNodeId, String viewId, + in Region bounds, int interactionId, IAccessibilityInteractionConnectionCallback callback, + int flags, int interrogatingPid, long interrogatingTid, in MagnificationSpec spec); + + void findAccessibilityNodeInfosByText(long accessibilityNodeId, String text, in Region bounds, + int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags, + int interrogatingPid, long interrogatingTid, in MagnificationSpec spec); + + void findFocus(long accessibilityNodeId, int focusType, in Region bounds, int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid, long interrogatingTid, in MagnificationSpec spec); - void findFocus(long accessibilityNodeId, int focusType, int interactionId, - IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid, - long interrogatingTid, in MagnificationSpec spec); - - void focusSearch(long accessibilityNodeId, int direction, int interactionId, + void focusSearch(long accessibilityNodeId, int direction, in Region bounds, int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid, long interrogatingTid, in MagnificationSpec spec); diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index 4e2f52c5e5b7d..5d13fed9630cc 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -42,6 +42,7 @@ import android.content.pm.UserInfo; import android.database.ContentObserver; import android.graphics.Point; import android.graphics.Rect; +import android.graphics.Region; import android.hardware.display.DisplayManager; import android.hardware.input.InputManager; import android.net.Uri; @@ -162,6 +163,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { private final List mEnabledServicesForFeedbackTempList = new ArrayList<>(); + private final Region mTempRegion = new Region(); + private final Rect mTempRect = new Rect(); private final Point mTempPoint = new Point(); @@ -2161,6 +2164,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { throws RemoteException { final int resolvedWindowId; IAccessibilityInteractionConnection connection = null; + Region partialInteractiveRegion = mTempRegion; synchronized (mLock) { // We treat calls from a profile as if made by its parent as profiles // share the accessibility state of the parent. The call below @@ -2182,13 +2186,17 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { return false; } } + if (!mSecurityPolicy.computePartialInteractiveRegionForWindowLocked( + resolvedWindowId, partialInteractiveRegion)) { + partialInteractiveRegion = null; + } } final int interrogatingPid = Binder.getCallingPid(); final long identityToken = Binder.clearCallingIdentity(); MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId); try { - connection.findAccessibilityNodeInfosByViewId(accessibilityNodeId, - viewIdResName, interactionId, callback, mFetchFlags, interrogatingPid, + connection.findAccessibilityNodeInfosByViewId(accessibilityNodeId, viewIdResName, + partialInteractiveRegion, interactionId, callback, mFetchFlags, interrogatingPid, interrogatingTid, spec); return true; } catch (RemoteException re) { @@ -2208,6 +2216,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { throws RemoteException { final int resolvedWindowId; IAccessibilityInteractionConnection connection = null; + Region partialInteractiveRegion = mTempRegion; synchronized (mLock) { // We treat calls from a profile as if made by its parent as profiles // share the accessibility state of the parent. The call below @@ -2229,14 +2238,18 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { return false; } } + if (!mSecurityPolicy.computePartialInteractiveRegionForWindowLocked( + resolvedWindowId, partialInteractiveRegion)) { + partialInteractiveRegion = null; + } } final int interrogatingPid = Binder.getCallingPid(); final long identityToken = Binder.clearCallingIdentity(); MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId); try { connection.findAccessibilityNodeInfosByText(accessibilityNodeId, text, - interactionId, callback, mFetchFlags, interrogatingPid, interrogatingTid, - spec); + partialInteractiveRegion, interactionId, callback, mFetchFlags, interrogatingPid, + interrogatingTid, spec); return true; } catch (RemoteException re) { if (DEBUG) { @@ -2255,6 +2268,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { long interrogatingTid) throws RemoteException { final int resolvedWindowId; IAccessibilityInteractionConnection connection = null; + Region partialInteractiveRegion = mTempRegion; synchronized (mLock) { // We treat calls from a profile as if made by its parent as profiles // share the accessibility state of the parent. The call below @@ -2276,14 +2290,18 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { return false; } } + if (!mSecurityPolicy.computePartialInteractiveRegionForWindowLocked( + resolvedWindowId, partialInteractiveRegion)) { + partialInteractiveRegion = null; + } } final int interrogatingPid = Binder.getCallingPid(); final long identityToken = Binder.clearCallingIdentity(); MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId); try { connection.findAccessibilityNodeInfoByAccessibilityId(accessibilityNodeId, - interactionId, callback, mFetchFlags | flags, interrogatingPid, - interrogatingTid, spec); + partialInteractiveRegion, interactionId, callback, mFetchFlags | flags, + interrogatingPid, interrogatingTid, spec); return true; } catch (RemoteException re) { if (DEBUG) { @@ -2302,6 +2320,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { throws RemoteException { final int resolvedWindowId; IAccessibilityInteractionConnection connection = null; + Region partialInteractiveRegion = mTempRegion; synchronized (mLock) { // We treat calls from a profile as if made by its parent as profiles // share the accessibility state of the parent. The call below @@ -2324,13 +2343,17 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { return false; } } + if (!mSecurityPolicy.computePartialInteractiveRegionForWindowLocked( + resolvedWindowId, partialInteractiveRegion)) { + partialInteractiveRegion = null; + } } final int interrogatingPid = Binder.getCallingPid(); final long identityToken = Binder.clearCallingIdentity(); MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId); try { - connection.findFocus(accessibilityNodeId, focusType, interactionId, callback, - mFetchFlags, interrogatingPid, interrogatingTid, spec); + connection.findFocus(accessibilityNodeId, focusType, partialInteractiveRegion, interactionId, + callback, mFetchFlags, interrogatingPid, interrogatingTid, spec); return true; } catch (RemoteException re) { if (DEBUG) { @@ -2349,6 +2372,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { throws RemoteException { final int resolvedWindowId; IAccessibilityInteractionConnection connection = null; + Region partialInteractiveRegion = mTempRegion; synchronized (mLock) { // We treat calls from a profile as if made by its parent as profiles // share the accessibility state of the parent. The call below @@ -2370,13 +2394,17 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { return false; } } + if (!mSecurityPolicy.computePartialInteractiveRegionForWindowLocked( + resolvedWindowId, partialInteractiveRegion)) { + partialInteractiveRegion = null; + } } final int interrogatingPid = Binder.getCallingPid(); final long identityToken = Binder.clearCallingIdentity(); MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId); try { - connection.focusSearch(accessibilityNodeId, direction, interactionId, callback, - mFetchFlags, interrogatingPid, interrogatingTid, spec); + connection.focusSearch(accessibilityNodeId, direction, partialInteractiveRegion, interactionId, + callback, mFetchFlags, interrogatingPid, interrogatingTid, spec); return true; } catch (RemoteException re) { if (DEBUG) { @@ -3288,6 +3316,42 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } } + public boolean computePartialInteractiveRegionForWindowLocked(int windowId, + Region outRegion) { + if (mWindows == null) { + return false; + } + + // Windows are ordered in z order so start from the botton and find + // the window of interest. After that all windows that cover it should + // be subtracted from the resulting region. Note that for accessibility + // we are returning only interactive windows. + Region windowInteractiveRegion = null; + boolean windowInteractiveRegionChanged = false; + + final int windowCount = mWindows.size(); + for (int i = windowCount - 1; i >= 0; i--) { + AccessibilityWindowInfo currentWindow = mWindows.get(i); + if (windowInteractiveRegion == null) { + if (currentWindow.getId() == windowId) { + Rect currentWindowBounds = mTempRect; + currentWindow.getBoundsInScreen(currentWindowBounds); + outRegion.set(currentWindowBounds); + windowInteractiveRegion = outRegion; + continue; + } + } else { + Rect currentWindowBounds = mTempRect; + currentWindow.getBoundsInScreen(currentWindowBounds); + if (windowInteractiveRegion.op(currentWindowBounds, Region.Op.DIFFERENCE)) { + windowInteractiveRegionChanged = true; + } + } + } + + return windowInteractiveRegionChanged; + } + public void updateEventSourceLocked(AccessibilityEvent event) { if ((event.getEventType() & RETRIEVAL_ALLOWING_EVENT_TYPES) == 0) { event.setSource(null);