From fb1e80a247221ee7e8f5c5deba04812021d9d07e Mon Sep 17 00:00:00 2001 From: Svetoslav Ganov Date: Wed, 16 May 2012 17:33:19 -0700 Subject: Exposing some accessiblity actions only for enabled views. 1. Some accessibility actions should not be performed on disabled views. For example, scrolling should not be permitted while accessibility focus should be. Made a quick pass over the actions we expose now. Change-Id: I36626dfbc0d2f480309a910f58f1de64e9e05675 --- core/java/android/view/View.java | 4 +- core/java/android/widget/AbsListView.java | 52 ++++++++++++-------- core/java/android/widget/Gallery.java | 16 +++--- core/java/android/widget/HorizontalScrollView.java | 10 +++- core/java/android/widget/NumberPicker.java | 57 ++++++++++++++-------- core/java/android/widget/ScrollView.java | 21 +++++--- core/java/android/widget/StackView.java | 15 ++++-- core/java/android/widget/TextView.java | 3 +- 8 files changed, 110 insertions(+), 68 deletions(-) diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index a4fcd41..f698e57 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -4776,11 +4776,11 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS); } - if (isClickable()) { + if (isClickable() && isEnabled()) { info.addAction(AccessibilityNodeInfo.ACTION_CLICK); } - if (isLongClickable()) { + if (isLongClickable() && isEnabled()) { info.addAction(AccessibilityNodeInfo.ACTION_LONG_CLICK); } diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 04c8cdc..8643e9e 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -1470,11 +1470,13 @@ public abstract class AbsListView extends AdapterView implements Te public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(info); info.setClassName(AbsListView.class.getName()); - if (getFirstVisiblePosition() > 0) { - info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD); - } - if (getLastVisiblePosition() < getCount() - 1) { - info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD); + if (isEnabled()) { + if (getFirstVisiblePosition() > 0) { + info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD); + } + if (getLastVisiblePosition() < getCount() - 1) { + info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD); + } } } @@ -1485,14 +1487,14 @@ public abstract class AbsListView extends AdapterView implements Te } switch (action) { case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: { - if (getLastVisiblePosition() < getCount() - 1) { + if (isEnabled() && getLastVisiblePosition() < getCount() - 1) { final int viewportHeight = getHeight() - mListPadding.top - mListPadding.bottom; smoothScrollBy(viewportHeight, PositionScroller.SCROLL_DURATION); return true; } } return false; case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: { - if (mFirstPosition > 0) { + if (isEnabled() && mFirstPosition > 0) { final int viewportHeight = getHeight() - mListPadding.top - mListPadding.bottom; smoothScrollBy(-viewportHeight, PositionScroller.SCROLL_DURATION); return true; @@ -2294,17 +2296,19 @@ public abstract class AbsListView extends AdapterView implements Te return; } - if (isClickable()) { + if (isClickable() && isEnabled()) { info.addAction(AccessibilityNodeInfo.ACTION_CLICK); info.setClickable(true); } - if (isLongClickable()) { + if (isLongClickable() && isEnabled()) { info.addAction(AccessibilityNodeInfo.ACTION_LONG_CLICK); info.setLongClickable(true); } - info.addAction(AccessibilityNodeInfo.ACTION_SELECT); + if (isEnabled()) { + info.addAction(AccessibilityNodeInfo.ACTION_SELECT); + } if (position == getSelectedItemPosition()) { info.setSelected(true); @@ -2313,34 +2317,40 @@ public abstract class AbsListView extends AdapterView implements Te @Override public boolean performAccessibilityAction(View host, int action, Bundle arguments) { + if (super.performAccessibilityAction(host, action, arguments)) { + return true; + } + final int position = getPositionForView(host); if (position == INVALID_POSITION) { return false; } + if (!isEnabled()) { + return false; + } + final long id = getItemIdAtPosition(position); switch (action) { - case AccessibilityNodeInfo.ACTION_SELECT: + case AccessibilityNodeInfo.ACTION_SELECT: { setSelection(position); return true; - case AccessibilityNodeInfo.ACTION_CLICK: - if (!super.performAccessibilityAction(host, action, arguments)) { + } + case AccessibilityNodeInfo.ACTION_CLICK: { + if (isClickable()) { return performItemClick(host, position, id); } - return true; - case AccessibilityNodeInfo.ACTION_LONG_CLICK: - if (!super.performAccessibilityAction(host, action, arguments)) { + } return false; + case AccessibilityNodeInfo.ACTION_LONG_CLICK: { + if (isLongClickable()) { return performLongPress(host, position, id); } - return true; - case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS: - smoothScrollToPosition(position); - break; + } return false; } - return super.performAccessibilityAction(host, action, arguments); + return false; } } diff --git a/core/java/android/widget/Gallery.java b/core/java/android/widget/Gallery.java index b2c8164..6658fc2 100644 --- a/core/java/android/widget/Gallery.java +++ b/core/java/android/widget/Gallery.java @@ -1369,11 +1369,13 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList super.onInitializeAccessibilityNodeInfo(info); info.setClassName(Gallery.class.getName()); info.setScrollable(mItemCount > 1); - if (mItemCount > 0 && mSelectedPosition < mItemCount - 1) { - info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD); - } - if (mItemCount > 0 && mSelectedPosition > 0) { - info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD); + if (isEnabled()) { + if (mItemCount > 0 && mSelectedPosition < mItemCount - 1) { + info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD); + } + if (isEnabled() && mItemCount > 0 && mSelectedPosition > 0) { + info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD); + } } } @@ -1384,13 +1386,13 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList } switch (action) { case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: { - if (mItemCount > 0 && mSelectedPosition < mItemCount - 1) { + if (isEnabled() && mItemCount > 0 && mSelectedPosition < mItemCount - 1) { final int currentChildIndex = mSelectedPosition - mFirstPosition; return scrollToChild(currentChildIndex + 1); } } return false; case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: { - if (mItemCount > 0 && mSelectedPosition > 0) { + if (isEnabled() && mItemCount > 0 && mSelectedPosition > 0) { final int currentChildIndex = mSelectedPosition - mFirstPosition; return scrollToChild(currentChildIndex - 1); } diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java index f889cb7..8c6ce19 100644 --- a/core/java/android/widget/HorizontalScrollView.java +++ b/core/java/android/widget/HorizontalScrollView.java @@ -744,6 +744,9 @@ public class HorizontalScrollView extends FrameLayout { } switch (action) { case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: { + if (!isEnabled()) { + return false; + } final int viewportWidth = getWidth() - mPaddingLeft - mPaddingRight; final int targetScrollX = Math.min(mScrollX + viewportWidth, getScrollRange()); if (targetScrollX != mScrollX) { @@ -752,6 +755,9 @@ public class HorizontalScrollView extends FrameLayout { } } return false; case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: { + if (!isEnabled()) { + return false; + } final int viewportWidth = getWidth() - mPaddingLeft - mPaddingRight; final int targetScrollX = Math.max(0, mScrollX - viewportWidth); if (targetScrollX != mScrollX) { @@ -770,10 +776,10 @@ public class HorizontalScrollView extends FrameLayout { final int scrollRange = getScrollRange(); if (scrollRange > 0) { info.setScrollable(true); - if (mScrollX > 0) { + if (isEnabled() && mScrollX > 0) { info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD); } - if (mScrollX < scrollRange) { + if (isEnabled() && mScrollX < scrollRange) { info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD); } } diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java index b825e1b..16b8afa 100644 --- a/core/java/android/widget/NumberPicker.java +++ b/core/java/android/widget/NumberPicker.java @@ -2173,13 +2173,15 @@ public class NumberPicker extends LinearLayout { return false; } case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: { - if (getWrapSelectorWheel() || getValue() < getMaxValue()) { + if (NumberPicker.this.isEnabled() + && (getWrapSelectorWheel() || getValue() < getMaxValue())) { changeValueByOne(true); return true; } } return false; case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: { - if (getWrapSelectorWheel() || getValue() > getMinValue()) { + if (NumberPicker.this.isEnabled() + && (getWrapSelectorWheel() || getValue() > getMinValue())) { changeValueByOne(false); return true; } @@ -2189,20 +2191,23 @@ public class NumberPicker extends LinearLayout { case VIRTUAL_VIEW_ID_INPUT: { switch (action) { case AccessibilityNodeInfo.ACTION_FOCUS: { - if (!mInputText.isFocused()) { + if (NumberPicker.this.isEnabled() && !mInputText.isFocused()) { return mInputText.requestFocus(); } } break; case AccessibilityNodeInfo.ACTION_CLEAR_FOCUS: { - if (mInputText.isFocused()) { + if (NumberPicker.this.isEnabled() && mInputText.isFocused()) { mInputText.clearFocus(); return true; } return false; } case AccessibilityNodeInfo.ACTION_CLICK: { - showSoftInput(); - return true; + if (NumberPicker.this.isEnabled()) { + showSoftInput(); + return true; + } + return false; } case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS: { if (mAccessibilityFocusedView != virtualViewId) { @@ -2230,10 +2235,13 @@ public class NumberPicker extends LinearLayout { case VIRTUAL_VIEW_ID_INCREMENT: { switch (action) { case AccessibilityNodeInfo.ACTION_CLICK: { - NumberPicker.this.changeValueByOne(true); - sendAccessibilityEventForVirtualView(virtualViewId, - AccessibilityEvent.TYPE_VIEW_CLICKED); - } return true; + if (NumberPicker.this.isEnabled()) { + NumberPicker.this.changeValueByOne(true); + sendAccessibilityEventForVirtualView(virtualViewId, + AccessibilityEvent.TYPE_VIEW_CLICKED); + return true; + } + } return false; case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS: { if (mAccessibilityFocusedView != virtualViewId) { mAccessibilityFocusedView = virtualViewId; @@ -2257,11 +2265,14 @@ public class NumberPicker extends LinearLayout { case VIRTUAL_VIEW_ID_DECREMENT: { switch (action) { case AccessibilityNodeInfo.ACTION_CLICK: { - final boolean increment = (virtualViewId == VIRTUAL_VIEW_ID_INCREMENT); - NumberPicker.this.changeValueByOne(increment); - sendAccessibilityEventForVirtualView(virtualViewId, - AccessibilityEvent.TYPE_VIEW_CLICKED); - } return true; + if (NumberPicker.this.isEnabled()) { + final boolean increment = (virtualViewId == VIRTUAL_VIEW_ID_INCREMENT); + NumberPicker.this.changeValueByOne(increment); + sendAccessibilityEventForVirtualView(virtualViewId, + AccessibilityEvent.TYPE_VIEW_CLICKED); + return true; + } + } return false; case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS: { if (mAccessibilityFocusedView != virtualViewId) { mAccessibilityFocusedView = virtualViewId; @@ -2470,7 +2481,9 @@ public class NumberPicker extends LinearLayout { if (mAccessibilityFocusedView == virtualViewId) { info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS); } - info.addAction(AccessibilityNodeInfo.ACTION_CLICK); + if (NumberPicker.this.isEnabled()) { + info.addAction(AccessibilityNodeInfo.ACTION_CLICK); + } return info; } @@ -2509,11 +2522,13 @@ public class NumberPicker extends LinearLayout { if (mAccessibilityFocusedView == View.NO_ID) { info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS); } - if (getWrapSelectorWheel() || getValue() < getMaxValue()) { - info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD); - } - if (getWrapSelectorWheel() || getValue() > getMinValue()) { - info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD); + if (NumberPicker.this.isEnabled()) { + if (getWrapSelectorWheel() || getValue() < getMaxValue()) { + info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD); + } + if (getWrapSelectorWheel() || getValue() > getMinValue()) { + info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD); + } } return info; diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java index a499743..2a20c56 100644 --- a/core/java/android/widget/ScrollView.java +++ b/core/java/android/widget/ScrollView.java @@ -745,6 +745,9 @@ public class ScrollView extends FrameLayout { if (super.performAccessibilityAction(action, arguments)) { return true; } + if (!isEnabled()) { + return false; + } switch (action) { case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: { final int viewportHeight = getHeight() - mPaddingBottom - mPaddingTop; @@ -770,14 +773,16 @@ public class ScrollView extends FrameLayout { public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(info); info.setClassName(ScrollView.class.getName()); - final int scrollRange = getScrollRange(); - if (scrollRange > 0) { - info.setScrollable(true); - if (mScrollY > 0) { - info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD); - } - if (mScrollY < scrollRange) { - info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD); + if (isEnabled()) { + final int scrollRange = getScrollRange(); + if (scrollRange > 0) { + info.setScrollable(true); + if (mScrollY > 0) { + info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD); + } + if (mScrollY < scrollRange) { + info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD); + } } } } diff --git a/core/java/android/widget/StackView.java b/core/java/android/widget/StackView.java index dd0915b..293eda1 100644 --- a/core/java/android/widget/StackView.java +++ b/core/java/android/widget/StackView.java @@ -1230,11 +1230,13 @@ public class StackView extends AdapterViewAnimator { super.onInitializeAccessibilityNodeInfo(info); info.setClassName(StackView.class.getName()); info.setScrollable(getChildCount() > 1); - if (getDisplayedChild() < getChildCount() - 1) { - info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD); - } - if (getDisplayedChild() > 0) { - info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD); + if (isEnabled()) { + if (getDisplayedChild() < getChildCount() - 1) { + info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD); + } + if (getDisplayedChild() > 0) { + info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD); + } } } @@ -1243,6 +1245,9 @@ public class StackView extends AdapterViewAnimator { if (super.performAccessibilityAction(action, arguments)) { return true; } + if (!isEnabled()) { + return false; + } switch (action) { case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: { if (getDisplayedChild() < getChildCount() - 1) { diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index fc56e11..112881c 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -7739,8 +7739,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener info.setText(getTextForAccessibility()); } - if (TextUtils.isEmpty(getContentDescription()) - && !TextUtils.isEmpty(mText)) { + if (TextUtils.isEmpty(getContentDescription()) && !TextUtils.isEmpty(mText)) { info.addAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY); info.addAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY); info.setMovementGranularities(AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER -- cgit v1.1