blob: 978d5867288ba8e96b756c1bd06127b557f0491b [file] [log] [blame]
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001/*
2 * Copyright (C) 2010 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 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.server.am;
18
Winson Chung83471632016-12-13 11:02:12 -080019import static android.app.ActivityManager.StackId.ASSISTANT_STACK_ID;
Wale Ogunwale3797c222015-10-27 14:21:58 -070020import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
21import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
22import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
23import static android.app.ActivityManager.StackId.HOME_STACK_ID;
Wale Ogunwale56d75cf2016-03-09 15:14:47 -080024import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
Wale Ogunwale3797c222015-10-27 14:21:58 -070025import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
Winson Chung91e5c882017-04-21 14:44:38 -070026import static android.app.ActivityManager.StackId.RECENTS_STACK_ID;
Filip Gruszczynski3c2db1d12016-01-06 17:39:14 -080027import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
Wale Ogunwale5658e4b2016-02-12 12:22:19 -080028import static android.content.pm.ActivityInfo.FLAG_RESUME_WHILE_PAUSING;
Wale Ogunwale6dfdfd62015-04-15 12:01:38 -070029import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
Wale Ogunwalef5d1e352016-09-22 08:34:42 -070030import static android.view.Display.DEFAULT_DISPLAY;
Andrii Kulian7211d2e2017-01-27 15:58:05 -080031import static android.view.Display.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
Andrii Kulianfc8f82b2017-01-26 13:17:27 -080032
Andrii Kulian94e82d9b02017-07-13 15:33:06 -070033import static android.view.Display.INVALID_DISPLAY;
Jorim Jaggiaf80db42016-04-07 19:19:15 -070034import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ADD_REMOVE;
35import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
36import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_APP;
37import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
Jorim Jaggiaf80db42016-04-07 19:19:15 -070038import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONTAINERS;
Jorim Jaggiaf80db42016-04-07 19:19:15 -070039import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PAUSE;
40import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RELEASE;
41import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RESULTS;
42import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SAVED_STATE;
Jorim Jaggiaf80db42016-04-07 19:19:15 -070043import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
44import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STATES;
45import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
46import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
47import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TRANSITION;
48import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USER_LEAVING;
49import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
50import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_ADD_REMOVE;
51import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_APP;
52import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
Jorim Jaggiaf80db42016-04-07 19:19:15 -070053import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONTAINERS;
54import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PAUSE;
55import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RELEASE;
56import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RESULTS;
57import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SAVED_STATE;
Jorim Jaggiaf80db42016-04-07 19:19:15 -070058import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
59import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STATES;
60import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
61import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS;
62import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TRANSITION;
63import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_USER_LEAVING;
64import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
65import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
66import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
Craig Mautner84984fa2014-06-19 11:19:20 -070067import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
Winson Chung83471632016-12-13 11:02:12 -080068import static com.android.server.am.ActivityRecord.ASSISTANT_ACTIVITY_TYPE;
Jorim Jaggiaf80db42016-04-07 19:19:15 -070069import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
Wale Ogunwaleb9a0c992017-04-18 07:25:20 -070070import static com.android.server.am.ActivityStack.ActivityState.STOPPED;
71import static com.android.server.am.ActivityStack.ActivityState.STOPPING;
Wale Ogunwale39381972015-12-17 17:15:29 -080072import static com.android.server.am.ActivityStackSupervisor.FindTaskResult;
Winson Chung7c3ede32017-03-14 14:18:34 -070073import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
Winson Chung6954fc92017-03-24 16:22:12 -070074import static com.android.server.am.ActivityStackSupervisor.PAUSE_IMMEDIATELY;
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -070075import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
Winson Chung6954fc92017-03-24 16:22:12 -070076import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
Jorim Jaggiaf80db42016-04-07 19:19:15 -070077import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_CLOSE;
78import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
79import static com.android.server.wm.AppTransition.TRANSIT_NONE;
80import static com.android.server.wm.AppTransition.TRANSIT_TASK_CLOSE;
81import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
82import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN_BEHIND;
83import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_BACK;
84import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
Wale Ogunwalec5cc3012017-01-13 13:26:16 -080085import static java.lang.Integer.MAX_VALUE;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070086
87import android.app.Activity;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070088import android.app.ActivityManager;
Jorim Jaggiaf80db42016-04-07 19:19:15 -070089import android.app.ActivityManager.RunningTaskInfo;
Wale Ogunwale3797c222015-10-27 14:21:58 -070090import android.app.ActivityManager.StackId;
Dianne Hackborn7a2195c2012-03-19 17:38:00 -070091import android.app.ActivityOptions;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070092import android.app.AppGlobals;
Craig Mautner05d6272ba2013-02-11 09:39:27 -080093import android.app.IActivityController;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070094import android.app.ResultInfo;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070095import android.content.ComponentName;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070096import android.content.Intent;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070097import android.content.pm.ActivityInfo;
Todd Kennedy39bfee52016-02-24 10:28:21 -080098import android.content.pm.ApplicationInfo;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070099import android.content.res.Configuration;
Jorim Jaggiaf80db42016-04-07 19:19:15 -0700100import android.graphics.Point;
101import android.graphics.Rect;
Santos Cordon73ff7d82013-03-06 17:24:11 -0800102import android.net.Uri;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700103import android.os.Binder;
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700104import android.os.Bundle;
Craig Mautner329f4122013-11-07 09:10:42 -0800105import android.os.Debug;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700106import android.os.Handler;
107import android.os.IBinder;
Zoran Marcetaf958b322012-08-09 20:27:12 +0900108import android.os.Looper;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700109import android.os.Message;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700110import android.os.RemoteException;
111import android.os.SystemClock;
Craig Mautner329f4122013-11-07 09:10:42 -0800112import android.os.Trace;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700113import android.os.UserHandle;
Craig Mautner4c07d022014-06-11 17:12:59 -0700114import android.service.voice.IVoiceInteractionSession;
Jorim Jaggiaf80db42016-04-07 19:19:15 -0700115import android.util.ArraySet;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700116import android.util.EventLog;
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800117import android.util.IntArray;
Jorim Jaggi023da532016-04-20 22:42:32 -0700118import android.util.Log;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700119import android.util.Slog;
Andrii Kulian1e32e022016-09-16 15:29:34 -0700120import android.util.SparseArray;
Craig Mautner59c00972012-07-30 12:10:24 -0700121import android.view.Display;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700122
Bryce Lee840c5662017-04-13 10:02:51 -0700123import com.android.internal.annotations.VisibleForTesting;
Jorim Jaggiaf80db42016-04-07 19:19:15 -0700124import com.android.internal.app.IVoiceInteractor;
Jorim Jaggiaf80db42016-04-07 19:19:15 -0700125import com.android.internal.os.BatteryStatsImpl;
126import com.android.server.Watchdog;
127import com.android.server.am.ActivityManagerService.ItemMatcher;
Wale Ogunwale98d62312017-07-12 09:24:56 -0700128import com.android.server.wm.ConfigurationContainer;
Wale Ogunwale1666e312016-12-16 11:27:18 -0800129import com.android.server.wm.StackWindowController;
130import com.android.server.wm.StackWindowListener;
Jorim Jaggiaf80db42016-04-07 19:19:15 -0700131import com.android.server.wm.WindowManagerService;
132
Craig Mautnercae015f2013-02-08 14:31:27 -0800133import java.io.FileDescriptor;
Craig Mautnercae015f2013-02-08 14:31:27 -0800134import java.io.PrintWriter;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700135import java.lang.ref.WeakReference;
136import java.util.ArrayList;
137import java.util.Iterator;
138import java.util.List;
Kenny Roote6585b32013-12-13 12:00:26 -0800139import java.util.Objects;
Wale Ogunwale540e1232015-05-01 15:35:39 -0700140import java.util.Set;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700141
142/**
143 * State and management of a single stack of activities.
144 */
Winson Chung55893332017-02-17 17:13:10 -0800145class ActivityStack<T extends StackWindowController> extends ConfigurationContainer
146 implements StackWindowListener {
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800147
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800148 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStack" : TAG_AM;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -0700149 private static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE;
150 private static final String TAG_APP = TAG + POSTFIX_APP;
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800151 private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -0700152 private static final String TAG_CONTAINERS = TAG + POSTFIX_CONTAINERS;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700153 private static final String TAG_PAUSE = TAG + POSTFIX_PAUSE;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -0700154 private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700155 private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -0700156 private static final String TAG_SAVED_STATE = TAG + POSTFIX_SAVED_STATE;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700157 private static final String TAG_STACK = TAG + POSTFIX_STACK;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -0700158 private static final String TAG_STATES = TAG + POSTFIX_STATES;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700159 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
160 private static final String TAG_TASKS = TAG + POSTFIX_TASKS;
161 private static final String TAG_TRANSITION = TAG + POSTFIX_TRANSITION;
162 private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING;
163 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
Wale Ogunwale3ab9a272015-03-16 09:55:45 -0700164
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -0700165 // Ticks during which we check progress while waiting for an app to launch.
166 static final int LAUNCH_TICK = 500;
167
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700168 // How long we wait until giving up on the last activity to pause. This
169 // is short because it directly impacts the responsiveness of starting the
170 // next activity.
Andrii Kulian21713ac2016-10-12 22:05:05 -0700171 private static final int PAUSE_TIMEOUT = 500;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700172
Dianne Hackborn162bc0e2012-04-09 14:06:16 -0700173 // How long we wait for the activity to tell us it has stopped before
174 // giving up. This is a good amount of time because we really need this
175 // from the application in order to get its saved state.
Andrii Kulian21713ac2016-10-12 22:05:05 -0700176 private static final int STOP_TIMEOUT = 10 * 1000;
Dianne Hackborn162bc0e2012-04-09 14:06:16 -0700177
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700178 // How long we wait until giving up on an activity telling us it has
179 // finished destroying itself.
Andrii Kulian21713ac2016-10-12 22:05:05 -0700180 private static final int DESTROY_TIMEOUT = 10 * 1000;
Craig Mautnerd74f7d72013-02-26 13:41:02 -0800181
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700182 // How long until we reset a task when the user returns to it. Currently
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800183 // disabled.
Andrii Kulian21713ac2016-10-12 22:05:05 -0700184 private static final long ACTIVITY_INACTIVE_RESET_TIME = 0;
Craig Mautnerd74f7d72013-02-26 13:41:02 -0800185
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700186 // Set to false to disable the preview that is shown while a new activity
187 // is being started.
Andrii Kulian21713ac2016-10-12 22:05:05 -0700188 private static final boolean SHOW_APP_STARTING_PREVIEW = true;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800189
Craig Mautner5eda9b32013-07-02 11:58:16 -0700190 // How long to wait for all background Activities to redraw following a call to
191 // convertToTranslucent().
Andrii Kulian21713ac2016-10-12 22:05:05 -0700192 private static final long TRANSLUCENT_CONVERSION_TIMEOUT = 2000;
Craig Mautner5eda9b32013-07-02 11:58:16 -0700193
Filip Gruszczynskief2f72b2015-12-04 14:52:25 -0800194 // How many activities have to be scheduled to stop to force a stop pass.
195 private static final int MAX_STOPPING_TO_FORCE = 3;
196
Andrii Kulian1779e612016-10-12 21:58:25 -0700197 @Override
198 protected int getChildCount() {
199 return mTaskHistory.size();
200 }
201
202 @Override
203 protected ConfigurationContainer getChildAt(int index) {
204 return mTaskHistory.get(index);
205 }
206
207 @Override
208 protected ConfigurationContainer getParent() {
Andrii Kulian94e82d9b02017-07-13 15:33:06 -0700209 return getDisplay();
Andrii Kulian1779e612016-10-12 21:58:25 -0700210 }
211
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800212 @Override
Wale Ogunwale98d62312017-07-12 09:24:56 -0700213 protected void onParentChanged() {
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800214 super.onParentChanged();
215 mStackSupervisor.updateUIDsPresentOnDisplay();
216 }
217
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700218 enum ActivityState {
219 INITIALIZING,
220 RESUMED,
221 PAUSING,
222 PAUSED,
223 STOPPING,
224 STOPPED,
225 FINISHING,
226 DESTROYING,
227 DESTROYED
228 }
229
Filip Gruszczynski0e381e22016-01-14 16:31:33 -0800230 // Stack is not considered visible.
231 static final int STACK_INVISIBLE = 0;
232 // Stack is considered visible
233 static final int STACK_VISIBLE = 1;
Filip Gruszczynski0e381e22016-01-14 16:31:33 -0800234
Bryce Lee840c5662017-04-13 10:02:51 -0700235 @VisibleForTesting
Wale Ogunwale06579d62016-04-30 15:29:06 -0700236 /* The various modes for the method {@link #removeTask}. */
237 // Task is being completely removed from all stacks in the system.
Bryce Lee840c5662017-04-13 10:02:51 -0700238 protected static final int REMOVE_TASK_MODE_DESTROYING = 0;
Wale Ogunwale06579d62016-04-30 15:29:06 -0700239 // Task is being removed from this stack so we can add it to another stack. In the case we are
240 // moving we don't want to perform some operations on the task like removing it from window
241 // manager or recents.
242 static final int REMOVE_TASK_MODE_MOVING = 1;
243 // Similar to {@link #REMOVE_TASK_MODE_MOVING} and the task will be added to the top of its new
244 // stack and the new stack will be on top of all stacks.
Wale Ogunwale56d8d162017-05-30 11:12:20 -0700245 static final int REMOVE_TASK_MODE_MOVING_TO_TOP = 2;
Wale Ogunwale06579d62016-04-30 15:29:06 -0700246
Andrii Kulian1e32e022016-09-16 15:29:34 -0700247 // The height/width divide used when fitting a task within a bounds with method
248 // {@link #fitWithinBounds}.
249 // We always want the task to to be visible in the bounds without affecting its size when
250 // fitting. To make sure this is the case, we don't adjust the task left or top side pass
251 // the input bounds right or bottom side minus the width or height divided by this value.
252 private static final int FIT_WITHIN_BOUNDS_DIVIDER = 3;
253
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700254 final ActivityManagerService mService;
Andrii Kulian21713ac2016-10-12 22:05:05 -0700255 private final WindowManagerService mWindowManager;
Winson Chung55893332017-02-17 17:13:10 -0800256 T mWindowContainerController;
Wale Ogunwalec82f2f52014-12-09 09:32:50 -0800257 private final RecentTasks mRecentTasks;
Craig Mautnerd74f7d72013-02-26 13:41:02 -0800258
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700259 /**
260 * The back history of all previous (and possibly still
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800261 * running) activities. It contains #TaskRecord objects.
262 */
Todd Kennedy39bfee52016-02-24 10:28:21 -0800263 private final ArrayList<TaskRecord> mTaskHistory = new ArrayList<>();
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800264
265 /**
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700266 * List of running activities, sorted by recent usage.
267 * The first entry in the list is the least recently used.
268 * It contains HistoryRecord objects.
269 */
Wale Ogunwale53a29a92015-02-23 15:42:52 -0800270 final ArrayList<ActivityRecord> mLRUActivities = new ArrayList<>();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700271
272 /**
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700273 * Animations that for the current transition have requested not to
274 * be considered for the transition animation.
275 */
Wale Ogunwale53a29a92015-02-23 15:42:52 -0800276 final ArrayList<ActivityRecord> mNoAnimActivities = new ArrayList<>();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700277
278 /**
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700279 * When we are in the process of pausing an activity, before starting the
280 * next one, this variable holds the activity that is currently being paused.
281 */
Dianne Hackborn621e2fe2012-02-16 17:07:33 -0800282 ActivityRecord mPausingActivity = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700283
284 /**
285 * This is the last activity that we put into the paused state. This is
286 * used to determine if we need to do an activity transition while sleeping,
287 * when we normally hold the top activity paused.
288 */
289 ActivityRecord mLastPausedActivity = null;
290
291 /**
Craig Mautner0f922742013-08-06 08:44:42 -0700292 * Activities that specify No History must be removed once the user navigates away from them.
293 * If the device goes to sleep with such an activity in the paused state then we save it here
294 * and finish it later if another activity replaces it on wakeup.
295 */
296 ActivityRecord mLastNoHistoryActivity = null;
297
298 /**
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700299 * Current activity that is resumed, or null if there is none.
300 */
301 ActivityRecord mResumedActivity = null;
Craig Mautnerd74f7d72013-02-26 13:41:02 -0800302
Craig Mautner5eda9b32013-07-02 11:58:16 -0700303 // The topmost Activity passed to convertToTranslucent(). When non-null it means we are
304 // waiting for all Activities in mUndrawnActivitiesBelowTopTranslucent to be removed as they
305 // are drawn. When the last member of mUndrawnActivitiesBelowTopTranslucent is removed the
306 // Activity in mTranslucentActivityWaiting is notified via
307 // Activity.onTranslucentConversionComplete(false). If a timeout occurs prior to the last
308 // background activity being drawn then the same call will be made with a true value.
309 ActivityRecord mTranslucentActivityWaiting = null;
Andrii Kulian21713ac2016-10-12 22:05:05 -0700310 ArrayList<ActivityRecord> mUndrawnActivitiesBelowTopTranslucent = new ArrayList<>();
Craig Mautner5eda9b32013-07-02 11:58:16 -0700311
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700312 /**
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700313 * Set when we know we are going to be calling updateConfiguration()
314 * soon, so want to skip intermediate config checks.
315 */
316 boolean mConfigWillChange;
317
Winson Chung47900652017-04-06 18:44:25 -0700318 /**
319 * When set, will force the stack to report as invisible.
320 */
321 boolean mForceHidden = false;
322
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700323 // Whether or not this stack covers the entire screen; by default stacks are fullscreen
Todd Kennedyaab56db2015-01-30 09:39:53 -0800324 boolean mFullscreen = true;
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -0700325 // Current bounds of the stack or null if fullscreen.
326 Rect mBounds = null;
Todd Kennedyaab56db2015-01-30 09:39:53 -0800327
Andrii Kulian21713ac2016-10-12 22:05:05 -0700328 private boolean mUpdateBoundsDeferred;
329 private boolean mUpdateBoundsDeferredCalled;
330 private final Rect mDeferredBounds = new Rect();
331 private final Rect mDeferredTaskBounds = new Rect();
332 private final Rect mDeferredTaskInsetBounds = new Rect();
Jorim Jaggi192086e2016-03-11 17:17:03 +0100333
Dianne Hackborn2286cdc2013-07-01 19:10:06 -0700334 long mLaunchStartTime = 0;
335 long mFullyDrawnStartTime = 0;
Craig Mautnerd74f7d72013-02-26 13:41:02 -0800336
Craig Mautner858d8a62013-04-23 17:08:34 -0700337 int mCurrentUser;
Amith Yamasani742a6712011-05-04 14:49:28 -0700338
Craig Mautnerc00204b2013-03-05 15:02:14 -0800339 final int mStackId;
Craig Mautnere0a38842013-12-16 16:14:02 -0800340 /** The other stacks, in order, on the attached display. Updated at attach/detach time. */
Andrii Kulian94e82d9b02017-07-13 15:33:06 -0700341 // TODO: This list doesn't belong here...
Craig Mautnere0a38842013-12-16 16:14:02 -0800342 ArrayList<ActivityStack> mStacks;
343 /** The attached Display's unique identifier, or -1 if detached */
344 int mDisplayId;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800345
Andrii Kulian1e32e022016-09-16 15:29:34 -0700346 /** Temp variables used during override configuration update. */
347 private final SparseArray<Configuration> mTmpConfigs = new SparseArray<>();
348 private final SparseArray<Rect> mTmpBounds = new SparseArray<>();
349 private final SparseArray<Rect> mTmpInsetBounds = new SparseArray<>();
Wale Ogunwale1666e312016-12-16 11:27:18 -0800350 private final Rect mTmpRect2 = new Rect();
Andrii Kulian1e32e022016-09-16 15:29:34 -0700351
Craig Mautner27084302013-03-25 08:05:25 -0700352 /** Run all ActivityStacks through this */
Winson Chung5af42fc2017-03-24 17:11:33 -0700353 protected final ActivityStackSupervisor mStackSupervisor;
Craig Mautner27084302013-03-25 08:05:25 -0700354
Filip Gruszczynskie5390e72015-08-18 16:39:00 -0700355 private final LaunchingTaskPositioner mTaskPositioner;
356
Jorim Jaggife762342016-10-13 14:33:27 +0200357 private boolean mTopActivityOccludesKeyguard;
358 private ActivityRecord mTopDismissingKeyguardActivity;
359
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700360 static final int PAUSE_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 1;
Craig Mautner0eea92c2013-05-16 13:35:39 -0700361 static final int DESTROY_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 2;
362 static final int LAUNCH_TICK_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 3;
363 static final int STOP_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 4;
364 static final int DESTROY_ACTIVITIES_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 5;
Craig Mautner5eda9b32013-07-02 11:58:16 -0700365 static final int TRANSLUCENT_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 6;
Dianne Hackborn755c8bf2012-05-07 15:06:09 -0700366
Andrii Kulian21713ac2016-10-12 22:05:05 -0700367 private static class ScheduleDestroyArgs {
Dianne Hackborn755c8bf2012-05-07 15:06:09 -0700368 final ProcessRecord mOwner;
Dianne Hackborn755c8bf2012-05-07 15:06:09 -0700369 final String mReason;
Craig Mautneree2e45a2014-06-27 12:10:03 -0700370 ScheduleDestroyArgs(ProcessRecord owner, String reason) {
Dianne Hackborn755c8bf2012-05-07 15:06:09 -0700371 mOwner = owner;
Dianne Hackborn755c8bf2012-05-07 15:06:09 -0700372 mReason = reason;
373 }
374 }
375
Zoran Marcetaf958b322012-08-09 20:27:12 +0900376 final Handler mHandler;
377
Andrii Kulian21713ac2016-10-12 22:05:05 -0700378 private class ActivityStackHandler extends Handler {
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800379
Craig Mautnerc8143c62013-09-03 12:15:57 -0700380 ActivityStackHandler(Looper looper) {
Zoran Marcetaf958b322012-08-09 20:27:12 +0900381 super(looper);
382 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700383
Zoran Marcetaf958b322012-08-09 20:27:12 +0900384 @Override
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700385 public void handleMessage(Message msg) {
386 switch (msg.what) {
387 case PAUSE_TIMEOUT_MSG: {
Dianne Hackbornbe707852011-11-11 14:32:10 -0800388 ActivityRecord r = (ActivityRecord)msg.obj;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700389 // We don't at this point know if the activity is fullscreen,
390 // so we need to be conservative and assume it isn't.
Dianne Hackbornbe707852011-11-11 14:32:10 -0800391 Slog.w(TAG, "Activity pause timeout for " + r);
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -0700392 synchronized (mService) {
393 if (r.app != null) {
Craig Mautnerf7bfefb2013-05-16 17:30:44 -0700394 mService.logAppTooSlow(r.app, r.pauseTime, "pausing " + r);
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -0700395 }
Dianne Hackborna4e102e2014-09-04 22:52:27 -0700396 activityPausedLocked(r.appToken, true);
Craig Mautnerd2328952013-03-05 12:46:26 -0800397 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700398 } break;
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -0700399 case LAUNCH_TICK_MSG: {
400 ActivityRecord r = (ActivityRecord)msg.obj;
401 synchronized (mService) {
402 if (r.continueLaunchTickingLocked()) {
Craig Mautnerf7bfefb2013-05-16 17:30:44 -0700403 mService.logAppTooSlow(r.app, r.launchTickTime, "launching " + r);
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -0700404 }
405 }
406 } break;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700407 case DESTROY_TIMEOUT_MSG: {
Dianne Hackbornbe707852011-11-11 14:32:10 -0800408 ActivityRecord r = (ActivityRecord)msg.obj;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700409 // We don't at this point know if the activity is fullscreen,
410 // so we need to be conservative and assume it isn't.
Dianne Hackbornbe707852011-11-11 14:32:10 -0800411 Slog.w(TAG, "Activity destroy timeout for " + r);
Craig Mautnerd2328952013-03-05 12:46:26 -0800412 synchronized (mService) {
Craig Mautner299f9602015-01-26 09:47:33 -0800413 activityDestroyedLocked(r != null ? r.appToken : null, "destroyTimeout");
Craig Mautnerd2328952013-03-05 12:46:26 -0800414 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700415 } break;
Dianne Hackborn162bc0e2012-04-09 14:06:16 -0700416 case STOP_TIMEOUT_MSG: {
417 ActivityRecord r = (ActivityRecord)msg.obj;
418 // We don't at this point know if the activity is fullscreen,
419 // so we need to be conservative and assume it isn't.
420 Slog.w(TAG, "Activity stop timeout for " + r);
421 synchronized (mService) {
422 if (r.isInHistory()) {
Andrii Kulian21713ac2016-10-12 22:05:05 -0700423 r.activityStoppedLocked(null /* icicle */,
424 null /* persistentState */, null /* description */);
Dianne Hackborn162bc0e2012-04-09 14:06:16 -0700425 }
426 }
427 } break;
Dianne Hackborn755c8bf2012-05-07 15:06:09 -0700428 case DESTROY_ACTIVITIES_MSG: {
429 ScheduleDestroyArgs args = (ScheduleDestroyArgs)msg.obj;
430 synchronized (mService) {
Craig Mautneree2e45a2014-06-27 12:10:03 -0700431 destroyActivitiesLocked(args.mOwner, args.mReason);
Dianne Hackborn755c8bf2012-05-07 15:06:09 -0700432 }
Craig Mautner5eda9b32013-07-02 11:58:16 -0700433 } break;
434 case TRANSLUCENT_TIMEOUT_MSG: {
435 synchronized (mService) {
436 notifyActivityDrawnLocked(null);
437 }
438 } break;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700439 }
440 }
Craig Mautner4b71aa12012-12-27 17:20:01 -0800441 }
442
Craig Mautner34b73df2014-01-12 21:11:08 -0800443 int numActivities() {
Craig Mautner000f0022013-02-26 15:04:29 -0800444 int count = 0;
445 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
446 count += mTaskHistory.get(taskNdx).mActivities.size();
447 }
448 return count;
449 }
450
Andrii Kulian94e82d9b02017-07-13 15:33:06 -0700451 ActivityStack(ActivityStackSupervisor.ActivityDisplay display, int stackId,
452 ActivityStackSupervisor supervisor, RecentTasks recentTasks, boolean onTop) {
453 mStackSupervisor = supervisor;
454 mService = supervisor.mService;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800455 mHandler = new ActivityStackHandler(mService.mHandler.getLooper());
456 mWindowManager = mService.mWindowManager;
Andrii Kulian94e82d9b02017-07-13 15:33:06 -0700457 mStackId = stackId;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700458 mCurrentUser = mService.mUserController.getCurrentUserIdLocked();
Wale Ogunwalec82f2f52014-12-09 09:32:50 -0800459 mRecentTasks = recentTasks;
Filip Gruszczynskie5390e72015-08-18 16:39:00 -0700460 mTaskPositioner = mStackId == FREEFORM_WORKSPACE_STACK_ID
461 ? new LaunchingTaskPositioner() : null;
Wale Ogunwale1666e312016-12-16 11:27:18 -0800462 mTmpRect2.setEmpty();
Wale Ogunwale687b4272017-07-27 02:56:23 -0700463 final Configuration overrideConfig = getOverrideConfiguration();
Winson Chung55893332017-02-17 17:13:10 -0800464 mWindowContainerController = createStackWindowController(display.mDisplayId, onTop,
Wale Ogunwale687b4272017-07-27 02:56:23 -0700465 mTmpRect2, overrideConfig);
466 onOverrideConfigurationChanged(overrideConfig);
Andrii Kulian94e82d9b02017-07-13 15:33:06 -0700467 mStackSupervisor.mStacks.put(mStackId, this);
Wale Ogunwale1666e312016-12-16 11:27:18 -0800468 postAddToDisplay(display, mTmpRect2.isEmpty() ? null : mTmpRect2, onTop);
469 }
470
Wale Ogunwale687b4272017-07-27 02:56:23 -0700471 T createStackWindowController(int displayId, boolean onTop, Rect outBounds,
472 Configuration outOverrideConfig) {
473 return (T) new StackWindowController(mStackId, this, displayId, onTop, outBounds,
474 outOverrideConfig);
Winson Chung55893332017-02-17 17:13:10 -0800475 }
476
477 T getWindowContainerController() {
Wale Ogunwale1666e312016-12-16 11:27:18 -0800478 return mWindowContainerController;
Filip Gruszczynskie5390e72015-08-18 16:39:00 -0700479 }
480
Andrii Kulian839def92016-11-02 10:58:58 -0700481 /** Adds the stack to specified display and calls WindowManager to do the same. */
Wale Ogunwale1666e312016-12-16 11:27:18 -0800482 void reparent(ActivityStackSupervisor.ActivityDisplay activityDisplay, boolean onTop) {
483 removeFromDisplay();
484 mTmpRect2.setEmpty();
Wale Ogunwale1666e312016-12-16 11:27:18 -0800485 postAddToDisplay(activityDisplay, mTmpRect2.isEmpty() ? null : mTmpRect2, onTop);
Andrii Kulian250d6532017-02-08 23:30:45 -0800486 adjustFocusToNextFocusableStackLocked("reparent", true /* allowFocusSelf */);
487 mStackSupervisor.resumeFocusedStackTopActivityLocked();
Andrii Kulian51c1b672017-04-07 18:39:32 -0700488 // Update visibility of activities before notifying WM. This way it won't try to resize
489 // windows that are no longer visible.
490 mStackSupervisor.ensureActivitiesVisibleLocked(null /* starting */, 0 /* configChanges */,
491 !PRESERVE_WINDOWS);
492 mWindowContainerController.reparent(activityDisplay.mDisplayId, mTmpRect2, onTop);
Andrii Kulian839def92016-11-02 10:58:58 -0700493 }
494
495 /**
496 * Updates internal state after adding to new display.
497 * @param activityDisplay New display to which this stack was attached.
498 * @param bounds Updated bounds.
499 */
500 private void postAddToDisplay(ActivityStackSupervisor.ActivityDisplay activityDisplay,
Wale Ogunwale1666e312016-12-16 11:27:18 -0800501 Rect bounds, boolean onTop) {
Filip Gruszczynskie5390e72015-08-18 16:39:00 -0700502 mDisplayId = activityDisplay.mDisplayId;
503 mStacks = activityDisplay.mStacks;
Wale Ogunwale1666e312016-12-16 11:27:18 -0800504 mBounds = bounds != null ? new Rect(bounds) : null;
Filip Gruszczynskie5390e72015-08-18 16:39:00 -0700505 mFullscreen = mBounds == null;
506 if (mTaskPositioner != null) {
507 mTaskPositioner.setDisplay(activityDisplay.mDisplay);
508 mTaskPositioner.configure(mBounds);
509 }
Andrii Kulian1779e612016-10-12 21:58:25 -0700510 onParentChanged();
Wale Ogunwale961f4852016-02-01 20:25:54 -0800511
Winson Chung7c3ede32017-03-14 14:18:34 -0700512 activityDisplay.attachStack(this, findStackInsertIndex(onTop));
Wale Ogunwale961f4852016-02-01 20:25:54 -0800513 if (mStackId == DOCKED_STACK_ID) {
514 // If we created a docked stack we want to resize it so it resizes all other stacks
515 // in the system.
516 mStackSupervisor.resizeDockedStackLocked(
517 mBounds, null, null, null, null, PRESERVE_WINDOWS);
518 }
Filip Gruszczynskie5390e72015-08-18 16:39:00 -0700519 }
520
Andrii Kulian839def92016-11-02 10:58:58 -0700521 /**
Andrii Kulian839def92016-11-02 10:58:58 -0700522 * Updates the inner state of the stack to remove it from its current parent, so it can be
523 * either destroyed completely or re-parented.
524 */
525 private void removeFromDisplay() {
Andrii Kulian94e82d9b02017-07-13 15:33:06 -0700526 final ActivityStackSupervisor.ActivityDisplay display = getDisplay();
527 if (display != null) {
528 display.detachStack(this);
529 }
530 mDisplayId = INVALID_DISPLAY;
Filip Gruszczynskie5390e72015-08-18 16:39:00 -0700531 mStacks = null;
532 if (mTaskPositioner != null) {
533 mTaskPositioner.reset();
534 }
Jorim Jaggi899327f2016-02-25 20:44:18 -0500535 if (mStackId == DOCKED_STACK_ID) {
536 // If we removed a docked stack we want to resize it so it resizes all other stacks
537 // in the system to fullscreen.
538 mStackSupervisor.resizeDockedStackLocked(
539 null, null, null, null, null, PRESERVE_WINDOWS);
540 }
Andrii Kulian839def92016-11-02 10:58:58 -0700541 }
542
543 /** Removes the stack completely. Also calls WindowManager to do the same on its side. */
544 void remove() {
545 removeFromDisplay();
Andrii Kulian94e82d9b02017-07-13 15:33:06 -0700546 mStackSupervisor.mStacks.remove(mStackId);
Wale Ogunwale1666e312016-12-16 11:27:18 -0800547 mWindowContainerController.removeContainer();
548 mWindowContainerController = null;
Andrii Kulian6d6fb402016-10-26 16:15:25 -0700549 onParentChanged();
Filip Gruszczynskie5390e72015-08-18 16:39:00 -0700550 }
551
Andrii Kulian94e82d9b02017-07-13 15:33:06 -0700552 ActivityStackSupervisor.ActivityDisplay getDisplay() {
553 return mStackSupervisor.getActivityDisplay(mDisplayId);
554 }
555
Andrii Kulian21713ac2016-10-12 22:05:05 -0700556 void getDisplaySize(Point out) {
Andrii Kulian94e82d9b02017-07-13 15:33:06 -0700557 getDisplay().mDisplay.getSize(out);
Winsonc809cbb2015-11-02 12:06:15 -0800558 }
559
Matthew Ngaa2b6202017-02-10 14:48:21 -0800560 /**
561 * @see ActivityStack.getStackDockedModeBounds(Rect, Rect, Rect, boolean)
562 */
563 void getStackDockedModeBounds(Rect currentTempTaskBounds, Rect outStackBounds,
564 Rect outTempTaskBounds, boolean ignoreVisibility) {
565 mWindowContainerController.getStackDockedModeBounds(currentTempTaskBounds,
566 outStackBounds, outTempTaskBounds, ignoreVisibility);
Wale Ogunwale1666e312016-12-16 11:27:18 -0800567 }
568
569 void prepareFreezingTaskBounds() {
570 mWindowContainerController.prepareFreezingTaskBounds();
571 }
572
Wale Ogunwale1666e312016-12-16 11:27:18 -0800573 void getWindowContainerBounds(Rect outBounds) {
574 if (mWindowContainerController != null) {
575 mWindowContainerController.getBounds(outBounds);
Winson Chungb00dc5e2017-01-25 09:44:25 -0800576 return;
Wale Ogunwale1666e312016-12-16 11:27:18 -0800577 }
578 outBounds.setEmpty();
579 }
580
Matthew Ngaa2b6202017-02-10 14:48:21 -0800581 void getBoundsForNewConfiguration(Rect outBounds) {
582 mWindowContainerController.getBoundsForNewConfiguration(outBounds);
Wale Ogunwale1666e312016-12-16 11:27:18 -0800583 }
584
585 void positionChildWindowContainerAtTop(TaskRecord child) {
586 mWindowContainerController.positionChildAtTop(child.getWindowContainerController(),
587 true /* includingParents */);
588 }
589
Jorim Jaggi192086e2016-03-11 17:17:03 +0100590 /**
Winson Chung8bca9e42017-04-16 15:59:43 -0700591 * Returns whether to defer the scheduling of the multi-window mode.
592 */
593 boolean deferScheduleMultiWindowModeChanged() {
594 return false;
595 }
596
597 /**
Jorim Jaggi192086e2016-03-11 17:17:03 +0100598 * Defers updating the bounds of the stack. If the stack was resized/repositioned while
599 * deferring, the bounds will update in {@link #continueUpdateBounds()}.
600 */
601 void deferUpdateBounds() {
602 if (!mUpdateBoundsDeferred) {
603 mUpdateBoundsDeferred = true;
604 mUpdateBoundsDeferredCalled = false;
605 }
606 }
607
608 /**
609 * Continues updating bounds after updates have been deferred. If there was a resize attempt
610 * between {@link #deferUpdateBounds()} and {@link #continueUpdateBounds()}, the stack will
611 * be resized to that bounds.
612 */
613 void continueUpdateBounds() {
614 final boolean wasDeferred = mUpdateBoundsDeferred;
615 mUpdateBoundsDeferred = false;
616 if (wasDeferred && mUpdateBoundsDeferredCalled) {
Wale Ogunwale1666e312016-12-16 11:27:18 -0800617 resize(mDeferredBounds.isEmpty() ? null : mDeferredBounds,
Jorim Jaggi192086e2016-03-11 17:17:03 +0100618 mDeferredTaskBounds.isEmpty() ? null : mDeferredTaskBounds,
619 mDeferredTaskInsetBounds.isEmpty() ? null : mDeferredTaskInsetBounds);
620 }
621 }
622
623 boolean updateBoundsAllowed(Rect bounds, Rect tempTaskBounds,
624 Rect tempTaskInsetBounds) {
625 if (!mUpdateBoundsDeferred) {
626 return true;
627 }
628 if (bounds != null) {
629 mDeferredBounds.set(bounds);
630 } else {
631 mDeferredBounds.setEmpty();
632 }
633 if (tempTaskBounds != null) {
634 mDeferredTaskBounds.set(tempTaskBounds);
635 } else {
636 mDeferredTaskBounds.setEmpty();
637 }
638 if (tempTaskInsetBounds != null) {
639 mDeferredTaskInsetBounds.set(tempTaskInsetBounds);
640 } else {
641 mDeferredTaskInsetBounds.setEmpty();
642 }
643 mUpdateBoundsDeferredCalled = true;
644 return false;
645 }
646
Filip Gruszczynskie5390e72015-08-18 16:39:00 -0700647 void setBounds(Rect bounds) {
648 mBounds = mFullscreen ? null : new Rect(bounds);
Filip Gruszczynski9ac01a72015-09-04 11:12:17 -0700649 if (mTaskPositioner != null) {
650 mTaskPositioner.configure(bounds);
651 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700652 }
Craig Mautner5962b122012-10-05 14:45:52 -0700653
Wale Ogunwale42f07d92017-05-01 21:32:58 -0700654 ActivityRecord topRunningActivityLocked() {
Winson Chung3f103eb2017-04-12 21:53:59 -0700655 return topRunningActivityLocked(false /* focusableOnly */);
656 }
657
Jorim Jaggiea039a82017-08-02 14:37:49 +0200658 void getAllRunningVisibleActivitiesLocked(ArrayList<ActivityRecord> outActivities) {
659 outActivities.clear();
660 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
661 mTaskHistory.get(taskNdx).getAllRunningVisibleActivitiesLocked(outActivities);
662 }
663 }
664
Wale Ogunwale42f07d92017-05-01 21:32:58 -0700665 private ActivityRecord topRunningActivityLocked(boolean focusableOnly) {
Craig Mautnerd74f7d72013-02-26 13:41:02 -0800666 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -0700667 ActivityRecord r = mTaskHistory.get(taskNdx).topRunningActivityLocked();
Winson Chung3f103eb2017-04-12 21:53:59 -0700668 if (r != null && (!focusableOnly || r.isFocusable())) {
Craig Mautner6b74cb52013-09-27 17:02:21 -0700669 return r;
Craig Mautner11bf9a52013-02-19 14:08:51 -0800670 }
671 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700672 return null;
673 }
674
Wale Ogunwale42f07d92017-05-01 21:32:58 -0700675 ActivityRecord topRunningNonOverlayTaskActivity() {
676 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
677 final TaskRecord task = mTaskHistory.get(taskNdx);
678 final ArrayList<ActivityRecord> activities = task.mActivities;
679 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
680 final ActivityRecord r = activities.get(activityNdx);
681 if (!r.finishing && !r.mTaskOverlay) {
682 return r;
683 }
684 }
685 }
686 return null;
687 }
688
689 ActivityRecord topRunningNonDelayedActivityLocked(ActivityRecord notTop) {
Craig Mautnerd74f7d72013-02-26 13:41:02 -0800690 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
691 final TaskRecord task = mTaskHistory.get(taskNdx);
Craig Mautner11bf9a52013-02-19 14:08:51 -0800692 final ArrayList<ActivityRecord> activities = task.mActivities;
Craig Mautnerd74f7d72013-02-26 13:41:02 -0800693 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
694 ActivityRecord r = activities.get(activityNdx);
Chong Zhang87761972016-08-22 13:53:24 -0700695 if (!r.finishing && !r.delayedResume && r != notTop && r.okToShowLocked()) {
Craig Mautner11bf9a52013-02-19 14:08:51 -0800696 return r;
697 }
698 }
699 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700700 return null;
701 }
702
703 /**
704 * This is a simplified version of topRunningActivityLocked that provides a number of
705 * optional skip-over modes. It is intended for use with the ActivityController hook only.
Craig Mautner9658b312013-02-28 10:55:59 -0800706 *
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700707 * @param token If non-null, any history records matching this token will be skipped.
708 * @param taskId If non-zero, we'll attempt to skip over records with the same task ID.
Craig Mautner9658b312013-02-28 10:55:59 -0800709 *
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700710 * @return Returns the HistoryRecord of the next activity on the stack.
711 */
712 final ActivityRecord topRunningActivityLocked(IBinder token, int taskId) {
Craig Mautner11bf9a52013-02-19 14:08:51 -0800713 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
714 TaskRecord task = mTaskHistory.get(taskNdx);
715 if (task.taskId == taskId) {
716 continue;
717 }
718 ArrayList<ActivityRecord> activities = task.mActivities;
719 for (int i = activities.size() - 1; i >= 0; --i) {
720 final ActivityRecord r = activities.get(i);
721 // Note: the taskId check depends on real taskId fields being non-zero
Chong Zhang87761972016-08-22 13:53:24 -0700722 if (!r.finishing && (token != r.appToken) && r.okToShowLocked()) {
Craig Mautner11bf9a52013-02-19 14:08:51 -0800723 return r;
724 }
725 }
726 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700727 return null;
728 }
729
Craig Mautner8849a5e2013-04-02 16:41:03 -0700730 final ActivityRecord topActivity() {
Craig Mautner8849a5e2013-04-02 16:41:03 -0700731 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
732 ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
Craig Mautner0175b882014-09-07 18:05:31 -0700733 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
734 final ActivityRecord r = activities.get(activityNdx);
735 if (!r.finishing) {
736 return r;
737 }
Craig Mautner8849a5e2013-04-02 16:41:03 -0700738 }
739 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700740 return null;
Craig Mautner8849a5e2013-04-02 16:41:03 -0700741 }
742
Craig Mautner9e14d0f2013-05-01 11:26:09 -0700743 final TaskRecord topTask() {
744 final int size = mTaskHistory.size();
745 if (size > 0) {
746 return mTaskHistory.get(size - 1);
747 }
748 return null;
749 }
750
Winson Chung1cebea62017-06-26 17:22:27 -0700751 final TaskRecord bottomTask() {
752 if (mTaskHistory.isEmpty()) {
753 return null;
754 }
755 return mTaskHistory.get(0);
756 }
757
Craig Mautnerd2328952013-03-05 12:46:26 -0800758 TaskRecord taskForIdLocked(int id) {
759 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
760 final TaskRecord task = mTaskHistory.get(taskNdx);
761 if (task.taskId == id) {
762 return task;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800763 }
764 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700765 return null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700766 }
767
Craig Mautnerd2328952013-03-05 12:46:26 -0800768 ActivityRecord isInStackLocked(IBinder token) {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700769 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale60454db2015-01-23 16:05:07 -0800770 return isInStackLocked(r);
771 }
772
773 ActivityRecord isInStackLocked(ActivityRecord r) {
774 if (r == null) {
775 return null;
776 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700777 final TaskRecord task = r.getTask();
Andrii Kulian02b7a832016-10-06 23:11:56 -0700778 final ActivityStack stack = r.getStack();
779 if (stack != null && task.mActivities.contains(r) && mTaskHistory.contains(task)) {
780 if (stack != this) Slog.w(TAG,
Craig Mautnerd2328952013-03-05 12:46:26 -0800781 "Illegal state! task does not point to stack it is in.");
Wale Ogunwale60454db2015-01-23 16:05:07 -0800782 return r;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800783 }
Craig Mautnerd2328952013-03-05 12:46:26 -0800784 return null;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800785 }
786
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800787 boolean isInStackLocked(TaskRecord task) {
788 return mTaskHistory.contains(task);
789 }
790
791 /** Checks if there are tasks with specific UID in the stack. */
792 boolean isUidPresent(int uid) {
793 for (TaskRecord task : mTaskHistory) {
David Stevens82ea6cb2017-03-03 16:18:50 -0800794 for (ActivityRecord r : task.mActivities) {
795 if (r.getUid() == uid) {
796 return true;
797 }
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800798 }
799 }
800 return false;
801 }
802
803 /** Get all UIDs that are present in the stack. */
804 void getPresentUIDs(IntArray presentUIDs) {
805 for (TaskRecord task : mTaskHistory) {
David Stevens82ea6cb2017-03-03 16:18:50 -0800806 for (ActivityRecord r : task.mActivities) {
807 presentUIDs.add(r.getUid());
808 }
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800809 }
810 }
811
Winson Chungabb433b2017-03-24 09:35:42 -0700812 final void removeActivitiesFromLRUListLocked(TaskRecord task) {
813 for (ActivityRecord r : task.mActivities) {
814 mLRUActivities.remove(r);
815 }
816 }
817
Craig Mautner2420ead2013-04-01 17:13:20 -0700818 final boolean updateLRUListLocked(ActivityRecord r) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700819 final boolean hadit = mLRUActivities.remove(r);
820 mLRUActivities.add(r);
821 return hadit;
822 }
823
Craig Mautnerde4ef022013-04-07 19:01:33 -0700824 final boolean isHomeStack() {
825 return mStackId == HOME_STACK_ID;
826 }
827
Winson Chung91e5c882017-04-21 14:44:38 -0700828 final boolean isRecentsStack() {
829 return mStackId == RECENTS_STACK_ID;
830 }
831
Matthew Ngae1ff4f2016-11-10 15:49:14 -0800832 final boolean isHomeOrRecentsStack() {
833 return StackId.isHomeOrRecentsStack(mStackId);
834 }
835
Winson Chung0583d3d2015-12-18 10:03:12 -0500836 final boolean isDockedStack() {
837 return mStackId == DOCKED_STACK_ID;
838 }
839
840 final boolean isPinnedStack() {
841 return mStackId == PINNED_STACK_ID;
842 }
843
Winson Chung83471632016-12-13 11:02:12 -0800844 final boolean isAssistantStack() {
845 return mStackId == ASSISTANT_STACK_ID;
846 }
847
Craig Mautnere0a38842013-12-16 16:14:02 -0800848 final boolean isOnHomeDisplay() {
Andrii Kulian94e82d9b02017-07-13 15:33:06 -0700849 return isAttached() && mDisplayId == DEFAULT_DISPLAY;
Craig Mautnere0a38842013-12-16 16:14:02 -0800850 }
851
Wale Ogunwaleeae451e2015-08-04 15:20:50 -0700852 void moveToFront(String reason) {
853 moveToFront(reason, null);
854 }
855
856 /**
857 * @param reason The reason for moving the stack to the front.
858 * @param task If non-null, the task will be moved to the top of the stack.
859 * */
860 void moveToFront(String reason, TaskRecord task) {
Wale Ogunwale1e60e0c2015-10-28 13:36:10 -0700861 if (!isAttached()) {
862 return;
863 }
Wale Ogunwale925d0d12015-09-23 15:40:07 -0700864
Wale Ogunwale1e60e0c2015-10-28 13:36:10 -0700865 mStacks.remove(this);
Winson Chung7c3ede32017-03-14 14:18:34 -0700866 mStacks.add(findStackInsertIndex(ON_TOP), this);
Andrii Kulian839def92016-11-02 10:58:58 -0700867 mStackSupervisor.setFocusStackUnchecked(reason, this);
Wale Ogunwale1e60e0c2015-10-28 13:36:10 -0700868 if (task != null) {
869 insertTaskAtTop(task, null);
Wale Ogunwaleaa47c122016-09-23 16:39:53 -0700870 return;
Wale Ogunwale1e60e0c2015-10-28 13:36:10 -0700871 }
Wale Ogunwaleaa47c122016-09-23 16:39:53 -0700872
873 task = topTask();
Wale Ogunwale1e60e0c2015-10-28 13:36:10 -0700874 if (task != null) {
Wale Ogunwale1666e312016-12-16 11:27:18 -0800875 mWindowContainerController.positionChildAtTop(task.getWindowContainerController(),
876 true /* includingParents */);
Craig Mautner4a1cb222013-12-04 16:14:06 -0800877 }
Craig Mautnere0a38842013-12-16 16:14:02 -0800878 }
879
Jiaquan Hee13e9642016-06-15 15:16:13 -0700880 /**
881 * @param task If non-null, the task will be moved to the back of the stack.
882 * */
Andrii Kulian21713ac2016-10-12 22:05:05 -0700883 private void moveToBack(TaskRecord task) {
Jiaquan Hee13e9642016-06-15 15:16:13 -0700884 if (!isAttached()) {
885 return;
886 }
887
888 mStacks.remove(this);
889 mStacks.add(0, this);
890
891 if (task != null) {
892 mTaskHistory.remove(task);
893 mTaskHistory.add(0, task);
894 updateTaskMovement(task, false);
Wale Ogunwale1666e312016-12-16 11:27:18 -0800895 mWindowContainerController.positionChildAtBottom(task.getWindowContainerController());
Jiaquan Hee13e9642016-06-15 15:16:13 -0700896 }
897 }
898
Winson Chung7c3ede32017-03-14 14:18:34 -0700899 /**
900 * @return the index to insert a new stack into, taking the always-on-top stacks into account.
901 */
902 private int findStackInsertIndex(boolean onTop) {
903 if (onTop) {
904 int addIndex = mStacks.size();
905 if (addIndex > 0) {
906 final ActivityStack topStack = mStacks.get(addIndex - 1);
907 if (StackId.isAlwaysOnTop(topStack.mStackId) && topStack != this) {
908 // If the top stack is always on top, we move this stack just below it.
909 addIndex--;
910 }
911 }
912 return addIndex;
913 } else {
914 return 0;
915 }
916 }
917
Wale Ogunwaled046a012015-12-24 13:05:59 -0800918 boolean isFocusable() {
Wale Ogunwale4cea0f52015-12-25 06:30:31 -0800919 if (StackId.canReceiveKeys(mStackId)) {
920 return true;
921 }
922 // The stack isn't focusable. See if its top activity is focusable to force focus on the
923 // stack.
924 final ActivityRecord r = topRunningActivityLocked();
925 return r != null && r.isFocusable();
Wale Ogunwaled046a012015-12-24 13:05:59 -0800926 }
927
Craig Mautnere0a38842013-12-16 16:14:02 -0800928 final boolean isAttached() {
929 return mStacks != null;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800930 }
931
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700932 /**
Wale Ogunwale39381972015-12-17 17:15:29 -0800933 * Returns the top activity in any existing task matching the given Intent in the input result.
934 * Returns null if no such task is found.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700935 */
Wale Ogunwale39381972015-12-17 17:15:29 -0800936 void findTaskLocked(ActivityRecord target, FindTaskResult result) {
Craig Mautnerac6f8432013-07-17 13:24:59 -0700937 Intent intent = target.intent;
938 ActivityInfo info = target.info;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700939 ComponentName cls = intent.getComponent();
940 if (info.targetActivity != null) {
941 cls = new ComponentName(info.packageName, info.targetActivity);
942 }
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700943 final int userId = UserHandle.getUserId(info.applicationInfo.uid);
Craig Mautnerd00f4742014-03-12 14:17:26 -0700944 boolean isDocument = intent != null & intent.isDocument();
945 // If documentData is non-null then it must match the existing task data.
946 Uri documentData = isDocument ? intent.getData() : null;
Craig Mautner000f0022013-02-26 15:04:29 -0800947
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700948 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + target + " in " + this);
Craig Mautner000f0022013-02-26 15:04:29 -0800949 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
950 final TaskRecord task = mTaskHistory.get(taskNdx);
Dianne Hackborn91097de2014-04-04 18:02:06 -0700951 if (task.voiceSession != null) {
952 // We never match voice sessions; those always run independently.
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700953 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": voice session");
Dianne Hackborn91097de2014-04-04 18:02:06 -0700954 continue;
955 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700956 if (task.userId != userId) {
957 // Looking for a different task.
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700958 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": different user");
Craig Mautnerac6f8432013-07-17 13:24:59 -0700959 continue;
960 }
Craig Mautner000f0022013-02-26 15:04:29 -0800961 final ActivityRecord r = task.getTopActivity();
962 if (r == null || r.finishing || r.userId != userId ||
963 r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700964 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": mismatch root " + r);
Craig Mautner000f0022013-02-26 15:04:29 -0800965 continue;
966 }
Chong Zhangb546f7e2015-08-05 14:21:36 -0700967 if (r.mActivityType != target.mActivityType) {
968 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": mismatch activity type");
969 continue;
970 }
Craig Mautner000f0022013-02-26 15:04:29 -0800971
Craig Mautnerd00f4742014-03-12 14:17:26 -0700972 final Intent taskIntent = task.intent;
973 final Intent affinityIntent = task.affinityIntent;
974 final boolean taskIsDocument;
975 final Uri taskDocumentData;
976 if (taskIntent != null && taskIntent.isDocument()) {
977 taskIsDocument = true;
978 taskDocumentData = taskIntent.getData();
979 } else if (affinityIntent != null && affinityIntent.isDocument()) {
980 taskIsDocument = true;
981 taskDocumentData = affinityIntent.getData();
982 } else {
983 taskIsDocument = false;
984 taskDocumentData = null;
985 }
986
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700987 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Comparing existing cls="
Craig Mautnerd00f4742014-03-12 14:17:26 -0700988 + taskIntent.getComponent().flattenToShortString()
Bryce Leeaf691c02017-03-20 14:20:22 -0700989 + "/aff=" + r.getTask().rootAffinity + " to new cls="
Dianne Hackborn2a272d42013-10-16 13:34:33 -0700990 + intent.getComponent().flattenToShortString() + "/aff=" + info.taskAffinity);
Andrii Kulian206b9fa2016-06-02 13:18:01 -0700991 // TODO Refactor to remove duplications. Check if logic can be simplified.
992 if (taskIntent != null && taskIntent.getComponent() != null &&
Craig Mautnerffcfcaa2014-06-05 09:54:38 -0700993 taskIntent.getComponent().compareTo(cls) == 0 &&
Craig Mautnerd00f4742014-03-12 14:17:26 -0700994 Objects.equals(documentData, taskDocumentData)) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700995 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching class!");
Craig Mautner000f0022013-02-26 15:04:29 -0800996 //dump();
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700997 if (DEBUG_TASKS) Slog.d(TAG_TASKS,
998 "For Intent " + intent + " bringing to top: " + r.intent);
Wale Ogunwale39381972015-12-17 17:15:29 -0800999 result.r = r;
1000 result.matchedByRootAffinity = false;
1001 break;
Craig Mautnerffcfcaa2014-06-05 09:54:38 -07001002 } else if (affinityIntent != null && affinityIntent.getComponent() != null &&
1003 affinityIntent.getComponent().compareTo(cls) == 0 &&
Craig Mautnerd00f4742014-03-12 14:17:26 -07001004 Objects.equals(documentData, taskDocumentData)) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001005 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching class!");
Craig Mautner000f0022013-02-26 15:04:29 -08001006 //dump();
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001007 if (DEBUG_TASKS) Slog.d(TAG_TASKS,
1008 "For Intent " + intent + " bringing to top: " + r.intent);
Wale Ogunwale39381972015-12-17 17:15:29 -08001009 result.r = r;
1010 result.matchedByRootAffinity = false;
1011 break;
Andrii Kulian206b9fa2016-06-02 13:18:01 -07001012 } else if (!isDocument && !taskIsDocument
Winson Chung5b895b72017-05-01 13:46:25 -07001013 && result.r == null && task.rootAffinity != null) {
Andrii Kulian206b9fa2016-06-02 13:18:01 -07001014 if (task.rootAffinity.equals(target.taskAffinity)) {
1015 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching affinity candidate!");
1016 // It is possible for multiple tasks to have the same root affinity especially
1017 // if they are in separate stacks. We save off this candidate, but keep looking
1018 // to see if there is a better candidate.
1019 result.r = r;
1020 result.matchedByRootAffinity = true;
1021 }
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001022 } else if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Not a match: " + task);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001023 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001024 }
1025
1026 /**
1027 * Returns the first activity (starting from the top of the stack) that
1028 * is the same as the given activity. Returns null if no such activity
1029 * is found.
1030 */
Andrii Kuliand3bbb132016-06-16 16:00:20 -07001031 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info,
1032 boolean compareIntentFilters) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001033 ComponentName cls = intent.getComponent();
1034 if (info.targetActivity != null) {
1035 cls = new ComponentName(info.packageName, info.targetActivity);
1036 }
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07001037 final int userId = UserHandle.getUserId(info.applicationInfo.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001038
Craig Mautner000f0022013-02-26 15:04:29 -08001039 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
Wale Ogunwale3fcb4a82015-04-06 14:00:13 -07001040 final TaskRecord task = mTaskHistory.get(taskNdx);
Craig Mautnerac6f8432013-07-17 13:24:59 -07001041 final ArrayList<ActivityRecord> activities = task.mActivities;
Wale Ogunwale3fcb4a82015-04-06 14:00:13 -07001042
Craig Mautner000f0022013-02-26 15:04:29 -08001043 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
1044 ActivityRecord r = activities.get(activityNdx);
Chong Zhang87761972016-08-22 13:53:24 -07001045 if (!r.okToShowLocked()) {
Wale Ogunwale25073dd2015-07-21 16:54:54 -07001046 continue;
Wale Ogunwale3fcb4a82015-04-06 14:00:13 -07001047 }
Andrii Kuliand3bbb132016-06-16 16:00:20 -07001048 if (!r.finishing && r.userId == userId) {
1049 if (compareIntentFilters) {
1050 if (r.intent.filterEquals(intent)) {
1051 return r;
1052 }
1053 } else {
1054 if (r.intent.getComponent().equals(cls)) {
1055 return r;
1056 }
1057 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001058 }
1059 }
1060 }
1061
1062 return null;
1063 }
1064
Amith Yamasani742a6712011-05-04 14:49:28 -07001065 /*
Craig Mautnerac6f8432013-07-17 13:24:59 -07001066 * Move the activities around in the stack to bring a user to the foreground.
Amith Yamasani742a6712011-05-04 14:49:28 -07001067 */
Craig Mautner93529a42013-10-04 15:03:13 -07001068 final void switchUserLocked(int userId) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001069 if (mCurrentUser == userId) {
Craig Mautner93529a42013-10-04 15:03:13 -07001070 return;
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001071 }
1072 mCurrentUser = userId;
1073
1074 // Move userId's tasks to the top.
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001075 int index = mTaskHistory.size();
Craig Mautnerdb5c4fb2013-11-06 13:55:08 -08001076 for (int i = 0; i < index; ) {
Wale Ogunwale3fcb4a82015-04-06 14:00:13 -07001077 final TaskRecord task = mTaskHistory.get(i);
1078
Chong Zhang87761972016-08-22 13:53:24 -07001079 if (task.okToShowLocked()) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001080 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "switchUserLocked: stack=" + getStackId() +
Craig Mautner4f1df4f2013-10-15 15:44:14 -07001081 " moving " + task + " to top");
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001082 mTaskHistory.remove(i);
1083 mTaskHistory.add(task);
1084 --index;
Craig Mautnerdb5c4fb2013-11-06 13:55:08 -08001085 // Use same value for i.
1086 } else {
1087 ++i;
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001088 }
1089 }
Amith Yamasani742a6712011-05-04 14:49:28 -07001090 }
1091
Craig Mautner2420ead2013-04-01 17:13:20 -07001092 void minimalResumeActivityLocked(ActivityRecord r) {
Wale Ogunwale5658e4b2016-02-12 12:22:19 -08001093 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + r + " (starting new instance)"
1094 + " callers=" + Debug.getCallers(5));
Chong Zhang6cda19c2016-06-14 19:07:56 -07001095 setResumedActivityLocked(r, "minimalResumeActivityLocked");
Andrii Kulian21713ac2016-10-12 22:05:05 -07001096 r.completeResumeLocked();
Craig Mautner1e8b8722013-10-14 18:24:52 -07001097 setLaunchTime(r);
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07001098 if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE,
1099 "Launch completed; removing icicle of " + r.icicle);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001100 }
1101
Filip Gruszczynski3d82ed62015-12-10 10:41:39 -08001102 void addRecentActivityLocked(ActivityRecord r) {
Chong Zhang45c25ce2015-08-10 22:18:26 -07001103 if (r != null) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001104 final TaskRecord task = r.getTask();
1105 mRecentTasks.addLocked(task);
1106 task.touchActiveTime();
Chong Zhang45c25ce2015-08-10 22:18:26 -07001107 }
1108 }
1109
Narayan Kamath7829c812015-06-08 17:39:43 +01001110 private void startLaunchTraces(String packageName) {
Dianne Hackborncee04b52013-07-03 17:01:28 -07001111 if (mFullyDrawnStartTime != 0) {
1112 Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
1113 }
Narayan Kamath7829c812015-06-08 17:39:43 +01001114 Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "launching: " + packageName, 0);
Dianne Hackborncee04b52013-07-03 17:01:28 -07001115 Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
1116 }
1117
1118 private void stopFullyDrawnTraceIfNeeded() {
1119 if (mFullyDrawnStartTime != 0 && mLaunchStartTime == 0) {
1120 Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
1121 mFullyDrawnStartTime = 0;
1122 }
1123 }
1124
Craig Mautnere79d42682013-04-01 19:01:53 -07001125 void setLaunchTime(ActivityRecord r) {
Dianne Hackborn2286cdc2013-07-01 19:10:06 -07001126 if (r.displayStartTime == 0) {
1127 r.fullyDrawnStartTime = r.displayStartTime = SystemClock.uptimeMillis();
1128 if (mLaunchStartTime == 0) {
Narayan Kamath7829c812015-06-08 17:39:43 +01001129 startLaunchTraces(r.packageName);
Dianne Hackborn2286cdc2013-07-01 19:10:06 -07001130 mLaunchStartTime = mFullyDrawnStartTime = r.displayStartTime;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001131 }
Dianne Hackborn2286cdc2013-07-01 19:10:06 -07001132 } else if (mLaunchStartTime == 0) {
Narayan Kamath7829c812015-06-08 17:39:43 +01001133 startLaunchTraces(r.packageName);
Dianne Hackborn2286cdc2013-07-01 19:10:06 -07001134 mLaunchStartTime = mFullyDrawnStartTime = SystemClock.uptimeMillis();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001135 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001136 }
Craig Mautneraab647e2013-02-28 16:31:36 -08001137
Andrii Kulian21713ac2016-10-12 22:05:05 -07001138 private void clearLaunchTime(ActivityRecord r) {
Craig Mautner5c494542013-09-06 11:59:38 -07001139 // Make sure that there is no activity waiting for this to launch.
1140 if (mStackSupervisor.mWaitingActivityLaunched.isEmpty()) {
1141 r.displayStartTime = r.fullyDrawnStartTime = 0;
1142 } else {
1143 mStackSupervisor.removeTimeoutsForActivityLocked(r);
1144 mStackSupervisor.scheduleIdleTimeoutLocked(r);
1145 }
Dianne Hackborn2286cdc2013-07-01 19:10:06 -07001146 }
1147
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001148 void awakeFromSleepingLocked() {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001149 // Ensure activities are no longer sleeping.
Craig Mautnerd44711d2013-02-23 11:24:36 -08001150 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
1151 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
1152 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
1153 activities.get(activityNdx).setSleeping(false);
1154 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001155 }
Craig Mautnerf49b0a42014-11-20 15:06:40 -08001156 if (mPausingActivity != null) {
1157 Slog.d(TAG, "awakeFromSleepingLocked: previously pausing activity didn't pause");
1158 activityPausedLocked(mPausingActivity.appToken, true);
1159 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001160 }
1161
Todd Kennedy39bfee52016-02-24 10:28:21 -08001162 void updateActivityApplicationInfoLocked(ApplicationInfo aInfo) {
1163 final String packageName = aInfo.packageName;
Makoto Onuki8b9963a2017-05-18 13:56:30 -07001164 final int userId = UserHandle.getUserId(aInfo.uid);
1165
Todd Kennedy39bfee52016-02-24 10:28:21 -08001166 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
1167 final List<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
1168 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
Makoto Onuki8b9963a2017-05-18 13:56:30 -07001169 final ActivityRecord ar = activities.get(activityNdx);
1170
1171 if ((userId == ar.userId) && packageName.equals(ar.packageName)) {
1172 ar.info.applicationInfo = aInfo;
Todd Kennedy39bfee52016-02-24 10:28:21 -08001173 }
1174 }
1175 }
1176 }
1177
David Stevens9440dc82017-03-16 19:00:20 -07001178 void checkReadyForSleep() {
1179 if (shouldSleepActivities() && goToSleepIfPossible(false /* shuttingDown */)) {
1180 mStackSupervisor.checkReadyForSleepLocked(true /* allowDelay */);
1181 }
1182 }
1183
Craig Mautner0eea92c2013-05-16 13:35:39 -07001184 /**
David Stevens9440dc82017-03-16 19:00:20 -07001185 * Tries to put the activities in the stack to sleep.
1186 *
1187 * If the stack is not in a state where its activities can be put to sleep, this function will
1188 * start any necessary actions to move the stack into such a state. It is expected that this
1189 * function get called again when those actions complete.
1190 *
1191 * @param shuttingDown true when the called because the device is shutting down.
David Stevens18abd0e2017-08-17 14:55:47 -07001192 * @return true if the stack finished going to sleep, false if the stack only started the
1193 * process of going to sleep (checkReadyForSleep will be called when that process finishes).
Craig Mautner0eea92c2013-05-16 13:35:39 -07001194 */
David Stevens9440dc82017-03-16 19:00:20 -07001195 boolean goToSleepIfPossible(boolean shuttingDown) {
1196 boolean shouldSleep = true;
1197
Craig Mautner0eea92c2013-05-16 13:35:39 -07001198 if (mResumedActivity != null) {
1199 // Still have something resumed; can't sleep until it is paused.
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001200 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep needs to pause " + mResumedActivity);
1201 if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
1202 "Sleep => pause with userLeaving=false");
Bryce Lee5daa3122017-04-19 10:40:42 -07001203
1204 // If we are in the middle of resuming the top activity in
1205 // {@link #resumeTopActivityUncheckedLocked}, mResumedActivity will be set but not
1206 // resumed yet. We must not proceed pausing the activity here. This method will be
David Stevens9440dc82017-03-16 19:00:20 -07001207 // called again if necessary as part of {@link #checkReadyForSleep} or
Bryce Lee5daa3122017-04-19 10:40:42 -07001208 // {@link ActivityStackSupervisor#checkReadyForSleepLocked}.
1209 if (mStackSupervisor.inResumeTopActivity) {
1210 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "In the middle of resuming top activity "
1211 + mResumedActivity);
David Stevens9440dc82017-03-16 19:00:20 -07001212 } else {
1213 startPausingLocked(false, true, null, false);
Bryce Lee5daa3122017-04-19 10:40:42 -07001214 }
David Stevens9440dc82017-03-16 19:00:20 -07001215 shouldSleep = false ;
1216 } else if (mPausingActivity != null) {
Craig Mautner0eea92c2013-05-16 13:35:39 -07001217 // Still waiting for something to pause; can't sleep yet.
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001218 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still waiting to pause " + mPausingActivity);
David Stevens9440dc82017-03-16 19:00:20 -07001219 shouldSleep = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001220 }
David Stevens9440dc82017-03-16 19:00:20 -07001221
1222 if (!shuttingDown) {
1223 if (containsActivityFromStack(mStackSupervisor.mStoppingActivities)) {
1224 // Still need to tell some activities to stop; can't sleep yet.
1225 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to stop "
1226 + mStackSupervisor.mStoppingActivities.size() + " activities");
1227
1228 mStackSupervisor.scheduleIdleLocked();
1229 shouldSleep = false;
1230 }
1231
1232 if (containsActivityFromStack(mStackSupervisor.mGoingToSleepActivities)) {
1233 // Still need to tell some activities to sleep; can't sleep yet.
1234 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to sleep "
1235 + mStackSupervisor.mGoingToSleepActivities.size() + " activities");
1236 shouldSleep = false;
1237 }
1238 }
1239
1240 if (shouldSleep) {
1241 goToSleep();
1242 }
1243
David Stevens18abd0e2017-08-17 14:55:47 -07001244 return shouldSleep;
Craig Mautner0eea92c2013-05-16 13:35:39 -07001245 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001246
David Stevens18abd0e2017-08-17 14:55:47 -07001247 void goToSleep() {
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -07001248 ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001249
Andrii Kulianf9949d52016-05-06 12:53:25 -07001250 // Make sure any paused or stopped but visible activities are now sleeping.
Craig Mautner0eea92c2013-05-16 13:35:39 -07001251 // This ensures that the activity's onStop() is called.
1252 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
1253 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
1254 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
1255 final ActivityRecord r = activities.get(activityNdx);
Wale Ogunwaleb9a0c992017-04-18 07:25:20 -07001256 if (r.state == STOPPING || r.state == STOPPED
Andrii Kulianf9949d52016-05-06 12:53:25 -07001257 || r.state == ActivityState.PAUSED || r.state == ActivityState.PAUSING) {
Craig Mautner0eea92c2013-05-16 13:35:39 -07001258 r.setSleeping(true);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001259 }
1260 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001261 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001262 }
Craig Mautner59c00972012-07-30 12:10:24 -07001263
David Stevens9440dc82017-03-16 19:00:20 -07001264 private boolean containsActivityFromStack(List<ActivityRecord> rs) {
1265 for (ActivityRecord r : rs) {
1266 if (r.getStack() == this) {
1267 return true;
1268 }
1269 }
1270 return false;
1271 }
1272
Dianne Hackborna4e102e2014-09-04 22:52:27 -07001273 /**
Winson Chung4dabf232017-01-25 13:25:22 -08001274 * Schedule a pause timeout in case the app doesn't respond. We don't give it much time because
1275 * this directly impacts the responsiveness seen by the user.
1276 */
1277 private void schedulePauseTimeout(ActivityRecord r) {
1278 final Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
1279 msg.obj = r;
1280 r.pauseTime = SystemClock.uptimeMillis();
1281 mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
1282 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Waiting for pause to complete...");
1283 }
1284
1285 /**
Dianne Hackborna4e102e2014-09-04 22:52:27 -07001286 * Start pausing the currently resumed activity. It is an error to call this if there
1287 * is already an activity being paused or there is no resumed activity.
1288 *
1289 * @param userLeaving True if this should result in an onUserLeaving to the current activity.
1290 * @param uiSleeping True if this is happening with the user interface going to sleep (the
1291 * screen turning off).
Wale Ogunwale950faff2016-08-08 09:51:04 -07001292 * @param resuming The activity we are currently trying to resume or null if this is not being
1293 * called as part of resuming the top activity, so we shouldn't try to instigate
1294 * a resume here if not null.
Winson Chung6954fc92017-03-24 16:22:12 -07001295 * @param pauseImmediately True if the caller does not want to wait for the activity callback to
1296 * complete pausing.
Dianne Hackborna4e102e2014-09-04 22:52:27 -07001297 * @return Returns true if an activity now is in the PAUSING state, and we are waiting for
1298 * it to tell us when it is done.
1299 */
Wale Ogunwale950faff2016-08-08 09:51:04 -07001300 final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
Winson Chung6954fc92017-03-24 16:22:12 -07001301 ActivityRecord resuming, boolean pauseImmediately) {
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08001302 if (mPausingActivity != null) {
riddle_hsu7dfe4d72015-02-16 18:43:49 +08001303 Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity
1304 + " state=" + mPausingActivity.state);
David Stevens9440dc82017-03-16 19:00:20 -07001305 if (!shouldSleepActivities()) {
riddle_hsu7dfe4d72015-02-16 18:43:49 +08001306 // Avoid recursion among check for sleep and complete pause during sleeping.
1307 // Because activity will be paused immediately after resume, just let pause
1308 // be completed by the order of activity paused from clients.
Wale Ogunwale950faff2016-08-08 09:51:04 -07001309 completePauseLocked(false, resuming);
riddle_hsu7dfe4d72015-02-16 18:43:49 +08001310 }
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08001311 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001312 ActivityRecord prev = mResumedActivity;
Bryce Lee5daa3122017-04-19 10:40:42 -07001313
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001314 if (prev == null) {
Wale Ogunwale950faff2016-08-08 09:51:04 -07001315 if (resuming == null) {
Dianne Hackborna4e102e2014-09-04 22:52:27 -07001316 Slog.wtf(TAG, "Trying to pause when nothing is resumed");
Wale Ogunwaled046a012015-12-24 13:05:59 -08001317 mStackSupervisor.resumeFocusedStackTopActivityLocked();
Dianne Hackborna4e102e2014-09-04 22:52:27 -07001318 }
1319 return false;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001320 }
Craig Mautnerdf88d732014-01-27 09:21:32 -08001321
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07001322 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSING: " + prev);
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001323 else if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Start pausing: " + prev);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001324 mResumedActivity = null;
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08001325 mPausingActivity = prev;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001326 mLastPausedActivity = prev;
Craig Mautner0f922742013-08-06 08:44:42 -07001327 mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
1328 || (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001329 prev.state = ActivityState.PAUSING;
Bryce Leeaf691c02017-03-20 14:20:22 -07001330 prev.getTask().touchActiveTime();
Dianne Hackborn2286cdc2013-07-01 19:10:06 -07001331 clearLaunchTime(prev);
Craig Mautner6f6d56f2013-10-24 16:02:07 -07001332 final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();
Wale Ogunwale979f5ed2015-10-12 11:22:50 -07001333 if (mService.mHasRecents
Bryce Leeaf691c02017-03-20 14:20:22 -07001334 && (next == null || next.noDisplay || next.getTask() != prev.getTask()
1335 || uiSleeping)) {
Jorim Jaggic2f262b2015-12-07 16:59:10 -08001336 prev.mUpdateTaskThumbnailWhenHidden = true;
Craig Mautner6f6d56f2013-10-24 16:02:07 -07001337 }
Dianne Hackborncee04b52013-07-03 17:01:28 -07001338 stopFullyDrawnTraceIfNeeded();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001339
1340 mService.updateCpuStats();
Craig Mautneraab647e2013-02-28 16:31:36 -08001341
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001342 if (prev.app != null && prev.app.thread != null) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001343 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001344 try {
1345 EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
Dianne Hackbornb12e1352012-09-26 11:39:20 -07001346 prev.userId, System.identityHashCode(prev),
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001347 prev.shortComponentName);
Jeff Sharkey5782da72013-04-25 14:32:30 -07001348 mService.updateUsageStats(prev, false);
Dianne Hackbornbe707852011-11-11 14:32:10 -08001349 prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
Winson Chung6954fc92017-03-24 16:22:12 -07001350 userLeaving, prev.configChangeFlags, pauseImmediately);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001351 } catch (Exception e) {
1352 // Ignore exception, if process died other code will cleanup.
1353 Slog.w(TAG, "Exception thrown during pause", e);
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08001354 mPausingActivity = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001355 mLastPausedActivity = null;
Craig Mautner0f922742013-08-06 08:44:42 -07001356 mLastNoHistoryActivity = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001357 }
1358 } else {
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08001359 mPausingActivity = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001360 mLastPausedActivity = null;
Craig Mautner0f922742013-08-06 08:44:42 -07001361 mLastNoHistoryActivity = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001362 }
1363
1364 // If we are not going to sleep, we want to ensure the device is
1365 // awake until the next activity is started.
Fyodor Kupolov9b80b942016-06-16 16:29:05 -07001366 if (!uiSleeping && !mService.isSleepingOrShuttingDownLocked()) {
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001367 mStackSupervisor.acquireLaunchWakelock();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001368 }
1369
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08001370 if (mPausingActivity != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001371 // Have the window manager pause its key dispatching until the new
1372 // activity has started. If we're pausing the activity just because
1373 // the screen is being turned off and the UI is sleeping, don't interrupt
1374 // key dispatch; the same activity will pick it up again on wakeup.
1375 if (!uiSleeping) {
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08001376 prev.pauseKeyDispatchingLocked();
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001377 } else if (DEBUG_PAUSE) {
1378 Slog.v(TAG_PAUSE, "Key dispatch not paused for screen off");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001379 }
1380
Winson Chung6954fc92017-03-24 16:22:12 -07001381 if (pauseImmediately) {
Dianne Hackborna4e102e2014-09-04 22:52:27 -07001382 // If the caller said they don't want to wait for the pause, then complete
1383 // the pause now.
Wale Ogunwale950faff2016-08-08 09:51:04 -07001384 completePauseLocked(false, resuming);
Dianne Hackborna4e102e2014-09-04 22:52:27 -07001385 return false;
1386
1387 } else {
Winson Chung4dabf232017-01-25 13:25:22 -08001388 schedulePauseTimeout(prev);
Dianne Hackborna4e102e2014-09-04 22:52:27 -07001389 return true;
1390 }
1391
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001392 } else {
1393 // This activity failed to schedule the
1394 // pause, so just treat it as being paused now.
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001395 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Activity not running, resuming next.");
Wale Ogunwale950faff2016-08-08 09:51:04 -07001396 if (resuming == null) {
Wale Ogunwaled046a012015-12-24 13:05:59 -08001397 mStackSupervisor.resumeFocusedStackTopActivityLocked();
Dianne Hackborna4e102e2014-09-04 22:52:27 -07001398 }
1399 return false;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001400 }
1401 }
Dianne Hackbornad9b32112012-09-17 15:35:01 -07001402
Dianne Hackborna4e102e2014-09-04 22:52:27 -07001403 final void activityPausedLocked(IBinder token, boolean timeout) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001404 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE,
1405 "Activity paused: token=" + token + ", timeout=" + timeout);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001406
Craig Mautnerd2328952013-03-05 12:46:26 -08001407 final ActivityRecord r = isInStackLocked(token);
1408 if (r != null) {
1409 mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
1410 if (mPausingActivity == r) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07001411 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + r
Craig Mautnerd2328952013-03-05 12:46:26 -08001412 + (timeout ? " (due to timeout)" : " (pause complete)"));
Jorim Jaggife762342016-10-13 14:33:27 +02001413 mService.mWindowManager.deferSurfaceLayout();
1414 try {
Winson Chung3f103eb2017-04-12 21:53:59 -07001415 completePauseLocked(true /* resumeNext */, null /* resumingActivity */);
Jorim Jaggife762342016-10-13 14:33:27 +02001416 } finally {
1417 mService.mWindowManager.continueSurfaceLayout();
1418 }
Wale Ogunwale5658e4b2016-02-12 12:22:19 -08001419 return;
Craig Mautnerd2328952013-03-05 12:46:26 -08001420 } else {
1421 EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,
1422 r.userId, System.identityHashCode(r), r.shortComponentName,
1423 mPausingActivity != null
1424 ? mPausingActivity.shortComponentName : "(none)");
riddle_hsu9caeef72015-10-20 16:34:05 +08001425 if (r.state == ActivityState.PAUSING) {
1426 r.state = ActivityState.PAUSED;
1427 if (r.finishing) {
1428 if (DEBUG_PAUSE) Slog.v(TAG,
1429 "Executing finish of failed to pause activity: " + r);
1430 finishCurrentActivityLocked(r, FINISH_AFTER_VISIBLE, false);
1431 }
louis_chang047dfd42015-04-08 16:35:55 +08001432 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001433 }
1434 }
Wale Ogunwale5658e4b2016-02-12 12:22:19 -08001435 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001436 }
1437
Wale Ogunwale950faff2016-08-08 09:51:04 -07001438 private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08001439 ActivityRecord prev = mPausingActivity;
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001440 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev);
Craig Mautneraab647e2013-02-28 16:31:36 -08001441
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08001442 if (prev != null) {
Wale Ogunwaleb9a0c992017-04-18 07:25:20 -07001443 final boolean wasStopping = prev.state == STOPPING;
Dianne Hackborna4e102e2014-09-04 22:52:27 -07001444 prev.state = ActivityState.PAUSED;
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08001445 if (prev.finishing) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001446 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev);
Dianne Hackborn2d1b3782012-09-09 17:49:39 -07001447 prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false);
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08001448 } else if (prev.app != null) {
Wale Ogunwaled8026642016-02-09 20:40:18 -08001449 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueue pending stop if needed: " + prev
1450 + " wasStopping=" + wasStopping + " visible=" + prev.visible);
Bryce Lee4a194382017-04-04 14:32:48 -07001451 if (mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(prev)) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001452 if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(TAG_PAUSE,
1453 "Complete pause, no longer waiting: " + prev);
Dianne Hackborncbb722e2012-02-07 18:33:49 -08001454 }
Wale Ogunwalef81c1d12016-01-12 12:20:18 -08001455 if (prev.deferRelaunchUntilPaused) {
1456 // Complete the deferred relaunch that was waiting for pause to complete.
1457 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Re-launching after pause: " + prev);
Andrii Kulian21713ac2016-10-12 22:05:05 -07001458 prev.relaunchActivityLocked(false /* andResume */,
Wale Ogunwalef81c1d12016-01-12 12:20:18 -08001459 prev.preserveWindowOnDeferredRelaunch);
Filip Gruszczynskidba623a2015-12-04 15:45:35 -08001460 } else if (wasStopping) {
1461 // We are also stopping, the stop request must have gone soon after the pause.
1462 // We can't clobber it, because the stop confirmation will not be handled.
1463 // We don't need to schedule another stop, we only need to let it happen.
Wale Ogunwaleb9a0c992017-04-18 07:25:20 -07001464 prev.state = STOPPING;
David Stevens9440dc82017-03-16 19:00:20 -07001465 } else if (!prev.visible || shouldSleepOrShutDownActivities()) {
Wale Ogunwaleec950642017-04-25 07:44:21 -07001466 // Clear out any deferred client hide we might currently have.
1467 prev.setDeferHidingClient(false);
Jose Lima4b6c6692014-08-12 17:41:12 -07001468 // If we were visible then resumeTopActivities will release resources before
Wale Ogunwaleec950642017-04-25 07:44:21 -07001469 // stopping.
Winson Chung4dabf232017-01-25 13:25:22 -08001470 addToStopping(prev, true /* scheduleIdle */, false /* idleDelayed */);
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08001471 }
1472 } else {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001473 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "App died during pause, not stopping: " + prev);
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08001474 prev = null;
Dianne Hackborncbb722e2012-02-07 18:33:49 -08001475 }
Wale Ogunwale07927bf2015-03-28 17:21:05 -07001476 // It is possible the activity was freezing the screen before it was paused.
1477 // In that case go ahead and remove the freeze this activity has on the screen
1478 // since it is no longer visible.
Wale Ogunwalee8524002016-09-13 16:34:57 -07001479 if (prev != null) {
1480 prev.stopFreezingScreenLocked(true /*force*/);
1481 }
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08001482 mPausingActivity = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001483 }
Dianne Hackborncbb722e2012-02-07 18:33:49 -08001484
Dianne Hackborna4e102e2014-09-04 22:52:27 -07001485 if (resumeNext) {
1486 final ActivityStack topStack = mStackSupervisor.getFocusedStack();
David Stevens9440dc82017-03-16 19:00:20 -07001487 if (!topStack.shouldSleepOrShutDownActivities()) {
Wale Ogunwaled046a012015-12-24 13:05:59 -08001488 mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);
Dianne Hackborna4e102e2014-09-04 22:52:27 -07001489 } else {
David Stevens9440dc82017-03-16 19:00:20 -07001490 checkReadyForSleep();
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -07001491 ActivityRecord top = topStack.topRunningActivityLocked();
Dianne Hackborna4e102e2014-09-04 22:52:27 -07001492 if (top == null || (prev != null && top != prev)) {
Wale Ogunwaled046a012015-12-24 13:05:59 -08001493 // If there are no more activities available to run, do resume anyway to start
1494 // something. Also if the top activity on the stack is not the just paused
1495 // activity, we need to go ahead and resume it to ensure we complete an
1496 // in-flight app switch.
1497 mStackSupervisor.resumeFocusedStackTopActivityLocked();
Dianne Hackborna4e102e2014-09-04 22:52:27 -07001498 }
Dianne Hackborn42e620c2012-06-24 13:20:51 -07001499 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001500 }
Craig Mautneraab647e2013-02-28 16:31:36 -08001501
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08001502 if (prev != null) {
1503 prev.resumeKeyDispatchingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001504
Craig Mautner525f3d92013-05-07 14:01:50 -07001505 if (prev.app != null && prev.cpuTimeAtResume > 0
1506 && mService.mBatteryStatsService.isOnBattery()) {
Dianne Hackborn652973f2014-09-10 17:08:48 -07001507 long diff = mService.mProcessCpuTracker.getCpuTimeForPid(prev.app.pid)
1508 - prev.cpuTimeAtResume;
Craig Mautner525f3d92013-05-07 14:01:50 -07001509 if (diff > 0) {
1510 BatteryStatsImpl bsi = mService.mBatteryStatsService.getActiveStatistics();
1511 synchronized (bsi) {
1512 BatteryStatsImpl.Uid.Proc ps =
1513 bsi.getProcessStatsLocked(prev.info.applicationInfo.uid,
Dianne Hackbornd2932242013-08-05 18:18:42 -07001514 prev.info.packageName);
Craig Mautner525f3d92013-05-07 14:01:50 -07001515 if (ps != null) {
1516 ps.addForegroundTimeLocked(diff);
1517 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001518 }
1519 }
1520 }
Craig Mautner525f3d92013-05-07 14:01:50 -07001521 prev.cpuTimeAtResume = 0; // reset it
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001522 }
Winson Chung740c3ac2014-11-12 16:14:38 -08001523
Andrii Kulian8290f8f2016-06-30 17:51:32 -07001524 // Notify when the task stack has changed, but only if visibilities changed (not just
1525 // focus). Also if there is an active pinned stack - we always want to notify it about
1526 // task stack changes, because its positioning may depend on it.
1527 if (mStackSupervisor.mAppVisibilitiesChangedSinceLastPause
1528 || mService.mStackSupervisor.getStack(PINNED_STACK_ID) != null) {
Yorke Leebd54c2a2016-10-25 13:49:23 -07001529 mService.mTaskChangeNotificationController.notifyTaskStackChanged();
Jorim Jaggia0fdeec2016-01-07 14:42:28 +01001530 mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = false;
1531 }
Wale Ogunwale5658e4b2016-02-12 12:22:19 -08001532
Wale Ogunwale950faff2016-08-08 09:51:04 -07001533 mStackSupervisor.ensureActivitiesVisibleLocked(resuming, 0, !PRESERVE_WINDOWS);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001534 }
1535
Winson Chung4dabf232017-01-25 13:25:22 -08001536 void addToStopping(ActivityRecord r, boolean scheduleIdle, boolean idleDelayed) {
Chong Zhang46b1ac62016-02-18 17:53:57 -08001537 if (!mStackSupervisor.mStoppingActivities.contains(r)) {
1538 mStackSupervisor.mStoppingActivities.add(r);
1539 }
1540
1541 // If we already have a few activities waiting to stop, then give up
1542 // on things going idle and start clearing them out. Or if r is the
1543 // last of activity of the last task the stack will be empty and must
1544 // be cleared immediately.
1545 boolean forceIdle = mStackSupervisor.mStoppingActivities.size() > MAX_STOPPING_TO_FORCE
1546 || (r.frontOfTask && mTaskHistory.size() <= 1);
Winson Chung4dabf232017-01-25 13:25:22 -08001547 if (scheduleIdle || forceIdle) {
Chong Zhang46b1ac62016-02-18 17:53:57 -08001548 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Scheduling idle now: forceIdle="
Winson Chung4dabf232017-01-25 13:25:22 -08001549 + forceIdle + "immediate=" + !idleDelayed);
1550 if (!idleDelayed) {
1551 mStackSupervisor.scheduleIdleLocked();
1552 } else {
1553 mStackSupervisor.scheduleIdleTimeoutLocked(r);
1554 }
Filip Gruszczynskief2f72b2015-12-04 14:52:25 -08001555 } else {
David Stevens9440dc82017-03-16 19:00:20 -07001556 checkReadyForSleep();
Filip Gruszczynskief2f72b2015-12-04 14:52:25 -08001557 }
1558 }
1559
Craig Mautnerfa387ad2014-08-05 11:16:41 -07001560 // Find the first visible activity above the passed activity and if it is translucent return it
1561 // otherwise return null;
1562 ActivityRecord findNextTranslucentActivity(ActivityRecord r) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001563 TaskRecord task = r.getTask();
Craig Mautnerfa387ad2014-08-05 11:16:41 -07001564 if (task == null) {
1565 return null;
1566 }
1567
Andrii Kulian02b7a832016-10-06 23:11:56 -07001568 final ActivityStack stack = task.getStack();
Craig Mautnerfa387ad2014-08-05 11:16:41 -07001569 if (stack == null) {
1570 return null;
1571 }
1572
1573 int stackNdx = mStacks.indexOf(stack);
1574
1575 ArrayList<TaskRecord> tasks = stack.mTaskHistory;
1576 int taskNdx = tasks.indexOf(task);
1577
1578 ArrayList<ActivityRecord> activities = task.mActivities;
1579 int activityNdx = activities.indexOf(r) + 1;
1580
1581 final int numStacks = mStacks.size();
1582 while (stackNdx < numStacks) {
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001583 final ActivityStack historyStack = mStacks.get(stackNdx);
Todd Kennedyaab56db2015-01-30 09:39:53 -08001584 tasks = historyStack.mTaskHistory;
Craig Mautnerfa387ad2014-08-05 11:16:41 -07001585 final int numTasks = tasks.size();
1586 while (taskNdx < numTasks) {
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001587 final TaskRecord currentTask = tasks.get(taskNdx);
1588 activities = currentTask.mActivities;
Craig Mautnerfa387ad2014-08-05 11:16:41 -07001589 final int numActivities = activities.size();
1590 while (activityNdx < numActivities) {
1591 final ActivityRecord activity = activities.get(activityNdx);
1592 if (!activity.finishing) {
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001593 return historyStack.mFullscreen
1594 && currentTask.mFullscreen && activity.fullscreen ? null : activity;
Craig Mautnerfa387ad2014-08-05 11:16:41 -07001595 }
1596 ++activityNdx;
1597 }
1598 activityNdx = 0;
1599 ++taskNdx;
1600 }
1601 taskNdx = 0;
1602 ++stackNdx;
1603 }
1604
1605 return null;
1606 }
1607
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -07001608 /** Returns true if the stack contains a fullscreen task. */
1609 private boolean hasFullscreenTask() {
1610 for (int i = mTaskHistory.size() - 1; i >= 0; --i) {
1611 final TaskRecord task = mTaskHistory.get(i);
1612 if (task.mFullscreen) {
1613 return true;
1614 }
1615 }
1616 return false;
1617 }
1618
Wale Ogunwale8051c5c2016-03-04 10:27:32 -08001619 /**
1620 * Returns true if the stack is translucent and can have other contents visible behind it if
1621 * needed. A stack is considered translucent if it don't contain a visible or
1622 * starting (about to be visible) activity that is fullscreen (opaque).
1623 * @param starting The currently starting activity or null if there is none.
Wale Ogunwale56d75cf2016-03-09 15:14:47 -08001624 * @param stackBehindId The id of the stack directly behind this one.
Wale Ogunwale8051c5c2016-03-04 10:27:32 -08001625 */
Wale Ogunwale56d75cf2016-03-09 15:14:47 -08001626 private boolean isStackTranslucent(ActivityRecord starting, int stackBehindId) {
Wale Ogunwale8051c5c2016-03-04 10:27:32 -08001627 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
1628 final TaskRecord task = mTaskHistory.get(taskNdx);
Wale Ogunwale1e3523c2015-09-16 13:11:10 -07001629 final ArrayList<ActivityRecord> activities = task.mActivities;
1630 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
1631 final ActivityRecord r = activities.get(activityNdx);
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -07001632
Wale Ogunwale56d75cf2016-03-09 15:14:47 -08001633 if (r.finishing) {
1634 // We don't factor in finishing activities when determining translucency since
1635 // they will be gone soon.
1636 continue;
1637 }
1638
1639 if (!r.visible && r != starting) {
1640 // Also ignore invisible activities that are not the currently starting
1641 // activity (about to be visible).
1642 continue;
1643 }
1644
1645 if (r.fullscreen) {
1646 // Stack isn't translucent if it has at least one fullscreen activity
1647 // that is visible.
1648 return false;
1649 }
1650
Winson Chunge74ad8d2017-02-17 15:12:25 -08001651 if (!isHomeOrRecentsStack() && r.frontOfTask && task.isOverHomeStack()
1652 && !StackId.isHomeOrRecentsStack(stackBehindId) && !isAssistantStack()) {
Wale Ogunwale56d75cf2016-03-09 15:14:47 -08001653 // Stack isn't translucent if it's top activity should have the home stack
Winson Chunge74ad8d2017-02-17 15:12:25 -08001654 // behind it and the stack currently behind it isn't the home or recents stack
1655 // or the assistant stack.
Wale Ogunwale1e3523c2015-09-16 13:11:10 -07001656 return false;
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -07001657 }
1658 }
1659 }
Wale Ogunwale1e3523c2015-09-16 13:11:10 -07001660 return true;
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -07001661 }
1662
Wale Ogunwalecd501ec2017-04-07 08:53:41 -07001663 /** Returns true if the stack is currently considered visible. */
1664 boolean isVisible() {
Winson Chung47900652017-04-06 18:44:25 -07001665 return mWindowContainerController != null && mWindowContainerController.isVisible()
1666 && !mForceHidden;
Wale Ogunwalecd501ec2017-04-07 08:53:41 -07001667 }
1668
Filip Gruszczynski0e381e22016-01-14 16:31:33 -08001669 /**
Wale Ogunwalec981ad52017-06-13 11:40:06 -07001670 * Returns what the stack visibility should be: {@link #STACK_INVISIBLE} or
1671 * {@link #STACK_VISIBLE}.
Wale Ogunwalecd501ec2017-04-07 08:53:41 -07001672 *
Wale Ogunwale8051c5c2016-03-04 10:27:32 -08001673 * @param starting The currently starting activity or null if there is none.
Filip Gruszczynski0e381e22016-01-14 16:31:33 -08001674 */
Wale Ogunwalecd501ec2017-04-07 08:53:41 -07001675 int shouldBeVisible(ActivityRecord starting) {
Winson Chung47900652017-04-06 18:44:25 -07001676 if (!isAttached() || mForceHidden) {
Filip Gruszczynski0e381e22016-01-14 16:31:33 -08001677 return STACK_INVISIBLE;
Jose Lima7ba71252014-04-30 12:59:27 -07001678 }
1679
Andrii Kuliane8d928a2016-11-14 18:38:14 -08001680 if (mStackSupervisor.isFrontStackOnDisplay(this) || mStackSupervisor.isFocusedStack(this)) {
Filip Gruszczynski0e381e22016-01-14 16:31:33 -08001681 return STACK_VISIBLE;
Wale Ogunwale99db1862015-10-23 20:08:22 -07001682 }
1683
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -07001684 final int stackIndex = mStacks.indexOf(this);
1685
1686 if (stackIndex == mStacks.size() - 1) {
1687 Slog.wtf(TAG,
1688 "Stack=" + this + " isn't front stack but is at the top of the stack list");
Filip Gruszczynski0e381e22016-01-14 16:31:33 -08001689 return STACK_INVISIBLE;
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -07001690 }
1691
Andrii Kulian0864bbb2017-02-16 15:45:58 -08001692 // Check position and visibility of this stack relative to the front stack on its display.
1693 final ActivityStack topStack = getTopStackOnDisplay();
1694 final int topStackId = topStack.mStackId;
Wale Ogunwale1e3523c2015-09-16 13:11:10 -07001695
1696 if (mStackId == DOCKED_STACK_ID) {
Winson Chunge74ad8d2017-02-17 15:12:25 -08001697 // If the assistant stack is focused and translucent, then the docked stack is always
1698 // visible
Winson Chung521f0112017-03-13 16:14:45 -07001699 if (topStack.isAssistantStack()) {
1700 return (topStack.isStackTranslucent(starting, DOCKED_STACK_ID)) ? STACK_VISIBLE
1701 : STACK_INVISIBLE;
Winson Chunge74ad8d2017-02-17 15:12:25 -08001702 }
Matthew Ng6875d472017-05-01 13:59:50 -07001703 return STACK_VISIBLE;
Wale Ogunwale1e3523c2015-09-16 13:11:10 -07001704 }
1705
Matthew Ng330757d2017-02-28 14:19:17 -08001706 // Set home stack to invisible when it is below but not immediately below the docked stack
1707 // A case would be if recents stack exists but has no tasks and is below the docked stack
1708 // and home stack is below recents
1709 if (mStackId == HOME_STACK_ID) {
1710 int dockedStackIndex = mStacks.indexOf(mStackSupervisor.getStack(DOCKED_STACK_ID));
1711 if (dockedStackIndex > stackIndex && stackIndex != dockedStackIndex - 1) {
1712 return STACK_INVISIBLE;
1713 }
1714 }
1715
Andrii Kulian0864bbb2017-02-16 15:45:58 -08001716 // Find the first stack behind front stack that actually got something visible.
1717 int stackBehindTopIndex = mStacks.indexOf(topStack) - 1;
1718 while (stackBehindTopIndex >= 0 &&
1719 mStacks.get(stackBehindTopIndex).topRunningActivityLocked() == null) {
1720 stackBehindTopIndex--;
Chong Zhangb16cf342015-11-12 17:22:40 -08001721 }
Andrii Kulian0864bbb2017-02-16 15:45:58 -08001722 final int stackBehindTopId = (stackBehindTopIndex >= 0)
1723 ? mStacks.get(stackBehindTopIndex).mStackId : INVALID_STACK_ID;
Winson Chungdd7593a2017-07-05 18:02:36 -07001724 if (topStackId == DOCKED_STACK_ID || StackId.isAlwaysOnTop(topStackId)) {
1725 if (stackIndex == stackBehindTopIndex) {
1726 // Stacks directly behind the docked or pinned stack are always visible.
1727 return STACK_VISIBLE;
1728 } else if (StackId.isAlwaysOnTop(topStackId) && stackIndex == stackBehindTopIndex - 1) {
1729 // Otherwise, this stack can also be visible if it is directly behind a docked stack
1730 // or translucent assistant stack behind an always-on-top top-most stack
1731 if (stackBehindTopId == DOCKED_STACK_ID) {
1732 return STACK_VISIBLE;
1733 } else if (stackBehindTopId == ASSISTANT_STACK_ID) {
1734 return mStacks.get(stackBehindTopIndex).isStackTranslucent(starting, mStackId)
1735 ? STACK_VISIBLE : STACK_INVISIBLE;
1736 }
1737 }
Matthew Ng6875d472017-05-01 13:59:50 -07001738 }
Wale Ogunwale56d75cf2016-03-09 15:14:47 -08001739
Andrii Kulian0864bbb2017-02-16 15:45:58 -08001740 if (StackId.isBackdropToTranslucentActivity(topStackId)
1741 && topStack.isStackTranslucent(starting, stackBehindTopId)) {
Winson Chung83471632016-12-13 11:02:12 -08001742 // Stacks behind the fullscreen or assistant stack with a translucent activity are
1743 // always visible so they can act as a backdrop to the translucent activity.
Wale Ogunwalebd26d2a2015-09-22 22:08:37 -07001744 // For example, dialog activities
Andrii Kulian0864bbb2017-02-16 15:45:58 -08001745 if (stackIndex == stackBehindTopIndex) {
Filip Gruszczynski0e381e22016-01-14 16:31:33 -08001746 return STACK_VISIBLE;
Wale Ogunwalebd26d2a2015-09-22 22:08:37 -07001747 }
Andrii Kulian0864bbb2017-02-16 15:45:58 -08001748 if (stackBehindTopIndex >= 0) {
1749 if ((stackBehindTopId == DOCKED_STACK_ID
1750 || stackBehindTopId == PINNED_STACK_ID)
1751 && stackIndex == (stackBehindTopIndex - 1)) {
Wale Ogunwale99db1862015-10-23 20:08:22 -07001752 // The stack behind the docked or pinned stack is also visible so we can have a
1753 // complete backdrop to the translucent activity when the docked stack is up.
Filip Gruszczynski0e381e22016-01-14 16:31:33 -08001754 return STACK_VISIBLE;
Wale Ogunwalebd26d2a2015-09-22 22:08:37 -07001755 }
1756 }
Wale Ogunwale1e3523c2015-09-16 13:11:10 -07001757 }
1758
Wale Ogunwale3797c222015-10-27 14:21:58 -07001759 if (StackId.isStaticStack(mStackId)) {
Wale Ogunwale1e3523c2015-09-16 13:11:10 -07001760 // Visibility of any static stack should have been determined by the conditions above.
Filip Gruszczynski0e381e22016-01-14 16:31:33 -08001761 return STACK_INVISIBLE;
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -07001762 }
1763
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -07001764 for (int i = stackIndex + 1; i < mStacks.size(); i++) {
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001765 final ActivityStack stack = mStacks.get(i);
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -07001766
1767 if (!stack.mFullscreen && !stack.hasFullscreenTask()) {
1768 continue;
1769 }
1770
Wale Ogunwale3797c222015-10-27 14:21:58 -07001771 if (!StackId.isDynamicStacksVisibleBehindAllowed(stack.mStackId)) {
Wale Ogunwale1e3523c2015-09-16 13:11:10 -07001772 // These stacks can't have any dynamic stacks visible behind them.
Filip Gruszczynski0e381e22016-01-14 16:31:33 -08001773 return STACK_INVISIBLE;
Todd Kennedyaab56db2015-01-30 09:39:53 -08001774 }
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -07001775
Wale Ogunwale56d75cf2016-03-09 15:14:47 -08001776 if (!stack.isStackTranslucent(starting, INVALID_STACK_ID)) {
Filip Gruszczynski0e381e22016-01-14 16:31:33 -08001777 return STACK_INVISIBLE;
Jose Lima7ba71252014-04-30 12:59:27 -07001778 }
1779 }
1780
Filip Gruszczynski0e381e22016-01-14 16:31:33 -08001781 return STACK_VISIBLE;
Jose Lima7ba71252014-04-30 12:59:27 -07001782 }
1783
Chong Zhangfdcc4d42015-10-14 16:50:12 -07001784 final int rankTaskLayers(int baseLayer) {
1785 int layer = 0;
1786 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
1787 final TaskRecord task = mTaskHistory.get(taskNdx);
1788 ActivityRecord r = task.topRunningActivityLocked();
1789 if (r == null || r.finishing || !r.visible) {
1790 task.mLayerRank = -1;
1791 } else {
1792 task.mLayerRank = baseLayer + layer++;
1793 }
1794 }
1795 return layer;
1796 }
1797
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001798 /**
1799 * Make sure that all activities that need to be visible (that is, they
1800 * currently can be seen by the user) actually are.
1801 */
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -07001802 final void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
1803 boolean preserveWindows) {
Jorim Jaggife762342016-10-13 14:33:27 +02001804 mTopActivityOccludesKeyguard = false;
1805 mTopDismissingKeyguardActivity = null;
1806 mStackSupervisor.mKeyguardController.beginActivityVisibilityUpdate();
1807 try {
1808 ActivityRecord top = topRunningActivityLocked();
1809 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "ensureActivitiesVisible behind " + top
1810 + " configChanges=0x" + Integer.toHexString(configChanges));
1811 if (top != null) {
1812 checkTranslucentActivityWaiting(top);
1813 }
Craig Mautner5eda9b32013-07-02 11:58:16 -07001814
Jorim Jaggife762342016-10-13 14:33:27 +02001815 // If the top activity is not fullscreen, then we need to
1816 // make sure any activities under it are now visible.
1817 boolean aboveTop = top != null;
Wale Ogunwalecd501ec2017-04-07 08:53:41 -07001818 final int stackVisibility = shouldBeVisible(starting);
Jorim Jaggife762342016-10-13 14:33:27 +02001819 final boolean stackInvisible = stackVisibility != STACK_VISIBLE;
Jorim Jaggife762342016-10-13 14:33:27 +02001820 boolean behindFullscreenActivity = stackInvisible;
1821 boolean resumeNextActivity = mStackSupervisor.isFocusedStack(this)
1822 && (isInStackLocked(starting) == null);
1823 boolean behindTranslucentActivity = false;
Jorim Jaggife762342016-10-13 14:33:27 +02001824 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
1825 final TaskRecord task = mTaskHistory.get(taskNdx);
1826 final ArrayList<ActivityRecord> activities = task.mActivities;
1827 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
1828 final ActivityRecord r = activities.get(activityNdx);
1829 if (r.finishing) {
1830 // Normally the screenshot will be taken in makeInvisible(). When an activity
1831 // is finishing, we no longer change its visibility, but we still need to take
1832 // the screenshots if startPausingLocked decided it should be taken.
1833 if (r.mUpdateTaskThumbnailWhenHidden) {
1834 r.updateThumbnailLocked(r.screenshotActivityLocked(),
1835 null /* description */);
1836 r.mUpdateTaskThumbnailWhenHidden = false;
1837 }
1838 continue;
Chong Zhang22bc8512016-04-07 13:47:18 -07001839 }
Jorim Jaggife762342016-10-13 14:33:27 +02001840 final boolean isTop = r == top;
1841 if (aboveTop && !isTop) {
1842 continue;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001843 }
Jorim Jaggife762342016-10-13 14:33:27 +02001844 aboveTop = false;
Craig Mautnerd44711d2013-02-23 11:24:36 -08001845
Jorim Jaggife762342016-10-13 14:33:27 +02001846 // Check whether activity should be visible without Keyguard influence
Jorim Jaggi241ae102016-11-02 21:57:33 -07001847 final boolean visibleIgnoringKeyguard = r.shouldBeVisibleIgnoringKeyguard(
Jorim Jaggi241ae102016-11-02 21:57:33 -07001848 behindFullscreenActivity);
1849 r.visibleIgnoringKeyguard = visibleIgnoringKeyguard;
Jorim Jaggife762342016-10-13 14:33:27 +02001850
1851 // Now check whether it's really visible depending on Keyguard state.
Jorim Jaggi241ae102016-11-02 21:57:33 -07001852 final boolean reallyVisible = checkKeyguardVisibility(r,
1853 visibleIgnoringKeyguard, isTop);
1854 if (visibleIgnoringKeyguard) {
Jorim Jaggife762342016-10-13 14:33:27 +02001855 behindFullscreenActivity = updateBehindFullscreen(stackInvisible,
1856 behindFullscreenActivity, task, r);
1857 if (behindFullscreenActivity && !r.fullscreen) {
1858 behindTranslucentActivity = true;
1859 }
1860 }
1861 if (reallyVisible) {
1862 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make visible? " + r
1863 + " finishing=" + r.finishing + " state=" + r.state);
1864 // First: if this is not the current activity being started, make
1865 // sure it matches the current configuration.
1866 if (r != starting) {
1867 r.ensureActivityConfigurationLocked(0 /* globalChanges */, preserveWindows);
1868 }
1869
1870 if (r.app == null || r.app.thread == null) {
1871 if (makeVisibleAndRestartIfNeeded(starting, configChanges, isTop,
1872 resumeNextActivity, r)) {
1873 if (activityNdx >= activities.size()) {
1874 // Record may be removed if its process needs to restart.
1875 activityNdx = activities.size() - 1;
1876 } else {
1877 resumeNextActivity = false;
1878 }
1879 }
1880 } else if (r.visible) {
1881 // If this activity is already visible, then there is nothing to do here.
1882 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
1883 "Skipping: already visible at " + r);
1884
1885 if (r.handleAlreadyVisible()) {
Wale Ogunwaled046a012015-12-24 13:05:59 -08001886 resumeNextActivity = false;
riddle_hsu36ee73d2015-06-05 16:38:38 +08001887 }
Jorim Jaggife762342016-10-13 14:33:27 +02001888 } else {
1889 r.makeVisibleIfNeeded(starting);
Craig Mautnerd44711d2013-02-23 11:24:36 -08001890 }
Jorim Jaggife762342016-10-13 14:33:27 +02001891 // Aggregate current change flags.
1892 configChanges |= r.configChangeFlags;
Craig Mautnerbb742462014-07-07 15:28:55 -07001893 } else {
Jorim Jaggife762342016-10-13 14:33:27 +02001894 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make invisible? " + r
1895 + " finishing=" + r.finishing + " state=" + r.state + " stackInvisible="
1896 + stackInvisible + " behindFullscreenActivity="
1897 + behindFullscreenActivity + " mLaunchTaskBehind="
1898 + r.mLaunchTaskBehind);
Wale Ogunwalec981ad52017-06-13 11:40:06 -07001899 makeInvisible(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001900 }
Jorim Jaggife762342016-10-13 14:33:27 +02001901 }
1902 if (mStackId == FREEFORM_WORKSPACE_STACK_ID) {
1903 // The visibility of tasks and the activities they contain in freeform stack are
1904 // determined individually unlike other stacks where the visibility or fullscreen
1905 // status of an activity in a previous task affects other.
1906 behindFullscreenActivity = stackVisibility == STACK_INVISIBLE;
1907 } else if (mStackId == HOME_STACK_ID) {
Wale Ogunwale069bbd32017-02-03 07:58:14 -08001908 if (task.isHomeTask()) {
Jorim Jaggife762342016-10-13 14:33:27 +02001909 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Home task: at " + task
1910 + " stackInvisible=" + stackInvisible
1911 + " behindFullscreenActivity=" + behindFullscreenActivity);
1912 // No other task in the home stack should be visible behind the home activity.
1913 // Home activities is usually a translucent activity with the wallpaper behind
1914 // them. However, when they don't have the wallpaper behind them, we want to
1915 // show activities in the next application stack behind them vs. another
1916 // task in the home stack like recents.
1917 behindFullscreenActivity = true;
1918 } else if (task.isRecentsTask()
1919 && task.getTaskToReturnTo() == APPLICATION_ACTIVITY_TYPE) {
1920 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
1921 "Recents task returning to app: at " + task
1922 + " stackInvisible=" + stackInvisible
1923 + " behindFullscreenActivity=" + behindFullscreenActivity);
1924 // We don't want any other tasks in the home stack visible if the recents
1925 // activity is going to be returning to an application activity type.
1926 // We do this to preserve the visible order the user used to get into the
1927 // recents activity. The recents activity is normally translucent and if it
1928 // doesn't have the wallpaper behind it the next activity in the home stack
1929 // shouldn't be visible when the home stack is brought to the front to display
1930 // the recents activity from an app.
1931 behindFullscreenActivity = true;
Filip Gruszczynski0e381e22016-01-14 16:31:33 -08001932 }
Winson Chung1cebea62017-06-26 17:22:27 -07001933 } else if (mStackId == FULLSCREEN_WORKSPACE_STACK_ID) {
1934 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Skipping after task=" + task
1935 + " returning to non-application type=" + task.getTaskToReturnTo());
Winson Chung03157022017-07-19 11:58:59 -07001936 // Once we reach a fullscreen stack task that has a running activity and should
1937 // return to another stack task, then no other activities behind that one should
1938 // be visible.
1939 if (task.topRunningActivityLocked() != null &&
1940 task.getTaskToReturnTo() != APPLICATION_ACTIVITY_TYPE) {
Winson Chung1cebea62017-06-26 17:22:27 -07001941 behindFullscreenActivity = true;
1942 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001943 }
1944 }
Wale Ogunwale74e26592016-02-05 11:48:37 -08001945
Jorim Jaggife762342016-10-13 14:33:27 +02001946 if (mTranslucentActivityWaiting != null &&
1947 mUndrawnActivitiesBelowTopTranslucent.isEmpty()) {
1948 // Nothing is getting drawn or everything was already visible, don't wait for timeout.
1949 notifyActivityDrawnLocked(null);
1950 }
1951 } finally {
1952 mStackSupervisor.mKeyguardController.endActivityVisibilityUpdate();
1953 }
1954 }
1955
Jorim Jaggi8b702ed2017-01-20 16:59:03 +01001956 void addStartingWindowsForVisibleActivities(boolean taskSwitch) {
1957 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
1958 mTaskHistory.get(taskNdx).addStartingWindowsForVisibleActivities(taskSwitch);
1959 }
1960 }
1961
Jorim Jaggife762342016-10-13 14:33:27 +02001962 /**
1963 * @return true if the top visible activity wants to occlude the Keyguard, false otherwise
1964 */
1965 boolean topActivityOccludesKeyguard() {
1966 return mTopActivityOccludesKeyguard;
1967 }
1968
1969 /**
1970 * @return the top most visible activity that wants to dismiss Keyguard
1971 */
1972 ActivityRecord getTopDismissingKeyguardActivity() {
1973 return mTopDismissingKeyguardActivity;
1974 }
1975
1976 /**
1977 * Checks whether {@param r} should be visible depending on Keyguard state and updates
1978 * {@link #mTopActivityOccludesKeyguard} and {@link #mTopDismissingKeyguardActivity} if
1979 * necessary.
1980 *
1981 * @return true if {@param r} is visible taken Keyguard state into account, false otherwise
1982 */
Wale Ogunwaled334a052017-05-12 07:17:36 -07001983 boolean checkKeyguardVisibility(ActivityRecord r, boolean shouldBeVisible,
Jorim Jaggife762342016-10-13 14:33:27 +02001984 boolean isTop) {
Winson Chung0655da02016-12-16 17:05:01 -08001985 final boolean isInPinnedStack = r.getStack().getStackId() == PINNED_STACK_ID;
Jorim Jaggife762342016-10-13 14:33:27 +02001986 final boolean keyguardShowing = mStackSupervisor.mKeyguardController.isKeyguardShowing();
1987 final boolean keyguardLocked = mStackSupervisor.mKeyguardController.isKeyguardLocked();
chaviw59b98852017-06-13 12:05:44 -07001988 final boolean showWhenLocked = r.canShowWhenLocked() && !isInPinnedStack;
Jorim Jaggie69c9312016-10-31 18:24:38 -07001989 final boolean dismissKeyguard = r.hasDismissKeyguardWindows();
Jorim Jaggife762342016-10-13 14:33:27 +02001990 if (shouldBeVisible) {
Jorim Jaggie69c9312016-10-31 18:24:38 -07001991 if (dismissKeyguard && mTopDismissingKeyguardActivity == null) {
Jorim Jaggife762342016-10-13 14:33:27 +02001992 mTopDismissingKeyguardActivity = r;
1993 }
1994
1995 // Only the top activity may control occluded, as we can't occlude the Keyguard if the
1996 // top app doesn't want to occlude it.
1997 if (isTop) {
1998 mTopActivityOccludesKeyguard |= showWhenLocked;
Wale Ogunwalec219c0b2015-09-12 09:18:07 -07001999 }
Andrii Kulianfc8f82b2017-01-26 13:17:27 -08002000
Andrii Kulian7211d2e2017-01-27 15:58:05 -08002001 final boolean canShowWithKeyguard = canShowWithInsecureKeyguard()
Andrii Kulianfc8f82b2017-01-26 13:17:27 -08002002 && mStackSupervisor.mKeyguardController.canDismissKeyguard();
2003 if (canShowWithKeyguard) {
2004 return true;
2005 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002006 }
Jorim Jaggife762342016-10-13 14:33:27 +02002007 if (keyguardShowing) {
Craig Mautnereb8abf72014-07-02 15:04:09 -07002008
Jorim Jaggie69c9312016-10-31 18:24:38 -07002009 // If keyguard is showing, nothing is visible, except if we are able to dismiss Keyguard
2010 // right away.
2011 return shouldBeVisible && mStackSupervisor.mKeyguardController
Jorim Jaggi07961872016-11-23 11:28:57 +01002012 .canShowActivityWhileKeyguardShowing(r, dismissKeyguard);
Jorim Jaggife762342016-10-13 14:33:27 +02002013 } else if (keyguardLocked) {
Jorim Jaggi07961872016-11-23 11:28:57 +01002014 return shouldBeVisible && mStackSupervisor.mKeyguardController.canShowWhileOccluded(
2015 dismissKeyguard, showWhenLocked);
Jorim Jaggife762342016-10-13 14:33:27 +02002016 } else {
2017 return shouldBeVisible;
Craig Mautnereb8abf72014-07-02 15:04:09 -07002018 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002019 }
Craig Mautner58547802013-03-05 08:23:53 -08002020
Andrii Kulianfc8f82b2017-01-26 13:17:27 -08002021 /**
2022 * Check if the display to which this stack is attached has
Andrii Kulian7211d2e2017-01-27 15:58:05 -08002023 * {@link Display#FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD} applied.
Andrii Kulianfc8f82b2017-01-26 13:17:27 -08002024 */
Andrii Kulian7211d2e2017-01-27 15:58:05 -08002025 private boolean canShowWithInsecureKeyguard() {
Andrii Kulian94e82d9b02017-07-13 15:33:06 -07002026 final ActivityStackSupervisor.ActivityDisplay activityDisplay = getDisplay();
Andrii Kulianfc8f82b2017-01-26 13:17:27 -08002027 if (activityDisplay == null) {
2028 throw new IllegalStateException("Stack is not attached to any display, stackId="
2029 + mStackId);
2030 }
2031
2032 final int flags = activityDisplay.mDisplay.getFlags();
Andrii Kulian7211d2e2017-01-27 15:58:05 -08002033 return (flags & FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0;
Andrii Kulianfc8f82b2017-01-26 13:17:27 -08002034 }
2035
Filip Gruszczynski9104aea2015-11-13 16:42:05 -08002036 private void checkTranslucentActivityWaiting(ActivityRecord top) {
2037 if (mTranslucentActivityWaiting != top) {
2038 mUndrawnActivitiesBelowTopTranslucent.clear();
2039 if (mTranslucentActivityWaiting != null) {
2040 // Call the callback with a timeout indication.
2041 notifyActivityDrawnLocked(null);
2042 mTranslucentActivityWaiting = null;
2043 }
2044 mHandler.removeMessages(TRANSLUCENT_TIMEOUT_MSG);
2045 }
2046 }
2047
2048 private boolean makeVisibleAndRestartIfNeeded(ActivityRecord starting, int configChanges,
Wale Ogunwaled046a012015-12-24 13:05:59 -08002049 boolean isTop, boolean andResume, ActivityRecord r) {
Filip Gruszczynski9104aea2015-11-13 16:42:05 -08002050 // We need to make sure the app is running if it's the top, or it is just made visible from
2051 // invisible. If the app is already visible, it must have died while it was visible. In this
2052 // case, we'll show the dead window but will not restart the app. Otherwise we could end up
2053 // thrashing.
Filip Gruszczynski21199bd2015-12-02 12:49:58 -08002054 if (isTop || !r.visible) {
Filip Gruszczynski9104aea2015-11-13 16:42:05 -08002055 // This activity needs to be visible, but isn't even running...
2056 // get it started and resume if no other stack in this stack is resumed.
2057 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Start and freeze screen for " + r);
2058 if (r != starting) {
2059 r.startFreezingScreenLocked(r.app, configChanges);
2060 }
2061 if (!r.visible || r.mLaunchTaskBehind) {
2062 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Starting and making visible: " + r);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002063 r.setVisible(true);
Filip Gruszczynski9104aea2015-11-13 16:42:05 -08002064 }
2065 if (r != starting) {
Wale Ogunwaled046a012015-12-24 13:05:59 -08002066 mStackSupervisor.startSpecificActivityLocked(r, andResume, false);
Filip Gruszczynski9104aea2015-11-13 16:42:05 -08002067 return true;
2068 }
2069 }
2070 return false;
2071 }
2072
Wale Ogunwalec981ad52017-06-13 11:40:06 -07002073 // TODO: Should probably be moved into ActivityRecord.
2074 private void makeInvisible(ActivityRecord r) {
Filip Gruszczynski9104aea2015-11-13 16:42:05 -08002075 if (!r.visible) {
2076 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Already invisible: " + r);
2077 return;
2078 }
2079 // Now for any activities that aren't visible to the user, make sure they no longer are
2080 // keeping the screen frozen.
Filip Gruszczynski4e7fe712016-01-13 13:22:44 -08002081 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Making invisible: " + r + " " + r.state);
Filip Gruszczynski9104aea2015-11-13 16:42:05 -08002082 try {
Wale Ogunwaleb9a0c992017-04-18 07:25:20 -07002083 final boolean canEnterPictureInPicture = r.checkEnterPictureInPictureState(
Winson Chung298f95b2017-08-10 15:57:18 -07002084 "makeInvisible", true /* beforeStopping */);
Wale Ogunwale89973222017-04-23 18:39:45 -07002085 // Defer telling the client it is hidden if it can enter Pip and isn't current stopped
2086 // or stopping. This gives it a chance to enter Pip in onPause().
2087 final boolean deferHidingClient = canEnterPictureInPicture
2088 && r.state != STOPPING && r.state != STOPPED;
Wale Ogunwaleec950642017-04-25 07:44:21 -07002089 r.setDeferHidingClient(deferHidingClient);
2090 r.setVisible(false);
Wale Ogunwaleb9a0c992017-04-18 07:25:20 -07002091
Filip Gruszczynski9104aea2015-11-13 16:42:05 -08002092 switch (r.state) {
2093 case STOPPING:
2094 case STOPPED:
2095 if (r.app != null && r.app.thread != null) {
2096 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
2097 "Scheduling invisibility: " + r);
2098 r.app.thread.scheduleWindowVisibility(r.appToken, false);
2099 }
Winson Chungc2baac02017-01-11 13:34:47 -08002100
2101 // Reset the flag indicating that an app can enter picture-in-picture once the
2102 // activity is hidden
2103 r.supportsPictureInPictureWhilePausing = false;
Filip Gruszczynski9104aea2015-11-13 16:42:05 -08002104 break;
2105
2106 case INITIALIZING:
2107 case RESUMED:
2108 case PAUSING:
2109 case PAUSED:
Wale Ogunwalec981ad52017-06-13 11:40:06 -07002110 addToStopping(r, true /* scheduleIdle */,
2111 canEnterPictureInPicture /* idleDelayed */);
Filip Gruszczynski9104aea2015-11-13 16:42:05 -08002112 break;
2113
2114 default:
2115 break;
2116 }
2117 } catch (Exception e) {
2118 // Just skip on any failure; we'll make it visible when it next restarts.
2119 Slog.w(TAG, "Exception thrown making hidden: " + r.intent.getComponent(), e);
2120 }
2121 }
2122
2123 private boolean updateBehindFullscreen(boolean stackInvisible, boolean behindFullscreenActivity,
2124 TaskRecord task, ActivityRecord r) {
2125 if (r.fullscreen) {
Filip Gruszczynski9104aea2015-11-13 16:42:05 -08002126 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Fullscreen: at " + r
Wale Ogunwale673cbd22016-01-30 18:30:55 -08002127 + " stackInvisible=" + stackInvisible
2128 + " behindFullscreenActivity=" + behindFullscreenActivity);
Filip Gruszczynski0e381e22016-01-14 16:31:33 -08002129 // At this point, nothing else needs to be shown in this task.
Filip Gruszczynski9104aea2015-11-13 16:42:05 -08002130 behindFullscreenActivity = true;
Matthew Ngae1ff4f2016-11-10 15:49:14 -08002131 } else if (!isHomeOrRecentsStack() && r.frontOfTask && task.isOverHomeStack()) {
Filip Gruszczynski9104aea2015-11-13 16:42:05 -08002132 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Showing home: at " + r
2133 + " stackInvisible=" + stackInvisible
2134 + " behindFullscreenActivity=" + behindFullscreenActivity);
Filip Gruszczynski0e381e22016-01-14 16:31:33 -08002135 behindFullscreenActivity = true;
Filip Gruszczynski9104aea2015-11-13 16:42:05 -08002136 }
2137 return behindFullscreenActivity;
2138 }
2139
Todd Kennedyaab56db2015-01-30 09:39:53 -08002140 void convertActivityToTranslucent(ActivityRecord r) {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002141 mTranslucentActivityWaiting = r;
2142 mUndrawnActivitiesBelowTopTranslucent.clear();
2143 mHandler.sendEmptyMessageDelayed(TRANSLUCENT_TIMEOUT_MSG, TRANSLUCENT_CONVERSION_TIMEOUT);
2144 }
2145
Dianne Hackbornb5a380d2015-05-20 18:18:46 -07002146 void clearOtherAppTimeTrackers(AppTimeTracker except) {
2147 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
2148 final TaskRecord task = mTaskHistory.get(taskNdx);
2149 final ArrayList<ActivityRecord> activities = task.mActivities;
2150 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2151 final ActivityRecord r = activities.get(activityNdx);
2152 if ( r.appTimeTracker != except) {
2153 r.appTimeTracker = null;
2154 }
2155 }
2156 }
2157 }
2158
Craig Mautner5eda9b32013-07-02 11:58:16 -07002159 /**
2160 * Called as activities below the top translucent activity are redrawn. When the last one is
2161 * redrawn notify the top activity by calling
2162 * {@link Activity#onTranslucentConversionComplete}.
2163 *
2164 * @param r The most recent background activity to be drawn. Or, if r is null then a timeout
2165 * occurred and the activity will be notified immediately.
2166 */
2167 void notifyActivityDrawnLocked(ActivityRecord r) {
2168 if ((r == null)
2169 || (mUndrawnActivitiesBelowTopTranslucent.remove(r) &&
2170 mUndrawnActivitiesBelowTopTranslucent.isEmpty())) {
2171 // The last undrawn activity below the top has just been drawn. If there is an
2172 // opaque activity at the top, notify it that it can become translucent safely now.
2173 final ActivityRecord waitingActivity = mTranslucentActivityWaiting;
2174 mTranslucentActivityWaiting = null;
2175 mUndrawnActivitiesBelowTopTranslucent.clear();
2176 mHandler.removeMessages(TRANSLUCENT_TIMEOUT_MSG);
2177
Craig Mautner71dd1b62014-02-18 15:48:52 -08002178 if (waitingActivity != null) {
2179 mWindowManager.setWindowOpaque(waitingActivity.appToken, false);
2180 if (waitingActivity.app != null && waitingActivity.app.thread != null) {
2181 try {
2182 waitingActivity.app.thread.scheduleTranslucentConversionComplete(
2183 waitingActivity.appToken, r != null);
2184 } catch (RemoteException e) {
2185 }
Craig Mautner5eda9b32013-07-02 11:58:16 -07002186 }
2187 }
2188 }
2189 }
2190
Craig Mautnera61bc652013-10-28 15:43:18 -07002191 /** If any activities below the top running one are in the INITIALIZING state and they have a
2192 * starting window displayed then remove that starting window. It is possible that the activity
2193 * in this state will never resumed in which case that starting window will be orphaned. */
2194 void cancelInitializingActivities() {
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -07002195 final ActivityRecord topActivity = topRunningActivityLocked();
Craig Mautnera61bc652013-10-28 15:43:18 -07002196 boolean aboveTop = true;
Wale Ogunwale68741142016-05-17 09:40:02 -07002197 // We don't want to clear starting window for activities that aren't behind fullscreen
2198 // activities as we need to display their starting window until they are done initializing.
2199 boolean behindFullscreenActivity = false;
Wale Ogunwale98742a52016-07-12 10:29:12 -07002200
Wale Ogunwalecd501ec2017-04-07 08:53:41 -07002201 if (shouldBeVisible(null) == STACK_INVISIBLE) {
Wale Ogunwale98742a52016-07-12 10:29:12 -07002202 // The stack is not visible, so no activity in it should be displaying a starting
2203 // window. Mark all activities below top and behind fullscreen.
2204 aboveTop = false;
2205 behindFullscreenActivity = true;
2206 }
2207
Craig Mautnera61bc652013-10-28 15:43:18 -07002208 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
2209 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
2210 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2211 final ActivityRecord r = activities.get(activityNdx);
2212 if (aboveTop) {
2213 if (r == topActivity) {
2214 aboveTop = false;
2215 }
Wale Ogunwale68741142016-05-17 09:40:02 -07002216 behindFullscreenActivity |= r.fullscreen;
Craig Mautnera61bc652013-10-28 15:43:18 -07002217 continue;
2218 }
2219
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002220 r.removeOrphanedStartingWindow(behindFullscreenActivity);
Wale Ogunwale68741142016-05-17 09:40:02 -07002221 behindFullscreenActivity |= r.fullscreen;
Craig Mautnera61bc652013-10-28 15:43:18 -07002222 }
2223 }
2224 }
2225
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002226 /**
2227 * Ensure that the top activity in the stack is resumed.
2228 *
2229 * @param prev The previously resumed activity, for when in the process
2230 * of pausing; can be null to call from elsewhere.
Wale Ogunwaled046a012015-12-24 13:05:59 -08002231 * @param options Activity options.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002232 *
2233 * @return Returns true if something is being resumed, or false if
2234 * nothing happened.
Wale Ogunwaled046a012015-12-24 13:05:59 -08002235 *
2236 * NOTE: It is not safe to call this method directly as it can cause an activity in a
2237 * non-focused stack to be resumed.
2238 * Use {@link ActivityStackSupervisor#resumeFocusedStackTopActivityLocked} to resume the
2239 * right activity for the current system state.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002240 */
Wale Ogunwaled046a012015-12-24 13:05:59 -08002241 boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
Craig Mautner42d04db2014-11-06 12:13:23 -08002242 if (mStackSupervisor.inResumeTopActivity) {
Craig Mautner544efa72014-09-04 16:41:20 -07002243 // Don't even start recursing.
2244 return false;
2245 }
2246
2247 boolean result = false;
2248 try {
2249 // Protect against recursion.
Craig Mautner42d04db2014-11-06 12:13:23 -08002250 mStackSupervisor.inResumeTopActivity = true;
Craig Mautner544efa72014-09-04 16:41:20 -07002251 result = resumeTopActivityInnerLocked(prev, options);
2252 } finally {
Craig Mautner42d04db2014-11-06 12:13:23 -08002253 mStackSupervisor.inResumeTopActivity = false;
Craig Mautner544efa72014-09-04 16:41:20 -07002254 }
chaviw59b98852017-06-13 12:05:44 -07002255
Bryce Lee5daa3122017-04-19 10:40:42 -07002256 // When resuming the top activity, it may be necessary to pause the top activity (for
2257 // example, returning to the lock screen. We suppress the normal pause logic in
2258 // {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the end.
2259 // We call the {@link ActivityStackSupervisor#checkReadyForSleepLocked} again here to ensure
chaviw59b98852017-06-13 12:05:44 -07002260 // any necessary pause logic occurs. In the case where the Activity will be shown regardless
2261 // of the lock screen, the call to {@link ActivityStackSupervisor#checkReadyForSleepLocked}
2262 // is skipped.
2263 final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
2264 if (next == null || !next.canTurnScreenOn()) {
David Stevens9440dc82017-03-16 19:00:20 -07002265 checkReadyForSleep();
chaviw59b98852017-06-13 12:05:44 -07002266 }
Bryce Lee5daa3122017-04-19 10:40:42 -07002267
Craig Mautner544efa72014-09-04 16:41:20 -07002268 return result;
2269 }
2270
Chong Zhang6cda19c2016-06-14 19:07:56 -07002271 void setResumedActivityLocked(ActivityRecord r, String reason) {
2272 // TODO: move mResumedActivity to stack supervisor,
2273 // there should only be 1 global copy of resumed activity.
2274 mResumedActivity = r;
Chong Zhangd2cb3112016-07-20 11:13:22 -07002275 r.state = ActivityState.RESUMED;
Chong Zhang6cda19c2016-06-14 19:07:56 -07002276 mService.setResumedActivityUncheckLocked(r, reason);
Bryce Leeaf691c02017-03-20 14:20:22 -07002277 final TaskRecord task = r.getTask();
2278 task.touchActiveTime();
2279 mRecentTasks.addLocked(task);
Chong Zhang6cda19c2016-06-14 19:07:56 -07002280 }
2281
Chong Zhang280d3322015-11-03 17:27:26 -08002282 private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
Dianne Hackborn7622a0f2014-09-30 14:31:42 -07002283 if (!mService.mBooting && !mService.mBooted) {
2284 // Not ready yet!
2285 return false;
2286 }
2287
Winson Chung3f103eb2017-04-12 21:53:59 -07002288 // Find the next top-most activity to resume in this stack that is not finishing and is
2289 // focusable. If it is not focusable, we will fall into the case below to resume the
2290 // top activity in the next focusable task.
2291 final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
Andrii Kulian7fc22812016-12-28 13:04:11 -08002292
2293 final boolean hasRunningActivity = next != null;
2294
Andrii Kulian94e82d9b02017-07-13 15:33:06 -07002295 // TODO: Maybe this entire condition can get removed?
2296 if (hasRunningActivity && getDisplay() == null) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08002297 return false;
2298 }
2299
Wale Ogunwale2be760d2016-02-17 11:16:10 -08002300 mStackSupervisor.cancelInitializingActivities();
Craig Mautnera61bc652013-10-28 15:43:18 -07002301
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002302 // Remember how we'll process this pause/resume situation, and ensure
2303 // that the state is reset however we wind up proceeding.
Craig Mautnerde4ef022013-04-07 19:01:33 -07002304 final boolean userLeaving = mStackSupervisor.mUserLeaving;
2305 mStackSupervisor.mUserLeaving = false;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002306
Andrii Kulian7fc22812016-12-28 13:04:11 -08002307 if (!hasRunningActivity) {
2308 // There are no activities left in the stack, let's look somewhere else.
2309 return resumeTopActivityInNextFocusableStack(prev, options, "noMoreActivities");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002310 }
2311
2312 next.delayedResume = false;
Craig Mautner58547802013-03-05 08:23:53 -08002313
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002314 // If the top activity is the resumed one, nothing to do.
Craig Mautnerde4ef022013-04-07 19:01:33 -07002315 if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
2316 mStackSupervisor.allResumedActivitiesComplete()) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002317 // Make sure we have executed any pending transitions, since there
2318 // should be nothing left to do at this point.
skuhne@google.com1b974dc2016-12-09 13:41:29 -08002319 executeAppTransition(options);
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07002320 if (DEBUG_STATES) Slog.d(TAG_STATES,
2321 "resumeTopActivityLocked: Top activity resumed " + next);
Craig Mautnercf910b02013-04-23 11:23:27 -07002322 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002323 return false;
2324 }
2325
Bryce Leeaf691c02017-03-20 14:20:22 -07002326 final TaskRecord nextTask = next.getTask();
2327 final TaskRecord prevTask = prev != null ? prev.getTask() : null;
Andrii Kulian02b7a832016-10-06 23:11:56 -07002328 if (prevTask != null && prevTask.getStack() == this &&
Craig Mautner84984fa2014-06-19 11:19:20 -07002329 prevTask.isOverHomeStack() && prev.finishing && prev.frontOfTask) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002330 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
Craig Mautner525f3d92013-05-07 14:01:50 -07002331 if (prevTask == nextTask) {
Craig Mautner1aa9d0d3f2013-12-16 15:58:31 -08002332 prevTask.setFrontOfTask();
Craig Mautner525f3d92013-05-07 14:01:50 -07002333 } else if (prevTask != topTask()) {
Craig Mautner84984fa2014-06-19 11:19:20 -07002334 // This task is going away but it was supposed to return to the home stack.
Craig Mautnere418ecd2013-05-01 17:02:29 -07002335 // Now the task above it has to return to the home task instead.
Craig Mautner525f3d92013-05-07 14:01:50 -07002336 final int taskNdx = mTaskHistory.indexOf(prevTask) + 1;
Craig Mautner84984fa2014-06-19 11:19:20 -07002337 mTaskHistory.get(taskNdx).setTaskToReturnTo(HOME_ACTIVITY_TYPE);
louis_chang2d094e92015-01-21 19:01:52 +08002338 } else if (!isOnHomeDisplay()) {
2339 return false;
2340 } else if (!isHomeStack()){
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07002341 if (DEBUG_STATES) Slog.d(TAG_STATES,
Craig Mautnere0a38842013-12-16 16:14:02 -08002342 "resumeTopActivityLocked: Launching home next");
Craig Mautner84984fa2014-06-19 11:19:20 -07002343 return isOnHomeDisplay() &&
Matthew Ngae1ff4f2016-11-10 15:49:14 -08002344 mStackSupervisor.resumeHomeStackTask(prev, "prevFinished");
Craig Mautnere418ecd2013-05-01 17:02:29 -07002345 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07002346 }
2347
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002348 // If we are sleeping, and there is no resumed activity, and the top
2349 // activity is paused, well that is the state we want.
David Stevens9440dc82017-03-16 19:00:20 -07002350 if (shouldSleepOrShutDownActivities()
p13451dbad2872012-04-18 11:39:23 +09002351 && mLastPausedActivity == next
Craig Mautner5314a402013-09-26 12:40:16 -07002352 && mStackSupervisor.allPausedActivitiesComplete()) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002353 // Make sure we have executed any pending transitions, since there
2354 // should be nothing left to do at this point.
skuhne@google.com1b974dc2016-12-09 13:41:29 -08002355 executeAppTransition(options);
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07002356 if (DEBUG_STATES) Slog.d(TAG_STATES,
2357 "resumeTopActivityLocked: Going to sleep and all paused");
Craig Mautnercf910b02013-04-23 11:23:27 -07002358 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002359 return false;
2360 }
Dianne Hackborn80a4af22012-08-27 19:18:31 -07002361
2362 // Make sure that the user who owns this activity is started. If not,
2363 // we will just leave it as is because someone should be bringing
2364 // another user's activities to the top of the stack.
Fyodor Kupolov610acda2015-10-19 18:44:07 -07002365 if (!mService.mUserController.hasStartedUserState(next.userId)) {
Dianne Hackborn80a4af22012-08-27 19:18:31 -07002366 Slog.w(TAG, "Skipping resume of top activity " + next
2367 + ": user " + next.userId + " is stopped");
Craig Mautnercf910b02013-04-23 11:23:27 -07002368 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
Dianne Hackborn80a4af22012-08-27 19:18:31 -07002369 return false;
2370 }
2371
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002372 // The activity may be waiting for stop, but that is no longer
2373 // appropriate for it.
Craig Mautnerde4ef022013-04-07 19:01:33 -07002374 mStackSupervisor.mStoppingActivities.remove(next);
Craig Mautner0eea92c2013-05-16 13:35:39 -07002375 mStackSupervisor.mGoingToSleepActivities.remove(next);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002376 next.sleeping = false;
Bryce Lee4a194382017-04-04 14:32:48 -07002377 mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(next);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002378
Wale Ogunwaleee006da2015-03-30 14:49:25 -07002379 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resuming " + next);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002380
Wale Ogunwale5658e4b2016-02-12 12:22:19 -08002381 // If we are currently pausing an activity, then don't do anything until that is done.
Craig Mautner69ada552013-04-18 13:51:51 -07002382 if (!mStackSupervisor.allPausedActivitiesComplete()) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07002383 if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
Craig Mautnerac6f8432013-07-17 13:24:59 -07002384 "resumeTopActivityLocked: Skip resume: some activity pausing.");
Craig Mautnercf910b02013-04-23 11:23:27 -07002385 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08002386 return false;
2387 }
2388
Dianne Hackborn3d07c942015-03-13 18:02:54 -07002389 mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);
2390
Wale Ogunwale89973222017-04-23 18:39:45 -07002391 boolean lastResumedCanPip = false;
2392 final ActivityStack lastFocusedStack = mStackSupervisor.getLastStack();
2393 if (lastFocusedStack != null && lastFocusedStack != this) {
2394 // So, why aren't we using prev here??? See the param comment on the method. prev doesn't
2395 // represent the last resumed activity. However, the last focus stack does if it isn't null.
2396 final ActivityRecord lastResumed = lastFocusedStack.mResumedActivity;
2397 lastResumedCanPip = lastResumed != null && lastResumed.checkEnterPictureInPictureState(
Winson Chung298f95b2017-08-10 15:57:18 -07002398 "resumeTopActivity", userLeaving /* beforeStopping */);
Wale Ogunwale89973222017-04-23 18:39:45 -07002399 }
Winson Chungc2baac02017-01-11 13:34:47 -08002400 // If the flag RESUME_WHILE_PAUSING is set, then continue to schedule the previous activity
Wale Ogunwaleb9a0c992017-04-18 07:25:20 -07002401 // to be paused, while at the same time resuming the new resume activity only if the
2402 // previous activity can't go into Pip since we want to give Pip activities a chance to
2403 // enter Pip before resuming the next activity.
Wale Ogunwale89973222017-04-23 18:39:45 -07002404 final boolean resumeWhilePausing = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0
2405 && !lastResumedCanPip;
2406
Winson Chungc2baac02017-01-11 13:34:47 -08002407 boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);
Craig Mautnereb957862013-04-24 15:34:32 -07002408 if (mResumedActivity != null) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07002409 if (DEBUG_STATES) Slog.d(TAG_STATES,
2410 "resumeTopActivityLocked: Pausing " + mResumedActivity);
Winson Chungc2baac02017-01-11 13:34:47 -08002411 pausing |= startPausingLocked(userLeaving, false, next, false);
Craig Mautnereb957862013-04-24 15:34:32 -07002412 }
Winson Chungc2baac02017-01-11 13:34:47 -08002413 if (pausing && !resumeWhilePausing) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07002414 if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG_STATES,
Craig Mautnerac6f8432013-07-17 13:24:59 -07002415 "resumeTopActivityLocked: Skip resume: need to start pausing");
Dianne Hackbornad9b32112012-09-17 15:35:01 -07002416 // At this point we want to put the upcoming activity's process
2417 // at the top of the LRU list, since we know we will be needing it
2418 // very soon and it would be a waste to let it get killed if it
2419 // happens to be sitting towards the end.
2420 if (next.app != null && next.app.thread != null) {
Dianne Hackborndb926082013-10-31 16:32:44 -07002421 mService.updateLruProcessLocked(next.app, true, null);
Dianne Hackbornad9b32112012-09-17 15:35:01 -07002422 }
Craig Mautnercf910b02013-04-23 11:23:27 -07002423 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002424 return true;
Wale Ogunwalecac5c322016-05-23 10:56:33 -07002425 } else if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
2426 mStackSupervisor.allResumedActivitiesComplete()) {
2427 // It is possible for the activity to be resumed when we paused back stacks above if the
2428 // next activity doesn't have to wait for pause to complete.
2429 // So, nothing else to-do except:
2430 // Make sure we have executed any pending transitions, since there
2431 // should be nothing left to do at this point.
skuhne@google.com1b974dc2016-12-09 13:41:29 -08002432 executeAppTransition(options);
Wale Ogunwalecac5c322016-05-23 10:56:33 -07002433 if (DEBUG_STATES) Slog.d(TAG_STATES,
2434 "resumeTopActivityLocked: Top activity resumed (dontWaitForPause) " + next);
2435 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
2436 return true;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002437 }
2438
Christopher Tated3f175c2012-06-14 14:16:54 -07002439 // If the most recent activity was noHistory but was only stopped rather
2440 // than stopped+finished because the device went to sleep, we need to make
2441 // sure to finish it as we're making a new activity topmost.
David Stevens9440dc82017-03-16 19:00:20 -07002442 if (shouldSleepActivities() && mLastNoHistoryActivity != null &&
Craig Mautner0f922742013-08-06 08:44:42 -07002443 !mLastNoHistoryActivity.finishing) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07002444 if (DEBUG_STATES) Slog.d(TAG_STATES,
2445 "no-history finish of " + mLastNoHistoryActivity + " on new resume");
Craig Mautner0f922742013-08-06 08:44:42 -07002446 requestFinishActivityLocked(mLastNoHistoryActivity.appToken, Activity.RESULT_CANCELED,
Todd Kennedy539db512014-12-15 09:57:55 -08002447 null, "resume-no-history", false);
Craig Mautner0f922742013-08-06 08:44:42 -07002448 mLastNoHistoryActivity = null;
Christopher Tated3f175c2012-06-14 14:16:54 -07002449 }
2450
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002451 if (prev != null && prev != next) {
Bryce Lee4a194382017-04-04 14:32:48 -07002452 if (!mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(prev)
Craig Mautner8c14c152015-01-15 17:32:07 -08002453 && next != null && !next.nowVisible) {
Bryce Lee4a194382017-04-04 14:32:48 -07002454 mStackSupervisor.mActivitiesWaitingForVisibleActivity.add(prev);
Wale Ogunwaleee006da2015-03-30 14:49:25 -07002455 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
2456 "Resuming top, waiting visible to hide: " + prev);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002457 } else {
2458 // The next activity is already visible, so hide the previous
2459 // activity's windows right now so we can show the new one ASAP.
2460 // We only do this if the previous is finishing, which should mean
2461 // it is on top of the one being resumed so hiding it quickly
2462 // is good. Otherwise, we want to do the normal route of allowing
2463 // the resumed activity to be shown so we can decide if the
2464 // previous should actually be hidden depending on whether the
2465 // new one is found to be full-screen or not.
2466 if (prev.finishing) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002467 prev.setVisibility(false);
Wale Ogunwaleee006da2015-03-30 14:49:25 -07002468 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
2469 "Not waiting for visible to hide: " + prev + ", waitingVisible="
Bryce Lee4a194382017-04-04 14:32:48 -07002470 + mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(prev)
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002471 + ", nowVisible=" + next.nowVisible);
2472 } else {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07002473 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
Craig Mautner8c14c152015-01-15 17:32:07 -08002474 "Previous already visible but still waiting to hide: " + prev
Wale Ogunwaleee006da2015-03-30 14:49:25 -07002475 + ", waitingVisible="
Bryce Lee4a194382017-04-04 14:32:48 -07002476 + mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(prev)
Wale Ogunwaleee006da2015-03-30 14:49:25 -07002477 + ", nowVisible=" + next.nowVisible);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002478 }
2479 }
2480 }
2481
Dianne Hackborne7f97212011-02-24 14:40:20 -08002482 // Launching this app's activity, make sure the app is no longer
2483 // considered stopped.
2484 try {
2485 AppGlobals.getPackageManager().setPackageStoppedState(
Amith Yamasani483f3b02012-03-13 16:08:00 -07002486 next.packageName, false, next.userId); /* TODO: Verify if correct userid */
Dianne Hackborne7f97212011-02-24 14:40:20 -08002487 } catch (RemoteException e1) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08002488 } catch (IllegalArgumentException e) {
2489 Slog.w(TAG, "Failed trying to unstop package "
2490 + next.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08002491 }
2492
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002493 // We are starting up the next activity, so tell the window manager
2494 // that the previous one will be hidden soon. This way it can know
2495 // to ignore it when computing the desired screen orientation.
Craig Mautner525f3d92013-05-07 14:01:50 -07002496 boolean anim = true;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002497 if (prev != null) {
2498 if (prev.finishing) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07002499 if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002500 "Prepare close transition: prev=" + prev);
2501 if (mNoAnimActivities.contains(prev)) {
Craig Mautner525f3d92013-05-07 14:01:50 -07002502 anim = false;
Jorim Jaggiaf80db42016-04-07 19:19:15 -07002503 mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002504 } else {
Bryce Leeaf691c02017-03-20 14:20:22 -07002505 mWindowManager.prepareAppTransition(prev.getTask() == next.getTask()
Jorim Jaggiaf80db42016-04-07 19:19:15 -07002506 ? TRANSIT_ACTIVITY_CLOSE
2507 : TRANSIT_TASK_CLOSE, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002508 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002509 prev.setVisibility(false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002510 } else {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07002511 if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
2512 "Prepare open transition: prev=" + prev);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002513 if (mNoAnimActivities.contains(next)) {
Craig Mautner525f3d92013-05-07 14:01:50 -07002514 anim = false;
Jorim Jaggiaf80db42016-04-07 19:19:15 -07002515 mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002516 } else {
Bryce Leeaf691c02017-03-20 14:20:22 -07002517 mWindowManager.prepareAppTransition(prev.getTask() == next.getTask()
Jorim Jaggiaf80db42016-04-07 19:19:15 -07002518 ? TRANSIT_ACTIVITY_OPEN
Craig Mautnerbb742462014-07-07 15:28:55 -07002519 : next.mLaunchTaskBehind
Jorim Jaggiaf80db42016-04-07 19:19:15 -07002520 ? TRANSIT_TASK_OPEN_BEHIND
2521 : TRANSIT_TASK_OPEN, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002522 }
2523 }
Craig Mautner967212c2013-04-13 21:10:58 -07002524 } else {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07002525 if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare open transition: no previous");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002526 if (mNoAnimActivities.contains(next)) {
Craig Mautner525f3d92013-05-07 14:01:50 -07002527 anim = false;
Jorim Jaggiaf80db42016-04-07 19:19:15 -07002528 mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002529 } else {
Jorim Jaggiaf80db42016-04-07 19:19:15 -07002530 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002531 }
2532 }
Adam Powellcfbe9be2013-11-06 14:58:58 -08002533
2534 Bundle resumeAnimOptions = null;
Craig Mautner525f3d92013-05-07 14:01:50 -07002535 if (anim) {
Adam Powellcfbe9be2013-11-06 14:58:58 -08002536 ActivityOptions opts = next.getOptionsForTargetActivityLocked();
2537 if (opts != null) {
2538 resumeAnimOptions = opts.toBundle();
2539 }
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07002540 next.applyOptionsLocked();
2541 } else {
2542 next.clearOptionsLocked();
2543 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002544
Craig Mautnercf910b02013-04-23 11:23:27 -07002545 ActivityStack lastStack = mStackSupervisor.getLastStack();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002546 if (next.app != null && next.app.thread != null) {
Chong Zhangdea4bd92016-03-15 12:50:03 -07002547 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resume running: " + next
2548 + " stopped=" + next.stopped + " visible=" + next.visible);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002549
Chong Zhangd127c6d2016-05-02 16:36:41 -07002550 // If the previous activity is translucent, force a visibility update of
2551 // the next activity, so that it's added to WM's opening app list, and
2552 // transition animation can be set up properly.
2553 // For example, pressing Home button with a translucent activity in focus.
2554 // Launcher is already visible in this case. If we don't add it to opening
2555 // apps, maybeUpdateTransitToWallpaper() will fail to identify this as a
2556 // TRANSIT_WALLPAPER_OPEN animation, and run some funny animation.
2557 final boolean lastActivityTranslucent = lastStack != null
2558 && (!lastStack.mFullscreen
2559 || (lastStack.mLastPausedActivity != null
2560 && !lastStack.mLastPausedActivity.fullscreen));
2561
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002562 // This activity is now becoming visible.
Chong Zhangd127c6d2016-05-02 16:36:41 -07002563 if (!next.visible || next.stopped || lastActivityTranslucent) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002564 next.setVisibility(true);
Jorim Jaggi1b025a62016-02-03 19:27:49 -08002565 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002566
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002567 // schedule launch ticks to collect information about slow apps.
2568 next.startLaunchTickingLocked();
2569
Craig Mautnerf88c50f2013-04-18 19:25:12 -07002570 ActivityRecord lastResumedActivity =
2571 lastStack == null ? null :lastStack.mResumedActivity;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002572 ActivityState lastState = next.state;
2573
2574 mService.updateCpuStats();
Craig Mautner58547802013-03-05 08:23:53 -08002575
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07002576 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + next + " (in existing)");
Chong Zhang6cda19c2016-06-14 19:07:56 -07002577
2578 setResumedActivityLocked(next, "resumeTopActivityInnerLocked");
2579
Dianne Hackborndb926082013-10-31 16:32:44 -07002580 mService.updateLruProcessLocked(next.app, true, null);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002581 updateLRUListLocked(next);
Dianne Hackborndb926082013-10-31 16:32:44 -07002582 mService.updateOomAdjLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002583
2584 // Have the window manager re-evaluate the orientation of
2585 // the screen based on the new activity order.
Craig Mautner525f3d92013-05-07 14:01:50 -07002586 boolean notUpdated = true;
Wale Ogunwale1e60e0c2015-10-28 13:36:10 -07002587 if (mStackSupervisor.isFocusedStack(this)) {
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002588 final Configuration config = mWindowManager.updateOrientationFromAppTokens(
2589 mStackSupervisor.getDisplayOverrideConfiguration(mDisplayId),
2590 next.mayFreezeScreenLocked(next.app) ? next.appToken : null, mDisplayId);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002591 if (config != null) {
2592 next.frozenBeforeDestroy = true;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002593 }
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002594 notUpdated = !mService.updateDisplayOverrideConfigurationLocked(config, next,
2595 false /* deferResume */, mDisplayId);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002596 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002597
Craig Mautner525f3d92013-05-07 14:01:50 -07002598 if (notUpdated) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002599 // The configuration update wasn't able to keep the existing
2600 // instance of the activity, and instead started a new one.
2601 // We should be all done, but let's just make sure our activity
2602 // is still at the top and schedule another run if something
2603 // weird happened.
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -07002604 ActivityRecord nextNext = topRunningActivityLocked();
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07002605 if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_STATES,
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002606 "Activity config changed during resume: " + next
2607 + ", new next: " + nextNext);
2608 if (nextNext != next) {
2609 // Do over!
Craig Mautner05d29032013-05-03 13:40:13 -07002610 mStackSupervisor.scheduleResumeTopActivities();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002611 }
Chong Zhangd2cb3112016-07-20 11:13:22 -07002612 if (!next.visible || next.stopped) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002613 next.setVisibility(true);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002614 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07002615 next.completeResumeLocked();
Craig Mautnercf910b02013-04-23 11:23:27 -07002616 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
Chong Zhangd2cb3112016-07-20 11:13:22 -07002617 return true;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002618 }
Craig Mautner58547802013-03-05 08:23:53 -08002619
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002620 try {
2621 // Deliver all pending results.
Craig Mautner05d6272ba2013-02-11 09:39:27 -08002622 ArrayList<ResultInfo> a = next.results;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002623 if (a != null) {
2624 final int N = a.size();
2625 if (!next.finishing && N > 0) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07002626 if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
2627 "Delivering results to " + next + ": " + a);
Dianne Hackbornbe707852011-11-11 14:32:10 -08002628 next.app.thread.scheduleSendResult(next.appToken, a);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002629 }
2630 }
2631
2632 if (next.newIntents != null) {
Wale Ogunwale826c7062016-09-13 08:25:54 -07002633 next.app.thread.scheduleNewIntent(
2634 next.newIntents, next.appToken, false /* andPause */);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002635 }
2636
Wale Ogunwale8d5a5422016-03-03 18:28:21 -08002637 // Well the app will no longer be stopped.
2638 // Clear app token stopped state in window manager if needed.
Jorim Jaggibae01b12017-04-11 16:29:10 -07002639 next.notifyAppResumed(next.stopped);
Wale Ogunwale8d5a5422016-03-03 18:28:21 -08002640
Craig Mautner299f9602015-01-26 09:47:33 -08002641 EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, next.userId,
Bryce Leeaf691c02017-03-20 14:20:22 -07002642 System.identityHashCode(next), next.getTask().taskId,
2643 next.shortComponentName);
Craig Mautner58547802013-03-05 08:23:53 -08002644
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002645 next.sleeping = false;
Alan Viverette5f31b982016-06-21 14:46:14 -04002646 mService.showUnsupportedZoomDialogIfNeededLocked(next);
Craig Mautner2420ead2013-04-01 17:13:20 -07002647 mService.showAskCompatModeDialogLocked(next);
Dianne Hackborn905577f2011-09-07 18:31:28 -07002648 next.app.pendingUiClean = true;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07002649 next.app.forceProcessStateUpTo(mService.mTopProcessState);
George Mount2c92c972014-03-20 09:38:23 -07002650 next.clearOptionsLocked();
Dianne Hackborna413dc02013-07-12 12:02:55 -07002651 next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,
Adam Powellcfbe9be2013-11-06 14:58:58 -08002652 mService.isNextTransitionForward(), resumeAnimOptions);
Craig Mautner58547802013-03-05 08:23:53 -08002653
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07002654 if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Resumed " + next);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002655 } catch (Exception e) {
2656 // Whoops, need to restart this activity!
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07002657 if (DEBUG_STATES) Slog.v(TAG_STATES, "Resume failed; resetting state to "
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002658 + lastState + ": " + next);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002659 next.state = lastState;
Craig Mautnerf88c50f2013-04-18 19:25:12 -07002660 if (lastStack != null) {
2661 lastStack.mResumedActivity = lastResumedActivity;
2662 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002663 Slog.i(TAG, "Restarting because process died: " + next);
2664 if (!next.hasBeenLaunched) {
2665 next.hasBeenLaunched = true;
Craig Mautnerf88c50f2013-04-18 19:25:12 -07002666 } else if (SHOW_APP_STARTING_PREVIEW && lastStack != null &&
Andrii Kulian7d95df42017-02-15 10:11:48 -08002667 mStackSupervisor.isFrontStackOnDisplay(lastStack)) {
Jorim Jaggi02886a82016-12-06 09:10:06 -08002668 next.showStartingWindow(null /* prev */, false /* newTask */,
2669 false /* taskSwitch */);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002670 }
George Mount2c92c972014-03-20 09:38:23 -07002671 mStackSupervisor.startSpecificActivityLocked(next, true, false);
Craig Mautnercf910b02013-04-23 11:23:27 -07002672 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002673 return true;
2674 }
2675
2676 // From this point on, if something goes wrong there is no way
2677 // to recover the activity.
2678 try {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002679 next.completeResumeLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002680 } catch (Exception e) {
2681 // If any exception gets thrown, toss away this
2682 // activity and try the next one.
2683 Slog.w(TAG, "Exception thrown during resume of " + next, e);
Dianne Hackbornbe707852011-11-11 14:32:10 -08002684 requestFinishActivityLocked(next.appToken, Activity.RESULT_CANCELED, null,
Dianne Hackborn2d1b3782012-09-09 17:49:39 -07002685 "resume-exception", true);
Craig Mautnercf910b02013-04-23 11:23:27 -07002686 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002687 return true;
2688 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002689 } else {
2690 // Whoops, need to restart this activity!
2691 if (!next.hasBeenLaunched) {
2692 next.hasBeenLaunched = true;
2693 } else {
2694 if (SHOW_APP_STARTING_PREVIEW) {
Jorim Jaggi02886a82016-12-06 09:10:06 -08002695 next.showStartingWindow(null /* prev */, false /* newTask */,
2696 false /* taskSwich */);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002697 }
Wale Ogunwaleee006da2015-03-30 14:49:25 -07002698 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002699 }
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07002700 if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
George Mount2c92c972014-03-20 09:38:23 -07002701 mStackSupervisor.startSpecificActivityLocked(next, true, true);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002702 }
2703
Craig Mautnercf910b02013-04-23 11:23:27 -07002704 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002705 return true;
2706 }
2707
Andrii Kulian7fc22812016-12-28 13:04:11 -08002708 private boolean resumeTopActivityInNextFocusableStack(ActivityRecord prev,
2709 ActivityOptions options, String reason) {
Winson Chung83471632016-12-13 11:02:12 -08002710 if ((!mFullscreen || !isOnHomeDisplay()) && adjustFocusToNextFocusableStackLocked(reason)) {
Andrii Kulian7fc22812016-12-28 13:04:11 -08002711 // Try to move focus to the next visible stack with a running activity if this
2712 // stack is not covering the entire screen or is on a secondary display (with no home
2713 // stack).
2714 return mStackSupervisor.resumeFocusedStackTopActivityLocked(
2715 mStackSupervisor.getFocusedStack(), prev, null);
2716 }
2717
2718 // Let's just start up the Launcher...
2719 ActivityOptions.abort(options);
2720 if (DEBUG_STATES) Slog.d(TAG_STATES,
2721 "resumeTopActivityInNextFocusableStack: " + reason + ", go home");
2722 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
2723 // Only resume home if on home display
2724 return isOnHomeDisplay() &&
2725 mStackSupervisor.resumeHomeStackTask(prev, reason);
2726 }
2727
riddle_hsuc215a4f2014-12-27 12:10:45 +08002728 private TaskRecord getNextTask(TaskRecord targetTask) {
2729 final int index = mTaskHistory.indexOf(targetTask);
2730 if (index >= 0) {
2731 final int numTasks = mTaskHistory.size();
2732 for (int i = index + 1; i < numTasks; ++i) {
2733 TaskRecord task = mTaskHistory.get(i);
2734 if (task.userId == targetTask.userId) {
2735 return task;
2736 }
2737 }
2738 }
2739 return null;
2740 }
2741
Wale Ogunwalec5cc3012017-01-13 13:26:16 -08002742 /** Returns the position the input task should be placed in this stack. */
2743 int getAdjustedPositionForTask(TaskRecord task, int suggestedPosition,
2744 ActivityRecord starting) {
2745
2746 int maxPosition = mTaskHistory.size();
2747 if ((starting != null && starting.okToShowLocked())
2748 || (starting == null && task.okToShowLocked())) {
2749 // If the task or starting activity can be shown, then whatever position is okay.
2750 return Math.min(suggestedPosition, maxPosition);
2751 }
2752
2753 // The task can't be shown, put non-current user tasks below current user tasks.
2754 while (maxPosition > 0) {
2755 final TaskRecord tmpTask = mTaskHistory.get(maxPosition - 1);
2756 if (!mStackSupervisor.isCurrentProfileLocked(tmpTask.userId)
2757 || tmpTask.topRunningActivityLocked() == null) {
2758 break;
2759 }
2760 maxPosition--;
2761 }
2762
2763 return Math.min(suggestedPosition, maxPosition);
2764 }
2765
Andrii Kuliand2765632016-12-12 22:26:34 -08002766 /**
2767 * Used from {@link ActivityStack#positionTask(TaskRecord, int)}.
2768 * @see ActivityManagerService#positionTaskInStack(int, int, int).
2769 */
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -07002770 private void insertTaskAtPosition(TaskRecord task, int position) {
2771 if (position >= mTaskHistory.size()) {
2772 insertTaskAtTop(task, null);
2773 return;
2774 }
Wale Ogunwalec5cc3012017-01-13 13:26:16 -08002775 position = getAdjustedPositionForTask(task, position, null /* starting */);
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -07002776 mTaskHistory.remove(task);
2777 mTaskHistory.add(position, task);
Wale Ogunwale1666e312016-12-16 11:27:18 -08002778 mWindowContainerController.positionChildAt(task.getWindowContainerController(), position,
2779 task.mBounds, task.getOverrideConfiguration());
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -07002780 updateTaskMovement(task, true);
2781 }
2782
Wale Ogunwalec5cc3012017-01-13 13:26:16 -08002783 private void insertTaskAtTop(TaskRecord task, ActivityRecord starting) {
2784 updateTaskReturnToForTopInsertion(task);
2785 // TODO: Better place to put all the code below...may be addTask...
2786 mTaskHistory.remove(task);
2787 // Now put task at top.
2788 final int position = getAdjustedPositionForTask(task, mTaskHistory.size(), starting);
2789 mTaskHistory.add(position, task);
2790 updateTaskMovement(task, true);
Wale Ogunwale1666e312016-12-16 11:27:18 -08002791 mWindowContainerController.positionChildAtTop(task.getWindowContainerController(),
2792 true /* includingParents */);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -08002793 }
2794
Winson Chung83471632016-12-13 11:02:12 -08002795 /**
2796 * Updates the {@param task}'s return type before it is moved to the top.
2797 */
Wale Ogunwalec5cc3012017-01-13 13:26:16 -08002798 private void updateTaskReturnToForTopInsertion(TaskRecord task) {
Andrii Kuliandc0f8932016-06-28 16:34:02 -07002799 boolean isLastTaskOverHome = false;
Winson Chung83471632016-12-13 11:02:12 -08002800 // If the moving task is over the home or assistant stack, transfer its return type to next
2801 // task so that they return to the same stack
2802 if (task.isOverHomeStack() || task.isOverAssistantStack()) {
riddle_hsuc215a4f2014-12-27 12:10:45 +08002803 final TaskRecord nextTask = getNextTask(task);
2804 if (nextTask != null) {
2805 nextTask.setTaskToReturnTo(task.getTaskToReturnTo());
Andrii Kuliandc0f8932016-06-28 16:34:02 -07002806 } else {
2807 isLastTaskOverHome = true;
riddle_hsuc215a4f2014-12-27 12:10:45 +08002808 }
2809 }
2810
Winson Chung83471632016-12-13 11:02:12 -08002811 // If this is not on the default display, then just set the return type to application
2812 if (!isOnHomeDisplay()) {
2813 task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
2814 return;
2815 }
2816
Winson Chung83471632016-12-13 11:02:12 -08002817 final ActivityStack lastStack = mStackSupervisor.getLastStack();
Bryce Leeaf691c02017-03-20 14:20:22 -07002818
2819 // If there is no last task, do not set task to return to
2820 if (lastStack == null) {
2821 return;
2822 }
2823
2824 // If the task was launched from the assistant stack, set the return type to assistant
2825 if (lastStack.isAssistantStack()) {
Winson Chung83471632016-12-13 11:02:12 -08002826 task.setTaskToReturnTo(ASSISTANT_ACTIVITY_TYPE);
2827 return;
2828 }
2829
Craig Mautner9c85c202013-10-04 20:11:26 -07002830 // If this is being moved to the top by another activity or being launched from the home
riddle_hsuc215a4f2014-12-27 12:10:45 +08002831 // activity, set mTaskToReturnTo accordingly.
Winson Chung83471632016-12-13 11:02:12 -08002832 final boolean fromHomeOrRecents = lastStack.isHomeOrRecentsStack();
2833 final TaskRecord topTask = lastStack.topTask();
2834 if (!isHomeOrRecentsStack() && (fromHomeOrRecents || topTask() != task)) {
2835 // If it's a last task over home - we default to keep its return to type not to
2836 // make underlying task focused when this one will be finished.
2837 int returnToType = isLastTaskOverHome
2838 ? task.getTaskToReturnTo() : APPLICATION_ACTIVITY_TYPE;
2839 if (fromHomeOrRecents && StackId.allowTopTaskToReturnHome(mStackId)) {
2840 returnToType = topTask == null ? HOME_ACTIVITY_TYPE : topTask.taskType;
Craig Mautnere0a38842013-12-16 16:14:02 -08002841 }
Winson Chung83471632016-12-13 11:02:12 -08002842 task.setTaskToReturnTo(returnToType);
Craig Mautner9c85c202013-10-04 20:11:26 -07002843 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07002844 }
Craig Mautner11bf9a52013-02-19 14:08:51 -08002845
Winson Chungb5c41b72016-12-07 15:00:47 -08002846 final void startActivityLocked(ActivityRecord r, ActivityRecord focusedTopActivity,
2847 boolean newTask, boolean keepCurTransition, ActivityOptions options) {
Bryce Leeaf691c02017-03-20 14:20:22 -07002848 TaskRecord rTask = r.getTask();
Craig Mautnerd2328952013-03-05 12:46:26 -08002849 final int taskId = rTask.taskId;
Craig Mautnerbb742462014-07-07 15:28:55 -07002850 // mLaunchTaskBehind tasks get placed at the back of the task stack.
2851 if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) {
Craig Mautner77878772013-03-04 19:46:24 -08002852 // Last activity in task had been removed or ActivityManagerService is reusing task.
2853 // Insert or replace.
Craig Mautner77878772013-03-04 19:46:24 -08002854 // Might not even be in.
Wale Ogunwale3fcb4a82015-04-06 14:00:13 -07002855 insertTaskAtTop(rTask, r);
Craig Mautner77878772013-03-04 19:46:24 -08002856 }
Craig Mautner525f3d92013-05-07 14:01:50 -07002857 TaskRecord task = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002858 if (!newTask) {
2859 // If starting in an existing task, find where that is...
Craig Mautner70a86932013-02-28 22:37:44 -08002860 boolean startIt = true;
2861 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
2862 task = mTaskHistory.get(taskNdx);
riddle_hsu9bcc6e82014-07-31 00:26:51 +08002863 if (task.getTopActivity() == null) {
2864 // All activities in task are finishing.
2865 continue;
2866 }
Bryce Leeaf691c02017-03-20 14:20:22 -07002867 if (task == rTask) {
Craig Mautner70a86932013-02-28 22:37:44 -08002868 // Here it is! Now, if this is not yet visible to the
2869 // user, then just add it without starting; it will
2870 // get started when the user navigates back to it.
Craig Mautner70a86932013-02-28 22:37:44 -08002871 if (!startIt) {
2872 if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to task "
2873 + task, new RuntimeException("here").fillInStackTrace());
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002874 r.createWindowContainer();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07002875 ActivityOptions.abort(options);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002876 return;
2877 }
2878 break;
Craig Mautner70a86932013-02-28 22:37:44 -08002879 } else if (task.numFullscreen > 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002880 startIt = false;
2881 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002882 }
2883 }
2884
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002885 // Place a new activity at top of stack, so it is next to interact with the user.
Craig Mautner70a86932013-02-28 22:37:44 -08002886
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002887 // If we are not placing the new activity frontmost, we do not want to deliver the
2888 // onUserLeaving callback to the actual frontmost activity
Bryce Leeaf691c02017-03-20 14:20:22 -07002889 final TaskRecord activityTask = r.getTask();
2890 if (task == activityTask && mTaskHistory.indexOf(task) != (mTaskHistory.size() - 1)) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07002891 mStackSupervisor.mUserLeaving = false;
Wale Ogunwaleee006da2015-03-30 14:49:25 -07002892 if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
Craig Mautner70a86932013-02-28 22:37:44 -08002893 "startActivity() behind front, mUserLeaving=false");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002894 }
Craig Mautner70a86932013-02-28 22:37:44 -08002895
Bryce Leeaf691c02017-03-20 14:20:22 -07002896 task = activityTask;
Craig Mautner70a86932013-02-28 22:37:44 -08002897
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002898 // Slot the activity into the history stack and proceed
Craig Mautner70a86932013-02-28 22:37:44 -08002899 if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to stack to task " + task,
Craig Mautner56f52db2013-02-25 10:03:01 -08002900 new RuntimeException("here").fillInStackTrace());
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002901 // TODO: Need to investigate if it is okay for the controller to already be created by the
2902 // time we get to this point. I think it is, but need to double check.
2903 // Use test in b/34179495 to trace the call path.
2904 if (r.getWindowContainerController() == null) {
2905 r.createWindowContainer();
2906 }
Craig Mautner1aa9d0d3f2013-12-16 15:58:31 -08002907 task.setFrontOfTask();
Craig Mautner70a86932013-02-28 22:37:44 -08002908
Matthew Ngae1ff4f2016-11-10 15:49:14 -08002909 if (!isHomeOrRecentsStack() || numActivities() > 0) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07002910 if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002911 "Prepare open transition: starting " + r);
Wale Ogunwaleee006da2015-03-30 14:49:25 -07002912 if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
Jorim Jaggiaf80db42016-04-07 19:19:15 -07002913 mWindowManager.prepareAppTransition(TRANSIT_NONE, keepCurTransition);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002914 mNoAnimActivities.add(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002915 } else {
Winson Chungb5c41b72016-12-07 15:00:47 -08002916 int transit = TRANSIT_ACTIVITY_OPEN;
2917 if (newTask) {
2918 if (r.mLaunchTaskBehind) {
2919 transit = TRANSIT_TASK_OPEN_BEHIND;
2920 } else {
Winson Chungc2baac02017-01-11 13:34:47 -08002921 // If a new task is being launched, then mark the existing top activity as
Winson Chung942a85c2017-07-11 15:07:45 -07002922 // supporting picture-in-picture while pausing only if the starting activity
2923 // would not be considered an overlay on top of the current activity
2924 // (eg. not fullscreen, or the assistant)
Winson Chung4aede8a2017-07-05 12:23:25 -07002925 if (focusedTopActivity != null
2926 && focusedTopActivity.getStackId() != PINNED_STACK_ID
Winson Chung942a85c2017-07-11 15:07:45 -07002927 && r.getStackId() != ASSISTANT_STACK_ID
2928 && r.fullscreen) {
Winson Chungc2baac02017-01-11 13:34:47 -08002929 focusedTopActivity.supportsPictureInPictureWhilePausing = true;
Winson Chungb5c41b72016-12-07 15:00:47 -08002930 }
2931 transit = TRANSIT_TASK_OPEN;
2932 }
2933 }
2934 mWindowManager.prepareAppTransition(transit, keepCurTransition);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002935 mNoAnimActivities.remove(r);
2936 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002937 boolean doShow = true;
2938 if (newTask) {
2939 // Even though this activity is starting fresh, we still need
2940 // to reset it to make sure we apply affinities to move any
2941 // existing activities from other tasks in to it.
2942 // If the caller has requested that the target task be
2943 // reset, then do so.
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07002944 if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002945 resetTaskIfNeededLocked(r, r);
2946 doShow = topRunningNonDelayedActivityLocked(null) == r;
2947 }
Chong Zhang280d3322015-11-03 17:27:26 -08002948 } else if (options != null && options.getAnimationType()
George Mount70778d72014-07-01 16:33:45 -07002949 == ActivityOptions.ANIM_SCENE_TRANSITION) {
2950 doShow = false;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002951 }
Craig Mautnerbb742462014-07-07 15:28:55 -07002952 if (r.mLaunchTaskBehind) {
2953 // Don't do a starting window for mLaunchTaskBehind. More importantly make sure we
2954 // tell WindowManager that r is visible even though it is at the back of the stack.
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002955 r.setVisibility(true);
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -07002956 ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Craig Mautnerbb742462014-07-07 15:28:55 -07002957 } else if (SHOW_APP_STARTING_PREVIEW && doShow) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002958 // Figure out if we are transitioning from another activity that is
2959 // "has the same starting icon" as the next one. This allows the
2960 // window manager to keep the previous window it had previously
2961 // created, if it still had one.
Bryce Leeaf691c02017-03-20 14:20:22 -07002962 TaskRecord prevTask = r.getTask();
2963 ActivityRecord prev = prevTask.topRunningActivityWithStartingWindowLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002964 if (prev != null) {
2965 // We don't want to reuse the previous starting preview if:
2966 // (1) The current activity is in a different task.
Bryce Leeaf691c02017-03-20 14:20:22 -07002967 if (prev.getTask() != prevTask) {
Craig Mautner29219d92013-04-16 20:19:12 -07002968 prev = null;
2969 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002970 // (2) The current activity is already displayed.
Craig Mautner29219d92013-04-16 20:19:12 -07002971 else if (prev.nowVisible) {
2972 prev = null;
2973 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002974 }
Jorim Jaggi02886a82016-12-06 09:10:06 -08002975 r.showStartingWindow(prev, newTask, isTaskSwitch(r, focusedTopActivity));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002976 }
2977 } else {
2978 // If this is the first activity, don't do any fancy animations,
2979 // because there is nothing for it to animate on top of.
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07002980 ActivityOptions.abort(options);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002981 }
Dianne Hackbornbe707852011-11-11 14:32:10 -08002982 }
2983
Jorim Jaggi02886a82016-12-06 09:10:06 -08002984 private boolean isTaskSwitch(ActivityRecord r,
2985 ActivityRecord topFocusedActivity) {
Bryce Leeaf691c02017-03-20 14:20:22 -07002986 return topFocusedActivity != null && r.getTask() != topFocusedActivity.getTask();
Jorim Jaggi02886a82016-12-06 09:10:06 -08002987 }
2988
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002989 /**
2990 * Perform a reset of the given task, if needed as part of launching it.
2991 * Returns the new HistoryRecord at the top of the task.
2992 */
Craig Mautnere3a74d52013-02-22 14:14:58 -08002993 /**
2994 * Helper method for #resetTaskIfNeededLocked.
2995 * We are inside of the task being reset... we'll either finish this activity, push it out
2996 * for another task, or leave it as-is.
2997 * @param task The task containing the Activity (taskTop) that might be reset.
2998 * @param forceReset
2999 * @return An ActivityOptions that needs to be processed.
3000 */
Andrii Kulian21713ac2016-10-12 22:05:05 -07003001 private ActivityOptions resetTargetTaskIfNeededLocked(TaskRecord task, boolean forceReset) {
Craig Mautnere3a74d52013-02-22 14:14:58 -08003002 ActivityOptions topOptions = null;
3003
3004 int replyChainEnd = -1;
3005 boolean canMoveOptions = true;
3006
3007 // We only do this for activities that are not the root of the task (since if we finish
3008 // the root, we may no longer have the task!).
3009 final ArrayList<ActivityRecord> activities = task.mActivities;
3010 final int numActivities = activities.size();
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07003011 final int rootActivityNdx = task.findEffectiveRootIndex();
3012 for (int i = numActivities - 1; i > rootActivityNdx; --i ) {
Craig Mautnere3a74d52013-02-22 14:14:58 -08003013 ActivityRecord target = activities.get(i);
Craig Mautner76ae2f02014-07-16 16:16:19 +00003014 if (target.frontOfTask)
3015 break;
Craig Mautnere3a74d52013-02-22 14:14:58 -08003016
3017 final int flags = target.info.flags;
3018 final boolean finishOnTaskLaunch =
3019 (flags & ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH) != 0;
3020 final boolean allowTaskReparenting =
3021 (flags & ActivityInfo.FLAG_ALLOW_TASK_REPARENTING) != 0;
3022 final boolean clearWhenTaskReset =
3023 (target.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0;
3024
3025 if (!finishOnTaskLaunch
3026 && !clearWhenTaskReset
3027 && target.resultTo != null) {
3028 // If this activity is sending a reply to a previous
3029 // activity, we can't do anything with it now until
3030 // we reach the start of the reply chain.
3031 // XXX note that we are assuming the result is always
3032 // to the previous activity, which is almost always
3033 // the case but we really shouldn't count on.
3034 if (replyChainEnd < 0) {
3035 replyChainEnd = i;
3036 }
3037 } else if (!finishOnTaskLaunch
3038 && !clearWhenTaskReset
3039 && allowTaskReparenting
3040 && target.taskAffinity != null
3041 && !target.taskAffinity.equals(task.affinity)) {
3042 // If this activity has an affinity for another
3043 // task, then we need to move it out of here. We will
3044 // move it as far out of the way as possible, to the
3045 // bottom of the activity stack. This also keeps it
3046 // correctly ordered with any activities we previously
3047 // moved.
Craig Mautner329f4122013-11-07 09:10:42 -08003048 final TaskRecord targetTask;
Craig Mautnerdccb7702013-09-17 15:53:34 -07003049 final ActivityRecord bottom =
3050 !mTaskHistory.isEmpty() && !mTaskHistory.get(0).mActivities.isEmpty() ?
Craig Mautner329f4122013-11-07 09:10:42 -08003051 mTaskHistory.get(0).mActivities.get(0) : null;
Craig Mautnerdccb7702013-09-17 15:53:34 -07003052 if (bottom != null && target.taskAffinity != null
Bryce Leeaf691c02017-03-20 14:20:22 -07003053 && target.taskAffinity.equals(bottom.getTask().affinity)) {
Craig Mautnere3a74d52013-02-22 14:14:58 -08003054 // If the activity currently at the bottom has the
3055 // same task affinity as the one we are moving,
3056 // then merge it into the same task.
Bryce Leeaf691c02017-03-20 14:20:22 -07003057 targetTask = bottom.getTask();
Wale Ogunwaleee006da2015-03-30 14:49:25 -07003058 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Start pushing activity " + target
Bryce Leeaf691c02017-03-20 14:20:22 -07003059 + " out to bottom task " + targetTask);
Craig Mautnere3a74d52013-02-22 14:14:58 -08003060 } else {
Suprabh Shukla09a88f52015-12-02 14:36:31 -08003061 targetTask = createTaskRecord(
3062 mStackSupervisor.getNextTaskIdForUserLocked(target.userId),
Wale Ogunwale72919d22016-12-08 18:58:50 -08003063 target.info, null, null, null, false, target.mActivityType);
Craig Mautner329f4122013-11-07 09:10:42 -08003064 targetTask.affinityIntent = target.intent;
Wale Ogunwaleee006da2015-03-30 14:49:25 -07003065 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Start pushing activity " + target
Bryce Leeaf691c02017-03-20 14:20:22 -07003066 + " out to new task " + targetTask);
Craig Mautnere3a74d52013-02-22 14:14:58 -08003067 }
3068
Craig Mautner525f3d92013-05-07 14:01:50 -07003069 boolean noOptions = canMoveOptions;
Craig Mautnere3a74d52013-02-22 14:14:58 -08003070 final int start = replyChainEnd < 0 ? i : replyChainEnd;
3071 for (int srcPos = start; srcPos >= i; --srcPos) {
Craig Mautnerdccb7702013-09-17 15:53:34 -07003072 final ActivityRecord p = activities.get(srcPos);
Craig Mautnere3a74d52013-02-22 14:14:58 -08003073 if (p.finishing) {
3074 continue;
3075 }
3076
Craig Mautnere3a74d52013-02-22 14:14:58 -08003077 canMoveOptions = false;
Craig Mautner525f3d92013-05-07 14:01:50 -07003078 if (noOptions && topOptions == null) {
Craig Mautnere3a74d52013-02-22 14:14:58 -08003079 topOptions = p.takeOptionsLocked();
3080 if (topOptions != null) {
Craig Mautner525f3d92013-05-07 14:01:50 -07003081 noOptions = false;
Craig Mautnere3a74d52013-02-22 14:14:58 -08003082 }
3083 }
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07003084 if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE,
3085 "Removing activity " + p + " from task=" + task + " adding to task="
3086 + targetTask + " Callers=" + Debug.getCallers(4));
Wale Ogunwaleee006da2015-03-30 14:49:25 -07003087 if (DEBUG_TASKS) Slog.v(TAG_TASKS,
Bryce Leeaf691c02017-03-20 14:20:22 -07003088 "Pushing next activity " + p + " out to target's task " + target);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08003089 p.reparent(targetTask, 0 /* position - bottom */, "resetTargetTaskIfNeeded");
Craig Mautnere3a74d52013-02-22 14:14:58 -08003090 }
3091
Wale Ogunwale1666e312016-12-16 11:27:18 -08003092 mWindowContainerController.positionChildAtBottom(
3093 targetTask.getWindowContainerController());
Craig Mautnere3a74d52013-02-22 14:14:58 -08003094 replyChainEnd = -1;
3095 } else if (forceReset || finishOnTaskLaunch || clearWhenTaskReset) {
3096 // If the activity should just be removed -- either
3097 // because it asks for it, or the task should be
3098 // cleared -- then finish it and anything that is
3099 // part of its reply chain.
3100 int end;
3101 if (clearWhenTaskReset) {
3102 // In this case, we want to finish this activity
3103 // and everything above it, so be sneaky and pretend
3104 // like these are all in the reply chain.
Mark Lu4b5a9a02014-12-09 14:47:13 +08003105 end = activities.size() - 1;
Craig Mautnere3a74d52013-02-22 14:14:58 -08003106 } else if (replyChainEnd < 0) {
3107 end = i;
3108 } else {
3109 end = replyChainEnd;
3110 }
Craig Mautner525f3d92013-05-07 14:01:50 -07003111 boolean noOptions = canMoveOptions;
Craig Mautnere3a74d52013-02-22 14:14:58 -08003112 for (int srcPos = i; srcPos <= end; srcPos++) {
Craig Mautner525f3d92013-05-07 14:01:50 -07003113 ActivityRecord p = activities.get(srcPos);
Craig Mautnere3a74d52013-02-22 14:14:58 -08003114 if (p.finishing) {
3115 continue;
3116 }
3117 canMoveOptions = false;
Craig Mautner525f3d92013-05-07 14:01:50 -07003118 if (noOptions && topOptions == null) {
Craig Mautnere3a74d52013-02-22 14:14:58 -08003119 topOptions = p.takeOptionsLocked();
3120 if (topOptions != null) {
Craig Mautner525f3d92013-05-07 14:01:50 -07003121 noOptions = false;
Craig Mautnere3a74d52013-02-22 14:14:58 -08003122 }
3123 }
Wale Ogunwaleee006da2015-03-30 14:49:25 -07003124 if (DEBUG_TASKS) Slog.w(TAG_TASKS,
Craig Mautner58547802013-03-05 08:23:53 -08003125 "resetTaskIntendedTask: calling finishActivity on " + p);
Todd Kennedy539db512014-12-15 09:57:55 -08003126 if (finishActivityLocked(
3127 p, Activity.RESULT_CANCELED, null, "reset-task", false)) {
Craig Mautnere3a74d52013-02-22 14:14:58 -08003128 end--;
3129 srcPos--;
3130 }
3131 }
3132 replyChainEnd = -1;
3133 } else {
3134 // If we were in the middle of a chain, well the
3135 // activity that started it all doesn't want anything
3136 // special, so leave it all as-is.
3137 replyChainEnd = -1;
3138 }
3139 }
3140
3141 return topOptions;
3142 }
3143
3144 /**
3145 * Helper method for #resetTaskIfNeededLocked. Processes all of the activities in a given
3146 * TaskRecord looking for an affinity with the task of resetTaskIfNeededLocked.taskTop.
3147 * @param affinityTask The task we are looking for an affinity to.
3148 * @param task Task that resetTaskIfNeededLocked.taskTop belongs to.
3149 * @param topTaskIsHigher True if #task has already been processed by resetTaskIfNeededLocked.
3150 * @param forceReset Flag passed in to resetTaskIfNeededLocked.
3151 */
Craig Mautner525f3d92013-05-07 14:01:50 -07003152 private int resetAffinityTaskIfNeededLocked(TaskRecord affinityTask, TaskRecord task,
Craig Mautner77878772013-03-04 19:46:24 -08003153 boolean topTaskIsHigher, boolean forceReset, int taskInsertionPoint) {
Craig Mautnere3a74d52013-02-22 14:14:58 -08003154 int replyChainEnd = -1;
3155 final int taskId = task.taskId;
3156 final String taskAffinity = task.affinity;
3157
3158 final ArrayList<ActivityRecord> activities = affinityTask.mActivities;
3159 final int numActivities = activities.size();
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07003160 final int rootActivityNdx = affinityTask.findEffectiveRootIndex();
3161
3162 // Do not operate on or below the effective root Activity.
3163 for (int i = numActivities - 1; i > rootActivityNdx; --i) {
Craig Mautnere3a74d52013-02-22 14:14:58 -08003164 ActivityRecord target = activities.get(i);
Craig Mautner76ae2f02014-07-16 16:16:19 +00003165 if (target.frontOfTask)
3166 break;
Craig Mautnere3a74d52013-02-22 14:14:58 -08003167
3168 final int flags = target.info.flags;
3169 boolean finishOnTaskLaunch = (flags & ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH) != 0;
3170 boolean allowTaskReparenting = (flags & ActivityInfo.FLAG_ALLOW_TASK_REPARENTING) != 0;
3171
3172 if (target.resultTo != null) {
3173 // If this activity is sending a reply to a previous
3174 // activity, we can't do anything with it now until
3175 // we reach the start of the reply chain.
3176 // XXX note that we are assuming the result is always
3177 // to the previous activity, which is almost always
3178 // the case but we really shouldn't count on.
3179 if (replyChainEnd < 0) {
3180 replyChainEnd = i;
3181 }
3182 } else if (topTaskIsHigher
3183 && allowTaskReparenting
3184 && taskAffinity != null
3185 && taskAffinity.equals(target.taskAffinity)) {
3186 // This activity has an affinity for our task. Either remove it if we are
3187 // clearing or move it over to our task. Note that
3188 // we currently punt on the case where we are resetting a
3189 // task that is not at the top but who has activities above
3190 // with an affinity to it... this is really not a normal
3191 // case, and we will need to later pull that task to the front
3192 // and usually at that point we will do the reset and pick
3193 // up those remaining activities. (This only happens if
3194 // someone starts an activity in a new task from an activity
3195 // in a task that is not currently on top.)
3196 if (forceReset || finishOnTaskLaunch) {
3197 final int start = replyChainEnd >= 0 ? replyChainEnd : i;
Wale Ogunwaleee006da2015-03-30 14:49:25 -07003198 if (DEBUG_TASKS) Slog.v(TAG_TASKS,
3199 "Finishing task at index " + start + " to " + i);
Craig Mautnere3a74d52013-02-22 14:14:58 -08003200 for (int srcPos = start; srcPos >= i; --srcPos) {
3201 final ActivityRecord p = activities.get(srcPos);
3202 if (p.finishing) {
3203 continue;
3204 }
Todd Kennedy539db512014-12-15 09:57:55 -08003205 finishActivityLocked(
3206 p, Activity.RESULT_CANCELED, null, "move-affinity", false);
Craig Mautnere3a74d52013-02-22 14:14:58 -08003207 }
3208 } else {
Craig Mautner77878772013-03-04 19:46:24 -08003209 if (taskInsertionPoint < 0) {
3210 taskInsertionPoint = task.mActivities.size();
Craig Mautnerd2328952013-03-05 12:46:26 -08003211
Craig Mautner77878772013-03-04 19:46:24 -08003212 }
Craig Mautner77878772013-03-04 19:46:24 -08003213
3214 final int start = replyChainEnd >= 0 ? replyChainEnd : i;
Wale Ogunwaleee006da2015-03-30 14:49:25 -07003215 if (DEBUG_TASKS) Slog.v(TAG_TASKS,
3216 "Reparenting from task=" + affinityTask + ":" + start + "-" + i
3217 + " to task=" + task + ":" + taskInsertionPoint);
Craig Mautner77878772013-03-04 19:46:24 -08003218 for (int srcPos = start; srcPos >= i; --srcPos) {
Craig Mautnere3a74d52013-02-22 14:14:58 -08003219 final ActivityRecord p = activities.get(srcPos);
Winson Chung30480042017-01-26 10:55:34 -08003220 p.reparent(task, taskInsertionPoint, "resetAffinityTaskIfNeededLocked");
Craig Mautnere3a74d52013-02-22 14:14:58 -08003221
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07003222 if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE,
3223 "Removing and adding activity " + p + " to stack at " + task
3224 + " callers=" + Debug.getCallers(3));
Wale Ogunwaleee006da2015-03-30 14:49:25 -07003225 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Pulling activity " + p
3226 + " from " + srcPos + " in to resetting task " + task);
Craig Mautnere3a74d52013-02-22 14:14:58 -08003227 }
Wale Ogunwale1666e312016-12-16 11:27:18 -08003228 mWindowContainerController.positionChildAtTop(
3229 task.getWindowContainerController(), true /* includingParents */);
Craig Mautnere3a74d52013-02-22 14:14:58 -08003230
3231 // Now we've moved it in to place... but what if this is
3232 // a singleTop activity and we have put it on top of another
3233 // instance of the same activity? Then we drop the instance
3234 // below so it remains singleTop.
3235 if (target.info.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {
3236 ArrayList<ActivityRecord> taskActivities = task.mActivities;
Craig Mautnere3a74d52013-02-22 14:14:58 -08003237 int targetNdx = taskActivities.indexOf(target);
3238 if (targetNdx > 0) {
3239 ActivityRecord p = taskActivities.get(targetNdx - 1);
3240 if (p.intent.getComponent().equals(target.intent.getComponent())) {
Craig Mautner58547802013-03-05 08:23:53 -08003241 finishActivityLocked(p, Activity.RESULT_CANCELED, null, "replace",
3242 false);
Craig Mautnere3a74d52013-02-22 14:14:58 -08003243 }
3244 }
3245 }
3246 }
3247
3248 replyChainEnd = -1;
3249 }
3250 }
Craig Mautner77878772013-03-04 19:46:24 -08003251 return taskInsertionPoint;
Craig Mautnere3a74d52013-02-22 14:14:58 -08003252 }
3253
Craig Mautner8849a5e2013-04-02 16:41:03 -07003254 final ActivityRecord resetTaskIfNeededLocked(ActivityRecord taskTop,
Craig Mautnere3a74d52013-02-22 14:14:58 -08003255 ActivityRecord newActivity) {
3256 boolean forceReset =
3257 (newActivity.info.flags & ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0;
3258 if (ACTIVITY_INACTIVE_RESET_TIME > 0
Bryce Leeaf691c02017-03-20 14:20:22 -07003259 && taskTop.getTask().getInactiveDuration() > ACTIVITY_INACTIVE_RESET_TIME) {
Craig Mautnere3a74d52013-02-22 14:14:58 -08003260 if ((newActivity.info.flags & ActivityInfo.FLAG_ALWAYS_RETAIN_TASK_STATE) == 0) {
3261 forceReset = true;
3262 }
3263 }
3264
Bryce Leeaf691c02017-03-20 14:20:22 -07003265 final TaskRecord task = taskTop.getTask();
Craig Mautnere3a74d52013-02-22 14:14:58 -08003266
3267 /** False until we evaluate the TaskRecord associated with taskTop. Switches to true
3268 * for remaining tasks. Used for later tasks to reparent to task. */
3269 boolean taskFound = false;
3270
3271 /** If ActivityOptions are moved out and need to be aborted or moved to taskTop. */
3272 ActivityOptions topOptions = null;
3273
Craig Mautner77878772013-03-04 19:46:24 -08003274 // Preserve the location for reparenting in the new task.
3275 int reparentInsertionPoint = -1;
3276
Craig Mautnere3a74d52013-02-22 14:14:58 -08003277 for (int i = mTaskHistory.size() - 1; i >= 0; --i) {
3278 final TaskRecord targetTask = mTaskHistory.get(i);
3279
3280 if (targetTask == task) {
3281 topOptions = resetTargetTaskIfNeededLocked(task, forceReset);
3282 taskFound = true;
3283 } else {
Craig Mautner77878772013-03-04 19:46:24 -08003284 reparentInsertionPoint = resetAffinityTaskIfNeededLocked(targetTask, task,
3285 taskFound, forceReset, reparentInsertionPoint);
Craig Mautnere3a74d52013-02-22 14:14:58 -08003286 }
3287 }
3288
Craig Mautner70a86932013-02-28 22:37:44 -08003289 int taskNdx = mTaskHistory.indexOf(task);
riddle_hsu1d7919a2015-03-11 17:09:50 +08003290 if (taskNdx >= 0) {
3291 do {
3292 taskTop = mTaskHistory.get(taskNdx--).getTopActivity();
3293 } while (taskTop == null && taskNdx >= 0);
3294 }
Craig Mautner70a86932013-02-28 22:37:44 -08003295
Craig Mautnere3a74d52013-02-22 14:14:58 -08003296 if (topOptions != null) {
3297 // If we got some ActivityOptions from an activity on top that
3298 // was removed from the task, propagate them to the new real top.
3299 if (taskTop != null) {
Craig Mautnere3a74d52013-02-22 14:14:58 -08003300 taskTop.updateOptionsLocked(topOptions);
3301 } else {
Craig Mautnere3a74d52013-02-22 14:14:58 -08003302 topOptions.abort();
3303 }
3304 }
3305
3306 return taskTop;
3307 }
3308
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003309 void sendActivityResultLocked(int callingUid, ActivityRecord r,
3310 String resultWho, int requestCode, int resultCode, Intent data) {
3311
3312 if (callingUid > 0) {
3313 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
Nicolas Prevotc6cf95c2014-05-29 11:30:36 +01003314 data, r.getUriPermissionsLocked(), r.userId);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003315 }
3316
3317 if (DEBUG_RESULTS) Slog.v(TAG, "Send activity result to " + r
3318 + " : who=" + resultWho + " req=" + requestCode
3319 + " res=" + resultCode + " data=" + data);
3320 if (mResumedActivity == r && r.app != null && r.app.thread != null) {
3321 try {
3322 ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
3323 list.add(new ResultInfo(resultWho, requestCode,
3324 resultCode, data));
Dianne Hackbornbe707852011-11-11 14:32:10 -08003325 r.app.thread.scheduleSendResult(r.appToken, list);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003326 return;
3327 } catch (Exception e) {
3328 Slog.w(TAG, "Exception thrown sending result to " + r, e);
3329 }
3330 }
3331
3332 r.addResultLocked(null, resultWho, requestCode, resultCode, data);
3333 }
3334
Shunta Sato63b8ee32016-07-11 13:32:52 +09003335 /** Returns true if the task is one of the task finishing on-top of the top running task. */
3336 boolean isATopFinishingTask(TaskRecord task) {
3337 for (int i = mTaskHistory.size() - 1; i >= 0; --i) {
3338 final TaskRecord current = mTaskHistory.get(i);
3339 final ActivityRecord r = current.topRunningActivityLocked();
3340 if (r != null) {
3341 // We got a top running activity, so there isn't a top finishing task...
3342 return false;
3343 }
3344 if (current == task) {
3345 return true;
3346 }
3347 }
3348 return false;
3349 }
3350
Chong Zhang6cda19c2016-06-14 19:07:56 -07003351 private void adjustFocusedActivityStackLocked(ActivityRecord r, String reason) {
Shunta Sato63b8ee32016-07-11 13:32:52 +09003352 if (!mStackSupervisor.isFocusedStack(this) ||
3353 ((mResumedActivity != r) && (mResumedActivity != null))) {
Wale Ogunwaled045c822015-12-02 09:14:28 -08003354 return;
3355 }
3356
3357 final ActivityRecord next = topRunningActivityLocked();
3358 final String myReason = reason + " adjustFocus";
Bryce Lee3345c4e2017-04-25 07:40:41 -07003359
Wale Ogunwaled045c822015-12-02 09:14:28 -08003360 if (next != r) {
Wale Ogunwale4cea0f52015-12-25 06:30:31 -08003361 if (next != null && StackId.keepFocusInStackIfPossible(mStackId) && isFocusable()) {
Wale Ogunwaled045c822015-12-02 09:14:28 -08003362 // For freeform, docked, and pinned stacks we always keep the focus within the
Chong Zhang6cda19c2016-06-14 19:07:56 -07003363 // stack as long as there is a running activity.
Wale Ogunwaled045c822015-12-02 09:14:28 -08003364 return;
3365 } else {
Bryce Lee3345c4e2017-04-25 07:40:41 -07003366 // Task is not guaranteed to be non-null. For example, destroying the
3367 // {@link ActivityRecord} will disassociate the task from the activity.
Bryce Leeaf691c02017-03-20 14:20:22 -07003368 final TaskRecord task = r.getTask();
Bryce Lee3345c4e2017-04-25 07:40:41 -07003369
3370 if (task == null) {
3371 throw new IllegalStateException("activity no longer associated with task:" + r);
3372 }
3373
Winson Chung83471632016-12-13 11:02:12 -08003374 final boolean isAssistantOrOverAssistant = task.getStack().isAssistantStack() ||
3375 task.isOverAssistantStack();
Shunta Sato63b8ee32016-07-11 13:32:52 +09003376 if (r.frontOfTask && isATopFinishingTask(task)
3377 && (task.isOverHomeStack() || isAssistantOrOverAssistant)) {
Winson Chung83471632016-12-13 11:02:12 -08003378 // For non-fullscreen or assistant stack, we want to move the focus to the next
3379 // visible stack to prevent the home screen from moving to the top and obscuring
Wale Ogunwaled045c822015-12-02 09:14:28 -08003380 // other visible stacks.
Winson Chung83471632016-12-13 11:02:12 -08003381 if ((!mFullscreen || isAssistantOrOverAssistant)
Matthew Ngae1ff4f2016-11-10 15:49:14 -08003382 && adjustFocusToNextFocusableStackLocked(myReason)) {
Wale Ogunwaled045c822015-12-02 09:14:28 -08003383 return;
3384 }
3385 // Move the home stack to the top if this stack is fullscreen or there is no
3386 // other visible stack.
Winson Chung521f0112017-03-13 16:14:45 -07003387 if (task.isOverHomeStack() &&
3388 mStackSupervisor.moveHomeStackTaskToTop(myReason)) {
Wale Ogunwaled045c822015-12-02 09:14:28 -08003389 // Activity focus was already adjusted. Nothing else to do...
3390 return;
Wale Ogunwaled80c2632015-03-13 10:26:26 -07003391 }
Craig Mautner04f0b702013-10-22 12:31:01 -07003392 }
3393 }
Wale Ogunwaled045c822015-12-02 09:14:28 -08003394 }
Wale Ogunwaled697cea2015-02-20 17:19:49 -08003395
Chong Zhang6cda19c2016-06-14 19:07:56 -07003396 mStackSupervisor.moveFocusableActivityStackToFrontLocked(
3397 mStackSupervisor.topRunningActivityLocked(), myReason);
Craig Mautner04f0b702013-10-22 12:31:01 -07003398 }
3399
Andrii Kulian250d6532017-02-08 23:30:45 -08003400 /** Find next proper focusable stack and make it focused. */
Matthew Ngae1ff4f2016-11-10 15:49:14 -08003401 private boolean adjustFocusToNextFocusableStackLocked(String reason) {
Andrii Kulian250d6532017-02-08 23:30:45 -08003402 return adjustFocusToNextFocusableStackLocked(reason, false /* allowFocusSelf */);
3403 }
3404
3405 /**
3406 * Find next proper focusable stack and make it focused.
3407 * @param allowFocusSelf Is the focus allowed to remain on the same stack.
3408 */
3409 private boolean adjustFocusToNextFocusableStackLocked(String reason, boolean allowFocusSelf) {
Winson Chung1cebea62017-06-26 17:22:27 -07003410 if (isAssistantStack() && bottomTask() != null &&
3411 bottomTask().getTaskToReturnTo() == HOME_ACTIVITY_TYPE) {
3412 // If the current stack is the assistant stack, then use the return-to type to determine
3413 // whether to return to the home screen. This is needed to workaround an issue where
3414 // launching a fullscreen task (and subequently returning from that task) will cause
3415 // the fullscreen stack to be found as the next focusable stack below, even if the
3416 // assistant was launched over home.
3417 return mStackSupervisor.moveHomeStackTaskToTop(reason);
3418 }
3419
Andrii Kulian250d6532017-02-08 23:30:45 -08003420 final ActivityStack stack = mStackSupervisor.getNextFocusableStackLocked(
3421 allowFocusSelf ? null : this);
Wale Ogunwale4cea0f52015-12-25 06:30:31 -08003422 final String myReason = reason + " adjustFocusToNextFocusableStack";
Wale Ogunwaled697cea2015-02-20 17:19:49 -08003423 if (stack == null) {
3424 return false;
3425 }
Wale Ogunwaled34e80c2016-03-23 17:08:44 -07003426
Wale Ogunwalec750f5f2016-03-28 07:43:51 -07003427 final ActivityRecord top = stack.topRunningActivityLocked();
3428
Matthew Ngae1ff4f2016-11-10 15:49:14 -08003429 if (stack.isHomeOrRecentsStack() && (top == null || !top.visible)) {
Wale Ogunwalec750f5f2016-03-28 07:43:51 -07003430 // If we will be focusing on the home stack next and its current top activity isn't
Andrii Kulian250d6532017-02-08 23:30:45 -08003431 // visible, then use the task return to value to determine the home task to display
3432 // next.
Matthew Ngae1ff4f2016-11-10 15:49:14 -08003433 return mStackSupervisor.moveHomeStackTaskToTop(reason);
Wale Ogunwaled34e80c2016-03-23 17:08:44 -07003434 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07003435
Bryce Lee43f27212017-08-07 16:10:43 -07003436 if (stack.isAssistantStack() && top != null
3437 && top.getTask().getTaskToReturnTo() == HOME_ACTIVITY_TYPE) {
3438 // It is possible for the home stack to not be directly underneath the assistant stack.
3439 // For example, the assistant may start an activity in the fullscreen stack. Upon
3440 // returning to the assistant stack, we must ensure that the home stack is underneath
3441 // when appropriate.
3442 mStackSupervisor.moveHomeStackTaskToTop("adjustAssistantReturnToHome");
3443 }
3444
Chong Zhang6cda19c2016-06-14 19:07:56 -07003445 stack.moveToFront(myReason);
3446 return true;
Wale Ogunwaled697cea2015-02-20 17:19:49 -08003447 }
3448
Craig Mautnerf3333272013-04-22 10:55:53 -07003449 final void stopActivityLocked(ActivityRecord r) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07003450 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH, "Stopping: " + r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003451 if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
3452 || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) {
3453 if (!r.finishing) {
David Stevens9440dc82017-03-16 19:00:20 -07003454 if (!shouldSleepActivities()) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07003455 if (DEBUG_STATES) Slog.d(TAG_STATES, "no-history finish of " + r);
Wale Ogunwale3f529ee2015-07-12 15:14:01 -07003456 if (requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
3457 "stop-no-history", false)) {
Bryce Lee3345c4e2017-04-25 07:40:41 -07003458 // If {@link requestFinishActivityLocked} returns {@code true},
3459 // {@link adjustFocusedActivityStackLocked} would have been already called.
Wale Ogunwale3f529ee2015-07-12 15:14:01 -07003460 r.resumeKeyDispatchingLocked();
3461 return;
3462 }
Christopher Tated3f175c2012-06-14 14:16:54 -07003463 } else {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07003464 if (DEBUG_STATES) Slog.d(TAG_STATES, "Not finishing noHistory " + r
Christopher Tated3f175c2012-06-14 14:16:54 -07003465 + " on stop because we're just sleeping");
3466 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003467 }
Christopher Tate5007ddd2012-06-12 13:08:18 -07003468 }
3469
3470 if (r.app != null && r.app.thread != null) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07003471 adjustFocusedActivityStackLocked(r, "stopActivity");
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08003472 r.resumeKeyDispatchingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003473 try {
3474 r.stopped = false;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07003475 if (DEBUG_STATES) Slog.v(TAG_STATES,
3476 "Moving to STOPPING: " + r + " (stop requested)");
Wale Ogunwaleb9a0c992017-04-18 07:25:20 -07003477 r.state = STOPPING;
Wale Ogunwaleee006da2015-03-30 14:49:25 -07003478 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
3479 "Stopping visible=" + r.visible + " for " + r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003480 if (!r.visible) {
Wale Ogunwaleb9a0c992017-04-18 07:25:20 -07003481 r.setVisible(false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003482 }
Wale Ogunwalecd7043e2016-02-27 17:37:46 -08003483 EventLogTags.writeAmStopActivity(
3484 r.userId, System.identityHashCode(r), r.shortComponentName);
Dianne Hackbornbe707852011-11-11 14:32:10 -08003485 r.app.thread.scheduleStopActivity(r.appToken, r.visible, r.configChangeFlags);
David Stevens9440dc82017-03-16 19:00:20 -07003486 if (shouldSleepOrShutDownActivities()) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08003487 r.setSleeping(true);
3488 }
Craig Mautnerf7bfefb2013-05-16 17:30:44 -07003489 Message msg = mHandler.obtainMessage(STOP_TIMEOUT_MSG, r);
Dianne Hackborn162bc0e2012-04-09 14:06:16 -07003490 mHandler.sendMessageDelayed(msg, STOP_TIMEOUT);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003491 } catch (Exception e) {
3492 // Maybe just ignore exceptions here... if the process
3493 // has crashed, our death notification will clean things
3494 // up.
3495 Slog.w(TAG, "Exception thrown during pause", e);
3496 // Just in case, assume it to be stopped.
3497 r.stopped = true;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07003498 if (DEBUG_STATES) Slog.v(TAG_STATES, "Stop failed; moving to STOPPED: " + r);
Wale Ogunwaleb9a0c992017-04-18 07:25:20 -07003499 r.state = STOPPED;
Wale Ogunwalef81c1d12016-01-12 12:20:18 -08003500 if (r.deferRelaunchUntilPaused) {
Craig Mautneree2e45a2014-06-27 12:10:03 -07003501 destroyActivityLocked(r, true, "stop-except");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003502 }
3503 }
3504 }
3505 }
Craig Mautner23ac33b2013-04-01 16:26:35 -07003506
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003507 /**
3508 * @return Returns true if the activity is being finished, false if for
3509 * some reason it is being left as-is.
3510 */
3511 final boolean requestFinishActivityLocked(IBinder token, int resultCode,
Dianne Hackborn2d1b3782012-09-09 17:49:39 -07003512 Intent resultData, String reason, boolean oomAdj) {
Craig Mautnerd74f7d72013-02-26 13:41:02 -08003513 ActivityRecord r = isInStackLocked(token);
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07003514 if (DEBUG_RESULTS || DEBUG_STATES) Slog.v(TAG_STATES,
3515 "Finishing activity token=" + token + " r="
Christopher Tated3f175c2012-06-14 14:16:54 -07003516 + ", result=" + resultCode + ", data=" + resultData
3517 + ", reason=" + reason);
Craig Mautnerd74f7d72013-02-26 13:41:02 -08003518 if (r == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003519 return false;
3520 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003521
Craig Mautnerd44711d2013-02-23 11:24:36 -08003522 finishActivityLocked(r, resultCode, resultData, reason, oomAdj);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003523 return true;
3524 }
3525
Craig Mautnerd2328952013-03-05 12:46:26 -08003526 final void finishSubActivityLocked(ActivityRecord self, String resultWho, int requestCode) {
Craig Mautner9658b312013-02-28 10:55:59 -08003527 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
3528 ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
3529 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
3530 ActivityRecord r = activities.get(activityNdx);
3531 if (r.resultTo == self && r.requestCode == requestCode) {
3532 if ((r.resultWho == null && resultWho == null) ||
3533 (r.resultWho != null && r.resultWho.equals(resultWho))) {
3534 finishActivityLocked(r, Activity.RESULT_CANCELED, null, "request-sub",
3535 false);
3536 }
Dianne Hackbornecc5a9c2012-04-26 18:56:09 -07003537 }
3538 }
3539 }
Dianne Hackborn2d1b3782012-09-09 17:49:39 -07003540 mService.updateOomAdjLocked();
Dianne Hackbornecc5a9c2012-04-26 18:56:09 -07003541 }
3542
Adrian Roos20d7df32016-01-12 18:59:43 +01003543 final TaskRecord finishTopRunningActivityLocked(ProcessRecord app, String reason) {
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -07003544 ActivityRecord r = topRunningActivityLocked();
Adrian Roos20d7df32016-01-12 18:59:43 +01003545 TaskRecord finishedTask = null;
3546 if (r == null || r.app != app) {
3547 return null;
3548 }
3549 Slog.w(TAG, " Force finishing activity "
3550 + r.intent.getComponent().flattenToShortString());
Bryce Leeaf691c02017-03-20 14:20:22 -07003551 finishedTask = r.getTask();
3552 int taskNdx = mTaskHistory.indexOf(finishedTask);
3553 final TaskRecord task = finishedTask;
3554 int activityNdx = task.mActivities.indexOf(r);
Adrian Roos20d7df32016-01-12 18:59:43 +01003555 finishActivityLocked(r, Activity.RESULT_CANCELED, null, reason, false);
Bryce Leeaf691c02017-03-20 14:20:22 -07003556 finishedTask = task;
Adrian Roos20d7df32016-01-12 18:59:43 +01003557 // Also terminate any activities below it that aren't yet
3558 // stopped, to avoid a situation where one will get
3559 // re-start our crashing activity once it gets resumed again.
3560 --activityNdx;
3561 if (activityNdx < 0) {
3562 do {
3563 --taskNdx;
3564 if (taskNdx < 0) {
3565 break;
3566 }
3567 activityNdx = mTaskHistory.get(taskNdx).mActivities.size() - 1;
3568 } while (activityNdx < 0);
3569 }
3570 if (activityNdx >= 0) {
3571 r = mTaskHistory.get(taskNdx).mActivities.get(activityNdx);
3572 if (r.state == ActivityState.RESUMED
3573 || r.state == ActivityState.PAUSING
3574 || r.state == ActivityState.PAUSED) {
3575 if (!r.isHomeActivity() || mService.mHomeProcess != r.app) {
3576 Slog.w(TAG, " Force finishing activity "
3577 + r.intent.getComponent().flattenToShortString());
3578 finishActivityLocked(r, Activity.RESULT_CANCELED, null, reason, false);
Craig Mautner05d6272ba2013-02-11 09:39:27 -08003579 }
3580 }
3581 }
Adrian Roos20d7df32016-01-12 18:59:43 +01003582 return finishedTask;
Craig Mautner05d6272ba2013-02-11 09:39:27 -08003583 }
3584
Dianne Hackborn6ea0d0a2014-07-02 16:23:21 -07003585 final void finishVoiceTask(IVoiceInteractionSession session) {
3586 IBinder sessionBinder = session.asBinder();
3587 boolean didOne = false;
3588 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
3589 TaskRecord tr = mTaskHistory.get(taskNdx);
3590 if (tr.voiceSession != null && tr.voiceSession.asBinder() == sessionBinder) {
3591 for (int activityNdx = tr.mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
3592 ActivityRecord r = tr.mActivities.get(activityNdx);
3593 if (!r.finishing) {
3594 finishActivityLocked(r, Activity.RESULT_CANCELED, null, "finish-voice",
3595 false);
3596 didOne = true;
3597 }
3598 }
Amith Yamasani0af6fa72016-01-17 15:36:19 -08003599 } else {
3600 // Check if any of the activities are using voice
3601 for (int activityNdx = tr.mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
3602 ActivityRecord r = tr.mActivities.get(activityNdx);
3603 if (r.voiceSession != null
3604 && r.voiceSession.asBinder() == sessionBinder) {
3605 // Inform of cancellation
3606 r.clearVoiceSessionLocked();
3607 try {
3608 r.app.thread.scheduleLocalVoiceInteractionStarted((IBinder) r.appToken,
3609 null);
3610 } catch (RemoteException re) {
3611 // Ok
3612 }
Amith Yamasani0af6fa72016-01-17 15:36:19 -08003613 mService.finishRunningVoiceLocked();
3614 break;
3615 }
3616 }
Dianne Hackborn6ea0d0a2014-07-02 16:23:21 -07003617 }
3618 }
Amith Yamasani0af6fa72016-01-17 15:36:19 -08003619
Dianne Hackborn6ea0d0a2014-07-02 16:23:21 -07003620 if (didOne) {
3621 mService.updateOomAdjLocked();
3622 }
3623 }
3624
Craig Mautnerd2328952013-03-05 12:46:26 -08003625 final boolean finishActivityAffinityLocked(ActivityRecord r) {
Bryce Leeaf691c02017-03-20 14:20:22 -07003626 ArrayList<ActivityRecord> activities = r.getTask().mActivities;
Craig Mautnerd74f7d72013-02-26 13:41:02 -08003627 for (int index = activities.indexOf(r); index >= 0; --index) {
3628 ActivityRecord cur = activities.get(index);
Kenny Roote6585b32013-12-13 12:00:26 -08003629 if (!Objects.equals(cur.taskAffinity, r.taskAffinity)) {
Dianne Hackbornecc5a9c2012-04-26 18:56:09 -07003630 break;
3631 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07003632 finishActivityLocked(cur, Activity.RESULT_CANCELED, null, "request-affinity", true);
Dianne Hackbornecc5a9c2012-04-26 18:56:09 -07003633 }
3634 return true;
3635 }
3636
Andrii Kulian21713ac2016-10-12 22:05:05 -07003637 private void finishActivityResultsLocked(ActivityRecord r, int resultCode, Intent resultData) {
Dianne Hackborn5c607432012-02-28 14:44:19 -08003638 // send the result
3639 ActivityRecord resultTo = r.resultTo;
3640 if (resultTo != null) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07003641 if (DEBUG_RESULTS) Slog.v(TAG_RESULTS, "Adding result to " + resultTo
Dianne Hackborn5c607432012-02-28 14:44:19 -08003642 + " who=" + r.resultWho + " req=" + r.requestCode
3643 + " res=" + resultCode + " data=" + resultData);
Nicolas Prevotc6cf95c2014-05-29 11:30:36 +01003644 if (resultTo.userId != r.userId) {
Nicolas Prevot6b942b82014-06-02 15:20:42 +01003645 if (resultData != null) {
Nicolas Prevot107f7b72015-07-01 16:31:48 +01003646 resultData.prepareToLeaveUser(r.userId);
Nicolas Prevot6b942b82014-06-02 15:20:42 +01003647 }
Nicolas Prevotc6cf95c2014-05-29 11:30:36 +01003648 }
Dianne Hackborn5c607432012-02-28 14:44:19 -08003649 if (r.info.applicationInfo.uid > 0) {
3650 mService.grantUriPermissionFromIntentLocked(r.info.applicationInfo.uid,
3651 resultTo.packageName, resultData,
Nicolas Prevotc6cf95c2014-05-29 11:30:36 +01003652 resultTo.getUriPermissionsLocked(), resultTo.userId);
Dianne Hackborn5c607432012-02-28 14:44:19 -08003653 }
3654 resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode,
3655 resultData);
3656 r.resultTo = null;
3657 }
Wale Ogunwaleee006da2015-03-30 14:49:25 -07003658 else if (DEBUG_RESULTS) Slog.v(TAG_RESULTS, "No result destination from " + r);
Dianne Hackborn5c607432012-02-28 14:44:19 -08003659
3660 // Make sure this HistoryRecord is not holding on to other resources,
3661 // because clients have remote IPC references to this object so we
3662 // can't assume that will go away and want to avoid circular IPC refs.
3663 r.results = null;
3664 r.pendingResults = null;
3665 r.newIntents = null;
3666 r.icicle = null;
3667 }
3668
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003669 /**
Winson Chung6954fc92017-03-24 16:22:12 -07003670 * See {@link #finishActivityLocked(ActivityRecord, int, Intent, String, boolean, boolean)}
3671 */
3672 final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
3673 String reason, boolean oomAdj) {
3674 return finishActivityLocked(r, resultCode, resultData, reason, oomAdj, !PAUSE_IMMEDIATELY);
3675 }
3676
3677 /**
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003678 * @return Returns true if this activity has been removed from the history
3679 * list, or false if it is still in the list and will be removed later.
3680 */
Craig Mautnerf3333272013-04-22 10:55:53 -07003681 final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
Winson Chung6954fc92017-03-24 16:22:12 -07003682 String reason, boolean oomAdj, boolean pauseImmediately) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003683 if (r.finishing) {
3684 Slog.w(TAG, "Duplicate finish request for " + r);
3685 return false;
3686 }
3687
Jorim Jaggife762342016-10-13 14:33:27 +02003688 mWindowManager.deferSurfaceLayout();
3689 try {
3690 r.makeFinishingLocked();
Bryce Leeaf691c02017-03-20 14:20:22 -07003691 final TaskRecord task = r.getTask();
Jorim Jaggife762342016-10-13 14:33:27 +02003692 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
3693 r.userId, System.identityHashCode(r),
3694 task.taskId, r.shortComponentName, reason);
3695 final ArrayList<ActivityRecord> activities = task.mActivities;
3696 final int index = activities.indexOf(r);
3697 if (index < (activities.size() - 1)) {
3698 task.setFrontOfTask();
3699 if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
3700 // If the caller asked that this activity (and all above it)
3701 // be cleared when the task is reset, don't lose that information,
3702 // but propagate it up to the next activity.
3703 ActivityRecord next = activities.get(index+1);
3704 next.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
3705 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003706 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003707
Jorim Jaggife762342016-10-13 14:33:27 +02003708 r.pauseKeyDispatchingLocked();
Craig Mautner04f0b702013-10-22 12:31:01 -07003709
Jorim Jaggife762342016-10-13 14:33:27 +02003710 adjustFocusedActivityStackLocked(r, "finishActivity");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003711
Jorim Jaggife762342016-10-13 14:33:27 +02003712 finishActivityResultsLocked(r, resultCode, resultData);
Craig Mautner2420ead2013-04-01 17:13:20 -07003713
Yorke Leebdef5372017-04-10 16:38:51 -07003714 final boolean endTask = index <= 0 && !task.isClearingToReuseTask();
Jorim Jaggife762342016-10-13 14:33:27 +02003715 final int transit = endTask ? TRANSIT_TASK_CLOSE : TRANSIT_ACTIVITY_CLOSE;
3716 if (mResumedActivity == r) {
3717 if (DEBUG_VISIBILITY || DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
3718 "Prepare close transition: finishing " + r);
Winson Chung6954fc92017-03-24 16:22:12 -07003719 if (endTask) {
3720 mService.mTaskChangeNotificationController.notifyTaskRemovalStarted(
3721 task.taskId);
3722 }
Jorim Jaggiaf80db42016-04-07 19:19:15 -07003723 mWindowManager.prepareAppTransition(transit, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003724
Jorim Jaggife762342016-10-13 14:33:27 +02003725 // Tell window manager to prepare for this one to be removed.
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08003726 r.setVisibility(false);
Jorim Jaggife762342016-10-13 14:33:27 +02003727
3728 if (mPausingActivity == null) {
3729 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish needs to pause: " + r);
3730 if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
3731 "finish() => pause with userLeaving=false");
Winson Chung6954fc92017-03-24 16:22:12 -07003732 startPausingLocked(false, false, null, pauseImmediately);
Jorim Jaggife762342016-10-13 14:33:27 +02003733 }
3734
3735 if (endTask) {
3736 mStackSupervisor.removeLockedTaskLocked(task);
3737 }
3738 } else if (r.state != ActivityState.PAUSING) {
3739 // If the activity is PAUSING, we will complete the finish once
3740 // it is done pausing; else we can just directly finish it here.
3741 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish not pausing: " + r);
3742 if (r.visible) {
Winson Chung6954fc92017-03-24 16:22:12 -07003743 prepareActivityHideTransitionAnimation(r, transit);
3744 }
3745
3746 final int finishMode = (r.visible || r.nowVisible) ? FINISH_AFTER_VISIBLE
3747 : FINISH_AFTER_PAUSE;
3748 final boolean removedActivity = finishCurrentActivityLocked(r, finishMode, oomAdj)
3749 == null;
3750
3751 // The following code is an optimization. When the last non-task overlay activity
3752 // is removed from the task, we remove the entire task from the stack. However,
3753 // since that is done after the scheduled destroy callback from the activity, that
3754 // call to change the visibility of the task overlay activities would be out of
3755 // sync with the activitiy visibility being set for this finishing activity above.
3756 // In this case, we can set the visibility of all the task overlay activities when
3757 // we detect the last one is finishing to keep them in sync.
3758 if (task.onlyHasTaskOverlayActivities(true /* excludeFinishing */)) {
3759 for (ActivityRecord taskOverlay : task.mActivities) {
3760 if (!taskOverlay.mTaskOverlay) {
3761 continue;
3762 }
3763 prepareActivityHideTransitionAnimation(taskOverlay, transit);
Jorim Jaggife762342016-10-13 14:33:27 +02003764 }
3765 }
Winson Chung6954fc92017-03-24 16:22:12 -07003766 return removedActivity;
Jorim Jaggife762342016-10-13 14:33:27 +02003767 } else {
3768 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish waiting for pause of: " + r);
3769 }
3770
3771 return false;
3772 } finally {
3773 mWindowManager.continueSurfaceLayout();
3774 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003775 }
3776
Winson Chung6954fc92017-03-24 16:22:12 -07003777 private void prepareActivityHideTransitionAnimation(ActivityRecord r, int transit) {
3778 mWindowManager.prepareAppTransition(transit, false);
3779 r.setVisibility(false);
3780 mWindowManager.executeAppTransition();
Bryce Lee4a194382017-04-04 14:32:48 -07003781 if (!mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(r)) {
3782 mStackSupervisor.mActivitiesWaitingForVisibleActivity.add(r);
Winson Chung6954fc92017-03-24 16:22:12 -07003783 }
3784 }
3785
Craig Mautnerf3333272013-04-22 10:55:53 -07003786 static final int FINISH_IMMEDIATELY = 0;
3787 static final int FINISH_AFTER_PAUSE = 1;
3788 static final int FINISH_AFTER_VISIBLE = 2;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003789
Craig Mautnerf3333272013-04-22 10:55:53 -07003790 final ActivityRecord finishCurrentActivityLocked(ActivityRecord r, int mode, boolean oomAdj) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003791 // First things first: if this activity is currently visible,
3792 // and the resumed activity is not yet visible, then hold off on
3793 // finishing until the resumed one becomes visible.
Chong Zhang824b6dc2016-04-27 14:11:12 -07003794
3795 final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();
3796
Chong Zhangefd9a5b2016-04-26 16:21:07 -07003797 if (mode == FINISH_AFTER_VISIBLE && (r.visible || r.nowVisible)
Chong Zhang824b6dc2016-04-27 14:11:12 -07003798 && next != null && !next.nowVisible) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07003799 if (!mStackSupervisor.mStoppingActivities.contains(r)) {
Winson Chung4dabf232017-01-25 13:25:22 -08003800 addToStopping(r, false /* scheduleIdle */, false /* idleDelayed */);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003801 }
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07003802 if (DEBUG_STATES) Slog.v(TAG_STATES,
3803 "Moving to STOPPING: "+ r + " (finish requested)");
Wale Ogunwaleb9a0c992017-04-18 07:25:20 -07003804 r.state = STOPPING;
Dianne Hackborn2d1b3782012-09-09 17:49:39 -07003805 if (oomAdj) {
3806 mService.updateOomAdjLocked();
3807 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003808 return r;
3809 }
3810
3811 // make sure the record is cleaned out of other places.
Craig Mautnerde4ef022013-04-07 19:01:33 -07003812 mStackSupervisor.mStoppingActivities.remove(r);
Craig Mautner0eea92c2013-05-16 13:35:39 -07003813 mStackSupervisor.mGoingToSleepActivities.remove(r);
Bryce Lee4a194382017-04-04 14:32:48 -07003814 mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003815 if (mResumedActivity == r) {
3816 mResumedActivity = null;
3817 }
3818 final ActivityState prevState = r.state;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07003819 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to FINISHING: " + r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003820 r.state = ActivityState.FINISHING;
Andrii Kulian995fa2b2016-07-29 12:55:41 -07003821 final boolean finishingActivityInNonFocusedStack
Andrii Kulian02b7a832016-10-06 23:11:56 -07003822 = r.getStack() != mStackSupervisor.getFocusedStack()
Andrii Kulian995fa2b2016-07-29 12:55:41 -07003823 && prevState == ActivityState.PAUSED && mode == FINISH_AFTER_VISIBLE;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003824
3825 if (mode == FINISH_IMMEDIATELY
Wale Ogunwaleae30f302016-05-02 10:35:45 -07003826 || (prevState == ActivityState.PAUSED
Andrii Kulian995fa2b2016-07-29 12:55:41 -07003827 && (mode == FINISH_AFTER_PAUSE || mStackId == PINNED_STACK_ID))
3828 || finishingActivityInNonFocusedStack
Wale Ogunwaleb9a0c992017-04-18 07:25:20 -07003829 || prevState == STOPPING
3830 || prevState == STOPPED
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003831 || prevState == ActivityState.INITIALIZING) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07003832 r.makeFinishingLocked();
Craig Mautneree2e45a2014-06-27 12:10:03 -07003833 boolean activityRemoved = destroyActivityLocked(r, true, "finish-imm");
Andrii Kulian7318d632016-07-20 18:59:28 -07003834
Andrii Kulian995fa2b2016-07-29 12:55:41 -07003835 if (finishingActivityInNonFocusedStack) {
3836 // Finishing activity that was in paused state and it was in not currently focused
3837 // stack, need to make something visible in its place.
Andrii Kulian7318d632016-07-20 18:59:28 -07003838 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
3839 }
Dianne Hackborn42e620c2012-06-24 13:20:51 -07003840 if (activityRemoved) {
Wale Ogunwaled046a012015-12-24 13:05:59 -08003841 mStackSupervisor.resumeFocusedStackTopActivityLocked();
Dianne Hackborn42e620c2012-06-24 13:20:51 -07003842 }
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07003843 if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS,
Craig Mautnerd163e752014-06-13 17:18:47 -07003844 "destroyActivityLocked: finishCurrentActivityLocked r=" + r +
3845 " destroy returned removed=" + activityRemoved);
Dianne Hackborn42e620c2012-06-24 13:20:51 -07003846 return activityRemoved ? null : r;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003847 }
Craig Mautner05d6272ba2013-02-11 09:39:27 -08003848
3849 // Need to go through the full pause cycle to get this
3850 // activity into the stopped state and then finish it.
Wale Ogunwalee23149f2015-03-06 15:39:44 -08003851 if (DEBUG_ALL) Slog.v(TAG, "Enqueueing pending finish: " + r);
Craig Mautnerf3333272013-04-22 10:55:53 -07003852 mStackSupervisor.mFinishingActivities.add(r);
Martin Wallgrenc8733b82011-08-31 12:39:31 +02003853 r.resumeKeyDispatchingLocked();
Wale Ogunwaled046a012015-12-24 13:05:59 -08003854 mStackSupervisor.resumeFocusedStackTopActivityLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003855 return r;
3856 }
3857
Craig Mautneree36c772014-07-16 14:56:05 -07003858 void finishAllActivitiesLocked(boolean immediately) {
3859 boolean noActivitiesInStack = true;
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003860 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
3861 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
3862 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
3863 final ActivityRecord r = activities.get(activityNdx);
Craig Mautneree36c772014-07-16 14:56:05 -07003864 noActivitiesInStack = false;
3865 if (r.finishing && !immediately) {
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003866 continue;
3867 }
Craig Mautneree36c772014-07-16 14:56:05 -07003868 Slog.d(TAG, "finishAllActivitiesLocked: finishing " + r + " immediately");
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003869 finishCurrentActivityLocked(r, FINISH_IMMEDIATELY, false);
3870 }
3871 }
Craig Mautneree36c772014-07-16 14:56:05 -07003872 if (noActivitiesInStack) {
Andrii Kulian94e82d9b02017-07-13 15:33:06 -07003873 remove();
Craig Mautneree36c772014-07-16 14:56:05 -07003874 }
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003875 }
3876
Dianne Hackborn6f4d61f2014-08-21 17:50:42 -07003877 final boolean shouldUpRecreateTaskLocked(ActivityRecord srec, String destAffinity) {
3878 // Basic case: for simple app-centric recents, we need to recreate
3879 // the task if the affinity has changed.
Bryce Leeaf691c02017-03-20 14:20:22 -07003880 if (srec == null || srec.getTask().affinity == null ||
3881 !srec.getTask().affinity.equals(destAffinity)) {
Dianne Hackborn6f4d61f2014-08-21 17:50:42 -07003882 return true;
3883 }
3884 // Document-centric case: an app may be split in to multiple documents;
3885 // they need to re-create their task if this current activity is the root
3886 // of a document, unless simply finishing it will return them to the the
3887 // correct app behind.
Bryce Leeaf691c02017-03-20 14:20:22 -07003888 final TaskRecord task = srec.getTask();
3889 if (srec.frontOfTask && task != null && task.getBaseIntent() != null
3890 && task.getBaseIntent().isDocument()) {
Dianne Hackborn6f4d61f2014-08-21 17:50:42 -07003891 // Okay, this activity is at the root of its task. What to do, what to do...
Bryce Leeaf691c02017-03-20 14:20:22 -07003892 if (task.getTaskToReturnTo() != ActivityRecord.APPLICATION_ACTIVITY_TYPE) {
Dianne Hackborn6f4d61f2014-08-21 17:50:42 -07003893 // Finishing won't return to an application, so we need to recreate.
3894 return true;
3895 }
3896 // We now need to get the task below it to determine what to do.
Bryce Leeaf691c02017-03-20 14:20:22 -07003897 int taskIdx = mTaskHistory.indexOf(task);
Dianne Hackborn6f4d61f2014-08-21 17:50:42 -07003898 if (taskIdx <= 0) {
3899 Slog.w(TAG, "shouldUpRecreateTask: task not in history for " + srec);
3900 return false;
3901 }
3902 if (taskIdx == 0) {
3903 // At the bottom of the stack, nothing to go back to.
3904 return true;
3905 }
3906 TaskRecord prevTask = mTaskHistory.get(taskIdx);
Bryce Leeaf691c02017-03-20 14:20:22 -07003907 if (!task.affinity.equals(prevTask.affinity)) {
Dianne Hackborn6f4d61f2014-08-21 17:50:42 -07003908 // These are different apps, so need to recreate.
3909 return true;
3910 }
3911 }
3912 return false;
3913 }
3914
Wale Ogunwale7d701172015-03-11 15:36:30 -07003915 final boolean navigateUpToLocked(ActivityRecord srec, Intent destIntent, int resultCode,
Craig Mautner05d6272ba2013-02-11 09:39:27 -08003916 Intent resultData) {
Bryce Leeaf691c02017-03-20 14:20:22 -07003917 final TaskRecord task = srec.getTask();
Craig Mautner0247fc82013-02-28 14:32:06 -08003918 final ArrayList<ActivityRecord> activities = task.mActivities;
3919 final int start = activities.indexOf(srec);
3920 if (!mTaskHistory.contains(task) || (start < 0)) {
Craig Mautner05d6272ba2013-02-11 09:39:27 -08003921 return false;
3922 }
3923 int finishTo = start - 1;
Craig Mautner0247fc82013-02-28 14:32:06 -08003924 ActivityRecord parent = finishTo < 0 ? null : activities.get(finishTo);
Craig Mautner05d6272ba2013-02-11 09:39:27 -08003925 boolean foundParentInTask = false;
Craig Mautner0247fc82013-02-28 14:32:06 -08003926 final ComponentName dest = destIntent.getComponent();
3927 if (start > 0 && dest != null) {
3928 for (int i = finishTo; i >= 0; i--) {
3929 ActivityRecord r = activities.get(i);
3930 if (r.info.packageName.equals(dest.getPackageName()) &&
Craig Mautner05d6272ba2013-02-11 09:39:27 -08003931 r.info.name.equals(dest.getClassName())) {
3932 finishTo = i;
3933 parent = r;
3934 foundParentInTask = true;
3935 break;
3936 }
3937 }
3938 }
3939
3940 IActivityController controller = mService.mController;
3941 if (controller != null) {
3942 ActivityRecord next = topRunningActivityLocked(srec.appToken, 0);
3943 if (next != null) {
3944 // ask watcher if this is allowed
3945 boolean resumeOK = true;
3946 try {
3947 resumeOK = controller.activityResuming(next.packageName);
3948 } catch (RemoteException e) {
3949 mService.mController = null;
Kenny Rootadd58212013-05-07 09:47:34 -07003950 Watchdog.getInstance().setActivityController(null);
Craig Mautner05d6272ba2013-02-11 09:39:27 -08003951 }
3952
3953 if (!resumeOK) {
3954 return false;
3955 }
3956 }
3957 }
3958 final long origId = Binder.clearCallingIdentity();
3959 for (int i = start; i > finishTo; i--) {
Craig Mautner0247fc82013-02-28 14:32:06 -08003960 ActivityRecord r = activities.get(i);
3961 requestFinishActivityLocked(r.appToken, resultCode, resultData, "navigate-up", true);
Craig Mautner05d6272ba2013-02-11 09:39:27 -08003962 // Only return the supplied result for the first activity finished
3963 resultCode = Activity.RESULT_CANCELED;
3964 resultData = null;
3965 }
3966
3967 if (parent != null && foundParentInTask) {
3968 final int parentLaunchMode = parent.info.launchMode;
3969 final int destIntentFlags = destIntent.getFlags();
3970 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
3971 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
3972 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
3973 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
Dianne Hackborn85d558c2014-11-04 10:31:54 -08003974 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent,
3975 srec.packageName);
Craig Mautner05d6272ba2013-02-11 09:39:27 -08003976 } else {
3977 try {
3978 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
3979 destIntent.getComponent(), 0, srec.userId);
Filip Gruszczynski303210b2016-01-08 16:28:08 -08003980 int res = mService.mActivityStarter.startActivityLocked(srec.app.thread,
3981 destIntent, null /*ephemeralIntent*/, null, aInfo, null /*rInfo*/, null,
3982 null, parent.appToken, null, 0, -1, parent.launchedFromUid,
Todd Kennedy7440f172015-12-09 14:31:22 -08003983 parent.launchedFromPackage, -1, parent.launchedFromUid, 0, null,
Andrii Kulian94e82d9b02017-07-13 15:33:06 -07003984 false, true, null, null, "navigateUpTo");
Craig Mautner05d6272ba2013-02-11 09:39:27 -08003985 foundParentInTask = res == ActivityManager.START_SUCCESS;
3986 } catch (RemoteException e) {
3987 foundParentInTask = false;
3988 }
3989 requestFinishActivityLocked(parent.appToken, resultCode,
Todd Kennedy539db512014-12-15 09:57:55 -08003990 resultData, "navigate-top", true);
Craig Mautner05d6272ba2013-02-11 09:39:27 -08003991 }
3992 }
3993 Binder.restoreCallingIdentity(origId);
3994 return foundParentInTask;
3995 }
Bryce Leeaf691c02017-03-20 14:20:22 -07003996
3997 /**
3998 * Remove any state associated with the {@link ActivityRecord}. This should be called whenever
3999 * an activity moves away from the stack.
4000 */
4001 void onActivityRemovedFromStack(ActivityRecord r) {
4002 if (mResumedActivity == r) {
4003 mResumedActivity = null;
4004 }
4005 if (mPausingActivity == r) {
4006 mPausingActivity = null;
4007 }
4008
4009 removeTimeoutsForActivityLocked(r);
4010 }
4011
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004012 /**
4013 * Perform the common clean-up of an activity record. This is called both
4014 * as part of destroyActivityLocked() (when destroying the client-side
4015 * representation) and cleaning things up as a result of its hosting
4016 * processing going away, in which case there is no remaining client-side
4017 * state to destroy so only the cleanup here is needed.
Craig Mautneracebdc82015-02-24 10:53:03 -08004018 *
4019 * Note: Call before #removeActivityFromHistoryLocked.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004020 */
Andrii Kulian21713ac2016-10-12 22:05:05 -07004021 private void cleanUpActivityLocked(ActivityRecord r, boolean cleanServices, boolean setState) {
Bryce Leeaf691c02017-03-20 14:20:22 -07004022 onActivityRemovedFromStack(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004023
Wale Ogunwalef81c1d12016-01-12 12:20:18 -08004024 r.deferRelaunchUntilPaused = false;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004025 r.frozenBeforeDestroy = false;
4026
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004027 if (setState) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004028 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to DESTROYED: " + r + " (cleaning up)");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004029 r.state = ActivityState.DESTROYED;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004030 if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during cleanUp for activity " + r);
Dianne Hackborncc5a0552012-10-01 16:32:39 -07004031 r.app = null;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004032 }
4033
Bryce Lee4a194382017-04-04 14:32:48 -07004034 // Inform supervisor the activity has been removed.
4035 mStackSupervisor.cleanupActivity(r);
4036
Craig Mautner2420ead2013-04-01 17:13:20 -07004037
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004038 // Remove any pending results.
4039 if (r.finishing && r.pendingResults != null) {
4040 for (WeakReference<PendingIntentRecord> apr : r.pendingResults) {
4041 PendingIntentRecord rec = apr.get();
4042 if (rec != null) {
4043 mService.cancelIntentSenderLocked(rec, false);
4044 }
4045 }
4046 r.pendingResults = null;
4047 }
4048
4049 if (cleanServices) {
Craig Mautner2420ead2013-04-01 17:13:20 -07004050 cleanUpActivityServicesLocked(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004051 }
4052
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004053 // Get rid of any pending idle timeouts.
Dianne Hackborn42e620c2012-06-24 13:20:51 -07004054 removeTimeoutsForActivityLocked(r);
Wale Ogunwale8fd75422016-06-24 14:20:37 -07004055 // Clean-up activities are no longer relaunching (e.g. app process died). Notify window
4056 // manager so it can update its bookkeeping.
4057 mWindowManager.notifyAppRelaunchesCleared(r.appToken);
Dianne Hackborn42e620c2012-06-24 13:20:51 -07004058 }
4059
Winson Chung4dabf232017-01-25 13:25:22 -08004060 void removeTimeoutsForActivityLocked(ActivityRecord r) {
Craig Mautnerf3333272013-04-22 10:55:53 -07004061 mStackSupervisor.removeTimeoutsForActivityLocked(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004062 mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
Dianne Hackborn162bc0e2012-04-09 14:06:16 -07004063 mHandler.removeMessages(STOP_TIMEOUT_MSG, r);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07004064 mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r);
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07004065 r.finishLaunchTickingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004066 }
4067
Chong Zhangbffd8892016-08-08 11:16:06 -07004068 private void removeActivityFromHistoryLocked(ActivityRecord r, String reason) {
Dianne Hackborncc5a0552012-10-01 16:32:39 -07004069 finishActivityResultsLocked(r, Activity.RESULT_CANCELED, null);
Wale Ogunwale7d701172015-03-11 15:36:30 -07004070 r.makeFinishingLocked();
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004071 if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE,
4072 "Removing activity " + r + " from stack callers=" + Debug.getCallers(5));
4073
Dianne Hackborncc5a0552012-10-01 16:32:39 -07004074 r.takeFromHistory();
4075 removeTimeoutsForActivityLocked(r);
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004076 if (DEBUG_STATES) Slog.v(TAG_STATES,
4077 "Moving to DESTROYED: " + r + " (removed from history)");
Dianne Hackborncc5a0552012-10-01 16:32:39 -07004078 r.state = ActivityState.DESTROYED;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004079 if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during remove for activity " + r);
Dianne Hackborncc5a0552012-10-01 16:32:39 -07004080 r.app = null;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08004081 r.removeWindowContainer();
Bryce Leeaf691c02017-03-20 14:20:22 -07004082 final TaskRecord task = r.getTask();
Bryce Leeaa5e8c32017-03-01 16:01:06 -08004083 final boolean lastActivity = task != null ? task.removeActivity(r) : false;
Winson Chung6954fc92017-03-24 16:22:12 -07004084 // If we are removing the last activity in the task, not including task overlay activities,
4085 // then fall through into the block below to remove the entire task itself
4086 final boolean onlyHasTaskOverlays = task != null
4087 ? task.onlyHasTaskOverlayActivities(false /* excludingFinishing */) : false;
Bryce Leeaa5e8c32017-03-01 16:01:06 -08004088
Winson Chung6954fc92017-03-24 16:22:12 -07004089 if (lastActivity || onlyHasTaskOverlays) {
4090 if (DEBUG_STACK) {
4091 Slog.i(TAG_STACK,
4092 "removeActivityFromHistoryLocked: last activity removed from " + this
4093 + " onlyHasTaskOverlays=" + onlyHasTaskOverlays);
4094 }
4095
Chong Zhangbffd8892016-08-08 11:16:06 -07004096 if (mStackSupervisor.isFocusedStack(this) && task == topTask() &&
Craig Mautner84984fa2014-06-19 11:19:20 -07004097 task.isOverHomeStack()) {
Matthew Ngae1ff4f2016-11-10 15:49:14 -08004098 mStackSupervisor.moveHomeStackTaskToTop(reason);
Craig Mautner312ba862014-02-10 17:55:01 -08004099 }
Winson Chunge3c21e02017-04-11 18:02:17 -07004100
Bryce Leed6d26752017-05-25 13:57:46 -07004101 // The following block can be executed multiple times if there is more than one overlay.
4102 // {@link ActivityStackSupervisor#removeTaskByIdLocked} handles this by reverse lookup
4103 // of the task by id and exiting early if not found.
Winson Chunge3c21e02017-04-11 18:02:17 -07004104 if (onlyHasTaskOverlays) {
4105 // When destroying a task, tell the supervisor to remove it so that any activity it
4106 // has can be cleaned up correctly. This is currently the only place where we remove
4107 // a task with the DESTROYING mode, so instead of passing the onlyHasTaskOverlays
4108 // state into removeTask(), we just clear the task here before the other residual
4109 // work.
4110 // TODO: If the callers to removeTask() changes such that we have multiple places
4111 // where we are destroying the task, move this back into removeTask()
4112 mStackSupervisor.removeTaskByIdLocked(task.taskId, false /* killProcess */,
4113 !REMOVE_FROM_RECENTS, PAUSE_IMMEDIATELY);
Winson Chunge3c21e02017-04-11 18:02:17 -07004114 }
Bryce Lee1d930582017-05-01 08:35:24 -07004115
Bryce Leed6d26752017-05-25 13:57:46 -07004116 // We must keep the task around until all activities are destroyed. The following
4117 // statement will only execute once since overlays are also considered activities.
Bryce Lee1d930582017-05-01 08:35:24 -07004118 if (lastActivity) {
4119 removeTask(task, reason, REMOVE_TASK_MODE_DESTROYING);
4120 }
Craig Mautner312ba862014-02-10 17:55:01 -08004121 }
Dianne Hackborncc5a0552012-10-01 16:32:39 -07004122 cleanUpActivityServicesLocked(r);
4123 r.removeUriPermissionsLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004124 }
Craig Mautnerdbcb31f2013-04-02 12:32:53 -07004125
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004126 /**
4127 * Perform clean-up of service connections in an activity record.
4128 */
Andrii Kulian21713ac2016-10-12 22:05:05 -07004129 private void cleanUpActivityServicesLocked(ActivityRecord r) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004130 // Throw away any services that have been bound by this activity.
4131 if (r.connections != null) {
4132 Iterator<ConnectionRecord> it = r.connections.iterator();
4133 while (it.hasNext()) {
4134 ConnectionRecord c = it.next();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07004135 mService.mServices.removeConnectionLocked(c, null, r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004136 }
4137 r.connections = null;
4138 }
4139 }
Dianne Hackborn755c8bf2012-05-07 15:06:09 -07004140
Craig Mautneree2e45a2014-06-27 12:10:03 -07004141 final void scheduleDestroyActivities(ProcessRecord owner, String reason) {
Dianne Hackborn755c8bf2012-05-07 15:06:09 -07004142 Message msg = mHandler.obtainMessage(DESTROY_ACTIVITIES_MSG);
Craig Mautneree2e45a2014-06-27 12:10:03 -07004143 msg.obj = new ScheduleDestroyArgs(owner, reason);
Dianne Hackborn755c8bf2012-05-07 15:06:09 -07004144 mHandler.sendMessage(msg);
4145 }
4146
Andrii Kulian21713ac2016-10-12 22:05:05 -07004147 private void destroyActivitiesLocked(ProcessRecord owner, String reason) {
Dianne Hackborn755c8bf2012-05-07 15:06:09 -07004148 boolean lastIsOpaque = false;
Dianne Hackborn42e620c2012-06-24 13:20:51 -07004149 boolean activityRemoved = false;
Craig Mautnerd44711d2013-02-23 11:24:36 -08004150 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
4151 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
4152 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
4153 final ActivityRecord r = activities.get(activityNdx);
4154 if (r.finishing) {
4155 continue;
4156 }
4157 if (r.fullscreen) {
4158 lastIsOpaque = true;
4159 }
4160 if (owner != null && r.app != owner) {
4161 continue;
4162 }
4163 if (!lastIsOpaque) {
4164 continue;
4165 }
Dianne Hackborn89ad4562014-08-24 16:45:38 -07004166 if (r.isDestroyable()) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07004167 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Destroying " + r + " in state " + r.state
Craig Mautnerd44711d2013-02-23 11:24:36 -08004168 + " resumed=" + mResumedActivity
Dianne Hackborn89ad4562014-08-24 16:45:38 -07004169 + " pausing=" + mPausingActivity + " for reason " + reason);
Craig Mautneree2e45a2014-06-27 12:10:03 -07004170 if (destroyActivityLocked(r, true, reason)) {
Craig Mautnerd44711d2013-02-23 11:24:36 -08004171 activityRemoved = true;
4172 }
Dianne Hackborn42e620c2012-06-24 13:20:51 -07004173 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004174 }
4175 }
Dianne Hackborn42e620c2012-06-24 13:20:51 -07004176 if (activityRemoved) {
Wale Ogunwaled046a012015-12-24 13:05:59 -08004177 mStackSupervisor.resumeFocusedStackTopActivityLocked();
Dianne Hackborn42e620c2012-06-24 13:20:51 -07004178 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004179 }
4180
Dianne Hackborn89ad4562014-08-24 16:45:38 -07004181 final boolean safelyDestroyActivityLocked(ActivityRecord r, String reason) {
4182 if (r.isDestroyable()) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07004183 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
4184 "Destroying " + r + " in state " + r.state + " resumed=" + mResumedActivity
Dianne Hackborn89ad4562014-08-24 16:45:38 -07004185 + " pausing=" + mPausingActivity + " for reason " + reason);
4186 return destroyActivityLocked(r, true, reason);
4187 }
4188 return false;
4189 }
4190
4191 final int releaseSomeActivitiesLocked(ProcessRecord app, ArraySet<TaskRecord> tasks,
4192 String reason) {
4193 // Iterate over tasks starting at the back (oldest) first.
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004194 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Trying to release some activities in " + app);
Dianne Hackborn89ad4562014-08-24 16:45:38 -07004195 int maxTasks = tasks.size() / 4;
4196 if (maxTasks < 1) {
4197 maxTasks = 1;
4198 }
4199 int numReleased = 0;
4200 for (int taskNdx = 0; taskNdx < mTaskHistory.size() && maxTasks > 0; taskNdx++) {
4201 final TaskRecord task = mTaskHistory.get(taskNdx);
4202 if (!tasks.contains(task)) {
4203 continue;
4204 }
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004205 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Looking for activities to release in " + task);
Dianne Hackborn89ad4562014-08-24 16:45:38 -07004206 int curNum = 0;
4207 final ArrayList<ActivityRecord> activities = task.mActivities;
4208 for (int actNdx = 0; actNdx < activities.size(); actNdx++) {
4209 final ActivityRecord activity = activities.get(actNdx);
4210 if (activity.app == app && activity.isDestroyable()) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004211 if (DEBUG_RELEASE) Slog.v(TAG_RELEASE, "Destroying " + activity
Dianne Hackborn89ad4562014-08-24 16:45:38 -07004212 + " in state " + activity.state + " resumed=" + mResumedActivity
4213 + " pausing=" + mPausingActivity + " for reason " + reason);
4214 destroyActivityLocked(activity, true, reason);
4215 if (activities.get(actNdx) != activity) {
4216 // Was removed from list, back up so we don't miss the next one.
4217 actNdx--;
4218 }
4219 curNum++;
4220 }
4221 }
4222 if (curNum > 0) {
4223 numReleased += curNum;
4224 maxTasks--;
4225 if (mTaskHistory.get(taskNdx) != task) {
4226 // The entire task got removed, back up so we don't miss the next one.
4227 taskNdx--;
4228 }
4229 }
4230 }
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004231 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE,
4232 "Done releasing: did " + numReleased + " activities");
Dianne Hackborn89ad4562014-08-24 16:45:38 -07004233 return numReleased;
4234 }
4235
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004236 /**
4237 * Destroy the current CLIENT SIDE instance of an activity. This may be
4238 * called both when actually finishing an activity, or when performing
4239 * a configuration switch where we destroy the current client-side object
4240 * but then create a new client-side object for this same HistoryRecord.
4241 */
Craig Mautneree2e45a2014-06-27 12:10:03 -07004242 final boolean destroyActivityLocked(ActivityRecord r, boolean removeFromApp, String reason) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07004243 if (DEBUG_SWITCH || DEBUG_CLEANUP) Slog.v(TAG_SWITCH,
4244 "Removing activity from " + reason + ": token=" + r
Filip Gruszczynskia59ac9c2015-09-10 18:28:48 -07004245 + ", app=" + (r.app != null ? r.app.processName : "(null)"));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004246 EventLog.writeEvent(EventLogTags.AM_DESTROY_ACTIVITY,
Dianne Hackbornb12e1352012-09-26 11:39:20 -07004247 r.userId, System.identityHashCode(r),
Bryce Leeaf691c02017-03-20 14:20:22 -07004248 r.getTask().taskId, r.shortComponentName, reason);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004249
4250 boolean removedFromHistory = false;
Dianne Hackborncc5a0552012-10-01 16:32:39 -07004251
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004252 cleanUpActivityLocked(r, false, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004253
4254 final boolean hadApp = r.app != null;
Dianne Hackborncc5a0552012-10-01 16:32:39 -07004255
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004256 if (hadApp) {
4257 if (removeFromApp) {
Craig Mautnerd2328952013-03-05 12:46:26 -08004258 r.app.activities.remove(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004259 if (mService.mHeavyWeightProcess == r.app && r.app.activities.size() <= 0) {
4260 mService.mHeavyWeightProcess = null;
4261 mService.mHandler.sendEmptyMessage(
4262 ActivityManagerService.CANCEL_HEAVY_NOTIFICATION_MSG);
4263 }
Craig Mautnerc8143c62013-09-03 12:15:57 -07004264 if (r.app.activities.isEmpty()) {
Dianne Hackborn465fa392014-09-14 14:21:18 -07004265 // Update any services we are bound to that might care about whether
4266 // their client may have activities.
4267 mService.mServices.updateServiceConnectionActivitiesLocked(r.app);
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07004268 // No longer have activities, so update LRU list and oom adj.
Dianne Hackborndb926082013-10-31 16:32:44 -07004269 mService.updateLruProcessLocked(r.app, false, null);
Dianne Hackborn2d1b3782012-09-09 17:49:39 -07004270 mService.updateOomAdjLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004271 }
4272 }
4273
4274 boolean skipDestroy = false;
Craig Mautnerdbcb31f2013-04-02 12:32:53 -07004275
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004276 try {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07004277 if (DEBUG_SWITCH) Slog.i(TAG_SWITCH, "Destroying: " + r);
Dianne Hackbornbe707852011-11-11 14:32:10 -08004278 r.app.thread.scheduleDestroyActivity(r.appToken, r.finishing,
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004279 r.configChangeFlags);
4280 } catch (Exception e) {
4281 // We can just ignore exceptions here... if the process
4282 // has crashed, our death notification will clean things
4283 // up.
4284 //Slog.w(TAG, "Exception thrown during finish", e);
4285 if (r.finishing) {
Chong Zhangbffd8892016-08-08 11:16:06 -07004286 removeActivityFromHistoryLocked(r, reason + " exceptionInScheduleDestroy");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004287 removedFromHistory = true;
4288 skipDestroy = true;
4289 }
4290 }
4291
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004292 r.nowVisible = false;
Craig Mautnerdbcb31f2013-04-02 12:32:53 -07004293
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004294 // If the activity is finishing, we need to wait on removing it
4295 // from the list to give it a chance to do its cleanup. During
4296 // that time it may make calls back with its token so we need to
4297 // be able to find it on the list and so we don't want to remove
4298 // it from the list yet. Otherwise, we can just immediately put
4299 // it in the destroyed state since we are not removing it from the
4300 // list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004301 if (r.finishing && !skipDestroy) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004302 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to DESTROYING: " + r
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004303 + " (destroy requested)");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004304 r.state = ActivityState.DESTROYING;
Craig Mautnerf7bfefb2013-05-16 17:30:44 -07004305 Message msg = mHandler.obtainMessage(DESTROY_TIMEOUT_MSG, r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004306 mHandler.sendMessageDelayed(msg, DESTROY_TIMEOUT);
4307 } else {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004308 if (DEBUG_STATES) Slog.v(TAG_STATES,
4309 "Moving to DESTROYED: " + r + " (destroy skipped)");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004310 r.state = ActivityState.DESTROYED;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004311 if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during destroy for activity " + r);
Dianne Hackborncc5a0552012-10-01 16:32:39 -07004312 r.app = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004313 }
4314 } else {
4315 // remove this record from the history.
4316 if (r.finishing) {
Chong Zhangbffd8892016-08-08 11:16:06 -07004317 removeActivityFromHistoryLocked(r, reason + " hadNoApp");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004318 removedFromHistory = true;
4319 } else {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004320 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to DESTROYED: " + r + " (no app)");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004321 r.state = ActivityState.DESTROYED;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004322 if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during destroy for activity " + r);
Dianne Hackborncc5a0552012-10-01 16:32:39 -07004323 r.app = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004324 }
4325 }
4326
4327 r.configChangeFlags = 0;
Craig Mautnerdbcb31f2013-04-02 12:32:53 -07004328
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004329 if (!mLRUActivities.remove(r) && hadApp) {
4330 Slog.w(TAG, "Activity " + r + " being finished, but not in LRU list");
4331 }
Craig Mautnerdbcb31f2013-04-02 12:32:53 -07004332
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004333 return removedFromHistory;
4334 }
4335
Craig Mautner299f9602015-01-26 09:47:33 -08004336 final void activityDestroyedLocked(IBinder token, String reason) {
Craig Mautnerd2328952013-03-05 12:46:26 -08004337 final long origId = Binder.clearCallingIdentity();
4338 try {
Wale Ogunwale7d701172015-03-11 15:36:30 -07004339 ActivityRecord r = ActivityRecord.forTokenLocked(token);
Craig Mautnerd2328952013-03-05 12:46:26 -08004340 if (r != null) {
4341 mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004342 }
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004343 if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, "activityDestroyedLocked: r=" + r);
Craig Mautnerd2328952013-03-05 12:46:26 -08004344
Wale Ogunwale60454db2015-01-23 16:05:07 -08004345 if (isInStackLocked(r) != null) {
Craig Mautnerd2328952013-03-05 12:46:26 -08004346 if (r.state == ActivityState.DESTROYING) {
4347 cleanUpActivityLocked(r, true, false);
Chong Zhangbffd8892016-08-08 11:16:06 -07004348 removeActivityFromHistoryLocked(r, reason);
Craig Mautnerd2328952013-03-05 12:46:26 -08004349 }
4350 }
Wale Ogunwaled046a012015-12-24 13:05:59 -08004351 mStackSupervisor.resumeFocusedStackTopActivityLocked();
Craig Mautnerd2328952013-03-05 12:46:26 -08004352 } finally {
4353 Binder.restoreCallingIdentity(origId);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004354 }
4355 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07004356
Craig Mautner05d6272ba2013-02-11 09:39:27 -08004357 private void removeHistoryRecordsForAppLocked(ArrayList<ActivityRecord> list,
4358 ProcessRecord app, String listName) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004359 int i = list.size();
Wale Ogunwalee23149f2015-03-06 15:39:44 -08004360 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4361 "Removing app " + app + " from list " + listName + " with " + i + " entries");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004362 while (i > 0) {
4363 i--;
Craig Mautner05d6272ba2013-02-11 09:39:27 -08004364 ActivityRecord r = list.get(i);
Wale Ogunwalee23149f2015-03-06 15:39:44 -08004365 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, "Record #" + i + " " + r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004366 if (r.app == app) {
Wale Ogunwalee23149f2015-03-06 15:39:44 -08004367 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, "---> REMOVING this entry!");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004368 list.remove(i);
Dianne Hackborn42e620c2012-06-24 13:20:51 -07004369 removeTimeoutsForActivityLocked(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004370 }
4371 }
4372 }
4373
Andrii Kulian21713ac2016-10-12 22:05:05 -07004374 private boolean removeHistoryRecordsForAppLocked(ProcessRecord app) {
Dianne Hackborncc5a0552012-10-01 16:32:39 -07004375 removeHistoryRecordsForAppLocked(mLRUActivities, app, "mLRUActivities");
Craig Mautnerde4ef022013-04-07 19:01:33 -07004376 removeHistoryRecordsForAppLocked(mStackSupervisor.mStoppingActivities, app,
4377 "mStoppingActivities");
Craig Mautner0eea92c2013-05-16 13:35:39 -07004378 removeHistoryRecordsForAppLocked(mStackSupervisor.mGoingToSleepActivities, app,
4379 "mGoingToSleepActivities");
Bryce Lee4a194382017-04-04 14:32:48 -07004380 removeHistoryRecordsForAppLocked(mStackSupervisor.mActivitiesWaitingForVisibleActivity, app,
4381 "mActivitiesWaitingForVisibleActivity");
Craig Mautnerf3333272013-04-22 10:55:53 -07004382 removeHistoryRecordsForAppLocked(mStackSupervisor.mFinishingActivities, app,
4383 "mFinishingActivities");
Dianne Hackborncc5a0552012-10-01 16:32:39 -07004384
4385 boolean hasVisibleActivities = false;
4386
4387 // Clean out the history list.
Craig Mautner0247fc82013-02-28 14:32:06 -08004388 int i = numActivities();
Wale Ogunwalee23149f2015-03-06 15:39:44 -08004389 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4390 "Removing app " + app + " from history with " + i + " entries");
Craig Mautner0247fc82013-02-28 14:32:06 -08004391 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
4392 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
4393 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
4394 final ActivityRecord r = activities.get(activityNdx);
4395 --i;
Wale Ogunwalee23149f2015-03-06 15:39:44 -08004396 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4397 "Record #" + i + " " + r + ": app=" + r.app);
Craig Mautner0247fc82013-02-28 14:32:06 -08004398 if (r.app == app) {
riddle_hsu558e8492015-04-02 16:43:13 +08004399 if (r.visible) {
4400 hasVisibleActivities = true;
4401 }
Craig Mautneracebdc82015-02-24 10:53:03 -08004402 final boolean remove;
Craig Mautner0247fc82013-02-28 14:32:06 -08004403 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
4404 // Don't currently have state for the activity, or
4405 // it is finishing -- always remove it.
4406 remove = true;
Chong Zhang112eb8c2015-11-02 11:17:00 -08004407 } else if (!r.visible && r.launchCount > 2 &&
4408 r.lastLaunchTime > (SystemClock.uptimeMillis() - 60000)) {
Craig Mautner0247fc82013-02-28 14:32:06 -08004409 // We have launched this activity too many times since it was
4410 // able to run, so give up and remove it.
Chong Zhang112eb8c2015-11-02 11:17:00 -08004411 // (Note if the activity is visible, we don't remove the record.
4412 // We leave the dead window on the screen but the process will
4413 // not be restarted unless user explicitly tap on it.)
Craig Mautner0247fc82013-02-28 14:32:06 -08004414 remove = true;
4415 } else {
4416 // The process may be gone, but the activity lives on!
4417 remove = false;
Dianne Hackborncc5a0552012-10-01 16:32:39 -07004418 }
Craig Mautner0247fc82013-02-28 14:32:06 -08004419 if (remove) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004420 if (DEBUG_ADD_REMOVE || DEBUG_CLEANUP) Slog.i(TAG_ADD_REMOVE,
4421 "Removing activity " + r + " from stack at " + i
4422 + ": haveState=" + r.haveState
4423 + " stateNotNeeded=" + r.stateNotNeeded
4424 + " finishing=" + r.finishing
4425 + " state=" + r.state + " callers=" + Debug.getCallers(5));
Craig Mautner0247fc82013-02-28 14:32:06 -08004426 if (!r.finishing) {
4427 Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
4428 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
4429 r.userId, System.identityHashCode(r),
Bryce Leeaf691c02017-03-20 14:20:22 -07004430 r.getTask().taskId, r.shortComponentName,
Craig Mautner0247fc82013-02-28 14:32:06 -08004431 "proc died without state saved");
Jeff Sharkey5782da72013-04-25 14:32:30 -07004432 if (r.state == ActivityState.RESUMED) {
4433 mService.updateUsageStats(r, false);
4434 }
Craig Mautner0247fc82013-02-28 14:32:06 -08004435 }
Craig Mautner0247fc82013-02-28 14:32:06 -08004436 } else {
4437 // We have the current state for this activity, so
4438 // it can be restarted later when needed.
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004439 if (DEBUG_ALL) Slog.v(TAG, "Keeping entry, setting app to null");
4440 if (DEBUG_APP) Slog.v(TAG_APP,
4441 "Clearing app during removeHistory for activity " + r);
Craig Mautner0247fc82013-02-28 14:32:06 -08004442 r.app = null;
Chong Zhang112eb8c2015-11-02 11:17:00 -08004443 // Set nowVisible to previous visible state. If the app was visible while
4444 // it died, we leave the dead window on screen so it's basically visible.
4445 // This is needed when user later tap on the dead window, we need to stop
4446 // other apps when user transfers focus to the restarted activity.
4447 r.nowVisible = r.visible;
Craig Mautner0247fc82013-02-28 14:32:06 -08004448 if (!r.haveState) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004449 if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE,
Craig Mautner0247fc82013-02-28 14:32:06 -08004450 "App died, clearing saved state of " + r);
4451 r.icicle = null;
4452 }
Dianne Hackborncc5a0552012-10-01 16:32:39 -07004453 }
Craig Mautnerd2328952013-03-05 12:46:26 -08004454 cleanUpActivityLocked(r, true, true);
Craig Mautneracebdc82015-02-24 10:53:03 -08004455 if (remove) {
Chong Zhangbffd8892016-08-08 11:16:06 -07004456 removeActivityFromHistoryLocked(r, "appDied");
Craig Mautneracebdc82015-02-24 10:53:03 -08004457 }
Craig Mautner0247fc82013-02-28 14:32:06 -08004458 }
Dianne Hackborncc5a0552012-10-01 16:32:39 -07004459 }
4460 }
4461
4462 return hasVisibleActivities;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004463 }
Craig Mautner0247fc82013-02-28 14:32:06 -08004464
Andrii Kulian21713ac2016-10-12 22:05:05 -07004465 private void updateTransitLocked(int transit, ActivityOptions options) {
Dianne Hackborn7f58b952012-04-18 12:59:29 -07004466 if (options != null) {
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -07004467 ActivityRecord r = topRunningActivityLocked();
Dianne Hackborn7f58b952012-04-18 12:59:29 -07004468 if (r != null && r.state != ActivityState.RESUMED) {
4469 r.updateOptionsLocked(options);
4470 } else {
4471 ActivityOptions.abort(options);
4472 }
4473 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07004474 mWindowManager.prepareAppTransition(transit, false);
Dianne Hackborn7f58b952012-04-18 12:59:29 -07004475 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004476
Andrii Kulian21713ac2016-10-12 22:05:05 -07004477 private void updateTaskMovement(TaskRecord task, boolean toFront) {
Craig Mautner21d24a22014-04-23 11:45:37 -07004478 if (task.isPersistable) {
4479 task.mLastTimeMoved = System.currentTimeMillis();
4480 // Sign is used to keep tasks sorted when persisted. Tasks sent to the bottom most
4481 // recently will be most negative, tasks sent to the bottom before that will be less
4482 // negative. Similarly for recent tasks moved to the top which will be most positive.
4483 if (!toFront) {
4484 task.mLastTimeMoved *= -1;
4485 }
4486 }
Chong Zhangfdcc4d42015-10-14 16:50:12 -07004487 mStackSupervisor.invalidateTaskLayers();
Craig Mautner21d24a22014-04-23 11:45:37 -07004488 }
4489
Matthew Ngae1ff4f2016-11-10 15:49:14 -08004490 void moveHomeStackTaskToTop() {
Craig Mautnera82aa092013-09-13 15:34:08 -07004491 final int top = mTaskHistory.size() - 1;
4492 for (int taskNdx = top; taskNdx >= 0; --taskNdx) {
4493 final TaskRecord task = mTaskHistory.get(taskNdx);
Matthew Ngae1ff4f2016-11-10 15:49:14 -08004494 if (task.taskType == HOME_ACTIVITY_TYPE) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07004495 if (DEBUG_TASKS || DEBUG_STACK) Slog.d(TAG_STACK,
4496 "moveHomeStackTaskToTop: moving " + task);
Craig Mautnera82aa092013-09-13 15:34:08 -07004497 mTaskHistory.remove(taskNdx);
4498 mTaskHistory.add(top, task);
Craig Mautner21d24a22014-04-23 11:45:37 -07004499 updateTaskMovement(task, true);
Craig Mautnera82aa092013-09-13 15:34:08 -07004500 return;
4501 }
4502 }
4503 }
4504
Chong Zhang280d3322015-11-03 17:27:26 -08004505 final void moveTaskToFrontLocked(TaskRecord tr, boolean noAnimation, ActivityOptions options,
Dianne Hackbornb5a380d2015-05-20 18:18:46 -07004506 AppTimeTracker timeTracker, String reason) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07004507 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "moveTaskToFront: " + tr);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004508
Andrii Kulian0864bbb2017-02-16 15:45:58 -08004509 final ActivityStack topStack = getTopStackOnDisplay();
4510 final ActivityRecord topActivity = topStack != null ? topStack.topActivity() : null;
Craig Mautner11bf9a52013-02-19 14:08:51 -08004511 final int numTasks = mTaskHistory.size();
4512 final int index = mTaskHistory.indexOf(tr);
Craig Mautner86d67a42013-05-14 10:34:38 -07004513 if (numTasks == 0 || index < 0) {
Craig Mautner11bf9a52013-02-19 14:08:51 -08004514 // nothing to do!
Craig Mautner8f5f7e92015-01-26 18:03:13 -08004515 if (noAnimation) {
Craig Mautner11bf9a52013-02-19 14:08:51 -08004516 ActivityOptions.abort(options);
4517 } else {
Jorim Jaggiaf80db42016-04-07 19:19:15 -07004518 updateTransitLocked(TRANSIT_TASK_TO_FRONT, options);
Craig Mautner11bf9a52013-02-19 14:08:51 -08004519 }
4520 return;
4521 }
4522
Dianne Hackbornb5a380d2015-05-20 18:18:46 -07004523 if (timeTracker != null) {
4524 // The caller wants a time tracker associated with this task.
4525 for (int i = tr.mActivities.size() - 1; i >= 0; i--) {
4526 tr.mActivities.get(i).appTimeTracker = timeTracker;
4527 }
4528 }
4529
Craig Mautner11bf9a52013-02-19 14:08:51 -08004530 // Shift all activities with this task up to the top
4531 // of the stack, keeping them in the same internal order.
Wale Ogunwale3fcb4a82015-04-06 14:00:13 -07004532 insertTaskAtTop(tr, null);
Wale Ogunwaled80c2632015-03-13 10:26:26 -07004533
Chong Zhang45c25ce2015-08-10 22:18:26 -07004534 // Don't refocus if invisible to current user
Andrii Kulian0864bbb2017-02-16 15:45:58 -08004535 final ActivityRecord top = tr.getTopActivity();
Chong Zhang87761972016-08-22 13:53:24 -07004536 if (top == null || !top.okToShowLocked()) {
Chong Zhang45c25ce2015-08-10 22:18:26 -07004537 addRecentActivityLocked(top);
4538 ActivityOptions.abort(options);
4539 return;
4540 }
4541
Wale Ogunwaled80c2632015-03-13 10:26:26 -07004542 // Set focus to the top running activity of this stack.
Andrii Kulian0864bbb2017-02-16 15:45:58 -08004543 final ActivityRecord r = topRunningActivityLocked();
Chong Zhang6cda19c2016-06-14 19:07:56 -07004544 mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, reason);
Craig Mautner11bf9a52013-02-19 14:08:51 -08004545
Wale Ogunwaleee006da2015-03-30 14:49:25 -07004546 if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to front transition: task=" + tr);
Craig Mautner8f5f7e92015-01-26 18:03:13 -08004547 if (noAnimation) {
Jorim Jaggiaf80db42016-04-07 19:19:15 -07004548 mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004549 if (r != null) {
4550 mNoAnimActivities.add(r);
4551 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07004552 ActivityOptions.abort(options);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004553 } else {
Jorim Jaggiaf80db42016-04-07 19:19:15 -07004554 updateTransitLocked(TRANSIT_TASK_TO_FRONT, options);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004555 }
Winson Chungc2baac02017-01-11 13:34:47 -08004556 // If a new task is moved to the front, then mark the existing top activity as supporting
Winson Chung942a85c2017-07-11 15:07:45 -07004557 // picture-in-picture while paused only if the task would not be considered an oerlay on top
4558 // of the current activity (eg. not fullscreen, or the assistant)
Winson Chung4aede8a2017-07-05 12:23:25 -07004559 if (topActivity != null && topActivity.getStackId() != PINNED_STACK_ID
Winson Chung942a85c2017-07-11 15:07:45 -07004560 && tr.getStackId() != ASSISTANT_STACK_ID && tr.containsOnlyFullscreenActivities()) {
Andrii Kulian0864bbb2017-02-16 15:45:58 -08004561 topActivity.supportsPictureInPictureWhilePausing = true;
Winson Chungb5c41b72016-12-07 15:00:47 -08004562 }
Craig Mautner30e2d722013-02-12 11:30:16 -08004563
Wale Ogunwaled046a012015-12-24 13:05:59 -08004564 mStackSupervisor.resumeFocusedStackTopActivityLocked();
Craig Mautner58547802013-03-05 08:23:53 -08004565 EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, tr.taskId);
Yorke Leebd54c2a2016-10-25 13:49:23 -07004566
4567 mService.mTaskChangeNotificationController.notifyTaskMovedToFront(tr.taskId);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004568 }
4569
4570 /**
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07004571 * Worker method for rearranging history stack. Implements the function of moving all
4572 * activities for a specific task (gathering them if disjoint) into a single group at the
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004573 * bottom of the stack.
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07004574 *
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004575 * If a watcher is installed, the action is preflighted and the watcher has an opportunity
4576 * to premeptively cancel the move.
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07004577 *
Craig Mautnerae7ecab2013-09-18 11:48:14 -07004578 * @param taskId The taskId to collect and move to the bottom.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004579 * @return Returns true if the move completed, false if not.
4580 */
Craig Mautner299f9602015-01-26 09:47:33 -08004581 final boolean moveTaskToBackLocked(int taskId) {
Craig Mautneraea74a52014-03-08 14:23:10 -08004582 final TaskRecord tr = taskForIdLocked(taskId);
4583 if (tr == null) {
4584 Slog.i(TAG, "moveTaskToBack: bad taskId=" + taskId);
4585 return false;
4586 }
Craig Mautneraea74a52014-03-08 14:23:10 -08004587 Slog.i(TAG, "moveTaskToBack: " + tr);
Winson Chung261c0f32017-03-07 16:54:31 -08004588
4589 // If the task is locked, then show the lock task toast
4590 if (mStackSupervisor.isLockedTask(tr)) {
4591 mStackSupervisor.showLockTaskToast();
4592 return false;
4593 }
Craig Mautnerb44de0d2013-02-21 20:00:58 -08004594
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004595 // If we have a watcher, preflight the move before committing to it. First check
4596 // for *other* available tasks, but if none are available, then try again allowing the
4597 // current task to be selected.
Andrii Kulian7d95df42017-02-15 10:11:48 -08004598 if (mStackSupervisor.isFrontStackOnDisplay(this) && mService.mController != null) {
Craig Mautnerae7ecab2013-09-18 11:48:14 -07004599 ActivityRecord next = topRunningActivityLocked(null, taskId);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004600 if (next == null) {
4601 next = topRunningActivityLocked(null, 0);
4602 }
4603 if (next != null) {
4604 // ask watcher if this is allowed
4605 boolean moveOK = true;
4606 try {
4607 moveOK = mService.mController.activityResuming(next.packageName);
4608 } catch (RemoteException e) {
4609 mService.mController = null;
Kenny Rootadd58212013-05-07 09:47:34 -07004610 Watchdog.getInstance().setActivityController(null);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004611 }
4612 if (!moveOK) {
4613 return false;
4614 }
4615 }
4616 }
4617
Wale Ogunwaleee006da2015-03-30 14:49:25 -07004618 if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to back transition: task=" + taskId);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004619
riddle_hsuc215a4f2014-12-27 12:10:45 +08004620 boolean prevIsHome = false;
Wale Ogunwale42709242015-08-11 13:54:42 -07004621
4622 // If true, we should resume the home activity next if the task we are moving to the
4623 // back is over the home stack. We force to false if the task we are moving to back
4624 // is the home task and we don't want it resumed after moving to the back.
4625 final boolean canGoHome = !tr.isHomeTask() && tr.isOverHomeStack();
4626 if (canGoHome) {
riddle_hsuc215a4f2014-12-27 12:10:45 +08004627 final TaskRecord nextTask = getNextTask(tr);
4628 if (nextTask != null) {
4629 nextTask.setTaskToReturnTo(tr.getTaskToReturnTo());
4630 } else {
4631 prevIsHome = true;
4632 }
4633 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004634
Winson Chung261c0f32017-03-07 16:54:31 -08004635 boolean requiresMove = mTaskHistory.indexOf(tr) != 0;
4636 if (requiresMove) {
4637 mTaskHistory.remove(tr);
4638 mTaskHistory.add(0, tr);
4639 updateTaskMovement(tr, false);
4640
4641 mWindowManager.prepareAppTransition(TRANSIT_TASK_TO_BACK, false);
4642 mWindowContainerController.positionChildAtBottom(tr.getWindowContainerController());
4643 }
4644
4645 if (mStackId == PINNED_STACK_ID) {
4646 mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
4647 return true;
4648 }
4649
4650 // Otherwise, there is an assumption that moving a task to the back moves it behind the
4651 // home activity. We make sure here that some activity in the stack will launch home.
Craig Mautnerc8143c62013-09-03 12:15:57 -07004652 int numTasks = mTaskHistory.size();
Craig Mautnerae7ecab2013-09-18 11:48:14 -07004653 for (int taskNdx = numTasks - 1; taskNdx >= 1; --taskNdx) {
4654 final TaskRecord task = mTaskHistory.get(taskNdx);
Craig Mautner84984fa2014-06-19 11:19:20 -07004655 if (task.isOverHomeStack()) {
Craig Mautnerc8143c62013-09-03 12:15:57 -07004656 break;
4657 }
Craig Mautnerae7ecab2013-09-18 11:48:14 -07004658 if (taskNdx == 1) {
4659 // Set the last task before tr to go to home.
Craig Mautner84984fa2014-06-19 11:19:20 -07004660 task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
Craig Mautnerae7ecab2013-09-18 11:48:14 -07004661 }
Craig Mautnerc8143c62013-09-03 12:15:57 -07004662 }
4663
Bryce Leeaf691c02017-03-20 14:20:22 -07004664 final TaskRecord task = mResumedActivity != null ? mResumedActivity.getTask() : null;
Wale Ogunwale42709242015-08-11 13:54:42 -07004665 if (prevIsHome || (task == tr && canGoHome) || (numTasks <= 1 && isOnHomeDisplay())) {
Dianne Hackborn7622a0f2014-09-30 14:31:42 -07004666 if (!mService.mBooting && !mService.mBooted) {
4667 // Not ready yet!
4668 return false;
4669 }
Craig Mautner84984fa2014-06-19 11:19:20 -07004670 tr.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
Matthew Ngae1ff4f2016-11-10 15:49:14 -08004671 return mStackSupervisor.resumeHomeStackTask(null, "moveTaskToBack");
Craig Mautnerde4ef022013-04-07 19:01:33 -07004672 }
4673
Wale Ogunwaled046a012015-12-24 13:05:59 -08004674 mStackSupervisor.resumeFocusedStackTopActivityLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004675 return true;
4676 }
Dianne Hackborn15491c62012-09-19 10:59:14 -07004677
Andrii Kulian0864bbb2017-02-16 15:45:58 -08004678 /**
4679 * Get the topmost stack on the current display. It may be different from focused stack, because
4680 * focus may be on another display.
4681 */
4682 private ActivityStack getTopStackOnDisplay() {
Andrii Kulian94e82d9b02017-07-13 15:33:06 -07004683 final ArrayList<ActivityStack> stacks = getDisplay().mStacks;
Andrii Kulian0864bbb2017-02-16 15:45:58 -08004684 return stacks.isEmpty() ? null : stacks.get(stacks.size() - 1);
4685 }
4686
Andrii Kulian21713ac2016-10-12 22:05:05 -07004687 static void logStartActivity(int tag, ActivityRecord r, TaskRecord task) {
Santos Cordon73ff7d82013-03-06 17:24:11 -08004688 final Uri data = r.intent.getData();
4689 final String strData = data != null ? data.toSafeString() : null;
4690
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004691 EventLog.writeEvent(tag,
Dianne Hackbornb12e1352012-09-26 11:39:20 -07004692 r.userId, System.identityHashCode(r), task.taskId,
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004693 r.shortComponentName, r.intent.getAction(),
Santos Cordon73ff7d82013-03-06 17:24:11 -08004694 r.intent.getType(), strData, r.intent.getFlags());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004695 }
4696
4697 /**
Wale Ogunwaledb0fa122016-05-16 15:12:03 -07004698 * Ensures all visible activities at or below the input activity have the right configuration.
4699 */
4700 void ensureVisibleActivitiesConfigurationLocked(ActivityRecord start, boolean preserveWindow) {
4701 if (start == null || !start.visible) {
4702 return;
4703 }
4704
Bryce Leeaf691c02017-03-20 14:20:22 -07004705 final TaskRecord startTask = start.getTask();
Wale Ogunwaledb0fa122016-05-16 15:12:03 -07004706 boolean behindFullscreen = false;
4707 boolean updatedConfig = false;
4708
4709 for (int taskIndex = mTaskHistory.indexOf(startTask); taskIndex >= 0; --taskIndex) {
4710 final TaskRecord task = mTaskHistory.get(taskIndex);
4711 final ArrayList<ActivityRecord> activities = task.mActivities;
4712 int activityIndex =
Bryce Leeaf691c02017-03-20 14:20:22 -07004713 (start.getTask() == task) ? activities.indexOf(start) : activities.size() - 1;
Wale Ogunwaledb0fa122016-05-16 15:12:03 -07004714 for (; activityIndex >= 0; --activityIndex) {
4715 final ActivityRecord r = activities.get(activityIndex);
Andrii Kulian21713ac2016-10-12 22:05:05 -07004716 updatedConfig |= r.ensureActivityConfigurationLocked(0 /* globalChanges */,
4717 preserveWindow);
Wale Ogunwaledb0fa122016-05-16 15:12:03 -07004718 if (r.fullscreen) {
4719 behindFullscreen = true;
4720 break;
4721 }
4722 }
4723 if (behindFullscreen) {
4724 break;
4725 }
4726 }
4727 if (updatedConfig) {
Wale Ogunwale089586f2016-06-20 14:16:22 -07004728 // Ensure the resumed state of the focus activity if we updated the configuration of
Wale Ogunwaledb0fa122016-05-16 15:12:03 -07004729 // any activity.
4730 mStackSupervisor.resumeFocusedStackTopActivityLocked();
4731 }
4732 }
4733
Wale Ogunwale1666e312016-12-16 11:27:18 -08004734 // TODO: Figure-out a way to consolidate with resize() method below.
4735 @Override
4736 public void requestResize(Rect bounds) {
4737 mService.resizeStack(mStackId, bounds, true /* allowResizeInDockedMode */,
4738 false /* preserveWindows */, false /* animate */, -1 /* animationDuration */);
4739 }
Andrii Kulian1e32e022016-09-16 15:29:34 -07004740
Wale Ogunwale1666e312016-12-16 11:27:18 -08004741 // TODO: Can only be called from special methods in ActivityStackSupervisor.
4742 // Need to consolidate those calls points into this resize method so anyone can call directly.
4743 void resize(Rect bounds, Rect tempTaskBounds, Rect tempTaskInsetBounds) {
4744 bounds = TaskRecord.validateBounds(bounds);
4745
4746 if (!updateBoundsAllowed(bounds, tempTaskBounds, tempTaskInsetBounds)) {
4747 return;
4748 }
4749
4750 // Update override configurations of all tasks in the stack.
4751 final Rect taskBounds = tempTaskBounds != null ? tempTaskBounds : bounds;
Andrii Kulian1e32e022016-09-16 15:29:34 -07004752 final Rect insetBounds = tempTaskInsetBounds != null ? tempTaskInsetBounds : taskBounds;
4753
4754 mTmpBounds.clear();
4755 mTmpConfigs.clear();
4756 mTmpInsetBounds.clear();
4757
4758 for (int i = mTaskHistory.size() - 1; i >= 0; i--) {
4759 final TaskRecord task = mTaskHistory.get(i);
4760 if (task.isResizeable()) {
4761 if (mStackId == FREEFORM_WORKSPACE_STACK_ID) {
4762 // For freeform stack we don't adjust the size of the tasks to match that
4763 // of the stack, but we do try to make sure the tasks are still contained
4764 // with the bounds of the stack.
Wale Ogunwale1666e312016-12-16 11:27:18 -08004765 mTmpRect2.set(task.mBounds);
4766 fitWithinBounds(mTmpRect2, bounds);
4767 task.updateOverrideConfiguration(mTmpRect2);
Andrii Kulian1e32e022016-09-16 15:29:34 -07004768 } else {
4769 task.updateOverrideConfiguration(taskBounds, insetBounds);
4770 }
4771 }
4772
Andrii Kulian1779e612016-10-12 21:58:25 -07004773 mTmpConfigs.put(task.taskId, task.getOverrideConfiguration());
Andrii Kulian1e32e022016-09-16 15:29:34 -07004774 mTmpBounds.put(task.taskId, task.mBounds);
4775 if (tempTaskInsetBounds != null) {
4776 mTmpInsetBounds.put(task.taskId, tempTaskInsetBounds);
4777 }
4778 }
4779
Wale Ogunwale1666e312016-12-16 11:27:18 -08004780 mFullscreen = mWindowContainerController.resize(bounds, mTmpConfigs, mTmpBounds,
Andrii Kulian1e32e022016-09-16 15:29:34 -07004781 mTmpInsetBounds);
Wale Ogunwale1666e312016-12-16 11:27:18 -08004782 setBounds(bounds);
Andrii Kulian1e32e022016-09-16 15:29:34 -07004783 }
4784
4785
4786 /**
4787 * Adjust bounds to stay within stack bounds.
4788 *
4789 * Since bounds might be outside of stack bounds, this method tries to move the bounds in a way
4790 * that keep them unchanged, but be contained within the stack bounds.
4791 *
4792 * @param bounds Bounds to be adjusted.
4793 * @param stackBounds Bounds within which the other bounds should remain.
4794 */
4795 private static void fitWithinBounds(Rect bounds, Rect stackBounds) {
4796 if (stackBounds == null || stackBounds.contains(bounds)) {
4797 return;
4798 }
4799
4800 if (bounds.left < stackBounds.left || bounds.right > stackBounds.right) {
4801 final int maxRight = stackBounds.right
4802 - (stackBounds.width() / FIT_WITHIN_BOUNDS_DIVIDER);
4803 int horizontalDiff = stackBounds.left - bounds.left;
4804 if ((horizontalDiff < 0 && bounds.left >= maxRight)
4805 || (bounds.left + horizontalDiff >= maxRight)) {
4806 horizontalDiff = maxRight - bounds.left;
4807 }
4808 bounds.left += horizontalDiff;
4809 bounds.right += horizontalDiff;
4810 }
4811
4812 if (bounds.top < stackBounds.top || bounds.bottom > stackBounds.bottom) {
4813 final int maxBottom = stackBounds.bottom
4814 - (stackBounds.height() / FIT_WITHIN_BOUNDS_DIVIDER);
4815 int verticalDiff = stackBounds.top - bounds.top;
4816 if ((verticalDiff < 0 && bounds.top >= maxBottom)
4817 || (bounds.top + verticalDiff >= maxBottom)) {
4818 verticalDiff = maxBottom - bounds.top;
4819 }
4820 bounds.top += verticalDiff;
4821 bounds.bottom += verticalDiff;
4822 }
4823 }
4824
Craig Mautnercae015f2013-02-08 14:31:27 -08004825 boolean willActivityBeVisibleLocked(IBinder token) {
Craig Mautnerd44711d2013-02-23 11:24:36 -08004826 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
4827 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
4828 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
4829 final ActivityRecord r = activities.get(activityNdx);
4830 if (r.appToken == token) {
Craig Mautner34b73df2014-01-12 21:11:08 -08004831 return true;
Craig Mautnerd44711d2013-02-23 11:24:36 -08004832 }
4833 if (r.fullscreen && !r.finishing) {
4834 return false;
4835 }
Craig Mautnercae015f2013-02-08 14:31:27 -08004836 }
4837 }
Wale Ogunwale7d701172015-03-11 15:36:30 -07004838 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
Craig Mautner34b73df2014-01-12 21:11:08 -08004839 if (r == null) {
4840 return false;
4841 }
4842 if (r.finishing) Slog.e(TAG, "willActivityBeVisibleLocked: Returning false,"
4843 + " would have returned true for r=" + r);
4844 return !r.finishing;
Craig Mautnercae015f2013-02-08 14:31:27 -08004845 }
4846
4847 void closeSystemDialogsLocked() {
Craig Mautnerd44711d2013-02-23 11:24:36 -08004848 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
4849 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
4850 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
4851 final ActivityRecord r = activities.get(activityNdx);
4852 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Craig Mautnerd2328952013-03-05 12:46:26 -08004853 finishActivityLocked(r, Activity.RESULT_CANCELED, null, "close-sys", true);
Craig Mautnerd44711d2013-02-23 11:24:36 -08004854 }
Craig Mautnercae015f2013-02-08 14:31:27 -08004855 }
4856 }
4857 }
4858
Wale Ogunwale540e1232015-05-01 15:35:39 -07004859 boolean finishDisabledPackageActivitiesLocked(String packageName, Set<String> filterByClasses,
4860 boolean doit, boolean evenPersistent, int userId) {
Craig Mautnercae015f2013-02-08 14:31:27 -08004861 boolean didSomething = false;
4862 TaskRecord lastTask = null;
Craig Mautner9d8a30d2014-07-07 17:26:20 +00004863 ComponentName homeActivity = null;
Craig Mautner56f52db2013-02-25 10:03:01 -08004864 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
4865 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
4866 int numActivities = activities.size();
4867 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
4868 ActivityRecord r = activities.get(activityNdx);
Wale Ogunwale540e1232015-05-01 15:35:39 -07004869 final boolean sameComponent =
4870 (r.packageName.equals(packageName) && (filterByClasses == null
4871 || filterByClasses.contains(r.realActivity.getClassName())))
4872 || (packageName == null && r.userId == userId);
Craig Mautner56f52db2013-02-25 10:03:01 -08004873 if ((userId == UserHandle.USER_ALL || r.userId == userId)
Bryce Leeaf691c02017-03-20 14:20:22 -07004874 && (sameComponent || r.getTask() == lastTask)
Craig Mautner56f52db2013-02-25 10:03:01 -08004875 && (r.app == null || evenPersistent || !r.app.persistent)) {
4876 if (!doit) {
4877 if (r.finishing) {
4878 // If this activity is just finishing, then it is not
4879 // interesting as far as something to stop.
4880 continue;
4881 }
4882 return true;
Craig Mautnercae015f2013-02-08 14:31:27 -08004883 }
Craig Mautner9d8a30d2014-07-07 17:26:20 +00004884 if (r.isHomeActivity()) {
4885 if (homeActivity != null && homeActivity.equals(r.realActivity)) {
4886 Slog.i(TAG, "Skip force-stop again " + r);
4887 continue;
4888 } else {
4889 homeActivity = r.realActivity;
4890 }
4891 }
Craig Mautner56f52db2013-02-25 10:03:01 -08004892 didSomething = true;
4893 Slog.i(TAG, " Force finishing activity " + r);
Wale Ogunwale540e1232015-05-01 15:35:39 -07004894 if (sameComponent) {
Craig Mautner56f52db2013-02-25 10:03:01 -08004895 if (r.app != null) {
4896 r.app.removed = true;
4897 }
4898 r.app = null;
Craig Mautnercae015f2013-02-08 14:31:27 -08004899 }
Bryce Leeaf691c02017-03-20 14:20:22 -07004900 lastTask = r.getTask();
Craig Mautnerd94b1b42013-05-01 11:58:03 -07004901 if (finishActivityLocked(r, Activity.RESULT_CANCELED, null, "force-stop",
4902 true)) {
4903 // r has been deleted from mActivities, accommodate.
4904 --numActivities;
4905 --activityNdx;
4906 }
Craig Mautnercae015f2013-02-08 14:31:27 -08004907 }
4908 }
4909 }
4910 return didSomething;
4911 }
4912
Dianne Hackborn09233282014-04-30 11:33:59 -07004913 void getTasksLocked(List<RunningTaskInfo> list, int callingUid, boolean allowed) {
riddle_hsuddc74152015-04-07 11:30:09 +08004914 boolean focusedStack = mStackSupervisor.getFocusedStack() == this;
4915 boolean topTask = true;
Craig Mautnerc0fd8052013-09-19 11:20:17 -07004916 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
Craig Mautneraab647e2013-02-28 16:31:36 -08004917 final TaskRecord task = mTaskHistory.get(taskNdx);
riddle_hsuddc74152015-04-07 11:30:09 +08004918 if (task.getTopActivity() == null) {
4919 continue;
4920 }
Craig Mautneraab647e2013-02-28 16:31:36 -08004921 ActivityRecord r = null;
4922 ActivityRecord top = null;
Wale Ogunwale6035e012015-04-14 15:54:10 -07004923 ActivityRecord tmp;
Craig Mautneraab647e2013-02-28 16:31:36 -08004924 int numActivities = 0;
4925 int numRunning = 0;
4926 final ArrayList<ActivityRecord> activities = task.mActivities;
Dianne Hackborn885fbe52014-08-23 15:23:58 -07004927 if (!allowed && !task.isHomeTask() && task.effectiveUid != callingUid) {
Dianne Hackborn09233282014-04-30 11:33:59 -07004928 continue;
4929 }
Craig Mautneraab647e2013-02-28 16:31:36 -08004930 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
Wale Ogunwale6035e012015-04-14 15:54:10 -07004931 tmp = activities.get(activityNdx);
4932 if (tmp.finishing) {
4933 continue;
4934 }
4935 r = tmp;
Craig Mautnercae015f2013-02-08 14:31:27 -08004936
Craig Mautneraab647e2013-02-28 16:31:36 -08004937 // Initialize state for next task if needed.
4938 if (top == null || (top.state == ActivityState.INITIALIZING)) {
4939 top = r;
4940 numActivities = numRunning = 0;
Craig Mautnercae015f2013-02-08 14:31:27 -08004941 }
Craig Mautneraab647e2013-02-28 16:31:36 -08004942
4943 // Add 'r' into the current task.
4944 numActivities++;
4945 if (r.app != null && r.app.thread != null) {
4946 numRunning++;
4947 }
4948
Wale Ogunwalee23149f2015-03-06 15:39:44 -08004949 if (DEBUG_ALL) Slog.v(
Craig Mautneraab647e2013-02-28 16:31:36 -08004950 TAG, r.intent.getComponent().flattenToShortString()
Bryce Leeaf691c02017-03-20 14:20:22 -07004951 + ": task=" + r.getTask());
Craig Mautneraab647e2013-02-28 16:31:36 -08004952 }
4953
4954 RunningTaskInfo ci = new RunningTaskInfo();
4955 ci.id = task.taskId;
Filip Gruszczynskid64ef3e2015-10-27 17:58:02 -07004956 ci.stackId = mStackId;
Craig Mautneraab647e2013-02-28 16:31:36 -08004957 ci.baseActivity = r.intent.getComponent();
4958 ci.topActivity = top.intent.getComponent();
Craig Mautnerc0fd8052013-09-19 11:20:17 -07004959 ci.lastActiveTime = task.lastActiveTime;
riddle_hsuddc74152015-04-07 11:30:09 +08004960 if (focusedStack && topTask) {
4961 // Give the latest time to ensure foreground task can be sorted
4962 // at the first, because lastActiveTime of creating task is 0.
4963 ci.lastActiveTime = System.currentTimeMillis();
4964 topTask = false;
4965 }
Craig Mautnerc0fd8052013-09-19 11:20:17 -07004966
Bryce Leeaf691c02017-03-20 14:20:22 -07004967 if (top.getTask() != null) {
4968 ci.description = top.getTask().lastDescription;
Craig Mautneraab647e2013-02-28 16:31:36 -08004969 }
4970 ci.numActivities = numActivities;
4971 ci.numRunning = numRunning;
Winson Chungd3395382016-12-13 11:49:09 -08004972 ci.supportsSplitScreenMultiWindow = task.supportsSplitScreen();
Jorim Jaggi29379ec2016-04-11 23:43:42 -07004973 ci.resizeMode = task.mResizeMode;
Craig Mautneraab647e2013-02-28 16:31:36 -08004974 list.add(ci);
Craig Mautnercae015f2013-02-08 14:31:27 -08004975 }
Craig Mautnercae015f2013-02-08 14:31:27 -08004976 }
4977
Andrii Kulian21713ac2016-10-12 22:05:05 -07004978 void unhandledBackLocked() {
Craig Mautneraab647e2013-02-28 16:31:36 -08004979 final int top = mTaskHistory.size() - 1;
Wale Ogunwaleee006da2015-03-30 14:49:25 -07004980 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH, "Performing unhandledBack(): top activity at " + top);
Craig Mautneraab647e2013-02-28 16:31:36 -08004981 if (top >= 0) {
4982 final ArrayList<ActivityRecord> activities = mTaskHistory.get(top).mActivities;
4983 int activityTop = activities.size() - 1;
Dianne Hackborn354736e2016-08-22 17:00:05 -07004984 if (activityTop >= 0) {
Craig Mautneraab647e2013-02-28 16:31:36 -08004985 finishActivityLocked(activities.get(activityTop), Activity.RESULT_CANCELED, null,
4986 "unhandled-back", true);
4987 }
Craig Mautnercae015f2013-02-08 14:31:27 -08004988 }
4989 }
4990
Craig Mautner6b74cb52013-09-27 17:02:21 -07004991 /**
4992 * Reset local parameters because an app's activity died.
4993 * @param app The app of the activity that died.
Craig Mautner19091252013-10-05 00:03:53 -07004994 * @return result from removeHistoryRecordsForAppLocked.
Craig Mautner6b74cb52013-09-27 17:02:21 -07004995 */
4996 boolean handleAppDiedLocked(ProcessRecord app) {
Craig Mautnere79d42682013-04-01 19:01:53 -07004997 if (mPausingActivity != null && mPausingActivity.app == app) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07004998 if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG_PAUSE,
Craig Mautnere79d42682013-04-01 19:01:53 -07004999 "App died while pausing: " + mPausingActivity);
5000 mPausingActivity = null;
5001 }
5002 if (mLastPausedActivity != null && mLastPausedActivity.app == app) {
5003 mLastPausedActivity = null;
Craig Mautner0f922742013-08-06 08:44:42 -07005004 mLastNoHistoryActivity = null;
Craig Mautnere79d42682013-04-01 19:01:53 -07005005 }
5006
Craig Mautner19091252013-10-05 00:03:53 -07005007 return removeHistoryRecordsForAppLocked(app);
Craig Mautnere79d42682013-04-01 19:01:53 -07005008 }
5009
Craig Mautnercae015f2013-02-08 14:31:27 -08005010 void handleAppCrashLocked(ProcessRecord app) {
Craig Mautnerd44711d2013-02-23 11:24:36 -08005011 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
5012 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
5013 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
5014 final ActivityRecord r = activities.get(activityNdx);
5015 if (r.app == app) {
5016 Slog.w(TAG, " Force finishing activity "
5017 + r.intent.getComponent().flattenToShortString());
Craig Mautner8e5b1332014-07-24 13:32:37 -07005018 // Force the destroy to skip right to removal.
5019 r.app = null;
5020 finishCurrentActivityLocked(r, FINISH_IMMEDIATELY, false);
Craig Mautnerd44711d2013-02-23 11:24:36 -08005021 }
Craig Mautnercae015f2013-02-08 14:31:27 -08005022 }
5023 }
5024 }
5025
Dianne Hackborn390517b2013-05-30 15:03:32 -07005026 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07005027 boolean dumpClient, String dumpPackage, boolean needSep, String header) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07005028 boolean printed = false;
Craig Mautneraab647e2013-02-28 16:31:36 -08005029 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
5030 final TaskRecord task = mTaskHistory.get(taskNdx);
Dianne Hackborn390517b2013-05-30 15:03:32 -07005031 printed |= ActivityStackSupervisor.dumpHistoryList(fd, pw,
5032 mTaskHistory.get(taskNdx).mActivities, " ", "Hist", true, !dumpAll,
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07005033 dumpClient, dumpPackage, needSep, header,
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -07005034 " Task id #" + task.taskId + "\n" +
5035 " mFullscreen=" + task.mFullscreen + "\n" +
5036 " mBounds=" + task.mBounds + "\n" +
Andrii Kulianf66a83d2016-05-17 12:17:44 -07005037 " mMinWidth=" + task.mMinWidth + "\n" +
5038 " mMinHeight=" + task.mMinHeight + "\n" +
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -07005039 " mLastNonFullscreenBounds=" + task.mLastNonFullscreenBounds);
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07005040 if (printed) {
5041 header = null;
5042 }
Craig Mautneraab647e2013-02-28 16:31:36 -08005043 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07005044 return printed;
Craig Mautnercae015f2013-02-08 14:31:27 -08005045 }
5046
5047 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
Winson Chung6998bc42017-02-28 17:07:05 -08005048 ArrayList<ActivityRecord> activities = new ArrayList<>();
Craig Mautnercae015f2013-02-08 14:31:27 -08005049
5050 if ("all".equals(name)) {
Craig Mautneraab647e2013-02-28 16:31:36 -08005051 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
5052 activities.addAll(mTaskHistory.get(taskNdx).mActivities);
Craig Mautnercae015f2013-02-08 14:31:27 -08005053 }
5054 } else if ("top".equals(name)) {
Craig Mautneraab647e2013-02-28 16:31:36 -08005055 final int top = mTaskHistory.size() - 1;
5056 if (top >= 0) {
5057 final ArrayList<ActivityRecord> list = mTaskHistory.get(top).mActivities;
5058 int listTop = list.size() - 1;
5059 if (listTop >= 0) {
5060 activities.add(list.get(listTop));
5061 }
Craig Mautnercae015f2013-02-08 14:31:27 -08005062 }
5063 } else {
5064 ItemMatcher matcher = new ItemMatcher();
5065 matcher.build(name);
5066
Craig Mautneraab647e2013-02-28 16:31:36 -08005067 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
5068 for (ActivityRecord r1 : mTaskHistory.get(taskNdx).mActivities) {
5069 if (matcher.match(r1, r1.intent.getComponent())) {
5070 activities.add(r1);
5071 }
Craig Mautnercae015f2013-02-08 14:31:27 -08005072 }
5073 }
5074 }
5075
5076 return activities;
5077 }
5078
5079 ActivityRecord restartPackage(String packageName) {
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -07005080 ActivityRecord starting = topRunningActivityLocked();
Craig Mautnercae015f2013-02-08 14:31:27 -08005081
5082 // All activities that came from the package must be
5083 // restarted as if there was a config change.
Craig Mautneraab647e2013-02-28 16:31:36 -08005084 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
5085 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
5086 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
5087 final ActivityRecord a = activities.get(activityNdx);
5088 if (a.info.packageName.equals(packageName)) {
5089 a.forceNewConfig = true;
5090 if (starting != null && a == starting && a.visible) {
5091 a.startFreezingScreenLocked(starting.app,
Filip Gruszczynski3c2db1d12016-01-06 17:39:14 -08005092 CONFIG_SCREEN_LAYOUT);
Craig Mautneraab647e2013-02-28 16:31:36 -08005093 }
Craig Mautnercae015f2013-02-08 14:31:27 -08005094 }
5095 }
5096 }
5097
5098 return starting;
5099 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -08005100
Wale Ogunwale000957c2015-04-03 08:19:12 -07005101 /**
5102 * Removes the input task from this stack.
5103 * @param task to remove.
5104 * @param reason for removal.
Wale Ogunwale06579d62016-04-30 15:29:06 -07005105 * @param mode task removal mode. Either {@link #REMOVE_TASK_MODE_DESTROYING},
5106 * {@link #REMOVE_TASK_MODE_MOVING}, {@link #REMOVE_TASK_MODE_MOVING_TO_TOP}.
Wale Ogunwale000957c2015-04-03 08:19:12 -07005107 */
Wale Ogunwale06579d62016-04-30 15:29:06 -07005108 void removeTask(TaskRecord task, String reason, int mode) {
Bryce Leeaf691c02017-03-20 14:20:22 -07005109 for (ActivityRecord record : task.mActivities) {
5110 onActivityRemovedFromStack(record);
Craig Mautner04a0ea62014-01-13 12:51:26 -08005111 }
5112
Craig Mautnerae7ecab2013-09-18 11:48:14 -07005113 final int taskNdx = mTaskHistory.indexOf(task);
5114 final int topTaskNdx = mTaskHistory.size() - 1;
Craig Mautner84984fa2014-06-19 11:19:20 -07005115 if (task.isOverHomeStack() && taskNdx < topTaskNdx) {
5116 final TaskRecord nextTask = mTaskHistory.get(taskNdx + 1);
Winson Chung83471632016-12-13 11:02:12 -08005117 if (!nextTask.isOverHomeStack() && !nextTask.isOverAssistantStack()) {
Craig Mautner84984fa2014-06-19 11:19:20 -07005118 nextTask.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
5119 }
Craig Mautnerae7ecab2013-09-18 11:48:14 -07005120 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07005121 mTaskHistory.remove(task);
Winson Chungabb433b2017-03-24 09:35:42 -07005122 removeActivitiesFromLRUListLocked(task);
Craig Mautner21d24a22014-04-23 11:45:37 -07005123 updateTaskMovement(task, true);
Craig Mautner41db4a72014-05-07 17:20:56 -07005124
Wale Ogunwale06579d62016-04-30 15:29:06 -07005125 if (mode == REMOVE_TASK_MODE_DESTROYING && task.mActivities.isEmpty()) {
Amith Yamasani0af6fa72016-01-17 15:36:19 -08005126 // TODO: VI what about activity?
Craig Mautner41db4a72014-05-07 17:20:56 -07005127 final boolean isVoiceSession = task.voiceSession != null;
5128 if (isVoiceSession) {
5129 try {
5130 task.voiceSession.taskFinished(task.intent, task.taskId);
5131 } catch (RemoteException e) {
5132 }
Dianne Hackbornc03c9162014-05-02 10:45:59 -07005133 }
Craig Mautner41db4a72014-05-07 17:20:56 -07005134 if (task.autoRemoveFromRecents() || isVoiceSession) {
5135 // Task creator asked to remove this when done, or this task was a voice
5136 // interaction, so it should not remain on the recent tasks list.
Wale Ogunwalec82f2f52014-12-09 09:32:50 -08005137 mRecentTasks.remove(task);
Winson Chung740c3ac2014-11-12 16:14:38 -08005138 task.removedFromRecents();
Craig Mautner41db4a72014-05-07 17:20:56 -07005139 }
Bryce Lee840c5662017-04-13 10:02:51 -07005140
5141 task.removeWindowContainer();
Dianne Hackborn91097de2014-04-04 18:02:06 -07005142 }
Craig Mautner04a0ea62014-01-13 12:51:26 -08005143
5144 if (mTaskHistory.isEmpty()) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07005145 if (DEBUG_STACK) Slog.i(TAG_STACK, "removeTask: removing stack=" + this);
Wale Ogunwale06579d62016-04-30 15:29:06 -07005146 // We only need to adjust focused stack if this stack is in focus and we are not in the
5147 // process of moving the task to the top of the stack that will be focused.
5148 if (isOnHomeDisplay() && mode != REMOVE_TASK_MODE_MOVING_TO_TOP
5149 && mStackSupervisor.isFocusedStack(this)) {
Wale Ogunwaled697cea2015-02-20 17:19:49 -08005150 String myReason = reason + " leftTaskHistoryEmpty";
Matthew Ngae1ff4f2016-11-10 15:49:14 -08005151 if (mFullscreen || !adjustFocusToNextFocusableStackLocked(myReason)) {
Wale Ogunwale925d0d12015-09-23 15:40:07 -07005152 mStackSupervisor.moveHomeStackToFront(myReason);
Wale Ogunwaled697cea2015-02-20 17:19:49 -08005153 }
Craig Mautner04a0ea62014-01-13 12:51:26 -08005154 }
Craig Mautner593a4e62014-01-15 17:55:51 -08005155 if (mStacks != null) {
5156 mStacks.remove(this);
5157 mStacks.add(0, this);
5158 }
Matthew Ngae1ff4f2016-11-10 15:49:14 -08005159 if (!isHomeOrRecentsStack()) {
Andrii Kulian94e82d9b02017-07-13 15:33:06 -07005160 remove();
Wale Ogunwale49853bf2015-02-23 09:24:42 -08005161 }
Craig Mautner04a0ea62014-01-13 12:51:26 -08005162 }
Wale Ogunwale04f4d6b2015-03-11 09:23:25 -07005163
Andrii Kulian02b7a832016-10-06 23:11:56 -07005164 task.setStack(null);
Winson Chungc81c0ce2017-03-17 12:27:30 -07005165
5166 // Notify if a task from the pinned stack is being removed (or moved depending on the mode)
5167 if (mStackId == PINNED_STACK_ID) {
5168 mService.mTaskChangeNotificationController.notifyActivityUnpinned();
5169 }
Craig Mautner0247fc82013-02-28 14:32:06 -08005170 }
5171
Dianne Hackborn91097de2014-04-04 18:02:06 -07005172 TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent,
5173 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
Wale Ogunwale72919d22016-12-08 18:58:50 -08005174 boolean toTop, int type) {
Craig Mautner21d24a22014-04-23 11:45:37 -07005175 TaskRecord task = new TaskRecord(mService, taskId, info, intent, voiceSession,
Wale Ogunwale72919d22016-12-08 18:58:50 -08005176 voiceInteractor, type);
Chong Zhang0fa656b2015-08-31 15:17:21 -07005177 // add the task to stack first, mTaskPositioner might need the stack association
Wale Ogunwale5f986092015-12-04 15:35:38 -08005178 addTask(task, toTop, "createTaskRecord");
Jorim Jaggife762342016-10-13 14:33:27 +02005179 final boolean isLockscreenShown =
5180 mService.mStackSupervisor.mKeyguardController.isKeyguardShowing();
Andrii Kulian2e751b82016-03-16 16:59:32 -07005181 if (!layoutTaskInStack(task, info.windowLayout) && mBounds != null && task.isResizeable()
Chong Zhang75b37202015-12-04 14:16:36 -08005182 && !isLockscreenShown) {
Wale Ogunwalea6e902e2015-09-21 18:37:15 -07005183 task.updateOverrideConfiguration(mBounds);
Filip Gruszczynskie5390e72015-08-18 16:39:00 -07005184 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -08005185 task.createWindowContainer(toTop, (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0);
Craig Mautner5d9c7be2013-02-15 14:02:56 -08005186 return task;
5187 }
Craig Mautnerc00204b2013-03-05 15:02:14 -08005188
Andrii Kulian2e751b82016-03-16 16:59:32 -07005189 boolean layoutTaskInStack(TaskRecord task, ActivityInfo.WindowLayout windowLayout) {
Wale Ogunwale935e5022015-11-10 12:36:10 -08005190 if (mTaskPositioner == null) {
5191 return false;
5192 }
Andrii Kulian2e751b82016-03-16 16:59:32 -07005193 mTaskPositioner.updateDefaultBounds(task, mTaskHistory, windowLayout);
Wale Ogunwale935e5022015-11-10 12:36:10 -08005194 return true;
5195 }
5196
Craig Mautnerc00204b2013-03-05 15:02:14 -08005197 ArrayList<TaskRecord> getAllTasks() {
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -08005198 return new ArrayList<>(mTaskHistory);
Craig Mautnerc00204b2013-03-05 15:02:14 -08005199 }
5200
Wale Ogunwale5f986092015-12-04 15:35:38 -08005201 void addTask(final TaskRecord task, final boolean toTop, String reason) {
Winson Chung5af42fc2017-03-24 17:11:33 -07005202 addTask(task, toTop ? MAX_VALUE : 0, true /* schedulePictureInPictureModeChange */, reason);
Wale Ogunwalec5cc3012017-01-13 13:26:16 -08005203 if (toTop) {
5204 // TODO: figure-out a way to remove this call.
Wale Ogunwale1666e312016-12-16 11:27:18 -08005205 mWindowContainerController.positionChildAtTop(task.getWindowContainerController(),
5206 true /* includingParents */);
Wale Ogunwalec5cc3012017-01-13 13:26:16 -08005207 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -08005208 }
5209
Wale Ogunwalec5cc3012017-01-13 13:26:16 -08005210 // TODO: This shouldn't allow automatic reparenting. Remove the call to preAddTask and deal
5211 // with the fall-out...
Winson Chung5af42fc2017-03-24 17:11:33 -07005212 void addTask(final TaskRecord task, int position, boolean schedulePictureInPictureModeChange,
5213 String reason) {
Wale Ogunwalec5cc3012017-01-13 13:26:16 -08005214 // TODO: Is this remove really needed? Need to look into the call path for the other addTask
5215 mTaskHistory.remove(task);
5216 position = getAdjustedPositionForTask(task, position, null /* starting */);
5217 final boolean toTop = position >= mTaskHistory.size();
Wale Ogunwale06579d62016-04-30 15:29:06 -07005218 final ActivityStack prevStack = preAddTask(task, reason, toTop);
Wale Ogunwale5f986092015-12-04 15:35:38 -08005219
Andrii Kulianfb1bf692017-01-17 11:17:34 -08005220 mTaskHistory.add(position, task);
Andrii Kulian02b7a832016-10-06 23:11:56 -07005221 task.setStack(this);
Wale Ogunwalec5cc3012017-01-13 13:26:16 -08005222
Craig Mautnerc00204b2013-03-05 15:02:14 -08005223 if (toTop) {
Wale Ogunwalec5cc3012017-01-13 13:26:16 -08005224 updateTaskReturnToForTopInsertion(task);
Craig Mautnerc00204b2013-03-05 15:02:14 -08005225 }
Wale Ogunwalec5cc3012017-01-13 13:26:16 -08005226
Wale Ogunwalec5cc3012017-01-13 13:26:16 -08005227 updateTaskMovement(task, toTop);
5228
Winson Chung5af42fc2017-03-24 17:11:33 -07005229 postAddTask(task, prevStack, schedulePictureInPictureModeChange);
Craig Mautnerc00204b2013-03-05 15:02:14 -08005230 }
5231
Wale Ogunwalec5cc3012017-01-13 13:26:16 -08005232 void positionChildAt(TaskRecord task, int index) {
5233
5234 if (task.getStack() != this) {
5235 throw new IllegalArgumentException("AS.positionChildAt: task=" + task
5236 + " is not a child of stack=" + this + " current parent=" + task.getStack());
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -08005237 }
5238
5239 task.updateOverrideConfigurationForStack(this);
5240
Jorim Jaggi023da532016-04-20 22:42:32 -07005241 final ActivityRecord topRunningActivity = task.topRunningActivityLocked();
Andrii Kulian02b7a832016-10-06 23:11:56 -07005242 final boolean wasResumed = topRunningActivity == task.getStack().mResumedActivity;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -08005243 insertTaskAtPosition(task, index);
Andrii Kulianfb1bf692017-01-17 11:17:34 -08005244 task.setStack(this);
Winson Chung5af42fc2017-03-24 17:11:33 -07005245 postAddTask(task, null /* prevStack */, true /* schedulePictureInPictureModeChange */);
Wale Ogunwalec5cc3012017-01-13 13:26:16 -08005246
Jorim Jaggi023da532016-04-20 22:42:32 -07005247 if (wasResumed) {
5248 if (mResumedActivity != null) {
5249 Log.wtf(TAG, "mResumedActivity was already set when moving mResumedActivity from"
5250 + " other stack to this stack mResumedActivity=" + mResumedActivity
5251 + " other mResumedActivity=" + topRunningActivity);
5252 }
5253 mResumedActivity = topRunningActivity;
5254 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -08005255
5256 // The task might have already been running and its visibility needs to be synchronized with
5257 // the visibility of the stack / windows.
5258 ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5259 mStackSupervisor.resumeFocusedStackTopActivityLocked();
Wale Ogunwale5f986092015-12-04 15:35:38 -08005260 }
5261
Wale Ogunwale06579d62016-04-30 15:29:06 -07005262 private ActivityStack preAddTask(TaskRecord task, String reason, boolean toTop) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07005263 final ActivityStack prevStack = task.getStack();
Wale Ogunwale5f986092015-12-04 15:35:38 -08005264 if (prevStack != null && prevStack != this) {
Wale Ogunwale06579d62016-04-30 15:29:06 -07005265 prevStack.removeTask(task, reason,
5266 toTop ? REMOVE_TASK_MODE_MOVING_TO_TOP : REMOVE_TASK_MODE_MOVING);
Wale Ogunwale5f986092015-12-04 15:35:38 -08005267 }
5268 return prevStack;
5269 }
5270
Winson Chung5af42fc2017-03-24 17:11:33 -07005271 /**
5272 * @param schedulePictureInPictureModeChange specifies whether or not to schedule the PiP mode
5273 * change. Callers may set this to false if they are explicitly scheduling PiP mode
5274 * changes themselves, like during the PiP animation
5275 */
5276 private void postAddTask(TaskRecord task, ActivityStack prevStack,
5277 boolean schedulePictureInPictureModeChange) {
5278 if (schedulePictureInPictureModeChange && prevStack != null) {
5279 mStackSupervisor.scheduleUpdatePictureInPictureModeIfNeeded(task, prevStack);
Wale Ogunwale5f986092015-12-04 15:35:38 -08005280 } else if (task.voiceSession != null) {
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -07005281 try {
5282 task.voiceSession.taskStarted(task.intent, task.taskId);
5283 } catch (RemoteException e) {
5284 }
5285 }
5286 }
5287
Winson Chungc2baac02017-01-11 13:34:47 -08005288 void moveToFrontAndResumeStateIfNeeded(ActivityRecord r, boolean moveToFront, boolean setResume,
5289 boolean setPause, String reason) {
Wale Ogunwaled046a012015-12-24 13:05:59 -08005290 if (!moveToFront) {
5291 return;
Wale Ogunwale079a0042015-10-24 11:44:07 -07005292 }
Wale Ogunwaled046a012015-12-24 13:05:59 -08005293
5294 // If the activity owns the last resumed activity, transfer that together,
5295 // so that we don't resume the same activity again in the new stack.
5296 // Apps may depend on onResume()/onPause() being called in pairs.
5297 if (setResume) {
5298 mResumedActivity = r;
Winson Chungabb433b2017-03-24 09:35:42 -07005299 updateLRUListLocked(r);
Wale Ogunwaled046a012015-12-24 13:05:59 -08005300 }
Winson Chungc2baac02017-01-11 13:34:47 -08005301 // If the activity was previously pausing, then ensure we transfer that as well
5302 if (setPause) {
5303 mPausingActivity = r;
Winson Chung4dabf232017-01-25 13:25:22 -08005304 schedulePauseTimeout(r);
Winson Chungc2baac02017-01-11 13:34:47 -08005305 }
Wale Ogunwaled046a012015-12-24 13:05:59 -08005306 // Move the stack in which we are placing the activity to the front. The call will also
5307 // make sure the activity focus is set.
5308 moveToFront(reason);
Wale Ogunwale079a0042015-10-24 11:44:07 -07005309 }
5310
Craig Mautnerc00204b2013-03-05 15:02:14 -08005311 public int getStackId() {
5312 return mStackId;
5313 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07005314
5315 @Override
5316 public String toString() {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07005317 return "ActivityStack{" + Integer.toHexString(System.identityHashCode(this))
5318 + " stackId=" + mStackId + ", " + mTaskHistory.size() + " tasks}";
Craig Mautnerde4ef022013-04-07 19:01:33 -07005319 }
Wale Ogunwale60454db2015-01-23 16:05:07 -08005320
Craig Mautner15df08a2015-04-01 12:17:18 -07005321 void onLockTaskPackagesUpdatedLocked() {
5322 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
5323 mTaskHistory.get(taskNdx).setLockTaskAuth();
5324 }
5325 }
skuhne@google.com1b974dc2016-12-09 13:41:29 -08005326
5327 void executeAppTransition(ActivityOptions options) {
5328 mWindowManager.executeAppTransition();
5329 mNoAnimActivities.clear();
5330 ActivityOptions.abort(options);
5331 }
David Stevens9440dc82017-03-16 19:00:20 -07005332
5333 boolean shouldSleepActivities() {
5334 final ActivityStackSupervisor.ActivityDisplay display = getDisplay();
5335 return display != null ? display.isSleeping() : mService.isSleepingLocked();
5336 }
5337
5338 boolean shouldSleepOrShutDownActivities() {
5339 return shouldSleepActivities() || mService.isShuttingDownLocked();
5340 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005341}