From 43d0d73d0789025cd92336ec241d2e2e21f558a3 Mon Sep 17 00:00:00 2001 From: Lucas Dupin Date: Thu, 16 Nov 2017 11:23:49 -0800 Subject: [PATCH] Add support for seamless transion from/to AoD Bug: 64155983 Test: runtest -x packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java Test: manual Change-Id: I06e72cd5964944c79fb7bfda6881fc4a5a79ca7b --- .../android/systemui/doze/DozeFactory.java | 7 +++-- .../com/android/systemui/doze/DozeHost.java | 1 + .../src/com/android/systemui/doze/DozeUi.java | 9 ++++-- .../statusbar/phone/DozeParameters.java | 22 +++++++++++++ .../systemui/statusbar/phone/ScrimState.java | 31 +++++++++++++------ .../systemui/statusbar/phone/StatusBar.java | 13 +++++++- .../statusbar/stack/StackStateAnimator.java | 2 +- .../android/systemui/doze/DozeHostFake.java | 6 ++++ .../com/android/systemui/doze/DozeUiTest.java | 27 ++++++++++++++-- .../statusbar/phone/ScrimControllerTest.java | 1 + 10 files changed, 100 insertions(+), 19 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java index 6f8bcff16a83b..a409fcb4504a3 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java @@ -63,7 +63,7 @@ public class DozeFactory { new DozeFalsingManagerAdapter(FalsingManager.getInstance(context)), createDozeTriggers(context, sensorManager, host, alarmManager, config, params, handler, wakeLock, machine), - createDozeUi(context, host, wakeLock, machine, handler, alarmManager), + createDozeUi(context, host, wakeLock, machine, handler, alarmManager, params), new DozeScreenState(wrappedService, handler), createDozeScreenBrightness(context, wrappedService, sensorManager, host, handler), }); @@ -89,8 +89,9 @@ public class DozeFactory { } private DozeMachine.Part createDozeUi(Context context, DozeHost host, WakeLock wakeLock, - DozeMachine machine, Handler handler, AlarmManager alarmManager) { - return new DozeUi(context, alarmManager, machine, wakeLock, host, handler); + DozeMachine machine, Handler handler, AlarmManager alarmManager, + DozeParameters params) { + return new DozeUi(context, alarmManager, machine, wakeLock, host, handler, params); } public static DozeHost getHost(DozeService service) { diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java index 2f607eee4f167..6a29299872a48 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java @@ -38,6 +38,7 @@ public interface DozeHost { void extendPulse(); void setAnimateWakeup(boolean animateWakeup); + void setAnimateScreenOff(boolean animateScreenOff); void onDoubleTap(float x, float y); diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java index 851b78cfcd491..b352ec97b2091 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java @@ -23,6 +23,7 @@ import android.os.SystemClock; import android.text.format.Formatter; import android.util.Log; +import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.util.AlarmTimeout; import com.android.systemui.util.wakelock.WakeLock; @@ -41,18 +42,22 @@ public class DozeUi implements DozeMachine.Part { private final WakeLock mWakeLock; private final DozeMachine mMachine; private final AlarmTimeout mTimeTicker; + private final boolean mCanAnimateWakeup; private long mLastTimeTickElapsed = 0; public DozeUi(Context context, AlarmManager alarmManager, DozeMachine machine, - WakeLock wakeLock, DozeHost host, Handler handler) { + WakeLock wakeLock, DozeHost host, Handler handler, + DozeParameters params) { mContext = context; mMachine = machine; mWakeLock = wakeLock; mHost = host; mHandler = handler; + mCanAnimateWakeup = !params.getDisplayNeedsBlanking(); mTimeTicker = new AlarmTimeout(alarmManager, this::onTimeTick, "doze_time_tick", handler); + mHost.setAnimateScreenOff(params.getCanControlScreenOffAnimation()); } private void pulseWhileDozing(int reason) { @@ -106,7 +111,7 @@ public class DozeUi implements DozeMachine.Part { // Keep current state. break; default: - mHost.setAnimateWakeup(false); + mHost.setAnimateWakeup(mCanAnimateWakeup); 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 3f57c2f9384f1..50cbd69e31c8b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java @@ -119,6 +119,28 @@ public class DozeParameters { return mAmbientDisplayConfiguration.alwaysOnEnabled(UserHandle.USER_CURRENT); } + /** + * Some screens need to be completely black before changing the display power mode, + * unexpected behavior might happen if this parameter isn't respected. + * + * @return true if screen needs to be completely black before a power transition. + */ + public boolean getDisplayNeedsBlanking() { + return mContext.getResources().getBoolean( + com.android.internal.R.bool.config_displayBlanksAfterDoze); + } + + /** + * Whether we can implement our own screen off animation or if we need + * to rely on DisplayPowerManager to dim the display. + * + * @return true if SystemUI can control the screen off animation. + */ + public boolean getCanControlScreenOffAnimation() { + return !mContext.getResources().getBoolean( + com.android.internal.R.bool.config_dozeAfterScreenOff); + } + private boolean getBoolean(String propName, int resId) { return SystemProperties.getBoolean(propName, mContext.getResources().getBoolean(resId)); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java index 0db98f3725614..c33cc509e8161 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java @@ -20,6 +20,7 @@ import android.graphics.Color; import android.os.Trace; import com.android.systemui.statusbar.ScrimView; +import com.android.systemui.statusbar.stack.StackStateAnimator; /** * Possible states of the ScrimController state machine. @@ -38,12 +39,18 @@ public enum ScrimState { @Override public void prepare(ScrimState previousState) { - // DisplayPowerManager will blank the screen, we'll just - // set our scrim to black in this frame to avoid flickering and - // fade it out afterwards. - mBlankScreen = previousState == ScrimState.AOD; + mBlankScreen = false; if (previousState == ScrimState.AOD) { - updateScrimColor(mScrimInFront, 1, Color.BLACK); + mAnimationDuration = StackStateAnimator.ANIMATION_DURATION_WAKEUP; + if (mDisplayRequiresBlanking) { + // DisplayPowerManager will blank the screen, we'll just + // set our scrim to black in this frame to avoid flickering and + // fade it out afterwards. + mBlankScreen = true; + updateScrimColor(mScrimInFront, 1, Color.BLACK); + } + } else { + mAnimationDuration = ScrimController.ANIMATION_DURATION; } mCurrentBehindAlpha = mScrimBehindAlphaKeyguard; mCurrentInFrontAlpha = 0; @@ -78,7 +85,7 @@ public enum ScrimState { AOD { @Override public void prepare(ScrimState previousState) { - if (previousState == ScrimState.PULSING) { + if (previousState == ScrimState.PULSING && !mCanControlScreenOff) { updateScrimColor(mScrimInFront, 1, Color.BLACK); } final boolean alwaysOnEnabled = mDozeParameters.getAlwaysOn(); @@ -89,7 +96,7 @@ public enum ScrimState { mCurrentBehindTint = Color.BLACK; // DisplayPowerManager will blank the screen for us, we just need // to set our state. - mAnimateChange = false; + mAnimateChange = mCanControlScreenOff; } }, @@ -103,8 +110,10 @@ public enum ScrimState { mCurrentInFrontAlpha = 0; mCurrentInFrontTint = Color.BLACK; mCurrentBehindTint = Color.BLACK; - mBlankScreen = true; - updateScrimColor(mScrimInFront, 1, Color.BLACK); + mBlankScreen = mDisplayRequiresBlanking; + if (mDisplayRequiresBlanking) { + updateScrimColor(mScrimInFront, 1, Color.BLACK); + } } }, @@ -147,11 +156,15 @@ public enum ScrimState { ScrimView mScrimInFront; ScrimView mScrimBehind; DozeParameters mDozeParameters; + boolean mDisplayRequiresBlanking; + boolean mCanControlScreenOff; public void init(ScrimView scrimInFront, ScrimView scrimBehind, DozeParameters dozeParameters) { mScrimInFront = scrimInFront; mScrimBehind = scrimBehind; mDozeParameters = dozeParameters; + mDisplayRequiresBlanking = dozeParameters.getDisplayNeedsBlanking(); + mCanControlScreenOff = dozeParameters.getCanControlScreenOffAnimation(); } public void prepare(ScrimState previousState) { 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 c61b7e84a318b..7b04f196ea110 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -4407,7 +4407,8 @@ public class StatusBar extends SystemUI implements DemoMode, private void updateDozingState() { Trace.traceCounter(Trace.TRACE_TAG_APP, "dozing", mDozing ? 1 : 0); Trace.beginSection("StatusBar#updateDozingState"); - boolean animate = !mDozing && mDozeServiceHost.shouldAnimateWakeup(); + boolean animate = (!mDozing && mDozeServiceHost.shouldAnimateWakeup()) + || (mDozing && mDozeServiceHost.shouldAnimateScreenOff()); mNotificationPanel.setDozing(mDozing, animate); mStackScroller.setDark(mDozing, animate, mWakeUpTouchLocation); mDozeScrimController.setDozing(mDozing); @@ -5175,6 +5176,7 @@ public class StatusBar extends SystemUI implements DemoMode, private final class DozeServiceHost implements DozeHost { private final ArrayList mCallbacks = new ArrayList<>(); private boolean mAnimateWakeup; + private boolean mAnimateScreenOff; private boolean mIgnoreTouchWhilePulsing; @Override @@ -5321,6 +5323,11 @@ public class StatusBar extends SystemUI implements DemoMode, mAnimateWakeup = animateWakeup; } + @Override + public void setAnimateScreenOff(boolean animateScreenOff) { + mAnimateScreenOff = animateScreenOff; + } + @Override public void onDoubleTap(float screenX, float screenY) { if (screenX > 0 && screenY > 0 && mAmbientIndicationContainer != null @@ -5365,6 +5372,10 @@ public class StatusBar extends SystemUI implements DemoMode, private boolean shouldAnimateWakeup() { return mAnimateWakeup; } + + public boolean shouldAnimateScreenOff() { + return mAnimateScreenOff; + } } public boolean shouldIgnoreTouch() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java index f78a718eff9f3..236c348e539b4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java @@ -40,7 +40,7 @@ import java.util.Stack; public class StackStateAnimator { public static final int ANIMATION_DURATION_STANDARD = 360; - public static final int ANIMATION_DURATION_WAKEUP = 200; + public static final int ANIMATION_DURATION_WAKEUP = 500; public static final int ANIMATION_DURATION_GO_TO_FULL_SHADE = 448; public static final int ANIMATION_DURATION_APPEAR_DISAPPEAR = 464; public static final int ANIMATION_DURATION_DIMMED_ACTIVATED = 220; diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java index 1c104cffc3c1c..3e6bd7e5bfe47 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java @@ -28,6 +28,7 @@ class DozeHostFake implements DozeHost { Callback callback; boolean pulseExtended; boolean animateWakeup; + boolean animateScreenOff; boolean dozing; float doubleTapX; float doubleTapY; @@ -102,6 +103,11 @@ class DozeHostFake implements DozeHost { this.animateWakeup = animateWakeup; } + @Override + public void setAnimateScreenOff(boolean animateScreenOff) { + this.animateScreenOff = animateScreenOff; + } + @Override public void onDoubleTap(float x, float y) { doubleTapX = y; diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java index 19a30cc3c2fdd..75ade9d603e5b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java @@ -16,6 +16,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.INITIALIZED; @@ -28,19 +29,20 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import android.app.AlarmManager; -import android.content.Context; import android.os.Handler; import android.os.HandlerThread; -import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import com.android.systemui.SysuiTestCase; +import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.util.wakelock.WakeLockFake; import org.junit.After; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -66,8 +68,11 @@ public class DozeUiTest extends SysuiTestCase { mWakeLock = new WakeLockFake(); mHost = new DozeHostFake(); mHandler = mHandlerThread.getThreadHandler(); + DozeParameters params = mock(DozeParameters.class); + when(params.getCanControlScreenOffAnimation()).thenReturn(true); + when(params.getDisplayNeedsBlanking()).thenReturn(false); - mDozeUi = new DozeUi(mContext, mAlarmManager, mMachine, mWakeLock, mHost, mHandler); + mDozeUi = new DozeUi(mContext, mAlarmManager, mMachine, mWakeLock, mHost, mHandler, params); } @After @@ -89,4 +94,20 @@ public class DozeUiTest extends SysuiTestCase { verify(mAlarmManager).setExact(anyInt(), anyLong(), eq("doze_time_tick"), any(), any()); } + + @Test + public void propagatesAnimateScreenOff() { + Assert.assertTrue("animateScreenOff should be true", mHost.animateScreenOff); + + DozeParameters params = mock(DozeParameters.class); + new DozeUi(mContext, mAlarmManager, mMachine, mWakeLock, mHost, mHandler, params); + Assert.assertFalse("animateScreenOff should be false", mHost.animateScreenOff); + } + + @Test + public void transitionSetsAnimateWakeup() { + mHost.animateWakeup = false; + mDozeUi.transitionTo(UNINITIALIZED, DOZE); + Assert.assertTrue("animateScreenOff should be true", mHost.animateWakeup); + } } \ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java index b9f695be90cf4..f04e285eb55e2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java @@ -70,6 +70,7 @@ public class ScrimControllerTest extends SysuiTestCase { mScrimVisibilityCallback = (Boolean visible) -> mScrimVisibile = visible; mDozeParamenters = mock(DozeParameters.class); when(mDozeParamenters.getAlwaysOn()).thenAnswer(invocation -> mAlwaysOnEnabled); + when(mDozeParamenters.getDisplayNeedsBlanking()).thenReturn(true); mScrimController = new SynchronousScrimController(mLightBarController, mScrimBehind, mScrimInFront, mHeadsUpScrim, mScrimVisibilityCallback, mDozeParamenters); }