RecentsActivity.java revision 480dd72daf927283997bdb4060091299add66832
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; 35dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chungimport android.view.ViewGroup; 368e548f7025ce930810479a8e628c325d09557fa3Winson Chungimport android.view.ViewStub; 37dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chungimport android.widget.FrameLayout; 388eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chungimport android.widget.Toast; 3947c4c69575e94635a9356e8a1faf4b56a0120452Winson Chungimport com.android.systemui.R; 40ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport com.android.systemui.recents.misc.DebugTrigger; 41ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport com.android.systemui.recents.misc.ReferenceCountedTrigger; 42ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport com.android.systemui.recents.misc.SystemServicesProxy; 43ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport com.android.systemui.recents.misc.Utilities; 44f1fbd77cf057e43926f9a0347692611386d09f40Winson Chungimport com.android.systemui.recents.model.RecentsTaskLoader; 45303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport com.android.systemui.recents.model.SpaceNode; 46dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chungimport com.android.systemui.recents.model.Task; 47303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport com.android.systemui.recents.model.TaskStack; 48dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chungimport com.android.systemui.recents.views.DebugOverlayView; 49303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport com.android.systemui.recents.views.RecentsView; 50cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chungimport com.android.systemui.recents.views.SystemBarScrimViews; 51d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chungimport com.android.systemui.recents.views.ViewAnimation; 52303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 53083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chungimport java.lang.ref.WeakReference; 54b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chungimport java.lang.reflect.InvocationTargetException; 55303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport java.util.ArrayList; 56303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 5785cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung/** 5885cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung * The main Recents activity that is started from AlternateRecentsComponent. 5985cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung */ 60f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chungpublic class RecentsActivity extends Activity implements RecentsView.RecentsViewCallbacks, 61dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks { 62d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung 6385cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung // Actions and Extras sent from AlternateRecentsComponent 64ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung final static String EXTRA_TRIGGERED_FROM_ALT_TAB = "extra_triggered_from_alt_tab"; 65ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung final static String ACTION_START_ENTER_ANIMATION = "action_start_enter_animation"; 66ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung final static String ACTION_TOGGLE_RECENTS_ACTIVITY = "action_toggle_recents_activity"; 67ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung final static String ACTION_HIDE_RECENTS_ACTIVITY = "action_hide_recents_activity"; 68ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 6985cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung RecentsConfiguration mConfig; 7085cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung boolean mVisible; 7185cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung 7285cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung // Top level views 73cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung RecentsView mRecentsView; 74cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung SystemBarScrimViews mScrimViews; 758e548f7025ce930810479a8e628c325d09557fa3Winson Chung ViewStub mEmptyViewStub; 76cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung View mEmptyView; 77dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung DebugOverlayView mDebugOverlay; 78cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung 7985cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung // Search AppWidget 80cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung RecentsAppWidgetHost mAppWidgetHost; 81cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung AppWidgetProviderInfo mSearchAppWidgetInfo; 82cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung AppWidgetHostView mSearchAppWidgetHostView; 83cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung 84cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung // Runnables to finish the Recents activity 85cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung FinishRecentsRunnable mFinishLaunchHomeRunnable; 86cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung 87d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung /** 8885cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung * A common Runnable to finish Recents either by calling finish() (with a custom animation) or 8985cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung * launching Home with some ActivityOptions. Generally we always launch home when we exit 9085cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung * Recents rather than just finishing the activity since we don't know what is behind Recents in 9185cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung * the task stack. The only case where we finish() directly is when we are cancelling the full 9285cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung * screen transition from the app. 93d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung */ 94d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung class FinishRecentsRunnable implements Runnable { 95d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung Intent mLaunchIntent; 96d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung ActivityOptions mLaunchOpts; 97d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung 98d7b2cb12ac90956843413c212769639044a0b6f2Winson Chung /** 99d7b2cb12ac90956843413c212769639044a0b6f2Winson Chung * Creates a finish runnable that starts the specified intent, using the given 100d7b2cb12ac90956843413c212769639044a0b6f2Winson Chung * ActivityOptions. 101d7b2cb12ac90956843413c212769639044a0b6f2Winson Chung */ 102d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung public FinishRecentsRunnable(Intent launchIntent, ActivityOptions opts) { 103d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung mLaunchIntent = launchIntent; 104d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung mLaunchOpts = opts; 105d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung } 106d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung 107d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung @Override 108d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung public void run() { 109d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung // Mark Recents as no longer visible 110d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung AlternateRecentsComponent.notifyVisibilityChanged(false); 1111e44934f0213caf5c434f63a69c9f05fa76e891dWinson Chung mVisible = false; 112d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung // Finish Recents 113d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung if (mLaunchIntent != null) { 114d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung if (mLaunchOpts != null) { 11585cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung startActivityAsUser(mLaunchIntent, UserHandle.CURRENT); 116d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung } else { 11785cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung startActivityAsUser(mLaunchIntent, mLaunchOpts.toBundle(), UserHandle.CURRENT); 118d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung } 119d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung } else { 120d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung finish(); 12185cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung overridePendingTransition(R.anim.recents_to_launcher_enter, 12285cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung R.anim.recents_to_launcher_exit); 123d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung } 124d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung } 125d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung } 126d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung 12785cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung /** 12885cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung * Broadcast receiver to handle messages from AlternateRecentsComponent. 12985cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung */ 1308eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung final BroadcastReceiver mServiceBroadcastReceiver = new BroadcastReceiver() { 13147c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung @Override 13247c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung public void onReceive(Context context, Intent intent) { 13347c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung String action = intent.getAction(); 134ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung if (action.equals(ACTION_HIDE_RECENTS_ACTIVITY)) { 135ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung if (intent.getBooleanExtra(EXTRA_TRIGGERED_FROM_ALT_TAB, false)) { 13685cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung // If we are hiding from releasing Alt-Tab, dismiss Recents to the focused app 13785cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung dismissRecentsToFocusedTaskOrHome(false); 1386cb485fd2e2f8ace05e1ff281ab0fc824d3652cbWinson Chung } else { 13985cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung // Otherwise, dismiss Recents to Home 14085cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung dismissRecentsToHome(true); 1416cb485fd2e2f8ace05e1ff281ab0fc824d3652cbWinson Chung } 142ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } else if (action.equals(ACTION_TOGGLE_RECENTS_ACTIVITY)) { 14385cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung // If we are toggling Recents, then first unfilter any filtered stacks first 14485cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung dismissRecentsToFocusedTaskOrHome(true); 145ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } else if (action.equals(ACTION_START_ENTER_ANIMATION)) { 146521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung // Try and start the enter animation (or restart it on configuration changed) 147c6011deffc80eaee6dfb1c7975e050bc71e5ea96Winson Chung ReferenceCountedTrigger t = new ReferenceCountedTrigger(context, null, null, null); 148dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung mRecentsView.startEnterRecentsAnimation(new ViewAnimation.TaskViewEnterContext(t)); 149d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung onEnterAnimationTriggered(); 15047c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung } 15147c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung } 15247c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung }; 153303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 15485cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung /** 15585cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung * Broadcast receiver to handle messages from the system 15685cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung */ 15731d66c60d8f518ce3a70972db348d797db92f42cWinson Chung final BroadcastReceiver mSystemBroadcastReceiver = new BroadcastReceiver() { 1586736905dc0e10689f7c63f6da43b31325caf966aWinson Chung @Override 1596736905dc0e10689f7c63f6da43b31325caf966aWinson Chung public void onReceive(Context context, Intent intent) { 16031d66c60d8f518ce3a70972db348d797db92f42cWinson Chung String action = intent.getAction(); 16185cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung if (action.equals(Intent.ACTION_SCREEN_OFF)) { 16285cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung // When the screen turns off, dismiss Recents to Home 16385cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung dismissRecentsToHome(false); 16431d66c60d8f518ce3a70972db348d797db92f42cWinson Chung } else if (action.equals(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED)) { 16585cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung // When the search activity changes, update the Search widget 16631d66c60d8f518ce3a70972db348d797db92f42cWinson Chung refreshSearchWidget(); 16731d66c60d8f518ce3a70972db348d797db92f42cWinson Chung } 168d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung } 169d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung }; 170d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung 17185cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung /** 17285cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung * A custom debug trigger to listen for a debug key chord. 17385cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung */ 1748eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung final DebugTrigger mDebugTrigger = new DebugTrigger(new Runnable() { 1758eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung @Override 1768eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung public void run() { 1778eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung onDebugModeTriggered(); 1788eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung } 1798eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung }); 1808eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung 181303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Updates the set of recent tasks */ 182b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung void updateRecentsTasks(Intent launchIntent) { 183dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung // Load all the tasks 184969f586533096999f10f5587f901949791154fa2Winson Chung RecentsTaskLoader loader = RecentsTaskLoader.getInstance(); 185969f586533096999f10f5587f901949791154fa2Winson Chung SpaceNode root = loader.reload(this, Constants.Values.RecentsTaskLoader.PreloadFirstTasksCount); 186969f586533096999f10f5587f901949791154fa2Winson Chung ArrayList<TaskStack> stacks = root.getStacks(); 187969f586533096999f10f5587f901949791154fa2Winson Chung if (!stacks.isEmpty()) { 188dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung mRecentsView.setTaskStacks(root.getStacks()); 189969f586533096999f10f5587f901949791154fa2Winson Chung } 190969f586533096999f10f5587f901949791154fa2Winson Chung 191b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung // Update the configuration based on the launch intent 192d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung mConfig.launchedFromHome = launchIntent.getBooleanExtra( 193d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung AlternateRecentsComponent.EXTRA_FROM_HOME, false); 194d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung mConfig.launchedFromAppWithThumbnail = launchIntent.getBooleanExtra( 195d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung AlternateRecentsComponent.EXTRA_FROM_APP_THUMBNAIL, false); 196d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung mConfig.launchedFromAppWithScreenshot = launchIntent.getBooleanExtra( 197d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung AlternateRecentsComponent.EXTRA_FROM_APP_FULL_SCREENSHOT, false); 198d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung mConfig.launchedWithAltTab = launchIntent.getBooleanExtra( 199d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung AlternateRecentsComponent.EXTRA_TRIGGERED_FROM_ALT_TAB, false); 200969f586533096999f10f5587f901949791154fa2Winson Chung mConfig.launchedWithNoRecentTasks = !root.hasTasks(); 2016057c91563402f900dfc7714a46e952d86172e2fWinson Chung mConfig.launchedToTaskId = launchIntent.getIntExtra( 2026057c91563402f900dfc7714a46e952d86172e2fWinson Chung AlternateRecentsComponent.EXTRA_TRIGGERED_FROM_TASK_ID, -1); 203303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 204dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung // Mark the task that is the launch target 205dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung int taskStackCount = stacks.size(); 206dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung if (mConfig.launchedToTaskId != -1) { 207dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung for (int i = 0; i < taskStackCount; i++) { 208dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung TaskStack stack = stacks.get(i); 209dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung ArrayList<Task> tasks = stack.getTasks(); 210dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung int taskCount = tasks.size(); 211dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung for (int j = 0; j < taskCount; j++) { 212dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung Task t = tasks.get(j); 213dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung if (t.key.id == mConfig.launchedToTaskId) { 214dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung t.isLaunchTarget = true; 215dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung break; 216dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung } 217dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung } 218dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung } 219dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung } 220dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung 22185cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung // Update the top level view's visibilities 222969f586533096999f10f5587f901949791154fa2Winson Chung if (mConfig.launchedWithNoRecentTasks) { 22385cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung if (mEmptyView == null) { 22485cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung mEmptyView = mEmptyViewStub.inflate(); 22585cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung } 226303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mEmptyView.setVisibility(View.VISIBLE); 227772b6b12a323b7999d8d3f335c199e6eb4e621e2Winson Chung mRecentsView.setSearchBarVisibility(View.GONE); 228303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } else { 22985cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung if (mEmptyView != null) { 23085cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung mEmptyView.setVisibility(View.GONE); 23185cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung } 232772b6b12a323b7999d8d3f335c199e6eb4e621e2Winson Chung if (mRecentsView.hasSearchBar()) { 233772b6b12a323b7999d8d3f335c199e6eb4e621e2Winson Chung mRecentsView.setSearchBarVisibility(View.VISIBLE); 234772b6b12a323b7999d8d3f335c199e6eb4e621e2Winson Chung } else { 235772b6b12a323b7999d8d3f335c199e6eb4e621e2Winson Chung addSearchBarAppWidgetView(); 236772b6b12a323b7999d8d3f335c199e6eb4e621e2Winson Chung } 237303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 2387aceb9a07fd3883c8f301ba93726d55494b0446eWinson Chung 23985cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung // Animate the SystemUI scrims into view 2407aceb9a07fd3883c8f301ba93726d55494b0446eWinson Chung mScrimViews.prepareEnterRecentsAnimation(); 241303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 242303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 243f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung /** Attempts to allocate and bind the search bar app widget */ 244f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung void bindSearchBarAppWidget() { 245814086db674d8eb298541b7e601e29c5c68e2074Winson Chung if (Constants.DebugFlags.App.EnableSearchLayout) { 246f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung SystemServicesProxy ssp = RecentsTaskLoader.getInstance().getSystemServicesProxy(); 247f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung 248f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung // Reset the host view and widget info 249f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung mSearchAppWidgetHostView = null; 250f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung mSearchAppWidgetInfo = null; 251f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung 252f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung // Try and load the app widget id from the settings 253d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung int appWidgetId = mConfig.searchBarAppWidgetId; 254f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung if (appWidgetId >= 0) { 255f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung mSearchAppWidgetInfo = ssp.getAppWidgetInfo(appWidgetId); 256f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung if (mSearchAppWidgetInfo == null) { 257f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung // If there is no actual widget associated with that id, then delete it and 258f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung // prepare to bind another app widget in its place 259f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung ssp.unbindSearchAppWidget(mAppWidgetHost, appWidgetId); 260f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung appWidgetId = -1; 261f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung } 262f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung } 263f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung 264f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung // If there is no id, then bind a new search app widget 265f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung if (appWidgetId < 0) { 266f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung Pair<Integer, AppWidgetProviderInfo> widgetInfo = 267f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung ssp.bindSearchAppWidget(mAppWidgetHost); 268f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung if (widgetInfo != null) { 269f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung // Save the app widget id into the settings 270d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung mConfig.updateSearchBarAppWidgetId(this, widgetInfo.first); 271f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung mSearchAppWidgetInfo = widgetInfo.second; 272f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung } 273f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung } 274f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung } 275f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung } 276f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung 277f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung /** Creates the search bar app widget view */ 278f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung void addSearchBarAppWidgetView() { 279814086db674d8eb298541b7e601e29c5c68e2074Winson Chung if (Constants.DebugFlags.App.EnableSearchLayout) { 280d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung int appWidgetId = mConfig.searchBarAppWidgetId; 281f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung if (appWidgetId >= 0) { 282f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung mSearchAppWidgetHostView = mAppWidgetHost.createView(this, appWidgetId, 283f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung mSearchAppWidgetInfo); 284f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung Bundle opts = new Bundle(); 285f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY, 286f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung AppWidgetProviderInfo.WIDGET_CATEGORY_RECENTS); 287f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung mSearchAppWidgetHostView.updateAppWidgetOptions(opts); 288f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung // Set the padding to 0 for this search widget 289f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung mSearchAppWidgetHostView.setPadding(0, 0, 0, 0); 290f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung mRecentsView.setSearchBar(mSearchAppWidgetHostView); 291f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung } else { 292f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung mRecentsView.setSearchBar(null); 293f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung } 294f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung } 295f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung } 296f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung 297303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Dismisses recents if we are already visible and the intent is to toggle the recents view */ 29885cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung boolean dismissRecentsToFocusedTaskOrHome(boolean checkFilteredStackState) { 29947c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung if (mVisible) { 30085cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung // If we currently have filtered stacks, then unfilter those first 30185cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung if (checkFilteredStackState && 30285cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung mRecentsView.unfilterFilteredStacks()) return true; 30385cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung // If we have a focused Task, launch that Task now 30485cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung if (mRecentsView.launchFocusedTask()) return true; 30585cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung // If we launched from Home, then return to Home 30685cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung if (mConfig.launchedFromHome) { 30785cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung dismissRecentsToHomeRaw(true); 30885cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung return true; 309303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 310dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung // Otherwise, try and return to the Task that Recents was launched from 311dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung if (mRecentsView.launchPreviousTask()) return true; 31285cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung // If none of the other cases apply, then just go Home 31385cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung dismissRecentsToHomeRaw(true); 31485cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung return true; 31585cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung } 31685cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung return false; 31785cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung } 31885cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung 31985cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung /** Dismisses Recents directly to Home. */ 32085cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung void dismissRecentsToHomeRaw(boolean animated) { 32185cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung if (animated) { 32285cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung ReferenceCountedTrigger exitTrigger = new ReferenceCountedTrigger(this, 32385cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung null, mFinishLaunchHomeRunnable, null); 32485cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung mRecentsView.startExitToHomeAnimation( 32585cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung new ViewAnimation.TaskViewExitContext(exitTrigger)); 32685cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung } else { 32785cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung mFinishLaunchHomeRunnable.run(); 32885cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung } 32985cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung } 33085cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung 33185cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung /** Dismisses Recents directly to Home if we currently aren't transitioning. */ 33285cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung boolean dismissRecentsToHome(boolean animated) { 33385cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung if (mVisible) { 33485cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung // Return to Home 33585cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung dismissRecentsToHomeRaw(animated); 33647c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung return true; 337303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 338303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return false; 339303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 340303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 341303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Called with the activity is first created. */ 342303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung @Override 343303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public void onCreate(Bundle savedInstanceState) { 344303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung super.onCreate(savedInstanceState); 345303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 346303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung // Initialize the loader and the configuration 347303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung RecentsTaskLoader.initialize(this); 34856e09b42a0f1670970872bef611a8036904ad6bfJason Monk mConfig = RecentsConfiguration.reinitialize(this, 34956e09b42a0f1670970872bef611a8036904ad6bfJason Monk RecentsTaskLoader.getInstance().getSystemServicesProxy()); 350303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 351d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung // Create the home intent runnable 352d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung Intent homeIntent = new Intent(Intent.ACTION_MAIN, null); 353d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung homeIntent.addCategory(Intent.CATEGORY_HOME); 354d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung homeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | 355d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 356d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung mFinishLaunchHomeRunnable = new FinishRecentsRunnable(homeIntent, 357d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung ActivityOptions.makeCustomAnimation(this, R.anim.recents_to_launcher_enter, 358d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung R.anim.recents_to_launcher_exit)); 359d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung 360f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung // Initialize the widget host (the host id is static and does not change) 361d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung mAppWidgetHost = new RecentsAppWidgetHost(this, Constants.Values.App.AppWidgetHostId); 362f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung 3638e548f7025ce930810479a8e628c325d09557fa3Winson Chung // Set the Recents layout 3648e548f7025ce930810479a8e628c325d09557fa3Winson Chung setContentView(R.layout.recents); 3658e548f7025ce930810479a8e628c325d09557fa3Winson Chung mRecentsView = (RecentsView) findViewById(R.id.recents_view); 36647c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung mRecentsView.setCallbacks(this); 367653f70c223f8742e2a3696641fe1d4b82bc2ca36Winson Chung mRecentsView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | 368653f70c223f8742e2a3696641fe1d4b82bc2ca36Winson Chung View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | 369653f70c223f8742e2a3696641fe1d4b82bc2ca36Winson Chung View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); 3708e548f7025ce930810479a8e628c325d09557fa3Winson Chung mEmptyViewStub = (ViewStub) findViewById(R.id.empty_view_stub); 3718e548f7025ce930810479a8e628c325d09557fa3Winson Chung mScrimViews = new SystemBarScrimViews(this, mConfig); 372dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung inflateDebugOverlay(); 373303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 374f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung // Bind the search app widget when we first start up 375f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung bindSearchBarAppWidget(); 376772b6b12a323b7999d8d3f335c199e6eb4e621e2Winson Chung // Update the recent tasks 377772b6b12a323b7999d8d3f335c199e6eb4e621e2Winson Chung updateRecentsTasks(getIntent()); 378521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung 37931d66c60d8f518ce3a70972db348d797db92f42cWinson Chung // Register the broadcast receiver to handle messages when the screen is turned off 38031d66c60d8f518ce3a70972db348d797db92f42cWinson Chung IntentFilter filter = new IntentFilter(); 38131d66c60d8f518ce3a70972db348d797db92f42cWinson Chung filter.addAction(Intent.ACTION_SCREEN_OFF); 38231d66c60d8f518ce3a70972db348d797db92f42cWinson Chung filter.addAction(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED); 38331d66c60d8f518ce3a70972db348d797db92f42cWinson Chung registerReceiver(mSystemBroadcastReceiver, filter); 38431d66c60d8f518ce3a70972db348d797db92f42cWinson Chung 38531d66c60d8f518ce3a70972db348d797db92f42cWinson Chung // Register any broadcast receivers for the task loader 38631d66c60d8f518ce3a70972db348d797db92f42cWinson Chung RecentsTaskLoader.getInstance().registerReceivers(this, mRecentsView); 38731d66c60d8f518ce3a70972db348d797db92f42cWinson Chung 388cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung // Private API calls to make the shadows look better 389b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung try { 390cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung Utilities.setShadowProperty("ambientShadowStrength", String.valueOf(35f)); 391cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung Utilities.setShadowProperty("ambientRatio", String.valueOf(0.5f)); 392b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung } catch (IllegalAccessException e) { 393b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung e.printStackTrace(); 394b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung } catch (InvocationTargetException e) { 395b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung e.printStackTrace(); 396b13c46e8b78272c4398068eed41f49ee4d403bccWinson Chung } 3977aceb9a07fd3883c8f301ba93726d55494b0446eWinson Chung 3986057c91563402f900dfc7714a46e952d86172e2fWinson Chung // Update if we are getting a configuration change 3996057c91563402f900dfc7714a46e952d86172e2fWinson Chung if (savedInstanceState != null) { 4006057c91563402f900dfc7714a46e952d86172e2fWinson Chung mConfig.updateOnConfigurationChange(); 4016057c91563402f900dfc7714a46e952d86172e2fWinson Chung onConfigurationChange(); 4026057c91563402f900dfc7714a46e952d86172e2fWinson Chung } 403521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung } 404521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung 405dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung /** Inflates the debug overlay if debug mode is enabled. */ 406dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung void inflateDebugOverlay() { 407dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung if (mConfig.debugModeEnabled && mDebugOverlay == null) { 408dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung ViewGroup parent = (ViewGroup) findViewById(android.R.id.content).getRootView(); 409dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung mDebugOverlay = new DebugOverlayView(this); 410dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams( 411dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung ViewGroup.LayoutParams.MATCH_PARENT, 412dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung ViewGroup.LayoutParams.MATCH_PARENT); 413dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung parent.addView(mDebugOverlay, lp); 414dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung mRecentsView.setDebugOverlay(mDebugOverlay); 415dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung } 416dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung } 417dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung 418521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung void onConfigurationChange() { 41985cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung // Update RecentsConfiguration 42056e09b42a0f1670970872bef611a8036904ad6bfJason Monk mConfig = RecentsConfiguration.reinitialize(this, 42156e09b42a0f1670970872bef611a8036904ad6bfJason Monk RecentsTaskLoader.getInstance().getSystemServicesProxy()); 42285cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung 423521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung // Try and start the enter animation (or restart it on configuration changed) 424c6011deffc80eaee6dfb1c7975e050bc71e5ea96Winson Chung ReferenceCountedTrigger t = new ReferenceCountedTrigger(this, null, null, null); 425dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung mRecentsView.startEnterRecentsAnimation(new ViewAnimation.TaskViewEnterContext(t)); 426d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung onEnterAnimationTriggered(); 427303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 428303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 429303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung @Override 430303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung protected void onNewIntent(Intent intent) { 431303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung super.onNewIntent(intent); 4326057c91563402f900dfc7714a46e952d86172e2fWinson Chung setIntent(intent); 43347c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung 434480dd72daf927283997bdb4060091299add66832Winson Chung // Reinitialize the configuration 435480dd72daf927283997bdb4060091299add66832Winson Chung RecentsConfiguration.reinitialize(this, RecentsTaskLoader.getInstance().getSystemServicesProxy()); 436480dd72daf927283997bdb4060091299add66832Winson Chung 437dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung // Clear any debug rects 438dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung if (mDebugOverlay != null) { 439dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung mDebugOverlay.clear(); 440dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung } 441dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung 442303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung // Update the recent tasks 443b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung updateRecentsTasks(intent); 444303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 445303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 446303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung @Override 447303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung protected void onStart() { 448303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung super.onStart(); 44947a3e65acc35cd3061bf3867e8b20753870fd892Winson Chung 45031d66c60d8f518ce3a70972db348d797db92f42cWinson Chung // Register the broadcast receiver to handle messages from our service 45131d66c60d8f518ce3a70972db348d797db92f42cWinson Chung IntentFilter filter = new IntentFilter(); 452ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung filter.addAction(ACTION_HIDE_RECENTS_ACTIVITY); 453ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung filter.addAction(ACTION_TOGGLE_RECENTS_ACTIVITY); 454ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung filter.addAction(ACTION_START_ENTER_ANIMATION); 45531d66c60d8f518ce3a70972db348d797db92f42cWinson Chung registerReceiver(mServiceBroadcastReceiver, filter); 456303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 457303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 458303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung @Override 459303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung protected void onResume() { 460303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung super.onResume(); 461083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung 462083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung // Start listening for widget package changes if there is one bound, post it since we don't 463083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung // want it stalling the startup 464083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung if (mConfig.searchBarAppWidgetId >= 0) { 465083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung final WeakReference<RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks> callback = 466083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung new WeakReference<RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks>(this); 467083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung mRecentsView.postDelayed(new Runnable() { 468083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung @Override 469083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung public void run() { 470083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks cb = callback.get(); 471083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung if (cb != null) { 472083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung mAppWidgetHost.startListening(cb); 473083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung } 474083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung } 475083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung }, 1); 476083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung } 47793748a11cba1b44edbc2e888c997533461355594Winson Chung 47885cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung // Mark Recents as visible 47993748a11cba1b44edbc2e888c997533461355594Winson Chung mVisible = true; 4806736905dc0e10689f7c63f6da43b31325caf966aWinson Chung } 4816736905dc0e10689f7c63f6da43b31325caf966aWinson Chung 4826736905dc0e10689f7c63f6da43b31325caf966aWinson Chung @Override 483303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung protected void onStop() { 484303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung super.onStop(); 48547c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung 48631d66c60d8f518ce3a70972db348d797db92f42cWinson Chung // Unregister the RecentsService receiver 48731d66c60d8f518ce3a70972db348d797db92f42cWinson Chung unregisterReceiver(mServiceBroadcastReceiver); 48831d66c60d8f518ce3a70972db348d797db92f42cWinson Chung 48931d66c60d8f518ce3a70972db348d797db92f42cWinson Chung // Stop listening for widget package changes if there was one bound 49085cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung if (mAppWidgetHost.isListening()) { 49131d66c60d8f518ce3a70972db348d797db92f42cWinson Chung mAppWidgetHost.stopListening(); 49231d66c60d8f518ce3a70972db348d797db92f42cWinson Chung } 49347c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung } 49447c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung 49547c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung @Override 49647c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung protected void onDestroy() { 49747c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung super.onDestroy(); 49831d66c60d8f518ce3a70972db348d797db92f42cWinson Chung 49985cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung // Unregister the system broadcast receivers 50031d66c60d8f518ce3a70972db348d797db92f42cWinson Chung unregisterReceiver(mSystemBroadcastReceiver); 50131d66c60d8f518ce3a70972db348d797db92f42cWinson Chung RecentsTaskLoader.getInstance().unregisterReceivers(); 502303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 503303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 504303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung @Override 5054d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung public void onTrimMemory(int level) { 5064d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung RecentsTaskLoader loader = RecentsTaskLoader.getInstance(); 5074d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung if (loader != null) { 5084d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung loader.onTrimMemory(level); 5094d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung } 5104d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung } 5114d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung 5124d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung @Override 5131e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung public boolean onKeyDown(int keyCode, KeyEvent event) { 5141e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung if (keyCode == KeyEvent.KEYCODE_TAB) { 5151e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung // Focus the next task in the stack 5161e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung final boolean backward = event.isShiftPressed(); 5171e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung mRecentsView.focusNextTask(!backward); 5181e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung return true; 519c6011deffc80eaee6dfb1c7975e050bc71e5ea96Winson Chung } else if (keyCode == KeyEvent.KEYCODE_DPAD_UP) { 520c6011deffc80eaee6dfb1c7975e050bc71e5ea96Winson Chung mRecentsView.focusNextTask(true); 521c6011deffc80eaee6dfb1c7975e050bc71e5ea96Winson Chung return true; 522c6011deffc80eaee6dfb1c7975e050bc71e5ea96Winson Chung } else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) { 523c6011deffc80eaee6dfb1c7975e050bc71e5ea96Winson Chung mRecentsView.focusNextTask(false); 524c6011deffc80eaee6dfb1c7975e050bc71e5ea96Winson Chung return true; 5251e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung } 5268eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung // Pass through the debug trigger 5278eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung mDebugTrigger.onKeyEvent(keyCode); 5281e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung return super.onKeyDown(keyCode, event); 5291e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung } 5301e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung 5311e8d71b605b4872e93200706a80a88a3ff25498cWinson Chung @Override 532a26fb7822ddf3511796279b847cc216bee9e7f70Winson Chung public void onUserInteraction() { 533a26fb7822ddf3511796279b847cc216bee9e7f70Winson Chung mRecentsView.onUserInteraction(); 534a26fb7822ddf3511796279b847cc216bee9e7f70Winson Chung } 535a26fb7822ddf3511796279b847cc216bee9e7f70Winson Chung 536a26fb7822ddf3511796279b847cc216bee9e7f70Winson Chung @Override 537303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public void onBackPressed() { 53804d0f756782e697a171aebbb35ae86c86b839a27Winson Chung // Test mode where back does not do anything 53904d0f756782e697a171aebbb35ae86c86b839a27Winson Chung if (mConfig.debugModeEnabled) return; 54004d0f756782e697a171aebbb35ae86c86b839a27Winson Chung 54185cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung // Dismiss Recents to the focused Task or Home 54285cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung dismissRecentsToFocusedTaskOrHome(true); 543303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 54447c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung 5458eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung /** Called when debug mode is triggered */ 5468eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung public void onDebugModeTriggered() { 547dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung 5488eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung if (mConfig.developerOptionsEnabled) { 5498eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung SharedPreferences settings = getSharedPreferences(getPackageName(), 0); 5508eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung if (settings.getBoolean(Constants.Values.App.Key_DebugModeEnabled, false)) { 5518eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung // Disable the debug mode 5528eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung settings.edit().remove(Constants.Values.App.Key_DebugModeEnabled).apply(); 553dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung mConfig.debugModeEnabled = false; 554dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung inflateDebugOverlay(); 555dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung mDebugOverlay.disable(); 5568eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung } else { 5578eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung // Enable the debug mode 5588eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung settings.edit().putBoolean(Constants.Values.App.Key_DebugModeEnabled, true).apply(); 559dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung mConfig.debugModeEnabled = true; 560dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung inflateDebugOverlay(); 561dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung mDebugOverlay.enable(); 5628eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung } 563dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung Toast.makeText(this, "Debug mode (" + Constants.Values.App.DebugModeVersion + ") " + 564dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung (mConfig.debugModeEnabled ? "Enabled" : "Disabled") + ", please restart Recents now", 565dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung Toast.LENGTH_SHORT).show(); 5668eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung } 5678eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung } 5688eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung 5698eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung /** Called when the enter recents animation is triggered. */ 570521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung public void onEnterAnimationTriggered() { 57185cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung // Animate the SystemUI scrim views 572cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung mScrimViews.startEnterRecentsAnimation(); 573969f586533096999f10f5587f901949791154fa2Winson Chung } 574969f586533096999f10f5587f901949791154fa2Winson Chung 575d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung /**** RecentsView.RecentsViewCallbacks Implementation ****/ 576d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung 577d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung @Override 578cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung public void onExitToHomeAnimationTriggered() { 57985cfec811e35025dbde54f4dc09fe0e1337c36b8Winson Chung // Animate the SystemUI scrim views out 580cdbbb7e33033d7ae368aa5b7007ec2b20ebdaff1Winson Chung mScrimViews.startExitRecentsAnimation(); 581d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung } 582d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung 583d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung @Override 5847aceb9a07fd3883c8f301ba93726d55494b0446eWinson Chung public void onTaskViewClicked() { 5859214eff52adf56b7c9532e40b784d52f9f94b6d1Winson Chung // Mark recents as no longer visible 5869214eff52adf56b7c9532e40b784d52f9f94b6d1Winson Chung AlternateRecentsComponent.notifyVisibilityChanged(false); 5871e44934f0213caf5c434f63a69c9f05fa76e891dWinson Chung mVisible = false; 58847c4c69575e94635a9356e8a1faf4b56a0120452Winson Chung } 589f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung 590d7b2cb12ac90956843413c212769639044a0b6f2Winson Chung @Override 5917aceb9a07fd3883c8f301ba93726d55494b0446eWinson Chung public void onAllTaskViewsDismissed() { 592d7b2cb12ac90956843413c212769639044a0b6f2Winson Chung mFinishLaunchHomeRunnable.run(); 593d7b2cb12ac90956843413c212769639044a0b6f2Winson Chung } 594d7b2cb12ac90956843413c212769639044a0b6f2Winson Chung 595d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung /**** RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks Implementation ****/ 596d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung 597f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung @Override 598d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung public void refreshSearchWidget() { 599d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung bindSearchBarAppWidget(); 600d543c1bea4d227470f5b6d6535b70e5090064c9aWinson Chung addSearchBarAppWidgetView(); 601f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung } 602303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung} 603