1b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan/*
2b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan * Copyright (C) 2016 The Android Open Source Project
3b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan *
4b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan * Licensed under the Apache License, Version 2.0 (the "License");
5b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan * you may not use this file except in compliance with the License.
6b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan * You may obtain a copy of the License at
7b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan *
8b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan *      http://www.apache.org/licenses/LICENSE-2.0
9b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan *
10b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan * Unless required by applicable law or agreed to in writing, software
11b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan * distributed under the License is distributed on an "AS IS" BASIS,
12b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan * See the License for the specific language governing permissions and
14b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan * limitations under the License.
15b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan */
16b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanpackage com.android.systemui.recents.tv;
17b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
18b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport android.app.Activity;
19b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport android.app.ActivityOptions;
20b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport android.content.Intent;
21c92a7d12e345e05272f3e84d49d75c77dc6e3edcJaewan Kimimport android.graphics.Rect;
22b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport android.os.Bundle;
23b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport android.os.UserHandle;
24b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport android.util.Log;
25b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport android.view.KeyEvent;
26b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport android.view.View;
27b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport android.view.ViewTreeObserver.OnPreDrawListener;
28b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport android.view.WindowManager;
29f915bf7e9b6b1d0f65f16788d98ee39df0bb2e7bJaewan Kimimport android.view.accessibility.AccessibilityEvent;
30c92a7d12e345e05272f3e84d49d75c77dc6e3edcJaewan Kimimport android.widget.FrameLayout.LayoutParams;
31c0d7058b14c24cd07912f5629c26b39b7b4673d5Winson
32b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport com.android.systemui.R;
33c0d7058b14c24cd07912f5629c26b39b7b4673d5Winsonimport com.android.systemui.recents.Recents;
34c0d7058b14c24cd07912f5629c26b39b7b4673d5Winsonimport com.android.systemui.recents.RecentsActivityLaunchState;
35c0d7058b14c24cd07912f5629c26b39b7b4673d5Winsonimport com.android.systemui.recents.RecentsConfiguration;
36c0d7058b14c24cd07912f5629c26b39b7b4673d5Winsonimport com.android.systemui.recents.RecentsImpl;
37b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport com.android.systemui.recents.events.EventBus;
38b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent;
39b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport com.android.systemui.recents.events.activity.DismissRecentsToHomeAnimationStarted;
40b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationCompletedEvent;
41b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport com.android.systemui.recents.events.activity.HideRecentsEvent;
42b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport com.android.systemui.recents.events.activity.LaunchTaskFailedEvent;
43b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport com.android.systemui.recents.events.activity.ToggleRecentsEvent;
44b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
45b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport com.android.systemui.recents.events.ui.AllTaskViewsDismissedEvent;
46b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport com.android.systemui.recents.events.ui.DeleteTaskDataEvent;
47b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport com.android.systemui.recents.events.ui.UserInteractionEvent;
48b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport com.android.systemui.recents.events.ui.focus.DismissFocusedTaskViewEvent;
49b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport com.android.systemui.recents.misc.SystemServicesProxy;
50b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport com.android.systemui.recents.model.RecentsPackageMonitor;
51b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport com.android.systemui.recents.model.RecentsTaskLoadPlan;
52b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport com.android.systemui.recents.model.RecentsTaskLoader;
53b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport com.android.systemui.recents.model.Task;
54b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport com.android.systemui.recents.model.TaskStack;
5567ed54a724df258738062e60d7f702f396502b49Sid Soundararajanimport com.android.systemui.recents.tv.animations.HomeRecentsEnterExitAnimationHolder;
56b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport com.android.systemui.recents.tv.views.RecentsTvView;
574332dda9a76191b0f055dedbea8d509a20d5c455Sid Soundararajanimport com.android.systemui.recents.tv.views.TaskCardView;
5867ed54a724df258738062e60d7f702f396502b49Sid Soundararajanimport com.android.systemui.recents.tv.views.TaskStackHorizontalGridView;
59b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport com.android.systemui.recents.tv.views.TaskStackHorizontalViewAdapter;
60b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport com.android.systemui.statusbar.BaseStatusBar;
61b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport com.android.systemui.tv.pip.PipManager;
62a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kimimport com.android.systemui.tv.pip.PipRecentsOverlayManager;
63b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
64b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanimport java.util.ArrayList;
651008cc25863be3d86e01c15eeabe9dfedb963224Sid Soundararajanimport java.util.Collections;
661008cc25863be3d86e01c15eeabe9dfedb963224Sid Soundararajanimport java.util.List;
67c92a7d12e345e05272f3e84d49d75c77dc6e3edcJaewan Kim
68b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan/**
69b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan * The main TV recents activity started by the RecentsImpl.
70b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan */
71b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajanpublic class RecentsTvActivity extends Activity implements OnPreDrawListener {
72b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    private final static String TAG = "RecentsTvActivity";
73b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    private final static boolean DEBUG = false;
74b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
75b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    public final static int EVENT_BUS_PRIORITY = Recents.EVENT_BUS_PRIORITY + 1;
76165410d445bf200ac615d4d1abc7221e95c5f82cSid Soundararajan    private final static String RECENTS_HOME_INTENT_EXTRA =
77165410d445bf200ac615d4d1abc7221e95c5f82cSid Soundararajan            "com.android.systemui.recents.tv.RecentsTvActivity.RECENTS_HOME_INTENT_EXTRA";
78b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
79b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    private boolean mFinishedOnStartup;
80b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    private RecentsPackageMonitor mPackageMonitor;
81b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    private long mLastTabKeyEventTime;
82b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    private boolean mIgnoreAltTabRelease;
8367ed54a724df258738062e60d7f702f396502b49Sid Soundararajan    private boolean mLaunchedFromHome;
84a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim    private boolean mTalkBackEnabled;
85b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
86b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    private RecentsTvView mRecentsView;
87a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim    private View mPipView;
88b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    private TaskStackHorizontalViewAdapter mTaskStackViewAdapter;
8967ed54a724df258738062e60d7f702f396502b49Sid Soundararajan    private TaskStackHorizontalGridView mTaskStackHorizontalGridView;
90b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    private FinishRecentsRunnable mFinishLaunchHomeRunnable;
9167ed54a724df258738062e60d7f702f396502b49Sid Soundararajan    private HomeRecentsEnterExitAnimationHolder mHomeRecentsEnterExitAnimationHolder;
92b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
93a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim    private final PipManager mPipManager = PipManager.getInstance();
94a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim    private final PipManager.Listener mPipListener = new PipManager.Listener() {
95c92a7d12e345e05272f3e84d49d75c77dc6e3edcJaewan Kim        @Override
9682ac50d607ac252905bf8a095d6e6061f023664eJaewan Kim        public void onPipEntered() {
9782ac50d607ac252905bf8a095d6e6061f023664eJaewan Kim            updatePipUI();
9882ac50d607ac252905bf8a095d6e6061f023664eJaewan Kim        }
9982ac50d607ac252905bf8a095d6e6061f023664eJaewan Kim
10082ac50d607ac252905bf8a095d6e6061f023664eJaewan Kim        @Override
101c92a7d12e345e05272f3e84d49d75c77dc6e3edcJaewan Kim        public void onPipActivityClosed() {
10282ac50d607ac252905bf8a095d6e6061f023664eJaewan Kim            updatePipUI();
103c92a7d12e345e05272f3e84d49d75c77dc6e3edcJaewan Kim        }
104c92a7d12e345e05272f3e84d49d75c77dc6e3edcJaewan Kim
105c92a7d12e345e05272f3e84d49d75c77dc6e3edcJaewan Kim        @Override
1068f584b8dee2a2a15a1777fabf6ba033b78419b9aJaewan Kim        public void onShowPipMenu() {
1078f584b8dee2a2a15a1777fabf6ba033b78419b9aJaewan Kim            updatePipUI();
1088f584b8dee2a2a15a1777fabf6ba033b78419b9aJaewan Kim        }
109c92a7d12e345e05272f3e84d49d75c77dc6e3edcJaewan Kim
110c92a7d12e345e05272f3e84d49d75c77dc6e3edcJaewan Kim        @Override
11172a67c93166b8da5f800e59f5d7ac18f33ad38e7Youngsang Cho        public void onMoveToFullscreen() {
11272a67c93166b8da5f800e59f5d7ac18f33ad38e7Youngsang Cho            // Recents should be dismissed when PIP moves to fullscreen. If not, Recents will
11372a67c93166b8da5f800e59f5d7ac18f33ad38e7Youngsang Cho            // be unnecessarily shown in the scenario: PIP->Fullscreen->PIP.
114419c89533a148d0037e98b801068bb81f8a2cd2aJaewan Kim            // Do not show Recents close animation because PIP->Fullscreen animation will be shown
115419c89533a148d0037e98b801068bb81f8a2cd2aJaewan Kim            // instead.
116419c89533a148d0037e98b801068bb81f8a2cd2aJaewan Kim            dismissRecentsToLaunchTargetTaskOrHome(false);
11772a67c93166b8da5f800e59f5d7ac18f33ad38e7Youngsang Cho        }
118c92a7d12e345e05272f3e84d49d75c77dc6e3edcJaewan Kim
119c92a7d12e345e05272f3e84d49d75c77dc6e3edcJaewan Kim        @Override
120c92a7d12e345e05272f3e84d49d75c77dc6e3edcJaewan Kim        public void onPipResizeAboutToStart() { }
121c92a7d12e345e05272f3e84d49d75c77dc6e3edcJaewan Kim    };
122a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim    private PipRecentsOverlayManager mPipRecentsOverlayManager;
123a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim    private final PipRecentsOverlayManager.Callback mPipRecentsOverlayManagerCallback =
124a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim            new PipRecentsOverlayManager.Callback() {
125a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim                @Override
126a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim                public void onClosed() {
127419c89533a148d0037e98b801068bb81f8a2cd2aJaewan Kim                    dismissRecentsToLaunchTargetTaskOrHome(true);
128a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim                }
129a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim
130a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim                @Override
131a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim                public void onBackPressed() {
132a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim                    RecentsTvActivity.this.onBackPressed();
133a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim                }
134a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim
135a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim                @Override
136a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim                public void onRecentsFocused() {
137a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim                    if (mTalkBackEnabled) {
138a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim                        mTaskStackHorizontalGridView.requestFocus();
139a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim                        mTaskStackHorizontalGridView.sendAccessibilityEvent(
140a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim                                AccessibilityEvent.TYPE_VIEW_FOCUSED);
141a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim                    }
142a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim                    mTaskStackHorizontalGridView.startFocusGainAnimation();
143a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim                }
144a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim            };
145a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim
146a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim    private final View.OnFocusChangeListener mPipViewFocusChangeListener =
147a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim            new View.OnFocusChangeListener() {
148a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim                @Override
149a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim                public void onFocusChange(View v, boolean hasFocus) {
150a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim                    if (hasFocus) {
151a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim                        requestPipControlsFocus();
152a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim                    }
153a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim                }
154a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim            };
155b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
156b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    /**
157b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan     * A common Runnable to finish Recents by launching Home with an animation depending on the
158b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan     * last activity launch state.  Generally we always launch home when we exit Recents rather than
159b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan     * just finishing the activity since we don't know what is behind Recents in the task stack.
160b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan     */
161b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    class FinishRecentsRunnable implements Runnable {
162b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        Intent mLaunchIntent;
163b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
164b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        /**
165b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan         * Creates a finish runnable that starts the specified intent.
166b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan         */
167b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        public FinishRecentsRunnable(Intent launchIntent) {
168b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            mLaunchIntent = launchIntent;
169b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        }
170b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
171b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        @Override
172b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        public void run() {
173b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            try {
174b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan                ActivityOptions opts = ActivityOptions.makeCustomAnimation(RecentsTvActivity.this,
175008ee15fe82c8216e8e4f67e3032de468cc6c92aWinson                        R.anim.recents_to_launcher_enter, R.anim.recents_to_launcher_exit);
176b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan                startActivityAsUser(mLaunchIntent, opts.toBundle(), UserHandle.CURRENT);
177b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            } catch (Exception e) {
178b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan                Log.e(TAG, getString(R.string.recents_launch_error_message, "Home"), e);
179b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            }
180b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        }
181b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    }
182b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
183b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    private void updateRecentsTasks() {
184b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        RecentsTaskLoader loader = Recents.getTaskLoader();
185b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        RecentsTaskLoadPlan plan = RecentsImpl.consumeInstanceLoadPlan();
186b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        if (plan == null) {
187b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            plan = loader.createLoadPlan(this);
188b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        }
189b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
190b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        RecentsConfiguration config = Recents.getConfiguration();
191b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        RecentsActivityLaunchState launchState = config.getLaunchState();
192b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        if (!plan.hasTasks()) {
193dfd7be012b889f92d3e7e6d80ff7fe6b55c75901Winson            loader.preloadTasks(plan, -1, !launchState.launchedFromHome);
194b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        }
1954332dda9a76191b0f055dedbea8d509a20d5c455Sid Soundararajan
1964332dda9a76191b0f055dedbea8d509a20d5c455Sid Soundararajan        int numVisibleTasks = TaskCardView.getNumberOfVisibleTasks(getApplicationContext());
19767ed54a724df258738062e60d7f702f396502b49Sid Soundararajan        mLaunchedFromHome = launchState.launchedFromHome;
198b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        TaskStack stack = plan.getTaskStack();
199b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options();
200b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        loadOpts.runningTaskId = launchState.launchedToTaskId;
2014332dda9a76191b0f055dedbea8d509a20d5c455Sid Soundararajan        loadOpts.numVisibleTasks = numVisibleTasks;
2024332dda9a76191b0f055dedbea8d509a20d5c455Sid Soundararajan        loadOpts.numVisibleTaskThumbnails = numVisibleTasks;
203b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        loader.loadTasks(this, plan, loadOpts);
204b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
2051008cc25863be3d86e01c15eeabe9dfedb963224Sid Soundararajan        List stackTasks = stack.getStackTasks();
2061008cc25863be3d86e01c15eeabe9dfedb963224Sid Soundararajan        Collections.reverse(stackTasks);
207b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        if (mTaskStackViewAdapter == null) {
2081008cc25863be3d86e01c15eeabe9dfedb963224Sid Soundararajan            mTaskStackViewAdapter = new TaskStackHorizontalViewAdapter(stackTasks);
20967ed54a724df258738062e60d7f702f396502b49Sid Soundararajan            mTaskStackHorizontalGridView = mRecentsView
21067ed54a724df258738062e60d7f702f396502b49Sid Soundararajan                    .setTaskStackViewAdapter(mTaskStackViewAdapter);
211a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim            mHomeRecentsEnterExitAnimationHolder = new HomeRecentsEnterExitAnimationHolder(
212a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim                    getApplicationContext(), mTaskStackHorizontalGridView);
213b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        } else {
2141008cc25863be3d86e01c15eeabe9dfedb963224Sid Soundararajan            mTaskStackViewAdapter.setNewStackTasks(stackTasks);
215b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        }
216a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim        mRecentsView.init(stack);
217b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
218b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        if (launchState.launchedToTaskId != -1) {
219b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            ArrayList<Task> tasks = stack.getStackTasks();
220b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            int taskCount = tasks.size();
221b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            for (int i = 0; i < taskCount; i++) {
222b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan                Task t = tasks.get(i);
223b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan                if (t.key.id == launchState.launchedToTaskId) {
224b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan                    t.isLaunchTarget = true;
225b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan                    break;
226b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan                }
227b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            }
228b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        }
229b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    }
230b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
231419c89533a148d0037e98b801068bb81f8a2cd2aJaewan Kim    boolean dismissRecentsToLaunchTargetTaskOrHome(boolean animate) {
232b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        SystemServicesProxy ssp = Recents.getSystemServices();
233d46b72788e8811d2e423ea1e5b2ff104ecb7f721Winson        if (ssp.isRecentsActivityVisible()) {
234b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            // If we have a focused Task, launch that Task now
235419c89533a148d0037e98b801068bb81f8a2cd2aJaewan Kim            if (mRecentsView.launchPreviousTask(animate)) {
236419c89533a148d0037e98b801068bb81f8a2cd2aJaewan Kim              return true;
237419c89533a148d0037e98b801068bb81f8a2cd2aJaewan Kim            }
238b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            // If none of the other cases apply, then just go Home
239419c89533a148d0037e98b801068bb81f8a2cd2aJaewan Kim            dismissRecentsToHome(animate /* animateTaskViews */);
240b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        }
241b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        return false;
242b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    }
243b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
244b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    boolean dismissRecentsToFocusedTaskOrHome() {
245b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        SystemServicesProxy ssp = Recents.getSystemServices();
246d46b72788e8811d2e423ea1e5b2ff104ecb7f721Winson        if (ssp.isRecentsActivityVisible()) {
247b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            // If we have a focused Task, launch that Task now
248b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            if (mRecentsView.launchFocusedTask()) return true;
249b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            // If none of the other cases apply, then just go Home
250b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            dismissRecentsToHome(true /* animateTaskViews */);
251b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            return true;
252b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        }
253b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        return false;
254b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    }
255b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
256b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    void dismissRecentsToHome(boolean animateTaskViews) {
25767ed54a724df258738062e60d7f702f396502b49Sid Soundararajan        Runnable closeSystemWindows = new Runnable() {
258b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            @Override
259b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            public void run() {
260b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan                Recents.getSystemServices().sendCloseSystemWindows(
261b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan                        BaseStatusBar.SYSTEM_DIALOG_REASON_HOME_KEY);
262b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            }
26367ed54a724df258738062e60d7f702f396502b49Sid Soundararajan        };
26467ed54a724df258738062e60d7f702f396502b49Sid Soundararajan        DismissRecentsToHomeAnimationStarted dismissEvent =
26567ed54a724df258738062e60d7f702f396502b49Sid Soundararajan                new DismissRecentsToHomeAnimationStarted(animateTaskViews);
26667ed54a724df258738062e60d7f702f396502b49Sid Soundararajan        dismissEvent.addPostAnimationCallback(mFinishLaunchHomeRunnable);
26767ed54a724df258738062e60d7f702f396502b49Sid Soundararajan        dismissEvent.addPostAnimationCallback(closeSystemWindows);
26867ed54a724df258738062e60d7f702f396502b49Sid Soundararajan
269419c89533a148d0037e98b801068bb81f8a2cd2aJaewan Kim        if (mTaskStackHorizontalGridView.getChildCount() > 0 && animateTaskViews) {
27067ed54a724df258738062e60d7f702f396502b49Sid Soundararajan            mHomeRecentsEnterExitAnimationHolder.startExitAnimation(dismissEvent);
27167ed54a724df258738062e60d7f702f396502b49Sid Soundararajan        } else {
27267ed54a724df258738062e60d7f702f396502b49Sid Soundararajan            closeSystemWindows.run();
27367ed54a724df258738062e60d7f702f396502b49Sid Soundararajan            mFinishLaunchHomeRunnable.run();
27467ed54a724df258738062e60d7f702f396502b49Sid Soundararajan        }
275b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    }
276b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
277b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    boolean dismissRecentsToHomeIfVisible(boolean animated) {
278b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        SystemServicesProxy ssp = Recents.getSystemServices();
279d46b72788e8811d2e423ea1e5b2ff104ecb7f721Winson        if (ssp.isRecentsActivityVisible()) {
280b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            // Return to Home
281b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            dismissRecentsToHome(animated);
282b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            return true;
283b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        }
284b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        return false;
285b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    }
286b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
287b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    @Override
288b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    public void onCreate(Bundle savedInstanceState) {
289b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        super.onCreate(savedInstanceState);
290b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        mFinishedOnStartup = false;
291b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
292b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        // In the case that the activity starts up before the Recents component has initialized
293b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        // (usually when debugging/pushing the SysUI apk), just finish this activity.
294b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        SystemServicesProxy ssp = Recents.getSystemServices();
295b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        if (ssp == null) {
296b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            mFinishedOnStartup = true;
297b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            finish();
298b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            return;
299b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        }
300a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim        mPipRecentsOverlayManager = PipManager.getInstance().getPipRecentsOverlayManager();
301b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
302b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        // Register this activity with the event bus
303b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        EventBus.getDefault().register(this, EVENT_BUS_PRIORITY);
304b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
305b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        mPackageMonitor = new RecentsPackageMonitor();
306b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        mPackageMonitor.register(this);
307b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
308b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        // Set the Recents layout
309b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        setContentView(R.layout.recents_on_tv);
310b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
311b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        mRecentsView = (RecentsTvView) findViewById(R.id.recents_view);
312b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        mRecentsView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
313b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
314b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan                View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
315a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim
316a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim        mPipView = findViewById(R.id.pip);
317a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim        mPipView.setOnFocusChangeListener(mPipViewFocusChangeListener);
318a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim        // Place mPipView at the PIP bounds for fine tuned focus handling.
31904cbe870ae6c8721d6322c248d40bb94a9cb5a09Jaewan Kim        Rect pipBounds = mPipManager.getRecentsFocusedPipBounds();
320a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim        LayoutParams lp = (LayoutParams) mPipView.getLayoutParams();
321a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim        lp.width = pipBounds.width();
322a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim        lp.height = pipBounds.height();
323a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim        lp.leftMargin = pipBounds.left;
324a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim        lp.topMargin = pipBounds.top;
325a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim        mPipView.setLayoutParams(lp);
3268f584b8dee2a2a15a1777fabf6ba033b78419b9aJaewan Kim
327a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim        mPipRecentsOverlayManager.setCallback(mPipRecentsOverlayManagerCallback);
3288f584b8dee2a2a15a1777fabf6ba033b78419b9aJaewan Kim
329b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        getWindow().getAttributes().privateFlags |=
330b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan                WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY;
331b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
332b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        // Create the home intent runnable
333b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        Intent homeIntent = new Intent(Intent.ACTION_MAIN, null);
334b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        homeIntent.addCategory(Intent.CATEGORY_HOME);
335b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        homeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
336b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan                Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
337165410d445bf200ac615d4d1abc7221e95c5f82cSid Soundararajan        homeIntent.putExtra(RECENTS_HOME_INTENT_EXTRA, true);
338b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        mFinishLaunchHomeRunnable = new FinishRecentsRunnable(homeIntent);
33982ac50d607ac252905bf8a095d6e6061f023664eJaewan Kim
34082ac50d607ac252905bf8a095d6e6061f023664eJaewan Kim        mPipManager.addListener(mPipListener);
341b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    }
342b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
343b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    @Override
344b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    protected void onNewIntent(Intent intent) {
345b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        super.onNewIntent(intent);
346b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        setIntent(intent);
347b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    }
348b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
349b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    @Override
350de3321d13bcac4108affa2a80de9c7d30eaa0ce6Sid Soundararajan    public void onEnterAnimationComplete() {
351de3321d13bcac4108affa2a80de9c7d30eaa0ce6Sid Soundararajan        super.onEnterAnimationComplete();
352de3321d13bcac4108affa2a80de9c7d30eaa0ce6Sid Soundararajan        if(mLaunchedFromHome) {
353de3321d13bcac4108affa2a80de9c7d30eaa0ce6Sid Soundararajan            mHomeRecentsEnterExitAnimationHolder.startEnterAnimation(mPipManager.isPipShown());
354de3321d13bcac4108affa2a80de9c7d30eaa0ce6Sid Soundararajan        }
355de3321d13bcac4108affa2a80de9c7d30eaa0ce6Sid Soundararajan        EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
356de3321d13bcac4108affa2a80de9c7d30eaa0ce6Sid Soundararajan    }
357de3321d13bcac4108affa2a80de9c7d30eaa0ce6Sid Soundararajan
358de3321d13bcac4108affa2a80de9c7d30eaa0ce6Sid Soundararajan    @Override
359de3321d13bcac4108affa2a80de9c7d30eaa0ce6Sid Soundararajan    public void onResume() {
360de3321d13bcac4108affa2a80de9c7d30eaa0ce6Sid Soundararajan        super.onResume();
361de3321d13bcac4108affa2a80de9c7d30eaa0ce6Sid Soundararajan        mPipRecentsOverlayManager.onRecentsResumed();
362b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        // Update the recent tasks
363b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        updateRecentsTasks();
364b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
365b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        // If this is a new instance from a configuration change, then we have to manually trigger
366b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        // the enter animation state, or if recents was relaunched by AM, without going through
367b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        // the normal mechanisms
368b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        RecentsConfiguration config = Recents.getConfiguration();
369b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        RecentsActivityLaunchState launchState = config.getLaunchState();
370b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        boolean wasLaunchedByAm = !launchState.launchedFromHome &&
371e693aafe0511c2a7ffc571b22abeefba44046225Winson                !launchState.launchedFromApp;
372a1ededd056d51532ab18354f17f8065ec1134535Winson        if (wasLaunchedByAm) {
373b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
374b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        }
375b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
376b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        // Notify that recents is now visible
377b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        SystemServicesProxy ssp = Recents.getSystemServices();
3788873754f66527d2cc9feab295dd4eef23298212aWinson        EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, true));
379061f81e7b03a7cc82157416ef53c88b70ebb5876Sid Soundararajan        if(mTaskStackHorizontalGridView.getStack().getTaskCount() > 1 && !mLaunchedFromHome) {
380061f81e7b03a7cc82157416ef53c88b70ebb5876Sid Soundararajan            // If there are 2 or more tasks, and we are not launching from home
381061f81e7b03a7cc82157416ef53c88b70ebb5876Sid Soundararajan            // set the selected position to the 2nd task to allow for faster app switching
382061f81e7b03a7cc82157416ef53c88b70ebb5876Sid Soundararajan            mTaskStackHorizontalGridView.setSelectedPosition(1);
383061f81e7b03a7cc82157416ef53c88b70ebb5876Sid Soundararajan        } else {
384061f81e7b03a7cc82157416ef53c88b70ebb5876Sid Soundararajan            mTaskStackHorizontalGridView.setSelectedPosition(0);
385061f81e7b03a7cc82157416ef53c88b70ebb5876Sid Soundararajan        }
386a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim        mRecentsView.getViewTreeObserver().addOnPreDrawListener(this);
38716c91bd47f1ed378441adc89cde69b161562e3b3Jaewan Kim
38817d29b6d70a23d56c55a50cce00ffa66ed58ac63Sid Soundararajan        View dismissPlaceholder = findViewById(R.id.dismiss_placeholder);
389a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim        mTalkBackEnabled = ssp.isTouchExplorationEnabled();
390a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim        if (mTalkBackEnabled) {
39117d29b6d70a23d56c55a50cce00ffa66ed58ac63Sid Soundararajan            dismissPlaceholder.setAccessibilityTraversalBefore(R.id.task_list);
39217d29b6d70a23d56c55a50cce00ffa66ed58ac63Sid Soundararajan            dismissPlaceholder.setAccessibilityTraversalAfter(R.id.dismiss_placeholder);
39317d29b6d70a23d56c55a50cce00ffa66ed58ac63Sid Soundararajan            mTaskStackHorizontalGridView.setAccessibilityTraversalAfter(R.id.dismiss_placeholder);
39417d29b6d70a23d56c55a50cce00ffa66ed58ac63Sid Soundararajan            mTaskStackHorizontalGridView.setAccessibilityTraversalBefore(R.id.pip);
39517d29b6d70a23d56c55a50cce00ffa66ed58ac63Sid Soundararajan            dismissPlaceholder.setOnClickListener(new View.OnClickListener() {
39617d29b6d70a23d56c55a50cce00ffa66ed58ac63Sid Soundararajan                @Override
39717d29b6d70a23d56c55a50cce00ffa66ed58ac63Sid Soundararajan                public void onClick(View v) {
39817d29b6d70a23d56c55a50cce00ffa66ed58ac63Sid Soundararajan                    mTaskStackHorizontalGridView.requestFocus();
39917d29b6d70a23d56c55a50cce00ffa66ed58ac63Sid Soundararajan                    mTaskStackHorizontalGridView.
40017d29b6d70a23d56c55a50cce00ffa66ed58ac63Sid Soundararajan                            sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
40117d29b6d70a23d56c55a50cce00ffa66ed58ac63Sid Soundararajan                    Task focusedTask = mTaskStackHorizontalGridView.getFocusedTask();
40217d29b6d70a23d56c55a50cce00ffa66ed58ac63Sid Soundararajan                    if (focusedTask != null) {
40317d29b6d70a23d56c55a50cce00ffa66ed58ac63Sid Soundararajan                        mTaskStackViewAdapter.removeTask(focusedTask);
40417d29b6d70a23d56c55a50cce00ffa66ed58ac63Sid Soundararajan                        EventBus.getDefault().send(new DeleteTaskDataEvent(focusedTask));
40517d29b6d70a23d56c55a50cce00ffa66ed58ac63Sid Soundararajan                    }
40617d29b6d70a23d56c55a50cce00ffa66ed58ac63Sid Soundararajan                }
40717d29b6d70a23d56c55a50cce00ffa66ed58ac63Sid Soundararajan            });
40817d29b6d70a23d56c55a50cce00ffa66ed58ac63Sid Soundararajan        }
409a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim
410a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim        // Initialize PIP UI
411a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim        if (mPipManager.isPipShown()) {
412a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim            if (mTalkBackEnabled) {
413a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim                // If talkback is on, use the mPipView to handle focus changes
414a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim                // between recents row and PIP controls.
415a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim                mPipView.setVisibility(View.VISIBLE);
416a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim            } else {
417a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim                mPipView.setVisibility(View.GONE);
418a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim            }
419a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim            // When PIP view has focus, recents overlay view will takes the focus
420a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim            // as if it's the part of the Recents UI.
421a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim            mPipRecentsOverlayManager.requestFocus(mTaskStackViewAdapter.getItemCount() > 0);
422a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim        } else {
423a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim            mPipView.setVisibility(View.GONE);
424a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim            mPipRecentsOverlayManager.removePipRecentsOverlayView();
425a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim        }
426a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim    }
427a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim
428a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim    @Override
429a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim    public void onPause() {
430a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim        super.onPause();
431a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim        mPipRecentsOverlayManager.onRecentsPaused();
432a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim    }
433a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim
434a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim    @Override
435b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    protected void onStop() {
436b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        super.onStop();
437b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
438b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        mIgnoreAltTabRelease = false;
439b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        // Notify that recents is now hidden
4408873754f66527d2cc9feab295dd4eef23298212aWinson        EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, false));
441b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
442b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        // Workaround for b/22542869, if the RecentsActivity is started again, but without going
443b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        // through SystemUI, we need to reset the config launch flags to ensure that we do not
444b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        // wait on the system to send a signal that was never queued.
445b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        RecentsConfiguration config = Recents.getConfiguration();
446b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        RecentsActivityLaunchState launchState = config.getLaunchState();
447e161f08e98fdbe6fe83f70ffa1ea11142a027ebeJorim Jaggi        launchState.reset();
4489df42a37c3bfe15f6515228f4a2c4f2f31c7978cJaewan Kim
4499df42a37c3bfe15f6515228f4a2c4f2f31c7978cJaewan Kim        // Workaround for b/28333917.
4509df42a37c3bfe15f6515228f4a2c4f2f31c7978cJaewan Kim        finish();
451b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    }
452b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
453b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    @Override
454b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    protected void onDestroy() {
455b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        super.onDestroy();
456b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
45782ac50d607ac252905bf8a095d6e6061f023664eJaewan Kim        mPipManager.removeListener(mPipListener);
458b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        // In the case that the activity finished on startup, just skip the unregistration below
459b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        if (mFinishedOnStartup) {
460b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            return;
461b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        }
462b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
463b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        // Unregister any broadcast receivers for the task loader
464b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        mPackageMonitor.unregister();
465b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
466b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        EventBus.getDefault().unregister(this);
467b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    }
468b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
469b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    @Override
470b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    public void onTrimMemory(int level) {
471b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        RecentsTaskLoader loader = Recents.getTaskLoader();
472b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        if (loader != null) {
473b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            loader.onTrimMemory(level);
474b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        }
475b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    }
476b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
477b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    @Override
478b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    public boolean onKeyDown(int keyCode, KeyEvent event) {
479b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        switch (keyCode) {
480b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            case KeyEvent.KEYCODE_DEL:
481b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            case KeyEvent.KEYCODE_FORWARD_DEL: {
482b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan                EventBus.getDefault().send(new DismissFocusedTaskViewEvent());
483b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan                return true;
484b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            }
485b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            default:
486b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan                break;
487b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        }
488b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        return super.onKeyDown(keyCode, event);
489b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    }
490b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
491b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    @Override
492b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    public void onUserInteraction() {
493b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        EventBus.getDefault().send(new UserInteractionEvent());
494b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    }
495b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
496b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    @Override
497b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    public void onBackPressed() {
498b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        // Back behaves like the recents button so just trigger a toggle event
499b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        EventBus.getDefault().send(new ToggleRecentsEvent());
500b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    }
501b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
502b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    /**** EventBus events ****/
503b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
504b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    public final void onBusEvent(ToggleRecentsEvent event) {
505b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
506b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        if (launchState.launchedFromHome) {
507b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            dismissRecentsToHome(true /* animateTaskViews */);
508b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        } else {
509419c89533a148d0037e98b801068bb81f8a2cd2aJaewan Kim            dismissRecentsToLaunchTargetTaskOrHome(true);
510b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        }
511b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    }
512b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
513b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    public final void onBusEvent(HideRecentsEvent event) {
514b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        if (event.triggeredFromAltTab) {
515b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            // If we are hiding from releasing Alt-Tab, dismiss Recents to the focused app
516b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            if (!mIgnoreAltTabRelease) {
517b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan                dismissRecentsToFocusedTaskOrHome();
518b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            }
519b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        } else if (event.triggeredFromHomeKey) {
520b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan                dismissRecentsToHome(true /* animateTaskViews */);
521b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        } else {
522b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            // Do nothing
523b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        }
524b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    }
525b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
526b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    public final void onBusEvent(CancelEnterRecentsWindowAnimationEvent event) {
527b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
528b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        int launchToTaskId = launchState.launchedToTaskId;
529b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        if (launchToTaskId != -1 &&
530b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan                (event.launchTask == null || launchToTaskId != event.launchTask.key.id)) {
531b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            SystemServicesProxy ssp = Recents.getSystemServices();
532b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            ssp.cancelWindowTransition(launchState.launchedToTaskId);
533b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            ssp.cancelThumbnailTransition(getTaskId());
534b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        }
535b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    }
536b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
537b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    public final void onBusEvent(DeleteTaskDataEvent event) {
538b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        // Remove any stored data from the loader
539b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        RecentsTaskLoader loader = Recents.getTaskLoader();
540b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        loader.deleteTaskData(event.task, false);
541b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
542b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        // Remove the task from activity manager
543b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        SystemServicesProxy ssp = Recents.getSystemServices();
544b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        ssp.removeTask(event.task.key.id);
545b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    }
546b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
547b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    public final void onBusEvent(AllTaskViewsDismissedEvent event) {
54885b0a0f1eccc0c32a2032385f2f199c76c50a917Sid Soundararajan        if (mPipManager.isPipShown()) {
549b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            mRecentsView.showEmptyView();
550a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim            mPipRecentsOverlayManager.requestFocus(false);
551b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        } else {
55285b0a0f1eccc0c32a2032385f2f199c76c50a917Sid Soundararajan            dismissRecentsToHome(false);
553b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        }
554b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    }
555b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
556b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    public final void onBusEvent(LaunchTaskFailedEvent event) {
557b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        // Return to Home
558b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        dismissRecentsToHome(true /* animateTaskViews */);
559b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    }
560b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan
561b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    @Override
562b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    public boolean onPreDraw() {
563b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        mRecentsView.getViewTreeObserver().removeOnPreDrawListener(this);
564a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim        // Sets the initial values for enter animation.
565a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim        // Animation will be started in {@link #onEnterAnimationComplete()}
566a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim        if (mLaunchedFromHome) {
567a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim            mHomeRecentsEnterExitAnimationHolder
568a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim                    .setEnterFromHomeStartingAnimationValues(mPipManager.isPipShown());
56967ed54a724df258738062e60d7f702f396502b49Sid Soundararajan        } else {
570a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim            mHomeRecentsEnterExitAnimationHolder
571a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim                    .setEnterFromAppStartingAnimationValues(mPipManager.isPipShown());
57267ed54a724df258738062e60d7f702f396502b49Sid Soundararajan        }
573b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        // We post to make sure that this information is delivered after this traversals is
574b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        // finished.
575b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        mRecentsView.post(new Runnable() {
576b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            @Override
577b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            public void run() {
578b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan                Recents.getSystemServices().endProlongedAnimations();
579b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan            }
580b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        });
581b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan        return true;
582b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan    }
58382ac50d607ac252905bf8a095d6e6061f023664eJaewan Kim
58482ac50d607ac252905bf8a095d6e6061f023664eJaewan Kim    private void updatePipUI() {
585a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim        if (!mPipManager.isPipShown()) {
586a0d4d2588dfa5cbd09100c5b06c8ecfeaaf3a279Jaewan Kim            mPipRecentsOverlayManager.removePipRecentsOverlayView();
587a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim            mTaskStackHorizontalGridView.startFocusLossAnimation();
588a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim        } else {
589a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim            Log.w(TAG, "An activity entered PIP mode while Recents is shown");
59004cbe870ae6c8721d6322c248d40bb94a9cb5a09Jaewan Kim        }
59104cbe870ae6c8721d6322c248d40bb94a9cb5a09Jaewan Kim    }
59204cbe870ae6c8721d6322c248d40bb94a9cb5a09Jaewan Kim
59304cbe870ae6c8721d6322c248d40bb94a9cb5a09Jaewan Kim    /**
594a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim     * Requests the focus to the PIP controls.
59504cbe870ae6c8721d6322c248d40bb94a9cb5a09Jaewan Kim     * This starts the relevant recents row animation
59604cbe870ae6c8721d6322c248d40bb94a9cb5a09Jaewan Kim     * and give focus to the recents overlay if needed.
59704cbe870ae6c8721d6322c248d40bb94a9cb5a09Jaewan Kim     */
598a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim    public void requestPipControlsFocus() {
599a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim        if (!mPipManager.isPipShown()) {
600a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim            return;
60182ac50d607ac252905bf8a095d6e6061f023664eJaewan Kim        }
602a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim
603a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim        mTaskStackHorizontalGridView.startFocusLossAnimation();
604a9e0621f33233c43f29e876b6c1055cf1dc855fcJaewan Kim        mPipRecentsOverlayManager.requestFocus(mTaskStackViewAdapter.getItemCount() > 0);
60582ac50d607ac252905bf8a095d6e6061f023664eJaewan Kim    }
606b58c46acec2e270f24ca587a64298f06cefb09cbSid Soundararajan}
607