AOD: Prolong AOD2 after interaction, turn off AOD when prox covered

Turns off AOD 1 and 2 when the proximity sensor is covered.
Also extends the AOD2 duration when the screen is touched or
the lift gesture is triggered.

Also fixes some issues with the fingerprint unlock transition
from AOD where the doze state for the NotificationPanelView
was cleared too early.

Also hides the wallpaper while we're dozing.

Test: runtest -x packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
Fixes: 36893539
Fixes: 36893538
Fixes: 36033906
Fixes: 37327153
Change-Id: I3fccae1515a0daf2ff99589ed78ec947687e6262
This commit is contained in:
Adrian Roos
2017-04-13 16:52:51 -07:00
parent 1aade4e4a1
commit 67cca7442b
11 changed files with 159 additions and 17 deletions

View File

@@ -33,6 +33,8 @@ public interface DozeHost {
boolean isPulsingBlocked();
void startPendingIntentDismissingKeyguard(PendingIntent intent);
void abortPulsing();
void extendPulse();
interface Callback {
default void onNotificationHeadsUp() {}

View File

@@ -58,12 +58,15 @@ public class DozeMachine {
/** Pulse is done showing. Followed by transition to DOZE or DOZE_AOD. */
DOZE_PULSE_DONE,
/** Doze is done. DozeService is finished. */
FINISH;
FINISH,
/** AOD, but the display is temporarily off. */
DOZE_AOD_PAUSED;
boolean canPulse() {
switch (this) {
case DOZE:
case DOZE_AOD:
case DOZE_AOD_PAUSED:
return true;
default:
return false;
@@ -85,6 +88,7 @@ public class DozeMachine {
case UNINITIALIZED:
case INITIALIZED:
case DOZE:
case DOZE_AOD_PAUSED:
return Display.STATE_OFF;
case DOZE_PULSING:
case DOZE_AOD:
@@ -241,6 +245,11 @@ public class DozeMachine {
if (mState == State.FINISH) {
return State.FINISH;
}
if ((mState == State.DOZE_AOD_PAUSED || mState == State.DOZE_AOD || mState == State.DOZE)
&& requestedState == State.DOZE_PULSE_DONE) {
Log.i(TAG, "Dropping pulse done because current state is already done: " + mState);
return mState;
}
if (requestedState == State.DOZE_REQUEST_PULSE && !mState.canPulse()) {
Log.i(TAG, "Dropping pulse request because current state can't pulse: " + mState);
return mState;

View File

@@ -22,6 +22,8 @@ import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.hardware.TriggerEvent;
import android.hardware.TriggerEventListener;
@@ -40,6 +42,7 @@ import com.android.systemui.util.wakelock.WakeLock;
import java.io.PrintWriter;
import java.util.List;
import java.util.function.Consumer;
public class DozeSensors {
@@ -55,18 +58,22 @@ public class DozeSensors {
private final DozeParameters mDozeParameters;
private final AmbientDisplayConfiguration mConfig;
private final WakeLock mWakeLock;
private final Consumer<Boolean> mProxCallback;
private final Callback mCallback;
private final Handler mHandler = new Handler();
private final ProxSensor mProxSensor;
public DozeSensors(Context context, SensorManager sensorManager, DozeParameters dozeParameters,
AmbientDisplayConfiguration config, WakeLock wakeLock, Callback callback) {
AmbientDisplayConfiguration config, WakeLock wakeLock, Callback callback,
Consumer<Boolean> proxCallback) {
mContext = context;
mSensorManager = sensorManager;
mDozeParameters = dozeParameters;
mConfig = config;
mWakeLock = wakeLock;
mProxCallback = proxCallback;
mResolver = mContext.getContentResolver();
mSensors = new TriggerSensor[] {
@@ -86,6 +93,8 @@ public class DozeSensors {
true /* configured */,
DozeLog.PULSE_REASON_SENSOR_DOUBLE_TAP)
};
mProxSensor = new ProxSensor();
mCallback = callback;
}
@@ -129,6 +138,10 @@ public class DozeSensors {
}
}
public void setProxListening(boolean listen) {
mProxSensor.setRegistered(listen);
}
private final ContentObserver mSettingsObserver = new ContentObserver(mHandler) {
@Override
public void onChange(boolean selfChange, Uri uri, int userId) {
@@ -152,6 +165,43 @@ public class DozeSensors {
}
}
private class ProxSensor implements SensorEventListener {
boolean mRegistered;
Boolean mCurrentlyFar;
void setRegistered(boolean register) {
if (mRegistered == register) {
// Send an update even if we don't re-register.
mHandler.post(() -> {
if (mCurrentlyFar != null) {
mProxCallback.accept(mCurrentlyFar);
}
});
return;
}
if (register) {
mRegistered = mSensorManager.registerListener(this,
mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY),
SensorManager.SENSOR_DELAY_NORMAL, mHandler);
} else {
mSensorManager.unregisterListener(this);
mRegistered = false;
mCurrentlyFar = null;
}
}
@Override
public void onSensorChanged(SensorEvent event) {
mCurrentlyFar = event.values[0] >= event.sensor.getMaximumRange();
mProxCallback.accept(mCurrentlyFar);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
private class TriggerSensor extends TriggerEventListener {
final Sensor mSensor;
final boolean mConfigured;

View File

@@ -46,6 +46,7 @@ import java.io.PrintWriter;
public class DozeTriggers implements DozeMachine.Part {
private static final String TAG = "DozeTriggers";
private static final boolean DEBUG = DozeService.DEBUG;
/** adb shell am broadcast -a com.android.systemui.doze.pulse com.android.systemui */
private static final String PULSE_ACTION = "com.android.systemui.doze.pulse";
@@ -81,7 +82,7 @@ public class DozeTriggers implements DozeMachine.Part {
mWakeLock = wakeLock;
mAllowPulseTriggers = allowPulseTriggers;
mDozeSensors = new DozeSensors(context, mSensorManager, dozeParameters, config,
wakeLock, this::onSensor);
wakeLock, this::onSensor, this::onProximityFar);
mUiModeManager = mContext.getSystemService(UiModeManager.class);
}
@@ -113,6 +114,22 @@ public class DozeTriggers implements DozeMachine.Part {
}
}
private void onProximityFar(boolean far) {
final boolean near = !far;
DozeMachine.State state = mMachine.getState();
if (near && state == DozeMachine.State.DOZE_PULSING) {
if (DEBUG) Log.i(TAG, "Prox NEAR, ending pulse");
mMachine.requestState(DozeMachine.State.DOZE_PULSE_DONE);
}
if (far && state == DozeMachine.State.DOZE_AOD_PAUSED) {
if (DEBUG) Log.i(TAG, "Prox FAR, unpausing AOD");
mMachine.requestState(DozeMachine.State.DOZE_AOD);
} else if (near && state == DozeMachine.State.DOZE_AOD) {
if (DEBUG) Log.i(TAG, "Prox NEAR, pausing AOD");
mMachine.requestState(DozeMachine.State.DOZE_AOD_PAUSED);
}
}
private void onCarMode() {
mMachine.requestState(DozeMachine.State.FINISH);
}
@@ -131,15 +148,21 @@ public class DozeTriggers implements DozeMachine.Part {
break;
case DOZE:
case DOZE_AOD:
case DOZE_AOD_PAUSED:
mDozeSensors.setProxListening(newState != DozeMachine.State.DOZE);
mDozeSensors.setListening(true);
if (oldState != DozeMachine.State.INITIALIZED) {
mDozeSensors.reregisterAllSensors();
}
break;
case DOZE_PULSING:
mDozeSensors.setProxListening(true);
break;
case FINISH:
mBroadcastReceiver.unregister(mContext);
mDozeHost.removeCallback(mHostCallback);
mDozeSensors.setListening(false);
mDozeSensors.setProxListening(false);
break;
default:
}
@@ -156,6 +179,7 @@ public class DozeTriggers implements DozeMachine.Part {
private void requestPulse(final int reason, boolean performedProxCheck) {
Assert.isMainThread();
mDozeHost.extendPulse();
if (mPulsePending || !mAllowPulseTriggers || !canPulse()) {
return;
}
@@ -286,6 +310,8 @@ public class DozeTriggers implements DozeMachine.Part {
}
private class TriggerReceiver extends BroadcastReceiver {
private boolean mRegistered;
@Override
public void onReceive(Context context, Intent intent) {
if (PULSE_ACTION.equals(intent.getAction())) {
@@ -301,14 +327,22 @@ public class DozeTriggers implements DozeMachine.Part {
}
public void register(Context context) {
if (mRegistered) {
return;
}
IntentFilter filter = new IntentFilter(PULSE_ACTION);
filter.addAction(UiModeManager.ACTION_ENTER_CAR_MODE);
filter.addAction(Intent.ACTION_USER_SWITCHED);
context.registerReceiver(this, filter);
mRegistered = true;
}
public void unregister(Context context) {
if (!mRegistered) {
return;
}
context.unregisterReceiver(this);
mRegistered = false;
}
}

View File

@@ -75,11 +75,14 @@ public class DozeUi implements DozeMachine.Part {
scheduleTimeTick();
break;
case DOZE:
case DOZE_AOD_PAUSED:
unscheduleTimeTick();
break;
case DOZE_REQUEST_PULSE:
pulseWhileDozing(DozeLog.PULSE_REASON_NOTIFICATION /* TODO */);
break;
case DOZE_PULSE_DONE:
mHost.abortPulsing();
case INITIALIZED:
mHost.startDozing();
break;

View File

@@ -158,6 +158,10 @@ public class DozeParameters {
return sPickupSubtypePerformsProxMatcher.isIn(subType);
}
public int getPulseVisibleDurationExtended() {
return 2 * getPulseVisibleDuration();
}
/**
* Parses a spec of the form `1,2,3,!5,*`. The resulting object will match numbers that are

View File

@@ -30,6 +30,7 @@ import com.android.keyguard.KeyguardStatusView;
import com.android.systemui.Interpolators;
import com.android.systemui.doze.DozeHost;
import com.android.systemui.doze.DozeLog;
import com.android.systemui.doze.DozeTriggers;
/**
* Controller which handles all the doze animations of the scrims.
@@ -43,8 +44,6 @@ public class DozeScrimController {
private final ScrimController mScrimController;
private final Context mContext;
private final View mStackScroller;
private final NotificationPanelView mNotificationPanelView;
private boolean mDozing;
private DozeHost.PulseCallback mPulseCallback;
@@ -53,24 +52,22 @@ public class DozeScrimController {
private Animator mBehindAnimator;
private float mInFrontTarget;
private float mBehindTarget;
private boolean mDozingAborted;
public DozeScrimController(ScrimController scrimController, Context context,
View stackScroller, NotificationPanelView notificationPanelView) {
public DozeScrimController(ScrimController scrimController, Context context) {
mContext = context;
mStackScroller = stackScroller;
mScrimController = scrimController;
mDozeParameters = new DozeParameters(context);
mNotificationPanelView = notificationPanelView;
}
public void setDozing(boolean dozing, boolean animate) {
if (mDozing == dozing) return;
mDozing = dozing;
if (mDozing) {
mDozingAborted = false;
abortAnimations();
mScrimController.setDozeBehindAlpha(1f);
mScrimController.setDozeInFrontAlpha(mDozeParameters.getAlwaysOn() ? 0f : 1f);
mNotificationPanelView.setDark(true);
} else {
cancelPulsing();
if (animate) {
@@ -85,8 +82,6 @@ public class DozeScrimController {
mScrimController.setDozeBehindAlpha(0f);
mScrimController.setDozeInFrontAlpha(0f);
}
// TODO: animate
mNotificationPanelView.setDark(false);
}
}
@@ -116,10 +111,19 @@ public class DozeScrimController {
cancelPulsing();
if (mDozing) {
mScrimController.setDozeBehindAlpha(1f);
mScrimController.setDozeInFrontAlpha(1f);
mScrimController.setDozeInFrontAlpha(
mDozeParameters.getAlwaysOn() && !mDozingAborted ? 0f : 1f);
}
}
/**
* Aborts dozing immediately.
*/
public void abortDoze() {
mDozingAborted = true;
abortPulsing();
}
public void onScreenTurnedOn() {
if (isPulsing()) {
final boolean pickupOrDoubleTap = mPulseReason == DozeLog.PULSE_REASON_SENSOR_PICKUP
@@ -139,12 +143,17 @@ public class DozeScrimController {
return mDozing;
}
public void extendPulse() {
mHandler.removeCallbacks(mPulseOut);
}
private void cancelPulsing() {
if (DEBUG) Log.d(TAG, "Cancel pulsing");
if (mPulseCallback != null) {
mHandler.removeCallbacks(mPulseIn);
mHandler.removeCallbacks(mPulseOut);
mHandler.removeCallbacks(mPulseOutExtended);
pulseFinished();
}
}
@@ -271,12 +280,23 @@ public class DozeScrimController {
if (DEBUG) Log.d(TAG, "Pulse in finished, mDozing=" + mDozing);
if (!mDozing) return;
mHandler.postDelayed(mPulseOut, mDozeParameters.getPulseVisibleDuration());
mHandler.postDelayed(mPulseOutExtended,
mDozeParameters.getPulseVisibleDurationExtended());
}
};
private final Runnable mPulseOutExtended = new Runnable() {
@Override
public void run() {
mHandler.removeCallbacks(mPulseOut);
mPulseOut.run();
}
};
private final Runnable mPulseOut = new Runnable() {
@Override
public void run() {
mHandler.removeCallbacks(mPulseOutExtended);
if (DEBUG) Log.d(TAG, "Pulse out, mDozing=" + mDozing);
if (!mDozing) return;
startScrimAnimation(true /* inFront */, mDozeParameters.getAlwaysOn() ? 0 : 1,

View File

@@ -221,7 +221,7 @@ public class FingerprintUnlockController extends KeyguardUpdateMonitorCallback {
case MODE_WAKE_AND_UNLOCK:
Trace.beginSection("MODE_WAKE_AND_UNLOCK");
mStatusBarWindowManager.setStatusBarFocusable(false);
mDozeScrimController.abortPulsing();
mDozeScrimController.abortDoze();
mKeyguardViewMediator.onWakeAndUnlocking();
mScrimController.setWakeAndUnlocking();
if (mStatusBar.getNavigationBarView() != null) {

View File

@@ -1112,8 +1112,7 @@ public class StatusBar extends SystemUI implements DemoMode,
}
mHeadsUpManager.addListener(mScrimController);
mStackScroller.setScrimController(mScrimController);
mDozeScrimController = new DozeScrimController(mScrimController, context, mStackScroller,
mNotificationPanel);
mDozeScrimController = new DozeScrimController(mScrimController, context);
// Other icons
mVolumeComponent = getComponent(VolumeComponent.class);
@@ -4330,6 +4329,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mStackScroller.setDark(mDozing, animate, mWakeUpTouchLocation);
mScrimController.setDozing(mDozing);
mKeyguardIndicationController.setDozing(mDozing);
mNotificationPanel.setDark(mDozing);
// Immediately abort the dozing from the doze scrim controller in case of wake-and-unlock
// for pulsing so the Keyguard fade-out animation scrim can take over.
@@ -4956,6 +4956,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mDozing = mDozingRequested && mState == StatusBarState.KEYGUARD
|| mFingerprintUnlockController.getMode()
== FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING;
mStatusBarWindowManager.setDozing(mDozing);
updateDozingState();
Trace.endSection();
}
@@ -5063,6 +5064,16 @@ public class StatusBar extends SystemUI implements DemoMode,
StatusBar.this.startPendingIntentDismissingKeyguard(intent);
}
@Override
public void abortPulsing() {
mDozeScrimController.abortPulsing();
}
@Override
public void extendPulse() {
mDozeScrimController.extendPulse();
}
}
// Begin Extra BaseStatusBar methods.

View File

@@ -118,7 +118,7 @@ public class StatusBarWindowManager implements RemoteInputController.Callback, D
mLpChanged.privateFlags &= ~WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
}
if (state.keyguardShowing && !state.backdropShowing) {
if (state.keyguardShowing && !state.backdropShowing && !state.dozing) {
mLpChanged.flags |= WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
} else {
mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
@@ -357,6 +357,11 @@ public class StatusBarWindowManager implements RemoteInputController.Callback, D
apply(mCurrentState);
}
public void setDozing(boolean dozing) {
mCurrentState.dozing = dozing;
apply(mCurrentState);
}
public void setBarHeight(int barHeight) {
mBarHeight = barHeight;
apply(mCurrentState);
@@ -404,6 +409,7 @@ public class StatusBarWindowManager implements RemoteInputController.Callback, D
boolean remoteInputActive;
boolean forcePluginOpen;
boolean dozing;
private boolean isKeyguardShowingAndNotOccluded() {
return keyguardShowing && !keyguardOccluded;

View File

@@ -255,6 +255,9 @@ public class StatusBarWindowView extends FrameLayout {
if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
mStackScrollLayout.closeControlsIfOutsideTouch(ev);
}
if (mService.isDozing()) {
mService.mDozeScrimController.extendPulse();
}
return super.dispatchTouchEvent(ev);
}