summaryrefslogtreecommitdiffstats
path: root/core/java/android/view/accessibility
diff options
context:
space:
mode:
authorSvetoslav <svetoslavganov@google.com>2014-12-29 09:40:42 -0800
committerSvetoslav <svetoslavganov@google.com>2014-12-29 09:40:46 -0800
commite5ea48a7fe295a2815bab57f2e870901ce48b312 (patch)
tree3dae9c11cf3c951d79d2e8c2d76e9391abb133d0 /core/java/android/view/accessibility
parentaf84e073bce12c6ae0c737339804e96314bb663d (diff)
downloadframeworks_base-e5ea48a7fe295a2815bab57f2e870901ce48b312.zip
frameworks_base-e5ea48a7fe295a2815bab57f2e870901ce48b312.tar.gz
frameworks_base-e5ea48a7fe295a2815bab57f2e870901ce48b312.tar.bz2
Fix a race in accessibility manager.
The accessibility manager has APIs for clients to observe changes in accessibility, touch exploration, and high contrast states. The notification of the listeners has to be done with no lock held but in an attempt to do that the code was incorrectly iterating over the copy on write collection. bug:18840784 Change-Id: I6803ff1657fbf6b0cc7936671d5bbdebb5cbf6bb
Diffstat (limited to 'core/java/android/view/accessibility')
-rw-r--r--core/java/android/view/accessibility/AccessibilityManager.java32
1 files changed, 15 insertions, 17 deletions
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index c3b17db..e77b862 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -459,7 +459,7 @@ public final class AccessibilityManager {
*/
public boolean addAccessibilityStateChangeListener(
@NonNull AccessibilityStateChangeListener listener) {
- // Final CopyOnArrayList - no lock needed.
+ // Final CopyOnWriteArrayList - no lock needed.
return mAccessibilityStateChangeListeners.add(listener);
}
@@ -471,7 +471,7 @@ public final class AccessibilityManager {
*/
public boolean removeAccessibilityStateChangeListener(
@NonNull AccessibilityStateChangeListener listener) {
- // Final CopyOnArrayList - no lock needed.
+ // Final CopyOnWriteArrayList - no lock needed.
return mAccessibilityStateChangeListeners.remove(listener);
}
@@ -484,7 +484,7 @@ public final class AccessibilityManager {
*/
public boolean addTouchExplorationStateChangeListener(
@NonNull TouchExplorationStateChangeListener listener) {
- // Final CopyOnArrayList - no lock needed.
+ // Final CopyOnWriteArrayList - no lock needed.
return mTouchExplorationStateChangeListeners.add(listener);
}
@@ -496,7 +496,7 @@ public final class AccessibilityManager {
*/
public boolean removeTouchExplorationStateChangeListener(
@NonNull TouchExplorationStateChangeListener listener) {
- // Final CopyOnArrayList - no lock needed.
+ // Final CopyOnWriteArrayList - no lock needed.
return mTouchExplorationStateChangeListeners.remove(listener);
}
@@ -511,7 +511,7 @@ public final class AccessibilityManager {
*/
public boolean addHighTextContrastStateChangeListener(
@NonNull HighTextContrastChangeListener listener) {
- // Final CopyOnArrayList - no lock needed.
+ // Final CopyOnWriteArrayList - no lock needed.
return mHighTextContrastStateChangeListeners.add(listener);
}
@@ -525,7 +525,7 @@ public final class AccessibilityManager {
*/
public boolean removeHighTextContrastStateChangeListener(
@NonNull HighTextContrastChangeListener listener) {
- // Final CopyOnArrayList - no lock needed.
+ // Final CopyOnWriteArrayList - no lock needed.
return mHighTextContrastStateChangeListeners.remove(listener);
}
@@ -640,9 +640,9 @@ public final class AccessibilityManager {
synchronized (mLock) {
isEnabled = mIsEnabled;
}
- final int listenerCount = mAccessibilityStateChangeListeners.size();
- for (int i = 0; i < listenerCount; i++) {
- mAccessibilityStateChangeListeners.get(i).onAccessibilityStateChanged(isEnabled);
+ // Listeners are a final CopyOnWriteArrayList, hence no lock needed.
+ for (AccessibilityStateChangeListener listener :mAccessibilityStateChangeListeners) {
+ listener.onAccessibilityStateChanged(isEnabled);
}
}
@@ -654,10 +654,9 @@ public final class AccessibilityManager {
synchronized (mLock) {
isTouchExplorationEnabled = mIsTouchExplorationEnabled;
}
- final int listenerCount = mTouchExplorationStateChangeListeners.size();
- for (int i = 0; i < listenerCount; i++) {
- mTouchExplorationStateChangeListeners.get(i)
- .onTouchExplorationStateChanged(isTouchExplorationEnabled);
+ // Listeners are a final CopyOnWriteArrayList, hence no lock needed.
+ for (TouchExplorationStateChangeListener listener :mTouchExplorationStateChangeListeners) {
+ listener.onTouchExplorationStateChanged(isTouchExplorationEnabled);
}
}
@@ -669,10 +668,9 @@ public final class AccessibilityManager {
synchronized (mLock) {
isHighTextContrastEnabled = mIsHighTextContrastEnabled;
}
- final int listenerCount = mHighTextContrastStateChangeListeners.size();
- for (int i = 0; i < listenerCount; i++) {
- mHighTextContrastStateChangeListeners.get(i)
- .onHighTextContrastStateChanged(isHighTextContrastEnabled);
+ // Listeners are a final CopyOnWriteArrayList, hence no lock needed.
+ for (HighTextContrastChangeListener listener : mHighTextContrastStateChangeListeners) {
+ listener.onHighTextContrastStateChanged(isHighTextContrastEnabled);
}
}