From 2a7d804124deecb6aaf98a60b6dd85b4b7fe42d9 Mon Sep 17 00:00:00 2001 From: Dave Mankoff Date: Thu, 11 Jun 2020 12:41:48 -0400 Subject: [PATCH] Leave Prox registered when safe to do so. This CL allows a proximity sensor operating in dual mode to leave its secondary sensor regitered where it is told it is safe to do so. This is generally when the screen is in some sort of doze or aod mode. The sensor does not itself manage this state but expects clients to tell it when it it safe. Fixes: 157717162 Test: atest SystemUITests && manual Change-Id: Ie89e80aa7440b4964fb61c144ae3b8bc4808f0ac --- .../android/systemui/doze/DozeSensors.java | 8 ++++ .../android/systemui/doze/DozeTriggers.java | 1 + .../util/sensors/ProximitySensor.java | 37 +++++++++++++------ .../util/sensors/ProximitySensorDualTest.java | 32 ++++++++++++++++ 4 files changed, 67 insertions(+), 11 deletions(-) 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;