/*
 * Copyright (C) 2014 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 java.lang.Float.isNaN;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.annotation.IntDef;
import android.app.AlarmManager;
import android.graphics.Color;
import android.os.Handler;
import android.os.Trace;
import android.util.Log;
import android.util.MathUtils;
import android.util.Pair;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;

import androidx.annotation.FloatRange;
import androidx.annotation.Nullable;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.colorextraction.ColorExtractor.GradientColors;
import com.android.internal.graphics.ColorUtils;
import com.android.internal.util.function.TriConsumer;
import com.android.keyguard.BouncerPanelExpansionCalculator;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.settingslib.Utils;
import com.android.systemui.DejankUtils;
import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.animation.ShadeInterpolation;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dock.DockManager;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.scrim.ScrimView;
import com.android.systemui.statusbar.notification.stack.ViewState;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.AlarmTimeout;
import com.android.systemui.util.wakelock.DelayedWakeLock;
import com.android.systemui.util.wakelock.WakeLock;

import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.concurrent.Executor;
import java.util.function.Consumer;

import javax.inject.Inject;

/**
 * Controls both the scrim behind the notifications and in front of the notifications (when a
 * security method gets shown).
 */
@SysUISingleton
public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dumpable {

    static final String TAG = "ScrimController";
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);

    // debug mode colors scrims with below debug colors, irrespectively of which state they're in
    public static final boolean DEBUG_MODE = false;

    public static final int DEBUG_NOTIFICATIONS_TINT = Color.RED;
    public static final int DEBUG_FRONT_TINT = Color.GREEN;
    public static final int DEBUG_BEHIND_TINT = Color.BLUE;

    /**
     * General scrim animation duration.
     */
    public static final long ANIMATION_DURATION = 220;
    /**
     * Longer duration, currently only used when going to AOD.
     */
    public static final long ANIMATION_DURATION_LONG = 1000;
    /**
     * When both scrims have 0 alpha.
     */
    public static final int TRANSPARENT = 0;
    /**
     * When scrims aren't transparent (alpha 0) but also not opaque (alpha 1.)
     */
    public static final int SEMI_TRANSPARENT = 1;
    /**
     * When at least 1 scrim is fully opaque (alpha set to 1.)
     */
    public static final int OPAQUE = 2;
    private boolean mClipsQsScrim;

    /**
     * The amount of progress we are currently in if we're transitioning to the full shade.
     * 0.0f means we're not transitioning yet, while 1 means we're all the way in the full
     * shade.
     */
    private float mTransitionToFullShadeProgress;

    /**
     * Same as {@link #mTransitionToFullShadeProgress}, but specifically for the notifications scrim
     * on the lock screen.
     *
     * On split shade lock screen we want the different scrims to fade in at different times and
     * rates.
     */
    private float mTransitionToLockScreenFullShadeNotificationsProgress;

    /**
     * If we're currently transitioning to the full shade.
     */
    private boolean mTransitioningToFullShade;

    /**
     * Is there currently an unocclusion animation running. Used to avoid bright flickers
     * of the notification scrim.
     */
    private boolean mUnOcclusionAnimationRunning;

    /**
     * The percentage of the bouncer which is hidden. If 1, the bouncer is completely hidden. If
     * 0, the bouncer is visible.
     */
    @FloatRange(from = 0, to = 1)
    private float mBouncerHiddenFraction = KeyguardBouncer.EXPANSION_HIDDEN;

    /**
     * Set whether an unocclusion animation is currently running on the notification panel. Used
     * to avoid bright flickers of the notification scrim.
     */
    public void setUnocclusionAnimationRunning(boolean unocclusionAnimationRunning) {
        mUnOcclusionAnimationRunning = unocclusionAnimationRunning;
    }

    @IntDef(prefix = {"VISIBILITY_"}, value = {
            TRANSPARENT,
            SEMI_TRANSPARENT,
            OPAQUE
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface ScrimVisibility {
    }

    /**
     * Default alpha value for most scrims.
     */
    protected static final float KEYGUARD_SCRIM_ALPHA = 0.2f;
    /**
     * Scrim opacity when the phone is about to wake-up.
     */
    public static final float WAKE_SENSOR_SCRIM_ALPHA = 0.6f;

    /**
     * The default scrim under the shade and dialogs.
     * This should not be lower than 0.54, otherwise we won't pass GAR.
     */
    public static final float BUSY_SCRIM_ALPHA = 1f;

    /**
     * Scrim opacity that can have text on top.
     */
    public static final float GAR_SCRIM_ALPHA = 0.6f;

    static final int TAG_KEY_ANIM = R.id.scrim;
    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 ScrimState mState = ScrimState.UNINITIALIZED;

    private ScrimView mScrimInFront;
    private ScrimView mNotificationsScrim;
    private ScrimView mScrimBehind;

    private Runnable mScrimBehindChangeRunnable;

    private final KeyguardStateController mKeyguardStateController;
    private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
    private final DozeParameters mDozeParameters;
    private final DockManager mDockManager;
    private final AlarmTimeout mTimeTicker;
    private final KeyguardVisibilityCallback mKeyguardVisibilityCallback;
    private final Handler mHandler;
    private final Executor mMainExecutor;
    private final ScreenOffAnimationController mScreenOffAnimationController;
    private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
    private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;

    private GradientColors mColors;
    private boolean mNeedsDrawableColorUpdate;

    private float mAdditionalScrimBehindAlphaKeyguard = 0f;
    // Combined scrim behind keyguard alpha of default scrim + additional scrim
    // (if wallpaper dimming is applied).
    private float mScrimBehindAlphaKeyguard = KEYGUARD_SCRIM_ALPHA;
    private final float mDefaultScrimAlpha;

    private float mRawPanelExpansionFraction;
    private float mPanelScrimMinFraction;
    // Calculated based on mRawPanelExpansionFraction and mPanelScrimMinFraction
    private float mPanelExpansionFraction = 1f; // Assume shade is expanded during initialization
    private float mQsExpansion;
    private boolean mQsBottomVisible;
    private boolean mAnimatingPanelExpansionOnUnlock; // don't animate scrim

    private boolean mDarkenWhileDragging;
    private boolean mExpansionAffectsAlpha = true;
    private boolean mAnimateChange;
    private boolean mUpdatePending;
    private boolean mTracking;
    private long mAnimationDuration = -1;
    private long mAnimationDelay;
    private Animator.AnimatorListener mAnimatorListener;
    private final Interpolator mInterpolator = new DecelerateInterpolator();

    private float mInFrontAlpha = NOT_INITIALIZED;
    private float mBehindAlpha = NOT_INITIALIZED;
    private float mNotificationsAlpha = NOT_INITIALIZED;

    private int mInFrontTint;
    private int mBehindTint;
    private int mNotificationsTint;

    private boolean mWallpaperVisibilityTimedOut;
    private int mScrimsVisibility;
    private final TriConsumer<ScrimState, Float, GradientColors> mScrimStateListener;
    private Consumer<Integer> mScrimVisibleListener;
    private boolean mBlankScreen;
    private boolean mScreenBlankingCallbackCalled;
    private Callback mCallback;
    private boolean mWallpaperSupportsAmbientMode;
    private boolean mScreenOn;

    // Scrim blanking callbacks
    private Runnable mPendingFrameCallback;
    private Runnable mBlankingTransitionRunnable;

    private final WakeLock mWakeLock;
    private boolean mWakeLockHeld;
    private boolean mKeyguardOccluded;

    @Inject
    public ScrimController(LightBarController lightBarController, DozeParameters dozeParameters,
            AlarmManager alarmManager, KeyguardStateController keyguardStateController,
            DelayedWakeLock.Builder delayedWakeLockBuilder, Handler handler,
            KeyguardUpdateMonitor keyguardUpdateMonitor, DockManager dockManager,
            ConfigurationController configurationController, @Main Executor mainExecutor,
            ScreenOffAnimationController screenOffAnimationController,
            KeyguardUnlockAnimationController keyguardUnlockAnimationController,
            StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
        mScrimStateListener = lightBarController::setScrimState;
        mDefaultScrimAlpha = BUSY_SCRIM_ALPHA;

        mKeyguardStateController = keyguardStateController;
        mDarkenWhileDragging = !mKeyguardStateController.canDismissLockScreen();
        mKeyguardUpdateMonitor = keyguardUpdateMonitor;
        mKeyguardVisibilityCallback = new KeyguardVisibilityCallback();
        mHandler = handler;
        mMainExecutor = mainExecutor;
        mScreenOffAnimationController = screenOffAnimationController;
        mTimeTicker = new AlarmTimeout(alarmManager, this::onHideWallpaperTimeout,
                "hide_aod_wallpaper", mHandler);
        mWakeLock = delayedWakeLockBuilder.setHandler(mHandler).setTag("Scrims").build();
        // 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.
        mDozeParameters = dozeParameters;
        mDockManager = dockManager;
        mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
        keyguardStateController.addCallback(new KeyguardStateController.Callback() {
            @Override
            public void onKeyguardFadingAwayChanged() {
                setKeyguardFadingAway(keyguardStateController.isKeyguardFadingAway(),
                        keyguardStateController.getKeyguardFadingAwayDuration());
            }
        });
        mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
        configurationController.addCallback(new ConfigurationController.ConfigurationListener() {
            @Override
            public void onThemeChanged() {
                ScrimController.this.onThemeChanged();
            }

            @Override
            public void onUiModeChanged() {
                ScrimController.this.onThemeChanged();
            }
        });
        mColors = new GradientColors();
    }

    /**
     * Attach the controller to the supplied views.
     */
    public void attachViews(ScrimView behindScrim, ScrimView notificationsScrim,
                            ScrimView scrimInFront) {
        mNotificationsScrim = notificationsScrim;
        mScrimBehind = behindScrim;
        mScrimInFront = scrimInFront;
        updateThemeColors();

        behindScrim.enableBottomEdgeConcave(mClipsQsScrim);
        mNotificationsScrim.enableRoundedCorners(true);

        if (mScrimBehindChangeRunnable != null) {
            mScrimBehind.setChangeRunnable(mScrimBehindChangeRunnable, mMainExecutor);
            mScrimBehindChangeRunnable = null;
        }

        final ScrimState[] states = ScrimState.values();
        for (int i = 0; i < states.length; i++) {
            states[i].init(mScrimInFront, mScrimBehind, mDozeParameters, mDockManager);
            states[i].setScrimBehindAlphaKeyguard(mScrimBehindAlphaKeyguard);
            states[i].setDefaultScrimAlpha(mDefaultScrimAlpha);
        }

        mScrimBehind.setDefaultFocusHighlightEnabled(false);
        mNotificationsScrim.setDefaultFocusHighlightEnabled(false);
        mScrimInFront.setDefaultFocusHighlightEnabled(false);
        updateScrims();
        mKeyguardUpdateMonitor.registerCallback(mKeyguardVisibilityCallback);
    }

    /**
     * Sets corner radius of scrims.
     */
    public void setScrimCornerRadius(int radius) {
        if (mScrimBehind == null || mNotificationsScrim == null) {
            return;
        }
        mScrimBehind.setCornerRadius(radius);
        mNotificationsScrim.setCornerRadius(radius);
    }

    void setScrimVisibleListener(Consumer<Integer> listener) {
        mScrimVisibleListener = listener;
    }

    public void transitionTo(ScrimState state) {
        transitionTo(state, null);
    }

    public void transitionTo(ScrimState state, Callback callback) {
        if (state == mState) {
            // Call the callback anyway, unless it's already enqueued
            if (callback != null && mCallback != callback) {
                callback.onFinished();
            }
            return;
        } else if (DEBUG) {
            Log.d(TAG, "State changed to: " + state);
        }

        if (state == ScrimState.UNINITIALIZED) {
            throw new IllegalArgumentException("Cannot change to UNINITIALIZED.");
        }

        final ScrimState oldState = mState;
        mState = state;
        Trace.traceCounter(Trace.TRACE_TAG_APP, "scrim_state", mState.ordinal());

        if (mCallback != null) {
            mCallback.onCancelled();
        }
        mCallback = callback;

        state.prepare(oldState);
        mScreenBlankingCallbackCalled = false;
        mAnimationDelay = 0;
        mBlankScreen = state.getBlanksScreen();
        mAnimateChange = state.getAnimateChange();
        mAnimationDuration = state.getAnimationDuration();

        applyState();

        // Scrim might acquire focus when user is navigating with a D-pad or a keyboard.
        // We need to disable focus otherwise AOD would end up with a gray overlay.
        mScrimInFront.setFocusable(!state.isLowPowerState());
        mScrimBehind.setFocusable(!state.isLowPowerState());
        mNotificationsScrim.setFocusable(!state.isLowPowerState());

        mScrimInFront.setBlendWithMainColor(state.shouldBlendWithMainColor());

        // Cancel blanking transitions that were pending before we requested a new state
        if (mPendingFrameCallback != null) {
            mScrimBehind.removeCallbacks(mPendingFrameCallback);
            mPendingFrameCallback = null;
        }
        if (mHandler.hasCallbacks(mBlankingTransitionRunnable)) {
            mHandler.removeCallbacks(mBlankingTransitionRunnable);
            mBlankingTransitionRunnable = null;
        }

        // 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;

        // The device might sleep if it's entering AOD, we need to make sure that
        // the animation plays properly until the last frame.
        // It's important to avoid holding the wakelock unless necessary because
        // WakeLock#aqcuire will trigger an IPC and will cause jank.
        if (mState.isLowPowerState()) {
            holdWakeLock();
        }

        // AOD wallpapers should fade away after a while.
        // Docking pulses may take a long time, wallpapers should also fade away after a while.
        mWallpaperVisibilityTimedOut = false;
        if (shouldFadeAwayWallpaper()) {
            DejankUtils.postAfterTraversal(() -> {
                mTimeTicker.schedule(mDozeParameters.getWallpaperAodDuration(),
                        AlarmTimeout.MODE_IGNORE_IF_SCHEDULED);
            });
        } else {
            DejankUtils.postAfterTraversal(mTimeTicker::cancel);
        }

        if (mKeyguardUpdateMonitor.needsSlowUnlockTransition() && mState == ScrimState.UNLOCKED) {
            mAnimationDelay = CentralSurfaces.FADE_KEYGUARD_START_DELAY;
            scheduleUpdate();
        } else if (((oldState == ScrimState.AOD || oldState == ScrimState.PULSING)  // leaving doze
                && (!mDozeParameters.getAlwaysOn() || mState == ScrimState.UNLOCKED))
                || (mState == ScrimState.AOD && !mDozeParameters.getDisplayNeedsBlanking())) {
            // Scheduling a frame isn't enough when:
            //  • Leaving doze and we need to modify scrim color immediately
            //  • ColorFade will not kick-in and scrim cannot wait for pre-draw.
            onPreDraw();
        } else {
            // Schedule a frame
            scheduleUpdate();
        }

        dispatchBackScrimState(mScrimBehind.getViewAlpha());
    }

    private boolean shouldFadeAwayWallpaper() {
        if (!mWallpaperSupportsAmbientMode) {
            return false;
        }

        if (mState == ScrimState.AOD
                && (mDozeParameters.getAlwaysOn() || mDockManager.isDocked())) {
            return true;
        }

        return false;
    }

    public ScrimState getState() {
        return mState;
    }

    /**
     * Sets the additional scrim behind alpha keyguard that would be blended with the default scrim
     * by applying alpha composition on both values.
     *
     * @param additionalScrimAlpha alpha value of additional scrim behind alpha keyguard.
     */
    protected void setAdditionalScrimBehindAlphaKeyguard(float additionalScrimAlpha) {
        mAdditionalScrimBehindAlphaKeyguard = additionalScrimAlpha;
    }

    /**
     * Applies alpha composition to the default scrim behind alpha keyguard and the additional
     * scrim alpha, and sets this value to the scrim behind alpha keyguard.
     * This is used to apply additional keyguard dimming on top of the default scrim alpha value.
     */
    protected void applyCompositeAlphaOnScrimBehindKeyguard() {
        int compositeAlpha = ColorUtils.compositeAlpha(
                (int) (255 * mAdditionalScrimBehindAlphaKeyguard),
                (int) (255 * KEYGUARD_SCRIM_ALPHA));
        float keyguardScrimAlpha = (float) compositeAlpha / 255;
        setScrimBehindValues(keyguardScrimAlpha);
    }

    /**
     * Sets the scrim behind alpha keyguard values. This is how much the keyguard will be dimmed.
     *
     * @param scrimBehindAlphaKeyguard alpha value of the scrim behind
     */
    private void setScrimBehindValues(float scrimBehindAlphaKeyguard) {
        mScrimBehindAlphaKeyguard = scrimBehindAlphaKeyguard;
        ScrimState[] states = ScrimState.values();
        for (int i = 0; i < states.length; i++) {
            states[i].setScrimBehindAlphaKeyguard(scrimBehindAlphaKeyguard);
        }
        scheduleUpdate();
    }

    public void onTrackingStarted() {
        mTracking = true;
        mDarkenWhileDragging = !mKeyguardStateController.canDismissLockScreen();
        if (!mKeyguardUnlockAnimationController.isPlayingCannedUnlockAnimation()) {
            mAnimatingPanelExpansionOnUnlock = false;
        }
    }

    public void onExpandingFinished() {
        mTracking = false;
        setUnocclusionAnimationRunning(false);
    }

    @VisibleForTesting
    protected void onHideWallpaperTimeout() {
        if (mState != ScrimState.AOD && mState != ScrimState.PULSING) {
            return;
        }

        holdWakeLock();
        mWallpaperVisibilityTimedOut = true;
        mAnimateChange = true;
        mAnimationDuration = mDozeParameters.getWallpaperFadeOutDuration();
        scheduleUpdate();
    }

    private void holdWakeLock() {
        if (!mWakeLockHeld) {
            if (mWakeLock != null) {
                mWakeLockHeld = true;
                mWakeLock.acquire(TAG);
            } else {
                Log.w(TAG, "Cannot hold wake lock, it has not been set yet");
            }
        }
    }

    /**
     * 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.
     *
     * See {@link ScrimShadeTransitionController#onPanelExpansionChanged}.
     *
     * @param rawPanelExpansionFraction From 0 to 1 where 0 means collapsed and 1 expanded.
     */
    public void setRawPanelExpansionFraction(
             @FloatRange(from = 0.0, to = 1.0) float rawPanelExpansionFraction) {
        if (isNaN(rawPanelExpansionFraction)) {
            throw new IllegalArgumentException("rawPanelExpansionFraction should not be NaN");
        }
        mRawPanelExpansionFraction = rawPanelExpansionFraction;
        calculateAndUpdatePanelExpansion();
    }

    /** See {@link NotificationPanelViewController#setPanelScrimMinFraction(float)}. */
    public void setPanelScrimMinFraction(float minFraction) {
        if (isNaN(minFraction)) {
            throw new IllegalArgumentException("minFraction should not be NaN");
        }
        mPanelScrimMinFraction = minFraction;
        calculateAndUpdatePanelExpansion();
    }

    private void calculateAndUpdatePanelExpansion() {
        float panelExpansionFraction = mRawPanelExpansionFraction;
        if (mPanelScrimMinFraction < 1.0f) {
            panelExpansionFraction = Math.max(
                    (mRawPanelExpansionFraction - mPanelScrimMinFraction)
                            / (1.0f - mPanelScrimMinFraction),
                    0);
        }

        if (mPanelExpansionFraction != panelExpansionFraction) {
            if (panelExpansionFraction != 0f
                    && mKeyguardUnlockAnimationController.isPlayingCannedUnlockAnimation()) {
                mAnimatingPanelExpansionOnUnlock = true;
            } else if (panelExpansionFraction == 0f) {
                mAnimatingPanelExpansionOnUnlock = false;
            }

            mPanelExpansionFraction = panelExpansionFraction;

            boolean relevantState = (mState == ScrimState.UNLOCKED
                    || mState == ScrimState.KEYGUARD
                    || mState == ScrimState.DREAMING
                    || mState == ScrimState.SHADE_LOCKED
                    || mState == ScrimState.PULSING);
            if (!(relevantState && mExpansionAffectsAlpha) || mAnimatingPanelExpansionOnUnlock) {
                return;
            }
            applyAndDispatchState();
        }
    }

    /**
     * Set the amount of progress we are currently in if we're transitioning to the full shade.
     * 0.0f means we're not transitioning yet, while 1 means we're all the way in the full
     * shade.
     *
     * @param progress the progress for all scrims.
     * @param lockScreenNotificationsProgress the progress specifically for the notifications scrim.
     */
    public void setTransitionToFullShadeProgress(float progress,
            float lockScreenNotificationsProgress) {
        if (progress != mTransitionToFullShadeProgress || lockScreenNotificationsProgress
                != mTransitionToLockScreenFullShadeNotificationsProgress) {
            mTransitionToFullShadeProgress = progress;
            mTransitionToLockScreenFullShadeNotificationsProgress = lockScreenNotificationsProgress;
            setTransitionToFullShade(progress > 0.0f || lockScreenNotificationsProgress > 0.0f);
            applyAndDispatchState();
        }
    }

    /**
     * Set if we're currently transitioning to the full shade
     */
    private void setTransitionToFullShade(boolean transitioning) {
        if (transitioning != mTransitioningToFullShade) {
            mTransitioningToFullShade = transitioning;
            if (transitioning) {
                // Let's make sure the shade locked is ready
                ScrimState.SHADE_LOCKED.prepare(mState);
            }
        }
    }


    /**
     * Set bounds for notifications background, all coordinates are absolute
     */
    public void setNotificationsBounds(float left, float top, float right, float bottom) {
        if (mClipsQsScrim) {
            // notification scrim's rounded corners are anti-aliased, but clipping of the QS/behind
            // scrim can't be and it's causing jagged corners. That's why notification scrim needs
            // to overlap QS scrim by one pixel horizontally (left - 1 and right + 1)
            // see: b/186644628
            mNotificationsScrim.setDrawableBounds(left - 1, top, right + 1, bottom);
            mScrimBehind.setBottomEdgePosition((int) top);
        } else {
            mNotificationsScrim.setDrawableBounds(left, top, right, bottom);
        }
    }

    /**
     * Sets the amount of vertical over scroll that should be performed on the notifications scrim.
     */
    public void setNotificationsOverScrollAmount(int overScrollAmount) {
        mNotificationsScrim.setTranslationY(overScrollAmount);
    }

    /**
     * Current state of the QuickSettings when pulling it from the top.
     *
     * @param expansionFraction From 0 to 1 where 0 means collapsed and 1 expanded.
     * @param qsPanelBottomY Absolute Y position of qs panel bottom
     */
    public void setQsPosition(float expansionFraction, int qsPanelBottomY) {
        if (isNaN(expansionFraction)) {
            return;
        }
        expansionFraction = ShadeInterpolation.getNotificationScrimAlpha(expansionFraction);
        boolean qsBottomVisible = qsPanelBottomY > 0;
        if (mQsExpansion != expansionFraction || mQsBottomVisible != qsBottomVisible) {
            mQsExpansion = expansionFraction;
            mQsBottomVisible = qsBottomVisible;
            boolean relevantState = (mState == ScrimState.SHADE_LOCKED
                    || mState == ScrimState.KEYGUARD
                    || mState == ScrimState.PULSING);
            if (!(relevantState && mExpansionAffectsAlpha)) {
                return;
            }
            applyAndDispatchState();
        }
    }

    /**
     * Updates the percentage of the bouncer which is hidden.
     */
    public void setBouncerHiddenFraction(@FloatRange(from = 0, to = 1) float bouncerHiddenAmount) {
        if (mBouncerHiddenFraction == bouncerHiddenAmount) {
            return;
        }
        mBouncerHiddenFraction = bouncerHiddenAmount;
        if (mState == ScrimState.DREAMING) {
            // Only the dreaming state requires this for the scrim calculation, so we should
            // only trigger an update if dreaming.
            applyAndDispatchState();
        }
    }

    /**
     * If QS and notification scrims should not overlap, and should be clipped to each other's
     * bounds instead.
     */
    public void setClipsQsScrim(boolean clipScrim) {
        if (clipScrim == mClipsQsScrim) {
            return;
        }
        mClipsQsScrim = clipScrim;
        for (ScrimState state : ScrimState.values()) {
            state.setClipQsScrim(mClipsQsScrim);
        }
        if (mScrimBehind != null) {
            mScrimBehind.enableBottomEdgeConcave(mClipsQsScrim);
        }
        if (mState != ScrimState.UNINITIALIZED) {
            // the clipScrimState has changed, let's reprepare ourselves
            mState.prepare(mState);
            applyAndDispatchState();
        }
    }

    @VisibleForTesting
    public boolean getClipQsScrim() {
        return mClipsQsScrim;
    }

    private void setOrAdaptCurrentAnimation(@Nullable View scrim) {
        if (scrim == null) {
            return;
        }

        float alpha = getCurrentScrimAlpha(scrim);
        boolean qsScrimPullingDown = scrim == mScrimBehind && mQsBottomVisible;
        if (isAnimating(scrim) && !qsScrimPullingDown) {
            // Adapt current animation.
            ValueAnimator previousAnimator = (ValueAnimator) scrim.getTag(TAG_KEY_ANIM);
            float previousEndValue = (Float) scrim.getTag(TAG_END_ALPHA);
            float previousStartValue = (Float) scrim.getTag(TAG_START_ALPHA);
            float relativeDiff = alpha - previousEndValue;
            float newStartValue = previousStartValue + relativeDiff;
            scrim.setTag(TAG_START_ALPHA, newStartValue);
            scrim.setTag(TAG_END_ALPHA, alpha);
            previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime());
        } else {
            // Set animation.
            updateScrimColor(scrim, alpha, getCurrentScrimTint(scrim));
        }
    }

    private void applyState() {
        mInFrontTint = mState.getFrontTint();
        mBehindTint = mState.getBehindTint();
        mNotificationsTint = mState.getNotifTint();

        mInFrontAlpha = mState.getFrontAlpha();
        mBehindAlpha = mState.getBehindAlpha();
        mNotificationsAlpha = mState.getNotifAlpha();

        assertAlphasValid();

        if (!mExpansionAffectsAlpha) {
            return;
        }

        if (mState == ScrimState.UNLOCKED || mState == ScrimState.DREAMING) {
            // Darken scrim as you pull down the shade when unlocked, unless the shade is expanding
            // because we're doing the screen off animation OR the shade is collapsing because
            // we're playing the unlock animation
            if (!mScreenOffAnimationController.shouldExpandNotifications()
                    && !mAnimatingPanelExpansionOnUnlock) {
                float behindFraction = getInterpolatedFraction();
                behindFraction = (float) Math.pow(behindFraction, 0.8f);
                if (mClipsQsScrim) {
                    mBehindAlpha = 1;
                    mNotificationsAlpha = behindFraction * mDefaultScrimAlpha;
                } else {
                    mBehindAlpha = behindFraction * mDefaultScrimAlpha;
                    // Delay fade-in of notification scrim a bit further, to coincide with the
                    // view fade in. Otherwise the empty panel can be quite jarring.
                    mNotificationsAlpha = MathUtils.constrainedMap(0f, 1f, 0.3f, 0.75f,
                            mPanelExpansionFraction);
                }
                mBehindTint = mState.getBehindTint();
                mInFrontAlpha = 0;
            }

            if (mBouncerHiddenFraction != KeyguardBouncer.EXPANSION_HIDDEN) {
                final float interpolatedFraction =
                        BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(
                                mBouncerHiddenFraction);
                mBehindAlpha = MathUtils.lerp(mDefaultScrimAlpha, mBehindAlpha,
                        interpolatedFraction);
                mBehindTint = ColorUtils.blendARGB(ScrimState.BOUNCER.getBehindTint(),
                        mBehindTint,
                        interpolatedFraction);
            }
        } else if (mState == ScrimState.AUTH_SCRIMMED_SHADE) {
            float behindFraction = getInterpolatedFraction();
            behindFraction = (float) Math.pow(behindFraction, 0.8f);

            mBehindAlpha = behindFraction * mDefaultScrimAlpha;
            mNotificationsAlpha = mBehindAlpha;
            if (mClipsQsScrim) {
                mBehindAlpha = 1;
                mBehindTint = Color.BLACK;
            }
        } else if (mState == ScrimState.KEYGUARD || mState == ScrimState.SHADE_LOCKED
                || mState == ScrimState.PULSING) {
            Pair<Integer, Float> result = calculateBackStateForState(mState);
            int behindTint = result.first;
            float behindAlpha = result.second;
            if (mTransitionToFullShadeProgress > 0.0f) {
                Pair<Integer, Float> shadeResult = calculateBackStateForState(
                        ScrimState.SHADE_LOCKED);
                behindAlpha = MathUtils.lerp(behindAlpha, shadeResult.second,
                        mTransitionToFullShadeProgress);
                behindTint = ColorUtils.blendARGB(behindTint, shadeResult.first,
                        mTransitionToFullShadeProgress);
            }
            mInFrontAlpha = mState.getFrontAlpha();
            if (mClipsQsScrim) {
                mNotificationsAlpha = behindAlpha;
                mNotificationsTint = behindTint;
                mBehindAlpha = 1;
                mBehindTint = Color.BLACK;
            } else {
                mBehindAlpha = behindAlpha;
                if (mState == ScrimState.SHADE_LOCKED) {
                    // going from KEYGUARD to SHADE_LOCKED state
                    mNotificationsAlpha = getInterpolatedFraction();
                } else {
                    mNotificationsAlpha = Math.max(1.0f - getInterpolatedFraction(), mQsExpansion);
                }
                if (mState == ScrimState.KEYGUARD
                        && mTransitionToLockScreenFullShadeNotificationsProgress > 0.0f) {
                    // Interpolate the notification alpha when transitioning!
                    mNotificationsAlpha = MathUtils.lerp(
                            mNotificationsAlpha,
                            getInterpolatedFraction(),
                            mTransitionToLockScreenFullShadeNotificationsProgress);
                }
                mNotificationsTint = mState.getNotifTint();
                mBehindTint = behindTint;
            }

            // At the end of a launch animation over the lockscreen, the state is either KEYGUARD or
            // SHADE_LOCKED and this code is called. We have to set the notification alpha to 0
            // otherwise there is a flicker to its previous value.
            boolean hideNotificationScrim = (mState == ScrimState.KEYGUARD
                    && mTransitionToFullShadeProgress == 0
                    && mQsExpansion == 0
                    && !mClipsQsScrim);
            if (mKeyguardOccluded || hideNotificationScrim) {
                mNotificationsAlpha = 0;
            }
            if (mUnOcclusionAnimationRunning && mState == ScrimState.KEYGUARD) {
                // We're unoccluding the keyguard and don't want to have a bright flash.
                mNotificationsAlpha = ScrimState.KEYGUARD.getNotifAlpha();
                mNotificationsTint = ScrimState.KEYGUARD.getNotifTint();
                mBehindAlpha = ScrimState.KEYGUARD.getBehindAlpha();
                mBehindTint = ScrimState.KEYGUARD.getBehindTint();
            }
        }
        if (mState != ScrimState.UNLOCKED) {
            mAnimatingPanelExpansionOnUnlock = false;
        }

        assertAlphasValid();
    }

    private void assertAlphasValid() {
        if (isNaN(mBehindAlpha) || isNaN(mInFrontAlpha) || isNaN(mNotificationsAlpha)) {
            throw new IllegalStateException("Scrim opacity is NaN for state: " + mState
                    + ", front: " + mInFrontAlpha + ", back: " + mBehindAlpha + ", notif: "
                    + mNotificationsAlpha);
        }
    }

    private Pair<Integer, Float> calculateBackStateForState(ScrimState state) {
        // Either darken of make the scrim transparent when you
        // pull down the shade
        float interpolatedFract = getInterpolatedFraction();

        float stateBehind = mClipsQsScrim ? state.getNotifAlpha() : state.getBehindAlpha();
        float behindAlpha;
        int behindTint;
        if (mDarkenWhileDragging) {
            behindAlpha = MathUtils.lerp(mDefaultScrimAlpha, stateBehind,
                    interpolatedFract);
        } else {
            behindAlpha = MathUtils.lerp(0 /* start */, stateBehind,
                    interpolatedFract);
        }
        if (mClipsQsScrim) {
            behindTint = ColorUtils.blendARGB(ScrimState.BOUNCER.getNotifTint(),
                    state.getNotifTint(), interpolatedFract);
        } else {
            behindTint = ColorUtils.blendARGB(ScrimState.BOUNCER.getBehindTint(),
                    state.getBehindTint(), interpolatedFract);
        }
        if (mQsExpansion > 0) {
            behindAlpha = MathUtils.lerp(behindAlpha, mDefaultScrimAlpha, mQsExpansion);
            float tintProgress = mQsExpansion;
            if (mStatusBarKeyguardViewManager.isBouncerInTransit()) {
                // this is case of - on lockscreen - going from expanded QS to bouncer.
                // Because mQsExpansion is already interpolated and transition between tints
                // is too slow, we want to speed it up and make it more aligned to bouncer
                // showing up progress. This issue is visible on large screens, both portrait and
                // split shade because then transition is between very different tints
                tintProgress = BouncerPanelExpansionCalculator
                        .showBouncerProgress(mPanelExpansionFraction);
            }
            int stateTint = mClipsQsScrim ? ScrimState.SHADE_LOCKED.getNotifTint()
                    : ScrimState.SHADE_LOCKED.getBehindTint();
            behindTint = ColorUtils.blendARGB(behindTint, stateTint, tintProgress);
        }

        // If the keyguard is going away, we should not be opaque.
        if (mKeyguardStateController.isKeyguardGoingAway()) {
            behindAlpha = 0f;
        }

        return new Pair<>(behindTint, behindAlpha);
    }


    private void applyAndDispatchState() {
        applyState();
        if (mUpdatePending) {
            return;
        }
        setOrAdaptCurrentAnimation(mScrimBehind);
        setOrAdaptCurrentAnimation(mNotificationsScrim);
        setOrAdaptCurrentAnimation(mScrimInFront);
        dispatchBackScrimState(mScrimBehind.getViewAlpha());

        // Reset wallpaper timeout if it's already timeout like expanding panel while PULSING
        // and docking.
        if (mWallpaperVisibilityTimedOut) {
            mWallpaperVisibilityTimedOut = false;
            DejankUtils.postAfterTraversal(() -> {
                mTimeTicker.schedule(mDozeParameters.getWallpaperAodDuration(),
                        AlarmTimeout.MODE_IGNORE_IF_SCHEDULED);
            });
        }
    }

    /**
     * Sets the front scrim opacity in AOD so it's not as bright.
     * <p>
     * Displays usually don't support multiple dimming settings when in low power mode.
     * The workaround is to modify the front scrim opacity when in AOD, so it's not as
     * bright when you're at the movies or lying down on bed.
     * <p>
     * This value will be lost during transitions and only updated again after the the
     * device is dozing when the light sensor is on.
     */
    public void setAodFrontScrimAlpha(float alpha) {
        if (mInFrontAlpha != alpha && shouldUpdateFrontScrimAlpha()) {
            mInFrontAlpha = alpha;
            updateScrims();
        }

        mState.AOD.setAodFrontScrimAlpha(alpha);
        mState.PULSING.setAodFrontScrimAlpha(alpha);
    }

    private boolean shouldUpdateFrontScrimAlpha() {
        if (mState == ScrimState.AOD
                && (mDozeParameters.getAlwaysOn() || mDockManager.isDocked())) {
            return true;
        }

        if (mState == ScrimState.PULSING) {
            return true;
        }

        return false;
    }

    /**
     * If the lock screen sensor is active.
     */
    public void setWakeLockScreenSensorActive(boolean active) {
        for (ScrimState state : ScrimState.values()) {
            state.setWakeLockScreenSensorActive(active);
        }

        if (mState == ScrimState.PULSING) {
            float newBehindAlpha = mState.getBehindAlpha();
            if (mBehindAlpha != newBehindAlpha) {
                mBehindAlpha = newBehindAlpha;
                if (isNaN(mBehindAlpha)) {
                    throw new IllegalStateException("Scrim opacity is NaN for state: " + mState
                            + ", back: " + mBehindAlpha);
                }
                updateScrims();
            }
        }
    }

    protected void scheduleUpdate() {
        if (mUpdatePending || mScrimBehind == null) return;

        // Make sure that a frame gets scheduled.
        mScrimBehind.invalidate();
        mScrimBehind.getViewTreeObserver().addOnPreDrawListener(this);
        mUpdatePending = true;
    }

    protected void updateScrims() {
        // Make sure we have the right gradients and their opacities will satisfy GAR.
        if (mNeedsDrawableColorUpdate) {
            mNeedsDrawableColorUpdate = false;
            // Only animate scrim color if the scrim view is actually visible
            boolean animateScrimInFront = mScrimInFront.getViewAlpha() != 0 && !mBlankScreen;
            boolean animateBehindScrim = mScrimBehind.getViewAlpha() != 0 && !mBlankScreen;
            boolean animateScrimNotifications = mNotificationsScrim.getViewAlpha() != 0
                    && !mBlankScreen;

            mScrimInFront.setColors(mColors, animateScrimInFront);
            mScrimBehind.setColors(mColors, animateBehindScrim);
            mNotificationsScrim.setColors(mColors, animateScrimNotifications);

            dispatchBackScrimState(mScrimBehind.getViewAlpha());
        }

        // We want to override the back scrim opacity for the AOD state
        // when it's time to fade the wallpaper away.
        boolean aodWallpaperTimeout = (mState == ScrimState.AOD || mState == ScrimState.PULSING)
                && mWallpaperVisibilityTimedOut;
        // We also want to hide FLAG_SHOW_WHEN_LOCKED activities under the scrim.
        boolean hideFlagShowWhenLockedActivities =
                (mState == ScrimState.PULSING || mState == ScrimState.AOD)
                && mKeyguardOccluded;
        if (aodWallpaperTimeout || hideFlagShowWhenLockedActivities) {
            mBehindAlpha = 1;
        }
        // Prevent notification scrim flicker when transitioning away from keyguard.
        if (mKeyguardStateController.isKeyguardGoingAway()) {
            mNotificationsAlpha = 0;
        }

        // Prevent flickering for activities above keyguard and quick settings in keyguard.
        if (mKeyguardOccluded
                && (mState == ScrimState.KEYGUARD || mState == ScrimState.SHADE_LOCKED)) {
            mBehindAlpha = 0;
            mNotificationsAlpha = 0;
        }

        setScrimAlpha(mScrimInFront, mInFrontAlpha);
        setScrimAlpha(mScrimBehind, mBehindAlpha);
        setScrimAlpha(mNotificationsScrim, mNotificationsAlpha);

        // The animation could have all already finished, let's call onFinished just in case
        onFinished(mState);
        dispatchScrimsVisible();
    }

    private void dispatchBackScrimState(float alpha) {
        // When clipping QS, the notification scrim is the one that feels behind.
        // mScrimBehind will be drawing black and its opacity will always be 1.
        if (mClipsQsScrim && mQsBottomVisible) {
            alpha = mNotificationsAlpha;
        }
        mScrimStateListener.accept(mState, alpha, mScrimInFront.getColors());
    }

    private void dispatchScrimsVisible() {
        final ScrimView backScrim = mClipsQsScrim ? mNotificationsScrim : mScrimBehind;
        final int currentScrimVisibility;
        if (mScrimInFront.getViewAlpha() == 1 || backScrim.getViewAlpha() == 1) {
            currentScrimVisibility = OPAQUE;
        } else if (mScrimInFront.getViewAlpha() == 0 && backScrim.getViewAlpha() == 0) {
            currentScrimVisibility = TRANSPARENT;
        } else {
            currentScrimVisibility = SEMI_TRANSPARENT;
        }

        if (mScrimsVisibility != currentScrimVisibility) {
            mScrimsVisibility = currentScrimVisibility;
            mScrimVisibleListener.accept(currentScrimVisibility);
        }
    }

    private float getInterpolatedFraction() {
        if (mStatusBarKeyguardViewManager.isBouncerInTransit()) {
            return BouncerPanelExpansionCalculator
                    .aboutToShowBouncerProgress(mPanelExpansionFraction);
        }
        return ShadeInterpolation.getNotificationScrimAlpha(mPanelExpansionFraction);
    }

    private void setScrimAlpha(ScrimView scrim, float alpha) {
        if (alpha == 0f) {
            scrim.setClickable(false);
        } else {
            // Eat touch events (unless dozing).
            scrim.setClickable(mState != ScrimState.AOD);
        }
        updateScrim(scrim, alpha);
    }

    private String getScrimName(ScrimView scrim) {
        if (scrim == mScrimInFront) {
            return "front_scrim";
        } else if (scrim == mScrimBehind) {
            return "behind_scrim";
        } else if (scrim == mNotificationsScrim) {
            return "notifications_scrim";
        }
        return "unknown_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;
            if (DEBUG_MODE) {
                tint = getDebugScrimTint(scrimView);
            }

            Trace.traceCounter(Trace.TRACE_TAG_APP, getScrimName(scrimView) + "_alpha",
                    (int) (alpha * 255));

            Trace.traceCounter(Trace.TRACE_TAG_APP, getScrimName(scrimView) + "_tint",
                    Color.alpha(tint));
            scrimView.setTint(tint);
            scrimView.setViewAlpha(alpha);
        } else {
            scrim.setAlpha(alpha);
        }
        dispatchScrimsVisible();
    }

    private int getDebugScrimTint(ScrimView scrim) {
        if (scrim == mScrimBehind) return DEBUG_BEHIND_TINT;
        if (scrim == mScrimInFront) return DEBUG_FRONT_TINT;
        if (scrim == mNotificationsScrim) return DEBUG_NOTIFICATIONS_TINT;
        throw new RuntimeException("scrim can't be matched with known scrims");
    }

    private void startScrimAnimation(final View scrim, float current) {
        ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
        if (mAnimatorListener != null) {
            anim.addListener(mAnimatorListener);
        }
        final int initialScrimTint = scrim instanceof ScrimView ? ((ScrimView) scrim).getTint() :
                Color.TRANSPARENT;
        anim.addUpdateListener(animation -> {
            final float startAlpha = (Float) scrim.getTag(TAG_START_ALPHA);
            final float animAmount = (float) animation.getAnimatedValue();
            final int finalScrimTint = getCurrentScrimTint(scrim);
            final float finalScrimAlpha = getCurrentScrimAlpha(scrim);
            float alpha = MathUtils.lerp(startAlpha, finalScrimAlpha, animAmount);
            alpha = MathUtils.constrain(alpha, 0f, 1f);
            int tint = ColorUtils.blendARGB(initialScrimTint, finalScrimTint, animAmount);
            updateScrimColor(scrim, alpha, tint);
            dispatchScrimsVisible();
        });
        anim.setInterpolator(mInterpolator);
        anim.setStartDelay(mAnimationDelay);
        anim.setDuration(mAnimationDuration);
        anim.addListener(new AnimatorListenerAdapter() {
            private final ScrimState mLastState = mState;
            private final Callback mLastCallback = mCallback;

            @Override
            public void onAnimationEnd(Animator animation) {
                scrim.setTag(TAG_KEY_ANIM, null);
                onFinished(mLastCallback, mLastState);

                dispatchScrimsVisible();
            }
        });

        // Cache alpha values because we might want to update this animator in the future if
        // the user expands the panel while the animation is still running.
        scrim.setTag(TAG_START_ALPHA, current);
        scrim.setTag(TAG_END_ALPHA, getCurrentScrimAlpha(scrim));

        scrim.setTag(TAG_KEY_ANIM, anim);
        anim.start();
    }

    private float getCurrentScrimAlpha(View scrim) {
        if (scrim == mScrimInFront) {
            return mInFrontAlpha;
        } else if (scrim == mScrimBehind) {
            return mBehindAlpha;
        } else if (scrim == mNotificationsScrim) {
            return mNotificationsAlpha;
        } else {
            throw new IllegalArgumentException("Unknown scrim view");
        }
    }

    private int getCurrentScrimTint(View scrim) {
        if (scrim == mScrimInFront) {
            return mInFrontTint;
        } else if (scrim == mScrimBehind) {
            return mBehindTint;
        } else if (scrim == mNotificationsScrim) {
            return mNotificationsTint;
        } else {
            throw new IllegalArgumentException("Unknown scrim view");
        }
    }

    @Override
    public boolean onPreDraw() {
        mScrimBehind.getViewTreeObserver().removeOnPreDrawListener(this);
        mUpdatePending = false;
        if (mCallback != null) {
            mCallback.onStart();
        }
        updateScrims();
        return true;
    }

    /**
     * @param state that finished
     */
    private void onFinished(ScrimState state) {
        onFinished(mCallback, state);
    }

    private void onFinished(Callback callback, ScrimState state) {
        if (mPendingFrameCallback != null) {
            // No animations can finish while we're waiting on the blanking to finish
            return;

        }
        if (isAnimating(mScrimBehind)
                || isAnimating(mNotificationsScrim)
                || isAnimating(mScrimInFront)) {
            if (callback != null && callback != mCallback) {
                // Since we only notify the callback that we're finished once everything has
                // finished, we need to make sure that any changing callbacks are also invoked
                callback.onFinished();
            }
            return;
        }
        if (mWakeLockHeld) {
            mWakeLock.release(TAG);
            mWakeLockHeld = false;
        }

        if (callback != null) {
            callback.onFinished();

            if (callback == mCallback) {
                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 (state == ScrimState.UNLOCKED) {
            mInFrontTint = Color.TRANSPARENT;
            mBehindTint = mState.getBehindTint();
            mNotificationsTint = mState.getNotifTint();
            updateScrimColor(mScrimInFront, mInFrontAlpha, mInFrontTint);
            updateScrimColor(mScrimBehind, mBehindAlpha, mBehindTint);
            updateScrimColor(mNotificationsScrim, mNotificationsAlpha, mNotificationsTint);
        }
    }

    private boolean isAnimating(@Nullable View scrim) {
        return scrim != null && scrim.getTag(TAG_KEY_ANIM) != null;
    }

    @VisibleForTesting
    void setAnimatorListener(Animator.AnimatorListener animatorListener) {
        mAnimatorListener = animatorListener;
    }

    private void updateScrim(ScrimView scrim, float alpha) {
        final float currentAlpha = scrim.getViewAlpha();

        ValueAnimator previousAnimator = ViewState.getChildTag(scrim, TAG_KEY_ANIM);
        if (previousAnimator != null) {
            // Previous animators should always be cancelled. Not doing so would cause
            // overlap, especially on states that don't animate, leading to flickering,
            // and in the worst case, an internal state that doesn't represent what
            // transitionTo requested.
            cancelAnimator(previousAnimator);
        }

        if (mPendingFrameCallback != null) {
            // Display is off and we're waiting.
            return;
        } else if (mBlankScreen) {
            // Need to blank the display before continuing.
            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;
            }
        }

        if (scrim == mScrimBehind) {
            dispatchBackScrimState(alpha);
        }

        final boolean wantsAlphaUpdate = alpha != currentAlpha;
        final boolean wantsTintUpdate = scrim.getTint() != getCurrentScrimTint(scrim);

        if (wantsAlphaUpdate || wantsTintUpdate) {
            if (mAnimateChange) {
                startScrimAnimation(scrim, currentAlpha);
            } else {
                // update the alpha directly
                updateScrimColor(scrim, alpha, getCurrentScrimTint(scrim));
            }
        }
    }

    private void cancelAnimator(ValueAnimator previousAnimator) {
        if (previousAnimator != null) {
            previousAnimator.cancel();
        }
    }

    private void blankDisplay() {
        updateScrimColor(mScrimInFront, 1, Color.BLACK);

        // Notify callback that the screen is completely black and we're
        // ready to change the display power mode
        mPendingFrameCallback = () -> {
            if (mCallback != null) {
                mCallback.onDisplayBlanked();
                mScreenBlankingCallbackCalled = true;
            }

            mBlankingTransitionRunnable = () -> {
                mBlankingTransitionRunnable = null;
                mPendingFrameCallback = 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.
            final int delay = mScreenOn ? 32 : 500;
            if (DEBUG) {
                Log.d(TAG, "Fading out scrims with delay: " + delay);
            }
            mHandler.postDelayed(mBlankingTransitionRunnable, delay);
        };
        doOnTheNextFrame(mPendingFrameCallback);
    }

    /**
     * Executes a callback after the frame has hit the display.
     *
     * @param callback What to run.
     */
    @VisibleForTesting
    protected void doOnTheNextFrame(Runnable callback) {
        // Just calling View#postOnAnimation isn't enough because the frame might not have reached
        // the display yet. A timeout is the safest solution.
        mScrimBehind.postOnAnimationDelayed(callback, 32 /* delayMillis */);
    }

    public void setScrimBehindChangeRunnable(Runnable changeRunnable) {
        // TODO: remove this. This is necessary because of an order-of-operations limitation.
        // The fix is to move more of these class into @CentralSurfacesScope
        if (mScrimBehind == null) {
            mScrimBehindChangeRunnable = changeRunnable;
        } else {
            mScrimBehind.setChangeRunnable(changeRunnable, mMainExecutor);
        }
    }

    public void setCurrentUser(int currentUser) {
        // Don't care in the base class.
    }

    private void updateThemeColors() {
        if (mScrimBehind == null) return;
        int background = Utils.getColorAttr(mScrimBehind.getContext(),
                android.R.attr.colorBackgroundFloating).getDefaultColor();
        int accent = Utils.getColorAccent(mScrimBehind.getContext()).getDefaultColor();
        mColors.setMainColor(background);
        mColors.setSecondaryColor(accent);
        mColors.setSupportsDarkText(
                ColorUtils.calculateContrast(mColors.getMainColor(), Color.WHITE) > 4.5);
        mNeedsDrawableColorUpdate = true;
    }

    private void onThemeChanged() {
        updateThemeColors();
        scheduleUpdate();
    }

    @Override
    public void dump(PrintWriter pw, String[] args) {
        pw.println(" ScrimController: ");
        pw.print("  state: ");
        pw.println(mState);
        pw.println("    mClipQsScrim = " + mState.mClipQsScrim);

        pw.print("  frontScrim:");
        pw.print(" viewAlpha=");
        pw.print(mScrimInFront.getViewAlpha());
        pw.print(" alpha=");
        pw.print(mInFrontAlpha);
        pw.print(" tint=0x");
        pw.println(Integer.toHexString(mScrimInFront.getTint()));

        pw.print("  behindScrim:");
        pw.print(" viewAlpha=");
        pw.print(mScrimBehind.getViewAlpha());
        pw.print(" alpha=");
        pw.print(mBehindAlpha);
        pw.print(" tint=0x");
        pw.println(Integer.toHexString(mScrimBehind.getTint()));

        pw.print("  notificationsScrim:");
        pw.print(" viewAlpha=");
        pw.print(mNotificationsScrim.getViewAlpha());
        pw.print(" alpha=");
        pw.print(mNotificationsAlpha);
        pw.print(" tint=0x");
        pw.println(Integer.toHexString(mNotificationsScrim.getTint()));

        pw.print("  mTracking=");
        pw.println(mTracking);
        pw.print("  mDefaultScrimAlpha=");
        pw.println(mDefaultScrimAlpha);
        pw.print("  mPanelExpansionFraction=");
        pw.println(mPanelExpansionFraction);
        pw.print("  mExpansionAffectsAlpha=");
        pw.println(mExpansionAffectsAlpha);

        pw.print("  mState.getMaxLightRevealScrimAlpha=");
        pw.println(mState.getMaxLightRevealScrimAlpha());
    }

    public void setWallpaperSupportsAmbientMode(boolean wallpaperSupportsAmbientMode) {
        mWallpaperSupportsAmbientMode = wallpaperSupportsAmbientMode;
        ScrimState[] states = ScrimState.values();
        for (int i = 0; i < states.length; i++) {
            states[i].setWallpaperSupportsAmbientMode(wallpaperSupportsAmbientMode);
        }
    }

    /**
     * Interrupts blanking transitions once the display notifies that it's already on.
     */
    public void onScreenTurnedOn() {
        mScreenOn = true;
        if (mHandler.hasCallbacks(mBlankingTransitionRunnable)) {
            if (DEBUG) {
                Log.d(TAG, "Shorter blanking because screen turned on. All good.");
            }
            mHandler.removeCallbacks(mBlankingTransitionRunnable);
            mBlankingTransitionRunnable.run();
        }
    }

    public void onScreenTurnedOff() {
        mScreenOn = false;
    }

    public void setExpansionAffectsAlpha(boolean expansionAffectsAlpha) {
        mExpansionAffectsAlpha = expansionAffectsAlpha;
    }

    public void setKeyguardOccluded(boolean keyguardOccluded) {
        mKeyguardOccluded = keyguardOccluded;
        updateScrims();
    }

    public void setHasBackdrop(boolean hasBackdrop) {
        for (ScrimState state : ScrimState.values()) {
            state.setHasBackdrop(hasBackdrop);
        }

        // Backdrop event may arrive after state was already applied,
        // in this case, back-scrim needs to be re-evaluated
        if (mState == ScrimState.AOD || mState == ScrimState.PULSING) {
            float newBehindAlpha = mState.getBehindAlpha();
            if (isNaN(newBehindAlpha)) {
                throw new IllegalStateException("Scrim opacity is NaN for state: " + mState
                        + ", back: " + mBehindAlpha);
            }
            if (mBehindAlpha != newBehindAlpha) {
                mBehindAlpha = newBehindAlpha;
                updateScrims();
            }
        }
    }

    private void setKeyguardFadingAway(boolean fadingAway, long duration) {
        for (ScrimState state : ScrimState.values()) {
            state.setKeyguardFadingAway(fadingAway, duration);
        }
    }

    public void setLaunchingAffordanceWithPreview(boolean launchingAffordanceWithPreview) {
        for (ScrimState state : ScrimState.values()) {
            state.setLaunchingAffordanceWithPreview(launchingAffordanceWithPreview);
        }
    }

    public interface Callback {
        default void onStart() {
        }

        default void onDisplayBlanked() {
        }

        default void onFinished() {
        }

        default void onCancelled() {
        }
    }

    /**
     * Simple keyguard callback that updates scrims when keyguard visibility changes.
     */
    private class KeyguardVisibilityCallback extends KeyguardUpdateMonitorCallback {

        @Override
        public void onKeyguardVisibilityChanged(boolean showing) {
            mNeedsDrawableColorUpdate = true;
            scheduleUpdate();
        }
    }
}
