RecentsActivity.java revision d7b2cb12ac90956843413c212769639044a0b6f2
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;
31d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chungimport android.os.UserHandle;
32f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chungimport android.util.Pair;
331e8d71b605b4872e93200706a80a88a3ff25498cWinson Chungimport android.view.KeyEvent;
34303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport android.view.View;
358e548f7025ce930810479a8e628c325d09557fa3Winson Chungimport android.view.ViewStub;
368eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chungimport android.widget.Toast;
3747c4c69575e94635a9356e8a1faf4b56a0120452Winson Chungimport com.android.systemui.R;
38f1fbd77cf057e43926f9a0347692611386d09f40Winson Chungimport com.android.systemui.recents.model.RecentsTaskLoader;
39303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport com.android.systemui.recents.model.SpaceNode;
40303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport com.android.systemui.recents.model.TaskStack;
418e548f7025ce930810479a8e628c325d09557fa3Winson Chungimport com.android.systemui.recents.views.FullscreenTransitionOverlayView;
42303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport com.android.systemui.recents.views.RecentsView;
43cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chungimport com.android.systemui.recents.views.SystemBarScrimViews;
44d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chungimport com.android.systemui.recents.views.ViewAnimation;
45303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
46b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chungimport java.lang.reflect.InvocationTargetException;
47303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport java.util.ArrayList;
48303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
49303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung/* Activity */
50f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chungpublic class RecentsActivity extends Activity implements RecentsView.RecentsViewCallbacks,
51d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks,
528e548f7025ce930810479a8e628c325d09557fa3Winson Chung        FullscreenTransitionOverlayView.FullScreenTransitionViewCallbacks {
53d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung
54cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung    RecentsView mRecentsView;
55cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung    SystemBarScrimViews mScrimViews;
568e548f7025ce930810479a8e628c325d09557fa3Winson Chung    ViewStub mEmptyViewStub;
57cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung    View mEmptyView;
588e548f7025ce930810479a8e628c325d09557fa3Winson Chung    ViewStub mFullscreenOverlayStub;
598e548f7025ce930810479a8e628c325d09557fa3Winson Chung    FullscreenTransitionOverlayView mFullScreenOverlayView;
60cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung
61cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung    RecentsConfiguration mConfig;
62cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung
63cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung    RecentsAppWidgetHost mAppWidgetHost;
64cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung    AppWidgetProviderInfo mSearchAppWidgetInfo;
65cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung    AppWidgetHostView mSearchAppWidgetHostView;
66cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung
67cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung    boolean mVisible;
68cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung    boolean mTaskLaunched;
69cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung
70cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung    // Runnables to finish the Recents activity
71cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung    FinishRecentsRunnable mFinishRunnable = new FinishRecentsRunnable(true);
72cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung    FinishRecentsRunnable mFinishWithoutAnimationRunnable = new FinishRecentsRunnable(false);
73cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung    FinishRecentsRunnable mFinishLaunchHomeRunnable;
74cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung
75d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung    /**
76d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung     * A Runnable to finish Recents either with/without a transition, and either by calling finish()
77d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung     * or just launching the specified intent.
78d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung     */
79d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung    class FinishRecentsRunnable implements Runnable {
80d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        boolean mUseCustomFinishTransition;
81d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        Intent mLaunchIntent;
82d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        ActivityOptions mLaunchOpts;
83d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung
84d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        public FinishRecentsRunnable(boolean withTransition) {
85d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung            mUseCustomFinishTransition = withTransition;
86d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        }
87d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung
88d7b2cb12ac90956843413c212769639044a0b6f2Winson Chung        /**
89d7b2cb12ac90956843413c212769639044a0b6f2Winson Chung         * Creates a finish runnable that starts the specified intent, using the given
90d7b2cb12ac90956843413c212769639044a0b6f2Winson Chung         * ActivityOptions.
91d7b2cb12ac90956843413c212769639044a0b6f2Winson Chung         */
92d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        public FinishRecentsRunnable(Intent launchIntent, ActivityOptions opts) {
93d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung            mLaunchIntent = launchIntent;
94d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung            mLaunchOpts = opts;
95d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        }
96d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung
97d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        @Override
98d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        public void run() {
99d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung            // Mark Recents as no longer visible
100d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung            AlternateRecentsComponent.notifyVisibilityChanged(false);
101d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung            // Finish Recents
102d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung            if (mLaunchIntent != null) {
103d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung                if (mLaunchOpts != null) {
104d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung                    startActivityAsUser(mLaunchIntent, new UserHandle(UserHandle.USER_CURRENT));
105d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung                } else {
106d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung                    startActivityAsUser(mLaunchIntent, mLaunchOpts.toBundle(),
107d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung                            new UserHandle(UserHandle.USER_CURRENT));
108d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung                }
109d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung            } else {
110d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung                finish();
111d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung                if (mUseCustomFinishTransition) {
112d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung                    overridePendingTransition(R.anim.recents_to_launcher_enter,
113d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung                            R.anim.recents_to_launcher_exit);
114d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung                }
115d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung            }
116d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        }
117d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung    }
118d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung
1196736905dc0e10689f7c63f6da43b31325caf966aWinson Chung    // Broadcast receiver to handle messages from our RecentsService
1208eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung    final BroadcastReceiver mServiceBroadcastReceiver = new BroadcastReceiver() {
12147c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        @Override
12247c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        public void onReceive(Context context, Intent intent) {
12347c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung            String action = intent.getAction();
12410f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung            if (Console.Enabled) {
12510f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                Console.log(Constants.Log.App.SystemUIHandshake,
12610f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                        "[RecentsActivity|serviceBroadcast]", action, Console.AnsiRed);
12710f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung            }
1281e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung            if (action.equals(RecentsService.ACTION_HIDE_RECENTS_ACTIVITY)) {
1296cb485fd2e2f8ace05e1ff281ab0fc824d3652cbWinson Chung                if (intent.getBooleanExtra(RecentsService.EXTRA_TRIGGERED_FROM_ALT_TAB, false)) {
1306cb485fd2e2f8ace05e1ff281ab0fc824d3652cbWinson Chung                    // Dismiss recents, launching the focused task
1316cb485fd2e2f8ace05e1ff281ab0fc824d3652cbWinson Chung                    dismissRecentsIfVisible();
1326cb485fd2e2f8ace05e1ff281ab0fc824d3652cbWinson Chung                } else {
133d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                    // If we are mid-animation into Recents, then reverse it and finish
1348e548f7025ce930810479a8e628c325d09557fa3Winson Chung                    if (mFullScreenOverlayView == null ||
1358e548f7025ce930810479a8e628c325d09557fa3Winson Chung                            !mFullScreenOverlayView.cancelAnimateOnEnterRecents(mFinishRunnable)) {
136d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung                        // Otherwise, either finish Recents, or launch Home directly
137d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                        ReferenceCountedTrigger exitTrigger = new ReferenceCountedTrigger(context,
138d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung                                null, mFinishLaunchHomeRunnable, null);
139969f586533096999f10f5587f901949791154fa2Winson Chung                        mRecentsView.startExitToHomeAnimation(
140d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                                new ViewAnimation.TaskViewExitContext(exitTrigger));
141d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                    }
1426cb485fd2e2f8ace05e1ff281ab0fc824d3652cbWinson Chung                }
1431e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung            } else if (action.equals(RecentsService.ACTION_TOGGLE_RECENTS_ACTIVITY)) {
144c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung                // Try and unfilter and filtered stacks
145c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung                if (!mRecentsView.unfilterFilteredStacks()) {
146c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung                    // If there are no filtered stacks, dismiss recents and launch the first task
147c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung                    dismissRecentsIfVisible();
148c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung                }
14924cf152483c03dc446875c8d6440348174317bc5Winson Chung            } else if (action.equals(RecentsService.ACTION_START_ENTER_ANIMATION)) {
150521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung                // Try and start the enter animation (or restart it on configuration changed)
1518e548f7025ce930810479a8e628c325d09557fa3Winson Chung                mRecentsView.startEnterRecentsAnimation(new ViewAnimation.TaskViewEnterContext(mFullScreenOverlayView));
152d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                // Call our callback
153d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                onEnterAnimationTriggered();
1548eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung            } else if (action.equals(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED)) {
1558eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung                // Refresh the search widget
1568eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung                refreshSearchWidget();
15747c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung            }
15847c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        }
15947c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung    };
160303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
1616736905dc0e10689f7c63f6da43b31325caf966aWinson Chung    // Broadcast receiver to handle messages from the system
1628eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung    final BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() {
1636736905dc0e10689f7c63f6da43b31325caf966aWinson Chung        @Override
1646736905dc0e10689f7c63f6da43b31325caf966aWinson Chung        public void onReceive(Context context, Intent intent) {
165d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung            mFinishWithoutAnimationRunnable.run();
166d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        }
167d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung    };
168d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung
1698eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung    // Debug trigger
1708eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung    final DebugTrigger mDebugTrigger = new DebugTrigger(new Runnable() {
1718eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung        @Override
1728eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung        public void run() {
1738eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung            onDebugModeTriggered();
1748eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung        }
1758eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung    });
1768eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung
177303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Updates the set of recent tasks */
178b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung    void updateRecentsTasks(Intent launchIntent) {
179969f586533096999f10f5587f901949791154fa2Winson Chung        RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
180969f586533096999f10f5587f901949791154fa2Winson Chung        SpaceNode root = loader.reload(this, Constants.Values.RecentsTaskLoader.PreloadFirstTasksCount);
181969f586533096999f10f5587f901949791154fa2Winson Chung        ArrayList<TaskStack> stacks = root.getStacks();
182969f586533096999f10f5587f901949791154fa2Winson Chung        if (!stacks.isEmpty()) {
183969f586533096999f10f5587f901949791154fa2Winson Chung            mRecentsView.setBSP(root);
184969f586533096999f10f5587f901949791154fa2Winson Chung        }
185969f586533096999f10f5587f901949791154fa2Winson Chung
186b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung        // Update the configuration based on the launch intent
187d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        mConfig.launchedFromHome = launchIntent.getBooleanExtra(
188d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                AlternateRecentsComponent.EXTRA_FROM_HOME, false);
189d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        mConfig.launchedFromAppWithThumbnail = launchIntent.getBooleanExtra(
190d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                AlternateRecentsComponent.EXTRA_FROM_APP_THUMBNAIL, false);
191d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        mConfig.launchedFromAppWithScreenshot = launchIntent.getBooleanExtra(
192d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                AlternateRecentsComponent.EXTRA_FROM_APP_FULL_SCREENSHOT, false);
193d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        mConfig.launchedWithAltTab = launchIntent.getBooleanExtra(
194d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                AlternateRecentsComponent.EXTRA_TRIGGERED_FROM_ALT_TAB, false);
195969f586533096999f10f5587f901949791154fa2Winson Chung        mConfig.launchedWithNoRecentTasks = !root.hasTasks();
196303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
19706795630f62e1e7ad89825db23d7656f8dcd6c5aWinson Chung        // Show the scrim if we animate into Recents without window transitions
198cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung        mScrimViews.prepareEnterRecentsAnimation();
199521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung
200303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        // Add the default no-recents layout
2018e548f7025ce930810479a8e628c325d09557fa3Winson Chung        if (mEmptyView == null) {
2028e548f7025ce930810479a8e628c325d09557fa3Winson Chung            mEmptyView = mEmptyViewStub.inflate();
2038e548f7025ce930810479a8e628c325d09557fa3Winson Chung        }
204969f586533096999f10f5587f901949791154fa2Winson Chung        if (mConfig.launchedWithNoRecentTasks) {
205303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung            mEmptyView.setVisibility(View.VISIBLE);
206303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        } else {
207303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung            mEmptyView.setVisibility(View.GONE);
208303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        }
209303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
210303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
211f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    /** Attempts to allocate and bind the search bar app widget */
212f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    void bindSearchBarAppWidget() {
213814086db674d8eb298541b7e601e29c5c68e2074Winson Chung        if (Constants.DebugFlags.App.EnableSearchLayout) {
214f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            SystemServicesProxy ssp = RecentsTaskLoader.getInstance().getSystemServicesProxy();
215f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
216f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            // Reset the host view and widget info
217f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            mSearchAppWidgetHostView = null;
218f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            mSearchAppWidgetInfo = null;
219f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
220f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            // Try and load the app widget id from the settings
221d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung            int appWidgetId = mConfig.searchBarAppWidgetId;
222f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            if (appWidgetId >= 0) {
223f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                mSearchAppWidgetInfo = ssp.getAppWidgetInfo(appWidgetId);
224f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                if (mSearchAppWidgetInfo == null) {
225f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                    // If there is no actual widget associated with that id, then delete it and
226f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                    // prepare to bind another app widget in its place
227f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                    ssp.unbindSearchAppWidget(mAppWidgetHost, appWidgetId);
228f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                    appWidgetId = -1;
229f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                }
23010f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                if (Console.Enabled) {
23110f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    Console.log(Constants.Log.App.SystemUIHandshake,
23210f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                            "[RecentsActivity|onCreate|settings|appWidgetId]",
23310f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                            "Id: " + appWidgetId,
23410f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                            Console.AnsiBlue);
23510f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                }
236f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            }
237f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
238f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            // If there is no id, then bind a new search app widget
239f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            if (appWidgetId < 0) {
240f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                Pair<Integer, AppWidgetProviderInfo> widgetInfo =
241f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                        ssp.bindSearchAppWidget(mAppWidgetHost);
242f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                if (widgetInfo != null) {
24310f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    if (Console.Enabled) {
24410f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                        Console.log(Constants.Log.App.SystemUIHandshake,
24510f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                                "[RecentsActivity|onCreate|searchWidget]",
24610f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                                "Id: " + widgetInfo.first + " Info: " + widgetInfo.second,
24710f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                                Console.AnsiBlue);
24810f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    }
249f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
250f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                    // Save the app widget id into the settings
251d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                    mConfig.updateSearchBarAppWidgetId(this, widgetInfo.first);
252f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                    mSearchAppWidgetInfo = widgetInfo.second;
253f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                }
254f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            }
255f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        }
256f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    }
257f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
258f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    /** Creates the search bar app widget view */
259f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    void addSearchBarAppWidgetView() {
260814086db674d8eb298541b7e601e29c5c68e2074Winson Chung        if (Constants.DebugFlags.App.EnableSearchLayout) {
261d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung            int appWidgetId = mConfig.searchBarAppWidgetId;
262f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            if (appWidgetId >= 0) {
26310f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                if (Console.Enabled) {
26410f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    Console.log(Constants.Log.App.SystemUIHandshake,
26510f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                            "[RecentsActivity|onCreate|addSearchAppWidgetView]",
26610f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                            "Id: " + appWidgetId,
26710f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                            Console.AnsiBlue);
26810f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                }
269f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                mSearchAppWidgetHostView = mAppWidgetHost.createView(this, appWidgetId,
270f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                        mSearchAppWidgetInfo);
271f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                Bundle opts = new Bundle();
272f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,
273f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                        AppWidgetProviderInfo.WIDGET_CATEGORY_RECENTS);
274f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                mSearchAppWidgetHostView.updateAppWidgetOptions(opts);
275f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                // Set the padding to 0 for this search widget
276f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                mSearchAppWidgetHostView.setPadding(0, 0, 0, 0);
277f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                mRecentsView.setSearchBar(mSearchAppWidgetHostView);
278f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            } else {
279f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                mRecentsView.setSearchBar(null);
280f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            }
281f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        }
282f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    }
283f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
284303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Dismisses recents if we are already visible and the intent is to toggle the recents view */
28547c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung    boolean dismissRecentsIfVisible() {
28647c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        if (mVisible) {
287d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung            // If we are mid-animation into Recents, then reverse it and finish
2888e548f7025ce930810479a8e628c325d09557fa3Winson Chung            if (mFullScreenOverlayView == null ||
2898e548f7025ce930810479a8e628c325d09557fa3Winson Chung                    !mFullScreenOverlayView.cancelAnimateOnEnterRecents(mFinishRunnable)) {
290d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                // If we have a focused task, then launch that task
291d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                if (!mRecentsView.launchFocusedTask()) {
2921f76132d4dc0d96bf34d8580064b8dadf24eb9f4Winson Chung                    if (mConfig.launchedFromHome) {
2931f76132d4dc0d96bf34d8580064b8dadf24eb9f4Winson Chung                        // Just start the animation out of recents
294d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                        ReferenceCountedTrigger exitTrigger = new ReferenceCountedTrigger(this,
295d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung                                null, mFinishLaunchHomeRunnable, null);
296969f586533096999f10f5587f901949791154fa2Winson Chung                        mRecentsView.startExitToHomeAnimation(
297d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                                new ViewAnimation.TaskViewExitContext(exitTrigger));
2981f76132d4dc0d96bf34d8580064b8dadf24eb9f4Winson Chung                    } else {
2991f76132d4dc0d96bf34d8580064b8dadf24eb9f4Winson Chung                        // Otherwise, try and launch the first task
3001f76132d4dc0d96bf34d8580064b8dadf24eb9f4Winson Chung                        if (!mRecentsView.launchFirstTask()) {
3011f76132d4dc0d96bf34d8580064b8dadf24eb9f4Winson Chung                            // If there are no tasks, then just finish recents
302d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung                            mFinishLaunchHomeRunnable.run();
3031f76132d4dc0d96bf34d8580064b8dadf24eb9f4Winson Chung                        }
304d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                    }
3051e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung                }
306303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung            }
30747c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung            return true;
308303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        }
309303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        return false;
310303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
311303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
312303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Called with the activity is first created. */
313303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    @Override
314303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    public void onCreate(Bundle savedInstanceState) {
315303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        super.onCreate(savedInstanceState);
31610f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        if (Console.Enabled) {
31710f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung            Console.logDivider(Constants.Log.App.SystemUIHandshake);
31810f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung            Console.log(Constants.Log.App.SystemUIHandshake, "[RecentsActivity|onCreate]",
31910f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    getIntent().getAction() + " visible: " + mVisible, Console.AnsiRed);
32010f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung            Console.logTraceTime(Constants.Log.App.TimeRecentsStartup,
32110f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    Constants.Log.App.TimeRecentsStartupKey, "onCreate");
32210f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        }
323303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
324303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        // Initialize the loader and the configuration
325303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        RecentsTaskLoader.initialize(this);
326d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        mConfig = RecentsConfiguration.reinitialize(this);
327303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
328d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        // Create the home intent runnable
329d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        Intent homeIntent = new Intent(Intent.ACTION_MAIN, null);
330d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        homeIntent.addCategory(Intent.CATEGORY_HOME);
331d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        homeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
332d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung                            Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
333d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        mFinishLaunchHomeRunnable = new FinishRecentsRunnable(homeIntent,
334d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung                ActivityOptions.makeCustomAnimation(this, R.anim.recents_to_launcher_enter,
335d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung                        R.anim.recents_to_launcher_exit));
336d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung
337f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        // Initialize the widget host (the host id is static and does not change)
338d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        mAppWidgetHost = new RecentsAppWidgetHost(this, Constants.Values.App.AppWidgetHostId);
339f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
3408e548f7025ce930810479a8e628c325d09557fa3Winson Chung        // Set the Recents layout
3418e548f7025ce930810479a8e628c325d09557fa3Winson Chung        setContentView(R.layout.recents);
3428e548f7025ce930810479a8e628c325d09557fa3Winson Chung        mRecentsView = (RecentsView) findViewById(R.id.recents_view);
34347c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        mRecentsView.setCallbacks(this);
344653f70c223f8742e2a3696641fe1d4b82bc2ca36Winson Chung        mRecentsView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
345653f70c223f8742e2a3696641fe1d4b82bc2ca36Winson Chung                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
346653f70c223f8742e2a3696641fe1d4b82bc2ca36Winson Chung                View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
3478e548f7025ce930810479a8e628c325d09557fa3Winson Chung        mEmptyViewStub = (ViewStub) findViewById(R.id.empty_view_stub);
3488e548f7025ce930810479a8e628c325d09557fa3Winson Chung        mFullscreenOverlayStub = (ViewStub) findViewById(R.id.fullscreen_overlay_stub);
3498e548f7025ce930810479a8e628c325d09557fa3Winson Chung        mScrimViews = new SystemBarScrimViews(this, mConfig);
350303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
351303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        // Update the recent tasks
352b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung        updateRecentsTasks(getIntent());
353f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
354d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        // Prepare the screenshot transition if necessary
355d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        if (Constants.DebugFlags.App.EnableScreenshotAppTransition) {
3568e548f7025ce930810479a8e628c325d09557fa3Winson Chung            mFullScreenOverlayView = (FullscreenTransitionOverlayView) mFullscreenOverlayStub.inflate();
3578e548f7025ce930810479a8e628c325d09557fa3Winson Chung            mFullScreenOverlayView.setCallbacks(this);
3588e548f7025ce930810479a8e628c325d09557fa3Winson Chung            mFullScreenOverlayView.prepareAnimateOnEnterRecents(AlternateRecentsComponent.getLastScreenshot());
359d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        }
360d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung
361f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        // Bind the search app widget when we first start up
362f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        bindSearchBarAppWidget();
363f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        // Add the search bar layout
364f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        addSearchBarAppWidgetView();
365521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung
366521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung        // Update if we are getting a configuration change
367521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung        if (savedInstanceState != null) {
368521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung            onConfigurationChange();
369521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung        }
370b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung
371cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung        // Private API calls to make the shadows look better
372b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung        try {
373cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung            Utilities.setShadowProperty("ambientShadowStrength", String.valueOf(35f));
374cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung            Utilities.setShadowProperty("ambientRatio", String.valueOf(0.5f));
375b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung        } catch (IllegalAccessException e) {
376b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung            e.printStackTrace();
377b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung        } catch (InvocationTargetException e) {
378b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung            e.printStackTrace();
379b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung        }
380521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung    }
381521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung
382521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung    void onConfigurationChange() {
383521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung        // Try and start the enter animation (or restart it on configuration changed)
3848e548f7025ce930810479a8e628c325d09557fa3Winson Chung        mRecentsView.startEnterRecentsAnimation(new ViewAnimation.TaskViewEnterContext(mFullScreenOverlayView));
385d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        // Call our callback
386d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        onEnterAnimationTriggered();
387303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
388303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
389303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    @Override
390303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    protected void onNewIntent(Intent intent) {
391303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        super.onNewIntent(intent);
39247c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        // Reset the task launched flag if we encounter an onNewIntent() before onStop()
39347c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        mTaskLaunched = false;
39447c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung
39510f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        if (Console.Enabled) {
39610f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung            Console.logDivider(Constants.Log.App.SystemUIHandshake);
39710f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung            Console.log(Constants.Log.App.SystemUIHandshake, "[RecentsActivity|onNewIntent]",
39810f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    intent.getAction() + " visible: " + mVisible, Console.AnsiRed);
39910f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung            Console.logTraceTime(Constants.Log.App.TimeRecentsStartup,
40010f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    Constants.Log.App.TimeRecentsStartupKey, "onNewIntent");
40110f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        }
402303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
403303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        // Initialize the loader and the configuration
404303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        RecentsTaskLoader.initialize(this);
405d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        mConfig = RecentsConfiguration.reinitialize(this);
406303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
407303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        // Update the recent tasks
408b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung        updateRecentsTasks(intent);
409f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
410d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        // Prepare the screenshot transition if necessary
411d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        if (Constants.DebugFlags.App.EnableScreenshotAppTransition) {
4128e548f7025ce930810479a8e628c325d09557fa3Winson Chung            mFullScreenOverlayView.prepareAnimateOnEnterRecents(AlternateRecentsComponent.getLastScreenshot());
413d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        }
414d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung
415f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        // Don't attempt to rebind the search bar widget, but just add the search bar layout
416f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        addSearchBarAppWidgetView();
417303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
418303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
419303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    @Override
420303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    protected void onStart() {
42110f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        if (Console.Enabled) {
42210f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung            Console.log(Constants.Log.App.SystemUIHandshake, "[RecentsActivity|onStart]", "",
42310f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    Console.AnsiRed);
42410f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        }
425303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        super.onStart();
42647a3e65acc35cd3061bf3867e8b20753870fd892Winson Chung
427303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        mVisible = true;
428303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
429303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
430303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    @Override
431303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    protected void onResume() {
43210f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        if (Console.Enabled) {
43310f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung            Console.log(Constants.Log.App.SystemUIHandshake, "[RecentsActivity|onResume]", "",
43410f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    Console.AnsiRed);
43510f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        }
436303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        super.onResume();
4376736905dc0e10689f7c63f6da43b31325caf966aWinson Chung    }
4386736905dc0e10689f7c63f6da43b31325caf966aWinson Chung
4396736905dc0e10689f7c63f6da43b31325caf966aWinson Chung    @Override
4406736905dc0e10689f7c63f6da43b31325caf966aWinson Chung    public void onAttachedToWindow() {
44110f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        if (Console.Enabled) {
44210f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung            Console.log(Constants.Log.App.SystemUIHandshake,
44310f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    "[RecentsActivity|onAttachedToWindow]", "",
44410f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    Console.AnsiRed);
44510f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        }
4466736905dc0e10689f7c63f6da43b31325caf966aWinson Chung        super.onAttachedToWindow();
44747c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung
44847c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        // Register the broadcast receiver to handle messages from our service
44947c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        IntentFilter filter = new IntentFilter();
4501e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung        filter.addAction(RecentsService.ACTION_HIDE_RECENTS_ACTIVITY);
45147c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        filter.addAction(RecentsService.ACTION_TOGGLE_RECENTS_ACTIVITY);
45224cf152483c03dc446875c8d6440348174317bc5Winson Chung        filter.addAction(RecentsService.ACTION_START_ENTER_ANIMATION);
4538eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung        filter.addAction(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED);
45447c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        registerReceiver(mServiceBroadcastReceiver, filter);
4556736905dc0e10689f7c63f6da43b31325caf966aWinson Chung
4566736905dc0e10689f7c63f6da43b31325caf966aWinson Chung        // Register the broadcast receiver to handle messages when the screen is turned off
4576736905dc0e10689f7c63f6da43b31325caf966aWinson Chung        filter = new IntentFilter();
4586736905dc0e10689f7c63f6da43b31325caf966aWinson Chung        filter.addAction(Intent.ACTION_SCREEN_OFF);
4596736905dc0e10689f7c63f6da43b31325caf966aWinson Chung        registerReceiver(mScreenOffReceiver, filter);
4609f49df933f01a32d04bdf92d53c943065aa8ddf7Winson Chung
4619f49df933f01a32d04bdf92d53c943065aa8ddf7Winson Chung        // Register any broadcast receivers for the task loader
4629f49df933f01a32d04bdf92d53c943065aa8ddf7Winson Chung        RecentsTaskLoader.getInstance().registerReceivers(this, mRecentsView);
463d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung
464d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        // Start listening for widget package changes if there is one bound
465d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        if (mConfig.searchBarAppWidgetId >= 0) {
466d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung            mAppWidgetHost.startListening(this);
467d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        }
468303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
469303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
470303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    @Override
4716736905dc0e10689f7c63f6da43b31325caf966aWinson Chung    public void onDetachedFromWindow() {
47210f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        if (Console.Enabled) {
47310f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung            Console.log(Constants.Log.App.SystemUIHandshake,
47410f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    "[RecentsActivity|onDetachedFromWindow]", "",
47510f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    Console.AnsiRed);
47610f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        }
4776736905dc0e10689f7c63f6da43b31325caf966aWinson Chung        super.onDetachedFromWindow();
478303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
47947c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        // Unregister any broadcast receivers we have registered
48047c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        unregisterReceiver(mServiceBroadcastReceiver);
4816736905dc0e10689f7c63f6da43b31325caf966aWinson Chung        unregisterReceiver(mScreenOffReceiver);
4829f49df933f01a32d04bdf92d53c943065aa8ddf7Winson Chung        RecentsTaskLoader.getInstance().unregisterReceivers();
483d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung
484d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        // Stop listening for widget package changes if there was one bound
485d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        if (mConfig.searchBarAppWidgetId >= 0) {
486d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung            mAppWidgetHost.stopListening();
487d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        }
4886736905dc0e10689f7c63f6da43b31325caf966aWinson Chung    }
4896736905dc0e10689f7c63f6da43b31325caf966aWinson Chung
4906736905dc0e10689f7c63f6da43b31325caf966aWinson Chung    @Override
4916736905dc0e10689f7c63f6da43b31325caf966aWinson Chung    protected void onPause() {
49210f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        if (Console.Enabled) {
49310f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung            Console.log(Constants.Log.App.SystemUIHandshake, "[RecentsActivity|onPause]", "",
49410f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    Console.AnsiRed);
49510f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        }
4966736905dc0e10689f7c63f6da43b31325caf966aWinson Chung        super.onPause();
497303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
498303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
499303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    @Override
500303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    protected void onStop() {
50110f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        if (Console.Enabled) {
50210f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung            Console.log(Constants.Log.App.SystemUIHandshake, "[RecentsActivity|onStop]", "",
50310f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    Console.AnsiRed);
50410f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        }
505303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        super.onStop();
50647c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung
507303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        mVisible = false;
50847c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        mTaskLaunched = false;
50947c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung    }
51047c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung
51147c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung    @Override
51247c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung    protected void onDestroy() {
51310f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        if (Console.Enabled) {
51410f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung            Console.log(Constants.Log.App.SystemUIHandshake, "[RecentsActivity|onDestroy]", "",
51510f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    Console.AnsiRed);
51610f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        }
51747c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        super.onDestroy();
518303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
519303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
520303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    @Override
5214d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung    public void onTrimMemory(int level) {
5224d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung        RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
5234d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung        if (loader != null) {
5244d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung            loader.onTrimMemory(level);
5254d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung        }
5264d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung    }
5274d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung
5284d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung    @Override
5291e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung    public boolean onKeyDown(int keyCode, KeyEvent event) {
5301e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung        if (keyCode == KeyEvent.KEYCODE_TAB) {
5311e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung            // Focus the next task in the stack
5321e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung            final boolean backward = event.isShiftPressed();
5331e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung            mRecentsView.focusNextTask(!backward);
5341e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung            return true;
5351e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung        }
5368eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung        // Pass through the debug trigger
5378eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung        mDebugTrigger.onKeyEvent(keyCode);
5381e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung        return super.onKeyDown(keyCode, event);
5391e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung    }
5401e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung
5411e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung    @Override
542a26fb7822ddf3511796279b847cc216bee9e7f70Winson Chung    public void onUserInteraction() {
543a26fb7822ddf3511796279b847cc216bee9e7f70Winson Chung        mRecentsView.onUserInteraction();
544a26fb7822ddf3511796279b847cc216bee9e7f70Winson Chung    }
545a26fb7822ddf3511796279b847cc216bee9e7f70Winson Chung
546a26fb7822ddf3511796279b847cc216bee9e7f70Winson Chung    @Override
547303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    public void onBackPressed() {
548d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        // If we are mid-animation into Recents, then reverse it and finish
5498e548f7025ce930810479a8e628c325d09557fa3Winson Chung        if (mFullScreenOverlayView == null ||
5508e548f7025ce930810479a8e628c325d09557fa3Winson Chung                !mFullScreenOverlayView.cancelAnimateOnEnterRecents(mFinishRunnable)) {
551d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung            // If we are currently filtering in any stacks, unfilter them first
552d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung            if (!mRecentsView.unfilterFilteredStacks()) {
553d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                if (mConfig.launchedFromHome) {
554d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                    // Just start the animation out of recents
555d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                    ReferenceCountedTrigger exitTrigger = new ReferenceCountedTrigger(this,
556d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung                            null, mFinishLaunchHomeRunnable, null);
557969f586533096999f10f5587f901949791154fa2Winson Chung                    mRecentsView.startExitToHomeAnimation(
558d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                            new ViewAnimation.TaskViewExitContext(exitTrigger));
559d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                } else {
560d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                    // Otherwise, try and launch the first task
561d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                    if (!mRecentsView.launchFirstTask()) {
562d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                        // If there are no tasks, then just finish recents
563d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung                        mFinishLaunchHomeRunnable.run();
564d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                    }
565d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                }
56656f4692a89a1afb2fe40aec8a9b6f26936b8e9a4Winson Chung            }
567303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        }
568303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
56947c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung
5708eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung    /** Called when debug mode is triggered */
5718eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung    public void onDebugModeTriggered() {
5728eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung        if (mConfig.developerOptionsEnabled) {
5738eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung            SharedPreferences settings = getSharedPreferences(getPackageName(), 0);
5748eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung            if (settings.getBoolean(Constants.Values.App.Key_DebugModeEnabled, false)) {
5758eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung                // Disable the debug mode
5768eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung                settings.edit().remove(Constants.Values.App.Key_DebugModeEnabled).apply();
5778eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung            } else {
5788eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung                // Enable the debug mode
5798eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung                settings.edit().putBoolean(Constants.Values.App.Key_DebugModeEnabled, true).apply();
5808eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung            }
5818eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung            Toast.makeText(this, "Debug mode (" + Constants.Values.App.DebugModeVersion +
5828eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung                    ") toggled, please restart Recents now", Toast.LENGTH_SHORT).show();
5838eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung        }
5848eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung    }
5858eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung
5868eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung    /** Called when the enter recents animation is triggered. */
587521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung    public void onEnterAnimationTriggered() {
588cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung        // Animate the scrims in
589cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung        mScrimViews.startEnterRecentsAnimation();
590969f586533096999f10f5587f901949791154fa2Winson Chung    }
591969f586533096999f10f5587f901949791154fa2Winson Chung
5928e548f7025ce930810479a8e628c325d09557fa3Winson Chung    /**** FullscreenTransitionOverlayView.FullScreenTransitionViewCallbacks Implementation ****/
593521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung
594521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung    @Override
595d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung    public void onEnterAnimationComplete(boolean canceled) {
596d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        if (!canceled) {
597d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung            // Reset the full screenshot transition view
598d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung            if (Constants.DebugFlags.App.EnableScreenshotAppTransition) {
5998e548f7025ce930810479a8e628c325d09557fa3Winson Chung                mFullScreenOverlayView.reset();
600d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung            }
601d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung
602d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung            // XXX: We should clean up the screenshot in this case as well, but it needs to happen
603d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung            //      after to animate up
604d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        }
605d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        // Recycle the full screen screenshot
606d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        AlternateRecentsComponent.consumeLastScreenshot();
607d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung    }
608d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung
609d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung    /**** RecentsView.RecentsViewCallbacks Implementation ****/
610d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung
611d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung    @Override
612cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung    public void onExitToHomeAnimationTriggered() {
613cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung        // Animate the scrims out
614cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung        mScrimViews.startExitRecentsAnimation();
615d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung    }
616d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung
617d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung    @Override
618c9567c07dd4953f5c5e3821d30525e50ed8b9b29Winson Chung    public void onTaskLaunching() {
61947c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        mTaskLaunched = true;
620521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung
6219214eff52adf56b7c9532e40b784d52f9f94b6d1Winson Chung        // Mark recents as no longer visible
6229214eff52adf56b7c9532e40b784d52f9f94b6d1Winson Chung        AlternateRecentsComponent.notifyVisibilityChanged(false);
62347c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung    }
624f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
625d7b2cb12ac90956843413c212769639044a0b6f2Winson Chung    @Override
626d7b2cb12ac90956843413c212769639044a0b6f2Winson Chung    public void onLastTaskRemoved() {
627d7b2cb12ac90956843413c212769639044a0b6f2Winson Chung        mFinishLaunchHomeRunnable.run();
628d7b2cb12ac90956843413c212769639044a0b6f2Winson Chung    }
629d7b2cb12ac90956843413c212769639044a0b6f2Winson Chung
630d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung    /**** RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks Implementation ****/
631d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung
632f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    @Override
633d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung    public void refreshSearchWidget() {
634d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        // Load the Search widget again
635d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        bindSearchBarAppWidget();
636d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung        addSearchBarAppWidgetView();
637f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    }
638303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung}
639