diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java index 9b1842a87904c..6f8bcff16a83b 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java @@ -58,22 +58,20 @@ public class DozeFactory { params); DozeMachine machine = new DozeMachine(wrappedService, config, wakeLock); - DozeScreenBrightness screenBrightness = createDozeScreenBrightness( - context, wrappedService, sensorManager, host, handler); machine.setParts(new DozeMachine.Part[]{ new DozePauser(handler, machine, alarmManager, new AlwaysOnDisplayPolicy(context)), new DozeFalsingManagerAdapter(FalsingManager.getInstance(context)), createDozeTriggers(context, sensorManager, host, alarmManager, config, params, - handler, screenBrightness, wakeLock, machine), + handler, wakeLock, machine), createDozeUi(context, host, wakeLock, machine, handler, alarmManager), new DozeScreenState(wrappedService, handler), - screenBrightness, + createDozeScreenBrightness(context, wrappedService, sensorManager, host, handler), }); return machine; } - private DozeScreenBrightness createDozeScreenBrightness(Context context, + private DozeMachine.Part createDozeScreenBrightness(Context context, DozeMachine.Service service, SensorManager sensorManager, DozeHost host, Handler handler) { Sensor sensor = DozeSensors.findSensorWithType(sensorManager, @@ -84,11 +82,10 @@ public class DozeFactory { private DozeTriggers createDozeTriggers(Context context, SensorManager sensorManager, DozeHost host, AlarmManager alarmManager, AmbientDisplayConfiguration config, - DozeParameters params, Handler handler, DozeScreenBrightness screenBrightness, - WakeLock wakeLock, DozeMachine machine) { + DozeParameters params, Handler handler, WakeLock wakeLock, DozeMachine machine) { boolean allowPulseTriggers = true; return new DozeTriggers(context, machine, host, alarmManager, config, params, - sensorManager, handler, screenBrightness, wakeLock, allowPulseTriggers); + sensorManager, handler, wakeLock, allowPulseTriggers); } private DozeMachine.Part createDozeUi(Context context, DozeHost host, WakeLock wakeLock, diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java index 92f8d8ce638a1..03407e2b86e7e 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java @@ -37,10 +37,11 @@ public class DozeScreenBrightness implements DozeMachine.Part, SensorEventListen private final Sensor mLightSensor; private final int[] mSensorToBrightness; private final int[] mSensorToScrimOpacity; + private boolean mRegistered; - private boolean mReady = true; - private ReadyListener mReadyListener; private int mDefaultDozeBrightness; + private boolean mPaused = false; + private int mLastSensorValue = -1; public DozeScreenBrightness(Context context, DozeMachine.Service service, SensorManager sensorManager, Sensor lightSensor, DozeHost host, @@ -86,22 +87,38 @@ public class DozeScreenBrightness implements DozeMachine.Part, SensorEventListen setLightSensorEnabled(false); break; } + if (newState != DozeMachine.State.FINISH) { + setPaused(newState == DozeMachine.State.DOZE_AOD_PAUSED); + } } @Override public void onSensorChanged(SensorEvent event) { if (mRegistered) { - int sensorValue = (int) event.values[0]; - int brightness = computeBrightness(sensorValue); - if (brightness > 0) { + mLastSensorValue = (int) event.values[0]; + updateBrightnessAndReady(); + } + } + + private void updateBrightnessAndReady() { + if (mRegistered) { + int brightness = computeBrightness(mLastSensorValue); + boolean brightnessReady = brightness > 0; + if (brightnessReady) { mDozeService.setDozeScreenBrightness(brightness); } - // If the brightness is zero or negative, this indicates that the brightness sensor is - // covered or reports that the screen should be off, therefore we're not ready to turn - // on the screen yet. - setReady(brightness > 0); - int scrimOpacity = computeScrimOpacity(sensorValue); + int scrimOpacity = -1; + if (mPaused) { + // If AOD is paused, force the screen black until the + // sensor reports a new brightness. This ensures that when the screen comes on + // again, it will only show after the brightness sensor has stabilized, + // avoiding a potential flicker. + scrimOpacity = 255; + } else if (brightnessReady) { + // Only unblank scrim once brightness is ready. + scrimOpacity = computeScrimOpacity(mLastSensorValue); + } if (scrimOpacity >= 0) { mDozeHost.setAodDimmingScrim(scrimOpacity / 255f); } @@ -128,47 +145,28 @@ public class DozeScreenBrightness implements DozeMachine.Part, SensorEventListen private void resetBrightnessToDefault() { mDozeService.setDozeScreenBrightness(mDefaultDozeBrightness); + mDozeHost.setAodDimmingScrim(0f); } private void setLightSensorEnabled(boolean enabled) { if (enabled && !mRegistered && mLightSensor != null) { // Wait until we get an event from the sensor until indicating ready. - setReady(false); mRegistered = mSensorManager.registerListener(this, mLightSensor, SensorManager.SENSOR_DELAY_NORMAL, mHandler); + mLastSensorValue = -1; } else if (!enabled && mRegistered) { mSensorManager.unregisterListener(this); mRegistered = false; + mLastSensorValue = -1; // Sensor is not enabled, hence we use the default brightness and are always ready. - setReady(true); } } - private void setReady(boolean ready) { - if (ready != mReady) { - mReady = ready; - if (mReadyListener != null) { - mReadyListener.onBrightnessReadyChanged(mReady); - } + private void setPaused(boolean paused) { + if (mPaused != paused) { + mPaused = paused; + updateBrightnessAndReady(); } } - public void setBrightnessReadyListener(ReadyListener l) { - mReadyListener = l; - l.onBrightnessReadyChanged(mReady); - } - - /** - * @return true if the screen brightness is properly calculated. - * - * Can be used to wait for transitioning out of the paused state, such that we don't turn the - * display on before the display brightness is properly calculated. - */ - public boolean isReady() { - return mReady; - } - - public interface ReadyListener { - void onBrightnessReadyChanged(boolean ready); - } } diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java index 8d8c55c2df54f..f7a258a2c959d 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java @@ -33,7 +33,6 @@ import android.os.UserHandle; import android.text.format.Formatter; import android.util.Log; -import com.android.internal.annotations.VisibleForTesting; import com.android.internal.hardware.AmbientDisplayConfiguration; import com.android.internal.util.Preconditions; import com.android.systemui.statusbar.phone.DozeParameters; @@ -66,7 +65,6 @@ public class DozeTriggers implements DozeMachine.Part { private final boolean mAllowPulseTriggers; private final UiModeManager mUiModeManager; private final TriggerReceiver mBroadcastReceiver = new TriggerReceiver(); - private final DozeScreenBrightness mDozeScreenBrightness; private long mNotificationPulseTime; private boolean mPulsePending; @@ -75,7 +73,7 @@ public class DozeTriggers implements DozeMachine.Part { public DozeTriggers(Context context, DozeMachine machine, DozeHost dozeHost, AlarmManager alarmManager, AmbientDisplayConfiguration config, DozeParameters dozeParameters, SensorManager sensorManager, Handler handler, - DozeScreenBrightness brightness, WakeLock wakeLock, boolean allowPulseTriggers) { + WakeLock wakeLock, boolean allowPulseTriggers) { mContext = context; mMachine = machine; mDozeHost = dozeHost; @@ -89,7 +87,6 @@ public class DozeTriggers implements DozeMachine.Part { config, wakeLock, this::onSensor, this::onProximityFar, new AlwaysOnDisplayPolicy(context)); mUiModeManager = mContext.getSystemService(UiModeManager.class); - mDozeScreenBrightness = brightness; } private void onNotification() { @@ -162,41 +159,16 @@ public class DozeTriggers implements DozeMachine.Part { private void onProximityFar(boolean far) { final boolean near = !far; final DozeMachine.State state = mMachine.getState(); + final boolean paused = (state == DozeMachine.State.DOZE_AOD_PAUSED); + final boolean pausing = (state == DozeMachine.State.DOZE_AOD_PAUSING); + final boolean aod = (state == DozeMachine.State.DOZE_AOD); if (state == DozeMachine.State.DOZE_PULSING) { boolean ignoreTouch = near; if (DEBUG) Log.i(TAG, "Prox changed, ignore touch = " + ignoreTouch); mDozeHost.onIgnoreTouchWhilePulsing(ignoreTouch); } - - recalculatePausing(); - } - - private void onBrightnessReady(boolean brightnessReady) { - // Post because this is sometimes called during state transitions and we cannot query - // the machine's state while it's transitioning. - mHandler.post(this::recalculatePausing); - } - - private void recalculatePausing() { - boolean brightnessReady = mDozeScreenBrightness.isReady(); - Boolean proxCurrentlyFar = mDozeSensors.isProximityCurrentlyFar(); - - // Treat UNKNOWN the same as FAR, such that we don't pause the display just because - // the prox has unknown state. - boolean proximityFar = proxCurrentlyFar == null || proxCurrentlyFar; - recalculatePausing(proximityFar, brightnessReady); - } - - @VisibleForTesting - void recalculatePausing(boolean proximityFar, boolean brightnessReady) { - final boolean near = !proximityFar; - final DozeMachine.State state = mMachine.getState(); - final boolean paused = (state == DozeMachine.State.DOZE_AOD_PAUSED); - final boolean pausing = (state == DozeMachine.State.DOZE_AOD_PAUSING); - final boolean aod = (state == DozeMachine.State.DOZE_AOD); - - if (proximityFar && (pausing || paused && brightnessReady)) { + if (far && (paused || pausing)) { if (DEBUG) Log.i(TAG, "Prox FAR, unpausing AOD"); mMachine.requestState(DozeMachine.State.DOZE_AOD); } else if (near && aod) { @@ -211,7 +183,6 @@ public class DozeTriggers implements DozeMachine.Part { case INITIALIZED: mBroadcastReceiver.register(mContext); mDozeHost.addCallback(mHostCallback); - mDozeScreenBrightness.setBrightnessReadyListener(this::onBrightnessReady); checkTriggersAtInit(); break; case DOZE: diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java index 333e73dc10f49..b0c9f32873ff6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java @@ -30,6 +30,7 @@ class DozeHostFake implements DozeHost { boolean dozing; float doubleTapX; float doubleTapY; + float aodDimmingScrimOpacity; @Override public void addCallback(@NonNull Callback callback) { @@ -114,4 +115,9 @@ class DozeHostFake implements DozeHost { @Override public void setDozeScreenBrightness(int value) { } + + @Override + public void setAodDimmingScrim(float scrimOpacity) { + aodDimmingScrimOpacity = scrimOpacity; + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java index 4f59fc4c6589d..5e12781399e50 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java @@ -30,6 +30,7 @@ import static com.android.systemui.doze.DozeMachine.State.UNINITIALIZED; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import android.os.PowerManager; @@ -149,8 +150,6 @@ public class DozeScreenBrightnessTest extends SysuiTestCase { mScreen.transitionTo(INITIALIZED, DOZE_AOD); mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSING); mScreen.transitionTo(DOZE_AOD_PAUSING, DOZE_AOD_PAUSED); - - assertTrue(mScreen.isReady()); } @Test @@ -165,87 +164,77 @@ public class DozeScreenBrightnessTest extends SysuiTestCase { } @Test - public void testNonPositiveBrightness_keepsPreviousBrightness() throws Exception { + public void testNonPositiveBrightness_keepsPreviousBrightnessAndScrim() throws Exception { + mScreen.transitionTo(UNINITIALIZED, INITIALIZED); + mScreen.transitionTo(INITIALIZED, DOZE_AOD); + + mSensor.sendSensorEvent(1); + mSensor.sendSensorEvent(0); + + assertEquals(1, mServiceFake.screenBrightness); + assertEquals(10/255f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */); + } + + @Test + public void pausingAod_softBlanks() throws Exception { mScreen.transitionTo(UNINITIALIZED, INITIALIZED); mScreen.transitionTo(INITIALIZED, DOZE_AOD); mSensor.sendSensorEvent(2); + + mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSING); + mScreen.transitionTo(DOZE_AOD_PAUSING, DOZE_AOD_PAUSED); + + assertEquals(1f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */); + mSensor.sendSensorEvent(0); + assertEquals(1f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */); - assertEquals(2, mServiceFake.screenBrightness); + mScreen.transitionTo(DOZE_AOD_PAUSED, DOZE_AOD); + assertEquals(1f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */); } @Test - public void readyWhenNotInitialized() { - assertTrue(mScreen.isReady()); - } - - @Test - public void readyWhenNotRegistered() { + public void pausingAod_softBlanks_withSpuriousSensorDuringPause() throws Exception { mScreen.transitionTo(UNINITIALIZED, INITIALIZED); - mScreen.transitionTo(INITIALIZED, DOZE); + mScreen.transitionTo(INITIALIZED, DOZE_AOD); + mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSING); + mScreen.transitionTo(DOZE_AOD_PAUSING, DOZE_AOD_PAUSED); - assertTrue(mScreen.isReady()); + mSensor.sendSensorEvent(1); + assertEquals(1f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */); } @Test - public void notReadyWhenRegistered_butNoEventYet() { + public void pausingAod_unblanksAfterSensor() throws Exception { mScreen.transitionTo(UNINITIALIZED, INITIALIZED); mScreen.transitionTo(INITIALIZED, DOZE_AOD); - assertFalse(mScreen.isReady()); - } + mSensor.sendSensorEvent(2); - @Test - public void notReady_afterZeroBrightness() { - mScreen.transitionTo(UNINITIALIZED, INITIALIZED); - mScreen.transitionTo(INITIALIZED, DOZE_AOD); + mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSING); + mScreen.transitionTo(DOZE_AOD_PAUSING, DOZE_AOD_PAUSED); mSensor.sendSensorEvent(0); - assertFalse(mScreen.isReady()); + mScreen.transitionTo(DOZE_AOD_PAUSED, DOZE_AOD); + + mSensor.sendSensorEvent(2); + + assertEquals(0f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */); } @Test - public void ready_afterNonZeroBrightness() { + public void pausingAod_unblanksIfSensorWasAlwaysReady() throws Exception { mScreen.transitionTo(UNINITIALIZED, INITIALIZED); mScreen.transitionTo(INITIALIZED, DOZE_AOD); - mSensor.sendSensorEvent(1); + mSensor.sendSensorEvent(2); - assertTrue(mScreen.isReady()); - } + mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSING); + mScreen.transitionTo(DOZE_AOD_PAUSING, DOZE_AOD_PAUSED); + mScreen.transitionTo(DOZE_AOD_PAUSED, DOZE_AOD); - @Test - public void notReady_nonZeroThenZeroBrightness() { - mScreen.transitionTo(UNINITIALIZED, INITIALIZED); - mScreen.transitionTo(INITIALIZED, DOZE_AOD); - - mSensor.sendSensorEvent(1); - mSensor.sendSensorEvent(0); - - assertFalse(mScreen.isReady()); - } - - @Test - public void readyListener_getsCalled_whenRegistering() throws Exception { - Boolean[] ready = new Boolean[1]; - - mScreen.setBrightnessReadyListener((x) -> ready[0] = true); - - assertTrue(ready[0]); - } - - @Test - public void readyListener_getsCalled_whenReadyChanges() throws Exception { - Boolean[] ready = new Boolean[1]; - mScreen.setBrightnessReadyListener((x) -> ready[0] = true); - - mScreen.transitionTo(UNINITIALIZED, INITIALIZED); - mScreen.transitionTo(INITIALIZED, DOZE_AOD); - - ready[0] = null; - mSensor.sendSensorEvent(1); - assertTrue(ready[0]); + assertEquals(0f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */); } } \ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java index 6a9dac4cf8c39..a8ea1c0770da8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java @@ -58,7 +58,6 @@ public class DozeTriggersTest extends SysuiTestCase { private WakeLock mWakeLock; private Instrumentation mInstrumentation; private AlarmManager mAlarmManager; - private DozeScreenBrightness mDozeScreenBrightness; @BeforeClass public static void setupSuite() { @@ -77,12 +76,10 @@ public class DozeTriggersTest extends SysuiTestCase { mSensors = new FakeSensorManager(mContext); mHandler = new Handler(Looper.getMainLooper()); mWakeLock = new WakeLockFake(); - mDozeScreenBrightness = mock(DozeScreenBrightness.class); mInstrumentation.runOnMainSync(() -> { mTriggers = new DozeTriggers(mContext, mMachine, mHost, mAlarmManager, - mConfig, mParameters, mSensors, mHandler, mDozeScreenBrightness, - mWakeLock, true); + mConfig, mParameters, mSensors, mHandler, mWakeLock, true); }); } @@ -115,22 +112,4 @@ public class DozeTriggersTest extends SysuiTestCase { verify(mMachine).requestPulse(anyInt()); } - @Test - public void unpausing_fromPaused_waitsForBrightnessReady() throws Exception { - when(mMachine.getState()).thenReturn(DozeMachine.State.DOZE_AOD_PAUSED); - - mTriggers.recalculatePausing(true /* proxFar */, false /* brightnessReady */); - verify(mMachine, never()).requestState(any()); - - mTriggers.recalculatePausing(true /* proxFar */, true /* brightnessReady */); - verify(mMachine).requestState(DozeMachine.State.DOZE_AOD); - } - - @Test - public void unpausing_fromPausing_doesntWaitForBrightnessReady() throws Exception { - when(mMachine.getState()).thenReturn(DozeMachine.State.DOZE_AOD_PAUSED); - - mTriggers.recalculatePausing(true /* proxFar */, false /* brightnessReady */); - verify(mMachine).requestState(DozeMachine.State.DOZE_AOD); - } }