RecentsActivity.java revision 15a2ba813a3c16ebc52f943ff80d4b67c05af310
1303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung/*
2303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * Copyright (C) 2014 The Android Open Source Project
3303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung *
4303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * Licensed under the Apache License, Version 2.0 (the "License");
5303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * you may not use this file except in compliance with the License.
6303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * You may obtain a copy of the License at
7303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung *
8303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung *      http://www.apache.org/licenses/LICENSE-2.0
9303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung *
10303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * Unless required by applicable law or agreed to in writing, software
11303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * distributed under the License is distributed on an "AS IS" BASIS,
12303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * See the License for the specific language governing permissions and
14303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * limitations under the License.
15303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung */
16303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
17303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungpackage com.android.systemui.recents;
18303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
19303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport android.app.Activity;
20d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chungimport android.app.ActivityOptions;
218eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chungimport android.app.SearchManager;
22f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chungimport android.appwidget.AppWidgetHostView;
23f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chungimport android.appwidget.AppWidgetManager;
24f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chungimport android.appwidget.AppWidgetProviderInfo;
2547c4c69575e94635a9356e8a1faf4b56a0120452Winson Chungimport android.content.BroadcastReceiver;
2647c4c69575e94635a9356e8a1faf4b56a0120452Winson Chungimport android.content.Context;
27303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport android.content.Intent;
2847c4c69575e94635a9356e8a1faf4b56a0120452Winson Chungimport android.content.IntentFilter;
298eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chungimport android.content.SharedPreferences;
30303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport android.os.Bundle;
3115a2ba813a3c16ebc52f943ff80d4b67c05af310Winson Chungimport android.os.SystemClock;
32d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chungimport android.os.UserHandle;
33f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chungimport android.util.Pair;
341e8d71b605b4872e93200706a80a88a3ff25498cWinson Chungimport android.view.KeyEvent;
35303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport android.view.View;
368e548f7025ce930810479a8e628c325d09557fa3Winson Chungimport android.view.ViewStub;
378eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chungimport android.widget.Toast;
3818f99d91349a4f5ce55e22ed33f1f57eb1b0297bJason Monk
3947c4c69575e94635a9356e8a1faf4b56a0120452Winson Chungimport com.android.systemui.R;
40ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport com.android.systemui.recents.misc.DebugTrigger;
41ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport com.android.systemui.recents.misc.ReferenceCountedTrigger;
42ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport com.android.systemui.recents.misc.SystemServicesProxy;
43ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport com.android.systemui.recents.misc.Utilities;
44a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chungimport com.android.systemui.recents.model.RecentsTaskLoadPlan;
45f1fbd77cf057e43926f9a0347692611386d09f40Winson Chungimport com.android.systemui.recents.model.RecentsTaskLoader;
46303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport com.android.systemui.recents.model.SpaceNode;
47dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chungimport com.android.systemui.recents.model.Task;
48303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport com.android.systemui.recents.model.TaskStack;
49dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chungimport com.android.systemui.recents.views.DebugOverlayView;
50303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport com.android.systemui.recents.views.RecentsView;
51cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chungimport com.android.systemui.recents.views.SystemBarScrimViews;
52d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chungimport com.android.systemui.recents.views.ViewAnimation;
5318f99d91349a4f5ce55e22ed33f1f57eb1b0297bJason Monkimport com.android.systemui.statusbar.phone.PhoneStatusBar;
5418f99d91349a4f5ce55e22ed33f1f57eb1b0297bJason Monkimport com.android.systemui.SystemUIApplication;
55303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
56083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chungimport java.lang.ref.WeakReference;
57b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chungimport java.lang.reflect.InvocationTargetException;
58303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport java.util.ArrayList;
59303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
6085cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung/**
6185cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung * The main Recents activity that is started from AlternateRecentsComponent.
6285cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung */
63f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chungpublic class RecentsActivity extends Activity implements RecentsView.RecentsViewCallbacks,
642915b9d14876c8e63ca82415807bcfb602ebad43Winson Chung        RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks,
652915b9d14876c8e63ca82415807bcfb602ebad43Winson Chung        DebugOverlayView.DebugOverlayViewCallbacks {
66d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung
6785cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung    RecentsConfiguration mConfig;
6885cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung    boolean mVisible;
69a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung    long mLastTabKeyEventTime;
7085cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung
7185cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung    // Top level views
72cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung    RecentsView mRecentsView;
73cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung    SystemBarScrimViews mScrimViews;
748e548f7025ce930810479a8e628c325d09557fa3Winson Chung    ViewStub mEmptyViewStub;
752915b9d14876c8e63ca82415807bcfb602ebad43Winson Chung    ViewStub mDebugOverlayStub;
76cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung    View mEmptyView;
77dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung    DebugOverlayView mDebugOverlay;
78cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung
7985cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung    // Search AppWidget
80cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung    RecentsAppWidgetHost mAppWidgetHost;
81cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung    AppWidgetProviderInfo mSearchAppWidgetInfo;
82cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung    AppWidgetHostView mSearchAppWidgetHostView;
83cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung
84cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung    // Runnables to finish the Recents activity
85cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung    FinishRecentsRunnable mFinishLaunchHomeRunnable;
86cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung
8718f99d91349a4f5ce55e22ed33f1f57eb1b0297bJason Monk    private PhoneStatusBar mStatusBar;
8818f99d91349a4f5ce55e22ed33f1f57eb1b0297bJason Monk
89d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung    /**
9085cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung     * A common Runnable to finish Recents either by calling finish() (with a custom animation) or
9185cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung     * launching Home with some ActivityOptions.  Generally we always launch home when we exit
9285cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung     * Recents rather than just finishing the activity since we don't know what is behind Recents in
9385cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung     * the task stack.  The only case where we finish() directly is when we are cancelling the full
9485cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung     * screen transition from the app.
95d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung     */
96d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung    class FinishRecentsRunnable implements Runnable {
97d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        Intent mLaunchIntent;
98d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        ActivityOptions mLaunchOpts;
99d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung
100d7b2cb12ac90956843413c212769639044a0b6f2Winson Chung        /**
101d7b2cb12ac90956843413c212769639044a0b6f2Winson Chung         * Creates a finish runnable that starts the specified intent, using the given
102d7b2cb12ac90956843413c212769639044a0b6f2Winson Chung         * ActivityOptions.
103d7b2cb12ac90956843413c212769639044a0b6f2Winson Chung         */
104d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        public FinishRecentsRunnable(Intent launchIntent, ActivityOptions opts) {
105d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung            mLaunchIntent = launchIntent;
106d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung            mLaunchOpts = opts;
107d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        }
108d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung
109d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        @Override
110d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        public void run() {
111d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung            // Mark Recents as no longer visible
112bac679b0d47aee0c9f3228ce2957ab4fe5b3609eWinson Chung            onRecentsActivityVisibilityChanged(false);
113d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung            // Finish Recents
114d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung            if (mLaunchIntent != null) {
115d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung                if (mLaunchOpts != null) {
11685cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung                    startActivityAsUser(mLaunchIntent, mLaunchOpts.toBundle(), UserHandle.CURRENT);
117bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung                } else {
118bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung                    startActivityAsUser(mLaunchIntent, UserHandle.CURRENT);
119d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung                }
120d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung            } else {
121d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung                finish();
12285cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung                overridePendingTransition(R.anim.recents_to_launcher_enter,
12385cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung                        R.anim.recents_to_launcher_exit);
124d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung            }
125d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        }
126d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung    }
127d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung
12885cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung    /**
12985cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung     * Broadcast receiver to handle messages from AlternateRecentsComponent.
13085cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung     */
1318eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung    final BroadcastReceiver mServiceBroadcastReceiver = new BroadcastReceiver() {
13247c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        @Override
13347c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        public void onReceive(Context context, Intent intent) {
13447c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung            String action = intent.getAction();
135cdcd487abad10f728f0542accc42a31d1f7fedacWinson Chung            if (action.equals(AlternateRecentsComponent.ACTION_HIDE_RECENTS_ACTIVITY)) {
136cdcd487abad10f728f0542accc42a31d1f7fedacWinson Chung                // Mark Recents as no longer visible
137cdcd487abad10f728f0542accc42a31d1f7fedacWinson Chung                AlternateRecentsComponent.notifyVisibilityChanged(false);
138cdcd487abad10f728f0542accc42a31d1f7fedacWinson Chung                if (intent.getBooleanExtra(AlternateRecentsComponent.EXTRA_TRIGGERED_FROM_ALT_TAB, false)) {
13985cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung                    // If we are hiding from releasing Alt-Tab, dismiss Recents to the focused app
14085cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung                    dismissRecentsToFocusedTaskOrHome(false);
141cdcd487abad10f728f0542accc42a31d1f7fedacWinson Chung                } else if (intent.getBooleanExtra(AlternateRecentsComponent.EXTRA_TRIGGERED_FROM_HOME_KEY, false)) {
14285cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung                    // Otherwise, dismiss Recents to Home
14385cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung                    dismissRecentsToHome(true);
144cdcd487abad10f728f0542accc42a31d1f7fedacWinson Chung                } else {
145cdcd487abad10f728f0542accc42a31d1f7fedacWinson Chung                    // Do nothing, another activity is being launched on top of Recents
1466cb485fd2e2f8ace05e1ff281ab0fc824d3652cbWinson Chung                }
147cdcd487abad10f728f0542accc42a31d1f7fedacWinson Chung            } else if (action.equals(AlternateRecentsComponent.ACTION_TOGGLE_RECENTS_ACTIVITY)) {
14885cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung                // If we are toggling Recents, then first unfilter any filtered stacks first
14985cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung                dismissRecentsToFocusedTaskOrHome(true);
150b0a28ea5d381cd3a8477cf7fd82797199c80ca67Winson Chung            } else if (action.equals(AlternateRecentsComponent.ACTION_START_ENTER_ANIMATION)) {
151b0a28ea5d381cd3a8477cf7fd82797199c80ca67Winson Chung                // Trigger the enter animation
152b0a28ea5d381cd3a8477cf7fd82797199c80ca67Winson Chung                onEnterAnimationTriggered();
153b0a28ea5d381cd3a8477cf7fd82797199c80ca67Winson Chung                // Notify the fallback receiver that we have successfully got the broadcast
154b0a28ea5d381cd3a8477cf7fd82797199c80ca67Winson Chung                // See AlternateRecentsComponent.onAnimationStarted()
155b0a28ea5d381cd3a8477cf7fd82797199c80ca67Winson Chung                setResultCode(Activity.RESULT_OK);
15647c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung            }
15747c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        }
15847c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung    };
159303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
16085cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung    /**
16185cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung     * Broadcast receiver to handle messages from the system
16285cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung     */
16331d66c60d8f518ce3a70972db348d797db92f42cWinson Chung    final BroadcastReceiver mSystemBroadcastReceiver = new BroadcastReceiver() {
1646736905dc0e10689f7c63f6da43b31325caf966aWinson Chung        @Override
1656736905dc0e10689f7c63f6da43b31325caf966aWinson Chung        public void onReceive(Context context, Intent intent) {
16631d66c60d8f518ce3a70972db348d797db92f42cWinson Chung            String action = intent.getAction();
16785cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung            if (action.equals(Intent.ACTION_SCREEN_OFF)) {
16885cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung                // When the screen turns off, dismiss Recents to Home
16985cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung                dismissRecentsToHome(false);
170a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung                // Preload the metadata for all tasks in the background
171a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung                RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
172a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung                RecentsTaskLoadPlan plan = loader.createLoadPlan(context);
173a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung                loader.preloadTasks(plan, true /* isTopTaskHome */);
17431d66c60d8f518ce3a70972db348d797db92f42cWinson Chung            } else if (action.equals(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED)) {
17585cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung                // When the search activity changes, update the Search widget
17631d66c60d8f518ce3a70972db348d797db92f42cWinson Chung                refreshSearchWidget();
17731d66c60d8f518ce3a70972db348d797db92f42cWinson Chung            }
178d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        }
179d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung    };
180d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung
18185cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung    /**
18285cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung     * A custom debug trigger to listen for a debug key chord.
18385cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung     */
1848eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung    final DebugTrigger mDebugTrigger = new DebugTrigger(new Runnable() {
1858eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung        @Override
1868eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung        public void run() {
1878eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung            onDebugModeTriggered();
1888eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung        }
1898eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung    });
1908eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung
191303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Updates the set of recent tasks */
192b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung    void updateRecentsTasks(Intent launchIntent) {
193b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung        // Update the configuration based on the launch intent
194bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung        boolean fromSearchHome = launchIntent.getBooleanExtra(
195bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung                AlternateRecentsComponent.EXTRA_FROM_SEARCH_HOME, false);
196a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung        int numVisibleTasks = launchIntent.getIntExtra(
197a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung                AlternateRecentsComponent.EXTRA_NUM_VISIBLE_TASKS, 0);
198a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung        int numVisibleThumbnails = launchIntent.getIntExtra(
199a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung                AlternateRecentsComponent.EXTRA_NUM_VISIBLE_THUMBNAILS, 0);
200bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung        mConfig.launchedFromHome = fromSearchHome || launchIntent.getBooleanExtra(
201d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                AlternateRecentsComponent.EXTRA_FROM_HOME, false);
202d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        mConfig.launchedFromAppWithThumbnail = launchIntent.getBooleanExtra(
203d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                AlternateRecentsComponent.EXTRA_FROM_APP_THUMBNAIL, false);
204cdcd487abad10f728f0542accc42a31d1f7fedacWinson Chung        mConfig.launchedToTaskId = launchIntent.getIntExtra(
205cdcd487abad10f728f0542accc42a31d1f7fedacWinson Chung                AlternateRecentsComponent.EXTRA_FROM_TASK_ID, -1);
206d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        mConfig.launchedWithAltTab = launchIntent.getBooleanExtra(
207d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                AlternateRecentsComponent.EXTRA_TRIGGERED_FROM_ALT_TAB, false);
208b0a28ea5d381cd3a8477cf7fd82797199c80ca67Winson Chung        mConfig.launchedReuseTaskStackViews = launchIntent.getBooleanExtra(
209b0a28ea5d381cd3a8477cf7fd82797199c80ca67Winson Chung                AlternateRecentsComponent.EXTRA_REUSE_TASK_STACK_VIEWS, false);
2109cb5c4e3854aa7f2ddab707920b688c3108cbc85Winson Chung
211a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung        // If AlternateRecentsComponent has preloaded a load plan, then use that to prevent
212a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung        // reconstructing the task stack
2139cb5c4e3854aa7f2ddab707920b688c3108cbc85Winson Chung        RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
214a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung        RecentsTaskLoadPlan plan = AlternateRecentsComponent.consumeInstanceLoadPlan();
215a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung        if (plan == null) {
216a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung            plan = loader.createLoadPlan(this);
217a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung        }
218a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung
219a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung        // Start loading tasks according to the load plan
22090d5136ebd59c9aff9543ea5750d4c5d57ac99dcWinson Chung        if (plan.getTaskStack() == null) {
22190d5136ebd59c9aff9543ea5750d4c5d57ac99dcWinson Chung            loader.preloadTasks(plan, mConfig.launchedFromHome);
22290d5136ebd59c9aff9543ea5750d4c5d57ac99dcWinson Chung        }
223a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung        RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options();
224a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung        loadOpts.runningTaskId = mConfig.launchedToTaskId;
225a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung        loadOpts.numVisibleTasks = numVisibleTasks;
226a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung        loadOpts.numVisibleTaskThumbnails = numVisibleThumbnails;
227a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung        loader.loadTasks(this, plan, loadOpts);
228a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung
229a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung        SpaceNode root = plan.getSpaceNode();
2309cb5c4e3854aa7f2ddab707920b688c3108cbc85Winson Chung        ArrayList<TaskStack> stacks = root.getStacks();
231a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung        boolean hasTasks = root.hasTasks();
232a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung        if (hasTasks) {
233a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung            mRecentsView.setTaskStacks(stacks);
2349cb5c4e3854aa7f2ddab707920b688c3108cbc85Winson Chung        }
235a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung        mConfig.launchedWithNoRecentTasks = !hasTasks;
236303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
237bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung        // Create the home intent runnable
238bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung        Intent homeIntent = new Intent(Intent.ACTION_MAIN, null);
239bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung        homeIntent.addCategory(Intent.CATEGORY_HOME);
240bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung        homeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
241bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung                Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
242bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung        mFinishLaunchHomeRunnable = new FinishRecentsRunnable(homeIntent,
243bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung            ActivityOptions.makeCustomAnimation(this,
244bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung                fromSearchHome ? R.anim.recents_to_search_launcher_enter :
245bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung                        R.anim.recents_to_launcher_enter,
246bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung                fromSearchHome ? R.anim.recents_to_search_launcher_exit :
247bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung                        R.anim.recents_to_launcher_exit));
248bf8871db617d76ee66c5cf803f0bafa5e93998e9Winson Chung
249dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung        // Mark the task that is the launch target
250dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung        int taskStackCount = stacks.size();
251dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung        if (mConfig.launchedToTaskId != -1) {
252dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung            for (int i = 0; i < taskStackCount; i++) {
253dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung                TaskStack stack = stacks.get(i);
254dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung                ArrayList<Task> tasks = stack.getTasks();
255dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung                int taskCount = tasks.size();
256dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung                for (int j = 0; j < taskCount; j++) {
257dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung                    Task t = tasks.get(j);
258dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung                    if (t.key.id == mConfig.launchedToTaskId) {
259dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung                        t.isLaunchTarget = true;
260dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung                        break;
261dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung                    }
262dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung                }
263dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung            }
264dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung        }
265dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung
26685cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung        // Update the top level view's visibilities
267969f586533096999f10f5587f901949791154fa2Winson Chung        if (mConfig.launchedWithNoRecentTasks) {
26885cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung            if (mEmptyView == null) {
26985cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung                mEmptyView = mEmptyViewStub.inflate();
27085cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung            }
271303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung            mEmptyView.setVisibility(View.VISIBLE);
272772b6b12a323b7999d8d3f335c199e6eb4e621e2Winson Chung            mRecentsView.setSearchBarVisibility(View.GONE);
273303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        } else {
27485cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung            if (mEmptyView != null) {
27585cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung                mEmptyView.setVisibility(View.GONE);
27685cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung            }
277772b6b12a323b7999d8d3f335c199e6eb4e621e2Winson Chung            if (mRecentsView.hasSearchBar()) {
278772b6b12a323b7999d8d3f335c199e6eb4e621e2Winson Chung                mRecentsView.setSearchBarVisibility(View.VISIBLE);
279772b6b12a323b7999d8d3f335c199e6eb4e621e2Winson Chung            } else {
280772b6b12a323b7999d8d3f335c199e6eb4e621e2Winson Chung                addSearchBarAppWidgetView();
281772b6b12a323b7999d8d3f335c199e6eb4e621e2Winson Chung            }
282303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        }
2837aceb9a07fd3883c8f301ba93726d55494b0446eWinson Chung
28485cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung        // Animate the SystemUI scrims into view
2857aceb9a07fd3883c8f301ba93726d55494b0446eWinson Chung        mScrimViews.prepareEnterRecentsAnimation();
286303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
287303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
288f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    /** Attempts to allocate and bind the search bar app widget */
289f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    void bindSearchBarAppWidget() {
290814086db674d8eb298541b7e601e29c5c68e2074Winson Chung        if (Constants.DebugFlags.App.EnableSearchLayout) {
291f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            SystemServicesProxy ssp = RecentsTaskLoader.getInstance().getSystemServicesProxy();
292f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
293f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            // Reset the host view and widget info
294f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            mSearchAppWidgetHostView = null;
295f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            mSearchAppWidgetInfo = null;
296f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
297f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            // Try and load the app widget id from the settings
298d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung            int appWidgetId = mConfig.searchBarAppWidgetId;
299f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            if (appWidgetId >= 0) {
300f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                mSearchAppWidgetInfo = ssp.getAppWidgetInfo(appWidgetId);
301f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                if (mSearchAppWidgetInfo == null) {
302f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                    // If there is no actual widget associated with that id, then delete it and
303f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                    // prepare to bind another app widget in its place
304f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                    ssp.unbindSearchAppWidget(mAppWidgetHost, appWidgetId);
305f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                    appWidgetId = -1;
306f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                }
307f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            }
308f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
309f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            // If there is no id, then bind a new search app widget
310f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            if (appWidgetId < 0) {
311f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                Pair<Integer, AppWidgetProviderInfo> widgetInfo =
312f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                        ssp.bindSearchAppWidget(mAppWidgetHost);
313f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                if (widgetInfo != null) {
314f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                    // Save the app widget id into the settings
315d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                    mConfig.updateSearchBarAppWidgetId(this, widgetInfo.first);
316f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                    mSearchAppWidgetInfo = widgetInfo.second;
317f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                }
318f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            }
319f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        }
320f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    }
321f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
322f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    /** Creates the search bar app widget view */
323f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    void addSearchBarAppWidgetView() {
324814086db674d8eb298541b7e601e29c5c68e2074Winson Chung        if (Constants.DebugFlags.App.EnableSearchLayout) {
325d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung            int appWidgetId = mConfig.searchBarAppWidgetId;
326f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            if (appWidgetId >= 0) {
327f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                mSearchAppWidgetHostView = mAppWidgetHost.createView(this, appWidgetId,
328f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                        mSearchAppWidgetInfo);
329f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                Bundle opts = new Bundle();
330f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,
331ee0b12161ab8563378e33e9d694d15ed1a757a26Winson Chung                        AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX);
332f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                mSearchAppWidgetHostView.updateAppWidgetOptions(opts);
333f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                // Set the padding to 0 for this search widget
334f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                mSearchAppWidgetHostView.setPadding(0, 0, 0, 0);
335f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                mRecentsView.setSearchBar(mSearchAppWidgetHostView);
336f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            } else {
337f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                mRecentsView.setSearchBar(null);
338f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            }
339f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        }
340f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    }
341f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
342303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Dismisses recents if we are already visible and the intent is to toggle the recents view */
34385cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung    boolean dismissRecentsToFocusedTaskOrHome(boolean checkFilteredStackState) {
34447c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        if (mVisible) {
34585cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung            // If we currently have filtered stacks, then unfilter those first
34685cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung            if (checkFilteredStackState &&
34785cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung                mRecentsView.unfilterFilteredStacks()) return true;
34885cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung            // If we have a focused Task, launch that Task now
34985cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung            if (mRecentsView.launchFocusedTask()) return true;
35085cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung            // If we launched from Home, then return to Home
35185cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung            if (mConfig.launchedFromHome) {
35285cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung                dismissRecentsToHomeRaw(true);
35385cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung                return true;
354303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung            }
355dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung            // Otherwise, try and return to the Task that Recents was launched from
356dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung            if (mRecentsView.launchPreviousTask()) return true;
35785cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung            // If none of the other cases apply, then just go Home
35885cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung            dismissRecentsToHomeRaw(true);
35985cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung            return true;
36085cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung        }
36185cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung        return false;
36285cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung    }
36385cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung
36485cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung    /** Dismisses Recents directly to Home. */
36585cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung    void dismissRecentsToHomeRaw(boolean animated) {
36685cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung        if (animated) {
36785cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung            ReferenceCountedTrigger exitTrigger = new ReferenceCountedTrigger(this,
36885cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung                    null, mFinishLaunchHomeRunnable, null);
36985cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung            mRecentsView.startExitToHomeAnimation(
37085cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung                    new ViewAnimation.TaskViewExitContext(exitTrigger));
37185cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung        } else {
37285cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung            mFinishLaunchHomeRunnable.run();
37385cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung        }
37485cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung    }
37585cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung
37685cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung    /** Dismisses Recents directly to Home if we currently aren't transitioning. */
37785cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung    boolean dismissRecentsToHome(boolean animated) {
37885cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung        if (mVisible) {
37985cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung            // Return to Home
38085cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung            dismissRecentsToHomeRaw(animated);
38147c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung            return true;
382303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        }
383303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        return false;
384303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
385303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
386303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Called with the activity is first created. */
387303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    @Override
388303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    public void onCreate(Bundle savedInstanceState) {
389303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        super.onCreate(savedInstanceState);
39015155519ba9ce8302d5ca1771f7816cd683a2051Winson Chung        // For the non-primary user, ensure that the SystemSericesProxy is initialized
39115155519ba9ce8302d5ca1771f7816cd683a2051Winson Chung        RecentsTaskLoader.initialize(this);
392303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
393303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        // Initialize the loader and the configuration
39456e09b42a0f1670970872bef611a8036904ad6bfJason Monk        mConfig = RecentsConfiguration.reinitialize(this,
39556e09b42a0f1670970872bef611a8036904ad6bfJason Monk                RecentsTaskLoader.getInstance().getSystemServicesProxy());
396303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
397f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        // Initialize the widget host (the host id is static and does not change)
398d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        mAppWidgetHost = new RecentsAppWidgetHost(this, Constants.Values.App.AppWidgetHostId);
399f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
4008e548f7025ce930810479a8e628c325d09557fa3Winson Chung        // Set the Recents layout
4018e548f7025ce930810479a8e628c325d09557fa3Winson Chung        setContentView(R.layout.recents);
4028e548f7025ce930810479a8e628c325d09557fa3Winson Chung        mRecentsView = (RecentsView) findViewById(R.id.recents_view);
40347c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        mRecentsView.setCallbacks(this);
404653f70c223f8742e2a3696641fe1d4b82bc2ca36Winson Chung        mRecentsView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
405653f70c223f8742e2a3696641fe1d4b82bc2ca36Winson Chung                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
406653f70c223f8742e2a3696641fe1d4b82bc2ca36Winson Chung                View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
4078e548f7025ce930810479a8e628c325d09557fa3Winson Chung        mEmptyViewStub = (ViewStub) findViewById(R.id.empty_view_stub);
4082915b9d14876c8e63ca82415807bcfb602ebad43Winson Chung        mDebugOverlayStub = (ViewStub) findViewById(R.id.debug_overlay_stub);
4098e548f7025ce930810479a8e628c325d09557fa3Winson Chung        mScrimViews = new SystemBarScrimViews(this, mConfig);
410dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung        inflateDebugOverlay();
411303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
412f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        // Bind the search app widget when we first start up
413f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        bindSearchBarAppWidget();
414772b6b12a323b7999d8d3f335c199e6eb4e621e2Winson Chung        // Update the recent tasks
415772b6b12a323b7999d8d3f335c199e6eb4e621e2Winson Chung        updateRecentsTasks(getIntent());
416521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung
41731d66c60d8f518ce3a70972db348d797db92f42cWinson Chung        // Register the broadcast receiver to handle messages when the screen is turned off
41831d66c60d8f518ce3a70972db348d797db92f42cWinson Chung        IntentFilter filter = new IntentFilter();
41931d66c60d8f518ce3a70972db348d797db92f42cWinson Chung        filter.addAction(Intent.ACTION_SCREEN_OFF);
42031d66c60d8f518ce3a70972db348d797db92f42cWinson Chung        filter.addAction(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED);
42131d66c60d8f518ce3a70972db348d797db92f42cWinson Chung        registerReceiver(mSystemBroadcastReceiver, filter);
42231d66c60d8f518ce3a70972db348d797db92f42cWinson Chung
423cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung        // Private API calls to make the shadows look better
424b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung        try {
42560a729c8e93461c9446d0c8cd519b40dec01e8d8Winson Chung            Utilities.setShadowProperty("ambientRatio", String.valueOf(1.5f));
426b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung        } catch (IllegalAccessException e) {
427b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung            e.printStackTrace();
428b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung        } catch (InvocationTargetException e) {
429b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung            e.printStackTrace();
430b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung        }
4317aceb9a07fd3883c8f301ba93726d55494b0446eWinson Chung
4326057c91563402f900dfc7714a46e952d86172e2fWinson Chung        // Update if we are getting a configuration change
4336057c91563402f900dfc7714a46e952d86172e2fWinson Chung        if (savedInstanceState != null) {
434b0a28ea5d381cd3a8477cf7fd82797199c80ca67Winson Chung            // Update RecentsConfiguration
435b0a28ea5d381cd3a8477cf7fd82797199c80ca67Winson Chung            mConfig = RecentsConfiguration.reinitialize(this,
436b0a28ea5d381cd3a8477cf7fd82797199c80ca67Winson Chung                    RecentsTaskLoader.getInstance().getSystemServicesProxy());
4376057c91563402f900dfc7714a46e952d86172e2fWinson Chung            mConfig.updateOnConfigurationChange();
438b0a28ea5d381cd3a8477cf7fd82797199c80ca67Winson Chung            // Trigger the enter animation
439b0a28ea5d381cd3a8477cf7fd82797199c80ca67Winson Chung            onEnterAnimationTriggered();
4406057c91563402f900dfc7714a46e952d86172e2fWinson Chung        }
441905950abd017b5a135e26179b5ba29378732cf5aWinson Chung
442905950abd017b5a135e26179b5ba29378732cf5aWinson Chung        // Start listening for widget package changes if there is one bound, post it since we don't
443905950abd017b5a135e26179b5ba29378732cf5aWinson Chung        // want it stalling the startup
444905950abd017b5a135e26179b5ba29378732cf5aWinson Chung        if (mConfig.searchBarAppWidgetId >= 0) {
445905950abd017b5a135e26179b5ba29378732cf5aWinson Chung            final WeakReference<RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks> callback =
446905950abd017b5a135e26179b5ba29378732cf5aWinson Chung                    new WeakReference<RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks>(this);
447905950abd017b5a135e26179b5ba29378732cf5aWinson Chung            mRecentsView.post(new Runnable() {
448905950abd017b5a135e26179b5ba29378732cf5aWinson Chung                @Override
449905950abd017b5a135e26179b5ba29378732cf5aWinson Chung                public void run() {
450905950abd017b5a135e26179b5ba29378732cf5aWinson Chung                    RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks cb = callback.get();
451905950abd017b5a135e26179b5ba29378732cf5aWinson Chung                    if (cb != null) {
452905950abd017b5a135e26179b5ba29378732cf5aWinson Chung                        mAppWidgetHost.startListening(cb);
453905950abd017b5a135e26179b5ba29378732cf5aWinson Chung                    }
454905950abd017b5a135e26179b5ba29378732cf5aWinson Chung                }
455905950abd017b5a135e26179b5ba29378732cf5aWinson Chung            });
456905950abd017b5a135e26179b5ba29378732cf5aWinson Chung        }
45718f99d91349a4f5ce55e22ed33f1f57eb1b0297bJason Monk
45818f99d91349a4f5ce55e22ed33f1f57eb1b0297bJason Monk        mStatusBar = ((SystemUIApplication) getApplication())
45918f99d91349a4f5ce55e22ed33f1f57eb1b0297bJason Monk                .getComponent(PhoneStatusBar.class);
460521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung    }
461521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung
462dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung    /** Inflates the debug overlay if debug mode is enabled. */
463dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung    void inflateDebugOverlay() {
464a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung        if (!Constants.DebugFlags.App.EnableDebugMode) return;
465a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung
466dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung        if (mConfig.debugModeEnabled && mDebugOverlay == null) {
4672915b9d14876c8e63ca82415807bcfb602ebad43Winson Chung            // Inflate the overlay and seek bars
4682915b9d14876c8e63ca82415807bcfb602ebad43Winson Chung            mDebugOverlay = (DebugOverlayView) mDebugOverlayStub.inflate();
4692915b9d14876c8e63ca82415807bcfb602ebad43Winson Chung            mDebugOverlay.setCallbacks(this);
470dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung            mRecentsView.setDebugOverlay(mDebugOverlay);
471dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung        }
472dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung    }
473dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung
474bac679b0d47aee0c9f3228ce2957ab4fe5b3609eWinson Chung    /** Handles changes to the activity visibility. */
475bac679b0d47aee0c9f3228ce2957ab4fe5b3609eWinson Chung    void onRecentsActivityVisibilityChanged(boolean visible) {
476bac679b0d47aee0c9f3228ce2957ab4fe5b3609eWinson Chung        if (!visible) {
477bac679b0d47aee0c9f3228ce2957ab4fe5b3609eWinson Chung            AlternateRecentsComponent.notifyVisibilityChanged(visible);
478bac679b0d47aee0c9f3228ce2957ab4fe5b3609eWinson Chung        }
479bac679b0d47aee0c9f3228ce2957ab4fe5b3609eWinson Chung        mVisible = visible;
480bac679b0d47aee0c9f3228ce2957ab4fe5b3609eWinson Chung    }
481bac679b0d47aee0c9f3228ce2957ab4fe5b3609eWinson Chung
482303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    @Override
483303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    protected void onNewIntent(Intent intent) {
484303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        super.onNewIntent(intent);
4856057c91563402f900dfc7714a46e952d86172e2fWinson Chung        setIntent(intent);
48647c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung
487480dd72daf927283997bdb4060091299add66832Winson Chung        // Reinitialize the configuration
488480dd72daf927283997bdb4060091299add66832Winson Chung        RecentsConfiguration.reinitialize(this, RecentsTaskLoader.getInstance().getSystemServicesProxy());
489480dd72daf927283997bdb4060091299add66832Winson Chung
490dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung        // Clear any debug rects
491dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung        if (mDebugOverlay != null) {
492dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung            mDebugOverlay.clear();
493dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung        }
494dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung
495303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        // Update the recent tasks
496b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung        updateRecentsTasks(intent);
497303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
498303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
499303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    @Override
500303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    protected void onStart() {
501303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        super.onStart();
50247a3e65acc35cd3061bf3867e8b20753870fd892Winson Chung
50331d66c60d8f518ce3a70972db348d797db92f42cWinson Chung        // Register the broadcast receiver to handle messages from our service
50431d66c60d8f518ce3a70972db348d797db92f42cWinson Chung        IntentFilter filter = new IntentFilter();
505cdcd487abad10f728f0542accc42a31d1f7fedacWinson Chung        filter.addAction(AlternateRecentsComponent.ACTION_HIDE_RECENTS_ACTIVITY);
506cdcd487abad10f728f0542accc42a31d1f7fedacWinson Chung        filter.addAction(AlternateRecentsComponent.ACTION_TOGGLE_RECENTS_ACTIVITY);
507b0a28ea5d381cd3a8477cf7fd82797199c80ca67Winson Chung        filter.addAction(AlternateRecentsComponent.ACTION_START_ENTER_ANIMATION);
50831d66c60d8f518ce3a70972db348d797db92f42cWinson Chung        registerReceiver(mServiceBroadcastReceiver, filter);
50919fc117c2f8f0719aa40a1ff0efe27e2bd6d1efcWinson Chung
51019fc117c2f8f0719aa40a1ff0efe27e2bd6d1efcWinson Chung        // Register any broadcast receivers for the task loader
51119fc117c2f8f0719aa40a1ff0efe27e2bd6d1efcWinson Chung        RecentsTaskLoader.getInstance().registerReceivers(this, mRecentsView);
512303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
513303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
514303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    @Override
515303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    protected void onResume() {
516303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        super.onResume();
517083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung
51885cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung        // Mark Recents as visible
519bac679b0d47aee0c9f3228ce2957ab4fe5b3609eWinson Chung        onRecentsActivityVisibilityChanged(true);
5206736905dc0e10689f7c63f6da43b31325caf966aWinson Chung    }
5216736905dc0e10689f7c63f6da43b31325caf966aWinson Chung
5226736905dc0e10689f7c63f6da43b31325caf966aWinson Chung    @Override
523303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    protected void onStop() {
524303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        super.onStop();
52547c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung
526b0a28ea5d381cd3a8477cf7fd82797199c80ca67Winson Chung        // Notify the views that we are no longer visible
527b0a28ea5d381cd3a8477cf7fd82797199c80ca67Winson Chung        mRecentsView.onRecentsHidden();
52819fc117c2f8f0719aa40a1ff0efe27e2bd6d1efcWinson Chung
52931d66c60d8f518ce3a70972db348d797db92f42cWinson Chung        // Unregister the RecentsService receiver
53031d66c60d8f518ce3a70972db348d797db92f42cWinson Chung        unregisterReceiver(mServiceBroadcastReceiver);
53131d66c60d8f518ce3a70972db348d797db92f42cWinson Chung
53219fc117c2f8f0719aa40a1ff0efe27e2bd6d1efcWinson Chung        // Unregister any broadcast receivers for the task loader
53319fc117c2f8f0719aa40a1ff0efe27e2bd6d1efcWinson Chung        RecentsTaskLoader.getInstance().unregisterReceivers();
53447c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung    }
53547c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung
53647c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung    @Override
53747c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung    protected void onDestroy() {
53847c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        super.onDestroy();
53931d66c60d8f518ce3a70972db348d797db92f42cWinson Chung
54085cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung        // Unregister the system broadcast receivers
54131d66c60d8f518ce3a70972db348d797db92f42cWinson Chung        unregisterReceiver(mSystemBroadcastReceiver);
542905950abd017b5a135e26179b5ba29378732cf5aWinson Chung
543905950abd017b5a135e26179b5ba29378732cf5aWinson Chung        // Stop listening for widget package changes if there was one bound
544905950abd017b5a135e26179b5ba29378732cf5aWinson Chung        if (mAppWidgetHost.isListening()) {
545905950abd017b5a135e26179b5ba29378732cf5aWinson Chung            mAppWidgetHost.stopListening();
546905950abd017b5a135e26179b5ba29378732cf5aWinson Chung        }
547303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
548303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
549b0a28ea5d381cd3a8477cf7fd82797199c80ca67Winson Chung    public void onEnterAnimationTriggered() {
550353c0b91daa97fa87f077be0f403fe7db8dedb40Winson Chung        // Try and start the enter animation (or restart it on configuration changed)
551353c0b91daa97fa87f077be0f403fe7db8dedb40Winson Chung        ReferenceCountedTrigger t = new ReferenceCountedTrigger(this, null, null, null);
552353c0b91daa97fa87f077be0f403fe7db8dedb40Winson Chung        mRecentsView.startEnterRecentsAnimation(new ViewAnimation.TaskViewEnterContext(t));
553353c0b91daa97fa87f077be0f403fe7db8dedb40Winson Chung
554353c0b91daa97fa87f077be0f403fe7db8dedb40Winson Chung        // Animate the SystemUI scrim views
555353c0b91daa97fa87f077be0f403fe7db8dedb40Winson Chung        mScrimViews.startEnterRecentsAnimation();
556353c0b91daa97fa87f077be0f403fe7db8dedb40Winson Chung    }
557353c0b91daa97fa87f077be0f403fe7db8dedb40Winson Chung
558353c0b91daa97fa87f077be0f403fe7db8dedb40Winson Chung    @Override
5594d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung    public void onTrimMemory(int level) {
5604d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung        RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
5614d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung        if (loader != null) {
5624d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung            loader.onTrimMemory(level);
5634d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung        }
5644d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung    }
5654d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung
5664d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung    @Override
5671e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung    public boolean onKeyDown(int keyCode, KeyEvent event) {
568a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung        switch (keyCode) {
569a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung            case KeyEvent.KEYCODE_TAB: {
57015a2ba813a3c16ebc52f943ff80d4b67c05af310Winson Chung                boolean hasRepKeyTimeElapsed = (SystemClock.elapsedRealtime() -
571a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung                        mLastTabKeyEventTime) > mConfig.altTabKeyDelay;
572a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung                if (event.getRepeatCount() <= 0 || hasRepKeyTimeElapsed) {
573a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung                    // Focus the next task in the stack
574a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung                    final boolean backward = event.isShiftPressed();
575a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung                    mRecentsView.focusNextTask(!backward);
57615a2ba813a3c16ebc52f943ff80d4b67c05af310Winson Chung                    mLastTabKeyEventTime = SystemClock.elapsedRealtime();
577a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung                }
578a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung                return true;
579a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung            }
580a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung            case KeyEvent.KEYCODE_DPAD_UP: {
581a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung                mRecentsView.focusNextTask(true);
582a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung                return true;
583a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung            }
584a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung            case KeyEvent.KEYCODE_DPAD_DOWN: {
585a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung                mRecentsView.focusNextTask(false);
586a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung                return true;
587a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung            }
588a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung            case KeyEvent.KEYCODE_DEL:
589a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung            case KeyEvent.KEYCODE_FORWARD_DEL: {
590a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung                mRecentsView.dismissFocusedTask();
591a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung                return true;
592a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung            }
593a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung            default:
594a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung                break;
5951e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung        }
5968eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung        // Pass through the debug trigger
5978eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung        mDebugTrigger.onKeyEvent(keyCode);
5981e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung        return super.onKeyDown(keyCode, event);
5991e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung    }
6001e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung
6011e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung    @Override
602a26fb7822ddf3511796279b847cc216bee9e7f70Winson Chung    public void onUserInteraction() {
603a26fb7822ddf3511796279b847cc216bee9e7f70Winson Chung        mRecentsView.onUserInteraction();
604a26fb7822ddf3511796279b847cc216bee9e7f70Winson Chung    }
605a26fb7822ddf3511796279b847cc216bee9e7f70Winson Chung
606a26fb7822ddf3511796279b847cc216bee9e7f70Winson Chung    @Override
607303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    public void onBackPressed() {
60804d0f756782e697a171aebbb35ae86c86b839a27Winson Chung        // Test mode where back does not do anything
60904d0f756782e697a171aebbb35ae86c86b839a27Winson Chung        if (mConfig.debugModeEnabled) return;
61004d0f756782e697a171aebbb35ae86c86b839a27Winson Chung
61185cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung        // Dismiss Recents to the focused Task or Home
61285cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung        dismissRecentsToFocusedTaskOrHome(true);
613303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
61447c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung
6158eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung    /** Called when debug mode is triggered */
6168eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung    public void onDebugModeTriggered() {
6178eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung        if (mConfig.developerOptionsEnabled) {
6188eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung            SharedPreferences settings = getSharedPreferences(getPackageName(), 0);
6198eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung            if (settings.getBoolean(Constants.Values.App.Key_DebugModeEnabled, false)) {
6208eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung                // Disable the debug mode
6218eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung                settings.edit().remove(Constants.Values.App.Key_DebugModeEnabled).apply();
622dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung                mConfig.debugModeEnabled = false;
623dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung                inflateDebugOverlay();
624a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung                if (mDebugOverlay != null) {
625a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung                    mDebugOverlay.disable();
626a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung                }
6278eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung            } else {
6288eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung                // Enable the debug mode
6298eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung                settings.edit().putBoolean(Constants.Values.App.Key_DebugModeEnabled, true).apply();
630dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung                mConfig.debugModeEnabled = true;
631dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung                inflateDebugOverlay();
632a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung                if (mDebugOverlay != null) {
633a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung                    mDebugOverlay.enable();
634a91c293be26b2deb5434eb827a800fa0c80dc92cWinson Chung                }
6358eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung            }
636dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung            Toast.makeText(this, "Debug mode (" + Constants.Values.App.DebugModeVersion + ") " +
637dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung                (mConfig.debugModeEnabled ? "Enabled" : "Disabled") + ", please restart Recents now",
638dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung                Toast.LENGTH_SHORT).show();
6398eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung        }
6408eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung    }
6418eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung
642d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung    /**** RecentsView.RecentsViewCallbacks Implementation ****/
643d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung
644d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung    @Override
645cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung    public void onExitToHomeAnimationTriggered() {
64685cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung        // Animate the SystemUI scrim views out
647cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung        mScrimViews.startExitRecentsAnimation();
648d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung    }
649d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung
650d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung    @Override
6517aceb9a07fd3883c8f301ba93726d55494b0446eWinson Chung    public void onTaskViewClicked() {
6529214eff52adf56b7c9532e40b784d52f9f94b6d1Winson Chung        // Mark recents as no longer visible
653bac679b0d47aee0c9f3228ce2957ab4fe5b3609eWinson Chung        onRecentsActivityVisibilityChanged(false);
65447c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung    }
655f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
656d7b2cb12ac90956843413c212769639044a0b6f2Winson Chung    @Override
6574e96eb709d2f1b6b1cd233c8a99f6706fde70bb1Winson Chung    public void onTaskLaunchFailed() {
6584e96eb709d2f1b6b1cd233c8a99f6706fde70bb1Winson Chung        // Return to Home
6594e96eb709d2f1b6b1cd233c8a99f6706fde70bb1Winson Chung        dismissRecentsToHomeRaw(true);
6604e96eb709d2f1b6b1cd233c8a99f6706fde70bb1Winson Chung    }
6614e96eb709d2f1b6b1cd233c8a99f6706fde70bb1Winson Chung
6624e96eb709d2f1b6b1cd233c8a99f6706fde70bb1Winson Chung    @Override
6637aceb9a07fd3883c8f301ba93726d55494b0446eWinson Chung    public void onAllTaskViewsDismissed() {
664d7b2cb12ac90956843413c212769639044a0b6f2Winson Chung        mFinishLaunchHomeRunnable.run();
665d7b2cb12ac90956843413c212769639044a0b6f2Winson Chung    }
666d7b2cb12ac90956843413c212769639044a0b6f2Winson Chung
66718f99d91349a4f5ce55e22ed33f1f57eb1b0297bJason Monk    @Override
66818f99d91349a4f5ce55e22ed33f1f57eb1b0297bJason Monk    public void onScreenPinningRequest() {
66918f99d91349a4f5ce55e22ed33f1f57eb1b0297bJason Monk        if (mStatusBar != null) {
67018f99d91349a4f5ce55e22ed33f1f57eb1b0297bJason Monk            mStatusBar.showScreenPinningRequest(false);
67118f99d91349a4f5ce55e22ed33f1f57eb1b0297bJason Monk        }
67218f99d91349a4f5ce55e22ed33f1f57eb1b0297bJason Monk    }
67318f99d91349a4f5ce55e22ed33f1f57eb1b0297bJason Monk
674d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung    /**** RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks Implementation ****/
675d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung
676f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    @Override
677d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung    public void refreshSearchWidget() {
678d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        bindSearchBarAppWidget();
679d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        addSearchBarAppWidgetView();
680f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    }
6812915b9d14876c8e63ca82415807bcfb602ebad43Winson Chung
6822915b9d14876c8e63ca82415807bcfb602ebad43Winson Chung    /**** DebugOverlayView.DebugOverlayViewCallbacks ****/
6832915b9d14876c8e63ca82415807bcfb602ebad43Winson Chung
6842915b9d14876c8e63ca82415807bcfb602ebad43Winson Chung    @Override
6852915b9d14876c8e63ca82415807bcfb602ebad43Winson Chung    public void onPrimarySeekBarChanged(float progress) {
6862915b9d14876c8e63ca82415807bcfb602ebad43Winson Chung        // Do nothing
6872915b9d14876c8e63ca82415807bcfb602ebad43Winson Chung    }
6882915b9d14876c8e63ca82415807bcfb602ebad43Winson Chung
6892915b9d14876c8e63ca82415807bcfb602ebad43Winson Chung    @Override
6902915b9d14876c8e63ca82415807bcfb602ebad43Winson Chung    public void onSecondarySeekBarChanged(float progress) {
6912915b9d14876c8e63ca82415807bcfb602ebad43Winson Chung        // Do nothing
6922915b9d14876c8e63ca82415807bcfb602ebad43Winson Chung    }
693303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung}
694