From 9c3e0e68260fe50456996d75304b73054cbde94a Mon Sep 17 00:00:00 2001 From: alanv Date: Fri, 18 May 2012 17:43:35 -0700 Subject: [PATCH] Fix accessibility actions in AbsListView. Check adapter for position enabled state, check selection index. Bug: 6508142 Change-Id: If25a133533a7316ef7eba8761522bd2ee4f6338d --- core/java/android/widget/AbsListView.java | 58 +++++++++++++++-------- 1 file changed, 39 insertions(+), 19 deletions(-) diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 8643e9eaaed73..31824f33b740f 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -1451,7 +1451,7 @@ public abstract class AbsListView extends AdapterView implements Te final int lastVisiblePosition = getLastVisiblePosition(); if (mLastAccessibilityScrollEventFromIndex == firstVisiblePosition && mLastAccessibilityScrollEventToIndex == lastVisiblePosition) { - return; + return; } else { mLastAccessibilityScrollEventFromIndex = firstVisiblePosition; mLastAccessibilityScrollEventToIndex = lastVisiblePosition; @@ -2291,28 +2291,37 @@ public abstract class AbsListView extends AdapterView implements Te super.onInitializeAccessibilityNodeInfo(host, info); final int position = getPositionForView(host); + final ListAdapter adapter = getAdapter(); - if (position == INVALID_POSITION) { + if ((position == INVALID_POSITION) || (adapter == null)) { + // Cannot perform actions on invalid items. + info.setEnabled(false); return; } - if (isClickable() && isEnabled()) { - info.addAction(AccessibilityNodeInfo.ACTION_CLICK); - info.setClickable(true); - } - - if (isLongClickable() && isEnabled()) { - info.addAction(AccessibilityNodeInfo.ACTION_LONG_CLICK); - info.setLongClickable(true); - } - - if (isEnabled()) { - info.addAction(AccessibilityNodeInfo.ACTION_SELECT); + if (!isEnabled() || !adapter.isEnabled(position)) { + // Cannot perform actions on invalid items. + info.setEnabled(false); + return; } if (position == getSelectedItemPosition()) { info.setSelected(true); + info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_SELECTION); + } else { + info.addAction(AccessibilityNodeInfo.ACTION_SELECT); } + + if (isClickable()) { + info.addAction(AccessibilityNodeInfo.ACTION_CLICK); + info.setClickable(true); + } + + if (isLongClickable()) { + info.addAction(AccessibilityNodeInfo.ACTION_LONG_CLICK); + info.setLongClickable(true); + } + } @Override @@ -2322,22 +2331,33 @@ public abstract class AbsListView extends AdapterView implements Te } final int position = getPositionForView(host); + final ListAdapter adapter = getAdapter(); - if (position == INVALID_POSITION) { + if ((position == INVALID_POSITION) || (adapter == null)) { + // Cannot perform actions on invalid items. return false; } - if (!isEnabled()) { + if (!isEnabled() || !adapter.isEnabled(position)) { + // Cannot perform actions on disabled items. return false; } final long id = getItemIdAtPosition(position); switch (action) { + case AccessibilityNodeInfo.ACTION_CLEAR_SELECTION: { + if (getSelectedItemPosition() == position) { + setSelection(INVALID_POSITION); + return true; + } + } return false; case AccessibilityNodeInfo.ACTION_SELECT: { - setSelection(position); - return true; - } + if (getSelectedItemPosition() != position) { + setSelection(position); + return true; + } + } return false; case AccessibilityNodeInfo.ACTION_CLICK: { if (isClickable()) { return performItemClick(host, position, id);