Merge "Accessibility services cannot obtain the source of an event coming from a root namespace descendant."

This commit is contained in:
Svetoslav Ganov
2011-10-03 17:43:39 -07:00
committed by Android (Google) Code Review
5 changed files with 66 additions and 27 deletions

View File

@@ -12092,6 +12092,39 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
return findViewTraversal(id);
}
/**
* Finds a view by its unuque and stable accessibility id.
*
* @param accessibilityId The searched accessibility id.
* @return The found view.
*/
final View findViewByAccessibilityId(int accessibilityId) {
if (accessibilityId < 0) {
return null;
}
return findViewByAccessibilityIdTraversal(accessibilityId);
}
/**
* Performs the traversal to find a view by its unuque and stable accessibility id.
*
* <strong>Note:</strong>This method does not stop at the root namespace
* boundary since the user can touch the screen at an arbitrary location
* potentially crossing the root namespace bounday which will send an
* accessibility event to accessibility services and they should be able
* to obtain the event source. Also accessibility ids are guaranteed to be
* unique in the window.
*
* @param accessibilityId The accessibility id.
* @return The found view.
*/
View findViewByAccessibilityIdTraversal(int accessibilityId) {
if (getAccessibilityViewId() == accessibilityId) {
return this;
}
return null;
}
/**
* Look for a child view with the given tag. If this view has the given
* tag, return this view.

View File

@@ -821,6 +821,24 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
}
@Override
View findViewByAccessibilityIdTraversal(int accessibilityId) {
View foundView = super.findViewByAccessibilityIdTraversal(accessibilityId);
if (foundView != null) {
return foundView;
}
final int childrenCount = mChildrenCount;
final View[] children = mChildren;
for (int i = 0; i < childrenCount; i++) {
View child = children[i];
foundView = child.findViewByAccessibilityIdTraversal(accessibilityId);
if (foundView != null) {
return foundView;
}
}
return null;
}
/**
* {@inheritDoc}
*/

View File

@@ -74,7 +74,6 @@ import android.view.inputmethod.InputMethodManager;
import android.widget.Scroller;
import com.android.internal.policy.PolicyManager;
import com.android.internal.util.Predicate;
import com.android.internal.view.BaseSurfaceHolder;
import com.android.internal.view.IInputMethodCallback;
import com.android.internal.view.IInputMethodSession;
@@ -4462,9 +4461,6 @@ public final class ViewRootImpl extends Handler implements ViewParent,
final class AccessibilityInteractionController {
private static final int POOL_SIZE = 5;
private FindByAccessibilitytIdPredicate mFindByAccessibilityIdPredicate =
new FindByAccessibilitytIdPredicate();
private ArrayList<AccessibilityNodeInfo> mTempAccessibilityNodeInfoList =
new ArrayList<AccessibilityNodeInfo>();
@@ -4551,11 +4547,8 @@ public final class ViewRootImpl extends Handler implements ViewParent,
AccessibilityNodeInfo info = null;
try {
FindByAccessibilitytIdPredicate predicate = mFindByAccessibilityIdPredicate;
predicate.init(accessibilityId);
View root = ViewRootImpl.this.mView;
View target = root.findViewByPredicate(predicate);
if (target != null && target.getVisibility() == View.VISIBLE) {
View target = findViewByAccessibilityId(accessibilityId);
if (target != null) {
info = target.createAccessibilityNodeInfo();
}
} finally {
@@ -4794,25 +4787,12 @@ public final class ViewRootImpl extends Handler implements ViewParent,
if (root == null) {
return null;
}
mFindByAccessibilityIdPredicate.init(accessibilityId);
View foundView = root.findViewByPredicate(mFindByAccessibilityIdPredicate);
if (foundView == null || foundView.getVisibility() != View.VISIBLE) {
View foundView = root.findViewByAccessibilityId(accessibilityId);
if (foundView != null && foundView.getVisibility() != View.VISIBLE) {
return null;
}
return foundView;
}
private final class FindByAccessibilitytIdPredicate implements Predicate<View> {
public int mSearchedId;
public void init(int searchedId) {
mSearchedId = searchedId;
}
public boolean apply(View view) {
return (view.getAccessibilityViewId() == mSearchedId);
}
}
}
private class SendWindowContentChangedAccessibilityEvent implements Runnable {

View File

@@ -25,6 +25,7 @@ import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.text.format.DateUtils;
import android.text.format.Time;
import android.util.AttributeSet;
import android.view.View;
@@ -228,6 +229,8 @@ public class AnalogClock extends View {
mMinutes = minute + second / 60.0f;
mHour = hour + mMinutes / 60.0f;
mChanged = true;
updateContentDescription(mCalendar);
}
private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@@ -243,4 +246,11 @@ public class AnalogClock extends View {
invalidate();
}
};
private void updateContentDescription(Time time) {
final int flags = DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_24HOUR;
String contentDescription = DateUtils.formatDateTime(mContext,
time.toMillis(false), flags);
setContentDescription(contentDescription);
}
}

View File

@@ -237,9 +237,7 @@ public class TimePicker extends FrameLayout {
}
// set the content descriptions
if (AccessibilityManager.getInstance(mContext).isEnabled()) {
setContentDescriptions();
}
setContentDescriptions();
}
@Override