Loading packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java +8 −5 Original line number Diff line number Diff line Loading @@ -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, Loading @@ -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, Loading packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java +55 −7 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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; Loading @@ -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 Loading @@ -65,7 +79,6 @@ public class DozeScreenBrightness implements DozeMachine.Part, SensorEventListen setLightSensorEnabled(true); break; case DOZE: case DOZE_AOD_PAUSED: setLightSensorEnabled(false); resetBrightnessToDefault(); break; Loading @@ -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) { Loading Loading @@ -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); } } packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java +2 −1 Original line number Diff line number Diff line Loading @@ -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; Loading packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java +34 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading @@ -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() { Loading Loading @@ -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) { Loading @@ -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: Loading packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java +109 −26 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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); } Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading @@ -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
packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java +8 −5 Original line number Diff line number Diff line Loading @@ -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, Loading @@ -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, Loading
packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java +55 −7 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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; Loading @@ -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 Loading @@ -65,7 +79,6 @@ public class DozeScreenBrightness implements DozeMachine.Part, SensorEventListen setLightSensorEnabled(true); break; case DOZE: case DOZE_AOD_PAUSED: setLightSensorEnabled(false); resetBrightnessToDefault(); break; Loading @@ -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) { Loading Loading @@ -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); } }
packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java +2 −1 Original line number Diff line number Diff line Loading @@ -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; Loading
packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java +34 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading @@ -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() { Loading Loading @@ -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) { Loading @@ -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: Loading
packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java +109 −26 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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); } Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading @@ -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