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:
@@ -33,6 +33,8 @@ public interface DozeHost {
|
||||
boolean isPulsingBlocked();
|
||||
|
||||
void startPendingIntentDismissingKeyguard(PendingIntent intent);
|
||||
void abortPulsing();
|
||||
void extendPulse();
|
||||
|
||||
interface Callback {
|
||||
default void onNotificationHeadsUp() {}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user