[go: nahoru, domu]

137c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung/*
237c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung * Copyright (C) 2014 The Android Open Source Project
337c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung *
437c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung * Licensed under the Apache License, Version 2.0 (the "License");
537c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung * you may not use this file except in compliance with the License.
637c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung * You may obtain a copy of the License at
737c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung *
8b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schiller * http://www.apache.org/licenses/LICENSE-2.0
937c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung *
1037c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung * Unless required by applicable law or agreed to in writing, software
1137c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung * distributed under the License is distributed on an "AS IS" BASIS,
1237c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1337c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung * See the License for the specific language governing permissions and
1437c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung * limitations under the License.
1537c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung */
1637c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung
1737c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chungpackage com.android.systemui.recents.views;
1837c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung
19c5ef63f4e95329158d88a6cbb05789b57098222dWinsonimport android.animation.Animator;
20c5ef63f4e95329158d88a6cbb05789b57098222dWinsonimport android.animation.AnimatorListenerAdapter;
2194a0e89adb30b050f4b3319d93753b34d48e8490Winsonimport android.annotation.Nullable;
22c5ef63f4e95329158d88a6cbb05789b57098222dWinsonimport android.content.ComponentName;
2337c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chungimport android.content.Context;
24c5ef63f4e95329158d88a6cbb05789b57098222dWinsonimport android.content.pm.ActivityInfo;
2594a0e89adb30b050f4b3319d93753b34d48e8490Winsonimport android.content.res.Resources;
26cd23c849afefe58b213d5abb1c581f15d3ad543aWinson Chungimport android.graphics.Canvas;
27a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chungimport android.graphics.Color;
2894a0e89adb30b050f4b3319d93753b34d48e8490Winsonimport android.graphics.ColorFilter;
29cd23c849afefe58b213d5abb1c581f15d3ad543aWinson Chungimport android.graphics.Paint;
3094a0e89adb30b050f4b3319d93753b34d48e8490Winsonimport android.graphics.PixelFormat;
31c5ef63f4e95329158d88a6cbb05789b57098222dWinsonimport android.graphics.PorterDuff;
328aa7d161a11965cd75eace74e1bcf15421bbea18Skuhneimport android.graphics.Rect;
3335f3050959e43bf378f9a0adcaef13729206c7e4Winsonimport android.graphics.drawable.Drawable;
3418227e483167c590121fd300d03c999dd057204cWinsonimport android.graphics.drawable.RippleDrawable;
35b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schillerimport android.os.CountDownTimer;
36c5ef63f4e95329158d88a6cbb05789b57098222dWinsonimport android.support.v4.graphics.ColorUtils;
3737c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chungimport android.util.AttributeSet;
38217009356efa2b854ab3981dff8d315a0d679c73Winsonimport android.view.Gravity;
39d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chungimport android.view.View;
40c5ef63f4e95329158d88a6cbb05789b57098222dWinsonimport android.view.ViewAnimationUtils;
41231bc9c54a48921f9c6a1ae187969c9bfe9d121fWinsonimport android.view.ViewDebug;
42217009356efa2b854ab3981dff8d315a0d679c73Winsonimport android.view.ViewGroup;
4337c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chungimport android.widget.FrameLayout;
4437c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chungimport android.widget.ImageView;
45b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schillerimport android.widget.ProgressBar;
4637c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chungimport android.widget.TextView;
47c0d7058b14c24cd07912f5629c26b39b7b4673d5Winson
482536c7ed446203ea12b38cf05a88e603f8d1b768Winsonimport com.android.internal.logging.MetricsLogger;
49c0d7058b14c24cd07912f5629c26b39b7b4673d5Winsonimport com.android.systemui.Interpolators;
5037c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chungimport com.android.systemui.R;
51f5e22e71cb5f8699a4312c797af068f655cbe629Winson Chungimport com.android.systemui.recents.Constants;
52e7f138c7f0a190c86cec10fb32fa106aacae4093Winsonimport com.android.systemui.recents.Recents;
532536c7ed446203ea12b38cf05a88e603f8d1b768Winsonimport com.android.systemui.recents.events.EventBus;
5448f2cda829ddb761697a0efb0cad42a62480c130Winson Chungimport com.android.systemui.recents.events.activity.LaunchTaskEvent;
552536c7ed446203ea12b38cf05a88e603f8d1b768Winsonimport com.android.systemui.recents.events.ui.ShowApplicationInfoEvent;
568aa7d161a11965cd75eace74e1bcf15421bbea18Skuhneimport com.android.systemui.recents.misc.SystemServicesProxy;
57a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chungimport com.android.systemui.recents.misc.Utilities;
5837c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chungimport com.android.systemui.recents.model.Task;
5937c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung
6048f2cda829ddb761697a0efb0cad42a62480c130Winson Chungimport static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
6148f2cda829ddb761697a0efb0cad42a62480c130Winson Chungimport static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
6248f2cda829ddb761697a0efb0cad42a62480c130Winson Chungimport static android.app.ActivityManager.StackId.INVALID_STACK_ID;
6348f2cda829ddb761697a0efb0cad42a62480c130Winson Chung
6437c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung/* The task bar view */
652536c7ed446203ea12b38cf05a88e603f8d1b768Winsonpublic class TaskViewHeader extends FrameLayout
662536c7ed446203ea12b38cf05a88e603f8d1b768Winson        implements View.OnClickListener, View.OnLongClickListener {
67d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung
6812858a6eaea8ae85e7244bd904e1e31291ceea3cWinson    private static final float HIGHLIGHT_LIGHTNESS_INCREMENT = 0.075f;
69c5ef63f4e95329158d88a6cbb05789b57098222dWinson    private static final float OVERLAY_LIGHTNESS_INCREMENT = -0.0625f;
70c5ef63f4e95329158d88a6cbb05789b57098222dWinson    private static final int OVERLAY_REVEAL_DURATION = 250;
71b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schiller    private static final long FOCUS_INDICATOR_INTERVAL_MS = 30;
7294a0e89adb30b050f4b3319d93753b34d48e8490Winson
7394a0e89adb30b050f4b3319d93753b34d48e8490Winson    /**
7494a0e89adb30b050f4b3319d93753b34d48e8490Winson     * A color drawable that draws a slight highlight at the top to help it stand out.
7594a0e89adb30b050f4b3319d93753b34d48e8490Winson     */
7694a0e89adb30b050f4b3319d93753b34d48e8490Winson    private class HighlightColorDrawable extends Drawable {
7794a0e89adb30b050f4b3319d93753b34d48e8490Winson
7894a0e89adb30b050f4b3319d93753b34d48e8490Winson        private Paint mHighlightPaint = new Paint();
7994a0e89adb30b050f4b3319d93753b34d48e8490Winson        private Paint mBackgroundPaint = new Paint();
808be1634a543022bd6ee0c1e974d3201d452981e8Winson        private int mColor;
818be1634a543022bd6ee0c1e974d3201d452981e8Winson        private float mDimAlpha;
8294a0e89adb30b050f4b3319d93753b34d48e8490Winson
8394a0e89adb30b050f4b3319d93753b34d48e8490Winson        public HighlightColorDrawable() {
8494a0e89adb30b050f4b3319d93753b34d48e8490Winson            mBackgroundPaint.setColor(Color.argb(255, 0, 0, 0));
8594a0e89adb30b050f4b3319d93753b34d48e8490Winson            mBackgroundPaint.setAntiAlias(true);
8694a0e89adb30b050f4b3319d93753b34d48e8490Winson            mHighlightPaint.setColor(Color.argb(255, 255, 255, 255));
8794a0e89adb30b050f4b3319d93753b34d48e8490Winson            mHighlightPaint.setAntiAlias(true);
8894a0e89adb30b050f4b3319d93753b34d48e8490Winson        }
8994a0e89adb30b050f4b3319d93753b34d48e8490Winson
9094a0e89adb30b050f4b3319d93753b34d48e8490Winson        public void setColorAndDim(int color, float dimAlpha) {
918be1634a543022bd6ee0c1e974d3201d452981e8Winson            if (mColor != color || Float.compare(mDimAlpha, dimAlpha) != 0) {
928be1634a543022bd6ee0c1e974d3201d452981e8Winson                mColor = color;
938be1634a543022bd6ee0c1e974d3201d452981e8Winson                mDimAlpha = dimAlpha;
948be1634a543022bd6ee0c1e974d3201d452981e8Winson                mBackgroundPaint.setColor(color);
958be1634a543022bd6ee0c1e974d3201d452981e8Winson
968be1634a543022bd6ee0c1e974d3201d452981e8Winson                ColorUtils.colorToHSL(color, mTmpHSL);
978be1634a543022bd6ee0c1e974d3201d452981e8Winson                // TODO: Consider using the saturation of the color to adjust the lightness as well
988be1634a543022bd6ee0c1e974d3201d452981e8Winson                mTmpHSL[2] = Math.min(1f,
998be1634a543022bd6ee0c1e974d3201d452981e8Winson                        mTmpHSL[2] + HIGHLIGHT_LIGHTNESS_INCREMENT * (1.0f - dimAlpha));
1008be1634a543022bd6ee0c1e974d3201d452981e8Winson                mHighlightPaint.setColor(ColorUtils.HSLToColor(mTmpHSL));
1018be1634a543022bd6ee0c1e974d3201d452981e8Winson
1028be1634a543022bd6ee0c1e974d3201d452981e8Winson                invalidateSelf();
1038be1634a543022bd6ee0c1e974d3201d452981e8Winson            }
10494a0e89adb30b050f4b3319d93753b34d48e8490Winson        }
10594a0e89adb30b050f4b3319d93753b34d48e8490Winson
10694a0e89adb30b050f4b3319d93753b34d48e8490Winson        @Override
10794a0e89adb30b050f4b3319d93753b34d48e8490Winson        public void setColorFilter(@Nullable ColorFilter colorFilter) {
10894a0e89adb30b050f4b3319d93753b34d48e8490Winson            // Do nothing
10994a0e89adb30b050f4b3319d93753b34d48e8490Winson        }
11094a0e89adb30b050f4b3319d93753b34d48e8490Winson
11194a0e89adb30b050f4b3319d93753b34d48e8490Winson        @Override
11294a0e89adb30b050f4b3319d93753b34d48e8490Winson        public void setAlpha(int alpha) {
11394a0e89adb30b050f4b3319d93753b34d48e8490Winson            // Do nothing
11494a0e89adb30b050f4b3319d93753b34d48e8490Winson        }
11594a0e89adb30b050f4b3319d93753b34d48e8490Winson
11694a0e89adb30b050f4b3319d93753b34d48e8490Winson        @Override
11794a0e89adb30b050f4b3319d93753b34d48e8490Winson        public void draw(Canvas canvas) {
11894a0e89adb30b050f4b3319d93753b34d48e8490Winson            // Draw the highlight at the top edge (but put the bottom edge just out of view)
11994a0e89adb30b050f4b3319d93753b34d48e8490Winson            canvas.drawRoundRect(0, 0, mTaskViewRect.width(),
12094a0e89adb30b050f4b3319d93753b34d48e8490Winson                    2 * Math.max(mHighlightHeight, mCornerRadius),
12194a0e89adb30b050f4b3319d93753b34d48e8490Winson                    mCornerRadius, mCornerRadius, mHighlightPaint);
12294a0e89adb30b050f4b3319d93753b34d48e8490Winson
12394a0e89adb30b050f4b3319d93753b34d48e8490Winson            // Draw the background with the rounded corners
12494a0e89adb30b050f4b3319d93753b34d48e8490Winson            canvas.drawRoundRect(0, mHighlightHeight, mTaskViewRect.width(),
12594a0e89adb30b050f4b3319d93753b34d48e8490Winson                    getHeight() + mCornerRadius,
12694a0e89adb30b050f4b3319d93753b34d48e8490Winson                    mCornerRadius, mCornerRadius, mBackgroundPaint);
12794a0e89adb30b050f4b3319d93753b34d48e8490Winson        }
12894a0e89adb30b050f4b3319d93753b34d48e8490Winson
12994a0e89adb30b050f4b3319d93753b34d48e8490Winson        @Override
13094a0e89adb30b050f4b3319d93753b34d48e8490Winson        public int getOpacity() {
13194a0e89adb30b050f4b3319d93753b34d48e8490Winson            return PixelFormat.OPAQUE;
13294a0e89adb30b050f4b3319d93753b34d48e8490Winson        }
1338be1634a543022bd6ee0c1e974d3201d452981e8Winson
1348be1634a543022bd6ee0c1e974d3201d452981e8Winson        public int getColor() {
1358be1634a543022bd6ee0c1e974d3201d452981e8Winson            return mColor;
1368be1634a543022bd6ee0c1e974d3201d452981e8Winson        }
13794a0e89adb30b050f4b3319d93753b34d48e8490Winson    }
13894a0e89adb30b050f4b3319d93753b34d48e8490Winson
1392536c7ed446203ea12b38cf05a88e603f8d1b768Winson    Task mTask;
140d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung
141353c0b91daa97fa87f077be0f403fe7db8dedb40Winson Chung    // Header views
142296278a0679375b8c43962a9e3c9bb4e8ab201e7Winson Chung    ImageView mIconView;
143296278a0679375b8c43962a9e3c9bb4e8ab201e7Winson Chung    TextView mTitleView;
144c5ef63f4e95329158d88a6cbb05789b57098222dWinson    ImageView mMoveTaskButton;
145c5ef63f4e95329158d88a6cbb05789b57098222dWinson    ImageView mDismissButton;
146c5ef63f4e95329158d88a6cbb05789b57098222dWinson    FrameLayout mAppOverlayView;
147c5ef63f4e95329158d88a6cbb05789b57098222dWinson    ImageView mAppIconView;
148c5ef63f4e95329158d88a6cbb05789b57098222dWinson    ImageView mAppInfoView;
149c5ef63f4e95329158d88a6cbb05789b57098222dWinson    TextView mAppTitleView;
150b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schiller    ProgressBar mFocusTimerIndicator;
15137c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung
152353c0b91daa97fa87f077be0f403fe7db8dedb40Winson Chung    // Header drawables
153231bc9c54a48921f9c6a1ae187969c9bfe9d121fWinson    @ViewDebug.ExportedProperty(category="recents")
154de0591a0788c96757cce1eed93a7e8bc8bd0ef01Winson    Rect mTaskViewRect = new Rect();
155217009356efa2b854ab3981dff8d315a0d679c73Winson    int mHeaderBarHeight;
156217009356efa2b854ab3981dff8d315a0d679c73Winson    int mHeaderButtonPadding;
15735f3050959e43bf378f9a0adcaef13729206c7e4Winson    int mCornerRadius;
15835f3050959e43bf378f9a0adcaef13729206c7e4Winson    int mHighlightHeight;
159231bc9c54a48921f9c6a1ae187969c9bfe9d121fWinson    @ViewDebug.ExportedProperty(category="recents")
16094a0e89adb30b050f4b3319d93753b34d48e8490Winson    float mDimAlpha;
16154e297a5bb143e60e29fd7dfe87e04a8cc96c72cWinson Chung    Drawable mLightDismissDrawable;
16254e297a5bb143e60e29fd7dfe87e04a8cc96c72cWinson Chung    Drawable mDarkDismissDrawable;
1633e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson    Drawable mLightFreeformIcon;
1643e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson    Drawable mDarkFreeformIcon;
1653e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson    Drawable mLightFullscreenIcon;
1663e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson    Drawable mDarkFullscreenIcon;
167c5ef63f4e95329158d88a6cbb05789b57098222dWinson    Drawable mLightInfoIcon;
168c5ef63f4e95329158d88a6cbb05789b57098222dWinson    Drawable mDarkInfoIcon;
16994a0e89adb30b050f4b3319d93753b34d48e8490Winson    int mTaskBarViewLightTextColor;
17094a0e89adb30b050f4b3319d93753b34d48e8490Winson    int mTaskBarViewDarkTextColor;
1718be1634a543022bd6ee0c1e974d3201d452981e8Winson    int mDisabledTaskBarBackgroundColor;
172c5ef63f4e95329158d88a6cbb05789b57098222dWinson    int mMoveTaskTargetStackId = INVALID_STACK_ID;
173dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung
17494a0e89adb30b050f4b3319d93753b34d48e8490Winson    // Header background
17594a0e89adb30b050f4b3319d93753b34d48e8490Winson    private HighlightColorDrawable mBackground;
176c5ef63f4e95329158d88a6cbb05789b57098222dWinson    private HighlightColorDrawable mOverlayBackground;
177c5ef63f4e95329158d88a6cbb05789b57098222dWinson    private float[] mTmpHSL = new float[3];
178353c0b91daa97fa87f077be0f403fe7db8dedb40Winson Chung
179353c0b91daa97fa87f077be0f403fe7db8dedb40Winson Chung    // Header dim, which is only used when task view hardware layers are not used
18094a0e89adb30b050f4b3319d93753b34d48e8490Winson    private Paint mDimLayerPaint = new Paint();
181cd23c849afefe58b213d5abb1c581f15d3ad543aWinson Chung
182b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schiller    private CountDownTimer mFocusTimerCountDown;
183b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schiller
184ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung    public TaskViewHeader(Context context) {
18537c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung        this(context, null);
18637c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung    }
18737c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung
188ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung    public TaskViewHeader(Context context, AttributeSet attrs) {
18937c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung        this(context, attrs, 0);
19037c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung    }
19137c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung
192ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung    public TaskViewHeader(Context context, AttributeSet attrs, int defStyleAttr) {
19337c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung        this(context, attrs, defStyleAttr, 0);
19437c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung    }
19537c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung
196ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung    public TaskViewHeader(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
19737c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung        super(context, attrs, defStyleAttr, defStyleRes);
198cd23c849afefe58b213d5abb1c581f15d3ad543aWinson Chung        setWillNotDraw(false);
199cd23c849afefe58b213d5abb1c581f15d3ad543aWinson Chung
200cd23c849afefe58b213d5abb1c581f15d3ad543aWinson Chung        // Load the dismiss resources
20194a0e89adb30b050f4b3319d93753b34d48e8490Winson        Resources res = context.getResources();
202911f400c2eab4eb15e0491a2affd918901867d2eWinson Chung        mLightDismissDrawable = context.getDrawable(R.drawable.recents_dismiss_light);
203911f400c2eab4eb15e0491a2affd918901867d2eWinson Chung        mDarkDismissDrawable = context.getDrawable(R.drawable.recents_dismiss_dark);
20494a0e89adb30b050f4b3319d93753b34d48e8490Winson        mCornerRadius = res.getDimensionPixelSize(R.dimen.recents_task_view_rounded_corners_radius);
20594a0e89adb30b050f4b3319d93753b34d48e8490Winson        mHighlightHeight = res.getDimensionPixelSize(R.dimen.recents_task_view_highlight);
20694a0e89adb30b050f4b3319d93753b34d48e8490Winson        mTaskBarViewLightTextColor = context.getColor(R.color.recents_task_bar_light_text_color);
20794a0e89adb30b050f4b3319d93753b34d48e8490Winson        mTaskBarViewDarkTextColor = context.getColor(R.color.recents_task_bar_dark_text_color);
2083e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson        mLightFreeformIcon = context.getDrawable(R.drawable.recents_move_task_freeform_light);
2093e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson        mDarkFreeformIcon = context.getDrawable(R.drawable.recents_move_task_freeform_dark);
2103e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson        mLightFullscreenIcon = context.getDrawable(R.drawable.recents_move_task_fullscreen_light);
2113e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson        mDarkFullscreenIcon = context.getDrawable(R.drawable.recents_move_task_fullscreen_dark);
212c5ef63f4e95329158d88a6cbb05789b57098222dWinson        mLightInfoIcon = context.getDrawable(R.drawable.recents_info_light);
213c5ef63f4e95329158d88a6cbb05789b57098222dWinson        mDarkInfoIcon = context.getDrawable(R.drawable.recents_info_dark);
2148be1634a543022bd6ee0c1e974d3201d452981e8Winson        mDisabledTaskBarBackgroundColor =
2158be1634a543022bd6ee0c1e974d3201d452981e8Winson                context.getColor(R.color.recents_task_bar_disabled_background_color);
2163e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson
21794a0e89adb30b050f4b3319d93753b34d48e8490Winson        // Configure the background and dim
21894a0e89adb30b050f4b3319d93753b34d48e8490Winson        mBackground = new HighlightColorDrawable();
21994a0e89adb30b050f4b3319d93753b34d48e8490Winson        mBackground.setColorAndDim(Color.argb(255, 0, 0, 0), 0f);
22094a0e89adb30b050f4b3319d93753b34d48e8490Winson        setBackground(mBackground);
221c5ef63f4e95329158d88a6cbb05789b57098222dWinson        mOverlayBackground = new HighlightColorDrawable();
22294a0e89adb30b050f4b3319d93753b34d48e8490Winson        mDimLayerPaint.setColor(Color.argb(255, 0, 0, 0));
22394a0e89adb30b050f4b3319d93753b34d48e8490Winson        mDimLayerPaint.setAntiAlias(true);
22437c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung    }
22537c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung
226c5ef63f4e95329158d88a6cbb05789b57098222dWinson    /**
227c5ef63f4e95329158d88a6cbb05789b57098222dWinson     * Resets this header along with the TaskView.
228c5ef63f4e95329158d88a6cbb05789b57098222dWinson     */
229c5ef63f4e95329158d88a6cbb05789b57098222dWinson    public void reset() {
230c5ef63f4e95329158d88a6cbb05789b57098222dWinson        hideAppOverlay(true /* immediate */);
231c5ef63f4e95329158d88a6cbb05789b57098222dWinson    }
232c5ef63f4e95329158d88a6cbb05789b57098222dWinson
23337c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung    @Override
23437c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung    protected void onFinishInflate() {
235bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung        SystemServicesProxy ssp = Recents.getSystemServices();
236bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung
23737c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung        // Initialize the icon and description views
238296278a0679375b8c43962a9e3c9bb4e8ab201e7Winson Chung        mIconView = (ImageView) findViewById(R.id.icon);
239296278a0679375b8c43962a9e3c9bb4e8ab201e7Winson Chung        mIconView.setOnLongClickListener(this);
240296278a0679375b8c43962a9e3c9bb4e8ab201e7Winson Chung        mTitleView = (TextView) findViewById(R.id.title);
24154e297a5bb143e60e29fd7dfe87e04a8cc96c72cWinson Chung        mDismissButton = (ImageView) findViewById(R.id.dismiss_task);
242bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung        if (ssp.hasFreeformWorkspaceSupport()) {
243bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung            mMoveTaskButton = (ImageView) findViewById(R.id.move_task);
244bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung        }
245217009356efa2b854ab3981dff8d315a0d679c73Winson
246619e40cd56266a362ab7da80cb9e4eba6c33b204Winson        onConfigurationChanged();
247217009356efa2b854ab3981dff8d315a0d679c73Winson    }
248217009356efa2b854ab3981dff8d315a0d679c73Winson
249217009356efa2b854ab3981dff8d315a0d679c73Winson    /**
250217009356efa2b854ab3981dff8d315a0d679c73Winson     * Programmatically sets the layout params for a header bar layout.  This is necessary because
251217009356efa2b854ab3981dff8d315a0d679c73Winson     * we can't get resources based on the current configuration, but instead need to get them
252217009356efa2b854ab3981dff8d315a0d679c73Winson     * based on the device configuration.
253217009356efa2b854ab3981dff8d315a0d679c73Winson     */
254217009356efa2b854ab3981dff8d315a0d679c73Winson    private void updateLayoutParams(View icon, View title, View secondaryButton, View button) {
255217009356efa2b854ab3981dff8d315a0d679c73Winson        FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
256217009356efa2b854ab3981dff8d315a0d679c73Winson                ViewGroup.LayoutParams.MATCH_PARENT, mHeaderBarHeight, Gravity.TOP);
257217009356efa2b854ab3981dff8d315a0d679c73Winson        setLayoutParams(lp);
258217009356efa2b854ab3981dff8d315a0d679c73Winson        lp = new FrameLayout.LayoutParams(mHeaderBarHeight, mHeaderBarHeight, Gravity.START);
259217009356efa2b854ab3981dff8d315a0d679c73Winson        icon.setLayoutParams(lp);
260217009356efa2b854ab3981dff8d315a0d679c73Winson        lp = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
261217009356efa2b854ab3981dff8d315a0d679c73Winson                ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.START | Gravity.CENTER_VERTICAL);
262a1ededd056d51532ab18354f17f8065ec1134535Winson        lp.setMarginStart(mHeaderBarHeight);
263198523763af21c49d1d2c71fb65c1f7da356712bWinson        lp.setMarginEnd(mMoveTaskButton != null
264217009356efa2b854ab3981dff8d315a0d679c73Winson                ? 2 * mHeaderBarHeight
265198523763af21c49d1d2c71fb65c1f7da356712bWinson                : mHeaderBarHeight);
266217009356efa2b854ab3981dff8d315a0d679c73Winson        title.setLayoutParams(lp);
267217009356efa2b854ab3981dff8d315a0d679c73Winson        if (secondaryButton != null) {
268217009356efa2b854ab3981dff8d315a0d679c73Winson            lp = new FrameLayout.LayoutParams(mHeaderBarHeight, mHeaderBarHeight, Gravity.END);
269a1ededd056d51532ab18354f17f8065ec1134535Winson            lp.setMarginEnd(mHeaderBarHeight);
270217009356efa2b854ab3981dff8d315a0d679c73Winson            secondaryButton.setLayoutParams(lp);
271217009356efa2b854ab3981dff8d315a0d679c73Winson            secondaryButton.setPadding(mHeaderButtonPadding, mHeaderButtonPadding,
272217009356efa2b854ab3981dff8d315a0d679c73Winson                    mHeaderButtonPadding, mHeaderButtonPadding);
273217009356efa2b854ab3981dff8d315a0d679c73Winson        }
274217009356efa2b854ab3981dff8d315a0d679c73Winson        lp = new FrameLayout.LayoutParams(mHeaderBarHeight, mHeaderBarHeight, Gravity.END);
275217009356efa2b854ab3981dff8d315a0d679c73Winson        button.setLayoutParams(lp);
276217009356efa2b854ab3981dff8d315a0d679c73Winson        button.setPadding(mHeaderButtonPadding, mHeaderButtonPadding, mHeaderButtonPadding,
277217009356efa2b854ab3981dff8d315a0d679c73Winson                mHeaderButtonPadding);
27854e297a5bb143e60e29fd7dfe87e04a8cc96c72cWinson Chung    }
27954e297a5bb143e60e29fd7dfe87e04a8cc96c72cWinson Chung
280619e40cd56266a362ab7da80cb9e4eba6c33b204Winson    /**
281619e40cd56266a362ab7da80cb9e4eba6c33b204Winson     * Update the header view when the configuration changes.
282619e40cd56266a362ab7da80cb9e4eba6c33b204Winson     */
283670ea71f1b4ae59a0cd6608ae44b0fb78a1144c4Winson    public void onConfigurationChanged() {
284619e40cd56266a362ab7da80cb9e4eba6c33b204Winson        // Update the dimensions of everything in the header. We do this because we need to use
285619e40cd56266a362ab7da80cb9e4eba6c33b204Winson        // resources for the display, and not the current configuration.
286619e40cd56266a362ab7da80cb9e4eba6c33b204Winson        Resources res = getResources();
28725160db73f37619a26a3d87a06625925d881b0fdJorim Jaggi        int headerBarHeight = TaskStackLayoutAlgorithm.getDimensionForDevice(getContext(),
288619e40cd56266a362ab7da80cb9e4eba6c33b204Winson                R.dimen.recents_task_view_header_height,
289619e40cd56266a362ab7da80cb9e4eba6c33b204Winson                R.dimen.recents_task_view_header_height,
290619e40cd56266a362ab7da80cb9e4eba6c33b204Winson                R.dimen.recents_task_view_header_height,
291619e40cd56266a362ab7da80cb9e4eba6c33b204Winson                R.dimen.recents_task_view_header_height_tablet_land,
292619e40cd56266a362ab7da80cb9e4eba6c33b204Winson                R.dimen.recents_task_view_header_height,
293619e40cd56266a362ab7da80cb9e4eba6c33b204Winson                R.dimen.recents_task_view_header_height_tablet_land);
29425160db73f37619a26a3d87a06625925d881b0fdJorim Jaggi        int headerButtonPadding = TaskStackLayoutAlgorithm.getDimensionForDevice(getContext(),
295619e40cd56266a362ab7da80cb9e4eba6c33b204Winson                R.dimen.recents_task_view_header_button_padding,
296619e40cd56266a362ab7da80cb9e4eba6c33b204Winson                R.dimen.recents_task_view_header_button_padding,
297619e40cd56266a362ab7da80cb9e4eba6c33b204Winson                R.dimen.recents_task_view_header_button_padding,
298619e40cd56266a362ab7da80cb9e4eba6c33b204Winson                R.dimen.recents_task_view_header_button_padding_tablet_land,
299619e40cd56266a362ab7da80cb9e4eba6c33b204Winson                R.dimen.recents_task_view_header_button_padding,
300619e40cd56266a362ab7da80cb9e4eba6c33b204Winson                R.dimen.recents_task_view_header_button_padding_tablet_land);
301670ea71f1b4ae59a0cd6608ae44b0fb78a1144c4Winson        if (headerBarHeight != mHeaderBarHeight || headerButtonPadding != mHeaderButtonPadding) {
302670ea71f1b4ae59a0cd6608ae44b0fb78a1144c4Winson            mHeaderBarHeight = headerBarHeight;
303670ea71f1b4ae59a0cd6608ae44b0fb78a1144c4Winson            mHeaderButtonPadding = headerButtonPadding;
304670ea71f1b4ae59a0cd6608ae44b0fb78a1144c4Winson            updateLayoutParams(mIconView, mTitleView, mMoveTaskButton, mDismissButton);
305670ea71f1b4ae59a0cd6608ae44b0fb78a1144c4Winson            if (mAppOverlayView != null) {
306670ea71f1b4ae59a0cd6608ae44b0fb78a1144c4Winson                updateLayoutParams(mAppIconView, mAppTitleView, null, mAppInfoView);
307670ea71f1b4ae59a0cd6608ae44b0fb78a1144c4Winson            }
308619e40cd56266a362ab7da80cb9e4eba6c33b204Winson        }
309619e40cd56266a362ab7da80cb9e4eba6c33b204Winson    }
310619e40cd56266a362ab7da80cb9e4eba6c33b204Winson
311bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung    @Override
312bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
313bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung        super.onLayout(changed, left, top, right, bottom);
314bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung
315bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung        // Since we update the position of children based on the width of the parent and this view
316bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung        // recompute these changes with the new view size
317bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung        onTaskViewSizeChanged(mTaskViewRect.width(), mTaskViewRect.height());
318bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung    }
319bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung
320de0591a0788c96757cce1eed93a7e8bc8bd0ef01Winson    /**
321de0591a0788c96757cce1eed93a7e8bc8bd0ef01Winson     * Called when the task view frame changes, allowing us to move the contents of the header
322de0591a0788c96757cce1eed93a7e8bc8bd0ef01Winson     * to match the frame changes.
323de0591a0788c96757cce1eed93a7e8bc8bd0ef01Winson     */
324de0591a0788c96757cce1eed93a7e8bc8bd0ef01Winson    public void onTaskViewSizeChanged(int width, int height) {
325de0591a0788c96757cce1eed93a7e8bc8bd0ef01Winson        mTaskViewRect.set(0, 0, width, height);
326bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung
327bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung        boolean showTitle = true;
328bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung        boolean showMoveIcon = true;
329bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung        boolean showDismissIcon = true;
330bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung        int rightInset = width - getMeasuredWidth();
331bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung
332bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung        if (mTask != null && mTask.isFreeformTask()) {
333bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung            // For freeform tasks, we always show the app icon, and only show the title, move-task
334bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung            // icon, and the dismiss icon if there is room
335bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung            int appIconWidth = mIconView.getMeasuredWidth();
336bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung            int titleWidth = (int) mTitleView.getPaint().measureText(mTask.title);
337bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung            int dismissWidth = mDismissButton.getMeasuredWidth();
338bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung            int moveTaskWidth = mMoveTaskButton != null
339bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung                    ? mMoveTaskButton.getMeasuredWidth()
340bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung                    : 0;
341bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung            showTitle = width >= (appIconWidth + dismissWidth + moveTaskWidth + titleWidth);
342bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung            showMoveIcon = width >= (appIconWidth + dismissWidth + moveTaskWidth);
343bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung            showDismissIcon = width >= (appIconWidth + dismissWidth);
344de0591a0788c96757cce1eed93a7e8bc8bd0ef01Winson        }
345bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung
346bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung        mTitleView.setVisibility(showTitle ? View.VISIBLE : View.INVISIBLE);
347bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung        if (mMoveTaskButton != null) {
348bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung            mMoveTaskButton.setVisibility(showMoveIcon ? View.VISIBLE : View.INVISIBLE);
349bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung            mMoveTaskButton.setTranslationX(rightInset);
350de0591a0788c96757cce1eed93a7e8bc8bd0ef01Winson        }
351bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung        mDismissButton.setVisibility(showDismissIcon ? View.VISIBLE : View.INVISIBLE);
352bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung        mDismissButton.setTranslationX(rightInset);
35367c79578f94646bade5d336af0d4491179c1b37dWinson
35467c79578f94646bade5d336af0d4491179c1b37dWinson        setLeftTopRightBottom(0, 0, width, getMeasuredHeight());
355de0591a0788c96757cce1eed93a7e8bc8bd0ef01Winson    }
356de0591a0788c96757cce1eed93a7e8bc8bd0ef01Winson
357cd23c849afefe58b213d5abb1c581f15d3ad543aWinson Chung    @Override
358be8e696a1f40a61c52a74022f4f084fdc0600f90Winson    public void onDrawForeground(Canvas canvas) {
359be8e696a1f40a61c52a74022f4f084fdc0600f90Winson        super.onDrawForeground(canvas);
36094a0e89adb30b050f4b3319d93753b34d48e8490Winson
36194a0e89adb30b050f4b3319d93753b34d48e8490Winson        // Draw the dim layer with the rounded corners
36294a0e89adb30b050f4b3319d93753b34d48e8490Winson        canvas.drawRoundRect(0, 0, mTaskViewRect.width(), getHeight() + mCornerRadius,
36394a0e89adb30b050f4b3319d93753b34d48e8490Winson                mCornerRadius, mCornerRadius, mDimLayerPaint);
364cd23c849afefe58b213d5abb1c581f15d3ad543aWinson Chung    }
365cd23c849afefe58b213d5abb1c581f15d3ad543aWinson Chung
366b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schiller    /** Starts the focus timer. */
3674b9cded14346a7d8781ee6549c44888eb4ec9d83Winson    public void startFocusTimerIndicator(int duration) {
368c5ef63f4e95329158d88a6cbb05789b57098222dWinson        if (mFocusTimerIndicator == null) {
369c5ef63f4e95329158d88a6cbb05789b57098222dWinson            return;
370c5ef63f4e95329158d88a6cbb05789b57098222dWinson        }
371c5ef63f4e95329158d88a6cbb05789b57098222dWinson
372b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schiller        mFocusTimerIndicator.setVisibility(View.VISIBLE);
3734b9cded14346a7d8781ee6549c44888eb4ec9d83Winson        mFocusTimerIndicator.setMax(duration);
3744b9cded14346a7d8781ee6549c44888eb4ec9d83Winson        mFocusTimerIndicator.setProgress(duration);
3754b9cded14346a7d8781ee6549c44888eb4ec9d83Winson        if (mFocusTimerCountDown != null) {
3764b9cded14346a7d8781ee6549c44888eb4ec9d83Winson            mFocusTimerCountDown.cancel();
377b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schiller        }
3784b9cded14346a7d8781ee6549c44888eb4ec9d83Winson        mFocusTimerCountDown = new CountDownTimer(duration,
3794b9cded14346a7d8781ee6549c44888eb4ec9d83Winson                FOCUS_INDICATOR_INTERVAL_MS) {
3804b9cded14346a7d8781ee6549c44888eb4ec9d83Winson            public void onTick(long millisUntilFinished) {
3814b9cded14346a7d8781ee6549c44888eb4ec9d83Winson                mFocusTimerIndicator.setProgress((int) millisUntilFinished);
3824b9cded14346a7d8781ee6549c44888eb4ec9d83Winson            }
3834b9cded14346a7d8781ee6549c44888eb4ec9d83Winson
3844b9cded14346a7d8781ee6549c44888eb4ec9d83Winson            public void onFinish() {
3854b9cded14346a7d8781ee6549c44888eb4ec9d83Winson                // Do nothing
3864b9cded14346a7d8781ee6549c44888eb4ec9d83Winson            }
3874b9cded14346a7d8781ee6549c44888eb4ec9d83Winson        }.start();
388b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schiller    }
389b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schiller
390b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schiller    /** Cancels the focus timer. */
391b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schiller    public void cancelFocusTimerIndicator() {
392c5ef63f4e95329158d88a6cbb05789b57098222dWinson        if (mFocusTimerIndicator == null) {
393c5ef63f4e95329158d88a6cbb05789b57098222dWinson            return;
394c5ef63f4e95329158d88a6cbb05789b57098222dWinson        }
395c5ef63f4e95329158d88a6cbb05789b57098222dWinson
396c5ef63f4e95329158d88a6cbb05789b57098222dWinson        if (mFocusTimerCountDown != null) {
397b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schiller            mFocusTimerCountDown.cancel();
398b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schiller            mFocusTimerIndicator.setProgress(0);
399b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schiller            mFocusTimerIndicator.setVisibility(View.INVISIBLE);
400b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schiller        }
401b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schiller    }
402b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schiller
40322574afa00b7e32b7c4c5a1b98deebd67751b364Winson    /** Only exposed for the workaround for b/27815919. */
40422574afa00b7e32b7c4c5a1b98deebd67751b364Winson    public ImageView getIconView() {
40522574afa00b7e32b7c4c5a1b98deebd67751b364Winson        return mIconView;
40622574afa00b7e32b7c4c5a1b98deebd67751b364Winson    }
40722574afa00b7e32b7c4c5a1b98deebd67751b364Winson
408b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schiller    /** Returns the secondary color for a primary color. */
409b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schiller    int getSecondaryColor(int primaryColor, boolean useLightOverlayColor) {
410b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schiller        int overlayColor = useLightOverlayColor ? Color.WHITE : Color.BLACK;
411b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schiller        return Utilities.getColorWithOverlay(primaryColor, overlayColor, 0.8f);
412b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schiller    }
413b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schiller
414353c0b91daa97fa87f077be0f403fe7db8dedb40Winson Chung    /**
415353c0b91daa97fa87f077be0f403fe7db8dedb40Winson Chung     * Sets the dim alpha, only used when we are not using hardware layers.
416353c0b91daa97fa87f077be0f403fe7db8dedb40Winson Chung     * (see RecentsConfiguration.useHardwareLayers)
417353c0b91daa97fa87f077be0f403fe7db8dedb40Winson Chung     */
418e693aafe0511c2a7ffc571b22abeefba44046225Winson    public void setDimAlpha(float dimAlpha) {
419e693aafe0511c2a7ffc571b22abeefba44046225Winson        if (Float.compare(mDimAlpha, dimAlpha) != 0) {
420e693aafe0511c2a7ffc571b22abeefba44046225Winson            mDimAlpha = dimAlpha;
42159924fe0d9136cf349759bea1e06b661603f95feWinson            mTitleView.setAlpha(1f - dimAlpha);
422e693aafe0511c2a7ffc571b22abeefba44046225Winson            updateBackgroundColor(mBackground.getColor(), dimAlpha);
423e693aafe0511c2a7ffc571b22abeefba44046225Winson        }
424353c0b91daa97fa87f077be0f403fe7db8dedb40Winson Chung    }
425353c0b91daa97fa87f077be0f403fe7db8dedb40Winson Chung
42694a0e89adb30b050f4b3319d93753b34d48e8490Winson    /**
42794a0e89adb30b050f4b3319d93753b34d48e8490Winson     * Updates the background and highlight colors for this header.
42894a0e89adb30b050f4b3319d93753b34d48e8490Winson     */
4298be1634a543022bd6ee0c1e974d3201d452981e8Winson    private void updateBackgroundColor(int color, float dimAlpha) {
43094a0e89adb30b050f4b3319d93753b34d48e8490Winson        if (mTask != null) {
4318be1634a543022bd6ee0c1e974d3201d452981e8Winson            mBackground.setColorAndDim(color, dimAlpha);
432c5ef63f4e95329158d88a6cbb05789b57098222dWinson            // TODO: Consider using the saturation of the color to adjust the lightness as well
4338be1634a543022bd6ee0c1e974d3201d452981e8Winson            ColorUtils.colorToHSL(color, mTmpHSL);
434c5ef63f4e95329158d88a6cbb05789b57098222dWinson            mTmpHSL[2] = Math.min(1f, mTmpHSL[2] + OVERLAY_LIGHTNESS_INCREMENT * (1.0f - dimAlpha));
435c5ef63f4e95329158d88a6cbb05789b57098222dWinson            mOverlayBackground.setColorAndDim(ColorUtils.HSLToColor(mTmpHSL), dimAlpha);
43694a0e89adb30b050f4b3319d93753b34d48e8490Winson            mDimLayerPaint.setAlpha((int) (dimAlpha * 255));
437bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung            invalidate();
43894a0e89adb30b050f4b3319d93753b34d48e8490Winson        }
43994a0e89adb30b050f4b3319d93753b34d48e8490Winson    }
44094a0e89adb30b050f4b3319d93753b34d48e8490Winson
441d2a030613154e2007d9816e090c39e9726e7adbaWinson    /**
442d2a030613154e2007d9816e090c39e9726e7adbaWinson     * Binds the bar view to the task.
443d2a030613154e2007d9816e090c39e9726e7adbaWinson     */
444d2a030613154e2007d9816e090c39e9726e7adbaWinson    public void bindToTask(Task t, boolean touchExplorationEnabled, boolean disabledInSafeMode) {
4452536c7ed446203ea12b38cf05a88e603f8d1b768Winson        mTask = t;
4462536c7ed446203ea12b38cf05a88e603f8d1b768Winson
4478be1634a543022bd6ee0c1e974d3201d452981e8Winson        int primaryColor = disabledInSafeMode
4488be1634a543022bd6ee0c1e974d3201d452981e8Winson                ? mDisabledTaskBarBackgroundColor
4498be1634a543022bd6ee0c1e974d3201d452981e8Winson                : t.colorPrimary;
450e693aafe0511c2a7ffc571b22abeefba44046225Winson        if (mBackground.getColor() != primaryColor) {
451e693aafe0511c2a7ffc571b22abeefba44046225Winson            updateBackgroundColor(primaryColor, mDimAlpha);
452e693aafe0511c2a7ffc571b22abeefba44046225Winson        }
453296278a0679375b8c43962a9e3c9bb4e8ab201e7Winson Chung        if (!mTitleView.getText().toString().equals(t.title)) {
454296278a0679375b8c43962a9e3c9bb4e8ab201e7Winson Chung            mTitleView.setText(t.title);
455bdbb87dd7410dda10be04e01ec3a7e8344919293Winson Chung        }
456b92dd6358180eb7e6b7a57de1efa38e16597e650Winson        mTitleView.setContentDescription(t.titleDescription);
457296278a0679375b8c43962a9e3c9bb4e8ab201e7Winson Chung        mTitleView.setTextColor(t.useLightOnPrimaryColor ?
45894a0e89adb30b050f4b3319d93753b34d48e8490Winson                mTaskBarViewLightTextColor : mTaskBarViewDarkTextColor);
45993748a11cba1b44edbc2e888c997533461355594Winson Chung        mDismissButton.setImageDrawable(t.useLightOnPrimaryColor ?
46093748a11cba1b44edbc2e888c997533461355594Winson Chung                mLightDismissDrawable : mDarkDismissDrawable);
4615500390a006f2bbea565068234774a36cea076c0Winson        mDismissButton.setContentDescription(t.dismissDescription);
4623e5f0af085293004b378c07d2c52e51f1b32d1a2Winson        mDismissButton.setOnClickListener(this);
4633e5f0af085293004b378c07d2c52e51f1b32d1a2Winson        mDismissButton.setClickable(false);
46418227e483167c590121fd300d03c999dd057204cWinson        ((RippleDrawable) mDismissButton.getBackground()).setForceSoftware(true);
46548f2cda829ddb761697a0efb0cad42a62480c130Winson Chung
46648f2cda829ddb761697a0efb0cad42a62480c130Winson Chung        // When freeform workspaces are enabled, then update the move-task button depending on the
46748f2cda829ddb761697a0efb0cad42a62480c130Winson Chung        // current task
468bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung        if (mMoveTaskButton != null) {
46948f2cda829ddb761697a0efb0cad42a62480c130Winson Chung            if (t.isFreeformTask()) {
47048f2cda829ddb761697a0efb0cad42a62480c130Winson Chung                mMoveTaskTargetStackId = FULLSCREEN_WORKSPACE_STACK_ID;
4713e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson                mMoveTaskButton.setImageDrawable(t.useLightOnPrimaryColor
4723e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson                        ? mLightFullscreenIcon
4733e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson                        : mDarkFullscreenIcon);
47448f2cda829ddb761697a0efb0cad42a62480c130Winson Chung            } else {
47548f2cda829ddb761697a0efb0cad42a62480c130Winson Chung                mMoveTaskTargetStackId = FREEFORM_WORKSPACE_STACK_ID;
4763e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson                mMoveTaskButton.setImageDrawable(t.useLightOnPrimaryColor
4773e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson                        ? mLightFreeformIcon
4783e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson                        : mDarkFreeformIcon);
47948f2cda829ddb761697a0efb0cad42a62480c130Winson Chung            }
4803e5f0af085293004b378c07d2c52e51f1b32d1a2Winson            mMoveTaskButton.setOnClickListener(this);
4813e5f0af085293004b378c07d2c52e51f1b32d1a2Winson            mMoveTaskButton.setClickable(false);
48218227e483167c590121fd300d03c999dd057204cWinson            ((RippleDrawable) mMoveTaskButton.getBackground()).setForceSoftware(true);
48348f2cda829ddb761697a0efb0cad42a62480c130Winson Chung        }
4842536c7ed446203ea12b38cf05a88e603f8d1b768Winson
4854b9cded14346a7d8781ee6549c44888eb4ec9d83Winson        if (Recents.getDebugFlags().isFastToggleRecentsEnabled()) {
486c5ef63f4e95329158d88a6cbb05789b57098222dWinson            if (mFocusTimerIndicator == null) {
4879b001396c26e5b5ee95e0a54213a8a421179e365Winson                mFocusTimerIndicator = (ProgressBar) Utilities.findViewStubById(this,
4889b001396c26e5b5ee95e0a54213a8a421179e365Winson                        R.id.focus_timer_indicator_stub).inflate();
489c5ef63f4e95329158d88a6cbb05789b57098222dWinson            }
490c5ef63f4e95329158d88a6cbb05789b57098222dWinson            mFocusTimerIndicator.getProgressDrawable()
491c5ef63f4e95329158d88a6cbb05789b57098222dWinson                    .setColorFilter(
492c5ef63f4e95329158d88a6cbb05789b57098222dWinson                            getSecondaryColor(t.colorPrimary, t.useLightOnPrimaryColor),
493c5ef63f4e95329158d88a6cbb05789b57098222dWinson                            PorterDuff.Mode.SRC_IN);
494c5ef63f4e95329158d88a6cbb05789b57098222dWinson        }
495b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schiller
4962536c7ed446203ea12b38cf05a88e603f8d1b768Winson        // In accessibility, a single click on the focused app info button will show it
497bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung        if (touchExplorationEnabled) {
498b92dd6358180eb7e6b7a57de1efa38e16597e650Winson            mIconView.setContentDescription(t.appInfoDescription);
499296278a0679375b8c43962a9e3c9bb4e8ab201e7Winson Chung            mIconView.setOnClickListener(this);
5003e5f0af085293004b378c07d2c52e51f1b32d1a2Winson            mIconView.setClickable(true);
5012536c7ed446203ea12b38cf05a88e603f8d1b768Winson        }
5022536c7ed446203ea12b38cf05a88e603f8d1b768Winson    }
5032536c7ed446203ea12b38cf05a88e603f8d1b768Winson
504d2a030613154e2007d9816e090c39e9726e7adbaWinson    /**
505d2a030613154e2007d9816e090c39e9726e7adbaWinson     * Called when the bound task's data has loaded and this view should update to reflect the
506d2a030613154e2007d9816e090c39e9726e7adbaWinson     * changes.
507d2a030613154e2007d9816e090c39e9726e7adbaWinson     */
508d2a030613154e2007d9816e090c39e9726e7adbaWinson    public void onTaskDataLoaded() {
509d2a030613154e2007d9816e090c39e9726e7adbaWinson        if (mTask.icon != null) {
510d2a030613154e2007d9816e090c39e9726e7adbaWinson            mIconView.setImageDrawable(mTask.icon);
511d2a030613154e2007d9816e090c39e9726e7adbaWinson        }
512d2a030613154e2007d9816e090c39e9726e7adbaWinson    }
513d2a030613154e2007d9816e090c39e9726e7adbaWinson
5142536c7ed446203ea12b38cf05a88e603f8d1b768Winson    /** Unbinds the bar view from the task */
515bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung    void unbindFromTask(boolean touchExplorationEnabled) {
5162536c7ed446203ea12b38cf05a88e603f8d1b768Winson        mTask = null;
517296278a0679375b8c43962a9e3c9bb4e8ab201e7Winson Chung        mIconView.setImageDrawable(null);
518bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung        if (touchExplorationEnabled) {
5193e5f0af085293004b378c07d2c52e51f1b32d1a2Winson            mIconView.setClickable(false);
520bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung        }
521969f586533096999f10f5587f901949791154fa2Winson Chung    }
522969f586533096999f10f5587f901949791154fa2Winson Chung
523a26fb7822ddf3511796279b847cc216bee9e7f70Winson Chung    /** Animates this task bar if the user does not interact with the stack after a certain time. */
524a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung    void startNoUserInteractionAnimation() {
525bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung        int duration = getResources().getInteger(R.integer.recents_task_enter_from_app_duration);
526bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung        mDismissButton.setVisibility(View.VISIBLE);
5273e5f0af085293004b378c07d2c52e51f1b32d1a2Winson        mDismissButton.setClickable(true);
528bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung        if (mDismissButton.getVisibility() == VISIBLE) {
529133ad44269e4b45e056793b579a7628aa4d91ccbWinson Chung            mDismissButton.animate()
530133ad44269e4b45e056793b579a7628aa4d91ccbWinson Chung                    .alpha(1f)
531133ad44269e4b45e056793b579a7628aa4d91ccbWinson Chung                    .setInterpolator(Interpolators.FAST_OUT_LINEAR_IN)
532bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung                    .setDuration(duration)
533133ad44269e4b45e056793b579a7628aa4d91ccbWinson Chung                    .start();
534bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung        } else {
535bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung            mDismissButton.setAlpha(1f);
536bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung        }
537bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung        if (mMoveTaskButton != null) {
538bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung            if (mMoveTaskButton.getVisibility() == VISIBLE) {
539bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung                mMoveTaskButton.setVisibility(View.VISIBLE);
5403e5f0af085293004b378c07d2c52e51f1b32d1a2Winson                mMoveTaskButton.setClickable(true);
541bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung                mMoveTaskButton.animate()
542bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung                        .alpha(1f)
543bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung                        .setInterpolator(Interpolators.FAST_OUT_LINEAR_IN)
544bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung                        .setDuration(duration)
545bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung                        .start();
546bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung            } else {
547bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung                mMoveTaskButton.setAlpha(1f);
548bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung            }
549133ad44269e4b45e056793b579a7628aa4d91ccbWinson Chung        }
550a26fb7822ddf3511796279b847cc216bee9e7f70Winson Chung    }
551a26fb7822ddf3511796279b847cc216bee9e7f70Winson Chung
552b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schiller    /**
553b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schiller     * Mark this task view that the user does has not interacted with the stack after a certain
554b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schiller     * time.
555b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schiller     */
556a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung    void setNoUserInteractionState() {
557bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung        mDismissButton.setVisibility(View.VISIBLE);
558bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung        mDismissButton.animate().cancel();
559bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung        mDismissButton.setAlpha(1f);
5603e5f0af085293004b378c07d2c52e51f1b32d1a2Winson        mDismissButton.setClickable(true);
561bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung        if (mMoveTaskButton != null) {
562bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung            mMoveTaskButton.setVisibility(View.VISIBLE);
563bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung            mMoveTaskButton.animate().cancel();
564bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung            mMoveTaskButton.setAlpha(1f);
5653e5f0af085293004b378c07d2c52e51f1b32d1a2Winson            mMoveTaskButton.setClickable(true);
566133ad44269e4b45e056793b579a7628aa4d91ccbWinson Chung        }
567a26fb7822ddf3511796279b847cc216bee9e7f70Winson Chung    }
568a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung
569b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schiller    /**
570b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schiller     * Resets the state tracking that the user has not interacted with the stack after a certain
571b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schiller     * time.
572b124d5607fb6bdfcc9e6c2e9ae24cadaf7f0b55bPeter Schiller     */
573b0a28ea5d381cd3a8477cf7fd82797199c80ca67Winson Chung    void resetNoUserInteractionState() {
574b0a28ea5d381cd3a8477cf7fd82797199c80ca67Winson Chung        mDismissButton.setVisibility(View.INVISIBLE);
575bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung        mDismissButton.setAlpha(0f);
5763e5f0af085293004b378c07d2c52e51f1b32d1a2Winson        mDismissButton.setClickable(false);
577bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung        if (mMoveTaskButton != null) {
578bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung            mMoveTaskButton.setVisibility(View.INVISIBLE);
579bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung            mMoveTaskButton.setAlpha(0f);
5803e5f0af085293004b378c07d2c52e51f1b32d1a2Winson            mMoveTaskButton.setClickable(false);
581bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung        }
582b0a28ea5d381cd3a8477cf7fd82797199c80ca67Winson Chung    }
583b0a28ea5d381cd3a8477cf7fd82797199c80ca67Winson Chung
584bf5dbf1c151eb64f4068f233e72b0a867348bf8cWinson Chung    @Override
585bf5dbf1c151eb64f4068f233e72b0a867348bf8cWinson Chung    protected int[] onCreateDrawableState(int extraSpace) {
586bf5dbf1c151eb64f4068f233e72b0a867348bf8cWinson Chung
587bf5dbf1c151eb64f4068f233e72b0a867348bf8cWinson Chung        // Don't forward our state to the drawable - we do it manually in onTaskViewFocusChanged.
588bf5dbf1c151eb64f4068f233e72b0a867348bf8cWinson Chung        // This is to prevent layer trashing when the view is pressed.
589bf5dbf1c151eb64f4068f233e72b0a867348bf8cWinson Chung        return new int[] {};
590bf5dbf1c151eb64f4068f233e72b0a867348bf8cWinson Chung    }
591bf5dbf1c151eb64f4068f233e72b0a867348bf8cWinson Chung
592900fb48d269e2fbf3baea995c6324e4c08ad7c22Jorim Jaggi    @Override
5932536c7ed446203ea12b38cf05a88e603f8d1b768Winson    public void onClick(View v) {
594296278a0679375b8c43962a9e3c9bb4e8ab201e7Winson Chung        if (v == mIconView) {
595bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung            // In accessibility, a single click on the focused app info button will show it
596bbb3d3de3c058f115ab1fba0ddb7238e54745c0bWinson Chung            EventBus.getDefault().send(new ShowApplicationInfoEvent(mTask));
5972536c7ed446203ea12b38cf05a88e603f8d1b768Winson        } else if (v == mDismissButton) {
598be7607af8875236b9cf7bdb5f5aa089c207529afWinson            TaskView tv = Utilities.findParent(this, TaskView.class);
5992536c7ed446203ea12b38cf05a88e603f8d1b768Winson            tv.dismissTask();
6002536c7ed446203ea12b38cf05a88e603f8d1b768Winson
6012536c7ed446203ea12b38cf05a88e603f8d1b768Winson            // Keep track of deletions by the dismiss button
6022536c7ed446203ea12b38cf05a88e603f8d1b768Winson            MetricsLogger.histogram(getContext(), "overview_task_dismissed_source",
6032536c7ed446203ea12b38cf05a88e603f8d1b768Winson                    Constants.Metrics.DismissSourceHeaderButton);
6042536c7ed446203ea12b38cf05a88e603f8d1b768Winson        } else if (v == mMoveTaskButton) {
60548f2cda829ddb761697a0efb0cad42a62480c130Winson Chung            TaskView tv = Utilities.findParent(this, TaskView.class);
60648f2cda829ddb761697a0efb0cad42a62480c130Winson Chung            Rect bounds = mMoveTaskTargetStackId == FREEFORM_WORKSPACE_STACK_ID
60748f2cda829ddb761697a0efb0cad42a62480c130Winson Chung                    ? new Rect(mTaskViewRect)
60848f2cda829ddb761697a0efb0cad42a62480c130Winson Chung                    : new Rect();
60948f2cda829ddb761697a0efb0cad42a62480c130Winson Chung            EventBus.getDefault().send(new LaunchTaskEvent(tv, mTask, bounds,
61048f2cda829ddb761697a0efb0cad42a62480c130Winson Chung                    mMoveTaskTargetStackId, false));
611c5ef63f4e95329158d88a6cbb05789b57098222dWinson        } else if (v == mAppInfoView) {
612c5ef63f4e95329158d88a6cbb05789b57098222dWinson            EventBus.getDefault().send(new ShowApplicationInfoEvent(mTask));
613c5ef63f4e95329158d88a6cbb05789b57098222dWinson        } else if (v == mAppIconView) {
614c5ef63f4e95329158d88a6cbb05789b57098222dWinson            hideAppOverlay(false /* immediate */);
6152536c7ed446203ea12b38cf05a88e603f8d1b768Winson        }
6162536c7ed446203ea12b38cf05a88e603f8d1b768Winson    }
6172536c7ed446203ea12b38cf05a88e603f8d1b768Winson
6182536c7ed446203ea12b38cf05a88e603f8d1b768Winson    @Override
6192536c7ed446203ea12b38cf05a88e603f8d1b768Winson    public boolean onLongClick(View v) {
620296278a0679375b8c43962a9e3c9bb4e8ab201e7Winson Chung        if (v == mIconView) {
621c5ef63f4e95329158d88a6cbb05789b57098222dWinson            showAppOverlay();
622c5ef63f4e95329158d88a6cbb05789b57098222dWinson            return true;
623c5ef63f4e95329158d88a6cbb05789b57098222dWinson        } else if (v == mAppIconView) {
624c5ef63f4e95329158d88a6cbb05789b57098222dWinson            hideAppOverlay(false /* immediate */);
6252536c7ed446203ea12b38cf05a88e603f8d1b768Winson            return true;
6262536c7ed446203ea12b38cf05a88e603f8d1b768Winson        }
6272536c7ed446203ea12b38cf05a88e603f8d1b768Winson        return false;
6282536c7ed446203ea12b38cf05a88e603f8d1b768Winson    }
629c5ef63f4e95329158d88a6cbb05789b57098222dWinson
630c5ef63f4e95329158d88a6cbb05789b57098222dWinson    /**
631c5ef63f4e95329158d88a6cbb05789b57098222dWinson     * Shows the application overlay.
632c5ef63f4e95329158d88a6cbb05789b57098222dWinson     */
633c5ef63f4e95329158d88a6cbb05789b57098222dWinson    private void showAppOverlay() {
634c5ef63f4e95329158d88a6cbb05789b57098222dWinson        // Skip early if the task is invalid
635c5ef63f4e95329158d88a6cbb05789b57098222dWinson        SystemServicesProxy ssp = Recents.getSystemServices();
636c5ef63f4e95329158d88a6cbb05789b57098222dWinson        ComponentName cn = mTask.key.getComponent();
637c5ef63f4e95329158d88a6cbb05789b57098222dWinson        int userId = mTask.key.userId;
638c5ef63f4e95329158d88a6cbb05789b57098222dWinson        ActivityInfo activityInfo = ssp.getActivityInfo(cn, userId);
639c5ef63f4e95329158d88a6cbb05789b57098222dWinson        if (activityInfo == null) {
640c5ef63f4e95329158d88a6cbb05789b57098222dWinson            return;
641c5ef63f4e95329158d88a6cbb05789b57098222dWinson        }
642c5ef63f4e95329158d88a6cbb05789b57098222dWinson
643c5ef63f4e95329158d88a6cbb05789b57098222dWinson        // Inflate the overlay if necessary
644c5ef63f4e95329158d88a6cbb05789b57098222dWinson        if (mAppOverlayView == null) {
6459b001396c26e5b5ee95e0a54213a8a421179e365Winson            mAppOverlayView = (FrameLayout) Utilities.findViewStubById(this,
6469b001396c26e5b5ee95e0a54213a8a421179e365Winson                    R.id.app_overlay_stub).inflate();
647c5ef63f4e95329158d88a6cbb05789b57098222dWinson            mAppOverlayView.setBackground(mOverlayBackground);
648c5ef63f4e95329158d88a6cbb05789b57098222dWinson            mAppIconView = (ImageView) mAppOverlayView.findViewById(R.id.app_icon);
649c5ef63f4e95329158d88a6cbb05789b57098222dWinson            mAppIconView.setOnClickListener(this);
650c5ef63f4e95329158d88a6cbb05789b57098222dWinson            mAppIconView.setOnLongClickListener(this);
651c5ef63f4e95329158d88a6cbb05789b57098222dWinson            mAppInfoView = (ImageView) mAppOverlayView.findViewById(R.id.app_info);
652c5ef63f4e95329158d88a6cbb05789b57098222dWinson            mAppInfoView.setOnClickListener(this);
653c5ef63f4e95329158d88a6cbb05789b57098222dWinson            mAppTitleView = (TextView) mAppOverlayView.findViewById(R.id.app_title);
654217009356efa2b854ab3981dff8d315a0d679c73Winson            updateLayoutParams(mAppIconView, mAppTitleView, null, mAppInfoView);
655c5ef63f4e95329158d88a6cbb05789b57098222dWinson        }
656c5ef63f4e95329158d88a6cbb05789b57098222dWinson
657c5ef63f4e95329158d88a6cbb05789b57098222dWinson        // Update the overlay contents for the current app
658c5ef63f4e95329158d88a6cbb05789b57098222dWinson        mAppTitleView.setText(ssp.getBadgedApplicationLabel(activityInfo.applicationInfo, userId));
6594c84a8c481093e81c2e27de4cecf92c41992f4a1Winson        mAppTitleView.setTextColor(mTask.useLightOnPrimaryColor ?
6604c84a8c481093e81c2e27de4cecf92c41992f4a1Winson                mTaskBarViewLightTextColor : mTaskBarViewDarkTextColor);
6614c84a8c481093e81c2e27de4cecf92c41992f4a1Winson        mAppIconView.setImageDrawable(ssp.getBadgedApplicationIcon(activityInfo.applicationInfo,
6624c84a8c481093e81c2e27de4cecf92c41992f4a1Winson                userId));
663c5ef63f4e95329158d88a6cbb05789b57098222dWinson        mAppInfoView.setImageDrawable(mTask.useLightOnPrimaryColor
664c5ef63f4e95329158d88a6cbb05789b57098222dWinson                ? mLightInfoIcon
665c5ef63f4e95329158d88a6cbb05789b57098222dWinson                : mDarkInfoIcon);
666c5ef63f4e95329158d88a6cbb05789b57098222dWinson        mAppOverlayView.setVisibility(View.VISIBLE);
667c5ef63f4e95329158d88a6cbb05789b57098222dWinson
668c5ef63f4e95329158d88a6cbb05789b57098222dWinson        int x = mIconView.getLeft() + mIconView.getWidth() / 2;
669c5ef63f4e95329158d88a6cbb05789b57098222dWinson        int y = mIconView.getTop() + mIconView.getHeight() / 2;
670c5ef63f4e95329158d88a6cbb05789b57098222dWinson        Animator revealAnim = ViewAnimationUtils.createCircularReveal(mAppOverlayView, x, y, 0,
671c5ef63f4e95329158d88a6cbb05789b57098222dWinson                getWidth());
672c5ef63f4e95329158d88a6cbb05789b57098222dWinson        revealAnim.setDuration(OVERLAY_REVEAL_DURATION);
673c0d7058b14c24cd07912f5629c26b39b7b4673d5Winson        revealAnim.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
674c5ef63f4e95329158d88a6cbb05789b57098222dWinson        revealAnim.start();
675c5ef63f4e95329158d88a6cbb05789b57098222dWinson    }
676c5ef63f4e95329158d88a6cbb05789b57098222dWinson
677c5ef63f4e95329158d88a6cbb05789b57098222dWinson    /**
678c5ef63f4e95329158d88a6cbb05789b57098222dWinson     * Hide the application overlay.
679c5ef63f4e95329158d88a6cbb05789b57098222dWinson     */
680c5ef63f4e95329158d88a6cbb05789b57098222dWinson    private void hideAppOverlay(boolean immediate) {
681c5ef63f4e95329158d88a6cbb05789b57098222dWinson        // Skip if we haven't even loaded the overlay yet
682c5ef63f4e95329158d88a6cbb05789b57098222dWinson        if (mAppOverlayView == null) {
683c5ef63f4e95329158d88a6cbb05789b57098222dWinson            return;
684c5ef63f4e95329158d88a6cbb05789b57098222dWinson        }
685c5ef63f4e95329158d88a6cbb05789b57098222dWinson
686c5ef63f4e95329158d88a6cbb05789b57098222dWinson        if (immediate) {
687c5ef63f4e95329158d88a6cbb05789b57098222dWinson            mAppOverlayView.setVisibility(View.GONE);
688c5ef63f4e95329158d88a6cbb05789b57098222dWinson        } else {
689c5ef63f4e95329158d88a6cbb05789b57098222dWinson            int x = mIconView.getLeft() + mIconView.getWidth() / 2;
690c5ef63f4e95329158d88a6cbb05789b57098222dWinson            int y = mIconView.getTop() + mIconView.getHeight() / 2;
691c5ef63f4e95329158d88a6cbb05789b57098222dWinson            Animator revealAnim = ViewAnimationUtils.createCircularReveal(mAppOverlayView, x, y,
692c5ef63f4e95329158d88a6cbb05789b57098222dWinson                    getWidth(), 0);
693c5ef63f4e95329158d88a6cbb05789b57098222dWinson            revealAnim.setDuration(OVERLAY_REVEAL_DURATION);
694c0d7058b14c24cd07912f5629c26b39b7b4673d5Winson            revealAnim.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
695c5ef63f4e95329158d88a6cbb05789b57098222dWinson            revealAnim.addListener(new AnimatorListenerAdapter() {
696c5ef63f4e95329158d88a6cbb05789b57098222dWinson                @Override
697c5ef63f4e95329158d88a6cbb05789b57098222dWinson                public void onAnimationEnd(Animator animation) {
698c5ef63f4e95329158d88a6cbb05789b57098222dWinson                    mAppOverlayView.setVisibility(View.GONE);
699c5ef63f4e95329158d88a6cbb05789b57098222dWinson                }
700c5ef63f4e95329158d88a6cbb05789b57098222dWinson            });
701c5ef63f4e95329158d88a6cbb05789b57098222dWinson            revealAnim.start();
702c5ef63f4e95329158d88a6cbb05789b57098222dWinson        }
703c5ef63f4e95329158d88a6cbb05789b57098222dWinson    }
70437c8d8ef855aacb074ee0b702a46dbc62b7551a2Winson Chung}
705