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
This commit is contained in:
@@ -459,7 +459,7 @@ public final class AccessibilityManager {
|
|||||||
*/
|
*/
|
||||||
public boolean addAccessibilityStateChangeListener(
|
public boolean addAccessibilityStateChangeListener(
|
||||||
@NonNull AccessibilityStateChangeListener listener) {
|
@NonNull AccessibilityStateChangeListener listener) {
|
||||||
// Final CopyOnArrayList - no lock needed.
|
// Final CopyOnWriteArrayList - no lock needed.
|
||||||
return mAccessibilityStateChangeListeners.add(listener);
|
return mAccessibilityStateChangeListeners.add(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -471,7 +471,7 @@ public final class AccessibilityManager {
|
|||||||
*/
|
*/
|
||||||
public boolean removeAccessibilityStateChangeListener(
|
public boolean removeAccessibilityStateChangeListener(
|
||||||
@NonNull AccessibilityStateChangeListener listener) {
|
@NonNull AccessibilityStateChangeListener listener) {
|
||||||
// Final CopyOnArrayList - no lock needed.
|
// Final CopyOnWriteArrayList - no lock needed.
|
||||||
return mAccessibilityStateChangeListeners.remove(listener);
|
return mAccessibilityStateChangeListeners.remove(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -484,7 +484,7 @@ public final class AccessibilityManager {
|
|||||||
*/
|
*/
|
||||||
public boolean addTouchExplorationStateChangeListener(
|
public boolean addTouchExplorationStateChangeListener(
|
||||||
@NonNull TouchExplorationStateChangeListener listener) {
|
@NonNull TouchExplorationStateChangeListener listener) {
|
||||||
// Final CopyOnArrayList - no lock needed.
|
// Final CopyOnWriteArrayList - no lock needed.
|
||||||
return mTouchExplorationStateChangeListeners.add(listener);
|
return mTouchExplorationStateChangeListeners.add(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -496,7 +496,7 @@ public final class AccessibilityManager {
|
|||||||
*/
|
*/
|
||||||
public boolean removeTouchExplorationStateChangeListener(
|
public boolean removeTouchExplorationStateChangeListener(
|
||||||
@NonNull TouchExplorationStateChangeListener listener) {
|
@NonNull TouchExplorationStateChangeListener listener) {
|
||||||
// Final CopyOnArrayList - no lock needed.
|
// Final CopyOnWriteArrayList - no lock needed.
|
||||||
return mTouchExplorationStateChangeListeners.remove(listener);
|
return mTouchExplorationStateChangeListeners.remove(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -511,7 +511,7 @@ public final class AccessibilityManager {
|
|||||||
*/
|
*/
|
||||||
public boolean addHighTextContrastStateChangeListener(
|
public boolean addHighTextContrastStateChangeListener(
|
||||||
@NonNull HighTextContrastChangeListener listener) {
|
@NonNull HighTextContrastChangeListener listener) {
|
||||||
// Final CopyOnArrayList - no lock needed.
|
// Final CopyOnWriteArrayList - no lock needed.
|
||||||
return mHighTextContrastStateChangeListeners.add(listener);
|
return mHighTextContrastStateChangeListeners.add(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -525,7 +525,7 @@ public final class AccessibilityManager {
|
|||||||
*/
|
*/
|
||||||
public boolean removeHighTextContrastStateChangeListener(
|
public boolean removeHighTextContrastStateChangeListener(
|
||||||
@NonNull HighTextContrastChangeListener listener) {
|
@NonNull HighTextContrastChangeListener listener) {
|
||||||
// Final CopyOnArrayList - no lock needed.
|
// Final CopyOnWriteArrayList - no lock needed.
|
||||||
return mHighTextContrastStateChangeListeners.remove(listener);
|
return mHighTextContrastStateChangeListeners.remove(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -640,9 +640,9 @@ public final class AccessibilityManager {
|
|||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
isEnabled = mIsEnabled;
|
isEnabled = mIsEnabled;
|
||||||
}
|
}
|
||||||
final int listenerCount = mAccessibilityStateChangeListeners.size();
|
// Listeners are a final CopyOnWriteArrayList, hence no lock needed.
|
||||||
for (int i = 0; i < listenerCount; i++) {
|
for (AccessibilityStateChangeListener listener :mAccessibilityStateChangeListeners) {
|
||||||
mAccessibilityStateChangeListeners.get(i).onAccessibilityStateChanged(isEnabled);
|
listener.onAccessibilityStateChanged(isEnabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -654,10 +654,9 @@ public final class AccessibilityManager {
|
|||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
isTouchExplorationEnabled = mIsTouchExplorationEnabled;
|
isTouchExplorationEnabled = mIsTouchExplorationEnabled;
|
||||||
}
|
}
|
||||||
final int listenerCount = mTouchExplorationStateChangeListeners.size();
|
// Listeners are a final CopyOnWriteArrayList, hence no lock needed.
|
||||||
for (int i = 0; i < listenerCount; i++) {
|
for (TouchExplorationStateChangeListener listener :mTouchExplorationStateChangeListeners) {
|
||||||
mTouchExplorationStateChangeListeners.get(i)
|
listener.onTouchExplorationStateChanged(isTouchExplorationEnabled);
|
||||||
.onTouchExplorationStateChanged(isTouchExplorationEnabled);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -669,10 +668,9 @@ public final class AccessibilityManager {
|
|||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
isHighTextContrastEnabled = mIsHighTextContrastEnabled;
|
isHighTextContrastEnabled = mIsHighTextContrastEnabled;
|
||||||
}
|
}
|
||||||
final int listenerCount = mHighTextContrastStateChangeListeners.size();
|
// Listeners are a final CopyOnWriteArrayList, hence no lock needed.
|
||||||
for (int i = 0; i < listenerCount; i++) {
|
for (HighTextContrastChangeListener listener : mHighTextContrastStateChangeListeners) {
|
||||||
mHighTextContrastStateChangeListeners.get(i)
|
listener.onHighTextContrastStateChanged(isHighTextContrastEnabled);
|
||||||
.onHighTextContrastStateChanged(isHighTextContrastEnabled);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user