From 67cca7442bfeffc0bace506a796cfdd39e5d511c Mon Sep 17 00:00:00 2001 From: Adrian Roos Date: Thu, 13 Apr 2017 16:52:51 -0700 Subject: [PATCH] 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 --- .../com/android/systemui/doze/DozeHost.java | 2 + .../android/systemui/doze/DozeMachine.java | 11 +++- .../android/systemui/doze/DozeSensors.java | 52 ++++++++++++++++++- .../android/systemui/doze/DozeTriggers.java | 36 ++++++++++++- .../src/com/android/systemui/doze/DozeUi.java | 3 ++ .../statusbar/phone/DozeParameters.java | 4 ++ .../statusbar/phone/DozeScrimController.java | 40 ++++++++++---- .../phone/FingerprintUnlockController.java | 2 +- .../systemui/statusbar/phone/StatusBar.java | 15 +++++- .../phone/StatusBarWindowManager.java | 8 ++- .../statusbar/phone/StatusBarWindowView.java | 3 ++ 11 files changed, 159 insertions(+), 17 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java index f3fb1efb7decb..ec56e15dbd8d4 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java @@ -33,6 +33,8 @@ public interface DozeHost { boolean isPulsingBlocked(); void startPendingIntentDismissingKeyguard(PendingIntent intent); + void abortPulsing(); + void extendPulse(); interface Callback { default void onNotificationHeadsUp() {} diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java index f27521e20bbca..1cc5fb956c99d 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java @@ -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; diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java index 2ac06579f259e..73f522244a608 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java @@ -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 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 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; diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java index 1b9bf73847b58..9b3593b9cbdda 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java @@ -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; } } diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java index f577654c724c3..6098a20a0c648 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java @@ -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; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java index 7b2e9979fb33e..1a00d7e98c881 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java @@ -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 diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java index b78f7482b9f38..c5f23c5e066ad 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java @@ -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, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java index 2bb3cbc31cebb..92069142a61fa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java @@ -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) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 472af653af6e8..41563258d168d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -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. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java index deb0070ccbc01..0326e4025a795 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java @@ -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; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java index 1848d4ea438bf..1a09d75be6325 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java @@ -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); }