diff --git a/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java b/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java index c5a66a7c7fe2f..19c477dfe0a53 100644 --- a/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java +++ b/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java @@ -86,9 +86,12 @@ public class ProximitySensor implements ThresholdSensor { public void onThresholdCrossed(ThresholdSensorEvent event) { // If we no longer have a "below" signal and the secondary sensor is not // considered "safe", then we need to turn it off. - if (!mSecondarySafe && (!mLastPrimaryEvent.getBelow() || !event.getBelow())) { + if (!mSecondarySafe + && (mLastPrimaryEvent == null + || !mLastPrimaryEvent.getBelow() + || !event.getBelow())) { mSecondaryThresholdSensor.pause(); - if (!mLastPrimaryEvent.getBelow()) { + if (mLastPrimaryEvent == null || !mLastPrimaryEvent.getBelow()) { // Only check the secondary as long as the primary thinks we're near. mCancelSecondaryRunnable = null; return; @@ -100,7 +103,9 @@ public class ProximitySensor implements ThresholdSensor { } logDebug("Secondary sensor event: " + event.getBelow() + "."); - onSensorEvent(event); + if (!mPaused) { + onSensorEvent(event); + } } }; @@ -252,9 +257,10 @@ public class ProximitySensor implements ThresholdSensor { return; } if (mLastEvent != null) { + ThresholdSensorEvent lastEvent = mLastEvent; // Listeners can null out mLastEvent. List listeners = new ArrayList<>(mListeners); listeners.forEach(proximitySensorListener -> - proximitySensorListener.onThresholdCrossed(mLastEvent)); + proximitySensorListener.onThresholdCrossed(lastEvent)); } mAlerting.set(false); diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorDualTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorDualTest.java index bb498d7bdefdc..bae1d98aa3102 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorDualTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorDualTest.java @@ -152,6 +152,32 @@ public class ProximitySensorDualTest extends SysuiTestCase { assertFalse(mProximitySensor.isRegistered()); } + @Test + public void testUnregisterDuringCallback() { + ThresholdSensor.Listener listenerA = event -> mProximitySensor.pause(); + TestableListener listenerB = new TestableListener(); + + assertFalse(mProximitySensor.isRegistered()); + mProximitySensor.register(listenerA); + mProximitySensor.register(listenerB); + assertTrue(mProximitySensor.isRegistered()); + assertFalse(mThresholdSensorPrimary.isPaused()); + assertTrue(mThresholdSensorSecondary.isPaused()); + assertNull(listenerB.mLastEvent); + + // listenerA will pause the proximity sensor, unregistering it. + mThresholdSensorPrimary.triggerEvent(true, 0); + mThresholdSensorSecondary.triggerEvent(true, 0); + assertTrue(listenerB.mLastEvent.getBelow()); + assertEquals(1, listenerB.mCallCount); + + + // A second call to trigger it should be ignored. + mThresholdSensorSecondary.triggerEvent(false, 0); + assertTrue(listenerB.mLastEvent.getBelow()); + assertEquals(1, listenerB.mCallCount); + } + @Test public void testPauseAndResume() { TestableListener listener = new TestableListener();