blob: fd3c9526149dd95b3cfe330b38ad8f05848808c5 [file] [log] [blame]
Jorim Jaggiecc798e2014-05-26 18:14:37 +02001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.systemui.statusbar.phone;
18
19import android.animation.Animator;
20import android.animation.AnimatorListenerAdapter;
21import android.animation.ValueAnimator;
Lucas Dupincdbb1cb2019-05-16 19:48:30 -070022import android.annotation.IntDef;
Lucas Dupin82aa1632017-12-13 00:13:57 -080023import android.app.AlarmManager;
John Spurlockd06aa572014-09-10 10:40:49 -040024import android.content.Context;
Lucas Dupin8da8f2e92017-04-21 14:02:16 -070025import android.graphics.Color;
Anthony Chene658cc22017-04-27 11:17:35 -070026import android.graphics.drawable.Drawable;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080027import android.os.Handler;
Adrian Roosa5c63222017-07-27 16:33:39 +020028import android.os.Trace;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080029import android.util.Log;
Lucas Dupina0bf8512017-05-24 17:04:47 -070030import android.util.MathUtils;
Jorim Jaggiecc798e2014-05-26 18:14:37 +020031import android.view.View;
32import android.view.ViewTreeObserver;
Jorim Jaggiecc798e2014-05-26 18:14:37 +020033import android.view.animation.DecelerateInterpolator;
34import android.view.animation.Interpolator;
Lucas Dupin8da8f2e92017-04-21 14:02:16 -070035
Lucas Dupin9e3fa102017-11-08 17:16:55 -080036import com.android.internal.annotations.VisibleForTesting;
Lucas Dupine2292a92017-07-06 14:35:30 -070037import com.android.internal.colorextraction.ColorExtractor;
38import com.android.internal.colorextraction.ColorExtractor.GradientColors;
39import com.android.internal.colorextraction.ColorExtractor.OnColorsChangedListener;
Lucas Dupin9324aa92017-07-26 20:29:38 -070040import com.android.internal.graphics.ColorUtils;
Yohei Yukawa795f0102018-04-13 14:55:30 -070041import com.android.internal.util.function.TriConsumer;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -070042import com.android.keyguard.KeyguardUpdateMonitor;
Lucas Dupinf8463ee2018-06-11 16:18:15 -070043import com.android.keyguard.KeyguardUpdateMonitorCallback;
Lucas Dupin314d41f2017-05-08 15:52:58 -070044import com.android.systemui.Dependency;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080045import com.android.systemui.Dumpable;
John Spurlockbf370992014-06-17 13:58:31 -040046import com.android.systemui.R;
Lucas Dupin1ead7fc2017-05-24 14:14:44 -070047import com.android.systemui.colorextraction.SysuiColorExtractor;
Selim Cineka0fad3b2014-09-19 17:20:05 +020048import com.android.systemui.statusbar.ScrimView;
Rohan Shah20790b82018-07-02 17:21:04 -070049import com.android.systemui.statusbar.notification.stack.ViewState;
Selim Cinek72cd9a72019-08-09 17:19:57 -070050import com.android.systemui.statusbar.policy.KeyguardMonitor;
Lucas Dupin82aa1632017-12-13 00:13:57 -080051import com.android.systemui.util.AlarmTimeout;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080052import com.android.systemui.util.wakelock.DelayedWakeLock;
53import com.android.systemui.util.wakelock.WakeLock;
John Spurlockbf370992014-06-17 13:58:31 -040054
Lucas Dupin9e3fa102017-11-08 17:16:55 -080055import java.io.FileDescriptor;
Adrian Roosba7ca592017-08-15 17:48:05 +020056import java.io.PrintWriter;
Lucas Dupincdbb1cb2019-05-16 19:48:30 -070057import java.lang.annotation.Retention;
58import java.lang.annotation.RetentionPolicy;
Adrian Roosa5c63222017-07-27 16:33:39 +020059import java.util.function.Consumer;
60
Jorim Jaggiecc798e2014-05-26 18:14:37 +020061/**
62 * Controls both the scrim behind the notifications and in front of the notifications (when a
63 * security method gets shown).
64 */
Selim Cinek99e9adf2018-03-15 09:17:47 -070065public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnColorsChangedListener,
66 Dumpable {
Lucas Dupin9e3fa102017-11-08 17:16:55 -080067
Lucas Dupin55c6e802018-09-27 18:07:36 -070068 static final String TAG = "ScrimController";
Lucas Dupin9e3fa102017-11-08 17:16:55 -080069 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
70
Lucas Dupin4749f1b2018-04-04 15:09:06 -070071 /**
72 * General scrim animation duration.
73 */
John Spurlock8b12f222014-09-09 11:54:11 -040074 public static final long ANIMATION_DURATION = 220;
Lucas Dupin4749f1b2018-04-04 15:09:06 -070075 /**
76 * Longer duration, currently only used when going to AOD.
77 */
78 public static final long ANIMATION_DURATION_LONG = 1000;
Lucas Dupin82aa1632017-12-13 00:13:57 -080079 /**
80 * When both scrims have 0 alpha.
81 */
Lyn Hanbde48202019-05-29 19:18:29 -070082 public static final int TRANSPARENT = 0;
Lucas Dupin82aa1632017-12-13 00:13:57 -080083 /**
84 * When scrims aren't transparent (alpha 0) but also not opaque (alpha 1.)
85 */
Lyn Hanbde48202019-05-29 19:18:29 -070086 public static final int SEMI_TRANSPARENT = 1;
Lucas Dupin82aa1632017-12-13 00:13:57 -080087 /**
88 * When at least 1 scrim is fully opaque (alpha set to 1.)
89 */
Lyn Hanbde48202019-05-29 19:18:29 -070090 public static final int OPAQUE = 2;
Lucas Dupincdbb1cb2019-05-16 19:48:30 -070091
Lyn Hanbde48202019-05-29 19:18:29 -070092 @IntDef(prefix = {"VISIBILITY_"}, value = {
93 TRANSPARENT,
94 SEMI_TRANSPARENT,
95 OPAQUE
Lucas Dupincdbb1cb2019-05-16 19:48:30 -070096 })
97 @Retention(RetentionPolicy.SOURCE)
Lyn Hanbde48202019-05-29 19:18:29 -070098 public @interface ScrimVisibility {
99 }
Lucas Dupincdbb1cb2019-05-16 19:48:30 -0700100
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800101 /**
102 * Default alpha value for most scrims.
103 */
Lucas Dupin3d36dd82019-01-02 14:38:35 -0800104 public static final float GRADIENT_SCRIM_ALPHA = 0.2f;
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800105 /**
Lucas Dupin3113db62019-03-08 18:21:27 -0800106 * Scrim opacity when the phone is about to wake-up.
107 */
Lucas Dupin5f00fa52019-03-27 22:46:53 -0700108 public static final float WAKE_SENSOR_SCRIM_ALPHA = 0.6f;
Lucas Dupin3113db62019-03-08 18:21:27 -0800109 /**
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800110 * A scrim varies its opacity based on a busyness factor, for example
111 * how many notifications are currently visible.
112 */
Lucas Dupinde64ee02018-12-21 14:45:12 -0800113 public static final float GRADIENT_SCRIM_ALPHA_BUSY = 0.7f;
Lucas Dupinde64ee02018-12-21 14:45:12 -0800114
Lucas Dupin55c6e802018-09-27 18:07:36 -0700115 /**
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800116 * The most common scrim, the one under the keyguard.
117 */
Lucas Dupina0bf8512017-05-24 17:04:47 -0700118 protected static final float SCRIM_BEHIND_ALPHA_KEYGUARD = GRADIENT_SCRIM_ALPHA;
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800119
120 static final int TAG_KEY_ANIM = R.id.scrim;
Selim Cinek5104a6d2015-12-18 18:38:31 -0800121 private static final int TAG_START_ALPHA = R.id.scrim_alpha_start;
122 private static final int TAG_END_ALPHA = R.id.scrim_alpha_end;
Selim Cinek511f2702017-04-10 19:53:01 -0700123 private static final float NOT_INITIALIZED = -1;
John Spurlockbf370992014-06-17 13:58:31 -0400124
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800125 private ScrimState mState = ScrimState.UNINITIALIZED;
126 private final Context mContext;
Lyn Hanbde48202019-05-29 19:18:29 -0700127
Lucas Dupin8da8f2e92017-04-21 14:02:16 -0700128 protected final ScrimView mScrimInFront;
Lyn Hanbde48202019-05-29 19:18:29 -0700129 protected final ScrimView mScrimBehind;
130 protected final ScrimView mScrimForBubble;
131
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800132 private final UnlockMethodCache mUnlockMethodCache;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -0700133 private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800134 private final DozeParameters mDozeParameters;
Lucas Dupin82aa1632017-12-13 00:13:57 -0800135 private final AlarmTimeout mTimeTicker;
Lucas Dupin690c6f52018-07-10 15:28:57 -0700136 private final KeyguardVisibilityCallback mKeyguardVisibilityCallback;
Lucas Dupin54fbfb32019-03-05 18:08:13 -0800137 private final Handler mHandler;
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200138
Lucas Dupin1ead7fc2017-05-24 14:14:44 -0700139 private final SysuiColorExtractor mColorExtractor;
Lucas Dupin2bd3af62019-03-25 17:44:28 -0700140 private GradientColors mColors;
Lucas Dupin8da8f2e92017-04-21 14:02:16 -0700141 private boolean mNeedsDrawableColorUpdate;
142
Anthony Chen3cb3ad92016-12-01 10:58:47 -0800143 protected float mScrimBehindAlpha;
Lucas Dupin9324aa92017-07-26 20:29:38 -0700144 protected float mScrimBehindAlphaResValue;
Evan Rosky9a895012016-04-21 11:26:15 -0700145 protected float mScrimBehindAlphaKeyguard = SCRIM_BEHIND_ALPHA_KEYGUARD;
Xiaohui Chen4dab4b52016-03-07 12:31:14 -0800146
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800147 // Assuming the shade is expanded during initialization
148 private float mExpansionFraction = 1f;
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200149
150 private boolean mDarkenWhileDragging;
Lucas Dupin67f02632018-03-12 11:08:31 -0700151 private boolean mExpansionAffectsAlpha = true;
Evan Rosky9a895012016-04-21 11:26:15 -0700152 protected boolean mAnimateChange;
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200153 private boolean mUpdatePending;
Jorim Jaggie93698b2016-11-11 18:24:38 -0800154 private boolean mTracking;
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800155 protected long mAnimationDuration = -1;
Jorim Jaggie29b2db2014-05-30 23:17:03 +0200156 private long mAnimationDelay;
157 private Runnable mOnAnimationFinished;
Jorim Jaggif5304ad2017-07-17 18:31:13 +0200158 private boolean mDeferFinishedListener;
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200159 private final Interpolator mInterpolator = new DecelerateInterpolator();
Lyn Hanbde48202019-05-29 19:18:29 -0700160
161 private float mInFrontAlpha = NOT_INITIALIZED;
162 private float mBehindAlpha = NOT_INITIALIZED;
163 private float mBubbleAlpha = NOT_INITIALIZED;
164
165 private int mInFrontTint;
166 private int mBehindTint;
167 private int mBubbleTint;
168
Lucas Dupin82aa1632017-12-13 00:13:57 -0800169 private boolean mWallpaperVisibilityTimedOut;
Lucas Dupin82aa1632017-12-13 00:13:57 -0800170 private int mScrimsVisibility;
Yohei Yukawa795f0102018-04-13 14:55:30 -0700171 private final TriConsumer<ScrimState, Float, GradientColors> mScrimStateListener;
Lucas Dupin82aa1632017-12-13 00:13:57 -0800172 private final Consumer<Integer> mScrimVisibleListener;
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800173 private boolean mBlankScreen;
174 private boolean mScreenBlankingCallbackCalled;
175 private Callback mCallback;
Lucas Dupin82aa1632017-12-13 00:13:57 -0800176 private boolean mWallpaperSupportsAmbientMode;
Lucas Dupin3a64ed72018-02-12 12:44:37 -0800177 private boolean mScreenOn;
Lucas Dupin53cf12a2018-02-05 16:14:45 -0800178
179 // Scrim blanking callbacks
Lucas Dupin0791d972018-03-26 13:32:16 -0700180 private Runnable mPendingFrameCallback;
Lucas Dupin53cf12a2018-02-05 16:14:45 -0800181 private Runnable mBlankingTransitionRunnable;
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800182
183 private final WakeLock mWakeLock;
184 private boolean mWakeLockHeld;
Lucas Dupind5107302018-03-19 15:30:29 -0700185 private boolean mKeyguardOccluded;
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200186
Lyn Hanbde48202019-05-29 19:18:29 -0700187 public ScrimController(ScrimView scrimBehind, ScrimView scrimInFront, ScrimView scrimForBubble,
Yohei Yukawa795f0102018-04-13 14:55:30 -0700188 TriConsumer<ScrimState, Float, GradientColors> scrimStateListener,
shawnlin317db372018-04-09 19:49:48 +0800189 Consumer<Integer> scrimVisibleListener, DozeParameters dozeParameters,
Selim Cinek72cd9a72019-08-09 17:19:57 -0700190 AlarmManager alarmManager, KeyguardMonitor keyguardMonitor) {
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200191 mScrimBehind = scrimBehind;
192 mScrimInFront = scrimInFront;
Lyn Hanbde48202019-05-29 19:18:29 -0700193 mScrimForBubble = scrimForBubble;
194
Yohei Yukawa795f0102018-04-13 14:55:30 -0700195 mScrimStateListener = scrimStateListener;
Adrian Roosa5c63222017-07-27 16:33:39 +0200196 mScrimVisibleListener = scrimVisibleListener;
Lyn Hanbde48202019-05-29 19:18:29 -0700197
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800198 mContext = scrimBehind.getContext();
199 mUnlockMethodCache = UnlockMethodCache.getInstance(mContext);
Lucas Dupinbc9aac12018-03-04 20:18:15 -0800200 mDarkenWhileDragging = !mUnlockMethodCache.canSkipBouncer();
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800201 mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
Lucas Dupin690c6f52018-07-10 15:28:57 -0700202 mKeyguardVisibilityCallback = new KeyguardVisibilityCallback();
203 mKeyguardUpdateMonitor.registerCallback(mKeyguardVisibilityCallback);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800204 mScrimBehindAlphaResValue = mContext.getResources().getFloat(R.dimen.scrim_behind_alpha);
Lucas Dupin54fbfb32019-03-05 18:08:13 -0800205 mHandler = getHandler();
Lucas Dupin82aa1632017-12-13 00:13:57 -0800206 mTimeTicker = new AlarmTimeout(alarmManager, this::onHideWallpaperTimeout,
Lucas Dupin54fbfb32019-03-05 18:08:13 -0800207 "hide_aod_wallpaper", mHandler);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800208 mWakeLock = createWakeLock();
Lucas Dupin9324aa92017-07-26 20:29:38 -0700209 // Scrim alpha is initially set to the value on the resource but might be changed
210 // to make sure that text on top of it is legible.
211 mScrimBehindAlpha = mScrimBehindAlphaResValue;
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800212 mDozeParameters = dozeParameters;
Selim Cinek72cd9a72019-08-09 17:19:57 -0700213 keyguardMonitor.addCallback(new KeyguardMonitor.Callback() {
214 @Override
215 public void onKeyguardFadingAwayChanged() {
216 setKeyguardFadingAway(keyguardMonitor.isKeyguardFadingAway(),
217 keyguardMonitor.getKeyguardFadingAwayDuration());
218 }
219 });
Anthony Chen3cb3ad92016-12-01 10:58:47 -0800220
Lucas Dupin1ead7fc2017-05-24 14:14:44 -0700221 mColorExtractor = Dependency.get(SysuiColorExtractor.class);
Lucas Dupin314d41f2017-05-08 15:52:58 -0700222 mColorExtractor.addOnColorsChangedListener(this);
Lucas Dupin2bd3af62019-03-25 17:44:28 -0700223 mColors = mColorExtractor.getNeutralColors();
Lucas Dupin8da8f2e92017-04-21 14:02:16 -0700224 mNeedsDrawableColorUpdate = true;
225
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800226 final ScrimState[] states = ScrimState.values();
227 for (int i = 0; i < states.length; i++) {
Lyn Hanbde48202019-05-29 19:18:29 -0700228 states[i].init(mScrimInFront, mScrimBehind, mScrimForBubble, mDozeParameters);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800229 states[i].setScrimBehindAlphaKeyguard(mScrimBehindAlphaKeyguard);
230 }
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800231
Lucas Dupin373356b2018-04-07 10:50:25 -0700232 mScrimBehind.setDefaultFocusHighlightEnabled(false);
233 mScrimInFront.setDefaultFocusHighlightEnabled(false);
Lyn Hanbde48202019-05-29 19:18:29 -0700234 mScrimForBubble.setDefaultFocusHighlightEnabled(false);
Lucas Dupin373356b2018-04-07 10:50:25 -0700235
Selim Cinek511f2702017-04-10 19:53:01 -0700236 updateScrims();
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200237 }
238
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800239 public void transitionTo(ScrimState state) {
240 transitionTo(state, null);
241 }
Lucas Dupin8da8f2e92017-04-21 14:02:16 -0700242
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800243 public void transitionTo(ScrimState state, Callback callback) {
244 if (state == mState) {
Lucas Dupin19aba8e2017-12-11 12:42:26 -0800245 // Call the callback anyway, unless it's already enqueued
246 if (callback != null && mCallback != callback) {
247 callback.onFinished();
248 }
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800249 return;
250 } else if (DEBUG) {
251 Log.d(TAG, "State changed to: " + state);
252 }
253
254 if (state == ScrimState.UNINITIALIZED) {
255 throw new IllegalArgumentException("Cannot change to UNINITIALIZED.");
256 }
257
Lucas Dupin8635c442017-12-08 10:36:28 -0800258 final ScrimState oldState = mState;
259 mState = state;
Lucas Dupin5866aaf2018-02-02 14:45:31 -0800260 Trace.traceCounter(Trace.TRACE_TAG_APP, "scrim_state", mState.getIndex());
Lucas Dupin8635c442017-12-08 10:36:28 -0800261
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800262 if (mCallback != null) {
263 mCallback.onCancelled();
264 }
265 mCallback = callback;
266
Lucas Dupin8635c442017-12-08 10:36:28 -0800267 state.prepare(oldState);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800268 mScreenBlankingCallbackCalled = false;
269 mAnimationDelay = 0;
270 mBlankScreen = state.getBlanksScreen();
271 mAnimateChange = state.getAnimateChange();
272 mAnimationDuration = state.getAnimationDuration();
Lyn Hanbde48202019-05-29 19:18:29 -0700273
274 mInFrontTint = state.getFrontTint();
275 mBehindTint = state.getBehindTint();
276 mBubbleTint = state.getBubbleTint();
277
278 mInFrontAlpha = state.getFrontAlpha();
279 mBehindAlpha = state.getBehindAlpha();
280 mBubbleAlpha = state.getBubbleAlpha();
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800281 applyExpansionToAlpha();
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800282
Lucas Dupin38962d72018-03-14 12:41:39 -0700283 // Scrim might acquire focus when user is navigating with a D-pad or a keyboard.
284 // We need to disable focus otherwise AOD would end up with a gray overlay.
285 mScrimInFront.setFocusable(!state.isLowPowerState());
286 mScrimBehind.setFocusable(!state.isLowPowerState());
287
Lucas Dupin53cf12a2018-02-05 16:14:45 -0800288 // Cancel blanking transitions that were pending before we requested a new state
Lucas Dupin8c7cb022018-02-05 10:49:03 -0800289 if (mPendingFrameCallback != null) {
Lucas Dupin0791d972018-03-26 13:32:16 -0700290 mScrimBehind.removeCallbacks(mPendingFrameCallback);
Lucas Dupin8c7cb022018-02-05 10:49:03 -0800291 mPendingFrameCallback = null;
292 }
Lucas Dupin54fbfb32019-03-05 18:08:13 -0800293 if (mHandler.hasCallbacks(mBlankingTransitionRunnable)) {
294 mHandler.removeCallbacks(mBlankingTransitionRunnable);
Lucas Dupin53cf12a2018-02-05 16:14:45 -0800295 mBlankingTransitionRunnable = null;
296 }
Lucas Dupin8c7cb022018-02-05 10:49:03 -0800297
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800298 // Showing/hiding the keyguard means that scrim colors have to be switched, not necessary
299 // to do the same when you're just showing the brightness mirror.
300 mNeedsDrawableColorUpdate = state != ScrimState.BRIGHTNESS_MIRROR;
301
Lucas Dupineea53b32017-12-18 13:47:14 -0800302 // The device might sleep if it's entering AOD, we need to make sure that
303 // the animation plays properly until the last frame.
304 // It's important to avoid holding the wakelock unless necessary because
305 // WakeLock#aqcuire will trigger an IPC and will cause jank.
Lucas Dupin38962d72018-03-14 12:41:39 -0700306 if (mState.isLowPowerState()) {
Lucas Dupineea53b32017-12-18 13:47:14 -0800307 holdWakeLock();
308 }
Lucas Dupin82aa1632017-12-13 00:13:57 -0800309
TYM Tsaia71c8922019-01-07 15:57:53 +0800310 // AOD wallpapers should fade away after a while.
311 // Docking pulses may take a long time, wallpapers should also fade away after a while.
Jerry Changbde4c0c2019-06-13 16:58:41 +0800312 mWallpaperVisibilityTimedOut = false;
313 if (shouldFadeAwayWallpaper()) {
314 mTimeTicker.schedule(mDozeParameters.getWallpaperAodDuration(),
315 AlarmTimeout.MODE_IGNORE_IF_SCHEDULED);
Lucas Dupinc7804042018-12-21 12:26:33 -0800316 } else {
Lucas Dupin82aa1632017-12-13 00:13:57 -0800317 mTimeTicker.cancel();
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800318 }
319
Lucas Dupinff307d52018-02-05 21:16:39 -0800320 if (mKeyguardUpdateMonitor.needsSlowUnlockTransition() && mState == ScrimState.UNLOCKED) {
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800321 // In case the user isn't unlocked, make sure to delay a bit because the system is hosed
322 // with too many things at this case, in order to not skip the initial frames.
323 mScrimInFront.postOnAnimationDelayed(this::scheduleUpdate, 16);
324 mAnimationDelay = StatusBar.FADE_KEYGUARD_START_DELAY;
Lucas Dupin0791d972018-03-26 13:32:16 -0700325 } else if ((!mDozeParameters.getAlwaysOn() && oldState == ScrimState.AOD)
Lucas Dupin16cfe452018-02-08 13:14:50 -0800326 || (mState == ScrimState.AOD && !mDozeParameters.getDisplayNeedsBlanking())) {
327 // Scheduling a frame isn't enough when:
328 // • Leaving doze and we need to modify scrim color immediately
329 // • ColorFade will not kick-in and scrim cannot wait for pre-draw.
Lucas Dupinff307d52018-02-05 21:16:39 -0800330 onPreDraw();
331 } else {
332 scheduleUpdate();
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800333 }
Yohei Yukawa795f0102018-04-13 14:55:30 -0700334
335 dispatchScrimState(mScrimBehind.getViewAlpha());
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800336 }
337
Jerry Changbde4c0c2019-06-13 16:58:41 +0800338 private boolean shouldFadeAwayWallpaper() {
339 if (!mWallpaperSupportsAmbientMode) {
340 return false;
341 }
342
343 if (mState == ScrimState.AOD && mDozeParameters.getAlwaysOn()) {
344 return true;
345 }
346
347 if (mState == ScrimState.PULSING
348 && mCallback != null && mCallback.shouldTimeoutWallpaper()) {
349 return true;
350 }
351
352 return false;
353 }
354
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800355 public ScrimState getState() {
356 return mState;
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200357 }
358
Lucas Dupinbc9aac12018-03-04 20:18:15 -0800359 protected void setScrimBehindValues(float scrimBehindAlphaKeyguard) {
Jorim Jaggie31f6b82016-07-01 16:15:09 -0700360 mScrimBehindAlphaKeyguard = scrimBehindAlphaKeyguard;
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800361 ScrimState[] states = ScrimState.values();
362 for (int i = 0; i < states.length; i++) {
363 states[i].setScrimBehindAlphaKeyguard(scrimBehindAlphaKeyguard);
364 }
Jorim Jaggie31f6b82016-07-01 16:15:09 -0700365 scheduleUpdate();
366 }
367
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200368 public void onTrackingStarted() {
Jorim Jaggie93698b2016-11-11 18:24:38 -0800369 mTracking = true;
Selim Cineke8bae622015-07-15 13:24:06 -0700370 mDarkenWhileDragging = !mUnlockMethodCache.canSkipBouncer();
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200371 }
372
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +0200373 public void onExpandingFinished() {
Jorim Jaggie93698b2016-11-11 18:24:38 -0800374 mTracking = false;
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +0200375 }
376
Lucas Dupin82aa1632017-12-13 00:13:57 -0800377 @VisibleForTesting
378 protected void onHideWallpaperTimeout() {
TYM Tsaia71c8922019-01-07 15:57:53 +0800379 if (mState != ScrimState.AOD && mState != ScrimState.PULSING) {
Lucas Dupin82aa1632017-12-13 00:13:57 -0800380 return;
381 }
382
383 holdWakeLock();
384 mWallpaperVisibilityTimedOut = true;
385 mAnimateChange = true;
386 mAnimationDuration = mDozeParameters.getWallpaperFadeOutDuration();
387 scheduleUpdate();
388 }
389
390 private void holdWakeLock() {
391 if (!mWakeLockHeld) {
392 if (mWakeLock != null) {
393 mWakeLockHeld = true;
Lucas Dupinee4c9b72019-02-18 17:04:58 -0800394 mWakeLock.acquire(TAG);
Lucas Dupin82aa1632017-12-13 00:13:57 -0800395 } else {
396 Log.w(TAG, "Cannot hold wake lock, it has not been set yet");
397 }
398 }
399 }
400
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800401 /**
402 * Current state of the shade expansion when pulling it from the top.
403 * This value is 1 when on top of the keyguard and goes to 0 as the user drags up.
404 *
405 * The expansion fraction is tied to the scrim opacity.
406 *
Lucas Dupin3daf3b02018-02-27 17:23:41 -0800407 * @param fraction From 0 to 1 where 0 means collapsed and 1 expanded.
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800408 */
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200409 public void setPanelExpansion(float fraction) {
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800410 if (mExpansionFraction != fraction) {
411 mExpansionFraction = fraction;
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800412
Lyn Hanbde48202019-05-29 19:18:29 -0700413 boolean relevantState = (mState == ScrimState.UNLOCKED
414 || mState == ScrimState.KEYGUARD
415 || mState == ScrimState.PULSING
416 || mState == ScrimState.BUBBLE_EXPANDED);
417 if (!(relevantState && mExpansionAffectsAlpha)) {
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800418 return;
419 }
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800420 applyExpansionToAlpha();
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800421 if (mUpdatePending) {
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800422 return;
423 }
Lucas Dupin3daf3b02018-02-27 17:23:41 -0800424 setOrAdaptCurrentAnimation(mScrimBehind);
425 setOrAdaptCurrentAnimation(mScrimInFront);
Lyn Hanbde48202019-05-29 19:18:29 -0700426 setOrAdaptCurrentAnimation(mScrimForBubble);
Yohei Yukawa795f0102018-04-13 14:55:30 -0700427 dispatchScrimState(mScrimBehind.getViewAlpha());
Jerry Changbde4c0c2019-06-13 16:58:41 +0800428
429 // Reset wallpaper timeout if it's already timeout like expanding panel while PULSING
430 // and docking.
431 if (mWallpaperVisibilityTimedOut) {
432 mWallpaperVisibilityTimedOut = false;
433 mTimeTicker.schedule(mDozeParameters.getWallpaperAodDuration(),
434 AlarmTimeout.MODE_IGNORE_IF_SCHEDULED);
435 }
Lucas Dupin3daf3b02018-02-27 17:23:41 -0800436 }
437 }
438
439 private void setOrAdaptCurrentAnimation(View scrim) {
Lyn Hanbde48202019-05-29 19:18:29 -0700440 float alpha = getCurrentScrimAlpha(scrim);
441 if (isAnimating(scrim)) {
442 // Adapt current animation.
Lucas Dupin3daf3b02018-02-27 17:23:41 -0800443 ValueAnimator previousAnimator = (ValueAnimator) scrim.getTag(TAG_KEY_ANIM);
Lucas Dupin3daf3b02018-02-27 17:23:41 -0800444 float previousEndValue = (Float) scrim.getTag(TAG_END_ALPHA);
445 float previousStartValue = (Float) scrim.getTag(TAG_START_ALPHA);
446 float relativeDiff = alpha - previousEndValue;
447 float newStartValue = previousStartValue + relativeDiff;
448 scrim.setTag(TAG_START_ALPHA, newStartValue);
449 scrim.setTag(TAG_END_ALPHA, alpha);
450 previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime());
Lyn Hanbde48202019-05-29 19:18:29 -0700451 } else {
452 // Set animation.
453 updateScrimColor(scrim, alpha, getCurrentScrimTint(scrim));
Jorim Jaggi93439da2014-06-30 23:53:39 +0200454 }
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200455 }
456
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800457 private void applyExpansionToAlpha() {
Lucas Dupin67f02632018-03-12 11:08:31 -0700458 if (!mExpansionAffectsAlpha) {
459 return;
460 }
461
Lyn Hanbde48202019-05-29 19:18:29 -0700462 if (mState == ScrimState.UNLOCKED || mState == ScrimState.BUBBLE_EXPANDED) {
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800463 // Darken scrim as you pull down the shade when unlocked
464 float behindFraction = getInterpolatedFraction();
465 behindFraction = (float) Math.pow(behindFraction, 0.8f);
Lyn Hanbde48202019-05-29 19:18:29 -0700466 mBehindAlpha = behindFraction * GRADIENT_SCRIM_ALPHA_BUSY;
467 mInFrontAlpha = 0;
Lucas Dupin1c327432019-01-03 13:37:53 -0800468 } else if (mState == ScrimState.KEYGUARD || mState == ScrimState.PULSING) {
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800469 // Either darken of make the scrim transparent when you
470 // pull down the shade
471 float interpolatedFract = getInterpolatedFraction();
Lucas Dupin3d36dd82019-01-02 14:38:35 -0800472 float alphaBehind = mState.getBehindAlpha();
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800473 if (mDarkenWhileDragging) {
Lyn Hanbde48202019-05-29 19:18:29 -0700474 mBehindAlpha = MathUtils.lerp(GRADIENT_SCRIM_ALPHA_BUSY, alphaBehind,
Lucas Dupinb380c882018-02-25 21:57:17 -0800475 interpolatedFract);
Chris.CC Leed424e202019-09-16 12:17:19 +0800476 mInFrontAlpha = mState.getFrontAlpha();
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800477 } else {
Lyn Hanbde48202019-05-29 19:18:29 -0700478 mBehindAlpha = MathUtils.lerp(0 /* start */, alphaBehind,
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800479 interpolatedFract);
Chris.CC Leed424e202019-09-16 12:17:19 +0800480 mInFrontAlpha = mState.getFrontAlpha();
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800481 }
Lyn Hanbde48202019-05-29 19:18:29 -0700482 mBehindTint = ColorUtils.blendARGB(ScrimState.BOUNCER.getBehindTint(),
Lucas Dupin4cf01062019-03-08 17:07:49 -0800483 mState.getBehindTint(), interpolatedFract);
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800484 }
485 }
486
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800487 /**
Anthony Chene658cc22017-04-27 11:17:35 -0700488 * Sets the given drawable as the background of the scrim that shows up behind the
489 * notifications.
490 */
491 public void setScrimBehindDrawable(Drawable drawable) {
492 mScrimBehind.setDrawable(drawable);
493 }
494
Michael Wrightcae88752018-04-16 23:13:54 +0100495 /**
Lucas Dupin69bda602018-05-18 17:24:52 -0700496 * Sets the front scrim opacity in AOD so it's not as bright.
497 * <p>
498 * Displays usually don't support multiple dimming settings when in low power mode.
499 * The workaround is to modify the front scrim opacity when in AOD, so it's not as
500 * bright when you're at the movies or lying down on bed.
501 * <p>
502 * This value will be lost during transitions and only updated again after the the
503 * device is dozing when the light sensor is on.
Michael Wrightcae88752018-04-16 23:13:54 +0100504 */
505 public void setAodFrontScrimAlpha(float alpha) {
Chris.CC Leed424e202019-09-16 12:17:19 +0800506 if (((mState == ScrimState.AOD && mDozeParameters.getAlwaysOn())
507 || mState == ScrimState.PULSING) && mInFrontAlpha != alpha) {
Lyn Hanbde48202019-05-29 19:18:29 -0700508 mInFrontAlpha = alpha;
Lucas Dupin8523d132018-05-31 17:34:32 -0700509 updateScrims();
Michael Wrightcae88752018-04-16 23:13:54 +0100510 }
511
512 mState.AOD.setAodFrontScrimAlpha(alpha);
Chris.CC Leed424e202019-09-16 12:17:19 +0800513 mState.PULSING.setAodFrontScrimAlpha(alpha);
Michael Wrightcae88752018-04-16 23:13:54 +0100514 }
515
Lucas Dupin5f00fa52019-03-27 22:46:53 -0700516 /**
Lucas Dupin34306c32019-07-16 11:56:53 -0700517 * Set front scrim to black, cancelling animations, in order to prepare to fade them
518 * away once the display turns on.
519 */
520 public void prepareForGentleWakeUp() {
521 if (mState == ScrimState.AOD && mDozeParameters.getAlwaysOn()) {
Mady Mellorfa8c70d2019-07-17 13:44:01 -0700522 mInFrontAlpha = 1f;
Mady Mellor4035ef52019-07-25 11:10:02 -0700523 mInFrontTint = Color.BLACK;
524 mBehindTint = Color.BLACK;
Lucas Dupin34306c32019-07-16 11:56:53 -0700525 mAnimateChange = false;
526 updateScrims();
527 mAnimateChange = true;
528 mAnimationDuration = ANIMATION_DURATION_LONG;
529 }
530 }
531
532 /**
Lucas Dupin5f00fa52019-03-27 22:46:53 -0700533 * If the lock screen sensor is active.
534 */
535 public void setWakeLockScreenSensorActive(boolean active) {
536 for (ScrimState state : ScrimState.values()) {
537 state.setWakeLockScreenSensorActive(active);
538 }
539
540 if (mState == ScrimState.PULSING) {
541 float newBehindAlpha = mState.getBehindAlpha();
Lyn Hanbde48202019-05-29 19:18:29 -0700542 if (mBehindAlpha != newBehindAlpha) {
543 mBehindAlpha = newBehindAlpha;
Lucas Dupin5f00fa52019-03-27 22:46:53 -0700544 updateScrims();
545 }
546 }
547 }
548
Evan Rosky9a895012016-04-21 11:26:15 -0700549 protected void scheduleUpdate() {
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200550 if (mUpdatePending) return;
Jorim Jaggie29b2db2014-05-30 23:17:03 +0200551
552 // Make sure that a frame gets scheduled.
553 mScrimBehind.invalidate();
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200554 mScrimBehind.getViewTreeObserver().addOnPreDrawListener(this);
555 mUpdatePending = true;
556 }
557
Xiaohui Chen5da71352016-02-22 10:04:41 -0800558 protected void updateScrims() {
Lucas Dupin9324aa92017-07-26 20:29:38 -0700559 // Make sure we have the right gradients and their opacities will satisfy GAR.
Lucas Dupin8da8f2e92017-04-21 14:02:16 -0700560 if (mNeedsDrawableColorUpdate) {
561 mNeedsDrawableColorUpdate = false;
Lucas Dupinf8463ee2018-06-11 16:18:15 -0700562 // Only animate scrim color if the scrim view is actually visible
563 boolean animateScrimInFront = mScrimInFront.getViewAlpha() != 0 && !mBlankScreen;
564 boolean animateScrimBehind = mScrimBehind.getViewAlpha() != 0 && !mBlankScreen;
Lyn Hanbde48202019-05-29 19:18:29 -0700565 boolean animateScrimForBubble = mScrimForBubble.getViewAlpha() != 0 && !mBlankScreen;
566
Lucas Dupin2bd3af62019-03-25 17:44:28 -0700567 mScrimInFront.setColors(mColors, animateScrimInFront);
568 mScrimBehind.setColors(mColors, animateScrimBehind);
Lyn Hanbde48202019-05-29 19:18:29 -0700569 mScrimForBubble.setColors(mColors, animateScrimForBubble);
Lucas Dupin9324aa92017-07-26 20:29:38 -0700570
571 // Calculate minimum scrim opacity for white or black text.
Lucas Dupin2bd3af62019-03-25 17:44:28 -0700572 int textColor = mColors.supportsDarkText() ? Color.BLACK : Color.WHITE;
573 int mainColor = mColors.getMainColor();
Lucas Dupin9324aa92017-07-26 20:29:38 -0700574 float minOpacity = ColorUtils.calculateMinimumBackgroundAlpha(textColor, mainColor,
575 4.5f /* minimumContrast */) / 255f;
576 mScrimBehindAlpha = Math.max(mScrimBehindAlphaResValue, minOpacity);
Yohei Yukawa795f0102018-04-13 14:55:30 -0700577 dispatchScrimState(mScrimBehind.getViewAlpha());
Lucas Dupin8da8f2e92017-04-21 14:02:16 -0700578 }
579
Lucas Dupind5107302018-03-19 15:30:29 -0700580 // We want to override the back scrim opacity for the AOD state
Lucas Dupin82aa1632017-12-13 00:13:57 -0800581 // when it's time to fade the wallpaper away.
TYM Tsaia71c8922019-01-07 15:57:53 +0800582 boolean aodWallpaperTimeout = (mState == ScrimState.AOD || mState == ScrimState.PULSING)
583 && mWallpaperVisibilityTimedOut;
Lucas Dupind5107302018-03-19 15:30:29 -0700584 // We also want to hide FLAG_SHOW_WHEN_LOCKED activities under the scrim.
585 boolean occludedKeyguard = (mState == ScrimState.PULSING || mState == ScrimState.AOD)
586 && mKeyguardOccluded;
587 if (aodWallpaperTimeout || occludedKeyguard) {
Lyn Hanbde48202019-05-29 19:18:29 -0700588 mBehindAlpha = 1;
Lucas Dupin82aa1632017-12-13 00:13:57 -0800589 }
Lyn Hanbde48202019-05-29 19:18:29 -0700590 setScrimAlpha(mScrimInFront, mInFrontAlpha);
591 setScrimAlpha(mScrimBehind, mBehindAlpha);
592 setScrimAlpha(mScrimForBubble, mBubbleAlpha);
Adrian Roosa5c63222017-07-27 16:33:39 +0200593 dispatchScrimsVisible();
594 }
595
Yohei Yukawa795f0102018-04-13 14:55:30 -0700596 private void dispatchScrimState(float alpha) {
597 mScrimStateListener.accept(mState, alpha, mScrimInFront.getColors());
598 }
599
Adrian Roosa5c63222017-07-27 16:33:39 +0200600 private void dispatchScrimsVisible() {
Lucas Dupin82aa1632017-12-13 00:13:57 -0800601 final int currentScrimVisibility;
602 if (mScrimInFront.getViewAlpha() == 1 || mScrimBehind.getViewAlpha() == 1) {
Lyn Hanbde48202019-05-29 19:18:29 -0700603 currentScrimVisibility = OPAQUE;
Lucas Dupin82aa1632017-12-13 00:13:57 -0800604 } else if (mScrimInFront.getViewAlpha() == 0 && mScrimBehind.getViewAlpha() == 0) {
Lyn Hanbde48202019-05-29 19:18:29 -0700605 currentScrimVisibility = TRANSPARENT;
Lucas Dupin82aa1632017-12-13 00:13:57 -0800606 } else {
Lyn Hanbde48202019-05-29 19:18:29 -0700607 currentScrimVisibility = SEMI_TRANSPARENT;
Lucas Dupin82aa1632017-12-13 00:13:57 -0800608 }
Adrian Roosa5c63222017-07-27 16:33:39 +0200609
Lucas Dupin82aa1632017-12-13 00:13:57 -0800610 if (mScrimsVisibility != currentScrimVisibility) {
611 mScrimsVisibility = currentScrimVisibility;
612 mScrimVisibleListener.accept(currentScrimVisibility);
Adrian Roosa5c63222017-07-27 16:33:39 +0200613 }
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200614 }
615
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800616 private float getInterpolatedFraction() {
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800617 float frac = mExpansionFraction;
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200618 // let's start this 20% of the way down the screen
619 frac = frac * 1.2f - 0.2f;
620 if (frac <= 0) {
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800621 return 0;
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200622 } else {
623 // woo, special effects
Lyn Hanbde48202019-05-29 19:18:29 -0700624 return (float) (1f - 0.5f * (1f - Math.cos(3.14159f * Math.pow(1f - frac, 2f))));
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200625 }
626 }
627
Lucas Dupin3daf3b02018-02-27 17:23:41 -0800628 private void setScrimAlpha(ScrimView scrim, float alpha) {
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800629 if (alpha == 0f) {
630 scrim.setClickable(false);
Selim Cinekaac93252015-04-14 20:04:12 -0700631 } else {
Lucas Dupin1c327432019-01-03 13:37:53 -0800632 // Eat touch events (unless dozing).
633 scrim.setClickable(mState != ScrimState.AOD);
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200634 }
Lucas Dupin3daf3b02018-02-27 17:23:41 -0800635 updateScrim(scrim, alpha);
Jorim Jaggi048af1f2014-11-11 22:51:10 +0100636 }
637
Lyn Hanbde48202019-05-29 19:18:29 -0700638 private String getScrimName(ScrimView scrim) {
639 if (scrim == mScrimInFront) {
640 return "front_scrim";
641 } else if (scrim == mScrimBehind) {
642 return "back_scrim";
643 } else if (scrim == mScrimForBubble) {
644 return "bubble_scrim";
645 }
646 return "unknown_scrim";
647 }
648
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800649 private void updateScrimColor(View scrim, float alpha, int tint) {
650 alpha = Math.max(0, Math.min(1.0f, alpha));
Selim Cinekaac93252015-04-14 20:04:12 -0700651 if (scrim instanceof ScrimView) {
Lucas Dupin8da8f2e92017-04-21 14:02:16 -0700652 ScrimView scrimView = (ScrimView) scrim;
Lucas Dupin8da8f2e92017-04-21 14:02:16 -0700653
Lyn Hanbde48202019-05-29 19:18:29 -0700654 Trace.traceCounter(Trace.TRACE_TAG_APP, getScrimName(scrimView) + "_alpha",
Adrian Roosa5c63222017-07-27 16:33:39 +0200655 (int) (alpha * 255));
656
Lyn Hanbde48202019-05-29 19:18:29 -0700657 Trace.traceCounter(Trace.TRACE_TAG_APP, getScrimName(scrimView) + "_tint",
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800658 Color.alpha(tint));
Adrian Roosa5c63222017-07-27 16:33:39 +0200659
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800660 scrimView.setTint(tint);
661 scrimView.setViewAlpha(alpha);
Selim Cinekaac93252015-04-14 20:04:12 -0700662 } else {
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800663 scrim.setAlpha(alpha);
Selim Cinekaac93252015-04-14 20:04:12 -0700664 }
Selim Cinek8cd80402017-08-01 10:44:29 -0700665 dispatchScrimsVisible();
Jorim Jaggi048af1f2014-11-11 22:51:10 +0100666 }
667
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800668 private void startScrimAnimation(final View scrim, float current) {
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800669 ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
670 final int initialScrimTint = scrim instanceof ScrimView ? ((ScrimView) scrim).getTint() :
671 Color.TRANSPARENT;
Lucas Dupin8da8f2e92017-04-21 14:02:16 -0700672 anim.addUpdateListener(animation -> {
Lucas Dupin3daf3b02018-02-27 17:23:41 -0800673 final float startAlpha = (Float) scrim.getTag(TAG_START_ALPHA);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800674 final float animAmount = (float) animation.getAnimatedValue();
Lucas Dupin3daf3b02018-02-27 17:23:41 -0800675 final int finalScrimTint = getCurrentScrimTint(scrim);
676 final float finalScrimAlpha = getCurrentScrimAlpha(scrim);
677 float alpha = MathUtils.lerp(startAlpha, finalScrimAlpha, animAmount);
678 alpha = MathUtils.constrain(alpha, 0f, 1f);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800679 int tint = ColorUtils.blendARGB(initialScrimTint, finalScrimTint, animAmount);
680 updateScrimColor(scrim, alpha, tint);
Adrian Roosa5c63222017-07-27 16:33:39 +0200681 dispatchScrimsVisible();
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200682 });
Lucas Dupin3503c5f2018-03-02 19:04:00 -0800683 anim.setInterpolator(mInterpolator);
Jorim Jaggie29b2db2014-05-30 23:17:03 +0200684 anim.setStartDelay(mAnimationDelay);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800685 anim.setDuration(mAnimationDuration);
Jorim Jaggie29b2db2014-05-30 23:17:03 +0200686 anim.addListener(new AnimatorListenerAdapter() {
Joanne Chunga393ad62019-01-16 21:41:31 +0800687 private Callback lastCallback = mCallback;
688
Jorim Jaggie29b2db2014-05-30 23:17:03 +0200689 @Override
690 public void onAnimationEnd(Animator animation) {
Joanne Chunga393ad62019-01-16 21:41:31 +0800691 onFinished(lastCallback);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800692
693 scrim.setTag(TAG_KEY_ANIM, null);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800694 dispatchScrimsVisible();
695
Jorim Jaggif5304ad2017-07-17 18:31:13 +0200696 if (!mDeferFinishedListener && mOnAnimationFinished != null) {
Jorim Jaggie29b2db2014-05-30 23:17:03 +0200697 mOnAnimationFinished.run();
698 mOnAnimationFinished = null;
699 }
700 }
701 });
Lucas Dupin3daf3b02018-02-27 17:23:41 -0800702
703 // Cache alpha values because we might want to update this animator in the future if
704 // the user expands the panel while the animation is still running.
705 scrim.setTag(TAG_START_ALPHA, current);
706 scrim.setTag(TAG_END_ALPHA, getCurrentScrimAlpha(scrim));
707
John Spurlockbf370992014-06-17 13:58:31 -0400708 scrim.setTag(TAG_KEY_ANIM, anim);
Lucas Dupin3daf3b02018-02-27 17:23:41 -0800709 anim.start();
710 }
711
712 private float getCurrentScrimAlpha(View scrim) {
713 if (scrim == mScrimInFront) {
Lyn Hanbde48202019-05-29 19:18:29 -0700714 return mInFrontAlpha;
Lucas Dupin3daf3b02018-02-27 17:23:41 -0800715 } else if (scrim == mScrimBehind) {
Lyn Hanbde48202019-05-29 19:18:29 -0700716 return mBehindAlpha;
717 } else if (scrim == mScrimForBubble) {
718 return mBubbleAlpha;
Lucas Dupin3daf3b02018-02-27 17:23:41 -0800719 } else {
720 throw new IllegalArgumentException("Unknown scrim view");
721 }
722 }
723
724 private int getCurrentScrimTint(View scrim) {
725 if (scrim == mScrimInFront) {
Lyn Hanbde48202019-05-29 19:18:29 -0700726 return mInFrontTint;
Lucas Dupin3daf3b02018-02-27 17:23:41 -0800727 } else if (scrim == mScrimBehind) {
Lyn Hanbde48202019-05-29 19:18:29 -0700728 return mBehindTint;
729 } else if (scrim == mScrimForBubble) {
730 return mBubbleTint;
Lucas Dupin3daf3b02018-02-27 17:23:41 -0800731 } else {
732 throw new IllegalArgumentException("Unknown scrim view");
733 }
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200734 }
735
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200736 @Override
737 public boolean onPreDraw() {
738 mScrimBehind.getViewTreeObserver().removeOnPreDrawListener(this);
739 mUpdatePending = false;
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800740 if (mCallback != null) {
741 mCallback.onStart();
Selim Cinek372d1bd2015-08-14 13:19:37 -0700742 }
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200743 updateScrims();
Lucas Dupin3503c5f2018-03-02 19:04:00 -0800744 if (mOnAnimationFinished != null && !isAnimating(mScrimInFront)
745 && !isAnimating(mScrimBehind)) {
746 mOnAnimationFinished.run();
747 mOnAnimationFinished = null;
748 }
Selim Cinekedd32b82015-06-23 22:05:58 -0400749 return true;
750 }
751
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800752 private void onFinished() {
Joanne Chunga393ad62019-01-16 21:41:31 +0800753 onFinished(mCallback);
754 }
755
756 private void onFinished(Callback callback) {
Selim Cinek22fa9752019-09-26 16:53:31 -0700757 if (!hasReachedFinalState(mScrimBehind)
758 || !hasReachedFinalState(mScrimInFront)
759 || !hasReachedFinalState(mScrimForBubble)) {
760 if (callback != null && callback != mCallback) {
761 // Since we only notify the callback that we're finished once everything has
762 // finished, we need to make sure that any changing callbacks are also invoked
763 callback.onFinished();
764 }
765 return;
766 }
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800767 if (mWakeLockHeld) {
Lucas Dupinee4c9b72019-02-18 17:04:58 -0800768 mWakeLock.release(TAG);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800769 mWakeLockHeld = false;
770 }
Joanne Chunga393ad62019-01-16 21:41:31 +0800771
772 if (callback != null) {
773 callback.onFinished();
774
775 if (callback == mCallback) {
776 mCallback = null;
777 }
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800778 }
Joanne Chunga393ad62019-01-16 21:41:31 +0800779
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800780 // When unlocking with fingerprint, we'll fade the scrims from black to transparent.
781 // At the end of the animation we need to remove the tint.
782 if (mState == ScrimState.UNLOCKED) {
Lyn Hanbde48202019-05-29 19:18:29 -0700783 mInFrontTint = Color.TRANSPARENT;
784 mBehindTint = Color.TRANSPARENT;
785 mBubbleTint = Color.TRANSPARENT;
Selim Cinek22fa9752019-09-26 16:53:31 -0700786 updateScrimColor(mScrimInFront, mInFrontAlpha, mInFrontTint);
787 updateScrimColor(mScrimBehind, mBehindAlpha, mBehindTint);
788 updateScrimColor(mScrimForBubble, mBubbleAlpha, mBubbleTint);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800789 }
790 }
791
Selim Cinek22fa9752019-09-26 16:53:31 -0700792 private boolean hasReachedFinalState(ScrimView scrim) {
793 return scrim.getViewAlpha() == getCurrentScrimAlpha(scrim)
794 && scrim.getTint() == getCurrentScrimTint(scrim);
795 }
796
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700797 private boolean isAnimating(View scrim) {
798 return scrim.getTag(TAG_KEY_ANIM) != null;
799 }
800
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800801 @VisibleForTesting
802 void setOnAnimationFinished(Runnable onAnimationFinished) {
803 mOnAnimationFinished = onAnimationFinished;
804 }
Adrian Roos5f72c922016-03-08 15:54:26 -0800805
Lucas Dupin3daf3b02018-02-27 17:23:41 -0800806 private void updateScrim(ScrimView scrim, float alpha) {
807 final float currentAlpha = scrim.getViewAlpha();
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800808
809 ValueAnimator previousAnimator = ViewState.getChildTag(scrim, TAG_KEY_ANIM);
Selim Cinekaac93252015-04-14 20:04:12 -0700810 if (previousAnimator != null) {
Lucas Dupin3daf3b02018-02-27 17:23:41 -0800811 if (mAnimateChange) {
Jorim Jaggif5304ad2017-07-17 18:31:13 +0200812 // We are not done yet! Defer calling the finished listener.
Lucas Dupin3daf3b02018-02-27 17:23:41 -0800813 mDeferFinishedListener = true;
Selim Cinekaac93252015-04-14 20:04:12 -0700814 }
Lucas Dupin3daf3b02018-02-27 17:23:41 -0800815 // Previous animators should always be cancelled. Not doing so would cause
816 // overlap, especially on states that don't animate, leading to flickering,
817 // and in the worst case, an internal state that doesn't represent what
818 // transitionTo requested.
819 cancelAnimator(previousAnimator);
820 mDeferFinishedListener = false;
Selim Cinekaac93252015-04-14 20:04:12 -0700821 }
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800822
Lucas Dupin8c7cb022018-02-05 10:49:03 -0800823 if (mPendingFrameCallback != null) {
824 // Display is off and we're waiting.
825 return;
826 } else if (mBlankScreen) {
827 // Need to blank the display before continuing.
828 blankDisplay();
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800829 return;
830 } else if (!mScreenBlankingCallbackCalled) {
831 // Not blanking the screen. Letting the callback know that we're ready
832 // to replace what was on the screen before.
833 if (mCallback != null) {
834 mCallback.onDisplayBlanked();
835 mScreenBlankingCallbackCalled = true;
836 }
837 }
838
Lucas Dupin6afae372017-11-30 13:09:22 -0500839 if (scrim == mScrimBehind) {
Yohei Yukawa795f0102018-04-13 14:55:30 -0700840 dispatchScrimState(alpha);
Lucas Dupin6afae372017-11-30 13:09:22 -0500841 }
842
Lucas Dupin3daf3b02018-02-27 17:23:41 -0800843 final boolean wantsAlphaUpdate = alpha != currentAlpha;
Lucas Dupin3503c5f2018-03-02 19:04:00 -0800844 final boolean wantsTintUpdate = scrim.getTint() != getCurrentScrimTint(scrim);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800845
846 if (wantsAlphaUpdate || wantsTintUpdate) {
Lucas Dupin3daf3b02018-02-27 17:23:41 -0800847 if (mAnimateChange) {
848 startScrimAnimation(scrim, currentAlpha);
Selim Cinekaac93252015-04-14 20:04:12 -0700849 } else {
Lucas Dupin3daf3b02018-02-27 17:23:41 -0800850 // update the alpha directly
851 updateScrimColor(scrim, alpha, getCurrentScrimTint(scrim));
852 onFinished();
Selim Cinekaac93252015-04-14 20:04:12 -0700853 }
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800854 } else {
855 onFinished();
Selim Cinekaac93252015-04-14 20:04:12 -0700856 }
857 }
858
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800859 @VisibleForTesting
860 protected void cancelAnimator(ValueAnimator previousAnimator) {
861 if (previousAnimator != null) {
862 previousAnimator.cancel();
863 }
864 }
865
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800866 private void blankDisplay() {
Lucas Dupin8c7cb022018-02-05 10:49:03 -0800867 updateScrimColor(mScrimInFront, 1, Color.BLACK);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800868
Lucas Dupin8c7cb022018-02-05 10:49:03 -0800869 // Notify callback that the screen is completely black and we're
870 // ready to change the display power mode
Lucas Dupin0791d972018-03-26 13:32:16 -0700871 mPendingFrameCallback = () -> {
Lucas Dupin8c7cb022018-02-05 10:49:03 -0800872 if (mCallback != null) {
873 mCallback.onDisplayBlanked();
874 mScreenBlankingCallbackCalled = true;
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800875 }
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800876
Lucas Dupin53cf12a2018-02-05 16:14:45 -0800877 mBlankingTransitionRunnable = () -> {
878 mBlankingTransitionRunnable = null;
Lucas Dupin8c7cb022018-02-05 10:49:03 -0800879 mPendingFrameCallback = null;
880 mBlankScreen = false;
881 // Try again.
882 updateScrims();
883 };
884
885 // Setting power states can happen after we push out the frame. Make sure we
886 // stay fully opaque until the power state request reaches the lower levels.
Lucas Dupin0791d972018-03-26 13:32:16 -0700887 final int delay = mScreenOn ? 32 : 500;
Lucas Dupin53cf12a2018-02-05 16:14:45 -0800888 if (DEBUG) {
Lucas Dupin3a64ed72018-02-12 12:44:37 -0800889 Log.d(TAG, "Fading out scrims with delay: " + delay);
Lucas Dupin53cf12a2018-02-05 16:14:45 -0800890 }
Lucas Dupin54fbfb32019-03-05 18:08:13 -0800891 mHandler.postDelayed(mBlankingTransitionRunnable, delay);
Lucas Dupin8c7cb022018-02-05 10:49:03 -0800892 };
893 doOnTheNextFrame(mPendingFrameCallback);
894 }
895
Lucas Dupin0791d972018-03-26 13:32:16 -0700896 /**
897 * Executes a callback after the frame has hit the display.
Lyn Hanbde48202019-05-29 19:18:29 -0700898 *
Lucas Dupin0791d972018-03-26 13:32:16 -0700899 * @param callback What to run.
900 */
Lucas Dupin8c7cb022018-02-05 10:49:03 -0800901 @VisibleForTesting
Lucas Dupin0791d972018-03-26 13:32:16 -0700902 protected void doOnTheNextFrame(Runnable callback) {
903 // Just calling View#postOnAnimation isn't enough because the frame might not have reached
904 // the display yet. A timeout is the safest solution.
905 mScrimBehind.postOnAnimationDelayed(callback, 32 /* delayMillis */);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800906 }
907
908 @VisibleForTesting
909 protected Handler getHandler() {
Lucas Dupin54fbfb32019-03-05 18:08:13 -0800910 return new Handler();
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800911 }
912
Lucas Dupin8da8f2e92017-04-21 14:02:16 -0700913 public int getBackgroundColor() {
Lucas Dupin2bd3af62019-03-25 17:44:28 -0700914 int color = mColors.getMainColor();
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800915 return Color.argb((int) (mScrimBehind.getViewAlpha() * Color.alpha(color)),
Lucas Dupin8da8f2e92017-04-21 14:02:16 -0700916 Color.red(color), Color.green(color), Color.blue(color));
Selim Cinekd35c2792016-01-21 13:20:57 -0800917 }
918
919 public void setScrimBehindChangeRunnable(Runnable changeRunnable) {
920 mScrimBehind.setChangeRunnable(changeRunnable);
921 }
Selim Cineke803491c2016-04-09 21:24:45 -0700922
Jorim Jaggie31f6b82016-07-01 16:15:09 -0700923 public void setCurrentUser(int currentUser) {
924 // Don't care in the base class.
925 }
Lucas Dupin8da8f2e92017-04-21 14:02:16 -0700926
927 @Override
Lucas Dupin7aaa3532017-05-28 08:51:07 -0700928 public void onColorsChanged(ColorExtractor colorExtractor, int which) {
Lucas Dupin2bd3af62019-03-25 17:44:28 -0700929 mColors = mColorExtractor.getNeutralColors();
930 mNeedsDrawableColorUpdate = true;
931 scheduleUpdate();
Lucas Dupin8da8f2e92017-04-21 14:02:16 -0700932 }
Adrian Roosba7ca592017-08-15 17:48:05 +0200933
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800934 @VisibleForTesting
935 protected WakeLock createWakeLock() {
Lucas Dupin54fbfb32019-03-05 18:08:13 -0800936 return new DelayedWakeLock(mHandler, WakeLock.createPartial(mContext, "Scrims"));
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800937 }
Adrian Roosba7ca592017-08-15 17:48:05 +0200938
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800939 @Override
940 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Lucas Dupin3fcdd472018-01-19 19:06:45 -0800941 pw.println(" ScrimController: ");
Lyn Hanbde48202019-05-29 19:18:29 -0700942 pw.print(" state: ");
943 pw.println(mState);
Adrian Roosba7ca592017-08-15 17:48:05 +0200944
Lyn Hanbde48202019-05-29 19:18:29 -0700945 pw.print(" frontScrim:");
946 pw.print(" viewAlpha=");
947 pw.print(mScrimInFront.getViewAlpha());
948 pw.print(" alpha=");
949 pw.print(mInFrontAlpha);
950 pw.print(" tint=0x");
951 pw.println(Integer.toHexString(mScrimInFront.getTint()));
Adrian Roosba7ca592017-08-15 17:48:05 +0200952
Lyn Hanbde48202019-05-29 19:18:29 -0700953 pw.print(" backScrim:");
954 pw.print(" viewAlpha=");
955 pw.print(mScrimBehind.getViewAlpha());
956 pw.print(" alpha=");
957 pw.print(mBehindAlpha);
958 pw.print(" tint=0x");
959 pw.println(Integer.toHexString(mScrimBehind.getTint()));
960
961 pw.print(" bubbleScrim:");
962 pw.print(" viewAlpha=");
963 pw.print(mScrimForBubble.getViewAlpha());
964 pw.print(" alpha=");
965 pw.print(mBubbleAlpha);
966 pw.print(" tint=0x");
967 pw.println(Integer.toHexString(mScrimForBubble.getTint()));
968
969 pw.print(" mTracking=");
970 pw.println(mTracking);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800971 }
972
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700973 public void setWallpaperSupportsAmbientMode(boolean wallpaperSupportsAmbientMode) {
Lucas Dupin82aa1632017-12-13 00:13:57 -0800974 mWallpaperSupportsAmbientMode = wallpaperSupportsAmbientMode;
975 ScrimState[] states = ScrimState.values();
976 for (int i = 0; i < states.length; i++) {
977 states[i].setWallpaperSupportsAmbientMode(wallpaperSupportsAmbientMode);
978 }
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700979 }
980
Lucas Dupin53cf12a2018-02-05 16:14:45 -0800981 /**
982 * Interrupts blanking transitions once the display notifies that it's already on.
983 */
984 public void onScreenTurnedOn() {
Lucas Dupin3a64ed72018-02-12 12:44:37 -0800985 mScreenOn = true;
Lucas Dupin54fbfb32019-03-05 18:08:13 -0800986 if (mHandler.hasCallbacks(mBlankingTransitionRunnable)) {
Lucas Dupin53cf12a2018-02-05 16:14:45 -0800987 if (DEBUG) {
988 Log.d(TAG, "Shorter blanking because screen turned on. All good.");
989 }
Lucas Dupin54fbfb32019-03-05 18:08:13 -0800990 mHandler.removeCallbacks(mBlankingTransitionRunnable);
Lucas Dupin53cf12a2018-02-05 16:14:45 -0800991 mBlankingTransitionRunnable.run();
992 }
993 }
994
Lucas Dupin3a64ed72018-02-12 12:44:37 -0800995 public void onScreenTurnedOff() {
996 mScreenOn = false;
997 }
998
Lucas Dupin67f02632018-03-12 11:08:31 -0700999 public void setExpansionAffectsAlpha(boolean expansionAffectsAlpha) {
1000 mExpansionAffectsAlpha = expansionAffectsAlpha;
1001 }
1002
Lucas Dupind5107302018-03-19 15:30:29 -07001003 public void setKeyguardOccluded(boolean keyguardOccluded) {
1004 mKeyguardOccluded = keyguardOccluded;
Lucas Dupin63d72172018-06-06 11:42:55 -07001005 updateScrims();
Lucas Dupind5107302018-03-19 15:30:29 -07001006 }
1007
Lucas Dupinf8463ee2018-06-11 16:18:15 -07001008 public void setHasBackdrop(boolean hasBackdrop) {
Lucas Dupin193677c2018-06-11 19:16:03 -07001009 for (ScrimState state : ScrimState.values()) {
1010 state.setHasBackdrop(hasBackdrop);
1011 }
Lucas Dupin9bee5822018-07-09 14:32:53 -07001012
1013 // Backdrop event may arrive after state was already applied,
1014 // in this case, back-scrim needs to be re-evaluated
1015 if (mState == ScrimState.AOD || mState == ScrimState.PULSING) {
Lucas Dupin3d36dd82019-01-02 14:38:35 -08001016 float newBehindAlpha = mState.getBehindAlpha();
Lyn Hanbde48202019-05-29 19:18:29 -07001017 if (mBehindAlpha != newBehindAlpha) {
1018 mBehindAlpha = newBehindAlpha;
Lucas Dupin9bee5822018-07-09 14:32:53 -07001019 updateScrims();
1020 }
1021 }
Lucas Dupin193677c2018-06-11 19:16:03 -07001022 }
1023
Selim Cinek72cd9a72019-08-09 17:19:57 -07001024 private void setKeyguardFadingAway(boolean fadingAway, long duration) {
Selim Cinek84b2acc2019-07-07 00:40:38 -07001025 for (ScrimState state : ScrimState.values()) {
Selim Cinek72cd9a72019-08-09 17:19:57 -07001026 state.setKeyguardFadingAway(fadingAway, duration);
Selim Cinek84b2acc2019-07-07 00:40:38 -07001027 }
1028 }
1029
Lucas Dupin193677c2018-06-11 19:16:03 -07001030 public void setLaunchingAffordanceWithPreview(boolean launchingAffordanceWithPreview) {
1031 for (ScrimState state : ScrimState.values()) {
1032 state.setLaunchingAffordanceWithPreview(launchingAffordanceWithPreview);
Lucas Dupinf8463ee2018-06-11 16:18:15 -07001033 }
1034 }
1035
Lucas Dupin9e3fa102017-11-08 17:16:55 -08001036 public interface Callback {
1037 default void onStart() {
1038 }
Lyn Hanbde48202019-05-29 19:18:29 -07001039
Lucas Dupin9e3fa102017-11-08 17:16:55 -08001040 default void onDisplayBlanked() {
1041 }
Lyn Hanbde48202019-05-29 19:18:29 -07001042
Lucas Dupin9e3fa102017-11-08 17:16:55 -08001043 default void onFinished() {
1044 }
Lyn Hanbde48202019-05-29 19:18:29 -07001045
Lucas Dupin9e3fa102017-11-08 17:16:55 -08001046 default void onCancelled() {
1047 }
Jerry Changbde4c0c2019-06-13 16:58:41 +08001048 /** Returns whether to timeout wallpaper or not. */
1049 default boolean shouldTimeoutWallpaper() {
1050 return false;
1051 }
Adrian Roosba7ca592017-08-15 17:48:05 +02001052 }
Lucas Dupin690c6f52018-07-10 15:28:57 -07001053
1054 /**
1055 * Simple keyguard callback that updates scrims when keyguard visibility changes.
1056 */
1057 private class KeyguardVisibilityCallback extends KeyguardUpdateMonitorCallback {
1058
1059 @Override
1060 public void onKeyguardVisibilityChanged(boolean showing) {
1061 mNeedsDrawableColorUpdate = true;
1062 scheduleUpdate();
1063 }
1064 }
Jorim Jaggiecc798e2014-05-26 18:14:37 +02001065}