blob: c4e0db46f4dad84f82b265ca716aa23c71716fd4 [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
Wale Ogunwale59507092018-10-29 09:00:30 -070017package com.android.server.wm;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070018
Wale Ogunwale30e441d2017-11-09 08:28:45 -080019import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SPLIT_SCREEN;
Matthew Nga51dcaa2018-05-07 15:36:06 -070020import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
Matthew Ng99b3cdc2018-05-01 14:24:38 -070021import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
Wale Ogunwale30e441d2017-11-09 08:28:45 -080022import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -070023import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
24import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
Wale Ogunwale44f036f2017-09-29 05:09:09 -070025import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
Wale Ogunwale68278562017-09-23 17:13:55 -070026import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
Wale Ogunwale2b07da82017-11-08 14:52:40 -080027import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
Wale Ogunwale9dcf9462017-09-19 15:13:01 -070028import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Wale Ogunwale68278562017-09-23 17:13:55 -070029import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Wale Ogunwalef75962a2017-08-23 14:58:04 -070030import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Wale Ogunwale44f036f2017-09-29 05:09:09 -070031import static android.app.WindowConfiguration.activityTypeToString;
32import static android.app.WindowConfiguration.windowingModeToString;
Filip Gruszczynski3c2db1d12016-01-06 17:39:14 -080033import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
Wale Ogunwale5658e4b2016-02-12 12:22:19 -080034import static android.content.pm.ActivityInfo.FLAG_RESUME_WHILE_PAUSING;
Wale Ogunwale6dfdfd62015-04-15 12:01:38 -070035import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
Wale Ogunwalef5d1e352016-09-22 08:34:42 -070036import static android.view.Display.DEFAULT_DISPLAY;
Andrii Kulian7211d2e2017-01-27 15:58:05 -080037import static android.view.Display.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
Andrii Kulian94e82d9b02017-07-13 15:33:06 -070038import static android.view.Display.INVALID_DISPLAY;
Louis Chang7d0037c2018-08-13 12:42:06 +080039import static android.view.WindowManager.TRANSIT_ACTIVITY_CLOSE;
40import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
41import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE;
42import static android.view.WindowManager.TRANSIT_NONE;
Issei Suzukicac2a502019-04-16 16:52:50 +020043import static android.view.WindowManager.TRANSIT_SHOW_SINGLE_TASK_DISPLAY;
Louis Chang7d0037c2018-08-13 12:42:06 +080044import static android.view.WindowManager.TRANSIT_TASK_CLOSE;
45import static android.view.WindowManager.TRANSIT_TASK_OPEN;
46import static android.view.WindowManager.TRANSIT_TASK_OPEN_BEHIND;
47import static android.view.WindowManager.TRANSIT_TASK_TO_BACK;
48import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
Winson Chung1dbc8112017-09-28 18:05:31 -070049
Evan Roskye747c3e2018-10-30 20:06:41 -070050import static com.android.server.am.ActivityStackProto.BOUNDS;
51import static com.android.server.am.ActivityStackProto.CONFIGURATION_CONTAINER;
52import static com.android.server.am.ActivityStackProto.DISPLAY_ID;
53import static com.android.server.am.ActivityStackProto.FULLSCREEN;
54import static com.android.server.am.ActivityStackProto.ID;
55import static com.android.server.am.ActivityStackProto.RESUMED_ACTIVITY;
56import static com.android.server.am.ActivityStackProto.TASKS;
Wale Ogunwale59507092018-10-29 09:00:30 -070057import static com.android.server.wm.ActivityDisplay.POSITION_BOTTOM;
58import static com.android.server.wm.ActivityDisplay.POSITION_TOP;
59import static com.android.server.wm.ActivityStack.ActivityState.DESTROYED;
60import static com.android.server.wm.ActivityStack.ActivityState.DESTROYING;
61import static com.android.server.wm.ActivityStack.ActivityState.FINISHING;
62import static com.android.server.wm.ActivityStack.ActivityState.PAUSED;
63import static com.android.server.wm.ActivityStack.ActivityState.PAUSING;
64import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
65import static com.android.server.wm.ActivityStack.ActivityState.STOPPED;
66import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
Wale Ogunwale59507092018-10-29 09:00:30 -070067import static com.android.server.wm.ActivityStackSupervisor.PAUSE_IMMEDIATELY;
68import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
69import static com.android.server.wm.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
Garfield Tan347bd602018-12-21 15:11:12 -080070import static com.android.server.wm.ActivityStackSupervisor.dumpHistoryList;
71import static com.android.server.wm.ActivityStackSupervisor.printThisActivity;
Wale Ogunwale59507092018-10-29 09:00:30 -070072import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ADD_REMOVE;
73import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL;
74import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_APP;
75import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP;
76import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONTAINERS;
77import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PAUSE;
78import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RELEASE;
79import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS;
80import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SAVED_STATE;
81import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STACK;
82import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES;
83import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
84import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
85import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TRANSITION;
86import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_USER_LEAVING;
87import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_VISIBILITY;
88import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_ADD_REMOVE;
89import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_APP;
90import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CLEANUP;
91import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONTAINERS;
92import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_PAUSE;
93import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RELEASE;
94import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RESULTS;
95import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SAVED_STATE;
96import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STACK;
97import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STATES;
98import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
99import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS;
100import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TRANSITION;
101import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_USER_LEAVING;
102import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_VISIBILITY;
103import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
104import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
105import static com.android.server.wm.ActivityTaskManagerService.H.FIRST_ACTIVITY_STACK_MSG;
106import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE;
107import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800108import static com.android.server.wm.RootActivityContainer.FindTaskResult;
Louis Changf2835df2018-10-17 15:14:45 +0800109
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800110import static java.lang.Integer.MAX_VALUE;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700111
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800112import android.annotation.IntDef;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700113import android.app.Activity;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700114import android.app.ActivityManager;
Wale Ogunwale53783742018-09-16 10:21:51 -0700115import android.app.ActivityManagerInternal;
Dianne Hackborn7a2195c2012-03-19 17:38:00 -0700116import android.app.ActivityOptions;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700117import android.app.AppGlobals;
Craig Mautner05d6272ba2013-02-11 09:39:27 -0800118import android.app.IActivityController;
Yunfan Chen279f5582018-12-12 15:24:50 -0800119import android.app.RemoteAction;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700120import android.app.ResultInfo;
Winson Chung61c9e5a2017-10-11 10:39:32 -0700121import android.app.WindowConfiguration.ActivityType;
122import android.app.WindowConfiguration.WindowingMode;
Andrii Kulian446e8242017-10-26 15:17:29 -0700123import android.app.servertransaction.ActivityResultItem;
Andrii Kulian9956d892018-02-14 13:48:56 -0800124import android.app.servertransaction.ClientTransaction;
Andrii Kulian446e8242017-10-26 15:17:29 -0700125import android.app.servertransaction.DestroyActivityItem;
Louis Chang7d0037c2018-08-13 12:42:06 +0800126import android.app.servertransaction.NewIntentItem;
Andrii Kulian446e8242017-10-26 15:17:29 -0700127import android.app.servertransaction.PauseActivityItem;
128import android.app.servertransaction.ResumeActivityItem;
129import android.app.servertransaction.StopActivityItem;
Louis Chang7d0037c2018-08-13 12:42:06 +0800130import android.app.servertransaction.WindowVisibilityItem;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700131import android.content.ComponentName;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700132import android.content.Intent;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700133import android.content.pm.ActivityInfo;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800134import android.content.pm.ApplicationInfo;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700135import android.content.res.Configuration;
Jorim Jaggiaf80db42016-04-07 19:19:15 -0700136import android.graphics.Rect;
Santos Cordon73ff7d82013-03-06 17:24:11 -0800137import android.net.Uri;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700138import android.os.Binder;
Craig Mautner329f4122013-11-07 09:10:42 -0800139import android.os.Debug;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700140import android.os.Handler;
141import android.os.IBinder;
Zoran Marcetaf958b322012-08-09 20:27:12 +0900142import android.os.Looper;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700143import android.os.Message;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700144import android.os.RemoteException;
145import android.os.SystemClock;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700146import android.os.UserHandle;
Craig Mautner4c07d022014-06-11 17:12:59 -0700147import android.service.voice.IVoiceInteractionSession;
Jorim Jaggiaf80db42016-04-07 19:19:15 -0700148import android.util.ArraySet;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700149import android.util.EventLog;
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800150import android.util.IntArray;
Jorim Jaggi023da532016-04-20 22:42:32 -0700151import android.util.Log;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700152import android.util.Slog;
Steven Timotius4346f0a2017-09-12 11:07:21 -0700153import android.util.proto.ProtoOutputStream;
Craig Mautner59c00972012-07-30 12:10:24 -0700154import android.view.Display;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700155
Andreas Gampea36dc622018-02-05 17:19:22 -0800156import com.android.internal.annotations.GuardedBy;
Bryce Lee840c5662017-04-13 10:02:51 -0700157import com.android.internal.annotations.VisibleForTesting;
Jorim Jaggiaf80db42016-04-07 19:19:15 -0700158import com.android.internal.app.IVoiceInteractor;
Wale Ogunwale53783742018-09-16 10:21:51 -0700159import com.android.internal.util.function.pooled.PooledLambda;
Jorim Jaggiaf80db42016-04-07 19:19:15 -0700160import com.android.server.Watchdog;
Wale Ogunwale59507092018-10-29 09:00:30 -0700161import com.android.server.am.ActivityManagerService;
Jorim Jaggiaf80db42016-04-07 19:19:15 -0700162import com.android.server.am.ActivityManagerService.ItemMatcher;
Wale Ogunwale59507092018-10-29 09:00:30 -0700163import com.android.server.am.AppTimeTracker;
164import com.android.server.am.EventLogTags;
165import com.android.server.am.PendingIntentRecord;
Jorim Jaggiaf80db42016-04-07 19:19:15 -0700166
Craig Mautnercae015f2013-02-08 14:31:27 -0800167import java.io.FileDescriptor;
Craig Mautnercae015f2013-02-08 14:31:27 -0800168import java.io.PrintWriter;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700169import java.lang.ref.WeakReference;
170import java.util.ArrayList;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700171import java.util.List;
Kenny Roote6585b32013-12-13 12:00:26 -0800172import java.util.Objects;
Wale Ogunwale540e1232015-05-01 15:35:39 -0700173import java.util.Set;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700174
175/**
176 * State and management of a single stack of activities.
177 */
Yunfan Chen279f5582018-12-12 15:24:50 -0800178class ActivityStack extends ConfigurationContainer {
Wale Ogunwale98875612018-10-12 07:53:02 -0700179 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStack" : TAG_ATM;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -0700180 private static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE;
181 private static final String TAG_APP = TAG + POSTFIX_APP;
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800182 private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -0700183 private static final String TAG_CONTAINERS = TAG + POSTFIX_CONTAINERS;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700184 private static final String TAG_PAUSE = TAG + POSTFIX_PAUSE;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -0700185 private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700186 private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -0700187 private static final String TAG_SAVED_STATE = TAG + POSTFIX_SAVED_STATE;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700188 private static final String TAG_STACK = TAG + POSTFIX_STACK;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -0700189 private static final String TAG_STATES = TAG + POSTFIX_STATES;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700190 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
191 private static final String TAG_TASKS = TAG + POSTFIX_TASKS;
192 private static final String TAG_TRANSITION = TAG + POSTFIX_TRANSITION;
193 private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING;
194 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
Wale Ogunwale3ab9a272015-03-16 09:55:45 -0700195
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -0700196 // Ticks during which we check progress while waiting for an app to launch.
197 static final int LAUNCH_TICK = 500;
198
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700199 // How long we wait until giving up on the last activity to pause. This
200 // is short because it directly impacts the responsiveness of starting the
201 // next activity.
Andrii Kulian21713ac2016-10-12 22:05:05 -0700202 private static final int PAUSE_TIMEOUT = 500;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700203
Dianne Hackborn162bc0e2012-04-09 14:06:16 -0700204 // How long we wait for the activity to tell us it has stopped before
205 // giving up. This is a good amount of time because we really need this
Robert Carr3406d462018-03-15 16:19:07 -0700206 // from the application in order to get its saved state. Once the stop
207 // is complete we may start destroying client resources triggering
208 // crashes if the UI thread was hung. We put this timeout one second behind
209 // the ANR timeout so these situations will generate ANR instead of
210 // Surface lost or other errors.
211 private static final int STOP_TIMEOUT = 11 * 1000;
Dianne Hackborn162bc0e2012-04-09 14:06:16 -0700212
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700213 // How long we wait until giving up on an activity telling us it has
214 // finished destroying itself.
Andrii Kulian21713ac2016-10-12 22:05:05 -0700215 private static final int DESTROY_TIMEOUT = 10 * 1000;
Craig Mautnerd74f7d72013-02-26 13:41:02 -0800216
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700217 // Set to false to disable the preview that is shown while a new activity
218 // is being started.
Andrii Kulian21713ac2016-10-12 22:05:05 -0700219 private static final boolean SHOW_APP_STARTING_PREVIEW = true;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800220
Craig Mautner5eda9b32013-07-02 11:58:16 -0700221 // How long to wait for all background Activities to redraw following a call to
222 // convertToTranslucent().
Andrii Kulian21713ac2016-10-12 22:05:05 -0700223 private static final long TRANSLUCENT_CONVERSION_TIMEOUT = 2000;
Craig Mautner5eda9b32013-07-02 11:58:16 -0700224
Filip Gruszczynskief2f72b2015-12-04 14:52:25 -0800225 // How many activities have to be scheduled to stop to force a stop pass.
226 private static final int MAX_STOPPING_TO_FORCE = 3;
227
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800228 @IntDef(prefix = {"STACK_VISIBILITY"}, value = {
229 STACK_VISIBILITY_VISIBLE,
230 STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
231 STACK_VISIBILITY_INVISIBLE,
232 })
233 @interface StackVisibility {}
234
235 /** Stack is visible. No other stacks on top that fully or partially occlude it. */
236 static final int STACK_VISIBILITY_VISIBLE = 0;
237
238 /** Stack is partially occluded by other translucent stack(s) on top of it. */
239 static final int STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT = 1;
240
241 /** Stack is completely invisible. */
242 static final int STACK_VISIBILITY_INVISIBLE = 2;
243
Andrii Kulian1779e612016-10-12 21:58:25 -0700244 @Override
245 protected int getChildCount() {
246 return mTaskHistory.size();
247 }
248
249 @Override
Garfield Tanb5cc09f2018-09-28 10:06:52 -0700250 protected TaskRecord getChildAt(int index) {
Andrii Kulian1779e612016-10-12 21:58:25 -0700251 return mTaskHistory.get(index);
252 }
253
254 @Override
Evan Roskyc5abbd82018-10-05 16:02:19 -0700255 protected ActivityDisplay getParent() {
Andrii Kulian94e82d9b02017-07-13 15:33:06 -0700256 return getDisplay();
Andrii Kulian1779e612016-10-12 21:58:25 -0700257 }
258
Evan Roskyc5abbd82018-10-05 16:02:19 -0700259 void setParent(ActivityDisplay parent) {
260 ActivityDisplay current = getParent();
261 if (current != parent) {
262 mDisplayId = parent.mDisplayId;
263 onParentChanged();
264 }
265 }
266
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800267 @Override
Wale Ogunwale98d62312017-07-12 09:24:56 -0700268 protected void onParentChanged() {
Evan Roskyc5abbd82018-10-05 16:02:19 -0700269 ActivityDisplay display = getParent();
270 if (display != null) {
271 // Rotations are relative to the display. This means if there are 2 displays rotated
272 // differently (eg. 2 monitors with one landscape and one portrait), moving a stack
273 // from one to the other could look like a rotation change. To prevent this
274 // apparent rotation change (and corresponding bounds rotation), pretend like our
275 // current rotation is already the same as the new display.
276 // Note, if ActivityStack or related logic ever gets nested, this logic will need
277 // to move to onConfigurationChanged.
278 getConfiguration().windowConfiguration.setRotation(
279 display.getWindowConfiguration().getRotation());
280 }
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800281 super.onParentChanged();
Evan Roskyc5abbd82018-10-05 16:02:19 -0700282 if (display != null && inSplitScreenPrimaryWindowingMode()) {
283 // If we created a docked stack we want to resize it so it resizes all other stacks
284 // in the system.
Riddle Hsud1069732019-05-09 17:04:31 +0800285 getStackDockedModeBounds(null /* dockedBounds */, null /* currentTempTaskBounds */,
286 mTmpRect /* outStackBounds */, mTmpRect2 /* outTempTaskBounds */);
287 mStackSupervisor.resizeDockedStackLocked(getRequestedOverrideBounds(), mTmpRect,
Evan Roskydfe3da72018-10-26 17:21:06 -0700288 mTmpRect2, null, null, PRESERVE_WINDOWS);
Evan Roskyc5abbd82018-10-05 16:02:19 -0700289 }
Wale Ogunwaled32da472018-11-16 07:19:28 -0800290 mRootActivityContainer.updateUIDsPresentOnDisplay();
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800291 }
292
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700293 enum ActivityState {
294 INITIALIZING,
295 RESUMED,
296 PAUSING,
297 PAUSED,
298 STOPPING,
299 STOPPED,
300 FINISHING,
301 DESTROYING,
Riddle Hsu7b766fd2019-01-28 21:14:59 +0800302 DESTROYED,
303 RESTARTING_PROCESS
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700304 }
305
Bryce Lee840c5662017-04-13 10:02:51 -0700306 @VisibleForTesting
Wale Ogunwale06579d62016-04-30 15:29:06 -0700307 /* The various modes for the method {@link #removeTask}. */
308 // Task is being completely removed from all stacks in the system.
Bryce Lee840c5662017-04-13 10:02:51 -0700309 protected static final int REMOVE_TASK_MODE_DESTROYING = 0;
Wale Ogunwale06579d62016-04-30 15:29:06 -0700310 // Task is being removed from this stack so we can add it to another stack. In the case we are
311 // moving we don't want to perform some operations on the task like removing it from window
312 // manager or recents.
313 static final int REMOVE_TASK_MODE_MOVING = 1;
314 // Similar to {@link #REMOVE_TASK_MODE_MOVING} and the task will be added to the top of its new
315 // stack and the new stack will be on top of all stacks.
Wale Ogunwale56d8d162017-05-30 11:12:20 -0700316 static final int REMOVE_TASK_MODE_MOVING_TO_TOP = 2;
Wale Ogunwale06579d62016-04-30 15:29:06 -0700317
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700318 final ActivityTaskManagerService mService;
Yunfan Chen279f5582018-12-12 15:24:50 -0800319 final WindowManagerService mWindowManager;
Craig Mautnerd74f7d72013-02-26 13:41:02 -0800320
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700321 /**
322 * The back history of all previous (and possibly still
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800323 * running) activities. It contains #TaskRecord objects.
324 */
Todd Kennedy39bfee52016-02-24 10:28:21 -0800325 private final ArrayList<TaskRecord> mTaskHistory = new ArrayList<>();
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800326
327 /**
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700328 * List of running activities, sorted by recent usage.
329 * The first entry in the list is the least recently used.
330 * It contains HistoryRecord objects.
331 */
Garfield Tan347bd602018-12-21 15:11:12 -0800332 private final ArrayList<ActivityRecord> mLRUActivities = new ArrayList<>();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700333
334 /**
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700335 * When we are in the process of pausing an activity, before starting the
336 * next one, this variable holds the activity that is currently being paused.
337 */
Dianne Hackborn621e2fe2012-02-16 17:07:33 -0800338 ActivityRecord mPausingActivity = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700339
340 /**
341 * This is the last activity that we put into the paused state. This is
342 * used to determine if we need to do an activity transition while sleeping,
343 * when we normally hold the top activity paused.
344 */
345 ActivityRecord mLastPausedActivity = null;
346
347 /**
Craig Mautner0f922742013-08-06 08:44:42 -0700348 * Activities that specify No History must be removed once the user navigates away from them.
349 * If the device goes to sleep with such an activity in the paused state then we save it here
350 * and finish it later if another activity replaces it on wakeup.
351 */
352 ActivityRecord mLastNoHistoryActivity = null;
353
354 /**
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700355 * Current activity that is resumed, or null if there is none.
356 */
357 ActivityRecord mResumedActivity = null;
Craig Mautnerd74f7d72013-02-26 13:41:02 -0800358
Craig Mautner5eda9b32013-07-02 11:58:16 -0700359 // The topmost Activity passed to convertToTranslucent(). When non-null it means we are
360 // waiting for all Activities in mUndrawnActivitiesBelowTopTranslucent to be removed as they
361 // are drawn. When the last member of mUndrawnActivitiesBelowTopTranslucent is removed the
362 // Activity in mTranslucentActivityWaiting is notified via
363 // Activity.onTranslucentConversionComplete(false). If a timeout occurs prior to the last
364 // background activity being drawn then the same call will be made with a true value.
365 ActivityRecord mTranslucentActivityWaiting = null;
Andrii Kulian21713ac2016-10-12 22:05:05 -0700366 ArrayList<ActivityRecord> mUndrawnActivitiesBelowTopTranslucent = new ArrayList<>();
Craig Mautner5eda9b32013-07-02 11:58:16 -0700367
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700368 /**
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700369 * Set when we know we are going to be calling updateConfiguration()
370 * soon, so want to skip intermediate config checks.
371 */
372 boolean mConfigWillChange;
373
Winson Chung47900652017-04-06 18:44:25 -0700374 /**
375 * When set, will force the stack to report as invisible.
376 */
377 boolean mForceHidden = false;
378
Andrii Kulian6b321512019-01-23 06:37:00 +0000379 /**
380 * Used to keep resumeTopActivityUncheckedLocked() from being entered recursively
381 */
382 boolean mInResumeTopActivity = false;
383
Andrii Kulian21713ac2016-10-12 22:05:05 -0700384 private boolean mUpdateBoundsDeferred;
385 private boolean mUpdateBoundsDeferredCalled;
Evan Rosky1ac84462018-11-13 11:25:30 -0800386 private boolean mUpdateDisplayedBoundsDeferredCalled;
Andrii Kulian21713ac2016-10-12 22:05:05 -0700387 private final Rect mDeferredBounds = new Rect();
Evan Rosky1ac84462018-11-13 11:25:30 -0800388 private final Rect mDeferredDisplayedBounds = new Rect();
Jorim Jaggi192086e2016-03-11 17:17:03 +0100389
Craig Mautner858d8a62013-04-23 17:08:34 -0700390 int mCurrentUser;
Amith Yamasani742a6712011-05-04 14:49:28 -0700391
Craig Mautnerc00204b2013-03-05 15:02:14 -0800392 final int mStackId;
Craig Mautnere0a38842013-12-16 16:14:02 -0800393 /** The attached Display's unique identifier, or -1 if detached */
394 int mDisplayId;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800395
Evan Rosky10475742018-09-05 19:02:48 -0700396 /** Stores the override windowing-mode from before a transient mode change (eg. split) */
397 private int mRestoreOverrideWindowingMode = WINDOWING_MODE_UNDEFINED;
398
Evan Roskyc5abbd82018-10-05 16:02:19 -0700399 private final Rect mTmpRect = new Rect();
Wale Ogunwale1666e312016-12-16 11:27:18 -0800400 private final Rect mTmpRect2 = new Rect();
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800401 private final ActivityOptions mTmpOptions = ActivityOptions.makeBasic();
Andrii Kulian1e32e022016-09-16 15:29:34 -0700402
Bryce Leefbd263b42018-03-07 10:33:55 -0800403 /** List for processing through a set of activities */
404 private final ArrayList<ActivityRecord> mTmpActivities = new ArrayList<>();
405
Craig Mautner27084302013-03-25 08:05:25 -0700406 /** Run all ActivityStacks through this */
Winson Chung5af42fc2017-03-24 17:11:33 -0700407 protected final ActivityStackSupervisor mStackSupervisor;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800408 protected final RootActivityContainer mRootActivityContainer;
Craig Mautner27084302013-03-25 08:05:25 -0700409
Jorim Jaggife762342016-10-13 14:33:27 +0200410 private boolean mTopActivityOccludesKeyguard;
411 private ActivityRecord mTopDismissingKeyguardActivity;
412
Wale Ogunwale98875612018-10-12 07:53:02 -0700413 static final int PAUSE_TIMEOUT_MSG = FIRST_ACTIVITY_STACK_MSG + 1;
414 static final int DESTROY_TIMEOUT_MSG = FIRST_ACTIVITY_STACK_MSG + 2;
415 static final int LAUNCH_TICK_MSG = FIRST_ACTIVITY_STACK_MSG + 3;
416 static final int STOP_TIMEOUT_MSG = FIRST_ACTIVITY_STACK_MSG + 4;
417 static final int DESTROY_ACTIVITIES_MSG = FIRST_ACTIVITY_STACK_MSG + 5;
418 static final int TRANSLUCENT_TIMEOUT_MSG = FIRST_ACTIVITY_STACK_MSG + 6;
Dianne Hackborn755c8bf2012-05-07 15:06:09 -0700419
Yunfan Chen279f5582018-12-12 15:24:50 -0800420 // TODO: remove after unification.
421 TaskStack mTaskStack;
422
Andrii Kulian21713ac2016-10-12 22:05:05 -0700423 private static class ScheduleDestroyArgs {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700424 final WindowProcessController mOwner;
Dianne Hackborn755c8bf2012-05-07 15:06:09 -0700425 final String mReason;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700426 ScheduleDestroyArgs(WindowProcessController owner, String reason) {
Dianne Hackborn755c8bf2012-05-07 15:06:09 -0700427 mOwner = owner;
Dianne Hackborn755c8bf2012-05-07 15:06:09 -0700428 mReason = reason;
429 }
430 }
431
Zoran Marcetaf958b322012-08-09 20:27:12 +0900432 final Handler mHandler;
433
Andrii Kulian21713ac2016-10-12 22:05:05 -0700434 private class ActivityStackHandler extends Handler {
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800435
Craig Mautnerc8143c62013-09-03 12:15:57 -0700436 ActivityStackHandler(Looper looper) {
Zoran Marcetaf958b322012-08-09 20:27:12 +0900437 super(looper);
438 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700439
Zoran Marcetaf958b322012-08-09 20:27:12 +0900440 @Override
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700441 public void handleMessage(Message msg) {
442 switch (msg.what) {
443 case PAUSE_TIMEOUT_MSG: {
Dianne Hackbornbe707852011-11-11 14:32:10 -0800444 ActivityRecord r = (ActivityRecord)msg.obj;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700445 // We don't at this point know if the activity is fullscreen,
446 // so we need to be conservative and assume it isn't.
Dianne Hackbornbe707852011-11-11 14:32:10 -0800447 Slog.w(TAG, "Activity pause timeout for " + r);
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700448 synchronized (mService.mGlobalLock) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700449 if (r.hasProcess()) {
450 mService.logAppTooSlow(r.app, r.pauseTime, "pausing " + r);
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -0700451 }
Dianne Hackborna4e102e2014-09-04 22:52:27 -0700452 activityPausedLocked(r.appToken, true);
Craig Mautnerd2328952013-03-05 12:46:26 -0800453 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700454 } break;
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -0700455 case LAUNCH_TICK_MSG: {
456 ActivityRecord r = (ActivityRecord)msg.obj;
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700457 synchronized (mService.mGlobalLock) {
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -0700458 if (r.continueLaunchTickingLocked()) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700459 mService.logAppTooSlow(r.app, r.launchTickTime, "launching " + r);
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -0700460 }
461 }
462 } break;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700463 case DESTROY_TIMEOUT_MSG: {
Dianne Hackbornbe707852011-11-11 14:32:10 -0800464 ActivityRecord r = (ActivityRecord)msg.obj;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700465 // We don't at this point know if the activity is fullscreen,
466 // so we need to be conservative and assume it isn't.
Dianne Hackbornbe707852011-11-11 14:32:10 -0800467 Slog.w(TAG, "Activity destroy timeout for " + r);
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700468 synchronized (mService.mGlobalLock) {
Craig Mautner299f9602015-01-26 09:47:33 -0800469 activityDestroyedLocked(r != null ? r.appToken : null, "destroyTimeout");
Craig Mautnerd2328952013-03-05 12:46:26 -0800470 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700471 } break;
Dianne Hackborn162bc0e2012-04-09 14:06:16 -0700472 case STOP_TIMEOUT_MSG: {
473 ActivityRecord r = (ActivityRecord)msg.obj;
474 // We don't at this point know if the activity is fullscreen,
475 // so we need to be conservative and assume it isn't.
476 Slog.w(TAG, "Activity stop timeout for " + r);
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700477 synchronized (mService.mGlobalLock) {
Dianne Hackborn162bc0e2012-04-09 14:06:16 -0700478 if (r.isInHistory()) {
Andrii Kulian21713ac2016-10-12 22:05:05 -0700479 r.activityStoppedLocked(null /* icicle */,
480 null /* persistentState */, null /* description */);
Dianne Hackborn162bc0e2012-04-09 14:06:16 -0700481 }
482 }
483 } break;
Dianne Hackborn755c8bf2012-05-07 15:06:09 -0700484 case DESTROY_ACTIVITIES_MSG: {
485 ScheduleDestroyArgs args = (ScheduleDestroyArgs)msg.obj;
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700486 synchronized (mService.mGlobalLock) {
Craig Mautneree2e45a2014-06-27 12:10:03 -0700487 destroyActivitiesLocked(args.mOwner, args.mReason);
Dianne Hackborn755c8bf2012-05-07 15:06:09 -0700488 }
Craig Mautner5eda9b32013-07-02 11:58:16 -0700489 } break;
490 case TRANSLUCENT_TIMEOUT_MSG: {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700491 synchronized (mService.mGlobalLock) {
Craig Mautner5eda9b32013-07-02 11:58:16 -0700492 notifyActivityDrawnLocked(null);
493 }
494 } break;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700495 }
496 }
Craig Mautner4b71aa12012-12-27 17:20:01 -0800497 }
498
Craig Mautner34b73df2014-01-12 21:11:08 -0800499 int numActivities() {
Craig Mautner000f0022013-02-26 15:04:29 -0800500 int count = 0;
501 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
502 count += mTaskHistory.get(taskNdx).mActivities.size();
503 }
504 return count;
505 }
506
Wale Ogunwale9dcf9462017-09-19 15:13:01 -0700507 ActivityStack(ActivityDisplay display, int stackId, ActivityStackSupervisor supervisor,
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700508 int windowingMode, int activityType, boolean onTop) {
Andrii Kulian94e82d9b02017-07-13 15:33:06 -0700509 mStackSupervisor = supervisor;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700510 mService = supervisor.mService;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800511 mRootActivityContainer = mService.mRootActivityContainer;
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700512 mHandler = new ActivityStackHandler(supervisor.mLooper);
Craig Mautner4a1cb222013-12-04 16:14:06 -0800513 mWindowManager = mService.mWindowManager;
Andrii Kulian94e82d9b02017-07-13 15:33:06 -0700514 mStackId = stackId;
Wale Ogunwale86b74462018-07-02 08:42:43 -0700515 mCurrentUser = mService.mAmInternal.getCurrentUserId();
Andrii Kulian2fcc4512018-01-25 16:39:27 -0800516 // Set display id before setting activity and window type to make sure it won't affect
517 // stacks on a wrong display.
518 mDisplayId = display.mDisplayId;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700519 setActivityType(activityType);
Yunfan Chen279f5582018-12-12 15:24:50 -0800520 createTaskStack(display.mDisplayId, onTop, mTmpRect2);
Evan Roskyc5abbd82018-10-05 16:02:19 -0700521 setWindowingMode(windowingMode, false /* animate */, false /* showRecents */,
522 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */,
523 true /* creating */);
524 display.addChild(this, onTop ? POSITION_TOP : POSITION_BOTTOM);
Wale Ogunwale1666e312016-12-16 11:27:18 -0800525 }
526
Yunfan Chen279f5582018-12-12 15:24:50 -0800527 void createTaskStack(int displayId, boolean onTop, Rect outBounds) {
528 final DisplayContent dc = mWindowManager.mRoot.getDisplayContent(displayId);
529 if (dc == null) {
530 throw new IllegalArgumentException("Trying to add stackId=" + mStackId
531 + " to unknown displayId=" + displayId);
532 }
533 mTaskStack = new TaskStack(mWindowManager, mStackId, this);
534 dc.setStackOnDisplay(mStackId, onTop, mTaskStack);
535 if (mTaskStack.matchParentBounds()) {
536 outBounds.setEmpty();
537 } else {
538 mTaskStack.getRawBounds(outBounds);
539 }
Winson Chung55893332017-02-17 17:13:10 -0800540 }
541
Yunfan Chen279f5582018-12-12 15:24:50 -0800542 TaskStack getTaskStack() {
543 return mTaskStack;
Filip Gruszczynskie5390e72015-08-18 16:39:00 -0700544 }
545
Bryce Leec4ab62a2018-03-05 14:19:26 -0800546 /**
547 * This should be called when an activity in a child task changes state. This should only
548 * be called from
549 * {@link TaskRecord#onActivityStateChanged(ActivityRecord, ActivityState, String)}.
550 * @param record The {@link ActivityRecord} whose state has changed.
551 * @param state The new state.
552 * @param reason The reason for the change.
553 */
554 void onActivityStateChanged(ActivityRecord record, ActivityState state, String reason) {
555 if (record == mResumedActivity && state != RESUMED) {
Bryce Lee84730a02018-04-03 14:10:04 -0700556 setResumedActivity(null, reason + " - onActivityStateChanged");
Bryce Leec4ab62a2018-03-05 14:19:26 -0800557 }
558
559 if (state == RESUMED) {
560 if (DEBUG_STACK) Slog.v(TAG_STACK, "set resumed activity to:" + record + " reason:"
561 + reason);
Bryce Lee84730a02018-04-03 14:10:04 -0700562 setResumedActivity(record, reason + " - onActivityStateChanged");
Wale Ogunwaled32da472018-11-16 07:19:28 -0800563 if (record == mRootActivityContainer.getTopResumedActivity()) {
Riddle Hsu3026e8d2018-08-03 15:50:53 +0800564 // TODO(b/111361570): Support multiple focused apps in WM
Andrii Kulianab132ee2018-07-24 22:10:21 +0800565 mService.setResumedActivityUncheckLocked(record, reason);
566 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800567 mStackSupervisor.mRecentTasks.add(record.getTaskRecord());
Bryce Leec4ab62a2018-03-05 14:19:26 -0800568 }
569 }
570
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -0700571 @Override
572 public void onConfigurationChanged(Configuration newParentConfig) {
573 final int prevWindowingMode = getWindowingMode();
Kazuki Takise048e2662018-06-27 17:05:11 +0900574 final boolean prevIsAlwaysOnTop = isAlwaysOnTop();
Evan Roskyc5abbd82018-10-05 16:02:19 -0700575 final int prevRotation = getWindowConfiguration().getRotation();
576 final int prevDensity = getConfiguration().densityDpi;
577 final int prevScreenW = getConfiguration().screenWidthDp;
578 final int prevScreenH = getConfiguration().screenHeightDp;
Riddle Hsud1069732019-05-09 17:04:31 +0800579 final Rect newBounds = mTmpRect;
580 // Initialize the new bounds by previous bounds as the input and output for calculating
581 // override bounds in pinned (pip) or split-screen mode.
582 getBounds(newBounds);
Evan Roskye747c3e2018-10-30 20:06:41 -0700583
584 super.onConfigurationChanged(newParentConfig);
Riddle Hsud1069732019-05-09 17:04:31 +0800585 final ActivityDisplay display = getDisplay();
586 if (display == null || getTaskStack() == null) {
Yunfan Chen279f5582018-12-12 15:24:50 -0800587 return;
588 }
Evan Roskyc5abbd82018-10-05 16:02:19 -0700589
Riddle Hsud1069732019-05-09 17:04:31 +0800590 final boolean windowingModeChanged = prevWindowingMode != getWindowingMode();
591 final int overrideWindowingMode = getRequestedOverrideWindowingMode();
Evan Roskyc5abbd82018-10-05 16:02:19 -0700592 // Update bounds if applicable
593 boolean hasNewOverrideBounds = false;
594 // Use override windowing mode to prevent extra bounds changes if inheriting the mode.
Riddle Hsud1069732019-05-09 17:04:31 +0800595 if (overrideWindowingMode == WINDOWING_MODE_PINNED) {
Evan Roskyc5abbd82018-10-05 16:02:19 -0700596 // Pinned calculation already includes rotation
Riddle Hsud1069732019-05-09 17:04:31 +0800597 hasNewOverrideBounds = getTaskStack().calculatePinnedBoundsForConfigChange(newBounds);
598 } else if (!matchParentBounds()) {
599 // If the parent (display) has rotated, rotate our bounds to best-fit where their
600 // bounds were on the pre-rotated display.
Evan Roskyc5abbd82018-10-05 16:02:19 -0700601 final int newRotation = getWindowConfiguration().getRotation();
Riddle Hsud1069732019-05-09 17:04:31 +0800602 final boolean rotationChanged = prevRotation != newRotation;
603 if (rotationChanged) {
604 display.mDisplayContent.rotateBounds(
605 newParentConfig.windowConfiguration.getBounds(), prevRotation, newRotation,
606 newBounds);
607 hasNewOverrideBounds = true;
608 }
Evan Roskyc5abbd82018-10-05 16:02:19 -0700609
Riddle Hsud1069732019-05-09 17:04:31 +0800610 // Use override windowing mode to prevent extra bounds changes if inheriting the mode.
611 if (overrideWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
612 || overrideWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) {
Evan Roskyc5abbd82018-10-05 16:02:19 -0700613 // If entering split screen or if something about the available split area changes,
614 // recalculate the split windows to match the new configuration.
Riddle Hsud1069732019-05-09 17:04:31 +0800615 if (rotationChanged || windowingModeChanged
Evan Roskyc5abbd82018-10-05 16:02:19 -0700616 || prevDensity != getConfiguration().densityDpi
Evan Roskyc5abbd82018-10-05 16:02:19 -0700617 || prevScreenW != getConfiguration().screenWidthDp
618 || prevScreenH != getConfiguration().screenHeightDp) {
Riddle Hsud1069732019-05-09 17:04:31 +0800619 getTaskStack().calculateDockedBoundsForConfigChange(newParentConfig, newBounds);
620 hasNewOverrideBounds = true;
Evan Roskyc5abbd82018-10-05 16:02:19 -0700621 }
622 }
623 }
Riddle Hsud1069732019-05-09 17:04:31 +0800624
625 if (windowingModeChanged) {
Evan Roskyc5abbd82018-10-05 16:02:19 -0700626 // Use override windowing mode to prevent extra bounds changes if inheriting the mode.
Riddle Hsud1069732019-05-09 17:04:31 +0800627 if (overrideWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
628 getStackDockedModeBounds(null /* dockedBounds */, null /* currentTempTaskBounds */,
629 newBounds /* outStackBounds */, mTmpRect2 /* outTempTaskBounds */);
Evan Roskyc5abbd82018-10-05 16:02:19 -0700630 // immediately resize so docked bounds are available in onSplitScreenModeActivated
Evan Rosky1ac84462018-11-13 11:25:30 -0800631 setTaskDisplayedBounds(null);
Riddle Hsud1069732019-05-09 17:04:31 +0800632 setTaskBounds(newBounds);
633 setBounds(newBounds);
634 newBounds.set(newBounds);
635 } else if (overrideWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) {
Evan Roskyc5abbd82018-10-05 16:02:19 -0700636 Rect dockedBounds = display.getSplitScreenPrimaryStack().getBounds();
Wale Ogunwale3a256e62018-12-06 14:41:18 -0800637 final boolean isMinimizedDock =
Riddle Hsud1069732019-05-09 17:04:31 +0800638 display.mDisplayContent.getDockedDividerController().isMinimizedDock();
Evan Roskyc5abbd82018-10-05 16:02:19 -0700639 if (isMinimizedDock) {
640 TaskRecord topTask = display.getSplitScreenPrimaryStack().topTask();
641 if (topTask != null) {
642 dockedBounds = topTask.getBounds();
643 }
644 }
Riddle Hsud1069732019-05-09 17:04:31 +0800645 getStackDockedModeBounds(dockedBounds, null /* currentTempTaskBounds */,
646 newBounds /* outStackBounds */, mTmpRect2 /* outTempTaskBounds */);
Evan Roskyc5abbd82018-10-05 16:02:19 -0700647 hasNewOverrideBounds = true;
648 }
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -0700649 display.onStackWindowingModeChanged(this);
650 }
Evan Roskyc5abbd82018-10-05 16:02:19 -0700651 if (hasNewOverrideBounds) {
Riddle Hsud1069732019-05-09 17:04:31 +0800652 // Note the resizeStack may enter onConfigurationChanged recursively, so we make a copy
653 // of the temporary bounds (newBounds is mTmpRect) to avoid it being modified.
654 mRootActivityContainer.resizeStack(this, new Rect(newBounds), null /* tempTaskBounds */,
655 null /* tempTaskInsetBounds */, PRESERVE_WINDOWS,
Evan Roskyc5abbd82018-10-05 16:02:19 -0700656 true /* allowResizeInDockedMode */, true /* deferResume */);
Evan Roskye747c3e2018-10-30 20:06:41 -0700657 }
Kazuki Takise048e2662018-06-27 17:05:11 +0900658 if (prevIsAlwaysOnTop != isAlwaysOnTop()) {
659 // Since always on top is only on when the stack is freeform or pinned, the state
660 // can be toggled when the windowing mode changes. We must make sure the stack is
661 // placed properly when always on top state changes.
Riddle Hsu57831b52018-07-27 00:31:48 +0800662 display.positionChildAtTop(this, false /* includingParents */);
Kazuki Takise048e2662018-06-27 17:05:11 +0900663 }
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -0700664 }
665
Wale Ogunwaleab5de372017-10-18 06:46:31 -0700666 @Override
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800667 public void setWindowingMode(int windowingMode) {
Winson Chung3e36f822018-01-16 12:06:04 -0800668 setWindowingMode(windowingMode, false /* animate */, false /* showRecents */,
Evan Roskyc5abbd82018-10-05 16:02:19 -0700669 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */,
670 false /* creating */);
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800671 }
672
Evan Rosky10475742018-09-05 19:02:48 -0700673 /**
674 * A transient windowing mode is one which activities enter into temporarily. Examples of this
675 * are Split window modes and pip. Non-transient modes are modes that displays can adopt.
676 *
677 * @param windowingMode the windowingMode to test for transient-ness.
678 * @return {@code true} if the windowing mode is transient, {@code false} otherwise.
679 */
680 private static boolean isTransientWindowingMode(int windowingMode) {
681 // TODO(b/114842032): add PIP if/when it uses mode transitions instead of task reparenting
682 return windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
683 || windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
684 }
685
686 /**
687 * Specialization of {@link #setWindowingMode(int)} for this subclass.
688 *
689 * @param preferredWindowingMode the preferred windowing mode. This may not be honored depending
690 * on the state of things. For example, WINDOWING_MODE_UNDEFINED will resolve to the
691 * previous non-transient mode if this stack is currently in a transient mode.
692 * @param animate Can be used to prevent animation.
693 * @param showRecents Controls whether recents is shown on the other side of a split while
694 * entering split mode.
695 * @param enteringSplitScreenMode {@code true} if entering split mode.
696 * @param deferEnsuringVisibility Whether visibility updates are deferred. This is set when
697 * many operations (which can effect visibility) are being performed in bulk.
Evan Roskyc5abbd82018-10-05 16:02:19 -0700698 * @param creating {@code true} if this is being run during ActivityStack construction.
Evan Rosky10475742018-09-05 19:02:48 -0700699 */
Wale Ogunwaledf262f52017-12-07 18:17:12 -0800700 void setWindowingMode(int preferredWindowingMode, boolean animate, boolean showRecents,
Evan Roskyc5abbd82018-10-05 16:02:19 -0700701 boolean enteringSplitScreenMode, boolean deferEnsuringVisibility, boolean creating) {
Tiger Huang6dcbee62019-02-20 21:45:55 +0800702 mWindowManager.inSurfaceTransaction(() -> setWindowingModeInSurfaceTransaction(
703 preferredWindowingMode, animate, showRecents, enteringSplitScreenMode,
704 deferEnsuringVisibility, creating));
705 }
706
707 private void setWindowingModeInSurfaceTransaction(int preferredWindowingMode, boolean animate,
708 boolean showRecents, boolean enteringSplitScreenMode, boolean deferEnsuringVisibility,
709 boolean creating) {
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800710 final int currentMode = getWindowingMode();
Evan Roskydfe3da72018-10-26 17:21:06 -0700711 final int currentOverrideMode = getRequestedOverrideWindowingMode();
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800712 final ActivityDisplay display = getDisplay();
713 final TaskRecord topTask = topTask();
714 final ActivityStack splitScreenStack = display.getSplitScreenPrimaryStack();
Evan Rosky9ba524e2018-01-03 16:27:56 -0800715 int windowingMode = preferredWindowingMode;
Evan Rosky10475742018-09-05 19:02:48 -0700716 if (preferredWindowingMode == WINDOWING_MODE_UNDEFINED
717 && isTransientWindowingMode(currentMode)) {
718 // Leaving a transient mode. Interpret UNDEFINED as "restore"
719 windowingMode = mRestoreOverrideWindowingMode;
720 }
721 mTmpOptions.setLaunchWindowingMode(windowingMode);
722
Wale Ogunwale1dbc5c82017-12-08 08:12:20 -0800723 // Need to make sure windowing mode is supported. If we in the process of creating the stack
724 // no need to resolve the windowing mode again as it is already resolved to the right mode.
Evan Rosky9ba524e2018-01-03 16:27:56 -0800725 if (!creating) {
726 windowingMode = display.validateWindowingMode(windowingMode,
727 null /* ActivityRecord */, topTask, getActivityType());
728 }
729 if (splitScreenStack == this
730 && windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) {
731 // Resolution to split-screen secondary for the primary split-screen stack means
Evan Rosky10475742018-09-05 19:02:48 -0700732 // we want to leave split-screen mode.
733 windowingMode = mRestoreOverrideWindowingMode;
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800734 }
735
Wale Ogunwaleac36e4d2017-11-29 13:30:26 -0800736 final boolean alreadyInSplitScreenMode = display.hasSplitScreenPrimaryStack();
737
Wale Ogunwale1dbc5c82017-12-08 08:12:20 -0800738 // Don't send non-resizeable notifications if the windowing mode changed was a side effect
739 // of us entering split-screen mode.
740 final boolean sendNonResizeableNotification = !enteringSplitScreenMode;
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800741 // Take any required action due to us not supporting the preferred windowing mode.
Wale Ogunwale1dbc5c82017-12-08 08:12:20 -0800742 if (alreadyInSplitScreenMode && windowingMode == WINDOWING_MODE_FULLSCREEN
743 && sendNonResizeableNotification && isActivityTypeStandardOrUndefined()) {
744 final boolean preferredSplitScreen =
745 preferredWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
746 || preferredWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
747 if (preferredSplitScreen || creating) {
748 // Looks like we can't launch in split screen mode or the stack we are launching
749 // doesn't support split-screen mode, go ahead an dismiss split-screen and display a
750 // warning toast about it.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700751 mService.getTaskChangeNotificationController().notifyActivityDismissingDockedStack();
Evan Roskyc5abbd82018-10-05 16:02:19 -0700752 final ActivityStack primarySplitStack = display.getSplitScreenPrimaryStack();
Tiger Huang6dcbee62019-02-20 21:45:55 +0800753 primarySplitStack.setWindowingModeInSurfaceTransaction(WINDOWING_MODE_UNDEFINED,
Andrii Kulian9da138a2018-04-24 17:12:44 -0700754 false /* animate */, false /* showRecents */,
Evan Roskyc5abbd82018-10-05 16:02:19 -0700755 false /* enteringSplitScreenMode */, true /* deferEnsuringVisibility */,
756 primarySplitStack == this ? creating : false);
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800757 }
758 }
759
760 if (currentMode == windowingMode) {
Evan Rosky10475742018-09-05 19:02:48 -0700761 // You are already in the window mode, so we can skip most of the work below. However,
762 // it's possible that we have inherited the current windowing mode from a parent. So,
763 // fulfill this method's contract by setting the override mode directly.
Evan Roskydfe3da72018-10-26 17:21:06 -0700764 getRequestedOverrideConfiguration().windowConfiguration.setWindowingMode(windowingMode);
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800765 return;
766 }
767
768 final WindowManagerService wm = mService.mWindowManager;
769 final ActivityRecord topActivity = getTopActivity();
770
Evan Rosky10475742018-09-05 19:02:48 -0700771 // For now, assume that the Stack's windowing mode is what will actually be used
772 // by it's activities. In the future, there may be situations where this doesn't
773 // happen; so at that point, this message will need to handle that.
774 int likelyResolvedMode = windowingMode;
775 if (windowingMode == WINDOWING_MODE_UNDEFINED) {
776 final ConfigurationContainer parent = getParent();
777 likelyResolvedMode = parent != null ? parent.getWindowingMode()
778 : WINDOWING_MODE_FULLSCREEN;
779 }
780 if (sendNonResizeableNotification && likelyResolvedMode != WINDOWING_MODE_FULLSCREEN
Wale Ogunwaledf262f52017-12-07 18:17:12 -0800781 && topActivity != null && topActivity.isNonResizableOrForcedResizable()
782 && !topActivity.noDisplay) {
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800783 // Inform the user that they are starting an app that may not work correctly in
784 // multi-window mode.
785 final String packageName = topActivity.appInfo.packageName;
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700786 mService.getTaskChangeNotificationController().notifyActivityForcedResizable(
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800787 topTask.taskId, FORCED_RESIZEABLE_REASON_SPLIT_SCREEN, packageName);
788 }
789
790 wm.deferSurfaceLayout();
791 try {
792 if (!animate && topActivity != null) {
Jorim Jaggifa9ed962018-01-25 00:16:49 +0100793 mStackSupervisor.mNoAnimActivities.add(topActivity);
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800794 }
795 super.setWindowingMode(windowingMode);
Evan Rosky7d0705f2018-07-30 12:30:13 -0700796 // setWindowingMode triggers an onConfigurationChanged cascade which can result in a
797 // different resolved windowing mode (usually when preferredWindowingMode is UNDEFINED).
Evan Rosky9ba524e2018-01-03 16:27:56 -0800798 windowingMode = getWindowingMode();
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800799
Wale Ogunwale1dbc5c82017-12-08 08:12:20 -0800800 if (creating) {
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800801 // Nothing else to do if we don't have a window container yet. E.g. call from ctor.
802 return;
803 }
804
805 if (windowingMode == WINDOWING_MODE_PINNED || currentMode == WINDOWING_MODE_PINNED) {
806 // TODO: Need to remove use of PinnedActivityStack for this to be supported.
807 // NOTE: Need to ASS.scheduleUpdatePictureInPictureModeIfNeeded() in
808 // setWindowModeUnchecked() when this support is added. See TaskRecord.reparent()
809 throw new IllegalArgumentException(
810 "Changing pinned windowing mode not currently supported");
811 }
812
813 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY && splitScreenStack != null) {
814 // We already have a split-screen stack in this display, so just move the tasks over.
815 // TODO: Figure-out how to do all the stuff in
816 // AMS.setTaskWindowingModeSplitScreenPrimary
817 throw new IllegalArgumentException("Setting primary split-screen windowing mode"
818 + " while there is already one isn't currently supported");
819 //return;
820 }
Evan Rosky10475742018-09-05 19:02:48 -0700821 if (isTransientWindowingMode(windowingMode) && !isTransientWindowingMode(currentMode)) {
822 mRestoreOverrideWindowingMode = currentOverrideMode;
823 }
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800824
825 mTmpRect2.setEmpty();
826 if (windowingMode != WINDOWING_MODE_FULLSCREEN) {
Yunfan Chen279f5582018-12-12 15:24:50 -0800827 if (mTaskStack.matchParentBounds()) {
828 mTmpRect2.setEmpty();
829 } else {
830 mTaskStack.getRawBounds(mTmpRect2);
831 }
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800832 }
833
Evan Roskydfe3da72018-10-26 17:21:06 -0700834 if (!Objects.equals(getRequestedOverrideBounds(), mTmpRect2)) {
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800835 resize(mTmpRect2, null /* tempTaskBounds */, null /* tempTaskInsetBounds */);
836 }
837 } finally {
Wale Ogunwalec59b4f62017-11-30 11:05:43 -0800838 if (showRecents && !alreadyInSplitScreenMode && mDisplayId == DEFAULT_DISPLAY
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800839 && windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
840 // Make sure recents stack exist when creating a dock stack as it normally needs to
841 // be on the other side of the docked stack and we make visibility decisions based
842 // on that.
843 // TODO: This is only here to help out with the case where recents stack doesn't
844 // exist yet. For that case the initial size of the split-screen stack will be the
845 // the one where the home stack is visible since recents isn't visible yet, but the
846 // divider will be off. I think we should just make the initial bounds that of home
847 // so that the divider matches and remove this logic.
Winson Chungc1674272018-02-21 10:15:17 -0800848 // TODO: This is currently only called when entering split-screen while in another
849 // task, and from the tests
Matthew Ng30307122018-04-13 11:36:34 -0700850 // TODO (b/78247419): Check if launcher and overview are same then move home stack
851 // instead of recents stack. Then fix the rotation animation from fullscreen to
852 // minimized mode
Wale Ogunwale1dbc5c82017-12-08 08:12:20 -0800853 final ActivityStack recentStack = display.getOrCreateStack(
854 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_RECENTS,
855 true /* onTop */);
856 recentStack.moveToFront("setWindowingMode");
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800857 // If task moved to docked stack - show recents if needed.
Winson Chungdff7a732017-12-11 12:17:06 -0800858 mService.mWindowManager.showRecentApps();
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800859 }
860 wm.continueSurfaceLayout();
861 }
862
Andrii Kulian9da138a2018-04-24 17:12:44 -0700863 if (!deferEnsuringVisibility) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800864 mRootActivityContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS);
865 mRootActivityContainer.resumeFocusedStacksTopActivities();
Wale Ogunwale1dbc5c82017-12-08 08:12:20 -0800866 }
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800867 }
868
869 @Override
Wale Ogunwaleab5de372017-10-18 06:46:31 -0700870 public boolean isCompatible(int windowingMode, int activityType) {
871 // TODO: Should we just move this to ConfigurationContainer?
872 if (activityType == ACTIVITY_TYPE_UNDEFINED) {
873 // Undefined activity types end up in a standard stack once the stack is created on a
874 // display, so they should be considered compatible.
875 activityType = ACTIVITY_TYPE_STANDARD;
876 }
Wale Ogunwaleab5de372017-10-18 06:46:31 -0700877 return super.isCompatible(windowingMode, activityType);
878 }
879
Andrii Kulian839def92016-11-02 10:58:58 -0700880 /** Adds the stack to specified display and calls WindowManager to do the same. */
Riddle Hsu402b4402018-11-06 17:23:15 +0800881 void reparent(ActivityDisplay activityDisplay, boolean onTop, boolean displayRemoved) {
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700882 // TODO: We should probably resolve the windowing mode for the stack on the new display here
883 // so that it end up in a compatible mode in the new display. e.g. split-screen secondary.
Wale Ogunwale1666e312016-12-16 11:27:18 -0800884 removeFromDisplay();
Winson Chungf34c6022018-01-25 09:44:30 -0800885 // Reparent the window container before we try to update the position when adding it to
886 // the new display below
Wale Ogunwale1666e312016-12-16 11:27:18 -0800887 mTmpRect2.setEmpty();
Yunfan Chen279f5582018-12-12 15:24:50 -0800888 if (mTaskStack == null) {
889 // TODO: Remove after unification.
890 Log.w(TAG, "Task stack is not valid when reparenting.");
891 } else {
892 mTaskStack.reparent(activityDisplay.mDisplayId, mTmpRect2, onTop);
893 }
Evan Roskyc5abbd82018-10-05 16:02:19 -0700894 setBounds(mTmpRect2.isEmpty() ? null : mTmpRect2);
895 activityDisplay.addChild(this, onTop ? POSITION_TOP : POSITION_BOTTOM);
Riddle Hsu402b4402018-11-06 17:23:15 +0800896 if (!displayRemoved) {
897 postReparent();
898 }
899 }
900
901 /** Resume next focusable stack after reparenting to another display. */
902 void postReparent() {
Wale Ogunwale66e16852017-10-19 13:35:52 -0700903 adjustFocusToNextFocusableStack("reparent", true /* allowFocusSelf */);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800904 mRootActivityContainer.resumeFocusedStacksTopActivities();
Andrii Kulian51c1b672017-04-07 18:39:32 -0700905 // Update visibility of activities before notifying WM. This way it won't try to resize
906 // windows that are no longer visible.
Wale Ogunwaled32da472018-11-16 07:19:28 -0800907 mRootActivityContainer.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
Andrii Kulian51c1b672017-04-07 18:39:32 -0700908 !PRESERVE_WINDOWS);
Andrii Kulian839def92016-11-02 10:58:58 -0700909 }
910
911 /**
Andrii Kulian839def92016-11-02 10:58:58 -0700912 * Updates the inner state of the stack to remove it from its current parent, so it can be
913 * either destroyed completely or re-parented.
914 */
915 private void removeFromDisplay() {
Wale Ogunwale9dcf9462017-09-19 15:13:01 -0700916 final ActivityDisplay display = getDisplay();
917 if (display != null) {
918 display.removeChild(this);
919 }
920 mDisplayId = INVALID_DISPLAY;
Andrii Kulian839def92016-11-02 10:58:58 -0700921 }
922
923 /** Removes the stack completely. Also calls WindowManager to do the same on its side. */
924 void remove() {
925 removeFromDisplay();
Yunfan Chen279f5582018-12-12 15:24:50 -0800926 if (mTaskStack != null) {
927 mTaskStack.removeIfPossible();
928 mTaskStack = null;
929 }
Andrii Kulian6d6fb402016-10-26 16:15:25 -0700930 onParentChanged();
Filip Gruszczynskie5390e72015-08-18 16:39:00 -0700931 }
932
Wale Ogunwale9dcf9462017-09-19 15:13:01 -0700933 ActivityDisplay getDisplay() {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800934 return mRootActivityContainer.getActivityDisplay(mDisplayId);
Andrii Kulian94e82d9b02017-07-13 15:33:06 -0700935 }
936
Matthew Ngaa2b6202017-02-10 14:48:21 -0800937 /**
Evan Roskyc5abbd82018-10-05 16:02:19 -0700938 * @see #getStackDockedModeBounds(Rect, Rect, Rect, Rect)
Matthew Ngaa2b6202017-02-10 14:48:21 -0800939 */
Evan Roskyc5abbd82018-10-05 16:02:19 -0700940 void getStackDockedModeBounds(Rect dockedBounds, Rect currentTempTaskBounds,
941 Rect outStackBounds, Rect outTempTaskBounds) {
Yunfan Chen279f5582018-12-12 15:24:50 -0800942 if (mTaskStack != null) {
943 mTaskStack.getStackDockedModeBoundsLocked(getParent().getConfiguration(), dockedBounds,
944 currentTempTaskBounds, outStackBounds, outTempTaskBounds);
945 } else {
946 outStackBounds.setEmpty();
947 outTempTaskBounds.setEmpty();
948 }
Wale Ogunwale1666e312016-12-16 11:27:18 -0800949 }
950
951 void prepareFreezingTaskBounds() {
Yunfan Chen279f5582018-12-12 15:24:50 -0800952 if (mTaskStack != null) {
953 // TODO: This cannot be false after unification.
954 mTaskStack.prepareFreezingTaskBounds();
955 }
Wale Ogunwale1666e312016-12-16 11:27:18 -0800956 }
957
Wale Ogunwale1666e312016-12-16 11:27:18 -0800958 void getWindowContainerBounds(Rect outBounds) {
Yunfan Chen279f5582018-12-12 15:24:50 -0800959 if (mTaskStack != null) {
960 mTaskStack.getBounds(outBounds);
Winson Chungb00dc5e2017-01-25 09:44:25 -0800961 return;
Wale Ogunwale1666e312016-12-16 11:27:18 -0800962 }
963 outBounds.setEmpty();
964 }
965
Wale Ogunwale1666e312016-12-16 11:27:18 -0800966 void positionChildWindowContainerAtTop(TaskRecord child) {
Yunfan Chen279f5582018-12-12 15:24:50 -0800967 if (mTaskStack != null) {
968 // TODO: Remove after unification. This cannot be false after that.
969 mTaskStack.positionChildAtTop(child.getTask(), true /* includingParents */);
970 }
Wale Ogunwale1666e312016-12-16 11:27:18 -0800971 }
972
Riddle Hsu86cb7de2018-08-13 23:29:58 +0800973 void positionChildWindowContainerAtBottom(TaskRecord child) {
Riddle Hsu138ef932018-10-26 17:12:06 +0800974 // If there are other focusable stacks on the display, the z-order of the display should not
975 // be changed just because a task was placed at the bottom. E.g. if it is moving the topmost
976 // task to bottom, the next focusable stack on the same display should be focused.
977 final ActivityStack nextFocusableStack = getDisplay().getNextFocusableStack(
978 child.getStack(), true /* ignoreCurrent */);
Yunfan Chen279f5582018-12-12 15:24:50 -0800979 if (mTaskStack != null) {
980 // TODO: Remove after unification. This cannot be false after that.
981 mTaskStack.positionChildAtBottom(child.getTask(),
982 nextFocusableStack == null /* includingParents */);
983 }
Riddle Hsu86cb7de2018-08-13 23:29:58 +0800984 }
985
Jorim Jaggi192086e2016-03-11 17:17:03 +0100986 /**
Winson Chung8bca9e42017-04-16 15:59:43 -0700987 * Returns whether to defer the scheduling of the multi-window mode.
988 */
989 boolean deferScheduleMultiWindowModeChanged() {
Yunfan Chen279f5582018-12-12 15:24:50 -0800990 if (inPinnedWindowingMode()) {
991 // For the pinned stack, the deferring of the multi-window mode changed is tied to the
992 // transition animation into picture-in-picture, and is called once the animation
993 // completes, or is interrupted in a way that would leave the stack in a non-fullscreen
994 // state.
995 // @see BoundsAnimationController
996 // @see BoundsAnimationControllerTests
997 if (getTaskStack() == null) return false;
998 return getTaskStack().deferScheduleMultiWindowModeChanged();
999 }
Winson Chung8bca9e42017-04-16 15:59:43 -07001000 return false;
1001 }
1002
1003 /**
Jorim Jaggi192086e2016-03-11 17:17:03 +01001004 * Defers updating the bounds of the stack. If the stack was resized/repositioned while
1005 * deferring, the bounds will update in {@link #continueUpdateBounds()}.
1006 */
1007 void deferUpdateBounds() {
1008 if (!mUpdateBoundsDeferred) {
1009 mUpdateBoundsDeferred = true;
1010 mUpdateBoundsDeferredCalled = false;
1011 }
1012 }
1013
1014 /**
1015 * Continues updating bounds after updates have been deferred. If there was a resize attempt
1016 * between {@link #deferUpdateBounds()} and {@link #continueUpdateBounds()}, the stack will
1017 * be resized to that bounds.
1018 */
1019 void continueUpdateBounds() {
Evan Rosky1ac84462018-11-13 11:25:30 -08001020 if (mUpdateBoundsDeferred) {
1021 mUpdateBoundsDeferred = false;
1022 if (mUpdateBoundsDeferredCalled) {
1023 setTaskBounds(mDeferredBounds);
1024 setBounds(mDeferredBounds);
1025 }
1026 if (mUpdateDisplayedBoundsDeferredCalled) {
1027 setTaskDisplayedBounds(mDeferredDisplayedBounds);
1028 }
Jorim Jaggi192086e2016-03-11 17:17:03 +01001029 }
1030 }
1031
Evan Rosky1ac84462018-11-13 11:25:30 -08001032 boolean updateBoundsAllowed(Rect bounds) {
Jorim Jaggi192086e2016-03-11 17:17:03 +01001033 if (!mUpdateBoundsDeferred) {
1034 return true;
1035 }
1036 if (bounds != null) {
1037 mDeferredBounds.set(bounds);
1038 } else {
1039 mDeferredBounds.setEmpty();
1040 }
Jorim Jaggi192086e2016-03-11 17:17:03 +01001041 mUpdateBoundsDeferredCalled = true;
1042 return false;
1043 }
1044
Evan Rosky1ac84462018-11-13 11:25:30 -08001045 boolean updateDisplayedBoundsAllowed(Rect bounds) {
1046 if (!mUpdateBoundsDeferred) {
1047 return true;
1048 }
1049 if (bounds != null) {
1050 mDeferredDisplayedBounds.set(bounds);
1051 } else {
1052 mDeferredDisplayedBounds.setEmpty();
1053 }
1054 mUpdateDisplayedBoundsDeferredCalled = true;
1055 return false;
1056 }
1057
Bryce Leef3c6a472017-11-14 14:53:06 -08001058 @Override
1059 public int setBounds(Rect bounds) {
1060 return super.setBounds(!inMultiWindowMode() ? null : bounds);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001061 }
Craig Mautner5962b122012-10-05 14:45:52 -07001062
Wale Ogunwale42f07d92017-05-01 21:32:58 -07001063 ActivityRecord topRunningActivityLocked() {
Winson Chung3f103eb2017-04-12 21:53:59 -07001064 return topRunningActivityLocked(false /* focusableOnly */);
1065 }
1066
Jorim Jaggiea039a82017-08-02 14:37:49 +02001067 void getAllRunningVisibleActivitiesLocked(ArrayList<ActivityRecord> outActivities) {
1068 outActivities.clear();
1069 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
1070 mTaskHistory.get(taskNdx).getAllRunningVisibleActivitiesLocked(outActivities);
1071 }
1072 }
1073
Andrii Kulian52d255c2018-07-13 11:32:19 -07001074 ActivityRecord topRunningActivityLocked(boolean focusableOnly) {
Craig Mautnerd74f7d72013-02-26 13:41:02 -08001075 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -07001076 ActivityRecord r = mTaskHistory.get(taskNdx).topRunningActivityLocked();
Winson Chung3f103eb2017-04-12 21:53:59 -07001077 if (r != null && (!focusableOnly || r.isFocusable())) {
Craig Mautner6b74cb52013-09-27 17:02:21 -07001078 return r;
Craig Mautner11bf9a52013-02-19 14:08:51 -08001079 }
1080 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001081 return null;
1082 }
1083
Wale Ogunwale42f07d92017-05-01 21:32:58 -07001084 ActivityRecord topRunningNonOverlayTaskActivity() {
1085 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
1086 final TaskRecord task = mTaskHistory.get(taskNdx);
1087 final ArrayList<ActivityRecord> activities = task.mActivities;
1088 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
1089 final ActivityRecord r = activities.get(activityNdx);
1090 if (!r.finishing && !r.mTaskOverlay) {
1091 return r;
1092 }
1093 }
1094 }
1095 return null;
1096 }
1097
1098 ActivityRecord topRunningNonDelayedActivityLocked(ActivityRecord notTop) {
Craig Mautnerd74f7d72013-02-26 13:41:02 -08001099 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
1100 final TaskRecord task = mTaskHistory.get(taskNdx);
Craig Mautner11bf9a52013-02-19 14:08:51 -08001101 final ArrayList<ActivityRecord> activities = task.mActivities;
Craig Mautnerd74f7d72013-02-26 13:41:02 -08001102 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
1103 ActivityRecord r = activities.get(activityNdx);
Chong Zhang87761972016-08-22 13:53:24 -07001104 if (!r.finishing && !r.delayedResume && r != notTop && r.okToShowLocked()) {
Craig Mautner11bf9a52013-02-19 14:08:51 -08001105 return r;
1106 }
1107 }
1108 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001109 return null;
1110 }
1111
1112 /**
Wale Ogunwaled32da472018-11-16 07:19:28 -08001113 * This is a simplified version of topRunningActivity that provides a number of
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001114 * optional skip-over modes. It is intended for use with the ActivityController hook only.
Craig Mautner9658b312013-02-28 10:55:59 -08001115 *
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001116 * @param token If non-null, any history records matching this token will be skipped.
1117 * @param taskId If non-zero, we'll attempt to skip over records with the same task ID.
Craig Mautner9658b312013-02-28 10:55:59 -08001118 *
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001119 * @return Returns the HistoryRecord of the next activity on the stack.
1120 */
1121 final ActivityRecord topRunningActivityLocked(IBinder token, int taskId) {
Craig Mautner11bf9a52013-02-19 14:08:51 -08001122 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
1123 TaskRecord task = mTaskHistory.get(taskNdx);
1124 if (task.taskId == taskId) {
1125 continue;
1126 }
1127 ArrayList<ActivityRecord> activities = task.mActivities;
1128 for (int i = activities.size() - 1; i >= 0; --i) {
1129 final ActivityRecord r = activities.get(i);
1130 // Note: the taskId check depends on real taskId fields being non-zero
Chong Zhang87761972016-08-22 13:53:24 -07001131 if (!r.finishing && (token != r.appToken) && r.okToShowLocked()) {
Craig Mautner11bf9a52013-02-19 14:08:51 -08001132 return r;
1133 }
1134 }
1135 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001136 return null;
1137 }
1138
Wale Ogunwale30e441d2017-11-09 08:28:45 -08001139 ActivityRecord getTopActivity() {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001140 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
Wale Ogunwale30e441d2017-11-09 08:28:45 -08001141 final ActivityRecord r = mTaskHistory.get(taskNdx).getTopActivity();
1142 if (r != null) {
1143 return r;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001144 }
1145 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07001146 return null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001147 }
1148
Craig Mautner9e14d0f2013-05-01 11:26:09 -07001149 final TaskRecord topTask() {
1150 final int size = mTaskHistory.size();
1151 if (size > 0) {
1152 return mTaskHistory.get(size - 1);
1153 }
1154 return null;
1155 }
1156
Wale Ogunwale30e441d2017-11-09 08:28:45 -08001157 private TaskRecord bottomTask() {
Winson Chung1cebea62017-06-26 17:22:27 -07001158 if (mTaskHistory.isEmpty()) {
1159 return null;
1160 }
1161 return mTaskHistory.get(0);
1162 }
1163
Craig Mautnerd2328952013-03-05 12:46:26 -08001164 TaskRecord taskForIdLocked(int id) {
1165 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
1166 final TaskRecord task = mTaskHistory.get(taskNdx);
1167 if (task.taskId == id) {
1168 return task;
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001169 }
1170 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07001171 return null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001172 }
1173
Craig Mautnerd2328952013-03-05 12:46:26 -08001174 ActivityRecord isInStackLocked(IBinder token) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07001175 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale60454db2015-01-23 16:05:07 -08001176 return isInStackLocked(r);
1177 }
1178
1179 ActivityRecord isInStackLocked(ActivityRecord r) {
1180 if (r == null) {
1181 return null;
1182 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001183 final TaskRecord task = r.getTaskRecord();
1184 final ActivityStack stack = r.getActivityStack();
Andrii Kulian02b7a832016-10-06 23:11:56 -07001185 if (stack != null && task.mActivities.contains(r) && mTaskHistory.contains(task)) {
1186 if (stack != this) Slog.w(TAG,
Craig Mautnerd2328952013-03-05 12:46:26 -08001187 "Illegal state! task does not point to stack it is in.");
Wale Ogunwale60454db2015-01-23 16:05:07 -08001188 return r;
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001189 }
Craig Mautnerd2328952013-03-05 12:46:26 -08001190 return null;
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001191 }
1192
Andrii Kulianfb1bf692017-01-17 11:17:34 -08001193 boolean isInStackLocked(TaskRecord task) {
1194 return mTaskHistory.contains(task);
1195 }
1196
1197 /** Checks if there are tasks with specific UID in the stack. */
1198 boolean isUidPresent(int uid) {
1199 for (TaskRecord task : mTaskHistory) {
David Stevens82ea6cb2017-03-03 16:18:50 -08001200 for (ActivityRecord r : task.mActivities) {
1201 if (r.getUid() == uid) {
1202 return true;
1203 }
Andrii Kulianfb1bf692017-01-17 11:17:34 -08001204 }
1205 }
1206 return false;
1207 }
1208
1209 /** Get all UIDs that are present in the stack. */
1210 void getPresentUIDs(IntArray presentUIDs) {
1211 for (TaskRecord task : mTaskHistory) {
David Stevens82ea6cb2017-03-03 16:18:50 -08001212 for (ActivityRecord r : task.mActivities) {
1213 presentUIDs.add(r.getUid());
1214 }
Andrii Kulianfb1bf692017-01-17 11:17:34 -08001215 }
1216 }
1217
Wale Ogunwale9e737db2018-12-17 15:42:37 -08001218 /** @return true if the stack can only contain one task */
1219 boolean isSingleTaskInstance() {
1220 final ActivityDisplay display = getDisplay();
1221 return display != null && display.isSingleTaskInstance();
1222 }
1223
Winson Chungabb433b2017-03-24 09:35:42 -07001224 final void removeActivitiesFromLRUListLocked(TaskRecord task) {
1225 for (ActivityRecord r : task.mActivities) {
1226 mLRUActivities.remove(r);
1227 }
1228 }
1229
Craig Mautner2420ead2013-04-01 17:13:20 -07001230 final boolean updateLRUListLocked(ActivityRecord r) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001231 final boolean hadit = mLRUActivities.remove(r);
1232 mLRUActivities.add(r);
1233 return hadit;
1234 }
1235
Matthew Ngae1ff4f2016-11-10 15:49:14 -08001236 final boolean isHomeOrRecentsStack() {
Wale Ogunwale68278562017-09-23 17:13:55 -07001237 return isActivityTypeHome() || isActivityTypeRecents();
Matthew Ngae1ff4f2016-11-10 15:49:14 -08001238 }
1239
Craig Mautnere0a38842013-12-16 16:14:02 -08001240 final boolean isOnHomeDisplay() {
Wale Ogunwale9dcf9462017-09-19 15:13:01 -07001241 return mDisplayId == DEFAULT_DISPLAY;
Craig Mautnere0a38842013-12-16 16:14:02 -08001242 }
1243
Wale Ogunwale66e16852017-10-19 13:35:52 -07001244 private boolean returnsToHomeStack() {
1245 return !inMultiWindowMode()
1246 && !mTaskHistory.isEmpty()
1247 && mTaskHistory.get(0).returnsToHomeStack();
1248 }
1249
Wale Ogunwaleeae451e2015-08-04 15:20:50 -07001250 void moveToFront(String reason) {
1251 moveToFront(reason, null);
1252 }
1253
1254 /**
1255 * @param reason The reason for moving the stack to the front.
1256 * @param task If non-null, the task will be moved to the top of the stack.
1257 * */
1258 void moveToFront(String reason, TaskRecord task) {
Wale Ogunwale1e60e0c2015-10-28 13:36:10 -07001259 if (!isAttached()) {
1260 return;
1261 }
Wale Ogunwale925d0d12015-09-23 15:40:07 -07001262
Wale Ogunwalebb285872018-03-01 13:05:30 -08001263 final ActivityDisplay display = getDisplay();
1264
1265 if (inSplitScreenSecondaryWindowingMode()) {
1266 // If the stack is in split-screen seconardy mode, we need to make sure we move the
1267 // primary split-screen stack forward in the case it is currently behind a fullscreen
1268 // stack so both halves of the split-screen appear on-top and the fullscreen stack isn't
1269 // cutting between them.
1270 // TODO(b/70677280): This is a workaround until we can fix as part of b/70677280.
1271 final ActivityStack topFullScreenStack =
1272 display.getTopStackInWindowingMode(WINDOWING_MODE_FULLSCREEN);
1273 if (topFullScreenStack != null) {
1274 final ActivityStack primarySplitScreenStack = display.getSplitScreenPrimaryStack();
1275 if (display.getIndexOf(topFullScreenStack)
1276 > display.getIndexOf(primarySplitScreenStack)) {
1277 primarySplitScreenStack.moveToFront(reason + " splitScreenToTop");
1278 }
1279 }
1280 }
1281
Wale Ogunwale66e16852017-10-19 13:35:52 -07001282 if (!isActivityTypeHome() && returnsToHomeStack()) {
1283 // Make sure the home stack is behind this stack since that is where we should return to
1284 // when this stack is no longer visible.
Louis Changbd48dca2018-08-29 17:44:34 +08001285 display.moveHomeStackToFront(reason + " returnToHome");
Wale Ogunwale66e16852017-10-19 13:35:52 -07001286 }
1287
Riddle Hsubbb63c22018-10-03 12:28:29 +08001288 final boolean movingTask = task != null;
1289 display.positionChildAtTop(this, !movingTask /* includingParents */, reason);
1290 if (movingTask) {
Andrii Kulian52d255c2018-07-13 11:32:19 -07001291 // This also moves the entire hierarchy branch to top, including parents
Riddle Hsubbb63c22018-10-03 12:28:29 +08001292 insertTaskAtTop(task, null /* starting */);
Wale Ogunwale1e60e0c2015-10-28 13:36:10 -07001293 }
Craig Mautnere0a38842013-12-16 16:14:02 -08001294 }
1295
Evan Rosky9c448172017-11-02 14:19:27 -07001296 /**
1297 * @param reason The reason for moving the stack to the back.
1298 * @param task If non-null, the task will be moved to the bottom of the stack.
1299 **/
1300 void moveToBack(String reason, TaskRecord task) {
1301 if (!isAttached()) {
1302 return;
1303 }
1304
Bryce Lee8cab4a02018-01-05 09:00:49 -08001305 /**
1306 * The intent behind moving a primary split screen stack to the back is usually to hide
1307 * behind the home stack. Exit split screen in this case.
1308 */
1309 if (getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
Evan Rosky10475742018-09-05 19:02:48 -07001310 setWindowingMode(WINDOWING_MODE_UNDEFINED);
Bryce Lee8cab4a02018-01-05 09:00:49 -08001311 }
1312
Riddle Hsubbb63c22018-10-03 12:28:29 +08001313 getDisplay().positionChildAtBottom(this, reason);
Evan Rosky9c448172017-11-02 14:19:27 -07001314 if (task != null) {
1315 insertTaskAtBottom(task);
Evan Rosky9c448172017-11-02 14:19:27 -07001316 }
1317 }
1318
Wale Ogunwaled046a012015-12-24 13:05:59 -08001319 boolean isFocusable() {
Wale Ogunwale4cea0f52015-12-25 06:30:31 -08001320 final ActivityRecord r = topRunningActivityLocked();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001321 return mRootActivityContainer.isFocusable(this, r != null && r.isFocusable());
Wale Ogunwaled046a012015-12-24 13:05:59 -08001322 }
1323
Riddle Hsu75016992018-09-20 20:37:14 +08001324 boolean isFocusableAndVisible() {
1325 return isFocusable() && shouldBeVisible(null /* starting */);
1326 }
1327
Craig Mautnere0a38842013-12-16 16:14:02 -08001328 final boolean isAttached() {
Riddle Hsu402b4402018-11-06 17:23:15 +08001329 final ActivityDisplay display = getDisplay();
1330 return display != null && !display.isRemoved();
Craig Mautner4a1cb222013-12-04 16:14:06 -08001331 }
1332
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001333 /**
Wale Ogunwale39381972015-12-17 17:15:29 -08001334 * Returns the top activity in any existing task matching the given Intent in the input result.
1335 * Returns null if no such task is found.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001336 */
Wale Ogunwale39381972015-12-17 17:15:29 -08001337 void findTaskLocked(ActivityRecord target, FindTaskResult result) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001338 Intent intent = target.intent;
1339 ActivityInfo info = target.info;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001340 ComponentName cls = intent.getComponent();
1341 if (info.targetActivity != null) {
1342 cls = new ComponentName(info.packageName, info.targetActivity);
1343 }
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07001344 final int userId = UserHandle.getUserId(info.applicationInfo.uid);
Craig Mautnerd00f4742014-03-12 14:17:26 -07001345 boolean isDocument = intent != null & intent.isDocument();
1346 // If documentData is non-null then it must match the existing task data.
1347 Uri documentData = isDocument ? intent.getData() : null;
Craig Mautner000f0022013-02-26 15:04:29 -08001348
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001349 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + target + " in " + this);
Craig Mautner000f0022013-02-26 15:04:29 -08001350 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
1351 final TaskRecord task = mTaskHistory.get(taskNdx);
Dianne Hackborn91097de2014-04-04 18:02:06 -07001352 if (task.voiceSession != null) {
1353 // We never match voice sessions; those always run independently.
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001354 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": voice session");
Dianne Hackborn91097de2014-04-04 18:02:06 -07001355 continue;
1356 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001357 if (task.userId != userId) {
1358 // Looking for a different task.
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001359 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": different user");
Craig Mautnerac6f8432013-07-17 13:24:59 -07001360 continue;
1361 }
Bryce Lee9f6affd2017-09-01 09:18:35 -07001362
1363 // Overlays should not be considered as the task's logical top activity.
1364 final ActivityRecord r = task.getTopActivity(false /* includeOverlays */);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001365 if (r == null || r.finishing || r.mUserId != userId ||
Craig Mautner000f0022013-02-26 15:04:29 -08001366 r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001367 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": mismatch root " + r);
Craig Mautner000f0022013-02-26 15:04:29 -08001368 continue;
1369 }
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001370 if (!r.hasCompatibleActivityType(target)) {
Chong Zhangb546f7e2015-08-05 14:21:36 -07001371 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": mismatch activity type");
1372 continue;
1373 }
Craig Mautner000f0022013-02-26 15:04:29 -08001374
Craig Mautnerd00f4742014-03-12 14:17:26 -07001375 final Intent taskIntent = task.intent;
1376 final Intent affinityIntent = task.affinityIntent;
1377 final boolean taskIsDocument;
1378 final Uri taskDocumentData;
1379 if (taskIntent != null && taskIntent.isDocument()) {
1380 taskIsDocument = true;
1381 taskDocumentData = taskIntent.getData();
1382 } else if (affinityIntent != null && affinityIntent.isDocument()) {
1383 taskIsDocument = true;
1384 taskDocumentData = affinityIntent.getData();
1385 } else {
1386 taskIsDocument = false;
1387 taskDocumentData = null;
1388 }
1389
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001390 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Comparing existing cls="
Louis Changb05c8d82019-06-25 11:56:55 +08001391 + (task.realActivity != null ? task.realActivity.flattenToShortString() : "")
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001392 + "/aff=" + r.getTaskRecord().rootAffinity + " to new cls="
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001393 + intent.getComponent().flattenToShortString() + "/aff=" + info.taskAffinity);
Andrii Kulian206b9fa2016-06-02 13:18:01 -07001394 // TODO Refactor to remove duplications. Check if logic can be simplified.
Louis Changb05c8d82019-06-25 11:56:55 +08001395 if (task.realActivity != null && task.realActivity.compareTo(cls) == 0
1396 && Objects.equals(documentData, taskDocumentData)) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001397 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching class!");
Craig Mautner000f0022013-02-26 15:04:29 -08001398 //dump();
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001399 if (DEBUG_TASKS) Slog.d(TAG_TASKS,
1400 "For Intent " + intent + " bringing to top: " + r.intent);
Louis Changc85b1a32018-08-14 16:40:53 +08001401 result.mRecord = r;
1402 result.mIdealMatch = true;
Wale Ogunwale39381972015-12-17 17:15:29 -08001403 break;
Craig Mautnerffcfcaa2014-06-05 09:54:38 -07001404 } else if (affinityIntent != null && affinityIntent.getComponent() != null &&
1405 affinityIntent.getComponent().compareTo(cls) == 0 &&
Craig Mautnerd00f4742014-03-12 14:17:26 -07001406 Objects.equals(documentData, taskDocumentData)) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001407 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching class!");
Craig Mautner000f0022013-02-26 15:04:29 -08001408 //dump();
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001409 if (DEBUG_TASKS) Slog.d(TAG_TASKS,
1410 "For Intent " + intent + " bringing to top: " + r.intent);
Louis Changc85b1a32018-08-14 16:40:53 +08001411 result.mRecord = r;
1412 result.mIdealMatch = true;
Wale Ogunwale39381972015-12-17 17:15:29 -08001413 break;
Andrii Kulian206b9fa2016-06-02 13:18:01 -07001414 } else if (!isDocument && !taskIsDocument
Louis Changc85b1a32018-08-14 16:40:53 +08001415 && result.mRecord == null && task.rootAffinity != null) {
Andrii Kulian206b9fa2016-06-02 13:18:01 -07001416 if (task.rootAffinity.equals(target.taskAffinity)) {
1417 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching affinity candidate!");
1418 // It is possible for multiple tasks to have the same root affinity especially
1419 // if they are in separate stacks. We save off this candidate, but keep looking
1420 // to see if there is a better candidate.
Louis Changc85b1a32018-08-14 16:40:53 +08001421 result.mRecord = r;
1422 result.mIdealMatch = false;
Andrii Kulian206b9fa2016-06-02 13:18:01 -07001423 }
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001424 } else if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Not a match: " + task);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001425 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001426 }
1427
1428 /**
1429 * Returns the first activity (starting from the top of the stack) that
1430 * is the same as the given activity. Returns null if no such activity
1431 * is found.
1432 */
Andrii Kuliand3bbb132016-06-16 16:00:20 -07001433 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info,
1434 boolean compareIntentFilters) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001435 ComponentName cls = intent.getComponent();
1436 if (info.targetActivity != null) {
1437 cls = new ComponentName(info.packageName, info.targetActivity);
1438 }
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07001439 final int userId = UserHandle.getUserId(info.applicationInfo.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001440
Craig Mautner000f0022013-02-26 15:04:29 -08001441 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
Wale Ogunwale3fcb4a82015-04-06 14:00:13 -07001442 final TaskRecord task = mTaskHistory.get(taskNdx);
Craig Mautnerac6f8432013-07-17 13:24:59 -07001443 final ArrayList<ActivityRecord> activities = task.mActivities;
Wale Ogunwale3fcb4a82015-04-06 14:00:13 -07001444
Craig Mautner000f0022013-02-26 15:04:29 -08001445 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
1446 ActivityRecord r = activities.get(activityNdx);
Chong Zhang87761972016-08-22 13:53:24 -07001447 if (!r.okToShowLocked()) {
Wale Ogunwale25073dd2015-07-21 16:54:54 -07001448 continue;
Wale Ogunwale3fcb4a82015-04-06 14:00:13 -07001449 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001450 if (!r.finishing && r.mUserId == userId) {
Andrii Kuliand3bbb132016-06-16 16:00:20 -07001451 if (compareIntentFilters) {
1452 if (r.intent.filterEquals(intent)) {
1453 return r;
1454 }
1455 } else {
1456 if (r.intent.getComponent().equals(cls)) {
1457 return r;
1458 }
1459 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001460 }
1461 }
1462 }
1463
1464 return null;
1465 }
1466
Amith Yamasani742a6712011-05-04 14:49:28 -07001467 /*
Craig Mautnerac6f8432013-07-17 13:24:59 -07001468 * Move the activities around in the stack to bring a user to the foreground.
Amith Yamasani742a6712011-05-04 14:49:28 -07001469 */
Craig Mautner93529a42013-10-04 15:03:13 -07001470 final void switchUserLocked(int userId) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001471 if (mCurrentUser == userId) {
Craig Mautner93529a42013-10-04 15:03:13 -07001472 return;
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001473 }
1474 mCurrentUser = userId;
1475
1476 // Move userId's tasks to the top.
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001477 int index = mTaskHistory.size();
Craig Mautnerdb5c4fb2013-11-06 13:55:08 -08001478 for (int i = 0; i < index; ) {
Wale Ogunwale3fcb4a82015-04-06 14:00:13 -07001479 final TaskRecord task = mTaskHistory.get(i);
1480
Chong Zhang87761972016-08-22 13:53:24 -07001481 if (task.okToShowLocked()) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001482 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "switchUser: stack=" + getStackId() +
Craig Mautner4f1df4f2013-10-15 15:44:14 -07001483 " moving " + task + " to top");
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001484 mTaskHistory.remove(i);
1485 mTaskHistory.add(task);
1486 --index;
Craig Mautnerdb5c4fb2013-11-06 13:55:08 -08001487 // Use same value for i.
1488 } else {
1489 ++i;
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001490 }
1491 }
Amith Yamasani742a6712011-05-04 14:49:28 -07001492 }
1493
Craig Mautner2420ead2013-04-01 17:13:20 -07001494 void minimalResumeActivityLocked(ActivityRecord r) {
Wale Ogunwale5658e4b2016-02-12 12:22:19 -08001495 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + r + " (starting new instance)"
1496 + " callers=" + Debug.getCallers(5));
Bryce Leec4ab62a2018-03-05 14:19:26 -08001497 r.setState(RESUMED, "minimalResumeActivityLocked");
Andrii Kulian21713ac2016-10-12 22:05:05 -07001498 r.completeResumeLocked();
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07001499 if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE,
1500 "Launch completed; removing icicle of " + r.icicle);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001501 }
1502
Andrii Kulian21713ac2016-10-12 22:05:05 -07001503 private void clearLaunchTime(ActivityRecord r) {
Craig Mautner5c494542013-09-06 11:59:38 -07001504 // Make sure that there is no activity waiting for this to launch.
Vishnu Nair132ee832018-09-28 15:00:05 -07001505 if (!mStackSupervisor.mWaitingActivityLaunched.isEmpty()) {
Craig Mautner5c494542013-09-06 11:59:38 -07001506 mStackSupervisor.removeTimeoutsForActivityLocked(r);
1507 mStackSupervisor.scheduleIdleTimeoutLocked(r);
1508 }
Dianne Hackborn2286cdc2013-07-01 19:10:06 -07001509 }
1510
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001511 void awakeFromSleepingLocked() {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001512 // Ensure activities are no longer sleeping.
Craig Mautnerd44711d2013-02-23 11:24:36 -08001513 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
1514 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
1515 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
1516 activities.get(activityNdx).setSleeping(false);
1517 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001518 }
Craig Mautnerf49b0a42014-11-20 15:06:40 -08001519 if (mPausingActivity != null) {
1520 Slog.d(TAG, "awakeFromSleepingLocked: previously pausing activity didn't pause");
1521 activityPausedLocked(mPausingActivity.appToken, true);
1522 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001523 }
1524
Todd Kennedy39bfee52016-02-24 10:28:21 -08001525 void updateActivityApplicationInfoLocked(ApplicationInfo aInfo) {
1526 final String packageName = aInfo.packageName;
Makoto Onuki8b9963a2017-05-18 13:56:30 -07001527 final int userId = UserHandle.getUserId(aInfo.uid);
1528
Todd Kennedy39bfee52016-02-24 10:28:21 -08001529 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
1530 final List<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
1531 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
Makoto Onuki8b9963a2017-05-18 13:56:30 -07001532 final ActivityRecord ar = activities.get(activityNdx);
1533
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001534 if ((userId == ar.mUserId) && packageName.equals(ar.packageName)) {
Philip P. Moltmanncff8f0f2018-03-27 12:51:51 -07001535 ar.updateApplicationInfo(aInfo);
Todd Kennedy39bfee52016-02-24 10:28:21 -08001536 }
1537 }
1538 }
1539 }
1540
David Stevens9440dc82017-03-16 19:00:20 -07001541 void checkReadyForSleep() {
1542 if (shouldSleepActivities() && goToSleepIfPossible(false /* shuttingDown */)) {
1543 mStackSupervisor.checkReadyForSleepLocked(true /* allowDelay */);
1544 }
1545 }
1546
Craig Mautner0eea92c2013-05-16 13:35:39 -07001547 /**
David Stevens9440dc82017-03-16 19:00:20 -07001548 * Tries to put the activities in the stack to sleep.
1549 *
1550 * If the stack is not in a state where its activities can be put to sleep, this function will
1551 * start any necessary actions to move the stack into such a state. It is expected that this
1552 * function get called again when those actions complete.
1553 *
1554 * @param shuttingDown true when the called because the device is shutting down.
David Stevens18abd0e2017-08-17 14:55:47 -07001555 * @return true if the stack finished going to sleep, false if the stack only started the
1556 * process of going to sleep (checkReadyForSleep will be called when that process finishes).
Craig Mautner0eea92c2013-05-16 13:35:39 -07001557 */
David Stevens9440dc82017-03-16 19:00:20 -07001558 boolean goToSleepIfPossible(boolean shuttingDown) {
1559 boolean shouldSleep = true;
1560
Craig Mautner0eea92c2013-05-16 13:35:39 -07001561 if (mResumedActivity != null) {
1562 // Still have something resumed; can't sleep until it is paused.
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001563 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep needs to pause " + mResumedActivity);
1564 if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
1565 "Sleep => pause with userLeaving=false");
Bryce Lee5daa3122017-04-19 10:40:42 -07001566
chaviwa1d68532018-03-16 15:33:43 -07001567 startPausingLocked(false, true, null, false);
David Stevens9440dc82017-03-16 19:00:20 -07001568 shouldSleep = false ;
1569 } else if (mPausingActivity != null) {
Craig Mautner0eea92c2013-05-16 13:35:39 -07001570 // Still waiting for something to pause; can't sleep yet.
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001571 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still waiting to pause " + mPausingActivity);
David Stevens9440dc82017-03-16 19:00:20 -07001572 shouldSleep = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001573 }
David Stevens9440dc82017-03-16 19:00:20 -07001574
1575 if (!shuttingDown) {
1576 if (containsActivityFromStack(mStackSupervisor.mStoppingActivities)) {
1577 // Still need to tell some activities to stop; can't sleep yet.
1578 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to stop "
1579 + mStackSupervisor.mStoppingActivities.size() + " activities");
1580
1581 mStackSupervisor.scheduleIdleLocked();
1582 shouldSleep = false;
1583 }
1584
1585 if (containsActivityFromStack(mStackSupervisor.mGoingToSleepActivities)) {
1586 // Still need to tell some activities to sleep; can't sleep yet.
1587 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to sleep "
1588 + mStackSupervisor.mGoingToSleepActivities.size() + " activities");
1589 shouldSleep = false;
1590 }
1591 }
1592
1593 if (shouldSleep) {
1594 goToSleep();
1595 }
1596
David Stevens18abd0e2017-08-17 14:55:47 -07001597 return shouldSleep;
Craig Mautner0eea92c2013-05-16 13:35:39 -07001598 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001599
David Stevens18abd0e2017-08-17 14:55:47 -07001600 void goToSleep() {
Andrii Kulianf4479ee2018-05-23 17:52:48 -07001601 // Ensure visibility without updating configuration, as activities are about to sleep.
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07001602 ensureActivitiesVisibleLocked(null /* starting */, 0 /* configChanges */,
1603 !PRESERVE_WINDOWS);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001604
Andrii Kulianf9949d52016-05-06 12:53:25 -07001605 // Make sure any paused or stopped but visible activities are now sleeping.
Craig Mautner0eea92c2013-05-16 13:35:39 -07001606 // This ensures that the activity's onStop() is called.
1607 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
1608 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
1609 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
1610 final ActivityRecord r = activities.get(activityNdx);
Bryce Lee7ace3952018-02-16 14:34:32 -08001611 if (r.isState(STOPPING, STOPPED, PAUSED, PAUSING)) {
Craig Mautner0eea92c2013-05-16 13:35:39 -07001612 r.setSleeping(true);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001613 }
1614 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001615 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001616 }
Craig Mautner59c00972012-07-30 12:10:24 -07001617
David Stevens9440dc82017-03-16 19:00:20 -07001618 private boolean containsActivityFromStack(List<ActivityRecord> rs) {
1619 for (ActivityRecord r : rs) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001620 if (r.getActivityStack() == this) {
David Stevens9440dc82017-03-16 19:00:20 -07001621 return true;
1622 }
1623 }
1624 return false;
1625 }
1626
Dianne Hackborna4e102e2014-09-04 22:52:27 -07001627 /**
Winson Chung4dabf232017-01-25 13:25:22 -08001628 * Schedule a pause timeout in case the app doesn't respond. We don't give it much time because
1629 * this directly impacts the responsiveness seen by the user.
1630 */
1631 private void schedulePauseTimeout(ActivityRecord r) {
1632 final Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
1633 msg.obj = r;
1634 r.pauseTime = SystemClock.uptimeMillis();
1635 mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
1636 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Waiting for pause to complete...");
1637 }
1638
1639 /**
Dianne Hackborna4e102e2014-09-04 22:52:27 -07001640 * Start pausing the currently resumed activity. It is an error to call this if there
1641 * is already an activity being paused or there is no resumed activity.
1642 *
1643 * @param userLeaving True if this should result in an onUserLeaving to the current activity.
1644 * @param uiSleeping True if this is happening with the user interface going to sleep (the
1645 * screen turning off).
Wale Ogunwale950faff2016-08-08 09:51:04 -07001646 * @param resuming The activity we are currently trying to resume or null if this is not being
1647 * called as part of resuming the top activity, so we shouldn't try to instigate
1648 * a resume here if not null.
Winson Chung6954fc92017-03-24 16:22:12 -07001649 * @param pauseImmediately True if the caller does not want to wait for the activity callback to
1650 * complete pausing.
Dianne Hackborna4e102e2014-09-04 22:52:27 -07001651 * @return Returns true if an activity now is in the PAUSING state, and we are waiting for
1652 * it to tell us when it is done.
1653 */
Wale Ogunwale950faff2016-08-08 09:51:04 -07001654 final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
Winson Chung6954fc92017-03-24 16:22:12 -07001655 ActivityRecord resuming, boolean pauseImmediately) {
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08001656 if (mPausingActivity != null) {
riddle_hsu7dfe4d72015-02-16 18:43:49 +08001657 Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity
Bryce Lee7ace3952018-02-16 14:34:32 -08001658 + " state=" + mPausingActivity.getState());
David Stevens9440dc82017-03-16 19:00:20 -07001659 if (!shouldSleepActivities()) {
riddle_hsu7dfe4d72015-02-16 18:43:49 +08001660 // Avoid recursion among check for sleep and complete pause during sleeping.
1661 // Because activity will be paused immediately after resume, just let pause
1662 // be completed by the order of activity paused from clients.
Wale Ogunwale950faff2016-08-08 09:51:04 -07001663 completePauseLocked(false, resuming);
riddle_hsu7dfe4d72015-02-16 18:43:49 +08001664 }
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08001665 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001666 ActivityRecord prev = mResumedActivity;
Bryce Lee5daa3122017-04-19 10:40:42 -07001667
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001668 if (prev == null) {
Wale Ogunwale950faff2016-08-08 09:51:04 -07001669 if (resuming == null) {
Dianne Hackborna4e102e2014-09-04 22:52:27 -07001670 Slog.wtf(TAG, "Trying to pause when nothing is resumed");
Wale Ogunwaled32da472018-11-16 07:19:28 -08001671 mRootActivityContainer.resumeFocusedStacksTopActivities();
Dianne Hackborna4e102e2014-09-04 22:52:27 -07001672 }
1673 return false;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001674 }
Craig Mautnerdf88d732014-01-27 09:21:32 -08001675
Andrii Kulianb1888aa2018-02-16 14:40:42 -08001676 if (prev == resuming) {
1677 Slog.wtf(TAG, "Trying to pause activity that is in process of being resumed");
1678 return false;
1679 }
1680
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07001681 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSING: " + prev);
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001682 else if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Start pausing: " + prev);
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08001683 mPausingActivity = prev;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001684 mLastPausedActivity = prev;
Craig Mautner0f922742013-08-06 08:44:42 -07001685 mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
1686 || (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
Bryce Lee7ace3952018-02-16 14:34:32 -08001687 prev.setState(PAUSING, "startPausingLocked");
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001688 prev.getTaskRecord().touchActiveTime();
Dianne Hackborn2286cdc2013-07-01 19:10:06 -07001689 clearLaunchTime(prev);
Jorim Jaggie7d2b852017-08-28 17:55:15 +02001690
Wale Ogunwale53783742018-09-16 10:21:51 -07001691 mService.updateCpuStats();
Craig Mautneraab647e2013-02-28 16:31:36 -08001692
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001693 if (prev.attachedToProcess()) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001694 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001695 try {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001696 EventLogTags.writeAmPauseActivity(prev.mUserId, System.identityHashCode(prev),
Wale Ogunwalec59b4f62017-11-30 11:05:43 -08001697 prev.shortComponentName, "userLeaving=" + userLeaving);
Andrii Kulian446e8242017-10-26 15:17:29 -07001698
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001699 mService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
1700 prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving,
Bryce Lee1d0d5142018-04-12 10:35:07 -07001701 prev.configChangeFlags, pauseImmediately));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001702 } catch (Exception e) {
1703 // Ignore exception, if process died other code will cleanup.
1704 Slog.w(TAG, "Exception thrown during pause", e);
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08001705 mPausingActivity = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001706 mLastPausedActivity = null;
Craig Mautner0f922742013-08-06 08:44:42 -07001707 mLastNoHistoryActivity = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001708 }
1709 } else {
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08001710 mPausingActivity = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001711 mLastPausedActivity = null;
Craig Mautner0f922742013-08-06 08:44:42 -07001712 mLastNoHistoryActivity = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001713 }
1714
1715 // If we are not going to sleep, we want to ensure the device is
1716 // awake until the next activity is started.
Wale Ogunwalef6733932018-06-27 05:14:34 -07001717 if (!uiSleeping && !mService.isSleepingOrShuttingDownLocked()) {
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001718 mStackSupervisor.acquireLaunchWakelock();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001719 }
1720
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08001721 if (mPausingActivity != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001722 // Have the window manager pause its key dispatching until the new
1723 // activity has started. If we're pausing the activity just because
1724 // the screen is being turned off and the UI is sleeping, don't interrupt
1725 // key dispatch; the same activity will pick it up again on wakeup.
1726 if (!uiSleeping) {
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08001727 prev.pauseKeyDispatchingLocked();
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001728 } else if (DEBUG_PAUSE) {
1729 Slog.v(TAG_PAUSE, "Key dispatch not paused for screen off");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001730 }
1731
Winson Chung6954fc92017-03-24 16:22:12 -07001732 if (pauseImmediately) {
Dianne Hackborna4e102e2014-09-04 22:52:27 -07001733 // If the caller said they don't want to wait for the pause, then complete
1734 // the pause now.
Wale Ogunwale950faff2016-08-08 09:51:04 -07001735 completePauseLocked(false, resuming);
Dianne Hackborna4e102e2014-09-04 22:52:27 -07001736 return false;
1737
1738 } else {
Winson Chung4dabf232017-01-25 13:25:22 -08001739 schedulePauseTimeout(prev);
Dianne Hackborna4e102e2014-09-04 22:52:27 -07001740 return true;
1741 }
1742
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001743 } else {
1744 // This activity failed to schedule the
1745 // pause, so just treat it as being paused now.
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001746 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Activity not running, resuming next.");
Wale Ogunwale950faff2016-08-08 09:51:04 -07001747 if (resuming == null) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001748 mRootActivityContainer.resumeFocusedStacksTopActivities();
Dianne Hackborna4e102e2014-09-04 22:52:27 -07001749 }
1750 return false;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001751 }
1752 }
Dianne Hackbornad9b32112012-09-17 15:35:01 -07001753
Dianne Hackborna4e102e2014-09-04 22:52:27 -07001754 final void activityPausedLocked(IBinder token, boolean timeout) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001755 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE,
1756 "Activity paused: token=" + token + ", timeout=" + timeout);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001757
Craig Mautnerd2328952013-03-05 12:46:26 -08001758 final ActivityRecord r = isInStackLocked(token);
Andrii Kulian6b321512019-01-23 06:37:00 +00001759
Craig Mautnerd2328952013-03-05 12:46:26 -08001760 if (r != null) {
1761 mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
1762 if (mPausingActivity == r) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07001763 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + r
Craig Mautnerd2328952013-03-05 12:46:26 -08001764 + (timeout ? " (due to timeout)" : " (pause complete)"));
Jorim Jaggife762342016-10-13 14:33:27 +02001765 mService.mWindowManager.deferSurfaceLayout();
1766 try {
Winson Chung3f103eb2017-04-12 21:53:59 -07001767 completePauseLocked(true /* resumeNext */, null /* resumingActivity */);
Jorim Jaggife762342016-10-13 14:33:27 +02001768 } finally {
1769 mService.mWindowManager.continueSurfaceLayout();
1770 }
Wale Ogunwale5658e4b2016-02-12 12:22:19 -08001771 return;
Craig Mautnerd2328952013-03-05 12:46:26 -08001772 } else {
1773 EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001774 r.mUserId, System.identityHashCode(r), r.shortComponentName,
Craig Mautnerd2328952013-03-05 12:46:26 -08001775 mPausingActivity != null
1776 ? mPausingActivity.shortComponentName : "(none)");
Bryce Lee7ace3952018-02-16 14:34:32 -08001777 if (r.isState(PAUSING)) {
1778 r.setState(PAUSED, "activityPausedLocked");
riddle_hsu9caeef72015-10-20 16:34:05 +08001779 if (r.finishing) {
1780 if (DEBUG_PAUSE) Slog.v(TAG,
1781 "Executing finish of failed to pause activity: " + r);
Bryce Leef52974c2018-02-14 15:12:01 -08001782 finishCurrentActivityLocked(r, FINISH_AFTER_VISIBLE, false,
1783 "activityPausedLocked");
riddle_hsu9caeef72015-10-20 16:34:05 +08001784 }
louis_chang047dfd42015-04-08 16:35:55 +08001785 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001786 }
1787 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08001788 mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001789 }
1790
Wale Ogunwale950faff2016-08-08 09:51:04 -07001791 private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08001792 ActivityRecord prev = mPausingActivity;
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001793 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev);
Craig Mautneraab647e2013-02-28 16:31:36 -08001794
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08001795 if (prev != null) {
chaviw4ad54912018-05-30 11:05:44 -07001796 prev.setWillCloseOrEnterPip(false);
Bryce Lee7ace3952018-02-16 14:34:32 -08001797 final boolean wasStopping = prev.isState(STOPPING);
1798 prev.setState(PAUSED, "completePausedLocked");
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08001799 if (prev.finishing) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001800 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev);
Bryce Leef52974c2018-02-14 15:12:01 -08001801 prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false,
Charles Chen69362cd2019-03-29 15:18:45 +08001802 "completePausedLocked");
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001803 } else if (prev.hasProcess()) {
Wale Ogunwaled8026642016-02-09 20:40:18 -08001804 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueue pending stop if needed: " + prev
1805 + " wasStopping=" + wasStopping + " visible=" + prev.visible);
Wale Ogunwalef81c1d12016-01-12 12:20:18 -08001806 if (prev.deferRelaunchUntilPaused) {
1807 // Complete the deferred relaunch that was waiting for pause to complete.
1808 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Re-launching after pause: " + prev);
Andrii Kulian21713ac2016-10-12 22:05:05 -07001809 prev.relaunchActivityLocked(false /* andResume */,
Wale Ogunwalef81c1d12016-01-12 12:20:18 -08001810 prev.preserveWindowOnDeferredRelaunch);
Filip Gruszczynskidba623a2015-12-04 15:45:35 -08001811 } else if (wasStopping) {
1812 // We are also stopping, the stop request must have gone soon after the pause.
1813 // We can't clobber it, because the stop confirmation will not be handled.
1814 // We don't need to schedule another stop, we only need to let it happen.
Bryce Lee7ace3952018-02-16 14:34:32 -08001815 prev.setState(STOPPING, "completePausedLocked");
David Stevens9440dc82017-03-16 19:00:20 -07001816 } else if (!prev.visible || shouldSleepOrShutDownActivities()) {
Wale Ogunwaleec950642017-04-25 07:44:21 -07001817 // Clear out any deferred client hide we might currently have.
1818 prev.setDeferHidingClient(false);
Jose Lima4b6c6692014-08-12 17:41:12 -07001819 // If we were visible then resumeTopActivities will release resources before
Wale Ogunwaleec950642017-04-25 07:44:21 -07001820 // stopping.
wilsonshih401e50f2019-04-30 12:55:48 +08001821 addToStopping(prev, true /* scheduleIdle */, false /* idleDelayed */,
1822 "completePauseLocked");
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08001823 }
1824 } else {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001825 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "App died during pause, not stopping: " + prev);
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08001826 prev = null;
Dianne Hackborncbb722e2012-02-07 18:33:49 -08001827 }
Wale Ogunwale07927bf2015-03-28 17:21:05 -07001828 // It is possible the activity was freezing the screen before it was paused.
1829 // In that case go ahead and remove the freeze this activity has on the screen
1830 // since it is no longer visible.
Wale Ogunwalee8524002016-09-13 16:34:57 -07001831 if (prev != null) {
1832 prev.stopFreezingScreenLocked(true /*force*/);
1833 }
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08001834 mPausingActivity = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001835 }
Dianne Hackborncbb722e2012-02-07 18:33:49 -08001836
Dianne Hackborna4e102e2014-09-04 22:52:27 -07001837 if (resumeNext) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001838 final ActivityStack topStack = mRootActivityContainer.getTopDisplayFocusedStack();
David Stevens9440dc82017-03-16 19:00:20 -07001839 if (!topStack.shouldSleepOrShutDownActivities()) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001840 mRootActivityContainer.resumeFocusedStacksTopActivities(topStack, prev, null);
Dianne Hackborna4e102e2014-09-04 22:52:27 -07001841 } else {
David Stevens9440dc82017-03-16 19:00:20 -07001842 checkReadyForSleep();
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -07001843 ActivityRecord top = topStack.topRunningActivityLocked();
Dianne Hackborna4e102e2014-09-04 22:52:27 -07001844 if (top == null || (prev != null && top != prev)) {
Wale Ogunwaled046a012015-12-24 13:05:59 -08001845 // If there are no more activities available to run, do resume anyway to start
1846 // something. Also if the top activity on the stack is not the just paused
1847 // activity, we need to go ahead and resume it to ensure we complete an
1848 // in-flight app switch.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001849 mRootActivityContainer.resumeFocusedStacksTopActivities();
Dianne Hackborna4e102e2014-09-04 22:52:27 -07001850 }
Dianne Hackborn42e620c2012-06-24 13:20:51 -07001851 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001852 }
Craig Mautneraab647e2013-02-28 16:31:36 -08001853
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08001854 if (prev != null) {
1855 prev.resumeKeyDispatchingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001856
Louis Chang1bb884a2018-10-08 19:29:18 +08001857 if (prev.hasProcess() && prev.cpuTimeAtResume > 0) {
1858 final long diff = prev.app.getCpuTime() - prev.cpuTimeAtResume;
1859 if (diff > 0) {
1860 final Runnable r = PooledLambda.obtainRunnable(
1861 ActivityManagerInternal::updateForegroundTimeIfOnBattery,
1862 mService.mAmInternal, prev.info.packageName,
1863 prev.info.applicationInfo.uid,
1864 diff);
1865 mService.mH.post(r);
1866 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001867 }
Craig Mautner525f3d92013-05-07 14:01:50 -07001868 prev.cpuTimeAtResume = 0; // reset it
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001869 }
Winson Chung740c3ac2014-11-12 16:14:38 -08001870
Andrii Kulian8290f8f2016-06-30 17:51:32 -07001871 // Notify when the task stack has changed, but only if visibilities changed (not just
1872 // focus). Also if there is an active pinned stack - we always want to notify it about
1873 // task stack changes, because its positioning may depend on it.
1874 if (mStackSupervisor.mAppVisibilitiesChangedSinceLastPause
Louis Chang24f7a032018-12-11 10:49:48 +08001875 || (getDisplay() != null && getDisplay().hasPinnedStack())) {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001876 mService.getTaskChangeNotificationController().notifyTaskStackChanged();
Jorim Jaggia0fdeec2016-01-07 14:42:28 +01001877 mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = false;
1878 }
Wale Ogunwale5658e4b2016-02-12 12:22:19 -08001879
Wale Ogunwaled32da472018-11-16 07:19:28 -08001880 mRootActivityContainer.ensureActivitiesVisible(resuming, 0, !PRESERVE_WINDOWS);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001881 }
1882
wilsonshih401e50f2019-04-30 12:55:48 +08001883 private void addToStopping(ActivityRecord r, boolean scheduleIdle, boolean idleDelayed,
1884 String reason) {
Chong Zhang46b1ac62016-02-18 17:53:57 -08001885 if (!mStackSupervisor.mStoppingActivities.contains(r)) {
wilsonshih401e50f2019-04-30 12:55:48 +08001886 EventLog.writeEvent(EventLogTags.AM_ADD_TO_STOPPING, r.mUserId,
1887 System.identityHashCode(r), r.shortComponentName, reason);
Chong Zhang46b1ac62016-02-18 17:53:57 -08001888 mStackSupervisor.mStoppingActivities.add(r);
1889 }
1890
1891 // If we already have a few activities waiting to stop, then give up
1892 // on things going idle and start clearing them out. Or if r is the
1893 // last of activity of the last task the stack will be empty and must
1894 // be cleared immediately.
1895 boolean forceIdle = mStackSupervisor.mStoppingActivities.size() > MAX_STOPPING_TO_FORCE
1896 || (r.frontOfTask && mTaskHistory.size() <= 1);
Winson Chung4dabf232017-01-25 13:25:22 -08001897 if (scheduleIdle || forceIdle) {
Chong Zhang46b1ac62016-02-18 17:53:57 -08001898 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Scheduling idle now: forceIdle="
Winson Chung4dabf232017-01-25 13:25:22 -08001899 + forceIdle + "immediate=" + !idleDelayed);
1900 if (!idleDelayed) {
1901 mStackSupervisor.scheduleIdleLocked();
1902 } else {
1903 mStackSupervisor.scheduleIdleTimeoutLocked(r);
1904 }
Filip Gruszczynskief2f72b2015-12-04 14:52:25 -08001905 } else {
David Stevens9440dc82017-03-16 19:00:20 -07001906 checkReadyForSleep();
Filip Gruszczynskief2f72b2015-12-04 14:52:25 -08001907 }
1908 }
1909
Wale Ogunwale8051c5c2016-03-04 10:27:32 -08001910 /**
1911 * Returns true if the stack is translucent and can have other contents visible behind it if
1912 * needed. A stack is considered translucent if it don't contain a visible or
1913 * starting (about to be visible) activity that is fullscreen (opaque).
1914 * @param starting The currently starting activity or null if there is none.
1915 */
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -07001916 @VisibleForTesting
Wale Ogunwale66e16852017-10-19 13:35:52 -07001917 boolean isStackTranslucent(ActivityRecord starting) {
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -07001918 if (!isAttached() || mForceHidden) {
1919 return true;
1920 }
Wale Ogunwale8051c5c2016-03-04 10:27:32 -08001921 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
1922 final TaskRecord task = mTaskHistory.get(taskNdx);
Wale Ogunwale1e3523c2015-09-16 13:11:10 -07001923 final ArrayList<ActivityRecord> activities = task.mActivities;
1924 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
1925 final ActivityRecord r = activities.get(activityNdx);
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -07001926
Wale Ogunwale56d75cf2016-03-09 15:14:47 -08001927 if (r.finishing) {
1928 // We don't factor in finishing activities when determining translucency since
1929 // they will be gone soon.
1930 continue;
1931 }
1932
Wale Ogunwale2cca8622017-12-11 08:40:13 -08001933 if (!r.visibleIgnoringKeyguard && r != starting) {
Wale Ogunwale56d75cf2016-03-09 15:14:47 -08001934 // Also ignore invisible activities that are not the currently starting
1935 // activity (about to be visible).
1936 continue;
1937 }
1938
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -07001939 if (r.fullscreen || r.hasWallpaper) {
Wale Ogunwale56d75cf2016-03-09 15:14:47 -08001940 // Stack isn't translucent if it has at least one fullscreen activity
1941 // that is visible.
1942 return false;
1943 }
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -07001944 }
1945 }
Wale Ogunwale1e3523c2015-09-16 13:11:10 -07001946 return true;
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -07001947 }
1948
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07001949 boolean isTopStackOnDisplay() {
Andrii Kulian52d255c2018-07-13 11:32:19 -07001950 final ActivityDisplay display = getDisplay();
1951 return display != null && display.isTopStack(this);
1952 }
1953
1954 /**
1955 * @return {@code true} if this is the focused stack on its current display, {@code false}
1956 * otherwise.
1957 */
1958 boolean isFocusedStackOnDisplay() {
1959 final ActivityDisplay display = getDisplay();
1960 return display != null && this == display.getFocusedStack();
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07001961 }
1962
Adrian Roosa6d6aab2018-04-19 18:58:22 +02001963 boolean isTopActivityVisible() {
1964 final ActivityRecord topActivity = getTopActivity();
1965 return topActivity != null && topActivity.visible;
1966 }
1967
Filip Gruszczynski0e381e22016-01-14 16:31:33 -08001968 /**
Wale Ogunwale9dcf9462017-09-19 15:13:01 -07001969 * Returns true if the stack should be visible.
Wale Ogunwalecd501ec2017-04-07 08:53:41 -07001970 *
Wale Ogunwale8051c5c2016-03-04 10:27:32 -08001971 * @param starting The currently starting activity or null if there is none.
Filip Gruszczynski0e381e22016-01-14 16:31:33 -08001972 */
Wale Ogunwale9dcf9462017-09-19 15:13:01 -07001973 boolean shouldBeVisible(ActivityRecord starting) {
Andrii Kulian0c869cc2019-02-06 19:50:32 -08001974 return getVisibility(starting) != STACK_VISIBILITY_INVISIBLE;
1975 }
1976
1977 /**
1978 * Returns true if the stack should be visible.
1979 *
1980 * @param starting The currently starting activity or null if there is none.
1981 */
1982 @StackVisibility
1983 int getVisibility(ActivityRecord starting) {
Winson Chung47900652017-04-06 18:44:25 -07001984 if (!isAttached() || mForceHidden) {
Andrii Kulian0c869cc2019-02-06 19:50:32 -08001985 return STACK_VISIBILITY_INVISIBLE;
Jose Lima7ba71252014-04-30 12:59:27 -07001986 }
Wale Ogunwale99db1862015-10-23 20:08:22 -07001987
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -07001988 final ActivityDisplay display = getDisplay();
Wale Ogunwale8e923af2018-03-23 08:48:11 -07001989 boolean gotSplitScreenStack = false;
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -07001990 boolean gotOpaqueSplitScreenPrimary = false;
1991 boolean gotOpaqueSplitScreenSecondary = false;
Andrii Kulian0c869cc2019-02-06 19:50:32 -08001992 boolean gotTranslucentFullscreen = false;
1993 boolean gotTranslucentSplitScreenPrimary = false;
1994 boolean gotTranslucentSplitScreenSecondary = false;
1995 boolean shouldBeVisible = true;
Wale Ogunwale68278562017-09-23 17:13:55 -07001996 final int windowingMode = getWindowingMode();
Wale Ogunwale8e923af2018-03-23 08:48:11 -07001997 final boolean isAssistantType = isActivityTypeAssistant();
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -07001998 for (int i = display.getChildCount() - 1; i >= 0; --i) {
1999 final ActivityStack other = display.getChildAt(i);
Louis Changf2835df2018-10-17 15:14:45 +08002000 final boolean hasRunningActivities = other.topRunningActivityLocked() != null;
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -07002001 if (other == this) {
Louis Changf2835df2018-10-17 15:14:45 +08002002 // Should be visible if there is no other stack occluding it, unless it doesn't
2003 // have any running activities, not starting one and not home stack.
Andrii Kulian0c869cc2019-02-06 19:50:32 -08002004 shouldBeVisible = hasRunningActivities || isInStackLocked(starting) != null
Louis Changf2835df2018-10-17 15:14:45 +08002005 || isActivityTypeHome();
Andrii Kulian0c869cc2019-02-06 19:50:32 -08002006 break;
Louis Changf2835df2018-10-17 15:14:45 +08002007 }
2008
2009 if (!hasRunningActivities) {
2010 continue;
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -07002011 }
Wale Ogunwale68278562017-09-23 17:13:55 -07002012
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -07002013 final int otherWindowingMode = other.getWindowingMode();
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -07002014
2015 if (otherWindowingMode == WINDOWING_MODE_FULLSCREEN) {
Matthew Ng99b3cdc2018-05-01 14:24:38 -07002016 // In this case the home stack isn't resizeable even though we are in split-screen
2017 // mode. We still want the primary splitscreen stack to be visible as there will be
2018 // a slight hint of it in the status bar area above the non-resizeable home
Matthew Nga51dcaa2018-05-07 15:36:06 -07002019 // activity. In addition, if the fullscreen assistant is over primary splitscreen
2020 // stack, the stack should still be visible in the background as long as the recents
2021 // animation is running.
2022 final int activityType = other.getActivityType();
2023 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
2024 if (activityType == ACTIVITY_TYPE_HOME
2025 || (activityType == ACTIVITY_TYPE_ASSISTANT
Andrii Kulian0c869cc2019-02-06 19:50:32 -08002026 && mWindowManager.getRecentsAnimationController() != null)) {
2027 break;
Matthew Nga51dcaa2018-05-07 15:36:06 -07002028 }
Matthew Ng99b3cdc2018-05-01 14:24:38 -07002029 }
Wale Ogunwale66e16852017-10-19 13:35:52 -07002030 if (other.isStackTranslucent(starting)) {
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -07002031 // Can be visible behind a translucent fullscreen stack.
Andrii Kulian0c869cc2019-02-06 19:50:32 -08002032 gotTranslucentFullscreen = true;
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -07002033 continue;
2034 }
Andrii Kulian0c869cc2019-02-06 19:50:32 -08002035 return STACK_VISIBILITY_INVISIBLE;
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -07002036 } else if (otherWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
2037 && !gotOpaqueSplitScreenPrimary) {
Wale Ogunwale8e923af2018-03-23 08:48:11 -07002038 gotSplitScreenStack = true;
Andrii Kulian0c869cc2019-02-06 19:50:32 -08002039 gotTranslucentSplitScreenPrimary = other.isStackTranslucent(starting);
2040 gotOpaqueSplitScreenPrimary = !gotTranslucentSplitScreenPrimary;
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -07002041 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
2042 && gotOpaqueSplitScreenPrimary) {
2043 // Can not be visible behind another opaque stack in split-screen-primary mode.
Andrii Kulian0c869cc2019-02-06 19:50:32 -08002044 return STACK_VISIBILITY_INVISIBLE;
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -07002045 }
2046 } else if (otherWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
2047 && !gotOpaqueSplitScreenSecondary) {
Wale Ogunwale8e923af2018-03-23 08:48:11 -07002048 gotSplitScreenStack = true;
Andrii Kulian0c869cc2019-02-06 19:50:32 -08002049 gotTranslucentSplitScreenSecondary = other.isStackTranslucent(starting);
2050 gotOpaqueSplitScreenSecondary = !gotTranslucentSplitScreenSecondary;
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -07002051 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
2052 && gotOpaqueSplitScreenSecondary) {
2053 // Can not be visible behind another opaque stack in split-screen-secondary mode.
Andrii Kulian0c869cc2019-02-06 19:50:32 -08002054 return STACK_VISIBILITY_INVISIBLE;
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -07002055 }
2056 }
2057 if (gotOpaqueSplitScreenPrimary && gotOpaqueSplitScreenSecondary) {
2058 // Can not be visible if we are in split-screen windowing mode and both halves of
2059 // the screen are opaque.
Andrii Kulian0c869cc2019-02-06 19:50:32 -08002060 return STACK_VISIBILITY_INVISIBLE;
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -07002061 }
Wale Ogunwale8e923af2018-03-23 08:48:11 -07002062 if (isAssistantType && gotSplitScreenStack) {
2063 // Assistant stack can't be visible behind split-screen. In addition to this not
2064 // making sense, it also works around an issue here we boost the z-order of the
2065 // assistant window surfaces in window manager whenever it is visible.
Andrii Kulian0c869cc2019-02-06 19:50:32 -08002066 return STACK_VISIBILITY_INVISIBLE;
Wale Ogunwale8e923af2018-03-23 08:48:11 -07002067 }
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -07002068 }
2069
Andrii Kulian0c869cc2019-02-06 19:50:32 -08002070 if (!shouldBeVisible) {
2071 return STACK_VISIBILITY_INVISIBLE;
2072 }
2073
2074 // Handle cases when there can be a translucent split-screen stack on top.
2075 switch (windowingMode) {
2076 case WINDOWING_MODE_FULLSCREEN:
2077 if (gotTranslucentSplitScreenPrimary || gotTranslucentSplitScreenSecondary) {
2078 // At least one of the split-screen stacks that covers this one is translucent.
2079 return STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT;
2080 }
2081 break;
2082 case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
2083 if (gotTranslucentSplitScreenPrimary) {
2084 // Covered by translucent primary split-screen on top.
2085 return STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT;
2086 }
2087 break;
2088 case WINDOWING_MODE_SPLIT_SCREEN_SECONDARY:
2089 if (gotTranslucentSplitScreenSecondary) {
2090 // Covered by translucent secondary split-screen on top.
2091 return STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT;
2092 }
2093 break;
2094 }
2095
2096 // Lastly - check if there is a translucent fullscreen stack on top.
2097 return gotTranslucentFullscreen ? STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT
2098 : STACK_VISIBILITY_VISIBLE;
Wale Ogunwale68278562017-09-23 17:13:55 -07002099 }
2100
Chong Zhangfdcc4d42015-10-14 16:50:12 -07002101 final int rankTaskLayers(int baseLayer) {
2102 int layer = 0;
2103 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
2104 final TaskRecord task = mTaskHistory.get(taskNdx);
2105 ActivityRecord r = task.topRunningActivityLocked();
2106 if (r == null || r.finishing || !r.visible) {
2107 task.mLayerRank = -1;
2108 } else {
2109 task.mLayerRank = baseLayer + layer++;
2110 }
2111 }
2112 return layer;
2113 }
2114
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002115 /**
Andrii Kulianf4479ee2018-05-23 17:52:48 -07002116 * Make sure that all activities that need to be visible in the stack (that is, they
2117 * currently can be seen by the user) actually are and update their configuration.
2118 */
2119 final void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
2120 boolean preserveWindows) {
2121 ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows,
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07002122 true /* notifyClients */);
Andrii Kulianf4479ee2018-05-23 17:52:48 -07002123 }
2124
2125 /**
2126 * Ensure visibility with an option to also update the configuration of visible activities.
2127 * @see #ensureActivitiesVisibleLocked(ActivityRecord, int, boolean)
Wale Ogunwaled32da472018-11-16 07:19:28 -08002128 * @see RootActivityContainer#ensureActivitiesVisible(ActivityRecord, int, boolean)
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002129 */
Wale Ogunwale66e16852017-10-19 13:35:52 -07002130 // TODO: Should be re-worked based on the fact that each task as a stack in most cases.
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -07002131 final void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07002132 boolean preserveWindows, boolean notifyClients) {
Jorim Jaggife762342016-10-13 14:33:27 +02002133 mTopActivityOccludesKeyguard = false;
2134 mTopDismissingKeyguardActivity = null;
Bryce Lee2a3cc462017-10-27 10:57:35 -07002135 mStackSupervisor.getKeyguardController().beginActivityVisibilityUpdate();
Jorim Jaggife762342016-10-13 14:33:27 +02002136 try {
2137 ActivityRecord top = topRunningActivityLocked();
2138 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "ensureActivitiesVisible behind " + top
2139 + " configChanges=0x" + Integer.toHexString(configChanges));
2140 if (top != null) {
2141 checkTranslucentActivityWaiting(top);
2142 }
Craig Mautner5eda9b32013-07-02 11:58:16 -07002143
Jorim Jaggife762342016-10-13 14:33:27 +02002144 // If the top activity is not fullscreen, then we need to
2145 // make sure any activities under it are now visible.
2146 boolean aboveTop = top != null;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002147 final boolean stackShouldBeVisible = shouldBeVisible(starting);
2148 boolean behindFullscreenActivity = !stackShouldBeVisible;
Andrii Kulian6b321512019-01-23 06:37:00 +00002149 boolean resumeNextActivity = isFocusable() && isInStackLocked(starting) == null;
Jorim Jaggife762342016-10-13 14:33:27 +02002150 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
2151 final TaskRecord task = mTaskHistory.get(taskNdx);
2152 final ArrayList<ActivityRecord> activities = task.mActivities;
2153 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2154 final ActivityRecord r = activities.get(activityNdx);
2155 if (r.finishing) {
Jorim Jaggife762342016-10-13 14:33:27 +02002156 continue;
Chong Zhang22bc8512016-04-07 13:47:18 -07002157 }
Jorim Jaggife762342016-10-13 14:33:27 +02002158 final boolean isTop = r == top;
2159 if (aboveTop && !isTop) {
2160 continue;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002161 }
Jorim Jaggife762342016-10-13 14:33:27 +02002162 aboveTop = false;
Craig Mautnerd44711d2013-02-23 11:24:36 -08002163
Jorim Jaggife762342016-10-13 14:33:27 +02002164 // Check whether activity should be visible without Keyguard influence
Jorim Jaggi241ae102016-11-02 21:57:33 -07002165 final boolean visibleIgnoringKeyguard = r.shouldBeVisibleIgnoringKeyguard(
Jorim Jaggi241ae102016-11-02 21:57:33 -07002166 behindFullscreenActivity);
Garfield Tan47e576c2019-01-28 10:26:23 -08002167 final boolean reallyVisible = r.shouldBeVisible(behindFullscreenActivity);
Jorim Jaggi241ae102016-11-02 21:57:33 -07002168 if (visibleIgnoringKeyguard) {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002169 behindFullscreenActivity = updateBehindFullscreen(!stackShouldBeVisible,
Wale Ogunwale66e16852017-10-19 13:35:52 -07002170 behindFullscreenActivity, r);
Jorim Jaggife762342016-10-13 14:33:27 +02002171 }
2172 if (reallyVisible) {
2173 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make visible? " + r
Bryce Lee7ace3952018-02-16 14:34:32 -08002174 + " finishing=" + r.finishing + " state=" + r.getState());
Jorim Jaggife762342016-10-13 14:33:27 +02002175 // First: if this is not the current activity being started, make
2176 // sure it matches the current configuration.
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07002177 if (r != starting && notifyClients) {
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -08002178 r.ensureActivityConfiguration(0 /* globalChanges */, preserveWindows,
2179 true /* ignoreStopState */);
Jorim Jaggife762342016-10-13 14:33:27 +02002180 }
2181
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002182 if (!r.attachedToProcess()) {
Jorim Jaggife762342016-10-13 14:33:27 +02002183 if (makeVisibleAndRestartIfNeeded(starting, configChanges, isTop,
2184 resumeNextActivity, r)) {
2185 if (activityNdx >= activities.size()) {
2186 // Record may be removed if its process needs to restart.
2187 activityNdx = activities.size() - 1;
2188 } else {
2189 resumeNextActivity = false;
2190 }
2191 }
2192 } else if (r.visible) {
2193 // If this activity is already visible, then there is nothing to do here.
2194 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
2195 "Skipping: already visible at " + r);
2196
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07002197 if (r.mClientVisibilityDeferred && notifyClients) {
2198 r.makeClientVisible();
2199 }
2200
Jorim Jaggife762342016-10-13 14:33:27 +02002201 if (r.handleAlreadyVisible()) {
Wale Ogunwaled046a012015-12-24 13:05:59 -08002202 resumeNextActivity = false;
riddle_hsu36ee73d2015-06-05 16:38:38 +08002203 }
Andrii Kulian6b321512019-01-23 06:37:00 +00002204
2205 if (notifyClients) {
2206 r.makeActiveIfNeeded(starting);
2207 }
Jorim Jaggife762342016-10-13 14:33:27 +02002208 } else {
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07002209 r.makeVisibleIfNeeded(starting, notifyClients);
Craig Mautnerd44711d2013-02-23 11:24:36 -08002210 }
Jorim Jaggife762342016-10-13 14:33:27 +02002211 // Aggregate current change flags.
2212 configChanges |= r.configChangeFlags;
Craig Mautnerbb742462014-07-07 15:28:55 -07002213 } else {
Jorim Jaggife762342016-10-13 14:33:27 +02002214 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make invisible? " + r
Bryce Lee7ace3952018-02-16 14:34:32 -08002215 + " finishing=" + r.finishing + " state=" + r.getState()
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002216 + " stackShouldBeVisible=" + stackShouldBeVisible
Wale Ogunwale9dcf9462017-09-19 15:13:01 -07002217 + " behindFullscreenActivity=" + behindFullscreenActivity
2218 + " mLaunchTaskBehind=" + r.mLaunchTaskBehind);
Wale Ogunwalec981ad52017-06-13 11:40:06 -07002219 makeInvisible(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002220 }
Jorim Jaggife762342016-10-13 14:33:27 +02002221 }
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002222 final int windowingMode = getWindowingMode();
2223 if (windowingMode == WINDOWING_MODE_FREEFORM) {
Jorim Jaggife762342016-10-13 14:33:27 +02002224 // The visibility of tasks and the activities they contain in freeform stack are
2225 // determined individually unlike other stacks where the visibility or fullscreen
2226 // status of an activity in a previous task affects other.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002227 behindFullscreenActivity = !stackShouldBeVisible;
Wale Ogunwale68278562017-09-23 17:13:55 -07002228 } else if (isActivityTypeHome()) {
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07002229 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Home task: at " + task
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002230 + " stackShouldBeVisible=" + stackShouldBeVisible
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07002231 + " behindFullscreenActivity=" + behindFullscreenActivity);
2232 // No other task in the home stack should be visible behind the home activity.
2233 // Home activities is usually a translucent activity with the wallpaper behind
2234 // them. However, when they don't have the wallpaper behind them, we want to
2235 // show activities in the next application stack behind them vs. another
2236 // task in the home stack like recents.
2237 behindFullscreenActivity = true;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002238 }
2239 }
Wale Ogunwale74e26592016-02-05 11:48:37 -08002240
Jorim Jaggife762342016-10-13 14:33:27 +02002241 if (mTranslucentActivityWaiting != null &&
2242 mUndrawnActivitiesBelowTopTranslucent.isEmpty()) {
2243 // Nothing is getting drawn or everything was already visible, don't wait for timeout.
2244 notifyActivityDrawnLocked(null);
2245 }
2246 } finally {
Bryce Lee2a3cc462017-10-27 10:57:35 -07002247 mStackSupervisor.getKeyguardController().endActivityVisibilityUpdate();
Jorim Jaggife762342016-10-13 14:33:27 +02002248 }
2249 }
2250
Jorim Jaggi8b702ed2017-01-20 16:59:03 +01002251 void addStartingWindowsForVisibleActivities(boolean taskSwitch) {
2252 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
2253 mTaskHistory.get(taskNdx).addStartingWindowsForVisibleActivities(taskSwitch);
2254 }
2255 }
2256
Jorim Jaggife762342016-10-13 14:33:27 +02002257 /**
2258 * @return true if the top visible activity wants to occlude the Keyguard, false otherwise
2259 */
2260 boolean topActivityOccludesKeyguard() {
2261 return mTopActivityOccludesKeyguard;
2262 }
2263
2264 /**
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002265 * Returns true if this stack should be resized to match the bounds specified by
2266 * {@link ActivityOptions#setLaunchBounds} when launching an activity into the stack.
2267 */
2268 boolean resizeStackWithLaunchBounds() {
2269 return inPinnedWindowingMode();
2270 }
2271
Wale Ogunwale30e441d2017-11-09 08:28:45 -08002272 @Override
2273 public boolean supportsSplitScreenWindowingMode() {
2274 final TaskRecord topTask = topTask();
2275 return super.supportsSplitScreenWindowingMode()
2276 && (topTask == null || topTask.supportsSplitScreenWindowingMode());
2277 }
2278
Wale Ogunwale2b07da82017-11-08 14:52:40 -08002279 /** @return True if the resizing of the primary-split-screen stack affects this stack size. */
2280 boolean affectedBySplitScreenResize() {
2281 if (!supportsSplitScreenWindowingMode()) {
2282 return false;
2283 }
2284 final int windowingMode = getWindowingMode();
2285 return windowingMode != WINDOWING_MODE_FREEFORM && windowingMode != WINDOWING_MODE_PINNED;
2286 }
2287
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002288 /**
Jorim Jaggife762342016-10-13 14:33:27 +02002289 * @return the top most visible activity that wants to dismiss Keyguard
2290 */
2291 ActivityRecord getTopDismissingKeyguardActivity() {
2292 return mTopDismissingKeyguardActivity;
2293 }
2294
2295 /**
2296 * Checks whether {@param r} should be visible depending on Keyguard state and updates
2297 * {@link #mTopActivityOccludesKeyguard} and {@link #mTopDismissingKeyguardActivity} if
2298 * necessary.
2299 *
2300 * @return true if {@param r} is visible taken Keyguard state into account, false otherwise
2301 */
Wale Ogunwale2cca8622017-12-11 08:40:13 -08002302 boolean checkKeyguardVisibility(ActivityRecord r, boolean shouldBeVisible, boolean isTop) {
Lucas Dupin47a65c72018-02-15 14:16:18 -08002303 final int displayId = mDisplayId != INVALID_DISPLAY ? mDisplayId : DEFAULT_DISPLAY;
2304 final boolean keyguardOrAodShowing = mStackSupervisor.getKeyguardController()
2305 .isKeyguardOrAodShowing(displayId);
Bryce Lee2a3cc462017-10-27 10:57:35 -07002306 final boolean keyguardLocked = mStackSupervisor.getKeyguardController().isKeyguardLocked();
Wale Ogunwale2cca8622017-12-11 08:40:13 -08002307 final boolean showWhenLocked = r.canShowWhenLocked();
Issei Suzuki74e1eb22018-12-20 17:42:52 +01002308 final boolean dismissKeyguard = r.mAppWindowToken != null
2309 && r.mAppWindowToken.containsDismissKeyguardWindow();
Jorim Jaggife762342016-10-13 14:33:27 +02002310 if (shouldBeVisible) {
Jorim Jaggie69c9312016-10-31 18:24:38 -07002311 if (dismissKeyguard && mTopDismissingKeyguardActivity == null) {
Jorim Jaggife762342016-10-13 14:33:27 +02002312 mTopDismissingKeyguardActivity = r;
2313 }
2314
2315 // Only the top activity may control occluded, as we can't occlude the Keyguard if the
2316 // top app doesn't want to occlude it.
2317 if (isTop) {
2318 mTopActivityOccludesKeyguard |= showWhenLocked;
Wale Ogunwalec219c0b2015-09-12 09:18:07 -07002319 }
Andrii Kulianfc8f82b2017-01-26 13:17:27 -08002320
Andrii Kulian7211d2e2017-01-27 15:58:05 -08002321 final boolean canShowWithKeyguard = canShowWithInsecureKeyguard()
Bryce Lee2a3cc462017-10-27 10:57:35 -07002322 && mStackSupervisor.getKeyguardController().canDismissKeyguard();
Andrii Kulianfc8f82b2017-01-26 13:17:27 -08002323 if (canShowWithKeyguard) {
2324 return true;
2325 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002326 }
Lucas Dupin47a65c72018-02-15 14:16:18 -08002327 if (keyguardOrAodShowing) {
Jorim Jaggie69c9312016-10-31 18:24:38 -07002328 // If keyguard is showing, nothing is visible, except if we are able to dismiss Keyguard
Lucas Dupin47a65c72018-02-15 14:16:18 -08002329 // right away and AOD isn't visible.
Bryce Lee2a3cc462017-10-27 10:57:35 -07002330 return shouldBeVisible && mStackSupervisor.getKeyguardController()
Jorim Jaggi07961872016-11-23 11:28:57 +01002331 .canShowActivityWhileKeyguardShowing(r, dismissKeyguard);
Jorim Jaggife762342016-10-13 14:33:27 +02002332 } else if (keyguardLocked) {
Bryce Lee2a3cc462017-10-27 10:57:35 -07002333 return shouldBeVisible && mStackSupervisor.getKeyguardController().canShowWhileOccluded(
Jorim Jaggi07961872016-11-23 11:28:57 +01002334 dismissKeyguard, showWhenLocked);
Jorim Jaggife762342016-10-13 14:33:27 +02002335 } else {
2336 return shouldBeVisible;
Craig Mautnereb8abf72014-07-02 15:04:09 -07002337 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002338 }
Craig Mautner58547802013-03-05 08:23:53 -08002339
Andrii Kulianfc8f82b2017-01-26 13:17:27 -08002340 /**
2341 * Check if the display to which this stack is attached has
Andrii Kulian7211d2e2017-01-27 15:58:05 -08002342 * {@link Display#FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD} applied.
Andrii Kulianfc8f82b2017-01-26 13:17:27 -08002343 */
wilsonshih498a4b82018-12-11 16:10:16 +08002344 boolean canShowWithInsecureKeyguard() {
Wale Ogunwale9dcf9462017-09-19 15:13:01 -07002345 final ActivityDisplay activityDisplay = getDisplay();
Andrii Kulianfc8f82b2017-01-26 13:17:27 -08002346 if (activityDisplay == null) {
2347 throw new IllegalStateException("Stack is not attached to any display, stackId="
2348 + mStackId);
2349 }
2350
2351 final int flags = activityDisplay.mDisplay.getFlags();
Andrii Kulian7211d2e2017-01-27 15:58:05 -08002352 return (flags & FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0;
Andrii Kulianfc8f82b2017-01-26 13:17:27 -08002353 }
2354
Filip Gruszczynski9104aea2015-11-13 16:42:05 -08002355 private void checkTranslucentActivityWaiting(ActivityRecord top) {
2356 if (mTranslucentActivityWaiting != top) {
2357 mUndrawnActivitiesBelowTopTranslucent.clear();
2358 if (mTranslucentActivityWaiting != null) {
2359 // Call the callback with a timeout indication.
2360 notifyActivityDrawnLocked(null);
2361 mTranslucentActivityWaiting = null;
2362 }
2363 mHandler.removeMessages(TRANSLUCENT_TIMEOUT_MSG);
2364 }
2365 }
2366
2367 private boolean makeVisibleAndRestartIfNeeded(ActivityRecord starting, int configChanges,
Wale Ogunwaled046a012015-12-24 13:05:59 -08002368 boolean isTop, boolean andResume, ActivityRecord r) {
Filip Gruszczynski9104aea2015-11-13 16:42:05 -08002369 // We need to make sure the app is running if it's the top, or it is just made visible from
2370 // invisible. If the app is already visible, it must have died while it was visible. In this
2371 // case, we'll show the dead window but will not restart the app. Otherwise we could end up
2372 // thrashing.
Filip Gruszczynski21199bd2015-12-02 12:49:58 -08002373 if (isTop || !r.visible) {
Filip Gruszczynski9104aea2015-11-13 16:42:05 -08002374 // This activity needs to be visible, but isn't even running...
2375 // get it started and resume if no other stack in this stack is resumed.
2376 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Start and freeze screen for " + r);
2377 if (r != starting) {
2378 r.startFreezingScreenLocked(r.app, configChanges);
2379 }
2380 if (!r.visible || r.mLaunchTaskBehind) {
2381 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Starting and making visible: " + r);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002382 r.setVisible(true);
Filip Gruszczynski9104aea2015-11-13 16:42:05 -08002383 }
2384 if (r != starting) {
Louis Chang7cf84602019-05-30 15:35:40 +08002385 // We should not resume activities that being launched behind because these
2386 // activities are actually behind other fullscreen activities, but still required
2387 // to be visible (such as performing Recents animation).
2388 mStackSupervisor.startSpecificActivityLocked(r, andResume && !r.mLaunchTaskBehind,
2389 true /* checkConfig */);
Filip Gruszczynski9104aea2015-11-13 16:42:05 -08002390 return true;
2391 }
2392 }
2393 return false;
2394 }
2395
Wale Ogunwalec981ad52017-06-13 11:40:06 -07002396 // TODO: Should probably be moved into ActivityRecord.
2397 private void makeInvisible(ActivityRecord r) {
Filip Gruszczynski9104aea2015-11-13 16:42:05 -08002398 if (!r.visible) {
2399 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Already invisible: " + r);
2400 return;
2401 }
2402 // Now for any activities that aren't visible to the user, make sure they no longer are
2403 // keeping the screen frozen.
Bryce Lee7ace3952018-02-16 14:34:32 -08002404 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Making invisible: " + r + " " + r.getState());
Filip Gruszczynski9104aea2015-11-13 16:42:05 -08002405 try {
Wale Ogunwaleb9a0c992017-04-18 07:25:20 -07002406 final boolean canEnterPictureInPicture = r.checkEnterPictureInPictureState(
Winson Chung298f95b2017-08-10 15:57:18 -07002407 "makeInvisible", true /* beforeStopping */);
Wale Ogunwale08488a62017-09-05 12:37:03 -07002408 // Defer telling the client it is hidden if it can enter Pip and isn't current paused,
2409 // stopped or stopping. This gives it a chance to enter Pip in onPause().
2410 // TODO: There is still a question surrounding activities in multi-window mode that want
2411 // to enter Pip after they are paused, but are still visible. I they should be okay to
2412 // enter Pip in those cases, but not "auto-Pip" which is what this condition covers and
2413 // the current contract for "auto-Pip" is that the app should enter it before onPause
2414 // returns. Just need to confirm this reasoning makes sense.
Wale Ogunwale89973222017-04-23 18:39:45 -07002415 final boolean deferHidingClient = canEnterPictureInPicture
Bryce Lee7ace3952018-02-16 14:34:32 -08002416 && !r.isState(STOPPING, STOPPED, PAUSED);
Wale Ogunwaleec950642017-04-25 07:44:21 -07002417 r.setDeferHidingClient(deferHidingClient);
2418 r.setVisible(false);
Wale Ogunwaleb9a0c992017-04-18 07:25:20 -07002419
Bryce Lee7ace3952018-02-16 14:34:32 -08002420 switch (r.getState()) {
Filip Gruszczynski9104aea2015-11-13 16:42:05 -08002421 case STOPPING:
2422 case STOPPED:
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002423 if (r.attachedToProcess()) {
Filip Gruszczynski9104aea2015-11-13 16:42:05 -08002424 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
2425 "Scheduling invisibility: " + r);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002426 mService.getLifecycleManager().scheduleTransaction(r.app.getThread(),
2427 r.appToken, WindowVisibilityItem.obtain(false /* showWindow */));
Filip Gruszczynski9104aea2015-11-13 16:42:05 -08002428 }
Winson Chungc2baac02017-01-11 13:34:47 -08002429
2430 // Reset the flag indicating that an app can enter picture-in-picture once the
2431 // activity is hidden
Winson Chungf7e03e12017-08-22 11:32:16 -07002432 r.supportsEnterPipOnTaskSwitch = false;
Filip Gruszczynski9104aea2015-11-13 16:42:05 -08002433 break;
2434
2435 case INITIALIZING:
2436 case RESUMED:
2437 case PAUSING:
2438 case PAUSED:
Wale Ogunwalec981ad52017-06-13 11:40:06 -07002439 addToStopping(r, true /* scheduleIdle */,
wilsonshih401e50f2019-04-30 12:55:48 +08002440 canEnterPictureInPicture /* idleDelayed */, "makeInvisible");
Filip Gruszczynski9104aea2015-11-13 16:42:05 -08002441 break;
2442
2443 default:
2444 break;
2445 }
2446 } catch (Exception e) {
2447 // Just skip on any failure; we'll make it visible when it next restarts.
2448 Slog.w(TAG, "Exception thrown making hidden: " + r.intent.getComponent(), e);
2449 }
2450 }
2451
2452 private boolean updateBehindFullscreen(boolean stackInvisible, boolean behindFullscreenActivity,
Wale Ogunwale66e16852017-10-19 13:35:52 -07002453 ActivityRecord r) {
Filip Gruszczynski9104aea2015-11-13 16:42:05 -08002454 if (r.fullscreen) {
Filip Gruszczynski9104aea2015-11-13 16:42:05 -08002455 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Fullscreen: at " + r
Wale Ogunwale673cbd22016-01-30 18:30:55 -08002456 + " stackInvisible=" + stackInvisible
2457 + " behindFullscreenActivity=" + behindFullscreenActivity);
Filip Gruszczynski0e381e22016-01-14 16:31:33 -08002458 // At this point, nothing else needs to be shown in this task.
Filip Gruszczynski9104aea2015-11-13 16:42:05 -08002459 behindFullscreenActivity = true;
Filip Gruszczynski9104aea2015-11-13 16:42:05 -08002460 }
2461 return behindFullscreenActivity;
2462 }
2463
Todd Kennedyaab56db2015-01-30 09:39:53 -08002464 void convertActivityToTranslucent(ActivityRecord r) {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002465 mTranslucentActivityWaiting = r;
2466 mUndrawnActivitiesBelowTopTranslucent.clear();
2467 mHandler.sendEmptyMessageDelayed(TRANSLUCENT_TIMEOUT_MSG, TRANSLUCENT_CONVERSION_TIMEOUT);
2468 }
2469
Dianne Hackbornb5a380d2015-05-20 18:18:46 -07002470 void clearOtherAppTimeTrackers(AppTimeTracker except) {
2471 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
2472 final TaskRecord task = mTaskHistory.get(taskNdx);
2473 final ArrayList<ActivityRecord> activities = task.mActivities;
2474 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2475 final ActivityRecord r = activities.get(activityNdx);
2476 if ( r.appTimeTracker != except) {
2477 r.appTimeTracker = null;
2478 }
2479 }
2480 }
2481 }
2482
Craig Mautner5eda9b32013-07-02 11:58:16 -07002483 /**
2484 * Called as activities below the top translucent activity are redrawn. When the last one is
2485 * redrawn notify the top activity by calling
2486 * {@link Activity#onTranslucentConversionComplete}.
2487 *
2488 * @param r The most recent background activity to be drawn. Or, if r is null then a timeout
2489 * occurred and the activity will be notified immediately.
2490 */
2491 void notifyActivityDrawnLocked(ActivityRecord r) {
2492 if ((r == null)
2493 || (mUndrawnActivitiesBelowTopTranslucent.remove(r) &&
2494 mUndrawnActivitiesBelowTopTranslucent.isEmpty())) {
2495 // The last undrawn activity below the top has just been drawn. If there is an
2496 // opaque activity at the top, notify it that it can become translucent safely now.
2497 final ActivityRecord waitingActivity = mTranslucentActivityWaiting;
2498 mTranslucentActivityWaiting = null;
2499 mUndrawnActivitiesBelowTopTranslucent.clear();
2500 mHandler.removeMessages(TRANSLUCENT_TIMEOUT_MSG);
2501
Craig Mautner71dd1b62014-02-18 15:48:52 -08002502 if (waitingActivity != null) {
2503 mWindowManager.setWindowOpaque(waitingActivity.appToken, false);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002504 if (waitingActivity.attachedToProcess()) {
Craig Mautner71dd1b62014-02-18 15:48:52 -08002505 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002506 waitingActivity.app.getThread().scheduleTranslucentConversionComplete(
Craig Mautner71dd1b62014-02-18 15:48:52 -08002507 waitingActivity.appToken, r != null);
2508 } catch (RemoteException e) {
2509 }
Craig Mautner5eda9b32013-07-02 11:58:16 -07002510 }
2511 }
2512 }
2513 }
2514
Craig Mautnera61bc652013-10-28 15:43:18 -07002515 /** If any activities below the top running one are in the INITIALIZING state and they have a
2516 * starting window displayed then remove that starting window. It is possible that the activity
2517 * in this state will never resumed in which case that starting window will be orphaned. */
2518 void cancelInitializingActivities() {
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -07002519 final ActivityRecord topActivity = topRunningActivityLocked();
Craig Mautnera61bc652013-10-28 15:43:18 -07002520 boolean aboveTop = true;
Wale Ogunwale68741142016-05-17 09:40:02 -07002521 // We don't want to clear starting window for activities that aren't behind fullscreen
2522 // activities as we need to display their starting window until they are done initializing.
2523 boolean behindFullscreenActivity = false;
Wale Ogunwale98742a52016-07-12 10:29:12 -07002524
Wale Ogunwale9dcf9462017-09-19 15:13:01 -07002525 if (!shouldBeVisible(null)) {
Wale Ogunwale98742a52016-07-12 10:29:12 -07002526 // The stack is not visible, so no activity in it should be displaying a starting
2527 // window. Mark all activities below top and behind fullscreen.
2528 aboveTop = false;
2529 behindFullscreenActivity = true;
2530 }
2531
Craig Mautnera61bc652013-10-28 15:43:18 -07002532 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
2533 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
2534 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2535 final ActivityRecord r = activities.get(activityNdx);
2536 if (aboveTop) {
2537 if (r == topActivity) {
2538 aboveTop = false;
2539 }
Wale Ogunwale68741142016-05-17 09:40:02 -07002540 behindFullscreenActivity |= r.fullscreen;
Craig Mautnera61bc652013-10-28 15:43:18 -07002541 continue;
2542 }
2543
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002544 r.removeOrphanedStartingWindow(behindFullscreenActivity);
Wale Ogunwale68741142016-05-17 09:40:02 -07002545 behindFullscreenActivity |= r.fullscreen;
Craig Mautnera61bc652013-10-28 15:43:18 -07002546 }
2547 }
2548 }
2549
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002550 /**
2551 * Ensure that the top activity in the stack is resumed.
2552 *
2553 * @param prev The previously resumed activity, for when in the process
2554 * of pausing; can be null to call from elsewhere.
Wale Ogunwaled046a012015-12-24 13:05:59 -08002555 * @param options Activity options.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002556 *
2557 * @return Returns true if something is being resumed, or false if
2558 * nothing happened.
Wale Ogunwaled046a012015-12-24 13:05:59 -08002559 *
2560 * NOTE: It is not safe to call this method directly as it can cause an activity in a
2561 * non-focused stack to be resumed.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002562 * Use {@link RootActivityContainer#resumeFocusedStacksTopActivities} to resume the
Wale Ogunwaled046a012015-12-24 13:05:59 -08002563 * right activity for the current system state.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002564 */
Andreas Gampea36dc622018-02-05 17:19:22 -08002565 @GuardedBy("mService")
Wale Ogunwaled046a012015-12-24 13:05:59 -08002566 boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
Andrii Kulian6b321512019-01-23 06:37:00 +00002567 if (mInResumeTopActivity) {
Craig Mautner544efa72014-09-04 16:41:20 -07002568 // Don't even start recursing.
2569 return false;
2570 }
2571
2572 boolean result = false;
2573 try {
2574 // Protect against recursion.
Andrii Kulian6b321512019-01-23 06:37:00 +00002575 mInResumeTopActivity = true;
Bryce Lee69ad8182017-09-28 10:01:36 -07002576 result = resumeTopActivityInnerLocked(prev, options);
Bryce Leefc7cedd2018-03-01 15:38:07 -08002577
2578 // When resuming the top activity, it may be necessary to pause the top activity (for
2579 // example, returning to the lock screen. We suppress the normal pause logic in
2580 // {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the
2581 // end. We call the {@link ActivityStackSupervisor#checkReadyForSleepLocked} again here
2582 // to ensure any necessary pause logic occurs. In the case where the Activity will be
2583 // shown regardless of the lock screen, the call to
2584 // {@link ActivityStackSupervisor#checkReadyForSleepLocked} is skipped.
2585 final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
2586 if (next == null || !next.canTurnScreenOn()) {
2587 checkReadyForSleep();
2588 }
Craig Mautner544efa72014-09-04 16:41:20 -07002589 } finally {
Andrii Kulian6b321512019-01-23 06:37:00 +00002590 mInResumeTopActivity = false;
Craig Mautner544efa72014-09-04 16:41:20 -07002591 }
chaviw59b98852017-06-13 12:05:44 -07002592
Craig Mautner544efa72014-09-04 16:41:20 -07002593 return result;
2594 }
2595
Bryce Leec4ab62a2018-03-05 14:19:26 -08002596 /**
2597 * Returns the currently resumed activity.
2598 */
2599 protected ActivityRecord getResumedActivity() {
2600 return mResumedActivity;
2601 }
2602
Bryce Lee84730a02018-04-03 14:10:04 -07002603 private void setResumedActivity(ActivityRecord r, String reason) {
2604 if (mResumedActivity == r) {
2605 return;
2606 }
Bryce Leec4ab62a2018-03-05 14:19:26 -08002607
Bryce Lee84730a02018-04-03 14:10:04 -07002608 if (DEBUG_STACK) Slog.d(TAG_STACK, "setResumedActivity stack:" + this + " + from: "
2609 + mResumedActivity + " to:" + r + " reason:" + reason);
2610 mResumedActivity = r;
Louis Chang3b21bdc2019-03-25 15:49:14 +08002611 mStackSupervisor.updateTopResumedActivityIfNeeded();
Chong Zhang6cda19c2016-06-14 19:07:56 -07002612 }
2613
Andreas Gampea36dc622018-02-05 17:19:22 -08002614 @GuardedBy("mService")
Chong Zhang280d3322015-11-03 17:27:26 -08002615 private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
Wale Ogunwale53783742018-09-16 10:21:51 -07002616 if (!mService.isBooting() && !mService.isBooted()) {
Dianne Hackborn7622a0f2014-09-30 14:31:42 -07002617 // Not ready yet!
2618 return false;
2619 }
2620
Winson Chung3f103eb2017-04-12 21:53:59 -07002621 // Find the next top-most activity to resume in this stack that is not finishing and is
2622 // focusable. If it is not focusable, we will fall into the case below to resume the
2623 // top activity in the next focusable task.
Andrii Kulian6b321512019-01-23 06:37:00 +00002624 ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
Andrii Kulian7fc22812016-12-28 13:04:11 -08002625
2626 final boolean hasRunningActivity = next != null;
2627
Andrii Kulian94e82d9b02017-07-13 15:33:06 -07002628 // TODO: Maybe this entire condition can get removed?
Wale Ogunwale66e16852017-10-19 13:35:52 -07002629 if (hasRunningActivity && !isAttached()) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08002630 return false;
2631 }
2632
Wale Ogunwaled32da472018-11-16 07:19:28 -08002633 mRootActivityContainer.cancelInitializingActivities();
Craig Mautnera61bc652013-10-28 15:43:18 -07002634
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002635 // Remember how we'll process this pause/resume situation, and ensure
2636 // that the state is reset however we wind up proceeding.
Wale Ogunwalec59b4f62017-11-30 11:05:43 -08002637 boolean userLeaving = mStackSupervisor.mUserLeaving;
Craig Mautnerde4ef022013-04-07 19:01:33 -07002638 mStackSupervisor.mUserLeaving = false;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002639
Andrii Kulian7fc22812016-12-28 13:04:11 -08002640 if (!hasRunningActivity) {
2641 // There are no activities left in the stack, let's look somewhere else.
Andrii Kulian3ff5a0b2019-05-16 13:18:04 -07002642 return resumeNextFocusableActivityWhenStackIsEmpty(prev, options);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002643 }
2644
2645 next.delayedResume = false;
Riddle Hsubbb63c22018-10-03 12:28:29 +08002646 final ActivityDisplay display = getDisplay();
Craig Mautner58547802013-03-05 08:23:53 -08002647
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002648 // If the top activity is the resumed one, nothing to do.
Bryce Lee7ace3952018-02-16 14:34:32 -08002649 if (mResumedActivity == next && next.isState(RESUMED)
Riddle Hsubbb63c22018-10-03 12:28:29 +08002650 && display.allResumedActivitiesComplete()) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002651 // Make sure we have executed any pending transitions, since there
2652 // should be nothing left to do at this point.
skuhne@google.com1b974dc2016-12-09 13:41:29 -08002653 executeAppTransition(options);
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07002654 if (DEBUG_STATES) Slog.d(TAG_STATES,
2655 "resumeTopActivityLocked: Top activity resumed " + next);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002656 return false;
2657 }
2658
Louis Chang77ce34d2019-01-03 15:45:12 +08002659 if (!next.canResumeByCompat()) {
2660 return false;
2661 }
2662
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002663 // If we are sleeping, and there is no resumed activity, and the top
2664 // activity is paused, well that is the state we want.
David Stevens9440dc82017-03-16 19:00:20 -07002665 if (shouldSleepOrShutDownActivities()
p13451dbad2872012-04-18 11:39:23 +09002666 && mLastPausedActivity == next
Wale Ogunwaled32da472018-11-16 07:19:28 -08002667 && mRootActivityContainer.allPausedActivitiesComplete()) {
Riddle Hsuef713772018-09-18 01:28:53 +08002668 // If the current top activity may be able to occlude keyguard but the occluded state
2669 // has not been set, update visibility and check again if we should continue to resume.
2670 boolean nothingToResume = true;
Riddle Hsu32a87b82018-11-21 00:08:19 +08002671 if (!mService.mShuttingDown) {
2672 final boolean canShowWhenLocked = !mTopActivityOccludesKeyguard
2673 && next.canShowWhenLocked();
2674 final boolean mayDismissKeyguard = mTopDismissingKeyguardActivity != next
Issei Suzuki74e1eb22018-12-20 17:42:52 +01002675 && next.mAppWindowToken != null
2676 && next.mAppWindowToken.containsDismissKeyguardWindow();
2677
Riddle Hsu32a87b82018-11-21 00:08:19 +08002678 if (canShowWhenLocked || mayDismissKeyguard) {
2679 ensureActivitiesVisibleLocked(null /* starting */, 0 /* configChanges */,
2680 !PRESERVE_WINDOWS);
2681 nothingToResume = shouldSleepActivities();
2682 }
Riddle Hsuef713772018-09-18 01:28:53 +08002683 }
2684 if (nothingToResume) {
2685 // Make sure we have executed any pending transitions, since there
2686 // should be nothing left to do at this point.
2687 executeAppTransition(options);
2688 if (DEBUG_STATES) Slog.d(TAG_STATES,
2689 "resumeTopActivityLocked: Going to sleep and all paused");
Riddle Hsuef713772018-09-18 01:28:53 +08002690 return false;
2691 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002692 }
Dianne Hackborn80a4af22012-08-27 19:18:31 -07002693
2694 // Make sure that the user who owns this activity is started. If not,
2695 // we will just leave it as is because someone should be bringing
2696 // another user's activities to the top of the stack.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002697 if (!mService.mAmInternal.hasStartedUserState(next.mUserId)) {
Dianne Hackborn80a4af22012-08-27 19:18:31 -07002698 Slog.w(TAG, "Skipping resume of top activity " + next
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002699 + ": user " + next.mUserId + " is stopped");
Dianne Hackborn80a4af22012-08-27 19:18:31 -07002700 return false;
2701 }
2702
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002703 // The activity may be waiting for stop, but that is no longer
2704 // appropriate for it.
Craig Mautnerde4ef022013-04-07 19:01:33 -07002705 mStackSupervisor.mStoppingActivities.remove(next);
Craig Mautner0eea92c2013-05-16 13:35:39 -07002706 mStackSupervisor.mGoingToSleepActivities.remove(next);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002707 next.sleeping = false;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002708
Wale Ogunwaleee006da2015-03-30 14:49:25 -07002709 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resuming " + next);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002710
Wale Ogunwale5658e4b2016-02-12 12:22:19 -08002711 // If we are currently pausing an activity, then don't do anything until that is done.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002712 if (!mRootActivityContainer.allPausedActivitiesComplete()) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07002713 if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
Craig Mautnerac6f8432013-07-17 13:24:59 -07002714 "resumeTopActivityLocked: Skip resume: some activity pausing.");
Andrii Kulian6b321512019-01-23 06:37:00 +00002715
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08002716 return false;
2717 }
2718
Dianne Hackborn3d07c942015-03-13 18:02:54 -07002719 mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);
2720
Wale Ogunwale89973222017-04-23 18:39:45 -07002721 boolean lastResumedCanPip = false;
chaviw4ad54912018-05-30 11:05:44 -07002722 ActivityRecord lastResumed = null;
Riddle Hsubbb63c22018-10-03 12:28:29 +08002723 final ActivityStack lastFocusedStack = display.getLastFocusedStack();
Wale Ogunwale89973222017-04-23 18:39:45 -07002724 if (lastFocusedStack != null && lastFocusedStack != this) {
2725 // So, why aren't we using prev here??? See the param comment on the method. prev doesn't
2726 // represent the last resumed activity. However, the last focus stack does if it isn't null.
chaviw4ad54912018-05-30 11:05:44 -07002727 lastResumed = lastFocusedStack.mResumedActivity;
Wale Ogunwalec59b4f62017-11-30 11:05:43 -08002728 if (userLeaving && inMultiWindowMode() && lastFocusedStack.shouldBeVisible(next)) {
2729 // The user isn't leaving if this stack is the multi-window mode and the last
2730 // focused stack should still be visible.
2731 if(DEBUG_USER_LEAVING) Slog.i(TAG_USER_LEAVING, "Overriding userLeaving to false"
2732 + " next=" + next + " lastResumed=" + lastResumed);
2733 userLeaving = false;
2734 }
Wale Ogunwale89973222017-04-23 18:39:45 -07002735 lastResumedCanPip = lastResumed != null && lastResumed.checkEnterPictureInPictureState(
Winson Chung298f95b2017-08-10 15:57:18 -07002736 "resumeTopActivity", userLeaving /* beforeStopping */);
Wale Ogunwale89973222017-04-23 18:39:45 -07002737 }
Winson Chungc2baac02017-01-11 13:34:47 -08002738 // If the flag RESUME_WHILE_PAUSING is set, then continue to schedule the previous activity
Wale Ogunwaleb9a0c992017-04-18 07:25:20 -07002739 // to be paused, while at the same time resuming the new resume activity only if the
2740 // previous activity can't go into Pip since we want to give Pip activities a chance to
2741 // enter Pip before resuming the next activity.
Wale Ogunwale89973222017-04-23 18:39:45 -07002742 final boolean resumeWhilePausing = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0
2743 && !lastResumedCanPip;
2744
Andrii Kulianab132ee2018-07-24 22:10:21 +08002745 boolean pausing = getDisplay().pauseBackStacks(userLeaving, next, false);
Craig Mautnereb957862013-04-24 15:34:32 -07002746 if (mResumedActivity != null) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07002747 if (DEBUG_STATES) Slog.d(TAG_STATES,
2748 "resumeTopActivityLocked: Pausing " + mResumedActivity);
Winson Chungc2baac02017-01-11 13:34:47 -08002749 pausing |= startPausingLocked(userLeaving, false, next, false);
Craig Mautnereb957862013-04-24 15:34:32 -07002750 }
Winson Chungc2baac02017-01-11 13:34:47 -08002751 if (pausing && !resumeWhilePausing) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07002752 if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG_STATES,
Craig Mautnerac6f8432013-07-17 13:24:59 -07002753 "resumeTopActivityLocked: Skip resume: need to start pausing");
Dianne Hackbornad9b32112012-09-17 15:35:01 -07002754 // At this point we want to put the upcoming activity's process
2755 // at the top of the LRU list, since we know we will be needing it
2756 // very soon and it would be a waste to let it get killed if it
2757 // happens to be sitting towards the end.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002758 if (next.attachedToProcess()) {
2759 next.app.updateProcessInfo(false /* updateServiceConnectionActivities */,
Riddle Hsu17e38422019-04-12 16:55:11 +08002760 true /* activityChange */, false /* updateOomAdj */);
Dianne Hackbornad9b32112012-09-17 15:35:01 -07002761 }
chaviw4ad54912018-05-30 11:05:44 -07002762 if (lastResumed != null) {
2763 lastResumed.setWillCloseOrEnterPip(true);
2764 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002765 return true;
Bryce Lee7ace3952018-02-16 14:34:32 -08002766 } else if (mResumedActivity == next && next.isState(RESUMED)
Riddle Hsubbb63c22018-10-03 12:28:29 +08002767 && display.allResumedActivitiesComplete()) {
Wale Ogunwalecac5c322016-05-23 10:56:33 -07002768 // It is possible for the activity to be resumed when we paused back stacks above if the
2769 // next activity doesn't have to wait for pause to complete.
2770 // So, nothing else to-do except:
2771 // Make sure we have executed any pending transitions, since there
2772 // should be nothing left to do at this point.
skuhne@google.com1b974dc2016-12-09 13:41:29 -08002773 executeAppTransition(options);
Wale Ogunwalecac5c322016-05-23 10:56:33 -07002774 if (DEBUG_STATES) Slog.d(TAG_STATES,
2775 "resumeTopActivityLocked: Top activity resumed (dontWaitForPause) " + next);
Wale Ogunwalecac5c322016-05-23 10:56:33 -07002776 return true;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002777 }
2778
Christopher Tated3f175c2012-06-14 14:16:54 -07002779 // If the most recent activity was noHistory but was only stopped rather
2780 // than stopped+finished because the device went to sleep, we need to make
2781 // sure to finish it as we're making a new activity topmost.
David Stevens9440dc82017-03-16 19:00:20 -07002782 if (shouldSleepActivities() && mLastNoHistoryActivity != null &&
Craig Mautner0f922742013-08-06 08:44:42 -07002783 !mLastNoHistoryActivity.finishing) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07002784 if (DEBUG_STATES) Slog.d(TAG_STATES,
2785 "no-history finish of " + mLastNoHistoryActivity + " on new resume");
Craig Mautner0f922742013-08-06 08:44:42 -07002786 requestFinishActivityLocked(mLastNoHistoryActivity.appToken, Activity.RESULT_CANCELED,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00002787 null, "resume-no-history", false);
Craig Mautner0f922742013-08-06 08:44:42 -07002788 mLastNoHistoryActivity = null;
Christopher Tated3f175c2012-06-14 14:16:54 -07002789 }
2790
Jorim Jaggi9b5e3312019-03-01 18:08:00 +01002791 if (prev != null && prev != next && next.nowVisible) {
2792
2793 // The next activity is already visible, so hide the previous
2794 // activity's windows right now so we can show the new one ASAP.
2795 // We only do this if the previous is finishing, which should mean
2796 // it is on top of the one being resumed so hiding it quickly
2797 // is good. Otherwise, we want to do the normal route of allowing
2798 // the resumed activity to be shown so we can decide if the
2799 // previous should actually be hidden depending on whether the
2800 // new one is found to be full-screen or not.
2801 if (prev.finishing) {
2802 prev.setVisibility(false);
Wale Ogunwaleee006da2015-03-30 14:49:25 -07002803 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
Jorim Jaggi9b5e3312019-03-01 18:08:00 +01002804 "Not waiting for visible to hide: " + prev
2805 + ", nowVisible=" + next.nowVisible);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002806 } else {
Jorim Jaggi9b5e3312019-03-01 18:08:00 +01002807 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
2808 "Previous already visible but still waiting to hide: " + prev
2809 + ", nowVisible=" + next.nowVisible);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002810 }
Jorim Jaggi9b5e3312019-03-01 18:08:00 +01002811
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002812 }
2813
Dianne Hackborne7f97212011-02-24 14:40:20 -08002814 // Launching this app's activity, make sure the app is no longer
2815 // considered stopped.
2816 try {
2817 AppGlobals.getPackageManager().setPackageStoppedState(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002818 next.packageName, false, next.mUserId); /* TODO: Verify if correct userid */
Dianne Hackborne7f97212011-02-24 14:40:20 -08002819 } catch (RemoteException e1) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08002820 } catch (IllegalArgumentException e) {
2821 Slog.w(TAG, "Failed trying to unstop package "
2822 + next.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08002823 }
2824
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002825 // We are starting up the next activity, so tell the window manager
2826 // that the previous one will be hidden soon. This way it can know
2827 // to ignore it when computing the desired screen orientation.
Craig Mautner525f3d92013-05-07 14:01:50 -07002828 boolean anim = true;
Wale Ogunwale3a256e62018-12-06 14:41:18 -08002829 final DisplayContent dc = getDisplay().mDisplayContent;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002830 if (prev != null) {
2831 if (prev.finishing) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07002832 if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002833 "Prepare close transition: prev=" + prev);
Jorim Jaggifa9ed962018-01-25 00:16:49 +01002834 if (mStackSupervisor.mNoAnimActivities.contains(prev)) {
Craig Mautner525f3d92013-05-07 14:01:50 -07002835 anim = false;
Wale Ogunwale3a256e62018-12-06 14:41:18 -08002836 dc.prepareAppTransition(TRANSIT_NONE, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002837 } else {
Wale Ogunwale3a256e62018-12-06 14:41:18 -08002838 dc.prepareAppTransition(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002839 prev.getTaskRecord() == next.getTaskRecord() ? TRANSIT_ACTIVITY_CLOSE
lumark588a3e82018-07-20 18:53:54 +08002840 : TRANSIT_TASK_CLOSE, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002841 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002842 prev.setVisibility(false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002843 } else {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07002844 if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
2845 "Prepare open transition: prev=" + prev);
Jorim Jaggifa9ed962018-01-25 00:16:49 +01002846 if (mStackSupervisor.mNoAnimActivities.contains(next)) {
Craig Mautner525f3d92013-05-07 14:01:50 -07002847 anim = false;
Wale Ogunwale3a256e62018-12-06 14:41:18 -08002848 dc.prepareAppTransition(TRANSIT_NONE, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002849 } else {
Wale Ogunwale3a256e62018-12-06 14:41:18 -08002850 dc.prepareAppTransition(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002851 prev.getTaskRecord() == next.getTaskRecord() ? TRANSIT_ACTIVITY_OPEN
lumark588a3e82018-07-20 18:53:54 +08002852 : next.mLaunchTaskBehind ? TRANSIT_TASK_OPEN_BEHIND
2853 : TRANSIT_TASK_OPEN, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002854 }
2855 }
Craig Mautner967212c2013-04-13 21:10:58 -07002856 } else {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07002857 if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare open transition: no previous");
Jorim Jaggifa9ed962018-01-25 00:16:49 +01002858 if (mStackSupervisor.mNoAnimActivities.contains(next)) {
Craig Mautner525f3d92013-05-07 14:01:50 -07002859 anim = false;
Wale Ogunwale3a256e62018-12-06 14:41:18 -08002860 dc.prepareAppTransition(TRANSIT_NONE, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002861 } else {
Wale Ogunwale3a256e62018-12-06 14:41:18 -08002862 dc.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002863 }
2864 }
Adam Powellcfbe9be2013-11-06 14:58:58 -08002865
Craig Mautner525f3d92013-05-07 14:01:50 -07002866 if (anim) {
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07002867 next.applyOptionsLocked();
2868 } else {
2869 next.clearOptionsLocked();
2870 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002871
Jorim Jaggifa9ed962018-01-25 00:16:49 +01002872 mStackSupervisor.mNoAnimActivities.clear();
2873
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002874 if (next.attachedToProcess()) {
Chong Zhangdea4bd92016-03-15 12:50:03 -07002875 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resume running: " + next
2876 + " stopped=" + next.stopped + " visible=" + next.visible);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002877
Chong Zhangd127c6d2016-05-02 16:36:41 -07002878 // If the previous activity is translucent, force a visibility update of
2879 // the next activity, so that it's added to WM's opening app list, and
2880 // transition animation can be set up properly.
2881 // For example, pressing Home button with a translucent activity in focus.
2882 // Launcher is already visible in this case. If we don't add it to opening
2883 // apps, maybeUpdateTransitToWallpaper() will fail to identify this as a
2884 // TRANSIT_WALLPAPER_OPEN animation, and run some funny animation.
Riddle Hsubbb63c22018-10-03 12:28:29 +08002885 final boolean lastActivityTranslucent = lastFocusedStack != null
2886 && (lastFocusedStack.inMultiWindowMode()
2887 || (lastFocusedStack.mLastPausedActivity != null
2888 && !lastFocusedStack.mLastPausedActivity.fullscreen));
Chong Zhangd127c6d2016-05-02 16:36:41 -07002889
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -08002890 // This activity is now becoming visible.
2891 if (!next.visible || next.stopped || lastActivityTranslucent) {
2892 next.setVisibility(true);
2893 }
2894
2895 // schedule launch ticks to collect information about slow apps.
2896 next.startLaunchTickingLocked();
2897
2898 ActivityRecord lastResumedActivity =
2899 lastFocusedStack == null ? null : lastFocusedStack.mResumedActivity;
2900 final ActivityState lastState = next.getState();
2901
2902 mService.updateCpuStats();
2903
2904 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + next
2905 + " (in existing)");
2906
2907 next.setState(RESUMED, "resumeTopActivityInnerLocked");
2908
2909 next.app.updateProcessInfo(false /* updateServiceConnectionActivities */,
Riddle Hsu17e38422019-04-12 16:55:11 +08002910 true /* activityChange */, true /* updateOomAdj */);
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -08002911 updateLRUListLocked(next);
2912
2913 // Have the window manager re-evaluate the orientation of
2914 // the screen based on the new activity order.
2915 boolean notUpdated = true;
2916
Andrii Kulian6b321512019-01-23 06:37:00 +00002917 // Activity should also be visible if set mLaunchTaskBehind to true (see
2918 // ActivityRecord#shouldBeVisibleIgnoringKeyguard()).
2919 if (shouldBeVisible(next)) {
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -08002920 // We have special rotation behavior when here is some active activity that
2921 // requests specific orientation or Keyguard is locked. Make sure all activity
2922 // visibilities are set correctly as well as the transition is updated if needed
2923 // to get the correct rotation behavior. Otherwise the following call to update
2924 // the orientation may cause incorrect configurations delivered to client as a
2925 // result of invisible window resize.
2926 // TODO: Remove this once visibilities are set correctly immediately when
2927 // starting an activity.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002928 notUpdated = !mRootActivityContainer.ensureVisibilityAndConfig(next, mDisplayId,
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -08002929 true /* markFrozenIfConfigChanged */, false /* deferResume */);
2930 }
2931
2932 if (notUpdated) {
2933 // The configuration update wasn't able to keep the existing
2934 // instance of the activity, and instead started a new one.
2935 // We should be all done, but let's just make sure our activity
2936 // is still at the top and schedule another run if something
2937 // weird happened.
2938 ActivityRecord nextNext = topRunningActivityLocked();
2939 if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_STATES,
2940 "Activity config changed during resume: " + next
2941 + ", new next: " + nextNext);
2942 if (nextNext != next) {
2943 // Do over!
2944 mStackSupervisor.scheduleResumeTopActivities();
2945 }
2946 if (!next.visible || next.stopped) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002947 next.setVisibility(true);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002948 }
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -08002949 next.completeResumeLocked();
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -08002950 return true;
2951 }
Craig Mautner58547802013-03-05 08:23:53 -08002952
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -08002953 try {
2954 final ClientTransaction transaction =
2955 ClientTransaction.obtain(next.app.getThread(), next.appToken);
2956 // Deliver all pending results.
2957 ArrayList<ResultInfo> a = next.results;
2958 if (a != null) {
2959 final int N = a.size();
2960 if (!next.finishing && N > 0) {
2961 if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
2962 "Delivering results to " + next + ": " + a);
2963 transaction.addCallback(ActivityResultItem.obtain(a));
2964 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002965 }
2966
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -08002967 if (next.newIntents != null) {
Louis Chang92d16522019-02-27 12:56:18 +08002968 transaction.addCallback(NewIntentItem.obtain(next.newIntents));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002969 }
2970
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -08002971 // Well the app will no longer be stopped.
2972 // Clear app token stopped state in window manager if needed.
2973 next.notifyAppResumed(next.stopped);
Wale Ogunwale8d5a5422016-03-03 18:28:21 -08002974
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002975 EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, next.mUserId,
2976 System.identityHashCode(next), next.getTaskRecord().taskId,
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -08002977 next.shortComponentName);
Craig Mautner58547802013-03-05 08:23:53 -08002978
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -08002979 next.sleeping = false;
2980 mService.getAppWarningsLocked().onResumeActivity(next);
2981 next.app.setPendingUiCleanAndForceProcessStateUpTo(mService.mTopProcessState);
2982 next.clearOptionsLocked();
2983 transaction.setLifecycleStateRequest(
2984 ResumeActivityItem.obtain(next.app.getReportedProcState(),
Wale Ogunwale3a256e62018-12-06 14:41:18 -08002985 getDisplay().mDisplayContent.isNextTransitionForward()));
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -08002986 mService.getLifecycleManager().scheduleTransaction(transaction);
Craig Mautner58547802013-03-05 08:23:53 -08002987
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -08002988 if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Resumed "
2989 + next);
2990 } catch (Exception e) {
2991 // Whoops, need to restart this activity!
2992 if (DEBUG_STATES) Slog.v(TAG_STATES, "Resume failed; resetting state to "
2993 + lastState + ": " + next);
2994 next.setState(lastState, "resumeTopActivityInnerLocked");
Bryce Lee69ad8182017-09-28 10:01:36 -07002995
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -08002996 // lastResumedActivity being non-null implies there is a lastStack present.
2997 if (lastResumedActivity != null) {
2998 lastResumedActivity.setState(RESUMED, "resumeTopActivityInnerLocked");
Craig Mautnerf88c50f2013-04-18 19:25:12 -07002999 }
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -08003000
3001 Slog.i(TAG, "Restarting because process died: " + next);
3002 if (!next.hasBeenLaunched) {
3003 next.hasBeenLaunched = true;
3004 } else if (SHOW_APP_STARTING_PREVIEW && lastFocusedStack != null
3005 && lastFocusedStack.isTopStackOnDisplay()) {
3006 next.showStartingWindow(null /* prev */, false /* newTask */,
3007 false /* taskSwitch */);
3008 }
3009 mStackSupervisor.startSpecificActivityLocked(next, true, false);
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -08003010 return true;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003011 }
3012
3013 // From this point on, if something goes wrong there is no way
3014 // to recover the activity.
3015 try {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003016 next.completeResumeLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003017 } catch (Exception e) {
3018 // If any exception gets thrown, toss away this
3019 // activity and try the next one.
3020 Slog.w(TAG, "Exception thrown during resume of " + next, e);
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00003021 requestFinishActivityLocked(next.appToken, Activity.RESULT_CANCELED, null,
Dianne Hackborn2d1b3782012-09-09 17:49:39 -07003022 "resume-exception", true);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003023 return true;
3024 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003025 } else {
3026 // Whoops, need to restart this activity!
3027 if (!next.hasBeenLaunched) {
3028 next.hasBeenLaunched = true;
3029 } else {
3030 if (SHOW_APP_STARTING_PREVIEW) {
Jorim Jaggi02886a82016-12-06 09:10:06 -08003031 next.showStartingWindow(null /* prev */, false /* newTask */,
3032 false /* taskSwich */);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003033 }
Wale Ogunwaleee006da2015-03-30 14:49:25 -07003034 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003035 }
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07003036 if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
George Mount2c92c972014-03-20 09:38:23 -07003037 mStackSupervisor.startSpecificActivityLocked(next, true, true);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003038 }
3039
3040 return true;
3041 }
3042
Andrii Kulian3ff5a0b2019-05-16 13:18:04 -07003043 /**
3044 * Resume the next eligible activity in a focusable stack when this one does not have any
3045 * running activities left. The focus will be adjusted to the next focusable stack and
3046 * top running activities will be resumed in all focusable stacks. However, if the current stack
3047 * is a home stack - we have to keep it focused, start and resume a home activity on the current
3048 * display instead to make sure that the display is not empty.
3049 */
3050 private boolean resumeNextFocusableActivityWhenStackIsEmpty(ActivityRecord prev,
3051 ActivityOptions options) {
3052 final String reason = "noMoreActivities";
3053
3054 if (!isActivityTypeHome()) {
3055 final ActivityStack nextFocusedStack = adjustFocusToNextFocusableStack(reason);
3056 if (nextFocusedStack != null) {
3057 // Try to move focus to the next visible stack with a running activity if this
3058 // stack is not covering the entire screen or is on a secondary display with no home
3059 // stack.
3060 return mRootActivityContainer.resumeFocusedStacksTopActivities(nextFocusedStack,
3061 prev, null /* targetOptions */);
3062 }
Andrii Kulian7fc22812016-12-28 13:04:11 -08003063 }
3064
Andrii Kulian3ff5a0b2019-05-16 13:18:04 -07003065 // If the current stack is a home stack, or if focus didn't switch to a different stack -
3066 // just start up the Launcher...
Andrii Kulian7fc22812016-12-28 13:04:11 -08003067 ActivityOptions.abort(options);
3068 if (DEBUG_STATES) Slog.d(TAG_STATES,
Andrii Kulian3ff5a0b2019-05-16 13:18:04 -07003069 "resumeNextFocusableActivityWhenStackIsEmpty: " + reason + ", go home");
Louis Chang77551ed2019-04-29 12:42:19 +08003070 return mRootActivityContainer.resumeHomeActivity(prev, reason, mDisplayId);
Andrii Kulian7fc22812016-12-28 13:04:11 -08003071 }
3072
Wale Ogunwalec5cc3012017-01-13 13:26:16 -08003073 /** Returns the position the input task should be placed in this stack. */
3074 int getAdjustedPositionForTask(TaskRecord task, int suggestedPosition,
3075 ActivityRecord starting) {
3076
3077 int maxPosition = mTaskHistory.size();
3078 if ((starting != null && starting.okToShowLocked())
3079 || (starting == null && task.okToShowLocked())) {
3080 // If the task or starting activity can be shown, then whatever position is okay.
3081 return Math.min(suggestedPosition, maxPosition);
3082 }
3083
3084 // The task can't be shown, put non-current user tasks below current user tasks.
3085 while (maxPosition > 0) {
3086 final TaskRecord tmpTask = mTaskHistory.get(maxPosition - 1);
3087 if (!mStackSupervisor.isCurrentProfileLocked(tmpTask.userId)
3088 || tmpTask.topRunningActivityLocked() == null) {
3089 break;
3090 }
3091 maxPosition--;
3092 }
3093
3094 return Math.min(suggestedPosition, maxPosition);
3095 }
3096
Andrii Kuliand2765632016-12-12 22:26:34 -08003097 /**
3098 * Used from {@link ActivityStack#positionTask(TaskRecord, int)}.
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003099 * @see ActivityTaskManagerService#positionTaskInStack(int, int, int).
Andrii Kuliand2765632016-12-12 22:26:34 -08003100 */
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -07003101 private void insertTaskAtPosition(TaskRecord task, int position) {
3102 if (position >= mTaskHistory.size()) {
3103 insertTaskAtTop(task, null);
3104 return;
Evan Rosky9c448172017-11-02 14:19:27 -07003105 } else if (position <= 0) {
3106 insertTaskAtBottom(task);
3107 return;
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -07003108 }
Wale Ogunwalec5cc3012017-01-13 13:26:16 -08003109 position = getAdjustedPositionForTask(task, position, null /* starting */);
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -07003110 mTaskHistory.remove(task);
3111 mTaskHistory.add(position, task);
Yunfan Chen279f5582018-12-12 15:24:50 -08003112 if (mTaskStack != null) {
3113 // TODO: this could not be false after unification.
3114 mTaskStack.positionChildAt(task.getTask(), position);
3115 }
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -07003116 updateTaskMovement(task, true);
3117 }
3118
Wale Ogunwalec5cc3012017-01-13 13:26:16 -08003119 private void insertTaskAtTop(TaskRecord task, ActivityRecord starting) {
Wale Ogunwalec5cc3012017-01-13 13:26:16 -08003120 // TODO: Better place to put all the code below...may be addTask...
3121 mTaskHistory.remove(task);
3122 // Now put task at top.
3123 final int position = getAdjustedPositionForTask(task, mTaskHistory.size(), starting);
3124 mTaskHistory.add(position, task);
3125 updateTaskMovement(task, true);
Riddle Hsu86cb7de2018-08-13 23:29:58 +08003126 positionChildWindowContainerAtTop(task);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -08003127 }
3128
Evan Rosky9c448172017-11-02 14:19:27 -07003129 private void insertTaskAtBottom(TaskRecord task) {
Evan Rosky9c448172017-11-02 14:19:27 -07003130 mTaskHistory.remove(task);
3131 final int position = getAdjustedPositionForTask(task, 0, null);
3132 mTaskHistory.add(position, task);
3133 updateTaskMovement(task, true);
Riddle Hsu86cb7de2018-08-13 23:29:58 +08003134 positionChildWindowContainerAtBottom(task);
Evan Rosky9c448172017-11-02 14:19:27 -07003135 }
3136
Bryce Leead5b8322018-03-08 14:28:52 -08003137 void startActivityLocked(ActivityRecord r, ActivityRecord focusedTopActivity,
Winson Chungb5c41b72016-12-07 15:00:47 -08003138 boolean newTask, boolean keepCurTransition, ActivityOptions options) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003139 TaskRecord rTask = r.getTaskRecord();
Craig Mautnerd2328952013-03-05 12:46:26 -08003140 final int taskId = rTask.taskId;
Craig Mautnerbb742462014-07-07 15:28:55 -07003141 // mLaunchTaskBehind tasks get placed at the back of the task stack.
3142 if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) {
Craig Mautner77878772013-03-04 19:46:24 -08003143 // Last activity in task had been removed or ActivityManagerService is reusing task.
3144 // Insert or replace.
Craig Mautner77878772013-03-04 19:46:24 -08003145 // Might not even be in.
Wale Ogunwale3fcb4a82015-04-06 14:00:13 -07003146 insertTaskAtTop(rTask, r);
Craig Mautner77878772013-03-04 19:46:24 -08003147 }
Craig Mautner525f3d92013-05-07 14:01:50 -07003148 TaskRecord task = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003149 if (!newTask) {
3150 // If starting in an existing task, find where that is...
Craig Mautner70a86932013-02-28 22:37:44 -08003151 boolean startIt = true;
3152 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
3153 task = mTaskHistory.get(taskNdx);
riddle_hsu9bcc6e82014-07-31 00:26:51 +08003154 if (task.getTopActivity() == null) {
3155 // All activities in task are finishing.
3156 continue;
3157 }
Bryce Leeaf691c02017-03-20 14:20:22 -07003158 if (task == rTask) {
Craig Mautner70a86932013-02-28 22:37:44 -08003159 // Here it is! Now, if this is not yet visible to the
3160 // user, then just add it without starting; it will
3161 // get started when the user navigates back to it.
Craig Mautner70a86932013-02-28 22:37:44 -08003162 if (!startIt) {
3163 if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to task "
3164 + task, new RuntimeException("here").fillInStackTrace());
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08003165 r.createAppWindowToken();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003166 ActivityOptions.abort(options);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003167 return;
3168 }
3169 break;
Craig Mautner70a86932013-02-28 22:37:44 -08003170 } else if (task.numFullscreen > 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003171 startIt = false;
3172 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003173 }
3174 }
3175
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08003176 // Place a new activity at top of stack, so it is next to interact with the user.
Craig Mautner70a86932013-02-28 22:37:44 -08003177
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08003178 // If we are not placing the new activity frontmost, we do not want to deliver the
3179 // onUserLeaving callback to the actual frontmost activity
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003180 final TaskRecord activityTask = r.getTaskRecord();
Bryce Leeaf691c02017-03-20 14:20:22 -07003181 if (task == activityTask && mTaskHistory.indexOf(task) != (mTaskHistory.size() - 1)) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07003182 mStackSupervisor.mUserLeaving = false;
Wale Ogunwaleee006da2015-03-30 14:49:25 -07003183 if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
Craig Mautner70a86932013-02-28 22:37:44 -08003184 "startActivity() behind front, mUserLeaving=false");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003185 }
Craig Mautner70a86932013-02-28 22:37:44 -08003186
Bryce Leeaf691c02017-03-20 14:20:22 -07003187 task = activityTask;
Craig Mautner70a86932013-02-28 22:37:44 -08003188
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003189 // Slot the activity into the history stack and proceed
Craig Mautner70a86932013-02-28 22:37:44 -08003190 if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to stack to task " + task,
Craig Mautner56f52db2013-02-25 10:03:01 -08003191 new RuntimeException("here").fillInStackTrace());
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08003192 // TODO: Need to investigate if it is okay for the controller to already be created by the
3193 // time we get to this point. I think it is, but need to double check.
3194 // Use test in b/34179495 to trace the call path.
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08003195 if (r.mAppWindowToken == null) {
3196 r.createAppWindowToken();
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08003197 }
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08003198
Craig Mautner1aa9d0d3f2013-12-16 15:58:31 -08003199 task.setFrontOfTask();
Craig Mautner70a86932013-02-28 22:37:44 -08003200
Matthew Ngae1ff4f2016-11-10 15:49:14 -08003201 if (!isHomeOrRecentsStack() || numActivities() > 0) {
Wale Ogunwale3a256e62018-12-06 14:41:18 -08003202 final DisplayContent dc = getDisplay().mDisplayContent;
Wale Ogunwaleee006da2015-03-30 14:49:25 -07003203 if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003204 "Prepare open transition: starting " + r);
Wale Ogunwaleee006da2015-03-30 14:49:25 -07003205 if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
Wale Ogunwale3a256e62018-12-06 14:41:18 -08003206 dc.prepareAppTransition(TRANSIT_NONE, keepCurTransition);
Jorim Jaggifa9ed962018-01-25 00:16:49 +01003207 mStackSupervisor.mNoAnimActivities.add(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003208 } else {
Winson Chungb5c41b72016-12-07 15:00:47 -08003209 int transit = TRANSIT_ACTIVITY_OPEN;
3210 if (newTask) {
3211 if (r.mLaunchTaskBehind) {
3212 transit = TRANSIT_TASK_OPEN_BEHIND;
Issei Suzukicac2a502019-04-16 16:52:50 +02003213 } else if (getDisplay().isSingleTaskInstance()) {
3214 transit = TRANSIT_SHOW_SINGLE_TASK_DISPLAY;
Winson Chungb5c41b72016-12-07 15:00:47 -08003215 } else {
Winson Chungc2baac02017-01-11 13:34:47 -08003216 // If a new task is being launched, then mark the existing top activity as
Winson Chung942a85c2017-07-11 15:07:45 -07003217 // supporting picture-in-picture while pausing only if the starting activity
3218 // would not be considered an overlay on top of the current activity
3219 // (eg. not fullscreen, or the assistant)
Winson Chungf7e03e12017-08-22 11:32:16 -07003220 if (canEnterPipOnTaskSwitch(focusedTopActivity,
3221 null /* toFrontTask */, r, options)) {
3222 focusedTopActivity.supportsEnterPipOnTaskSwitch = true;
Winson Chungb5c41b72016-12-07 15:00:47 -08003223 }
3224 transit = TRANSIT_TASK_OPEN;
3225 }
3226 }
Wale Ogunwale3a256e62018-12-06 14:41:18 -08003227 dc.prepareAppTransition(transit, keepCurTransition);
Jorim Jaggifa9ed962018-01-25 00:16:49 +01003228 mStackSupervisor.mNoAnimActivities.remove(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003229 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003230 boolean doShow = true;
3231 if (newTask) {
3232 // Even though this activity is starting fresh, we still need
3233 // to reset it to make sure we apply affinities to move any
3234 // existing activities from other tasks in to it.
3235 // If the caller has requested that the target task be
3236 // reset, then do so.
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07003237 if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003238 resetTaskIfNeededLocked(r, r);
3239 doShow = topRunningNonDelayedActivityLocked(null) == r;
3240 }
Chong Zhang280d3322015-11-03 17:27:26 -08003241 } else if (options != null && options.getAnimationType()
George Mount70778d72014-07-01 16:33:45 -07003242 == ActivityOptions.ANIM_SCENE_TRANSITION) {
3243 doShow = false;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003244 }
Craig Mautnerbb742462014-07-07 15:28:55 -07003245 if (r.mLaunchTaskBehind) {
3246 // Don't do a starting window for mLaunchTaskBehind. More importantly make sure we
3247 // tell WindowManager that r is visible even though it is at the back of the stack.
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08003248 r.setVisibility(true);
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -07003249 ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Craig Mautnerbb742462014-07-07 15:28:55 -07003250 } else if (SHOW_APP_STARTING_PREVIEW && doShow) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003251 // Figure out if we are transitioning from another activity that is
3252 // "has the same starting icon" as the next one. This allows the
3253 // window manager to keep the previous window it had previously
3254 // created, if it still had one.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003255 TaskRecord prevTask = r.getTaskRecord();
Bryce Leeaf691c02017-03-20 14:20:22 -07003256 ActivityRecord prev = prevTask.topRunningActivityWithStartingWindowLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003257 if (prev != null) {
3258 // We don't want to reuse the previous starting preview if:
3259 // (1) The current activity is in a different task.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003260 if (prev.getTaskRecord() != prevTask) {
Craig Mautner29219d92013-04-16 20:19:12 -07003261 prev = null;
3262 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003263 // (2) The current activity is already displayed.
Craig Mautner29219d92013-04-16 20:19:12 -07003264 else if (prev.nowVisible) {
3265 prev = null;
3266 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003267 }
Jorim Jaggi02886a82016-12-06 09:10:06 -08003268 r.showStartingWindow(prev, newTask, isTaskSwitch(r, focusedTopActivity));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003269 }
3270 } else {
3271 // If this is the first activity, don't do any fancy animations,
3272 // because there is nothing for it to animate on top of.
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003273 ActivityOptions.abort(options);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003274 }
Dianne Hackbornbe707852011-11-11 14:32:10 -08003275 }
3276
Winson Chungf7e03e12017-08-22 11:32:16 -07003277 /**
3278 * @return Whether the switch to another task can trigger the currently running activity to
3279 * enter PiP while it is pausing (if supported). Only one of {@param toFrontTask} or
3280 * {@param toFrontActivity} should be set.
3281 */
3282 private boolean canEnterPipOnTaskSwitch(ActivityRecord pipCandidate,
3283 TaskRecord toFrontTask, ActivityRecord toFrontActivity, ActivityOptions opts) {
3284 if (opts != null && opts.disallowEnterPictureInPictureWhileLaunching()) {
3285 // Ensure the caller has requested not to trigger auto-enter PiP
3286 return false;
3287 }
Wale Ogunwale44f036f2017-09-29 05:09:09 -07003288 if (pipCandidate == null || pipCandidate.inPinnedWindowingMode()) {
Winson Chungf7e03e12017-08-22 11:32:16 -07003289 // Ensure that we do not trigger entering PiP an activity on the pinned stack
3290 return false;
3291 }
Wale Ogunwale68278562017-09-23 17:13:55 -07003292 final ActivityStack targetStack = toFrontTask != null
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003293 ? toFrontTask.getStack() : toFrontActivity.getActivityStack();
Wale Ogunwale68278562017-09-23 17:13:55 -07003294 if (targetStack != null && targetStack.isActivityTypeAssistant()) {
Winson Chungf7e03e12017-08-22 11:32:16 -07003295 // Ensure the task/activity being brought forward is not the assistant
3296 return false;
3297 }
Winson Chungf7e03e12017-08-22 11:32:16 -07003298 return true;
3299 }
3300
Jorim Jaggi02886a82016-12-06 09:10:06 -08003301 private boolean isTaskSwitch(ActivityRecord r,
3302 ActivityRecord topFocusedActivity) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003303 return topFocusedActivity != null && r.getTaskRecord() != topFocusedActivity.getTaskRecord();
Jorim Jaggi02886a82016-12-06 09:10:06 -08003304 }
3305
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003306 /**
3307 * Perform a reset of the given task, if needed as part of launching it.
3308 * Returns the new HistoryRecord at the top of the task.
3309 */
Craig Mautnere3a74d52013-02-22 14:14:58 -08003310 /**
3311 * Helper method for #resetTaskIfNeededLocked.
3312 * We are inside of the task being reset... we'll either finish this activity, push it out
3313 * for another task, or leave it as-is.
3314 * @param task The task containing the Activity (taskTop) that might be reset.
3315 * @param forceReset
3316 * @return An ActivityOptions that needs to be processed.
3317 */
Andrii Kulian21713ac2016-10-12 22:05:05 -07003318 private ActivityOptions resetTargetTaskIfNeededLocked(TaskRecord task, boolean forceReset) {
Craig Mautnere3a74d52013-02-22 14:14:58 -08003319 ActivityOptions topOptions = null;
3320
3321 int replyChainEnd = -1;
3322 boolean canMoveOptions = true;
3323
3324 // We only do this for activities that are not the root of the task (since if we finish
3325 // the root, we may no longer have the task!).
3326 final ArrayList<ActivityRecord> activities = task.mActivities;
3327 final int numActivities = activities.size();
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07003328 final int rootActivityNdx = task.findEffectiveRootIndex();
3329 for (int i = numActivities - 1; i > rootActivityNdx; --i ) {
Craig Mautnere3a74d52013-02-22 14:14:58 -08003330 ActivityRecord target = activities.get(i);
Craig Mautner76ae2f02014-07-16 16:16:19 +00003331 if (target.frontOfTask)
3332 break;
Craig Mautnere3a74d52013-02-22 14:14:58 -08003333
3334 final int flags = target.info.flags;
3335 final boolean finishOnTaskLaunch =
3336 (flags & ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH) != 0;
3337 final boolean allowTaskReparenting =
3338 (flags & ActivityInfo.FLAG_ALLOW_TASK_REPARENTING) != 0;
3339 final boolean clearWhenTaskReset =
3340 (target.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0;
3341
3342 if (!finishOnTaskLaunch
3343 && !clearWhenTaskReset
3344 && target.resultTo != null) {
3345 // If this activity is sending a reply to a previous
3346 // activity, we can't do anything with it now until
3347 // we reach the start of the reply chain.
3348 // XXX note that we are assuming the result is always
3349 // to the previous activity, which is almost always
3350 // the case but we really shouldn't count on.
3351 if (replyChainEnd < 0) {
3352 replyChainEnd = i;
3353 }
3354 } else if (!finishOnTaskLaunch
3355 && !clearWhenTaskReset
3356 && allowTaskReparenting
3357 && target.taskAffinity != null
3358 && !target.taskAffinity.equals(task.affinity)) {
3359 // If this activity has an affinity for another
3360 // task, then we need to move it out of here. We will
3361 // move it as far out of the way as possible, to the
3362 // bottom of the activity stack. This also keeps it
3363 // correctly ordered with any activities we previously
3364 // moved.
Craig Mautner329f4122013-11-07 09:10:42 -08003365 final TaskRecord targetTask;
Craig Mautnerdccb7702013-09-17 15:53:34 -07003366 final ActivityRecord bottom =
3367 !mTaskHistory.isEmpty() && !mTaskHistory.get(0).mActivities.isEmpty() ?
Craig Mautner329f4122013-11-07 09:10:42 -08003368 mTaskHistory.get(0).mActivities.get(0) : null;
Craig Mautnerdccb7702013-09-17 15:53:34 -07003369 if (bottom != null && target.taskAffinity != null
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003370 && target.taskAffinity.equals(bottom.getTaskRecord().affinity)) {
Craig Mautnere3a74d52013-02-22 14:14:58 -08003371 // If the activity currently at the bottom has the
3372 // same task affinity as the one we are moving,
3373 // then merge it into the same task.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003374 targetTask = bottom.getTaskRecord();
Wale Ogunwaleee006da2015-03-30 14:49:25 -07003375 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Start pushing activity " + target
Bryce Leeaf691c02017-03-20 14:20:22 -07003376 + " out to bottom task " + targetTask);
Craig Mautnere3a74d52013-02-22 14:14:58 -08003377 } else {
Suprabh Shukla09a88f52015-12-02 14:36:31 -08003378 targetTask = createTaskRecord(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003379 mStackSupervisor.getNextTaskIdForUserLocked(target.mUserId),
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07003380 target.info, null, null, null, false);
Craig Mautner329f4122013-11-07 09:10:42 -08003381 targetTask.affinityIntent = target.intent;
Wale Ogunwaleee006da2015-03-30 14:49:25 -07003382 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Start pushing activity " + target
Bryce Leeaf691c02017-03-20 14:20:22 -07003383 + " out to new task " + targetTask);
Craig Mautnere3a74d52013-02-22 14:14:58 -08003384 }
3385
Craig Mautner525f3d92013-05-07 14:01:50 -07003386 boolean noOptions = canMoveOptions;
Craig Mautnere3a74d52013-02-22 14:14:58 -08003387 final int start = replyChainEnd < 0 ? i : replyChainEnd;
3388 for (int srcPos = start; srcPos >= i; --srcPos) {
Craig Mautnerdccb7702013-09-17 15:53:34 -07003389 final ActivityRecord p = activities.get(srcPos);
Craig Mautnere3a74d52013-02-22 14:14:58 -08003390 if (p.finishing) {
3391 continue;
3392 }
3393
Craig Mautnere3a74d52013-02-22 14:14:58 -08003394 canMoveOptions = false;
Craig Mautner525f3d92013-05-07 14:01:50 -07003395 if (noOptions && topOptions == null) {
Jorim Jaggi346702a2019-05-08 17:49:33 +02003396 topOptions = p.takeOptionsLocked(false /* fromClient */);
Craig Mautnere3a74d52013-02-22 14:14:58 -08003397 if (topOptions != null) {
Craig Mautner525f3d92013-05-07 14:01:50 -07003398 noOptions = false;
Craig Mautnere3a74d52013-02-22 14:14:58 -08003399 }
3400 }
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07003401 if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE,
3402 "Removing activity " + p + " from task=" + task + " adding to task="
3403 + targetTask + " Callers=" + Debug.getCallers(4));
Wale Ogunwaleee006da2015-03-30 14:49:25 -07003404 if (DEBUG_TASKS) Slog.v(TAG_TASKS,
Bryce Leeaf691c02017-03-20 14:20:22 -07003405 "Pushing next activity " + p + " out to target's task " + target);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08003406 p.reparent(targetTask, 0 /* position - bottom */, "resetTargetTaskIfNeeded");
Craig Mautnere3a74d52013-02-22 14:14:58 -08003407 }
3408
Riddle Hsu86cb7de2018-08-13 23:29:58 +08003409 positionChildWindowContainerAtBottom(targetTask);
Craig Mautnere3a74d52013-02-22 14:14:58 -08003410 replyChainEnd = -1;
3411 } else if (forceReset || finishOnTaskLaunch || clearWhenTaskReset) {
3412 // If the activity should just be removed -- either
3413 // because it asks for it, or the task should be
3414 // cleared -- then finish it and anything that is
3415 // part of its reply chain.
3416 int end;
3417 if (clearWhenTaskReset) {
3418 // In this case, we want to finish this activity
3419 // and everything above it, so be sneaky and pretend
3420 // like these are all in the reply chain.
Mark Lu4b5a9a02014-12-09 14:47:13 +08003421 end = activities.size() - 1;
Craig Mautnere3a74d52013-02-22 14:14:58 -08003422 } else if (replyChainEnd < 0) {
3423 end = i;
3424 } else {
3425 end = replyChainEnd;
3426 }
Craig Mautner525f3d92013-05-07 14:01:50 -07003427 boolean noOptions = canMoveOptions;
Craig Mautnere3a74d52013-02-22 14:14:58 -08003428 for (int srcPos = i; srcPos <= end; srcPos++) {
Craig Mautner525f3d92013-05-07 14:01:50 -07003429 ActivityRecord p = activities.get(srcPos);
Craig Mautnere3a74d52013-02-22 14:14:58 -08003430 if (p.finishing) {
3431 continue;
3432 }
3433 canMoveOptions = false;
Craig Mautner525f3d92013-05-07 14:01:50 -07003434 if (noOptions && topOptions == null) {
Jorim Jaggi346702a2019-05-08 17:49:33 +02003435 topOptions = p.takeOptionsLocked(false /* fromClient */);
Craig Mautnere3a74d52013-02-22 14:14:58 -08003436 if (topOptions != null) {
Craig Mautner525f3d92013-05-07 14:01:50 -07003437 noOptions = false;
Craig Mautnere3a74d52013-02-22 14:14:58 -08003438 }
3439 }
Wale Ogunwaleee006da2015-03-30 14:49:25 -07003440 if (DEBUG_TASKS) Slog.w(TAG_TASKS,
Craig Mautner58547802013-03-05 08:23:53 -08003441 "resetTaskIntendedTask: calling finishActivity on " + p);
Todd Kennedy539db512014-12-15 09:57:55 -08003442 if (finishActivityLocked(
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00003443 p, Activity.RESULT_CANCELED, null, "reset-task", false)) {
Craig Mautnere3a74d52013-02-22 14:14:58 -08003444 end--;
3445 srcPos--;
3446 }
3447 }
3448 replyChainEnd = -1;
3449 } else {
3450 // If we were in the middle of a chain, well the
3451 // activity that started it all doesn't want anything
3452 // special, so leave it all as-is.
3453 replyChainEnd = -1;
3454 }
3455 }
3456
3457 return topOptions;
3458 }
3459
3460 /**
3461 * Helper method for #resetTaskIfNeededLocked. Processes all of the activities in a given
3462 * TaskRecord looking for an affinity with the task of resetTaskIfNeededLocked.taskTop.
3463 * @param affinityTask The task we are looking for an affinity to.
3464 * @param task Task that resetTaskIfNeededLocked.taskTop belongs to.
3465 * @param topTaskIsHigher True if #task has already been processed by resetTaskIfNeededLocked.
3466 * @param forceReset Flag passed in to resetTaskIfNeededLocked.
3467 */
Craig Mautner525f3d92013-05-07 14:01:50 -07003468 private int resetAffinityTaskIfNeededLocked(TaskRecord affinityTask, TaskRecord task,
Craig Mautner77878772013-03-04 19:46:24 -08003469 boolean topTaskIsHigher, boolean forceReset, int taskInsertionPoint) {
Craig Mautnere3a74d52013-02-22 14:14:58 -08003470 int replyChainEnd = -1;
3471 final int taskId = task.taskId;
3472 final String taskAffinity = task.affinity;
3473
3474 final ArrayList<ActivityRecord> activities = affinityTask.mActivities;
3475 final int numActivities = activities.size();
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07003476 final int rootActivityNdx = affinityTask.findEffectiveRootIndex();
3477
3478 // Do not operate on or below the effective root Activity.
3479 for (int i = numActivities - 1; i > rootActivityNdx; --i) {
Craig Mautnere3a74d52013-02-22 14:14:58 -08003480 ActivityRecord target = activities.get(i);
Craig Mautner76ae2f02014-07-16 16:16:19 +00003481 if (target.frontOfTask)
3482 break;
Craig Mautnere3a74d52013-02-22 14:14:58 -08003483
3484 final int flags = target.info.flags;
3485 boolean finishOnTaskLaunch = (flags & ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH) != 0;
3486 boolean allowTaskReparenting = (flags & ActivityInfo.FLAG_ALLOW_TASK_REPARENTING) != 0;
3487
3488 if (target.resultTo != null) {
3489 // If this activity is sending a reply to a previous
3490 // activity, we can't do anything with it now until
3491 // we reach the start of the reply chain.
3492 // XXX note that we are assuming the result is always
3493 // to the previous activity, which is almost always
3494 // the case but we really shouldn't count on.
3495 if (replyChainEnd < 0) {
3496 replyChainEnd = i;
3497 }
3498 } else if (topTaskIsHigher
3499 && allowTaskReparenting
3500 && taskAffinity != null
3501 && taskAffinity.equals(target.taskAffinity)) {
3502 // This activity has an affinity for our task. Either remove it if we are
3503 // clearing or move it over to our task. Note that
3504 // we currently punt on the case where we are resetting a
3505 // task that is not at the top but who has activities above
3506 // with an affinity to it... this is really not a normal
3507 // case, and we will need to later pull that task to the front
3508 // and usually at that point we will do the reset and pick
3509 // up those remaining activities. (This only happens if
3510 // someone starts an activity in a new task from an activity
3511 // in a task that is not currently on top.)
3512 if (forceReset || finishOnTaskLaunch) {
3513 final int start = replyChainEnd >= 0 ? replyChainEnd : i;
Wale Ogunwaleee006da2015-03-30 14:49:25 -07003514 if (DEBUG_TASKS) Slog.v(TAG_TASKS,
3515 "Finishing task at index " + start + " to " + i);
Craig Mautnere3a74d52013-02-22 14:14:58 -08003516 for (int srcPos = start; srcPos >= i; --srcPos) {
3517 final ActivityRecord p = activities.get(srcPos);
3518 if (p.finishing) {
3519 continue;
3520 }
Todd Kennedy539db512014-12-15 09:57:55 -08003521 finishActivityLocked(
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00003522 p, Activity.RESULT_CANCELED, null, "move-affinity", false);
Craig Mautnere3a74d52013-02-22 14:14:58 -08003523 }
3524 } else {
Craig Mautner77878772013-03-04 19:46:24 -08003525 if (taskInsertionPoint < 0) {
3526 taskInsertionPoint = task.mActivities.size();
Craig Mautnerd2328952013-03-05 12:46:26 -08003527
Craig Mautner77878772013-03-04 19:46:24 -08003528 }
Craig Mautner77878772013-03-04 19:46:24 -08003529
3530 final int start = replyChainEnd >= 0 ? replyChainEnd : i;
Wale Ogunwaleee006da2015-03-30 14:49:25 -07003531 if (DEBUG_TASKS) Slog.v(TAG_TASKS,
3532 "Reparenting from task=" + affinityTask + ":" + start + "-" + i
3533 + " to task=" + task + ":" + taskInsertionPoint);
Craig Mautner77878772013-03-04 19:46:24 -08003534 for (int srcPos = start; srcPos >= i; --srcPos) {
Craig Mautnere3a74d52013-02-22 14:14:58 -08003535 final ActivityRecord p = activities.get(srcPos);
Winson Chung30480042017-01-26 10:55:34 -08003536 p.reparent(task, taskInsertionPoint, "resetAffinityTaskIfNeededLocked");
Craig Mautnere3a74d52013-02-22 14:14:58 -08003537
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07003538 if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE,
3539 "Removing and adding activity " + p + " to stack at " + task
3540 + " callers=" + Debug.getCallers(3));
Wale Ogunwaleee006da2015-03-30 14:49:25 -07003541 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Pulling activity " + p
3542 + " from " + srcPos + " in to resetting task " + task);
Craig Mautnere3a74d52013-02-22 14:14:58 -08003543 }
Riddle Hsu86cb7de2018-08-13 23:29:58 +08003544 positionChildWindowContainerAtTop(task);
Craig Mautnere3a74d52013-02-22 14:14:58 -08003545
3546 // Now we've moved it in to place... but what if this is
3547 // a singleTop activity and we have put it on top of another
3548 // instance of the same activity? Then we drop the instance
3549 // below so it remains singleTop.
3550 if (target.info.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {
3551 ArrayList<ActivityRecord> taskActivities = task.mActivities;
Craig Mautnere3a74d52013-02-22 14:14:58 -08003552 int targetNdx = taskActivities.indexOf(target);
3553 if (targetNdx > 0) {
3554 ActivityRecord p = taskActivities.get(targetNdx - 1);
3555 if (p.intent.getComponent().equals(target.intent.getComponent())) {
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00003556 finishActivityLocked(p, Activity.RESULT_CANCELED, null, "replace",
3557 false);
Craig Mautnere3a74d52013-02-22 14:14:58 -08003558 }
3559 }
3560 }
3561 }
3562
3563 replyChainEnd = -1;
3564 }
3565 }
Craig Mautner77878772013-03-04 19:46:24 -08003566 return taskInsertionPoint;
Craig Mautnere3a74d52013-02-22 14:14:58 -08003567 }
3568
Craig Mautner8849a5e2013-04-02 16:41:03 -07003569 final ActivityRecord resetTaskIfNeededLocked(ActivityRecord taskTop,
Craig Mautnere3a74d52013-02-22 14:14:58 -08003570 ActivityRecord newActivity) {
Winson Chung5fa39752017-10-04 14:50:15 -07003571 final boolean forceReset =
Craig Mautnere3a74d52013-02-22 14:14:58 -08003572 (newActivity.info.flags & ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003573 final TaskRecord task = taskTop.getTaskRecord();
Craig Mautnere3a74d52013-02-22 14:14:58 -08003574
3575 /** False until we evaluate the TaskRecord associated with taskTop. Switches to true
3576 * for remaining tasks. Used for later tasks to reparent to task. */
3577 boolean taskFound = false;
3578
3579 /** If ActivityOptions are moved out and need to be aborted or moved to taskTop. */
3580 ActivityOptions topOptions = null;
3581
Craig Mautner77878772013-03-04 19:46:24 -08003582 // Preserve the location for reparenting in the new task.
3583 int reparentInsertionPoint = -1;
3584
Craig Mautnere3a74d52013-02-22 14:14:58 -08003585 for (int i = mTaskHistory.size() - 1; i >= 0; --i) {
3586 final TaskRecord targetTask = mTaskHistory.get(i);
3587
3588 if (targetTask == task) {
3589 topOptions = resetTargetTaskIfNeededLocked(task, forceReset);
3590 taskFound = true;
3591 } else {
Craig Mautner77878772013-03-04 19:46:24 -08003592 reparentInsertionPoint = resetAffinityTaskIfNeededLocked(targetTask, task,
3593 taskFound, forceReset, reparentInsertionPoint);
Craig Mautnere3a74d52013-02-22 14:14:58 -08003594 }
3595 }
3596
Craig Mautner70a86932013-02-28 22:37:44 -08003597 int taskNdx = mTaskHistory.indexOf(task);
riddle_hsu1d7919a2015-03-11 17:09:50 +08003598 if (taskNdx >= 0) {
3599 do {
3600 taskTop = mTaskHistory.get(taskNdx--).getTopActivity();
3601 } while (taskTop == null && taskNdx >= 0);
3602 }
Craig Mautner70a86932013-02-28 22:37:44 -08003603
Craig Mautnere3a74d52013-02-22 14:14:58 -08003604 if (topOptions != null) {
3605 // If we got some ActivityOptions from an activity on top that
3606 // was removed from the task, propagate them to the new real top.
3607 if (taskTop != null) {
Craig Mautnere3a74d52013-02-22 14:14:58 -08003608 taskTop.updateOptionsLocked(topOptions);
3609 } else {
Craig Mautnere3a74d52013-02-22 14:14:58 -08003610 topOptions.abort();
3611 }
3612 }
3613
3614 return taskTop;
3615 }
3616
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00003617 void sendActivityResultLocked(int callingUid, ActivityRecord r,
3618 String resultWho, int requestCode, int resultCode, Intent data) {
3619
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003620 if (callingUid > 0) {
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00003621 mService.mUgmInternal.grantUriPermissionFromIntent(callingUid, r.packageName,
3622 data, r.getUriPermissionsLocked(), r.mUserId);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003623 }
3624
3625 if (DEBUG_RESULTS) Slog.v(TAG, "Send activity result to " + r
3626 + " : who=" + resultWho + " req=" + requestCode
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00003627 + " res=" + resultCode + " data=" + data);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003628 if (mResumedActivity == r && r.attachedToProcess()) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003629 try {
3630 ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
3631 list.add(new ResultInfo(resultWho, requestCode,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00003632 resultCode, data));
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003633 mService.getLifecycleManager().scheduleTransaction(r.app.getThread(), r.appToken,
Andrii Kulian9c5ea9c2017-12-07 09:31:01 -08003634 ActivityResultItem.obtain(list));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003635 return;
3636 } catch (Exception e) {
3637 Slog.w(TAG, "Exception thrown sending result to " + r, e);
3638 }
3639 }
3640
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00003641 r.addResultLocked(null, resultWho, requestCode, resultCode, data);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003642 }
3643
Shunta Sato63b8ee32016-07-11 13:32:52 +09003644 /** Returns true if the task is one of the task finishing on-top of the top running task. */
Wale Ogunwale66e16852017-10-19 13:35:52 -07003645 private boolean isATopFinishingTask(TaskRecord task) {
Shunta Sato63b8ee32016-07-11 13:32:52 +09003646 for (int i = mTaskHistory.size() - 1; i >= 0; --i) {
3647 final TaskRecord current = mTaskHistory.get(i);
3648 final ActivityRecord r = current.topRunningActivityLocked();
3649 if (r != null) {
3650 // We got a top running activity, so there isn't a top finishing task...
3651 return false;
3652 }
3653 if (current == task) {
3654 return true;
3655 }
3656 }
3657 return false;
3658 }
3659
Wale Ogunwale66e16852017-10-19 13:35:52 -07003660 private void adjustFocusedActivityStack(ActivityRecord r, String reason) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08003661 if (!mRootActivityContainer.isTopDisplayFocusedStack(this) ||
Shunta Sato63b8ee32016-07-11 13:32:52 +09003662 ((mResumedActivity != r) && (mResumedActivity != null))) {
Wale Ogunwaled045c822015-12-02 09:14:28 -08003663 return;
3664 }
3665
3666 final ActivityRecord next = topRunningActivityLocked();
3667 final String myReason = reason + " adjustFocus";
Bryce Lee3345c4e2017-04-25 07:40:41 -07003668
Wale Ogunwale66e16852017-10-19 13:35:52 -07003669 if (next == r) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08003670 final ActivityRecord top = mRootActivityContainer.topRunningActivity();
Louis Chang19443452018-10-09 12:10:21 +08003671 if (top != null) {
3672 top.moveFocusableActivityToTop(myReason);
3673 }
Wale Ogunwale66e16852017-10-19 13:35:52 -07003674 return;
Wale Ogunwaled045c822015-12-02 09:14:28 -08003675 }
Wale Ogunwaled697cea2015-02-20 17:19:49 -08003676
Wale Ogunwale66e16852017-10-19 13:35:52 -07003677 if (next != null && isFocusable()) {
3678 // Keep focus in stack if we have a top running activity and are focusable.
3679 return;
3680 }
3681
3682 // Task is not guaranteed to be non-null. For example, destroying the
3683 // {@link ActivityRecord} will disassociate the task from the activity.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003684 final TaskRecord task = r.getTaskRecord();
Wale Ogunwale66e16852017-10-19 13:35:52 -07003685
3686 if (task == null) {
3687 throw new IllegalStateException("activity no longer associated with task:" + r);
3688 }
3689
3690 // Move focus to next focusable stack if possible.
Riddle Hsu3026e8d2018-08-03 15:50:53 +08003691 final ActivityStack nextFocusableStack = adjustFocusToNextFocusableStack(myReason);
3692 if (nextFocusableStack != null) {
3693 final ActivityRecord top = nextFocusableStack.topRunningActivityLocked();
Wale Ogunwaled32da472018-11-16 07:19:28 -08003694 if (top != null && top == mRootActivityContainer.getTopResumedActivity()) {
Riddle Hsu3026e8d2018-08-03 15:50:53 +08003695 // TODO(b/111361570): Remove this and update focused app per-display in
3696 // WindowManager every time an activity becomes resumed in
3697 // ActivityTaskManagerService#setResumedActivityUncheckLocked().
3698 mService.setResumedActivityUncheckLocked(top, reason);
3699 }
Wale Ogunwale66e16852017-10-19 13:35:52 -07003700 return;
3701 }
3702
3703 // Whatever...go home.
Louis Changbd48dca2018-08-29 17:44:34 +08003704 getDisplay().moveHomeActivityToTop(myReason);
Craig Mautner04f0b702013-10-22 12:31:01 -07003705 }
3706
Andrii Kulianab132ee2018-07-24 22:10:21 +08003707 /**
3708 * Find next proper focusable stack and make it focused.
3709 * @return The stack that now got the focus, {@code null} if none found.
3710 */
3711 ActivityStack adjustFocusToNextFocusableStack(String reason) {
Wale Ogunwale66e16852017-10-19 13:35:52 -07003712 return adjustFocusToNextFocusableStack(reason, false /* allowFocusSelf */);
Andrii Kulian250d6532017-02-08 23:30:45 -08003713 }
3714
3715 /**
3716 * Find next proper focusable stack and make it focused.
3717 * @param allowFocusSelf Is the focus allowed to remain on the same stack.
Andrii Kulianab132ee2018-07-24 22:10:21 +08003718 * @return The stack that now got the focus, {@code null} if none found.
Andrii Kulian250d6532017-02-08 23:30:45 -08003719 */
Andrii Kulianab132ee2018-07-24 22:10:21 +08003720 private ActivityStack adjustFocusToNextFocusableStack(String reason, boolean allowFocusSelf) {
Wale Ogunwalee1f68ce2018-03-09 08:58:54 -08003721 final ActivityStack stack =
Wale Ogunwaled32da472018-11-16 07:19:28 -08003722 mRootActivityContainer.getNextFocusableStack(this, !allowFocusSelf);
Wale Ogunwale4cea0f52015-12-25 06:30:31 -08003723 final String myReason = reason + " adjustFocusToNextFocusableStack";
Wale Ogunwaled697cea2015-02-20 17:19:49 -08003724 if (stack == null) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08003725 return null;
Wale Ogunwaled697cea2015-02-20 17:19:49 -08003726 }
Wale Ogunwaled34e80c2016-03-23 17:08:44 -07003727
Wale Ogunwalec750f5f2016-03-28 07:43:51 -07003728 final ActivityRecord top = stack.topRunningActivityLocked();
3729
Wale Ogunwale66e16852017-10-19 13:35:52 -07003730 if (stack.isActivityTypeHome() && (top == null || !top.visible)) {
Wale Ogunwalec750f5f2016-03-28 07:43:51 -07003731 // If we will be focusing on the home stack next and its current top activity isn't
Wale Ogunwale66e16852017-10-19 13:35:52 -07003732 // visible, then use the move the home stack task to top to make the activity visible.
Louis Changbd48dca2018-08-29 17:44:34 +08003733 stack.getDisplay().moveHomeActivityToTop(reason);
Andrii Kulianab132ee2018-07-24 22:10:21 +08003734 return stack;
Wale Ogunwaled34e80c2016-03-23 17:08:44 -07003735 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07003736
3737 stack.moveToFront(myReason);
Andrii Kulianab132ee2018-07-24 22:10:21 +08003738 return stack;
Wale Ogunwaled697cea2015-02-20 17:19:49 -08003739 }
3740
Craig Mautnerf3333272013-04-22 10:55:53 -07003741 final void stopActivityLocked(ActivityRecord r) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07003742 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH, "Stopping: " + r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003743 if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
3744 || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) {
3745 if (!r.finishing) {
David Stevens9440dc82017-03-16 19:00:20 -07003746 if (!shouldSleepActivities()) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07003747 if (DEBUG_STATES) Slog.d(TAG_STATES, "no-history finish of " + r);
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00003748 if (requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
3749 "stop-no-history", false)) {
Bryce Lee3345c4e2017-04-25 07:40:41 -07003750 // If {@link requestFinishActivityLocked} returns {@code true},
Wale Ogunwale66e16852017-10-19 13:35:52 -07003751 // {@link adjustFocusedActivityStack} would have been already called.
Wale Ogunwale3f529ee2015-07-12 15:14:01 -07003752 r.resumeKeyDispatchingLocked();
3753 return;
3754 }
Christopher Tated3f175c2012-06-14 14:16:54 -07003755 } else {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07003756 if (DEBUG_STATES) Slog.d(TAG_STATES, "Not finishing noHistory " + r
Christopher Tated3f175c2012-06-14 14:16:54 -07003757 + " on stop because we're just sleeping");
3758 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003759 }
Christopher Tate5007ddd2012-06-12 13:08:18 -07003760 }
3761
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003762 if (r.attachedToProcess()) {
Wale Ogunwale66e16852017-10-19 13:35:52 -07003763 adjustFocusedActivityStack(r, "stopActivity");
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08003764 r.resumeKeyDispatchingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003765 try {
3766 r.stopped = false;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07003767 if (DEBUG_STATES) Slog.v(TAG_STATES,
3768 "Moving to STOPPING: " + r + " (stop requested)");
Bryce Lee7ace3952018-02-16 14:34:32 -08003769 r.setState(STOPPING, "stopActivityLocked");
Wale Ogunwaleee006da2015-03-30 14:49:25 -07003770 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
3771 "Stopping visible=" + r.visible + " for " + r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003772 if (!r.visible) {
Wale Ogunwaleb9a0c992017-04-18 07:25:20 -07003773 r.setVisible(false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003774 }
Wale Ogunwalecd7043e2016-02-27 17:37:46 -08003775 EventLogTags.writeAmStopActivity(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003776 r.mUserId, System.identityHashCode(r), r.shortComponentName);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003777 mService.getLifecycleManager().scheduleTransaction(r.app.getThread(), r.appToken,
Bryce Lee1d0d5142018-04-12 10:35:07 -07003778 StopActivityItem.obtain(r.visible, r.configChangeFlags));
David Stevens9440dc82017-03-16 19:00:20 -07003779 if (shouldSleepOrShutDownActivities()) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08003780 r.setSleeping(true);
3781 }
Craig Mautnerf7bfefb2013-05-16 17:30:44 -07003782 Message msg = mHandler.obtainMessage(STOP_TIMEOUT_MSG, r);
Dianne Hackborn162bc0e2012-04-09 14:06:16 -07003783 mHandler.sendMessageDelayed(msg, STOP_TIMEOUT);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003784 } catch (Exception e) {
3785 // Maybe just ignore exceptions here... if the process
3786 // has crashed, our death notification will clean things
3787 // up.
3788 Slog.w(TAG, "Exception thrown during pause", e);
3789 // Just in case, assume it to be stopped.
3790 r.stopped = true;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07003791 if (DEBUG_STATES) Slog.v(TAG_STATES, "Stop failed; moving to STOPPED: " + r);
Bryce Lee7ace3952018-02-16 14:34:32 -08003792 r.setState(STOPPED, "stopActivityLocked");
Wale Ogunwalef81c1d12016-01-12 12:20:18 -08003793 if (r.deferRelaunchUntilPaused) {
Craig Mautneree2e45a2014-06-27 12:10:03 -07003794 destroyActivityLocked(r, true, "stop-except");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003795 }
3796 }
3797 }
3798 }
Craig Mautner23ac33b2013-04-01 16:26:35 -07003799
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003800 /**
3801 * @return Returns true if the activity is being finished, false if for
3802 * some reason it is being left as-is.
3803 */
3804 final boolean requestFinishActivityLocked(IBinder token, int resultCode,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00003805 Intent resultData, String reason, boolean oomAdj) {
Craig Mautnerd74f7d72013-02-26 13:41:02 -08003806 ActivityRecord r = isInStackLocked(token);
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07003807 if (DEBUG_RESULTS || DEBUG_STATES) Slog.v(TAG_STATES,
3808 "Finishing activity token=" + token + " r="
Christopher Tated3f175c2012-06-14 14:16:54 -07003809 + ", result=" + resultCode + ", data=" + resultData
3810 + ", reason=" + reason);
Craig Mautnerd74f7d72013-02-26 13:41:02 -08003811 if (r == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003812 return false;
3813 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003814
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00003815 finishActivityLocked(r, resultCode, resultData, reason, oomAdj);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003816 return true;
3817 }
3818
Craig Mautnerd2328952013-03-05 12:46:26 -08003819 final void finishSubActivityLocked(ActivityRecord self, String resultWho, int requestCode) {
Craig Mautner9658b312013-02-28 10:55:59 -08003820 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
3821 ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
3822 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
3823 ActivityRecord r = activities.get(activityNdx);
3824 if (r.resultTo == self && r.requestCode == requestCode) {
3825 if ((r.resultWho == null && resultWho == null) ||
3826 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00003827 finishActivityLocked(r, Activity.RESULT_CANCELED, null, "request-sub",
3828 false);
Craig Mautner9658b312013-02-28 10:55:59 -08003829 }
Dianne Hackbornecc5a9c2012-04-26 18:56:09 -07003830 }
3831 }
3832 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003833 mService.updateOomAdj();
Dianne Hackbornecc5a9c2012-04-26 18:56:09 -07003834 }
3835
Andrii Kulian8cc92ac62018-04-02 23:14:18 -07003836 /**
3837 * Finish the topmost activity that belongs to the crashed app. We may also finish the activity
3838 * that requested launch of the crashed one to prevent launch-crash loop.
3839 * @param app The app that crashed.
3840 * @param reason Reason to perform this action.
3841 * @return The task that was finished in this stack, {@code null} if top running activity does
3842 * not belong to the crashed app.
3843 */
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003844 final TaskRecord finishTopCrashedActivityLocked(WindowProcessController app, String reason) {
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -07003845 ActivityRecord r = topRunningActivityLocked();
Adrian Roos20d7df32016-01-12 18:59:43 +01003846 TaskRecord finishedTask = null;
3847 if (r == null || r.app != app) {
3848 return null;
3849 }
3850 Slog.w(TAG, " Force finishing activity "
3851 + r.intent.getComponent().flattenToShortString());
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003852 finishedTask = r.getTaskRecord();
Bryce Leeaf691c02017-03-20 14:20:22 -07003853 int taskNdx = mTaskHistory.indexOf(finishedTask);
3854 final TaskRecord task = finishedTask;
3855 int activityNdx = task.mActivities.indexOf(r);
Wale Ogunwale3a256e62018-12-06 14:41:18 -08003856 getDisplay().mDisplayContent.prepareAppTransition(
lumark588a3e82018-07-20 18:53:54 +08003857 TRANSIT_CRASHING_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */);
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00003858 finishActivityLocked(r, Activity.RESULT_CANCELED, null, reason, false);
Bryce Leeaf691c02017-03-20 14:20:22 -07003859 finishedTask = task;
Adrian Roos20d7df32016-01-12 18:59:43 +01003860 // Also terminate any activities below it that aren't yet
3861 // stopped, to avoid a situation where one will get
3862 // re-start our crashing activity once it gets resumed again.
3863 --activityNdx;
3864 if (activityNdx < 0) {
3865 do {
3866 --taskNdx;
3867 if (taskNdx < 0) {
3868 break;
3869 }
3870 activityNdx = mTaskHistory.get(taskNdx).mActivities.size() - 1;
3871 } while (activityNdx < 0);
3872 }
3873 if (activityNdx >= 0) {
3874 r = mTaskHistory.get(taskNdx).mActivities.get(activityNdx);
Bryce Lee7ace3952018-02-16 14:34:32 -08003875 if (r.isState(RESUMED, PAUSING, PAUSED)) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003876 if (!r.isActivityTypeHome() || mService.mHomeProcess != r.app) {
Adrian Roos20d7df32016-01-12 18:59:43 +01003877 Slog.w(TAG, " Force finishing activity "
3878 + r.intent.getComponent().flattenToShortString());
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00003879 finishActivityLocked(r, Activity.RESULT_CANCELED, null, reason, false);
Craig Mautner05d6272ba2013-02-11 09:39:27 -08003880 }
3881 }
3882 }
Adrian Roos20d7df32016-01-12 18:59:43 +01003883 return finishedTask;
Craig Mautner05d6272ba2013-02-11 09:39:27 -08003884 }
3885
Dianne Hackborn6ea0d0a2014-07-02 16:23:21 -07003886 final void finishVoiceTask(IVoiceInteractionSession session) {
3887 IBinder sessionBinder = session.asBinder();
3888 boolean didOne = false;
3889 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
3890 TaskRecord tr = mTaskHistory.get(taskNdx);
3891 if (tr.voiceSession != null && tr.voiceSession.asBinder() == sessionBinder) {
3892 for (int activityNdx = tr.mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
3893 ActivityRecord r = tr.mActivities.get(activityNdx);
3894 if (!r.finishing) {
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00003895 finishActivityLocked(r, Activity.RESULT_CANCELED, null, "finish-voice",
3896 false);
Dianne Hackborn6ea0d0a2014-07-02 16:23:21 -07003897 didOne = true;
3898 }
3899 }
Amith Yamasani0af6fa72016-01-17 15:36:19 -08003900 } else {
3901 // Check if any of the activities are using voice
3902 for (int activityNdx = tr.mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
3903 ActivityRecord r = tr.mActivities.get(activityNdx);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003904 if (r.voiceSession != null && r.voiceSession.asBinder() == sessionBinder) {
Amith Yamasani0af6fa72016-01-17 15:36:19 -08003905 // Inform of cancellation
3906 r.clearVoiceSessionLocked();
3907 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003908 r.app.getThread().scheduleLocalVoiceInteractionStarted(
3909 r.appToken, null);
Amith Yamasani0af6fa72016-01-17 15:36:19 -08003910 } catch (RemoteException re) {
3911 // Ok
3912 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003913 mService.finishRunningVoiceLocked();
Amith Yamasani0af6fa72016-01-17 15:36:19 -08003914 break;
3915 }
3916 }
Dianne Hackborn6ea0d0a2014-07-02 16:23:21 -07003917 }
3918 }
Amith Yamasani0af6fa72016-01-17 15:36:19 -08003919
Dianne Hackborn6ea0d0a2014-07-02 16:23:21 -07003920 if (didOne) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07003921 mService.updateOomAdj();
Dianne Hackborn6ea0d0a2014-07-02 16:23:21 -07003922 }
3923 }
3924
Craig Mautnerd2328952013-03-05 12:46:26 -08003925 final boolean finishActivityAffinityLocked(ActivityRecord r) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003926 ArrayList<ActivityRecord> activities = r.getTaskRecord().mActivities;
Craig Mautnerd74f7d72013-02-26 13:41:02 -08003927 for (int index = activities.indexOf(r); index >= 0; --index) {
3928 ActivityRecord cur = activities.get(index);
Kenny Roote6585b32013-12-13 12:00:26 -08003929 if (!Objects.equals(cur.taskAffinity, r.taskAffinity)) {
Dianne Hackbornecc5a9c2012-04-26 18:56:09 -07003930 break;
3931 }
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00003932 finishActivityLocked(cur, Activity.RESULT_CANCELED, null, "request-affinity", true);
Dianne Hackbornecc5a9c2012-04-26 18:56:09 -07003933 }
3934 return true;
3935 }
3936
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00003937 private void finishActivityResultsLocked(ActivityRecord r, int resultCode, Intent resultData) {
Dianne Hackborn5c607432012-02-28 14:44:19 -08003938 // send the result
3939 ActivityRecord resultTo = r.resultTo;
3940 if (resultTo != null) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07003941 if (DEBUG_RESULTS) Slog.v(TAG_RESULTS, "Adding result to " + resultTo
Dianne Hackborn5c607432012-02-28 14:44:19 -08003942 + " who=" + r.resultWho + " req=" + r.requestCode
3943 + " res=" + resultCode + " data=" + resultData);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003944 if (resultTo.mUserId != r.mUserId) {
Nicolas Prevot6b942b82014-06-02 15:20:42 +01003945 if (resultData != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003946 resultData.prepareToLeaveUser(r.mUserId);
Nicolas Prevot6b942b82014-06-02 15:20:42 +01003947 }
Nicolas Prevotc6cf95c2014-05-29 11:30:36 +01003948 }
Dianne Hackborn5c607432012-02-28 14:44:19 -08003949 if (r.info.applicationInfo.uid > 0) {
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00003950 mService.mUgmInternal.grantUriPermissionFromIntent(r.info.applicationInfo.uid,
3951 resultTo.packageName, resultData,
3952 resultTo.getUriPermissionsLocked(), resultTo.mUserId);
Dianne Hackborn5c607432012-02-28 14:44:19 -08003953 }
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07003954 resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode, resultData);
Dianne Hackborn5c607432012-02-28 14:44:19 -08003955 r.resultTo = null;
3956 }
Wale Ogunwaleee006da2015-03-30 14:49:25 -07003957 else if (DEBUG_RESULTS) Slog.v(TAG_RESULTS, "No result destination from " + r);
Dianne Hackborn5c607432012-02-28 14:44:19 -08003958
3959 // Make sure this HistoryRecord is not holding on to other resources,
3960 // because clients have remote IPC references to this object so we
3961 // can't assume that will go away and want to avoid circular IPC refs.
3962 r.results = null;
3963 r.pendingResults = null;
3964 r.newIntents = null;
3965 r.icicle = null;
3966 }
3967
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00003968 /**
3969 * See {@link #finishActivityLocked(ActivityRecord, int, Intent, String, boolean, boolean)}
3970 */
Winson Chung6954fc92017-03-24 16:22:12 -07003971 final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00003972 String reason, boolean oomAdj) {
3973 return finishActivityLocked(r, resultCode, resultData, reason, oomAdj, !PAUSE_IMMEDIATELY);
Winson Chung6954fc92017-03-24 16:22:12 -07003974 }
3975
3976 /**
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003977 * @return Returns true if this activity has been removed from the history
3978 * list, or false if it is still in the list and will be removed later.
3979 */
Craig Mautnerf3333272013-04-22 10:55:53 -07003980 final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00003981 String reason, boolean oomAdj, boolean pauseImmediately) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003982 if (r.finishing) {
3983 Slog.w(TAG, "Duplicate finish request for " + r);
3984 return false;
3985 }
3986
Jorim Jaggife762342016-10-13 14:33:27 +02003987 mWindowManager.deferSurfaceLayout();
3988 try {
3989 r.makeFinishingLocked();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003990 final TaskRecord task = r.getTaskRecord();
Jorim Jaggife762342016-10-13 14:33:27 +02003991 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003992 r.mUserId, System.identityHashCode(r),
Jorim Jaggife762342016-10-13 14:33:27 +02003993 task.taskId, r.shortComponentName, reason);
3994 final ArrayList<ActivityRecord> activities = task.mActivities;
3995 final int index = activities.indexOf(r);
3996 if (index < (activities.size() - 1)) {
3997 task.setFrontOfTask();
3998 if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
3999 // If the caller asked that this activity (and all above it)
4000 // be cleared when the task is reset, don't lose that information,
4001 // but propagate it up to the next activity.
4002 ActivityRecord next = activities.get(index+1);
4003 next.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
4004 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004005 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004006
Jorim Jaggife762342016-10-13 14:33:27 +02004007 r.pauseKeyDispatchingLocked();
Craig Mautner04f0b702013-10-22 12:31:01 -07004008
Wale Ogunwale66e16852017-10-19 13:35:52 -07004009 adjustFocusedActivityStack(r, "finishActivity");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004010
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00004011 finishActivityResultsLocked(r, resultCode, resultData);
Craig Mautner2420ead2013-04-01 17:13:20 -07004012
Yorke Leebdef5372017-04-10 16:38:51 -07004013 final boolean endTask = index <= 0 && !task.isClearingToReuseTask();
Jorim Jaggife762342016-10-13 14:33:27 +02004014 final int transit = endTask ? TRANSIT_TASK_CLOSE : TRANSIT_ACTIVITY_CLOSE;
4015 if (mResumedActivity == r) {
4016 if (DEBUG_VISIBILITY || DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
4017 "Prepare close transition: finishing " + r);
Winson Chung6954fc92017-03-24 16:22:12 -07004018 if (endTask) {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07004019 mService.getTaskChangeNotificationController().notifyTaskRemovalStarted(
Mark Renoufc808f062019-02-07 15:20:37 -05004020 task.getTaskInfo());
Winson Chung6954fc92017-03-24 16:22:12 -07004021 }
Wale Ogunwale3a256e62018-12-06 14:41:18 -08004022 getDisplay().mDisplayContent.prepareAppTransition(transit, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004023
Jorim Jaggife762342016-10-13 14:33:27 +02004024 // Tell window manager to prepare for this one to be removed.
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08004025 r.setVisibility(false);
Jorim Jaggife762342016-10-13 14:33:27 +02004026
4027 if (mPausingActivity == null) {
4028 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish needs to pause: " + r);
4029 if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
4030 "finish() => pause with userLeaving=false");
Winson Chung6954fc92017-03-24 16:22:12 -07004031 startPausingLocked(false, false, null, pauseImmediately);
Jorim Jaggife762342016-10-13 14:33:27 +02004032 }
4033
4034 if (endTask) {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07004035 mService.getLockTaskController().clearLockedTask(task);
Jorim Jaggife762342016-10-13 14:33:27 +02004036 }
Bryce Lee7ace3952018-02-16 14:34:32 -08004037 } else if (!r.isState(PAUSING)) {
Jorim Jaggife762342016-10-13 14:33:27 +02004038 // If the activity is PAUSING, we will complete the finish once
4039 // it is done pausing; else we can just directly finish it here.
4040 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish not pausing: " + r);
4041 if (r.visible) {
Winson Chung6954fc92017-03-24 16:22:12 -07004042 prepareActivityHideTransitionAnimation(r, transit);
4043 }
4044
4045 final int finishMode = (r.visible || r.nowVisible) ? FINISH_AFTER_VISIBLE
4046 : FINISH_AFTER_PAUSE;
Bryce Leef52974c2018-02-14 15:12:01 -08004047 final boolean removedActivity = finishCurrentActivityLocked(r, finishMode, oomAdj,
4048 "finishActivityLocked") == null;
Winson Chung6954fc92017-03-24 16:22:12 -07004049
4050 // The following code is an optimization. When the last non-task overlay activity
4051 // is removed from the task, we remove the entire task from the stack. However,
4052 // since that is done after the scheduled destroy callback from the activity, that
4053 // call to change the visibility of the task overlay activities would be out of
4054 // sync with the activitiy visibility being set for this finishing activity above.
4055 // In this case, we can set the visibility of all the task overlay activities when
4056 // we detect the last one is finishing to keep them in sync.
4057 if (task.onlyHasTaskOverlayActivities(true /* excludeFinishing */)) {
4058 for (ActivityRecord taskOverlay : task.mActivities) {
4059 if (!taskOverlay.mTaskOverlay) {
4060 continue;
4061 }
4062 prepareActivityHideTransitionAnimation(taskOverlay, transit);
Jorim Jaggife762342016-10-13 14:33:27 +02004063 }
4064 }
Winson Chung6954fc92017-03-24 16:22:12 -07004065 return removedActivity;
Jorim Jaggife762342016-10-13 14:33:27 +02004066 } else {
4067 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish waiting for pause of: " + r);
4068 }
4069
4070 return false;
4071 } finally {
4072 mWindowManager.continueSurfaceLayout();
4073 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004074 }
4075
Winson Chung6954fc92017-03-24 16:22:12 -07004076 private void prepareActivityHideTransitionAnimation(ActivityRecord r, int transit) {
Wale Ogunwale3a256e62018-12-06 14:41:18 -08004077 final DisplayContent dc = getDisplay().mDisplayContent;
4078 dc.prepareAppTransition(transit, false);
Winson Chung6954fc92017-03-24 16:22:12 -07004079 r.setVisibility(false);
Wale Ogunwale3a256e62018-12-06 14:41:18 -08004080 dc.executeAppTransition();
Winson Chung6954fc92017-03-24 16:22:12 -07004081 }
4082
Craig Mautnerf3333272013-04-22 10:55:53 -07004083 static final int FINISH_IMMEDIATELY = 0;
4084 static final int FINISH_AFTER_PAUSE = 1;
4085 static final int FINISH_AFTER_VISIBLE = 2;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004086
Bryce Leef52974c2018-02-14 15:12:01 -08004087 final ActivityRecord finishCurrentActivityLocked(ActivityRecord r, int mode, boolean oomAdj,
4088 String reason) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004089 // First things first: if this activity is currently visible,
4090 // and the resumed activity is not yet visible, then hold off on
4091 // finishing until the resumed one becomes visible.
Chong Zhang824b6dc2016-04-27 14:11:12 -07004092
Bryce Leec961e0a2018-04-13 17:58:02 -07004093 // The activity that we are finishing may be over the lock screen. In this case, we do not
4094 // want to consider activities that cannot be shown on the lock screen as running and should
4095 // proceed with finishing the activity if there is no valid next top running activity.
lumarka6681162019-04-12 01:47:54 +08004096 // Note that if this finishing activity is floating task, we don't need to wait the
4097 // next activity resume and can destroy it directly.
Riddle Hsue10cea52018-10-16 23:33:23 +08004098 final ActivityDisplay display = getDisplay();
4099 final ActivityRecord next = display.topRunningActivity(true /* considerKeyguardState */);
lumarka6681162019-04-12 01:47:54 +08004100 final boolean isFloating = r.getConfiguration().windowConfiguration.tasksAreFloating();
Chong Zhang824b6dc2016-04-27 14:11:12 -07004101
Chong Zhangefd9a5b2016-04-26 16:21:07 -07004102 if (mode == FINISH_AFTER_VISIBLE && (r.visible || r.nowVisible)
lumarka6681162019-04-12 01:47:54 +08004103 && next != null && !next.nowVisible && !isFloating) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07004104 if (!mStackSupervisor.mStoppingActivities.contains(r)) {
wilsonshih401e50f2019-04-30 12:55:48 +08004105 addToStopping(r, false /* scheduleIdle */, false /* idleDelayed */,
4106 "finishCurrentActivityLocked");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004107 }
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004108 if (DEBUG_STATES) Slog.v(TAG_STATES,
4109 "Moving to STOPPING: "+ r + " (finish requested)");
Bryce Lee7ace3952018-02-16 14:34:32 -08004110 r.setState(STOPPING, "finishCurrentActivityLocked");
Dianne Hackborn2d1b3782012-09-09 17:49:39 -07004111 if (oomAdj) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004112 mService.updateOomAdj();
Dianne Hackborn2d1b3782012-09-09 17:49:39 -07004113 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004114 return r;
4115 }
4116
4117 // make sure the record is cleaned out of other places.
Craig Mautnerde4ef022013-04-07 19:01:33 -07004118 mStackSupervisor.mStoppingActivities.remove(r);
Craig Mautner0eea92c2013-05-16 13:35:39 -07004119 mStackSupervisor.mGoingToSleepActivities.remove(r);
Bryce Lee7ace3952018-02-16 14:34:32 -08004120 final ActivityState prevState = r.getState();
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004121 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to FINISHING: " + r);
Bryce Leeb0f993f2018-03-02 15:38:01 -08004122
Bryce Lee7ace3952018-02-16 14:34:32 -08004123 r.setState(FINISHING, "finishCurrentActivityLocked");
wilsonshih8824a8a2019-03-12 17:21:35 +08004124
4125 // Don't destroy activity immediately if the display contains home stack, although there is
4126 // no next activity at the moment but another home activity should be started later. Keep
4127 // this activity alive until next home activity is resumed then user won't see a temporary
4128 // black screen.
4129 final boolean noRunningStack = next == null && display.topRunningActivity() == null
4130 && display.getHomeStack() == null;
4131 final boolean noFocusedStack = r.getActivityStack() != display.getFocusedStack();
Riddle Hsue10cea52018-10-16 23:33:23 +08004132 final boolean finishingInNonFocusedStackOrNoRunning = mode == FINISH_AFTER_VISIBLE
wilsonshih8824a8a2019-03-12 17:21:35 +08004133 && prevState == PAUSED && (noFocusedStack || noRunningStack);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004134
4135 if (mode == FINISH_IMMEDIATELY
Bryce Lee7ace3952018-02-16 14:34:32 -08004136 || (prevState == PAUSED
Wale Ogunwale44f036f2017-09-29 05:09:09 -07004137 && (mode == FINISH_AFTER_PAUSE || inPinnedWindowingMode()))
Riddle Hsue10cea52018-10-16 23:33:23 +08004138 || finishingInNonFocusedStackOrNoRunning
Wale Ogunwaleb9a0c992017-04-18 07:25:20 -07004139 || prevState == STOPPING
4140 || prevState == STOPPED
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004141 || prevState == ActivityState.INITIALIZING) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07004142 r.makeFinishingLocked();
Bryce Leef52974c2018-02-14 15:12:01 -08004143 boolean activityRemoved = destroyActivityLocked(r, true, "finish-imm:" + reason);
Andrii Kulian7318d632016-07-20 18:59:28 -07004144
Riddle Hsue10cea52018-10-16 23:33:23 +08004145 if (finishingInNonFocusedStackOrNoRunning) {
Andrii Kulian995fa2b2016-07-29 12:55:41 -07004146 // Finishing activity that was in paused state and it was in not currently focused
Riddle Hsue10cea52018-10-16 23:33:23 +08004147 // stack, need to make something visible in its place. Also if the display does not
4148 // have running activity, the configuration may need to be updated for restoring
4149 // original orientation of the display.
Wale Ogunwaled32da472018-11-16 07:19:28 -08004150 mRootActivityContainer.ensureVisibilityAndConfig(next, mDisplayId,
Andrii Kulianf4479ee2018-05-23 17:52:48 -07004151 false /* markFrozenIfConfigChanged */, true /* deferResume */);
Andrii Kulian7318d632016-07-20 18:59:28 -07004152 }
Dianne Hackborn42e620c2012-06-24 13:20:51 -07004153 if (activityRemoved) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08004154 mRootActivityContainer.resumeFocusedStacksTopActivities();
Dianne Hackborn42e620c2012-06-24 13:20:51 -07004155 }
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004156 if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS,
Craig Mautnerd163e752014-06-13 17:18:47 -07004157 "destroyActivityLocked: finishCurrentActivityLocked r=" + r +
4158 " destroy returned removed=" + activityRemoved);
Dianne Hackborn42e620c2012-06-24 13:20:51 -07004159 return activityRemoved ? null : r;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004160 }
Craig Mautner05d6272ba2013-02-11 09:39:27 -08004161
4162 // Need to go through the full pause cycle to get this
4163 // activity into the stopped state and then finish it.
Wale Ogunwalee23149f2015-03-06 15:39:44 -08004164 if (DEBUG_ALL) Slog.v(TAG, "Enqueueing pending finish: " + r);
Craig Mautnerf3333272013-04-22 10:55:53 -07004165 mStackSupervisor.mFinishingActivities.add(r);
Martin Wallgrenc8733b82011-08-31 12:39:31 +02004166 r.resumeKeyDispatchingLocked();
Wale Ogunwaled32da472018-11-16 07:19:28 -08004167 mRootActivityContainer.resumeFocusedStacksTopActivities();
Andrii Kulian6b321512019-01-23 06:37:00 +00004168 // If activity was not paused at this point - explicitly pause it to start finishing
4169 // process. Finishing will be completed once it reports pause back.
4170 if (r.isState(RESUMED) && mPausingActivity != null) {
4171 startPausingLocked(false /* userLeaving */, false /* uiSleeping */, next /* resuming */,
4172 false /* dontWait */);
4173 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004174 return r;
4175 }
4176
Craig Mautneree36c772014-07-16 14:56:05 -07004177 void finishAllActivitiesLocked(boolean immediately) {
4178 boolean noActivitiesInStack = true;
Craig Mautnerf4c909b2014-04-17 18:39:38 -07004179 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
4180 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
4181 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
4182 final ActivityRecord r = activities.get(activityNdx);
Craig Mautneree36c772014-07-16 14:56:05 -07004183 noActivitiesInStack = false;
4184 if (r.finishing && !immediately) {
Craig Mautnerf4c909b2014-04-17 18:39:38 -07004185 continue;
4186 }
Craig Mautneree36c772014-07-16 14:56:05 -07004187 Slog.d(TAG, "finishAllActivitiesLocked: finishing " + r + " immediately");
Bryce Leef52974c2018-02-14 15:12:01 -08004188 finishCurrentActivityLocked(r, FINISH_IMMEDIATELY, false,
4189 "finishAllActivitiesLocked");
Craig Mautnerf4c909b2014-04-17 18:39:38 -07004190 }
4191 }
Craig Mautneree36c772014-07-16 14:56:05 -07004192 if (noActivitiesInStack) {
Andrii Kulian94e82d9b02017-07-13 15:33:06 -07004193 remove();
Craig Mautneree36c772014-07-16 14:56:05 -07004194 }
Craig Mautnerf4c909b2014-04-17 18:39:38 -07004195 }
4196
Wale Ogunwale66e16852017-10-19 13:35:52 -07004197 /** @return true if the stack behind this one is a standard activity type. */
4198 boolean inFrontOfStandardStack() {
4199 final ActivityDisplay display = getDisplay();
4200 if (display == null) {
4201 return false;
4202 }
4203 final int index = display.getIndexOf(this);
4204 if (index == 0) {
4205 return false;
4206 }
4207 final ActivityStack stackBehind = display.getChildAt(index - 1);
4208 return stackBehind.isActivityTypeStandard();
4209 }
4210
4211 boolean shouldUpRecreateTaskLocked(ActivityRecord srec, String destAffinity) {
Dianne Hackborn6f4d61f2014-08-21 17:50:42 -07004212 // Basic case: for simple app-centric recents, we need to recreate
4213 // the task if the affinity has changed.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08004214 if (srec == null || srec.getTaskRecord().affinity == null ||
4215 !srec.getTaskRecord().affinity.equals(destAffinity)) {
Dianne Hackborn6f4d61f2014-08-21 17:50:42 -07004216 return true;
4217 }
4218 // Document-centric case: an app may be split in to multiple documents;
4219 // they need to re-create their task if this current activity is the root
4220 // of a document, unless simply finishing it will return them to the the
4221 // correct app behind.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08004222 final TaskRecord task = srec.getTaskRecord();
Wale Ogunwale66e16852017-10-19 13:35:52 -07004223 if (srec.frontOfTask && task.getBaseIntent() != null && task.getBaseIntent().isDocument()) {
Dianne Hackborn6f4d61f2014-08-21 17:50:42 -07004224 // Okay, this activity is at the root of its task. What to do, what to do...
Wale Ogunwale66e16852017-10-19 13:35:52 -07004225 if (!inFrontOfStandardStack()) {
Dianne Hackborn6f4d61f2014-08-21 17:50:42 -07004226 // Finishing won't return to an application, so we need to recreate.
4227 return true;
4228 }
4229 // We now need to get the task below it to determine what to do.
Bryce Leeaf691c02017-03-20 14:20:22 -07004230 int taskIdx = mTaskHistory.indexOf(task);
Dianne Hackborn6f4d61f2014-08-21 17:50:42 -07004231 if (taskIdx <= 0) {
4232 Slog.w(TAG, "shouldUpRecreateTask: task not in history for " + srec);
4233 return false;
4234 }
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07004235 final TaskRecord prevTask = mTaskHistory.get(taskIdx);
Bryce Leeaf691c02017-03-20 14:20:22 -07004236 if (!task.affinity.equals(prevTask.affinity)) {
Dianne Hackborn6f4d61f2014-08-21 17:50:42 -07004237 // These are different apps, so need to recreate.
4238 return true;
4239 }
4240 }
4241 return false;
4242 }
4243
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00004244 final boolean navigateUpToLocked(ActivityRecord srec, Intent destIntent, int resultCode,
4245 Intent resultData) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08004246 final TaskRecord task = srec.getTaskRecord();
Craig Mautner0247fc82013-02-28 14:32:06 -08004247 final ArrayList<ActivityRecord> activities = task.mActivities;
4248 final int start = activities.indexOf(srec);
4249 if (!mTaskHistory.contains(task) || (start < 0)) {
Craig Mautner05d6272ba2013-02-11 09:39:27 -08004250 return false;
4251 }
4252 int finishTo = start - 1;
Craig Mautner0247fc82013-02-28 14:32:06 -08004253 ActivityRecord parent = finishTo < 0 ? null : activities.get(finishTo);
Craig Mautner05d6272ba2013-02-11 09:39:27 -08004254 boolean foundParentInTask = false;
Craig Mautner0247fc82013-02-28 14:32:06 -08004255 final ComponentName dest = destIntent.getComponent();
4256 if (start > 0 && dest != null) {
4257 for (int i = finishTo; i >= 0; i--) {
4258 ActivityRecord r = activities.get(i);
4259 if (r.info.packageName.equals(dest.getPackageName()) &&
Craig Mautner05d6272ba2013-02-11 09:39:27 -08004260 r.info.name.equals(dest.getClassName())) {
4261 finishTo = i;
4262 parent = r;
4263 foundParentInTask = true;
4264 break;
4265 }
4266 }
4267 }
4268
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004269 // TODO: There is a dup. of this block of code in ActivityTaskManagerService.finishActivity
4270 // We should consolidate.
4271 IActivityController controller = mService.mController;
Craig Mautner05d6272ba2013-02-11 09:39:27 -08004272 if (controller != null) {
4273 ActivityRecord next = topRunningActivityLocked(srec.appToken, 0);
4274 if (next != null) {
4275 // ask watcher if this is allowed
4276 boolean resumeOK = true;
4277 try {
4278 resumeOK = controller.activityResuming(next.packageName);
4279 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004280 mService.mController = null;
Kenny Rootadd58212013-05-07 09:47:34 -07004281 Watchdog.getInstance().setActivityController(null);
Craig Mautner05d6272ba2013-02-11 09:39:27 -08004282 }
4283
4284 if (!resumeOK) {
4285 return false;
4286 }
4287 }
4288 }
4289 final long origId = Binder.clearCallingIdentity();
4290 for (int i = start; i > finishTo; i--) {
Craig Mautner0247fc82013-02-28 14:32:06 -08004291 ActivityRecord r = activities.get(i);
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00004292 requestFinishActivityLocked(r.appToken, resultCode, resultData, "navigate-up", true);
Craig Mautner05d6272ba2013-02-11 09:39:27 -08004293 // Only return the supplied result for the first activity finished
4294 resultCode = Activity.RESULT_CANCELED;
4295 resultData = null;
4296 }
4297
4298 if (parent != null && foundParentInTask) {
4299 final int parentLaunchMode = parent.info.launchMode;
4300 final int destIntentFlags = destIntent.getFlags();
4301 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
4302 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
4303 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
4304 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
Dianne Hackborn85d558c2014-11-04 10:31:54 -08004305 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00004306 srec.packageName);
Craig Mautner05d6272ba2013-02-11 09:39:27 -08004307 } else {
4308 try {
4309 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
Philip P. Moltmanncff8f0f2018-03-27 12:51:51 -07004310 destIntent.getComponent(), ActivityManagerService.STOCK_PM_FLAGS,
Wale Ogunwale8b19de92018-11-29 19:58:26 -08004311 srec.mUserId);
Bryce Lee4c9a5972017-12-01 22:14:24 -08004312 // TODO(b/64750076): Check if calling pid should really be -1.
4313 final int res = mService.getActivityStartController()
4314 .obtainStarter(destIntent, "navigateUpTo")
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004315 .setCaller(srec.app.getThread())
Bryce Lee4c9a5972017-12-01 22:14:24 -08004316 .setActivityInfo(aInfo)
4317 .setResultTo(parent.appToken)
4318 .setCallingPid(-1)
4319 .setCallingUid(parent.launchedFromUid)
4320 .setCallingPackage(parent.launchedFromPackage)
4321 .setRealCallingPid(-1)
4322 .setRealCallingUid(parent.launchedFromUid)
4323 .setComponentSpecified(true)
4324 .execute();
Craig Mautner05d6272ba2013-02-11 09:39:27 -08004325 foundParentInTask = res == ActivityManager.START_SUCCESS;
4326 } catch (RemoteException e) {
4327 foundParentInTask = false;
4328 }
4329 requestFinishActivityLocked(parent.appToken, resultCode,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00004330 resultData, "navigate-top", true);
Craig Mautner05d6272ba2013-02-11 09:39:27 -08004331 }
4332 }
4333 Binder.restoreCallingIdentity(origId);
4334 return foundParentInTask;
4335 }
Bryce Leeaf691c02017-03-20 14:20:22 -07004336
4337 /**
4338 * Remove any state associated with the {@link ActivityRecord}. This should be called whenever
4339 * an activity moves away from the stack.
4340 */
4341 void onActivityRemovedFromStack(ActivityRecord r) {
Bryce Lee84730a02018-04-03 14:10:04 -07004342 removeTimeoutsForActivityLocked(r);
4343
4344 if (mResumedActivity != null && mResumedActivity == r) {
4345 setResumedActivity(null, "onActivityRemovedFromStack");
Bryce Leeaf691c02017-03-20 14:20:22 -07004346 }
Bryce Lee84730a02018-04-03 14:10:04 -07004347 if (mPausingActivity != null && mPausingActivity == r) {
Bryce Leeaf691c02017-03-20 14:20:22 -07004348 mPausingActivity = null;
4349 }
Bryce Lee84730a02018-04-03 14:10:04 -07004350 }
Bryce Leeaf691c02017-03-20 14:20:22 -07004351
Bryce Lee84730a02018-04-03 14:10:04 -07004352 void onActivityAddedToStack(ActivityRecord r) {
4353 if(r.getState() == RESUMED) {
4354 setResumedActivity(r, "onActivityAddedToStack");
4355 }
Bryce Leeaf691c02017-03-20 14:20:22 -07004356 }
4357
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004358 /**
4359 * Perform the common clean-up of an activity record. This is called both
4360 * as part of destroyActivityLocked() (when destroying the client-side
4361 * representation) and cleaning things up as a result of its hosting
4362 * processing going away, in which case there is no remaining client-side
4363 * state to destroy so only the cleanup here is needed.
Craig Mautneracebdc82015-02-24 10:53:03 -08004364 *
4365 * Note: Call before #removeActivityFromHistoryLocked.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004366 */
Bryce Leec9406602018-03-09 11:02:10 -08004367 private void cleanUpActivityLocked(ActivityRecord r, boolean cleanServices, boolean setState) {
Bryce Leeaf691c02017-03-20 14:20:22 -07004368 onActivityRemovedFromStack(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004369
Wale Ogunwalef81c1d12016-01-12 12:20:18 -08004370 r.deferRelaunchUntilPaused = false;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004371 r.frozenBeforeDestroy = false;
4372
Bryce Leec9406602018-03-09 11:02:10 -08004373 if (setState) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004374 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to DESTROYED: " + r + " (cleaning up)");
Bryce Lee7ace3952018-02-16 14:34:32 -08004375 r.setState(DESTROYED, "cleanupActivityLocked");
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004376 if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during cleanUp for activity " + r);
Dianne Hackborncc5a0552012-10-01 16:32:39 -07004377 r.app = null;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004378 }
4379
Bryce Lee4a194382017-04-04 14:32:48 -07004380 // Inform supervisor the activity has been removed.
4381 mStackSupervisor.cleanupActivity(r);
4382
Craig Mautner2420ead2013-04-01 17:13:20 -07004383
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004384 // Remove any pending results.
4385 if (r.finishing && r.pendingResults != null) {
4386 for (WeakReference<PendingIntentRecord> apr : r.pendingResults) {
4387 PendingIntentRecord rec = apr.get();
4388 if (rec != null) {
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07004389 mService.mPendingIntentController.cancelIntentSender(rec, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004390 }
4391 }
4392 r.pendingResults = null;
4393 }
4394
4395 if (cleanServices) {
Craig Mautner2420ead2013-04-01 17:13:20 -07004396 cleanUpActivityServicesLocked(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004397 }
4398
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004399 // Get rid of any pending idle timeouts.
Dianne Hackborn42e620c2012-06-24 13:20:51 -07004400 removeTimeoutsForActivityLocked(r);
Wale Ogunwale8fd75422016-06-24 14:20:37 -07004401 // Clean-up activities are no longer relaunching (e.g. app process died). Notify window
4402 // manager so it can update its bookkeeping.
4403 mWindowManager.notifyAppRelaunchesCleared(r.appToken);
Dianne Hackborn42e620c2012-06-24 13:20:51 -07004404 }
4405
Wale Ogunwale53783742018-09-16 10:21:51 -07004406 private void removeTimeoutsForActivityLocked(ActivityRecord r) {
Craig Mautnerf3333272013-04-22 10:55:53 -07004407 mStackSupervisor.removeTimeoutsForActivityLocked(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004408 mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
Dianne Hackborn162bc0e2012-04-09 14:06:16 -07004409 mHandler.removeMessages(STOP_TIMEOUT_MSG, r);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07004410 mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r);
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07004411 r.finishLaunchTickingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004412 }
4413
Chong Zhangbffd8892016-08-08 11:16:06 -07004414 private void removeActivityFromHistoryLocked(ActivityRecord r, String reason) {
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00004415 finishActivityResultsLocked(r, Activity.RESULT_CANCELED, null);
Wale Ogunwale7d701172015-03-11 15:36:30 -07004416 r.makeFinishingLocked();
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004417 if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE,
4418 "Removing activity " + r + " from stack callers=" + Debug.getCallers(5));
4419
Dianne Hackborncc5a0552012-10-01 16:32:39 -07004420 r.takeFromHistory();
4421 removeTimeoutsForActivityLocked(r);
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004422 if (DEBUG_STATES) Slog.v(TAG_STATES,
4423 "Moving to DESTROYED: " + r + " (removed from history)");
Bryce Lee7ace3952018-02-16 14:34:32 -08004424 r.setState(DESTROYED, "removeActivityFromHistoryLocked");
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004425 if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during remove for activity " + r);
Dianne Hackborncc5a0552012-10-01 16:32:39 -07004426 r.app = null;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08004427 r.removeWindowContainer();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08004428 final TaskRecord task = r.getTaskRecord();
Bryce Leeaa5e8c32017-03-01 16:01:06 -08004429 final boolean lastActivity = task != null ? task.removeActivity(r) : false;
Winson Chung6954fc92017-03-24 16:22:12 -07004430 // If we are removing the last activity in the task, not including task overlay activities,
4431 // then fall through into the block below to remove the entire task itself
4432 final boolean onlyHasTaskOverlays = task != null
4433 ? task.onlyHasTaskOverlayActivities(false /* excludingFinishing */) : false;
Bryce Leeaa5e8c32017-03-01 16:01:06 -08004434
Winson Chung6954fc92017-03-24 16:22:12 -07004435 if (lastActivity || onlyHasTaskOverlays) {
4436 if (DEBUG_STACK) {
4437 Slog.i(TAG_STACK,
4438 "removeActivityFromHistoryLocked: last activity removed from " + this
4439 + " onlyHasTaskOverlays=" + onlyHasTaskOverlays);
4440 }
4441
Bryce Leed6d26752017-05-25 13:57:46 -07004442 // The following block can be executed multiple times if there is more than one overlay.
4443 // {@link ActivityStackSupervisor#removeTaskByIdLocked} handles this by reverse lookup
4444 // of the task by id and exiting early if not found.
Winson Chunge3c21e02017-04-11 18:02:17 -07004445 if (onlyHasTaskOverlays) {
4446 // When destroying a task, tell the supervisor to remove it so that any activity it
4447 // has can be cleaned up correctly. This is currently the only place where we remove
4448 // a task with the DESTROYING mode, so instead of passing the onlyHasTaskOverlays
4449 // state into removeTask(), we just clear the task here before the other residual
4450 // work.
4451 // TODO: If the callers to removeTask() changes such that we have multiple places
4452 // where we are destroying the task, move this back into removeTask()
4453 mStackSupervisor.removeTaskByIdLocked(task.taskId, false /* killProcess */,
Winson Chung0ec2a352017-10-26 11:38:30 -07004454 !REMOVE_FROM_RECENTS, PAUSE_IMMEDIATELY, reason);
Winson Chunge3c21e02017-04-11 18:02:17 -07004455 }
Bryce Lee1d930582017-05-01 08:35:24 -07004456
Bryce Leed6d26752017-05-25 13:57:46 -07004457 // We must keep the task around until all activities are destroyed. The following
4458 // statement will only execute once since overlays are also considered activities.
Bryce Lee1d930582017-05-01 08:35:24 -07004459 if (lastActivity) {
4460 removeTask(task, reason, REMOVE_TASK_MODE_DESTROYING);
4461 }
Craig Mautner312ba862014-02-10 17:55:01 -08004462 }
Dianne Hackborncc5a0552012-10-01 16:32:39 -07004463 cleanUpActivityServicesLocked(r);
4464 r.removeUriPermissionsLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004465 }
Craig Mautnerdbcb31f2013-04-02 12:32:53 -07004466
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004467 /**
4468 * Perform clean-up of service connections in an activity record.
4469 */
Andrii Kulian21713ac2016-10-12 22:05:05 -07004470 private void cleanUpActivityServicesLocked(ActivityRecord r) {
Wale Ogunwalec4e63a42018-10-02 13:19:54 -07004471 if (r.mServiceConnectionsHolder == null) {
4472 return;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004473 }
Wale Ogunwalec4e63a42018-10-02 13:19:54 -07004474 // Throw away any services that have been bound by this activity.
4475 r.mServiceConnectionsHolder.disconnectActivityFromServices();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004476 }
Dianne Hackborn755c8bf2012-05-07 15:06:09 -07004477
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004478 final void scheduleDestroyActivities(WindowProcessController owner, String reason) {
Dianne Hackborn755c8bf2012-05-07 15:06:09 -07004479 Message msg = mHandler.obtainMessage(DESTROY_ACTIVITIES_MSG);
Craig Mautneree2e45a2014-06-27 12:10:03 -07004480 msg.obj = new ScheduleDestroyArgs(owner, reason);
Dianne Hackborn755c8bf2012-05-07 15:06:09 -07004481 mHandler.sendMessage(msg);
4482 }
4483
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004484 private void destroyActivitiesLocked(WindowProcessController owner, String reason) {
Dianne Hackborn755c8bf2012-05-07 15:06:09 -07004485 boolean lastIsOpaque = false;
Dianne Hackborn42e620c2012-06-24 13:20:51 -07004486 boolean activityRemoved = false;
Craig Mautnerd44711d2013-02-23 11:24:36 -08004487 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
4488 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
4489 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
4490 final ActivityRecord r = activities.get(activityNdx);
4491 if (r.finishing) {
4492 continue;
4493 }
4494 if (r.fullscreen) {
4495 lastIsOpaque = true;
4496 }
4497 if (owner != null && r.app != owner) {
4498 continue;
4499 }
4500 if (!lastIsOpaque) {
4501 continue;
4502 }
Dianne Hackborn89ad4562014-08-24 16:45:38 -07004503 if (r.isDestroyable()) {
Bryce Lee7ace3952018-02-16 14:34:32 -08004504 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Destroying " + r
4505 + " in state " + r.getState()
Craig Mautnerd44711d2013-02-23 11:24:36 -08004506 + " resumed=" + mResumedActivity
Dianne Hackborn89ad4562014-08-24 16:45:38 -07004507 + " pausing=" + mPausingActivity + " for reason " + reason);
Craig Mautneree2e45a2014-06-27 12:10:03 -07004508 if (destroyActivityLocked(r, true, reason)) {
Craig Mautnerd44711d2013-02-23 11:24:36 -08004509 activityRemoved = true;
4510 }
Dianne Hackborn42e620c2012-06-24 13:20:51 -07004511 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004512 }
4513 }
Dianne Hackborn42e620c2012-06-24 13:20:51 -07004514 if (activityRemoved) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08004515 mRootActivityContainer.resumeFocusedStacksTopActivities();
Dianne Hackborn42e620c2012-06-24 13:20:51 -07004516 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004517 }
4518
Dianne Hackborn89ad4562014-08-24 16:45:38 -07004519 final boolean safelyDestroyActivityLocked(ActivityRecord r, String reason) {
4520 if (r.isDestroyable()) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07004521 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
Bryce Lee7ace3952018-02-16 14:34:32 -08004522 "Destroying " + r + " in state " + r.getState() + " resumed=" + mResumedActivity
Dianne Hackborn89ad4562014-08-24 16:45:38 -07004523 + " pausing=" + mPausingActivity + " for reason " + reason);
4524 return destroyActivityLocked(r, true, reason);
4525 }
4526 return false;
4527 }
4528
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004529 final int releaseSomeActivitiesLocked(WindowProcessController app, ArraySet<TaskRecord> tasks,
Dianne Hackborn89ad4562014-08-24 16:45:38 -07004530 String reason) {
4531 // Iterate over tasks starting at the back (oldest) first.
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004532 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Trying to release some activities in " + app);
Dianne Hackborn89ad4562014-08-24 16:45:38 -07004533 int maxTasks = tasks.size() / 4;
4534 if (maxTasks < 1) {
4535 maxTasks = 1;
4536 }
4537 int numReleased = 0;
4538 for (int taskNdx = 0; taskNdx < mTaskHistory.size() && maxTasks > 0; taskNdx++) {
4539 final TaskRecord task = mTaskHistory.get(taskNdx);
4540 if (!tasks.contains(task)) {
4541 continue;
4542 }
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004543 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Looking for activities to release in " + task);
Dianne Hackborn89ad4562014-08-24 16:45:38 -07004544 int curNum = 0;
4545 final ArrayList<ActivityRecord> activities = task.mActivities;
4546 for (int actNdx = 0; actNdx < activities.size(); actNdx++) {
4547 final ActivityRecord activity = activities.get(actNdx);
4548 if (activity.app == app && activity.isDestroyable()) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004549 if (DEBUG_RELEASE) Slog.v(TAG_RELEASE, "Destroying " + activity
Bryce Lee7ace3952018-02-16 14:34:32 -08004550 + " in state " + activity.getState() + " resumed=" + mResumedActivity
Dianne Hackborn89ad4562014-08-24 16:45:38 -07004551 + " pausing=" + mPausingActivity + " for reason " + reason);
4552 destroyActivityLocked(activity, true, reason);
4553 if (activities.get(actNdx) != activity) {
4554 // Was removed from list, back up so we don't miss the next one.
4555 actNdx--;
4556 }
4557 curNum++;
4558 }
4559 }
4560 if (curNum > 0) {
4561 numReleased += curNum;
4562 maxTasks--;
4563 if (mTaskHistory.get(taskNdx) != task) {
4564 // The entire task got removed, back up so we don't miss the next one.
4565 taskNdx--;
4566 }
4567 }
4568 }
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004569 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE,
4570 "Done releasing: did " + numReleased + " activities");
Dianne Hackborn89ad4562014-08-24 16:45:38 -07004571 return numReleased;
4572 }
4573
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004574 /**
4575 * Destroy the current CLIENT SIDE instance of an activity. This may be
4576 * called both when actually finishing an activity, or when performing
4577 * a configuration switch where we destroy the current client-side object
4578 * but then create a new client-side object for this same HistoryRecord.
4579 */
Craig Mautneree2e45a2014-06-27 12:10:03 -07004580 final boolean destroyActivityLocked(ActivityRecord r, boolean removeFromApp, String reason) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07004581 if (DEBUG_SWITCH || DEBUG_CLEANUP) Slog.v(TAG_SWITCH,
4582 "Removing activity from " + reason + ": token=" + r
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004583 + ", app=" + (r.hasProcess() ? r.app.mName : "(null)"));
Bryce Leeb0f993f2018-03-02 15:38:01 -08004584
4585 if (r.isState(DESTROYING, DESTROYED)) {
Bryce Leec9406602018-03-09 11:02:10 -08004586 if (DEBUG_STATES) Slog.v(TAG_STATES, "activity " + r + " already destroying."
Bryce Leeb0f993f2018-03-02 15:38:01 -08004587 + "skipping request with reason:" + reason);
4588 return false;
4589 }
4590
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004591 EventLog.writeEvent(EventLogTags.AM_DESTROY_ACTIVITY,
Wale Ogunwale8b19de92018-11-29 19:58:26 -08004592 r.mUserId, System.identityHashCode(r),
4593 r.getTaskRecord().taskId, r.shortComponentName, reason);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004594
4595 boolean removedFromHistory = false;
Dianne Hackborncc5a0552012-10-01 16:32:39 -07004596
Bryce Leec9406602018-03-09 11:02:10 -08004597 cleanUpActivityLocked(r, false, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004598
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004599 final boolean hadApp = r.hasProcess();
Dianne Hackborncc5a0552012-10-01 16:32:39 -07004600
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004601 if (hadApp) {
4602 if (removeFromApp) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004603 r.app.removeActivity(r);
Wale Ogunwale53783742018-09-16 10:21:51 -07004604 if (!r.app.hasActivities()) {
4605 mService.clearHeavyWeightProcessIfEquals(r.app);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004606 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004607 if (!r.app.hasActivities()) {
Dianne Hackborn465fa392014-09-14 14:21:18 -07004608 // Update any services we are bound to that might care about whether
4609 // their client may have activities.
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07004610 // No longer have activities, so update LRU list and oom adj.
Riddle Hsu17e38422019-04-12 16:55:11 +08004611 r.app.updateProcessInfo(true /* updateServiceConnectionActivities */,
4612 false /* activityChange */, true /* updateOomAdj */);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004613 }
4614 }
4615
4616 boolean skipDestroy = false;
Craig Mautnerdbcb31f2013-04-02 12:32:53 -07004617
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004618 try {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07004619 if (DEBUG_SWITCH) Slog.i(TAG_SWITCH, "Destroying: " + r);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004620 mService.getLifecycleManager().scheduleTransaction(r.app.getThread(), r.appToken,
Bryce Lee1d0d5142018-04-12 10:35:07 -07004621 DestroyActivityItem.obtain(r.finishing, r.configChangeFlags));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004622 } catch (Exception e) {
4623 // We can just ignore exceptions here... if the process
4624 // has crashed, our death notification will clean things
4625 // up.
4626 //Slog.w(TAG, "Exception thrown during finish", e);
4627 if (r.finishing) {
Chong Zhangbffd8892016-08-08 11:16:06 -07004628 removeActivityFromHistoryLocked(r, reason + " exceptionInScheduleDestroy");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004629 removedFromHistory = true;
4630 skipDestroy = true;
4631 }
4632 }
4633
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004634 r.nowVisible = false;
Craig Mautnerdbcb31f2013-04-02 12:32:53 -07004635
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004636 // If the activity is finishing, we need to wait on removing it
4637 // from the list to give it a chance to do its cleanup. During
4638 // that time it may make calls back with its token so we need to
4639 // be able to find it on the list and so we don't want to remove
4640 // it from the list yet. Otherwise, we can just immediately put
4641 // it in the destroyed state since we are not removing it from the
4642 // list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004643 if (r.finishing && !skipDestroy) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004644 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to DESTROYING: " + r
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004645 + " (destroy requested)");
Bryce Lee7ace3952018-02-16 14:34:32 -08004646 r.setState(DESTROYING,
4647 "destroyActivityLocked. finishing and not skipping destroy");
Craig Mautnerf7bfefb2013-05-16 17:30:44 -07004648 Message msg = mHandler.obtainMessage(DESTROY_TIMEOUT_MSG, r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004649 mHandler.sendMessageDelayed(msg, DESTROY_TIMEOUT);
4650 } else {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004651 if (DEBUG_STATES) Slog.v(TAG_STATES,
4652 "Moving to DESTROYED: " + r + " (destroy skipped)");
Bryce Lee7ace3952018-02-16 14:34:32 -08004653 r.setState(DESTROYED,
4654 "destroyActivityLocked. not finishing or skipping destroy");
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004655 if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during destroy for activity " + r);
Dianne Hackborncc5a0552012-10-01 16:32:39 -07004656 r.app = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004657 }
4658 } else {
4659 // remove this record from the history.
4660 if (r.finishing) {
Chong Zhangbffd8892016-08-08 11:16:06 -07004661 removeActivityFromHistoryLocked(r, reason + " hadNoApp");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004662 removedFromHistory = true;
4663 } else {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004664 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to DESTROYED: " + r + " (no app)");
Bryce Lee7ace3952018-02-16 14:34:32 -08004665 r.setState(DESTROYED, "destroyActivityLocked. not finishing and had no app");
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004666 if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during destroy for activity " + r);
Dianne Hackborncc5a0552012-10-01 16:32:39 -07004667 r.app = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004668 }
4669 }
4670
4671 r.configChangeFlags = 0;
Craig Mautnerdbcb31f2013-04-02 12:32:53 -07004672
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004673 if (!mLRUActivities.remove(r) && hadApp) {
4674 Slog.w(TAG, "Activity " + r + " being finished, but not in LRU list");
4675 }
Craig Mautnerdbcb31f2013-04-02 12:32:53 -07004676
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004677 return removedFromHistory;
4678 }
4679
Craig Mautner299f9602015-01-26 09:47:33 -08004680 final void activityDestroyedLocked(IBinder token, String reason) {
Craig Mautnerd2328952013-03-05 12:46:26 -08004681 final long origId = Binder.clearCallingIdentity();
4682 try {
Bryce Lee7ace3952018-02-16 14:34:32 -08004683 activityDestroyedLocked(ActivityRecord.forTokenLocked(token), reason);
Craig Mautnerd2328952013-03-05 12:46:26 -08004684 } finally {
4685 Binder.restoreCallingIdentity(origId);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004686 }
4687 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07004688
Bryce Leec9406602018-03-09 11:02:10 -08004689 /**
4690 * This method is to only be called from the client via binder when the activity is destroyed
4691 * AND finished.
4692 */
Bryce Lee7ace3952018-02-16 14:34:32 -08004693 final void activityDestroyedLocked(ActivityRecord record, String reason) {
4694 if (record != null) {
4695 mHandler.removeMessages(DESTROY_TIMEOUT_MSG, record);
4696 }
4697
4698 if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, "activityDestroyedLocked: r=" + record);
4699
4700 if (isInStackLocked(record) != null) {
4701 if (record.isState(DESTROYING, DESTROYED)) {
Bryce Leec9406602018-03-09 11:02:10 -08004702 cleanUpActivityLocked(record, true, false);
Bryce Lee7ace3952018-02-16 14:34:32 -08004703 removeActivityFromHistoryLocked(record, reason);
4704 }
4705 }
4706
Wale Ogunwaled32da472018-11-16 07:19:28 -08004707 mRootActivityContainer.resumeFocusedStacksTopActivities();
Bryce Lee7ace3952018-02-16 14:34:32 -08004708 }
4709
Craig Mautner05d6272ba2013-02-11 09:39:27 -08004710 private void removeHistoryRecordsForAppLocked(ArrayList<ActivityRecord> list,
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004711 WindowProcessController app, String listName) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004712 int i = list.size();
Wale Ogunwalee23149f2015-03-06 15:39:44 -08004713 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4714 "Removing app " + app + " from list " + listName + " with " + i + " entries");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004715 while (i > 0) {
4716 i--;
Craig Mautner05d6272ba2013-02-11 09:39:27 -08004717 ActivityRecord r = list.get(i);
Wale Ogunwalee23149f2015-03-06 15:39:44 -08004718 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, "Record #" + i + " " + r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004719 if (r.app == app) {
Wale Ogunwalee23149f2015-03-06 15:39:44 -08004720 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, "---> REMOVING this entry!");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004721 list.remove(i);
Dianne Hackborn42e620c2012-06-24 13:20:51 -07004722 removeTimeoutsForActivityLocked(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004723 }
4724 }
4725 }
4726
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004727 private boolean removeHistoryRecordsForAppLocked(WindowProcessController app) {
Dianne Hackborncc5a0552012-10-01 16:32:39 -07004728 removeHistoryRecordsForAppLocked(mLRUActivities, app, "mLRUActivities");
Craig Mautnerde4ef022013-04-07 19:01:33 -07004729 removeHistoryRecordsForAppLocked(mStackSupervisor.mStoppingActivities, app,
4730 "mStoppingActivities");
Craig Mautner0eea92c2013-05-16 13:35:39 -07004731 removeHistoryRecordsForAppLocked(mStackSupervisor.mGoingToSleepActivities, app,
4732 "mGoingToSleepActivities");
Craig Mautnerf3333272013-04-22 10:55:53 -07004733 removeHistoryRecordsForAppLocked(mStackSupervisor.mFinishingActivities, app,
4734 "mFinishingActivities");
Dianne Hackborncc5a0552012-10-01 16:32:39 -07004735
Riddle Hsuaaef7312019-01-24 19:00:58 +08004736 final boolean isProcessRemoved = app.isRemoved();
4737 if (isProcessRemoved) {
4738 // The package of the died process should be force-stopped, so make its activities as
4739 // finishing to prevent the process from being started again if the next top (or being
4740 // visible) activity also resides in the same process.
4741 app.makeFinishingForProcessRemoved();
4742 }
4743
Dianne Hackborncc5a0552012-10-01 16:32:39 -07004744 boolean hasVisibleActivities = false;
4745
4746 // Clean out the history list.
Craig Mautner0247fc82013-02-28 14:32:06 -08004747 int i = numActivities();
Wale Ogunwalee23149f2015-03-06 15:39:44 -08004748 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4749 "Removing app " + app + " from history with " + i + " entries");
Craig Mautner0247fc82013-02-28 14:32:06 -08004750 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
4751 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
Bryce Leefbd263b42018-03-07 10:33:55 -08004752 mTmpActivities.clear();
4753 mTmpActivities.addAll(activities);
4754
4755 while (!mTmpActivities.isEmpty()) {
4756 final int targetIndex = mTmpActivities.size() - 1;
4757 final ActivityRecord r = mTmpActivities.remove(targetIndex);
Wale Ogunwalee23149f2015-03-06 15:39:44 -08004758 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
Bryce Leefbd263b42018-03-07 10:33:55 -08004759 "Record #" + targetIndex + " " + r + ": app=" + r.app);
4760
Craig Mautner0247fc82013-02-28 14:32:06 -08004761 if (r.app == app) {
riddle_hsu558e8492015-04-02 16:43:13 +08004762 if (r.visible) {
4763 hasVisibleActivities = true;
4764 }
Craig Mautneracebdc82015-02-24 10:53:03 -08004765 final boolean remove;
Garfield Tan2746ab52018-07-25 12:33:01 -07004766 if ((r.mRelaunchReason == RELAUNCH_REASON_WINDOWING_MODE_RESIZE
4767 || r.mRelaunchReason == RELAUNCH_REASON_FREE_RESIZE)
4768 && r.launchCount < 3 && !r.finishing) {
4769 // If the process crashed during a resize, always try to relaunch it, unless
4770 // it has failed more than twice. Skip activities that's already finishing
4771 // cleanly by itself.
4772 remove = false;
Riddle Hsu7b766fd2019-01-28 21:14:59 +08004773 } else if ((!r.haveState && !r.stateNotNeeded
4774 && !r.isState(ActivityState.RESTARTING_PROCESS)) || r.finishing) {
Craig Mautner0247fc82013-02-28 14:32:06 -08004775 // Don't currently have state for the activity, or
4776 // it is finishing -- always remove it.
4777 remove = true;
Chong Zhang112eb8c2015-11-02 11:17:00 -08004778 } else if (!r.visible && r.launchCount > 2 &&
4779 r.lastLaunchTime > (SystemClock.uptimeMillis() - 60000)) {
Craig Mautner0247fc82013-02-28 14:32:06 -08004780 // We have launched this activity too many times since it was
4781 // able to run, so give up and remove it.
Chong Zhang112eb8c2015-11-02 11:17:00 -08004782 // (Note if the activity is visible, we don't remove the record.
4783 // We leave the dead window on the screen but the process will
4784 // not be restarted unless user explicitly tap on it.)
Craig Mautner0247fc82013-02-28 14:32:06 -08004785 remove = true;
4786 } else {
4787 // The process may be gone, but the activity lives on!
4788 remove = false;
Dianne Hackborncc5a0552012-10-01 16:32:39 -07004789 }
Craig Mautner0247fc82013-02-28 14:32:06 -08004790 if (remove) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004791 if (DEBUG_ADD_REMOVE || DEBUG_CLEANUP) Slog.i(TAG_ADD_REMOVE,
4792 "Removing activity " + r + " from stack at " + i
4793 + ": haveState=" + r.haveState
4794 + " stateNotNeeded=" + r.stateNotNeeded
4795 + " finishing=" + r.finishing
Bryce Lee7ace3952018-02-16 14:34:32 -08004796 + " state=" + r.getState() + " callers=" + Debug.getCallers(5));
Riddle Hsuaaef7312019-01-24 19:00:58 +08004797 if (!r.finishing || isProcessRemoved) {
Craig Mautner0247fc82013-02-28 14:32:06 -08004798 Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
4799 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
Wale Ogunwale8b19de92018-11-29 19:58:26 -08004800 r.mUserId, System.identityHashCode(r),
4801 r.getTaskRecord().taskId, r.shortComponentName,
Craig Mautner0247fc82013-02-28 14:32:06 -08004802 "proc died without state saved");
4803 }
Craig Mautner0247fc82013-02-28 14:32:06 -08004804 } else {
4805 // We have the current state for this activity, so
4806 // it can be restarted later when needed.
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004807 if (DEBUG_ALL) Slog.v(TAG, "Keeping entry, setting app to null");
4808 if (DEBUG_APP) Slog.v(TAG_APP,
4809 "Clearing app during removeHistory for activity " + r);
Craig Mautner0247fc82013-02-28 14:32:06 -08004810 r.app = null;
Chong Zhang112eb8c2015-11-02 11:17:00 -08004811 // Set nowVisible to previous visible state. If the app was visible while
4812 // it died, we leave the dead window on screen so it's basically visible.
4813 // This is needed when user later tap on the dead window, we need to stop
4814 // other apps when user transfers focus to the restarted activity.
4815 r.nowVisible = r.visible;
Craig Mautner0247fc82013-02-28 14:32:06 -08004816 if (!r.haveState) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07004817 if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE,
Craig Mautner0247fc82013-02-28 14:32:06 -08004818 "App died, clearing saved state of " + r);
4819 r.icicle = null;
4820 }
Dianne Hackborncc5a0552012-10-01 16:32:39 -07004821 }
Bryce Leec9406602018-03-09 11:02:10 -08004822 cleanUpActivityLocked(r, true, true);
Craig Mautneracebdc82015-02-24 10:53:03 -08004823 if (remove) {
Chong Zhangbffd8892016-08-08 11:16:06 -07004824 removeActivityFromHistoryLocked(r, "appDied");
Craig Mautneracebdc82015-02-24 10:53:03 -08004825 }
Craig Mautner0247fc82013-02-28 14:32:06 -08004826 }
Dianne Hackborncc5a0552012-10-01 16:32:39 -07004827 }
4828 }
4829
4830 return hasVisibleActivities;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004831 }
Craig Mautner0247fc82013-02-28 14:32:06 -08004832
chaviw0d562bf2018-03-15 14:24:14 -07004833 private void updateTransitLocked(int transit, ActivityOptions options) {
Dianne Hackborn7f58b952012-04-18 12:59:29 -07004834 if (options != null) {
chaviw0d562bf2018-03-15 14:24:14 -07004835 ActivityRecord r = topRunningActivityLocked();
4836 if (r != null && !r.isState(RESUMED)) {
4837 r.updateOptionsLocked(options);
Dianne Hackborn7f58b952012-04-18 12:59:29 -07004838 } else {
4839 ActivityOptions.abort(options);
4840 }
4841 }
Wale Ogunwale3a256e62018-12-06 14:41:18 -08004842 getDisplay().mDisplayContent.prepareAppTransition(transit, false);
Dianne Hackborn7f58b952012-04-18 12:59:29 -07004843 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004844
Andrii Kulian21713ac2016-10-12 22:05:05 -07004845 private void updateTaskMovement(TaskRecord task, boolean toFront) {
Craig Mautner21d24a22014-04-23 11:45:37 -07004846 if (task.isPersistable) {
4847 task.mLastTimeMoved = System.currentTimeMillis();
4848 // Sign is used to keep tasks sorted when persisted. Tasks sent to the bottom most
4849 // recently will be most negative, tasks sent to the bottom before that will be less
4850 // negative. Similarly for recent tasks moved to the top which will be most positive.
4851 if (!toFront) {
4852 task.mLastTimeMoved *= -1;
4853 }
4854 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08004855 mRootActivityContainer.invalidateTaskLayers();
Craig Mautner21d24a22014-04-23 11:45:37 -07004856 }
4857
chaviw0d562bf2018-03-15 14:24:14 -07004858 final void moveTaskToFrontLocked(TaskRecord tr, boolean noAnimation, ActivityOptions options,
4859 AppTimeTracker timeTracker, String reason) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07004860 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "moveTaskToFront: " + tr);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004861
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07004862 final ActivityStack topStack = getDisplay().getTopStack();
Wale Ogunwale30e441d2017-11-09 08:28:45 -08004863 final ActivityRecord topActivity = topStack != null ? topStack.getTopActivity() : null;
Craig Mautner11bf9a52013-02-19 14:08:51 -08004864 final int numTasks = mTaskHistory.size();
4865 final int index = mTaskHistory.indexOf(tr);
Craig Mautner86d67a42013-05-14 10:34:38 -07004866 if (numTasks == 0 || index < 0) {
Craig Mautner11bf9a52013-02-19 14:08:51 -08004867 // nothing to do!
Craig Mautner8f5f7e92015-01-26 18:03:13 -08004868 if (noAnimation) {
Craig Mautner11bf9a52013-02-19 14:08:51 -08004869 ActivityOptions.abort(options);
4870 } else {
chaviw0d562bf2018-03-15 14:24:14 -07004871 updateTransitLocked(TRANSIT_TASK_TO_FRONT, options);
Craig Mautner11bf9a52013-02-19 14:08:51 -08004872 }
4873 return;
4874 }
4875
Dianne Hackbornb5a380d2015-05-20 18:18:46 -07004876 if (timeTracker != null) {
4877 // The caller wants a time tracker associated with this task.
4878 for (int i = tr.mActivities.size() - 1; i >= 0; i--) {
4879 tr.mActivities.get(i).appTimeTracker = timeTracker;
4880 }
4881 }
4882
Chavi Weingarten3a748552018-05-14 17:32:42 +00004883 try {
4884 // Defer updating the IME target since the new IME target will try to get computed
4885 // before updating all closing and opening apps, which can cause the ime target to
4886 // get calculated incorrectly.
4887 getDisplay().deferUpdateImeTarget();
Wale Ogunwaled80c2632015-03-13 10:26:26 -07004888
Chavi Weingarten3a748552018-05-14 17:32:42 +00004889 // Shift all activities with this task up to the top
4890 // of the stack, keeping them in the same internal order.
4891 insertTaskAtTop(tr, null);
4892
4893 // Don't refocus if invisible to current user
4894 final ActivityRecord top = tr.getTopActivity();
4895 if (top == null || !top.okToShowLocked()) {
4896 if (top != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08004897 mStackSupervisor.mRecentTasks.add(top.getTaskRecord());
Chavi Weingarten3a748552018-05-14 17:32:42 +00004898 }
4899 ActivityOptions.abort(options);
4900 return;
Winson Chung1dbc8112017-09-28 18:05:31 -07004901 }
Chavi Weingarten9e875b62018-05-14 16:10:59 +00004902
Chavi Weingarten3a748552018-05-14 17:32:42 +00004903 // Set focus to the top running activity of this stack.
4904 final ActivityRecord r = topRunningActivityLocked();
Louis Chang19443452018-10-09 12:10:21 +08004905 if (r != null) {
4906 r.moveFocusableActivityToTop(reason);
4907 }
Chavi Weingarten9e875b62018-05-14 16:10:59 +00004908
Chavi Weingarten3a748552018-05-14 17:32:42 +00004909 if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to front transition: task=" + tr);
4910 if (noAnimation) {
Wale Ogunwale3a256e62018-12-06 14:41:18 -08004911 getDisplay().mDisplayContent.prepareAppTransition(TRANSIT_NONE, false);
Chavi Weingarten3a748552018-05-14 17:32:42 +00004912 if (r != null) {
4913 mStackSupervisor.mNoAnimActivities.add(r);
4914 }
4915 ActivityOptions.abort(options);
4916 } else {
4917 updateTransitLocked(TRANSIT_TASK_TO_FRONT, options);
Chavi Weingarten9e875b62018-05-14 16:10:59 +00004918 }
Chavi Weingarten3a748552018-05-14 17:32:42 +00004919 // If a new task is moved to the front, then mark the existing top activity as
4920 // supporting
Chavi Weingarten9e875b62018-05-14 16:10:59 +00004921
Chavi Weingarten3a748552018-05-14 17:32:42 +00004922 // picture-in-picture while paused only if the task would not be considered an oerlay
4923 // on top
4924 // of the current activity (eg. not fullscreen, or the assistant)
4925 if (canEnterPipOnTaskSwitch(topActivity, tr, null /* toFrontActivity */,
4926 options)) {
4927 topActivity.supportsEnterPipOnTaskSwitch = true;
4928 }
Chavi Weingarten9e875b62018-05-14 16:10:59 +00004929
Wale Ogunwaled32da472018-11-16 07:19:28 -08004930 mRootActivityContainer.resumeFocusedStacksTopActivities();
Chavi Weingarten3a748552018-05-14 17:32:42 +00004931 EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, tr.taskId);
Mark Renoufc808f062019-02-07 15:20:37 -05004932 mService.getTaskChangeNotificationController().notifyTaskMovedToFront(tr.getTaskInfo());
Chavi Weingarten3a748552018-05-14 17:32:42 +00004933 } finally {
4934 getDisplay().continueUpdateImeTarget();
4935 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004936 }
4937
4938 /**
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07004939 * Worker method for rearranging history stack. Implements the function of moving all
4940 * activities for a specific task (gathering them if disjoint) into a single group at the
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004941 * bottom of the stack.
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07004942 *
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004943 * If a watcher is installed, the action is preflighted and the watcher has an opportunity
4944 * to premeptively cancel the move.
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07004945 *
Craig Mautnerae7ecab2013-09-18 11:48:14 -07004946 * @param taskId The taskId to collect and move to the bottom.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004947 * @return Returns true if the move completed, false if not.
4948 */
Craig Mautner299f9602015-01-26 09:47:33 -08004949 final boolean moveTaskToBackLocked(int taskId) {
Craig Mautneraea74a52014-03-08 14:23:10 -08004950 final TaskRecord tr = taskForIdLocked(taskId);
4951 if (tr == null) {
4952 Slog.i(TAG, "moveTaskToBack: bad taskId=" + taskId);
4953 return false;
4954 }
Craig Mautneraea74a52014-03-08 14:23:10 -08004955 Slog.i(TAG, "moveTaskToBack: " + tr);
Winson Chung261c0f32017-03-07 16:54:31 -08004956
Charles Heff9b4dff2017-09-22 10:18:37 +01004957 // In LockTask mode, moving a locked task to the back of the stack may expose unlocked
4958 // ones. Therefore we need to check if this operation is allowed.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07004959 if (!mService.getLockTaskController().canMoveTaskToBack(tr)) {
Winson Chung261c0f32017-03-07 16:54:31 -08004960 return false;
4961 }
Craig Mautnerb44de0d2013-02-21 20:00:58 -08004962
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004963 // If we have a watcher, preflight the move before committing to it. First check
4964 // for *other* available tasks, but if none are available, then try again allowing the
4965 // current task to be selected.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004966 if (isTopStackOnDisplay() && mService.mController != null) {
Craig Mautnerae7ecab2013-09-18 11:48:14 -07004967 ActivityRecord next = topRunningActivityLocked(null, taskId);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004968 if (next == null) {
4969 next = topRunningActivityLocked(null, 0);
4970 }
4971 if (next != null) {
4972 // ask watcher if this is allowed
4973 boolean moveOK = true;
4974 try {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004975 moveOK = mService.mController.activityResuming(next.packageName);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004976 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004977 mService.mController = null;
Kenny Rootadd58212013-05-07 09:47:34 -07004978 Watchdog.getInstance().setActivityController(null);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004979 }
4980 if (!moveOK) {
4981 return false;
4982 }
4983 }
4984 }
4985
Wale Ogunwaleee006da2015-03-30 14:49:25 -07004986 if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to back transition: task=" + taskId);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004987
Wale Ogunwale66e16852017-10-19 13:35:52 -07004988 mTaskHistory.remove(tr);
4989 mTaskHistory.add(0, tr);
4990 updateTaskMovement(tr, false);
Wale Ogunwale42709242015-08-11 13:54:42 -07004991
Wale Ogunwale3a256e62018-12-06 14:41:18 -08004992 getDisplay().mDisplayContent.prepareAppTransition(TRANSIT_TASK_TO_BACK, false);
Evan Rosky9c448172017-11-02 14:19:27 -07004993 moveToBack("moveTaskToBackLocked", tr);
Winson Chung261c0f32017-03-07 16:54:31 -08004994
Wale Ogunwale44f036f2017-09-29 05:09:09 -07004995 if (inPinnedWindowingMode()) {
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07004996 mStackSupervisor.removeStack(this);
Winson Chung261c0f32017-03-07 16:54:31 -08004997 return true;
4998 }
4999
Evan Rosky80b2cb72019-05-31 20:18:02 -07005000 ActivityRecord topActivity = getDisplay().topRunningActivity();
5001 ActivityStack topStack = topActivity.getActivityStack();
5002 if (topStack != null && topStack != this && topActivity.isState(RESUMED)) {
5003 // The new top activity is already resumed, so there's a good chance that nothing will
5004 // get resumed below. So, update visibility now in case the transition is closed
5005 // prematurely.
5006 mRootActivityContainer.ensureVisibilityAndConfig(null /* starting */,
5007 getDisplay().mDisplayId, false /* markFrozenIfConfigChanged */,
5008 false /* deferResume */);
5009 }
5010
Wale Ogunwaled32da472018-11-16 07:19:28 -08005011 mRootActivityContainer.resumeFocusedStacksTopActivities();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005012 return true;
5013 }
Dianne Hackborn15491c62012-09-19 10:59:14 -07005014
Andrii Kulian21713ac2016-10-12 22:05:05 -07005015 static void logStartActivity(int tag, ActivityRecord r, TaskRecord task) {
Santos Cordon73ff7d82013-03-06 17:24:11 -08005016 final Uri data = r.intent.getData();
5017 final String strData = data != null ? data.toSafeString() : null;
5018
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005019 EventLog.writeEvent(tag,
Wale Ogunwale8b19de92018-11-29 19:58:26 -08005020 r.mUserId, System.identityHashCode(r), task.taskId,
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005021 r.shortComponentName, r.intent.getAction(),
Santos Cordon73ff7d82013-03-06 17:24:11 -08005022 r.intent.getType(), strData, r.intent.getFlags());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005023 }
5024
5025 /**
Wale Ogunwaledb0fa122016-05-16 15:12:03 -07005026 * Ensures all visible activities at or below the input activity have the right configuration.
5027 */
5028 void ensureVisibleActivitiesConfigurationLocked(ActivityRecord start, boolean preserveWindow) {
5029 if (start == null || !start.visible) {
5030 return;
5031 }
5032
Wale Ogunwale8b19de92018-11-29 19:58:26 -08005033 final TaskRecord startTask = start.getTaskRecord();
Wale Ogunwaledb0fa122016-05-16 15:12:03 -07005034 boolean behindFullscreen = false;
5035 boolean updatedConfig = false;
5036
5037 for (int taskIndex = mTaskHistory.indexOf(startTask); taskIndex >= 0; --taskIndex) {
5038 final TaskRecord task = mTaskHistory.get(taskIndex);
5039 final ArrayList<ActivityRecord> activities = task.mActivities;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08005040 int activityIndex = (start.getTaskRecord() == task)
5041 ? activities.indexOf(start) : activities.size() - 1;
Wale Ogunwaledb0fa122016-05-16 15:12:03 -07005042 for (; activityIndex >= 0; --activityIndex) {
5043 final ActivityRecord r = activities.get(activityIndex);
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -08005044 updatedConfig |= r.ensureActivityConfiguration(0 /* globalChanges */,
Andrii Kulian21713ac2016-10-12 22:05:05 -07005045 preserveWindow);
Wale Ogunwaledb0fa122016-05-16 15:12:03 -07005046 if (r.fullscreen) {
5047 behindFullscreen = true;
5048 break;
5049 }
5050 }
5051 if (behindFullscreen) {
5052 break;
5053 }
5054 }
5055 if (updatedConfig) {
Wale Ogunwale089586f2016-06-20 14:16:22 -07005056 // Ensure the resumed state of the focus activity if we updated the configuration of
Wale Ogunwaledb0fa122016-05-16 15:12:03 -07005057 // any activity.
Wale Ogunwaled32da472018-11-16 07:19:28 -08005058 mRootActivityContainer.resumeFocusedStacksTopActivities();
Wale Ogunwaledb0fa122016-05-16 15:12:03 -07005059 }
5060 }
5061
Wale Ogunwale1666e312016-12-16 11:27:18 -08005062 // TODO: Figure-out a way to consolidate with resize() method below.
Yunfan Chen279f5582018-12-12 15:24:50 -08005063 void requestResize(Rect bounds) {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07005064 mService.resizeStack(mStackId, bounds,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07005065 true /* allowResizeInDockedMode */, false /* preserveWindows */,
5066 false /* animate */, -1 /* animationDuration */);
Wale Ogunwale1666e312016-12-16 11:27:18 -08005067 }
Andrii Kulian1e32e022016-09-16 15:29:34 -07005068
Wale Ogunwale1666e312016-12-16 11:27:18 -08005069 // TODO: Can only be called from special methods in ActivityStackSupervisor.
5070 // Need to consolidate those calls points into this resize method so anyone can call directly.
5071 void resize(Rect bounds, Rect tempTaskBounds, Rect tempTaskInsetBounds) {
Evan Rosky1ac84462018-11-13 11:25:30 -08005072 if (!updateBoundsAllowed(bounds)) {
Wale Ogunwale1666e312016-12-16 11:27:18 -08005073 return;
5074 }
5075
5076 // Update override configurations of all tasks in the stack.
5077 final Rect taskBounds = tempTaskBounds != null ? tempTaskBounds : bounds;
Andrii Kulian1e32e022016-09-16 15:29:34 -07005078
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -08005079 for (int i = mTaskHistory.size() - 1; i >= 0; i--) {
5080 final TaskRecord task = mTaskHistory.get(i);
5081 if (task.isResizeable()) {
Garfield Tan020607d2018-12-17 17:01:58 -08005082 task.updateOverrideConfiguration(taskBounds, tempTaskInsetBounds);
Andrii Kulian1e32e022016-09-16 15:29:34 -07005083 }
Andrii Kulian1e32e022016-09-16 15:29:34 -07005084 }
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -08005085
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -08005086 setBounds(bounds);
Andrii Kulian1e32e022016-09-16 15:29:34 -07005087 }
5088
Winson Chung15036ca2018-05-31 15:51:47 -07005089 void onPipAnimationEndResize() {
Yunfan Chen279f5582018-12-12 15:24:50 -08005090 if (mTaskStack == null) return;
5091 mTaskStack.onPipAnimationEndResize();
Winson Chung15036ca2018-05-31 15:51:47 -07005092 }
5093
Andrii Kulian1e32e022016-09-16 15:29:34 -07005094
5095 /**
Evan Rosky1ac84462018-11-13 11:25:30 -08005096 * Until we can break this "set task bounds to same as stack bounds" behavior, this
5097 * basically resizes both stack and task bounds to the same bounds.
Andrii Kulian1e32e022016-09-16 15:29:34 -07005098 */
Evan Rosky1ac84462018-11-13 11:25:30 -08005099 void setTaskBounds(Rect bounds) {
5100 if (!updateBoundsAllowed(bounds)) {
Andrii Kulian1e32e022016-09-16 15:29:34 -07005101 return;
5102 }
5103
Evan Rosky1ac84462018-11-13 11:25:30 -08005104 for (int i = mTaskHistory.size() - 1; i >= 0; i--) {
5105 final TaskRecord task = mTaskHistory.get(i);
5106 if (task.isResizeable()) {
5107 task.setBounds(bounds);
5108 } else {
5109 task.setBounds(null);
Andrii Kulian1e32e022016-09-16 15:29:34 -07005110 }
Evan Rosky1ac84462018-11-13 11:25:30 -08005111 }
5112 }
5113
5114 /** Helper to setDisplayedBounds on all child tasks */
5115 void setTaskDisplayedBounds(Rect bounds) {
5116 if (!updateDisplayedBoundsAllowed(bounds)) {
5117 return;
Andrii Kulian1e32e022016-09-16 15:29:34 -07005118 }
5119
Evan Rosky1ac84462018-11-13 11:25:30 -08005120 for (int i = mTaskHistory.size() - 1; i >= 0; i--) {
5121 final TaskRecord task = mTaskHistory.get(i);
5122 if (bounds == null || bounds.isEmpty()) {
5123 task.setDisplayedBounds(null);
5124 } else if (task.isResizeable()) {
5125 task.setDisplayedBounds(bounds);
Andrii Kulian1e32e022016-09-16 15:29:34 -07005126 }
Andrii Kulian1e32e022016-09-16 15:29:34 -07005127 }
5128 }
5129
Craig Mautnercae015f2013-02-08 14:31:27 -08005130 boolean willActivityBeVisibleLocked(IBinder token) {
Craig Mautnerd44711d2013-02-23 11:24:36 -08005131 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
5132 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
5133 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
5134 final ActivityRecord r = activities.get(activityNdx);
5135 if (r.appToken == token) {
Craig Mautner34b73df2014-01-12 21:11:08 -08005136 return true;
Craig Mautnerd44711d2013-02-23 11:24:36 -08005137 }
5138 if (r.fullscreen && !r.finishing) {
5139 return false;
5140 }
Craig Mautnercae015f2013-02-08 14:31:27 -08005141 }
5142 }
Wale Ogunwale7d701172015-03-11 15:36:30 -07005143 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
Craig Mautner34b73df2014-01-12 21:11:08 -08005144 if (r == null) {
5145 return false;
5146 }
5147 if (r.finishing) Slog.e(TAG, "willActivityBeVisibleLocked: Returning false,"
5148 + " would have returned true for r=" + r);
5149 return !r.finishing;
Craig Mautnercae015f2013-02-08 14:31:27 -08005150 }
5151
5152 void closeSystemDialogsLocked() {
Craig Mautnerd44711d2013-02-23 11:24:36 -08005153 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
5154 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
5155 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
5156 final ActivityRecord r = activities.get(activityNdx);
5157 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00005158 finishActivityLocked(r, Activity.RESULT_CANCELED, null, "close-sys", true);
Craig Mautnerd44711d2013-02-23 11:24:36 -08005159 }
Craig Mautnercae015f2013-02-08 14:31:27 -08005160 }
5161 }
5162 }
5163
Wale Ogunwale540e1232015-05-01 15:35:39 -07005164 boolean finishDisabledPackageActivitiesLocked(String packageName, Set<String> filterByClasses,
5165 boolean doit, boolean evenPersistent, int userId) {
Craig Mautnercae015f2013-02-08 14:31:27 -08005166 boolean didSomething = false;
5167 TaskRecord lastTask = null;
Craig Mautner9d8a30d2014-07-07 17:26:20 +00005168 ComponentName homeActivity = null;
Craig Mautner56f52db2013-02-25 10:03:01 -08005169 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
5170 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
Bryce Leefbd263b42018-03-07 10:33:55 -08005171 mTmpActivities.clear();
5172 mTmpActivities.addAll(activities);
5173
5174 while (!mTmpActivities.isEmpty()) {
5175 ActivityRecord r = mTmpActivities.remove(0);
Wale Ogunwale540e1232015-05-01 15:35:39 -07005176 final boolean sameComponent =
5177 (r.packageName.equals(packageName) && (filterByClasses == null
Wale Ogunwale8b19de92018-11-29 19:58:26 -08005178 || filterByClasses.contains(r.mActivityComponent.getClassName())))
5179 || (packageName == null && r.mUserId == userId);
5180 if ((userId == UserHandle.USER_ALL || r.mUserId == userId)
5181 && (sameComponent || r.getTaskRecord() == lastTask)
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005182 && (r.app == null || evenPersistent || !r.app.isPersistent())) {
Craig Mautner56f52db2013-02-25 10:03:01 -08005183 if (!doit) {
5184 if (r.finishing) {
5185 // If this activity is just finishing, then it is not
5186 // interesting as far as something to stop.
5187 continue;
5188 }
5189 return true;
Craig Mautnercae015f2013-02-08 14:31:27 -08005190 }
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07005191 if (r.isActivityTypeHome()) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08005192 if (homeActivity != null && homeActivity.equals(r.mActivityComponent)) {
Craig Mautner9d8a30d2014-07-07 17:26:20 +00005193 Slog.i(TAG, "Skip force-stop again " + r);
5194 continue;
5195 } else {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08005196 homeActivity = r.mActivityComponent;
Craig Mautner9d8a30d2014-07-07 17:26:20 +00005197 }
5198 }
Craig Mautner56f52db2013-02-25 10:03:01 -08005199 didSomething = true;
5200 Slog.i(TAG, " Force finishing activity " + r);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08005201 lastTask = r.getTaskRecord();
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00005202 finishActivityLocked(r, Activity.RESULT_CANCELED, null, "force-stop",
5203 true);
Craig Mautnercae015f2013-02-08 14:31:27 -08005204 }
5205 }
5206 }
5207 return didSomething;
5208 }
5209
Winson Chung61c9e5a2017-10-11 10:39:32 -07005210 /**
5211 * @return The set of running tasks through {@param tasksOut} that are available to the caller.
5212 * If {@param ignoreActivityType} or {@param ignoreWindowingMode} are not undefined,
5213 * then skip running tasks that match those types.
5214 */
5215 void getRunningTasks(List<TaskRecord> tasksOut, @ActivityType int ignoreActivityType,
5216 @WindowingMode int ignoreWindowingMode, int callingUid, boolean allowed) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08005217 boolean focusedStack = mRootActivityContainer.getTopDisplayFocusedStack() == this;
riddle_hsuddc74152015-04-07 11:30:09 +08005218 boolean topTask = true;
Craig Mautnerc0fd8052013-09-19 11:20:17 -07005219 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
Craig Mautneraab647e2013-02-28 16:31:36 -08005220 final TaskRecord task = mTaskHistory.get(taskNdx);
riddle_hsuddc74152015-04-07 11:30:09 +08005221 if (task.getTopActivity() == null) {
Winson Chung61c9e5a2017-10-11 10:39:32 -07005222 // Skip if there are no activities in the task
riddle_hsuddc74152015-04-07 11:30:09 +08005223 continue;
5224 }
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07005225 if (!allowed && !task.isActivityTypeHome() && task.effectiveUid != callingUid) {
Winson Chung61c9e5a2017-10-11 10:39:32 -07005226 // Skip if the caller can't fetch this task
Dianne Hackborn09233282014-04-30 11:33:59 -07005227 continue;
5228 }
Winson Chung61c9e5a2017-10-11 10:39:32 -07005229 if (ignoreActivityType != ACTIVITY_TYPE_UNDEFINED
5230 && task.getActivityType() == ignoreActivityType) {
5231 // Skip ignored activity type
5232 continue;
Craig Mautneraab647e2013-02-28 16:31:36 -08005233 }
Winson Chung61c9e5a2017-10-11 10:39:32 -07005234 if (ignoreWindowingMode != WINDOWING_MODE_UNDEFINED
5235 && task.getWindowingMode() == ignoreWindowingMode) {
5236 // Skip ignored windowing mode
5237 continue;
5238 }
riddle_hsuddc74152015-04-07 11:30:09 +08005239 if (focusedStack && topTask) {
Winson Chung61c9e5a2017-10-11 10:39:32 -07005240 // For the focused stack top task, update the last stack active time so that it can
5241 // be used to determine the order of the tasks (it may not be set for newly created
5242 // tasks)
5243 task.lastActiveTime = SystemClock.elapsedRealtime();
riddle_hsuddc74152015-04-07 11:30:09 +08005244 topTask = false;
5245 }
Winson Chung61c9e5a2017-10-11 10:39:32 -07005246 tasksOut.add(task);
Craig Mautnercae015f2013-02-08 14:31:27 -08005247 }
Craig Mautnercae015f2013-02-08 14:31:27 -08005248 }
5249
Andrii Kulian21713ac2016-10-12 22:05:05 -07005250 void unhandledBackLocked() {
Craig Mautneraab647e2013-02-28 16:31:36 -08005251 final int top = mTaskHistory.size() - 1;
Wale Ogunwaleee006da2015-03-30 14:49:25 -07005252 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH, "Performing unhandledBack(): top activity at " + top);
Craig Mautneraab647e2013-02-28 16:31:36 -08005253 if (top >= 0) {
5254 final ArrayList<ActivityRecord> activities = mTaskHistory.get(top).mActivities;
5255 int activityTop = activities.size() - 1;
Dianne Hackborn354736e2016-08-22 17:00:05 -07005256 if (activityTop >= 0) {
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00005257 finishActivityLocked(activities.get(activityTop), Activity.RESULT_CANCELED, null,
5258 "unhandled-back", true);
Craig Mautneraab647e2013-02-28 16:31:36 -08005259 }
Craig Mautnercae015f2013-02-08 14:31:27 -08005260 }
5261 }
5262
Craig Mautner6b74cb52013-09-27 17:02:21 -07005263 /**
5264 * Reset local parameters because an app's activity died.
5265 * @param app The app of the activity that died.
Craig Mautner19091252013-10-05 00:03:53 -07005266 * @return result from removeHistoryRecordsForAppLocked.
Craig Mautner6b74cb52013-09-27 17:02:21 -07005267 */
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005268 boolean handleAppDiedLocked(WindowProcessController app) {
Craig Mautnere79d42682013-04-01 19:01:53 -07005269 if (mPausingActivity != null && mPausingActivity.app == app) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07005270 if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG_PAUSE,
Craig Mautnere79d42682013-04-01 19:01:53 -07005271 "App died while pausing: " + mPausingActivity);
5272 mPausingActivity = null;
5273 }
5274 if (mLastPausedActivity != null && mLastPausedActivity.app == app) {
5275 mLastPausedActivity = null;
Craig Mautner0f922742013-08-06 08:44:42 -07005276 mLastNoHistoryActivity = null;
Craig Mautnere79d42682013-04-01 19:01:53 -07005277 }
5278
Craig Mautner19091252013-10-05 00:03:53 -07005279 return removeHistoryRecordsForAppLocked(app);
Craig Mautnere79d42682013-04-01 19:01:53 -07005280 }
5281
Wale Ogunwaled32da472018-11-16 07:19:28 -08005282 void handleAppCrash(WindowProcessController app) {
Craig Mautnerd44711d2013-02-23 11:24:36 -08005283 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
5284 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
5285 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
5286 final ActivityRecord r = activities.get(activityNdx);
5287 if (r.app == app) {
5288 Slog.w(TAG, " Force finishing activity "
5289 + r.intent.getComponent().flattenToShortString());
Craig Mautner8e5b1332014-07-24 13:32:37 -07005290 // Force the destroy to skip right to removal.
5291 r.app = null;
Wale Ogunwale3a256e62018-12-06 14:41:18 -08005292 getDisplay().mDisplayContent.prepareAppTransition(
lumark588a3e82018-07-20 18:53:54 +08005293 TRANSIT_CRASHING_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */);
Bryce Leef52974c2018-02-14 15:12:01 -08005294 finishCurrentActivityLocked(r, FINISH_IMMEDIATELY, false,
5295 "handleAppCrashedLocked");
Craig Mautnerd44711d2013-02-23 11:24:36 -08005296 }
Craig Mautnercae015f2013-02-08 14:31:27 -08005297 }
5298 }
5299 }
5300
Garfield Tan347bd602018-12-21 15:11:12 -08005301 boolean dump(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient,
5302 String dumpPackage, boolean needSep) {
5303 pw.println(" Stack #" + mStackId
5304 + ": type=" + activityTypeToString(getActivityType())
5305 + " mode=" + windowingModeToString(getWindowingMode()));
5306 pw.println(" isSleeping=" + shouldSleepActivities());
5307 pw.println(" mBounds=" + getRequestedOverrideBounds());
5308
5309 boolean printed = dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
5310 needSep);
5311
5312 printed |= dumpHistoryList(fd, pw, mLRUActivities, " ", "Run", false,
5313 !dumpAll, false, dumpPackage, true,
5314 " Running activities (most recent first):", null);
5315
5316 needSep = printed;
5317 boolean pr = printThisActivity(pw, mPausingActivity, dumpPackage, needSep,
5318 " mPausingActivity: ");
5319 if (pr) {
5320 printed = true;
5321 needSep = false;
5322 }
5323 pr = printThisActivity(pw, getResumedActivity(), dumpPackage, needSep,
5324 " mResumedActivity: ");
5325 if (pr) {
5326 printed = true;
5327 needSep = false;
5328 }
5329 if (dumpAll) {
5330 pr = printThisActivity(pw, mLastPausedActivity, dumpPackage, needSep,
5331 " mLastPausedActivity: ");
5332 if (pr) {
5333 printed = true;
5334 needSep = true;
5335 }
5336 printed |= printThisActivity(pw, mLastNoHistoryActivity, dumpPackage,
5337 needSep, " mLastNoHistoryActivity: ");
5338 }
5339 return printed;
5340 }
5341
Dianne Hackborn390517b2013-05-30 15:03:32 -07005342 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
Wale Ogunwale34a5b572017-08-31 08:29:41 -07005343 boolean dumpClient, String dumpPackage, boolean needSep) {
5344
5345 if (mTaskHistory.isEmpty()) {
5346 return false;
5347 }
5348 final String prefix = " ";
Craig Mautneraab647e2013-02-28 16:31:36 -08005349 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
5350 final TaskRecord task = mTaskHistory.get(taskNdx);
Wale Ogunwale34a5b572017-08-31 08:29:41 -07005351 if (needSep) {
5352 pw.println("");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07005353 }
Wale Ogunwale34a5b572017-08-31 08:29:41 -07005354 pw.println(prefix + "Task id #" + task.taskId);
Evan Roskydfe3da72018-10-26 17:21:06 -07005355 pw.println(prefix + "mBounds=" + task.getRequestedOverrideBounds());
Wale Ogunwale34a5b572017-08-31 08:29:41 -07005356 pw.println(prefix + "mMinWidth=" + task.mMinWidth);
5357 pw.println(prefix + "mMinHeight=" + task.mMinHeight);
5358 pw.println(prefix + "mLastNonFullscreenBounds=" + task.mLastNonFullscreenBounds);
5359 pw.println(prefix + "* " + task);
5360 task.dump(pw, prefix + " ");
Garfield Tan347bd602018-12-21 15:11:12 -08005361 dumpHistoryList(fd, pw, mTaskHistory.get(taskNdx).mActivities,
Wale Ogunwale34a5b572017-08-31 08:29:41 -07005362 prefix, "Hist", true, !dumpAll, dumpClient, dumpPackage, false, null, task);
Craig Mautneraab647e2013-02-28 16:31:36 -08005363 }
Wale Ogunwale34a5b572017-08-31 08:29:41 -07005364 return true;
Craig Mautnercae015f2013-02-08 14:31:27 -08005365 }
5366
5367 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
Winson Chung6998bc42017-02-28 17:07:05 -08005368 ArrayList<ActivityRecord> activities = new ArrayList<>();
Craig Mautnercae015f2013-02-08 14:31:27 -08005369
5370 if ("all".equals(name)) {
Craig Mautneraab647e2013-02-28 16:31:36 -08005371 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
5372 activities.addAll(mTaskHistory.get(taskNdx).mActivities);
Craig Mautnercae015f2013-02-08 14:31:27 -08005373 }
5374 } else if ("top".equals(name)) {
Craig Mautneraab647e2013-02-28 16:31:36 -08005375 final int top = mTaskHistory.size() - 1;
5376 if (top >= 0) {
5377 final ArrayList<ActivityRecord> list = mTaskHistory.get(top).mActivities;
5378 int listTop = list.size() - 1;
5379 if (listTop >= 0) {
5380 activities.add(list.get(listTop));
5381 }
Craig Mautnercae015f2013-02-08 14:31:27 -08005382 }
5383 } else {
5384 ItemMatcher matcher = new ItemMatcher();
5385 matcher.build(name);
5386
Craig Mautneraab647e2013-02-28 16:31:36 -08005387 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
5388 for (ActivityRecord r1 : mTaskHistory.get(taskNdx).mActivities) {
5389 if (matcher.match(r1, r1.intent.getComponent())) {
5390 activities.add(r1);
5391 }
Craig Mautnercae015f2013-02-08 14:31:27 -08005392 }
5393 }
5394 }
5395
5396 return activities;
5397 }
5398
5399 ActivityRecord restartPackage(String packageName) {
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -07005400 ActivityRecord starting = topRunningActivityLocked();
Craig Mautnercae015f2013-02-08 14:31:27 -08005401
5402 // All activities that came from the package must be
5403 // restarted as if there was a config change.
Craig Mautneraab647e2013-02-28 16:31:36 -08005404 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
5405 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
5406 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
5407 final ActivityRecord a = activities.get(activityNdx);
5408 if (a.info.packageName.equals(packageName)) {
5409 a.forceNewConfig = true;
5410 if (starting != null && a == starting && a.visible) {
5411 a.startFreezingScreenLocked(starting.app,
Filip Gruszczynski3c2db1d12016-01-06 17:39:14 -08005412 CONFIG_SCREEN_LAYOUT);
Craig Mautneraab647e2013-02-28 16:31:36 -08005413 }
Craig Mautnercae015f2013-02-08 14:31:27 -08005414 }
5415 }
5416 }
5417
5418 return starting;
5419 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -08005420
Wale Ogunwale000957c2015-04-03 08:19:12 -07005421 /**
5422 * Removes the input task from this stack.
Garfield Tan891146c2018-10-09 12:14:00 -07005423 *
Wale Ogunwale000957c2015-04-03 08:19:12 -07005424 * @param task to remove.
5425 * @param reason for removal.
Wale Ogunwale06579d62016-04-30 15:29:06 -07005426 * @param mode task removal mode. Either {@link #REMOVE_TASK_MODE_DESTROYING},
5427 * {@link #REMOVE_TASK_MODE_MOVING}, {@link #REMOVE_TASK_MODE_MOVING_TO_TOP}.
Wale Ogunwale000957c2015-04-03 08:19:12 -07005428 */
Wale Ogunwale06579d62016-04-30 15:29:06 -07005429 void removeTask(TaskRecord task, String reason, int mode) {
Bryce Lee2b8e0372018-04-05 17:01:37 -07005430 final boolean removed = mTaskHistory.remove(task);
5431
5432 if (removed) {
5433 EventLog.writeEvent(EventLogTags.AM_REMOVE_TASK, task.taskId, getStackId());
5434 }
5435
Winson Chungabb433b2017-03-24 09:35:42 -07005436 removeActivitiesFromLRUListLocked(task);
Craig Mautner21d24a22014-04-23 11:45:37 -07005437 updateTaskMovement(task, true);
Craig Mautner41db4a72014-05-07 17:20:56 -07005438
Garfield Tan347bd602018-12-21 15:11:12 -08005439 if (mode == REMOVE_TASK_MODE_DESTROYING) {
5440 task.cleanUpResourcesForDestroy();
Dianne Hackborn91097de2014-04-04 18:02:06 -07005441 }
Craig Mautner04a0ea62014-01-13 12:51:26 -08005442
5443 if (mTaskHistory.isEmpty()) {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07005444 if (DEBUG_STACK) Slog.i(TAG_STACK, "removeTask: removing stack=" + this);
Wale Ogunwale06579d62016-04-30 15:29:06 -07005445 // We only need to adjust focused stack if this stack is in focus and we are not in the
5446 // process of moving the task to the top of the stack that will be focused.
Louis Changbd48dca2018-08-29 17:44:34 +08005447 if (mode != REMOVE_TASK_MODE_MOVING_TO_TOP
Wale Ogunwaled32da472018-11-16 07:19:28 -08005448 && mRootActivityContainer.isTopDisplayFocusedStack(this)) {
Wale Ogunwaled697cea2015-02-20 17:19:49 -08005449 String myReason = reason + " leftTaskHistoryEmpty";
Andrii Kulianab132ee2018-07-24 22:10:21 +08005450 if (!inMultiWindowMode() || adjustFocusToNextFocusableStack(myReason) == null) {
Louis Changbd48dca2018-08-29 17:44:34 +08005451 getDisplay().moveHomeStackToFront(myReason);
Wale Ogunwaled697cea2015-02-20 17:19:49 -08005452 }
Craig Mautner04a0ea62014-01-13 12:51:26 -08005453 }
Wale Ogunwale9dcf9462017-09-19 15:13:01 -07005454 if (isAttached()) {
5455 getDisplay().positionChildAtBottom(this);
Craig Mautner593a4e62014-01-15 17:55:51 -08005456 }
Jeff Changa2ee83d2018-12-26 20:24:47 +08005457 if (!isActivityTypeHome() || !isAttached()) {
Andrii Kulian94e82d9b02017-07-13 15:33:06 -07005458 remove();
Wale Ogunwale49853bf2015-02-23 09:24:42 -08005459 }
Craig Mautner04a0ea62014-01-13 12:51:26 -08005460 }
Wale Ogunwale04f4d6b2015-03-11 09:23:25 -07005461
Andrii Kulian02b7a832016-10-06 23:11:56 -07005462 task.setStack(null);
Winson Chungc81c0ce2017-03-17 12:27:30 -07005463
5464 // Notify if a task from the pinned stack is being removed (or moved depending on the mode)
Wale Ogunwale44f036f2017-09-29 05:09:09 -07005465 if (inPinnedWindowingMode()) {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07005466 mService.getTaskChangeNotificationController().notifyActivityUnpinned();
Winson Chungc81c0ce2017-03-17 12:27:30 -07005467 }
Craig Mautner0247fc82013-02-28 14:32:06 -08005468 }
5469
Dianne Hackborn91097de2014-04-04 18:02:06 -07005470 TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent,
5471 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07005472 boolean toTop) {
Bryce Leeb802ea12017-11-15 21:25:03 -08005473 return createTaskRecord(taskId, info, intent, voiceSession, voiceInteractor, toTop,
5474 null /*activity*/, null /*source*/, null /*options*/);
5475 }
5476
5477 TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent,
5478 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
5479 boolean toTop, ActivityRecord activity, ActivityRecord source,
5480 ActivityOptions options) {
Garfield Tan9b1efea2017-12-05 16:43:46 -08005481 final TaskRecord task = TaskRecord.create(
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07005482 mService, taskId, info, intent, voiceSession, voiceInteractor);
Chong Zhang0fa656b2015-08-31 15:17:21 -07005483 // add the task to stack first, mTaskPositioner might need the stack association
Wale Ogunwale5f986092015-12-04 15:35:38 -08005484 addTask(task, toTop, "createTaskRecord");
Lucas Dupin47a65c72018-02-15 14:16:18 -08005485 final int displayId = mDisplayId != INVALID_DISPLAY ? mDisplayId : DEFAULT_DISPLAY;
Bryce Lee2a3cc462017-10-27 10:57:35 -07005486 final boolean isLockscreenShown = mService.mStackSupervisor.getKeyguardController()
Lucas Dupin47a65c72018-02-15 14:16:18 -08005487 .isKeyguardOrAodShowing(displayId);
Bryce Leeec55eb02017-12-05 20:51:27 -08005488 if (!mStackSupervisor.getLaunchParamsController()
Bryce Leeb802ea12017-11-15 21:25:03 -08005489 .layoutTask(task, info.windowLayout, activity, source, options)
Bryce Leef3c6a472017-11-14 14:53:06 -08005490 && !matchParentBounds() && task.isResizeable() && !isLockscreenShown) {
Evan Roskydfe3da72018-10-26 17:21:06 -07005491 task.updateOverrideConfiguration(getRequestedOverrideBounds());
Filip Gruszczynskie5390e72015-08-18 16:39:00 -07005492 }
Yunfan Chen0e7aff92018-12-05 16:35:32 -08005493 task.createTask(toTop, (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0);
Craig Mautner5d9c7be2013-02-15 14:02:56 -08005494 return task;
5495 }
Craig Mautnerc00204b2013-03-05 15:02:14 -08005496
5497 ArrayList<TaskRecord> getAllTasks() {
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -08005498 return new ArrayList<>(mTaskHistory);
Craig Mautnerc00204b2013-03-05 15:02:14 -08005499 }
5500
Wale Ogunwale5f986092015-12-04 15:35:38 -08005501 void addTask(final TaskRecord task, final boolean toTop, String reason) {
Winson Chung5af42fc2017-03-24 17:11:33 -07005502 addTask(task, toTop ? MAX_VALUE : 0, true /* schedulePictureInPictureModeChange */, reason);
Wale Ogunwalec5cc3012017-01-13 13:26:16 -08005503 if (toTop) {
5504 // TODO: figure-out a way to remove this call.
Riddle Hsu86cb7de2018-08-13 23:29:58 +08005505 positionChildWindowContainerAtTop(task);
Wale Ogunwalec5cc3012017-01-13 13:26:16 -08005506 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -08005507 }
5508
Wale Ogunwalec5cc3012017-01-13 13:26:16 -08005509 // TODO: This shouldn't allow automatic reparenting. Remove the call to preAddTask and deal
5510 // with the fall-out...
Winson Chung5af42fc2017-03-24 17:11:33 -07005511 void addTask(final TaskRecord task, int position, boolean schedulePictureInPictureModeChange,
5512 String reason) {
Wale Ogunwalec5cc3012017-01-13 13:26:16 -08005513 // TODO: Is this remove really needed? Need to look into the call path for the other addTask
5514 mTaskHistory.remove(task);
Wale Ogunwale9e737db2018-12-17 15:42:37 -08005515 if (isSingleTaskInstance() && !mTaskHistory.isEmpty()) {
5516 throw new IllegalStateException("Can only have one child on stack=" + this);
5517 }
5518
Wale Ogunwalec5cc3012017-01-13 13:26:16 -08005519 position = getAdjustedPositionForTask(task, position, null /* starting */);
5520 final boolean toTop = position >= mTaskHistory.size();
Wale Ogunwale06579d62016-04-30 15:29:06 -07005521 final ActivityStack prevStack = preAddTask(task, reason, toTop);
Wale Ogunwale5f986092015-12-04 15:35:38 -08005522
Andrii Kulianfb1bf692017-01-17 11:17:34 -08005523 mTaskHistory.add(position, task);
Andrii Kulian02b7a832016-10-06 23:11:56 -07005524 task.setStack(this);
Wale Ogunwalec5cc3012017-01-13 13:26:16 -08005525
Wale Ogunwalec5cc3012017-01-13 13:26:16 -08005526 updateTaskMovement(task, toTop);
5527
Winson Chung5af42fc2017-03-24 17:11:33 -07005528 postAddTask(task, prevStack, schedulePictureInPictureModeChange);
Craig Mautnerc00204b2013-03-05 15:02:14 -08005529 }
5530
Wale Ogunwalec5cc3012017-01-13 13:26:16 -08005531 void positionChildAt(TaskRecord task, int index) {
5532
5533 if (task.getStack() != this) {
5534 throw new IllegalArgumentException("AS.positionChildAt: task=" + task
5535 + " is not a child of stack=" + this + " current parent=" + task.getStack());
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -08005536 }
5537
5538 task.updateOverrideConfigurationForStack(this);
5539
Jorim Jaggi023da532016-04-20 22:42:32 -07005540 final ActivityRecord topRunningActivity = task.topRunningActivityLocked();
Andrii Kulian02b7a832016-10-06 23:11:56 -07005541 final boolean wasResumed = topRunningActivity == task.getStack().mResumedActivity;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -08005542 insertTaskAtPosition(task, index);
Andrii Kulianfb1bf692017-01-17 11:17:34 -08005543 task.setStack(this);
Winson Chung5af42fc2017-03-24 17:11:33 -07005544 postAddTask(task, null /* prevStack */, true /* schedulePictureInPictureModeChange */);
Wale Ogunwalec5cc3012017-01-13 13:26:16 -08005545
Jorim Jaggi023da532016-04-20 22:42:32 -07005546 if (wasResumed) {
5547 if (mResumedActivity != null) {
5548 Log.wtf(TAG, "mResumedActivity was already set when moving mResumedActivity from"
5549 + " other stack to this stack mResumedActivity=" + mResumedActivity
5550 + " other mResumedActivity=" + topRunningActivity);
5551 }
Bryce Leec4ab62a2018-03-05 14:19:26 -08005552 topRunningActivity.setState(RESUMED, "positionChildAt");
Jorim Jaggi023da532016-04-20 22:42:32 -07005553 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -08005554
5555 // The task might have already been running and its visibility needs to be synchronized with
5556 // the visibility of the stack / windows.
5557 ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Wale Ogunwaled32da472018-11-16 07:19:28 -08005558 mRootActivityContainer.resumeFocusedStacksTopActivities();
Wale Ogunwale5f986092015-12-04 15:35:38 -08005559 }
5560
Wale Ogunwale06579d62016-04-30 15:29:06 -07005561 private ActivityStack preAddTask(TaskRecord task, String reason, boolean toTop) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07005562 final ActivityStack prevStack = task.getStack();
Wale Ogunwale5f986092015-12-04 15:35:38 -08005563 if (prevStack != null && prevStack != this) {
Wale Ogunwale06579d62016-04-30 15:29:06 -07005564 prevStack.removeTask(task, reason,
5565 toTop ? REMOVE_TASK_MODE_MOVING_TO_TOP : REMOVE_TASK_MODE_MOVING);
Wale Ogunwale5f986092015-12-04 15:35:38 -08005566 }
5567 return prevStack;
5568 }
5569
Winson Chung5af42fc2017-03-24 17:11:33 -07005570 /**
5571 * @param schedulePictureInPictureModeChange specifies whether or not to schedule the PiP mode
5572 * change. Callers may set this to false if they are explicitly scheduling PiP mode
5573 * changes themselves, like during the PiP animation
5574 */
5575 private void postAddTask(TaskRecord task, ActivityStack prevStack,
5576 boolean schedulePictureInPictureModeChange) {
5577 if (schedulePictureInPictureModeChange && prevStack != null) {
5578 mStackSupervisor.scheduleUpdatePictureInPictureModeIfNeeded(task, prevStack);
Wale Ogunwale5f986092015-12-04 15:35:38 -08005579 } else if (task.voiceSession != null) {
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -07005580 try {
5581 task.voiceSession.taskStarted(task.intent, task.taskId);
5582 } catch (RemoteException e) {
5583 }
5584 }
5585 }
5586
Kazuki Takisef85197b2018-06-18 18:18:36 +09005587 public void setAlwaysOnTop(boolean alwaysOnTop) {
5588 if (isAlwaysOnTop() == alwaysOnTop) {
5589 return;
5590 }
5591 super.setAlwaysOnTop(alwaysOnTop);
5592 final ActivityDisplay display = getDisplay();
5593 // positionChildAtTop() must be called even when always on top gets turned off because we
5594 // need to make sure that the stack is moved from among always on top windows to below other
5595 // always on top windows. Since the position the stack should be inserted into is calculated
5596 // properly in {@link ActivityDisplay#getTopInsertPosition()} in both cases, we can just
5597 // request that the stack is put at top here.
Riddle Hsu57831b52018-07-27 00:31:48 +08005598 display.positionChildAtTop(this, false /* includingParents */);
Kazuki Takisef85197b2018-06-18 18:18:36 +09005599 }
5600
Riddle Hsu16567132018-08-16 21:37:47 +08005601 /** NOTE: Should only be called from {@link TaskRecord#reparent}. */
Winson Chungc2baac02017-01-11 13:34:47 -08005602 void moveToFrontAndResumeStateIfNeeded(ActivityRecord r, boolean moveToFront, boolean setResume,
5603 boolean setPause, String reason) {
Wale Ogunwaled046a012015-12-24 13:05:59 -08005604 if (!moveToFront) {
5605 return;
Wale Ogunwale079a0042015-10-24 11:44:07 -07005606 }
Wale Ogunwaled046a012015-12-24 13:05:59 -08005607
Riddle Hsu16567132018-08-16 21:37:47 +08005608 final ActivityState origState = r.getState();
Wale Ogunwaled046a012015-12-24 13:05:59 -08005609 // If the activity owns the last resumed activity, transfer that together,
5610 // so that we don't resume the same activity again in the new stack.
5611 // Apps may depend on onResume()/onPause() being called in pairs.
5612 if (setResume) {
Bryce Leec4ab62a2018-03-05 14:19:26 -08005613 r.setState(RESUMED, "moveToFrontAndResumeStateIfNeeded");
Winson Chungabb433b2017-03-24 09:35:42 -07005614 updateLRUListLocked(r);
Wale Ogunwaled046a012015-12-24 13:05:59 -08005615 }
Winson Chungc2baac02017-01-11 13:34:47 -08005616 // If the activity was previously pausing, then ensure we transfer that as well
5617 if (setPause) {
5618 mPausingActivity = r;
Winson Chung4dabf232017-01-25 13:25:22 -08005619 schedulePauseTimeout(r);
Winson Chungc2baac02017-01-11 13:34:47 -08005620 }
Riddle Hsu16567132018-08-16 21:37:47 +08005621 // Move the stack in which we are placing the activity to the front.
Wale Ogunwaled046a012015-12-24 13:05:59 -08005622 moveToFront(reason);
Riddle Hsu16567132018-08-16 21:37:47 +08005623 // If the original state is resumed, there is no state change to update focused app.
5624 // So here makes sure the activity focus is set if it is the top.
Wale Ogunwaled32da472018-11-16 07:19:28 -08005625 if (origState == RESUMED && r == mRootActivityContainer.getTopResumedActivity()) {
Riddle Hsu16567132018-08-16 21:37:47 +08005626 // TODO(b/111361570): Support multiple focused apps in WM
5627 mService.setResumedActivityUncheckLocked(r, reason);
5628 }
Wale Ogunwale079a0042015-10-24 11:44:07 -07005629 }
5630
Yunfan Chen279f5582018-12-12 15:24:50 -08005631
5632 Rect getDefaultPictureInPictureBounds(float aspectRatio) {
5633 if (getTaskStack() == null) return null;
5634 return getTaskStack().getPictureInPictureBounds(aspectRatio, null /* currentStackBounds */);
5635 }
5636
5637 void animateResizePinnedStack(Rect sourceHintBounds, Rect toBounds, int animationDuration,
5638 boolean fromFullscreen) {
5639 if (!inPinnedWindowingMode()) return;
5640 if (skipResizeAnimation(toBounds == null /* toFullscreen */)) {
5641 mService.moveTasksToFullscreenStack(mStackId, true /* onTop */);
5642 } else {
5643 if (getTaskStack() == null) return;
5644 getTaskStack().animateResizePinnedStack(toBounds, sourceHintBounds,
5645 animationDuration, fromFullscreen);
5646 }
5647 }
5648
wilsonshih5c4cf522019-01-25 09:03:47 +08005649 /**
5650 * Get current bounds of this stack, return empty when it is unavailable.
5651 * @see TaskStack#getAnimationOrCurrentBounds(Rect)
5652 */
5653 void getAnimationOrCurrentBounds(Rect outBounds) {
5654 final TaskStack stack = getTaskStack();
5655 if (stack == null) {
5656 outBounds.setEmpty();
5657 return;
5658 }
5659 stack.getAnimationOrCurrentBounds(outBounds);
5660 }
5661
Yunfan Chen279f5582018-12-12 15:24:50 -08005662 private boolean skipResizeAnimation(boolean toFullscreen) {
5663 if (!toFullscreen) {
5664 return false;
5665 }
5666 final Configuration parentConfig = getParent().getConfiguration();
5667 final ActivityRecord top = topRunningNonOverlayTaskActivity();
5668 return top != null && !top.isConfigurationCompatible(parentConfig);
5669 }
5670
5671 void setPictureInPictureAspectRatio(float aspectRatio) {
5672 if (getTaskStack() == null) return;
5673 getTaskStack().setPictureInPictureAspectRatio(aspectRatio);
5674 }
5675
5676 void setPictureInPictureActions(List<RemoteAction> actions) {
5677 if (getTaskStack() == null) return;
5678 getTaskStack().setPictureInPictureActions(actions);
5679 }
5680
5681 boolean isAnimatingBoundsToFullscreen() {
5682 if (getTaskStack() == null) return false;
5683 return getTaskStack().isAnimatingBoundsToFullscreen();
5684 }
5685
5686 public void updatePictureInPictureModeForPinnedStackAnimation(Rect targetStackBounds,
5687 boolean forceUpdate) {
5688 // It is guaranteed that the activities requiring the update will be in the pinned stack at
5689 // this point (either reparented before the animation into PiP, or before reparenting after
5690 // the animation out of PiP)
5691 synchronized (mService.mGlobalLock) {
5692 if (!isAttached()) {
5693 return;
5694 }
5695 ArrayList<TaskRecord> tasks = getAllTasks();
5696 for (int i = 0; i < tasks.size(); i++) {
5697 mStackSupervisor.updatePictureInPictureMode(tasks.get(i), targetStackBounds,
5698 forceUpdate);
5699 }
5700 }
5701 }
5702
Craig Mautnerc00204b2013-03-05 15:02:14 -08005703 public int getStackId() {
5704 return mStackId;
5705 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07005706
5707 @Override
5708 public String toString() {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07005709 return "ActivityStack{" + Integer.toHexString(System.identityHashCode(this))
Wale Ogunwale44f036f2017-09-29 05:09:09 -07005710 + " stackId=" + mStackId + " type=" + activityTypeToString(getActivityType())
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -07005711 + " mode=" + windowingModeToString(getWindowingMode())
Wale Ogunwale8e923af2018-03-23 08:48:11 -07005712 + " visible=" + shouldBeVisible(null /* starting */)
5713 + " translucent=" + isStackTranslucent(null /* starting */)
5714 + ", "
Wale Ogunwale44f036f2017-09-29 05:09:09 -07005715 + mTaskHistory.size() + " tasks}";
Craig Mautnerde4ef022013-04-07 19:01:33 -07005716 }
Wale Ogunwale60454db2015-01-23 16:05:07 -08005717
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07005718 void onLockTaskPackagesUpdated() {
Craig Mautner15df08a2015-04-01 12:17:18 -07005719 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
5720 mTaskHistory.get(taskNdx).setLockTaskAuth();
5721 }
5722 }
skuhne@google.com1b974dc2016-12-09 13:41:29 -08005723
5724 void executeAppTransition(ActivityOptions options) {
Wale Ogunwale3a256e62018-12-06 14:41:18 -08005725 getDisplay().mDisplayContent.executeAppTransition();
skuhne@google.com1b974dc2016-12-09 13:41:29 -08005726 ActivityOptions.abort(options);
5727 }
David Stevens9440dc82017-03-16 19:00:20 -07005728
5729 boolean shouldSleepActivities() {
Wale Ogunwale9dcf9462017-09-19 15:13:01 -07005730 final ActivityDisplay display = getDisplay();
Bryce Lee271617a2018-03-15 10:39:12 -07005731
5732 // Do not sleep activities in this stack if we're marked as focused and the keyguard
5733 // is in the process of going away.
Tiger Huang1e5b10a2018-07-30 20:19:51 +08005734 if (isFocusedStackOnDisplay()
Bryce Lee271617a2018-03-15 10:39:12 -07005735 && mStackSupervisor.getKeyguardController().isKeyguardGoingAway()) {
5736 return false;
5737 }
5738
Wale Ogunwalef6733932018-06-27 05:14:34 -07005739 return display != null ? display.isSleeping() : mService.isSleepingLocked();
David Stevens9440dc82017-03-16 19:00:20 -07005740 }
5741
5742 boolean shouldSleepOrShutDownActivities() {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005743 return shouldSleepActivities() || mService.mShuttingDown;
David Stevens9440dc82017-03-16 19:00:20 -07005744 }
Steven Timotius4346f0a2017-09-12 11:07:21 -07005745
Nataniel Borges023ecb52019-01-16 14:15:43 -08005746 public void writeToProto(ProtoOutputStream proto, long fieldId,
5747 @WindowTraceLogLevel int logLevel) {
Steven Timotius4346f0a2017-09-12 11:07:21 -07005748 final long token = proto.start(fieldId);
Nataniel Borges023ecb52019-01-16 14:15:43 -08005749 super.writeToProto(proto, CONFIGURATION_CONTAINER, logLevel);
Steven Timotius4346f0a2017-09-12 11:07:21 -07005750 proto.write(ID, mStackId);
5751 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
5752 final TaskRecord task = mTaskHistory.get(taskNdx);
Nataniel Borges023ecb52019-01-16 14:15:43 -08005753 task.writeToProto(proto, TASKS, logLevel);
Steven Timotius4346f0a2017-09-12 11:07:21 -07005754 }
5755 if (mResumedActivity != null) {
5756 mResumedActivity.writeIdentifierToProto(proto, RESUMED_ACTIVITY);
5757 }
5758 proto.write(DISPLAY_ID, mDisplayId);
Bryce Leef3c6a472017-11-14 14:53:06 -08005759 if (!matchParentBounds()) {
Evan Roskydfe3da72018-10-26 17:21:06 -07005760 final Rect bounds = getRequestedOverrideBounds();
Bryce Leef3c6a472017-11-14 14:53:06 -08005761 bounds.writeToProto(proto, BOUNDS);
Steven Timotius4346f0a2017-09-12 11:07:21 -07005762 }
Bryce Leef3c6a472017-11-14 14:53:06 -08005763
5764 // TODO: Remove, no longer needed with windowingMode.
5765 proto.write(FULLSCREEN, matchParentBounds());
Steven Timotius4346f0a2017-09-12 11:07:21 -07005766 proto.end(token);
5767 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005768}