Merge "Cannot interact with dialogs when IME is up and on not touch explored popups." into jb-dev

This commit is contained in:
Svetoslav Ganov
2012-06-07 13:50:58 -07:00
committed by Android (Google) Code Review
9 changed files with 347 additions and 123 deletions

View File

@ -138,18 +138,26 @@ final class AccessibilityInteractionController {
} }
public void findAccessibilityNodeInfoByAccessibilityIdClientThread( public void findAccessibilityNodeInfoByAccessibilityIdClientThread(
long accessibilityNodeId, int interactionId, long accessibilityNodeId, int windowLeft, int windowTop, int interactionId,
IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid, IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid,
long interrogatingTid) { long interrogatingTid) {
Message message = mHandler.obtainMessage(); Message message = mHandler.obtainMessage();
message.what = PrivateHandler.MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID; message.what = PrivateHandler.MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID;
message.arg1 = flags; message.arg1 = flags;
SomeArgs args = mPool.acquire(); SomeArgs args = mPool.acquire();
args.argi1 = AccessibilityNodeInfo.getAccessibilityViewId(accessibilityNodeId); args.argi1 = AccessibilityNodeInfo.getAccessibilityViewId(accessibilityNodeId);
args.argi2 = AccessibilityNodeInfo.getVirtualDescendantId(accessibilityNodeId); args.argi2 = AccessibilityNodeInfo.getVirtualDescendantId(accessibilityNodeId);
args.argi3 = interactionId; args.argi3 = interactionId;
args.arg1 = callback; args.arg1 = callback;
SomeArgs moreArgs = mPool.acquire();
moreArgs.argi1 = windowLeft;
moreArgs.argi2 = windowTop;
args.arg2 = moreArgs;
message.obj = args; message.obj = args;
// If the interrogation is performed by the same thread as the main UI // 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 // thread in this process, set the message as a static reference so
// after this call completes the same thread but in the interrogating // after this call completes the same thread but in the interrogating
@ -164,13 +172,21 @@ final class AccessibilityInteractionController {
private void findAccessibilityNodeInfoByAccessibilityIdUiThread(Message message) { private void findAccessibilityNodeInfoByAccessibilityIdUiThread(Message message) {
final int flags = message.arg1; final int flags = message.arg1;
SomeArgs args = (SomeArgs) message.obj; SomeArgs args = (SomeArgs) message.obj;
final int accessibilityViewId = args.argi1; final int accessibilityViewId = args.argi1;
final int virtualDescendantId = args.argi2; final int virtualDescendantId = args.argi2;
final int interactionId = args.argi3; final int interactionId = args.argi3;
final IAccessibilityInteractionConnectionCallback callback = final IAccessibilityInteractionConnectionCallback callback =
(IAccessibilityInteractionConnectionCallback) args.arg1; (IAccessibilityInteractionConnectionCallback) args.arg1;
SomeArgs moreArgs = (SomeArgs) args.arg2;
mViewRootImpl.mAttachInfo.mActualWindowLeft = moreArgs.argi1;
mViewRootImpl.mAttachInfo.mActualWindowTop = moreArgs.argi2;
mPool.release(moreArgs);
mPool.release(args); mPool.release(args);
List<AccessibilityNodeInfo> infos = mTempAccessibilityNodeInfoList; List<AccessibilityNodeInfo> infos = mTempAccessibilityNodeInfoList;
infos.clear(); infos.clear();
try { try {
@ -200,17 +216,26 @@ final class AccessibilityInteractionController {
} }
public void findAccessibilityNodeInfoByViewIdClientThread(long accessibilityNodeId, public void findAccessibilityNodeInfoByViewIdClientThread(long accessibilityNodeId,
int viewId, int interactionId, IAccessibilityInteractionConnectionCallback callback, int viewId, int windowLeft, int windowTop, int interactionId,
int flags, int interrogatingPid, long interrogatingTid) { IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid,
long interrogatingTid) {
Message message = mHandler.obtainMessage(); Message message = mHandler.obtainMessage();
message.what = PrivateHandler.MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_VIEW_ID; message.what = PrivateHandler.MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_VIEW_ID;
message.arg1 = flags; message.arg1 = flags;
message.arg2 = AccessibilityNodeInfo.getAccessibilityViewId(accessibilityNodeId); message.arg2 = AccessibilityNodeInfo.getAccessibilityViewId(accessibilityNodeId);
SomeArgs args = mPool.acquire(); SomeArgs args = mPool.acquire();
args.argi1 = viewId; args.argi1 = viewId;
args.argi2 = interactionId; args.argi2 = interactionId;
args.arg1 = callback; args.arg1 = callback;
SomeArgs moreArgs = mPool.acquire();
moreArgs.argi1 = windowLeft;
moreArgs.argi2 = windowTop;
args.arg2 = moreArgs;
message.obj = args; message.obj = args;
// If the interrogation is performed by the same thread as the main UI // 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 // thread in this process, set the message as a static reference so
// after this call completes the same thread but in the interrogating // after this call completes the same thread but in the interrogating
@ -226,12 +251,20 @@ final class AccessibilityInteractionController {
private void findAccessibilityNodeInfoByViewIdUiThread(Message message) { private void findAccessibilityNodeInfoByViewIdUiThread(Message message) {
final int flags = message.arg1; final int flags = message.arg1;
final int accessibilityViewId = message.arg2; final int accessibilityViewId = message.arg2;
SomeArgs args = (SomeArgs) message.obj; SomeArgs args = (SomeArgs) message.obj;
final int viewId = args.argi1; final int viewId = args.argi1;
final int interactionId = args.argi2; final int interactionId = args.argi2;
final IAccessibilityInteractionConnectionCallback callback = final IAccessibilityInteractionConnectionCallback callback =
(IAccessibilityInteractionConnectionCallback) args.arg1; (IAccessibilityInteractionConnectionCallback) args.arg1;
SomeArgs moreArgs = (SomeArgs) args.arg2;
mViewRootImpl.mAttachInfo.mActualWindowLeft = moreArgs.argi1;
mViewRootImpl.mAttachInfo.mActualWindowTop = moreArgs.argi2;
mPool.release(moreArgs);
mPool.release(args); mPool.release(args);
AccessibilityNodeInfo info = null; AccessibilityNodeInfo info = null;
try { try {
if (mViewRootImpl.mView == null || mViewRootImpl.mAttachInfo == null) { if (mViewRootImpl.mView == null || mViewRootImpl.mAttachInfo == null) {
@ -262,18 +295,27 @@ final class AccessibilityInteractionController {
} }
public void findAccessibilityNodeInfosByTextClientThread(long accessibilityNodeId, public void findAccessibilityNodeInfosByTextClientThread(long accessibilityNodeId,
String text, int interactionId, IAccessibilityInteractionConnectionCallback callback, String text, int windowLeft, int windowTop, int interactionId,
int flags, int interrogatingPid, long interrogatingTid) { IAccessibilityInteractionConnectionCallback callback, int flags,
int interrogatingPid, long interrogatingTid) {
Message message = mHandler.obtainMessage(); Message message = mHandler.obtainMessage();
message.what = PrivateHandler.MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT; message.what = PrivateHandler.MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT;
message.arg1 = flags; message.arg1 = flags;
SomeArgs args = mPool.acquire(); SomeArgs args = mPool.acquire();
args.arg1 = text; args.arg1 = text;
args.argi1 = AccessibilityNodeInfo.getAccessibilityViewId(accessibilityNodeId); args.argi1 = AccessibilityNodeInfo.getAccessibilityViewId(accessibilityNodeId);
args.argi2 = AccessibilityNodeInfo.getVirtualDescendantId(accessibilityNodeId); args.argi2 = AccessibilityNodeInfo.getVirtualDescendantId(accessibilityNodeId);
args.argi3 = interactionId; args.argi3 = interactionId;
args.arg2 = callback;
SomeArgs moreArgs = mPool.acquire();
moreArgs.arg1 = callback;
moreArgs.argi1 = windowLeft;
moreArgs.argi2 = windowTop;
args.arg2 = moreArgs;
message.obj = args; message.obj = args;
// If the interrogation is performed by the same thread as the main UI // 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 // thread in this process, set the message as a static reference so
// after this call completes the same thread but in the interrogating // after this call completes the same thread but in the interrogating
@ -288,14 +330,22 @@ final class AccessibilityInteractionController {
private void findAccessibilityNodeInfosByTextUiThread(Message message) { private void findAccessibilityNodeInfosByTextUiThread(Message message) {
final int flags = message.arg1; final int flags = message.arg1;
SomeArgs args = (SomeArgs) message.obj; SomeArgs args = (SomeArgs) message.obj;
final String text = (String) args.arg1; final String text = (String) args.arg1;
final int accessibilityViewId = args.argi1; final int accessibilityViewId = args.argi1;
final int virtualDescendantId = args.argi2; final int virtualDescendantId = args.argi2;
final int interactionId = args.argi3; final int interactionId = args.argi3;
SomeArgs moreArgs = (SomeArgs) args.arg2;
final IAccessibilityInteractionConnectionCallback callback = final IAccessibilityInteractionConnectionCallback callback =
(IAccessibilityInteractionConnectionCallback) args.arg2; (IAccessibilityInteractionConnectionCallback) moreArgs.arg1;
mViewRootImpl.mAttachInfo.mActualWindowLeft = moreArgs.argi1;
mViewRootImpl.mAttachInfo.mActualWindowTop = moreArgs.argi2;
mPool.release(moreArgs);
mPool.release(args); mPool.release(args);
List<AccessibilityNodeInfo> infos = null; List<AccessibilityNodeInfo> infos = null;
try { try {
if (mViewRootImpl.mView == null || mViewRootImpl.mAttachInfo == null) { if (mViewRootImpl.mView == null || mViewRootImpl.mAttachInfo == null) {
@ -353,19 +403,27 @@ final class AccessibilityInteractionController {
} }
} }
public void findFocusClientThread(long accessibilityNodeId, int interactionId, int focusType, public void findFocusClientThread(long accessibilityNodeId, int focusType, int windowLeft,
IAccessibilityInteractionConnectionCallback callback, int flags, int interogatingPid, int windowTop, int interactionId, IAccessibilityInteractionConnectionCallback callback,
long interrogatingTid) { int flags, int interogatingPid, long interrogatingTid) {
Message message = mHandler.obtainMessage(); Message message = mHandler.obtainMessage();
message.what = PrivateHandler.MSG_FIND_FOCUS; message.what = PrivateHandler.MSG_FIND_FOCUS;
message.arg1 = flags; message.arg1 = flags;
message.arg2 = focusType; message.arg2 = focusType;
SomeArgs args = mPool.acquire(); SomeArgs args = mPool.acquire();
args.argi1 = interactionId; args.argi1 = interactionId;
args.argi2 = AccessibilityNodeInfo.getAccessibilityViewId(accessibilityNodeId); args.argi2 = AccessibilityNodeInfo.getAccessibilityViewId(accessibilityNodeId);
args.argi3 = AccessibilityNodeInfo.getVirtualDescendantId(accessibilityNodeId); args.argi3 = AccessibilityNodeInfo.getVirtualDescendantId(accessibilityNodeId);
args.arg1 = callback; args.arg1 = callback;
SomeArgs moreArgs = mPool.acquire();
moreArgs.argi1 = windowLeft;
moreArgs.argi2 = windowTop;
args.arg2 = moreArgs;
message.obj = args; message.obj = args;
// If the interrogation is performed by the same thread as the main UI // 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 // thread in this process, set the message as a static reference so
// after this call completes the same thread but in the interrogating // after this call completes the same thread but in the interrogating
@ -381,13 +439,21 @@ final class AccessibilityInteractionController {
private void findFocusUiThread(Message message) { private void findFocusUiThread(Message message) {
final int flags = message.arg1; final int flags = message.arg1;
final int focusType = message.arg2; final int focusType = message.arg2;
SomeArgs args = (SomeArgs) message.obj; SomeArgs args = (SomeArgs) message.obj;
final int interactionId = args.argi1; final int interactionId = args.argi1;
final int accessibilityViewId = args.argi2; final int accessibilityViewId = args.argi2;
final int virtualDescendantId = args.argi3; final int virtualDescendantId = args.argi3;
final IAccessibilityInteractionConnectionCallback callback = final IAccessibilityInteractionConnectionCallback callback =
(IAccessibilityInteractionConnectionCallback) args.arg1; (IAccessibilityInteractionConnectionCallback) args.arg1;
SomeArgs moreArgs = (SomeArgs) args.arg2;
mViewRootImpl.mAttachInfo.mActualWindowLeft = moreArgs.argi1;
mViewRootImpl.mAttachInfo.mActualWindowTop = moreArgs.argi2;
mPool.release(moreArgs);
mPool.release(args); mPool.release(args);
AccessibilityNodeInfo focused = null; AccessibilityNodeInfo focused = null;
try { try {
if (mViewRootImpl.mView == null || mViewRootImpl.mAttachInfo == null) { if (mViewRootImpl.mView == null || mViewRootImpl.mAttachInfo == null) {
@ -440,19 +506,27 @@ final class AccessibilityInteractionController {
} }
} }
public void focusSearchClientThread(long accessibilityNodeId, int interactionId, int direction, public void focusSearchClientThread(long accessibilityNodeId, int direction, int windowLeft,
IAccessibilityInteractionConnectionCallback callback, int flags, int interogatingPid, int windowTop, int interactionId, IAccessibilityInteractionConnectionCallback callback,
long interrogatingTid) { int flags, int interogatingPid, long interrogatingTid) {
Message message = mHandler.obtainMessage(); Message message = mHandler.obtainMessage();
message.what = PrivateHandler.MSG_FOCUS_SEARCH; message.what = PrivateHandler.MSG_FOCUS_SEARCH;
message.arg1 = flags; message.arg1 = flags;
message.arg2 = AccessibilityNodeInfo.getAccessibilityViewId(accessibilityNodeId); message.arg2 = AccessibilityNodeInfo.getAccessibilityViewId(accessibilityNodeId);
SomeArgs args = mPool.acquire(); SomeArgs args = mPool.acquire();
args.argi1 = AccessibilityNodeInfo.getVirtualDescendantId(accessibilityNodeId); args.argi1 = AccessibilityNodeInfo.getVirtualDescendantId(accessibilityNodeId);
args.argi2 = direction; args.argi2 = direction;
args.argi3 = interactionId; args.argi3 = interactionId;
args.arg1 = callback; args.arg1 = callback;
SomeArgs moreArgs = mPool.acquire();
moreArgs.argi1 = windowLeft;
moreArgs.argi2 = windowTop;
args.arg2 = moreArgs;
message.obj = args; message.obj = args;
// If the interrogation is performed by the same thread as the main UI // 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 // thread in this process, set the message as a static reference so
// after this call completes the same thread but in the interrogating // after this call completes the same thread but in the interrogating
@ -468,13 +542,21 @@ final class AccessibilityInteractionController {
private void focusSearchUiThread(Message message) { private void focusSearchUiThread(Message message) {
final int flags = message.arg1; final int flags = message.arg1;
final int accessibilityViewId = message.arg2; final int accessibilityViewId = message.arg2;
SomeArgs args = (SomeArgs) message.obj; SomeArgs args = (SomeArgs) message.obj;
final int virtualDescendantId = args.argi1; final int virtualDescendantId = args.argi1;
final int direction = args.argi2; final int direction = args.argi2;
final int interactionId = args.argi3; final int interactionId = args.argi3;
final IAccessibilityInteractionConnectionCallback callback = final IAccessibilityInteractionConnectionCallback callback =
(IAccessibilityInteractionConnectionCallback) args.arg1; (IAccessibilityInteractionConnectionCallback) args.arg1;
SomeArgs moreArgs = (SomeArgs) args.arg2;
mViewRootImpl.mAttachInfo.mActualWindowLeft = moreArgs.argi1;
mViewRootImpl.mAttachInfo.mActualWindowTop = moreArgs.argi2;
mPool.release(moreArgs);
mPool.release(args); mPool.release(args);
AccessibilityNodeInfo next = null; AccessibilityNodeInfo next = null;
try { try {
if (mViewRootImpl.mView == null || mViewRootImpl.mAttachInfo == null) { if (mViewRootImpl.mView == null || mViewRootImpl.mAttachInfo == null) {
@ -541,13 +623,16 @@ final class AccessibilityInteractionController {
message.what = PrivateHandler.MSG_PERFORM_ACCESSIBILITY_ACTION; message.what = PrivateHandler.MSG_PERFORM_ACCESSIBILITY_ACTION;
message.arg1 = flags; message.arg1 = flags;
message.arg2 = AccessibilityNodeInfo.getAccessibilityViewId(accessibilityNodeId); message.arg2 = AccessibilityNodeInfo.getAccessibilityViewId(accessibilityNodeId);
SomeArgs args = mPool.acquire(); SomeArgs args = mPool.acquire();
args.argi1 = AccessibilityNodeInfo.getVirtualDescendantId(accessibilityNodeId); args.argi1 = AccessibilityNodeInfo.getVirtualDescendantId(accessibilityNodeId);
args.argi2 = action; args.argi2 = action;
args.argi3 = interactionId; args.argi3 = interactionId;
args.arg1 = callback; args.arg1 = callback;
args.arg2 = arguments; args.arg2 = arguments;
message.obj = args; message.obj = args;
// If the interrogation is performed by the same thread as the main UI // 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 // thread in this process, set the message as a static reference so
// after this call completes the same thread but in the interrogating // after this call completes the same thread but in the interrogating
@ -563,6 +648,7 @@ final class AccessibilityInteractionController {
private void perfromAccessibilityActionUiThread(Message message) { private void perfromAccessibilityActionUiThread(Message message) {
final int flags = message.arg1; final int flags = message.arg1;
final int accessibilityViewId = message.arg2; final int accessibilityViewId = message.arg2;
SomeArgs args = (SomeArgs) message.obj; SomeArgs args = (SomeArgs) message.obj;
final int virtualDescendantId = args.argi1; final int virtualDescendantId = args.argi1;
final int action = args.argi2; final int action = args.argi2;
@ -570,7 +656,9 @@ final class AccessibilityInteractionController {
final IAccessibilityInteractionConnectionCallback callback = final IAccessibilityInteractionConnectionCallback callback =
(IAccessibilityInteractionConnectionCallback) args.arg1; (IAccessibilityInteractionConnectionCallback) args.arg1;
Bundle arguments = (Bundle) args.arg2; Bundle arguments = (Bundle) args.arg2;
mPool.release(args); mPool.release(args);
boolean succeeded = false; boolean succeeded = false;
try { try {
if (mViewRootImpl.mView == null || mViewRootImpl.mAttachInfo == null) { if (mViewRootImpl.mView == null || mViewRootImpl.mAttachInfo == null) {

View File

@ -3609,6 +3609,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
case R.styleable.View_importantForAccessibility: case R.styleable.View_importantForAccessibility:
setImportantForAccessibility(a.getInt(attr, setImportantForAccessibility(a.getInt(attr,
IMPORTANT_FOR_ACCESSIBILITY_DEFAULT)); IMPORTANT_FOR_ACCESSIBILITY_DEFAULT));
break;
} }
} }
@ -4901,6 +4902,30 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
} }
} }
/**
* Returns the delta between the actual and last reported window left.
*
* @hide
*/
public int getActualAndReportedWindowLeftDelta() {
if (mAttachInfo != null) {
return mAttachInfo.mActualWindowLeft - mAttachInfo.mWindowLeft;
}
return 0;
}
/**
* Returns the delta between the actual and last reported window top.
*
* @hide
*/
public int getActualAndReportedWindowTopDelta() {
if (mAttachInfo != null) {
return mAttachInfo.mActualWindowTop - mAttachInfo.mWindowTop;
}
return 0;
}
/** /**
* Computes whether this view is visible to the user. Such a view is * Computes whether this view is visible to the user. Such a view is
* attached, visible, all its predecessors are visible, it is not clipped * attached, visible, all its predecessors are visible, it is not clipped
@ -17306,6 +17331,20 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
*/ */
int mWindowTop; int mWindowTop;
/**
* Left actual position of this view's window.
*
* TODO: This is a workaround for 6623031. Remove when fixed.
*/
int mActualWindowLeft;
/**
* Actual top position of this view's window.
*
* TODO: This is a workaround for 6623031. Remove when fixed.
*/
int mActualWindowTop;
/** /**
* Indicates whether views need to use 32-bit drawing caches * Indicates whether views need to use 32-bit drawing caches
*/ */

View File

@ -5172,13 +5172,15 @@ public final class ViewRootImpl implements ViewParent,
@Override @Override
public void findAccessibilityNodeInfoByAccessibilityId(long accessibilityNodeId, public void findAccessibilityNodeInfoByAccessibilityId(long accessibilityNodeId,
int interactionId, IAccessibilityInteractionConnectionCallback callback, int windowLeft, int windowTop, int interactionId,
int flags, int interrogatingPid, long interrogatingTid) { IAccessibilityInteractionConnectionCallback callback, int flags,
int interrogatingPid, long interrogatingTid) {
ViewRootImpl viewRootImpl = mViewRootImpl.get(); ViewRootImpl viewRootImpl = mViewRootImpl.get();
if (viewRootImpl != null && viewRootImpl.mView != null) { if (viewRootImpl != null && viewRootImpl.mView != null) {
viewRootImpl.getAccessibilityInteractionController() viewRootImpl.getAccessibilityInteractionController()
.findAccessibilityNodeInfoByAccessibilityIdClientThread(accessibilityNodeId, .findAccessibilityNodeInfoByAccessibilityIdClientThread(accessibilityNodeId,
interactionId, callback, flags, interrogatingPid, interrogatingTid); windowLeft, windowTop, interactionId, callback, flags, interrogatingPid,
interrogatingTid);
} else { } else {
// We cannot make the call and notify the caller so it does not wait. // We cannot make the call and notify the caller so it does not wait.
try { try {
@ -5211,13 +5213,15 @@ public final class ViewRootImpl implements ViewParent,
@Override @Override
public void findAccessibilityNodeInfoByViewId(long accessibilityNodeId, int viewId, public void findAccessibilityNodeInfoByViewId(long accessibilityNodeId, int viewId,
int interactionId, IAccessibilityInteractionConnectionCallback callback, int windowLeft, int windowTop, int interactionId,
int flags, int interrogatingPid, long interrogatingTid) { IAccessibilityInteractionConnectionCallback callback, int flags,
int interrogatingPid, long interrogatingTid) {
ViewRootImpl viewRootImpl = mViewRootImpl.get(); ViewRootImpl viewRootImpl = mViewRootImpl.get();
if (viewRootImpl != null && viewRootImpl.mView != null) { if (viewRootImpl != null && viewRootImpl.mView != null) {
viewRootImpl.getAccessibilityInteractionController() viewRootImpl.getAccessibilityInteractionController()
.findAccessibilityNodeInfoByViewIdClientThread(accessibilityNodeId, viewId, .findAccessibilityNodeInfoByViewIdClientThread(accessibilityNodeId, viewId,
interactionId, callback, flags, interrogatingPid, interrogatingTid); windowLeft, windowTop, interactionId, callback, flags, interrogatingPid,
interrogatingTid);
} else { } else {
// We cannot make the call and notify the caller so it does not wait. // We cannot make the call and notify the caller so it does not wait.
try { try {
@ -5230,13 +5234,15 @@ public final class ViewRootImpl implements ViewParent,
@Override @Override
public void findAccessibilityNodeInfosByText(long accessibilityNodeId, String text, public void findAccessibilityNodeInfosByText(long accessibilityNodeId, String text,
int interactionId, IAccessibilityInteractionConnectionCallback callback, int windowLeft, int windowTop, int interactionId,
int flags, int interrogatingPid, long interrogatingTid) { IAccessibilityInteractionConnectionCallback callback, int flags,
int interrogatingPid, long interrogatingTid) {
ViewRootImpl viewRootImpl = mViewRootImpl.get(); ViewRootImpl viewRootImpl = mViewRootImpl.get();
if (viewRootImpl != null && viewRootImpl.mView != null) { if (viewRootImpl != null && viewRootImpl.mView != null) {
viewRootImpl.getAccessibilityInteractionController() viewRootImpl.getAccessibilityInteractionController()
.findAccessibilityNodeInfosByTextClientThread(accessibilityNodeId, text, .findAccessibilityNodeInfosByTextClientThread(accessibilityNodeId, text,
interactionId, callback, flags, interrogatingPid, interrogatingTid); windowLeft, windowTop, interactionId, callback, flags, interrogatingPid,
interrogatingTid);
} else { } else {
// We cannot make the call and notify the caller so it does not wait. // We cannot make the call and notify the caller so it does not wait.
try { try {
@ -5248,14 +5254,15 @@ public final class ViewRootImpl implements ViewParent,
} }
@Override @Override
public void findFocus(long accessibilityNodeId, int interactionId, int focusType, public void findFocus(long accessibilityNodeId, int focusType, int windowLeft,
IAccessibilityInteractionConnectionCallback callback, int flags, int windowTop, int interactionId,
IAccessibilityInteractionConnectionCallback callback, int flags,
int interrogatingPid, long interrogatingTid) { int interrogatingPid, long interrogatingTid) {
ViewRootImpl viewRootImpl = mViewRootImpl.get(); ViewRootImpl viewRootImpl = mViewRootImpl.get();
if (viewRootImpl != null && viewRootImpl.mView != null) { if (viewRootImpl != null && viewRootImpl.mView != null) {
viewRootImpl.getAccessibilityInteractionController() viewRootImpl.getAccessibilityInteractionController()
.findFocusClientThread(accessibilityNodeId, interactionId, focusType, .findFocusClientThread(accessibilityNodeId, focusType, windowLeft, windowTop,
callback, flags, interrogatingPid, interrogatingTid); interactionId, callback, flags, interrogatingPid, interrogatingTid);
} else { } else {
// We cannot make the call and notify the caller so it does not wait. // We cannot make the call and notify the caller so it does not wait.
try { try {
@ -5267,14 +5274,15 @@ public final class ViewRootImpl implements ViewParent,
} }
@Override @Override
public void focusSearch(long accessibilityNodeId, int interactionId, int direction, public void focusSearch(long accessibilityNodeId, int direction, int windowLeft,
int windowTop, int interactionId,
IAccessibilityInteractionConnectionCallback callback, int flags, IAccessibilityInteractionConnectionCallback callback, int flags,
int interrogatingPid, long interrogatingTid) { int interrogatingPid, long interrogatingTid) {
ViewRootImpl viewRootImpl = mViewRootImpl.get(); ViewRootImpl viewRootImpl = mViewRootImpl.get();
if (viewRootImpl != null && viewRootImpl.mView != null) { if (viewRootImpl != null && viewRootImpl.mView != null) {
viewRootImpl.getAccessibilityInteractionController() viewRootImpl.getAccessibilityInteractionController()
.focusSearchClientThread(accessibilityNodeId, interactionId, direction, .focusSearchClientThread(accessibilityNodeId, direction, windowLeft, windowTop,
callback, flags, interrogatingPid, interrogatingTid); interactionId, callback, flags, interrogatingPid, interrogatingTid);
} else { } else {
// We cannot make the call and notify the caller so it does not wait. // We cannot make the call and notify the caller so it does not wait.
try { try {

View File

@ -382,6 +382,10 @@ public class AccessibilityNodeInfo implements Parcelable {
private int mConnectionId = UNDEFINED; private int mConnectionId = UNDEFINED;
// TODO: These are a workaround for 6623031. Remove when fixed.
private int mActualAndReportedWindowLeftDelta;
private int mActualAndReportedWindowTopDelta;
/** /**
* Hide constructor from clients. * Hide constructor from clients.
*/ */
@ -428,6 +432,8 @@ public class AccessibilityNodeInfo implements Parcelable {
final int rootAccessibilityViewId = final int rootAccessibilityViewId =
(root != null) ? root.getAccessibilityViewId() : UNDEFINED; (root != null) ? root.getAccessibilityViewId() : UNDEFINED;
mSourceNodeId = makeNodeId(rootAccessibilityViewId, virtualDescendantId); mSourceNodeId = makeNodeId(rootAccessibilityViewId, virtualDescendantId);
mActualAndReportedWindowLeftDelta = root.getActualAndReportedWindowLeftDelta();
mActualAndReportedWindowTopDelta = root.getActualAndReportedWindowTopDelta();
} }
/** /**
@ -831,6 +837,7 @@ public class AccessibilityNodeInfo implements Parcelable {
public void setBoundsInScreen(Rect bounds) { public void setBoundsInScreen(Rect bounds) {
enforceNotSealed(); enforceNotSealed();
mBoundsInScreen.set(bounds.left, bounds.top, bounds.right, bounds.bottom); mBoundsInScreen.set(bounds.left, bounds.top, bounds.right, bounds.bottom);
mBoundsInScreen.offset(mActualAndReportedWindowLeftDelta, mActualAndReportedWindowTopDelta);
} }
/** /**

View File

@ -28,25 +28,25 @@ import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
*/ */
oneway interface IAccessibilityInteractionConnection { oneway interface IAccessibilityInteractionConnection {
void findAccessibilityNodeInfoByAccessibilityId(long accessibilityNodeId, int interactionId, void findAccessibilityNodeInfoByAccessibilityId(long accessibilityNodeId, int windowLeft,
IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid, int windowTop, int interactionId, IAccessibilityInteractionConnectionCallback callback,
long interrogatingTid); int flags, int interrogatingPid, long interrogatingTid);
void findAccessibilityNodeInfoByViewId(long accessibilityNodeId, int id, int interactionId, void findAccessibilityNodeInfoByViewId(long accessibilityNodeId, int viewId, int windowLeft,
IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid, int windowTop, int interactionId, IAccessibilityInteractionConnectionCallback callback,
long interrogatingTid); int flags, int interrogatingPid, long interrogatingTid);
void findAccessibilityNodeInfosByText(long accessibilityNodeId, String text, int interactionId, void findAccessibilityNodeInfosByText(long accessibilityNodeId, String text, int windowLeft,
IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid, int windowTop, int interactionId, IAccessibilityInteractionConnectionCallback callback,
long interrogatingTid); int flags, int interrogatingPid, long interrogatingTid);
void findFocus(long accessibilityNodeId, int interactionId, int focusType, void findFocus(long accessibilityNodeId, int focusType, int windowLeft, int windowTop,
IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid, int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags,
long interrogatingTid); int interrogatingPid, long interrogatingTid);
void focusSearch(long accessibilityNodeId, int interactionId, int direction, void focusSearch(long accessibilityNodeId, int direction, int windowLeft, int windowTop,
IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid, int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags,
long interrogatingTid); int interrogatingPid, long interrogatingTid);
void performAccessibilityAction(long accessibilityNodeId, int action, in Bundle arguments, void performAccessibilityAction(long accessibilityNodeId, int action, in Bundle arguments,
int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags, int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags,

View File

@ -25,6 +25,7 @@ import android.view.InputDevice;
import android.view.InputEvent; import android.view.InputEvent;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.WindowManagerPolicy; import android.view.WindowManagerPolicy;
import android.view.accessibility.AccessibilityEvent;
/** /**
* Input filter for accessibility. * Input filter for accessibility.
@ -120,4 +121,8 @@ public class AccessibilityInputFilter extends InputFilter {
super.onInputEvent(event, policyFlags); super.onInputEvent(event, policyFlags);
} }
} }
public void onAccessibilityEvent(AccessibilityEvent event) {
mTouchExplorer.onAccessibilityEvent(event);
}
} }

View File

@ -141,8 +141,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
private final SimpleStringSplitter mStringColonSplitter = new SimpleStringSplitter(COMPONENT_NAME_SEPARATOR); private final SimpleStringSplitter mStringColonSplitter = new SimpleStringSplitter(COMPONENT_NAME_SEPARATOR);
private final Rect mTempRect = new Rect();
private PackageManager mPackageManager; private PackageManager mPackageManager;
private int mHandledFeedbackTypes = 0; private int mHandledFeedbackTypes = 0;
@ -403,7 +401,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
notifyAccessibilityServicesDelayedLocked(event, false); notifyAccessibilityServicesDelayedLocked(event, false);
notifyAccessibilityServicesDelayedLocked(event, true); notifyAccessibilityServicesDelayedLocked(event, true);
} }
if (mHasInputFilter && mInputFilter != null) {
mInputFilter.onAccessibilityEvent(event);
}
event.recycle(); event.recycle();
mHandledFeedbackTypes = 0; mHandledFeedbackTypes = 0;
} }
@ -543,17 +543,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
} }
/** /**
* Gets the bounds of the accessibility focus if the provided, * Gets the bounds of the accessibility focus in the active window.
* point coordinates are within the currently active window
* and accessibility focus is found within the latter.
* *
* @param x X coordinate.
* @param y Y coordinate
* @param outBounds The output to which to write the focus bounds. * @param outBounds The output to which to write the focus bounds.
* @return The accessibility focus rectangle if the point is in the * @return Whether accessibility focus was found and the bounds are populated.
* window and the window has accessibility focus.
*/ */
boolean getAccessibilityFocusBounds(int x, int y, Rect outBounds) { boolean getAccessibilityFocusBoundsInActiveWindow(Rect outBounds) {
// Instead of keeping track of accessibility focus events per // Instead of keeping track of accessibility focus events per
// window to be able to find the focus in the active window, // window to be able to find the focus in the active window,
// we take a stateless approach and look it up. This is fine // we take a stateless approach and look it up. This is fine
@ -568,11 +563,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
if (root == null) { if (root == null) {
return false; return false;
} }
Rect bounds = mTempRect;
root.getBoundsInScreen(bounds);
if (!bounds.contains(x, y)) {
return false;
}
AccessibilityNodeInfo focus = root.findFocus( AccessibilityNodeInfo focus = root.findFocus(
AccessibilityNodeInfo.FOCUS_ACCESSIBILITY); AccessibilityNodeInfo.FOCUS_ACCESSIBILITY);
if (focus == null) { if (focus == null) {
@ -585,6 +575,19 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
} }
} }
/**
* Gets the bounds of the active window.
*
* @param outBounds The output to which to write the bounds.
*/
void getActiveWindowBounds(Rect outBounds) {
synchronized (mLock) {
final int windowId = mSecurityPolicy.mActiveWindowId;
IBinder token = mWindowIdToWindowTokenMap.get(windowId);
mWindowManagerService.getWindowFrame(token, outBounds);
}
}
private Service getQueryBridge() { private Service getQueryBridge() {
if (mQueryBridge == null) { if (mQueryBridge == null) {
AccessibilityServiceInfo info = new AccessibilityServiceInfo(); AccessibilityServiceInfo info = new AccessibilityServiceInfo();
@ -1316,6 +1319,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
IAccessibilityInteractionConnectionCallback callback, long interrogatingTid) IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)
throws RemoteException { throws RemoteException {
final int resolvedWindowId = resolveAccessibilityWindowId(accessibilityWindowId); final int resolvedWindowId = resolveAccessibilityWindowId(accessibilityWindowId);
final int windowLeft;
final int windowTop;
IAccessibilityInteractionConnection connection = null; IAccessibilityInteractionConnection connection = null;
synchronized (mLock) { synchronized (mLock) {
mSecurityPolicy.enforceCanRetrieveWindowContent(this); mSecurityPolicy.enforceCanRetrieveWindowContent(this);
@ -1328,6 +1333,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
return 0; return 0;
} }
} }
IBinder token = mWindowIdToWindowTokenMap.get(resolvedWindowId);
mWindowManagerService.getWindowFrame(token, mTempBounds);
windowLeft = mTempBounds.left;
windowTop = mTempBounds.top;
} }
final int flags = (mIncludeNotImportantViews) ? final int flags = (mIncludeNotImportantViews) ?
AccessibilityNodeInfo.INCLUDE_NOT_IMPORTANT_VIEWS : 0; AccessibilityNodeInfo.INCLUDE_NOT_IMPORTANT_VIEWS : 0;
@ -1335,7 +1344,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
final long identityToken = Binder.clearCallingIdentity(); final long identityToken = Binder.clearCallingIdentity();
try { try {
connection.findAccessibilityNodeInfoByViewId(accessibilityNodeId, viewId, connection.findAccessibilityNodeInfoByViewId(accessibilityNodeId, viewId,
interactionId, callback, flags, interrogatingPid, interrogatingTid); windowLeft, windowTop, interactionId, callback, flags, interrogatingPid,
interrogatingTid);
} catch (RemoteException re) { } catch (RemoteException re) {
if (DEBUG) { if (DEBUG) {
Slog.e(LOG_TAG, "Error findAccessibilityNodeInfoByViewId()."); Slog.e(LOG_TAG, "Error findAccessibilityNodeInfoByViewId().");
@ -1352,6 +1362,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
IAccessibilityInteractionConnectionCallback callback, long interrogatingTid) IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)
throws RemoteException { throws RemoteException {
final int resolvedWindowId = resolveAccessibilityWindowId(accessibilityWindowId); final int resolvedWindowId = resolveAccessibilityWindowId(accessibilityWindowId);
final int windowLeft;
final int windowTop;
IAccessibilityInteractionConnection connection = null; IAccessibilityInteractionConnection connection = null;
synchronized (mLock) { synchronized (mLock) {
mSecurityPolicy.enforceCanRetrieveWindowContent(this); mSecurityPolicy.enforceCanRetrieveWindowContent(this);
@ -1365,14 +1377,19 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
return 0; return 0;
} }
} }
IBinder token = mWindowIdToWindowTokenMap.get(resolvedWindowId);
mWindowManagerService.getWindowFrame(token, mTempBounds);
windowLeft = mTempBounds.left;
windowTop = mTempBounds.top;
} }
final int flags = (mIncludeNotImportantViews) ? final int flags = (mIncludeNotImportantViews) ?
AccessibilityNodeInfo.INCLUDE_NOT_IMPORTANT_VIEWS : 0; AccessibilityNodeInfo.INCLUDE_NOT_IMPORTANT_VIEWS : 0;
final int interrogatingPid = Binder.getCallingPid(); final int interrogatingPid = Binder.getCallingPid();
final long identityToken = Binder.clearCallingIdentity(); final long identityToken = Binder.clearCallingIdentity();
try { try {
connection.findAccessibilityNodeInfosByText(accessibilityNodeId, text, connection.findAccessibilityNodeInfosByText(accessibilityNodeId, text, windowLeft,
interactionId, callback, flags, interrogatingPid, interrogatingTid); windowTop, interactionId, callback, flags, interrogatingPid,
interrogatingTid);
} catch (RemoteException re) { } catch (RemoteException re) {
if (DEBUG) { if (DEBUG) {
Slog.e(LOG_TAG, "Error calling findAccessibilityNodeInfosByText()"); Slog.e(LOG_TAG, "Error calling findAccessibilityNodeInfosByText()");
@ -1389,6 +1406,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
IAccessibilityInteractionConnectionCallback callback, int flags, IAccessibilityInteractionConnectionCallback callback, int flags,
long interrogatingTid) throws RemoteException { long interrogatingTid) throws RemoteException {
final int resolvedWindowId = resolveAccessibilityWindowId(accessibilityWindowId); final int resolvedWindowId = resolveAccessibilityWindowId(accessibilityWindowId);
final int windowLeft;
final int windowTop;
IAccessibilityInteractionConnection connection = null; IAccessibilityInteractionConnection connection = null;
synchronized (mLock) { synchronized (mLock) {
mSecurityPolicy.enforceCanRetrieveWindowContent(this); mSecurityPolicy.enforceCanRetrieveWindowContent(this);
@ -1402,6 +1421,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
return 0; return 0;
} }
} }
IBinder token = mWindowIdToWindowTokenMap.get(resolvedWindowId);
mWindowManagerService.getWindowFrame(token, mTempBounds);
windowLeft = mTempBounds.left;
windowTop = mTempBounds.top;
} }
final int allFlags = flags | ((mIncludeNotImportantViews) ? final int allFlags = flags | ((mIncludeNotImportantViews) ?
AccessibilityNodeInfo.INCLUDE_NOT_IMPORTANT_VIEWS : 0); AccessibilityNodeInfo.INCLUDE_NOT_IMPORTANT_VIEWS : 0);
@ -1409,7 +1432,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
final long identityToken = Binder.clearCallingIdentity(); final long identityToken = Binder.clearCallingIdentity();
try { try {
connection.findAccessibilityNodeInfoByAccessibilityId(accessibilityNodeId, connection.findAccessibilityNodeInfoByAccessibilityId(accessibilityNodeId,
interactionId, callback, allFlags, interrogatingPid, interrogatingTid); windowLeft, windowTop, interactionId, callback, allFlags, interrogatingPid,
interrogatingTid);
} catch (RemoteException re) { } catch (RemoteException re) {
if (DEBUG) { if (DEBUG) {
Slog.e(LOG_TAG, "Error calling findAccessibilityNodeInfoByAccessibilityId()"); Slog.e(LOG_TAG, "Error calling findAccessibilityNodeInfoByAccessibilityId()");
@ -1426,6 +1450,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
IAccessibilityInteractionConnectionCallback callback, long interrogatingTid) IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)
throws RemoteException { throws RemoteException {
final int resolvedWindowId = resolveAccessibilityWindowId(accessibilityWindowId); final int resolvedWindowId = resolveAccessibilityWindowId(accessibilityWindowId);
final int windowLeft;
final int windowTop;
IAccessibilityInteractionConnection connection = null; IAccessibilityInteractionConnection connection = null;
synchronized (mLock) { synchronized (mLock) {
mSecurityPolicy.enforceCanRetrieveWindowContent(this); mSecurityPolicy.enforceCanRetrieveWindowContent(this);
@ -1439,14 +1465,18 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
return 0; return 0;
} }
} }
IBinder token = mWindowIdToWindowTokenMap.get(resolvedWindowId);
mWindowManagerService.getWindowFrame(token, mTempBounds);
windowLeft = mTempBounds.left;
windowTop = mTempBounds.top;
} }
final int flags = (mIncludeNotImportantViews) ? final int flags = (mIncludeNotImportantViews) ?
AccessibilityNodeInfo.INCLUDE_NOT_IMPORTANT_VIEWS : 0; AccessibilityNodeInfo.INCLUDE_NOT_IMPORTANT_VIEWS : 0;
final int interrogatingPid = Binder.getCallingPid(); final int interrogatingPid = Binder.getCallingPid();
final long identityToken = Binder.clearCallingIdentity(); final long identityToken = Binder.clearCallingIdentity();
try { try {
connection.findFocus(accessibilityNodeId, interactionId, focusType, callback, connection.findFocus(accessibilityNodeId, focusType, windowLeft, windowTop,
flags, interrogatingPid, interrogatingTid); interactionId, callback, flags, interrogatingPid, interrogatingTid);
} catch (RemoteException re) { } catch (RemoteException re) {
if (DEBUG) { if (DEBUG) {
Slog.e(LOG_TAG, "Error calling findAccessibilityFocus()"); Slog.e(LOG_TAG, "Error calling findAccessibilityFocus()");
@ -1463,6 +1493,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
IAccessibilityInteractionConnectionCallback callback, long interrogatingTid) IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)
throws RemoteException { throws RemoteException {
final int resolvedWindowId = resolveAccessibilityWindowId(accessibilityWindowId); final int resolvedWindowId = resolveAccessibilityWindowId(accessibilityWindowId);
final int windowLeft;
final int windowTop;
IAccessibilityInteractionConnection connection = null; IAccessibilityInteractionConnection connection = null;
synchronized (mLock) { synchronized (mLock) {
mSecurityPolicy.enforceCanRetrieveWindowContent(this); mSecurityPolicy.enforceCanRetrieveWindowContent(this);
@ -1476,14 +1508,18 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
return 0; return 0;
} }
} }
IBinder token = mWindowIdToWindowTokenMap.get(resolvedWindowId);
mWindowManagerService.getWindowFrame(token, mTempBounds);
windowLeft = mTempBounds.left;
windowTop = mTempBounds.top;
} }
final int flags = (mIncludeNotImportantViews) ? final int flags = (mIncludeNotImportantViews) ?
AccessibilityNodeInfo.INCLUDE_NOT_IMPORTANT_VIEWS : 0; AccessibilityNodeInfo.INCLUDE_NOT_IMPORTANT_VIEWS : 0;
final int interrogatingPid = Binder.getCallingPid(); final int interrogatingPid = Binder.getCallingPid();
final long identityToken = Binder.clearCallingIdentity(); final long identityToken = Binder.clearCallingIdentity();
try { try {
connection.focusSearch(accessibilityNodeId, interactionId, direction, callback, connection.focusSearch(accessibilityNodeId, direction, windowLeft, windowTop,
flags, interrogatingPid, interrogatingTid); interactionId, callback, flags, interrogatingPid, interrogatingTid);
} catch (RemoteException re) { } catch (RemoteException re) {
if (DEBUG) { if (DEBUG) {
Slog.e(LOG_TAG, "Error calling accessibilityFocusSearch()"); Slog.e(LOG_TAG, "Error calling accessibilityFocusSearch()");

View File

@ -33,6 +33,7 @@ import android.view.MotionEvent.PointerProperties;
import android.view.VelocityTracker; import android.view.VelocityTracker;
import android.view.ViewConfiguration; import android.view.ViewConfiguration;
import android.view.WindowManagerPolicy; import android.view.WindowManagerPolicy;
import android.view.accessibility.AccessibilityEvent;
import com.android.internal.R; import com.android.internal.R;
import com.android.server.input.InputFilter; import com.android.server.input.InputFilter;
@ -293,6 +294,21 @@ public class TouchExplorer {
} }
} }
public void onAccessibilityEvent(AccessibilityEvent event) {
// If a new window opens or the accessibility focus moves we no longer
// want to click/long press on the last touch explored location.
final int eventType = event.getEventType();
switch (eventType) {
case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED: {
if (mInjectedPointerTracker.mLastInjectedHoverEvent != null) {
mInjectedPointerTracker.mLastInjectedHoverEvent.recycle();
mInjectedPointerTracker.mLastInjectedHoverEvent = null;
}
} break;
}
}
/** /**
* Handles a motion event in touch exploring state. * Handles a motion event in touch exploring state.
* *
@ -1037,30 +1053,40 @@ public class TouchExplorer {
// is actually clicked. // is actually clicked.
sendExitEventsIfNeeded(policyFlags); sendExitEventsIfNeeded(policyFlags);
// If the last touched explored location is not within the focused int clickLocationX;
// window we will click at that exact spot, otherwise we find the int clickLocationY;
// accessibility focus and if the tap is within its bounds we click
// there, otherwise we pick the middle of the focus rectangle.
MotionEvent lastEvent = mInjectedPointerTracker.getLastInjectedHoverEvent();
if (lastEvent == null) {
return;
}
final int exploreLocationX = (int) lastEvent.getX(lastEvent.getActionIndex());
final int exploreLocationY = (int) lastEvent.getY(lastEvent.getActionIndex());
Rect bounds = mTempRect;
boolean useLastHoverLocation = false;
final int pointerId = secondTapUp.getPointerId(secondTapUp.getActionIndex()); final int pointerId = secondTapUp.getPointerId(secondTapUp.getActionIndex());
final int pointerIndex = secondTapUp.findPointerIndex(pointerId); final int pointerIndex = secondTapUp.findPointerIndex(pointerId);
if (mAms.getAccessibilityFocusBounds(exploreLocationX, exploreLocationY, bounds)) {
// If the user's last touch explored location is not MotionEvent lastExploreEvent = mInjectedPointerTracker.getLastInjectedHoverEvent();
// within the accessibility focus bounds we use the center if (lastExploreEvent == null) {
// of the accessibility focused rectangle. // No last touch explored event but there is accessibility focus in
if (!bounds.contains((int) secondTapUp.getX(pointerIndex), // the active window. We click in the middle of the focus bounds.
(int) secondTapUp.getY(pointerIndex))) { Rect focusBounds = mTempRect;
useLastHoverLocation = true; if (mAms.getAccessibilityFocusBoundsInActiveWindow(focusBounds)) {
clickLocationX = focusBounds.centerX();
clickLocationY = focusBounds.centerY();
} else {
// Out of luck - do nothing.
return;
}
} else {
// If the click is within the active window but not within the
// accessibility focus bounds we click in the focus center.
final int lastExplorePointerIndex = lastExploreEvent.getActionIndex();
clickLocationX = (int) lastExploreEvent.getX(lastExplorePointerIndex);
clickLocationY = (int) lastExploreEvent.getY(lastExplorePointerIndex);
Rect activeWindowBounds = mTempRect;
mAms.getActiveWindowBounds(activeWindowBounds);
if (activeWindowBounds.contains(clickLocationX, clickLocationY)) {
Rect focusBounds = mTempRect;
if (mAms.getAccessibilityFocusBoundsInActiveWindow(focusBounds)) {
if (!focusBounds.contains(clickLocationX, clickLocationY)) {
clickLocationX = focusBounds.centerX();
clickLocationY = focusBounds.centerY();
}
}
} }
} }
@ -1070,8 +1096,8 @@ public class TouchExplorer {
secondTapUp.getPointerProperties(pointerIndex, properties[0]); secondTapUp.getPointerProperties(pointerIndex, properties[0]);
PointerCoords[] coords = new PointerCoords[1]; PointerCoords[] coords = new PointerCoords[1];
coords[0] = new PointerCoords(); coords[0] = new PointerCoords();
coords[0].x = (useLastHoverLocation) ? bounds.centerX() : exploreLocationX; coords[0].x = clickLocationX;
coords[0].y = (useLastHoverLocation) ? bounds.centerY() : exploreLocationY; coords[0].y = clickLocationY;
MotionEvent event = MotionEvent.obtain(secondTapUp.getDownTime(), MotionEvent event = MotionEvent.obtain(secondTapUp.getDownTime(),
secondTapUp.getEventTime(), MotionEvent.ACTION_DOWN, 1, properties, secondTapUp.getEventTime(), MotionEvent.ACTION_DOWN, 1, properties,
coords, 0, 0, 1.0f, 1.0f, secondTapUp.getDeviceId(), 0, coords, 0, 0, 1.0f, 1.0f, secondTapUp.getDeviceId(), 0,
@ -1257,44 +1283,46 @@ public class TouchExplorer {
return; return;
} }
// If the last touched explored location is not within the focused int clickLocationX;
// window we will long press at that exact spot, otherwise we find the int clickLocationY;
// accessibility focus and if the tap is within its bounds we long press
// there, otherwise we pick the middle of the focus rectangle.
MotionEvent lastEvent = mInjectedPointerTracker.getLastInjectedHoverEvent();
if (lastEvent == null) {
return;
}
final int exploreLocationX = (int) lastEvent.getX(lastEvent.getActionIndex());
final int exploreLocationY = (int) lastEvent.getY(lastEvent.getActionIndex());
Rect bounds = mTempRect;
boolean useFocusedBounds = false;
final int pointerId = mEvent.getPointerId(mEvent.getActionIndex()); final int pointerId = mEvent.getPointerId(mEvent.getActionIndex());
final int pointerIndex = mEvent.findPointerIndex(pointerId); final int pointerIndex = mEvent.findPointerIndex(pointerId);
if (mAms.getAccessibilityFocusBounds(exploreLocationX, exploreLocationY, bounds)) {
// If the user's last touch explored location is not MotionEvent lastExploreEvent = mInjectedPointerTracker.getLastInjectedHoverEvent();
// within the accessibility focus bounds we use the center if (lastExploreEvent == null) {
// of the accessibility focused rectangle. // No last touch explored event but there is accessibility focus in
if (!bounds.contains((int) mEvent.getX(pointerIndex), // the active window. We click in the middle of the focus bounds.
(int) mEvent.getY(pointerIndex))) { Rect focusBounds = mTempRect;
useFocusedBounds = true; if (mAms.getAccessibilityFocusBoundsInActiveWindow(focusBounds)) {
clickLocationX = focusBounds.centerX();
clickLocationY = focusBounds.centerY();
} else {
// Out of luck - do nothing.
return;
}
} else {
// If the click is within the active window but not within the
// accessibility focus bounds we click in the focus center.
final int lastExplorePointerIndex = lastExploreEvent.getActionIndex();
clickLocationX = (int) lastExploreEvent.getX(lastExplorePointerIndex);
clickLocationY = (int) lastExploreEvent.getY(lastExplorePointerIndex);
Rect activeWindowBounds = mTempRect;
mAms.getActiveWindowBounds(activeWindowBounds);
if (activeWindowBounds.contains(clickLocationX, clickLocationY)) {
Rect focusBounds = mTempRect;
if (mAms.getAccessibilityFocusBoundsInActiveWindow(focusBounds)) {
if (!focusBounds.contains(clickLocationX, clickLocationY)) {
clickLocationX = focusBounds.centerX();
clickLocationY = focusBounds.centerY();
}
}
} }
} }
mLongPressingPointerId = mEvent.getPointerId(pointerIndex); mLongPressingPointerId = pointerId;
mLongPressingPointerDeltaX = (int) mEvent.getX(pointerIndex) - clickLocationX;
final int eventX = (int) mEvent.getX(pointerIndex); mLongPressingPointerDeltaY = (int) mEvent.getY(pointerIndex) - clickLocationY;
final int eventY = (int) mEvent.getY(pointerIndex);
if (useFocusedBounds) {
mLongPressingPointerDeltaX = eventX - bounds.centerX();
mLongPressingPointerDeltaY = eventY - bounds.centerY();
} else {
mLongPressingPointerDeltaX = eventX - exploreLocationX;
mLongPressingPointerDeltaY = eventY - exploreLocationY;
}
sendExitEventsIfNeeded(mPolicyFlags); sendExitEventsIfNeeded(mPolicyFlags);

View File

@ -6675,6 +6675,7 @@ public class WindowManagerService extends IWindowManager.Stub
} }
} }
// TODO: Put this on the IWindowManagerService and guard with a permission.
public IBinder getFocusedWindowClientToken() { public IBinder getFocusedWindowClientToken() {
synchronized (mWindowMap) { synchronized (mWindowMap) {
WindowState windowState = getFocusedWindowLocked(); WindowState windowState = getFocusedWindowLocked();
@ -6685,6 +6686,18 @@ public class WindowManagerService extends IWindowManager.Stub
} }
} }
// TODO: This is a workaround - remove when 6623031 is fixed.
public boolean getWindowFrame(IBinder token, Rect outBounds) {
synchronized (mWindowMap) {
WindowState windowState = mWindowMap.get(token);
if (windowState != null) {
outBounds.set(windowState.getFrameLw());
return true;
}
}
return false;
}
private WindowState getFocusedWindow() { private WindowState getFocusedWindow() {
synchronized (mWindowMap) { synchronized (mWindowMap) {
return getFocusedWindowLocked(); return getFocusedWindowLocked();