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

am: 1952fcffc3

Change-Id: I92b6d4ce3d1a17274809dfd123bea3ed56cd646c
This commit is contained in:
Andrew Lehmer
2017-09-14 01:52:07 +00:00
committed by android-build-merger
6 changed files with 95 additions and 155 deletions

View 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,

View 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);
}
}

View 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:

View 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;
}
}

View 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(1);
mSensor.sendSensorEvent(0);
assertEquals(1, mServiceFake.screenBrightness);
assertEquals(10/255f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */);
}
@Test
public void pausingAod_softBlanks() throws Exception {
mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
mScreen.transitionTo(INITIALIZED, DOZE_AOD);
mSensor.sendSensorEvent(2);
mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSING);
mScreen.transitionTo(DOZE_AOD_PAUSING, DOZE_AOD_PAUSED);
assertEquals(1f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */);
mSensor.sendSensorEvent(0);
assertEquals(1f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */);
assertEquals(2, mServiceFake.screenBrightness);
mScreen.transitionTo(DOZE_AOD_PAUSED, DOZE_AOD);
assertEquals(1f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */);
}
@Test
public void readyWhenNotInitialized() {
assertTrue(mScreen.isReady());
}
@Test
public void readyWhenNotRegistered() {
public void pausingAod_softBlanks_withSpuriousSensorDuringPause() throws Exception {
mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
mScreen.transitionTo(INITIALIZED, DOZE);
mScreen.transitionTo(INITIALIZED, DOZE_AOD);
mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSING);
mScreen.transitionTo(DOZE_AOD_PAUSING, DOZE_AOD_PAUSED);
assertTrue(mScreen.isReady());
mSensor.sendSensorEvent(1);
assertEquals(1f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */);
}
@Test
public void notReadyWhenRegistered_butNoEventYet() {
public void pausingAod_unblanksAfterSensor() throws Exception {
mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
mScreen.transitionTo(INITIALIZED, DOZE_AOD);
assertFalse(mScreen.isReady());
}
mSensor.sendSensorEvent(2);
@Test
public void notReady_afterZeroBrightness() {
mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
mScreen.transitionTo(INITIALIZED, DOZE_AOD);
mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSING);
mScreen.transitionTo(DOZE_AOD_PAUSING, DOZE_AOD_PAUSED);
mSensor.sendSensorEvent(0);
assertFalse(mScreen.isReady());
mScreen.transitionTo(DOZE_AOD_PAUSED, DOZE_AOD);
mSensor.sendSensorEvent(2);
assertEquals(0f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */);
}
@Test
public void ready_afterNonZeroBrightness() {
public void pausingAod_unblanksIfSensorWasAlwaysReady() throws Exception {
mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
mScreen.transitionTo(INITIALIZED, DOZE_AOD);
mSensor.sendSensorEvent(1);
mSensor.sendSensorEvent(2);
assertTrue(mScreen.isReady());
}
mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSING);
mScreen.transitionTo(DOZE_AOD_PAUSING, DOZE_AOD_PAUSED);
mScreen.transitionTo(DOZE_AOD_PAUSED, DOZE_AOD);
@Test
public void notReady_nonZeroThenZeroBrightness() {
mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
mScreen.transitionTo(INITIALIZED, DOZE_AOD);
mSensor.sendSensorEvent(1);
mSensor.sendSensorEvent(0);
assertFalse(mScreen.isReady());
}
@Test
public void readyListener_getsCalled_whenRegistering() throws Exception {
Boolean[] ready = new Boolean[1];
mScreen.setBrightnessReadyListener((x) -> ready[0] = true);
assertTrue(ready[0]);
}
@Test
public void readyListener_getsCalled_whenReadyChanges() throws Exception {
Boolean[] ready = new Boolean[1];
mScreen.setBrightnessReadyListener((x) -> ready[0] = true);
mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
mScreen.transitionTo(INITIALIZED, DOZE_AOD);
ready[0] = null;
mSensor.sendSensorEvent(1);
assertTrue(ready[0]);
assertEquals(0f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */);
}
}

View 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);
}
}