diff options
author | Svetoslav Ganov <svetoslavganov@google.com> | 2011-06-10 20:51:30 -0700 |
---|---|---|
committer | Svetoslav Ganov <svetoslavganov@google.com> | 2011-06-10 21:10:46 -0700 |
commit | eeee4d2c01d3c4ed99e4891dbc75c7de69a803fa (patch) | |
tree | 316a5bbeb6b5d98029a0996772dca1857fcb9059 /core/java/android/view/ViewAncestor.java | |
parent | eaf7ce6067707fcebd58067135376af51858d2e5 (diff) | |
download | frameworks_base-eeee4d2c01d3c4ed99e4891dbc75c7de69a803fa.zip frameworks_base-eeee4d2c01d3c4ed99e4891dbc75c7de69a803fa.tar.gz frameworks_base-eeee4d2c01d3c4ed99e4891dbc75c7de69a803fa.tar.bz2 |
Final polish of the interrogation feature.
1. Added a new event type for notifying client accessibilitiy
services for changes in the layout. The event is fired at
most once for a given time frame and is delivered to clients
only if it originates from the window that can be interrogated.
2. Exposed the findByText functionality in AccessibilityNodeInfo.
This is very useful for an accessibility service since it allows
searching for something the user knows is on the screen thus
avoiding touch exploring the content. Touch exploring is
excellent for learning the apps but knowing them search is
much faster.
3. Fixed a bug causing an accessibiliby service not to receive
the event source in case of more than one service is registered
and one of them does not have paermission to interrogate the window.
The same event was dispatched to multiple services but if one
of them does not have interrogation permission the event is
modified to remove the source causing subsequent serivices not
to get the later.
4. Moved the getSource setSource methods to AccessibilityRecord
instead in AccessibilityEvent.
5. Hiden some protected members in AccessibilityRecod which should
not be made public since getters exist.
6. Added the View absolute coordinates in the screen to AccessibilityNodeInfo.
This is needed for fast computation of relative positions of
views from accessibility - common use case for the later.
7. Fixed a couple of marshalling bugs.
8. Added a test for the object contract of AccessibilityNodeInfo.
Change-Id: Id9dc50c33aff441e4c93d25ea316c9bbc4bd7a35
Diffstat (limited to 'core/java/android/view/ViewAncestor.java')
-rw-r--r-- | core/java/android/view/ViewAncestor.java | 75 |
1 files changed, 66 insertions, 9 deletions
diff --git a/core/java/android/view/ViewAncestor.java b/core/java/android/view/ViewAncestor.java index 17d7454..914973e 100644 --- a/core/java/android/view/ViewAncestor.java +++ b/core/java/android/view/ViewAncestor.java @@ -136,6 +136,13 @@ public final class ViewAncestor extends Handler implements ViewParent, static final ArrayList<ComponentCallbacks> sConfigCallbacks = new ArrayList<ComponentCallbacks>(); + /** + * Delay before dispatching an accessibility event that the window + * content has changed. The window content is considered changed + * after a layout pass. + */ + private static final long SEND_WINDOW_CONTENT_CHANGED_DELAY_MILLIS = 500; + long mLastTrackballTime = 0; final TrackballAxis mTrackballAxisX = new TrackballAxis(); final TrackballAxis mTrackballAxisY = new TrackballAxis(); @@ -277,6 +284,8 @@ public final class ViewAncestor extends Handler implements ViewParent, AccessibilityInteractionConnectionManager mAccessibilityInteractionConnectionManager; + SendWindowContentChanged mSendWindowContentChanged; + private final int mDensity; /** @@ -1427,6 +1436,10 @@ public final class ViewAncestor extends Handler implements ViewParent, if (triggerGlobalLayoutListener) { attachInfo.mRecomputeGlobalAttributes = false; attachInfo.mTreeObserver.dispatchOnGlobalLayout(); + + if (AccessibilityManager.getInstance(host.mContext).isEnabled()) { + postSendWindowContentChangedCallback(); + } } if (computesInternalInsets) { @@ -2086,6 +2099,7 @@ public final class ViewAncestor extends Handler implements ViewParent, mAccessibilityInteractionConnectionManager.ensureNoConnection(); mAccessibilityManager.removeAccessibilityStateChangeListener( mAccessibilityInteractionConnectionManager); + removeSendWindowContentChangedCallback(); mView = null; mAttachInfo.mRootView = null; @@ -3671,6 +3685,29 @@ public final class ViewAncestor extends Handler implements ViewParent, } } + /** + * Post a callback to send a + * {@link AccessibilityEvent#TYPE_WINDOW_CONTENT_CHANGED} event. + */ + private void postSendWindowContentChangedCallback() { + if (mSendWindowContentChanged == null) { + mSendWindowContentChanged = new SendWindowContentChanged(); + } else { + removeCallbacks(mSendWindowContentChanged); + } + postDelayed(mSendWindowContentChanged, SEND_WINDOW_CONTENT_CHANGED_DELAY_MILLIS); + } + + /** + * Remove a posted callback to send a + * {@link AccessibilityEvent#TYPE_WINDOW_CONTENT_CHANGED} event. + */ + private void removeSendWindowContentChangedCallback() { + if (mSendWindowContentChanged != null) { + removeCallbacks(mSendWindowContentChanged); + } + } + public boolean showContextMenuForChild(View originalView) { return false; } @@ -4268,12 +4305,12 @@ public final class ViewAncestor extends Handler implements ViewParent, } } - public void findAccessibilityNodeInfosByViewText(String text, int interactionId, - IAccessibilityInteractionConnectionCallback callback) { + public void findAccessibilityNodeInfosByViewText(String text, int accessibilityId, + int interactionId, IAccessibilityInteractionConnectionCallback callback) { if (mViewAncestor.get() != null) { getAccessibilityInteractionController() - .findAccessibilityNodeInfosByViewTextClientThread(text, interactionId, - callback); + .findAccessibilityNodeInfosByViewTextClientThread(text, accessibilityId, + interactionId, callback); } } } @@ -4414,13 +4451,15 @@ public final class ViewAncestor extends Handler implements ViewParent, } } - public void findAccessibilityNodeInfosByViewTextClientThread(String text, int interactionId, + public void findAccessibilityNodeInfosByViewTextClientThread(String text, + int accessibilityViewId, int interactionId, IAccessibilityInteractionConnectionCallback callback) { Message message = Message.obtain(); message.what = DO_FIND_ACCESSIBLITY_NODE_INFO_BY_VIEW_TEXT; SomeArgs args = mPool.acquire(); args.arg1 = text; - args.argi1 = interactionId; + args.argi1 = accessibilityViewId; + args.argi2 = interactionId; args.arg2 = callback; message.obj = args; sendMessage(message); @@ -4429,18 +4468,28 @@ public final class ViewAncestor extends Handler implements ViewParent, public void findAccessibilityNodeInfosByViewTextUiThread(Message message) { SomeArgs args = (SomeArgs) message.obj; final String text = (String) args.arg1; - final int interactionId = args.argi1; + final int accessibilityViewId = args.argi1; + final int interactionId = args.argi2; final IAccessibilityInteractionConnectionCallback callback = (IAccessibilityInteractionConnectionCallback) args.arg2; mPool.release(args); List<AccessibilityNodeInfo> infos = null; try { - View root = ViewAncestor.this.mView; - ArrayList<View> foundViews = mAttachInfo.mFocusablesTempList; foundViews.clear(); + View root = null; + if (accessibilityViewId != View.NO_ID) { + root = findViewByAccessibilityId(accessibilityViewId); + } else { + root = ViewAncestor.this.mView; + } + + if (root == null) { + return; + } + root.findViewsWithText(foundViews, text); if (foundViews.isEmpty()) { return; @@ -4577,4 +4626,12 @@ public final class ViewAncestor extends Handler implements ViewParent, } } } + + private class SendWindowContentChanged implements Runnable { + public void run() { + if (mView != null) { + mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED); + } + } + } } |