RecentsActivity.java revision c9567c07dd4953f5c5e3821d30525e50ed8b9b29
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;
20f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chungimport android.appwidget.AppWidgetHost;
21f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chungimport android.appwidget.AppWidgetHostView;
22f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chungimport android.appwidget.AppWidgetManager;
23f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chungimport android.appwidget.AppWidgetProviderInfo;
2447c4c69575e94635a9356e8a1faf4b56a0120452Winson Chungimport android.content.BroadcastReceiver;
2547c4c69575e94635a9356e8a1faf4b56a0120452Winson Chungimport android.content.Context;
26303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport android.content.Intent;
2747c4c69575e94635a9356e8a1faf4b56a0120452Winson Chungimport android.content.IntentFilter;
28303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport android.os.Bundle;
29f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chungimport android.util.Pair;
30521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chungimport android.view.Gravity;
311e8d71b605b4872e93200706a80a88a3ff25498cWinson Chungimport android.view.KeyEvent;
32303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport android.view.LayoutInflater;
33303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport android.view.View;
34521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chungimport android.view.ViewGroup;
35303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport android.widget.FrameLayout;
3647c4c69575e94635a9356e8a1faf4b56a0120452Winson Chungimport com.android.systemui.R;
37303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport com.android.systemui.recents.model.SpaceNode;
38303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport com.android.systemui.recents.model.TaskStack;
39d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chungimport com.android.systemui.recents.views.FullScreenTransitionView;
40303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport com.android.systemui.recents.views.RecentsView;
41d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chungimport com.android.systemui.recents.views.ViewAnimation;
42303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
43b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chungimport java.lang.reflect.InvocationTargetException;
44b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chungimport java.lang.reflect.Method;
45303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport java.util.ArrayList;
46303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
47f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung/** Our special app widget host */
48f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chungclass RecentsAppWidgetHost extends AppWidgetHost {
49f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    /* Callbacks to notify when an app package changes */
50f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    interface RecentsAppWidgetHostCallbacks {
51f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        public void onProviderChanged(int appWidgetId, AppWidgetProviderInfo appWidgetInfo);
52f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    }
53f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
54f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    RecentsAppWidgetHostCallbacks mCb;
55f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
56f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    public RecentsAppWidgetHost(Context context, int hostId, RecentsAppWidgetHostCallbacks cb) {
57f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        super(context, hostId);
58f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        mCb = cb;
59f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    }
60f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
61f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    @Override
62f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    protected void onProviderChanged(int appWidgetId, AppWidgetProviderInfo appWidget) {
63f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        mCb.onProviderChanged(appWidgetId, appWidget);
64f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    }
65f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung}
66303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
67303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung/* Activity */
68f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chungpublic class RecentsActivity extends Activity implements RecentsView.RecentsViewCallbacks,
69d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks,
70d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        FullScreenTransitionView.FullScreenTransitionViewCallbacks {
71d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung
72303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    FrameLayout mContainerView;
73303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    RecentsView mRecentsView;
74303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    View mEmptyView;
75521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung    View mNavBarScrimView;
76d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung    FullScreenTransitionView mFullScreenshotView;
77d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung
78d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung    RecentsConfiguration mConfig;
7947c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung
80f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    AppWidgetHost mAppWidgetHost;
81f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    AppWidgetProviderInfo mSearchAppWidgetInfo;
82f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    AppWidgetHostView mSearchAppWidgetHostView;
83f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
84303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    boolean mVisible;
8547c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung    boolean mTaskLaunched;
8647c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung
87b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung    private static Method sPropertyMethod;
88b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung    static {
89b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung        try {
90b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung            Class<?> c = Class.forName("android.view.GLES20Canvas");
91b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung            sPropertyMethod = c.getDeclaredMethod("setProperty", String.class, String.class);
92b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung            if (!sPropertyMethod.isAccessible()) sPropertyMethod.setAccessible(true);
93b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung        } catch (ClassNotFoundException e) {
94b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung            e.printStackTrace();
95b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung        } catch (NoSuchMethodException e) {
96b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung            e.printStackTrace();
97b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung        }
98b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung    }
99b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung
1006736905dc0e10689f7c63f6da43b31325caf966aWinson Chung    // Broadcast receiver to handle messages from our RecentsService
10147c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung    BroadcastReceiver mServiceBroadcastReceiver = new BroadcastReceiver() {
10247c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        @Override
10347c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        public void onReceive(Context context, Intent intent) {
10447c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung            String action = intent.getAction();
10510f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung            if (Console.Enabled) {
10610f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                Console.log(Constants.Log.App.SystemUIHandshake,
10710f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                        "[RecentsActivity|serviceBroadcast]", action, Console.AnsiRed);
10810f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung            }
1091e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung            if (action.equals(RecentsService.ACTION_HIDE_RECENTS_ACTIVITY)) {
1106cb485fd2e2f8ace05e1ff281ab0fc824d3652cbWinson Chung                if (intent.getBooleanExtra(RecentsService.EXTRA_TRIGGERED_FROM_ALT_TAB, false)) {
1116cb485fd2e2f8ace05e1ff281ab0fc824d3652cbWinson Chung                    // Dismiss recents, launching the focused task
1126cb485fd2e2f8ace05e1ff281ab0fc824d3652cbWinson Chung                    dismissRecentsIfVisible();
1136cb485fd2e2f8ace05e1ff281ab0fc824d3652cbWinson Chung                } else {
114d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                    // If we are mid-animation into Recents, then reverse it and finish
115d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                    if (mFullScreenshotView == null ||
116d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                            !mFullScreenshotView.cancelAnimateOnEnterRecents(mFinishRunnable)) {
117d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                        // Otherwise, just finish the activity without launching any other activities
118d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                        ReferenceCountedTrigger exitTrigger = new ReferenceCountedTrigger(context,
119d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                                null, mFinishRunnable, null);
120969f586533096999f10f5587f901949791154fa2Winson Chung                        mRecentsView.startExitToHomeAnimation(
121d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                                new ViewAnimation.TaskViewExitContext(exitTrigger));
122d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                    }
1236cb485fd2e2f8ace05e1ff281ab0fc824d3652cbWinson Chung                }
1241e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung            } else if (action.equals(RecentsService.ACTION_TOGGLE_RECENTS_ACTIVITY)) {
125c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung                // Try and unfilter and filtered stacks
126c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung                if (!mRecentsView.unfilterFilteredStacks()) {
127c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung                    // If there are no filtered stacks, dismiss recents and launch the first task
128c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung                    dismissRecentsIfVisible();
129c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung                }
13024cf152483c03dc446875c8d6440348174317bc5Winson Chung            } else if (action.equals(RecentsService.ACTION_START_ENTER_ANIMATION)) {
131521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung                // Try and start the enter animation (or restart it on configuration changed)
132969f586533096999f10f5587f901949791154fa2Winson Chung                mRecentsView.startEnterRecentsAnimation(new ViewAnimation.TaskViewEnterContext(mFullScreenshotView));
133d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                // Call our callback
134d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                onEnterAnimationTriggered();
13547c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung            }
13647c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        }
13747c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung    };
138303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
1396736905dc0e10689f7c63f6da43b31325caf966aWinson Chung    // Broadcast receiver to handle messages from the system
1406736905dc0e10689f7c63f6da43b31325caf966aWinson Chung    BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() {
1416736905dc0e10689f7c63f6da43b31325caf966aWinson Chung        @Override
1426736905dc0e10689f7c63f6da43b31325caf966aWinson Chung        public void onReceive(Context context, Intent intent) {
1439214eff52adf56b7c9532e40b784d52f9f94b6d1Winson Chung            // Mark recents as no longer visible
1449214eff52adf56b7c9532e40b784d52f9f94b6d1Winson Chung            AlternateRecentsComponent.notifyVisibilityChanged(false);
1459214eff52adf56b7c9532e40b784d52f9f94b6d1Winson Chung            // Finish without an animations
1466736905dc0e10689f7c63f6da43b31325caf966aWinson Chung            finish();
1476736905dc0e10689f7c63f6da43b31325caf966aWinson Chung        }
1486736905dc0e10689f7c63f6da43b31325caf966aWinson Chung    };
1496736905dc0e10689f7c63f6da43b31325caf966aWinson Chung
150d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung    // A runnable to finish the Recents activity
151d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung    Runnable mFinishRunnable = new Runnable() {
152d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        @Override
153d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        public void run() {
1549214eff52adf56b7c9532e40b784d52f9f94b6d1Winson Chung            // Mark recents as no longer visible
1559214eff52adf56b7c9532e40b784d52f9f94b6d1Winson Chung            AlternateRecentsComponent.notifyVisibilityChanged(false);
1569214eff52adf56b7c9532e40b784d52f9f94b6d1Winson Chung            // Finish with an animations
157d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung            finish();
158d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung            overridePendingTransition(R.anim.recents_to_launcher_enter,
159d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                    R.anim.recents_to_launcher_exit);
160d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        }
161d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung    };
162d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung
163303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Updates the set of recent tasks */
164b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung    void updateRecentsTasks(Intent launchIntent) {
165969f586533096999f10f5587f901949791154fa2Winson Chung        RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
166969f586533096999f10f5587f901949791154fa2Winson Chung        SpaceNode root = loader.reload(this, Constants.Values.RecentsTaskLoader.PreloadFirstTasksCount);
167969f586533096999f10f5587f901949791154fa2Winson Chung        ArrayList<TaskStack> stacks = root.getStacks();
168969f586533096999f10f5587f901949791154fa2Winson Chung        if (!stacks.isEmpty()) {
169969f586533096999f10f5587f901949791154fa2Winson Chung            mRecentsView.setBSP(root);
170969f586533096999f10f5587f901949791154fa2Winson Chung        }
171969f586533096999f10f5587f901949791154fa2Winson Chung
172b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung        // Update the configuration based on the launch intent
173d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        mConfig.launchedFromHome = launchIntent.getBooleanExtra(
174d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                AlternateRecentsComponent.EXTRA_FROM_HOME, false);
175d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        mConfig.launchedFromAppWithThumbnail = launchIntent.getBooleanExtra(
176d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                AlternateRecentsComponent.EXTRA_FROM_APP_THUMBNAIL, false);
177d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        mConfig.launchedFromAppWithScreenshot = launchIntent.getBooleanExtra(
178d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                AlternateRecentsComponent.EXTRA_FROM_APP_FULL_SCREENSHOT, false);
179d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        mConfig.launchedWithAltTab = launchIntent.getBooleanExtra(
180d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                AlternateRecentsComponent.EXTRA_TRIGGERED_FROM_ALT_TAB, false);
181969f586533096999f10f5587f901949791154fa2Winson Chung        mConfig.launchedWithNoRecentTasks = !root.hasTasks();
182303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
183743d5c95f3a107639c0ff22f099cab2624da3e27Winson Chung        if (mConfig.shouldAnimateNavBarScrim()) {
184743d5c95f3a107639c0ff22f099cab2624da3e27Winson Chung            // Hide the scrim if we animate into Recents with window transitions
185743d5c95f3a107639c0ff22f099cab2624da3e27Winson Chung            mNavBarScrimView.setVisibility(View.INVISIBLE);
186743d5c95f3a107639c0ff22f099cab2624da3e27Winson Chung        } else {
187743d5c95f3a107639c0ff22f099cab2624da3e27Winson Chung            // Show the scrim if we animate into Recents without window transitions
188743d5c95f3a107639c0ff22f099cab2624da3e27Winson Chung            mNavBarScrimView.setVisibility(View.VISIBLE);
189743d5c95f3a107639c0ff22f099cab2624da3e27Winson Chung        }
190521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung
191303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        // Add the default no-recents layout
192969f586533096999f10f5587f901949791154fa2Winson Chung        if (mConfig.launchedWithNoRecentTasks) {
193303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung            mEmptyView.setVisibility(View.VISIBLE);
194969f586533096999f10f5587f901949791154fa2Winson Chung            mEmptyView.setBackgroundColor(0x80000000);
195303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        } else {
196303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung            mEmptyView.setVisibility(View.GONE);
197303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        }
198303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
199303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
200f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    /** Attempts to allocate and bind the search bar app widget */
201f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    void bindSearchBarAppWidget() {
202814086db674d8eb298541b7e601e29c5c68e2074Winson Chung        if (Constants.DebugFlags.App.EnableSearchLayout) {
203f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            SystemServicesProxy ssp = RecentsTaskLoader.getInstance().getSystemServicesProxy();
204f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
205f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            // Reset the host view and widget info
206f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            mSearchAppWidgetHostView = null;
207f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            mSearchAppWidgetInfo = null;
208f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
209f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            // Try and load the app widget id from the settings
210d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung            int appWidgetId = mConfig.searchBarAppWidgetId;
211f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            if (appWidgetId >= 0) {
212f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                mSearchAppWidgetInfo = ssp.getAppWidgetInfo(appWidgetId);
213f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                if (mSearchAppWidgetInfo == null) {
214f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                    // If there is no actual widget associated with that id, then delete it and
215f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                    // prepare to bind another app widget in its place
216f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                    ssp.unbindSearchAppWidget(mAppWidgetHost, appWidgetId);
217f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                    appWidgetId = -1;
218f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                }
21910f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                if (Console.Enabled) {
22010f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    Console.log(Constants.Log.App.SystemUIHandshake,
22110f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                            "[RecentsActivity|onCreate|settings|appWidgetId]",
22210f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                            "Id: " + appWidgetId,
22310f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                            Console.AnsiBlue);
22410f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                }
225f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            }
226f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
227f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            // If there is no id, then bind a new search app widget
228f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            if (appWidgetId < 0) {
229f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                Pair<Integer, AppWidgetProviderInfo> widgetInfo =
230f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                        ssp.bindSearchAppWidget(mAppWidgetHost);
231f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                if (widgetInfo != null) {
23210f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    if (Console.Enabled) {
23310f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                        Console.log(Constants.Log.App.SystemUIHandshake,
23410f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                                "[RecentsActivity|onCreate|searchWidget]",
23510f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                                "Id: " + widgetInfo.first + " Info: " + widgetInfo.second,
23610f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                                Console.AnsiBlue);
23710f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    }
238f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
239f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                    // Save the app widget id into the settings
240d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                    mConfig.updateSearchBarAppWidgetId(this, widgetInfo.first);
241f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                    mSearchAppWidgetInfo = widgetInfo.second;
242f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                }
243f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            }
244f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        }
245f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    }
246f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
247f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    /** Creates the search bar app widget view */
248f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    void addSearchBarAppWidgetView() {
249814086db674d8eb298541b7e601e29c5c68e2074Winson Chung        if (Constants.DebugFlags.App.EnableSearchLayout) {
250d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung            int appWidgetId = mConfig.searchBarAppWidgetId;
251f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            if (appWidgetId >= 0) {
25210f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                if (Console.Enabled) {
25310f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    Console.log(Constants.Log.App.SystemUIHandshake,
25410f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                            "[RecentsActivity|onCreate|addSearchAppWidgetView]",
25510f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                            "Id: " + appWidgetId,
25610f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                            Console.AnsiBlue);
25710f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                }
258f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                mSearchAppWidgetHostView = mAppWidgetHost.createView(this, appWidgetId,
259f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                        mSearchAppWidgetInfo);
260f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                Bundle opts = new Bundle();
261f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,
262f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                        AppWidgetProviderInfo.WIDGET_CATEGORY_RECENTS);
263f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                mSearchAppWidgetHostView.updateAppWidgetOptions(opts);
264f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                // Set the padding to 0 for this search widget
265f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                mSearchAppWidgetHostView.setPadding(0, 0, 0, 0);
266f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                mRecentsView.setSearchBar(mSearchAppWidgetHostView);
267f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            } else {
268f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung                mRecentsView.setSearchBar(null);
269f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            }
270f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        }
271f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    }
272f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
273303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Dismisses recents if we are already visible and the intent is to toggle the recents view */
27447c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung    boolean dismissRecentsIfVisible() {
27547c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        if (mVisible) {
276d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung            // If we are mid-animation into Recents, then reverse it and finish
277d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung            if (mFullScreenshotView == null ||
278d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                    !mFullScreenshotView.cancelAnimateOnEnterRecents(mFinishRunnable)) {
279d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                // If we have a focused task, then launch that task
280d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                if (!mRecentsView.launchFocusedTask()) {
281d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                    // If there are any tasks, then launch the first task
282d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                    if (!mRecentsView.launchFirstTask()) {
283d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                        // We really shouldn't hit this, but if we do, just animate out (aka. finish)
284d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                        ReferenceCountedTrigger exitTrigger = new ReferenceCountedTrigger(this,
285d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                                null, mFinishRunnable, null);
286969f586533096999f10f5587f901949791154fa2Winson Chung                        mRecentsView.startExitToHomeAnimation(
287d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                                new ViewAnimation.TaskViewExitContext(exitTrigger));
288d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                    }
2891e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung                }
290303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung            }
29147c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung            return true;
292303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        }
293303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        return false;
294303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
295303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
296303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Called with the activity is first created. */
297303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    @Override
298303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    public void onCreate(Bundle savedInstanceState) {
299303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        super.onCreate(savedInstanceState);
30010f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        if (Console.Enabled) {
30110f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung            Console.logDivider(Constants.Log.App.SystemUIHandshake);
30210f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung            Console.log(Constants.Log.App.SystemUIHandshake, "[RecentsActivity|onCreate]",
30310f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    getIntent().getAction() + " visible: " + mVisible, Console.AnsiRed);
30410f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung            Console.logTraceTime(Constants.Log.App.TimeRecentsStartup,
30510f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    Constants.Log.App.TimeRecentsStartupKey, "onCreate");
30610f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        }
307303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
308303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        // Initialize the loader and the configuration
309303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        RecentsTaskLoader.initialize(this);
310d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        mConfig = RecentsConfiguration.reinitialize(this);
311303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
312f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        // Initialize the widget host (the host id is static and does not change)
313f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        mAppWidgetHost = new RecentsAppWidgetHost(this, Constants.Values.App.AppWidgetHostId, this);
314f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
315303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        // Create the view hierarchy
316303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        mRecentsView = new RecentsView(this);
31747c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        mRecentsView.setCallbacks(this);
318303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        mRecentsView.setLayoutParams(new FrameLayout.LayoutParams(
319303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung                FrameLayout.LayoutParams.MATCH_PARENT,
320303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung                FrameLayout.LayoutParams.MATCH_PARENT));
321653f70c223f8742e2a3696641fe1d4b82bc2ca36Winson Chung        mRecentsView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
322653f70c223f8742e2a3696641fe1d4b82bc2ca36Winson Chung                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
323653f70c223f8742e2a3696641fe1d4b82bc2ca36Winson Chung                View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
324303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
325303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        // Create the empty view
326303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        LayoutInflater inflater = LayoutInflater.from(this);
327303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        mEmptyView = inflater.inflate(R.layout.recents_empty, mContainerView, false);
328521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung        mNavBarScrimView = inflater.inflate(R.layout.recents_nav_bar_scrim, mContainerView, false);
329b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung        mNavBarScrimView.setLayoutParams(new FrameLayout.LayoutParams(
330b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung                ViewGroup.LayoutParams.MATCH_PARENT,
331b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung                ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.BOTTOM));
332d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        if (Constants.DebugFlags.App.EnableScreenshotAppTransition) {
333d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung            mFullScreenshotView = new FullScreenTransitionView(this, this);
334d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung            mFullScreenshotView.setLayoutParams(new FrameLayout.LayoutParams(
335d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                    ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
336d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        }
337303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
338303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        mContainerView = new FrameLayout(this);
339303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        mContainerView.addView(mRecentsView);
340303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        mContainerView.addView(mEmptyView);
341d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        if (Constants.DebugFlags.App.EnableScreenshotAppTransition) {
342d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung            mContainerView.addView(mFullScreenshotView);
343d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        }
344521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung        mContainerView.addView(mNavBarScrimView);
345303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        setContentView(mContainerView);
346303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
347303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        // Update the recent tasks
348b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung        updateRecentsTasks(getIntent());
349f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
350d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        // Prepare the screenshot transition if necessary
351d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        if (Constants.DebugFlags.App.EnableScreenshotAppTransition) {
352d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung            mFullScreenshotView.prepareAnimateOnEnterRecents(AlternateRecentsComponent.getLastScreenshot());
353d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        }
354d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung
355f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        // Bind the search app widget when we first start up
356f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        bindSearchBarAppWidget();
357f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        // Add the search bar layout
358f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        addSearchBarAppWidgetView();
359521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung
360521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung        // Update if we are getting a configuration change
361521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung        if (savedInstanceState != null) {
362521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung            onConfigurationChange();
363521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung        }
364b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung
365b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung        // XXX: Update the shadows
366b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung        try {
367b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung            sPropertyMethod.invoke(null, "ambientShadowStrength", String.valueOf(35f));
368b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung            sPropertyMethod.invoke(null, "ambientRatio", String.valueOf(0.5f));
369b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung        } catch (IllegalAccessException e) {
370b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung            e.printStackTrace();
371b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung        } catch (InvocationTargetException e) {
372b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung            e.printStackTrace();
373b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung        }
374521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung    }
375521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung
376521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung    void onConfigurationChange() {
377521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung        // Try and start the enter animation (or restart it on configuration changed)
378969f586533096999f10f5587f901949791154fa2Winson Chung        mRecentsView.startEnterRecentsAnimation(new ViewAnimation.TaskViewEnterContext(mFullScreenshotView));
379d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        // Call our callback
380d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        onEnterAnimationTriggered();
381303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
382303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
383303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    @Override
384303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    protected void onNewIntent(Intent intent) {
385303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        super.onNewIntent(intent);
38647c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        // Reset the task launched flag if we encounter an onNewIntent() before onStop()
38747c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        mTaskLaunched = false;
38847c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung
38910f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        if (Console.Enabled) {
39010f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung            Console.logDivider(Constants.Log.App.SystemUIHandshake);
39110f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung            Console.log(Constants.Log.App.SystemUIHandshake, "[RecentsActivity|onNewIntent]",
39210f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    intent.getAction() + " visible: " + mVisible, Console.AnsiRed);
39310f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung            Console.logTraceTime(Constants.Log.App.TimeRecentsStartup,
39410f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    Constants.Log.App.TimeRecentsStartupKey, "onNewIntent");
39510f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        }
396303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
397303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        // Initialize the loader and the configuration
398303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        RecentsTaskLoader.initialize(this);
399d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        mConfig = RecentsConfiguration.reinitialize(this);
400303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
401303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        // Update the recent tasks
402b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung        updateRecentsTasks(intent);
403f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
404d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        // Prepare the screenshot transition if necessary
405d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        if (Constants.DebugFlags.App.EnableScreenshotAppTransition) {
406d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung            mFullScreenshotView.prepareAnimateOnEnterRecents(AlternateRecentsComponent.getLastScreenshot());
407d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        }
408d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung
409f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        // Don't attempt to rebind the search bar widget, but just add the search bar layout
410f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        addSearchBarAppWidgetView();
411303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
412303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
413303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    @Override
414303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    protected void onStart() {
41510f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        if (Console.Enabled) {
41610f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung            Console.log(Constants.Log.App.SystemUIHandshake, "[RecentsActivity|onStart]", "",
41710f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    Console.AnsiRed);
41810f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        }
419303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        super.onStart();
42047a3e65acc35cd3061bf3867e8b20753870fd892Winson Chung
42147a3e65acc35cd3061bf3867e8b20753870fd892Winson Chung        // Start listening for widget package changes if there is one bound
422d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        if (mConfig.searchBarAppWidgetId >= 0) {
42347a3e65acc35cd3061bf3867e8b20753870fd892Winson Chung            mAppWidgetHost.startListening();
42447a3e65acc35cd3061bf3867e8b20753870fd892Winson Chung        }
42547a3e65acc35cd3061bf3867e8b20753870fd892Winson Chung
426303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        mVisible = true;
427303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
428303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
429303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    @Override
430303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    protected void onResume() {
43110f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        if (Console.Enabled) {
43210f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung            Console.log(Constants.Log.App.SystemUIHandshake, "[RecentsActivity|onResume]", "",
43310f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    Console.AnsiRed);
43410f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        }
435303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        super.onResume();
4366736905dc0e10689f7c63f6da43b31325caf966aWinson Chung    }
4376736905dc0e10689f7c63f6da43b31325caf966aWinson Chung
4386736905dc0e10689f7c63f6da43b31325caf966aWinson Chung    @Override
4396736905dc0e10689f7c63f6da43b31325caf966aWinson Chung    public void onAttachedToWindow() {
44010f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        if (Console.Enabled) {
44110f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung            Console.log(Constants.Log.App.SystemUIHandshake,
44210f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    "[RecentsActivity|onAttachedToWindow]", "",
44310f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    Console.AnsiRed);
44410f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        }
4456736905dc0e10689f7c63f6da43b31325caf966aWinson Chung        super.onAttachedToWindow();
44647c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung
44747c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        // Register the broadcast receiver to handle messages from our service
44847c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        IntentFilter filter = new IntentFilter();
4491e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung        filter.addAction(RecentsService.ACTION_HIDE_RECENTS_ACTIVITY);
45047c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        filter.addAction(RecentsService.ACTION_TOGGLE_RECENTS_ACTIVITY);
45124cf152483c03dc446875c8d6440348174317bc5Winson Chung        filter.addAction(RecentsService.ACTION_START_ENTER_ANIMATION);
45247c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        registerReceiver(mServiceBroadcastReceiver, filter);
4536736905dc0e10689f7c63f6da43b31325caf966aWinson Chung
4546736905dc0e10689f7c63f6da43b31325caf966aWinson Chung        // Register the broadcast receiver to handle messages when the screen is turned off
4556736905dc0e10689f7c63f6da43b31325caf966aWinson Chung        filter = new IntentFilter();
4566736905dc0e10689f7c63f6da43b31325caf966aWinson Chung        filter.addAction(Intent.ACTION_SCREEN_OFF);
4576736905dc0e10689f7c63f6da43b31325caf966aWinson Chung        registerReceiver(mScreenOffReceiver, filter);
4589f49df933f01a32d04bdf92d53c943065aa8ddf7Winson Chung
4599f49df933f01a32d04bdf92d53c943065aa8ddf7Winson Chung        // Register any broadcast receivers for the task loader
4609f49df933f01a32d04bdf92d53c943065aa8ddf7Winson Chung        RecentsTaskLoader.getInstance().registerReceivers(this, mRecentsView);
461303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
462303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
463303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    @Override
4646736905dc0e10689f7c63f6da43b31325caf966aWinson Chung    public void onDetachedFromWindow() {
46510f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        if (Console.Enabled) {
46610f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung            Console.log(Constants.Log.App.SystemUIHandshake,
46710f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    "[RecentsActivity|onDetachedFromWindow]", "",
46810f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    Console.AnsiRed);
46910f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        }
4706736905dc0e10689f7c63f6da43b31325caf966aWinson Chung        super.onDetachedFromWindow();
471303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
47247c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        // Unregister any broadcast receivers we have registered
47347c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        unregisterReceiver(mServiceBroadcastReceiver);
4746736905dc0e10689f7c63f6da43b31325caf966aWinson Chung        unregisterReceiver(mScreenOffReceiver);
4759f49df933f01a32d04bdf92d53c943065aa8ddf7Winson Chung        RecentsTaskLoader.getInstance().unregisterReceivers();
4766736905dc0e10689f7c63f6da43b31325caf966aWinson Chung    }
4776736905dc0e10689f7c63f6da43b31325caf966aWinson Chung
4786736905dc0e10689f7c63f6da43b31325caf966aWinson Chung    @Override
4796736905dc0e10689f7c63f6da43b31325caf966aWinson Chung    protected void onPause() {
48010f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        if (Console.Enabled) {
48110f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung            Console.log(Constants.Log.App.SystemUIHandshake, "[RecentsActivity|onPause]", "",
48210f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    Console.AnsiRed);
48310f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        }
4846736905dc0e10689f7c63f6da43b31325caf966aWinson Chung        super.onPause();
485303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
486303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
487303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    @Override
488303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    protected void onStop() {
48910f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        if (Console.Enabled) {
49010f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung            Console.log(Constants.Log.App.SystemUIHandshake, "[RecentsActivity|onStop]", "",
49110f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    Console.AnsiRed);
49210f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        }
493303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        super.onStop();
49447c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung
49547a3e65acc35cd3061bf3867e8b20753870fd892Winson Chung        // Stop listening for widget package changes if there was one bound
496d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        if (mConfig.searchBarAppWidgetId >= 0) {
49747a3e65acc35cd3061bf3867e8b20753870fd892Winson Chung            mAppWidgetHost.stopListening();
49847a3e65acc35cd3061bf3867e8b20753870fd892Winson Chung        }
49947a3e65acc35cd3061bf3867e8b20753870fd892Winson Chung
500303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        mVisible = false;
50147c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        mTaskLaunched = false;
50247c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung    }
50347c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung
50447c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung    @Override
50547c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung    protected void onDestroy() {
50610f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        if (Console.Enabled) {
50710f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung            Console.log(Constants.Log.App.SystemUIHandshake, "[RecentsActivity|onDestroy]", "",
50810f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung                    Console.AnsiRed);
50910f8139d3b8dd7cd08a2fc688285b3b74a34f0dbWinson Chung        }
51047c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        super.onDestroy();
511303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
512303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
513303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    @Override
5144d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung    public void onTrimMemory(int level) {
5154d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung        RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
5164d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung        if (loader != null) {
5174d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung            loader.onTrimMemory(level);
5184d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung        }
5194d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung    }
5204d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung
5214d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung    @Override
5221e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung    public boolean onKeyDown(int keyCode, KeyEvent event) {
5231e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung        if (keyCode == KeyEvent.KEYCODE_TAB) {
5241e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung            // Focus the next task in the stack
5251e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung            final boolean backward = event.isShiftPressed();
5261e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung            mRecentsView.focusNextTask(!backward);
5271e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung            return true;
5281e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung        }
5291e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung
5301e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung        return super.onKeyDown(keyCode, event);
5311e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung    }
5321e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung
5331e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung    @Override
534a26fb7822ddf3511796279b847cc216bee9e7f70Winson Chung    public void onUserInteraction() {
535a26fb7822ddf3511796279b847cc216bee9e7f70Winson Chung        mRecentsView.onUserInteraction();
536a26fb7822ddf3511796279b847cc216bee9e7f70Winson Chung    }
537a26fb7822ddf3511796279b847cc216bee9e7f70Winson Chung
538a26fb7822ddf3511796279b847cc216bee9e7f70Winson Chung    @Override
539303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    public void onBackPressed() {
540d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        // If we are mid-animation into Recents, then reverse it and finish
541d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        if (mFullScreenshotView == null ||
542d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                !mFullScreenshotView.cancelAnimateOnEnterRecents(mFinishRunnable)) {
543d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung            // If we are currently filtering in any stacks, unfilter them first
544d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung            if (!mRecentsView.unfilterFilteredStacks()) {
545d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                if (mConfig.launchedFromHome) {
546d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                    // Just start the animation out of recents
547d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                    ReferenceCountedTrigger exitTrigger = new ReferenceCountedTrigger(this,
548d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                            null, mFinishRunnable, null);
549969f586533096999f10f5587f901949791154fa2Winson Chung                    mRecentsView.startExitToHomeAnimation(
550d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                            new ViewAnimation.TaskViewExitContext(exitTrigger));
551d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                } else {
552d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                    // Otherwise, try and launch the first task
553d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                    if (!mRecentsView.launchFirstTask()) {
554d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                        // If there are no tasks, then just finish recents
555d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                        ReferenceCountedTrigger exitTrigger = new ReferenceCountedTrigger(this,
556d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                                null, mFinishRunnable, null);
557969f586533096999f10f5587f901949791154fa2Winson Chung                        mRecentsView.startExitToHomeAnimation(
558d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                                new ViewAnimation.TaskViewExitContext(exitTrigger));
559d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                    }
560d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                }
56156f4692a89a1afb2fe40aec8a9b6f26936b8e9a4Winson Chung            }
562303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        }
563303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
56447c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung
565521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung    public void onEnterAnimationTriggered() {
566521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung        // Fade in the scrim
567743d5c95f3a107639c0ff22f099cab2624da3e27Winson Chung        if (mConfig.shouldAnimateNavBarScrim() && mConfig.hasNavBarScrim()) {
568521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung            mNavBarScrimView.setVisibility(View.VISIBLE);
569969f586533096999f10f5587f901949791154fa2Winson Chung            mNavBarScrimView.setTranslationY(mNavBarScrimView.getMeasuredHeight());
570969f586533096999f10f5587f901949791154fa2Winson Chung            mNavBarScrimView.animate()
571969f586533096999f10f5587f901949791154fa2Winson Chung                    .translationY(0)
572d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                    .setStartDelay(mConfig.taskBarEnterAnimDelay)
573d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                    .setDuration(mConfig.navBarScrimEnterDuration)
574969f586533096999f10f5587f901949791154fa2Winson Chung                    .setInterpolator(mConfig.quintOutInterpolator)
575969f586533096999f10f5587f901949791154fa2Winson Chung                    .start();
576969f586533096999f10f5587f901949791154fa2Winson Chung        }
577969f586533096999f10f5587f901949791154fa2Winson Chung    }
578969f586533096999f10f5587f901949791154fa2Winson Chung
579969f586533096999f10f5587f901949791154fa2Winson Chung    @Override
580969f586533096999f10f5587f901949791154fa2Winson Chung    public void onExitAnimationTriggered() {
581969f586533096999f10f5587f901949791154fa2Winson Chung        // Fade out the scrim
582969f586533096999f10f5587f901949791154fa2Winson Chung        if (mConfig.shouldAnimateNavBarScrim() && mConfig.hasNavBarScrim()) {
583969f586533096999f10f5587f901949791154fa2Winson Chung            mNavBarScrimView.animate()
584969f586533096999f10f5587f901949791154fa2Winson Chung                    .translationY(mNavBarScrimView.getMeasuredHeight())
585969f586533096999f10f5587f901949791154fa2Winson Chung                    .setStartDelay(0)
586969f586533096999f10f5587f901949791154fa2Winson Chung                    .setDuration(mConfig.taskBarExitAnimDuration)
587d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                    .setInterpolator(mConfig.fastOutSlowInInterpolator)
588521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung                    .start();
589521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung        }
590521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung    }
591521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung
592521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung    @Override
593d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung    public void onEnterAnimationComplete(boolean canceled) {
594d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        if (!canceled) {
595d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung            // Reset the full screenshot transition view
596d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung            if (Constants.DebugFlags.App.EnableScreenshotAppTransition) {
597d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung                mFullScreenshotView.reset();
598d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung            }
599d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung
600d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung            // XXX: We should clean up the screenshot in this case as well, but it needs to happen
601d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung            //      after to animate up
602d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        }
603d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        // Recycle the full screen screenshot
604d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        AlternateRecentsComponent.consumeLastScreenshot();
605d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung    }
606d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung
607d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung    @Override
608c9567c07dd4953f5c5e3821d30525e50ed8b9b29Winson Chung    public void onTaskLaunching() {
60947c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung        mTaskLaunched = true;
610521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung
6119214eff52adf56b7c9532e40b784d52f9f94b6d1Winson Chung        // Mark recents as no longer visible
6129214eff52adf56b7c9532e40b784d52f9f94b6d1Winson Chung        AlternateRecentsComponent.notifyVisibilityChanged(false);
61347c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung    }
614f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung
615f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    @Override
616f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    public void onProviderChanged(int appWidgetId, AppWidgetProviderInfo appWidgetInfo) {
617f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        SystemServicesProxy ssp = RecentsTaskLoader.getInstance().getSystemServicesProxy();
618d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung        if (appWidgetId > -1 && appWidgetId == mConfig.searchBarAppWidgetId) {
619f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            // The search provider may have changed, so just delete the old widget and bind it again
620f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            ssp.unbindSearchAppWidget(mAppWidgetHost, appWidgetId);
621d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung            mConfig.updateSearchBarAppWidgetId(this, -1);
622f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            // Load the widget again
623f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            bindSearchBarAppWidget();
624f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung            addSearchBarAppWidgetView();
625f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung        }
626f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung    }
627303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung}
628