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
This commit is contained in:
Dave Mankoff
2020-06-11 12:41:48 -04:00
parent 891fba3876
commit 2a7d804124
4 changed files with 67 additions and 11 deletions

View File

@@ -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();

View File

@@ -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);

View File

@@ -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();
}

View File

@@ -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;