From 899c8f2ba668080bc663732f610b683222a1bb77 Mon Sep 17 00:00:00 2001 From: Jay Shrauner Date: Thu, 14 Aug 2014 09:59:37 -0700 Subject: Prevent ConcurrentModificationExceptions Switch from HashSets to Sets backed by ConcurrentHashMaps, and from ArrayLists to CopyOnWriteArrayLists, to prevent exceptions when listeners remove themselves in their callback while iterating through the set or list. Bug:17030803 Change-Id: I99511e56d77526796679e2840437d0ea47062830 --- .../src/com/android/incallui/InCallPresenter.java | 51 ++++++++++++++-------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/InCallUI/src/com/android/incallui/InCallPresenter.java b/InCallUI/src/com/android/incallui/InCallPresenter.java index 66890eb8c..23775212a 100644 --- a/InCallUI/src/com/android/incallui/InCallPresenter.java +++ b/InCallUI/src/com/android/incallui/InCallPresenter.java @@ -29,13 +29,13 @@ import android.view.Surface; import android.view.View; import com.google.common.base.Preconditions; -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; /** * Takes updates from the CallList and notifies the InCallActivity (UI) @@ -50,11 +50,21 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener { private static InCallPresenter sInCallPresenter; - private final Set mListeners = Sets.newHashSet(); - private final ArrayList mIncomingCallListeners = Lists.newArrayList(); - private final Set mDetailsListeners = Sets.newHashSet(); - private final Set mOrientationListeners = Sets.newHashSet(); - private final Set mInCallEventListeners = Sets.newHashSet(); + /** + * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is + * load factor before resizing, 1 means we only expect a single thread to + * access the map so make only a single shard + */ + private final Set mListeners = Collections.newSetFromMap( + new ConcurrentHashMap(8, 0.9f, 1)); + private final List mIncomingCallListeners = + new CopyOnWriteArrayList(); + private final Set mDetailsListeners = Collections.newSetFromMap( + new ConcurrentHashMap(8, 0.9f, 1)); + private final Set mOrientationListeners = Collections.newSetFromMap( + new ConcurrentHashMap(8, 0.9f, 1)); + private final Set mInCallEventListeners = Collections.newSetFromMap( + new ConcurrentHashMap(8, 0.9f, 1)); private AudioModeProvider mAudioModeProvider; private StatusBarNotifier mStatusBarNotifier; @@ -400,8 +410,9 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener { } public void removeIncomingCallListener(IncomingCallListener listener) { - Preconditions.checkNotNull(listener); - mIncomingCallListeners.remove(listener); + if (listener != null) { + mIncomingCallListeners.remove(listener); + } } public void addListener(InCallStateListener listener) { @@ -410,8 +421,9 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener { } public void removeListener(InCallStateListener listener) { - Preconditions.checkNotNull(listener); - mListeners.remove(listener); + if (listener != null) { + mListeners.remove(listener); + } } public void addDetailsListener(InCallDetailsListener listener) { @@ -420,8 +432,9 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener { } public void removeDetailsListener(InCallDetailsListener listener) { - Preconditions.checkNotNull(listener); - mDetailsListeners.remove(listener); + if (listener != null) { + mDetailsListeners.remove(listener); + } } public void addOrientationListener(InCallOrientationListener listener) { @@ -430,8 +443,9 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener { } public void removeOrientationListener(InCallOrientationListener listener) { - Preconditions.checkNotNull(listener); - mOrientationListeners.remove(listener); + if (listener != null) { + mOrientationListeners.remove(listener); + } } public void addInCallEventListener(InCallEventListener listener) { @@ -440,8 +454,9 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener { } public void removeInCallEventListener(InCallEventListener listener) { - Preconditions.checkNotNull(listener); - mInCallEventListeners.remove(listener); + if (listener != null) { + mInCallEventListeners.remove(listener); + } } public ProximitySensor getProximitySensor() { -- cgit v1.2.3