diff options
Diffstat (limited to 'core/java/android/view/AccessibilityInteractionController.java')
-rw-r--r-- | core/java/android/view/AccessibilityInteractionController.java | 146 |
1 files changed, 130 insertions, 16 deletions
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java index a10dda3..a283b91 100644 --- a/core/java/android/view/AccessibilityInteractionController.java +++ b/core/java/android/view/AccessibilityInteractionController.java @@ -19,7 +19,6 @@ 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; import android.os.Looper; @@ -101,7 +100,7 @@ final class AccessibilityInteractionController { IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid, long interrogatingTid, MagnificationSpec spec) { Message message = mHandler.obtainMessage(); - message.what = PrivateHandler.MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID; + message.what = PrivateHandler.MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_ACCESSIBILITY_ID; message.arg1 = flags; SomeArgs args = SomeArgs.obtain(); @@ -176,7 +175,7 @@ final class AccessibilityInteractionController { 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.what = PrivateHandler.MSG_FIND_ACCESSIBILITY_NODE_INFOS_BY_VIEW_ID; message.arg1 = flags; message.arg2 = AccessibilityNodeInfo.getAccessibilityViewId(accessibilityNodeId); @@ -261,7 +260,7 @@ final class AccessibilityInteractionController { 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.what = PrivateHandler.MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_TEXT; message.arg1 = flags; SomeArgs args = SomeArgs.obtain(); @@ -637,6 +636,95 @@ final class AccessibilityInteractionController { } } + public void computeClickPointInScreenClientThread(long accessibilityNodeId, + Region interactiveRegion, int interactionId, + IAccessibilityInteractionConnectionCallback callback, int interrogatingPid, + long interrogatingTid, MagnificationSpec spec) { + Message message = mHandler.obtainMessage(); + message.what = PrivateHandler.MSG_COMPUTE_CLICK_POINT_IN_SCREEN; + + SomeArgs args = SomeArgs.obtain(); + args.argi1 = AccessibilityNodeInfo.getAccessibilityViewId(accessibilityNodeId); + args.argi2 = AccessibilityNodeInfo.getVirtualDescendantId(accessibilityNodeId); + 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 + // thread in this process, set the message as a static reference so + // after this call completes the same thread but in the interrogating + // client can handle the message to generate the result. + if (interrogatingPid == mMyProcessId && interrogatingTid == mMyLooperThreadId) { + AccessibilityInteractionClient.getInstanceForThread( + interrogatingTid).setSameThreadMessage(message); + } else { + mHandler.sendMessage(message); + } + } + + private void computeClickPointInScreenUiThread(Message message) { + SomeArgs args = (SomeArgs) message.obj; + final int accessibilityViewId = args.argi1; + final int virtualDescendantId = args.argi2; + final int interactionId = args.argi3; + final IAccessibilityInteractionConnectionCallback callback = + (IAccessibilityInteractionConnectionCallback) args.arg1; + final MagnificationSpec spec = (MagnificationSpec) args.arg2; + final Region interactiveRegion = (Region) args.arg3; + args.recycle(); + + boolean succeeded = false; + Point point = mTempPoint; + try { + if (mViewRootImpl.mView == null || mViewRootImpl.mAttachInfo == null) { + return; + } + View target = null; + if (accessibilityViewId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) { + target = findViewByAccessibilityId(accessibilityViewId); + } else { + target = mViewRootImpl.mView; + } + if (target != null && isShown(target)) { + AccessibilityNodeProvider provider = target.getAccessibilityNodeProvider(); + if (provider != null) { + // For virtual views just use the center of the bounds in screen. + AccessibilityNodeInfo node = null; + if (virtualDescendantId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) { + node = provider.createAccessibilityNodeInfo(virtualDescendantId); + } else { + node = provider.createAccessibilityNodeInfo( + AccessibilityNodeProvider.HOST_VIEW_ID); + } + if (node != null) { + succeeded = true; + Rect boundsInScreen = mTempRect; + node.getBoundsInScreen(boundsInScreen); + point.set(boundsInScreen.centerX(), boundsInScreen.centerY()); + } + } else if (virtualDescendantId == AccessibilityNodeInfo.UNDEFINED_ITEM_ID) { + // For a real view, ask the view to compute the click point. + succeeded = target.computeClickPointInScreenForAccessibility( + interactiveRegion, point); + } + } + } finally { + try { + Point result = null; + if (succeeded) { + applyAppScaleAndMagnificationSpecIfNeeded(point, spec); + result = point; + } + callback.setComputeClickPointInScreenActionResult(result, interactionId); + } catch (RemoteException re) { + /* ignore - the other side will time out */ + } + } + } + private View findViewByAccessibilityId(int accessibilityId) { View root = mViewRootImpl.mView; if (root == null) { @@ -688,6 +776,26 @@ final class AccessibilityInteractionController { } } + private void applyAppScaleAndMagnificationSpecIfNeeded(Point point, + MagnificationSpec spec) { + final float applicationScale = mViewRootImpl.mAttachInfo.mApplicationScale; + if (!shouldApplyAppScaleAndMagnificationSpec(applicationScale, spec)) { + return; + } + + if (applicationScale != 1.0f) { + point.x *= applicationScale; + point.y *= applicationScale; + } + + if (spec != null) { + point.x *= spec.scale; + point.y *= spec.scale; + point.x += (int) spec.offsetX; + point.y += (int) spec.offsetY; + } + } + private void applyAppScaleAndMagnificationSpecIfNeeded(AccessibilityNodeInfo info, MagnificationSpec spec) { if (info == null) { @@ -1080,11 +1188,12 @@ final class AccessibilityInteractionController { private class PrivateHandler extends Handler { private final static int MSG_PERFORM_ACCESSIBILITY_ACTION = 1; - private final static int MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID = 2; - private final static int MSG_FIND_ACCESSIBLITY_NODE_INFOS_BY_VIEW_ID = 3; - private final static int MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT = 4; + private final static int MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_ACCESSIBILITY_ID = 2; + private final static int MSG_FIND_ACCESSIBILITY_NODE_INFOS_BY_VIEW_ID = 3; + private final static int MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_TEXT = 4; private final static int MSG_FIND_FOCUS = 5; private final static int MSG_FOCUS_SEARCH = 6; + private final static int MSG_COMPUTE_CLICK_POINT_IN_SCREEN = 7; public PrivateHandler(Looper looper) { super(looper); @@ -1096,16 +1205,18 @@ final class AccessibilityInteractionController { switch (type) { case MSG_PERFORM_ACCESSIBILITY_ACTION: return "MSG_PERFORM_ACCESSIBILITY_ACTION"; - case MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID: - return "MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID"; - case MSG_FIND_ACCESSIBLITY_NODE_INFOS_BY_VIEW_ID: - return "MSG_FIND_ACCESSIBLITY_NODE_INFOS_BY_VIEW_ID"; - case MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT: - return "MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT"; + case MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_ACCESSIBILITY_ID: + return "MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_ACCESSIBILITY_ID"; + case MSG_FIND_ACCESSIBILITY_NODE_INFOS_BY_VIEW_ID: + return "MSG_FIND_ACCESSIBILITY_NODE_INFOS_BY_VIEW_ID"; + case MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_TEXT: + return "MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_TEXT"; case MSG_FIND_FOCUS: return "MSG_FIND_FOCUS"; case MSG_FOCUS_SEARCH: return "MSG_FOCUS_SEARCH"; + case MSG_COMPUTE_CLICK_POINT_IN_SCREEN: + return "MSG_COMPUTE_CLICK_POINT_IN_SCREEN"; default: throw new IllegalArgumentException("Unknown message type: " + type); } @@ -1115,16 +1226,16 @@ final class AccessibilityInteractionController { public void handleMessage(Message message) { final int type = message.what; switch (type) { - case MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID: { + case MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_ACCESSIBILITY_ID: { findAccessibilityNodeInfoByAccessibilityIdUiThread(message); } break; case MSG_PERFORM_ACCESSIBILITY_ACTION: { perfromAccessibilityActionUiThread(message); } break; - case MSG_FIND_ACCESSIBLITY_NODE_INFOS_BY_VIEW_ID: { + case MSG_FIND_ACCESSIBILITY_NODE_INFOS_BY_VIEW_ID: { findAccessibilityNodeInfosByViewIdUiThread(message); } break; - case MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT: { + case MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_TEXT: { findAccessibilityNodeInfosByTextUiThread(message); } break; case MSG_FIND_FOCUS: { @@ -1133,6 +1244,9 @@ final class AccessibilityInteractionController { case MSG_FOCUS_SEARCH: { focusSearchUiThread(message); } break; + case MSG_COMPUTE_CLICK_POINT_IN_SCREEN: { + computeClickPointInScreenUiThread(message); + } break; default: throw new IllegalArgumentException("Unknown message type: " + type); } |