diff options
| -rw-r--r-- | packages/SystemUI/src/com/android/systemui/util/condition/Monitor.java | 10 | ||||
| -rw-r--r-- | packages/SystemUI/tests/src/com/android/systemui/util/condition/ConditionMonitorTest.java | 18 |
2 files changed, 27 insertions, 1 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/util/condition/Monitor.java b/packages/SystemUI/src/com/android/systemui/util/condition/Monitor.java index 4e9030f8045c..dac8a0bff28a 100644 --- a/packages/SystemUI/src/com/android/systemui/util/condition/Monitor.java +++ b/packages/SystemUI/src/com/android/systemui/util/condition/Monitor.java @@ -92,7 +92,15 @@ public class Monitor { } private void updateConditionMetState(Condition condition) { - mConditions.get(condition).stream().forEach(token -> mSubscriptions.get(token).update()); + final ArraySet<Subscription.Token> subscriptions = mConditions.get(condition); + + // It's possible the condition was removed between the time the callback occurred and + // update was executed on the main thread. + if (subscriptions == null) { + return; + } + + subscriptions.stream().forEach(token -> mSubscriptions.get(token).update()); } /** diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/condition/ConditionMonitorTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/condition/ConditionMonitorTest.java index 1e35b0f0e68a..125b3627b342 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/util/condition/ConditionMonitorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/util/condition/ConditionMonitorTest.java @@ -159,6 +159,24 @@ public class ConditionMonitorTest extends SysuiTestCase { Mockito.clearInvocations(callback); } + // Ensure that updating a callback that is removed doesn't result in an exception due to the + // absence of the condition. + @Test + public void testUpdateRemovedCallback() { + final Monitor.Callback callback1 = + mock(Monitor.Callback.class); + final Monitor.Subscription.Token subscription1 = + mConditionMonitor.addSubscription(getDefaultBuilder(callback1).build()); + ArgumentCaptor<Condition.Callback> monitorCallback = + ArgumentCaptor.forClass(Condition.Callback.class); + mExecutor.runAllReady(); + verify(mCondition1).addCallback(monitorCallback.capture()); + // This will execute first before the handler for onConditionChanged. + mConditionMonitor.removeSubscription(subscription1); + monitorCallback.getValue().onConditionChanged(mCondition1); + mExecutor.runAllReady(); + } + @Test public void addCallback_addFirstCallback_addCallbackToAllConditions() { final Monitor.Callback callback1 = |