diff options
author | Svetoslav <svetoslavganov@google.com> | 2014-09-02 16:36:35 -0700 |
---|---|---|
committer | Svetoslav <svetoslavganov@google.com> | 2014-09-02 16:46:23 -0700 |
commit | 9ae9ed24aa252acbc2e6288068b991dd5291967b (patch) | |
tree | 11278c245609dfca5a3912853366bfa3e263a894 /services/accessibility | |
parent | 1611c21dfdf102fa4eadd3cab4c7bd5fda061826 (diff) | |
download | frameworks_base-9ae9ed24aa252acbc2e6288068b991dd5291967b.zip frameworks_base-9ae9ed24aa252acbc2e6288068b991dd5291967b.tar.gz frameworks_base-9ae9ed24aa252acbc2e6288068b991dd5291967b.tar.bz2 |
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
Diffstat (limited to 'services/accessibility')
-rw-r--r-- | services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java | 84 |
1 files changed, 74 insertions, 10 deletions
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index 4e2f52c..5d13fed 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<AccessibilityServiceInfo> 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); |