/*
 * 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.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.CountDownTimer;
import android.support.v4.graphics.ColorUtils;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewAnimationUtils;
import android.view.ViewDebug;
import android.view.ViewGroup;
import android.view.ViewStub;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.android.internal.logging.MetricsLogger;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.activity.LaunchTaskEvent;
import com.android.systemui.recents.events.ui.ShowApplicationInfoEvent;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.misc.Utilities;
import com.android.systemui.recents.model.Task;

import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;

/* The task bar view */
public class TaskViewHeader extends FrameLayout
        implements View.OnClickListener, View.OnLongClickListener {

    private static final float HIGHLIGHT_LIGHTNESS_INCREMENT = 0.075f;
    private static final float OVERLAY_LIGHTNESS_INCREMENT = -0.0625f;
    private static final int OVERLAY_REVEAL_DURATION = 250;
    private static final long FOCUS_INDICATOR_INTERVAL_MS = 30;

    /**
     * A color drawable that draws a slight highlight at the top to help it stand out.
     */
    private class HighlightColorDrawable extends Drawable {

        private Paint mHighlightPaint = new Paint();
        private Paint mBackgroundPaint = new Paint();
        private int mColor;
        private float mDimAlpha;

        public HighlightColorDrawable() {
            mBackgroundPaint.setColor(Color.argb(255, 0, 0, 0));
            mBackgroundPaint.setAntiAlias(true);
            mHighlightPaint.setColor(Color.argb(255, 255, 255, 255));
            mHighlightPaint.setAntiAlias(true);
        }

        public void setColorAndDim(int color, float dimAlpha) {
            if (mColor != color || Float.compare(mDimAlpha, dimAlpha) != 0) {
                mColor = color;
                mDimAlpha = dimAlpha;
                mBackgroundPaint.setColor(color);

                ColorUtils.colorToHSL(color, mTmpHSL);
                // TODO: Consider using the saturation of the color to adjust the lightness as well
                mTmpHSL[2] = Math.min(1f,
                        mTmpHSL[2] + HIGHLIGHT_LIGHTNESS_INCREMENT * (1.0f - dimAlpha));
                mHighlightPaint.setColor(ColorUtils.HSLToColor(mTmpHSL));

                invalidateSelf();
            }
        }

        @Override
        public void setColorFilter(@Nullable ColorFilter colorFilter) {
            // Do nothing
        }

        @Override
        public void setAlpha(int alpha) {
            // Do nothing
        }

        @Override
        public void draw(Canvas canvas) {
            // Draw the highlight at the top edge (but put the bottom edge just out of view)
            canvas.drawRoundRect(0, 0, mTaskViewRect.width(),
                    2 * Math.max(mHighlightHeight, mCornerRadius),
                    mCornerRadius, mCornerRadius, mHighlightPaint);

            // Draw the background with the rounded corners
            canvas.drawRoundRect(0, mHighlightHeight, mTaskViewRect.width(),
                    getHeight() + mCornerRadius,
                    mCornerRadius, mCornerRadius, mBackgroundPaint);
        }

        @Override
        public int getOpacity() {
            return PixelFormat.OPAQUE;
        }

        public int getColor() {
            return mColor;
        }
    }

    Task mTask;

    // Header views
    ImageView mIconView;
    TextView mTitleView;
    TextView mSubTitleView;
    ImageView mMoveTaskButton;
    ImageView mDismissButton;
    ViewStub mAppOverlayViewStub;
    FrameLayout mAppOverlayView;
    ImageView mAppIconView;
    ImageView mAppInfoView;
    TextView mAppTitleView;
    ViewStub mFocusTimerIndicatorStub;
    ProgressBar mFocusTimerIndicator;

    // Header drawables
    @ViewDebug.ExportedProperty(category="recents")
    Rect mTaskViewRect = new Rect();
    int mHeaderBarHeight;
    int mHeaderButtonPadding;
    int mCornerRadius;
    int mHighlightHeight;
    @ViewDebug.ExportedProperty(category="recents")
    float mDimAlpha;
    Drawable mLightDismissDrawable;
    Drawable mDarkDismissDrawable;
    Drawable mLightFreeformIcon;
    Drawable mDarkFreeformIcon;
    Drawable mLightFullscreenIcon;
    Drawable mDarkFullscreenIcon;
    Drawable mLightInfoIcon;
    Drawable mDarkInfoIcon;
    int mTaskBarViewLightTextColor;
    int mTaskBarViewDarkTextColor;
    int mDisabledTaskBarBackgroundColor;
    int mMoveTaskTargetStackId = INVALID_STACK_ID;

    // Header background
    private HighlightColorDrawable mBackground;
    private HighlightColorDrawable mOverlayBackground;
    private float[] mTmpHSL = new float[3];

    // Header dim, which is only used when task view hardware layers are not used
    private Paint mDimLayerPaint = new Paint();

    private CountDownTimer mFocusTimerCountDown;

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

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

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

    public TaskViewHeader(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        setWillNotDraw(false);

        // Load the dismiss resources
        Resources res = context.getResources();
        mLightDismissDrawable = context.getDrawable(R.drawable.recents_dismiss_light);
        mDarkDismissDrawable = context.getDrawable(R.drawable.recents_dismiss_dark);
        mCornerRadius = res.getDimensionPixelSize(R.dimen.recents_task_view_rounded_corners_radius);
        mHighlightHeight = res.getDimensionPixelSize(R.dimen.recents_task_view_highlight);
        mTaskBarViewLightTextColor = context.getColor(R.color.recents_task_bar_light_text_color);
        mTaskBarViewDarkTextColor = context.getColor(R.color.recents_task_bar_dark_text_color);
        mLightFreeformIcon = context.getDrawable(R.drawable.recents_move_task_freeform_light);
        mDarkFreeformIcon = context.getDrawable(R.drawable.recents_move_task_freeform_dark);
        mLightFullscreenIcon = context.getDrawable(R.drawable.recents_move_task_fullscreen_light);
        mDarkFullscreenIcon = context.getDrawable(R.drawable.recents_move_task_fullscreen_dark);
        mLightInfoIcon = context.getDrawable(R.drawable.recents_info_light);
        mDarkInfoIcon = context.getDrawable(R.drawable.recents_info_dark);
        mDisabledTaskBarBackgroundColor =
                context.getColor(R.color.recents_task_bar_disabled_background_color);

        // Configure the background and dim
        mBackground = new HighlightColorDrawable();
        mBackground.setColorAndDim(Color.argb(255, 0, 0, 0), 0f);
        setBackground(mBackground);
        mOverlayBackground = new HighlightColorDrawable();
        mDimLayerPaint.setColor(Color.argb(255, 0, 0, 0));
        mDimLayerPaint.setAntiAlias(true);
    }

    /**
     * Resets this header along with the TaskView.
     */
    public void reset() {
        hideAppOverlay(true /* immediate */);
    }

    @Override
    protected void onFinishInflate() {
        SystemServicesProxy ssp = Recents.getSystemServices();

        // Initialize the icon and description views
        mIconView = (ImageView) findViewById(R.id.icon);
        mIconView.setClickable(false);
        mIconView.setOnLongClickListener(this);
        mTitleView = (TextView) findViewById(R.id.title);
        mSubTitleView = (TextView) findViewById(R.id.sub_title);
        mDismissButton = (ImageView) findViewById(R.id.dismiss_task);
        if (ssp.hasFreeformWorkspaceSupport()) {
            mMoveTaskButton = (ImageView) findViewById(R.id.move_task);
        }
        mFocusTimerIndicatorStub = (ViewStub) findViewById(R.id.focus_timer_indicator_stub);
        mAppOverlayViewStub = (ViewStub) findViewById(R.id.app_overlay_stub);

        onConfigurationChanged();
    }

    /**
     * Programmatically sets the layout params for a header bar layout.  This is necessary because
     * we can't get resources based on the current configuration, but instead need to get them
     * based on the device configuration.
     */
    private void updateLayoutParams(View icon, View title, View secondaryButton, View button) {
        FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, mHeaderBarHeight, Gravity.TOP);
        setLayoutParams(lp);
        lp = new FrameLayout.LayoutParams(mHeaderBarHeight, mHeaderBarHeight, Gravity.START);
        icon.setLayoutParams(lp);
        lp = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.START | Gravity.CENTER_VERTICAL);
        lp.setMarginStart(mHeaderBarHeight);
        lp.rightMargin = mMoveTaskButton != null
                ? 2 * mHeaderBarHeight
                : mHeaderBarHeight;
        title.setLayoutParams(lp);
        if (secondaryButton != null) {
            lp = new FrameLayout.LayoutParams(mHeaderBarHeight, mHeaderBarHeight, Gravity.END);
            lp.setMarginEnd(mHeaderBarHeight);
            secondaryButton.setLayoutParams(lp);
            secondaryButton.setPadding(mHeaderButtonPadding, mHeaderButtonPadding,
                    mHeaderButtonPadding, mHeaderButtonPadding);
        }
        lp = new FrameLayout.LayoutParams(mHeaderBarHeight, mHeaderBarHeight, Gravity.END);
        button.setLayoutParams(lp);
        button.setPadding(mHeaderButtonPadding, mHeaderButtonPadding, mHeaderButtonPadding,
                mHeaderButtonPadding);
    }

    /**
     * Update the header view when the configuration changes.
     */
    void onConfigurationChanged() {
        // Update the dimensions of everything in the header. We do this because we need to use
        // resources for the display, and not the current configuration.
        Resources res = getResources();
        mHeaderBarHeight = TaskStackLayoutAlgorithm.getDimensionForDevice(res,
                R.dimen.recents_task_view_header_height,
                R.dimen.recents_task_view_header_height,
                R.dimen.recents_task_view_header_height,
                R.dimen.recents_task_view_header_height_tablet_land,
                R.dimen.recents_task_view_header_height,
                R.dimen.recents_task_view_header_height_tablet_land);
        mHeaderButtonPadding = TaskStackLayoutAlgorithm.getDimensionForDevice(res,
                R.dimen.recents_task_view_header_button_padding,
                R.dimen.recents_task_view_header_button_padding,
                R.dimen.recents_task_view_header_button_padding,
                R.dimen.recents_task_view_header_button_padding_tablet_land,
                R.dimen.recents_task_view_header_button_padding,
                R.dimen.recents_task_view_header_button_padding_tablet_land);
        updateLayoutParams(mIconView, findViewById(R.id.title_container), mMoveTaskButton,
                mDismissButton);
        if (mAppOverlayView != null) {
            updateLayoutParams(mAppIconView, mAppTitleView, null, mAppInfoView);
        }
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);

        // Since we update the position of children based on the width of the parent and this view
        // recompute these changes with the new view size
        onTaskViewSizeChanged(mTaskViewRect.width(), mTaskViewRect.height());
    }

    /**
     * Called when the task view frame changes, allowing us to move the contents of the header
     * to match the frame changes.
     */
    public void onTaskViewSizeChanged(int width, int height) {
        mTaskViewRect.set(0, 0, width, height);

        boolean showTitle = true;
        boolean showMoveIcon = true;
        boolean showDismissIcon = true;
        int rightInset = width - getMeasuredWidth();

        if (mTask != null && mTask.isFreeformTask()) {
            // For freeform tasks, we always show the app icon, and only show the title, move-task
            // icon, and the dismiss icon if there is room
            int appIconWidth = mIconView.getMeasuredWidth();
            int titleWidth = (int) mTitleView.getPaint().measureText(mTask.title);
            int dismissWidth = mDismissButton.getMeasuredWidth();
            int moveTaskWidth = mMoveTaskButton != null
                    ? mMoveTaskButton.getMeasuredWidth()
                    : 0;
            showTitle = width >= (appIconWidth + dismissWidth + moveTaskWidth + titleWidth);
            showMoveIcon = width >= (appIconWidth + dismissWidth + moveTaskWidth);
            showDismissIcon = width >= (appIconWidth + dismissWidth);
        }

        mTitleView.setVisibility(showTitle ? View.VISIBLE : View.INVISIBLE);
        if (mMoveTaskButton != null) {
            mMoveTaskButton.setVisibility(showMoveIcon ? View.VISIBLE : View.INVISIBLE);
            mMoveTaskButton.setTranslationX(rightInset);
        }
        mDismissButton.setVisibility(showDismissIcon ? View.VISIBLE : View.INVISIBLE);
        mDismissButton.setTranslationX(rightInset);
    }

    @Override
    public void onDrawForeground(Canvas canvas) {
        super.onDrawForeground(canvas);

        // Draw the dim layer with the rounded corners
        canvas.drawRoundRect(0, 0, mTaskViewRect.width(), getHeight() + mCornerRadius,
                mCornerRadius, mCornerRadius, mDimLayerPaint);
    }

    /** Starts the focus timer. */
    public void startFocusTimerIndicator(int duration) {
        if (mFocusTimerIndicator == null) {
            return;
        }

        mFocusTimerIndicator.setVisibility(View.VISIBLE);
        mFocusTimerIndicator.setMax(duration);
        mFocusTimerIndicator.setProgress(duration);
        if (mFocusTimerCountDown != null) {
            mFocusTimerCountDown.cancel();
        }
        mFocusTimerCountDown = new CountDownTimer(duration,
                FOCUS_INDICATOR_INTERVAL_MS) {
            public void onTick(long millisUntilFinished) {
                mFocusTimerIndicator.setProgress((int) millisUntilFinished);
            }

            public void onFinish() {
                // Do nothing
            }
        }.start();
    }

    /** Cancels the focus timer. */
    public void cancelFocusTimerIndicator() {
        if (mFocusTimerIndicator == null) {
            return;
        }

        if (mFocusTimerCountDown != null) {
            mFocusTimerCountDown.cancel();
            mFocusTimerIndicator.setProgress(0);
            mFocusTimerIndicator.setVisibility(View.INVISIBLE);
        }
    }

    /** Only exposed for the workaround for b/27815919. */
    public ImageView getIconView() {
        return mIconView;
    }

    /** Returns the secondary color for a primary color. */
    int getSecondaryColor(int primaryColor, boolean useLightOverlayColor) {
        int overlayColor = useLightOverlayColor ? Color.WHITE : Color.BLACK;
        return Utilities.getColorWithOverlay(primaryColor, overlayColor, 0.8f);
    }

    /**
     * Sets the dim alpha, only used when we are not using hardware layers.
     * (see RecentsConfiguration.useHardwareLayers)
     */
    public void setDimAlpha(float dimAlpha) {
        if (Float.compare(mDimAlpha, dimAlpha) != 0) {
            mDimAlpha = dimAlpha;
            mTitleView.setAlpha(1f - dimAlpha);
            updateBackgroundColor(mBackground.getColor(), dimAlpha);
        }
    }

    /**
     * Updates the background and highlight colors for this header.
     */
    private void updateBackgroundColor(int color, float dimAlpha) {
        if (mTask != null) {
            mBackground.setColorAndDim(color, dimAlpha);
            // TODO: Consider using the saturation of the color to adjust the lightness as well
            ColorUtils.colorToHSL(color, mTmpHSL);
            mTmpHSL[2] = Math.min(1f, mTmpHSL[2] + OVERLAY_LIGHTNESS_INCREMENT * (1.0f - dimAlpha));
            mOverlayBackground.setColorAndDim(ColorUtils.HSLToColor(mTmpHSL), dimAlpha);
            mDimLayerPaint.setAlpha((int) (dimAlpha * 255));
            invalidate();
        }
    }

    /** Binds the bar view to the task */
    public void rebindToTask(Task t, boolean touchExplorationEnabled, boolean disabledInSafeMode) {
        SystemServicesProxy ssp = Recents.getSystemServices();
        mTask = t;

        // If an activity icon is defined, then we use that as the primary icon to show in the bar,
        // otherwise, we fall back to the application icon
        int primaryColor = disabledInSafeMode
                ? mDisabledTaskBarBackgroundColor
                : t.colorPrimary;
        if (mBackground.getColor() != primaryColor) {
            updateBackgroundColor(primaryColor, mDimAlpha);
        }
        if (t.icon != null) {
            mIconView.setImageDrawable(t.icon);
        }
        if (!mTitleView.getText().toString().equals(t.title)) {
            mTitleView.setText(t.title);
        }
        mTitleView.setContentDescription(t.contentDescription);
        mTitleView.setTextColor(t.useLightOnPrimaryColor ?
                mTaskBarViewLightTextColor : mTaskBarViewDarkTextColor);
        if (!t.isDockable && ssp.hasDockedTask()) {
            mSubTitleView.setVisibility(View.VISIBLE);
            mSubTitleView.setTextColor(t.useLightOnPrimaryColor ?
                    mTaskBarViewLightTextColor : mTaskBarViewDarkTextColor);
        } else {
            mSubTitleView.setVisibility(View.GONE);
        }
        mDismissButton.setImageDrawable(t.useLightOnPrimaryColor ?
                mLightDismissDrawable : mDarkDismissDrawable);
        mDismissButton.setContentDescription(t.dismissDescription);

        // When freeform workspaces are enabled, then update the move-task button depending on the
        // current task
        if (mMoveTaskButton != null) {
            if (t.isFreeformTask()) {
                mMoveTaskTargetStackId = FULLSCREEN_WORKSPACE_STACK_ID;
                mMoveTaskButton.setImageDrawable(t.useLightOnPrimaryColor
                        ? mLightFullscreenIcon
                        : mDarkFullscreenIcon);
            } else {
                mMoveTaskTargetStackId = FREEFORM_WORKSPACE_STACK_ID;
                mMoveTaskButton.setImageDrawable(t.useLightOnPrimaryColor
                        ? mLightFreeformIcon
                        : mDarkFreeformIcon);
            }
        }

        if (Recents.getDebugFlags().isFastToggleRecentsEnabled()) {
            if (mFocusTimerIndicator == null) {
                mFocusTimerIndicator = (ProgressBar) mFocusTimerIndicatorStub.inflate();
            }
            mFocusTimerIndicator.getProgressDrawable()
                    .setColorFilter(
                            getSecondaryColor(t.colorPrimary, t.useLightOnPrimaryColor),
                            PorterDuff.Mode.SRC_IN);
        }

        // In accessibility, a single click on the focused app info button will show it
        if (touchExplorationEnabled) {
            mIconView.setOnClickListener(this);
        }
    }

    /** Unbinds the bar view from the task */
    void unbindFromTask(boolean touchExplorationEnabled) {
        mTask = null;
        mIconView.setImageDrawable(null);
        if (touchExplorationEnabled) {
            mIconView.setOnClickListener(null);
        }
    }

    /** Animates this task bar if the user does not interact with the stack after a certain time. */
    void startNoUserInteractionAnimation() {
        int duration = getResources().getInteger(R.integer.recents_task_enter_from_app_duration);
        mDismissButton.setOnClickListener(this);
        mDismissButton.setVisibility(View.VISIBLE);
        if (mDismissButton.getVisibility() == VISIBLE) {
            mDismissButton.animate()
                    .alpha(1f)
                    .setInterpolator(Interpolators.FAST_OUT_LINEAR_IN)
                    .setDuration(duration)
                    .start();
        } else {
            mDismissButton.setAlpha(1f);
        }
        if (mMoveTaskButton != null) {
            if (mMoveTaskButton.getVisibility() == VISIBLE) {
                mMoveTaskButton.setOnClickListener(this);
                mMoveTaskButton.setVisibility(View.VISIBLE);
                mMoveTaskButton.animate()
                        .alpha(1f)
                        .setInterpolator(Interpolators.FAST_OUT_LINEAR_IN)
                        .setDuration(duration)
                        .start();
            } else {
                mMoveTaskButton.setAlpha(1f);
            }
        }
    }

    /**
     * Mark this task view that the user does has not interacted with the stack after a certain
     * time.
     */
    void setNoUserInteractionState() {
        mDismissButton.setVisibility(View.VISIBLE);
        mDismissButton.animate().cancel();
        mDismissButton.setAlpha(1f);
        mDismissButton.setOnClickListener(this);
        if (mMoveTaskButton != null) {
            mMoveTaskButton.setVisibility(View.VISIBLE);
            mMoveTaskButton.animate().cancel();
            mMoveTaskButton.setAlpha(1f);
            mMoveTaskButton.setOnClickListener(this);
        }
    }

    /**
     * Resets the state tracking that the user has not interacted with the stack after a certain
     * time.
     */
    void resetNoUserInteractionState() {
        mDismissButton.setVisibility(View.INVISIBLE);
        mDismissButton.setAlpha(0f);
        mDismissButton.setOnClickListener(null);
        if (mMoveTaskButton != null) {
            mMoveTaskButton.setVisibility(View.INVISIBLE);
            mMoveTaskButton.setAlpha(0f);
            mMoveTaskButton.setOnClickListener(null);
        }
    }

    @Override
    protected int[] onCreateDrawableState(int extraSpace) {

        // Don't forward our state to the drawable - we do it manually in onTaskViewFocusChanged.
        // This is to prevent layer trashing when the view is pressed.
        return new int[] {};
    }

    @Override
    public void onClick(View v) {
        if (v == mIconView) {
            // In accessibility, a single click on the focused app info button will show it
            EventBus.getDefault().send(new ShowApplicationInfoEvent(mTask));
        } else if (v == mDismissButton) {
            TaskView tv = Utilities.findParent(this, TaskView.class);
            tv.dismissTask();

            // Keep track of deletions by the dismiss button
            MetricsLogger.histogram(getContext(), "overview_task_dismissed_source",
                    Constants.Metrics.DismissSourceHeaderButton);
        } else if (v == mMoveTaskButton) {
            TaskView tv = Utilities.findParent(this, TaskView.class);
            Rect bounds = mMoveTaskTargetStackId == FREEFORM_WORKSPACE_STACK_ID
                    ? new Rect(mTaskViewRect)
                    : new Rect();
            EventBus.getDefault().send(new LaunchTaskEvent(tv, mTask, bounds,
                    mMoveTaskTargetStackId, false));
        } else if (v == mAppInfoView) {
            EventBus.getDefault().send(new ShowApplicationInfoEvent(mTask));
        } else if (v == mAppIconView) {
            hideAppOverlay(false /* immediate */);
        }
    }

    @Override
    public boolean onLongClick(View v) {
        if (v == mIconView) {
            showAppOverlay();
            return true;
        } else if (v == mAppIconView) {
            hideAppOverlay(false /* immediate */);
            return true;
        }
        return false;
    }

    /**
     * Shows the application overlay.
     */
    private void showAppOverlay() {
        // Skip early if the task is invalid
        SystemServicesProxy ssp = Recents.getSystemServices();
        ComponentName cn = mTask.key.getComponent();
        int userId = mTask.key.userId;
        ActivityInfo activityInfo = ssp.getActivityInfo(cn, userId);
        if (activityInfo == null) {
            return;
        }

        // Inflate the overlay if necessary
        if (mAppOverlayView == null) {
            mAppOverlayView = (FrameLayout) mAppOverlayViewStub.inflate();
            mAppOverlayView.setBackground(mOverlayBackground);
            mAppIconView = (ImageView) mAppOverlayView.findViewById(R.id.app_icon);
            mAppIconView.setOnClickListener(this);
            mAppIconView.setOnLongClickListener(this);
            mAppInfoView = (ImageView) mAppOverlayView.findViewById(R.id.app_info);
            mAppInfoView.setOnClickListener(this);
            mAppTitleView = (TextView) mAppOverlayView.findViewById(R.id.app_title);
            updateLayoutParams(mAppIconView, mAppTitleView, null, mAppInfoView);
        }

        // Update the overlay contents for the current app
        mAppTitleView.setText(ssp.getBadgedApplicationLabel(activityInfo.applicationInfo, userId));
        mAppTitleView.setTextColor(mTask.useLightOnPrimaryColor ?
                mTaskBarViewLightTextColor : mTaskBarViewDarkTextColor);
        mAppIconView.setImageDrawable(ssp.getBadgedApplicationIcon(activityInfo.applicationInfo,
                userId));
        mAppInfoView.setImageDrawable(mTask.useLightOnPrimaryColor
                ? mLightInfoIcon
                : mDarkInfoIcon);
        mAppOverlayView.setVisibility(View.VISIBLE);

        int x = mIconView.getLeft() + mIconView.getWidth() / 2;
        int y = mIconView.getTop() + mIconView.getHeight() / 2;
        Animator revealAnim = ViewAnimationUtils.createCircularReveal(mAppOverlayView, x, y, 0,
                getWidth());
        revealAnim.setDuration(OVERLAY_REVEAL_DURATION);
        revealAnim.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
        revealAnim.start();
    }

    /**
     * Hide the application overlay.
     */
    private void hideAppOverlay(boolean immediate) {
        // Skip if we haven't even loaded the overlay yet
        if (mAppOverlayView == null) {
            return;
        }

        if (immediate) {
            mAppOverlayView.setVisibility(View.GONE);
        } else {
            int x = mIconView.getLeft() + mIconView.getWidth() / 2;
            int y = mIconView.getTop() + mIconView.getHeight() / 2;
            Animator revealAnim = ViewAnimationUtils.createCircularReveal(mAppOverlayView, x, y,
                    getWidth(), 0);
            revealAnim.setDuration(OVERLAY_REVEAL_DURATION);
            revealAnim.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
            revealAnim.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    mAppOverlayView.setVisibility(View.GONE);
                }
            });
            revealAnim.start();
        }
    }
}
