/*
 * 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 static android.app.ActivityManager.StackId.INVALID_STACK_ID;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Outline;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.FloatProperty;
import android.util.Property;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewDebug;
import android.view.ViewOutlineProvider;
import android.widget.TextView;
import android.widget.Toast;

import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.RecentsActivity;
import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.activity.LaunchTaskEvent;
import com.android.systemui.recents.events.ui.DismissTaskViewEvent;
import com.android.systemui.recents.events.ui.TaskViewDismissedEvent;
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.misc.ReferenceCountedTrigger;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.misc.Utilities;
import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.model.TaskStack;
import com.android.systemui.recents.model.ThumbnailData;

import java.io.PrintWriter;
import java.util.ArrayList;

/**
 * A {@link TaskView} represents a fixed view of a task. Because the TaskView's layout is directed
 * solely by the {@link TaskStackView}, we make it a fixed size layout which allows relayouts down
 * the view hierarchy, but not upwards from any of its children (the TaskView will relayout itself
 * with the previous bounds if any child requests layout).
 */
public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks,
        TaskStackAnimationHelper.Callbacks, View.OnClickListener, View.OnLongClickListener {

    /** The TaskView callbacks */
    interface TaskViewCallbacks {
        void onTaskViewClipStateChanged(TaskView tv);
    }

    /**
     * The dim overlay is generally calculated from the task progress, but occasionally (like when
     * launching) needs to be animated independently of the task progress.  This call is only used
     * when animating the task into Recents, when the header dim is already applied
     */
    public static final Property<TaskView, Float> DIM_ALPHA_WITHOUT_HEADER =
            new FloatProperty<TaskView>("dimAlphaWithoutHeader") {
                @Override
                public void setValue(TaskView tv, float dimAlpha) {
                    tv.setDimAlphaWithoutHeader(dimAlpha);
                }

                @Override
                public Float get(TaskView tv) {
                    return tv.getDimAlpha();
                }
            };

    /**
     * The dim overlay is generally calculated from the task progress, but occasionally (like when
     * launching) needs to be animated independently of the task progress.
     */
    public static final Property<TaskView, Float> DIM_ALPHA =
            new FloatProperty<TaskView>("dimAlpha") {
                @Override
                public void setValue(TaskView tv, float dimAlpha) {
                    tv.setDimAlpha(dimAlpha);
                }

                @Override
                public Float get(TaskView tv) {
                    return tv.getDimAlpha();
                }
            };

    /**
     * The dim overlay is generally calculated from the task progress, but occasionally (like when
     * launching) needs to be animated independently of the task progress.
     */
    public static final Property<TaskView, Float> VIEW_OUTLINE_ALPHA =
            new FloatProperty<TaskView>("viewOutlineAlpha") {
                @Override
                public void setValue(TaskView tv, float alpha) {
                    tv.getViewBounds().setAlpha(alpha);
                }

                @Override
                public Float get(TaskView tv) {
                    return tv.getViewBounds().getAlpha();
                }
            };

    @ViewDebug.ExportedProperty(category="recents")
    private float mDimAlpha;
    private float mActionButtonTranslationZ;

    @ViewDebug.ExportedProperty(deepExport=true, prefix="task_")
    private Task mTask;
    @ViewDebug.ExportedProperty(category="recents")
    private boolean mClipViewInStack = true;
    @ViewDebug.ExportedProperty(category="recents")
    private boolean mTouchExplorationEnabled;
    @ViewDebug.ExportedProperty(category="recents")
    private boolean mIsDisabledInSafeMode;
    @ViewDebug.ExportedProperty(deepExport=true, prefix="view_bounds_")
    private AnimateableViewBounds mViewBounds;

    private AnimatorSet mTransformAnimation;
    private ObjectAnimator mDimAnimator;
    private ObjectAnimator mOutlineAnimator;
    private final TaskViewTransform mTargetAnimationTransform = new TaskViewTransform();
    private ArrayList<Animator> mTmpAnimators = new ArrayList<>();

    @ViewDebug.ExportedProperty(deepExport=true, prefix="thumbnail_")
    protected TaskViewThumbnail mThumbnailView;
    @ViewDebug.ExportedProperty(deepExport=true, prefix="header_")
    protected TaskViewHeader mHeaderView;
    private View mActionButtonView;
    private View mIncompatibleAppToastView;
    private TaskViewCallbacks mCb;

    @ViewDebug.ExportedProperty(category="recents")
    private Point mDownTouchPos = new Point();

    private Toast mDisabledAppToast;

    public TaskView(Context context) {
        this(context, null);
    }

    public TaskView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public TaskView(Context context, AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

    public TaskView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        RecentsConfiguration config = Recents.getConfiguration();
        Resources res = context.getResources();
        mViewBounds = createOutlineProvider();
        if (config.fakeShadows) {
            setBackground(new FakeShadowDrawable(res, config));
        }
        setOutlineProvider(mViewBounds);
        setOnLongClickListener(this);
        setAccessibilityDelegate(new TaskViewAccessibilityDelegate(this));
    }

    /** Set callback */
    void setCallbacks(TaskViewCallbacks cb) {
        mCb = cb;
    }

    /**
     * Called from RecentsActivity when it is relaunched.
     */
    void onReload(boolean isResumingFromVisible) {
        if (!Recents.getSystemServices().hasFreeformWorkspaceSupport()) {
            resetNoUserInteractionState();
        }
        if (!isResumingFromVisible) {
            resetViewProperties();
        }
    }

    /** Gets the task */
    public Task getTask() {
        return mTask;
    }

    /* Create an outline provider to clip and outline the view */
    protected AnimateableViewBounds createOutlineProvider() {
        return new AnimateableViewBounds(this, mContext.getResources().getDimensionPixelSize(
            R.dimen.recents_task_view_shadow_rounded_corners_radius));
    }

    /** Returns the view bounds. */
    AnimateableViewBounds getViewBounds() {
        return mViewBounds;
    }

    @Override
    protected void onFinishInflate() {
        // Bind the views
        mHeaderView = findViewById(R.id.task_view_bar);
        mThumbnailView = findViewById(R.id.task_view_thumbnail);
        mThumbnailView.updateClipToTaskBar(mHeaderView);
        mActionButtonView = findViewById(R.id.lock_to_app_fab);
        mActionButtonView.setOutlineProvider(new ViewOutlineProvider() {
            @Override
            public void getOutline(View view, Outline outline) {
                // Set the outline to match the FAB background
                outline.setOval(0, 0, mActionButtonView.getWidth(), mActionButtonView.getHeight());
                outline.setAlpha(0.35f);
            }
        });
        mActionButtonView.setOnClickListener(this);
        mActionButtonTranslationZ = mActionButtonView.getTranslationZ();
    }

    /**
     * Update the task view when the configuration changes.
     */
    protected void onConfigurationChanged() {
        mHeaderView.onConfigurationChanged();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        if (w > 0 && h > 0) {
            mHeaderView.onTaskViewSizeChanged(w, h);
            mThumbnailView.onTaskViewSizeChanged(w, h);

            mActionButtonView.setTranslationX(w - getMeasuredWidth());
            mActionButtonView.setTranslationY(h - getMeasuredHeight());
        }
    }

    @Override
    public boolean hasOverlappingRendering() {
        return false;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            mDownTouchPos.set((int) (ev.getX() * getScaleX()), (int) (ev.getY() * getScaleY()));
        }
        return super.onInterceptTouchEvent(ev);
    }

    @Override
    protected void measureContents(int width, int height) {
        int widthWithoutPadding = width - mPaddingLeft - mPaddingRight;
        int heightWithoutPadding = height - mPaddingTop - mPaddingBottom;
        int widthSpec = MeasureSpec.makeMeasureSpec(widthWithoutPadding, MeasureSpec.EXACTLY);
        int heightSpec = MeasureSpec.makeMeasureSpec(heightWithoutPadding, MeasureSpec.EXACTLY);

        // Measure the content
        measureChildren(widthSpec, heightSpec);

        setMeasuredDimension(width, height);
    }

    void updateViewPropertiesToTaskTransform(TaskViewTransform toTransform,
            AnimationProps toAnimation, ValueAnimator.AnimatorUpdateListener updateCallback) {
        RecentsConfiguration config = Recents.getConfiguration();
        cancelTransformAnimation();

        // Compose the animations for the transform
        mTmpAnimators.clear();
        toTransform.applyToTaskView(this, mTmpAnimators, toAnimation, !config.fakeShadows);
        if (toAnimation.isImmediate()) {
            if (Float.compare(getDimAlpha(), toTransform.dimAlpha) != 0) {
                setDimAlpha(toTransform.dimAlpha);
            }
            if (Float.compare(mViewBounds.getAlpha(), toTransform.viewOutlineAlpha) != 0) {
                mViewBounds.setAlpha(toTransform.viewOutlineAlpha);
            }
            // Manually call back to the animator listener and update callback
            if (toAnimation.getListener() != null) {
                toAnimation.getListener().onAnimationEnd(null);
            }
            if (updateCallback != null) {
                updateCallback.onAnimationUpdate(null);
            }
        } else {
            // Both the progress and the update are a function of the bounds movement of the task
            if (Float.compare(getDimAlpha(), toTransform.dimAlpha) != 0) {
                mDimAnimator = ObjectAnimator.ofFloat(this, DIM_ALPHA, getDimAlpha(),
                        toTransform.dimAlpha);
                mTmpAnimators.add(toAnimation.apply(AnimationProps.BOUNDS, mDimAnimator));
            }
            if (Float.compare(mViewBounds.getAlpha(), toTransform.viewOutlineAlpha) != 0) {
                mOutlineAnimator = ObjectAnimator.ofFloat(this, VIEW_OUTLINE_ALPHA,
                        mViewBounds.getAlpha(), toTransform.viewOutlineAlpha);
                mTmpAnimators.add(toAnimation.apply(AnimationProps.BOUNDS, mOutlineAnimator));
            }
            if (updateCallback != null) {
                ValueAnimator updateCallbackAnim = ValueAnimator.ofInt(0, 1);
                updateCallbackAnim.addUpdateListener(updateCallback);
                mTmpAnimators.add(toAnimation.apply(AnimationProps.BOUNDS, updateCallbackAnim));
            }

            // Create the animator
            mTransformAnimation = toAnimation.createAnimator(mTmpAnimators);
            mTransformAnimation.start();
            mTargetAnimationTransform.copyFrom(toTransform);
        }
    }

    /** Resets this view's properties */
    void resetViewProperties() {
        cancelTransformAnimation();
        setDimAlpha(0);
        setVisibility(View.VISIBLE);
        getViewBounds().reset();
        getHeaderView().reset();
        TaskViewTransform.reset(this);

        mActionButtonView.setScaleX(1f);
        mActionButtonView.setScaleY(1f);
        mActionButtonView.setAlpha(0f);
        mActionButtonView.setTranslationX(0f);
        mActionButtonView.setTranslationY(0f);
        mActionButtonView.setTranslationZ(mActionButtonTranslationZ);
        if (mIncompatibleAppToastView != null) {
            mIncompatibleAppToastView.setVisibility(View.INVISIBLE);
        }
    }

    /**
     * @return whether we are animating towards {@param transform}
     */
    boolean isAnimatingTo(TaskViewTransform transform) {
        return mTransformAnimation != null && mTransformAnimation.isStarted()
                && mTargetAnimationTransform.isSame(transform);
    }

    /**
     * Cancels any current transform animations.
     */
    public void cancelTransformAnimation() {
        Utilities.cancelAnimationWithoutCallbacks(mTransformAnimation);
        Utilities.cancelAnimationWithoutCallbacks(mDimAnimator);
        Utilities.cancelAnimationWithoutCallbacks(mOutlineAnimator);
    }

    /** Enables/disables handling touch on this task view. */
    public void setTouchEnabled(boolean enabled) {
        setOnClickListener(enabled ? this : null);
    }

    /** Animates this task view if the user does not interact with the stack after a certain time. */
    public void startNoUserInteractionAnimation() {
        mHeaderView.startNoUserInteractionAnimation();
    }

    /** Mark this task view that the user does has not interacted with the stack after a certain time. */
    void setNoUserInteractionState() {
        mHeaderView.setNoUserInteractionState();
    }

    /** Resets the state tracking that the user has not interacted with the stack after a certain time. */
    void resetNoUserInteractionState() {
        mHeaderView.resetNoUserInteractionState();
    }

    /** Dismisses this task. */
    void dismissTask() {
        // Animate out the view and call the callback
        final TaskView tv = this;
        DismissTaskViewEvent dismissEvent = new DismissTaskViewEvent(tv);
        dismissEvent.addPostAnimationCallback(new Runnable() {
            @Override
            public void run() {
                EventBus.getDefault().send(new TaskViewDismissedEvent(mTask, tv,
                        new AnimationProps(TaskStackView.DEFAULT_SYNC_STACK_DURATION,
                                Interpolators.FAST_OUT_SLOW_IN)));
            }
        });
        EventBus.getDefault().send(dismissEvent);
    }

    /**
     * Returns whether this view should be clipped, or any views below should clip against this
     * view.
     */
    boolean shouldClipViewInStack() {
        // Never clip for freeform tasks or if invisible
        if (mTask.isFreeformTask() || getVisibility() != View.VISIBLE) {
            return false;
        }
        return mClipViewInStack;
    }

    /** Sets whether this view should be clipped, or clipped against. */
    void setClipViewInStack(boolean clip) {
        if (clip != mClipViewInStack) {
            mClipViewInStack = clip;
            if (mCb != null) {
                mCb.onTaskViewClipStateChanged(this);
            }
        }
    }

    public TaskViewHeader getHeaderView() {
        return mHeaderView;
    }

    /**
     * Sets the current dim.
     */
    public void setDimAlpha(float dimAlpha) {
        mDimAlpha = dimAlpha;
        mThumbnailView.setDimAlpha(dimAlpha);
        mHeaderView.setDimAlpha(dimAlpha);
    }

    /**
     * Sets the current dim without updating the header's dim.
     */
    public void setDimAlphaWithoutHeader(float dimAlpha) {
        mDimAlpha = dimAlpha;
        mThumbnailView.setDimAlpha(dimAlpha);
    }

    /**
     * Returns the current dim.
     */
    public float getDimAlpha() {
        return mDimAlpha;
    }

    /**
     * Explicitly sets the focused state of this task.
     */
    public void setFocusedState(boolean isFocused, boolean requestViewFocus) {
        if (isFocused) {
            if (requestViewFocus && !isFocused()) {
                requestFocus();
            }
        } else {
            if (isAccessibilityFocused() && mTouchExplorationEnabled) {
                clearAccessibilityFocus();
            }
        }
    }

    /**
     * Shows the action button.
     * @param fadeIn whether or not to animate the action button in.
     * @param fadeInDuration the duration of the action button animation, only used if
     *                       {@param fadeIn} is true.
     */
    public void showActionButton(boolean fadeIn, int fadeInDuration) {
        mActionButtonView.setVisibility(View.VISIBLE);

        if (fadeIn && mActionButtonView.getAlpha() < 1f) {
            mActionButtonView.animate()
                    .alpha(1f)
                    .scaleX(1f)
                    .scaleY(1f)
                    .setDuration(fadeInDuration)
                    .setInterpolator(Interpolators.ALPHA_IN)
                    .start();
        } else {
            mActionButtonView.setScaleX(1f);
            mActionButtonView.setScaleY(1f);
            mActionButtonView.setAlpha(1f);
            mActionButtonView.setTranslationZ(mActionButtonTranslationZ);
        }
    }

    /**
     * Immediately hides the action button.
     *
     * @param fadeOut whether or not to animate the action button out.
     */
    public void hideActionButton(boolean fadeOut, int fadeOutDuration, boolean scaleDown,
            final Animator.AnimatorListener animListener) {
        if (fadeOut && mActionButtonView.getAlpha() > 0f) {
            if (scaleDown) {
                float toScale = 0.9f;
                mActionButtonView.animate()
                        .scaleX(toScale)
                        .scaleY(toScale);
            }
            mActionButtonView.animate()
                    .alpha(0f)
                    .setDuration(fadeOutDuration)
                    .setInterpolator(Interpolators.ALPHA_OUT)
                    .withEndAction(new Runnable() {
                        @Override
                        public void run() {
                            if (animListener != null) {
                                animListener.onAnimationEnd(null);
                            }
                            mActionButtonView.setVisibility(View.INVISIBLE);
                        }
                    })
                    .start();
        } else {
            mActionButtonView.setAlpha(0f);
            mActionButtonView.setVisibility(View.INVISIBLE);
            if (animListener != null) {
                animListener.onAnimationEnd(null);
            }
        }
    }

    /**** TaskStackAnimationHelper.Callbacks Implementation ****/

    @Override
    public void onPrepareLaunchTargetForEnterAnimation() {
        // These values will be animated in when onStartLaunchTargetEnterAnimation() is called
        setDimAlphaWithoutHeader(0);
        mActionButtonView.setAlpha(0f);
        if (mIncompatibleAppToastView != null &&
                mIncompatibleAppToastView.getVisibility() == View.VISIBLE) {
            mIncompatibleAppToastView.setAlpha(0f);
        }
    }

    @Override
    public void onStartLaunchTargetEnterAnimation(TaskViewTransform transform, int duration,
            boolean screenPinningEnabled, ReferenceCountedTrigger postAnimationTrigger) {
        Utilities.cancelAnimationWithoutCallbacks(mDimAnimator);

        // Dim the view after the app window transitions down into recents
        postAnimationTrigger.increment();
        AnimationProps animation = new AnimationProps(duration, Interpolators.ALPHA_OUT);
        mDimAnimator = animation.apply(AnimationProps.DIM_ALPHA, ObjectAnimator.ofFloat(this,
                DIM_ALPHA_WITHOUT_HEADER, getDimAlpha(), transform.dimAlpha));
        mDimAnimator.addListener(postAnimationTrigger.decrementOnAnimationEnd());
        mDimAnimator.start();

        if (screenPinningEnabled) {
            showActionButton(true /* fadeIn */, duration /* fadeInDuration */);
        }

        if (mIncompatibleAppToastView != null &&
                mIncompatibleAppToastView.getVisibility() == View.VISIBLE) {
            mIncompatibleAppToastView.animate()
                    .alpha(1f)
                    .setDuration(duration)
                    .setInterpolator(Interpolators.ALPHA_IN)
                    .start();
        }
    }

    @Override
    public void onStartLaunchTargetLaunchAnimation(int duration, boolean screenPinningRequested,
            ReferenceCountedTrigger postAnimationTrigger) {
        Utilities.cancelAnimationWithoutCallbacks(mDimAnimator);

        // Un-dim the view before/while launching the target
        AnimationProps animation = new AnimationProps(duration, Interpolators.ALPHA_OUT);
        mDimAnimator = animation.apply(AnimationProps.DIM_ALPHA, ObjectAnimator.ofFloat(this,
                DIM_ALPHA, getDimAlpha(), 0));
        mDimAnimator.start();

        postAnimationTrigger.increment();
        hideActionButton(true /* fadeOut */, duration,
                !screenPinningRequested /* scaleDown */,
                postAnimationTrigger.decrementOnAnimationEnd());
    }

    @Override
    public void onStartFrontTaskEnterAnimation(boolean screenPinningEnabled) {
        if (screenPinningEnabled) {
            showActionButton(false /* fadeIn */, 0 /* fadeInDuration */);
        }
    }

    /**** TaskCallbacks Implementation ****/

    public void onTaskBound(Task t, boolean touchExplorationEnabled, int displayOrientation,
            Rect displayRect) {
        SystemServicesProxy ssp = Recents.getSystemServices();
        mTouchExplorationEnabled = touchExplorationEnabled;
        mTask = t;
        mTask.addCallback(this);
        mIsDisabledInSafeMode = !mTask.isSystemApp && ssp.isInSafeMode();
        mThumbnailView.bindToTask(mTask, mIsDisabledInSafeMode, displayOrientation, displayRect);
        mHeaderView.bindToTask(mTask, mTouchExplorationEnabled, mIsDisabledInSafeMode);

        if (!t.isDockable && ssp.hasDockedTask()) {
            if (mIncompatibleAppToastView == null) {
                mIncompatibleAppToastView = Utilities.findViewStubById(this,
                        R.id.incompatible_app_toast_stub).inflate();
                TextView msg = findViewById(com.android.internal.R.id.message);
                msg.setText(R.string.dock_non_resizeble_failed_to_dock_text);
            }
            mIncompatibleAppToastView.setVisibility(View.VISIBLE);
        } else if (mIncompatibleAppToastView != null) {
            mIncompatibleAppToastView.setVisibility(View.INVISIBLE);
        }
    }

    @Override
    public void onTaskDataLoaded(Task task, ThumbnailData thumbnailData) {
        // Update each of the views to the new task data
        mThumbnailView.onTaskDataLoaded(thumbnailData);
        mHeaderView.onTaskDataLoaded();
    }

    @Override
    public void onTaskDataUnloaded() {
        // Unbind each of the views from the task and remove the task callback
        mTask.removeCallback(this);
        mThumbnailView.unbindFromTask();
        mHeaderView.unbindFromTask(mTouchExplorationEnabled);
    }

    @Override
    public void onTaskStackIdChanged() {
        // Force rebind the header, the thumbnail does not change due to stack changes
        mHeaderView.bindToTask(mTask, mTouchExplorationEnabled, mIsDisabledInSafeMode);
        mHeaderView.onTaskDataLoaded();
    }

    /**** View.OnClickListener Implementation ****/

    @Override
     public void onClick(final View v) {
        if (mIsDisabledInSafeMode) {
            Context context = getContext();
            String msg = context.getString(R.string.recents_launch_disabled_message, mTask.title);
            if (mDisabledAppToast != null) {
                mDisabledAppToast.cancel();
            }
            mDisabledAppToast = Toast.makeText(context, msg, Toast.LENGTH_SHORT);
            mDisabledAppToast.show();
            return;
        }

        boolean screenPinningRequested = false;
        if (v == mActionButtonView) {
            // Reset the translation of the action button before we animate it out
            mActionButtonView.setTranslationZ(0f);
            screenPinningRequested = true;
        }
        EventBus.getDefault().send(new LaunchTaskEvent(this, mTask, null, INVALID_STACK_ID,
                screenPinningRequested));

        MetricsLogger.action(v.getContext(), MetricsEvent.ACTION_OVERVIEW_SELECT,
                mTask.key.getComponent().toString());
    }

    /**** View.OnLongClickListener Implementation ****/

    @Override
    public boolean onLongClick(View v) {
        SystemServicesProxy ssp = Recents.getSystemServices();
        boolean inBounds = false;
        Rect clipBounds = new Rect(mViewBounds.mClipBounds);
        if (!clipBounds.isEmpty()) {
            // If we are clipping the view to the bounds, manually do the hit test.
            clipBounds.scale(getScaleX());
            inBounds = clipBounds.contains(mDownTouchPos.x, mDownTouchPos.y);
        } else {
            // Otherwise just make sure we're within the view's bounds.
            inBounds = mDownTouchPos.x <= getWidth() && mDownTouchPos.y <= getHeight();
        }
        if (v == this && inBounds && !ssp.hasDockedTask()) {
            // Start listening for drag events
            setClipViewInStack(false);

            mDownTouchPos.x += ((1f - getScaleX()) * getWidth()) / 2;
            mDownTouchPos.y += ((1f - getScaleY()) * getHeight()) / 2;

            EventBus.getDefault().register(this, RecentsActivity.EVENT_BUS_PRIORITY + 1);
            EventBus.getDefault().send(new DragStartEvent(mTask, this, mDownTouchPos));
            return true;
        }
        return false;
    }

    /**** Events ****/

    public final void onBusEvent(DragEndEvent event) {
        if (!(event.dropTarget instanceof TaskStack.DockState)) {
            event.addPostAnimationCallback(() -> {
                // Reset the clip state for the drag view after the end animation completes
                setClipViewInStack(true);
            });
        }
        EventBus.getDefault().unregister(this);
    }

    public final void onBusEvent(DragEndCancelledEvent event) {
        // Reset the clip state for the drag view after the cancel animation completes
        event.addPostAnimationCallback(() -> {
            setClipViewInStack(true);
        });
    }

    public void dump(String prefix, PrintWriter writer) {
        String innerPrefix = prefix + "  ";

        writer.print(prefix); writer.print("TaskView");
        writer.print(" mTask="); writer.print(mTask.key.id);
        writer.println();

        mThumbnailView.dump(innerPrefix, writer);
    }
}
