blob: d7777d56933703ac5b81ace3b4a0d82295503bc8 [file] [log] [blame]
Winson Chung303e1ff2014-03-07 15:06:19 -08001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
Peter Schillerb124d562015-12-11 21:31:17 -08008 * http://www.apache.org/licenses/LICENSE-2.0
Winson Chung303e1ff2014-03-07 15:06:19 -08009 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.systemui.recents;
18
19import android.app.Activity;
Winson Chungd543c1b2014-06-23 15:06:45 -070020import android.app.ActivityOptions;
Winson2536c7e2015-10-01 15:49:31 -070021import android.app.TaskStackBuilder;
Winson Chung47c4c692014-03-17 10:17:11 -070022import android.content.BroadcastReceiver;
23import android.content.Context;
Winson Chung303e1ff2014-03-07 15:06:19 -080024import android.content.Intent;
Winson Chung47c4c692014-03-17 10:17:11 -070025import android.content.IntentFilter;
Winsona1809852016-03-15 11:41:37 -070026import android.content.res.Configuration;
Winson2536c7e2015-10-01 15:49:31 -070027import android.net.Uri;
Winson Chung303e1ff2014-03-07 15:06:19 -080028import android.os.Bundle;
Winson Chung15a2ba82014-11-18 11:19:24 -080029import android.os.SystemClock;
Winson Chungd543c1b2014-06-23 15:06:45 -070030import android.os.UserHandle;
Winson2536c7e2015-10-01 15:49:31 -070031import android.provider.Settings;
Winson1b585612015-11-06 09:16:26 -080032import android.util.Log;
Winson Chung1e8d71b2014-05-16 17:05:22 -070033import android.view.KeyEvent;
Winson Chung303e1ff2014-03-07 15:06:19 -080034import android.view.View;
Filip Gruszczynski14b4e572015-11-03 15:53:55 -080035import android.view.ViewTreeObserver;
Filip Gruszczynski1a4dfe52015-11-15 10:58:57 -080036import android.view.WindowManager;
Jorim Jaggic69bd222016-03-15 14:38:37 +010037import android.view.WindowManager.LayoutParams;
Chris Wrenf6e9228b2016-01-26 18:04:35 -050038
Winson Chung5c9f4b92015-06-25 16:16:46 -070039import com.android.internal.logging.MetricsLogger;
Chris Wrenf6e9228b2016-01-26 18:04:35 -050040import com.android.internal.logging.MetricsProto.MetricsEvent;
Winson Chung47c4c692014-03-17 10:17:11 -070041import com.android.systemui.R;
Winsonb78bb4f2015-09-24 17:22:57 -070042import com.android.systemui.recents.events.EventBus;
Winson13d30662015-11-06 15:30:29 -080043import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent;
Winsone693aaf2016-03-01 12:05:59 -080044import com.android.systemui.recents.events.activity.ConfigurationChangedEvent;
Winsonb1e71d02015-11-23 12:40:23 -080045import com.android.systemui.recents.events.activity.DebugFlagsChangedEvent;
Winsonef064132016-01-05 12:11:31 -080046import com.android.systemui.recents.events.activity.DismissRecentsToHomeAnimationStarted;
Jorim Jaggi192086e2016-03-11 17:17:03 +010047import com.android.systemui.recents.events.activity.DockedFirstAnimationFrameEvent;
Winson3fb67562015-11-11 10:39:03 -080048import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationCompletedEvent;
Winson1b585612015-11-06 09:16:26 -080049import com.android.systemui.recents.events.activity.EnterRecentsWindowLastAnimationFrameEvent;
Winsonef064132016-01-05 12:11:31 -080050import com.android.systemui.recents.events.activity.ExitRecentsWindowFirstAnimationFrameEvent;
Winson412e1802015-10-20 16:57:57 -070051import com.android.systemui.recents.events.activity.HideRecentsEvent;
Winson0d14d4d2015-10-26 17:05:04 -070052import com.android.systemui.recents.events.activity.IterateRecentsEvent;
Winson83c1b072015-11-09 10:48:04 -080053import com.android.systemui.recents.events.activity.LaunchTaskFailedEvent;
54import com.android.systemui.recents.events.activity.LaunchTaskSucceededEvent;
Winson88737542016-02-17 13:27:33 -080055import com.android.systemui.recents.events.activity.MultiWindowStateChangedEvent;
Winson412e1802015-10-20 16:57:57 -070056import com.android.systemui.recents.events.activity.ToggleRecentsEvent;
Winson190fe3bf2015-10-20 14:57:24 -070057import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
58import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
Winson397ae742015-11-20 11:27:33 -080059import com.android.systemui.recents.events.ui.AllTaskViewsDismissedEvent;
Winsonef064132016-01-05 12:11:31 -080060import com.android.systemui.recents.events.ui.DeleteTaskDataEvent;
Jorim Jaggi11cc01d2016-01-22 19:39:23 -080061import com.android.systemui.recents.events.ui.RecentsDrawnEvent;
Winson2536c7e2015-10-01 15:49:31 -070062import com.android.systemui.recents.events.ui.ShowApplicationInfoEvent;
Winsone5f1faa2015-11-20 12:26:23 -080063import com.android.systemui.recents.events.ui.StackViewScrolledEvent;
Winsonb1e71d02015-11-23 12:40:23 -080064import com.android.systemui.recents.events.ui.UpdateFreeformTaskViewVisibilityEvent;
Winsone7f138c2015-10-22 16:15:21 -070065import com.android.systemui.recents.events.ui.UserInteractionEvent;
Winson0d14d4d2015-10-26 17:05:04 -070066import com.android.systemui.recents.events.ui.focus.DismissFocusedTaskViewEvent;
67import com.android.systemui.recents.events.ui.focus.FocusNextTaskViewEvent;
68import com.android.systemui.recents.events.ui.focus.FocusPreviousTaskViewEvent;
Winson0d14d4d2015-10-26 17:05:04 -070069import com.android.systemui.recents.misc.DozeTrigger;
Winson Chungffa2ec62014-07-03 15:54:42 -070070import com.android.systemui.recents.misc.SystemServicesProxy;
Winsone6c90732015-09-24 16:06:29 -070071import com.android.systemui.recents.model.RecentsPackageMonitor;
Winson Chunga91c2932014-11-07 15:02:38 -080072import com.android.systemui.recents.model.RecentsTaskLoadPlan;
Winson Chungf1fbd772014-06-24 18:06:58 -070073import com.android.systemui.recents.model.RecentsTaskLoader;
Winson Chungdcfa7972014-07-22 12:27:13 -070074import com.android.systemui.recents.model.Task;
Winson Chung303e1ff2014-03-07 15:06:19 -080075import com.android.systemui.recents.model.TaskStack;
Winsona1ededd2016-03-25 12:23:12 -070076import com.android.systemui.recents.views.AnimationProps;
Winson Chung303e1ff2014-03-07 15:06:19 -080077import com.android.systemui.recents.views.RecentsView;
Winson Chungcdbbb7e2014-06-24 12:11:49 -070078import com.android.systemui.recents.views.SystemBarScrimViews;
Winsond8b1d632016-01-04 17:51:18 -080079import com.android.systemui.statusbar.BaseStatusBar;
Winson Chung303e1ff2014-03-07 15:06:19 -080080
Winson Chung85cfec82014-07-14 14:16:04 -070081/**
82 * The main Recents activity that is started from AlternateRecentsComponent.
83 */
Winson397ae742015-11-20 11:27:33 -080084public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreDrawListener {
Winson Chungd42a6cf2014-06-03 16:24:04 -070085
Winson0d14d4d2015-10-26 17:05:04 -070086 private final static String TAG = "RecentsActivity";
87 private final static boolean DEBUG = false;
88
Winsone6c90732015-09-24 16:06:29 -070089 public final static int EVENT_BUS_PRIORITY = Recents.EVENT_BUS_PRIORITY + 1;
90
Winsone5f1faa2015-11-20 12:26:23 -080091 private RecentsPackageMonitor mPackageMonitor;
92 private long mLastTabKeyEventTime;
Winson44849b82016-03-29 10:45:45 -070093 private int mLastOrientation = Configuration.ORIENTATION_UNDEFINED;
Winsone5f1faa2015-11-20 12:26:23 -080094 private boolean mFinishedOnStartup;
95 private boolean mIgnoreAltTabRelease;
Winson88737542016-02-17 13:27:33 -080096 private boolean mIsVisible;
Winson Chung85cfec82014-07-14 14:16:04 -070097
98 // Top level views
Winsone5f1faa2015-11-20 12:26:23 -080099 private RecentsView mRecentsView;
100 private SystemBarScrimViews mScrimViews;
Winson Chungcdbbb7e2014-06-24 12:11:49 -0700101
Winson Chungcdbbb7e2014-06-24 12:11:49 -0700102 // Runnables to finish the Recents activity
Winsone693aaf2016-03-01 12:05:59 -0800103 private Intent mHomeIntent;
Winson Chungcdbbb7e2014-06-24 12:11:49 -0700104
Winson0d14d4d2015-10-26 17:05:04 -0700105 // The trigger to automatically launch the current task
Peter Schillerb124d562015-12-11 21:31:17 -0800106 private int mFocusTimerDuration;
107 private DozeTrigger mIterateTrigger;
Winson4b9cded2016-01-26 16:26:47 -0800108 private final UserInteractionEvent mUserInteractionEvent = new UserInteractionEvent();
Winson0d14d4d2015-10-26 17:05:04 -0700109
Winson Chungd543c1b2014-06-23 15:06:45 -0700110 /**
Winson3fb67562015-11-11 10:39:03 -0800111 * A common Runnable to finish Recents by launching Home with an animation depending on the
Peter Schillerb124d562015-12-11 21:31:17 -0800112 * last activity launch state. Generally we always launch home when we exit Recents rather than
Winson3fb67562015-11-11 10:39:03 -0800113 * just finishing the activity since we don't know what is behind Recents in the task stack.
Winson Chungd543c1b2014-06-23 15:06:45 -0700114 */
Winsone693aaf2016-03-01 12:05:59 -0800115 class LaunchHomeRunnable implements Runnable {
Winson49df4202016-01-25 17:33:34 -0800116
Winson Chungd543c1b2014-06-23 15:06:45 -0700117 Intent mLaunchIntent;
Winson49df4202016-01-25 17:33:34 -0800118 ActivityOptions mOpts;
Winson Chungd543c1b2014-06-23 15:06:45 -0700119
Winson Chungd7b2cb12014-06-26 15:08:50 -0700120 /**
Winson3fb67562015-11-11 10:39:03 -0800121 * Creates a finish runnable that starts the specified intent.
Winson Chungd7b2cb12014-06-26 15:08:50 -0700122 */
Winsone693aaf2016-03-01 12:05:59 -0800123 public LaunchHomeRunnable(Intent launchIntent, ActivityOptions opts) {
Winson Chungd543c1b2014-06-23 15:06:45 -0700124 mLaunchIntent = launchIntent;
Winson40a22732016-02-02 18:07:00 -0800125 mOpts = opts;
Winson Chungd543c1b2014-06-23 15:06:45 -0700126 }
127
128 @Override
129 public void run() {
Winson2b9c1d32015-10-05 15:44:23 -0700130 try {
Winson49df4202016-01-25 17:33:34 -0800131 ActivityOptions opts = mOpts;
132 if (opts == null) {
133 opts = ActivityOptions.makeCustomAnimation(RecentsActivity.this,
Winson008ee15f2016-03-18 17:17:25 -0700134 R.anim.recents_to_launcher_enter, R.anim.recents_to_launcher_exit);
Winson49df4202016-01-25 17:33:34 -0800135 }
Winson3fb67562015-11-11 10:39:03 -0800136 startActivityAsUser(mLaunchIntent, opts.toBundle(), UserHandle.CURRENT);
Winson2b9c1d32015-10-05 15:44:23 -0700137 } catch (Exception e) {
Winson1b585612015-11-06 09:16:26 -0800138 Log.e(TAG, getString(R.string.recents_launch_error_message, "Home"), e);
Winson Chungd543c1b2014-06-23 15:06:45 -0700139 }
140 }
141 }
142
Winson Chung85cfec82014-07-14 14:16:04 -0700143 /**
Winson Chung85cfec82014-07-14 14:16:04 -0700144 * Broadcast receiver to handle messages from the system
145 */
Winson Chung31d66c62014-06-30 13:12:54 -0700146 final BroadcastReceiver mSystemBroadcastReceiver = new BroadcastReceiver() {
Winson Chung67369052014-04-07 17:35:48 -0700147 @Override
148 public void onReceive(Context context, Intent intent) {
Winson Chung31d66c62014-06-30 13:12:54 -0700149 String action = intent.getAction();
Winson Chung85cfec82014-07-14 14:16:04 -0700150 if (action.equals(Intent.ACTION_SCREEN_OFF)) {
151 // When the screen turns off, dismiss Recents to Home
Winson2b9c1d32015-10-05 15:44:23 -0700152 dismissRecentsToHomeIfVisible(false);
Winson Chung31d66c62014-06-30 13:12:54 -0700153 }
Winson Chungd42a6cf2014-06-03 16:24:04 -0700154 }
155 };
156
Winson0d14d4d2015-10-26 17:05:04 -0700157 /**
158 * Dismisses recents if we are already visible and the intent is to toggle the recents view.
159 */
Winson42329522016-02-05 10:39:46 -0800160 boolean dismissRecentsToFocusedTask(int logCategory) {
Winson0d14d4d2015-10-26 17:05:04 -0700161 SystemServicesProxy ssp = Recents.getSystemServices();
162 if (ssp.isRecentsTopMost(ssp.getTopMostTask(), null)) {
Winson0d14d4d2015-10-26 17:05:04 -0700163 // If we have a focused Task, launch that Task now
Winson42329522016-02-05 10:39:46 -0800164 if (mRecentsView.launchFocusedTask(logCategory)) return true;
Winson0d14d4d2015-10-26 17:05:04 -0700165 }
166 return false;
167 }
168
169 /**
Winsona0731a12015-12-02 15:10:14 -0800170 * Dismisses recents back to the launch target task.
171 */
172 boolean dismissRecentsToLaunchTargetTaskOrHome() {
173 SystemServicesProxy ssp = Recents.getSystemServices();
174 if (ssp.isRecentsTopMost(ssp.getTopMostTask(), null)) {
175 // If we have a focused Task, launch that Task now
176 if (mRecentsView.launchPreviousTask()) return true;
177 // If none of the other cases apply, then just go Home
Winsonef064132016-01-05 12:11:31 -0800178 dismissRecentsToHome(true /* animateTaskViews */);
Winsona0731a12015-12-02 15:10:14 -0800179 }
180 return false;
181 }
182
183 /**
Winson0d14d4d2015-10-26 17:05:04 -0700184 * Dismisses recents if we are already visible and the intent is to toggle the recents view.
185 */
Winson397ae742015-11-20 11:27:33 -0800186 boolean dismissRecentsToFocusedTaskOrHome() {
Winsone7f138c2015-10-22 16:15:21 -0700187 SystemServicesProxy ssp = Recents.getSystemServices();
Winson Chung2cf8b222015-01-20 11:44:05 -0800188 if (ssp.isRecentsTopMost(ssp.getTopMostTask(), null)) {
Winson Chung85cfec82014-07-14 14:16:04 -0700189 // If we have a focused Task, launch that Task now
Winson42329522016-02-05 10:39:46 -0800190 if (mRecentsView.launchFocusedTask(0 /* logCategory */)) return true;
Winson Chung85cfec82014-07-14 14:16:04 -0700191 // If none of the other cases apply, then just go Home
Winsonef064132016-01-05 12:11:31 -0800192 dismissRecentsToHome(true /* animateTaskViews */);
Winson Chung85cfec82014-07-14 14:16:04 -0700193 return true;
194 }
195 return false;
196 }
197
Winson2b9c1d32015-10-05 15:44:23 -0700198 /**
199 * Dismisses Recents directly to Home without checking whether it is currently visible.
200 */
Winsonef064132016-01-05 12:11:31 -0800201 void dismissRecentsToHome(boolean animateTaskViews) {
Winson49df4202016-01-25 17:33:34 -0800202 dismissRecentsToHome(animateTaskViews, null);
203 }
204
205 /**
206 * Dismisses Recents directly to Home without checking whether it is currently visible.
207 *
208 * @param overrideAnimation If not null, will override the default animation that is based on
209 * how Recents was launched.
210 */
211 void dismissRecentsToHome(boolean animateTaskViews, ActivityOptions overrideAnimation) {
Winsonef064132016-01-05 12:11:31 -0800212 DismissRecentsToHomeAnimationStarted dismissEvent =
213 new DismissRecentsToHomeAnimationStarted(animateTaskViews);
Winsone693aaf2016-03-01 12:05:59 -0800214 dismissEvent.addPostAnimationCallback(new LaunchHomeRunnable(mHomeIntent,
215 overrideAnimation));
Winsonef064132016-01-05 12:11:31 -0800216 dismissEvent.addPostAnimationCallback(new Runnable() {
217 @Override
218 public void run() {
219 Recents.getSystemServices().sendCloseSystemWindows(
220 BaseStatusBar.SYSTEM_DIALOG_REASON_HOME_KEY);
221 }
222 });
223 EventBus.getDefault().send(dismissEvent);
Wale Ogunwaled351ada2015-04-04 11:53:14 -0700224 }
225
Winson Chung85cfec82014-07-14 14:16:04 -0700226 /** Dismisses Recents directly to Home if we currently aren't transitioning. */
Winson2b9c1d32015-10-05 15:44:23 -0700227 boolean dismissRecentsToHomeIfVisible(boolean animated) {
Winsone7f138c2015-10-22 16:15:21 -0700228 SystemServicesProxy ssp = Recents.getSystemServices();
Winson Chung2cf8b222015-01-20 11:44:05 -0800229 if (ssp.isRecentsTopMost(ssp.getTopMostTask(), null)) {
Winson Chung85cfec82014-07-14 14:16:04 -0700230 // Return to Home
Winson2b9c1d32015-10-05 15:44:23 -0700231 dismissRecentsToHome(animated);
Winson Chung47c4c692014-03-17 10:17:11 -0700232 return true;
Winson Chung303e1ff2014-03-07 15:06:19 -0800233 }
234 return false;
235 }
236
237 /** Called with the activity is first created. */
238 @Override
239 public void onCreate(Bundle savedInstanceState) {
240 super.onCreate(savedInstanceState);
Winson3150e572015-10-23 15:07:24 -0700241 mFinishedOnStartup = false;
242
243 // In the case that the activity starts up before the Recents component has initialized
244 // (usually when debugging/pushing the SysUI apk), just finish this activity.
245 SystemServicesProxy ssp = Recents.getSystemServices();
246 if (ssp == null) {
247 mFinishedOnStartup = true;
248 finish();
249 return;
250 }
Winsonb78bb4f2015-09-24 17:22:57 -0700251
252 // Register this activity with the event bus
253 EventBus.getDefault().register(this, EVENT_BUS_PRIORITY);
254
Winson008ee15f2016-03-18 17:17:25 -0700255 // Initialize the package monitor
Winsone7f138c2015-10-22 16:15:21 -0700256 mPackageMonitor = new RecentsPackageMonitor();
257 mPackageMonitor.register(this);
Winson Chungf7bca432014-04-30 17:11:13 -0700258
Winson Chung8e548f72014-06-24 14:40:53 -0700259 // Set the Recents layout
260 setContentView(R.layout.recents);
Winson88737542016-02-17 13:27:33 -0800261 takeKeyEvents(true);
Winson Chung8e548f72014-06-24 14:40:53 -0700262 mRecentsView = (RecentsView) findViewById(R.id.recents_view);
Winson Chung653f70c22014-05-19 14:49:42 -0700263 mRecentsView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
264 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
265 View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
Winson35f30502015-09-28 11:24:36 -0700266 mScrimViews = new SystemBarScrimViews(this);
Filip Gruszczynski1a4dfe52015-11-15 10:58:57 -0800267 getWindow().getAttributes().privateFlags |=
268 WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY;
Winson Chung303e1ff2014-03-07 15:06:19 -0800269
Winson44849b82016-03-29 10:45:45 -0700270 mLastOrientation = getResources().getConfiguration().orientation;
Peter Schillerb124d562015-12-11 21:31:17 -0800271 mFocusTimerDuration = getResources().getInteger(R.integer.recents_auto_advance_duration);
272 mIterateTrigger = new DozeTrigger(mFocusTimerDuration, new Runnable() {
273 @Override
274 public void run() {
Winson42329522016-02-05 10:39:46 -0800275 dismissRecentsToFocusedTask(MetricsEvent.OVERVIEW_SELECT_TIMEOUT);
Peter Schillerb124d562015-12-11 21:31:17 -0800276 }
277 });
278
Winsone8a4eff2016-03-28 16:20:35 -0700279 // Set the window background
280 getWindow().setBackgroundDrawable(mRecentsView.getBackgroundScrim());
281
Winson3fb67562015-11-11 10:39:03 -0800282 // Create the home intent runnable
Winsone693aaf2016-03-01 12:05:59 -0800283 mHomeIntent = new Intent(Intent.ACTION_MAIN, null);
284 mHomeIntent.addCategory(Intent.CATEGORY_HOME);
285 mHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Winson3fb67562015-11-11 10:39:03 -0800286 Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
Winson3fb67562015-11-11 10:39:03 -0800287
Winson Chung31d66c62014-06-30 13:12:54 -0700288 // Register the broadcast receiver to handle messages when the screen is turned off
289 IntentFilter filter = new IntentFilter();
290 filter.addAction(Intent.ACTION_SCREEN_OFF);
Winson Chung31d66c62014-06-30 13:12:54 -0700291 registerReceiver(mSystemBroadcastReceiver, filter);
Jorim Jaggic69bd222016-03-15 14:38:37 +0100292
293 getWindow().addPrivateFlags(LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION);
Winsona1ededd2016-03-25 12:23:12 -0700294
295 // Reload the stack view
296 reloadStackView();
Winson Chung521e7dc2014-06-02 15:31:56 -0700297 }
298
Winson Chung303e1ff2014-03-07 15:06:19 -0800299 @Override
Winson Chung303e1ff2014-03-07 15:06:19 -0800300 protected void onStart() {
Winson Chung303e1ff2014-03-07 15:06:19 -0800301 super.onStart();
Winson Chung303e1ff2014-03-07 15:06:19 -0800302
Winsone7f138c2015-10-22 16:15:21 -0700303 // Notify that recents is now visible
Winson88737542016-02-17 13:27:33 -0800304 EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, true));
Chris Wrenf6e9228b2016-01-26 18:04:35 -0500305 MetricsLogger.visible(this, MetricsEvent.OVERVIEW_ACTIVITY);
Winson Chung67369052014-04-07 17:35:48 -0700306 }
307
308 @Override
Winsona1ededd2016-03-25 12:23:12 -0700309 protected void onNewIntent(Intent intent) {
310 super.onNewIntent(intent);
311
312 // Reload the stack view
313 reloadStackView();
Winson3fb67562015-11-11 10:39:03 -0800314 }
315
Winsona1ededd2016-03-25 12:23:12 -0700316 /**
317 * Reloads the stack views upon launching Recents.
318 */
319 private void reloadStackView() {
Winson88737542016-02-17 13:27:33 -0800320 // If the Recents component has preloaded a load plan, then use that to prevent
321 // reconstructing the task stack
322 RecentsTaskLoader loader = Recents.getTaskLoader();
323 RecentsTaskLoadPlan loadPlan = RecentsImpl.consumeInstanceLoadPlan();
324 if (loadPlan == null) {
325 loadPlan = loader.createLoadPlan(this);
326 }
327
328 // Start loading tasks according to the load plan
329 RecentsConfiguration config = Recents.getConfiguration();
330 RecentsActivityLaunchState launchState = config.getLaunchState();
331 if (!loadPlan.hasTasks()) {
Winson96e61342016-03-15 16:47:19 -0700332 loader.preloadTasks(loadPlan, launchState.launchedToTaskId,
333 launchState.launchedFromHome);
Winson88737542016-02-17 13:27:33 -0800334 }
335
336 RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options();
337 loadOpts.runningTaskId = launchState.launchedToTaskId;
338 loadOpts.numVisibleTasks = launchState.launchedNumVisibleTasks;
339 loadOpts.numVisibleTaskThumbnails = launchState.launchedNumVisibleThumbnails;
340 loader.loadTasks(this, loadPlan, loadOpts);
341 TaskStack stack = loadPlan.getTaskStack();
Winsona1ededd2016-03-25 12:23:12 -0700342 mRecentsView.onReload(mIsVisible, stack.getTaskCount() == 0);
343 mRecentsView.updateStack(stack);
Winson88737542016-02-17 13:27:33 -0800344
Winsona1ededd2016-03-25 12:23:12 -0700345 // Update the nav bar scrim, but defer the animation until the enter-window event
Winsonc69249f2016-03-28 13:38:39 -0700346 boolean animateNavBarScrim = !launchState.launchedViaDockGesture;
Winsona1ededd2016-03-25 12:23:12 -0700347 updateNavBarScrim(animateNavBarScrim, null);
Winson88737542016-02-17 13:27:33 -0800348
Winsona1ededd2016-03-25 12:23:12 -0700349 // If this is a new instance relaunched by AM, without going through the normal mechanisms,
350 // then we have to manually trigger the enter animation state
Winson88737542016-02-17 13:27:33 -0800351 boolean wasLaunchedByAm = !launchState.launchedFromHome &&
352 !launchState.launchedFromApp;
Winsona1ededd2016-03-25 12:23:12 -0700353 if (wasLaunchedByAm) {
Winson88737542016-02-17 13:27:33 -0800354 EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
355 }
356
Winson88737542016-02-17 13:27:33 -0800357 // Keep track of whether we launched from the nav bar button or via alt-tab
358 if (launchState.launchedWithAltTab) {
359 MetricsLogger.count(this, "overview_trigger_alttab", 1);
360 } else {
361 MetricsLogger.count(this, "overview_trigger_nav_btn", 1);
362 }
363
364 // Keep track of whether we launched from an app or from home
365 if (launchState.launchedFromApp) {
Winsona1ededd2016-03-25 12:23:12 -0700366 Task launchTarget = stack.getLaunchTarget();
367 int launchTaskIndexInStack = launchTarget != null
368 ? stack.indexOfStackTask(launchTarget)
369 : 0;
Winson88737542016-02-17 13:27:33 -0800370 MetricsLogger.count(this, "overview_source_app", 1);
371 // If from an app, track the stack index of the app in the stack (for affiliated tasks)
372 MetricsLogger.histogram(this, "overview_source_app_index", launchTaskIndexInStack);
373 } else {
374 MetricsLogger.count(this, "overview_source_home", 1);
375 }
376
377 // Keep track of the total stack task count
Winsona1ededd2016-03-25 12:23:12 -0700378 int taskCount = mRecentsView.getStack().getTaskCount();
Winson88737542016-02-17 13:27:33 -0800379 MetricsLogger.histogram(this, "overview_task_count", taskCount);
380
381 // After we have resumed, set the visible state until the next onStop() call
382 mIsVisible = true;
Jorim Jaggi6e18e002015-06-02 17:07:39 -0700383 }
384
385 @Override
Winsona1ededd2016-03-25 12:23:12 -0700386 public void onEnterAnimationComplete() {
387 super.onEnterAnimationComplete();
388 EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
389 }
390
391 @Override
392 protected void onResume() {
393 super.onResume();
394
395 // Notify of the next draw
396 mRecentsView.getViewTreeObserver().addOnPreDrawListener(
397 new ViewTreeObserver.OnPreDrawListener() {
398
399 @Override
400 public boolean onPreDraw() {
401 mRecentsView.getViewTreeObserver().removeOnPreDrawListener(this);
402 EventBus.getDefault().post(new RecentsDrawnEvent());
403 return true;
404 }
405 });
406 }
407
408 @Override
Winson88737542016-02-17 13:27:33 -0800409 protected void onPause() {
410 super.onPause();
Winson190fe3bf2015-10-20 14:57:24 -0700411
Winsone5f1faa2015-11-20 12:26:23 -0800412 mIgnoreAltTabRelease = false;
Winson88737542016-02-17 13:27:33 -0800413 mIterateTrigger.stopDozing();
Winson88737542016-02-17 13:27:33 -0800414 }
Winsone7f138c2015-10-22 16:15:21 -0700415
Winson88737542016-02-17 13:27:33 -0800416 @Override
Winsona1809852016-03-15 11:41:37 -0700417 public void onConfigurationChanged(Configuration newConfig) {
418 super.onConfigurationChanged(newConfig);
419
Winsona1ededd2016-03-25 12:23:12 -0700420 // Update the nav bar for the current orientation
421 updateNavBarScrim(false /* animateNavBarScrim */, AnimationProps.IMMEDIATE);
422
Winson44849b82016-03-29 10:45:45 -0700423 // Notify of the config change
424 int newOrientation = getResources().getConfiguration().orientation;
425 EventBus.getDefault().send(new ConfigurationChangedEvent(false /* fromMultiWindow */,
426 (mLastOrientation != newOrientation)));
427 mLastOrientation = newOrientation;
Winsona1809852016-03-15 11:41:37 -0700428 }
429
430 @Override
Winsona1ededd2016-03-25 12:23:12 -0700431 public void onMultiWindowChanged(boolean inMultiWindow) {
432 super.onMultiWindowChanged(inMultiWindow);
Winson44849b82016-03-29 10:45:45 -0700433 EventBus.getDefault().send(new ConfigurationChangedEvent(true /* fromMultiWindow */,
434 false /* fromOrientationChange */));
Winsona1ededd2016-03-25 12:23:12 -0700435
436 if (mRecentsView != null) {
437 // Reload the task stack completely
438 RecentsConfiguration config = Recents.getConfiguration();
439 RecentsActivityLaunchState launchState = config.getLaunchState();
440 RecentsTaskLoader loader = Recents.getTaskLoader();
441 RecentsTaskLoadPlan loadPlan = loader.createLoadPlan(this);
442 loader.preloadTasks(loadPlan, -1 /* topTaskId */, false /* isTopTaskHome */);
443
444 RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options();
445 loadOpts.numVisibleTasks = launchState.launchedNumVisibleTasks;
446 loadOpts.numVisibleTaskThumbnails = launchState.launchedNumVisibleThumbnails;
447 loader.loadTasks(this, loadPlan, loadOpts);
448
449 mRecentsView.updateStack(loadPlan.getTaskStack());
450 }
451
452 EventBus.getDefault().send(new MultiWindowStateChangedEvent(inMultiWindow));
453 }
454
455 @Override
Winson88737542016-02-17 13:27:33 -0800456 protected void onStop() {
457 super.onStop();
458
Winson88737542016-02-17 13:27:33 -0800459 // Notify that recents is now hidden
460 mIsVisible = false;
461 EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, false));
Chris Wrenf6e9228b2016-01-26 18:04:35 -0500462 MetricsLogger.hidden(this, MetricsEvent.OVERVIEW_ACTIVITY);
Winson73492c52016-03-09 17:44:54 -0800463
464 // Workaround for b/22542869, if the RecentsActivity is started again, but without going
465 // through SystemUI, we need to reset the config launch flags to ensure that we do not
466 // wait on the system to send a signal that was never queued.
467 RecentsConfiguration config = Recents.getConfiguration();
468 RecentsActivityLaunchState launchState = config.getLaunchState();
469 launchState.reset();
Winson Chung47c4c692014-03-17 10:17:11 -0700470 }
471
472 @Override
473 protected void onDestroy() {
Winson Chung47c4c692014-03-17 10:17:11 -0700474 super.onDestroy();
Winson Chung31d66c62014-06-30 13:12:54 -0700475
Winson3150e572015-10-23 15:07:24 -0700476 // In the case that the activity finished on startup, just skip the unregistration below
477 if (mFinishedOnStartup) {
478 return;
479 }
480
Winson Chung85cfec82014-07-14 14:16:04 -0700481 // Unregister the system broadcast receivers
Winson Chung31d66c62014-06-30 13:12:54 -0700482 unregisterReceiver(mSystemBroadcastReceiver);
Winson Chung905950a2014-09-17 09:25:27 +0200483
Winsone7f138c2015-10-22 16:15:21 -0700484 // Unregister any broadcast receivers for the task loader
485 mPackageMonitor.unregister();
486
Winsonb78bb4f2015-09-24 17:22:57 -0700487 EventBus.getDefault().unregister(this);
Winson Chung303e1ff2014-03-07 15:06:19 -0800488 }
489
Winson412e1802015-10-20 16:57:57 -0700490 @Override
491 public void onAttachedToWindow() {
492 super.onAttachedToWindow();
493 EventBus.getDefault().register(mScrimViews, EVENT_BUS_PRIORITY);
494 }
Winson Chungaf3bb692015-06-03 17:31:39 -0700495
Winson412e1802015-10-20 16:57:57 -0700496 @Override
497 public void onDetachedFromWindow() {
498 super.onDetachedFromWindow();
499 EventBus.getDefault().unregister(mScrimViews);
Winson Chung353c0b92014-10-16 17:43:23 -0700500 }
501
502 @Override
Winson Chung4d7b0922014-03-13 17:14:17 -0700503 public void onTrimMemory(int level) {
Winsone7f138c2015-10-22 16:15:21 -0700504 RecentsTaskLoader loader = Recents.getTaskLoader();
Winson Chung4d7b0922014-03-13 17:14:17 -0700505 if (loader != null) {
506 loader.onTrimMemory(level);
507 }
508 }
509
510 @Override
Winson Chung1e8d71b2014-05-16 17:05:22 -0700511 public boolean onKeyDown(int keyCode, KeyEvent event) {
Winson Chunga0e88b52014-08-11 19:25:42 -0700512 switch (keyCode) {
513 case KeyEvent.KEYCODE_TAB: {
Winson35f30502015-09-28 11:24:36 -0700514 int altTabKeyDelay = getResources().getInteger(R.integer.recents_alt_tab_key_delay);
Winson Chung15a2ba82014-11-18 11:19:24 -0800515 boolean hasRepKeyTimeElapsed = (SystemClock.elapsedRealtime() -
Winson35f30502015-09-28 11:24:36 -0700516 mLastTabKeyEventTime) > altTabKeyDelay;
Winson Chunga0e88b52014-08-11 19:25:42 -0700517 if (event.getRepeatCount() <= 0 || hasRepKeyTimeElapsed) {
518 // Focus the next task in the stack
519 final boolean backward = event.isShiftPressed();
Winson0d14d4d2015-10-26 17:05:04 -0700520 if (backward) {
521 EventBus.getDefault().send(new FocusPreviousTaskViewEvent());
522 } else {
Peter Schillerb124d562015-12-11 21:31:17 -0800523 EventBus.getDefault().send(
Winson4b9cded2016-01-26 16:26:47 -0800524 new FocusNextTaskViewEvent(0 /* timerIndicatorDuration */));
Winson0d14d4d2015-10-26 17:05:04 -0700525 }
Winson Chung15a2ba82014-11-18 11:19:24 -0800526 mLastTabKeyEventTime = SystemClock.elapsedRealtime();
Winsone5f1faa2015-11-20 12:26:23 -0800527
528 // In the case of another ALT event, don't ignore the next release
529 if (event.isAltPressed()) {
530 mIgnoreAltTabRelease = false;
531 }
Winson Chunga0e88b52014-08-11 19:25:42 -0700532 }
533 return true;
534 }
535 case KeyEvent.KEYCODE_DPAD_UP: {
Peter Schillerb124d562015-12-11 21:31:17 -0800536 EventBus.getDefault().send(
Winson4b9cded2016-01-26 16:26:47 -0800537 new FocusNextTaskViewEvent(0 /* timerIndicatorDuration */));
Winson Chunga0e88b52014-08-11 19:25:42 -0700538 return true;
539 }
540 case KeyEvent.KEYCODE_DPAD_DOWN: {
Winson0d14d4d2015-10-26 17:05:04 -0700541 EventBus.getDefault().send(new FocusPreviousTaskViewEvent());
Winson Chunga0e88b52014-08-11 19:25:42 -0700542 return true;
543 }
544 case KeyEvent.KEYCODE_DEL:
545 case KeyEvent.KEYCODE_FORWARD_DEL: {
Winsondf3012b2016-01-12 15:35:05 -0800546 if (event.getRepeatCount() <= 0) {
547 EventBus.getDefault().send(new DismissFocusedTaskViewEvent());
Winson0d14d4d2015-10-26 17:05:04 -0700548
Winsondf3012b2016-01-12 15:35:05 -0800549 // Keep track of deletions by keyboard
550 MetricsLogger.histogram(this, "overview_task_dismissed_source",
551 Constants.Metrics.DismissSourceKeyboard);
552 return true;
553 }
Winson Chunga0e88b52014-08-11 19:25:42 -0700554 }
555 default:
556 break;
Winson Chung1e8d71b2014-05-16 17:05:22 -0700557 }
Winson Chung1e8d71b2014-05-16 17:05:22 -0700558 return super.onKeyDown(keyCode, event);
559 }
560
561 @Override
Winson Chunga26fb782014-06-12 17:52:39 -0700562 public void onUserInteraction() {
Winson4b9cded2016-01-26 16:26:47 -0800563 EventBus.getDefault().send(mUserInteractionEvent);
Winson Chunga26fb782014-06-12 17:52:39 -0700564 }
565
566 @Override
Winson Chung303e1ff2014-03-07 15:06:19 -0800567 public void onBackPressed() {
Winsona0731a12015-12-02 15:10:14 -0800568 // Back behaves like the recents button so just trigger a toggle event
569 EventBus.getDefault().send(new ToggleRecentsEvent());
Winson Chung303e1ff2014-03-07 15:06:19 -0800570 }
Winson Chung47c4c692014-03-17 10:17:11 -0700571
Winsonb78bb4f2015-09-24 17:22:57 -0700572 /**** EventBus events ****/
Winson Chungd543c1b2014-06-23 15:06:45 -0700573
Winson412e1802015-10-20 16:57:57 -0700574 public final void onBusEvent(ToggleRecentsEvent event) {
Winson8f6ee482016-03-18 17:51:48 -0700575 RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
576 if (launchState.launchedFromHome) {
577 dismissRecentsToHome(true /* animateTaskViews */);
578 } else {
579 dismissRecentsToLaunchTargetTaskOrHome();
Winsonc29ff002015-11-20 16:00:45 -0800580 }
Winson412e1802015-10-20 16:57:57 -0700581 }
582
Winson0d14d4d2015-10-26 17:05:04 -0700583 public final void onBusEvent(IterateRecentsEvent event) {
Winson8f6ee482016-03-18 17:51:48 -0700584 final RecentsDebugFlags debugFlags = Recents.getDebugFlags();
Peter Schillerb124d562015-12-11 21:31:17 -0800585
Winson8f6ee482016-03-18 17:51:48 -0700586 // Start dozing after the recents button is clicked
587 int timerIndicatorDuration = 0;
588 if (debugFlags.isFastToggleRecentsEnabled()) {
589 timerIndicatorDuration = getResources().getInteger(
590 R.integer.recents_subsequent_auto_advance_duration);
Winson4b9cded2016-01-26 16:26:47 -0800591
Winson8f6ee482016-03-18 17:51:48 -0700592 mIterateTrigger.setDozeDuration(timerIndicatorDuration);
593 if (!mIterateTrigger.isDozing()) {
594 mIterateTrigger.startDozing();
595 } else {
596 mIterateTrigger.poke();
Winson8b1871d2015-11-20 09:56:20 -0800597 }
598 }
Winson8f6ee482016-03-18 17:51:48 -0700599
600 // Focus the next task
601 EventBus.getDefault().send(new FocusNextTaskViewEvent(timerIndicatorDuration));
602
603 MetricsLogger.action(this, MetricsEvent.ACTION_OVERVIEW_PAGE);
Winson0d14d4d2015-10-26 17:05:04 -0700604 }
605
606 public final void onBusEvent(UserInteractionEvent event) {
Winsonb61e6542016-02-04 14:37:18 -0800607 // Stop the fast-toggle dozer
Winson0d14d4d2015-10-26 17:05:04 -0700608 mIterateTrigger.stopDozing();
609 }
610
Winson412e1802015-10-20 16:57:57 -0700611 public final void onBusEvent(HideRecentsEvent event) {
612 if (event.triggeredFromAltTab) {
613 // If we are hiding from releasing Alt-Tab, dismiss Recents to the focused app
Winsone5f1faa2015-11-20 12:26:23 -0800614 if (!mIgnoreAltTabRelease) {
615 dismissRecentsToFocusedTaskOrHome();
616 }
Winson412e1802015-10-20 16:57:57 -0700617 } else if (event.triggeredFromHomeKey) {
Winson8f6ee482016-03-18 17:51:48 -0700618 dismissRecentsToHome(true /* animateTaskViews */);
Winson4b9cded2016-01-26 16:26:47 -0800619
620 // Cancel any pending dozes
621 EventBus.getDefault().send(mUserInteractionEvent);
Winson412e1802015-10-20 16:57:57 -0700622 } else {
623 // Do nothing
624 }
625 }
626
Filip Gruszczynski1a5203d2015-10-29 17:43:49 -0700627 public final void onBusEvent(EnterRecentsWindowLastAnimationFrameEvent event) {
Winsonb1e71d02015-11-23 12:40:23 -0800628 EventBus.getDefault().send(new UpdateFreeformTaskViewVisibilityEvent(true));
Filip Gruszczynski14b4e572015-11-03 15:53:55 -0800629 mRecentsView.getViewTreeObserver().addOnPreDrawListener(this);
Winsonb1e71d02015-11-23 12:40:23 -0800630 mRecentsView.invalidate();
Filip Gruszczynski1a5203d2015-10-29 17:43:49 -0700631 }
632
Filip Gruszczynski1a4dfe52015-11-15 10:58:57 -0800633 public final void onBusEvent(ExitRecentsWindowFirstAnimationFrameEvent event) {
Winsonb1e71d02015-11-23 12:40:23 -0800634 if (mRecentsView.isLastTaskLaunchedFreeform()) {
635 EventBus.getDefault().send(new UpdateFreeformTaskViewVisibilityEvent(false));
636 }
Filip Gruszczynski1a4dfe52015-11-15 10:58:57 -0800637 mRecentsView.getViewTreeObserver().addOnPreDrawListener(this);
Winsonb1e71d02015-11-23 12:40:23 -0800638 mRecentsView.invalidate();
Filip Gruszczynski1a4dfe52015-11-15 10:58:57 -0800639 }
640
Jorim Jaggi192086e2016-03-11 17:17:03 +0100641 public final void onBusEvent(DockedFirstAnimationFrameEvent event) {
642 mRecentsView.getViewTreeObserver().addOnPreDrawListener(this);
643 mRecentsView.invalidate();
644 }
645
Winson13d30662015-11-06 15:30:29 -0800646 public final void onBusEvent(CancelEnterRecentsWindowAnimationEvent event) {
647 RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
648 int launchToTaskId = launchState.launchedToTaskId;
649 if (launchToTaskId != -1 &&
650 (event.launchTask == null || launchToTaskId != event.launchTask.key.id)) {
651 SystemServicesProxy ssp = Recents.getSystemServices();
652 ssp.cancelWindowTransition(launchState.launchedToTaskId);
653 ssp.cancelThumbnailTransition(getTaskId());
654 }
655 }
656
Winson2536c7e2015-10-01 15:49:31 -0700657 public final void onBusEvent(ShowApplicationInfoEvent event) {
658 // Create a new task stack with the application info details activity
Winson2536c7e2015-10-01 15:49:31 -0700659 Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Winsone7f138c2015-10-22 16:15:21 -0700660 Uri.fromParts("package", event.task.key.getComponent().getPackageName(), null));
Winson2536c7e2015-10-01 15:49:31 -0700661 intent.setComponent(intent.resolveActivity(getPackageManager()));
662 TaskStackBuilder.create(this)
663 .addNextIntentWithParentStack(intent).startActivities(null,
Peter Schillerb124d562015-12-11 21:31:17 -0800664 new UserHandle(event.task.key.userId));
Winson2536c7e2015-10-01 15:49:31 -0700665
666 // Keep track of app-info invocations
667 MetricsLogger.count(this, "overview_app_info", 1);
668 }
669
Winsonef064132016-01-05 12:11:31 -0800670 public final void onBusEvent(DeleteTaskDataEvent event) {
Winson2536c7e2015-10-01 15:49:31 -0700671 // Remove any stored data from the loader
Winsone7f138c2015-10-22 16:15:21 -0700672 RecentsTaskLoader loader = Recents.getTaskLoader();
Winson2536c7e2015-10-01 15:49:31 -0700673 loader.deleteTaskData(event.task, false);
674
675 // Remove the task from activity manager
Winsone7f138c2015-10-22 16:15:21 -0700676 SystemServicesProxy ssp = Recents.getSystemServices();
677 ssp.removeTask(event.task.key.id);
Winson2536c7e2015-10-01 15:49:31 -0700678 }
679
Winson397ae742015-11-20 11:27:33 -0800680 public final void onBusEvent(AllTaskViewsDismissedEvent event) {
Winson Chung9a742902015-12-11 10:25:40 -0500681 SystemServicesProxy ssp = Recents.getSystemServices();
682 if (ssp.hasDockedTask()) {
Winson20684082016-03-16 17:13:34 -0700683 mRecentsView.showEmptyView(event.msgResId);
Winson Chung9a742902015-12-11 10:25:40 -0500684 } else {
685 // Just go straight home (no animation necessary because there are no more task views)
Winsonef064132016-01-05 12:11:31 -0800686 dismissRecentsToHome(false /* animateTaskViews */);
Winson Chung9a742902015-12-11 10:25:40 -0500687 }
Winson397ae742015-11-20 11:27:33 -0800688
689 // Keep track of all-deletions
690 MetricsLogger.count(this, "overview_task_all_dismissed", 1);
691 }
692
Winson83c1b072015-11-09 10:48:04 -0800693 public final void onBusEvent(LaunchTaskSucceededEvent event) {
694 MetricsLogger.histogram(this, "overview_task_launch_index", event.taskIndexFromStackFront);
695 }
696
697 public final void onBusEvent(LaunchTaskFailedEvent event) {
698 // Return to Home
Winsonef064132016-01-05 12:11:31 -0800699 dismissRecentsToHome(true /* animateTaskViews */);
Winson83c1b072015-11-09 10:48:04 -0800700
701 MetricsLogger.count(this, "overview_task_launch_failed", 1);
702 }
703
Winson412e1802015-10-20 16:57:57 -0700704 public final void onBusEvent(ScreenPinningRequestEvent event) {
705 MetricsLogger.count(this, "overview_screen_pinned", 1);
706 }
707
Winsonc742f972015-11-12 11:32:21 -0800708 public final void onBusEvent(DebugFlagsChangedEvent event) {
709 // Just finish recents so that we can reload the flags anew on the next instantiation
710 finish();
711 }
712
Winsone5f1faa2015-11-20 12:26:23 -0800713 public final void onBusEvent(StackViewScrolledEvent event) {
714 // Once the user has scrolled while holding alt-tab, then we should ignore the release of
715 // the key
716 mIgnoreAltTabRelease = true;
717 }
718
Filip Gruszczynski14b4e572015-11-03 15:53:55 -0800719 @Override
720 public boolean onPreDraw() {
721 mRecentsView.getViewTreeObserver().removeOnPreDrawListener(this);
722 // We post to make sure that this information is delivered after this traversals is
723 // finished.
724 mRecentsView.post(new Runnable() {
725 @Override
726 public void run() {
727 Recents.getSystemServices().endProlongedAnimations();
728 }
729 });
730 return true;
731 }
Winsona1ededd2016-03-25 12:23:12 -0700732
733 /**
734 * Updates the nav bar scrim.
735 */
736 private void updateNavBarScrim(boolean animateNavBarScrim, AnimationProps animation) {
737 // Animate the SystemUI scrims into view
738 SystemServicesProxy ssp = Recents.getSystemServices();
739 int taskCount = mRecentsView.getStack().getTaskCount();
740 boolean hasNavBarScrim = (taskCount > 0) && !ssp.hasTransposedNavBar();
741 mScrimViews.prepareEnterRecentsAnimation(hasNavBarScrim, animateNavBarScrim);
742 if (animateNavBarScrim && animation != null) {
743 mScrimViews.animateNavBarScrimVisibility(true, animation);
744 }
745 }
Winson Chung303e1ff2014-03-07 15:06:19 -0800746}