OSDN Git Service

AOD: Prewarm display while waiting for brightness sensor
authorAdrian Roos <roosa@google.com>
Wed, 6 Sep 2017 14:46:46 +0000 (16:46 +0200)
committerAdrian Roos <roosa@google.com>
Wed, 6 Sep 2017 16:20:10 +0000 (18:20 +0200)
This partially reverts commit a79ad59d49cdb3ef6f4cf864094063e3e9111586.

Instead of keeping AOD paused, we now turn the display on, but keep it soft
blanked by keeping the front scrim opaque black until we get a valid sensor
event.

Bug: 65010918
Test: runtest -x packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
Change-Id: Ic39d29814024d52117538a6a19adaf3866c7223e

packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java
packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java

index 9b1842a..6f8bcff 100644 (file)
@@ -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,
index 92f8d8c..03407e2 100644 (file)
@@ -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);
-    }
 }
index 8d8c55c..f7a258a 100644 (file)
@@ -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:
index 333e73d..b0c9f32 100644 (file)
@@ -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;
+    }
 }
index 4f59fc4..5e12781 100644 (file)
@@ -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(2);
+        mSensor.sendSensorEvent(1);
         mSensor.sendSensorEvent(0);
 
-        assertEquals(2, mServiceFake.screenBrightness);
-    }
-
-    @Test
-    public void readyWhenNotInitialized() {
-        assertTrue(mScreen.isReady());
-    }
-
-    @Test
-    public void readyWhenNotRegistered() {
-        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
-        mScreen.transitionTo(INITIALIZED, DOZE);
-
-        assertTrue(mScreen.isReady());
+        assertEquals(1, mServiceFake.screenBrightness);
+        assertEquals(10/255f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */);
     }
 
     @Test
-    public void notReadyWhenRegistered_butNoEventYet() {
+    public void pausingAod_softBlanks() 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);
+
+        assertEquals(1f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */);
 
         mSensor.sendSensorEvent(0);
+        assertEquals(1f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */);
 
-        assertFalse(mScreen.isReady());
+        mScreen.transitionTo(DOZE_AOD_PAUSED, DOZE_AOD);
+        assertEquals(1f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */);
     }
 
     @Test
-    public void ready_afterNonZeroBrightness() {
+    public void pausingAod_softBlanks_withSpuriousSensorDuringPause() throws Exception {
         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(1);
-
-        assertTrue(mScreen.isReady());
+        assertEquals(1f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */);
     }
 
     @Test
-    public void notReady_nonZeroThenZeroBrightness() {
+    public void pausingAod_unblanksAfterSensor() throws Exception {
         mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
         mScreen.transitionTo(INITIALIZED, DOZE_AOD);
 
-        mSensor.sendSensorEvent(1);
-        mSensor.sendSensorEvent(0);
+        mSensor.sendSensorEvent(2);
 
-        assertFalse(mScreen.isReady());
-    }
+        mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSING);
+        mScreen.transitionTo(DOZE_AOD_PAUSING, DOZE_AOD_PAUSED);
 
-    @Test
-    public void readyListener_getsCalled_whenRegistering() throws Exception {
-        Boolean[] ready = new Boolean[1];
+        mSensor.sendSensorEvent(0);
+
+        mScreen.transitionTo(DOZE_AOD_PAUSED, DOZE_AOD);
 
-        mScreen.setBrightnessReadyListener((x) -> ready[0] = true);
+        mSensor.sendSensorEvent(2);
 
-        assertTrue(ready[0]);
+        assertEquals(0f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */);
     }
 
     @Test
-    public void readyListener_getsCalled_whenReadyChanges() throws Exception {
-        Boolean[] ready = new Boolean[1];
-        mScreen.setBrightnessReadyListener((x) -> ready[0] = true);
-
+    public void pausingAod_unblanksIfSensorWasAlwaysReady() throws Exception {
         mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
         mScreen.transitionTo(INITIALIZED, DOZE_AOD);
 
-        ready[0] = null;
-        mSensor.sendSensorEvent(1);
-        assertTrue(ready[0]);
+        mSensor.sendSensorEvent(2);
+
+        mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSING);
+        mScreen.transitionTo(DOZE_AOD_PAUSING, DOZE_AOD_PAUSED);
+        mScreen.transitionTo(DOZE_AOD_PAUSED, DOZE_AOD);
+
+        assertEquals(0f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */);
     }
 }
\ No newline at end of file
index 6a9dac4..a8ea1c0 100644 (file)
@@ -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);
-    }
 }