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

Commit 9c608232 authored by Adrian Roos's avatar Adrian Roos Committed by android-build-merger
Browse files

Merge "AOD: Keep brightness sensor registered while covered" into oc-mr1-dev am: 10070c63

am: cd625c69

Change-Id: If62deed10330e05610dd6b2c5d868c8e0ce5b72e
parents f59de479 cd625c69
Loading
Loading
Loading
Loading
+8 −5
Original line number Diff line number Diff line
@@ -58,20 +58,22 @@ 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, wakeLock, machine),
                        handler, screenBrightness, wakeLock, machine),
                createDozeUi(context, host, wakeLock, machine, handler, alarmManager),
                new DozeScreenState(wrappedService, handler),
                createDozeScreenBrightness(context, wrappedService, sensorManager, host, handler),
                screenBrightness,
        });

        return machine;
    }

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

    private DozeTriggers createDozeTriggers(Context context, SensorManager sensorManager,
            DozeHost host, AlarmManager alarmManager, AmbientDisplayConfiguration config,
            DozeParameters params, Handler handler, WakeLock wakeLock, DozeMachine machine) {
            DozeParameters params, Handler handler, DozeScreenBrightness screenBrightness,
            WakeLock wakeLock, DozeMachine machine) {
        boolean allowPulseTriggers = true;
        return new DozeTriggers(context, machine, host, alarmManager, config, params,
                sensorManager, handler, wakeLock, allowPulseTriggers);
                sensorManager, handler, screenBrightness, wakeLock, allowPulseTriggers);
    }

    private DozeMachine.Part createDozeUi(Context context, DozeHost host, WakeLock wakeLock,
+55 −7
Original line number Diff line number Diff line
@@ -24,7 +24,6 @@ import android.hardware.SensorManager;
import android.os.Handler;

import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.R;

/**
 * Controls the screen brightness when dozing.
@@ -39,10 +38,14 @@ public class DozeScreenBrightness implements DozeMachine.Part, SensorEventListen
    private final int[] mSensorToBrightness;
    private final int[] mSensorToScrimOpacity;
    private boolean mRegistered;
    private boolean mReady = true;
    private ReadyListener mReadyListener;
    private int mDefaultDozeBrightness;

    public DozeScreenBrightness(Context context, DozeMachine.Service service,
            SensorManager sensorManager, Sensor lightSensor, DozeHost host,
            Handler handler, AlwaysOnDisplayPolicy policy) {
            Handler handler, int defaultDozeBrightness, int[] sensorToBrightness,
            int[] sensorToScrimOpacity) {
        mContext = context;
        mDozeService = service;
        mSensorManager = sensorManager;
@@ -50,8 +53,19 @@ public class DozeScreenBrightness implements DozeMachine.Part, SensorEventListen
        mDozeHost = host;
        mHandler = handler;

        mSensorToBrightness = policy.screenBrightnessArray;
        mSensorToScrimOpacity = policy.dimmingScrimArray;
        mDefaultDozeBrightness = defaultDozeBrightness;
        mSensorToBrightness = sensorToBrightness;
        mSensorToScrimOpacity = sensorToScrimOpacity;
    }

    @VisibleForTesting
    public DozeScreenBrightness(Context context, DozeMachine.Service service,
            SensorManager sensorManager, Sensor lightSensor, DozeHost host,
            Handler handler, AlwaysOnDisplayPolicy policy) {
        this(context, service, sensorManager, lightSensor, host, handler,
                context.getResources().getInteger(
                        com.android.internal.R.integer.config_screenBrightnessDoze),
                policy.screenBrightnessArray, policy.dimmingScrimArray);
    }

    @Override
@@ -65,7 +79,6 @@ public class DozeScreenBrightness implements DozeMachine.Part, SensorEventListen
                setLightSensorEnabled(true);
                break;
            case DOZE:
            case DOZE_AOD_PAUSED:
                setLightSensorEnabled(false);
                resetBrightnessToDefault();
                break;
@@ -83,6 +96,10 @@ public class DozeScreenBrightness implements DozeMachine.Part, SensorEventListen
            if (brightness > 0) {
                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);
            if (scrimOpacity >= 0) {
@@ -110,17 +127,48 @@ public class DozeScreenBrightness implements DozeMachine.Part, SensorEventListen
    }

    private void resetBrightnessToDefault() {
        mDozeService.setDozeScreenBrightness(mContext.getResources().getInteger(
                com.android.internal.R.integer.config_screenBrightnessDoze));
        mDozeService.setDozeScreenBrightness(mDefaultDozeBrightness);
    }

    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);
        } else if (!enabled && mRegistered) {
            mSensorManager.unregisterListener(this);
            mRegistered = false;
            // 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) {
        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);
    }
}
+2 −1
Original line number Diff line number Diff line
@@ -25,8 +25,9 @@ import android.view.Display;
public class DozeScreenState implements DozeMachine.Part {
    private final DozeMachine.Service mDozeService;
    private final Handler mHandler;
    private final Runnable mApplyPendingScreenState = this::applyPendingScreenState;

    private int mPendingScreenState = Display.STATE_UNKNOWN;
    private Runnable mApplyPendingScreenState = this::applyPendingScreenState;

    public DozeScreenState(DozeMachine.Service service, Handler handler) {
        mDozeService = service;
+34 −5
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ 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;
@@ -65,6 +66,7 @@ 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;
@@ -73,7 +75,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,
            WakeLock wakeLock, boolean allowPulseTriggers) {
            DozeScreenBrightness brightness, WakeLock wakeLock, boolean allowPulseTriggers) {
        mContext = context;
        mMachine = machine;
        mDozeHost = dozeHost;
@@ -87,6 +89,7 @@ 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() {
@@ -159,16 +162,41 @@ 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);
        }
        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");
            mMachine.requestState(DozeMachine.State.DOZE_AOD);
        } else if (near && aod) {
@@ -183,6 +211,7 @@ public class DozeTriggers implements DozeMachine.Part {
            case INITIALIZED:
                mBroadcastReceiver.register(mContext);
                mDozeHost.addCallback(mHostCallback);
                mDozeScreenBrightness.setBrightnessReadyListener(this::onBrightnessReady);
                checkTriggersAtInit();
                break;
            case DOZE:
+109 −26
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.systemui.doze;
import static com.android.systemui.doze.DozeMachine.State.DOZE;
import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD;
import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD_PAUSED;
import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD_PAUSING;
import static com.android.systemui.doze.DozeMachine.State.DOZE_PULSE_DONE;
import static com.android.systemui.doze.DozeMachine.State.DOZE_PULSING;
import static com.android.systemui.doze.DozeMachine.State.DOZE_REQUEST_PULSE;
@@ -27,6 +28,7 @@ import static com.android.systemui.doze.DozeMachine.State.INITIALIZED;
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.assertTrue;

@@ -38,15 +40,17 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.utils.hardware.FakeSensorManager;

import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(AndroidJUnit4.class)
@SmallTest
@Ignore
public class DozeScreenBrightnessTest extends SysuiTestCase {

    static final int DEFAULT_BRIGHTNESS = 10;
    static final int[] SENSOR_TO_BRIGHTNESS = new int[]{-1, 1, 2, 3, 4};
    static final int[] SENSOR_TO_OPACITY = new int[]{-1, 10, 0, 0, 0};

    DozeServiceFake mServiceFake;
    DozeScreenBrightness mScreen;
    FakeSensorManager.FakeGenericSensor mSensor;
@@ -61,14 +65,14 @@ public class DozeScreenBrightnessTest extends SysuiTestCase {
        mSensor = mSensorManager.getFakeLightSensor();
        mScreen = new DozeScreenBrightness(mContext, mServiceFake, mSensorManager,
                mSensor.getSensor(), mHostFake, null /* handler */,
                new AlwaysOnDisplayPolicy(mContext));
                DEFAULT_BRIGHTNESS, SENSOR_TO_BRIGHTNESS, SENSOR_TO_OPACITY);
    }

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

        assertNotEquals(PowerManager.BRIGHTNESS_DEFAULT, mServiceFake.screenBrightness);
        assertEquals(DEFAULT_BRIGHTNESS, mServiceFake.screenBrightness);
        assertTrue(mServiceFake.screenBrightness <= PowerManager.BRIGHTNESS_ON);
    }

@@ -77,35 +81,37 @@ public class DozeScreenBrightnessTest extends SysuiTestCase {
        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
        mScreen.transitionTo(INITIALIZED, DOZE_AOD);

        mSensor.sendSensorEvent(1000);
        mSensor.sendSensorEvent(3);

        assertEquals(1000, mServiceFake.screenBrightness);
        assertEquals(3, mServiceFake.screenBrightness);
    }

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

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

        mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSED);
        mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSING);
        mScreen.transitionTo(DOZE_AOD_PAUSING, DOZE_AOD_PAUSED);

        mSensor.sendSensorEvent(1001);
        mSensor.sendSensorEvent(2);

        assertNotEquals(1001, mServiceFake.screenBrightness);
        assertEquals(2, mServiceFake.screenBrightness);
    }

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

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

        mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSED);
        mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSING);
        mScreen.transitionTo(DOZE_AOD_PAUSING, DOZE_AOD_PAUSED);

        assertNotEquals(1000, mServiceFake.screenBrightness);
        assertEquals(1, mServiceFake.screenBrightness);
    }

    @Test
@@ -114,9 +120,9 @@ public class DozeScreenBrightnessTest extends SysuiTestCase {
        mScreen.transitionTo(INITIALIZED, DOZE);
        mScreen.transitionTo(DOZE, DOZE_REQUEST_PULSE);

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

        assertEquals(1000, mServiceFake.screenBrightness);
        assertEquals(1, mServiceFake.screenBrightness);
    }

    @Test
@@ -128,20 +134,23 @@ public class DozeScreenBrightnessTest extends SysuiTestCase {
        mScreen.transitionTo(DOZE_PULSING, DOZE_PULSE_DONE);
        mScreen.transitionTo(DOZE_PULSE_DONE, DOZE);

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

        assertNotEquals(1000, mServiceFake.screenBrightness);
        assertEquals(DEFAULT_BRIGHTNESS, mServiceFake.screenBrightness);
    }

    @Test
    public void testNullSensor() throws Exception {
        mScreen = new DozeScreenBrightness(mContext, mServiceFake, mSensorManager,
                null /* sensor */, mHostFake, null /* handler */,
                new AlwaysOnDisplayPolicy(mContext));
                DEFAULT_BRIGHTNESS, SENSOR_TO_BRIGHTNESS, SENSOR_TO_OPACITY);

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

        assertTrue(mScreen.isReady());
    }

    @Test
@@ -150,19 +159,93 @@ public class DozeScreenBrightnessTest extends SysuiTestCase {
        mScreen.transitionTo(INITIALIZED, DOZE_AOD);
        mScreen.transitionTo(DOZE_AOD, FINISH);

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

        assertNotEquals(1, mServiceFake.screenBrightness);
    }

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

        mSensor.sendSensorEvent(2);
        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());
    }

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

        assertFalse(mScreen.isReady());
    }

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

        mSensor.sendSensorEvent(0);

        assertFalse(mScreen.isReady());
    }

    @Test
    public void ready_afterNonZeroBrightness() {
        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
        mScreen.transitionTo(INITIALIZED, DOZE_AOD);

        assertNotEquals(1000, mServiceFake.screenBrightness);
        mSensor.sendSensorEvent(1);

        assertTrue(mScreen.isReady());
    }

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

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

        assertTrue("Brightness must be at least 1, but was " + mServiceFake.screenBrightness,
                mServiceFake.screenBrightness >= 1);
        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]);
    }
}
 No newline at end of file
Loading