/*
 * 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.recents.views;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.annotation.IntDef;
import android.content.ComponentName;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Rect;
import android.os.Bundle;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.MutableBoolean;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewDebug;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
import android.widget.ScrollView;

import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.Dependency;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.recents.LegacyRecentsImpl;
import com.android.systemui.recents.RecentsActivity;
import com.android.systemui.recents.RecentsActivityLaunchState;
import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.RecentsDebugFlags;
import com.android.systemui.recents.RecentsImpl;
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent;
import com.android.systemui.recents.events.activity.ConfigurationChangedEvent;
import com.android.systemui.recents.events.activity.DismissRecentsToHomeAnimationStarted;
import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationCompletedEvent;
import com.android.systemui.recents.events.activity.HideRecentsEvent;
import com.android.systemui.recents.events.activity.HideStackActionButtonEvent;
import com.android.systemui.recents.events.activity.LaunchMostRecentTaskRequestEvent;
import com.android.systemui.recents.events.activity.LaunchNextTaskRequestEvent;
import com.android.systemui.recents.events.activity.LaunchTaskEvent;
import com.android.systemui.recents.events.activity.LaunchTaskStartedEvent;
import com.android.systemui.recents.events.activity.MultiWindowStateChangedEvent;
import com.android.systemui.recents.events.activity.PackagesChangedEvent;
import com.android.systemui.recents.events.activity.ShowEmptyViewEvent;
import com.android.systemui.recents.events.activity.ShowStackActionButtonEvent;
import com.android.systemui.recents.events.component.ActivityPinnedEvent;
import com.android.systemui.recents.events.component.ExpandPipEvent;
import com.android.systemui.recents.events.component.HidePipMenuEvent;
import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
import com.android.systemui.recents.events.ui.AllTaskViewsDismissedEvent;
import com.android.systemui.recents.events.ui.DeleteTaskDataEvent;
import com.android.systemui.recents.events.ui.DismissAllTaskViewsEvent;
import com.android.systemui.recents.events.ui.DismissTaskViewEvent;
import com.android.systemui.recents.events.ui.RecentsGrowingEvent;
import com.android.systemui.recents.events.ui.TaskViewDismissedEvent;
import com.android.systemui.recents.events.ui.UserInteractionEvent;
import com.android.systemui.recents.events.ui.dragndrop.DragDropTargetChangedEvent;
import com.android.systemui.recents.events.ui.dragndrop.DragEndCancelledEvent;
import com.android.systemui.recents.events.ui.dragndrop.DragEndEvent;
import com.android.systemui.recents.events.ui.dragndrop.DragStartEvent;
import com.android.systemui.recents.events.ui.focus.DismissFocusedTaskViewEvent;
import com.android.systemui.recents.events.ui.focus.FocusNextTaskViewEvent;
import com.android.systemui.recents.events.ui.focus.FocusPreviousTaskViewEvent;
import com.android.systemui.recents.events.ui.focus.NavigateTaskViewEvent;
import com.android.systemui.recents.misc.DozeTrigger;
import com.android.systemui.recents.misc.ReferenceCountedTrigger;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.model.TaskStack;
import com.android.systemui.recents.utilities.AnimationProps;
import com.android.systemui.recents.utilities.Utilities;
import com.android.systemui.recents.views.grid.GridTaskView;
import com.android.systemui.recents.views.grid.TaskGridLayoutAlgorithm;
import com.android.systemui.recents.views.grid.TaskViewFocusFrame;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.system.ActivityManagerWrapper;

import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;


/* The visual representation of a task stack view */
public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCallbacks,
        TaskView.TaskViewCallbacks, TaskStackViewScroller.TaskStackViewScrollerCallbacks,
        TaskStackLayoutAlgorithm.TaskStackLayoutAlgorithmCallbacks,
        ViewPool.ViewPoolConsumer<TaskView, Task> {

    private static final String TAG = "TaskStackView";

    // The thresholds at which to show/hide the stack action button.
    private static final float SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD = 0.3f;
    private static final float HIDE_STACK_ACTION_BUTTON_SCROLL_THRESHOLD = 0.3f;

    public static final int DEFAULT_SYNC_STACK_DURATION = 200;
    public static final int SLOW_SYNC_STACK_DURATION = 250;
    private static final int DRAG_SCALE_DURATION = 175;
    static final float DRAG_SCALE_FACTOR = 1.05f;

    private static final int LAUNCH_NEXT_SCROLL_BASE_DURATION = 216;
    private static final int LAUNCH_NEXT_SCROLL_INCR_DURATION = 32;

    // The actions to perform when resetting to initial state,
    @Retention(RetentionPolicy.SOURCE)
    @IntDef({INITIAL_STATE_UPDATE_NONE, INITIAL_STATE_UPDATE_ALL, INITIAL_STATE_UPDATE_LAYOUT_ONLY})
    public @interface InitialStateAction {}
    /** Do not update the stack and layout to the initial state. */
    private static final int INITIAL_STATE_UPDATE_NONE = 0;
    /** Update both the stack and layout to the initial state. */
    private static final int INITIAL_STATE_UPDATE_ALL = 1;
    /** Update only the layout to the initial state. */
    private static final int INITIAL_STATE_UPDATE_LAYOUT_ONLY = 2;

    private LayoutInflater mInflater;
    private TaskStack mStack = new TaskStack();
    @ViewDebug.ExportedProperty(deepExport=true, prefix="layout_")
    TaskStackLayoutAlgorithm mLayoutAlgorithm;
    // The stable layout algorithm is only used to calculate the task rect with the stable bounds
    private TaskStackLayoutAlgorithm mStableLayoutAlgorithm;
    @ViewDebug.ExportedProperty(deepExport=true, prefix="scroller_")
    private TaskStackViewScroller mStackScroller;
    @ViewDebug.ExportedProperty(deepExport=true, prefix="touch_")
    private TaskStackViewTouchHandler mTouchHandler;
    private TaskStackAnimationHelper mAnimationHelper;
    private ViewPool<TaskView, Task> mViewPool;

    private ArrayList<TaskView> mTaskViews = new ArrayList<>();
    private ArrayList<TaskViewTransform> mCurrentTaskTransforms = new ArrayList<>();
    private ArraySet<Task.TaskKey> mIgnoreTasks = new ArraySet<>();
    private AnimationProps mDeferredTaskViewLayoutAnimation = null;

    @ViewDebug.ExportedProperty(deepExport=true, prefix="doze_")
    private DozeTrigger mUIDozeTrigger;
    @ViewDebug.ExportedProperty(deepExport=true, prefix="focused_task_")
    private Task mFocusedTask;

    private int mTaskCornerRadiusPx;
    private int mDividerSize;
    private int mStartTimerIndicatorDuration;

    @ViewDebug.ExportedProperty(category="recents")
    private boolean mTaskViewsClipDirty = true;
    @ViewDebug.ExportedProperty(category="recents")
    private boolean mEnterAnimationComplete = false;
    @ViewDebug.ExportedProperty(category="recents")
    private boolean mStackReloaded = false;
    @ViewDebug.ExportedProperty(category="recents")
    private boolean mFinishedLayoutAfterStackReload = false;
    @ViewDebug.ExportedProperty(category="recents")
    private boolean mLaunchNextAfterFirstMeasure = false;
    @ViewDebug.ExportedProperty(category="recents")
    @InitialStateAction
    private int mInitialState = INITIAL_STATE_UPDATE_ALL;
    @ViewDebug.ExportedProperty(category="recents")
    private boolean mInMeasureLayout = false;
    @ViewDebug.ExportedProperty(category="recents")
    boolean mTouchExplorationEnabled;
    @ViewDebug.ExportedProperty(category="recents")
    boolean mScreenPinningEnabled;

    // The stable stack bounds are the full bounds that we were measured with from RecentsView
    @ViewDebug.ExportedProperty(category="recents")
    private Rect mStableStackBounds = new Rect();
    // The current stack bounds are dynamic and may change as the user drags and drops
    @ViewDebug.ExportedProperty(category="recents")
    private Rect mStackBounds = new Rect();
    // The current window bounds at the point we were measured
    @ViewDebug.ExportedProperty(category="recents")
    private Rect mStableWindowRect = new Rect();
    // The current window bounds are dynamic and may change as the user drags and drops
    @ViewDebug.ExportedProperty(category="recents")
    private Rect mWindowRect = new Rect();
    // The current display bounds
    @ViewDebug.ExportedProperty(category="recents")
    private Rect mDisplayRect = new Rect();
    // The current display orientation
    @ViewDebug.ExportedProperty(category="recents")
    private int mDisplayOrientation = Configuration.ORIENTATION_UNDEFINED;

    private Rect mTmpRect = new Rect();
    private ArrayMap<Task.TaskKey, TaskView> mTmpTaskViewMap = new ArrayMap<>();
    private List<TaskView> mTmpTaskViews = new ArrayList<>();
    private TaskViewTransform mTmpTransform = new TaskViewTransform();
    private int[] mTmpIntPair = new int[2];
    private boolean mResetToInitialStateWhenResized;
    private int mLastWidth;
    private int mLastHeight;
    private boolean mStackActionButtonVisible;

    // Percentage of last ScrollP from the min to max scrollP that lives after configuration changes
    private float mLastScrollPPercent = -1;

    // We keep track of the task view focused by user interaction and draw a frame around it in the
    // grid layout.
    private TaskViewFocusFrame mTaskViewFocusFrame;

    private Task mPrefetchingTask;
    private final float mFastFlingVelocity;

    // A convenience update listener to request updating clipping of tasks
    private ValueAnimator.AnimatorUpdateListener mRequestUpdateClippingListener =
            new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    if (!mTaskViewsClipDirty) {
                        mTaskViewsClipDirty = true;
                        invalidate();
                    }
                }
            };

    private DropTarget mStackDropTarget = new DropTarget() {
        @Override
        public boolean acceptsDrop(int x, int y, int width, int height, Rect insets,
                boolean isCurrentTarget) {
            // This drop target has a fixed bounds and should be checked last, so just fall through
            // if it is the current target
            if (!isCurrentTarget) {
                return mLayoutAlgorithm.mStackRect.contains(x, y);
            }
            return false;
        }
    };

    public TaskStackView(Context context) {
        super(context);
        SystemServicesProxy ssp = LegacyRecentsImpl.getSystemServices();
        Resources res = context.getResources();

        // Set the stack first
        mStack.setCallbacks(this);
        mViewPool = new ViewPool<>(context, this);
        mInflater = LayoutInflater.from(context);
        mLayoutAlgorithm = new TaskStackLayoutAlgorithm(context, this);
        mStableLayoutAlgorithm = new TaskStackLayoutAlgorithm(context, null);
        mStackScroller = new TaskStackViewScroller(context, this, mLayoutAlgorithm);
        mTouchHandler = new TaskStackViewTouchHandler(
                context, this, mStackScroller, Dependency.get(FalsingManager.class));
        mAnimationHelper = new TaskStackAnimationHelper(context, this);
        mTaskCornerRadiusPx = LegacyRecentsImpl.getConfiguration().isGridEnabled ?
                res.getDimensionPixelSize(R.dimen.recents_grid_task_view_rounded_corners_radius) :
                res.getDimensionPixelSize(R.dimen.recents_task_view_rounded_corners_radius);
        mFastFlingVelocity = res.getDimensionPixelSize(R.dimen.recents_fast_fling_velocity);
        mDividerSize = ssp.getDockedDividerSize(context);
        mDisplayOrientation = Utilities.getAppConfiguration(mContext).orientation;
        mDisplayRect = ssp.getDisplayRect();
        mStackActionButtonVisible = false;

        // Create a frame to draw around the focused task view
        if (LegacyRecentsImpl.getConfiguration().isGridEnabled) {
            mTaskViewFocusFrame = new TaskViewFocusFrame(mContext, this,
                mLayoutAlgorithm.mTaskGridLayoutAlgorithm);
            addView(mTaskViewFocusFrame);
            getViewTreeObserver().addOnGlobalFocusChangeListener(mTaskViewFocusFrame);
        }

        int taskBarDismissDozeDelaySeconds = getResources().getInteger(
                R.integer.recents_task_bar_dismiss_delay_seconds);
        mUIDozeTrigger = new DozeTrigger(taskBarDismissDozeDelaySeconds, new Runnable() {
            @Override
            public void run() {
                // Show the task bar dismiss buttons
                List<TaskView> taskViews = getTaskViews();
                int taskViewCount = taskViews.size();
                for (int i = 0; i < taskViewCount; i++) {
                    TaskView tv = taskViews.get(i);
                    tv.startNoUserInteractionAnimation();
                }
            }
        });
        setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
    }

    @Override
    protected void onAttachedToWindow() {
        EventBus.getDefault().register(this, RecentsActivity.EVENT_BUS_PRIORITY + 1);
        super.onAttachedToWindow();
        readSystemFlags();
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        EventBus.getDefault().unregister(this);
    }

    /**
     * Called from RecentsActivity when it is relaunched.
     */
    void onReload(boolean isResumingFromVisible) {
        if (!isResumingFromVisible) {
            // Reset the focused task
            resetFocusedTask(getFocusedTask());
        }

        // Reset the state of each of the task views
        List<TaskView> taskViews = new ArrayList<>();
        taskViews.addAll(getTaskViews());
        taskViews.addAll(mViewPool.getViews());
        for (int i = taskViews.size() - 1; i >= 0; i--) {
            taskViews.get(i).onReload(isResumingFromVisible);
        }

        // Reset the stack state
        readSystemFlags();
        mTaskViewsClipDirty = true;
        mUIDozeTrigger.stopDozing();
        if (!isResumingFromVisible) {
            mStackScroller.reset();
            mStableLayoutAlgorithm.reset();
            mLayoutAlgorithm.reset();
            mLastScrollPPercent = -1;
        }

        // Since we always animate to the same place in (the initial state), always reset the stack
        // to the initial state when resuming
        mStackReloaded = true;
        mFinishedLayoutAfterStackReload = false;
        mLaunchNextAfterFirstMeasure = false;
        mInitialState = INITIAL_STATE_UPDATE_ALL;
        requestLayout();
    }

    /**
     * Sets the stack tasks of this TaskStackView from the given TaskStack.
     */
    public void setTasks(TaskStack stack, boolean allowNotifyStackChanges) {
        boolean isInitialized = mLayoutAlgorithm.isInitialized();

        // Only notify if we are already initialized, otherwise, everything will pick up all the
        // new and old tasks when we next layout
        mStack.setTasks(stack, allowNotifyStackChanges && isInitialized);
    }

    /** Returns the task stack. */
    public TaskStack getStack() {
        return mStack;
    }

    /**
     * Updates this TaskStackView to the initial state.
     */
    public void updateToInitialState() {
        mStackScroller.setStackScrollToInitialState();
        mLayoutAlgorithm.setTaskOverridesForInitialState(mStack, false /* ignoreScrollToFront */);
    }

    /** Updates the list of task views */
    void updateTaskViewsList() {
        mTaskViews.clear();
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            View v = getChildAt(i);
            if (v instanceof TaskView) {
                mTaskViews.add((TaskView) v);
            }
        }
    }

    /** Gets the list of task views */
    List<TaskView> getTaskViews() {
        return mTaskViews;
    }

    /**
     * Returns the front most task view.
     */
    private TaskView getFrontMostTaskView() {
        List<TaskView> taskViews = getTaskViews();
        if (taskViews.isEmpty()) {
            return null;
        }
        return taskViews.get(taskViews.size() - 1);
    }

    /**
     * Finds the child view given a specific {@param task}.
     */
    public TaskView getChildViewForTask(Task t) {
        List<TaskView> taskViews = getTaskViews();
        int taskViewCount = taskViews.size();
        for (int i = 0; i < taskViewCount; i++) {
            TaskView tv = taskViews.get(i);
            if (tv.getTask() == t) {
                return tv;
            }
        }
        return null;
    }

    /** Returns the stack algorithm for this task stack. */
    public TaskStackLayoutAlgorithm getStackAlgorithm() {
        return mLayoutAlgorithm;
    }

    /** Returns the grid algorithm for this task stack. */
    public TaskGridLayoutAlgorithm getGridAlgorithm() {
        return mLayoutAlgorithm.mTaskGridLayoutAlgorithm;
    }

    /**
     * Returns the touch handler for this task stack.
     */
    public TaskStackViewTouchHandler getTouchHandler() {
        return mTouchHandler;
    }

    /**
     * Adds a task to the ignored set.
     */
    void addIgnoreTask(Task task) {
        mIgnoreTasks.add(task.key);
    }

    /**
     * Removes a task from the ignored set.
     */
    void removeIgnoreTask(Task task) {
        mIgnoreTasks.remove(task.key);
    }

    /**
     * Returns whether the specified {@param task} is ignored.
     */
    boolean isIgnoredTask(Task task) {
        return mIgnoreTasks.contains(task.key);
    }

    /**
     * Computes the task transforms at the current stack scroll for all visible tasks. If a valid
     * target stack scroll is provided (ie. is different than {@param curStackScroll}), then the
     * visible range includes all tasks at the target stack scroll. This is useful for ensure that
     * all views necessary for a transition or animation will be visible at the start.
     *
     * @param taskTransforms The set of task view transforms to reuse, this list will be sized to
     *                       match the size of {@param tasks}
     * @param tasks The set of tasks for which to generate transforms
     * @param curStackScroll The current stack scroll
     * @param targetStackScroll The stack scroll that we anticipate we are going to be scrolling to.
     *                          The range of the union of the visible views at the current and
     *                          target stack scrolls will be returned.
     * @param ignoreTasksSet The set of tasks to skip for purposes of calculaing the visible range.
     *                       Transforms will still be calculated for the ignore tasks.
     * @return the front and back most visible task indices (there may be non visible tasks in
     *         between this range)
     */
    int[] computeVisibleTaskTransforms(ArrayList<TaskViewTransform> taskTransforms,
            ArrayList<Task> tasks, float curStackScroll, float targetStackScroll,
            ArraySet<Task.TaskKey> ignoreTasksSet, boolean ignoreTaskOverrides) {
        int taskCount = tasks.size();
        int[] visibleTaskRange = mTmpIntPair;
        visibleTaskRange[0] = -1;
        visibleTaskRange[1] = -1;
        boolean useTargetStackScroll = Float.compare(curStackScroll, targetStackScroll) != 0;

        // We can reuse the task transforms where possible to reduce object allocation
        matchTaskListSize(tasks, taskTransforms);

        // Update the stack transforms
        TaskViewTransform frontTransform = null;
        TaskViewTransform frontTransformAtTarget = null;
        TaskViewTransform transform = null;
        TaskViewTransform transformAtTarget = null;
        for (int i = taskCount - 1; i >= 0; i--) {
            Task task = tasks.get(i);

            // Calculate the current and (if necessary) the target transform for the task
            transform = mLayoutAlgorithm.getStackTransform(task, curStackScroll,
                    taskTransforms.get(i), frontTransform, ignoreTaskOverrides);
            if (useTargetStackScroll && !transform.visible) {
                // If we have a target stack scroll and the task is not currently visible, then we
                // just update the transform at the new scroll
                // TODO: Optimize this
                transformAtTarget = mLayoutAlgorithm.getStackTransform(task, targetStackScroll,
                    new TaskViewTransform(), frontTransformAtTarget);
                if (transformAtTarget.visible) {
                    transform.copyFrom(transformAtTarget);
                }
            }

            // For ignore tasks, only calculate the stack transform and skip the calculation of the
            // visible stack indices
            if (ignoreTasksSet.contains(task.key)) {
                continue;
            }

            frontTransform = transform;
            frontTransformAtTarget = transformAtTarget;
            if (transform.visible) {
                if (visibleTaskRange[0] < 0) {
                    visibleTaskRange[0] = i;
                }
                visibleTaskRange[1] = i;
            }
        }
        return visibleTaskRange;
    }

    /**
     * Binds the visible {@link TaskView}s at the given target scroll.
     */
    void bindVisibleTaskViews(float targetStackScroll) {
        bindVisibleTaskViews(targetStackScroll, false /* ignoreTaskOverrides */);
    }

    /**
     * Synchronizes the set of children {@link TaskView}s to match the visible set of tasks in the
     * current {@link TaskStack}. This call does not continue on to update their position to the
     * computed {@link TaskViewTransform}s of the visible range, but only ensures that they will
     * be added/removed from the view hierarchy and placed in the correct Z order and initial
     * position (if not currently on screen).
     *
     * @param targetStackScroll If provided, will ensure that the set of visible {@link TaskView}s
     *                          includes those visible at the current stack scroll, and all at the
     *                          target stack scroll.
     * @param ignoreTaskOverrides If set, the visible task computation will get the transforms for
     *                            tasks at their non-overridden task progress
     */
    void bindVisibleTaskViews(float targetStackScroll, boolean ignoreTaskOverrides) {
        // Get all the task transforms
        ArrayList<Task> tasks = mStack.getTasks();
        int[] visibleTaskRange = computeVisibleTaskTransforms(mCurrentTaskTransforms, tasks,
                mStackScroller.getStackScroll(), targetStackScroll, mIgnoreTasks,
                ignoreTaskOverrides);

        // Return all the invisible children to the pool
        mTmpTaskViewMap.clear();
        List<TaskView> taskViews = getTaskViews();
        int lastFocusedTaskIndex = -1;
        int taskViewCount = taskViews.size();
        for (int i = taskViewCount - 1; i >= 0; i--) {
            TaskView tv = taskViews.get(i);
            Task task = tv.getTask();

            // Skip ignored tasks
            if (mIgnoreTasks.contains(task.key)) {
                continue;
            }

            // It is possible for the set of lingering TaskViews to differ from the stack if the
            // stack was updated before the relayout.  If the task view is no longer in the stack,
            // then just return it back to the view pool.
            int taskIndex = mStack.indexOfTask(task);
            TaskViewTransform transform = null;
            if (taskIndex != -1) {
                transform = mCurrentTaskTransforms.get(taskIndex);
            }

            if (transform != null && transform.visible) {
                mTmpTaskViewMap.put(task.key, tv);
            } else {
                if (mTouchExplorationEnabled && Utilities.isDescendentAccessibilityFocused(tv)) {
                    lastFocusedTaskIndex = taskIndex;
                    resetFocusedTask(task);
                }
                mViewPool.returnViewToPool(tv);
            }
        }

        // Pick up all the newly visible children
        for (int i = tasks.size() - 1; i >= 0; i--) {
            Task task = tasks.get(i);
            TaskViewTransform transform = mCurrentTaskTransforms.get(i);

            // Skip ignored tasks
            if (mIgnoreTasks.contains(task.key)) {
                continue;
            }

            // Skip the invisible stack tasks
            if (!transform.visible) {
                continue;
            }

            TaskView tv = mTmpTaskViewMap.get(task.key);
            if (tv == null) {
                tv = mViewPool.pickUpViewFromPool(task, task);
                if (transform.rect.top <= mLayoutAlgorithm.mStackRect.top) {
                    updateTaskViewToTransform(tv, mLayoutAlgorithm.getBackOfStackTransform(),
                            AnimationProps.IMMEDIATE);
                } else {
                    updateTaskViewToTransform(tv, mLayoutAlgorithm.getFrontOfStackTransform(),
                            AnimationProps.IMMEDIATE);
                }
            } else {
                // Reattach it in the right z order
                final int taskIndex = mStack.indexOfTask(task);
                final int insertIndex = findTaskViewInsertIndex(task, taskIndex);
                if (insertIndex != getTaskViews().indexOf(tv)){
                    detachViewFromParent(tv);
                    attachViewToParent(tv, insertIndex, tv.getLayoutParams());
                    updateTaskViewsList();
                }
            }
        }

        updatePrefetchingTask(tasks, visibleTaskRange[0], visibleTaskRange[1]);

        // Update the focus if the previous focused task was returned to the view pool
        if (lastFocusedTaskIndex != -1) {
            int newFocusedTaskIndex = (lastFocusedTaskIndex < visibleTaskRange[1])
                    ? visibleTaskRange[1]
                    : visibleTaskRange[0];
            setFocusedTask(newFocusedTaskIndex, false /* scrollToTask */,
                    true /* requestViewFocus */);
            TaskView focusedTaskView = getChildViewForTask(mFocusedTask);
            if (focusedTaskView != null) {
                focusedTaskView.requestAccessibilityFocus();
            }
        }
    }

    /**
     * @see #relayoutTaskViews(AnimationProps, ArrayMap<Task, AnimationProps>, boolean)
     */
    public void relayoutTaskViews(AnimationProps animation) {
        relayoutTaskViews(animation, null /* animationOverrides */,
                false /* ignoreTaskOverrides */);
    }

    /**
     * Relayout the the visible {@link TaskView}s to their current transforms as specified by the
     * {@link TaskStackLayoutAlgorithm} with the given {@param animation}. This call cancels any
     * animations that are current running on those task views, and will ensure that the children
     * {@link TaskView}s will match the set of visible tasks in the stack.  If a {@link Task} has
     * an animation provided in {@param animationOverrides}, that will be used instead.
     */
    private void relayoutTaskViews(AnimationProps animation,
            ArrayMap<Task, AnimationProps> animationOverrides, boolean ignoreTaskOverrides) {
        // If we had a deferred animation, cancel that
        cancelDeferredTaskViewLayoutAnimation();

        // Synchronize the current set of TaskViews
        bindVisibleTaskViews(mStackScroller.getStackScroll(), ignoreTaskOverrides);

        // Animate them to their final transforms with the given animation
        List<TaskView> taskViews = getTaskViews();
        int taskViewCount = taskViews.size();
        for (int i = 0; i < taskViewCount; i++) {
            TaskView tv = taskViews.get(i);
            Task task = tv.getTask();

            if (mIgnoreTasks.contains(task.key)) {
                continue;
            }

            int taskIndex = mStack.indexOfTask(task);
            TaskViewTransform transform = mCurrentTaskTransforms.get(taskIndex);
            if (animationOverrides != null && animationOverrides.containsKey(task)) {
                animation = animationOverrides.get(task);
            }

            updateTaskViewToTransform(tv, transform, animation);
        }
    }

    /**
     * Posts an update to synchronize the {@link TaskView}s with the stack on the next frame.
     */
    void relayoutTaskViewsOnNextFrame(AnimationProps animation) {
        mDeferredTaskViewLayoutAnimation = animation;
        invalidate();
    }

    /**
     * Called to update a specific {@link TaskView} to a given {@link TaskViewTransform} with a
     * given set of {@link AnimationProps} properties.
     */
    public void updateTaskViewToTransform(TaskView taskView, TaskViewTransform transform,
            AnimationProps animation) {
        if (taskView.isAnimatingTo(transform)) {
            return;
        }
        taskView.cancelTransformAnimation();
        taskView.updateViewPropertiesToTaskTransform(transform, animation,
                mRequestUpdateClippingListener);
    }

    /**
     * Returns the current task transforms of all tasks, falling back to the stack layout if there
     * is no {@link TaskView} for the task.
     */
    public void getCurrentTaskTransforms(ArrayList<Task> tasks,
            ArrayList<TaskViewTransform> transformsOut) {
        matchTaskListSize(tasks, transformsOut);
        int focusState = mLayoutAlgorithm.getFocusState();
        for (int i = tasks.size() - 1; i >= 0; i--) {
            Task task = tasks.get(i);
            TaskViewTransform transform = transformsOut.get(i);
            TaskView tv = getChildViewForTask(task);
            if (tv != null) {
                transform.fillIn(tv);
            } else {
                mLayoutAlgorithm.getStackTransform(task, mStackScroller.getStackScroll(),
                        focusState, transform, null, true /* forceUpdate */,
                        false /* ignoreTaskOverrides */);
            }
            transform.visible = true;
        }
    }

    /**
     * Returns the task transforms for all the tasks in the stack if the stack was at the given
     * {@param stackScroll} and {@param focusState}.
     */
    public void getLayoutTaskTransforms(float stackScroll, int focusState, ArrayList<Task> tasks,
            boolean ignoreTaskOverrides, ArrayList<TaskViewTransform> transformsOut) {
        matchTaskListSize(tasks, transformsOut);
        for (int i = tasks.size() - 1; i >= 0; i--) {
            Task task = tasks.get(i);
            TaskViewTransform transform = transformsOut.get(i);
            mLayoutAlgorithm.getStackTransform(task, stackScroll, focusState, transform, null,
                    true /* forceUpdate */, ignoreTaskOverrides);
            transform.visible = true;
        }
    }

    /**
     * Cancels the next deferred task view layout.
     */
    void cancelDeferredTaskViewLayoutAnimation() {
        mDeferredTaskViewLayoutAnimation = null;
    }

    /**
     * Cancels all {@link TaskView} animations.
     */
    void cancelAllTaskViewAnimations() {
        List<TaskView> taskViews = getTaskViews();
        for (int i = taskViews.size() - 1; i >= 0; i--) {
            final TaskView tv = taskViews.get(i);
            if (!mIgnoreTasks.contains(tv.getTask().key)) {
                tv.cancelTransformAnimation();
            }
        }
    }

    /**
     * Updates the clip for each of the task views from back to front.
     */
    private void clipTaskViews() {
        // We never clip task views in grid layout
        if (LegacyRecentsImpl.getConfiguration().isGridEnabled) {
            return;
        }

        // Update the clip on each task child
        List<TaskView> taskViews = getTaskViews();
        TaskView tmpTv = null;
        TaskView prevVisibleTv = null;
        int taskViewCount = taskViews.size();
        for (int i = 0; i < taskViewCount; i++) {
            TaskView tv = taskViews.get(i);
            TaskView frontTv = null;
            int clipBottom = 0;

            if (isIgnoredTask(tv.getTask())) {
                // For each of the ignore tasks, update the translationZ of its TaskView to be
                // between the translationZ of the tasks immediately underneath it
                if (prevVisibleTv != null) {
                    tv.setTranslationZ(Math.max(tv.getTranslationZ(),
                            prevVisibleTv.getTranslationZ() + 0.1f));
                }
            }

            if (i < (taskViewCount - 1) && tv.shouldClipViewInStack()) {
                // Find the next view to clip against
                for (int j = i + 1; j < taskViewCount; j++) {
                    tmpTv = taskViews.get(j);

                    if (tmpTv.shouldClipViewInStack()) {
                        frontTv = tmpTv;
                        break;
                    }
                }

                // Clip against the next view, this is just an approximation since we are
                // stacked and we can make assumptions about the visibility of the this
                // task relative to the ones in front of it.
                if (frontTv != null) {
                    float taskBottom = tv.getBottom();
                    float frontTaskTop = frontTv.getTop();
                    if (frontTaskTop < taskBottom) {
                        // Map the stack view space coordinate (the rects) to view space
                        clipBottom = (int) (taskBottom - frontTaskTop) - mTaskCornerRadiusPx;
                    }
                }
            }
            tv.getViewBounds().setClipBottom(clipBottom);
            tv.mThumbnailView.updateThumbnailVisibility(clipBottom - tv.getPaddingBottom());
            prevVisibleTv = tv;
        }
        mTaskViewsClipDirty = false;
    }

    public void updateLayoutAlgorithm(boolean boundScrollToNewMinMax) {
        updateLayoutAlgorithm(boundScrollToNewMinMax, LegacyRecentsImpl.getConfiguration().getLaunchState());
    }

    /**
     * Updates the layout algorithm min and max virtual scroll bounds.
     */
   public void updateLayoutAlgorithm(boolean boundScrollToNewMinMax,
           RecentsActivityLaunchState launchState) {
        // Compute the min and max scroll values
        mLayoutAlgorithm.update(mStack, mIgnoreTasks, launchState, mLastScrollPPercent);

        if (boundScrollToNewMinMax) {
            mStackScroller.boundScroll();
        }
    }

    /**
     * Updates the stack layout to its stable places.
     */
    private void updateLayoutToStableBounds() {
        mWindowRect.set(mStableWindowRect);
        mStackBounds.set(mStableStackBounds);
        mLayoutAlgorithm.setSystemInsets(mStableLayoutAlgorithm.mSystemInsets);
        mLayoutAlgorithm.initialize(mDisplayRect, mWindowRect, mStackBounds);
        updateLayoutAlgorithm(true /* boundScroll */);
    }

    /** Returns the scroller. */
    public TaskStackViewScroller getScroller() {
        return mStackScroller;
    }

    /**
     * Sets the focused task to the provided (bounded taskIndex).
     *
     * @return whether or not the stack will scroll as a part of this focus change
     */
    public boolean setFocusedTask(int taskIndex, boolean scrollToTask,
            final boolean requestViewFocus) {
        return setFocusedTask(taskIndex, scrollToTask, requestViewFocus, 0);
    }

    /**
     * Sets the focused task to the provided (bounded focusTaskIndex).
     *
     * @return whether or not the stack will scroll as a part of this focus change
     */
    public boolean setFocusedTask(int focusTaskIndex, boolean scrollToTask,
            boolean requestViewFocus, int timerIndicatorDuration) {
        // Find the next task to focus
        int newFocusedTaskIndex = mStack.getTaskCount() > 0 ?
                Utilities.clamp(focusTaskIndex, 0, mStack.getTaskCount() - 1) : -1;
        final Task newFocusedTask = (newFocusedTaskIndex != -1) ?
                mStack.getTasks().get(newFocusedTaskIndex) : null;

        // Reset the last focused task state if changed
        if (mFocusedTask != null) {
            // Cancel the timer indicator, if applicable
            if (timerIndicatorDuration > 0) {
                final TaskView tv = getChildViewForTask(mFocusedTask);
                if (tv != null) {
                    tv.getHeaderView().cancelFocusTimerIndicator();
                }
            }

            resetFocusedTask(mFocusedTask);
        }

        boolean willScroll = false;
        mFocusedTask = newFocusedTask;

        if (newFocusedTask != null) {
            // Start the timer indicator, if applicable
            if (timerIndicatorDuration > 0) {
                final TaskView tv = getChildViewForTask(mFocusedTask);
                if (tv != null) {
                    tv.getHeaderView().startFocusTimerIndicator(timerIndicatorDuration);
                } else {
                    // The view is null; set a flag for later
                    mStartTimerIndicatorDuration = timerIndicatorDuration;
                }
            }

            if (scrollToTask) {
                // Cancel any running enter animations at this point when we scroll or change focus
                if (!mEnterAnimationComplete) {
                    cancelAllTaskViewAnimations();
                }

                mLayoutAlgorithm.clearUnfocusedTaskOverrides();
                willScroll = mAnimationHelper.startScrollToFocusedTaskAnimation(newFocusedTask,
                        requestViewFocus);
                if (willScroll) {
                    sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SCROLLED);
                }
            } else {
                // Focus the task view
                TaskView newFocusedTaskView = getChildViewForTask(newFocusedTask);
                if (newFocusedTaskView != null) {
                    newFocusedTaskView.setFocusedState(true, requestViewFocus);
                }
            }
            // Any time a task view gets the focus, we move the focus frame around it.
            if (mTaskViewFocusFrame != null) {
                mTaskViewFocusFrame.moveGridTaskViewFocus(getChildViewForTask(newFocusedTask));
            }
        }
        return willScroll;
    }

    /**
     * Sets the focused task relative to the currently focused task.
     *
     * @param forward whether to go to the next task in the stack (along the curve) or the previous
     * @param stackTasksOnly if set, will ensure that the traversal only goes along stack tasks, and
     *                       if the currently focused task is not a stack task, will set the focus
     *                       to the first visible stack task
     * @param animated determines whether to actually draw the highlight along with the change in
     *                            focus.
     */
    public void setRelativeFocusedTask(boolean forward, boolean stackTasksOnly, boolean animated) {
        setRelativeFocusedTask(forward, stackTasksOnly, animated, false, 0);
    }

    /**
     * Sets the focused task relative to the currently focused task.
     *
     * @param forward whether to go to the next task in the stack (along the curve) or the previous
     * @param stackTasksOnly if set, will ensure that the traversal only goes along stack tasks, and
     *                       if the currently focused task is not a stack task, will set the focus
     *                       to the first visible stack task
     * @param animated determines whether to actually draw the highlight along with the change in
     *                            focus.
     * @param cancelWindowAnimations if set, will attempt to cancel window animations if a scroll
     *                               happens.
     * @param timerIndicatorDuration the duration to initialize the auto-advance timer indicator
     */
    public void setRelativeFocusedTask(boolean forward, boolean stackTasksOnly, boolean animated,
                                       boolean cancelWindowAnimations, int timerIndicatorDuration) {
        Task focusedTask = getFocusedTask();
        int newIndex = mStack.indexOfTask(focusedTask);
        if (focusedTask != null) {
            if (stackTasksOnly) {
                List<Task> tasks =  mStack.getTasks();
                // Try the next task if it is a stack task
                int tmpNewIndex = newIndex + (forward ? -1 : 1);
                if (0 <= tmpNewIndex && tmpNewIndex < tasks.size()) {
                    newIndex = tmpNewIndex;
                }
            } else {
                // No restrictions, lets just move to the new task (looping forward/backwards if
                // necessary)
                int taskCount = mStack.getTaskCount();
                newIndex = (newIndex + (forward ? -1 : 1) + taskCount) % taskCount;
            }
        } else {
            // We don't have a focused task
            float stackScroll = mStackScroller.getStackScroll();
            ArrayList<Task> tasks = mStack.getTasks();
            int taskCount = tasks.size();
            if (useGridLayout()) {
                // For the grid layout, we directly set focus to the most recently used task
                // no matter we're moving forwards or backwards.
                newIndex = taskCount - 1;
            } else {
                // For the grid layout we pick a proper task to focus, according to the current
                // stack scroll.
                if (forward) {
                    // Walk backwards and focus the next task smaller than the current stack scroll
                    for (newIndex = taskCount - 1; newIndex >= 0; newIndex--) {
                        float taskP = mLayoutAlgorithm.getStackScrollForTask(tasks.get(newIndex));
                        if (Float.compare(taskP, stackScroll) <= 0) {
                            break;
                        }
                    }
                } else {
                    // Walk forwards and focus the next task larger than the current stack scroll
                    for (newIndex = 0; newIndex < taskCount; newIndex++) {
                        float taskP = mLayoutAlgorithm.getStackScrollForTask(tasks.get(newIndex));
                        if (Float.compare(taskP, stackScroll) >= 0) {
                            break;
                        }
                    }
                }
            }
        }
        if (newIndex != -1) {
            boolean willScroll = setFocusedTask(newIndex, true /* scrollToTask */,
                    true /* requestViewFocus */, timerIndicatorDuration);
            if (willScroll && cancelWindowAnimations) {
                // As we iterate to the next/previous task, cancel any current/lagging window
                // transition animations
                EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(null));
            }
        }
    }

    /**
     * Resets the focused task.
     */
    public void resetFocusedTask(Task task) {
        if (task != null) {
            TaskView tv = getChildViewForTask(task);
            if (tv != null) {
                tv.setFocusedState(false, false /* requestViewFocus */);
            }
        }
        if (mTaskViewFocusFrame != null) {
            mTaskViewFocusFrame.moveGridTaskViewFocus(null);
        }
        mFocusedTask = null;
    }

    /**
     * Returns the focused task.
     */
    public Task getFocusedTask() {
        return mFocusedTask;
    }

    /**
     * Returns the accessibility focused task.
     */
    Task getAccessibilityFocusedTask() {
        List<TaskView> taskViews = getTaskViews();
        int taskViewCount = taskViews.size();
        for (int i = 0; i < taskViewCount; i++) {
            TaskView tv = taskViews.get(i);
            if (Utilities.isDescendentAccessibilityFocused(tv)) {
                return tv.getTask();
            }
        }
        TaskView frontTv = getFrontMostTaskView();
        if (frontTv != null) {
            return frontTv.getTask();
        }
        return null;
    }

    @Override
    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
        super.onInitializeAccessibilityEvent(event);
        List<TaskView> taskViews = getTaskViews();
        int taskViewCount = taskViews.size();
        if (taskViewCount > 0) {
            TaskView backMostTask = taskViews.get(0);
            TaskView frontMostTask = taskViews.get(taskViewCount - 1);
            event.setFromIndex(mStack.indexOfTask(backMostTask.getTask()));
            event.setToIndex(mStack.indexOfTask(frontMostTask.getTask()));
            event.setContentDescription(frontMostTask.getTask().title);
        }
        event.setItemCount(mStack.getTaskCount());

        int stackHeight = mLayoutAlgorithm.mStackRect.height();
        event.setScrollY((int) (mStackScroller.getStackScroll() * stackHeight));
        event.setMaxScrollY((int) (mLayoutAlgorithm.mMaxScrollP * stackHeight));
    }

    @Override
    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
        super.onInitializeAccessibilityNodeInfo(info);
        List<TaskView> taskViews = getTaskViews();
        int taskViewCount = taskViews.size();
        if (taskViewCount > 1) {
            // Find the accessibility focused task
            Task focusedTask = getAccessibilityFocusedTask();
            info.setScrollable(true);
            int focusedTaskIndex = mStack.indexOfTask(focusedTask);
            if (focusedTaskIndex > 0 || !mStackActionButtonVisible) {
                info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
            }
            if (0 <= focusedTaskIndex && focusedTaskIndex < mStack.getTaskCount() - 1) {
                info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
            }
        }
    }

    @Override
    public CharSequence getAccessibilityClassName() {
        return ScrollView.class.getName();
    }

    @Override
    public boolean performAccessibilityAction(int action, Bundle arguments) {
        if (super.performAccessibilityAction(action, arguments)) {
            return true;
        }
        Task focusedTask = getAccessibilityFocusedTask();
        int taskIndex = mStack.indexOfTask(focusedTask);
        if (0 <= taskIndex && taskIndex < mStack.getTaskCount()) {
            switch (action) {
                case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: {
                    setFocusedTask(taskIndex + 1, true /* scrollToTask */, true /* requestViewFocus */,
                            0);
                    return true;
                }
                case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: {
                    setFocusedTask(taskIndex - 1, true /* scrollToTask */, true /* requestViewFocus */,
                            0);
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return mTouchHandler.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        return mTouchHandler.onTouchEvent(ev);
    }

    @Override
    public boolean onGenericMotionEvent(MotionEvent ev) {
        return mTouchHandler.onGenericMotionEvent(ev);
    }

    @Override
    public void computeScroll() {
        if (mStackScroller.computeScroll()) {
            // Notify accessibility
            sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SCROLLED);
            LegacyRecentsImpl.getTaskLoader().getHighResThumbnailLoader().setFlingingFast(
                    mStackScroller.getScrollVelocity() > mFastFlingVelocity);
        }
        if (mDeferredTaskViewLayoutAnimation != null) {
            relayoutTaskViews(mDeferredTaskViewLayoutAnimation);
            mTaskViewsClipDirty = true;
            mDeferredTaskViewLayoutAnimation = null;
        }
        if (mTaskViewsClipDirty) {
            clipTaskViews();
        }
        mLastScrollPPercent = Utilities.clamp(Utilities.unmapRange(mStackScroller.getStackScroll(),
            mLayoutAlgorithm.mMinScrollP, mLayoutAlgorithm.mMaxScrollP), 0, 1);
    }

    /**
     * Computes the maximum number of visible tasks and thumbnails. Requires that
     * updateLayoutForStack() is called first.
     */
    public TaskStackLayoutAlgorithm.VisibilityReport computeStackVisibilityReport() {
        return mLayoutAlgorithm.computeStackVisibilityReport(mStack.getTasks());
    }

    /**
     * Updates the system insets.
     */
    public void setSystemInsets(Rect systemInsets) {
        boolean changed = false;
        changed |= mStableLayoutAlgorithm.setSystemInsets(systemInsets);
        changed |= mLayoutAlgorithm.setSystemInsets(systemInsets);
        if (changed) {
            requestLayout();
        }
    }

    /**
     * This is called with the full window width and height to allow stack view children to
     * perform the full screen transition down.
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        mInMeasureLayout = true;
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);

        // Update the stable stack bounds, but only update the current stack bounds if the stable
        // bounds have changed.  This is because we may get spurious measures while dragging where
        // our current stack bounds reflect the target drop region.
        mLayoutAlgorithm.getTaskStackBounds(mDisplayRect, new Rect(0, 0, width, height),
                mLayoutAlgorithm.mSystemInsets.top, mLayoutAlgorithm.mSystemInsets.left,
                mLayoutAlgorithm.mSystemInsets.right, mTmpRect);
        if (!mTmpRect.equals(mStableStackBounds)) {
            mStableStackBounds.set(mTmpRect);
            mStackBounds.set(mTmpRect);
            mStableWindowRect.set(0, 0, width, height);
            mWindowRect.set(0, 0, width, height);
        }

        // Compute the rects in the stack algorithm
        mStableLayoutAlgorithm.initialize(mDisplayRect, mStableWindowRect, mStableStackBounds);
        mLayoutAlgorithm.initialize(mDisplayRect, mWindowRect, mStackBounds);
        updateLayoutAlgorithm(false /* boundScroll */);

        // If this is the first layout, then scroll to the front of the stack, then update the
        // TaskViews with the stack so that we can lay them out
        boolean resetToInitialState = (width != mLastWidth || height != mLastHeight)
                && mResetToInitialStateWhenResized;
        if (!mFinishedLayoutAfterStackReload || mInitialState != INITIAL_STATE_UPDATE_NONE
                || resetToInitialState) {
            if (mInitialState != INITIAL_STATE_UPDATE_LAYOUT_ONLY || resetToInitialState) {
                updateToInitialState();
                mResetToInitialStateWhenResized = false;
            }
            if (mFinishedLayoutAfterStackReload) {
                mInitialState = INITIAL_STATE_UPDATE_NONE;
            }
        }
        // If we got the launch-next event before the first layout pass, then re-send it after the
        // initial state has been updated
        if (mLaunchNextAfterFirstMeasure) {
            mLaunchNextAfterFirstMeasure = false;
            EventBus.getDefault().post(new LaunchNextTaskRequestEvent());
        }

        // Rebind all the views, including the ignore ones
        bindVisibleTaskViews(mStackScroller.getStackScroll(), false /* ignoreTaskOverrides */);

        // Measure each of the TaskViews
        mTmpTaskViews.clear();
        mTmpTaskViews.addAll(getTaskViews());
        mTmpTaskViews.addAll(mViewPool.getViews());
        int taskViewCount = mTmpTaskViews.size();
        for (int i = 0; i < taskViewCount; i++) {
            measureTaskView(mTmpTaskViews.get(i));
        }
        if (mTaskViewFocusFrame != null) {
            mTaskViewFocusFrame.measure();
        }

        setMeasuredDimension(width, height);
        mLastWidth = width;
        mLastHeight = height;
        mInMeasureLayout = false;
    }

    /**
     * Measures a TaskView.
     */
    private void measureTaskView(TaskView tv) {
        Rect padding = new Rect();
        if (tv.getBackground() != null) {
            tv.getBackground().getPadding(padding);
        }
        mTmpRect.set(mStableLayoutAlgorithm.getTaskRect());
        mTmpRect.union(mLayoutAlgorithm.getTaskRect());
        tv.measure(
                MeasureSpec.makeMeasureSpec(mTmpRect.width() + padding.left + padding.right,
                        MeasureSpec.EXACTLY),
                MeasureSpec.makeMeasureSpec(mTmpRect.height() + padding.top + padding.bottom,
                        MeasureSpec.EXACTLY));
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        // Layout each of the TaskViews
        mTmpTaskViews.clear();
        mTmpTaskViews.addAll(getTaskViews());
        mTmpTaskViews.addAll(mViewPool.getViews());
        int taskViewCount = mTmpTaskViews.size();
        for (int i = 0; i < taskViewCount; i++) {
            layoutTaskView(changed, mTmpTaskViews.get(i));
        }
        if (mTaskViewFocusFrame != null) {
            mTaskViewFocusFrame.layout();
        }

        if (changed) {
            if (mStackScroller.isScrollOutOfBounds()) {
                mStackScroller.boundScroll();
            }
        }

        // Relayout all of the task views including the ignored ones
        relayoutTaskViews(AnimationProps.IMMEDIATE);
        clipTaskViews();

        if (!mFinishedLayoutAfterStackReload) {
            // Prepare the task enter animations (this can be called numerous times)
            mInitialState = INITIAL_STATE_UPDATE_NONE;
            onFirstLayout();

            if (mStackReloaded) {
                mFinishedLayoutAfterStackReload = true;
                tryStartEnterAnimation();
            }
        }
    }

    /**
     * Lays out a TaskView.
     */
    private void layoutTaskView(boolean changed, TaskView tv) {
        if (changed) {
            Rect padding = new Rect();
            if (tv.getBackground() != null) {
                tv.getBackground().getPadding(padding);
            }
            mTmpRect.set(mStableLayoutAlgorithm.getTaskRect());
            mTmpRect.union(mLayoutAlgorithm.getTaskRect());
            tv.cancelTransformAnimation();
            tv.layout(mTmpRect.left - padding.left, mTmpRect.top - padding.top,
                    mTmpRect.right + padding.right, mTmpRect.bottom + padding.bottom);
        } else {
            // If the layout has not changed, then just lay it out again in-place
            tv.layout(tv.getLeft(), tv.getTop(), tv.getRight(), tv.getBottom());
        }
    }

    /** Handler for the first layout. */
    void onFirstLayout() {
        // Setup the view for the enter animation
        mAnimationHelper.prepareForEnterAnimation();

        // Set the task focused state without requesting view focus, and leave the focus animations
        // until after the enter-animation
        RecentsConfiguration config = LegacyRecentsImpl.getConfiguration();
        RecentsActivityLaunchState launchState = config.getLaunchState();

        // We set the initial focused task view iff the following conditions are satisfied:
        // 1. Recents is showing task views in stack layout.
        // 2. Recents is launched with ALT + TAB.
        boolean setFocusOnFirstLayout = !useGridLayout() || launchState.launchedWithAltTab;
        if (setFocusOnFirstLayout) {
            int focusedTaskIndex = getInitialFocusTaskIndex(launchState, mStack.getTaskCount(),
                useGridLayout());
            if (focusedTaskIndex != -1) {
                setFocusedTask(focusedTaskIndex, false /* scrollToTask */,
                        false /* requestViewFocus */);
            }
        }
        updateStackActionButtonVisibility();
    }

    public boolean isTouchPointInView(float x, float y, TaskView tv) {
        mTmpRect.set(tv.getLeft(), tv.getTop(), tv.getRight(), tv.getBottom());
        mTmpRect.offset((int) tv.getTranslationX(), (int) tv.getTranslationY());
        return mTmpRect.contains((int) x, (int) y);
    }

    /**
     * Returns a non-ignored task in the {@param tasks} list that can be used as an achor when
     * calculating the scroll position before and after a layout change.
     */
    public Task findAnchorTask(List<Task> tasks, MutableBoolean isFrontMostTask) {
        for (int i = tasks.size() - 1; i >= 0; i--) {
            Task task = tasks.get(i);

            // Ignore deleting tasks
            if (isIgnoredTask(task)) {
                if (i == tasks.size() - 1) {
                    isFrontMostTask.value = true;
                }
                continue;
            }
            return task;
        }
        return null;
    }

    /**** TaskStackCallbacks Implementation ****/

    @Override
    public void onStackTaskAdded(TaskStack stack, Task newTask) {
        // Update the min/max scroll and animate other task views into their new positions
        updateLayoutAlgorithm(true /* boundScroll */);

        // Animate all the tasks into place
        relayoutTaskViews(!mFinishedLayoutAfterStackReload
                ? AnimationProps.IMMEDIATE
                : new AnimationProps(DEFAULT_SYNC_STACK_DURATION, Interpolators.FAST_OUT_SLOW_IN));
    }

    /**
     * We expect that the {@link TaskView} associated with the removed task is already hidden.
     */
    @Override
    public void onStackTaskRemoved(TaskStack stack, Task removedTask, Task newFrontMostTask,
            AnimationProps animation, boolean fromDockGesture, boolean dismissRecentsIfAllRemoved) {
        if (mFocusedTask == removedTask) {
            resetFocusedTask(removedTask);
        }

        // Remove the view associated with this task, we can't rely on updateTransforms
        // to work here because the task is no longer in the list
        TaskView tv = getChildViewForTask(removedTask);
        if (tv != null) {
            mViewPool.returnViewToPool(tv);
        }

        // Remove the task from the ignored set
        removeIgnoreTask(removedTask);

        // If requested, relayout with the given animation
        if (animation != null) {
            updateLayoutAlgorithm(true /* boundScroll */);
            relayoutTaskViews(animation);
        }

        // Update the new front most task's action button
        if (mScreenPinningEnabled && newFrontMostTask != null) {
            TaskView frontTv = getChildViewForTask(newFrontMostTask);
            if (frontTv != null) {
                frontTv.showActionButton(true /* fadeIn */, DEFAULT_SYNC_STACK_DURATION);
            }
        }

        // If there are no remaining tasks, then just close recents
        if (mStack.getTaskCount() == 0) {
            if (dismissRecentsIfAllRemoved) {
                EventBus.getDefault().send(new AllTaskViewsDismissedEvent(fromDockGesture
                        ? R.string.recents_empty_message
                        : R.string.recents_empty_message_dismissed_all));
            } else {
                EventBus.getDefault().send(new ShowEmptyViewEvent());
            }
        }
    }

    @Override
    public void onStackTasksRemoved(TaskStack stack) {
        // Reset the focused task
        resetFocusedTask(getFocusedTask());

        // Return all the views to the pool
        List<TaskView> taskViews = new ArrayList<>();
        taskViews.addAll(getTaskViews());
        for (int i = taskViews.size() - 1; i >= 0; i--) {
            mViewPool.returnViewToPool(taskViews.get(i));
        }

        // Remove all the ignore tasks
        mIgnoreTasks.clear();

        // If there are no remaining tasks, then just close recents
        EventBus.getDefault().send(new AllTaskViewsDismissedEvent(
                R.string.recents_empty_message_dismissed_all));
    }

    @Override
    public void onStackTasksUpdated(TaskStack stack) {
        if (!mFinishedLayoutAfterStackReload) {
            return;
        }

        // Update the layout and immediately layout
        updateLayoutAlgorithm(false /* boundScroll */);
        relayoutTaskViews(AnimationProps.IMMEDIATE);

        // Rebind all the task views.  This will not trigger new resources to be loaded
        // unless they have actually changed
        List<TaskView> taskViews = getTaskViews();
        int taskViewCount = taskViews.size();
        for (int i = 0; i < taskViewCount; i++) {
            TaskView tv = taskViews.get(i);
            bindTaskView(tv, tv.getTask());
        }
    }

    /**** ViewPoolConsumer Implementation ****/

    @Override
    public TaskView createView(Context context) {
        if (LegacyRecentsImpl.getConfiguration().isGridEnabled) {
            return (GridTaskView) mInflater.inflate(R.layout.recents_grid_task_view, this, false);
        } else {
            return (TaskView) mInflater.inflate(R.layout.recents_task_view, this, false);
        }
    }

    @Override
    public void onReturnViewToPool(TaskView tv) {
        final Task task = tv.getTask();

        // Unbind the task from the task view
        unbindTaskView(tv, task);

        // Reset the view properties and view state
        tv.clearAccessibilityFocus();
        tv.resetViewProperties();
        tv.setFocusedState(false, false /* requestViewFocus */);
        tv.setClipViewInStack(false);
        if (mScreenPinningEnabled) {
            tv.hideActionButton(false /* fadeOut */, 0 /* duration */, false /* scaleDown */, null);
        }

        // Detach the view from the hierarchy
        detachViewFromParent(tv);
        // Update the task views list after removing the task view
        updateTaskViewsList();
    }

    @Override
    public void onPickUpViewFromPool(TaskView tv, Task task, boolean isNewView) {
        // Find the index where this task should be placed in the stack
        int taskIndex = mStack.indexOfTask(task);
        int insertIndex = findTaskViewInsertIndex(task, taskIndex);

        // Add/attach the view to the hierarchy
        if (isNewView) {
            if (mInMeasureLayout) {
                // If we are measuring the layout, then just add the view normally as it will be
                // laid out during the layout pass
                addView(tv, insertIndex);
            } else {
                // Otherwise, this is from a bindVisibleTaskViews() call outside the measure/layout
                // pass, and we should layout the new child ourselves
                ViewGroup.LayoutParams params = tv.getLayoutParams();
                if (params == null) {
                    params = generateDefaultLayoutParams();
                }
                addViewInLayout(tv, insertIndex, params, true /* preventRequestLayout */);
                measureTaskView(tv);
                layoutTaskView(true /* changed */, tv);
            }
        } else {
            attachViewToParent(tv, insertIndex, tv.getLayoutParams());
        }
        // Update the task views list after adding the new task view
        updateTaskViewsList();

        // Bind the task view to the new task
        bindTaskView(tv, task);

        // Set the new state for this view, including the callbacks and view clipping
        tv.setCallbacks(this);
        tv.setTouchEnabled(true);
        tv.setClipViewInStack(true);
        if (mFocusedTask == task) {
            tv.setFocusedState(true, false /* requestViewFocus */);
            if (mStartTimerIndicatorDuration > 0) {
                // The timer indicator couldn't be started before, so start it now
                tv.getHeaderView().startFocusTimerIndicator(mStartTimerIndicatorDuration);
                mStartTimerIndicatorDuration = 0;
            }
        }

        // Restore the action button visibility if it is the front most task view
        if (mScreenPinningEnabled && tv.getTask() == mStack.getFrontMostTask()) {
            tv.showActionButton(false /* fadeIn */, 0 /* fadeInDuration */);
        }
    }

    @Override
    public boolean hasPreferredData(TaskView tv, Task preferredData) {
        return (tv.getTask() == preferredData);
    }

    private void bindTaskView(TaskView tv, Task task) {
        // Rebind the task and request that this task's data be filled into the TaskView
        tv.onTaskBound(task, mTouchExplorationEnabled, mDisplayOrientation, mDisplayRect);

        // If the doze trigger has already fired, then update the state for this task view
        if (mUIDozeTrigger.isAsleep() ||
                useGridLayout() || LegacyRecentsImpl.getConfiguration().isLowRamDevice) {
            tv.setNoUserInteractionState();
        }

        if (task == mPrefetchingTask) {
            task.notifyTaskDataLoaded(task.thumbnail, task.icon);
        } else {
            // Load the task data
            LegacyRecentsImpl.getTaskLoader().loadTaskData(task);
        }
        LegacyRecentsImpl.getTaskLoader().getHighResThumbnailLoader().onTaskVisible(task);
    }

    private void unbindTaskView(TaskView tv, Task task) {
        if (task != mPrefetchingTask) {
            // Report that this task's data is no longer being used
            LegacyRecentsImpl.getTaskLoader().unloadTaskData(task);
        }
        LegacyRecentsImpl.getTaskLoader().getHighResThumbnailLoader().onTaskInvisible(task);
    }

    private void updatePrefetchingTask(ArrayList<Task> tasks, int frontIndex, int backIndex) {
        Task t = null;
        boolean somethingVisible = frontIndex != -1 && backIndex != -1;
        if (somethingVisible && frontIndex < tasks.size() - 1) {
            t = tasks.get(frontIndex + 1);
        }
        if (mPrefetchingTask != t) {
            if (mPrefetchingTask != null) {
                int index = tasks.indexOf(mPrefetchingTask);
                if (index < backIndex || index > frontIndex) {
                    LegacyRecentsImpl.getTaskLoader().unloadTaskData(mPrefetchingTask);
                }
            }
            mPrefetchingTask = t;
            if (t != null) {
                LegacyRecentsImpl.getTaskLoader().loadTaskData(t);
            }
        }
    }

    private void clearPrefetchingTask() {
        if (mPrefetchingTask != null) {
            LegacyRecentsImpl.getTaskLoader().unloadTaskData(mPrefetchingTask);
        }
        mPrefetchingTask = null;
    }

    /**** TaskViewCallbacks Implementation ****/

    @Override
    public void onTaskViewClipStateChanged(TaskView tv) {
        if (!mTaskViewsClipDirty) {
            mTaskViewsClipDirty = true;
            invalidate();
        }
    }

    /**** TaskStackLayoutAlgorithm.TaskStackLayoutAlgorithmCallbacks ****/

    @Override
    public void onFocusStateChanged(int prevFocusState, int curFocusState) {
        if (mDeferredTaskViewLayoutAnimation == null) {
            mUIDozeTrigger.poke();
            relayoutTaskViewsOnNextFrame(AnimationProps.IMMEDIATE);
        }
    }

    /**** TaskStackViewScroller.TaskStackViewScrollerCallbacks ****/

    @Override
    public void onStackScrollChanged(float prevScroll, float curScroll, AnimationProps animation) {
        mUIDozeTrigger.poke();
        if (animation != null) {
            relayoutTaskViewsOnNextFrame(animation);
        }

        // In grid layout, the stack action button always remains visible.
        if (mEnterAnimationComplete && !useGridLayout()) {
            if (LegacyRecentsImpl.getConfiguration().isLowRamDevice) {
                // Show stack button when user drags down to show older tasks on low ram devices
                if (mStack.getTaskCount() > 0 && !mStackActionButtonVisible
                        && mTouchHandler.mIsScrolling && curScroll - prevScroll < 0) {
                    // Going up
                    EventBus.getDefault().send(
                            new ShowStackActionButtonEvent(true /* translate */));
                }
                return;
            }
            if (prevScroll > SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD &&
                    curScroll <= SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD &&
                    mStack.getTaskCount() > 0) {
                EventBus.getDefault().send(new ShowStackActionButtonEvent(true /* translate */));
            } else if (prevScroll < HIDE_STACK_ACTION_BUTTON_SCROLL_THRESHOLD &&
                    curScroll >= HIDE_STACK_ACTION_BUTTON_SCROLL_THRESHOLD) {
                EventBus.getDefault().send(new HideStackActionButtonEvent());
            }
        }
    }

    /**** EventBus Events ****/

    public final void onBusEvent(PackagesChangedEvent event) {
        // Compute which components need to be removed
        ArraySet<ComponentName> removedComponents = mStack.computeComponentsRemoved(
                event.packageName, event.userId);

        // For other tasks, just remove them directly if they no longer exist
        ArrayList<Task> tasks = mStack.getTasks();
        for (int i = tasks.size() - 1; i >= 0; i--) {
            final Task t = tasks.get(i);
            if (removedComponents.contains(t.key.getComponent())) {
                final TaskView tv = getChildViewForTask(t);
                if (tv != null) {
                    // For visible children, defer removing the task until after the animation
                    tv.dismissTask();
                } else {
                    // Otherwise, remove the task from the stack immediately
                    mStack.removeTask(t, AnimationProps.IMMEDIATE, false /* fromDockGesture */);
                }
            }
        }
    }

    public final void onBusEvent(LaunchTaskEvent event) {
        // Cancel any doze triggers once a task is launched
        mUIDozeTrigger.stopDozing();
    }

    public final void onBusEvent(LaunchMostRecentTaskRequestEvent event) {
        if (mStack.getTaskCount() > 0) {
            Task mostRecentTask = mStack.getFrontMostTask();
            launchTask(mostRecentTask);
        }
    }

    public final void onBusEvent(ShowStackActionButtonEvent event) {
        mStackActionButtonVisible = true;
    }

    public final void onBusEvent(HideStackActionButtonEvent event) {
        mStackActionButtonVisible = false;
    }

    public final void onBusEvent(LaunchNextTaskRequestEvent event) {
        if (!mFinishedLayoutAfterStackReload) {
            mLaunchNextAfterFirstMeasure = true;
            return;
        }

        if (mStack.getTaskCount() == 0) {
            if (RecentsImpl.getLastPipTime() != -1) {
                EventBus.getDefault().send(new ExpandPipEvent());
                MetricsLogger.action(getContext(), MetricsEvent.OVERVIEW_LAUNCH_PREVIOUS_TASK,
                        "pip");
            } else {
                // If there are no tasks, then just hide recents back to home.
                EventBus.getDefault().send(new HideRecentsEvent(false, true));
            }
            return;
        }

        if (!LegacyRecentsImpl.getConfiguration().getLaunchState().launchedFromPipApp
                && mStack.isNextLaunchTargetPip(RecentsImpl.getLastPipTime())) {
            // If the launch task is in the pinned stack, then expand the PiP now
            EventBus.getDefault().send(new ExpandPipEvent());
            MetricsLogger.action(getContext(), MetricsEvent.OVERVIEW_LAUNCH_PREVIOUS_TASK, "pip");
        } else {
            final Task launchTask = mStack.getNextLaunchTarget();
            if (launchTask != null) {
                // Defer launching the task until the PiP menu has been dismissed (if it is
                // showing at all)
                HidePipMenuEvent hideMenuEvent = new HidePipMenuEvent();
                hideMenuEvent.addPostAnimationCallback(() -> {
                    launchTask(launchTask);
                });
                EventBus.getDefault().send(hideMenuEvent);
                MetricsLogger.action(getContext(), MetricsEvent.OVERVIEW_LAUNCH_PREVIOUS_TASK,
                        launchTask.key.getComponent().toString());
            }
        }
    }

    public final void onBusEvent(LaunchTaskStartedEvent event) {
        mAnimationHelper.startLaunchTaskAnimation(event.taskView, event.screenPinningRequested,
                event.getAnimationTrigger());
    }

    public final void onBusEvent(DismissRecentsToHomeAnimationStarted event) {
        // Stop any scrolling
        mTouchHandler.cancelNonDismissTaskAnimations();
        mStackScroller.stopScroller();
        mStackScroller.stopBoundScrollAnimation();
        cancelDeferredTaskViewLayoutAnimation();

        // Start the task animations
        mAnimationHelper.startExitToHomeAnimation(event.animated, event.getAnimationTrigger());

        // Dismiss the grid task view focus frame
        if (mTaskViewFocusFrame != null) {
            mTaskViewFocusFrame.moveGridTaskViewFocus(null);
        }
    }

    public final void onBusEvent(DismissFocusedTaskViewEvent event) {
        if (mFocusedTask != null) {
            if (mTaskViewFocusFrame != null) {
                mTaskViewFocusFrame.moveGridTaskViewFocus(null);
            }
            TaskView tv = getChildViewForTask(mFocusedTask);
            if (tv != null) {
                tv.dismissTask();
            }
            resetFocusedTask(mFocusedTask);
        }
    }

    public final void onBusEvent(DismissTaskViewEvent event) {
        // For visible children, defer removing the task until after the animation
        mAnimationHelper.startDeleteTaskAnimation(
                event.taskView, useGridLayout(), event.getAnimationTrigger());
    }

    public final void onBusEvent(final DismissAllTaskViewsEvent event) {
        // Keep track of the tasks which will have their data removed
        ArrayList<Task> tasks = new ArrayList<>(mStack.getTasks());
        mAnimationHelper.startDeleteAllTasksAnimation(
                getTaskViews(), useGridLayout(), event.getAnimationTrigger());
        event.addPostAnimationCallback(new Runnable() {
            @Override
            public void run() {
                // Announce for accessibility
                announceForAccessibility(getContext().getString(
                        R.string.accessibility_recents_all_items_dismissed));

                // Remove all tasks and delete the task data for all tasks
                mStack.removeAllTasks(true /* notifyStackChanges */);
                for (int i = tasks.size() - 1; i >= 0; i--) {
                    EventBus.getDefault().send(new DeleteTaskDataEvent(tasks.get(i)));
                }

                MetricsLogger.action(getContext(), MetricsEvent.OVERVIEW_DISMISS_ALL);
            }
        });

    }

    public final void onBusEvent(TaskViewDismissedEvent event) {
        // Announce for accessibility
        announceForAccessibility(getContext().getString(
                R.string.accessibility_recents_item_dismissed, event.task.title));

        if (useGridLayout() && event.animation != null) {
            event.animation.setListener(new AnimatorListenerAdapter() {
                public void onAnimationEnd(Animator animator) {
                    if (mTaskViewFocusFrame != null) {
                        // Resize the grid layout task view focus frame
                        mTaskViewFocusFrame.resize();
                    }
                }
            });
        }

        // Remove the task from the stack
        mStack.removeTask(event.task, event.animation, false /* fromDockGesture */);
        EventBus.getDefault().send(new DeleteTaskDataEvent(event.task));
        if (mStack.getTaskCount() > 0 && LegacyRecentsImpl.getConfiguration().isLowRamDevice) {
            EventBus.getDefault().send(new ShowStackActionButtonEvent(false /* translate */));
        }

        MetricsLogger.action(getContext(), MetricsEvent.OVERVIEW_DISMISS,
                event.task.key.getComponent().toString());
    }

    public final void onBusEvent(FocusNextTaskViewEvent event) {
        // Stop any scrolling
        mStackScroller.stopScroller();
        mStackScroller.stopBoundScrollAnimation();

        setRelativeFocusedTask(true, false /* stackTasksOnly */, true /* animated */, false, 0);
    }

    public final void onBusEvent(FocusPreviousTaskViewEvent event) {
        // Stop any scrolling
        mStackScroller.stopScroller();
        mStackScroller.stopBoundScrollAnimation();

        setRelativeFocusedTask(false, false /* stackTasksOnly */, true /* animated */);
    }

    public final void onBusEvent(NavigateTaskViewEvent event) {
        if (useGridLayout()) {
            final int taskCount = mStack.getTaskCount();
            final int currentIndex = mStack.indexOfTask(getFocusedTask());
            final int nextIndex = mLayoutAlgorithm.mTaskGridLayoutAlgorithm.navigateFocus(taskCount,
                    currentIndex, event.direction);
            setFocusedTask(nextIndex, false, true);
        } else {
            switch (event.direction) {
                case UP:
                    EventBus.getDefault().send(new FocusPreviousTaskViewEvent());
                    break;
                case DOWN:
                    EventBus.getDefault().send(new FocusNextTaskViewEvent());
                    break;
            }
        }
    }

    public final void onBusEvent(UserInteractionEvent event) {
        // Poke the doze trigger on user interaction
        mUIDozeTrigger.poke();

        RecentsDebugFlags debugFlags = LegacyRecentsImpl.getDebugFlags();
        if (mFocusedTask != null) {
            TaskView tv = getChildViewForTask(mFocusedTask);
            if (tv != null) {
                tv.getHeaderView().cancelFocusTimerIndicator();
            }
        }
    }

    public final void onBusEvent(DragStartEvent event) {
        // Ensure that the drag task is not animated
        addIgnoreTask(event.task);

        // Enlarge the dragged view slightly
        float finalScale = event.taskView.getScaleX() * DRAG_SCALE_FACTOR;
        mLayoutAlgorithm.getStackTransform(event.task, getScroller().getStackScroll(),
                mTmpTransform, null);
        mTmpTransform.scale = finalScale;
        mTmpTransform.translationZ = mLayoutAlgorithm.mMaxTranslationZ + 1;
        mTmpTransform.dimAlpha = 0f;
        updateTaskViewToTransform(event.taskView, mTmpTransform,
                new AnimationProps(DRAG_SCALE_DURATION, Interpolators.FAST_OUT_SLOW_IN));
    }

    public final void onBusEvent(DragDropTargetChangedEvent event) {
        AnimationProps animation = new AnimationProps(SLOW_SYNC_STACK_DURATION,
                Interpolators.FAST_OUT_SLOW_IN);
        boolean ignoreTaskOverrides = false;
        if (event.dropTarget instanceof DockState) {
            // Calculate the new task stack bounds that matches the window size that Recents will
            // have after the drop
            final DockState dockState = (DockState) event.dropTarget;
            Rect systemInsets = new Rect(mStableLayoutAlgorithm.mSystemInsets);
            // When docked, the nav bar insets are consumed and the activity is measured without
            // insets.  However, the window bounds include the insets, so we need to subtract them
            // here to make them identical.
            int height = getMeasuredHeight();
            height -= systemInsets.bottom;
            systemInsets.bottom = 0;
            mStackBounds.set(dockState.getDockedTaskStackBounds(mDisplayRect, getMeasuredWidth(),
                    height, mDividerSize, systemInsets,
                    mLayoutAlgorithm, getResources(), mWindowRect));
            mLayoutAlgorithm.setSystemInsets(systemInsets);
            mLayoutAlgorithm.initialize(mDisplayRect, mWindowRect, mStackBounds);
            updateLayoutAlgorithm(true /* boundScroll */);
            ignoreTaskOverrides = true;
        } else {
            // Restore the pre-drag task stack bounds, but ensure that we don't layout the dragging
            // task view, so add it back to the ignore set after updating the layout
            removeIgnoreTask(event.task);
            updateLayoutToStableBounds();
            addIgnoreTask(event.task);
        }
        relayoutTaskViews(animation, null /* animationOverrides */, ignoreTaskOverrides);
    }

    public final void onBusEvent(final DragEndEvent event) {
        // We don't handle drops on the dock regions
        if (event.dropTarget instanceof DockState) {
            // However, we do need to reset the overrides, since the last state of this task stack
            // view layout was ignoring task overrides (see DragDropTargetChangedEvent handler)
            mLayoutAlgorithm.clearUnfocusedTaskOverrides();
            return;
        }

        // Restore the task, so that relayout will apply to it below
        removeIgnoreTask(event.task);

        // Convert the dragging task view back to its final layout-space rect
        Utilities.setViewFrameFromTranslation(event.taskView);

        // Animate all the tasks into place
        ArrayMap<Task, AnimationProps> animationOverrides = new ArrayMap<>();
        animationOverrides.put(event.task, new AnimationProps(SLOW_SYNC_STACK_DURATION,
                Interpolators.FAST_OUT_SLOW_IN,
                event.getAnimationTrigger().decrementOnAnimationEnd()));
        relayoutTaskViews(new AnimationProps(SLOW_SYNC_STACK_DURATION,
                Interpolators.FAST_OUT_SLOW_IN));
        event.getAnimationTrigger().increment();
    }

    public final void onBusEvent(final DragEndCancelledEvent event) {
        // Restore the pre-drag task stack bounds, including the dragging task view
        removeIgnoreTask(event.task);
        updateLayoutToStableBounds();

        // Convert the dragging task view back to its final layout-space rect
        Utilities.setViewFrameFromTranslation(event.taskView);

        // Animate all the tasks into place
        ArrayMap<Task, AnimationProps> animationOverrides = new ArrayMap<>();
        animationOverrides.put(event.task, new AnimationProps(SLOW_SYNC_STACK_DURATION,
                Interpolators.FAST_OUT_SLOW_IN,
                event.getAnimationTrigger().decrementOnAnimationEnd()));
        relayoutTaskViews(new AnimationProps(SLOW_SYNC_STACK_DURATION,
                Interpolators.FAST_OUT_SLOW_IN));
        event.getAnimationTrigger().increment();
    }

    public final void onBusEvent(EnterRecentsWindowAnimationCompletedEvent event) {
        mEnterAnimationComplete = true;
        tryStartEnterAnimation();
    }

    private void tryStartEnterAnimation() {
        if (!mStackReloaded || !mFinishedLayoutAfterStackReload || !mEnterAnimationComplete) {
            return;
        }

        if (mStack.getTaskCount() > 0) {
            // Start the task enter animations
            ReferenceCountedTrigger trigger = new ReferenceCountedTrigger();
            mAnimationHelper.startEnterAnimation(trigger);

            // Add a runnable to the post animation ref counter to clear all the views
            trigger.addLastDecrementRunnable(() -> {
                // Start the dozer to trigger to trigger any UI that shows after a timeout
                mUIDozeTrigger.startDozing();

                // Update the focused state here -- since we only set the focused task without
                // requesting view focus in onFirstLayout(), actually request view focus and
                // animate the focused state if we are alt-tabbing now, after the window enter
                // animation is completed
                if (mFocusedTask != null) {
                    RecentsConfiguration config = LegacyRecentsImpl.getConfiguration();
                    RecentsActivityLaunchState launchState = config.getLaunchState();
                    setFocusedTask(mStack.indexOfTask(mFocusedTask),
                            false /* scrollToTask */, launchState.launchedWithAltTab);
                    TaskView focusedTaskView = getChildViewForTask(mFocusedTask);
                    if (mTouchExplorationEnabled && focusedTaskView != null) {
                        focusedTaskView.requestAccessibilityFocus();
                    }
                }
            });
        }

        // This flag is only used to choreograph the enter animation, so we can reset it here
        mStackReloaded = false;
    }

    public final void onBusEvent(final MultiWindowStateChangedEvent event) {
        if (event.inMultiWindow || !event.showDeferredAnimation) {
            setTasks(event.stack, true /* allowNotifyStackChanges */);
        } else {
            // Reset the launch state before handling the multiwindow change
            RecentsActivityLaunchState launchState = LegacyRecentsImpl.getConfiguration().getLaunchState();
            launchState.reset();

            // Defer until the next frame to ensure that we have received all the system insets, and
            // initial layout updates
            event.getAnimationTrigger().increment();
            post(new Runnable() {
                @Override
                public void run() {
                    // Scroll the stack to the front to see the undocked task
                    mAnimationHelper.startNewStackScrollAnimation(event.stack,
                            event.getAnimationTrigger());
                    event.getAnimationTrigger().decrement();
                }
            });
        }
    }

    public final void onBusEvent(ConfigurationChangedEvent event) {
        if (event.fromDeviceOrientationChange) {
            mDisplayOrientation = Utilities.getAppConfiguration(mContext).orientation;
            mDisplayRect = LegacyRecentsImpl.getSystemServices().getDisplayRect();

            // Always stop the scroller, otherwise, we may continue setting the stack scroll to the
            // wrong bounds in the new layout
            mStackScroller.stopScroller();
        }
        reloadOnConfigurationChange();

        // Notify the task views of the configuration change so they can reload their resources
        if (!event.fromMultiWindow) {
            mTmpTaskViews.clear();
            mTmpTaskViews.addAll(getTaskViews());
            mTmpTaskViews.addAll(mViewPool.getViews());
            int taskViewCount = mTmpTaskViews.size();
            for (int i = 0; i < taskViewCount; i++) {
                mTmpTaskViews.get(i).onConfigurationChanged();
            }
        }

        // Update the Clear All button in case we're switching in or out of grid layout.
        updateStackActionButtonVisibility();

        // Trigger a new layout and update to the initial state if necessary. When entering split
        // screen, the multi-window configuration change event can happen after the stack is already
        // reloaded (but pending measure/layout), in this case, do not override the intiial state
        // and just wait for the upcoming measure/layout pass.
        if (event.fromMultiWindow && mInitialState == INITIAL_STATE_UPDATE_NONE) {
            mInitialState = INITIAL_STATE_UPDATE_LAYOUT_ONLY;
            requestLayout();
        } else if (event.fromDeviceOrientationChange) {
            mInitialState = INITIAL_STATE_UPDATE_ALL;
            requestLayout();
        }
    }

    public final void onBusEvent(RecentsGrowingEvent event) {
        mResetToInitialStateWhenResized = true;
    }

    public final void onBusEvent(RecentsVisibilityChangedEvent event) {
        if (!event.visible) {
            if (mTaskViewFocusFrame != null) {
                mTaskViewFocusFrame.moveGridTaskViewFocus(null);
            }

            List<TaskView> taskViews = new ArrayList<>(getTaskViews());
            for (int i = 0; i < taskViews.size(); i++) {
                mViewPool.returnViewToPool(taskViews.get(i));
            }
            clearPrefetchingTask();

            // We can not reset mEnterAnimationComplete in onReload() because when docking the top
            // task, we can receive the enter animation callback before onReload(), so reset it
            // here onces Recents is not visible
            mEnterAnimationComplete = false;
        }
    }

    public final void onBusEvent(ActivityPinnedEvent event) {
        // If an activity enters PiP while Recents is open, remove the stack task associated with
        // the new PiP task
        Task removeTask = mStack.findTaskWithId(event.taskId);
        if (removeTask != null) {
            // In this case, we remove the task, but if the last task is removed, don't dismiss
            // Recents to home
            mStack.removeTask(removeTask, AnimationProps.IMMEDIATE, false /* fromDockGesture */,
                    false /* dismissRecentsIfAllRemoved */);
        }
        updateLayoutAlgorithm(false /* boundScroll */);
        updateToInitialState();
    }

    public void reloadOnConfigurationChange() {
        mStableLayoutAlgorithm.reloadOnConfigurationChange(getContext());
        mLayoutAlgorithm.reloadOnConfigurationChange(getContext());
    }

    /**
     * Returns the insert index for the task in the current set of task views. If the given task
     * is already in the task view list, then this method returns the insert index assuming it
     * is first removed at the previous index.
     *
     * @param task the task we are finding the index for
     * @param taskIndex the index of the task in the stack
     */
    private int findTaskViewInsertIndex(Task task, int taskIndex) {
        if (taskIndex != -1) {
            List<TaskView> taskViews = getTaskViews();
            boolean foundTaskView = false;
            int taskViewCount = taskViews.size();
            for (int i = 0; i < taskViewCount; i++) {
                Task tvTask = taskViews.get(i).getTask();
                if (tvTask == task) {
                    foundTaskView = true;
                } else if (taskIndex < mStack.indexOfTask(tvTask)) {
                    if (foundTaskView) {
                        return i - 1;
                    } else {
                        return i;
                    }
                }
            }
        }
        return -1;
    }

    private void launchTask(Task task) {
        // Stop all animations
        cancelAllTaskViewAnimations();

        float curScroll = mStackScroller.getStackScroll();
        float targetScroll = mLayoutAlgorithm.getStackScrollForTaskAtInitialOffset(task);
        float absScrollDiff = Math.abs(targetScroll - curScroll);
        if (getChildViewForTask(task) == null || absScrollDiff > 0.35f) {
            int duration = (int) (LAUNCH_NEXT_SCROLL_BASE_DURATION +
                    absScrollDiff * LAUNCH_NEXT_SCROLL_INCR_DURATION);
            mStackScroller.animateScroll(targetScroll,
                    duration, new Runnable() {
                        @Override
                        public void run() {
                            EventBus.getDefault().send(new LaunchTaskEvent(
                                    getChildViewForTask(task), task, null,
                                    false /* screenPinningRequested */));
                        }
                    });
        } else {
            EventBus.getDefault().send(new LaunchTaskEvent(getChildViewForTask(task), task, null,
                    false /* screenPinningRequested */));
        }
    }

    /**
     * Check whether we should use the grid layout.
     */
    public boolean useGridLayout() {
        return mLayoutAlgorithm.useGridLayout();
    }

    /**
     * Reads current system flags related to accessibility and screen pinning.
     */
    private void readSystemFlags() {
        SystemServicesProxy ssp = LegacyRecentsImpl.getSystemServices();
        mTouchExplorationEnabled = ssp.isTouchExplorationEnabled();
        mScreenPinningEnabled = ActivityManagerWrapper.getInstance().isScreenPinningEnabled()
                && !ActivityManagerWrapper.getInstance().isLockToAppActive();
    }

    private void updateStackActionButtonVisibility() {
        if (LegacyRecentsImpl.getConfiguration().isLowRamDevice) {
            return;
        }

        // Always show the button in grid layout.
        if (useGridLayout() ||
                (mStackScroller.getStackScroll() < SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD &&
                        mStack.getTaskCount() > 0)) {
            EventBus.getDefault().send(new ShowStackActionButtonEvent(false /* translate */));
        } else {
            EventBus.getDefault().send(new HideStackActionButtonEvent());
        }
    }

    /**
     * Returns the task to focus given the current launch state.
     */
    private int getInitialFocusTaskIndex(RecentsActivityLaunchState launchState, int numTasks,
            boolean useGridLayout) {
        if (launchState.launchedFromApp) {
            if (useGridLayout) {
                // If coming from another app to the grid layout, focus the front most task
                return numTasks - 1;
            }

            // If coming from another app, focus the next task
            return Math.max(0, numTasks - 2);
        } else {
            // If coming from home, focus the front most task
            return numTasks - 1;
        }
    }

    /**
     * Updates {@param transforms} to be the same size as {@param tasks}.
     */
    private void matchTaskListSize(List<Task> tasks, List<TaskViewTransform> transforms) {
        // We can reuse the task transforms where possible to reduce object allocation
        int taskTransformCount = transforms.size();
        int taskCount = tasks.size();
        if (taskTransformCount < taskCount) {
            // If there are less transforms than tasks, then add as many transforms as necessary
            for (int i = taskTransformCount; i < taskCount; i++) {
                transforms.add(new TaskViewTransform());
            }
        } else if (taskTransformCount > taskCount) {
            // If there are more transforms than tasks, then just subset the transform list
            transforms.subList(taskCount, taskTransformCount).clear();
        }
    }

    public void dump(String prefix, PrintWriter writer) {
        String innerPrefix = prefix + "  ";
        String id = Integer.toHexString(System.identityHashCode(this));

        writer.print(prefix); writer.print(TAG);
        writer.print(" hasDefRelayout=");
        writer.print(mDeferredTaskViewLayoutAnimation != null ? "Y" : "N");
        writer.print(" clipDirty="); writer.print(mTaskViewsClipDirty ? "Y" : "N");
        writer.print(" awaitingStackReload="); writer.print(mFinishedLayoutAfterStackReload ? "Y" : "N");
        writer.print(" initialState="); writer.print(mInitialState);
        writer.print(" inMeasureLayout="); writer.print(mInMeasureLayout ? "Y" : "N");
        writer.print(" enterAnimCompleted="); writer.print(mEnterAnimationComplete ? "Y" : "N");
        writer.print(" touchExplorationOn="); writer.print(mTouchExplorationEnabled ? "Y" : "N");
        writer.print(" screenPinningOn="); writer.print(mScreenPinningEnabled ? "Y" : "N");
        writer.print(" numIgnoreTasks="); writer.print(mIgnoreTasks.size());
        writer.print(" numViewPool="); writer.print(mViewPool.getViews().size());
        writer.print(" stableStackBounds="); writer.print(
                Utilities.dumpRect(mStableStackBounds));
        writer.print(" stackBounds="); writer.print(
                Utilities.dumpRect(mStackBounds));
        writer.print(" stableWindow="); writer.print(
                Utilities.dumpRect(mStableWindowRect));
        writer.print(" window="); writer.print(Utilities.dumpRect(mWindowRect));
        writer.print(" display="); writer.print(Utilities.dumpRect(mDisplayRect));
        writer.print(" orientation="); writer.print(mDisplayOrientation);
        writer.print(" [0x"); writer.print(id); writer.print("]");
        writer.println();

        if (mFocusedTask != null) {
            writer.print(innerPrefix);
            writer.print("Focused task: ");
            mFocusedTask.dump("", writer);
        }

        int numTaskViews = mTaskViews.size();
        for (int i = 0; i < numTaskViews; i++) {
            mTaskViews.get(i).dump(innerPrefix, writer);
        }

        mLayoutAlgorithm.dump(innerPrefix, writer);
        mStackScroller.dump(innerPrefix, writer);
    }
}
