blob: ed5cc2e2ce9f1d1272dc9a4fd35cce9d04109baa [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
Andrii Kulianab132ee2018-07-24 22:10:21 +080019import static android.app.ActivityTaskManager.INVALID_STACK_ID;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070020import static android.app.ActivityTaskManager.RESIZE_MODE_FORCED;
21import static android.app.ActivityTaskManager.RESIZE_MODE_SYSTEM;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -070022import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
23import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070024import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
25import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
26import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
27import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Wale Ogunwale44f036f2017-09-29 05:09:09 -070028import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Jorim Jaggi0a932142016-02-01 17:42:25 -080029import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
Wale Ogunwale66e16852017-10-19 13:35:52 -070030import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
Jorim Jaggi0a932142016-02-01 17:42:25 -080031import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
Wale Ogunwale66e16852017-10-19 13:35:52 -070032import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
Wale Ogunwale3eadad72016-10-13 09:16:59 -070033import static android.content.pm.ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY;
Jorim Jaggi0a932142016-02-01 17:42:25 -080034import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
35import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
36import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
37import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER;
skuhne@google.com322347b2016-12-02 12:54:03 -080038import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY;
39import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PORTRAIT_ONLY;
40import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PRESERVE_ORIENTATION;
Wale Ogunwaled829d362016-02-10 19:24:49 -080041import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
Wale Ogunwale625ed0c2016-10-18 08:50:31 -070042import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
Winson Chungd3395382016-12-13 11:49:09 -080043import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_AND_PIPABLE_DEPRECATED;
Wale Ogunwale625ed0c2016-10-18 08:50:31 -070044import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -080045import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
Suprabh Shukla7745c142016-03-07 18:21:10 -080046import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
Andrii Kulian036e3ad2017-04-19 10:55:10 -070047import static android.view.Display.DEFAULT_DISPLAY;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -070048
Jorim Jaggi0a932142016-02-01 17:42:25 -080049import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ADD_REMOVE;
50import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
51import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
52import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
53import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_ADD_REMOVE;
54import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
55import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
56import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS;
57import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
58import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
Wale Ogunwale3b232392016-05-13 15:37:13 -070059import static com.android.server.am.ActivityRecord.STARTING_WINDOW_SHOWN;
Wale Ogunwalec5cc3012017-01-13 13:26:16 -080060import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING;
Wale Ogunwale56d8d162017-05-30 11:12:20 -070061import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING_TO_TOP;
Wale Ogunwaleab5de372017-10-18 06:46:31 -070062import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
Winson Chung6954fc92017-03-24 16:22:12 -070063import static com.android.server.am.ActivityStackSupervisor.PAUSE_IMMEDIATELY;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -080064import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
Yi Jin6c6e9ca2018-03-20 16:53:35 -070065import static com.android.server.am.TaskRecordProto.ACTIVITIES;
Andrii Kulianab132ee2018-07-24 22:10:21 +080066import static com.android.server.am.TaskRecordProto.ACTIVITY_TYPE;
Yi Jin6c6e9ca2018-03-20 16:53:35 -070067import static com.android.server.am.TaskRecordProto.BOUNDS;
68import static com.android.server.am.TaskRecordProto.CONFIGURATION_CONTAINER;
69import static com.android.server.am.TaskRecordProto.FULLSCREEN;
70import static com.android.server.am.TaskRecordProto.ID;
71import static com.android.server.am.TaskRecordProto.LAST_NON_FULLSCREEN_BOUNDS;
72import static com.android.server.am.TaskRecordProto.MIN_HEIGHT;
73import static com.android.server.am.TaskRecordProto.MIN_WIDTH;
74import static com.android.server.am.TaskRecordProto.ORIG_ACTIVITY;
75import static com.android.server.am.TaskRecordProto.REAL_ACTIVITY;
76import static com.android.server.am.TaskRecordProto.RESIZE_MODE;
77import static com.android.server.am.TaskRecordProto.STACK_ID;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -070078
Winson Chung74666102017-02-22 17:49:24 -080079import static java.lang.Integer.MAX_VALUE;
80
Jorim Jaggie7d2b852017-08-28 17:55:15 +020081import android.annotation.IntDef;
82import android.annotation.Nullable;
83import android.app.Activity;
84import android.app.ActivityManager;
Jorim Jaggie7d2b852017-08-28 17:55:15 +020085import android.app.ActivityManager.TaskDescription;
86import android.app.ActivityManager.TaskSnapshot;
87import android.app.ActivityOptions;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070088import android.app.ActivityTaskManager;
Jorim Jaggie7d2b852017-08-28 17:55:15 +020089import android.app.AppGlobals;
Winson Chungabfdcce2018-07-02 17:23:33 -070090import android.app.TaskInfo;
Jorim Jaggie7d2b852017-08-28 17:55:15 +020091import android.content.ComponentName;
92import android.content.Intent;
93import android.content.pm.ActivityInfo;
94import android.content.pm.ApplicationInfo;
95import android.content.pm.IPackageManager;
96import android.content.pm.PackageManager;
97import android.content.res.Configuration;
98import android.graphics.Rect;
99import android.os.Debug;
100import android.os.RemoteException;
Winson Chungfb44d212017-10-04 11:39:10 -0700101import android.os.SystemClock;
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200102import android.os.Trace;
103import android.os.UserHandle;
104import android.provider.Settings;
105import android.service.voice.IVoiceInteractionSession;
106import android.util.DisplayMetrics;
107import android.util.Slog;
Steven Timotius4346f0a2017-09-12 11:07:21 -0700108import android.util.proto.ProtoOutputStream;
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200109
110import com.android.internal.annotations.VisibleForTesting;
111import com.android.internal.app.IVoiceInteractor;
112import com.android.internal.util.XmlUtils;
Winson Chung61c9e5a2017-10-11 10:39:32 -0700113import com.android.server.am.ActivityStack.ActivityState;
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200114import com.android.server.wm.AppWindowContainerController;
115import com.android.server.wm.ConfigurationContainer;
116import com.android.server.wm.StackWindowController;
117import com.android.server.wm.TaskWindowContainerController;
118import com.android.server.wm.TaskWindowContainerListener;
119import com.android.server.wm.WindowManagerService;
120
121import org.xmlpull.v1.XmlPullParser;
122import org.xmlpull.v1.XmlPullParserException;
123import org.xmlpull.v1.XmlSerializer;
124
125import java.io.IOException;
126import java.io.PrintWriter;
127import java.lang.annotation.Retention;
128import java.lang.annotation.RetentionPolicy;
129import java.util.ArrayList;
130import java.util.Objects;
131
Benjamin Franza83859f2017-07-03 16:34:14 +0100132class TaskRecord extends ConfigurationContainer implements TaskWindowContainerListener {
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800133 private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskRecord" : TAG_AM;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -0700134 private static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700135 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
Craig Mautnere0570202015-05-13 13:06:11 -0700136 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700137 private static final String TAG_TASKS = TAG + POSTFIX_TASKS;
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800138
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700139 private static final String ATTR_TASKID = "task_id";
Craig Mautner21d24a22014-04-23 11:45:37 -0700140 private static final String TAG_INTENT = "intent";
141 private static final String TAG_AFFINITYINTENT = "affinity_intent";
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700142 private static final String ATTR_REALACTIVITY = "real_activity";
143 private static final String ATTR_REALACTIVITY_SUSPENDED = "real_activity_suspended";
Craig Mautner21d24a22014-04-23 11:45:37 -0700144 private static final String ATTR_ORIGACTIVITY = "orig_activity";
Stefan Kuhnee88d1e52015-05-18 10:33:45 -0700145 private static final String TAG_ACTIVITY = "activity";
Craig Mautner21d24a22014-04-23 11:45:37 -0700146 private static final String ATTR_AFFINITY = "affinity";
Dianne Hackborn79228822014-09-16 11:11:23 -0700147 private static final String ATTR_ROOT_AFFINITY = "root_affinity";
Craig Mautner21d24a22014-04-23 11:45:37 -0700148 private static final String ATTR_ROOTHASRESET = "root_has_reset";
Dianne Hackborn13420f22014-07-18 15:43:56 -0700149 private static final String ATTR_AUTOREMOVERECENTS = "auto_remove_recents";
Craig Mautner21d24a22014-04-23 11:45:37 -0700150 private static final String ATTR_ASKEDCOMPATMODE = "asked_compat_mode";
151 private static final String ATTR_USERID = "user_id";
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800152 private static final String ATTR_USER_SETUP_COMPLETE = "user_setup_complete";
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700153 private static final String ATTR_EFFECTIVE_UID = "effective_uid";
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700154 @Deprecated
Craig Mautner21d24a22014-04-23 11:45:37 -0700155 private static final String ATTR_TASKTYPE = "task_type";
Craig Mautner21d24a22014-04-23 11:45:37 -0700156 private static final String ATTR_LASTDESCRIPTION = "last_description";
157 private static final String ATTR_LASTTIMEMOVED = "last_time_moved";
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700158 private static final String ATTR_NEVERRELINQUISH = "never_relinquish_identity";
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700159 private static final String ATTR_TASK_AFFILIATION = "task_affiliation";
Craig Mautnera228ae92014-07-09 05:44:55 -0700160 private static final String ATTR_PREV_AFFILIATION = "prev_affiliation";
161 private static final String ATTR_NEXT_AFFILIATION = "next_affiliation";
Winson Chungec396d62014-08-06 17:08:00 -0700162 private static final String ATTR_TASK_AFFILIATION_COLOR = "task_affiliation_color";
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700163 private static final String ATTR_CALLING_UID = "calling_uid";
164 private static final String ATTR_CALLING_PACKAGE = "calling_package";
Winson Chungd3395382016-12-13 11:49:09 -0800165 private static final String ATTR_SUPPORTS_PICTURE_IN_PICTURE = "supports_picture_in_picture";
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800166 private static final String ATTR_RESIZE_MODE = "resize_mode";
Wale Ogunwale706ed792015-08-02 10:29:44 -0700167 private static final String ATTR_NON_FULLSCREEN_BOUNDS = "non_fullscreen_bounds";
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700168 private static final String ATTR_MIN_WIDTH = "min_width";
169 private static final String ATTR_MIN_HEIGHT = "min_height";
Wale Ogunwale625ed0c2016-10-18 08:50:31 -0700170 private static final String ATTR_PERSIST_TASK_VERSION = "persist_task_version";
Andrii Kulian18d75122016-03-27 20:20:28 -0700171
Wale Ogunwale625ed0c2016-10-18 08:50:31 -0700172 // Current version of the task record we persist. Used to check if we need to run any upgrade
173 // code.
174 private static final int PERSIST_TASK_VERSION = 1;
Craig Mautner21d24a22014-04-23 11:45:37 -0700175
Wale Ogunwale18795a22014-12-03 11:38:33 -0800176 static final int INVALID_TASK_ID = -1;
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700177 private static final int INVALID_MIN_SIZE = -1;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800178
Winson Chung74666102017-02-22 17:49:24 -0800179 /**
180 * The modes to control how the stack is moved to the front when calling
181 * {@link TaskRecord#reparent}.
182 */
183 @Retention(RetentionPolicy.SOURCE)
184 @IntDef({
185 REPARENT_MOVE_STACK_TO_FRONT,
186 REPARENT_KEEP_STACK_AT_FRONT,
187 REPARENT_LEAVE_STACK_IN_PLACE
188 })
Wale Ogunwale66e16852017-10-19 13:35:52 -0700189 @interface ReparentMoveStackMode {}
Winson Chung74666102017-02-22 17:49:24 -0800190 // Moves the stack to the front if it was not at the front
Wale Ogunwale66e16852017-10-19 13:35:52 -0700191 static final int REPARENT_MOVE_STACK_TO_FRONT = 0;
Winson Chung74666102017-02-22 17:49:24 -0800192 // Only moves the stack to the front if it was focused or front most already
Wale Ogunwale66e16852017-10-19 13:35:52 -0700193 static final int REPARENT_KEEP_STACK_AT_FRONT = 1;
Winson Chung74666102017-02-22 17:49:24 -0800194 // Do not move the stack as a part of reparenting
Wale Ogunwale66e16852017-10-19 13:35:52 -0700195 static final int REPARENT_LEAVE_STACK_IN_PLACE = 2;
Winson Chung74666102017-02-22 17:49:24 -0800196
Garfield Tan9b1efea2017-12-05 16:43:46 -0800197 /**
198 * The factory used to create {@link TaskRecord}. This allows OEM subclass {@link TaskRecord}.
199 */
200 private static TaskRecordFactory sTaskRecordFactory;
201
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800202 final int taskId; // Unique identifier for this task.
Dianne Hackborn79228822014-09-16 11:11:23 -0700203 String affinity; // The affinity name for this task, or null; may change identity.
204 String rootAffinity; // Initial base affinity, or null; does not change from initial root.
Dianne Hackborn91097de2014-04-04 18:02:06 -0700205 final IVoiceInteractionSession voiceSession; // Voice interaction session driving task
206 final IVoiceInteractor voiceInteractor; // Associated interactor to provide to app
Bryce Lee1a990e52018-04-23 10:54:11 -0700207 Intent intent; // The original intent that started the task. Note that this value can
208 // be null.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800209 Intent affinityIntent; // Intent of affinity-moved activity that started this task.
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700210 int effectiveUid; // The current effective uid of the identity of this task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800211 ComponentName origActivity; // The non-alias activity component of the intent.
212 ComponentName realActivity; // The actual activity component that started the task.
Andrei Stingaceanu4ccec532016-01-13 12:10:21 +0000213 boolean realActivitySuspended; // True if the actual activity component that started the
214 // task is suspended.
Dianne Hackborn852975d2014-08-22 17:42:43 -0700215 boolean inRecents; // Actually in the recents list?
Winson Chungfb44d212017-10-04 11:39:10 -0700216 long lastActiveTime; // Last time this task was active in the current device session,
217 // including sleep. This time is initialized to the elapsed time when
218 // restored from disk.
Dianne Hackborn852975d2014-08-22 17:42:43 -0700219 boolean isAvailable; // Is the activity available to be launched?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800220 boolean rootWasReset; // True if the intent at the root of the task had
221 // the FLAG_ACTIVITY_RESET_TASK_IF_NEEDED flag.
Dianne Hackborn13420f22014-07-18 15:43:56 -0700222 boolean autoRemoveRecents; // If true, we should automatically remove the task from
223 // recents when activity finishes
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700224 boolean askedCompatMode;// Have asked the user about compat mode for this task.
Dianne Hackbornd38aed82014-06-10 21:36:35 -0700225 boolean hasBeenVisible; // Set if any activities in the task have been visible to the user.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800226
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700227 String stringName; // caching of toString() result.
Dianne Hackborn9da2d402012-03-15 13:43:08 -0700228 int userId; // user for which this task was created
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800229 boolean mUserSetupComplete; // The user set-up is complete as of the last time the task activity
230 // was changed.
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800231
232 int numFullscreen; // Number of fullscreen activities.
233
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800234 int mResizeMode; // The resize mode of this task and its activities.
235 // Based on the {@link ActivityInfo#resizeMode} of the root activity.
Wale Ogunwale069bbd32017-02-03 07:58:14 -0800236 private boolean mSupportsPictureInPicture; // Whether or not this task and its activities
237 // support PiP. Based on the {@link ActivityInfo#FLAG_SUPPORTS_PICTURE_IN_PICTURE} flag
238 // of the root activity.
Craig Mautner15df08a2015-04-01 12:17:18 -0700239 /** Can't be put in lockTask mode. */
240 final static int LOCK_TASK_AUTH_DONT_LOCK = 0;
Benjamin Franz469dd582015-06-09 14:24:36 +0100241 /** Can enter app pinning with user approval. Can never start over existing lockTask task. */
Craig Mautner15df08a2015-04-01 12:17:18 -0700242 final static int LOCK_TASK_AUTH_PINNABLE = 1;
243 /** Starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing lockTask task. */
244 final static int LOCK_TASK_AUTH_LAUNCHABLE = 2;
Benjamin Franz469dd582015-06-09 14:24:36 +0100245 /** Can enter lockTask without user approval. Can start over existing lockTask task. */
Craig Mautner15df08a2015-04-01 12:17:18 -0700246 final static int LOCK_TASK_AUTH_WHITELISTED = 3;
Benjamin Franz469dd582015-06-09 14:24:36 +0100247 /** Priv-app that starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing
248 * lockTask task. */
249 final static int LOCK_TASK_AUTH_LAUNCHABLE_PRIV = 4;
Craig Mautner15df08a2015-04-01 12:17:18 -0700250 int mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE;
251
252 int mLockTaskUid = -1; // The uid of the application that called startLockTask().
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800253
Winson Chung03a9bae2014-05-02 09:56:12 -0700254 // This represents the last resolved activity values for this task
255 // NOTE: This value needs to be persisted with each task
Craig Mautner648f69b2014-09-18 14:16:26 -0700256 TaskDescription lastTaskDescription = new TaskDescription();
Winson Chung03a9bae2014-05-02 09:56:12 -0700257
Craig Mautnerd2328952013-03-05 12:46:26 -0800258 /** List of all activities in the task arranged in history order */
Craig Mautner21d24a22014-04-23 11:45:37 -0700259 final ArrayList<ActivityRecord> mActivities;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800260
Andrii Kulian02b7a832016-10-06 23:11:56 -0700261 /** Current stack. Setter must always be used to update the value. */
262 private ActivityStack mStack;
Craig Mautnerd2328952013-03-05 12:46:26 -0800263
Dianne Hackborn68a06332017-11-15 17:54:18 -0800264 /** The process that had previously hosted the root activity of this task.
265 * Used to know that we should try harder to keep this process around, in case the
266 * user wants to return to it. */
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700267 private WindowProcessController mRootProcess;
Dianne Hackborn68a06332017-11-15 17:54:18 -0800268
Craig Mautner21d24a22014-04-23 11:45:37 -0700269 /** Takes on same value as first root activity */
270 boolean isPersistable = false;
Craig Mautnerffcfcaa2014-06-05 09:54:38 -0700271 int maxRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700272
273 /** Only used for persistable tasks, otherwise 0. The last time this task was moved. Used for
274 * determining the order when restoring. Sign indicates whether last task movement was to front
275 * (positive) or back (negative). Absolute value indicates time. */
276 long mLastTimeMoved = System.currentTimeMillis();
277
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700278 /** If original intent did not allow relinquishing task identity, save that information */
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700279 private boolean mNeverRelinquishIdentity = true;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700280
Craig Mautner362449a2014-06-20 14:04:39 -0700281 // Used in the unique case where we are clearing the task in order to reuse it. In that case we
282 // do not want to delete the stack when the task goes empty.
Filip Gruszczynskibe9dabd2016-01-19 12:23:10 -0800283 private boolean mReuseTask = false;
Craig Mautner362449a2014-06-20 14:04:39 -0700284
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700285 CharSequence lastDescription; // Last description captured for this item.
286
Craig Mautnera228ae92014-07-09 05:44:55 -0700287 int mAffiliatedTaskId; // taskId of parent affiliation or self if no parent.
Winson Chungec396d62014-08-06 17:08:00 -0700288 int mAffiliatedTaskColor; // color of the parent task affiliation.
Craig Mautnera228ae92014-07-09 05:44:55 -0700289 TaskRecord mPrevAffiliate; // previous task in affiliated chain.
Wale Ogunwale18795a22014-12-03 11:38:33 -0800290 int mPrevAffiliateTaskId = INVALID_TASK_ID; // previous id for persistence.
Craig Mautnera228ae92014-07-09 05:44:55 -0700291 TaskRecord mNextAffiliate; // next task in affiliated chain.
Wale Ogunwale18795a22014-12-03 11:38:33 -0800292 int mNextAffiliateTaskId = INVALID_TASK_ID; // next id for persistence.
Craig Mautnera228ae92014-07-09 05:44:55 -0700293
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700294 // For relaunching the task from recents as though it was launched by the original launcher.
295 int mCallingUid;
296 String mCallingPackage;
297
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700298 final ActivityTaskManagerService mService;
Craig Mautner21d24a22014-04-23 11:45:37 -0700299
Jorim Jaggi82c9dc92016-02-05 15:10:33 -0800300 private final Rect mTmpStableBounds = new Rect();
301 private final Rect mTmpNonDecorBounds = new Rect();
Wale Ogunwale9a08f822016-02-17 19:03:58 -0800302 private final Rect mTmpRect = new Rect();
Jorim Jaggi0a932142016-02-01 17:42:25 -0800303
Wale Ogunwale706ed792015-08-02 10:29:44 -0700304 // Last non-fullscreen bounds the task was launched in or resized to.
305 // The information is persisted and used to determine the appropriate stack to launch the
306 // task into on restore.
307 Rect mLastNonFullscreenBounds = null;
Andrii Kulian2e751b82016-03-16 16:59:32 -0700308 // Minimal width and height of this task when it's resizeable. -1 means it should use the
309 // default minimal width/height.
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700310 int mMinWidth;
311 int mMinHeight;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700312
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700313 // Ranking (from top) of this task among all visible tasks. (-1 means it's not visible)
314 // This number will be assigned when we evaluate OOM scores for all visible tasks.
315 int mLayerRank = -1;
316
Andrii Kulian1779e612016-10-12 21:58:25 -0700317 /** Helper object used for updating override configuration. */
318 private Configuration mTmpConfig = new Configuration();
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700319
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800320 private TaskWindowContainerController mWindowContainerController;
321
Garfield Tan9b1efea2017-12-05 16:43:46 -0800322 /**
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700323 * Don't use constructor directly. Use {@link #create(ActivityTaskManagerService, int,
324 * ActivityInfo, Intent, TaskDescription)} instead.
Garfield Tan9b1efea2017-12-05 16:43:46 -0800325 */
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700326 TaskRecord(ActivityTaskManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700327 IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700328 mService = service;
Suprabh Shukla23593142015-11-03 17:31:15 -0800329 userId = UserHandle.getUserId(info.applicationInfo.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330 taskId = _taskId;
Winson Chungfb44d212017-10-04 11:39:10 -0700331 lastActiveTime = SystemClock.elapsedRealtime();
Craig Mautnera228ae92014-07-09 05:44:55 -0700332 mAffiliatedTaskId = _taskId;
Dianne Hackborn91097de2014-04-04 18:02:06 -0700333 voiceSession = _voiceSession;
334 voiceInteractor = _voiceInteractor;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700335 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800336 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700337 mCallingUid = info.applicationInfo.uid;
338 mCallingPackage = info.packageName;
Martijn Coenend4a69702014-06-30 11:12:17 -0700339 setIntent(_intent, info);
Andrii Kulian2e751b82016-03-16 16:59:32 -0700340 setMinDimensions(info);
Winson730bf062016-03-31 18:04:56 -0700341 touchActiveTime();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700342 mService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
Craig Mautner21d24a22014-04-23 11:45:37 -0700343 }
344
Garfield Tan9b1efea2017-12-05 16:43:46 -0800345 /**
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700346 * Don't use constructor directly.
347 * Use {@link #create(ActivityTaskManagerService, int, ActivityInfo,
Garfield Tan9b1efea2017-12-05 16:43:46 -0800348 * Intent, IVoiceInteractionSession, IVoiceInteractor)} instead.
349 */
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700350 TaskRecord(ActivityTaskManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200351 TaskDescription _taskDescription) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700352 mService = service;
Suprabh Shukla23593142015-11-03 17:31:15 -0800353 userId = UserHandle.getUserId(info.applicationInfo.uid);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700354 taskId = _taskId;
Winson Chungfb44d212017-10-04 11:39:10 -0700355 lastActiveTime = SystemClock.elapsedRealtime();
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700356 mAffiliatedTaskId = _taskId;
357 voiceSession = null;
358 voiceInteractor = null;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700359 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800360 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700361 mCallingUid = info.applicationInfo.uid;
362 mCallingPackage = info.packageName;
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700363 setIntent(_intent, info);
Andrii Kulian2e751b82016-03-16 16:59:32 -0700364 setMinDimensions(info);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700365
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700366 isPersistable = true;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700367 // Clamp to [1, max].
368 maxRecents = Math.min(Math.max(info.maxRecents, 1),
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700369 ActivityTaskManager.getMaxAppRecentsLimitStatic());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700370
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700371 lastTaskDescription = _taskDescription;
Winson730bf062016-03-31 18:04:56 -0700372 touchActiveTime();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700373 mService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700374 }
375
Garfield Tan9b1efea2017-12-05 16:43:46 -0800376 /**
377 * Don't use constructor directly. This is only used by XML parser.
378 */
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700379 TaskRecord(ActivityTaskManagerService service, int _taskId, Intent _intent,
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800380 Intent _affinityIntent, String _affinity, String _rootAffinity,
381 ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700382 boolean _autoRemoveRecents, boolean _askedCompatMode, int _userId,
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800383 int _effectiveUid, String _lastDescription, ArrayList<ActivityRecord> activities,
Winson Chungfb44d212017-10-04 11:39:10 -0700384 long lastTimeMoved, boolean neverRelinquishIdentity,
385 TaskDescription _lastTaskDescription, int taskAffiliation, int prevTaskId,
386 int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage,
Charles He2bf28322017-10-12 22:24:49 +0100387 int resizeMode, boolean supportsPictureInPicture, boolean _realActivitySuspended,
388 boolean userSetupComplete, int minWidth, int minHeight) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700389 mService = service;
390 taskId = _taskId;
391 intent = _intent;
392 affinityIntent = _affinityIntent;
393 affinity = _affinity;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800394 rootAffinity = _rootAffinity;
Craig Mautner21d24a22014-04-23 11:45:37 -0700395 voiceSession = null;
396 voiceInteractor = null;
397 realActivity = _realActivity;
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800398 realActivitySuspended = _realActivitySuspended;
Craig Mautner21d24a22014-04-23 11:45:37 -0700399 origActivity = _origActivity;
400 rootWasReset = _rootWasReset;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700401 isAvailable = true;
Dianne Hackborn13420f22014-07-18 15:43:56 -0700402 autoRemoveRecents = _autoRemoveRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700403 askedCompatMode = _askedCompatMode;
Craig Mautner21d24a22014-04-23 11:45:37 -0700404 userId = _userId;
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800405 mUserSetupComplete = userSetupComplete;
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700406 effectiveUid = _effectiveUid;
Winson Chungfb44d212017-10-04 11:39:10 -0700407 lastActiveTime = SystemClock.elapsedRealtime();
Craig Mautner21d24a22014-04-23 11:45:37 -0700408 lastDescription = _lastDescription;
409 mActivities = activities;
410 mLastTimeMoved = lastTimeMoved;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700411 mNeverRelinquishIdentity = neverRelinquishIdentity;
Winson Chung2cb86c72014-06-25 12:03:30 -0700412 lastTaskDescription = _lastTaskDescription;
Craig Mautnera228ae92014-07-09 05:44:55 -0700413 mAffiliatedTaskId = taskAffiliation;
Winson Chungec396d62014-08-06 17:08:00 -0700414 mAffiliatedTaskColor = taskAffiliationColor;
Craig Mautnera228ae92014-07-09 05:44:55 -0700415 mPrevAffiliateTaskId = prevTaskId;
416 mNextAffiliateTaskId = nextTaskId;
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700417 mCallingUid = callingUid;
418 mCallingPackage = callingPackage;
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800419 mResizeMode = resizeMode;
Winson Chungd3395382016-12-13 11:49:09 -0800420 mSupportsPictureInPicture = supportsPictureInPicture;
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700421 mMinWidth = minWidth;
422 mMinHeight = minHeight;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700423 mService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800424 }
425
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800426 TaskWindowContainerController getWindowContainerController() {
427 return mWindowContainerController;
428 }
429
430 void createWindowContainer(boolean onTop, boolean showForAllUsers) {
431 if (mWindowContainerController != null) {
432 throw new IllegalArgumentException("Window container=" + mWindowContainerController
433 + " already created for task=" + this);
434 }
435
436 final Rect bounds = updateOverrideConfigurationFromLaunchBounds();
Bryce Lee04ab3462017-04-10 15:06:33 -0700437 setWindowContainerController(new TaskWindowContainerController(taskId, this,
Wale Ogunwale034a8ec2017-09-02 17:14:40 -0700438 getStack().getWindowContainerController(), userId, bounds,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700439 mResizeMode, mSupportsPictureInPicture, onTop,
440 showForAllUsers, lastTaskDescription));
Bryce Lee04ab3462017-04-10 15:06:33 -0700441 }
442
443 /**
444 * Should only be invoked from {@link #createWindowContainer(boolean, boolean)}.
445 */
446 @VisibleForTesting
447 protected void setWindowContainerController(TaskWindowContainerController controller) {
448 if (mWindowContainerController != null) {
449 throw new IllegalArgumentException("Window container=" + mWindowContainerController
450 + " already created for task=" + this);
451 }
452
453 mWindowContainerController = controller;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800454 }
455
456 void removeWindowContainer() {
Bryce Lee2b8e0372018-04-05 17:01:37 -0700457 mService.getLockTaskController().clearLockedTask(this);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800458 mWindowContainerController.removeContainer();
Wale Ogunwale3382ab12017-07-27 08:55:03 -0700459 if (!getWindowConfiguration().persistTaskBounds()) {
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800460 // Reset current bounds for task whose bounds shouldn't be persisted so it uses
461 // default configuration the next time it launches.
462 updateOverrideConfiguration(null);
463 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700464 mService.getTaskChangeNotificationController().notifyTaskRemoved(taskId);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800465 mWindowContainerController = null;
466 }
467
Jorim Jaggifb9d78a2017-01-05 18:57:12 +0100468 @Override
469 public void onSnapshotChanged(TaskSnapshot snapshot) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700470 mService.getTaskChangeNotificationController().notifyTaskSnapshotChanged(taskId, snapshot);
Jorim Jaggifb9d78a2017-01-05 18:57:12 +0100471 }
472
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800473 void setResizeMode(int resizeMode) {
474 if (mResizeMode == resizeMode) {
475 return;
476 }
477 mResizeMode = resizeMode;
478 mWindowContainerController.setResizeable(resizeMode);
479 mService.mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Andrii Kulianab132ee2018-07-24 22:10:21 +0800480 mService.mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800481 }
482
483 void setTaskDockedResizing(boolean resizing) {
484 mWindowContainerController.setTaskDockedResizing(resizing);
485 }
486
Wale Ogunwale1666e312016-12-16 11:27:18 -0800487 // TODO: Consolidate this with the resize() method below.
488 @Override
489 public void requestResize(Rect bounds, int resizeMode) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700490 mService.resizeTask(taskId, bounds, resizeMode);
Wale Ogunwale1666e312016-12-16 11:27:18 -0800491 }
492
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800493 boolean resize(Rect bounds, int resizeMode, boolean preserveWindow, boolean deferResume) {
Bryce Leef3c6a472017-11-14 14:53:06 -0800494 mService.mWindowManager.deferSurfaceLayout();
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800495
Bryce Leef3c6a472017-11-14 14:53:06 -0800496 try {
497 if (!isResizeable()) {
498 Slog.w(TAG, "resizeTask: task " + this + " not resizeable.");
499 return true;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800500 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800501
Bryce Leef3c6a472017-11-14 14:53:06 -0800502 // If this is a forced resize, let it go through even if the bounds is not changing,
503 // as we might need a relayout due to surface size change (to/from fullscreen).
504 final boolean forced = (resizeMode & RESIZE_MODE_FORCED) != 0;
505 if (equivalentOverrideBounds(bounds) && !forced) {
506 // Nothing to do here...
507 return true;
508 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800509
Bryce Leef3c6a472017-11-14 14:53:06 -0800510 if (mWindowContainerController == null) {
511 // Task doesn't exist in window manager yet (e.g. was restored from recents).
512 // All we can do for now is update the bounds so it can be used when the task is
513 // added to window manager.
514 updateOverrideConfiguration(bounds);
515 if (!inFreeformWindowingMode()) {
516 // re-restore the task so it can have the proper stack association.
517 mService.mStackSupervisor.restoreRecentTaskLocked(this, null, !ON_TOP);
518 }
519 return true;
520 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800521
Bryce Leef3c6a472017-11-14 14:53:06 -0800522 if (!canResizeToBounds(bounds)) {
523 throw new IllegalArgumentException("resizeTask: Can not resize task=" + this
524 + " to bounds=" + bounds + " resizeMode=" + mResizeMode);
525 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800526
Bryce Leef3c6a472017-11-14 14:53:06 -0800527 // Do not move the task to another stack here.
528 // This method assumes that the task is already placed in the right stack.
529 // we do not mess with that decision and we only do the resize!
530
531 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeTask_" + taskId);
532
533 final boolean updatedConfig = updateOverrideConfiguration(bounds);
534 // This variable holds information whether the configuration didn't change in a significant
535
536 // way and the activity was kept the way it was. If it's false, it means the activity
537 // had
538 // to be relaunched due to configuration change.
539 boolean kept = true;
540 if (updatedConfig) {
541 final ActivityRecord r = topRunningActivityLocked();
542 if (r != null && !deferResume) {
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -0800543 kept = r.ensureActivityConfiguration(0 /* globalChanges */,
Bryce Leef3c6a472017-11-14 14:53:06 -0800544 preserveWindow);
Garfield Tanb9151182018-06-25 16:29:21 -0700545 // Preserve other windows for resizing because if resizing happens when there
546 // is a dialog activity in the front, the activity that still shows some
547 // content to the user will become black and cause flickers. Note in most cases
548 // this won't cause tons of irrelevant windows being preserved because only
549 // activities in this task may experience a bounds change. Configs for other
550 // activities stay the same.
Bryce Leef3c6a472017-11-14 14:53:06 -0800551 mService.mStackSupervisor.ensureActivitiesVisibleLocked(r, 0,
Garfield Tanb9151182018-06-25 16:29:21 -0700552 preserveWindow);
Bryce Leef3c6a472017-11-14 14:53:06 -0800553 if (!kept) {
Andrii Kulianab132ee2018-07-24 22:10:21 +0800554 mService.mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Bryce Leef3c6a472017-11-14 14:53:06 -0800555 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800556 }
557 }
Bryce Leef3c6a472017-11-14 14:53:06 -0800558 mWindowContainerController.resize(kept, forced);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800559
Bryce Leef3c6a472017-11-14 14:53:06 -0800560 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
561 return kept;
562 } finally {
563 mService.mWindowManager.continueSurfaceLayout();
564 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800565 }
566
567 // TODO: Investigate combining with the resize() method above.
568 void resizeWindowContainer() {
Bryce Leef3c6a472017-11-14 14:53:06 -0800569 mWindowContainerController.resize(false /* relayout */, false /* forced */);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800570 }
571
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800572 void getWindowContainerBounds(Rect bounds) {
573 mWindowContainerController.getBounds(bounds);
574 }
575
Winson Chung74666102017-02-22 17:49:24 -0800576 /**
577 * Convenience method to reparent a task to the top or bottom position of the stack.
578 */
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700579 boolean reparent(ActivityStack preferredStack, boolean toTop,
580 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
581 String reason) {
582 return reparent(preferredStack, toTop ? MAX_VALUE : 0, moveStackMode, animate, deferResume,
583 true /* schedulePictureInPictureModeChange */, reason);
Winson Chung5af42fc2017-03-24 17:11:33 -0700584 }
585
586 /**
587 * Convenience method to reparent a task to the top or bottom position of the stack, with
588 * an option to skip scheduling the picture-in-picture mode change.
589 */
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700590 boolean reparent(ActivityStack preferredStack, boolean toTop,
591 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
592 boolean schedulePictureInPictureModeChange, String reason) {
593 return reparent(preferredStack, toTop ? MAX_VALUE : 0, moveStackMode, animate,
Winson Chung5af42fc2017-03-24 17:11:33 -0700594 deferResume, schedulePictureInPictureModeChange, reason);
595 }
596
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700597 /** Convenience method to reparent a task to a specific position of the stack. */
598 boolean reparent(ActivityStack preferredStack, int position,
599 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
600 String reason) {
601 return reparent(preferredStack, position, moveStackMode, animate, deferResume,
Winson Chung5af42fc2017-03-24 17:11:33 -0700602 true /* schedulePictureInPictureModeChange */, reason);
Winson Chung74666102017-02-22 17:49:24 -0800603 }
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800604
Winson Chung74666102017-02-22 17:49:24 -0800605 /**
606 * Reparents the task into a preferred stack, creating it if necessary.
607 *
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700608 * @param preferredStack the target stack to move this task
Winson Chung74666102017-02-22 17:49:24 -0800609 * @param position the position to place this task in the new stack
610 * @param animate whether or not we should wait for the new window created as a part of the
Winson Chung5af42fc2017-03-24 17:11:33 -0700611 * reparenting to be drawn and animated in
Winson Chung74666102017-02-22 17:49:24 -0800612 * @param moveStackMode whether or not to move the stack to the front always, only if it was
Winson Chung5af42fc2017-03-24 17:11:33 -0700613 * previously focused & in front, or never
Winson Chung74666102017-02-22 17:49:24 -0800614 * @param deferResume whether or not to update the visibility of other tasks and stacks that may
Winson Chung5af42fc2017-03-24 17:11:33 -0700615 * have changed as a result of this reparenting
616 * @param schedulePictureInPictureModeChange specifies whether or not to schedule the PiP mode
617 * change. Callers may set this to false if they are explicitly scheduling PiP mode
618 * changes themselves, like during the PiP animation
Winson Chung74666102017-02-22 17:49:24 -0800619 * @param reason the caller of this reparenting
Winson Chung5af42fc2017-03-24 17:11:33 -0700620 * @return whether the task was reparented
Winson Chung74666102017-02-22 17:49:24 -0800621 */
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700622 // TODO: Inspect all call sites and change to just changing windowing mode of the stack vs.
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700623 // re-parenting the task. Can only be done when we are no longer using static stack Ids.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700624 boolean reparent(ActivityStack preferredStack, int position,
625 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
626 boolean schedulePictureInPictureModeChange, String reason) {
Winson Chung74666102017-02-22 17:49:24 -0800627 final ActivityStackSupervisor supervisor = mService.mStackSupervisor;
628 final WindowManagerService windowManager = mService.mWindowManager;
629 final ActivityStack sourceStack = getStack();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700630 final ActivityStack toStack = supervisor.getReparentTargetStack(this, preferredStack,
Winson Chung74666102017-02-22 17:49:24 -0800631 position == MAX_VALUE);
632 if (toStack == sourceStack) {
633 return false;
634 }
Andrii Kulianb850ea52017-12-12 23:49:10 -0800635 if (!canBeLaunchedOnDisplay(toStack.mDisplayId)) {
636 return false;
637 }
Winson Chung74666102017-02-22 17:49:24 -0800638
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700639 final int toStackWindowingMode = toStack.getWindowingMode();
Winson Chung74666102017-02-22 17:49:24 -0800640 final ActivityRecord topActivity = getTopActivity();
641
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800642 final boolean mightReplaceWindow = topActivity != null
643 && replaceWindowsOnTaskMove(getWindowingMode(), toStackWindowingMode);
Winson Chung74666102017-02-22 17:49:24 -0800644 if (mightReplaceWindow) {
645 // We are about to relaunch the activity because its configuration changed due to
646 // being maximized, i.e. size change. The activity will first remove the old window
647 // and then add a new one. This call will tell window manager about this, so it can
648 // preserve the old window until the new one is drawn. This prevents having a gap
649 // between the removal and addition, in which no window is visible. We also want the
650 // entrance of the new window to be properly animated.
651 // Note here we always set the replacing window first, as the flags might be needed
652 // during the relaunch. If we end up not doing any relaunch, we clear the flags later.
653 windowManager.setWillReplaceWindow(topActivity.appToken, animate);
654 }
655
656 windowManager.deferSurfaceLayout();
657 boolean kept = true;
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800658 try {
Winson Chung74666102017-02-22 17:49:24 -0800659 final ActivityRecord r = topRunningActivityLocked();
Andrii Kulian5f750bc2018-07-17 08:57:23 -0700660 final boolean wasFocused = r != null && supervisor.isTopDisplayFocusedStack(sourceStack)
Winson Chung74666102017-02-22 17:49:24 -0800661 && (topRunningActivityLocked() == r);
Bryce Leec4ab62a2018-03-05 14:19:26 -0800662 final boolean wasResumed = r != null && sourceStack.getResumedActivity() == r;
Winson Chung95f8f0e2017-03-24 09:20:17 -0700663 final boolean wasPaused = r != null && sourceStack.mPausingActivity == r;
Winson Chung74666102017-02-22 17:49:24 -0800664
665 // In some cases the focused stack isn't the front stack. E.g. pinned stack.
666 // Whenever we are moving the top activity from the front stack we want to make sure to
667 // move the stack to the front.
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -0700668 final boolean wasFront = r != null && sourceStack.isTopStackOnDisplay()
Winson Chung74666102017-02-22 17:49:24 -0800669 && (sourceStack.topRunningActivityLocked() == r);
670
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800671 // Adjust the position for the new parent stack as needed.
Winson Chung74666102017-02-22 17:49:24 -0800672 position = toStack.getAdjustedPositionForTask(this, position, null /* starting */);
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800673
674 // Must reparent first in window manager to avoid a situation where AM can delete the
675 // we are coming from in WM before we reparent because it became empty.
Wale Ogunwale2719cc12017-04-14 09:45:27 -0700676 mWindowContainerController.reparent(toStack.getWindowContainerController(), position,
677 moveStackMode == REPARENT_MOVE_STACK_TO_FRONT);
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800678
Wale Ogunwale56d8d162017-05-30 11:12:20 -0700679 final boolean moveStackToFront = moveStackMode == REPARENT_MOVE_STACK_TO_FRONT
680 || (moveStackMode == REPARENT_KEEP_STACK_AT_FRONT && (wasFocused || wasFront));
Winson Chung74666102017-02-22 17:49:24 -0800681 // Move the task
Wale Ogunwale56d8d162017-05-30 11:12:20 -0700682 sourceStack.removeTask(this, reason, moveStackToFront
683 ? REMOVE_TASK_MODE_MOVING_TO_TOP : REMOVE_TASK_MODE_MOVING);
Winson Chung5af42fc2017-03-24 17:11:33 -0700684 toStack.addTask(this, position, false /* schedulePictureInPictureModeChange */, reason);
Winson Chung74666102017-02-22 17:49:24 -0800685
Winson Chung5af42fc2017-03-24 17:11:33 -0700686 if (schedulePictureInPictureModeChange) {
687 // Notify of picture-in-picture mode changes
688 supervisor.scheduleUpdatePictureInPictureModeIfNeeded(this, sourceStack);
689 }
Winson Chung74666102017-02-22 17:49:24 -0800690
691 // TODO: Ensure that this is actually necessary here
692 // Notify the voice session if required
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800693 if (voiceSession != null) {
694 try {
695 voiceSession.taskStarted(intent, taskId);
696 } catch (RemoteException e) {
697 }
698 }
Winson Chung74666102017-02-22 17:49:24 -0800699
700 // If the task had focus before (or we're requested to move focus), move focus to the
701 // new stack by moving the stack to the front.
Winson Chung95f8f0e2017-03-24 09:20:17 -0700702 if (r != null) {
703 toStack.moveToFrontAndResumeStateIfNeeded(r, moveStackToFront, wasResumed,
704 wasPaused, reason);
705 }
Winson Chung74666102017-02-22 17:49:24 -0800706 if (!animate) {
Jorim Jaggifa9ed962018-01-25 00:16:49 +0100707 mService.mStackSupervisor.mNoAnimActivities.add(topActivity);
Winson Chung74666102017-02-22 17:49:24 -0800708 }
709
710 // We might trigger a configuration change. Save the current task bounds for freezing.
711 // TODO: Should this call be moved inside the resize method in WM?
712 toStack.prepareFreezingTaskBounds();
713
714 // Make sure the task has the appropriate bounds/size for the stack it is in.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700715 final boolean toStackSplitScreenPrimary =
716 toStackWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Bryce Leef3c6a472017-11-14 14:53:06 -0800717 final Rect configBounds = getOverrideBounds();
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700718 if ((toStackWindowingMode == WINDOWING_MODE_FULLSCREEN
719 || toStackWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY)
Bryce Leef3c6a472017-11-14 14:53:06 -0800720 && !Objects.equals(configBounds, toStack.getOverrideBounds())) {
721 kept = resize(toStack.getOverrideBounds(), RESIZE_MODE_SYSTEM, !mightReplaceWindow,
Winson Chung74666102017-02-22 17:49:24 -0800722 deferResume);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700723 } else if (toStackWindowingMode == WINDOWING_MODE_FREEFORM) {
Winson Chung74666102017-02-22 17:49:24 -0800724 Rect bounds = getLaunchBounds();
725 if (bounds == null) {
Bryce Leeec55eb02017-12-05 20:51:27 -0800726 mService.mStackSupervisor.getLaunchParamsController().layoutTask(this, null);
Bryce Leef3c6a472017-11-14 14:53:06 -0800727 bounds = configBounds;
Winson Chung74666102017-02-22 17:49:24 -0800728 }
729 kept = resize(bounds, RESIZE_MODE_FORCED, !mightReplaceWindow, deferResume);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700730 } else if (toStackSplitScreenPrimary || toStackWindowingMode == WINDOWING_MODE_PINNED) {
731 if (toStackSplitScreenPrimary && moveStackMode == REPARENT_KEEP_STACK_AT_FRONT) {
Matthew Ng330757d2017-02-28 14:19:17 -0800732 // Move recents to front so it is not behind home stack when going into docked
733 // mode
734 mService.mStackSupervisor.moveRecentsStackToFront(reason);
735 }
Bryce Leef3c6a472017-11-14 14:53:06 -0800736 kept = resize(toStack.getOverrideBounds(), RESIZE_MODE_SYSTEM, !mightReplaceWindow,
Winson Chung74666102017-02-22 17:49:24 -0800737 deferResume);
738 }
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800739 } finally {
Winson Chung74666102017-02-22 17:49:24 -0800740 windowManager.continueSurfaceLayout();
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800741 }
Winson Chung74666102017-02-22 17:49:24 -0800742
743 if (mightReplaceWindow) {
744 // If we didn't actual do a relaunch (indicated by kept==true meaning we kept the old
745 // window), we need to clear the replace window settings. Otherwise, we schedule a
746 // timeout to remove the old window if the replacing window is not coming in time.
747 windowManager.scheduleClearWillReplaceWindows(topActivity.appToken, !kept);
748 }
749
750 if (!deferResume) {
751 // The task might have already been running and its visibility needs to be synchronized
752 // with the visibility of the stack / windows.
753 supervisor.ensureActivitiesVisibleLocked(null, 0, !mightReplaceWindow);
Andrii Kulianab132ee2018-07-24 22:10:21 +0800754 supervisor.resumeFocusedStacksTopActivitiesLocked();
Winson Chung74666102017-02-22 17:49:24 -0800755 }
756
Andrii Kulian036e3ad2017-04-19 10:55:10 -0700757 // TODO: Handle incorrect request to move before the actual move, not after.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700758 supervisor.handleNonResizableTaskIfNeeded(this, preferredStack.getWindowingMode(),
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -0700759 DEFAULT_DISPLAY, toStack);
Winson Chung74666102017-02-22 17:49:24 -0800760
Winson Chungdff7a732017-12-11 12:17:06 -0800761 return (preferredStack == toStack);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800762 }
763
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700764 /**
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800765 * @return True if the windows of tasks being moved to the target stack from the source stack
766 * should be replaced, meaning that window manager will keep the old window around until the new
767 * is ready.
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700768 */
769 private static boolean replaceWindowsOnTaskMove(
770 int sourceWindowingMode, int targetWindowingMode) {
771 return sourceWindowingMode == WINDOWING_MODE_FREEFORM
772 || targetWindowingMode == WINDOWING_MODE_FREEFORM;
773 }
774
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800775 void cancelWindowTransition() {
776 mWindowContainerController.cancelWindowTransition();
777 }
778
Jorim Jaggi7361bab2017-01-16 17:17:58 +0100779 /**
780 * DO NOT HOLD THE ACTIVITY MANAGER LOCK WHEN CALLING THIS METHOD!
781 */
Jorim Jaggi35e3f532017-03-17 17:06:50 +0100782 TaskSnapshot getSnapshot(boolean reducedResolution) {
Jorim Jaggi7361bab2017-01-16 17:17:58 +0100783
784 // TODO: Move this to {@link TaskWindowContainerController} once recent tasks are more
785 // synchronized between AM and WM.
Jorim Jaggi35e3f532017-03-17 17:06:50 +0100786 return mService.mWindowManager.getTaskSnapshot(taskId, userId, reducedResolution);
Jorim Jaggi02886a82016-12-06 09:10:06 -0800787 }
788
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800789 void touchActiveTime() {
Winson Chungfb44d212017-10-04 11:39:10 -0700790 lastActiveTime = SystemClock.elapsedRealtime();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800791 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700792
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800793 long getInactiveDuration() {
Winson Chungfb44d212017-10-04 11:39:10 -0700794 return SystemClock.elapsedRealtime() - lastActiveTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800795 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700796
Winson Chungfee26772014-08-05 12:21:52 -0700797 /** Sets the original intent, and the calling uid and package. */
798 void setIntent(ActivityRecord r) {
Winson Chungfee26772014-08-05 12:21:52 -0700799 mCallingUid = r.launchedFromUid;
800 mCallingPackage = r.launchedFromPackage;
Craig Mautner15df08a2015-04-01 12:17:18 -0700801 setIntent(r.intent, r.info);
Charles He2bf28322017-10-12 22:24:49 +0100802 setLockTaskAuth(r);
Winson Chungfee26772014-08-05 12:21:52 -0700803 }
804
805 /** Sets the original intent, _without_ updating the calling uid or package. */
806 private void setIntent(Intent _intent, ActivityInfo info) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700807 if (intent == null) {
808 mNeverRelinquishIdentity =
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700809 (info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700810 } else if (mNeverRelinquishIdentity) {
811 return;
812 }
813
814 affinity = info.taskAffinity;
Dianne Hackborn79228822014-09-16 11:11:23 -0700815 if (intent == null) {
816 // If this task already has an intent associated with it, don't set the root
817 // affinity -- we don't want it changing after initially set, but the initially
818 // set value may be null.
819 rootAffinity = affinity;
820 }
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700821 effectiveUid = info.applicationInfo.uid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700822 stringName = null;
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800823
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800824 if (info.targetActivity == null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800825 if (_intent != null) {
826 // If this Intent has a selector, we want to clear it for the
827 // recent task since it is not relevant if the user later wants
828 // to re-launch the app.
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700829 if (_intent.getSelector() != null || _intent.getSourceBounds() != null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800830 _intent = new Intent(_intent);
831 _intent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700832 _intent.setSourceBounds(null);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800833 }
834 }
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700835 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Setting Intent of " + this + " to " + _intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800836 intent = _intent;
837 realActivity = _intent != null ? _intent.getComponent() : null;
838 origActivity = null;
839 } else {
840 ComponentName targetComponent = new ComponentName(
841 info.packageName, info.targetActivity);
842 if (_intent != null) {
843 Intent targetIntent = new Intent(_intent);
844 targetIntent.setComponent(targetComponent);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800845 targetIntent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700846 targetIntent.setSourceBounds(null);
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700847 if (DEBUG_TASKS) Slog.v(TAG_TASKS,
Dianne Hackborn7f96b792012-05-29 18:46:45 -0700848 "Setting Intent of " + this + " to target " + targetIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800849 intent = targetIntent;
850 realActivity = targetComponent;
851 origActivity = _intent.getComponent();
852 } else {
853 intent = null;
854 realActivity = targetComponent;
855 origActivity = new ComponentName(info.packageName, info.name);
856 }
857 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700858
Craig Mautner47b20ba2014-09-17 17:23:44 -0700859 final int intentFlags = intent == null ? 0 : intent.getFlags();
860 if ((intentFlags & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800861 // Once we are set to an Intent with this flag, we count this
862 // task as having a true root activity.
863 rootWasReset = true;
864 }
Dianne Hackborn09233282014-04-30 11:33:59 -0700865 userId = UserHandle.getUserId(info.applicationInfo.uid);
Winson Chung36f3f032016-09-08 23:29:43 +0000866 mUserSetupComplete = Settings.Secure.getIntForUser(mService.mContext.getContentResolver(),
867 USER_SETUP_COMPLETE, 0, userId) != 0;
Craig Mautner41db4a72014-05-07 17:20:56 -0700868 if ((info.flags & ActivityInfo.FLAG_AUTO_REMOVE_FROM_RECENTS) != 0) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700869 // If the activity itself has requested auto-remove, then just always do it.
870 autoRemoveRecents = true;
Wale Ogunwale843bfb92015-03-27 11:06:48 -0700871 } else if ((intentFlags & (FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS))
872 == FLAG_ACTIVITY_NEW_DOCUMENT) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700873 // If the caller has not asked for the document to be retained, then we may
874 // want to turn on auto-remove, depending on whether the target has set its
875 // own document launch mode.
876 if (info.documentLaunchMode != ActivityInfo.DOCUMENT_LAUNCH_NONE) {
877 autoRemoveRecents = false;
878 } else {
879 autoRemoveRecents = true;
880 }
881 } else {
882 autoRemoveRecents = false;
Craig Mautner41db4a72014-05-07 17:20:56 -0700883 }
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800884 mResizeMode = info.resizeMode;
Winson Chungd3395382016-12-13 11:49:09 -0800885 mSupportsPictureInPicture = info.supportsPictureInPicture();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800886 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800887
Andrii Kulian2e751b82016-03-16 16:59:32 -0700888 /** Sets the original minimal width and height. */
889 private void setMinDimensions(ActivityInfo info) {
890 if (info != null && info.windowLayout != null) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700891 mMinWidth = info.windowLayout.minWidth;
892 mMinHeight = info.windowLayout.minHeight;
Andrii Kulian2e751b82016-03-16 16:59:32 -0700893 } else {
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700894 mMinWidth = INVALID_MIN_SIZE;
895 mMinHeight = INVALID_MIN_SIZE;
Andrii Kulian2e751b82016-03-16 16:59:32 -0700896 }
897 }
898
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800899 /**
Andrii Kulian206b9fa2016-06-02 13:18:01 -0700900 * Return true if the input activity has the same intent filter as the intent this task
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800901 * record is based on (normally the root activity intent).
902 */
Andrii Kulian206b9fa2016-06-02 13:18:01 -0700903 boolean isSameIntentFilter(ActivityRecord r) {
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800904 final Intent intent = new Intent(r.intent);
905 // Correct the activity intent for aliasing. The task record intent will always be based on
906 // the real activity that will be launched not the alias, so we need to use an intent with
907 // the component name pointing to the real activity not the alias in the activity record.
908 intent.setComponent(r.realActivity);
Bryce Lee1a990e52018-04-23 10:54:11 -0700909 return intent.filterEquals(this.intent);
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800910 }
911
Wale Ogunwale66e16852017-10-19 13:35:52 -0700912 boolean returnsToHomeStack() {
913 final int returnHomeFlags = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME;
Bryce Lee1a990e52018-04-23 10:54:11 -0700914 return intent != null && (intent.getFlags() & returnHomeFlags) == returnHomeFlags;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700915 }
916
Craig Mautnera228ae92014-07-09 05:44:55 -0700917 void setPrevAffiliate(TaskRecord prevAffiliate) {
918 mPrevAffiliate = prevAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800919 mPrevAffiliateTaskId = prevAffiliate == null ? INVALID_TASK_ID : prevAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700920 }
921
922 void setNextAffiliate(TaskRecord nextAffiliate) {
923 mNextAffiliate = nextAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800924 mNextAffiliateTaskId = nextAffiliate == null ? INVALID_TASK_ID : nextAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700925 }
926
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700927 <T extends ActivityStack> T getStack() {
928 return (T) mStack;
Andrii Kulian02b7a832016-10-06 23:11:56 -0700929 }
930
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800931 /**
932 * Must be used for setting parent stack because it performs configuration updates.
933 * Must be called after adding task as a child to the stack.
934 */
Andrii Kulian02b7a832016-10-06 23:11:56 -0700935 void setStack(ActivityStack stack) {
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800936 if (stack != null && !stack.isInStackLocked(this)) {
937 throw new IllegalStateException("Task must be added as a Stack child first.");
938 }
Bryce Lee84730a02018-04-03 14:10:04 -0700939 final ActivityStack oldStack = mStack;
Andrii Kulian02b7a832016-10-06 23:11:56 -0700940 mStack = stack;
Bryce Lee84730a02018-04-03 14:10:04 -0700941
942 // If the new {@link TaskRecord} is from a different {@link ActivityStack}, remove this
943 // {@link ActivityRecord} from its current {@link ActivityStack}.
944
945 if (oldStack != mStack) {
946 for (int i = getChildCount() - 1; i >= 0; --i) {
947 final ActivityRecord activity = getChildAt(i);
948
949 if (oldStack != null) {
950 oldStack.onActivityRemovedFromStack(activity);
951 }
952
953 if (mStack != null) {
954 stack.onActivityAddedToStack(activity);
955 }
956 }
957 }
958
Andrii Kulian1779e612016-10-12 21:58:25 -0700959 onParentChanged();
Andrii Kulian02b7a832016-10-06 23:11:56 -0700960 }
961
962 /**
963 * @return Id of current stack, {@link INVALID_STACK_ID} if no stack is set.
964 */
965 int getStackId() {
966 return mStack != null ? mStack.mStackId : INVALID_STACK_ID;
967 }
968
Andrii Kulian1779e612016-10-12 21:58:25 -0700969 @Override
970 protected int getChildCount() {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700971 return mActivities.size();
Andrii Kulian1779e612016-10-12 21:58:25 -0700972 }
973
974 @Override
chaviw82a0ba82018-03-15 14:26:29 -0700975 protected ActivityRecord getChildAt(int index) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700976 return mActivities.get(index);
Andrii Kulian1779e612016-10-12 21:58:25 -0700977 }
978
979 @Override
980 protected ConfigurationContainer getParent() {
981 return mStack;
982 }
983
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800984 @Override
Wale Ogunwale98d62312017-07-12 09:24:56 -0700985 protected void onParentChanged() {
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800986 super.onParentChanged();
987 mService.mStackSupervisor.updateUIDsPresentOnDisplay();
988 }
989
Craig Mautnera228ae92014-07-09 05:44:55 -0700990 // Close up recents linked list.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700991 private void closeRecentsChain() {
Craig Mautnera228ae92014-07-09 05:44:55 -0700992 if (mPrevAffiliate != null) {
993 mPrevAffiliate.setNextAffiliate(mNextAffiliate);
994 }
995 if (mNextAffiliate != null) {
996 mNextAffiliate.setPrevAffiliate(mPrevAffiliate);
997 }
998 setPrevAffiliate(null);
999 setNextAffiliate(null);
1000 }
1001
Winson Chung740c3ac2014-11-12 16:14:38 -08001002 void removedFromRecents() {
Dianne Hackborn852975d2014-08-22 17:42:43 -07001003 closeRecentsChain();
1004 if (inRecents) {
1005 inRecents = false;
Winson Chung740c3ac2014-11-12 16:14:38 -08001006 mService.notifyTaskPersisterLocked(this, false);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001007 }
Jorim Jaggif9084ec2017-01-16 13:16:59 +01001008
Dianne Hackborn68a06332017-11-15 17:54:18 -08001009 clearRootProcess();
1010
Jorim Jaggif9084ec2017-01-16 13:16:59 +01001011 // TODO: Use window container controller once tasks are better synced between AM and WM
1012 mService.mWindowManager.notifyTaskRemovedFromRecents(taskId, userId);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001013 }
1014
Craig Mautnera228ae92014-07-09 05:44:55 -07001015 void setTaskToAffiliateWith(TaskRecord taskToAffiliateWith) {
1016 closeRecentsChain();
1017 mAffiliatedTaskId = taskToAffiliateWith.mAffiliatedTaskId;
Winson Chungec396d62014-08-06 17:08:00 -07001018 mAffiliatedTaskColor = taskToAffiliateWith.mAffiliatedTaskColor;
Craig Mautnera228ae92014-07-09 05:44:55 -07001019 // Find the end
1020 while (taskToAffiliateWith.mNextAffiliate != null) {
1021 final TaskRecord nextRecents = taskToAffiliateWith.mNextAffiliate;
1022 if (nextRecents.mAffiliatedTaskId != mAffiliatedTaskId) {
1023 Slog.e(TAG, "setTaskToAffiliateWith: nextRecents=" + nextRecents + " affilTaskId="
1024 + nextRecents.mAffiliatedTaskId + " should be " + mAffiliatedTaskId);
1025 if (nextRecents.mPrevAffiliate == taskToAffiliateWith) {
1026 nextRecents.setPrevAffiliate(null);
1027 }
1028 taskToAffiliateWith.setNextAffiliate(null);
1029 break;
1030 }
1031 taskToAffiliateWith = nextRecents;
1032 }
1033 taskToAffiliateWith.setNextAffiliate(this);
1034 setPrevAffiliate(taskToAffiliateWith);
1035 setNextAffiliate(null);
1036 }
1037
Winson Chung1147c402014-05-14 11:05:00 -07001038 /** Returns the intent for the root activity for this task */
1039 Intent getBaseIntent() {
1040 return intent != null ? intent : affinityIntent;
1041 }
1042
Winson Chung3b3f4642014-04-22 10:08:18 -07001043 /** Returns the first non-finishing activity from the root. */
1044 ActivityRecord getRootActivity() {
1045 for (int i = 0; i < mActivities.size(); i++) {
1046 final ActivityRecord r = mActivities.get(i);
1047 if (r.finishing) {
1048 continue;
1049 }
1050 return r;
1051 }
1052 return null;
1053 }
1054
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001055 ActivityRecord getTopActivity() {
Bryce Lee9f6affd2017-09-01 09:18:35 -07001056 return getTopActivity(true /* includeOverlays */);
1057 }
1058
1059 ActivityRecord getTopActivity(boolean includeOverlays) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001060 for (int i = mActivities.size() - 1; i >= 0; --i) {
1061 final ActivityRecord r = mActivities.get(i);
Bryce Lee9f6affd2017-09-01 09:18:35 -07001062 if (r.finishing || (!includeOverlays && r.mTaskOverlay)) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001063 continue;
1064 }
1065 return r;
1066 }
1067 return null;
1068 }
1069
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -07001070 ActivityRecord topRunningActivityLocked() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001071 if (mStack != null) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07001072 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1073 ActivityRecord r = mActivities.get(activityNdx);
Chong Zhang87761972016-08-22 13:53:24 -07001074 if (!r.finishing && r.okToShowLocked()) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07001075 return r;
1076 }
Craig Mautner6b74cb52013-09-27 17:02:21 -07001077 }
1078 }
1079 return null;
1080 }
1081
Jorim Jaggi172e99f2017-10-20 14:33:18 +02001082 boolean isVisible() {
1083 for (int i = mActivities.size() - 1; i >= 0; --i) {
1084 final ActivityRecord r = mActivities.get(i);
1085 if (r.visible) {
1086 return true;
1087 }
1088 }
1089 return false;
1090 }
1091
Jorim Jaggiea039a82017-08-02 14:37:49 +02001092 void getAllRunningVisibleActivitiesLocked(ArrayList<ActivityRecord> outActivities) {
1093 if (mStack != null) {
1094 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1095 ActivityRecord r = mActivities.get(activityNdx);
Jorim Jaggi02f1d2f2017-08-04 14:29:16 +02001096 if (!r.finishing && r.okToShowLocked() && r.visibleIgnoringKeyguard) {
Jorim Jaggiea039a82017-08-02 14:37:49 +02001097 outActivities.add(r);
1098 }
1099 }
1100 }
1101 }
1102
Wale Ogunwale3b232392016-05-13 15:37:13 -07001103 ActivityRecord topRunningActivityWithStartingWindowLocked() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001104 if (mStack != null) {
Wale Ogunwale3b232392016-05-13 15:37:13 -07001105 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1106 ActivityRecord r = mActivities.get(activityNdx);
1107 if (r.mStartingWindowState != STARTING_WINDOW_SHOWN
Chong Zhang87761972016-08-22 13:53:24 -07001108 || r.finishing || !r.okToShowLocked()) {
Wale Ogunwale3b232392016-05-13 15:37:13 -07001109 continue;
1110 }
1111 return r;
1112 }
1113 }
1114 return null;
1115 }
1116
Winson Chung61c9e5a2017-10-11 10:39:32 -07001117 /**
1118 * Return the number of running activities, and the number of non-finishing/initializing
1119 * activities in the provided {@param reportOut} respectively.
1120 */
1121 void getNumRunningActivities(TaskActivitiesReport reportOut) {
1122 reportOut.reset();
1123 for (int i = mActivities.size() - 1; i >= 0; --i) {
1124 final ActivityRecord r = mActivities.get(i);
1125 if (r.finishing) {
1126 continue;
1127 }
1128
1129 reportOut.base = r;
1130
1131 // Increment the total number of non-finishing activities
1132 reportOut.numActivities++;
1133
Bryce Lee7ace3952018-02-16 14:34:32 -08001134 if (reportOut.top == null || (reportOut.top.isState(ActivityState.INITIALIZING))) {
Winson Chung61c9e5a2017-10-11 10:39:32 -07001135 reportOut.top = r;
1136 // Reset the number of running activities until we hit the first non-initializing
1137 // activity
1138 reportOut.numRunning = 0;
1139 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001140 if (r.attachedToProcess()) {
Winson Chung61c9e5a2017-10-11 10:39:32 -07001141 // Increment the number of actually running activities
1142 reportOut.numRunning++;
1143 }
1144 }
1145 }
1146
Chong Zhang87761972016-08-22 13:53:24 -07001147 boolean okToShowLocked() {
1148 // NOTE: If {@link TaskRecord#topRunningActivityLocked} return is not null then it is
1149 // okay to show the activity when locked.
1150 return mService.mStackSupervisor.isCurrentProfileLocked(userId)
1151 || topRunningActivityLocked() != null;
1152 }
1153
Craig Mautner3b475fe2013-12-16 15:58:31 -08001154 /** Call after activity movement or finish to make sure that frontOfTask is set correctly */
Bryce Leed71317c2017-02-07 14:27:22 -08001155 final void setFrontOfTask() {
1156 boolean foundFront = false;
Craig Mautner3b475fe2013-12-16 15:58:31 -08001157 final int numActivities = mActivities.size();
Craig Mautner704e40b2013-12-18 16:43:51 -08001158 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
Craig Mautner3b475fe2013-12-16 15:58:31 -08001159 final ActivityRecord r = mActivities.get(activityNdx);
1160 if (foundFront || r.finishing) {
1161 r.frontOfTask = false;
1162 } else {
1163 r.frontOfTask = true;
1164 // Set frontOfTask false for every following activity.
1165 foundFront = true;
1166 }
1167 }
Craig Mautner9587ee02014-06-23 15:00:10 +00001168 if (!foundFront && numActivities > 0) {
1169 // All activities of this task are finishing. As we ought to have a frontOfTask
1170 // activity, make the bottom activity front.
1171 mActivities.get(0).frontOfTask = true;
1172 }
Craig Mautner3b475fe2013-12-16 15:58:31 -08001173 }
1174
Craig Mautnerde4ef022013-04-07 19:01:33 -07001175 /**
Craig Mautner3b475fe2013-12-16 15:58:31 -08001176 * Reorder the history stack so that the passed activity is brought to the front.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001177 */
1178 final void moveActivityToFrontLocked(ActivityRecord newTop) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07001179 if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE,
1180 "Removing and adding activity " + newTop
1181 + " to stack at top callers=" + Debug.getCallers(4));
Craig Mautnerde4ef022013-04-07 19:01:33 -07001182
Craig Mautnerde4ef022013-04-07 19:01:33 -07001183 mActivities.remove(newTop);
1184 mActivities.add(newTop);
Bryce Leed58d7b32017-09-08 15:55:22 -07001185
1186 // Make sure window manager is aware of the position change.
1187 mWindowContainerController.positionChildAtTop(newTop.mWindowContainerController);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001188 updateEffectiveIntent();
Craig Mautner3b475fe2013-12-16 15:58:31 -08001189
Bryce Leed71317c2017-02-07 14:27:22 -08001190 setFrontOfTask();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001191 }
1192
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001193 void addActivityAtBottom(ActivityRecord r) {
Craig Mautner77878772013-03-04 19:46:24 -08001194 addActivityAtIndex(0, r);
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001195 }
1196
1197 void addActivityToTop(ActivityRecord r) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001198 addActivityAtIndex(mActivities.size(), r);
1199 }
1200
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001201 @Override
Wale Ogunwaleeea34ee92017-08-31 20:07:45 -07001202 /*@WindowConfiguration.ActivityType*/
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001203 public int getActivityType() {
1204 final int applicationType = super.getActivityType();
1205 if (applicationType != ACTIVITY_TYPE_UNDEFINED || mActivities.isEmpty()) {
1206 return applicationType;
1207 }
1208 return mActivities.get(0).getActivityType();
1209 }
1210
Winson Chung30480042017-01-26 10:55:34 -08001211 /**
1212 * Adds an activity {@param r} at the given {@param index}. The activity {@param r} must either
1213 * be in the current task or unparented to any task.
1214 */
Craig Mautner1602ec22013-05-12 10:24:27 -07001215 void addActivityAtIndex(int index, ActivityRecord r) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001216 TaskRecord task = r.getTask();
1217 if (task != null && task != this) {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001218 throw new IllegalArgumentException("Can not add r=" + " to task=" + this
Bryce Leeaf691c02017-03-20 14:20:22 -07001219 + " current parent=" + task);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001220 }
Bryce Leeaf691c02017-03-20 14:20:22 -07001221
1222 r.setTask(this);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001223
Craig Mautner6170f732013-04-02 13:05:23 -07001224 // Remove r first, and if it wasn't already in the list and it's fullscreen, count it.
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001225 if (!mActivities.remove(r) && r.fullscreen) {
1226 // Was not previously in list.
1227 numFullscreen++;
1228 }
Craig Mautner2c1faed2013-07-23 12:56:02 -07001229 // Only set this based on the first activity
1230 if (mActivities.isEmpty()) {
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001231 if (r.getActivityType() == ACTIVITY_TYPE_UNDEFINED) {
1232 // Normally non-standard activity type for the activity record will be set when the
1233 // object is created, however we delay setting the standard application type until
1234 // this point so that the task can set the type for additional activities added in
1235 // the else condition below.
1236 r.setActivityType(ACTIVITY_TYPE_STANDARD);
1237 }
1238 setActivityType(r.getActivityType());
Craig Mautner21d24a22014-04-23 11:45:37 -07001239 isPersistable = r.isPersistable();
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001240 mCallingUid = r.launchedFromUid;
1241 mCallingPackage = r.launchedFromPackage;
Dianne Hackborn852975d2014-08-22 17:42:43 -07001242 // Clamp to [1, max].
1243 maxRecents = Math.min(Math.max(r.info.maxRecents, 1),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001244 ActivityTaskManager.getMaxAppRecentsLimitStatic());
Craig Mautner2c1faed2013-07-23 12:56:02 -07001245 } else {
1246 // Otherwise make all added activities match this one.
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001247 r.setActivityType(getActivityType());
Craig Mautner78733002013-06-10 13:54:49 -07001248 }
Wale Ogunwale3b232392016-05-13 15:37:13 -07001249
1250 final int size = mActivities.size();
1251
1252 if (index == size && size > 0) {
1253 final ActivityRecord top = mActivities.get(size - 1);
1254 if (top.mTaskOverlay) {
1255 // Place below the task overlay activity since the overlay activity should always
1256 // be on top.
1257 index--;
1258 }
1259 }
1260
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001261 index = Math.min(size, index);
Craig Mautner77878772013-03-04 19:46:24 -08001262 mActivities.add(index, r);
Bryce Lee84730a02018-04-03 14:10:04 -07001263
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001264 updateEffectiveIntent();
Craig Mautner21d24a22014-04-23 11:45:37 -07001265 if (r.isPersistable()) {
1266 mService.notifyTaskPersisterLocked(this, false);
1267 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001268
1269 // Sync. with window manager
1270 updateOverrideConfigurationFromLaunchBounds();
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001271 final AppWindowContainerController appController = r.getWindowContainerController();
1272 if (appController != null) {
1273 // Only attempt to move in WM if the child has a controller. It is possible we haven't
1274 // created controller for the activity we are starting yet.
1275 mWindowContainerController.positionChildAt(appController, index);
1276 }
David Stevens82ea6cb2017-03-03 16:18:50 -08001277
1278 // Make sure the list of display UID whitelists is updated
1279 // now that this record is in a new task.
1280 mService.mStackSupervisor.updateUIDsPresentOnDisplay();
Craig Mautner77878772013-03-04 19:46:24 -08001281 }
1282
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001283 /**
Bryce Leeaf691c02017-03-20 14:20:22 -07001284 * Removes the specified activity from this task.
1285 * @param r The {@link ActivityRecord} to remove.
1286 * @return true if this was the last activity in the task.
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001287 */
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001288 boolean removeActivity(ActivityRecord r) {
Bryce Lee84730a02018-04-03 14:10:04 -07001289 return removeActivity(r, false /* reparenting */);
Bryce Leeaf691c02017-03-20 14:20:22 -07001290 }
1291
1292 boolean removeActivity(ActivityRecord r, boolean reparenting) {
1293 if (r.getTask() != this) {
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001294 throw new IllegalArgumentException(
1295 "Activity=" + r + " does not belong to task=" + this);
1296 }
1297
Bryce Lee84730a02018-04-03 14:10:04 -07001298 r.setTask(null /* task */, reparenting /* reparenting */);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001299
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001300 if (mActivities.remove(r) && r.fullscreen) {
1301 // Was previously in list.
1302 numFullscreen--;
1303 }
Craig Mautner21d24a22014-04-23 11:45:37 -07001304 if (r.isPersistable()) {
1305 mService.notifyTaskPersisterLocked(this, false);
1306 }
Wale Ogunwale89182d52016-03-11 10:38:36 -08001307
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001308 if (inPinnedWindowingMode()) {
Wale Ogunwale89182d52016-03-11 10:38:36 -08001309 // We normally notify listeners of task stack changes on pause, however pinned stack
1310 // activities are normally in the paused state so no notification will be sent there
1311 // before the activity is removed. We send it here so instead.
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001312 mService.getTaskChangeNotificationController().notifyTaskStackChanged();
Wale Ogunwale89182d52016-03-11 10:38:36 -08001313 }
1314
Craig Mautner41326202014-06-20 14:38:21 -07001315 if (mActivities.isEmpty()) {
Craig Mautner5afcd4d2014-06-21 18:11:33 -07001316 return !mReuseTask;
Craig Mautner41326202014-06-20 14:38:21 -07001317 }
1318 updateEffectiveIntent();
1319 return false;
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001320 }
1321
Winson Chung6954fc92017-03-24 16:22:12 -07001322 /**
1323 * @return whether or not there are ONLY task overlay activities in the stack.
1324 * If {@param excludeFinishing} is set, then ignore finishing activities in the check.
1325 * If there are no task overlay activities, this call returns false.
1326 */
1327 boolean onlyHasTaskOverlayActivities(boolean excludeFinishing) {
1328 int count = 0;
1329 for (int i = mActivities.size() - 1; i >= 0; i--) {
1330 final ActivityRecord r = mActivities.get(i);
1331 if (excludeFinishing && r.finishing) {
1332 continue;
1333 }
1334 if (!r.mTaskOverlay) {
1335 return false;
1336 }
1337 count++;
1338 }
1339 return count > 0;
1340 }
1341
Craig Mautner41db4a72014-05-07 17:20:56 -07001342 boolean autoRemoveFromRecents() {
Dianne Hackbornd38aed82014-06-10 21:36:35 -07001343 // We will automatically remove the task either if it has explicitly asked for
1344 // this, or it is empty and has never contained an activity that got shown to
1345 // the user.
Dianne Hackborn13420f22014-07-18 15:43:56 -07001346 return autoRemoveRecents || (mActivities.isEmpty() && !hasBeenVisible);
Craig Mautner41db4a72014-05-07 17:20:56 -07001347 }
1348
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001349 /**
1350 * Completely remove all activities associated with an existing
1351 * task starting at a specified index.
1352 */
Winson Chung0ec2a352017-10-26 11:38:30 -07001353 final void performClearTaskAtIndexLocked(int activityNdx, boolean pauseImmediately,
1354 String reason) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001355 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001356 for ( ; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001357 final ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001358 if (r.finishing) {
1359 continue;
1360 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07001361 if (mStack == null) {
Craig Mautner21d24a22014-04-23 11:45:37 -07001362 // Task was restored from persistent storage.
1363 r.takeFromHistory();
1364 mActivities.remove(activityNdx);
1365 --activityNdx;
1366 --numActivities;
Winson Chung6954fc92017-03-24 16:22:12 -07001367 } else if (mStack.finishActivityLocked(r, Activity.RESULT_CANCELED, null,
Winson Chung0ec2a352017-10-26 11:38:30 -07001368 reason, false, pauseImmediately)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001369 --activityNdx;
1370 --numActivities;
1371 }
1372 }
1373 }
1374
1375 /**
1376 * Completely remove all activities associated with an existing task.
1377 */
Benjamin Franza83859f2017-07-03 16:34:14 +01001378 void performClearTaskLocked() {
Craig Mautner362449a2014-06-20 14:04:39 -07001379 mReuseTask = true;
Winson Chung0ec2a352017-10-26 11:38:30 -07001380 performClearTaskAtIndexLocked(0, !PAUSE_IMMEDIATELY, "clear-task-all");
Craig Mautner362449a2014-06-20 14:04:39 -07001381 mReuseTask = false;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001382 }
1383
Filip Gruszczynskibe9dabd2016-01-19 12:23:10 -08001384 ActivityRecord performClearTaskForReuseLocked(ActivityRecord newR, int launchFlags) {
1385 mReuseTask = true;
1386 final ActivityRecord result = performClearTaskLocked(newR, launchFlags);
1387 mReuseTask = false;
1388 return result;
1389 }
1390
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001391 /**
1392 * Perform clear operation as requested by
1393 * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the
1394 * stack to the given task, then look for
1395 * an instance of that activity in the stack and, if found, finish all
1396 * activities on top of it and return the instance.
1397 *
1398 * @param newR Description of the new activity being started.
1399 * @return Returns the old activity that should be continued to be used,
1400 * or null if none was found.
1401 */
1402 final ActivityRecord performClearTaskLocked(ActivityRecord newR, int launchFlags) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001403 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001404 for (int activityNdx = numActivities - 1; activityNdx >= 0; --activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001405 ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001406 if (r.finishing) {
1407 continue;
1408 }
1409 if (r.realActivity.equals(newR.realActivity)) {
1410 // Here it is! Now finish everything in front...
Craig Mautner1602ec22013-05-12 10:24:27 -07001411 final ActivityRecord ret = r;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001412
1413 for (++activityNdx; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001414 r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001415 if (r.finishing) {
1416 continue;
1417 }
1418 ActivityOptions opts = r.takeOptionsLocked();
1419 if (opts != null) {
1420 ret.updateOptionsLocked(opts);
1421 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07001422 if (mStack != null && mStack.finishActivityLocked(
Todd Kennedy539db512014-12-15 09:57:55 -08001423 r, Activity.RESULT_CANCELED, null, "clear-task-stack", false)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001424 --activityNdx;
1425 --numActivities;
1426 }
1427 }
1428
1429 // Finally, if this is a normal launch mode (that is, not
1430 // expecting onNewIntent()), then we will finish the current
1431 // instance of the activity so a new fresh one can be started.
1432 if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE
Daichi Hirono15a02992016-04-27 18:47:01 +09001433 && (launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0
1434 && !ActivityStarter.isDocumentLaunchesIntoExisting(launchFlags)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001435 if (!ret.finishing) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001436 if (mStack != null) {
1437 mStack.finishActivityLocked(
Wale Ogunwale7d701172015-03-11 15:36:30 -07001438 ret, Activity.RESULT_CANCELED, null, "clear-task-top", false);
1439 }
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001440 return null;
1441 }
1442 }
1443
1444 return ret;
1445 }
1446 }
1447
1448 return null;
1449 }
1450
Winson Chung0ec2a352017-10-26 11:38:30 -07001451 void removeTaskActivitiesLocked(boolean pauseImmediately, String reason) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001452 // Just remove the entire task.
Winson Chung0ec2a352017-10-26 11:38:30 -07001453 performClearTaskAtIndexLocked(0, pauseImmediately, reason);
Craig Mautner9db9a0b2013-04-29 17:05:56 -07001454 }
1455
Craig Mautner432f64e2015-05-20 14:59:57 -07001456 String lockTaskAuthToString() {
1457 switch (mLockTaskAuth) {
1458 case LOCK_TASK_AUTH_DONT_LOCK: return "LOCK_TASK_AUTH_DONT_LOCK";
1459 case LOCK_TASK_AUTH_PINNABLE: return "LOCK_TASK_AUTH_PINNABLE";
1460 case LOCK_TASK_AUTH_LAUNCHABLE: return "LOCK_TASK_AUTH_LAUNCHABLE";
1461 case LOCK_TASK_AUTH_WHITELISTED: return "LOCK_TASK_AUTH_WHITELISTED";
Benjamin Franz469dd582015-06-09 14:24:36 +01001462 case LOCK_TASK_AUTH_LAUNCHABLE_PRIV: return "LOCK_TASK_AUTH_LAUNCHABLE_PRIV";
Craig Mautner432f64e2015-05-20 14:59:57 -07001463 default: return "unknown=" + mLockTaskAuth;
1464 }
1465 }
1466
Craig Mautner15df08a2015-04-01 12:17:18 -07001467 void setLockTaskAuth() {
Charles He2bf28322017-10-12 22:24:49 +01001468 setLockTaskAuth(getRootActivity());
1469 }
1470
1471 private void setLockTaskAuth(@Nullable ActivityRecord r) {
1472 if (r == null) {
1473 mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE;
1474 return;
1475 }
1476
Charles He520b2832017-09-02 15:27:16 +01001477 final String pkg = (realActivity != null) ? realActivity.getPackageName() : null;
Bryce Lee2b8e0372018-04-05 17:01:37 -07001478 final LockTaskController lockTaskController = mService.getLockTaskController();
Charles He2bf28322017-10-12 22:24:49 +01001479 switch (r.lockTaskLaunchMode) {
Craig Mautner15df08a2015-04-01 12:17:18 -07001480 case LOCK_TASK_LAUNCH_MODE_DEFAULT:
Bryce Lee2b8e0372018-04-05 17:01:37 -07001481 mLockTaskAuth = lockTaskController.isPackageWhitelisted(userId, pkg)
Charles He520b2832017-09-02 15:27:16 +01001482 ? LOCK_TASK_AUTH_WHITELISTED : LOCK_TASK_AUTH_PINNABLE;
Craig Mautner15df08a2015-04-01 12:17:18 -07001483 break;
1484
1485 case LOCK_TASK_LAUNCH_MODE_NEVER:
Benjamin Franz469dd582015-06-09 14:24:36 +01001486 mLockTaskAuth = LOCK_TASK_AUTH_DONT_LOCK;
Craig Mautner15df08a2015-04-01 12:17:18 -07001487 break;
1488
1489 case LOCK_TASK_LAUNCH_MODE_ALWAYS:
Benjamin Franz469dd582015-06-09 14:24:36 +01001490 mLockTaskAuth = LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
Craig Mautner15df08a2015-04-01 12:17:18 -07001491 break;
1492
1493 case LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED:
Bryce Lee2b8e0372018-04-05 17:01:37 -07001494 mLockTaskAuth = lockTaskController.isPackageWhitelisted(userId, pkg)
Charles He520b2832017-09-02 15:27:16 +01001495 ? LOCK_TASK_AUTH_LAUNCHABLE : LOCK_TASK_AUTH_PINNABLE;
Craig Mautner15df08a2015-04-01 12:17:18 -07001496 break;
1497 }
Craig Mautner432f64e2015-05-20 14:59:57 -07001498 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
1499 " mLockTaskAuth=" + lockTaskAuthToString());
Craig Mautner15df08a2015-04-01 12:17:18 -07001500 }
1501
Winson Chungd3395382016-12-13 11:49:09 -08001502 private boolean isResizeable(boolean checkSupportsPip) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001503 return (mService.mForceResizableActivities || ActivityInfo.isResizeableMode(mResizeMode)
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -07001504 || (checkSupportsPip && mSupportsPictureInPicture));
Winson Chungd3395382016-12-13 11:49:09 -08001505 }
1506
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001507 boolean isResizeable() {
Winson Chungd3395382016-12-13 11:49:09 -08001508 return isResizeable(true /* checkSupportsPip */);
1509 }
1510
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001511 @Override
1512 public boolean supportsSplitScreenWindowingMode() {
Winson Chungd3395382016-12-13 11:49:09 -08001513 // A task can not be docked even if it is considered resizeable because it only supports
1514 // picture-in-picture mode but has a non-resizeable resizeMode
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001515 return super.supportsSplitScreenWindowingMode()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001516 && mService.mSupportsSplitScreenMultiWindow
1517 && (mService.mForceResizableActivities
Bryce Leec857a5b2017-08-16 10:04:52 -07001518 || (isResizeable(false /* checkSupportsPip */)
1519 && !ActivityInfo.isPreserveOrientationMode(mResizeMode)));
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001520 }
1521
skuhne@google.com322347b2016-12-02 12:54:03 -08001522 /**
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001523 * Check whether this task can be launched on the specified display.
1524 * @param displayId Target display id.
1525 * @return {@code true} if either it is the default display or this activity is resizeable and
1526 * can be put a secondary screen.
1527 */
1528 boolean canBeLaunchedOnDisplay(int displayId) {
1529 return mService.mStackSupervisor.canPlaceEntityOnDisplay(displayId,
Andrii Kulian02689a72017-07-06 14:28:59 -07001530 isResizeable(false /* checkSupportsPip */), -1 /* don't check PID */,
1531 -1 /* don't check UID */, null /* activityInfo */);
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001532 }
1533
1534 /**
skuhne@google.com322347b2016-12-02 12:54:03 -08001535 * Check that a given bounds matches the application requested orientation.
1536 *
1537 * @param bounds The bounds to be tested.
1538 * @return True if the requested bounds are okay for a resizing request.
1539 */
Wale Ogunwale069bbd32017-02-03 07:58:14 -08001540 private boolean canResizeToBounds(Rect bounds) {
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001541 if (bounds == null || !inFreeformWindowingMode()) {
skuhne@google.com322347b2016-12-02 12:54:03 -08001542 // Note: If not on the freeform workspace, we ignore the bounds.
1543 return true;
1544 }
1545 final boolean landscape = bounds.width() > bounds.height();
Bryce Leef3c6a472017-11-14 14:53:06 -08001546 final Rect configBounds = getOverrideBounds();
skuhne@google.com322347b2016-12-02 12:54:03 -08001547 if (mResizeMode == RESIZE_MODE_FORCE_RESIZABLE_PRESERVE_ORIENTATION) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001548 return configBounds.isEmpty()
1549 || landscape == (configBounds.width() > configBounds.height());
skuhne@google.com322347b2016-12-02 12:54:03 -08001550 }
1551 return (mResizeMode != RESIZE_MODE_FORCE_RESIZABLE_PORTRAIT_ONLY || !landscape)
1552 && (mResizeMode != RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY || landscape);
1553 }
1554
Craig Mautner525f3d92013-05-07 14:01:50 -07001555 /**
Yorke Leebdef5372017-04-10 16:38:51 -07001556 * @return {@code true} if the task is being cleared for the purposes of being reused.
1557 */
1558 boolean isClearingToReuseTask() {
1559 return mReuseTask;
1560 }
1561
1562 /**
Craig Mautner525f3d92013-05-07 14:01:50 -07001563 * Find the activity in the history stack within the given task. Returns
1564 * the index within the history at which it's found, or < 0 if not found.
1565 */
1566 final ActivityRecord findActivityInHistoryLocked(ActivityRecord r) {
1567 final ComponentName realActivity = r.realActivity;
1568 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1569 ActivityRecord candidate = mActivities.get(activityNdx);
1570 if (candidate.finishing) {
1571 continue;
1572 }
1573 if (candidate.realActivity.equals(realActivity)) {
1574 return candidate;
1575 }
1576 }
1577 return null;
1578 }
1579
Winson Chunga449dc02014-05-16 11:15:04 -07001580 /** Updates the last task description values. */
1581 void updateTaskDescription() {
1582 // Traverse upwards looking for any break between main task activities and
1583 // utility activities.
1584 int activityNdx;
1585 final int numActivities = mActivities.size();
Wale Ogunwale3eadad72016-10-13 09:16:59 -07001586 final boolean relinquish = numActivities != 0 &&
1587 (mActivities.get(0).info.flags & FLAG_RELINQUISH_TASK_IDENTITY) != 0;
Winson Chunga449dc02014-05-16 11:15:04 -07001588 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
Craig Mautner21d24a22014-04-23 11:45:37 -07001589 ++activityNdx) {
Winson Chunga449dc02014-05-16 11:15:04 -07001590 final ActivityRecord r = mActivities.get(activityNdx);
Wale Ogunwale3eadad72016-10-13 09:16:59 -07001591 if (relinquish && (r.info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001592 // This will be the top activity for determining taskDescription. Pre-inc to
1593 // overcome initial decrement below.
1594 ++activityNdx;
1595 break;
1596 }
Winson Chunga449dc02014-05-16 11:15:04 -07001597 if (r.intent != null &&
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001598 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
Winson Chunga449dc02014-05-16 11:15:04 -07001599 break;
1600 }
1601 }
1602 if (activityNdx > 0) {
1603 // Traverse downwards starting below break looking for set label, icon.
1604 // Note that if there are activities in the task but none of them set the
1605 // recent activity values, then we do not fall back to the last set
1606 // values in the TaskRecord.
1607 String label = null;
Craig Mautner648f69b2014-09-18 14:16:26 -07001608 String iconFilename = null;
Matthew Ng54bc9422017-10-02 17:16:28 -07001609 int iconResource = -1;
Winson Chunga449dc02014-05-16 11:15:04 -07001610 int colorPrimary = 0;
Winson Chung1af8eda2016-02-05 17:55:56 +00001611 int colorBackground = 0;
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001612 int statusBarColor = 0;
1613 int navigationBarColor = 0;
1614 boolean topActivity = true;
Winson Chunga449dc02014-05-16 11:15:04 -07001615 for (--activityNdx; activityNdx >= 0; --activityNdx) {
1616 final ActivityRecord r = mActivities.get(activityNdx);
Winson Chung80f80db2018-05-30 21:13:25 -07001617 if (r.mTaskOverlay) {
1618 continue;
1619 }
Winson Chunga449dc02014-05-16 11:15:04 -07001620 if (r.taskDescription != null) {
1621 if (label == null) {
1622 label = r.taskDescription.getLabel();
1623 }
Matthew Ng54bc9422017-10-02 17:16:28 -07001624 if (iconResource == -1) {
1625 iconResource = r.taskDescription.getIconResource();
1626 }
Craig Mautner648f69b2014-09-18 14:16:26 -07001627 if (iconFilename == null) {
1628 iconFilename = r.taskDescription.getIconFilename();
Winson Chunga449dc02014-05-16 11:15:04 -07001629 }
1630 if (colorPrimary == 0) {
1631 colorPrimary = r.taskDescription.getPrimaryColor();
Winson Chunga449dc02014-05-16 11:15:04 -07001632 }
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001633 if (topActivity) {
Winson Chung1af8eda2016-02-05 17:55:56 +00001634 colorBackground = r.taskDescription.getBackgroundColor();
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001635 statusBarColor = r.taskDescription.getStatusBarColor();
1636 navigationBarColor = r.taskDescription.getNavigationBarColor();
Winson Chung1af8eda2016-02-05 17:55:56 +00001637 }
Winson Chunga449dc02014-05-16 11:15:04 -07001638 }
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001639 topActivity = false;
Winson Chunga449dc02014-05-16 11:15:04 -07001640 }
Matthew Ng54bc9422017-10-02 17:16:28 -07001641 lastTaskDescription = new TaskDescription(label, null, iconResource, iconFilename,
1642 colorPrimary, colorBackground, statusBarColor, navigationBarColor);
Jorim Jaggi829b9cd2017-01-23 16:20:53 +01001643 if (mWindowContainerController != null) {
1644 mWindowContainerController.setTaskDescription(lastTaskDescription);
1645 }
Winson Chungec396d62014-08-06 17:08:00 -07001646 // Update the task affiliation color if we are the parent of the group
1647 if (taskId == mAffiliatedTaskId) {
1648 mAffiliatedTaskColor = lastTaskDescription.getPrimaryColor();
1649 }
Winson Chunga449dc02014-05-16 11:15:04 -07001650 }
1651 }
1652
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001653 int findEffectiveRootIndex() {
Craig Mautner4767f4b2014-09-18 15:38:33 -07001654 int effectiveNdx = 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001655 final int topActivityNdx = mActivities.size() - 1;
Dianne Hackborn39569af2014-09-23 10:56:58 -07001656 for (int activityNdx = 0; activityNdx <= topActivityNdx; ++activityNdx) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001657 final ActivityRecord r = mActivities.get(activityNdx);
1658 if (r.finishing) {
1659 continue;
1660 }
Craig Mautner4767f4b2014-09-18 15:38:33 -07001661 effectiveNdx = activityNdx;
Wale Ogunwale3eadad72016-10-13 09:16:59 -07001662 if ((r.info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001663 break;
1664 }
1665 }
Craig Mautner4767f4b2014-09-18 15:38:33 -07001666 return effectiveNdx;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001667 }
1668
1669 void updateEffectiveIntent() {
1670 final int effectiveRootIndex = findEffectiveRootIndex();
1671 final ActivityRecord r = mActivities.get(effectiveRootIndex);
Winson Chungfee26772014-08-05 12:21:52 -07001672 setIntent(r);
Winson Chung8d9009e2017-11-16 15:43:05 -08001673
1674 // Update the task description when the activities change
1675 updateTaskDescription();
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001676 }
1677
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001678 private void adjustForMinimalTaskDimensions(Rect bounds) {
1679 if (bounds == null) {
1680 return;
1681 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001682 int minWidth = mMinWidth;
1683 int minHeight = mMinHeight;
Robert Carr9c5867d2016-03-10 15:52:46 -08001684 // If the task has no requested minimal size, we'd like to enforce a minimal size
1685 // so that the user can not render the task too small to manipulate. We don't need
1686 // to do this for the pinned stack as the bounds are controlled by the system.
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001687 if (!inPinnedWindowingMode()) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001688 if (minWidth == INVALID_MIN_SIZE) {
1689 minWidth = mService.mStackSupervisor.mDefaultMinSizeOfResizeableTask;
Andrii Kulian2e751b82016-03-16 16:59:32 -07001690 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001691 if (minHeight == INVALID_MIN_SIZE) {
1692 minHeight = mService.mStackSupervisor.mDefaultMinSizeOfResizeableTask;
Andrii Kulian2e751b82016-03-16 16:59:32 -07001693 }
Robert Carr9c5867d2016-03-10 15:52:46 -08001694 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001695 final boolean adjustWidth = minWidth > bounds.width();
1696 final boolean adjustHeight = minHeight > bounds.height();
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001697 if (!(adjustWidth || adjustHeight)) {
1698 return;
1699 }
1700
Bryce Leef3c6a472017-11-14 14:53:06 -08001701 final Rect configBounds = getOverrideBounds();
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001702 if (adjustWidth) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001703 if (!configBounds.isEmpty() && bounds.right == configBounds.right) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001704 bounds.left = bounds.right - minWidth;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001705 } else {
1706 // Either left bounds match, or neither match, or the previous bounds were
1707 // fullscreen and we default to keeping left.
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001708 bounds.right = bounds.left + minWidth;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001709 }
1710 }
1711 if (adjustHeight) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001712 if (!configBounds.isEmpty() && bounds.bottom == configBounds.bottom) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001713 bounds.top = bounds.bottom - minHeight;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001714 } else {
1715 // Either top bounds match, or neither match, or the previous bounds were
1716 // fullscreen and we default to keeping top.
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001717 bounds.bottom = bounds.top + minHeight;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001718 }
1719 }
1720 }
1721
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001722 /**
Winson Chung5af42fc2017-03-24 17:11:33 -07001723 * @return a new Configuration for this Task, given the provided {@param bounds} and
1724 * {@param insetBounds}.
1725 */
1726 Configuration computeNewOverrideConfigurationForBounds(Rect bounds, Rect insetBounds) {
1727 // Compute a new override configuration for the given bounds, if fullscreen bounds
1728 // (bounds == null), then leave the override config unset
1729 final Configuration newOverrideConfig = new Configuration();
1730 if (bounds != null) {
1731 newOverrideConfig.setTo(getOverrideConfiguration());
1732 mTmpRect.set(bounds);
1733 adjustForMinimalTaskDimensions(mTmpRect);
1734 computeOverrideConfiguration(newOverrideConfig, mTmpRect, insetBounds,
1735 mTmpRect.right != bounds.right, mTmpRect.bottom != bounds.bottom);
1736 }
1737
1738 return newOverrideConfig;
1739 }
1740
1741 /**
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001742 * Update task's override configuration based on the bounds.
Jorim Jaggi0a932142016-02-01 17:42:25 -08001743 * @param bounds The bounds of the task.
Andrii Kulian8072d112016-09-16 11:11:01 -07001744 * @return True if the override configuration was updated.
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001745 */
Andrii Kulian8072d112016-09-16 11:11:01 -07001746 boolean updateOverrideConfiguration(Rect bounds) {
Jorim Jaggi0a932142016-02-01 17:42:25 -08001747 return updateOverrideConfiguration(bounds, null /* insetBounds */);
1748 }
1749
1750 /**
1751 * Update task's override configuration based on the bounds.
1752 * @param bounds The bounds of the task.
1753 * @param insetBounds The bounds used to calculate the system insets, which is used here to
1754 * subtract the navigation bar/status bar size from the screen size reported
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001755 * to the application. See {@link IActivityTaskManager#resizeDockedStack}.
Andrii Kulian8072d112016-09-16 11:11:01 -07001756 * @return True if the override configuration was updated.
Jorim Jaggi0a932142016-02-01 17:42:25 -08001757 */
Andrii Kulian8072d112016-09-16 11:11:01 -07001758 boolean updateOverrideConfiguration(Rect bounds, @Nullable Rect insetBounds) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001759 if (equivalentOverrideBounds(bounds)) {
Andrii Kulian8072d112016-09-16 11:11:01 -07001760 return false;
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001761 }
Bryce Leef3c6a472017-11-14 14:53:06 -08001762 final Rect currentBounds = getOverrideBounds();
1763
Andrii Kulian1779e612016-10-12 21:58:25 -07001764 mTmpConfig.setTo(getOverrideConfiguration());
Andrii Kulian1779e612016-10-12 21:58:25 -07001765 final Configuration newConfig = getOverrideConfiguration();
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001766
Bryce Leef3c6a472017-11-14 14:53:06 -08001767 final boolean matchParentBounds = bounds == null || bounds.isEmpty();
Wale Ogunwale3382ab12017-07-27 08:55:03 -07001768 final boolean persistBounds = getWindowConfiguration().persistTaskBounds();
Bryce Leef3c6a472017-11-14 14:53:06 -08001769 if (matchParentBounds) {
1770 if (!currentBounds.isEmpty() && persistBounds) {
1771 mLastNonFullscreenBounds = currentBounds;
Wale Ogunwale706ed792015-08-02 10:29:44 -07001772 }
Bryce Leef3c6a472017-11-14 14:53:06 -08001773 setBounds(null);
Andrii Kulian1779e612016-10-12 21:58:25 -07001774 newConfig.unset();
Wale Ogunwale706ed792015-08-02 10:29:44 -07001775 } else {
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001776 mTmpRect.set(bounds);
1777 adjustForMinimalTaskDimensions(mTmpRect);
Bryce Leef3c6a472017-11-14 14:53:06 -08001778 setBounds(mTmpRect);
1779
Wale Ogunwale3382ab12017-07-27 08:55:03 -07001780 if (mStack == null || persistBounds) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001781 mLastNonFullscreenBounds = getOverrideBounds();
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -07001782 }
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07001783 computeOverrideConfiguration(newConfig, mTmpRect, insetBounds,
Andrii Kuliandaea3572016-04-08 13:20:51 -07001784 mTmpRect.right != bounds.right, mTmpRect.bottom != bounds.bottom);
Wale Ogunwale706ed792015-08-02 10:29:44 -07001785 }
Andrii Kulian1779e612016-10-12 21:58:25 -07001786 onOverrideConfigurationChanged(newConfig);
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08001787 return !mTmpConfig.equals(newConfig);
1788 }
Wale Ogunwale5f986092015-12-04 15:35:38 -08001789
Bryce Leec4ab62a2018-03-05 14:19:26 -08001790 /**
1791 * This should be called when an child activity changes state. This should only
1792 * be called from
1793 * {@link ActivityRecord#setState(ActivityState, String)} .
1794 * @param record The {@link ActivityRecord} whose state has changed.
1795 * @param state The new state.
1796 * @param reason The reason for the change.
1797 */
1798 void onActivityStateChanged(ActivityRecord record, ActivityState state, String reason) {
1799 final ActivityStack parent = getStack();
1800
1801 if (parent != null) {
1802 parent.onActivityStateChanged(record, state, reason);
1803 }
1804 }
1805
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08001806 @Override
1807 public void onConfigurationChanged(Configuration newParentConfig) {
1808 final boolean wasInMultiWindowMode = inMultiWindowMode();
1809 super.onConfigurationChanged(newParentConfig);
1810 if (wasInMultiWindowMode != inMultiWindowMode()) {
Winson Chung5af42fc2017-03-24 17:11:33 -07001811 mService.mStackSupervisor.scheduleUpdateMultiWindowMode(this);
Wale Ogunwale5f986092015-12-04 15:35:38 -08001812 }
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08001813 // TODO: Should also take care of Pip mode changes here.
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001814 }
1815
Andrii Kulian1779e612016-10-12 21:58:25 -07001816 /** Clears passed config and fills it with new override values. */
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07001817 // TODO(b/36505427): TaskRecord.computeOverrideConfiguration() is a utility method that doesn't
1818 // depend on task or stacks, but uses those object to get the display to base the calculation
1819 // on. Probably best to centralize calculations like this in ConfigurationContainer.
1820 void computeOverrideConfiguration(Configuration config, Rect bounds, Rect insetBounds,
Andrii Kuliana8a9bc52016-10-14 11:00:13 -07001821 boolean overrideWidth, boolean overrideHeight) {
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001822 mTmpNonDecorBounds.set(bounds);
1823 mTmpStableBounds.set(bounds);
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001824
Andrii Kulian1779e612016-10-12 21:58:25 -07001825 config.unset();
Winson Chungbdc646f2017-02-13 12:12:22 -08001826 final Configuration parentConfig = getParent().getConfiguration();
Bryce Lee7566d762017-03-30 09:34:15 -07001827
Andrii Kulian1779e612016-10-12 21:58:25 -07001828 final float density = parentConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001829
Winson Chungbdc646f2017-02-13 12:12:22 -08001830 if (mStack != null) {
1831 final StackWindowController stackController = mStack.getWindowContainerController();
1832 stackController.adjustConfigurationForBounds(bounds, insetBounds,
1833 mTmpNonDecorBounds, mTmpStableBounds, overrideWidth, overrideHeight, density,
Evan Roskyb0e38882018-04-25 12:48:54 -07001834 config, parentConfig, getWindowingMode());
Winson Chungbdc646f2017-02-13 12:12:22 -08001835 } else {
Bryce Lee7566d762017-03-30 09:34:15 -07001836 throw new IllegalArgumentException("Expected stack when calculating override config");
Winson Chungbdc646f2017-02-13 12:12:22 -08001837 }
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001838
Winson Chung60c1aba2017-03-14 17:47:42 -07001839 config.orientation = (config.screenWidthDp <= config.screenHeightDp)
1840 ? Configuration.ORIENTATION_PORTRAIT
1841 : Configuration.ORIENTATION_LANDSCAPE;
1842
Jorim Jaggi85639432016-05-06 17:27:55 -07001843 // For calculating screen layout, we need to use the non-decor inset screen area for the
1844 // calculation for compatibility reasons, i.e. screen area without system bars that could
1845 // never go away in Honeycomb.
Winson Chungbdc646f2017-02-13 12:12:22 -08001846 final int compatScreenWidthDp = (int) (mTmpNonDecorBounds.width() / density);
1847 final int compatScreenHeightDp = (int) (mTmpNonDecorBounds.height() / density);
Andrii Kulian1779e612016-10-12 21:58:25 -07001848 // We're only overriding LONG, SIZE and COMPAT parts of screenLayout, so we start override
1849 // calculation with partial default.
Louis Chang8b580162018-06-26 17:58:29 +08001850 // Reducing the screen layout starting from its parent config.
1851 final int sl = parentConfig.screenLayout &
1852 (Configuration.SCREENLAYOUT_LONG_MASK | Configuration.SCREENLAYOUT_SIZE_MASK);
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001853 final int longSize = Math.max(compatScreenHeightDp, compatScreenWidthDp);
Andrii Kulian1779e612016-10-12 21:58:25 -07001854 final int shortSize = Math.min(compatScreenHeightDp, compatScreenWidthDp);
Jorim Jaggi85639432016-05-06 17:27:55 -07001855 config.screenLayout = Configuration.reduceScreenLayout(sl, longSize, shortSize);
Jorim Jaggia95ca8d2016-01-15 22:54:46 -08001856 }
1857
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08001858 Rect updateOverrideConfigurationFromLaunchBounds() {
Bryce Leef3c6a472017-11-14 14:53:06 -08001859 final Rect bounds = getLaunchBounds();
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08001860 updateOverrideConfiguration(bounds);
Bryce Leef3c6a472017-11-14 14:53:06 -08001861 if (bounds != null && !bounds.isEmpty()) {
1862 // TODO: Review if we actually want to do this - we are setting the launch bounds
1863 // directly here.
1864 bounds.set(getOverrideBounds());
Andrii Kulian73336d812016-03-24 12:56:08 -07001865 }
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08001866 return bounds;
1867 }
1868
Wale Ogunwale935e5022015-11-10 12:36:10 -08001869 /** Updates the task's bounds and override configuration to match what is expected for the
1870 * input stack. */
1871 void updateOverrideConfigurationForStack(ActivityStack inStack) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001872 if (mStack != null && mStack == inStack) {
Wale Ogunwale935e5022015-11-10 12:36:10 -08001873 return;
1874 }
1875
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001876 if (inStack.inFreeformWindowingMode()) {
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001877 if (!isResizeable()) {
Wale Ogunwale935e5022015-11-10 12:36:10 -08001878 throw new IllegalArgumentException("Can not position non-resizeable task="
1879 + this + " in stack=" + inStack);
1880 }
Bryce Leef3c6a472017-11-14 14:53:06 -08001881 if (!matchParentBounds()) {
Wale Ogunwale935e5022015-11-10 12:36:10 -08001882 return;
1883 }
1884 if (mLastNonFullscreenBounds != null) {
1885 updateOverrideConfiguration(mLastNonFullscreenBounds);
1886 } else {
Bryce Leeec55eb02017-12-05 20:51:27 -08001887 mService.mStackSupervisor.getLaunchParamsController().layoutTask(this, null);
Wale Ogunwale935e5022015-11-10 12:36:10 -08001888 }
1889 } else {
Bryce Leef3c6a472017-11-14 14:53:06 -08001890 updateOverrideConfiguration(inStack.getOverrideBounds());
Wale Ogunwale935e5022015-11-10 12:36:10 -08001891 }
1892 }
1893
Wale Ogunwale706ed792015-08-02 10:29:44 -07001894 /** Returns the bounds that should be used to launch this task. */
Wale Ogunwale30e441d2017-11-09 08:28:45 -08001895 Rect getLaunchBounds() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001896 if (mStack == null) {
Chong Zhang7d5f5102016-01-13 10:29:24 -08001897 return null;
1898 }
1899
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001900 final int windowingMode = getWindowingMode();
1901 if (!isActivityTypeStandardOrUndefined()
1902 || windowingMode == WINDOWING_MODE_FULLSCREEN
1903 || (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY && !isResizeable())) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001904 return isResizeable() ? mStack.getOverrideBounds() : null;
Wale Ogunwale3382ab12017-07-27 08:55:03 -07001905 } else if (!getWindowConfiguration().persistTaskBounds()) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001906 return mStack.getOverrideBounds();
Wale Ogunwale706ed792015-08-02 10:29:44 -07001907 }
1908 return mLastNonFullscreenBounds;
1909 }
1910
Jorim Jaggi8b702ed2017-01-20 16:59:03 +01001911 void addStartingWindowsForVisibleActivities(boolean taskSwitch) {
1912 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1913 final ActivityRecord r = mActivities.get(activityNdx);
1914 if (r.visible) {
1915 r.showStartingWindow(null /* prev */, false /* newTask */, taskSwitch);
1916 }
1917 }
1918 }
1919
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001920 void setRootProcess(WindowProcessController proc) {
Dianne Hackborn68a06332017-11-15 17:54:18 -08001921 clearRootProcess();
1922 if (intent != null &&
1923 (intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0) {
1924 mRootProcess = proc;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001925 mRootProcess.addRecentTask(this);
Dianne Hackborn68a06332017-11-15 17:54:18 -08001926 }
1927 }
1928
1929 void clearRootProcess() {
1930 if (mRootProcess != null) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001931 mRootProcess.removeRecentTask(this);
Dianne Hackborn68a06332017-11-15 17:54:18 -08001932 mRootProcess = null;
1933 }
1934 }
1935
chaviw82a0ba82018-03-15 14:26:29 -07001936 void clearAllPendingOptions() {
1937 for (int i = getChildCount() - 1; i >= 0; i--) {
1938 getChildAt(i).clearOptionsLocked(false /* withAbort */);
1939 }
1940 }
1941
Winson Chungabfdcce2018-07-02 17:23:33 -07001942 /**
1943 * Fills in a {@link TaskInfo} with information from this task.
1944 * @param info the {@link TaskInfo} to fill in
1945 * @param reuseActivitiesReport a temporary activities report that we can reuse to fetch the
1946 * running activities
1947 */
1948 void fillTaskInfo(TaskInfo info, TaskActivitiesReport reuseActivitiesReport) {
1949 getNumRunningActivities(reuseActivitiesReport);
1950 info.userId = userId;
1951 info.stackId = getStackId();
1952 info.taskId = taskId;
1953 info.isRunning = getTopActivity() != null;
1954 info.baseIntent = getBaseIntent();
1955 info.baseActivity = reuseActivitiesReport.base != null
1956 ? reuseActivitiesReport.base.intent.getComponent()
1957 : null;
1958 info.topActivity = reuseActivitiesReport.top != null
1959 ? reuseActivitiesReport.top.intent.getComponent()
1960 : null;
1961 info.origActivity = origActivity;
1962 info.realActivity = realActivity;
1963 info.numActivities = reuseActivitiesReport.numActivities;
1964 info.lastActiveTime = lastActiveTime;
1965 info.taskDescription = new ActivityManager.TaskDescription(lastTaskDescription);
1966 info.supportsSplitScreenMultiWindow = supportsSplitScreenWindowingMode();
1967 info.resizeMode = mResizeMode;
1968 info.configuration.setTo(getConfiguration());
1969 }
1970
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001971 void dump(PrintWriter pw, String prefix) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001972 pw.print(prefix); pw.print("userId="); pw.print(userId);
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001973 pw.print(" effectiveUid="); UserHandle.formatUid(pw, effectiveUid);
1974 pw.print(" mCallingUid="); UserHandle.formatUid(pw, mCallingUid);
Suprabh Shukla7745c142016-03-07 18:21:10 -08001975 pw.print(" mUserSetupComplete="); pw.print(mUserSetupComplete);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001976 pw.print(" mCallingPackage="); pw.println(mCallingPackage);
Dianne Hackborn79228822014-09-16 11:11:23 -07001977 if (affinity != null || rootAffinity != null) {
1978 pw.print(prefix); pw.print("affinity="); pw.print(affinity);
1979 if (affinity == null || !affinity.equals(rootAffinity)) {
1980 pw.print(" root="); pw.println(rootAffinity);
1981 } else {
1982 pw.println();
1983 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001984 }
Dianne Hackborn91097de2014-04-04 18:02:06 -07001985 if (voiceSession != null || voiceInteractor != null) {
1986 pw.print(prefix); pw.print("VOICE: session=0x");
1987 pw.print(Integer.toHexString(System.identityHashCode(voiceSession)));
1988 pw.print(" interactor=0x");
1989 pw.println(Integer.toHexString(System.identityHashCode(voiceInteractor)));
1990 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001991 if (intent != null) {
1992 StringBuilder sb = new StringBuilder(128);
1993 sb.append(prefix); sb.append("intent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08001994 intent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001995 sb.append('}');
1996 pw.println(sb.toString());
1997 }
1998 if (affinityIntent != null) {
1999 StringBuilder sb = new StringBuilder(128);
2000 sb.append(prefix); sb.append("affinityIntent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08002001 affinityIntent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002002 sb.append('}');
2003 pw.println(sb.toString());
2004 }
2005 if (origActivity != null) {
2006 pw.print(prefix); pw.print("origActivity=");
2007 pw.println(origActivity.flattenToShortString());
2008 }
2009 if (realActivity != null) {
2010 pw.print(prefix); pw.print("realActivity=");
2011 pw.println(realActivity.flattenToShortString());
2012 }
Wale Ogunwale66e16852017-10-19 13:35:52 -07002013 if (autoRemoveRecents || isPersistable || !isActivityTypeStandard() || numFullscreen != 0) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002014 pw.print(prefix); pw.print("autoRemoveRecents="); pw.print(autoRemoveRecents);
Dianne Hackborn852975d2014-08-22 17:42:43 -07002015 pw.print(" isPersistable="); pw.print(isPersistable);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002016 pw.print(" numFullscreen="); pw.print(numFullscreen);
Wale Ogunwale66e16852017-10-19 13:35:52 -07002017 pw.print(" activityType="); pw.println(getActivityType());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002018 }
Craig Mautner432f64e2015-05-20 14:59:57 -07002019 if (rootWasReset || mNeverRelinquishIdentity || mReuseTask
2020 || mLockTaskAuth != LOCK_TASK_AUTH_PINNABLE) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002021 pw.print(prefix); pw.print("rootWasReset="); pw.print(rootWasReset);
2022 pw.print(" mNeverRelinquishIdentity="); pw.print(mNeverRelinquishIdentity);
Craig Mautner432f64e2015-05-20 14:59:57 -07002023 pw.print(" mReuseTask="); pw.print(mReuseTask);
2024 pw.print(" mLockTaskAuth="); pw.println(lockTaskAuthToString());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002025 }
Wale Ogunwale18795a22014-12-03 11:38:33 -08002026 if (mAffiliatedTaskId != taskId || mPrevAffiliateTaskId != INVALID_TASK_ID
2027 || mPrevAffiliate != null || mNextAffiliateTaskId != INVALID_TASK_ID
2028 || mNextAffiliate != null) {
Dianne Hackborn852975d2014-08-22 17:42:43 -07002029 pw.print(prefix); pw.print("affiliation="); pw.print(mAffiliatedTaskId);
2030 pw.print(" prevAffiliation="); pw.print(mPrevAffiliateTaskId);
2031 pw.print(" (");
2032 if (mPrevAffiliate == null) {
2033 pw.print("null");
2034 } else {
2035 pw.print(Integer.toHexString(System.identityHashCode(mPrevAffiliate)));
2036 }
2037 pw.print(") nextAffiliation="); pw.print(mNextAffiliateTaskId);
2038 pw.print(" (");
2039 if (mNextAffiliate == null) {
2040 pw.print("null");
2041 } else {
2042 pw.print(Integer.toHexString(System.identityHashCode(mNextAffiliate)));
2043 }
2044 pw.println(")");
2045 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002046 pw.print(prefix); pw.print("Activities="); pw.println(mActivities);
Dianne Hackborn852975d2014-08-22 17:42:43 -07002047 if (!askedCompatMode || !inRecents || !isAvailable) {
2048 pw.print(prefix); pw.print("askedCompatMode="); pw.print(askedCompatMode);
2049 pw.print(" inRecents="); pw.print(inRecents);
2050 pw.print(" isAvailable="); pw.println(isAvailable);
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002051 }
Dianne Hackborn852975d2014-08-22 17:42:43 -07002052 if (lastDescription != null) {
2053 pw.print(prefix); pw.print("lastDescription="); pw.println(lastDescription);
2054 }
Dianne Hackborn68a06332017-11-15 17:54:18 -08002055 if (mRootProcess != null) {
2056 pw.print(prefix); pw.print("mRootProcess="); pw.println(mRootProcess);
2057 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07002058 pw.print(prefix); pw.print("stackId="); pw.println(getStackId());
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002059 pw.print(prefix + "hasBeenVisible=" + hasBeenVisible);
2060 pw.print(" mResizeMode=" + ActivityInfo.resizeModeToString(mResizeMode));
Winson Chungd3395382016-12-13 11:49:09 -08002061 pw.print(" mSupportsPictureInPicture=" + mSupportsPictureInPicture);
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002062 pw.print(" isResizeable=" + isResizeable());
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002063 pw.print(" lastActiveTime=" + lastActiveTime);
2064 pw.println(" (inactive for " + (getInactiveDuration() / 1000) + "s)");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002065 }
2066
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002067 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002068 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002069 StringBuilder sb = new StringBuilder(128);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002070 if (stringName != null) {
2071 sb.append(stringName);
2072 sb.append(" U=");
2073 sb.append(userId);
Wale Ogunwale6c5eb1c2015-11-10 07:52:22 -08002074 sb.append(" StackId=");
Andrii Kulian02b7a832016-10-06 23:11:56 -07002075 sb.append(getStackId());
Craig Mautnerde4ef022013-04-07 19:01:33 -07002076 sb.append(" sz=");
2077 sb.append(mActivities.size());
2078 sb.append('}');
2079 return sb.toString();
2080 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002081 sb.append("TaskRecord{");
2082 sb.append(Integer.toHexString(System.identityHashCode(this)));
2083 sb.append(" #");
2084 sb.append(taskId);
2085 if (affinity != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002086 sb.append(" A=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002087 sb.append(affinity);
2088 } else if (intent != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002089 sb.append(" I=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002090 sb.append(intent.getComponent().flattenToShortString());
Bryce Leefbd263b42018-03-07 10:33:55 -08002091 } else if (affinityIntent != null && affinityIntent.getComponent() != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002092 sb.append(" aI=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002093 sb.append(affinityIntent.getComponent().flattenToShortString());
2094 } else {
2095 sb.append(" ??");
2096 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07002097 stringName = sb.toString();
2098 return toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002099 }
Steven Timotius4346f0a2017-09-12 11:07:21 -07002100
2101 public void writeToProto(ProtoOutputStream proto, long fieldId) {
2102 final long token = proto.start(fieldId);
Adrian Roos4921ccf2017-09-28 16:54:06 +02002103 super.writeToProto(proto, CONFIGURATION_CONTAINER, false /* trim */);
Steven Timotius4346f0a2017-09-12 11:07:21 -07002104 proto.write(ID, taskId);
2105 for (int i = mActivities.size() - 1; i >= 0; i--) {
2106 ActivityRecord activity = mActivities.get(i);
2107 activity.writeToProto(proto, ACTIVITIES);
2108 }
2109 proto.write(STACK_ID, mStack.mStackId);
2110 if (mLastNonFullscreenBounds != null) {
2111 mLastNonFullscreenBounds.writeToProto(proto, LAST_NON_FULLSCREEN_BOUNDS);
2112 }
2113 if (realActivity != null) {
2114 proto.write(REAL_ACTIVITY, realActivity.flattenToShortString());
2115 }
2116 if (origActivity != null) {
2117 proto.write(ORIG_ACTIVITY, origActivity.flattenToShortString());
2118 }
2119 proto.write(ACTIVITY_TYPE, getActivityType());
Steven Timotius4346f0a2017-09-12 11:07:21 -07002120 proto.write(RESIZE_MODE, mResizeMode);
Bryce Leef3c6a472017-11-14 14:53:06 -08002121 // TODO: Remove, no longer needed with windowingMode.
2122 proto.write(FULLSCREEN, matchParentBounds());
2123
2124 if (!matchParentBounds()) {
2125 final Rect bounds = getOverrideBounds();
2126 bounds.writeToProto(proto, BOUNDS);
Steven Timotius4346f0a2017-09-12 11:07:21 -07002127 }
2128 proto.write(MIN_WIDTH, mMinWidth);
2129 proto.write(MIN_HEIGHT, mMinHeight);
2130 proto.end(token);
2131 }
Winson Chung61c9e5a2017-10-11 10:39:32 -07002132
2133 /**
2134 * See {@link #getNumRunningActivities(TaskActivitiesReport)}.
2135 */
2136 static class TaskActivitiesReport {
2137 int numRunning;
2138 int numActivities;
2139 ActivityRecord top;
2140 ActivityRecord base;
2141
2142 void reset() {
2143 numRunning = numActivities = 0;
2144 top = base = null;
2145 }
2146 }
Garfield Tan9b1efea2017-12-05 16:43:46 -08002147
2148 /**
2149 * Saves this {@link TaskRecord} to XML using given serializer.
2150 */
2151 void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
2152 if (DEBUG_RECENTS) Slog.i(TAG_RECENTS, "Saving task=" + this);
2153
2154 out.attribute(null, ATTR_TASKID, String.valueOf(taskId));
2155 if (realActivity != null) {
2156 out.attribute(null, ATTR_REALACTIVITY, realActivity.flattenToShortString());
2157 }
2158 out.attribute(null, ATTR_REALACTIVITY_SUSPENDED, String.valueOf(realActivitySuspended));
2159 if (origActivity != null) {
2160 out.attribute(null, ATTR_ORIGACTIVITY, origActivity.flattenToShortString());
2161 }
2162 // Write affinity, and root affinity if it is different from affinity.
2163 // We use the special string "@" for a null root affinity, so we can identify
2164 // later whether we were given a root affinity or should just make it the
2165 // same as the affinity.
2166 if (affinity != null) {
2167 out.attribute(null, ATTR_AFFINITY, affinity);
2168 if (!affinity.equals(rootAffinity)) {
2169 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
2170 }
2171 } else if (rootAffinity != null) {
2172 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
2173 }
2174 out.attribute(null, ATTR_ROOTHASRESET, String.valueOf(rootWasReset));
2175 out.attribute(null, ATTR_AUTOREMOVERECENTS, String.valueOf(autoRemoveRecents));
2176 out.attribute(null, ATTR_ASKEDCOMPATMODE, String.valueOf(askedCompatMode));
2177 out.attribute(null, ATTR_USERID, String.valueOf(userId));
2178 out.attribute(null, ATTR_USER_SETUP_COMPLETE, String.valueOf(mUserSetupComplete));
2179 out.attribute(null, ATTR_EFFECTIVE_UID, String.valueOf(effectiveUid));
2180 out.attribute(null, ATTR_LASTTIMEMOVED, String.valueOf(mLastTimeMoved));
2181 out.attribute(null, ATTR_NEVERRELINQUISH, String.valueOf(mNeverRelinquishIdentity));
2182 if (lastDescription != null) {
2183 out.attribute(null, ATTR_LASTDESCRIPTION, lastDescription.toString());
2184 }
2185 if (lastTaskDescription != null) {
2186 lastTaskDescription.saveToXml(out);
2187 }
2188 out.attribute(null, ATTR_TASK_AFFILIATION_COLOR, String.valueOf(mAffiliatedTaskColor));
2189 out.attribute(null, ATTR_TASK_AFFILIATION, String.valueOf(mAffiliatedTaskId));
2190 out.attribute(null, ATTR_PREV_AFFILIATION, String.valueOf(mPrevAffiliateTaskId));
2191 out.attribute(null, ATTR_NEXT_AFFILIATION, String.valueOf(mNextAffiliateTaskId));
2192 out.attribute(null, ATTR_CALLING_UID, String.valueOf(mCallingUid));
2193 out.attribute(null, ATTR_CALLING_PACKAGE, mCallingPackage == null ? "" : mCallingPackage);
2194 out.attribute(null, ATTR_RESIZE_MODE, String.valueOf(mResizeMode));
2195 out.attribute(null, ATTR_SUPPORTS_PICTURE_IN_PICTURE,
2196 String.valueOf(mSupportsPictureInPicture));
2197 if (mLastNonFullscreenBounds != null) {
2198 out.attribute(
2199 null, ATTR_NON_FULLSCREEN_BOUNDS, mLastNonFullscreenBounds.flattenToString());
2200 }
2201 out.attribute(null, ATTR_MIN_WIDTH, String.valueOf(mMinWidth));
2202 out.attribute(null, ATTR_MIN_HEIGHT, String.valueOf(mMinHeight));
2203 out.attribute(null, ATTR_PERSIST_TASK_VERSION, String.valueOf(PERSIST_TASK_VERSION));
2204
2205 if (affinityIntent != null) {
2206 out.startTag(null, TAG_AFFINITYINTENT);
2207 affinityIntent.saveToXml(out);
2208 out.endTag(null, TAG_AFFINITYINTENT);
2209 }
2210
Bryce Lee1a990e52018-04-23 10:54:11 -07002211 if (intent != null) {
2212 out.startTag(null, TAG_INTENT);
2213 intent.saveToXml(out);
2214 out.endTag(null, TAG_INTENT);
2215 }
Garfield Tan9b1efea2017-12-05 16:43:46 -08002216
2217 final ArrayList<ActivityRecord> activities = mActivities;
2218 final int numActivities = activities.size();
2219 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
2220 final ActivityRecord r = activities.get(activityNdx);
2221 if (r.info.persistableMode == ActivityInfo.PERSIST_ROOT_ONLY || !r.isPersistable() ||
2222 ((r.intent.getFlags() & FLAG_ACTIVITY_NEW_DOCUMENT
2223 | FLAG_ACTIVITY_RETAIN_IN_RECENTS) == FLAG_ACTIVITY_NEW_DOCUMENT) &&
2224 activityNdx > 0) {
2225 // Stop at first non-persistable or first break in task (CLEAR_WHEN_TASK_RESET).
2226 break;
2227 }
2228 out.startTag(null, TAG_ACTIVITY);
2229 r.saveToXml(out);
2230 out.endTag(null, TAG_ACTIVITY);
2231 }
2232 }
2233
2234 @VisibleForTesting
2235 static TaskRecordFactory getTaskRecordFactory() {
2236 if (sTaskRecordFactory == null) {
2237 setTaskRecordFactory(new TaskRecordFactory());
2238 }
2239 return sTaskRecordFactory;
2240 }
2241
2242 static void setTaskRecordFactory(TaskRecordFactory factory) {
2243 sTaskRecordFactory = factory;
2244 }
2245
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002246 static TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002247 Intent intent, IVoiceInteractionSession voiceSession,
2248 IVoiceInteractor voiceInteractor) {
2249 return getTaskRecordFactory().create(
2250 service, taskId, info, intent, voiceSession, voiceInteractor);
2251 }
2252
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002253 static TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002254 Intent intent, TaskDescription taskDescription) {
2255 return getTaskRecordFactory().create(service, taskId, info, intent, taskDescription);
2256 }
2257
2258 static TaskRecord restoreFromXml(XmlPullParser in, ActivityStackSupervisor stackSupervisor)
2259 throws IOException, XmlPullParserException {
2260 return getTaskRecordFactory().restoreFromXml(in, stackSupervisor);
2261 }
2262
2263 /**
2264 * A factory class used to create {@link TaskRecord} or its subclass if any. This can be
2265 * specified when system boots by setting it with
2266 * {@link #setTaskRecordFactory(TaskRecordFactory)}.
2267 */
2268 static class TaskRecordFactory {
2269
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002270 TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002271 Intent intent, IVoiceInteractionSession voiceSession,
2272 IVoiceInteractor voiceInteractor) {
2273 return new TaskRecord(
2274 service, taskId, info, intent, voiceSession, voiceInteractor);
2275 }
2276
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002277 TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002278 Intent intent, TaskDescription taskDescription) {
2279 return new TaskRecord(service, taskId, info, intent, taskDescription);
2280 }
2281
2282 /**
2283 * Should only be used when we're restoring {@link TaskRecord} from storage.
2284 */
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002285 TaskRecord create(ActivityTaskManagerService service, int taskId, Intent intent,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002286 Intent affinityIntent, String affinity, String rootAffinity,
2287 ComponentName realActivity, ComponentName origActivity, boolean rootWasReset,
2288 boolean autoRemoveRecents, boolean askedCompatMode, int userId,
2289 int effectiveUid, String lastDescription, ArrayList<ActivityRecord> activities,
2290 long lastTimeMoved, boolean neverRelinquishIdentity,
2291 TaskDescription lastTaskDescription, int taskAffiliation, int prevTaskId,
2292 int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage,
2293 int resizeMode, boolean supportsPictureInPicture, boolean realActivitySuspended,
2294 boolean userSetupComplete, int minWidth, int minHeight) {
2295 return new TaskRecord(service, taskId, intent, affinityIntent, affinity,
2296 rootAffinity, realActivity, origActivity, rootWasReset, autoRemoveRecents,
2297 askedCompatMode, userId, effectiveUid, lastDescription, activities,
2298 lastTimeMoved, neverRelinquishIdentity, lastTaskDescription, taskAffiliation,
2299 prevTaskId, nextTaskId, taskAffiliationColor, callingUid, callingPackage,
2300 resizeMode, supportsPictureInPicture, realActivitySuspended, userSetupComplete,
2301 minWidth, minHeight);
2302 }
2303
2304 TaskRecord restoreFromXml(XmlPullParser in, ActivityStackSupervisor stackSupervisor)
2305 throws IOException, XmlPullParserException {
2306 Intent intent = null;
2307 Intent affinityIntent = null;
2308 ArrayList<ActivityRecord> activities = new ArrayList<>();
2309 ComponentName realActivity = null;
2310 boolean realActivitySuspended = false;
2311 ComponentName origActivity = null;
2312 String affinity = null;
2313 String rootAffinity = null;
2314 boolean hasRootAffinity = false;
2315 boolean rootHasReset = false;
2316 boolean autoRemoveRecents = false;
2317 boolean askedCompatMode = false;
2318 int taskType = 0;
2319 int userId = 0;
2320 boolean userSetupComplete = true;
2321 int effectiveUid = -1;
2322 String lastDescription = null;
2323 long lastTimeOnTop = 0;
2324 boolean neverRelinquishIdentity = true;
2325 int taskId = INVALID_TASK_ID;
2326 final int outerDepth = in.getDepth();
2327 TaskDescription taskDescription = new TaskDescription();
2328 int taskAffiliation = INVALID_TASK_ID;
2329 int taskAffiliationColor = 0;
2330 int prevTaskId = INVALID_TASK_ID;
2331 int nextTaskId = INVALID_TASK_ID;
2332 int callingUid = -1;
2333 String callingPackage = "";
2334 int resizeMode = RESIZE_MODE_FORCE_RESIZEABLE;
2335 boolean supportsPictureInPicture = false;
Garfield Tan367b35a2017-12-13 12:16:21 -08002336 Rect lastNonFullscreenBounds = null;
Garfield Tan9b1efea2017-12-05 16:43:46 -08002337 int minWidth = INVALID_MIN_SIZE;
2338 int minHeight = INVALID_MIN_SIZE;
2339 int persistTaskVersion = 0;
2340
2341 for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
2342 final String attrName = in.getAttributeName(attrNdx);
2343 final String attrValue = in.getAttributeValue(attrNdx);
2344 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: attribute name=" +
2345 attrName + " value=" + attrValue);
2346 switch (attrName) {
2347 case ATTR_TASKID:
2348 if (taskId == INVALID_TASK_ID) taskId = Integer.parseInt(attrValue);
2349 break;
2350 case ATTR_REALACTIVITY:
2351 realActivity = ComponentName.unflattenFromString(attrValue);
2352 break;
2353 case ATTR_REALACTIVITY_SUSPENDED:
2354 realActivitySuspended = Boolean.valueOf(attrValue);
2355 break;
2356 case ATTR_ORIGACTIVITY:
2357 origActivity = ComponentName.unflattenFromString(attrValue);
2358 break;
2359 case ATTR_AFFINITY:
2360 affinity = attrValue;
2361 break;
2362 case ATTR_ROOT_AFFINITY:
2363 rootAffinity = attrValue;
2364 hasRootAffinity = true;
2365 break;
2366 case ATTR_ROOTHASRESET:
2367 rootHasReset = Boolean.parseBoolean(attrValue);
2368 break;
2369 case ATTR_AUTOREMOVERECENTS:
2370 autoRemoveRecents = Boolean.parseBoolean(attrValue);
2371 break;
2372 case ATTR_ASKEDCOMPATMODE:
2373 askedCompatMode = Boolean.parseBoolean(attrValue);
2374 break;
2375 case ATTR_USERID:
2376 userId = Integer.parseInt(attrValue);
2377 break;
2378 case ATTR_USER_SETUP_COMPLETE:
2379 userSetupComplete = Boolean.parseBoolean(attrValue);
2380 break;
2381 case ATTR_EFFECTIVE_UID:
2382 effectiveUid = Integer.parseInt(attrValue);
2383 break;
2384 case ATTR_TASKTYPE:
2385 taskType = Integer.parseInt(attrValue);
2386 break;
2387 case ATTR_LASTDESCRIPTION:
2388 lastDescription = attrValue;
2389 break;
2390 case ATTR_LASTTIMEMOVED:
2391 lastTimeOnTop = Long.parseLong(attrValue);
2392 break;
2393 case ATTR_NEVERRELINQUISH:
2394 neverRelinquishIdentity = Boolean.parseBoolean(attrValue);
2395 break;
2396 case ATTR_TASK_AFFILIATION:
2397 taskAffiliation = Integer.parseInt(attrValue);
2398 break;
2399 case ATTR_PREV_AFFILIATION:
2400 prevTaskId = Integer.parseInt(attrValue);
2401 break;
2402 case ATTR_NEXT_AFFILIATION:
2403 nextTaskId = Integer.parseInt(attrValue);
2404 break;
2405 case ATTR_TASK_AFFILIATION_COLOR:
2406 taskAffiliationColor = Integer.parseInt(attrValue);
2407 break;
2408 case ATTR_CALLING_UID:
2409 callingUid = Integer.parseInt(attrValue);
2410 break;
2411 case ATTR_CALLING_PACKAGE:
2412 callingPackage = attrValue;
2413 break;
2414 case ATTR_RESIZE_MODE:
2415 resizeMode = Integer.parseInt(attrValue);
2416 break;
2417 case ATTR_SUPPORTS_PICTURE_IN_PICTURE:
2418 supportsPictureInPicture = Boolean.parseBoolean(attrValue);
2419 break;
2420 case ATTR_NON_FULLSCREEN_BOUNDS:
Garfield Tan367b35a2017-12-13 12:16:21 -08002421 lastNonFullscreenBounds = Rect.unflattenFromString(attrValue);
Garfield Tan9b1efea2017-12-05 16:43:46 -08002422 break;
2423 case ATTR_MIN_WIDTH:
2424 minWidth = Integer.parseInt(attrValue);
2425 break;
2426 case ATTR_MIN_HEIGHT:
2427 minHeight = Integer.parseInt(attrValue);
2428 break;
2429 case ATTR_PERSIST_TASK_VERSION:
2430 persistTaskVersion = Integer.parseInt(attrValue);
2431 break;
2432 default:
2433 if (attrName.startsWith(TaskDescription.ATTR_TASKDESCRIPTION_PREFIX)) {
2434 taskDescription.restoreFromXml(attrName, attrValue);
2435 } else {
2436 Slog.w(TAG, "TaskRecord: Unknown attribute=" + attrName);
2437 }
2438 }
2439 }
2440
2441 int event;
2442 while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
2443 (event != XmlPullParser.END_TAG || in.getDepth() >= outerDepth)) {
2444 if (event == XmlPullParser.START_TAG) {
2445 final String name = in.getName();
2446 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG,
2447 "TaskRecord: START_TAG name=" + name);
2448 if (TAG_AFFINITYINTENT.equals(name)) {
2449 affinityIntent = Intent.restoreFromXml(in);
2450 } else if (TAG_INTENT.equals(name)) {
2451 intent = Intent.restoreFromXml(in);
2452 } else if (TAG_ACTIVITY.equals(name)) {
2453 ActivityRecord activity =
2454 ActivityRecord.restoreFromXml(in, stackSupervisor);
2455 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: activity=" +
2456 activity);
2457 if (activity != null) {
2458 activities.add(activity);
2459 }
2460 } else {
Garfield Tan1e740192017-12-12 14:37:42 -08002461 handleUnknownTag(name, in);
Garfield Tan9b1efea2017-12-05 16:43:46 -08002462 }
2463 }
2464 }
2465 if (!hasRootAffinity) {
2466 rootAffinity = affinity;
2467 } else if ("@".equals(rootAffinity)) {
2468 rootAffinity = null;
2469 }
2470 if (effectiveUid <= 0) {
2471 Intent checkIntent = intent != null ? intent : affinityIntent;
2472 effectiveUid = 0;
2473 if (checkIntent != null) {
2474 IPackageManager pm = AppGlobals.getPackageManager();
2475 try {
2476 ApplicationInfo ai = pm.getApplicationInfo(
2477 checkIntent.getComponent().getPackageName(),
2478 PackageManager.MATCH_UNINSTALLED_PACKAGES
2479 | PackageManager.MATCH_DISABLED_COMPONENTS, userId);
2480 if (ai != null) {
2481 effectiveUid = ai.uid;
2482 }
2483 } catch (RemoteException e) {
2484 }
2485 }
2486 Slog.w(TAG, "Updating task #" + taskId + " for " + checkIntent
2487 + ": effectiveUid=" + effectiveUid);
2488 }
2489
2490 if (persistTaskVersion < 1) {
2491 // We need to convert the resize mode of home activities saved before version one if
2492 // they are marked as RESIZE_MODE_RESIZEABLE to
2493 // RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION since we didn't have that differentiation
2494 // before version 1 and the system didn't resize home activities before then.
2495 if (taskType == 1 /* old home type */ && resizeMode == RESIZE_MODE_RESIZEABLE) {
2496 resizeMode = RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
2497 }
2498 } else {
2499 // This activity has previously marked itself explicitly as both resizeable and
2500 // supporting picture-in-picture. Since there is no longer a requirement for
2501 // picture-in-picture activities to be resizeable, we can mark this simply as
2502 // resizeable and supporting picture-in-picture separately.
2503 if (resizeMode == RESIZE_MODE_RESIZEABLE_AND_PIPABLE_DEPRECATED) {
2504 resizeMode = RESIZE_MODE_RESIZEABLE;
2505 supportsPictureInPicture = true;
2506 }
2507 }
2508
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07002509 final TaskRecord task = create(stackSupervisor.mService,
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002510 taskId, intent, affinityIntent,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002511 affinity, rootAffinity, realActivity, origActivity, rootHasReset,
2512 autoRemoveRecents, askedCompatMode, userId, effectiveUid, lastDescription,
2513 activities, lastTimeOnTop, neverRelinquishIdentity, taskDescription,
2514 taskAffiliation, prevTaskId, nextTaskId, taskAffiliationColor, callingUid,
2515 callingPackage, resizeMode, supportsPictureInPicture, realActivitySuspended,
2516 userSetupComplete, minWidth, minHeight);
Garfield Tan367b35a2017-12-13 12:16:21 -08002517 task.mLastNonFullscreenBounds = lastNonFullscreenBounds;
2518 task.setBounds(lastNonFullscreenBounds);
Garfield Tan9b1efea2017-12-05 16:43:46 -08002519
2520 for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {
2521 activities.get(activityNdx).setTask(task);
2522 }
2523
2524 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Restored task=" + task);
2525 return task;
2526 }
Garfield Tan1e740192017-12-12 14:37:42 -08002527
2528 void handleUnknownTag(String name, XmlPullParser in)
2529 throws IOException, XmlPullParserException {
2530 Slog.e(TAG, "restoreTask: Unexpected name=" + name);
2531 XmlUtils.skipCurrentTag(in);
2532 }
Garfield Tan9b1efea2017-12-05 16:43:46 -08002533 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002534}