Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 647d6264 authored by Andrew Lehmer's avatar Andrew Lehmer Committed by android-build-merger
Browse files

Merge "AOD: Prewarm display while waiting for brightness sensor" into oc-mr1-dev am: 1952fcff

am: b4fe0c9f

Change-Id: I876c2d0afee23254b129a8694b3021085d35701d
parents ca048a52 b4fe0c9f
Loading
Loading
Loading
Loading
+5 −8
Original line number Original line Diff line number Diff line
@@ -58,22 +58,20 @@ public class DozeFactory {
                params);
                params);


        DozeMachine machine = new DozeMachine(wrappedService, config, wakeLock);
        DozeMachine machine = new DozeMachine(wrappedService, config, wakeLock);
        DozeScreenBrightness screenBrightness = createDozeScreenBrightness(
                context, wrappedService, sensorManager, host, handler);
        machine.setParts(new DozeMachine.Part[]{
        machine.setParts(new DozeMachine.Part[]{
                new DozePauser(handler, machine, alarmManager, new AlwaysOnDisplayPolicy(context)),
                new DozePauser(handler, machine, alarmManager, new AlwaysOnDisplayPolicy(context)),
                new DozeFalsingManagerAdapter(FalsingManager.getInstance(context)),
                new DozeFalsingManagerAdapter(FalsingManager.getInstance(context)),
                createDozeTriggers(context, sensorManager, host, alarmManager, config, params,
                createDozeTriggers(context, sensorManager, host, alarmManager, config, params,
                        handler, screenBrightness, wakeLock, machine),
                        handler, wakeLock, machine),
                createDozeUi(context, host, wakeLock, machine, handler, alarmManager),
                createDozeUi(context, host, wakeLock, machine, handler, alarmManager),
                new DozeScreenState(wrappedService, handler),
                new DozeScreenState(wrappedService, handler),
                screenBrightness,
                createDozeScreenBrightness(context, wrappedService, sensorManager, host, handler),
        });
        });


        return machine;
        return machine;
    }
    }


    private DozeScreenBrightness createDozeScreenBrightness(Context context,
    private DozeMachine.Part createDozeScreenBrightness(Context context,
            DozeMachine.Service service, SensorManager sensorManager, DozeHost host,
            DozeMachine.Service service, SensorManager sensorManager, DozeHost host,
            Handler handler) {
            Handler handler) {
        Sensor sensor = DozeSensors.findSensorWithType(sensorManager,
        Sensor sensor = DozeSensors.findSensorWithType(sensorManager,
@@ -84,11 +82,10 @@ public class DozeFactory {


    private DozeTriggers createDozeTriggers(Context context, SensorManager sensorManager,
    private DozeTriggers createDozeTriggers(Context context, SensorManager sensorManager,
            DozeHost host, AlarmManager alarmManager, AmbientDisplayConfiguration config,
            DozeHost host, AlarmManager alarmManager, AmbientDisplayConfiguration config,
            DozeParameters params, Handler handler, DozeScreenBrightness screenBrightness,
            DozeParameters params, Handler handler, WakeLock wakeLock, DozeMachine machine) {
            WakeLock wakeLock, DozeMachine machine) {
        boolean allowPulseTriggers = true;
        boolean allowPulseTriggers = true;
        return new DozeTriggers(context, machine, host, alarmManager, config, params,
        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,
    private DozeMachine.Part createDozeUi(Context context, DozeHost host, WakeLock wakeLock,
+34 −36
Original line number Original line Diff line number Diff line
@@ -37,10 +37,11 @@ public class DozeScreenBrightness implements DozeMachine.Part, SensorEventListen
    private final Sensor mLightSensor;
    private final Sensor mLightSensor;
    private final int[] mSensorToBrightness;
    private final int[] mSensorToBrightness;
    private final int[] mSensorToScrimOpacity;
    private final int[] mSensorToScrimOpacity;

    private boolean mRegistered;
    private boolean mRegistered;
    private boolean mReady = true;
    private ReadyListener mReadyListener;
    private int mDefaultDozeBrightness;
    private int mDefaultDozeBrightness;
    private boolean mPaused = false;
    private int mLastSensorValue = -1;


    public DozeScreenBrightness(Context context, DozeMachine.Service service,
    public DozeScreenBrightness(Context context, DozeMachine.Service service,
            SensorManager sensorManager, Sensor lightSensor, DozeHost host,
            SensorManager sensorManager, Sensor lightSensor, DozeHost host,
@@ -86,22 +87,38 @@ public class DozeScreenBrightness implements DozeMachine.Part, SensorEventListen
                setLightSensorEnabled(false);
                setLightSensorEnabled(false);
                break;
                break;
        }
        }
        if (newState != DozeMachine.State.FINISH) {
            setPaused(newState == DozeMachine.State.DOZE_AOD_PAUSED);
        }
    }
    }


    @Override
    @Override
    public void onSensorChanged(SensorEvent event) {
    public void onSensorChanged(SensorEvent event) {
        if (mRegistered) {
        if (mRegistered) {
            int sensorValue = (int) event.values[0];
            mLastSensorValue = (int) event.values[0];
            int brightness = computeBrightness(sensorValue);
            updateBrightnessAndReady();
            if (brightness > 0) {
        }
    }

    private void updateBrightnessAndReady() {
        if (mRegistered) {
            int brightness = computeBrightness(mLastSensorValue);
            boolean brightnessReady = brightness > 0;
            if (brightnessReady) {
                mDozeService.setDozeScreenBrightness(brightness);
                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) {
            if (scrimOpacity >= 0) {
                mDozeHost.setAodDimmingScrim(scrimOpacity / 255f);
                mDozeHost.setAodDimmingScrim(scrimOpacity / 255f);
            }
            }
@@ -128,47 +145,28 @@ public class DozeScreenBrightness implements DozeMachine.Part, SensorEventListen


    private void resetBrightnessToDefault() {
    private void resetBrightnessToDefault() {
        mDozeService.setDozeScreenBrightness(mDefaultDozeBrightness);
        mDozeService.setDozeScreenBrightness(mDefaultDozeBrightness);
        mDozeHost.setAodDimmingScrim(0f);
    }
    }


    private void setLightSensorEnabled(boolean enabled) {
    private void setLightSensorEnabled(boolean enabled) {
        if (enabled && !mRegistered && mLightSensor != null) {
        if (enabled && !mRegistered && mLightSensor != null) {
            // Wait until we get an event from the sensor until indicating ready.
            // Wait until we get an event from the sensor until indicating ready.
            setReady(false);
            mRegistered = mSensorManager.registerListener(this, mLightSensor,
            mRegistered = mSensorManager.registerListener(this, mLightSensor,
                    SensorManager.SENSOR_DELAY_NORMAL, mHandler);
                    SensorManager.SENSOR_DELAY_NORMAL, mHandler);
            mLastSensorValue = -1;
        } else if (!enabled && mRegistered) {
        } else if (!enabled && mRegistered) {
            mSensorManager.unregisterListener(this);
            mSensorManager.unregisterListener(this);
            mRegistered = false;
            mRegistered = false;
            mLastSensorValue = -1;
            // Sensor is not enabled, hence we use the default brightness and are always ready.
            // 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);
            }
        }
        }
    }
    }


    public void setBrightnessReadyListener(ReadyListener l) {
    private void setPaused(boolean paused) {
        mReadyListener = l;
        if (mPaused != paused) {
        l.onBrightnessReadyChanged(mReady);
            mPaused = paused;
            updateBrightnessAndReady();
        }
        }

    /**
     * @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);
    }
}
}
+5 −34
Original line number Original line Diff line number Diff line
@@ -33,7 +33,6 @@ import android.os.UserHandle;
import android.text.format.Formatter;
import android.text.format.Formatter;
import android.util.Log;
import android.util.Log;


import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.internal.util.Preconditions;
import com.android.internal.util.Preconditions;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.DozeParameters;
@@ -66,7 +65,6 @@ public class DozeTriggers implements DozeMachine.Part {
    private final boolean mAllowPulseTriggers;
    private final boolean mAllowPulseTriggers;
    private final UiModeManager mUiModeManager;
    private final UiModeManager mUiModeManager;
    private final TriggerReceiver mBroadcastReceiver = new TriggerReceiver();
    private final TriggerReceiver mBroadcastReceiver = new TriggerReceiver();
    private final DozeScreenBrightness mDozeScreenBrightness;


    private long mNotificationPulseTime;
    private long mNotificationPulseTime;
    private boolean mPulsePending;
    private boolean mPulsePending;
@@ -75,7 +73,7 @@ public class DozeTriggers implements DozeMachine.Part {
    public DozeTriggers(Context context, DozeMachine machine, DozeHost dozeHost,
    public DozeTriggers(Context context, DozeMachine machine, DozeHost dozeHost,
            AlarmManager alarmManager, AmbientDisplayConfiguration config,
            AlarmManager alarmManager, AmbientDisplayConfiguration config,
            DozeParameters dozeParameters, SensorManager sensorManager, Handler handler,
            DozeParameters dozeParameters, SensorManager sensorManager, Handler handler,
            DozeScreenBrightness brightness, WakeLock wakeLock, boolean allowPulseTriggers) {
            WakeLock wakeLock, boolean allowPulseTriggers) {
        mContext = context;
        mContext = context;
        mMachine = machine;
        mMachine = machine;
        mDozeHost = dozeHost;
        mDozeHost = dozeHost;
@@ -89,7 +87,6 @@ public class DozeTriggers implements DozeMachine.Part {
                config, wakeLock, this::onSensor, this::onProximityFar,
                config, wakeLock, this::onSensor, this::onProximityFar,
                new AlwaysOnDisplayPolicy(context));
                new AlwaysOnDisplayPolicy(context));
        mUiModeManager = mContext.getSystemService(UiModeManager.class);
        mUiModeManager = mContext.getSystemService(UiModeManager.class);
        mDozeScreenBrightness = brightness;
    }
    }


    private void onNotification() {
    private void onNotification() {
@@ -162,41 +159,16 @@ public class DozeTriggers implements DozeMachine.Part {
    private void onProximityFar(boolean far) {
    private void onProximityFar(boolean far) {
        final boolean near = !far;
        final boolean near = !far;
        final DozeMachine.State state = mMachine.getState();
        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) {
        if (state == DozeMachine.State.DOZE_PULSING) {
            boolean ignoreTouch = near;
            boolean ignoreTouch = near;
            if (DEBUG) Log.i(TAG, "Prox changed, ignore touch = " + ignoreTouch);
            if (DEBUG) Log.i(TAG, "Prox changed, ignore touch = " + ignoreTouch);
            mDozeHost.onIgnoreTouchWhilePulsing(ignoreTouch);
            mDozeHost.onIgnoreTouchWhilePulsing(ignoreTouch);
        }
        }

        if (far && (paused || pausing)) {
        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 (DEBUG) Log.i(TAG, "Prox FAR, unpausing AOD");
            if (DEBUG) Log.i(TAG, "Prox FAR, unpausing AOD");
            mMachine.requestState(DozeMachine.State.DOZE_AOD);
            mMachine.requestState(DozeMachine.State.DOZE_AOD);
        } else if (near && aod) {
        } else if (near && aod) {
@@ -211,7 +183,6 @@ public class DozeTriggers implements DozeMachine.Part {
            case INITIALIZED:
            case INITIALIZED:
                mBroadcastReceiver.register(mContext);
                mBroadcastReceiver.register(mContext);
                mDozeHost.addCallback(mHostCallback);
                mDozeHost.addCallback(mHostCallback);
                mDozeScreenBrightness.setBrightnessReadyListener(this::onBrightnessReady);
                checkTriggersAtInit();
                checkTriggersAtInit();
                break;
                break;
            case DOZE:
            case DOZE:
+6 −0
Original line number Original line Diff line number Diff line
@@ -30,6 +30,7 @@ class DozeHostFake implements DozeHost {
    boolean dozing;
    boolean dozing;
    float doubleTapX;
    float doubleTapX;
    float doubleTapY;
    float doubleTapY;
    float aodDimmingScrimOpacity;


    @Override
    @Override
    public void addCallback(@NonNull Callback callback) {
    public void addCallback(@NonNull Callback callback) {
@@ -114,4 +115,9 @@ class DozeHostFake implements DozeHost {
    @Override
    @Override
    public void setDozeScreenBrightness(int value) {
    public void setDozeScreenBrightness(int value) {
    }
    }

    @Override
    public void setAodDimmingScrim(float scrimOpacity) {
        aodDimmingScrimOpacity = scrimOpacity;
    }
}
}
+35 −46
Original line number Original line Diff line number Diff line
@@ -30,6 +30,7 @@ import static com.android.systemui.doze.DozeMachine.State.UNINITIALIZED;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertTrue;


import android.os.PowerManager;
import android.os.PowerManager;
@@ -149,8 +150,6 @@ public class DozeScreenBrightnessTest extends SysuiTestCase {
        mScreen.transitionTo(INITIALIZED, DOZE_AOD);
        mScreen.transitionTo(INITIALIZED, DOZE_AOD);
        mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSING);
        mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSING);
        mScreen.transitionTo(DOZE_AOD_PAUSING, DOZE_AOD_PAUSED);
        mScreen.transitionTo(DOZE_AOD_PAUSING, DOZE_AOD_PAUSED);

        assertTrue(mScreen.isReady());
    }
    }


    @Test
    @Test
@@ -165,87 +164,77 @@ public class DozeScreenBrightnessTest extends SysuiTestCase {
    }
    }


    @Test
    @Test
    public void testNonPositiveBrightness_keepsPreviousBrightness() throws Exception {
    public void testNonPositiveBrightness_keepsPreviousBrightnessAndScrim() throws Exception {
        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
        mScreen.transitionTo(INITIALIZED, DOZE_AOD);
        mScreen.transitionTo(INITIALIZED, DOZE_AOD);


        mSensor.sendSensorEvent(2);
        mSensor.sendSensorEvent(1);
        mSensor.sendSensorEvent(0);
        mSensor.sendSensorEvent(0);


        assertEquals(2, mServiceFake.screenBrightness);
        assertEquals(1, mServiceFake.screenBrightness);
    }
        assertEquals(10/255f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */);

    @Test
    public void readyWhenNotInitialized() {
        assertTrue(mScreen.isReady());
    }

    @Test
    public void readyWhenNotRegistered() {
        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
        mScreen.transitionTo(INITIALIZED, DOZE);

        assertTrue(mScreen.isReady());
    }
    }


    @Test
    @Test
    public void notReadyWhenRegistered_butNoEventYet() {
    public void pausingAod_softBlanks() throws Exception {
        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
        mScreen.transitionTo(INITIALIZED, DOZE_AOD);
        mScreen.transitionTo(INITIALIZED, DOZE_AOD);


        assertFalse(mScreen.isReady());
        mSensor.sendSensorEvent(2);
    }


    @Test
        mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSING);
    public void notReady_afterZeroBrightness() {
        mScreen.transitionTo(DOZE_AOD_PAUSING, DOZE_AOD_PAUSED);
        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);

        mScreen.transitionTo(INITIALIZED, DOZE_AOD);
        assertEquals(1f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */);


        mSensor.sendSensorEvent(0);
        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
    @Test
    public void ready_afterNonZeroBrightness() {
    public void pausingAod_softBlanks_withSpuriousSensorDuringPause() throws Exception {
        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
        mScreen.transitionTo(INITIALIZED, DOZE_AOD);
        mScreen.transitionTo(INITIALIZED, DOZE_AOD);
        mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSING);
        mScreen.transitionTo(DOZE_AOD_PAUSING, DOZE_AOD_PAUSED);


        mSensor.sendSensorEvent(1);
        mSensor.sendSensorEvent(1);

        assertEquals(1f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */);
        assertTrue(mScreen.isReady());
    }
    }


    @Test
    @Test
    public void notReady_nonZeroThenZeroBrightness() {
    public void pausingAod_unblanksAfterSensor() throws Exception {
        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
        mScreen.transitionTo(INITIALIZED, DOZE_AOD);
        mScreen.transitionTo(INITIALIZED, DOZE_AOD);


        mSensor.sendSensorEvent(1);
        mSensor.sendSensorEvent(2);
        mSensor.sendSensorEvent(0);


        assertFalse(mScreen.isReady());
        mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSING);
    }
        mScreen.transitionTo(DOZE_AOD_PAUSING, DOZE_AOD_PAUSED);


    @Test
        mSensor.sendSensorEvent(0);
    public void readyListener_getsCalled_whenRegistering() throws Exception {

        Boolean[] ready = new Boolean[1];
        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
    @Test
    public void readyListener_getsCalled_whenReadyChanges() throws Exception {
    public void pausingAod_unblanksIfSensorWasAlwaysReady() throws Exception {
        Boolean[] ready = new Boolean[1];
        mScreen.setBrightnessReadyListener((x) -> ready[0] = true);

        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
        mScreen.transitionTo(INITIALIZED, DOZE_AOD);
        mScreen.transitionTo(INITIALIZED, DOZE_AOD);


        ready[0] = null;
        mSensor.sendSensorEvent(2);
        mSensor.sendSensorEvent(1);

        assertTrue(ready[0]);
        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
Loading