summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Lucas Dupin <dupin@google.com> 2017-11-28 23:16:12 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2017-11-28 23:16:12 +0000
commit94de3518323afb32eacb5b69c081b184fa60e18d (patch)
tree009db1a7696378d6c31ba08bfa770069d6c89f65
parentd2b6b41095055ee385dc3f63fce6b8b5c0e55e26 (diff)
parent9e3fa1033c1fb43c82abf93f231636a4b103c0e4 (diff)
Merge "Refactoring ScrimController"
-rw-r--r--core/res/res/values/config.xml2
-rw-r--r--packages/SystemUI/res/values/config.xml5
-rw-r--r--packages/SystemUI/res/values/ids.xml1
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemUIFactory.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeHost.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java317
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java655
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java208
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java112
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java88
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java20
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/ScrimViewTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeScrimControllerTest.java99
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java300
19 files changed, 1131 insertions, 736 deletions
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 3512793103bf..65a7ec643078 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1955,7 +1955,7 @@
<string name="config_dozeLongPressSensorType" translatable="false"></string>
<!-- Control whether the always on display mode is available. This should only be enabled on
- devices where the display has be tuned to be power efficient in DOZE and/or DOZE_SUSPEND
+ devices where the display has been tuned to be power efficient in DOZE and/or DOZE_SUSPEND
states. -->
<bool name="config_dozeAlwaysOnDisplayAvailable">false</bool>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index cf7923805f0f..8e065d1bf06b 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -250,10 +250,7 @@
<string name="doze_brightness_sensor_type" translatable="false"></string>
<!-- Doze: pulse parameter - how long does it take to fade in? -->
- <integer name="doze_pulse_duration_in">900</integer>
-
- <!-- Doze: pulse parameter - how long does it take to fade in after a pickup? -->
- <integer name="doze_pulse_duration_in_pickup">130</integer>
+ <integer name="doze_pulse_duration_in">130</integer>
<!-- Doze: pulse parameter - once faded in, how long does it stay visible? -->
<integer name="doze_pulse_duration_visible">6000</integer>
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index cfd95b41825a..884e18918fd6 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -47,6 +47,7 @@
<item type="id" name="qs_icon_tag"/>
<item type="id" name="qs_slash_tag"/>
<item type="id" name="scrim"/>
+ <item type="id" name="scrim_blanking"/>
<item type="id" name="scrim_target"/>
<item type="id" name="scrim_alpha_start"/>
<item type="id" name="scrim_alpha_end"/>
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index 0c067ff38295..526a8f464441 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -28,6 +28,7 @@ import com.android.systemui.Dependency.DependencyProvider;
import com.android.systemui.keyguard.DismissCallbackRegistry;
import com.android.systemui.statusbar.KeyguardIndicationController;
import com.android.systemui.statusbar.ScrimView;
+import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.KeyguardBouncer;
import com.android.systemui.statusbar.phone.LightBarController;
import com.android.systemui.statusbar.phone.LockIcon;
@@ -86,10 +87,10 @@ public class SystemUIFactory {
public ScrimController createScrimController(LightBarController lightBarController,
ScrimView scrimBehind, ScrimView scrimInFront, View headsUpScrim,
- LockscreenWallpaper lockscreenWallpaper,
- Consumer<Boolean> scrimVisibleListener) {
+ LockscreenWallpaper lockscreenWallpaper, Consumer<Boolean> scrimVisibleListener,
+ DozeParameters dozeParameters) {
return new ScrimController(lightBarController, scrimBehind, scrimInFront, headsUpScrim,
- scrimVisibleListener);
+ scrimVisibleListener, dozeParameters);
}
public NotificationIconAreaController createNotificationIconAreaController(Context context,
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
index 7db118d7fb1c..2f607eee4f16 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
@@ -35,7 +35,6 @@ public interface DozeHost {
boolean isBlockingDoze();
void startPendingIntentDismissingKeyguard(PendingIntent intent);
- void abortPulsing();
void extendPulse();
void setAnimateWakeup(boolean animateWakeup);
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index b99e76a28c6d..c92acd068745 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -2028,12 +2028,9 @@ public class KeyguardViewMediator extends SystemUI {
}
public StatusBarKeyguardViewManager registerStatusBar(StatusBar statusBar,
- ViewGroup container,
- ScrimController scrimController,
- FingerprintUnlockController fingerprintUnlockController) {
+ ViewGroup container, FingerprintUnlockController fingerprintUnlockController) {
mStatusBarKeyguardViewManager.registerStatusBar(statusBar, container,
- scrimController, fingerprintUnlockController,
- mDismissCallbackRegistry);
+ fingerprintUnlockController, mDismissCallbackRegistry);
return mStatusBarKeyguardViewManager;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
index a53e348fd16c..fb9c037c236c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
@@ -252,6 +252,13 @@ public class ScrimView extends View implements ConfigurationController.Configura
return false;
}
+ /**
+ * It might look counterintuitive to have another method to set the alpha instead of
+ * only using {@link #setAlpha(float)}. In this case we're in a hardware layer
+ * optimizing blend modes, so it makes sense.
+ *
+ * @param alpha Gradient alpha from 0 to 1.
+ */
public void setViewAlpha(float alpha) {
if (alpha != mViewAlpha) {
mViewAlpha = alpha;
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 6b7397b3f8ca..3f57c2f9384f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -46,10 +46,8 @@ public class DozeParameters {
public void dump(PrintWriter pw) {
pw.println(" DozeParameters:");
pw.print(" getDisplayStateSupported(): "); pw.println(getDisplayStateSupported());
- pw.print(" getPulseDuration(pickup=false): "); pw.println(getPulseDuration(false));
- pw.print(" getPulseDuration(pickup=true): "); pw.println(getPulseDuration(true));
- pw.print(" getPulseInDuration(pickup=false): "); pw.println(getPulseInDuration(false));
- pw.print(" getPulseInDuration(pickup=true): "); pw.println(getPulseInDuration(true));
+ pw.print(" getPulseDuration(): "); pw.println(getPulseDuration());
+ pw.print(" getPulseInDuration(): "); pw.println(getPulseInDuration());
pw.print(" getPulseInVisibleDuration(): "); pw.println(getPulseVisibleDuration());
pw.print(" getPulseOutDuration(): "); pw.println(getPulseOutDuration());
pw.print(" getPulseOnSigMotion(): "); pw.println(getPulseOnSigMotion());
@@ -81,14 +79,12 @@ public class DozeParameters {
return mContext.getResources().getBoolean(R.bool.doze_suspend_display_state_supported);
}
- public int getPulseDuration(boolean pickup) {
- return getPulseInDuration(pickup) + getPulseVisibleDuration() + getPulseOutDuration();
+ public int getPulseDuration() {
+ return getPulseInDuration() + getPulseVisibleDuration() + getPulseOutDuration();
}
- public int getPulseInDuration(boolean pickupOrDoubleTap) {
- return pickupOrDoubleTap
- ? getInt("doze.pulse.duration.in.pickup", R.integer.doze_pulse_duration_in_pickup)
- : getInt("doze.pulse.duration.in", R.integer.doze_pulse_duration_in);
+ public int getPulseInDuration() {
+ return getInt("doze.pulse.duration.in", R.integer.doze_pulse_duration_in);
}
public int getPulseVisibleDuration() {
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 8afb8490808e..1011383b72e1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
@@ -16,16 +16,11 @@
package com.android.systemui.statusbar.phone;
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
import android.annotation.NonNull;
import android.content.Context;
import android.os.Handler;
import android.util.Log;
-import android.view.animation.Interpolator;
-import com.android.systemui.Interpolators;
import com.android.systemui.doze.DozeHost;
import com.android.systemui.doze.DozeLog;
@@ -40,74 +35,59 @@ public class DozeScrimController {
private final Handler mHandler = new Handler();
private final ScrimController mScrimController;
- private final Context mContext;
-
private boolean mDozing;
private DozeHost.PulseCallback mPulseCallback;
private int mPulseReason;
- private Animator mInFrontAnimator;
- private Animator mBehindAnimator;
- private float mInFrontTarget;
- private float mBehindTarget;
- private boolean mDozingAborted;
- private boolean mWakeAndUnlocking;
private boolean mFullyPulsing;
- private float mAodFrontScrimOpacity = 0;
- private Runnable mSetDozeInFrontAlphaDelayed;
+ private final ScrimController.Callback mScrimCallback = new ScrimController.Callback() {
+ @Override
+ public void onDisplayBlanked() {
+ if (DEBUG) {
+ Log.d(TAG, "Pulse in, mDozing=" + mDozing + " mPulseReason="
+ + DozeLog.pulseReasonToString(mPulseReason));
+ }
+ if (!mDozing) {
+ return;
+ }
+
+ // Signal that the pulse is ready to turn the screen on and draw.
+ pulseStarted();
+ }
+
+ @Override
+ public void onFinished() {
+ if (DEBUG) {
+ Log.d(TAG, "Pulse in finished, mDozing=" + mDozing);
+ }
+ if (!mDozing) {
+ return;
+ }
+ mHandler.postDelayed(mPulseOut, mDozeParameters.getPulseVisibleDuration());
+ mHandler.postDelayed(mPulseOutExtended,
+ mDozeParameters.getPulseVisibleDurationExtended());
+ mFullyPulsing = true;
+ }
+
+ /**
+ * Transition was aborted before it was over.
+ */
+ @Override
+ public void onCancelled() {
+ pulseFinished();
+ }
+ };
public DozeScrimController(ScrimController scrimController, Context context) {
- mContext = context;
mScrimController = scrimController;
mDozeParameters = new DozeParameters(context);
}
- public void setDozing(boolean dozing, boolean animate) {
+ public void setDozing(boolean dozing) {
if (mDozing == dozing) return;
mDozing = dozing;
- mWakeAndUnlocking = false;
- if (mDozing) {
- mDozingAborted = false;
- abortAnimations();
- mScrimController.setDozeBehindAlpha(1f);
- setDozeInFrontAlpha(mDozeParameters.getAlwaysOn() ? mAodFrontScrimOpacity : 1f);
- } else {
+ if (!mDozing) {
cancelPulsing();
- if (animate) {
- startScrimAnimation(false /* inFront */, 0f /* target */,
- NotificationPanelView.DOZE_ANIMATION_DURATION,
- Interpolators.LINEAR_OUT_SLOW_IN);
- startScrimAnimation(true /* inFront */, 0f /* target */,
- NotificationPanelView.DOZE_ANIMATION_DURATION,
- Interpolators.LINEAR_OUT_SLOW_IN);
- } else {
- abortAnimations();
- mScrimController.setDozeBehindAlpha(0f);
- setDozeInFrontAlpha(0f);
- }
- }
- }
-
- /**
- * Set the opacity of the front scrim when showing AOD1
- *
- * Used to emulate lower brightness values than the hardware supports natively.
- */
- public void setAodDimmingScrim(float scrimOpacity) {
- mAodFrontScrimOpacity = scrimOpacity;
- if (mDozing && !isPulsing() && !mDozingAborted && !mWakeAndUnlocking
- && mDozeParameters.getAlwaysOn()) {
- setDozeInFrontAlpha(mAodFrontScrimOpacity);
- }
- }
-
- public void setWakeAndUnlocking() {
- // Immediately abort the doze scrims in case of wake-and-unlock
- // for pulsing so the Keyguard fade-out animation scrim can take over.
- if (!mWakeAndUnlocking) {
- mWakeAndUnlocking = true;
- mScrimController.setDozeBehindAlpha(0f);
- setDozeInFrontAlpha(0f);
}
}
@@ -118,37 +98,21 @@ public class DozeScrimController {
}
if (!mDozing || mPulseCallback != null) {
+ if (DEBUG) {
+ Log.d(TAG, "Pulse supressed. Dozing: " + mDozeParameters + " had callback? "
+ + (mPulseCallback != null));
+ }
// Pulse suppressed.
callback.onPulseFinished();
return;
}
- // Begin pulse. Note that it's very important that the pulse finished callback
+ // Begin pulse. Note that it's very important that the pulse finished callback
// be invoked when we're done so that the caller can drop the pulse wakelock.
mPulseCallback = callback;
mPulseReason = reason;
- setDozeInFrontAlpha(1f);
- mHandler.post(mPulseIn);
- }
-
- /**
- * Aborts pulsing immediately.
- */
- public void abortPulsing() {
- cancelPulsing();
- if (mDozing && !mWakeAndUnlocking) {
- mScrimController.setDozeBehindAlpha(1f);
- setDozeInFrontAlpha(mDozeParameters.getAlwaysOn() && !mDozingAborted
- ? mAodFrontScrimOpacity : 1f);
- }
- }
- /**
- * Aborts dozing immediately.
- */
- public void abortDoze() {
- mDozingAborted = true;
- abortPulsing();
+ mScrimController.transitionTo(ScrimState.PULSING, mScrimCallback);
}
public void pulseOutNow() {
@@ -157,17 +121,6 @@ public class DozeScrimController {
}
}
- public void onScreenTurnedOn() {
- if (isPulsing()) {
- final boolean pickupOrDoubleTap = mPulseReason == DozeLog.PULSE_REASON_SENSOR_PICKUP
- || mPulseReason == DozeLog.PULSE_REASON_SENSOR_DOUBLE_TAP;
- startScrimAnimation(true /* inFront */, 0f,
- mDozeParameters.getPulseInDuration(pickupOrDoubleTap),
- pickupOrDoubleTap ? Interpolators.LINEAR_OUT_SLOW_IN : Interpolators.ALPHA_OUT,
- mPulseInFinished);
- }
- }
-
public boolean isPulsing() {
return mPulseCallback != null;
}
@@ -181,11 +134,9 @@ public class DozeScrimController {
}
private void cancelPulsing() {
- if (DEBUG) Log.d(TAG, "Cancel pulsing");
-
if (mPulseCallback != null) {
+ if (DEBUG) Log.d(TAG, "Cancel pulsing");
mFullyPulsing = false;
- mHandler.removeCallbacks(mPulseIn);
mHandler.removeCallbacks(mPulseOut);
mHandler.removeCallbacks(mPulseOutExtended);
pulseFinished();
@@ -193,151 +144,20 @@ public class DozeScrimController {
}
private void pulseStarted() {
+ DozeLog.tracePulseStart(mPulseReason);
if (mPulseCallback != null) {
mPulseCallback.onPulseStarted();
}
}
private void pulseFinished() {
+ DozeLog.tracePulseFinish();
if (mPulseCallback != null) {
mPulseCallback.onPulseFinished();
mPulseCallback = null;
}
}
- private void abortAnimations() {
- if (mInFrontAnimator != null) {
- mInFrontAnimator.cancel();
- }
- if (mBehindAnimator != null) {
- mBehindAnimator.cancel();
- }
- }
-
- private void startScrimAnimation(final boolean inFront, float target, long duration,
- Interpolator interpolator) {
- startScrimAnimation(inFront, target, duration, interpolator, null /* endRunnable */);
- }
-
- private void startScrimAnimation(final boolean inFront, float target, long duration,
- Interpolator interpolator, final Runnable endRunnable) {
- Animator current = getCurrentAnimator(inFront);
- if (current != null) {
- float currentTarget = getCurrentTarget(inFront);
- if (currentTarget == target) {
- return;
- }
- current.cancel();
- }
- ValueAnimator anim = ValueAnimator.ofFloat(getDozeAlpha(inFront), target);
- anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- float value = (float) animation.getAnimatedValue();
- setDozeAlpha(inFront, value);
- }
- });
- anim.setInterpolator(interpolator);
- anim.setDuration(duration);
- anim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- setCurrentAnimator(inFront, null);
- if (endRunnable != null) {
- endRunnable.run();
- }
- }
- });
- anim.start();
- setCurrentAnimator(inFront, anim);
- setCurrentTarget(inFront, target);
- }
-
- private float getCurrentTarget(boolean inFront) {
- return inFront ? mInFrontTarget : mBehindTarget;
- }
-
- private void setCurrentTarget(boolean inFront, float target) {
- if (inFront) {
- mInFrontTarget = target;
- } else {
- mBehindTarget = target;
- }
- }
-
- private Animator getCurrentAnimator(boolean inFront) {
- return inFront ? mInFrontAnimator : mBehindAnimator;
- }
-
- private void setCurrentAnimator(boolean inFront, Animator animator) {
- if (inFront) {
- mInFrontAnimator = animator;
- } else {
- mBehindAnimator = animator;
- }
- }
-
- private void setDozeAlpha(boolean inFront, float alpha) {
- if (mWakeAndUnlocking) {
- return;
- }
- if (inFront) {
- mScrimController.setDozeInFrontAlpha(alpha);
- } else {
- mScrimController.setDozeBehindAlpha(alpha);
- }
- }
-
- private float getDozeAlpha(boolean inFront) {
- return inFront
- ? mScrimController.getDozeInFrontAlpha()
- : mScrimController.getDozeBehindAlpha();
- }
-
- private void setDozeInFrontAlpha(float opacity) {
- setDozeInFrontAlphaDelayed(opacity, 0 /* delay */);
-
- }
-
- private void setDozeInFrontAlphaDelayed(float opacity, long delayMs) {
- if (mSetDozeInFrontAlphaDelayed != null) {
- mHandler.removeCallbacks(mSetDozeInFrontAlphaDelayed);
- mSetDozeInFrontAlphaDelayed = null;
- }
- if (delayMs <= 0) {
- mScrimController.setDozeInFrontAlpha(opacity);
- } else {
- mHandler.postDelayed(mSetDozeInFrontAlphaDelayed = () -> {
- setDozeInFrontAlpha(opacity);
- }, delayMs);
- }
- }
-
- private final Runnable mPulseIn = new Runnable() {
- @Override
- public void run() {
- if (DEBUG) Log.d(TAG, "Pulse in, mDozing=" + mDozing + " mPulseReason="
- + DozeLog.pulseReasonToString(mPulseReason));
- if (!mDozing) return;
- DozeLog.tracePulseStart(mPulseReason);
-
- // Signal that the pulse is ready to turn the screen on and draw.
- pulseStarted();
- }
- };
-
- private final Runnable mPulseInFinished = new Runnable() {
- @Override
- public void run() {
- if (DEBUG) Log.d(TAG, "Pulse in finished, mDozing=" + mDozing);
- if (!mDozing) return;
- mHandler.postDelayed(mPulseOut, mDozeParameters.getPulseVisibleDuration());
- mHandler.postDelayed(mPulseOutExtended,
- mDozeParameters.getPulseVisibleDurationExtended());
- mFullyPulsing = true;
- }
- };
-
private final Runnable mPulseOutExtended = new Runnable() {
@Override
public void run() {
@@ -354,38 +174,13 @@ public class DozeScrimController {
mHandler.removeCallbacks(mPulseOutExtended);
if (DEBUG) Log.d(TAG, "Pulse out, mDozing=" + mDozing);
if (!mDozing) return;
- startScrimAnimation(true /* inFront */, 1,
- mDozeParameters.getPulseOutDuration(),
- Interpolators.ALPHA_IN, mPulseOutFinishing);
- }
- };
-
- private final Runnable mPulseOutFinishing = new Runnable() {
- @Override
- public void run() {
- if (DEBUG) Log.d(TAG, "Pulse out finished");
- DozeLog.tracePulseFinish();
- if (mDozeParameters.getAlwaysOn() && mDozing) {
- // Setting power states can block rendering. For AOD, delay finishing the pulse and
- // setting the power state until the fully black scrim had time to hit the
- // framebuffer.
- mHandler.postDelayed(mPulseOutFinished, 30);
- } else {
- mPulseOutFinished.run();
- }
- }
- };
-
- private final Runnable mPulseOutFinished = new Runnable() {
- @Override
- public void run() {
- // Signal that the pulse is all finished so we can turn the screen off now.
- DozeScrimController.this.pulseFinished();
- if (mDozeParameters.getAlwaysOn()) {
- // Setting power states can happen after we push out the frame. Make sure we
- // stay fully opaque until the power state request reaches the lower levels.
- setDozeInFrontAlphaDelayed(mAodFrontScrimOpacity, 100);
- }
+ mScrimController.transitionTo(ScrimState.AOD,
+ new ScrimController.Callback() {
+ @Override
+ public void onDisplayBlanked() {
+ pulseFinished();
+ }
+ });
}
};
-}
+} \ No newline at end of file
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 91369dbd5f89..80d4061b3864 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
@@ -181,9 +181,9 @@ public class FingerprintUnlockController extends KeyguardUpdateMonitorCallback {
}
private boolean pulsingOrAod() {
- boolean pulsing = mDozeScrimController.isPulsing();
- boolean dozingWithScreenOn = mStatusBar.isDozing() && !mStatusBar.isScreenFullyOff();
- return pulsing || dozingWithScreenOn;
+ final ScrimState scrimState = mScrimController.getState();
+ return scrimState == ScrimState.AOD
+ || scrimState == ScrimState.PULSING;
}
@Override
@@ -246,15 +246,12 @@ public class FingerprintUnlockController extends KeyguardUpdateMonitorCallback {
true /* allowEnterAnimation */);
} else if (mMode == MODE_WAKE_AND_UNLOCK){
Trace.beginSection("MODE_WAKE_AND_UNLOCK");
- mDozeScrimController.abortDoze();
} else {
Trace.beginSection("MODE_WAKE_AND_UNLOCK_FROM_DREAM");
mUpdateMonitor.awakenFromDream();
}
mStatusBarWindowManager.setStatusBarFocusable(false);
mKeyguardViewMediator.onWakeAndUnlocking();
- mScrimController.setWakeAndUnlocking();
- mDozeScrimController.setWakeAndUnlocking();
if (mStatusBar.getNavigationBarView() != null) {
mStatusBar.getNavigationBarView().setWakeAndUnlocking(true);
}
@@ -269,6 +266,7 @@ public class FingerprintUnlockController extends KeyguardUpdateMonitorCallback {
}
private void showBouncer() {
+ mScrimController.transitionTo(ScrimState.BOUNCER);
mStatusBarKeyguardViewManager.animateCollapsePanels(
FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR);
mPendingShowBouncer = false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 702afa3a38b1..dfd4c1768268 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -25,7 +25,9 @@ import android.content.Context;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import android.os.Handler;
import android.os.Trace;
+import android.util.Log;
import android.util.MathUtils;
import android.view.View;
import android.view.ViewGroup;
@@ -34,12 +36,14 @@ import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.colorextraction.ColorExtractor;
import com.android.internal.colorextraction.ColorExtractor.GradientColors;
import com.android.internal.colorextraction.ColorExtractor.OnColorsChangedListener;
import com.android.internal.graphics.ColorUtils;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.Dependency;
+import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.statusbar.ExpandableNotificationRow;
@@ -47,7 +51,10 @@ import com.android.systemui.statusbar.NotificationData;
import com.android.systemui.statusbar.ScrimView;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
import com.android.systemui.statusbar.stack.ViewState;
+import com.android.systemui.util.wakelock.DelayedWakeLock;
+import com.android.systemui.util.wakelock.WakeLock;
+import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.function.Consumer;
@@ -56,33 +63,54 @@ import java.util.function.Consumer;
* security method gets shown).
*/
public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
- OnHeadsUpChangedListener, OnColorsChangedListener {
+ OnHeadsUpChangedListener, OnColorsChangedListener, Dumpable {
+
+ private static final String TAG = "ScrimController";
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
public static final long ANIMATION_DURATION = 220;
public static final Interpolator KEYGUARD_FADE_OUT_INTERPOLATOR
= new PathInterpolator(0f, 0, 0.7f, 1f);
public static final Interpolator KEYGUARD_FADE_OUT_INTERPOLATOR_LOCKED
= new PathInterpolator(0.3f, 0f, 0.8f, 1f);
- // Default alpha value for most scrims, if unsure use this constant
+ /**
+ * Default alpha value for most scrims.
+ */
public static final float GRADIENT_SCRIM_ALPHA = 0.45f;
- // A scrim varies its opacity based on a busyness factor, for example
- // how many notifications are currently visible.
+ /**
+ * A scrim varies its opacity based on a busyness factor, for example
+ * how many notifications are currently visible.
+ */
public static final float GRADIENT_SCRIM_ALPHA_BUSY = 0.70f;
+ /**
+ * The most common scrim, the one under the keyguard.
+ */
protected static final float SCRIM_BEHIND_ALPHA_KEYGUARD = GRADIENT_SCRIM_ALPHA;
+ /**
+ * We fade out the bottom scrim when the bouncer is visible.
+ */
protected static final float SCRIM_BEHIND_ALPHA_UNLOCKING = 0.2f;
- private static final float SCRIM_IN_FRONT_ALPHA = GRADIENT_SCRIM_ALPHA_BUSY;
- private static final float SCRIM_IN_FRONT_ALPHA_LOCKED = GRADIENT_SCRIM_ALPHA_BUSY;
- private static final int TAG_KEY_ANIM = R.id.scrim;
+ /**
+ * Opacity of the scrim behind the bouncer (the one doing actual background protection.)
+ */
+ protected static final float SCRIM_IN_FRONT_ALPHA_LOCKED = GRADIENT_SCRIM_ALPHA_BUSY;
+
+ static final int TAG_KEY_ANIM = R.id.scrim;
+ static final int TAG_KEY_ANIM_BLANK = R.id.scrim_blanking;
private static final int TAG_KEY_ANIM_TARGET = R.id.scrim_target;
private static final int TAG_START_ALPHA = R.id.scrim_alpha_start;
private static final int TAG_END_ALPHA = R.id.scrim_alpha_end;
private static final float NOT_INITIALIZED = -1;
- private final LightBarController mLightBarController;
+ private ScrimState mState = ScrimState.UNINITIALIZED;
+ private final Context mContext;
protected final ScrimView mScrimBehind;
protected final ScrimView mScrimInFront;
- private final UnlockMethodCache mUnlockMethodCache;
private final View mHeadsUpScrim;
+ private final LightBarController mLightBarController;
+ private final UnlockMethodCache mUnlockMethodCache;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+ private final DozeParameters mDozeParameters;
private final SysuiColorExtractor mColorExtractor;
private GradientColors mLockColors;
@@ -94,61 +122,53 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
protected float mScrimBehindAlphaKeyguard = SCRIM_BEHIND_ALPHA_KEYGUARD;
protected float mScrimBehindAlphaUnlocking = SCRIM_BEHIND_ALPHA_UNLOCKING;
- protected boolean mKeyguardShowing;
private float mFraction;
private boolean mDarkenWhileDragging;
- protected boolean mBouncerShowing;
- protected boolean mBouncerIsKeyguard = false;
- private boolean mWakeAndUnlocking;
protected boolean mAnimateChange;
private boolean mUpdatePending;
private boolean mTracking;
private boolean mAnimateKeyguardFadingOut;
- protected long mDurationOverride = -1;
+ protected long mAnimationDuration = -1;
private long mAnimationDelay;
private Runnable mOnAnimationFinished;
private boolean mDeferFinishedListener;
private final Interpolator mInterpolator = new DecelerateInterpolator();
- private boolean mDozing;
- private float mDozeInFrontAlpha;
- private float mDozeBehindAlpha;
private float mCurrentInFrontAlpha = NOT_INITIALIZED;
private float mCurrentBehindAlpha = NOT_INITIALIZED;
- private float mCurrentHeadsUpAlpha = NOT_INITIALIZED;
+ private int mCurrentInFrontTint;
+ private int mCurrentBehindTint;
private int mPinnedHeadsUpCount;
private float mTopHeadsUpDragAmount;
private View mDraggedHeadsUpView;
- private boolean mForceHideScrims;
- private boolean mSkipFirstFrame;
- private boolean mDontAnimateBouncerChanges;
private boolean mKeyguardFadingOutInProgress;
- private boolean mAnimatingDozeUnlock;
private ValueAnimator mKeyguardFadeoutAnimation;
- /** Wake up from AOD transition is starting; need fully opaque front scrim */
- private boolean mWakingUpFromAodStarting;
- /** Wake up from AOD transition is in progress; need black tint */
- private boolean mWakingUpFromAodInProgress;
- /** Wake up from AOD transition is animating; need to reset when animation finishes */
- private boolean mWakingUpFromAodAnimationRunning;
- private boolean mScrimsVisble;
+ private boolean mScrimsVisible;
private final Consumer<Boolean> mScrimVisibleListener;
+ private boolean mBlankScreen;
+ private boolean mScreenBlankingCallbackCalled;
+ private Callback mCallback;
+
+ private final WakeLock mWakeLock;
+ private boolean mWakeLockHeld;
public ScrimController(LightBarController lightBarController, ScrimView scrimBehind,
- ScrimView scrimInFront, View headsUpScrim,
- Consumer<Boolean> scrimVisibleListener) {
+ ScrimView scrimInFront, View headsUpScrim, Consumer<Boolean> scrimVisibleListener,
+ DozeParameters dozeParameters) {
mScrimBehind = scrimBehind;
mScrimInFront = scrimInFront;
mHeadsUpScrim = headsUpScrim;
mScrimVisibleListener = scrimVisibleListener;
- final Context context = scrimBehind.getContext();
- mUnlockMethodCache = UnlockMethodCache.getInstance(context);
- mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(context);
+ mContext = scrimBehind.getContext();
+ mUnlockMethodCache = UnlockMethodCache.getInstance(mContext);
+ mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
mLightBarController = lightBarController;
- mScrimBehindAlphaResValue = context.getResources().getFloat(R.dimen.scrim_behind_alpha);
+ mScrimBehindAlphaResValue = mContext.getResources().getFloat(R.dimen.scrim_behind_alpha);
+ mWakeLock = createWakeLock();
// Scrim alpha is initially set to the value on the resource but might be changed
// to make sure that text on top of it is legible.
mScrimBehindAlpha = mScrimBehindAlphaResValue;
+ mDozeParameters = dozeParameters;
mColorExtractor = Dependency.get(SysuiColorExtractor.class);
mColorExtractor.addOnColorsChangedListener(this);
@@ -158,159 +178,155 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
ColorExtractor.TYPE_DARK, true /* ignoreVisibility */);
mNeedsDrawableColorUpdate = true;
+ final ScrimState[] states = ScrimState.values();
+ for (int i = 0; i < states.length; i++) {
+ states[i].init(mScrimInFront, mScrimBehind, mDozeParameters);
+ states[i].setScrimBehindAlphaKeyguard(mScrimBehindAlphaKeyguard);
+ }
+ mState = ScrimState.UNINITIALIZED;
+
updateHeadsUpScrim(false);
updateScrims();
}
- public void setKeyguardShowing(boolean showing) {
- mKeyguardShowing = showing;
-
- // Showing/hiding the keyguard means that scrim colors have to be switched
- mNeedsDrawableColorUpdate = true;
- scheduleUpdate();
- }
-
- protected void setScrimBehindValues(float scrimBehindAlphaKeyguard,
- float scrimBehindAlphaUnlocking) {
- mScrimBehindAlphaKeyguard = scrimBehindAlphaKeyguard;
- mScrimBehindAlphaUnlocking = scrimBehindAlphaUnlocking;
- scheduleUpdate();
- }
-
- public void onTrackingStarted() {
- mTracking = true;
- mDarkenWhileDragging = !mUnlockMethodCache.canSkipBouncer();
- }
-
- public void onExpandingFinished() {
- mTracking = false;
+ public void transitionTo(ScrimState state) {
+ transitionTo(state, null);
}
- public void setPanelExpansion(float fraction) {
- if (mFraction != fraction) {
- mFraction = fraction;
- scheduleUpdate();
- if (mPinnedHeadsUpCount != 0) {
- updateHeadsUpScrim(false);
- }
- if (mKeyguardFadeoutAnimation != null && mTracking) {
- mKeyguardFadeoutAnimation.cancel();
- }
+ public void transitionTo(ScrimState state, Callback callback) {
+ if (state == mState) {
+ return;
+ } else if (DEBUG) {
+ Log.d(TAG, "State changed to: " + state);
}
- }
-
- public void setBouncerShowing(boolean showing) {
- mBouncerShowing = showing;
- mAnimateChange = !mTracking && !mDontAnimateBouncerChanges && !mKeyguardFadingOutInProgress;
- scheduleUpdate();
- }
- /** Prepares the wakeUpFromAod animation (while turning on screen); Forces black scrims. */
- public void prepareWakeUpFromAod() {
- if (mWakingUpFromAodInProgress) {
- return;
+ if (state == ScrimState.UNINITIALIZED) {
+ throw new IllegalArgumentException("Cannot change to UNINITIALIZED.");
}
- mWakingUpFromAodInProgress = true;
- mWakingUpFromAodStarting = true;
- mAnimateChange = false;
- scheduleUpdate();
- onPreDraw();
- }
- /** Starts the wakeUpFromAod animation (once screen is on); animate to transparent scrims. */
- public void wakeUpFromAod() {
- if (mWakeAndUnlocking || mAnimateKeyguardFadingOut) {
- // Wake and unlocking has a separate transition that must not be interfered with.
- mWakingUpFromAodStarting = false;
- mWakingUpFromAodInProgress = false;
- return;
+ if (mCallback != null) {
+ mCallback.onCancelled();
}
- if (mWakingUpFromAodStarting) {
- mWakingUpFromAodInProgress = true;
- mWakingUpFromAodStarting = false;
- mAnimateChange = true;
- scheduleUpdate();
+ mCallback = callback;
+
+ state.prepare(mState);
+ mScreenBlankingCallbackCalled = false;
+ mAnimationDelay = 0;
+ mBlankScreen = state.getBlanksScreen();
+ mAnimateChange = state.getAnimateChange();
+ mAnimationDuration = state.getAnimationDuration();
+ mCurrentInFrontTint = state.getFrontTint();
+ mCurrentBehindTint = state.getBehindTint();
+ mCurrentInFrontAlpha = state.getFrontAlpha();
+ mCurrentBehindAlpha = state.getBehindAlpha();
+
+ // Showing/hiding the keyguard means that scrim colors have to be switched, not necessary
+ // to do the same when you're just showing the brightness mirror.
+ mNeedsDrawableColorUpdate = state != ScrimState.BRIGHTNESS_MIRROR;
+
+ if (mKeyguardFadeoutAnimation != null) {
+ mKeyguardFadeoutAnimation.cancel();
}
- }
- public void setWakeAndUnlocking() {
- mWakeAndUnlocking = true;
- mAnimatingDozeUnlock = true;
- mWakingUpFromAodStarting = false;
- mWakingUpFromAodInProgress = false;
- scheduleUpdate();
- }
+ mState = state;
- public void animateKeyguardFadingOut(long delay, long duration, Runnable onAnimationFinished,
- boolean skipFirstFrame) {
- mWakeAndUnlocking = false;
- mAnimateKeyguardFadingOut = true;
- mDurationOverride = duration;
- mAnimationDelay = delay;
- mAnimateChange = true;
- mSkipFirstFrame = skipFirstFrame;
- mOnAnimationFinished = onAnimationFinished;
+ // Do not let the device sleep until we're done with all animations
+ if (!mWakeLockHeld) {
+ if (mWakeLock != null) {
+ mWakeLockHeld = true;
+ mWakeLock.acquire();
+ } else {
+ Log.w(TAG, "Cannot hold wake lock, it has not been set yet");
+ }
+ }
if (!mKeyguardUpdateMonitor.needsSlowUnlockTransition()) {
scheduleUpdate();
-
- // No need to wait for the next frame to be drawn for this case - onPreDraw will execute
- // the changes we just scheduled.
- onPreDraw();
} else {
-
// In case the user isn't unlocked, make sure to delay a bit because the system is hosed
- // with too many things in this case, in order to not skip the initial frames.
+ // with too many things at this case, in order to not skip the initial frames.
mScrimInFront.postOnAnimationDelayed(this::scheduleUpdate, 16);
+ mAnimationDelay = StatusBar.FADE_KEYGUARD_START_DELAY;
}
}
- public void abortKeyguardFadingOut() {
- if (mAnimateKeyguardFadingOut) {
- endAnimateKeyguardFadingOut(true /* force */);
- }
+ public ScrimState getState() {
+ return mState;
}
- public void animateKeyguardUnoccluding(long duration) {
- mAnimateChange = false;
- setScrimBehindAlpha(0f);
- mAnimateChange = true;
+ protected void setScrimBehindValues(float scrimBehindAlphaKeyguard,
+ float scrimBehindAlphaUnlocking) {
+ mScrimBehindAlphaKeyguard = scrimBehindAlphaKeyguard;
+ mScrimBehindAlphaUnlocking = scrimBehindAlphaUnlocking;
+ ScrimState[] states = ScrimState.values();
+ for (int i = 0; i < states.length; i++) {
+ states[i].setScrimBehindAlphaKeyguard(scrimBehindAlphaKeyguard);
+ }
scheduleUpdate();
- mDurationOverride = duration;
}
- public void animateGoingToFullShade(long delay, long duration) {
- mDurationOverride = duration;
- mAnimationDelay = delay;
- mAnimateChange = true;
- scheduleUpdate();
+ public void onTrackingStarted() {
+ mTracking = true;
+ mDarkenWhileDragging = !mUnlockMethodCache.canSkipBouncer();
}
- public void setDozing(boolean dozing) {
- if (mDozing != dozing) {
- mDozing = dozing;
- scheduleUpdate();
- }
+ public void onExpandingFinished() {
+ mTracking = false;
}
- public void setDozeInFrontAlpha(float alpha) {
- mDozeInFrontAlpha = alpha;
- updateScrimColor(mScrimInFront);
- }
+ /**
+ * Current state of the shade expansion when pulling it from the top.
+ * This value is 1 when on top of the keyguard and goes to 0 as the user drags up.
+ *
+ * The expansion fraction is tied to the scrim opacity.
+ *
+ * @param fraction From 0 to 1 where 0 means collapse and 1 expanded.
+ */
+ public void setPanelExpansion(float fraction) {
+ if (mFraction != fraction) {
+ mFraction = fraction;
- public void setDozeBehindAlpha(float alpha) {
- mDozeBehindAlpha = alpha;
- updateScrimColor(mScrimBehind);
- }
+ if (mState == ScrimState.UNLOCKED) {
+ // Darken scrim as you pull down the shade when unlocked
+ float behindFraction = getInterpolatedFraction();
+ behindFraction = (float) Math.pow(behindFraction, 0.8f);
+ mCurrentBehindAlpha = behindFraction * mScrimBehindAlphaKeyguard;
+ mCurrentInFrontAlpha = 0;
+ } else if (mState == ScrimState.KEYGUARD) {
+ if (mUpdatePending) {
+ return;
+ }
- public float getDozeBehindAlpha() {
- return mDozeBehindAlpha;
- }
+ // Either darken of make the scrim transparent when you
+ // pull down the shade
+ float interpolatedFract = getInterpolatedFraction();
+ if (mDarkenWhileDragging) {
+ mCurrentBehindAlpha = MathUtils.lerp(mScrimBehindAlphaUnlocking,
+ mScrimBehindAlphaKeyguard, interpolatedFract);
+ mCurrentInFrontAlpha = (1f - interpolatedFract) * SCRIM_IN_FRONT_ALPHA_LOCKED;
+ } else {
+ mCurrentBehindAlpha = MathUtils.lerp(0 /* start */, mScrimBehindAlphaKeyguard,
+ interpolatedFract);
+ mCurrentInFrontAlpha = 0;
+ }
+ } else {
+ Log.w(TAG, "Invalid state, cannot set panel expansion when: " + mState);
+ return;
+ }
+
+ if (mPinnedHeadsUpCount != 0) {
+ updateHeadsUpScrim(false);
+ }
- public float getDozeInFrontAlpha() {
- return mDozeInFrontAlpha;
+ updateScrim(false /* animate */, mScrimInFront, mCurrentInFrontAlpha);
+ updateScrim(false /* animate */, mScrimBehind, mCurrentBehindAlpha);
+ }
}
+ /**
+ * Keyguard and shade scrim opacity varies according to how many notifications are visible.
+ * @param notificationCount Number of visible notifications.
+ */
public void setNotificationCount(int notificationCount) {
final float maxNotificationDensity = 3;
float notificationDensity = Math.min(notificationCount / maxNotificationDensity, 1f);
@@ -319,15 +335,11 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
notificationDensity);
if (mScrimBehindAlphaKeyguard != newAlpha) {
mScrimBehindAlphaKeyguard = newAlpha;
- mAnimateChange = true;
- scheduleUpdate();
- }
- }
- private float getScrimInFrontAlpha() {
- return mKeyguardUpdateMonitor.needsSlowUnlockTransition()
- ? SCRIM_IN_FRONT_ALPHA_LOCKED
- : SCRIM_IN_FRONT_ALPHA;
+ if (mState == ScrimState.KEYGUARD || mState == ScrimState.BOUNCER) {
+ scheduleUpdate();
+ }
+ }
}
/**
@@ -352,7 +364,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
if (mNeedsDrawableColorUpdate) {
mNeedsDrawableColorUpdate = false;
final GradientColors currentScrimColors;
- if (mKeyguardShowing) {
+ if (mState == ScrimState.KEYGUARD || mState == ScrimState.BOUNCER) {
// Always animate color changes if we're seeing the keyguard
mScrimInFront.setColors(mLockColors, true /* animated */);
mScrimBehind.setColors(mLockColors, true /* animated */);
@@ -375,77 +387,31 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
mLightBarController.setScrimColor(mScrimInFront.getColors());
}
- if (mAnimateKeyguardFadingOut || mForceHideScrims) {
- setScrimInFrontAlpha(0f);
- setScrimBehindAlpha(0f);
- } else if (mWakeAndUnlocking) {
- // During wake and unlock, we first hide everything behind a black scrim, which then
- // gets faded out from animateKeyguardFadingOut. This must never be animated.
- mAnimateChange = false;
- if (mDozing) {
- setScrimInFrontAlpha(0f);
- setScrimBehindAlpha(1f);
- } else {
- setScrimInFrontAlpha(1f);
- setScrimBehindAlpha(0f);
- }
- } else if (!mKeyguardShowing && !mBouncerShowing && !mWakingUpFromAodStarting) {
- updateScrimNormal();
- setScrimInFrontAlpha(0);
- } else {
- updateScrimKeyguard();
- }
- mAnimateChange = false;
+ setScrimInFrontAlpha(mCurrentInFrontAlpha);
+ setScrimBehindAlpha(mCurrentBehindAlpha);
+
dispatchScrimsVisible();
}
private void dispatchScrimsVisible() {
boolean scrimsVisible = mScrimBehind.getViewAlpha() > 0 || mScrimInFront.getViewAlpha() > 0;
- if (mScrimsVisble != scrimsVisible) {
- mScrimsVisble = scrimsVisible;
+ if (mScrimsVisible != scrimsVisible) {
+ mScrimsVisible = scrimsVisible;
mScrimVisibleListener.accept(scrimsVisible);
}
}
- private void updateScrimKeyguard() {
- if (mTracking && mDarkenWhileDragging) {
- float behindFraction = Math.max(0, Math.min(mFraction, 1));
- float fraction = 1 - behindFraction;
- fraction = (float) Math.pow(fraction, 0.8f);
- behindFraction = (float) Math.pow(behindFraction, 0.8f);
- setScrimInFrontAlpha(fraction * getScrimInFrontAlpha());
- setScrimBehindAlpha(behindFraction * mScrimBehindAlphaKeyguard);
- } else if (mBouncerShowing && !mBouncerIsKeyguard) {
- setScrimInFrontAlpha(getScrimInFrontAlpha());
- updateScrimNormal();
- } else if (mBouncerShowing) {
- setScrimInFrontAlpha(0f);
- setScrimBehindAlpha(mScrimBehindAlpha);
- } else {
- float fraction = Math.max(0, Math.min(mFraction, 1));
- if (mWakingUpFromAodStarting) {
- setScrimInFrontAlpha(1f);
- } else {
- setScrimInFrontAlpha(0f);
- }
- setScrimBehindAlpha(fraction
- * (mScrimBehindAlphaKeyguard - mScrimBehindAlphaUnlocking)
- + mScrimBehindAlphaUnlocking);
- }
- }
-
- private void updateScrimNormal() {
+ private float getInterpolatedFraction() {
float frac = mFraction;
// let's start this 20% of the way down the screen
frac = frac * 1.2f - 0.2f;
if (frac <= 0) {
- setScrimBehindAlpha(0);
+ return 0;
} else {
// woo, special effects
- final float k = (float)(1f-0.5f*(1f-Math.cos(3.14159f * Math.pow(1f-frac, 2f))));
- setScrimBehindAlpha(k * mScrimBehindAlpha);
+ return (float)(1f-0.5f*(1f-Math.cos(3.14159f * Math.pow(1f-frac, 2f))));
}
}
@@ -455,102 +421,76 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
private void setScrimInFrontAlpha(float alpha) {
setScrimAlpha(mScrimInFront, alpha);
- if (alpha == 0f) {
- mScrimInFront.setClickable(false);
- } else {
- // Eat touch events (unless dozing).
- mScrimInFront.setClickable(!mDozing);
- }
}
private void setScrimAlpha(View scrim, float alpha) {
- updateScrim(mAnimateChange, scrim, alpha, getCurrentScrimAlpha(scrim));
- }
-
- protected float getDozeAlpha(View scrim) {
- return scrim == mScrimBehind ? mDozeBehindAlpha : mDozeInFrontAlpha;
- }
-
- protected float getCurrentScrimAlpha(View scrim) {
- return scrim == mScrimBehind ? mCurrentBehindAlpha
- : scrim == mScrimInFront ? mCurrentInFrontAlpha
- : mCurrentHeadsUpAlpha;
- }
-
- private void setCurrentScrimAlpha(View scrim, float alpha) {
- if (scrim == mScrimBehind) {
- mCurrentBehindAlpha = alpha;
- mLightBarController.setScrimAlpha(mCurrentBehindAlpha);
- } else if (scrim == mScrimInFront) {
- mCurrentInFrontAlpha = alpha;
+ if (alpha == 0f) {
+ scrim.setClickable(false);
} else {
- alpha = Math.max(0.0f, Math.min(1.0f, alpha));
- mCurrentHeadsUpAlpha = alpha;
+ // Eat touch events (unless dozing).
+ scrim.setClickable(!(mState == ScrimState.AOD));
}
+ updateScrim(mAnimateChange, scrim, alpha);
}
- private void updateScrimColor(View scrim) {
- float alpha1 = getCurrentScrimAlpha(scrim);
+ private void updateScrimColor(View scrim, float alpha, int tint) {
+ alpha = Math.max(0, Math.min(1.0f, alpha));
if (scrim instanceof ScrimView) {
ScrimView scrimView = (ScrimView) scrim;
- float dozeAlpha = getDozeAlpha(scrim);
- float alpha = 1 - (1 - alpha1) * (1 - dozeAlpha);
- alpha = Math.max(0, Math.min(1.0f, alpha));
- scrimView.setViewAlpha(alpha);
Trace.traceCounter(Trace.TRACE_TAG_APP,
scrim == mScrimInFront ? "front_scrim_alpha" : "back_scrim_alpha",
(int) (alpha * 255));
- int dozeTint = Color.TRANSPARENT;
-
- boolean dozing = mAnimatingDozeUnlock || mDozing;
- boolean frontScrimDozing = mWakingUpFromAodInProgress;
- if (dozing || frontScrimDozing && scrim == mScrimInFront) {
- dozeTint = Color.BLACK;
- }
Trace.traceCounter(Trace.TRACE_TAG_APP,
scrim == mScrimInFront ? "front_scrim_tint" : "back_scrim_tint",
- dozeTint == Color.BLACK ? 1 : 0);
+ Color.alpha(tint));
- scrimView.setTint(dozeTint);
+ scrimView.setTint(tint);
+ scrimView.setViewAlpha(alpha);
} else {
- scrim.setAlpha(alpha1);
+ scrim.setAlpha(alpha);
}
dispatchScrimsVisible();
}
- private void startScrimAnimation(final View scrim, float target) {
- float current = getCurrentScrimAlpha(scrim);
- ValueAnimator anim = ValueAnimator.ofFloat(current, target);
+ private int getCurrentScrimTint(View scrim) {
+ return scrim == mScrimInFront ? mCurrentInFrontTint : mCurrentBehindTint;
+ }
+
+ private void startScrimAnimation(final View scrim, float current, float target) {
+ ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
+ final int initialScrimTint = scrim instanceof ScrimView ? ((ScrimView) scrim).getTint() :
+ Color.TRANSPARENT;
anim.addUpdateListener(animation -> {
- float alpha = (float) animation.getAnimatedValue();
- setCurrentScrimAlpha(scrim, alpha);
- updateScrimColor(scrim);
+ final float animAmount = (float) animation.getAnimatedValue();
+ final int finalScrimTint = scrim == mScrimInFront ?
+ mCurrentInFrontTint : mCurrentBehindTint;
+ float alpha = MathUtils.lerp(current, target, animAmount);
+ int tint = ColorUtils.blendARGB(initialScrimTint, finalScrimTint, animAmount);
+ updateScrimColor(scrim, alpha, tint);
dispatchScrimsVisible();
});
anim.setInterpolator(getInterpolator());
anim.setStartDelay(mAnimationDelay);
- anim.setDuration(mDurationOverride != -1 ? mDurationOverride : ANIMATION_DURATION);
+ anim.setDuration(mAnimationDuration);
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- if (!mDeferFinishedListener && mOnAnimationFinished != null) {
- mOnAnimationFinished.run();
- mOnAnimationFinished = null;
- }
if (mKeyguardFadingOutInProgress) {
mKeyguardFadeoutAnimation = null;
mKeyguardFadingOutInProgress = false;
- mAnimatingDozeUnlock = false;
- }
- if (mWakingUpFromAodAnimationRunning && !mDeferFinishedListener) {
- mWakingUpFromAodAnimationRunning = false;
- mWakingUpFromAodInProgress = false;
}
+ onFinished();
+
scrim.setTag(TAG_KEY_ANIM, null);
scrim.setTag(TAG_KEY_ANIM_TARGET, null);
dispatchScrimsVisible();
+
+ if (!mDeferFinishedListener && mOnAnimationFinished != null) {
+ mOnAnimationFinished.run();
+ mOnAnimationFinished = null;
+ }
}
});
anim.start();
@@ -558,12 +498,6 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
mKeyguardFadingOutInProgress = true;
mKeyguardFadeoutAnimation = anim;
}
- if (mWakingUpFromAodInProgress) {
- mWakingUpFromAodAnimationRunning = true;
- }
- if (mSkipFirstFrame) {
- anim.setCurrentPlayTime(16);
- }
scrim.setTag(TAG_KEY_ANIM, anim);
scrim.setTag(TAG_KEY_ANIM_TARGET, target);
}
@@ -582,19 +516,33 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
public boolean onPreDraw() {
mScrimBehind.getViewTreeObserver().removeOnPreDrawListener(this);
mUpdatePending = false;
- if (mDontAnimateBouncerChanges) {
- mDontAnimateBouncerChanges = false;
+ if (mCallback != null) {
+ mCallback.onStart();
}
updateScrims();
- mDurationOverride = -1;
- mAnimationDelay = 0;
- mSkipFirstFrame = false;
// Make sure that we always call the listener even if we didn't start an animation.
endAnimateKeyguardFadingOut(false /* force */);
return true;
}
+ private void onFinished() {
+ if (mWakeLockHeld) {
+ mWakeLock.release();
+ mWakeLockHeld = false;
+ }
+ if (mCallback != null) {
+ mCallback.onFinished();
+ mCallback = null;
+ }
+ // When unlocking with fingerprint, we'll fade the scrims from black to transparent.
+ // At the end of the animation we need to remove the tint.
+ if (mState == ScrimState.UNLOCKED) {
+ mCurrentInFrontTint = Color.TRANSPARENT;
+ mCurrentBehindTint = Color.TRANSPARENT;
+ }
+ }
+
private void endAnimateKeyguardFadingOut(boolean force) {
mAnimateKeyguardFadingOut = false;
if (force || (!isAnimating(mScrimInFront) && !isAnimating(mScrimBehind))) {
@@ -603,8 +551,6 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
mOnAnimationFinished = null;
}
mKeyguardFadingOutInProgress = false;
- if (!mWakeAndUnlocking || force)
- mAnimatingDozeUnlock = false;
}
}
@@ -641,16 +587,19 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
}
private void updateHeadsUpScrim(boolean animate) {
- updateScrim(animate, mHeadsUpScrim, calculateHeadsUpAlpha(), mCurrentHeadsUpAlpha);
+ updateScrim(animate, mHeadsUpScrim, calculateHeadsUpAlpha());
}
- private void updateScrim(boolean animate, View scrim, float alpha, float currentAlpha) {
- if (mKeyguardFadingOutInProgress && mKeyguardFadeoutAnimation.getCurrentPlayTime() != 0) {
- return;
- }
+ @VisibleForTesting
+ void setOnAnimationFinished(Runnable onAnimationFinished) {
+ mOnAnimationFinished = onAnimationFinished;
+ }
+
+ private void updateScrim(boolean animate, View scrim, float alpha) {
+ final float currentAlpha = scrim instanceof ScrimView ? ((ScrimView) scrim).getViewAlpha()
+ : scrim.getAlpha();
- ValueAnimator previousAnimator = ViewState.getChildTag(scrim,
- TAG_KEY_ANIM);
+ ValueAnimator previousAnimator = ViewState.getChildTag(scrim, TAG_KEY_ANIM);
float animEndValue = -1;
if (previousAnimator != null) {
if (animate || alpha == currentAlpha) {
@@ -664,9 +613,32 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
animEndValue = ViewState.getChildTag(scrim, TAG_END_ALPHA);
}
}
- if (alpha != currentAlpha && alpha != animEndValue) {
+
+ final boolean blankingInProgress = mScrimInFront.getTag(TAG_KEY_ANIM_BLANK) != null;
+ if (mBlankScreen || blankingInProgress) {
+ if (!blankingInProgress) {
+ blankDisplay();
+ }
+ return;
+ } else if (!mScreenBlankingCallbackCalled) {
+ // Not blanking the screen. Letting the callback know that we're ready
+ // to replace what was on the screen before.
+ if (mCallback != null) {
+ mCallback.onDisplayBlanked();
+ mScreenBlankingCallbackCalled = true;
+ }
+ }
+
+ final ScrimView scrimView = scrim instanceof ScrimView ? (ScrimView) scrim : null;
+ final boolean wantsAlphaUpdate = alpha != currentAlpha && alpha != animEndValue;
+ final boolean wantsTintUpdate = scrimView != null
+ && scrimView.getTint() != getCurrentScrimTint(scrimView);
+
+ if (wantsAlphaUpdate || wantsTintUpdate) {
if (animate) {
- startScrimAnimation(scrim, alpha);
+ final float fromAlpha = scrimView == null ? scrim.getAlpha()
+ : scrimView.getViewAlpha();
+ startScrimAnimation(scrim, fromAlpha, alpha);
scrim.setTag(TAG_START_ALPHA, currentAlpha);
scrim.setTag(TAG_END_ALPHA, alpha);
} else {
@@ -685,13 +657,62 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime());
} else {
// update the alpha directly
- setCurrentScrimAlpha(scrim, alpha);
- updateScrimColor(scrim);
+ updateScrimColor(scrim, alpha, getCurrentScrimTint(scrim));
+ onFinished();
}
}
+ } else {
+ onFinished();
}
}
+ private void blankDisplay() {
+ final float initialAlpha = mScrimInFront.getViewAlpha();
+ final int initialTint = mScrimInFront.getTint();
+ ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
+ anim.addUpdateListener(animation -> {
+ final float amount = (float) animation.getAnimatedValue();
+ float animAlpha = MathUtils.lerp(initialAlpha, 1, amount);
+ int animTint = ColorUtils.blendARGB(initialTint, Color.BLACK, amount);
+ updateScrimColor(mScrimInFront, animAlpha, animTint);
+ dispatchScrimsVisible();
+ });
+ anim.setInterpolator(getInterpolator());
+ anim.setDuration(mDozeParameters.getPulseInDuration());
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (mCallback != null) {
+ mCallback.onDisplayBlanked();
+ mScreenBlankingCallbackCalled = true;
+ }
+ Runnable blankingCallback = () -> {
+ mScrimInFront.setTag(TAG_KEY_ANIM_BLANK, null);
+ mBlankScreen = false;
+ // Try again.
+ updateScrims();
+ };
+
+ // Setting power states can happen after we push out the frame. Make sure we
+ // stay fully opaque until the power state request reaches the lower levels.
+ getHandler().postDelayed(blankingCallback, 100);
+
+ }
+ });
+ anim.start();
+ mScrimInFront.setTag(TAG_KEY_ANIM_BLANK, anim);
+
+ // Finish animation if we're already at its final state
+ if (initialAlpha == 1 && mScrimInFront.getTint() == Color.BLACK) {
+ anim.end();
+ }
+ }
+
+ @VisibleForTesting
+ protected Handler getHandler() {
+ return Handler.getMain();
+ }
+
/**
* Set the amount the current top heads up view is dragged. The range is from 0 to 1 and 0 means
* the heads up is in its resting space and 1 means it's fully dragged out.
@@ -719,23 +740,13 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
return alpha * expandFactor;
}
- public void forceHideScrims(boolean hide, boolean animated) {
- mForceHideScrims = hide;
- mAnimateChange = animated;
- scheduleUpdate();
- }
-
- public void dontAnimateBouncerChangesUntilNextFrame() {
- mDontAnimateBouncerChanges = true;
- }
-
public void setExcludedBackgroundArea(Rect area) {
mScrimBehind.setExcludedArea(area);
}
public int getBackgroundColor() {
int color = mLockColors.getMainColor();
- return Color.argb((int) (mScrimBehind.getAlpha() * Color.alpha(color)),
+ return Color.argb((int) (mScrimBehind.getViewAlpha() * Color.alpha(color)),
Color.red(color), Color.green(color), Color.blue(color));
}
@@ -764,27 +775,41 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
}
if ((which & WallpaperManager.FLAG_SYSTEM) != 0) {
mSystemColors = mColorExtractor.getColors(WallpaperManager.FLAG_SYSTEM,
- ColorExtractor.TYPE_DARK, mKeyguardShowing);
+ ColorExtractor.TYPE_DARK, mState != ScrimState.UNLOCKED);
mNeedsDrawableColorUpdate = true;
scheduleUpdate();
}
}
- public void dump(PrintWriter pw) {
- pw.println(" ScrimController:");
+ @VisibleForTesting
+ protected WakeLock createWakeLock() {
+ return new DelayedWakeLock(getHandler(),
+ WakeLock.createPartial(mContext, "Doze"));
+ }
+ @Override
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ pw.println(" ScrimController:");
+ pw.print(" state:"); pw.println(mState);
pw.print(" frontScrim:"); pw.print(" viewAlpha="); pw.print(mScrimInFront.getViewAlpha());
pw.print(" alpha="); pw.print(mCurrentInFrontAlpha);
- pw.print(" dozeAlpha="); pw.print(mDozeInFrontAlpha);
pw.print(" tint=0x"); pw.println(Integer.toHexString(mScrimInFront.getTint()));
pw.print(" backScrim:"); pw.print(" viewAlpha="); pw.print(mScrimBehind.getViewAlpha());
pw.print(" alpha="); pw.print(mCurrentBehindAlpha);
- pw.print(" dozeAlpha="); pw.print(mDozeBehindAlpha);
pw.print(" tint=0x"); pw.println(Integer.toHexString(mScrimBehind.getTint()));
- pw.print(" mBouncerShowing="); pw.println(mBouncerShowing);
pw.print(" mTracking="); pw.println(mTracking);
- pw.print(" mForceHideScrims="); pw.println(mForceHideScrims);
+ }
+
+ public interface Callback {
+ default void onStart() {
+ }
+ default void onDisplayBlanked() {
+ }
+ default void onFinished() {
+ }
+ default void onCancelled() {
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
new file mode 100644
index 000000000000..0db98f372561
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import android.graphics.Color;
+import android.os.Trace;
+
+import com.android.systemui.statusbar.ScrimView;
+
+/**
+ * Possible states of the ScrimController state machine.
+ */
+public enum ScrimState {
+
+ /**
+ * Initial state.
+ */
+ UNINITIALIZED,
+
+ /**
+ * On the lock screen.
+ */
+ KEYGUARD {
+
+ @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;
+ if (previousState == ScrimState.AOD) {
+ updateScrimColor(mScrimInFront, 1, Color.BLACK);
+ }
+ mCurrentBehindAlpha = mScrimBehindAlphaKeyguard;
+ mCurrentInFrontAlpha = 0;
+ }
+ },
+
+ /**
+ * Showing password challenge.
+ */
+ BOUNCER {
+ @Override
+ public void prepare(ScrimState previousState) {
+ mCurrentBehindAlpha = ScrimController.SCRIM_BEHIND_ALPHA_UNLOCKING;
+ mCurrentInFrontAlpha = ScrimController.SCRIM_IN_FRONT_ALPHA_LOCKED;
+ }
+ },
+
+ /**
+ * Changing screen brightness from quick settings.
+ */
+ BRIGHTNESS_MIRROR {
+ @Override
+ public void prepare(ScrimState previousState) {
+ mCurrentBehindAlpha = 0;
+ mCurrentInFrontAlpha = 0;
+ }
+ },
+
+ /**
+ * Always on display or screen off.
+ */
+ AOD {
+ @Override
+ public void prepare(ScrimState previousState) {
+ if (previousState == ScrimState.PULSING) {
+ updateScrimColor(mScrimInFront, 1, Color.BLACK);
+ }
+ final boolean alwaysOnEnabled = mDozeParameters.getAlwaysOn();
+ mBlankScreen = previousState == ScrimState.PULSING;
+ mCurrentBehindAlpha = 1;
+ mCurrentInFrontAlpha = alwaysOnEnabled ? mAodFrontScrimAlpha : 1f;
+ mCurrentInFrontTint = Color.BLACK;
+ mCurrentBehindTint = Color.BLACK;
+ // DisplayPowerManager will blank the screen for us, we just need
+ // to set our state.
+ mAnimateChange = false;
+ }
+ },
+
+ /**
+ * When phone wakes up because you received a notification.
+ */
+ PULSING {
+ @Override
+ public void prepare(ScrimState previousState) {
+ mCurrentBehindAlpha = 1;
+ mCurrentInFrontAlpha = 0;
+ mCurrentInFrontTint = Color.BLACK;
+ mCurrentBehindTint = Color.BLACK;
+ mBlankScreen = true;
+ updateScrimColor(mScrimInFront, 1, Color.BLACK);
+ }
+ },
+
+ /**
+ * Unlocked on top of an app (launcher or any other activity.)
+ */
+ UNLOCKED {
+ @Override
+ public void prepare(ScrimState previousState) {
+ mCurrentBehindAlpha = 0;
+ mCurrentInFrontAlpha = 0;
+ mAnimationDuration = StatusBar.FADE_KEYGUARD_DURATION;
+
+ if (previousState == ScrimState.AOD) {
+ // Fade from black to transparent when coming directly from AOD
+ updateScrimColor(mScrimInFront, 1, Color.BLACK);
+ updateScrimColor(mScrimBehind, 1, Color.BLACK);
+ // Scrims should still be black at the end of the transition.
+ mCurrentInFrontTint = Color.BLACK;
+ mCurrentBehindTint = Color.BLACK;
+ mBlankScreen = true;
+ } else {
+ // Scrims should still be black at the end of the transition.
+ mCurrentInFrontTint = Color.TRANSPARENT;
+ mCurrentBehindTint = Color.TRANSPARENT;
+ mBlankScreen = false;
+ }
+ }
+ };
+
+ boolean mBlankScreen = false;
+ long mAnimationDuration = ScrimController.ANIMATION_DURATION;
+ int mCurrentInFrontTint = Color.TRANSPARENT;
+ int mCurrentBehindTint = Color.TRANSPARENT;
+ boolean mAnimateChange = true;
+ float mCurrentInFrontAlpha;
+ float mCurrentBehindAlpha;
+ float mAodFrontScrimAlpha;
+ float mScrimBehindAlphaKeyguard;
+ ScrimView mScrimInFront;
+ ScrimView mScrimBehind;
+ DozeParameters mDozeParameters;
+
+ public void init(ScrimView scrimInFront, ScrimView scrimBehind, DozeParameters dozeParameters) {
+ mScrimInFront = scrimInFront;
+ mScrimBehind = scrimBehind;
+ mDozeParameters = dozeParameters;
+ }
+
+ public void prepare(ScrimState previousState) {
+ }
+
+ public float getFrontAlpha() {
+ return mCurrentInFrontAlpha;
+ }
+
+ public float getBehindAlpha() {
+ return mCurrentBehindAlpha;
+ }
+
+ public int getFrontTint() {
+ return mCurrentInFrontTint;
+ }
+
+ public int getBehindTint() {
+ return mCurrentBehindTint;
+ }
+
+ public long getAnimationDuration() {
+ return mAnimationDuration;
+ }
+
+ public boolean getBlanksScreen() {
+ return mBlankScreen;
+ }
+
+ public void updateScrimColor(ScrimView scrim, float alpha, int tint) {
+ Trace.traceCounter(Trace.TRACE_TAG_APP,
+ scrim == mScrimInFront ? "front_scrim_alpha" : "back_scrim_alpha",
+ (int) (alpha * 255));
+
+ Trace.traceCounter(Trace.TRACE_TAG_APP,
+ scrim == mScrimInFront ? "front_scrim_tint" : "back_scrim_tint",
+ Color.alpha(tint));
+
+ scrim.setTint(tint);
+ scrim.setViewAlpha(alpha);
+ }
+
+ public boolean getAnimateChange() {
+ return mAnimateChange;
+ }
+
+ public void setAodFrontScrimAlpha(float aodFrontScrimAlpha) {
+ mAodFrontScrimAlpha = aodFrontScrimAlpha;
+ }
+
+ public void setScrimBehindAlphaKeyguard(float scrimBehindAlphaKeyguard) {
+ mScrimBehindAlphaKeyguard = scrimBehindAlphaKeyguard;
+ }
+} \ No newline at end of file
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 43cc0f771a97..a5609da78abb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -238,6 +238,7 @@ import com.android.systemui.statusbar.stack.NotificationStackScrollLayout
.OnChildLocationsChangedListener;
import com.android.systemui.util.NotificationChannels;
import com.android.systemui.util.leak.LeakDetector;
+import com.android.systemui.util.wakelock.WakeLock;
import com.android.systemui.volume.VolumeComponent;
import java.io.FileDescriptor;
@@ -386,6 +387,7 @@ public class StatusBar extends SystemUI implements DemoMode,
private VolumeComponent mVolumeComponent;
private BrightnessMirrorController mBrightnessMirrorController;
+ private boolean mBrightnessMirrorVisible;
protected FingerprintUnlockController mFingerprintUnlockController;
private LightBarController mLightBarController;
protected LockscreenWallpaper mLockscreenWallpaper;
@@ -646,6 +648,31 @@ public class StatusBar extends SystemUI implements DemoMode,
}
};
+ // Notifies StatusBarKeyguardViewManager every time the keyguard transition is over,
+ // this animation is tied to the scrim for historic reasons.
+ // TODO: notify when keyguard has faded away instead of the scrim.
+ private final ScrimController.Callback mUnlockScrimCallback = new ScrimController
+ .Callback() {
+ @Override
+ public void onFinished() {
+ notifyKeyguardState();
+ }
+
+ @Override
+ public void onCancelled() {
+ notifyKeyguardState();
+ }
+
+ private void notifyKeyguardState() {
+ if (mStatusBarKeyguardViewManager == null) {
+ Log.w(TAG, "Tried to notify keyguard visibility when "
+ + "mStatusBarKeyguardViewManager was null");
+ return;
+ }
+ mStatusBarKeyguardViewManager.onKeyguardFadedAway();
+ }
+ };
+
private NotificationMessagingUtil mMessagingUtil;
private KeyguardUserSwitcher mKeyguardUserSwitcher;
private UserSwitcherController mUserSwitcherController;
@@ -1045,7 +1072,7 @@ public class StatusBar extends SystemUI implements DemoMode,
if (mStatusBarWindowManager != null) {
mStatusBarWindowManager.setScrimsVisible(scrimsVisible);
}
- });
+ }, new DozeParameters(mContext));
if (mScrimSrcModeEnabled) {
Runnable runnable = () -> {
boolean asSrc = mBackdrop.getVisibility() != View.VISIBLE;
@@ -1081,7 +1108,10 @@ public class StatusBar extends SystemUI implements DemoMode,
final QSTileHost qsh = SystemUIFactory.getInstance().createQSTileHost(mContext, this,
mIconController);
mBrightnessMirrorController = new BrightnessMirrorController(mStatusBarWindow,
- mScrimController);
+ (visible) -> {
+ mBrightnessMirrorVisible = visible;
+ updateScrimController();
+ });
fragmentHostManager.addTagListener(QS.TAG, (tag, f) -> {
QS qs = (QS) f;
if (qs instanceof QSFragment) {
@@ -1457,8 +1487,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mDozeScrimController, keyguardViewMediator,
mScrimController, this, UnlockMethodCache.getInstance(mContext));
mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
- getBouncerContainer(), mScrimController,
- mFingerprintUnlockController);
+ getBouncerContainer(), mFingerprintUnlockController);
mKeyguardIndicationController
.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
mFingerprintUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
@@ -2640,7 +2669,7 @@ public class StatusBar extends SystemUI implements DemoMode,
}
public boolean isPulsing() {
- return mDozeScrimController.isPulsing();
+ return mDozeScrimController != null && mDozeScrimController.isPulsing();
}
@Override
@@ -3348,7 +3377,7 @@ public class StatusBar extends SystemUI implements DemoMode,
}
if (mScrimController != null) {
- mScrimController.dump(pw);
+ mScrimController.dump(fd, pw, args);
}
if (DUMPTRUCK) {
@@ -4081,7 +4110,6 @@ public class StatusBar extends SystemUI implements DemoMode,
releaseGestureWakeLock();
runLaunchTransitionEndRunnable();
mLaunchTransitionFadingAway = false;
- mScrimController.forceHideScrims(false /* hide */, false /* animated */);
updateMediaMetaData(true /* metaDataChanged */, true);
}
@@ -4114,7 +4142,7 @@ public class StatusBar extends SystemUI implements DemoMode,
if (beforeFading != null) {
beforeFading.run();
}
- mScrimController.forceHideScrims(true /* hide */, false /* animated */);
+ updateScrimController();
updateMediaMetaData(false, true);
mNotificationPanel.setAlpha(1);
mStackScroller.setParentNotFullyVisible(true);
@@ -4145,6 +4173,13 @@ public class StatusBar extends SystemUI implements DemoMode,
.setStartDelay(0)
.setDuration(FADE_KEYGUARD_DURATION_PULSING)
.setInterpolator(ScrimController.KEYGUARD_FADE_OUT_INTERPOLATOR)
+ .setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ hideKeyguard();
+ mStatusBarKeyguardViewManager.onKeyguardFadedAway();
+ }
+ })
.start();
}
@@ -4152,7 +4187,6 @@ public class StatusBar extends SystemUI implements DemoMode,
* Plays the animation when an activity that was occluding Keyguard goes away.
*/
public void animateKeyguardUnoccluding() {
- mScrimController.animateKeyguardUnoccluding(500);
mNotificationPanel.setExpandedFraction(0f);
animateExpandNotificationsPanel();
}
@@ -4340,11 +4374,6 @@ public class StatusBar extends SystemUI implements DemoMode,
mAmbientIndicationContainer.setVisibility(View.INVISIBLE);
}
}
- if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
- mScrimController.setKeyguardShowing(true);
- } else {
- mScrimController.setKeyguardShowing(false);
- }
mNotificationPanel.setBarState(mState, mKeyguardFadingAway, goingToFullShade);
updateTheme();
updateDozingState();
@@ -4352,6 +4381,7 @@ public class StatusBar extends SystemUI implements DemoMode,
updateStackScrollerState(goingToFullShade, fromShadeLocked);
updateNotifications();
checkBarModes();
+ updateScrimController();
updateMediaMetaData(false, mState != StatusBarState.KEYGUARD);
mKeyguardMonitor.notifyKeyguardState(mStatusBarKeyguardViewManager.isShowing(),
mUnlockMethodCache.isMethodSecure(),
@@ -4415,11 +4445,10 @@ public class StatusBar extends SystemUI implements DemoMode,
boolean animate = !mDozing && mDozeServiceHost.shouldAnimateWakeup();
mNotificationPanel.setDozing(mDozing, animate);
mStackScroller.setDark(mDozing, animate, mWakeUpTouchLocation);
- mScrimController.setDozing(mDozing);
+ mDozeScrimController.setDozing(mDozing);
mKeyguardIndicationController.setDozing(mDozing);
mNotificationPanel.setDark(mDozing, animate);
updateQsExpansionEnabled();
- mDozeScrimController.setDozing(mDozing, animate);
updateRowStates();
Trace.endSection();
}
@@ -4914,6 +4943,7 @@ public class StatusBar extends SystemUI implements DemoMode,
if (mStatusBarView != null) mStatusBarView.setBouncerShowing(bouncerShowing);
updateHideIconsForBouncer(true /* animate */);
recomputeDisableFlags(true /* animate */);
+ updateScrimController();
}
public void cancelCurrentTouch() {
@@ -4965,12 +4995,10 @@ public class StatusBar extends SystemUI implements DemoMode,
mStackScroller.setAnimationsEnabled(true);
mVisualStabilityManager.setScreenOn(true);
mNotificationPanel.setTouchDisabled(false);
-
- maybePrepareWakeUpFromAod();
-
mDozeServiceHost.stopDozing();
updateVisibleToUser();
updateIsKeyguard();
+ updateScrimController();
}
};
@@ -4980,18 +5008,16 @@ public class StatusBar extends SystemUI implements DemoMode,
mFalsingManager.onScreenTurningOn();
mNotificationPanel.onScreenTurningOn();
- maybePrepareWakeUpFromAod();
-
if (mLaunchCameraOnScreenTurningOn) {
mNotificationPanel.launchCamera(false, mLastCameraLaunchSource);
mLaunchCameraOnScreenTurningOn = false;
}
+
+ updateScrimController();
}
@Override
public void onScreenTurnedOn() {
- mScrimController.wakeUpFromAod();
- mDozeScrimController.onScreenTurnedOn();
}
@Override
@@ -5009,13 +5035,6 @@ public class StatusBar extends SystemUI implements DemoMode,
return mWakefulnessLifecycle.getWakefulness();
}
- private void maybePrepareWakeUpFromAod() {
- int wakefulness = mWakefulnessLifecycle.getWakefulness();
- if (mDozing && wakefulness == WAKEFULNESS_WAKING && !isPulsing()) {
- mScrimController.prepareWakeUpFromAod();
- }
- }
-
private void vibrateForCameraGesture() {
// Make sure to pass -1 for repeat so VibratorService doesn't stop us when going to sleep.
mVibrator.vibrate(mCameraLaunchGestureVibePattern, -1 /* repeat */);
@@ -5098,12 +5117,12 @@ public class StatusBar extends SystemUI implements DemoMode,
if (!mDeviceInteractive) {
// Avoid flickering of the scrim when we instant launch the camera and the bouncer
// comes on.
- mScrimController.dontAnimateBouncerChangesUntilNextFrame();
mGestureWakeLock.acquire(LAUNCH_TRANSITION_TIMEOUT_MS + 1000L);
}
if (isScreenTurningOnOrOn()) {
if (DEBUG_CAMERA_LIFT) Slog.d(TAG, "Launching camera");
mNotificationPanel.launchCamera(mDeviceInteractive /* animate */, source);
+ updateScrimController();
} else {
// We need to defer the camera launch until the screen comes on, since otherwise
// we will dismiss us too early since we are waiting on an activity to be drawn and
@@ -5145,15 +5164,16 @@ public class StatusBar extends SystemUI implements DemoMode,
private void updateDozing() {
Trace.beginSection("StatusBar#updateDozing");
// When in wake-and-unlock while pulsing, keep dozing state until fully unlocked.
- mDozing = mDozingRequested && mState == StatusBarState.KEYGUARD
+ boolean dozing = mDozingRequested && mState == StatusBarState.KEYGUARD
|| mFingerprintUnlockController.getMode()
== FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING;
// When in wake-and-unlock we may not have received a change to mState
// but we still should not be dozing, manually set to false.
if (mFingerprintUnlockController.getMode() ==
FingerprintUnlockController.MODE_WAKE_AND_UNLOCK) {
- mDozing = false;
+ dozing = false;
}
+ mDozing = dozing;
mStatusBarWindowManager.setDozing(mDozing);
mStatusBarKeyguardViewManager.setDozing(mDozing);
if (mAmbientIndicationContainer instanceof DozeReceiver) {
@@ -5163,6 +5183,24 @@ public class StatusBar extends SystemUI implements DemoMode,
Trace.endSection();
}
+ public void updateScrimController() {
+ if (mBouncerShowing) {
+ mScrimController.transitionTo(ScrimState.BOUNCER);
+ } else if (mLaunchCameraOnScreenTurningOn || isInLaunchTransition()) {
+ mScrimController.transitionTo(ScrimState.UNLOCKED, mUnlockScrimCallback);
+ } else if (mBrightnessMirrorVisible) {
+ mScrimController.transitionTo(ScrimState.BRIGHTNESS_MIRROR);
+ } else if (isPulsing()) {
+ // Handled in DozeScrimController#setPulsing
+ } else if (mDozing) {
+ mScrimController.transitionTo(ScrimState.AOD);
+ } else if (mIsKeyguard) {
+ mScrimController.transitionTo(ScrimState.KEYGUARD);
+ } else {
+ mScrimController.transitionTo(ScrimState.UNLOCKED, mUnlockScrimCallback);
+ }
+ }
+
public boolean isKeyguardShowing() {
if (mStatusBarKeyguardViewManager == null) {
Slog.i(TAG, "isKeyguardShowing() called before startKeyguard(), returning true");
@@ -5222,7 +5260,6 @@ public class StatusBar extends SystemUI implements DemoMode,
}
mDozeScrimController.pulse(new PulseCallback() {
-
@Override
public void onPulseStarted() {
callback.onPulseStarted();
@@ -5307,11 +5344,6 @@ public class StatusBar extends SystemUI implements DemoMode,
}
@Override
- public void abortPulsing() {
- mDozeScrimController.abortPulsing();
- }
-
- @Override
public void extendPulse() {
mDozeScrimController.extendPulse();
}
@@ -5347,7 +5379,7 @@ public class StatusBar extends SystemUI implements DemoMode,
@Override
public void setAodDimmingScrim(float scrimOpacity) {
- mDozeScrimController.setAodDimmingScrim(scrimOpacity);
+ ScrimState.AOD.setAodFrontScrimAlpha(scrimOpacity);
}
public void dispatchDoubleTap(float viewX, float viewY) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index bcde556a5954..ef05bbb4fe3d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -24,7 +24,6 @@ import android.content.ComponentCallbacks2;
import android.content.Context;
import android.os.Bundle;
import android.os.SystemClock;
-import android.os.Trace;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
@@ -71,17 +70,14 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
protected final Context mContext;
private final StatusBarWindowManager mStatusBarWindowManager;
- private final boolean mDisplayBlanksAfterDoze;
protected LockPatternUtils mLockPatternUtils;
protected ViewMediatorCallback mViewMediatorCallback;
protected StatusBar mStatusBar;
- private ScrimController mScrimController;
private FingerprintUnlockController mFingerprintUnlockController;
private ViewGroup mContainer;
- private boolean mScreenTurnedOn;
protected KeyguardBouncer mBouncer;
protected boolean mShowing;
protected boolean mOccluded;
@@ -95,12 +91,10 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
private boolean mLastBouncerDismissible;
protected boolean mLastRemoteInputActive;
private boolean mLastDozing;
- private boolean mLastDeferScrimFadeOut;
private int mLastFpMode;
private OnDismissAction mAfterKeyguardGoneAction;
private final ArrayList<Runnable> mAfterKeyguardGoneRunnables = new ArrayList<>();
- private boolean mDeferScrimFadeOut;
// Dismiss action to be launched when we stop dozing or the keyguard is gone.
private DismissWithActionRequest mPendingWakeupAction;
@@ -125,18 +119,14 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
mLockPatternUtils = lockPatternUtils;
mStatusBarWindowManager = Dependency.get(StatusBarWindowManager.class);
KeyguardUpdateMonitor.getInstance(context).registerCallback(mUpdateMonitorCallback);
- mDisplayBlanksAfterDoze = context.getResources().getBoolean(
- com.android.internal.R.bool.config_displayBlanksAfterDoze);
}
public void registerStatusBar(StatusBar statusBar,
ViewGroup container,
- ScrimController scrimController,
FingerprintUnlockController fingerprintUnlockController,
DismissCallbackRegistry dismissCallbackRegistry) {
mStatusBar = statusBar;
mContainer = container;
- mScrimController = scrimController;
mFingerprintUnlockController = fingerprintUnlockController;
mBouncer = SystemUIFactory.getInstance().createKeyguardBouncer(mContext,
mViewMediatorCallback, mLockPatternUtils, container, dismissCallbackRegistry);
@@ -149,7 +139,6 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
public void show(Bundle options) {
mShowing = true;
mStatusBarWindowManager.setKeyguardShowing(true);
- mScrimController.abortKeyguardFadingOut();
reset(true /* hideBouncerWhenShowing */);
}
@@ -253,15 +242,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
}
public void onScreenTurnedOn() {
- Trace.beginSection("StatusBarKeyguardViewManager#onScreenTurnedOn");
- mScreenTurnedOn = true;
- if (mDeferScrimFadeOut) {
- mDeferScrimFadeOut = false;
- animateScrimControllerKeyguardFadingOut(0, WAKE_AND_UNLOCK_SCRIM_FADEOUT_DURATION_MS,
- true /* skipFirstFrame */);
- updateStates();
- }
- Trace.endSection();
+ // TODO: remove
}
@Override
@@ -285,7 +266,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
}
public void onScreenTurnedOff() {
- mScreenTurnedOn = false;
+ // TODO: remove
}
public void notifyDeviceWakeUpRequested() {
@@ -374,10 +355,6 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
mStatusBarWindowManager.setKeyguardFadingAway(true);
hideBouncer(true /* destroyView */);
updateStates();
- mScrimController.animateKeyguardFadingOut(
- StatusBar.FADE_KEYGUARD_START_DELAY,
- StatusBar.FADE_KEYGUARD_DURATION, null,
- false /* skipFirstFrame */);
}
}, new Runnable() {
@Override
@@ -400,36 +377,16 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
mFingerprintUnlockController.startKeyguardFadingAway();
hideBouncer(true /* destroyView */);
if (wakeUnlockPulsing) {
- mStatusBarWindowManager.setKeyguardFadingAway(true);
mStatusBar.fadeKeyguardWhilePulsing();
- animateScrimControllerKeyguardFadingOut(delay, fadeoutDuration,
- mStatusBar::hideKeyguard, false /* skipFirstFrame */);
+ wakeAndUnlockDejank();
} else {
mFingerprintUnlockController.startKeyguardFadingAway();
mStatusBar.setKeyguardFadingAway(startTime, delay, fadeoutDuration);
boolean staying = mStatusBar.hideKeyguard();
if (!staying) {
mStatusBarWindowManager.setKeyguardFadingAway(true);
- if (mFingerprintUnlockController.getMode() == MODE_WAKE_AND_UNLOCK) {
- boolean turnedOnSinceAuth =
- mFingerprintUnlockController.hasScreenTurnedOnSinceAuthenticating();
- if (!mScreenTurnedOn || mDisplayBlanksAfterDoze && !turnedOnSinceAuth) {
- // Not ready to animate yet; either because the screen is not on yet,
- // or it is on but will turn off before waking out of doze.
- mDeferScrimFadeOut = true;
- } else {
-
- // Screen is already on, don't defer with fading out.
- animateScrimControllerKeyguardFadingOut(0,
- WAKE_AND_UNLOCK_SCRIM_FADEOUT_DURATION_MS,
- true /* skipFirstFrame */);
- }
- } else {
- animateScrimControllerKeyguardFadingOut(delay, fadeoutDuration,
- false /* skipFirstFrame */);
- }
+ wakeAndUnlockDejank();
} else {
- mScrimController.animateGoingToFullShade(delay, fadeoutDuration);
mStatusBar.finishKeyguardFadingAway();
mFingerprintUnlockController.finishKeyguardFadingAway();
}
@@ -449,30 +406,17 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
mBouncer.prepare();
}
- private void animateScrimControllerKeyguardFadingOut(long delay, long duration,
- boolean skipFirstFrame) {
- animateScrimControllerKeyguardFadingOut(delay, duration, null /* endRunnable */,
- skipFirstFrame);
+ public void onKeyguardFadedAway() {
+ mContainer.postDelayed(() -> mStatusBarWindowManager.setKeyguardFadingAway(false),
+ 100);
+ mStatusBar.finishKeyguardFadingAway();
+ mFingerprintUnlockController.finishKeyguardFadingAway();
+ WindowManagerGlobal.getInstance().trimMemory(
+ ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
+
}
- private void animateScrimControllerKeyguardFadingOut(long delay, long duration,
- final Runnable endRunnable, boolean skipFirstFrame) {
- Trace.asyncTraceBegin(Trace.TRACE_TAG_VIEW, "Fading out", 0);
- mScrimController.animateKeyguardFadingOut(delay, duration, new Runnable() {
- @Override
- public void run() {
- if (endRunnable != null) {
- endRunnable.run();
- }
- mContainer.postDelayed(() -> mStatusBarWindowManager.setKeyguardFadingAway(false),
- 100);
- mStatusBar.finishKeyguardFadingAway();
- mFingerprintUnlockController.finishKeyguardFadingAway();
- WindowManagerGlobal.getInstance().trimMemory(
- ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
- Trace.asyncTraceEnd(Trace.TRACE_TAG_VIEW, "Fading out", 0);
- }
- }, skipFirstFrame);
+ private void wakeAndUnlockDejank() {
if (mFingerprintUnlockController.getMode() == MODE_WAKE_AND_UNLOCK
&& LatencyTracker.isEnabled(mContext)) {
DejankUtils.postAfterTraversal(() ->
@@ -593,7 +537,6 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
if (bouncerShowing != mLastBouncerShowing || mFirstUpdate) {
mStatusBarWindowManager.setBouncerShowing(bouncerShowing);
mStatusBar.setBouncerShowing(bouncerShowing);
- mScrimController.setBouncerShowing(bouncerShowing);
}
KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
@@ -611,7 +554,6 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
mLastBouncerDismissible = bouncerDismissible;
mLastRemoteInputActive = remoteInputActive;
mLastDozing = mDozing;
- mLastDeferScrimFadeOut = mDeferScrimFadeOut;
mLastFpMode = mFingerprintUnlockController.getMode();
mStatusBar.onKeyguardViewManagerStatesUpdated();
}
@@ -624,7 +566,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
boolean keyguardShowing = mShowing && !mOccluded;
boolean hideWhileDozing = mDozing && fpMode != MODE_WAKE_AND_UNLOCK_PULSING;
return (!keyguardShowing && !hideWhileDozing || mBouncer.isShowing()
- || mRemoteInputActive) && !mDeferScrimFadeOut;
+ || mRemoteInputActive);
}
/**
@@ -634,7 +576,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
boolean keyguardShowing = mLastShowing && !mLastOccluded;
boolean hideWhileDozing = mLastDozing && mLastFpMode != MODE_WAKE_AND_UNLOCK_PULSING;
return (!keyguardShowing && !hideWhileDozing || mLastBouncerShowing
- || mLastRemoteInputActive) && !mLastDeferScrimFadeOut;
+ || mLastRemoteInputActive);
}
public boolean shouldDismissOnMenuPressed() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
index b0553d72dd49..a011952f1476 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.policy;
+import android.annotation.NonNull;
import android.util.ArraySet;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
@@ -26,46 +27,47 @@ import android.widget.FrameLayout;
import com.android.internal.util.Preconditions;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
-import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.StatusBarWindowView;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
+import java.util.function.Consumer;
+
/**
* Controls showing and hiding of the brightness mirror.
*/
public class BrightnessMirrorController
implements CallbackController<BrightnessMirrorController.BrightnessMirrorListener> {
- private final NotificationStackScrollLayout mStackScroller;
- public long TRANSITION_DURATION_OUT = 150;
- public long TRANSITION_DURATION_IN = 200;
+ private final static long TRANSITION_DURATION_OUT = 150;
+ private final static long TRANSITION_DURATION_IN = 200;
private final StatusBarWindowView mStatusBarWindow;
- private final ScrimController mScrimController;
+ private final NotificationStackScrollLayout mStackScroller;
+ private final Consumer<Boolean> mVisibilityCallback;
private final View mNotificationPanel;
private final ArraySet<BrightnessMirrorListener> mBrightnessMirrorListeners = new ArraySet<>();
private final int[] mInt2Cache = new int[2];
private View mBrightnessMirror;
public BrightnessMirrorController(StatusBarWindowView statusBarWindow,
- ScrimController scrimController) {
+ @NonNull Consumer<Boolean> visibilityCallback) {
mStatusBarWindow = statusBarWindow;
mBrightnessMirror = statusBarWindow.findViewById(R.id.brightness_mirror);
mNotificationPanel = statusBarWindow.findViewById(R.id.notification_panel);
mStackScroller = statusBarWindow.findViewById(R.id.notification_stack_scroller);
- mScrimController = scrimController;
+ mVisibilityCallback = visibilityCallback;
}
public void showMirror() {
mBrightnessMirror.setVisibility(View.VISIBLE);
mStackScroller.setFadingOut(true);
- mScrimController.forceHideScrims(true /* hide */, true /* animated */);
+ mVisibilityCallback.accept(true);
outAnimation(mNotificationPanel.animate())
.withLayer();
}
public void hideMirror() {
- mScrimController.forceHideScrims(false /* hide */, true /* animated */);
+ mVisibilityCallback.accept(false);
inAnimation(mNotificationPanel.animate())
.withLayer()
.withEndAction(() -> {
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 b0c9f32873ff..1c104cffc3c1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java
@@ -19,12 +19,13 @@ package com.android.systemui.doze;
import android.annotation.NonNull;
import android.app.PendingIntent;
+import com.android.systemui.util.wakelock.WakeLock;
+
/**
* A rudimentary fake for DozeHost.
*/
class DozeHostFake implements DozeHost {
Callback callback;
- boolean pulseAborted;
boolean pulseExtended;
boolean animateWakeup;
boolean dozing;
@@ -92,11 +93,6 @@ class DozeHostFake implements DozeHost {
}
@Override
- public void abortPulsing() {
- pulseAborted = true;
- }
-
- @Override
public void extendPulse() {
pulseExtended = true;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ScrimViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ScrimViewTest.java
index 4c3bf1081792..a4bcc69c0e10 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ScrimViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ScrimViewTest.java
@@ -86,9 +86,9 @@ public class ScrimViewTest extends LeakCheckedTest {
@Test
public void testSetViewAlpha_propagatesToDrawable() {
- float alpha = 0.5f;
+ final float alpha = 0.5f;
mView.setViewAlpha(alpha);
- assertEquals(mView.getViewAlpha(), alpha);
+ assertEquals("View alpha did not propagate to drawable", alpha, mView.getViewAlpha());
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeScrimControllerTest.java
new file mode 100644
index 000000000000..ca2f713d2b6f
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeScrimControllerTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+import android.os.Debug;
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.doze.DozeHost;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+@SmallTest
+public class DozeScrimControllerTest extends SysuiTestCase {
+
+ private ScrimController mScrimController;
+ private DozeScrimController mDozeScrimController;
+
+ @Before
+ public void setup() {
+ mScrimController = mock(ScrimController.class);
+ // Make sure callbacks will be invoked to complete the lifecycle.
+ doAnswer(invocationOnMock -> {
+ ScrimController.Callback callback = invocationOnMock.getArgument(1);
+ callback.onStart();
+ callback.onDisplayBlanked();
+ callback.onFinished();
+ return null;
+ }).when(mScrimController).transitionTo(any(ScrimState.class),
+ any(ScrimController.Callback.class));
+
+ mDozeScrimController = new DozeScrimController(mScrimController, getContext());
+ mDozeScrimController.setDozing(true);
+ }
+
+ @Test
+ public void changesScrimControllerState() {
+ mDozeScrimController.pulse(mock(DozeHost.PulseCallback.class), 0);
+ verify(mScrimController).transitionTo(eq(ScrimState.PULSING),
+ any(ScrimController.Callback.class));
+ }
+
+ @Test
+ public void callsPulseCallback() {
+ DozeHost.PulseCallback callback = mock(DozeHost.PulseCallback.class);
+ mDozeScrimController.pulse(callback, 0);
+
+ verify(callback).onPulseStarted();
+ mDozeScrimController.pulseOutNow();
+ verify(callback).onPulseFinished();
+ }
+
+ @Test
+ public void secondPulseIsSuppressed() {
+ DozeHost.PulseCallback callback1 = mock(DozeHost.PulseCallback.class);
+ DozeHost.PulseCallback callback2 = mock(DozeHost.PulseCallback.class);
+ mDozeScrimController.pulse(callback1, 0);
+ mDozeScrimController.pulse(callback2, 0);
+
+ verify(callback1, never()).onPulseFinished();
+ verify(callback2).onPulseFinished();
+ }
+
+ @Test
+ public void suppressesPulseIfNotDozing() {
+ mDozeScrimController.setDozing(false);
+ DozeHost.PulseCallback callback = mock(DozeHost.PulseCallback.class);
+ mDozeScrimController.pulse(callback, 0);
+
+ verify(callback).onPulseFinished();
+ }
+}
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
new file mode 100644
index 000000000000..b9f695be90cf
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.animation.Animator;
+import android.graphics.Color;
+import android.os.Handler;
+import android.os.Looper;
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.view.View;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.ScrimView;
+import com.android.systemui.util.wakelock.WakeLock;
+import com.android.systemui.utils.os.FakeHandler;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.function.Consumer;
+
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+@SmallTest
+public class ScrimControllerTest extends SysuiTestCase {
+
+ private SynchronousScrimController mScrimController;
+ private ScrimView mScrimBehind;
+ private ScrimView mScrimInFront;
+ private View mHeadsUpScrim;
+ private Consumer<Boolean> mScrimVisibilityCallback;
+ private Boolean mScrimVisibile;
+ private LightBarController mLightBarController;
+ private DozeParameters mDozeParamenters;
+ private WakeLock mWakeLock;
+ private boolean mAlwaysOnEnabled;
+
+ @Before
+ public void setup() {
+ mLightBarController = mock(LightBarController.class);
+ mScrimBehind = new ScrimView(getContext());
+ mScrimInFront = new ScrimView(getContext());
+ mHeadsUpScrim = mock(View.class);
+ mWakeLock = mock(WakeLock.class);
+ mAlwaysOnEnabled = true;
+ mScrimVisibilityCallback = (Boolean visible) -> mScrimVisibile = visible;
+ mDozeParamenters = mock(DozeParameters.class);
+ when(mDozeParamenters.getAlwaysOn()).thenAnswer(invocation -> mAlwaysOnEnabled);
+ mScrimController = new SynchronousScrimController(mLightBarController, mScrimBehind,
+ mScrimInFront, mHeadsUpScrim, mScrimVisibilityCallback, mDozeParamenters);
+ }
+
+ @Test
+ public void initialState() {
+ Assert.assertEquals("ScrimController should start initialized",
+ mScrimController.getState(), ScrimState.UNINITIALIZED);
+ }
+
+ @Test
+ public void transitionToKeyguard() {
+ mScrimController.transitionTo(ScrimState.KEYGUARD);
+ mScrimController.finishAnimationsImmediately();
+ // Front scrim should be transparent
+ // Back scrim should be visible without tint
+ assertScrimVisibility(false /* front */, true /* behind */);
+ assertScrimTint(mScrimBehind, false /* tinted */);
+ }
+
+ @Test
+ public void transitionToAod() {
+ mScrimController.transitionTo(ScrimState.AOD);
+ mScrimController.finishAnimationsImmediately();
+ // Front scrim should be transparent
+ // Back scrim should be visible with tint
+ assertScrimVisibility(false /* front */, true /* behind */);
+ assertScrimTint(mScrimBehind, true /* tinted */);
+ assertScrimTint(mScrimInFront, true /* tinted */);
+ }
+
+ @Test
+ public void transitionToPulsing() {
+ mScrimController.transitionTo(ScrimState.PULSING);
+ mScrimController.finishAnimationsImmediately();
+ // Front scrim should be transparent
+ // Back scrim should be visible with tint
+ // Pulse callback should have been invoked
+ assertScrimVisibility(false /* front */, true /* behind */);
+ assertScrimTint(mScrimBehind, true /* tinted */);
+ }
+
+ @Test
+ public void transitionToBouncer() {
+ mScrimController.transitionTo(ScrimState.BOUNCER);
+ mScrimController.finishAnimationsImmediately();
+ // Front scrim should be transparent
+ // Back scrim should be visible without tint
+ assertScrimVisibility(true /* front */, true /* behind */);
+ assertScrimTint(mScrimBehind, false /* tinted */);
+ }
+
+ @Test
+ public void transitionToUnlocked() {
+ mScrimController.transitionTo(ScrimState.UNLOCKED);
+ mScrimController.finishAnimationsImmediately();
+ // Front scrim should be transparent
+ // Back scrim should be transparent
+ assertScrimVisibility(false /* front */, false /* behind */);
+ assertScrimTint(mScrimBehind, false /* tinted */);
+ assertScrimTint(mScrimInFront, false /* tinted */);
+
+ // Back scrim should be visible after start dragging
+ mScrimController.setPanelExpansion(0.5f);
+ assertScrimVisibility(false /* front */, true /* behind */);
+ }
+
+ @Test
+ public void transitionToUnlockedFromAod() {
+ // Simulate unlock with fingerprint
+ mScrimController.transitionTo(ScrimState.AOD);
+ mScrimController.finishAnimationsImmediately();
+ mScrimController.transitionTo(ScrimState.UNLOCKED);
+ // Immediately tinted after the transition starts
+ assertScrimTint(mScrimInFront, true /* tinted */);
+ assertScrimTint(mScrimBehind, true /* tinted */);
+ mScrimController.finishAnimationsImmediately();
+ // Front scrim should be transparent
+ // Back scrim should be transparent
+ // Neither scrims should be tinted anymore after the animation.
+ assertScrimVisibility(false /* front */, false /* behind */);
+ assertScrimTint(mScrimInFront, false /* tinted */);
+ assertScrimTint(mScrimBehind, false /* tinted */);
+ }
+
+ @Test
+ public void scrimBlanksBeforeLeavingAoD() {
+ // Simulate unlock with fingerprint
+ mScrimController.transitionTo(ScrimState.AOD);
+ mScrimController.finishAnimationsImmediately();
+ mScrimController.transitionTo(ScrimState.UNLOCKED,
+ new ScrimController.Callback() {
+ @Override
+ public void onDisplayBlanked() {
+ // Front scrim should be black in the middle of the transition
+ Assert.assertTrue("Scrim should be visible during transition. Alpha: "
+ + mScrimInFront.getViewAlpha(), mScrimInFront.getViewAlpha() > 0);
+ assertScrimTint(mScrimInFront, true /* tinted */);
+ Assert.assertTrue("Scrim should be visible during transition.",
+ mScrimVisibile);
+ }
+ });
+ mScrimController.finishAnimationsImmediately();
+ }
+
+ @Test
+ public void testScrimCallback() {
+ int[] callOrder = {0, 0, 0};
+ int[] currentCall = {0};
+ mScrimController.transitionTo(ScrimState.AOD, new ScrimController.Callback() {
+ @Override
+ public void onStart() {
+ callOrder[0] = ++currentCall[0];
+ }
+
+ @Override
+ public void onDisplayBlanked() {
+ callOrder[1] = ++currentCall[0];
+ }
+
+ @Override
+ public void onFinished() {
+ callOrder[2] = ++currentCall[0];
+ }
+ });
+ mScrimController.finishAnimationsImmediately();
+ Assert.assertEquals("onStart called in wrong order", 1, callOrder[0]);
+ Assert.assertEquals("onDisplayBlanked called in wrong order", 2, callOrder[1]);
+ Assert.assertEquals("onFinished called in wrong order", 3, callOrder[2]);
+ }
+
+ @Test
+ public void testScrimCallbacksWithoutAmbientDisplay() {
+ mAlwaysOnEnabled = false;
+ testScrimCallback();
+ }
+
+ @Test
+ public void testScrimCallbackCancelled() {
+ boolean[] cancelledCalled = {false};
+ mScrimController.transitionTo(ScrimState.AOD, new ScrimController.Callback() {
+ @Override
+ public void onCancelled() {
+ cancelledCalled[0] = true;
+ }
+ });
+ mScrimController.transitionTo(ScrimState.PULSING);
+ Assert.assertTrue("onCancelled should have been called", cancelledCalled[0]);
+ }
+
+ @Test
+ public void testHoldsWakeLock() {
+ mScrimController.transitionTo(ScrimState.AOD);
+ verify(mWakeLock, times(1)).acquire();
+ verify(mWakeLock, never()).release();
+ mScrimController.finishAnimationsImmediately();
+ verify(mWakeLock, times(1)).release();
+ }
+
+ private void assertScrimTint(ScrimView scrimView, boolean tinted) {
+ final boolean viewIsTinted = scrimView.getTint() != Color.TRANSPARENT;
+ final String name = scrimView == mScrimInFront ? "front" : "back";
+ Assert.assertEquals("Tint test failed at state " + mScrimController.getState()
+ +" with scrim: " + name + " and tint: " + Integer.toHexString(scrimView.getTint()),
+ tinted, viewIsTinted);
+ }
+
+ private void assertScrimVisibility(boolean inFront, boolean behind) {
+ Assert.assertEquals("Unexpected front scrim visibility. Alpha is "
+ + mScrimInFront.getViewAlpha(), inFront, mScrimInFront.getViewAlpha() > 0);
+ Assert.assertEquals("Unexpected back scrim visibility. Alpha is "
+ + mScrimBehind.getViewAlpha(), behind, mScrimBehind.getViewAlpha() > 0);
+ Assert.assertEquals("Invalid visibility.", inFront || behind, mScrimVisibile);
+ }
+
+ /**
+ * Special version of ScrimController where animations have 0 duration for test purposes.
+ */
+ private class SynchronousScrimController extends ScrimController {
+
+ private FakeHandler mHandler;
+
+ public SynchronousScrimController(LightBarController lightBarController,
+ ScrimView scrimBehind, ScrimView scrimInFront, View headsUpScrim,
+ Consumer<Boolean> scrimVisibleListener, DozeParameters dozeParameters) {
+ super(lightBarController, scrimBehind, scrimInFront, headsUpScrim,
+ scrimVisibleListener, dozeParameters);
+ mHandler = new FakeHandler(Looper.myLooper());
+ }
+
+ public void finishAnimationsImmediately() {
+ boolean[] animationFinished = {false};
+ setOnAnimationFinished(()-> animationFinished[0] = true);
+
+ // Execute code that will trigger animations.
+ onPreDraw();
+
+ // Force finish screen blanking.
+ endAnimation(mScrimInFront, TAG_KEY_ANIM_BLANK);
+ mHandler.dispatchQueuedMessages();
+ // Force finish all animations.
+ endAnimation(mScrimBehind, TAG_KEY_ANIM);
+ endAnimation(mScrimInFront, TAG_KEY_ANIM);
+
+ if (!animationFinished[0]) {
+ throw new IllegalStateException("Animation never finished");
+ }
+ }
+
+ private void endAnimation(ScrimView scrimView, int tag) {
+ Animator animator = (Animator) scrimView.getTag(tag);
+ if (animator != null) {
+ animator.end();
+ }
+ }
+
+ @Override
+ protected Handler getHandler() {
+ return mHandler;
+ }
+
+ @Override
+ protected WakeLock createWakeLock() {
+ return mWakeLock;
+ }
+ }
+
+}