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