summaryrefslogtreecommitdiffstats
path: root/core/java/android/view/ViewAncestor.java
diff options
context:
space:
mode:
authorSvetoslav Ganov <svetoslavganov@google.com>2011-06-10 20:51:30 -0700
committerSvetoslav Ganov <svetoslavganov@google.com>2011-06-10 21:10:46 -0700
commiteeee4d2c01d3c4ed99e4891dbc75c7de69a803fa (patch)
tree316a5bbeb6b5d98029a0996772dca1857fcb9059 /core/java/android/view/ViewAncestor.java
parenteaf7ce6067707fcebd58067135376af51858d2e5 (diff)
downloadframeworks_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.java75
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);
+ }
+ }
+ }
}