diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java index 59aba3edce013..aebf41b884c4f 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java @@ -37,6 +37,7 @@ import android.os.UserHandle; import android.provider.Settings; import android.text.TextUtils; import android.util.Log; +import android.view.Display; import androidx.annotation.VisibleForTesting; @@ -266,6 +267,13 @@ public class DozeSensors { } } + void onScreenState(int state) { + mProximitySensor.setSecondarySafe( + state == Display.STATE_DOZE + || state == Display.STATE_DOZE_SUSPEND + || state == Display.STATE_OFF); + } + public void setProxListening(boolean listen) { if (mProximitySensor.isRegistered() && listen) { mProximitySensor.alertListeners(); diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java index d02cafbf277c0..c4e69755afeac 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java @@ -423,6 +423,7 @@ public class DozeTriggers implements DozeMachine.Part { @Override public void onScreenState(int state) { + mDozeSensors.onScreenState(state); if (state == Display.STATE_DOZE || state == Display.STATE_DOZE_SUSPEND || state == Display.STATE_OFF) { mDozeSensors.setProxListening(mWantProx); 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 ff7716a85ae1c..c5a66a7c7fe2f 100644 --- a/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java +++ b/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java @@ -72,6 +72,7 @@ public class ProximitySensor implements ThresholdSensor { private final AtomicBoolean mAlerting = new AtomicBoolean(); private Runnable mCancelSecondaryRunnable; private boolean mInitializedListeners = false; + private boolean mSecondarySafe = false; private ThresholdSensor.Listener mPrimaryEventListener = new ThresholdSensor.Listener() { @Override @@ -83,21 +84,22 @@ public class ProximitySensor implements ThresholdSensor { private ThresholdSensor.Listener mSecondaryEventListener = new ThresholdSensor.Listener() { @Override public void onThresholdCrossed(ThresholdSensorEvent event) { - // Only check the secondary as long as the primary thinks we're near. - if (!mLastPrimaryEvent.getBelow()) { + // 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())) { mSecondaryThresholdSensor.pause(); - mCancelSecondaryRunnable = null; - return; + if (!mLastPrimaryEvent.getBelow()) { + // Only check the secondary as long as the primary thinks we're near. + mCancelSecondaryRunnable = null; + return; + } else { + // Check this sensor again in a moment. + mCancelSecondaryRunnable = mDelayableExecutor.executeDelayed( + mSecondaryThresholdSensor::resume, SECONDARY_PING_INTERVAL_MS); + } } logDebug("Secondary sensor event: " + event.getBelow() + "."); - // This sensor should only be used briefly when uncovered. - if (!event.getBelow()) { - mSecondaryThresholdSensor.pause(); - // Check this sensor again in a moment. - mCancelSecondaryRunnable = mDelayableExecutor.executeDelayed( - mSecondaryThresholdSensor::resume, SECONDARY_PING_INTERVAL_MS); - } onSensorEvent(event); } }; @@ -145,6 +147,15 @@ public class ProximitySensor implements ThresholdSensor { registerInternal(); } + /** + * Sets that it is safe to leave the secondary sensor on indefinitely. + */ + public void setSecondarySafe(boolean safe) { + mSecondarySafe = safe; + if (!mSecondarySafe) { + mSecondaryThresholdSensor.pause(); + } + } /** * Returns true if we are registered with the SensorManager. @@ -278,6 +289,10 @@ public class ProximitySensor implements ThresholdSensor { return; } + if (!mSecondarySafe && !event.getBelow()) { + mSecondaryThresholdSensor.pause(); + } + mLastEvent = event; alertListeners(); } 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 433ec1887fd10..bb498d7bdefdc 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 @@ -292,6 +292,38 @@ public class ProximitySensorDualTest extends SysuiTestCase { mProximitySensor.unregister(listener); } + @Test + public void testSecondarySafe() { + mProximitySensor.setSecondarySafe(true); + + TestableListener listener = new TestableListener(); + + mProximitySensor.register(listener); + assertFalse(mThresholdSensorPrimary.isPaused()); + assertTrue(mThresholdSensorSecondary.isPaused()); + assertNull(listener.mLastEvent); + assertEquals(0, listener.mCallCount); + + mThresholdSensorPrimary.triggerEvent(true, 0); + assertNull(listener.mLastEvent); + assertEquals(0, listener.mCallCount); + mThresholdSensorSecondary.triggerEvent(true, 0); + assertTrue(listener.mLastEvent.getBelow()); + assertEquals(1, listener.mCallCount); + + // The secondary sensor should now remain resumed indefinitely. + assertFalse(mThresholdSensorSecondary.isPaused()); + mThresholdSensorPrimary.triggerEvent(false, 1); + assertFalse(listener.mLastEvent.getBelow()); + assertEquals(2, listener.mCallCount); + + // The secondary is still running, and not polling with the executor. + assertFalse(mThresholdSensorSecondary.isPaused()); + assertEquals(0, mFakeExecutor.numPending()); + + mProximitySensor.unregister(listener); + } + private static class TestableListener implements ThresholdSensor.Listener { ThresholdSensor.ThresholdSensorEvent mLastEvent; int mCallCount = 0;