blob: ef8cb1c07969fbf8b34c1c25e7e860a4e98019f1 [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
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700132// TODO: Make package private again once move to WM package is complete.
133public class TaskRecord extends ConfigurationContainer implements TaskWindowContainerListener {
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800134 private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskRecord" : TAG_AM;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -0700135 private static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700136 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
Craig Mautnere0570202015-05-13 13:06:11 -0700137 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700138 private static final String TAG_TASKS = TAG + POSTFIX_TASKS;
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800139
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700140 private static final String ATTR_TASKID = "task_id";
Craig Mautner21d24a22014-04-23 11:45:37 -0700141 private static final String TAG_INTENT = "intent";
142 private static final String TAG_AFFINITYINTENT = "affinity_intent";
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700143 private static final String ATTR_REALACTIVITY = "real_activity";
144 private static final String ATTR_REALACTIVITY_SUSPENDED = "real_activity_suspended";
Craig Mautner21d24a22014-04-23 11:45:37 -0700145 private static final String ATTR_ORIGACTIVITY = "orig_activity";
Stefan Kuhnee88d1e52015-05-18 10:33:45 -0700146 private static final String TAG_ACTIVITY = "activity";
Craig Mautner21d24a22014-04-23 11:45:37 -0700147 private static final String ATTR_AFFINITY = "affinity";
Dianne Hackborn79228822014-09-16 11:11:23 -0700148 private static final String ATTR_ROOT_AFFINITY = "root_affinity";
Craig Mautner21d24a22014-04-23 11:45:37 -0700149 private static final String ATTR_ROOTHASRESET = "root_has_reset";
Dianne Hackborn13420f22014-07-18 15:43:56 -0700150 private static final String ATTR_AUTOREMOVERECENTS = "auto_remove_recents";
Craig Mautner21d24a22014-04-23 11:45:37 -0700151 private static final String ATTR_ASKEDCOMPATMODE = "asked_compat_mode";
152 private static final String ATTR_USERID = "user_id";
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800153 private static final String ATTR_USER_SETUP_COMPLETE = "user_setup_complete";
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700154 private static final String ATTR_EFFECTIVE_UID = "effective_uid";
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700155 @Deprecated
Craig Mautner21d24a22014-04-23 11:45:37 -0700156 private static final String ATTR_TASKTYPE = "task_type";
Craig Mautner21d24a22014-04-23 11:45:37 -0700157 private static final String ATTR_LASTDESCRIPTION = "last_description";
158 private static final String ATTR_LASTTIMEMOVED = "last_time_moved";
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700159 private static final String ATTR_NEVERRELINQUISH = "never_relinquish_identity";
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700160 private static final String ATTR_TASK_AFFILIATION = "task_affiliation";
Craig Mautnera228ae92014-07-09 05:44:55 -0700161 private static final String ATTR_PREV_AFFILIATION = "prev_affiliation";
162 private static final String ATTR_NEXT_AFFILIATION = "next_affiliation";
Winson Chungec396d62014-08-06 17:08:00 -0700163 private static final String ATTR_TASK_AFFILIATION_COLOR = "task_affiliation_color";
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700164 private static final String ATTR_CALLING_UID = "calling_uid";
165 private static final String ATTR_CALLING_PACKAGE = "calling_package";
Winson Chungd3395382016-12-13 11:49:09 -0800166 private static final String ATTR_SUPPORTS_PICTURE_IN_PICTURE = "supports_picture_in_picture";
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800167 private static final String ATTR_RESIZE_MODE = "resize_mode";
Wale Ogunwale706ed792015-08-02 10:29:44 -0700168 private static final String ATTR_NON_FULLSCREEN_BOUNDS = "non_fullscreen_bounds";
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700169 private static final String ATTR_MIN_WIDTH = "min_width";
170 private static final String ATTR_MIN_HEIGHT = "min_height";
Wale Ogunwale625ed0c2016-10-18 08:50:31 -0700171 private static final String ATTR_PERSIST_TASK_VERSION = "persist_task_version";
Andrii Kulian18d75122016-03-27 20:20:28 -0700172
Wale Ogunwale625ed0c2016-10-18 08:50:31 -0700173 // Current version of the task record we persist. Used to check if we need to run any upgrade
174 // code.
175 private static final int PERSIST_TASK_VERSION = 1;
Craig Mautner21d24a22014-04-23 11:45:37 -0700176
Wale Ogunwale18795a22014-12-03 11:38:33 -0800177 static final int INVALID_TASK_ID = -1;
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700178 private static final int INVALID_MIN_SIZE = -1;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800179
Winson Chung74666102017-02-22 17:49:24 -0800180 /**
181 * The modes to control how the stack is moved to the front when calling
182 * {@link TaskRecord#reparent}.
183 */
184 @Retention(RetentionPolicy.SOURCE)
185 @IntDef({
186 REPARENT_MOVE_STACK_TO_FRONT,
187 REPARENT_KEEP_STACK_AT_FRONT,
188 REPARENT_LEAVE_STACK_IN_PLACE
189 })
Wale Ogunwale66e16852017-10-19 13:35:52 -0700190 @interface ReparentMoveStackMode {}
Winson Chung74666102017-02-22 17:49:24 -0800191 // Moves the stack to the front if it was not at the front
Wale Ogunwale66e16852017-10-19 13:35:52 -0700192 static final int REPARENT_MOVE_STACK_TO_FRONT = 0;
Winson Chung74666102017-02-22 17:49:24 -0800193 // Only moves the stack to the front if it was focused or front most already
Wale Ogunwale66e16852017-10-19 13:35:52 -0700194 static final int REPARENT_KEEP_STACK_AT_FRONT = 1;
Winson Chung74666102017-02-22 17:49:24 -0800195 // Do not move the stack as a part of reparenting
Wale Ogunwale66e16852017-10-19 13:35:52 -0700196 static final int REPARENT_LEAVE_STACK_IN_PLACE = 2;
Winson Chung74666102017-02-22 17:49:24 -0800197
Garfield Tan9b1efea2017-12-05 16:43:46 -0800198 /**
199 * The factory used to create {@link TaskRecord}. This allows OEM subclass {@link TaskRecord}.
200 */
201 private static TaskRecordFactory sTaskRecordFactory;
202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800203 final int taskId; // Unique identifier for this task.
Dianne Hackborn79228822014-09-16 11:11:23 -0700204 String affinity; // The affinity name for this task, or null; may change identity.
205 String rootAffinity; // Initial base affinity, or null; does not change from initial root.
Dianne Hackborn91097de2014-04-04 18:02:06 -0700206 final IVoiceInteractionSession voiceSession; // Voice interaction session driving task
207 final IVoiceInteractor voiceInteractor; // Associated interactor to provide to app
Bryce Lee1a990e52018-04-23 10:54:11 -0700208 Intent intent; // The original intent that started the task. Note that this value can
209 // be null.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800210 Intent affinityIntent; // Intent of affinity-moved activity that started this task.
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700211 int effectiveUid; // The current effective uid of the identity of this task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800212 ComponentName origActivity; // The non-alias activity component of the intent.
213 ComponentName realActivity; // The actual activity component that started the task.
Andrei Stingaceanu4ccec532016-01-13 12:10:21 +0000214 boolean realActivitySuspended; // True if the actual activity component that started the
215 // task is suspended.
Dianne Hackborn852975d2014-08-22 17:42:43 -0700216 boolean inRecents; // Actually in the recents list?
Winson Chungfb44d212017-10-04 11:39:10 -0700217 long lastActiveTime; // Last time this task was active in the current device session,
218 // including sleep. This time is initialized to the elapsed time when
219 // restored from disk.
Dianne Hackborn852975d2014-08-22 17:42:43 -0700220 boolean isAvailable; // Is the activity available to be launched?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221 boolean rootWasReset; // True if the intent at the root of the task had
222 // the FLAG_ACTIVITY_RESET_TASK_IF_NEEDED flag.
Dianne Hackborn13420f22014-07-18 15:43:56 -0700223 boolean autoRemoveRecents; // If true, we should automatically remove the task from
224 // recents when activity finishes
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700225 boolean askedCompatMode;// Have asked the user about compat mode for this task.
Dianne Hackbornd38aed82014-06-10 21:36:35 -0700226 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 -0800227
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700228 String stringName; // caching of toString() result.
Dianne Hackborn9da2d402012-03-15 13:43:08 -0700229 int userId; // user for which this task was created
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800230 boolean mUserSetupComplete; // The user set-up is complete as of the last time the task activity
231 // was changed.
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800232
233 int numFullscreen; // Number of fullscreen activities.
234
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800235 int mResizeMode; // The resize mode of this task and its activities.
236 // Based on the {@link ActivityInfo#resizeMode} of the root activity.
Wale Ogunwale069bbd32017-02-03 07:58:14 -0800237 private boolean mSupportsPictureInPicture; // Whether or not this task and its activities
238 // support PiP. Based on the {@link ActivityInfo#FLAG_SUPPORTS_PICTURE_IN_PICTURE} flag
239 // of the root activity.
Craig Mautner15df08a2015-04-01 12:17:18 -0700240 /** Can't be put in lockTask mode. */
241 final static int LOCK_TASK_AUTH_DONT_LOCK = 0;
Benjamin Franz469dd582015-06-09 14:24:36 +0100242 /** Can enter app pinning with user approval. Can never start over existing lockTask task. */
Craig Mautner15df08a2015-04-01 12:17:18 -0700243 final static int LOCK_TASK_AUTH_PINNABLE = 1;
244 /** Starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing lockTask task. */
245 final static int LOCK_TASK_AUTH_LAUNCHABLE = 2;
Benjamin Franz469dd582015-06-09 14:24:36 +0100246 /** Can enter lockTask without user approval. Can start over existing lockTask task. */
Craig Mautner15df08a2015-04-01 12:17:18 -0700247 final static int LOCK_TASK_AUTH_WHITELISTED = 3;
Benjamin Franz469dd582015-06-09 14:24:36 +0100248 /** Priv-app that starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing
249 * lockTask task. */
250 final static int LOCK_TASK_AUTH_LAUNCHABLE_PRIV = 4;
Craig Mautner15df08a2015-04-01 12:17:18 -0700251 int mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE;
252
253 int mLockTaskUid = -1; // The uid of the application that called startLockTask().
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800254
Winson Chung03a9bae2014-05-02 09:56:12 -0700255 // This represents the last resolved activity values for this task
256 // NOTE: This value needs to be persisted with each task
Craig Mautner648f69b2014-09-18 14:16:26 -0700257 TaskDescription lastTaskDescription = new TaskDescription();
Winson Chung03a9bae2014-05-02 09:56:12 -0700258
Craig Mautnerd2328952013-03-05 12:46:26 -0800259 /** List of all activities in the task arranged in history order */
Craig Mautner21d24a22014-04-23 11:45:37 -0700260 final ArrayList<ActivityRecord> mActivities;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800261
Andrii Kulian02b7a832016-10-06 23:11:56 -0700262 /** Current stack. Setter must always be used to update the value. */
263 private ActivityStack mStack;
Craig Mautnerd2328952013-03-05 12:46:26 -0800264
Dianne Hackborn68a06332017-11-15 17:54:18 -0800265 /** The process that had previously hosted the root activity of this task.
266 * Used to know that we should try harder to keep this process around, in case the
267 * user wants to return to it. */
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700268 private WindowProcessController mRootProcess;
Dianne Hackborn68a06332017-11-15 17:54:18 -0800269
Craig Mautner21d24a22014-04-23 11:45:37 -0700270 /** Takes on same value as first root activity */
271 boolean isPersistable = false;
Craig Mautnerffcfcaa2014-06-05 09:54:38 -0700272 int maxRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700273
274 /** Only used for persistable tasks, otherwise 0. The last time this task was moved. Used for
275 * determining the order when restoring. Sign indicates whether last task movement was to front
276 * (positive) or back (negative). Absolute value indicates time. */
277 long mLastTimeMoved = System.currentTimeMillis();
278
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700279 /** If original intent did not allow relinquishing task identity, save that information */
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700280 private boolean mNeverRelinquishIdentity = true;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700281
Craig Mautner362449a2014-06-20 14:04:39 -0700282 // Used in the unique case where we are clearing the task in order to reuse it. In that case we
283 // do not want to delete the stack when the task goes empty.
Filip Gruszczynskibe9dabd2016-01-19 12:23:10 -0800284 private boolean mReuseTask = false;
Craig Mautner362449a2014-06-20 14:04:39 -0700285
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700286 CharSequence lastDescription; // Last description captured for this item.
287
Craig Mautnera228ae92014-07-09 05:44:55 -0700288 int mAffiliatedTaskId; // taskId of parent affiliation or self if no parent.
Winson Chungec396d62014-08-06 17:08:00 -0700289 int mAffiliatedTaskColor; // color of the parent task affiliation.
Craig Mautnera228ae92014-07-09 05:44:55 -0700290 TaskRecord mPrevAffiliate; // previous task in affiliated chain.
Wale Ogunwale18795a22014-12-03 11:38:33 -0800291 int mPrevAffiliateTaskId = INVALID_TASK_ID; // previous id for persistence.
Craig Mautnera228ae92014-07-09 05:44:55 -0700292 TaskRecord mNextAffiliate; // next task in affiliated chain.
Wale Ogunwale18795a22014-12-03 11:38:33 -0800293 int mNextAffiliateTaskId = INVALID_TASK_ID; // next id for persistence.
Craig Mautnera228ae92014-07-09 05:44:55 -0700294
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700295 // For relaunching the task from recents as though it was launched by the original launcher.
296 int mCallingUid;
297 String mCallingPackage;
298
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700299 final ActivityTaskManagerService mService;
Craig Mautner21d24a22014-04-23 11:45:37 -0700300
Jorim Jaggi82c9dc92016-02-05 15:10:33 -0800301 private final Rect mTmpStableBounds = new Rect();
302 private final Rect mTmpNonDecorBounds = new Rect();
Wale Ogunwale9a08f822016-02-17 19:03:58 -0800303 private final Rect mTmpRect = new Rect();
Jorim Jaggi0a932142016-02-01 17:42:25 -0800304
Wale Ogunwale706ed792015-08-02 10:29:44 -0700305 // Last non-fullscreen bounds the task was launched in or resized to.
306 // The information is persisted and used to determine the appropriate stack to launch the
307 // task into on restore.
308 Rect mLastNonFullscreenBounds = null;
Andrii Kulian2e751b82016-03-16 16:59:32 -0700309 // Minimal width and height of this task when it's resizeable. -1 means it should use the
310 // default minimal width/height.
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700311 int mMinWidth;
312 int mMinHeight;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700313
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700314 // Ranking (from top) of this task among all visible tasks. (-1 means it's not visible)
315 // This number will be assigned when we evaluate OOM scores for all visible tasks.
316 int mLayerRank = -1;
317
Andrii Kulian1779e612016-10-12 21:58:25 -0700318 /** Helper object used for updating override configuration. */
319 private Configuration mTmpConfig = new Configuration();
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700320
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800321 private TaskWindowContainerController mWindowContainerController;
322
Garfield Tan9b1efea2017-12-05 16:43:46 -0800323 /**
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700324 * Don't use constructor directly. Use {@link #create(ActivityTaskManagerService, int,
325 * ActivityInfo, Intent, TaskDescription)} instead.
Garfield Tan9b1efea2017-12-05 16:43:46 -0800326 */
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700327 TaskRecord(ActivityTaskManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700328 IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700329 mService = service;
Suprabh Shukla23593142015-11-03 17:31:15 -0800330 userId = UserHandle.getUserId(info.applicationInfo.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800331 taskId = _taskId;
Winson Chungfb44d212017-10-04 11:39:10 -0700332 lastActiveTime = SystemClock.elapsedRealtime();
Craig Mautnera228ae92014-07-09 05:44:55 -0700333 mAffiliatedTaskId = _taskId;
Dianne Hackborn91097de2014-04-04 18:02:06 -0700334 voiceSession = _voiceSession;
335 voiceInteractor = _voiceInteractor;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700336 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800337 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700338 mCallingUid = info.applicationInfo.uid;
339 mCallingPackage = info.packageName;
Martijn Coenend4a69702014-06-30 11:12:17 -0700340 setIntent(_intent, info);
Andrii Kulian2e751b82016-03-16 16:59:32 -0700341 setMinDimensions(info);
Winson730bf062016-03-31 18:04:56 -0700342 touchActiveTime();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700343 mService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
Craig Mautner21d24a22014-04-23 11:45:37 -0700344 }
345
Garfield Tan9b1efea2017-12-05 16:43:46 -0800346 /**
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700347 * Don't use constructor directly.
348 * Use {@link #create(ActivityTaskManagerService, int, ActivityInfo,
Garfield Tan9b1efea2017-12-05 16:43:46 -0800349 * Intent, IVoiceInteractionSession, IVoiceInteractor)} instead.
350 */
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700351 TaskRecord(ActivityTaskManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200352 TaskDescription _taskDescription) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700353 mService = service;
Suprabh Shukla23593142015-11-03 17:31:15 -0800354 userId = UserHandle.getUserId(info.applicationInfo.uid);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700355 taskId = _taskId;
Winson Chungfb44d212017-10-04 11:39:10 -0700356 lastActiveTime = SystemClock.elapsedRealtime();
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700357 mAffiliatedTaskId = _taskId;
358 voiceSession = null;
359 voiceInteractor = null;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700360 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800361 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700362 mCallingUid = info.applicationInfo.uid;
363 mCallingPackage = info.packageName;
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700364 setIntent(_intent, info);
Andrii Kulian2e751b82016-03-16 16:59:32 -0700365 setMinDimensions(info);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700366
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700367 isPersistable = true;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700368 // Clamp to [1, max].
369 maxRecents = Math.min(Math.max(info.maxRecents, 1),
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700370 ActivityTaskManager.getMaxAppRecentsLimitStatic());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700371
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700372 lastTaskDescription = _taskDescription;
Winson730bf062016-03-31 18:04:56 -0700373 touchActiveTime();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700374 mService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700375 }
376
Garfield Tan9b1efea2017-12-05 16:43:46 -0800377 /**
378 * Don't use constructor directly. This is only used by XML parser.
379 */
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700380 TaskRecord(ActivityTaskManagerService service, int _taskId, Intent _intent,
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800381 Intent _affinityIntent, String _affinity, String _rootAffinity,
382 ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700383 boolean _autoRemoveRecents, boolean _askedCompatMode, int _userId,
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800384 int _effectiveUid, String _lastDescription, ArrayList<ActivityRecord> activities,
Winson Chungfb44d212017-10-04 11:39:10 -0700385 long lastTimeMoved, boolean neverRelinquishIdentity,
386 TaskDescription _lastTaskDescription, int taskAffiliation, int prevTaskId,
387 int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage,
Charles He2bf28322017-10-12 22:24:49 +0100388 int resizeMode, boolean supportsPictureInPicture, boolean _realActivitySuspended,
389 boolean userSetupComplete, int minWidth, int minHeight) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700390 mService = service;
391 taskId = _taskId;
392 intent = _intent;
393 affinityIntent = _affinityIntent;
394 affinity = _affinity;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800395 rootAffinity = _rootAffinity;
Craig Mautner21d24a22014-04-23 11:45:37 -0700396 voiceSession = null;
397 voiceInteractor = null;
398 realActivity = _realActivity;
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800399 realActivitySuspended = _realActivitySuspended;
Craig Mautner21d24a22014-04-23 11:45:37 -0700400 origActivity = _origActivity;
401 rootWasReset = _rootWasReset;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700402 isAvailable = true;
Dianne Hackborn13420f22014-07-18 15:43:56 -0700403 autoRemoveRecents = _autoRemoveRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700404 askedCompatMode = _askedCompatMode;
Craig Mautner21d24a22014-04-23 11:45:37 -0700405 userId = _userId;
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800406 mUserSetupComplete = userSetupComplete;
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700407 effectiveUid = _effectiveUid;
Winson Chungfb44d212017-10-04 11:39:10 -0700408 lastActiveTime = SystemClock.elapsedRealtime();
Craig Mautner21d24a22014-04-23 11:45:37 -0700409 lastDescription = _lastDescription;
410 mActivities = activities;
411 mLastTimeMoved = lastTimeMoved;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700412 mNeverRelinquishIdentity = neverRelinquishIdentity;
Winson Chung2cb86c72014-06-25 12:03:30 -0700413 lastTaskDescription = _lastTaskDescription;
Craig Mautnera228ae92014-07-09 05:44:55 -0700414 mAffiliatedTaskId = taskAffiliation;
Winson Chungec396d62014-08-06 17:08:00 -0700415 mAffiliatedTaskColor = taskAffiliationColor;
Craig Mautnera228ae92014-07-09 05:44:55 -0700416 mPrevAffiliateTaskId = prevTaskId;
417 mNextAffiliateTaskId = nextTaskId;
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700418 mCallingUid = callingUid;
419 mCallingPackage = callingPackage;
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800420 mResizeMode = resizeMode;
Winson Chungd3395382016-12-13 11:49:09 -0800421 mSupportsPictureInPicture = supportsPictureInPicture;
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700422 mMinWidth = minWidth;
423 mMinHeight = minHeight;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700424 mService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800425 }
426
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800427 TaskWindowContainerController getWindowContainerController() {
428 return mWindowContainerController;
429 }
430
431 void createWindowContainer(boolean onTop, boolean showForAllUsers) {
432 if (mWindowContainerController != null) {
433 throw new IllegalArgumentException("Window container=" + mWindowContainerController
434 + " already created for task=" + this);
435 }
436
437 final Rect bounds = updateOverrideConfigurationFromLaunchBounds();
Bryce Lee04ab3462017-04-10 15:06:33 -0700438 setWindowContainerController(new TaskWindowContainerController(taskId, this,
Wale Ogunwale034a8ec2017-09-02 17:14:40 -0700439 getStack().getWindowContainerController(), userId, bounds,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700440 mResizeMode, mSupportsPictureInPicture, onTop,
441 showForAllUsers, lastTaskDescription));
Bryce Lee04ab3462017-04-10 15:06:33 -0700442 }
443
444 /**
445 * Should only be invoked from {@link #createWindowContainer(boolean, boolean)}.
446 */
447 @VisibleForTesting
448 protected void setWindowContainerController(TaskWindowContainerController controller) {
449 if (mWindowContainerController != null) {
450 throw new IllegalArgumentException("Window container=" + mWindowContainerController
451 + " already created for task=" + this);
452 }
453
454 mWindowContainerController = controller;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800455 }
456
457 void removeWindowContainer() {
Bryce Lee2b8e0372018-04-05 17:01:37 -0700458 mService.getLockTaskController().clearLockedTask(this);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800459 mWindowContainerController.removeContainer();
Wale Ogunwale3382ab12017-07-27 08:55:03 -0700460 if (!getWindowConfiguration().persistTaskBounds()) {
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800461 // Reset current bounds for task whose bounds shouldn't be persisted so it uses
462 // default configuration the next time it launches.
463 updateOverrideConfiguration(null);
464 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700465 mService.getTaskChangeNotificationController().notifyTaskRemoved(taskId);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800466 mWindowContainerController = null;
467 }
468
Jorim Jaggifb9d78a2017-01-05 18:57:12 +0100469 @Override
470 public void onSnapshotChanged(TaskSnapshot snapshot) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700471 mService.getTaskChangeNotificationController().notifyTaskSnapshotChanged(taskId, snapshot);
Jorim Jaggifb9d78a2017-01-05 18:57:12 +0100472 }
473
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800474 void setResizeMode(int resizeMode) {
475 if (mResizeMode == resizeMode) {
476 return;
477 }
478 mResizeMode = resizeMode;
479 mWindowContainerController.setResizeable(resizeMode);
480 mService.mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Andrii Kulianab132ee2018-07-24 22:10:21 +0800481 mService.mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800482 }
483
484 void setTaskDockedResizing(boolean resizing) {
485 mWindowContainerController.setTaskDockedResizing(resizing);
486 }
487
Wale Ogunwale1666e312016-12-16 11:27:18 -0800488 // TODO: Consolidate this with the resize() method below.
489 @Override
490 public void requestResize(Rect bounds, int resizeMode) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700491 mService.resizeTask(taskId, bounds, resizeMode);
Wale Ogunwale1666e312016-12-16 11:27:18 -0800492 }
493
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800494 boolean resize(Rect bounds, int resizeMode, boolean preserveWindow, boolean deferResume) {
Bryce Leef3c6a472017-11-14 14:53:06 -0800495 mService.mWindowManager.deferSurfaceLayout();
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800496
Bryce Leef3c6a472017-11-14 14:53:06 -0800497 try {
498 if (!isResizeable()) {
499 Slog.w(TAG, "resizeTask: task " + this + " not resizeable.");
500 return true;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800501 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800502
Bryce Leef3c6a472017-11-14 14:53:06 -0800503 // If this is a forced resize, let it go through even if the bounds is not changing,
504 // as we might need a relayout due to surface size change (to/from fullscreen).
505 final boolean forced = (resizeMode & RESIZE_MODE_FORCED) != 0;
506 if (equivalentOverrideBounds(bounds) && !forced) {
507 // Nothing to do here...
508 return true;
509 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800510
Bryce Leef3c6a472017-11-14 14:53:06 -0800511 if (mWindowContainerController == null) {
512 // Task doesn't exist in window manager yet (e.g. was restored from recents).
513 // All we can do for now is update the bounds so it can be used when the task is
514 // added to window manager.
515 updateOverrideConfiguration(bounds);
516 if (!inFreeformWindowingMode()) {
517 // re-restore the task so it can have the proper stack association.
518 mService.mStackSupervisor.restoreRecentTaskLocked(this, null, !ON_TOP);
519 }
520 return true;
521 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800522
Bryce Leef3c6a472017-11-14 14:53:06 -0800523 if (!canResizeToBounds(bounds)) {
524 throw new IllegalArgumentException("resizeTask: Can not resize task=" + this
525 + " to bounds=" + bounds + " resizeMode=" + mResizeMode);
526 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800527
Bryce Leef3c6a472017-11-14 14:53:06 -0800528 // Do not move the task to another stack here.
529 // This method assumes that the task is already placed in the right stack.
530 // we do not mess with that decision and we only do the resize!
531
532 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeTask_" + taskId);
533
534 final boolean updatedConfig = updateOverrideConfiguration(bounds);
535 // This variable holds information whether the configuration didn't change in a significant
536
537 // way and the activity was kept the way it was. If it's false, it means the activity
538 // had
539 // to be relaunched due to configuration change.
540 boolean kept = true;
541 if (updatedConfig) {
542 final ActivityRecord r = topRunningActivityLocked();
543 if (r != null && !deferResume) {
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -0800544 kept = r.ensureActivityConfiguration(0 /* globalChanges */,
Bryce Leef3c6a472017-11-14 14:53:06 -0800545 preserveWindow);
Garfield Tanb9151182018-06-25 16:29:21 -0700546 // Preserve other windows for resizing because if resizing happens when there
547 // is a dialog activity in the front, the activity that still shows some
548 // content to the user will become black and cause flickers. Note in most cases
549 // this won't cause tons of irrelevant windows being preserved because only
550 // activities in this task may experience a bounds change. Configs for other
551 // activities stay the same.
Bryce Leef3c6a472017-11-14 14:53:06 -0800552 mService.mStackSupervisor.ensureActivitiesVisibleLocked(r, 0,
Garfield Tanb9151182018-06-25 16:29:21 -0700553 preserveWindow);
Bryce Leef3c6a472017-11-14 14:53:06 -0800554 if (!kept) {
Andrii Kulianab132ee2018-07-24 22:10:21 +0800555 mService.mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Bryce Leef3c6a472017-11-14 14:53:06 -0800556 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800557 }
558 }
Bryce Leef3c6a472017-11-14 14:53:06 -0800559 mWindowContainerController.resize(kept, forced);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800560
Bryce Leef3c6a472017-11-14 14:53:06 -0800561 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
562 return kept;
563 } finally {
564 mService.mWindowManager.continueSurfaceLayout();
565 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800566 }
567
568 // TODO: Investigate combining with the resize() method above.
569 void resizeWindowContainer() {
Bryce Leef3c6a472017-11-14 14:53:06 -0800570 mWindowContainerController.resize(false /* relayout */, false /* forced */);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800571 }
572
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800573 void getWindowContainerBounds(Rect bounds) {
574 mWindowContainerController.getBounds(bounds);
575 }
576
Winson Chung74666102017-02-22 17:49:24 -0800577 /**
578 * Convenience method to reparent a task to the top or bottom position of the stack.
579 */
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700580 boolean reparent(ActivityStack preferredStack, boolean toTop,
581 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
582 String reason) {
583 return reparent(preferredStack, toTop ? MAX_VALUE : 0, moveStackMode, animate, deferResume,
584 true /* schedulePictureInPictureModeChange */, reason);
Winson Chung5af42fc2017-03-24 17:11:33 -0700585 }
586
587 /**
588 * Convenience method to reparent a task to the top or bottom position of the stack, with
589 * an option to skip scheduling the picture-in-picture mode change.
590 */
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700591 boolean reparent(ActivityStack preferredStack, boolean toTop,
592 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
593 boolean schedulePictureInPictureModeChange, String reason) {
594 return reparent(preferredStack, toTop ? MAX_VALUE : 0, moveStackMode, animate,
Winson Chung5af42fc2017-03-24 17:11:33 -0700595 deferResume, schedulePictureInPictureModeChange, reason);
596 }
597
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700598 /** Convenience method to reparent a task to a specific position of the stack. */
599 boolean reparent(ActivityStack preferredStack, int position,
600 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
601 String reason) {
602 return reparent(preferredStack, position, moveStackMode, animate, deferResume,
Winson Chung5af42fc2017-03-24 17:11:33 -0700603 true /* schedulePictureInPictureModeChange */, reason);
Winson Chung74666102017-02-22 17:49:24 -0800604 }
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800605
Winson Chung74666102017-02-22 17:49:24 -0800606 /**
607 * Reparents the task into a preferred stack, creating it if necessary.
608 *
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700609 * @param preferredStack the target stack to move this task
Winson Chung74666102017-02-22 17:49:24 -0800610 * @param position the position to place this task in the new stack
611 * @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 -0700612 * reparenting to be drawn and animated in
Winson Chung74666102017-02-22 17:49:24 -0800613 * @param moveStackMode whether or not to move the stack to the front always, only if it was
Winson Chung5af42fc2017-03-24 17:11:33 -0700614 * previously focused & in front, or never
Winson Chung74666102017-02-22 17:49:24 -0800615 * @param deferResume whether or not to update the visibility of other tasks and stacks that may
Winson Chung5af42fc2017-03-24 17:11:33 -0700616 * have changed as a result of this reparenting
617 * @param schedulePictureInPictureModeChange specifies whether or not to schedule the PiP mode
618 * change. Callers may set this to false if they are explicitly scheduling PiP mode
619 * changes themselves, like during the PiP animation
Winson Chung74666102017-02-22 17:49:24 -0800620 * @param reason the caller of this reparenting
Winson Chung5af42fc2017-03-24 17:11:33 -0700621 * @return whether the task was reparented
Winson Chung74666102017-02-22 17:49:24 -0800622 */
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700623 // TODO: Inspect all call sites and change to just changing windowing mode of the stack vs.
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700624 // re-parenting the task. Can only be done when we are no longer using static stack Ids.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700625 boolean reparent(ActivityStack preferredStack, int position,
626 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
627 boolean schedulePictureInPictureModeChange, String reason) {
Winson Chung74666102017-02-22 17:49:24 -0800628 final ActivityStackSupervisor supervisor = mService.mStackSupervisor;
629 final WindowManagerService windowManager = mService.mWindowManager;
630 final ActivityStack sourceStack = getStack();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700631 final ActivityStack toStack = supervisor.getReparentTargetStack(this, preferredStack,
Winson Chung74666102017-02-22 17:49:24 -0800632 position == MAX_VALUE);
633 if (toStack == sourceStack) {
634 return false;
635 }
Andrii Kulianb850ea52017-12-12 23:49:10 -0800636 if (!canBeLaunchedOnDisplay(toStack.mDisplayId)) {
637 return false;
638 }
Winson Chung74666102017-02-22 17:49:24 -0800639
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700640 final int toStackWindowingMode = toStack.getWindowingMode();
Winson Chung74666102017-02-22 17:49:24 -0800641 final ActivityRecord topActivity = getTopActivity();
642
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800643 final boolean mightReplaceWindow = topActivity != null
644 && replaceWindowsOnTaskMove(getWindowingMode(), toStackWindowingMode);
Winson Chung74666102017-02-22 17:49:24 -0800645 if (mightReplaceWindow) {
646 // We are about to relaunch the activity because its configuration changed due to
647 // being maximized, i.e. size change. The activity will first remove the old window
648 // and then add a new one. This call will tell window manager about this, so it can
649 // preserve the old window until the new one is drawn. This prevents having a gap
650 // between the removal and addition, in which no window is visible. We also want the
651 // entrance of the new window to be properly animated.
652 // Note here we always set the replacing window first, as the flags might be needed
653 // during the relaunch. If we end up not doing any relaunch, we clear the flags later.
654 windowManager.setWillReplaceWindow(topActivity.appToken, animate);
655 }
656
657 windowManager.deferSurfaceLayout();
658 boolean kept = true;
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800659 try {
Winson Chung74666102017-02-22 17:49:24 -0800660 final ActivityRecord r = topRunningActivityLocked();
Andrii Kulian5f750bc2018-07-17 08:57:23 -0700661 final boolean wasFocused = r != null && supervisor.isTopDisplayFocusedStack(sourceStack)
Winson Chung74666102017-02-22 17:49:24 -0800662 && (topRunningActivityLocked() == r);
Bryce Leec4ab62a2018-03-05 14:19:26 -0800663 final boolean wasResumed = r != null && sourceStack.getResumedActivity() == r;
Winson Chung95f8f0e2017-03-24 09:20:17 -0700664 final boolean wasPaused = r != null && sourceStack.mPausingActivity == r;
Winson Chung74666102017-02-22 17:49:24 -0800665
666 // In some cases the focused stack isn't the front stack. E.g. pinned stack.
667 // Whenever we are moving the top activity from the front stack we want to make sure to
668 // move the stack to the front.
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -0700669 final boolean wasFront = r != null && sourceStack.isTopStackOnDisplay()
Winson Chung74666102017-02-22 17:49:24 -0800670 && (sourceStack.topRunningActivityLocked() == r);
671
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800672 // Adjust the position for the new parent stack as needed.
Winson Chung74666102017-02-22 17:49:24 -0800673 position = toStack.getAdjustedPositionForTask(this, position, null /* starting */);
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800674
675 // Must reparent first in window manager to avoid a situation where AM can delete the
676 // we are coming from in WM before we reparent because it became empty.
Wale Ogunwale2719cc12017-04-14 09:45:27 -0700677 mWindowContainerController.reparent(toStack.getWindowContainerController(), position,
678 moveStackMode == REPARENT_MOVE_STACK_TO_FRONT);
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800679
Wale Ogunwale56d8d162017-05-30 11:12:20 -0700680 final boolean moveStackToFront = moveStackMode == REPARENT_MOVE_STACK_TO_FRONT
681 || (moveStackMode == REPARENT_KEEP_STACK_AT_FRONT && (wasFocused || wasFront));
Winson Chung74666102017-02-22 17:49:24 -0800682 // Move the task
Wale Ogunwale56d8d162017-05-30 11:12:20 -0700683 sourceStack.removeTask(this, reason, moveStackToFront
684 ? REMOVE_TASK_MODE_MOVING_TO_TOP : REMOVE_TASK_MODE_MOVING);
Winson Chung5af42fc2017-03-24 17:11:33 -0700685 toStack.addTask(this, position, false /* schedulePictureInPictureModeChange */, reason);
Winson Chung74666102017-02-22 17:49:24 -0800686
Winson Chung5af42fc2017-03-24 17:11:33 -0700687 if (schedulePictureInPictureModeChange) {
688 // Notify of picture-in-picture mode changes
689 supervisor.scheduleUpdatePictureInPictureModeIfNeeded(this, sourceStack);
690 }
Winson Chung74666102017-02-22 17:49:24 -0800691
692 // TODO: Ensure that this is actually necessary here
693 // Notify the voice session if required
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800694 if (voiceSession != null) {
695 try {
696 voiceSession.taskStarted(intent, taskId);
697 } catch (RemoteException e) {
698 }
699 }
Winson Chung74666102017-02-22 17:49:24 -0800700
701 // If the task had focus before (or we're requested to move focus), move focus to the
702 // new stack by moving the stack to the front.
Winson Chung95f8f0e2017-03-24 09:20:17 -0700703 if (r != null) {
704 toStack.moveToFrontAndResumeStateIfNeeded(r, moveStackToFront, wasResumed,
705 wasPaused, reason);
706 }
Winson Chung74666102017-02-22 17:49:24 -0800707 if (!animate) {
Jorim Jaggifa9ed962018-01-25 00:16:49 +0100708 mService.mStackSupervisor.mNoAnimActivities.add(topActivity);
Winson Chung74666102017-02-22 17:49:24 -0800709 }
710
711 // We might trigger a configuration change. Save the current task bounds for freezing.
712 // TODO: Should this call be moved inside the resize method in WM?
713 toStack.prepareFreezingTaskBounds();
714
715 // Make sure the task has the appropriate bounds/size for the stack it is in.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700716 final boolean toStackSplitScreenPrimary =
717 toStackWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Bryce Leef3c6a472017-11-14 14:53:06 -0800718 final Rect configBounds = getOverrideBounds();
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700719 if ((toStackWindowingMode == WINDOWING_MODE_FULLSCREEN
720 || toStackWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY)
Bryce Leef3c6a472017-11-14 14:53:06 -0800721 && !Objects.equals(configBounds, toStack.getOverrideBounds())) {
722 kept = resize(toStack.getOverrideBounds(), RESIZE_MODE_SYSTEM, !mightReplaceWindow,
Winson Chung74666102017-02-22 17:49:24 -0800723 deferResume);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700724 } else if (toStackWindowingMode == WINDOWING_MODE_FREEFORM) {
Winson Chung74666102017-02-22 17:49:24 -0800725 Rect bounds = getLaunchBounds();
726 if (bounds == null) {
Bryce Leeec55eb02017-12-05 20:51:27 -0800727 mService.mStackSupervisor.getLaunchParamsController().layoutTask(this, null);
Bryce Leef3c6a472017-11-14 14:53:06 -0800728 bounds = configBounds;
Winson Chung74666102017-02-22 17:49:24 -0800729 }
730 kept = resize(bounds, RESIZE_MODE_FORCED, !mightReplaceWindow, deferResume);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700731 } else if (toStackSplitScreenPrimary || toStackWindowingMode == WINDOWING_MODE_PINNED) {
732 if (toStackSplitScreenPrimary && moveStackMode == REPARENT_KEEP_STACK_AT_FRONT) {
Matthew Ng330757d2017-02-28 14:19:17 -0800733 // Move recents to front so it is not behind home stack when going into docked
734 // mode
735 mService.mStackSupervisor.moveRecentsStackToFront(reason);
736 }
Bryce Leef3c6a472017-11-14 14:53:06 -0800737 kept = resize(toStack.getOverrideBounds(), RESIZE_MODE_SYSTEM, !mightReplaceWindow,
Winson Chung74666102017-02-22 17:49:24 -0800738 deferResume);
739 }
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800740 } finally {
Winson Chung74666102017-02-22 17:49:24 -0800741 windowManager.continueSurfaceLayout();
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800742 }
Winson Chung74666102017-02-22 17:49:24 -0800743
744 if (mightReplaceWindow) {
745 // If we didn't actual do a relaunch (indicated by kept==true meaning we kept the old
746 // window), we need to clear the replace window settings. Otherwise, we schedule a
747 // timeout to remove the old window if the replacing window is not coming in time.
748 windowManager.scheduleClearWillReplaceWindows(topActivity.appToken, !kept);
749 }
750
751 if (!deferResume) {
752 // The task might have already been running and its visibility needs to be synchronized
753 // with the visibility of the stack / windows.
754 supervisor.ensureActivitiesVisibleLocked(null, 0, !mightReplaceWindow);
Andrii Kulianab132ee2018-07-24 22:10:21 +0800755 supervisor.resumeFocusedStacksTopActivitiesLocked();
Winson Chung74666102017-02-22 17:49:24 -0800756 }
757
Andrii Kulian036e3ad2017-04-19 10:55:10 -0700758 // TODO: Handle incorrect request to move before the actual move, not after.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700759 supervisor.handleNonResizableTaskIfNeeded(this, preferredStack.getWindowingMode(),
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -0700760 DEFAULT_DISPLAY, toStack);
Winson Chung74666102017-02-22 17:49:24 -0800761
Winson Chungdff7a732017-12-11 12:17:06 -0800762 return (preferredStack == toStack);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800763 }
764
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700765 /**
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800766 * @return True if the windows of tasks being moved to the target stack from the source stack
767 * should be replaced, meaning that window manager will keep the old window around until the new
768 * is ready.
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700769 */
770 private static boolean replaceWindowsOnTaskMove(
771 int sourceWindowingMode, int targetWindowingMode) {
772 return sourceWindowingMode == WINDOWING_MODE_FREEFORM
773 || targetWindowingMode == WINDOWING_MODE_FREEFORM;
774 }
775
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800776 void cancelWindowTransition() {
777 mWindowContainerController.cancelWindowTransition();
778 }
779
Jorim Jaggi7361bab2017-01-16 17:17:58 +0100780 /**
781 * DO NOT HOLD THE ACTIVITY MANAGER LOCK WHEN CALLING THIS METHOD!
782 */
Jorim Jaggi35e3f532017-03-17 17:06:50 +0100783 TaskSnapshot getSnapshot(boolean reducedResolution) {
Jorim Jaggi7361bab2017-01-16 17:17:58 +0100784
785 // TODO: Move this to {@link TaskWindowContainerController} once recent tasks are more
786 // synchronized between AM and WM.
Jorim Jaggi35e3f532017-03-17 17:06:50 +0100787 return mService.mWindowManager.getTaskSnapshot(taskId, userId, reducedResolution);
Jorim Jaggi02886a82016-12-06 09:10:06 -0800788 }
789
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800790 void touchActiveTime() {
Winson Chungfb44d212017-10-04 11:39:10 -0700791 lastActiveTime = SystemClock.elapsedRealtime();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800792 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700793
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800794 long getInactiveDuration() {
Winson Chungfb44d212017-10-04 11:39:10 -0700795 return SystemClock.elapsedRealtime() - lastActiveTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800796 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700797
Winson Chungfee26772014-08-05 12:21:52 -0700798 /** Sets the original intent, and the calling uid and package. */
799 void setIntent(ActivityRecord r) {
Winson Chungfee26772014-08-05 12:21:52 -0700800 mCallingUid = r.launchedFromUid;
801 mCallingPackage = r.launchedFromPackage;
Craig Mautner15df08a2015-04-01 12:17:18 -0700802 setIntent(r.intent, r.info);
Charles He2bf28322017-10-12 22:24:49 +0100803 setLockTaskAuth(r);
Winson Chungfee26772014-08-05 12:21:52 -0700804 }
805
806 /** Sets the original intent, _without_ updating the calling uid or package. */
807 private void setIntent(Intent _intent, ActivityInfo info) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700808 if (intent == null) {
809 mNeverRelinquishIdentity =
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700810 (info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700811 } else if (mNeverRelinquishIdentity) {
812 return;
813 }
814
815 affinity = info.taskAffinity;
Dianne Hackborn79228822014-09-16 11:11:23 -0700816 if (intent == null) {
817 // If this task already has an intent associated with it, don't set the root
818 // affinity -- we don't want it changing after initially set, but the initially
819 // set value may be null.
820 rootAffinity = affinity;
821 }
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700822 effectiveUid = info.applicationInfo.uid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700823 stringName = null;
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800824
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800825 if (info.targetActivity == null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800826 if (_intent != null) {
827 // If this Intent has a selector, we want to clear it for the
828 // recent task since it is not relevant if the user later wants
829 // to re-launch the app.
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700830 if (_intent.getSelector() != null || _intent.getSourceBounds() != null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800831 _intent = new Intent(_intent);
832 _intent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700833 _intent.setSourceBounds(null);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800834 }
835 }
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700836 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Setting Intent of " + this + " to " + _intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800837 intent = _intent;
838 realActivity = _intent != null ? _intent.getComponent() : null;
839 origActivity = null;
840 } else {
841 ComponentName targetComponent = new ComponentName(
842 info.packageName, info.targetActivity);
843 if (_intent != null) {
844 Intent targetIntent = new Intent(_intent);
845 targetIntent.setComponent(targetComponent);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800846 targetIntent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700847 targetIntent.setSourceBounds(null);
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700848 if (DEBUG_TASKS) Slog.v(TAG_TASKS,
Dianne Hackborn7f96b792012-05-29 18:46:45 -0700849 "Setting Intent of " + this + " to target " + targetIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800850 intent = targetIntent;
851 realActivity = targetComponent;
852 origActivity = _intent.getComponent();
853 } else {
854 intent = null;
855 realActivity = targetComponent;
856 origActivity = new ComponentName(info.packageName, info.name);
857 }
858 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700859
Craig Mautner47b20ba2014-09-17 17:23:44 -0700860 final int intentFlags = intent == null ? 0 : intent.getFlags();
861 if ((intentFlags & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800862 // Once we are set to an Intent with this flag, we count this
863 // task as having a true root activity.
864 rootWasReset = true;
865 }
Dianne Hackborn09233282014-04-30 11:33:59 -0700866 userId = UserHandle.getUserId(info.applicationInfo.uid);
Winson Chung36f3f032016-09-08 23:29:43 +0000867 mUserSetupComplete = Settings.Secure.getIntForUser(mService.mContext.getContentResolver(),
868 USER_SETUP_COMPLETE, 0, userId) != 0;
Craig Mautner41db4a72014-05-07 17:20:56 -0700869 if ((info.flags & ActivityInfo.FLAG_AUTO_REMOVE_FROM_RECENTS) != 0) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700870 // If the activity itself has requested auto-remove, then just always do it.
871 autoRemoveRecents = true;
Wale Ogunwale843bfb92015-03-27 11:06:48 -0700872 } else if ((intentFlags & (FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS))
873 == FLAG_ACTIVITY_NEW_DOCUMENT) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700874 // If the caller has not asked for the document to be retained, then we may
875 // want to turn on auto-remove, depending on whether the target has set its
876 // own document launch mode.
877 if (info.documentLaunchMode != ActivityInfo.DOCUMENT_LAUNCH_NONE) {
878 autoRemoveRecents = false;
879 } else {
880 autoRemoveRecents = true;
881 }
882 } else {
883 autoRemoveRecents = false;
Craig Mautner41db4a72014-05-07 17:20:56 -0700884 }
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800885 mResizeMode = info.resizeMode;
Winson Chungd3395382016-12-13 11:49:09 -0800886 mSupportsPictureInPicture = info.supportsPictureInPicture();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800887 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800888
Andrii Kulian2e751b82016-03-16 16:59:32 -0700889 /** Sets the original minimal width and height. */
890 private void setMinDimensions(ActivityInfo info) {
891 if (info != null && info.windowLayout != null) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700892 mMinWidth = info.windowLayout.minWidth;
893 mMinHeight = info.windowLayout.minHeight;
Andrii Kulian2e751b82016-03-16 16:59:32 -0700894 } else {
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700895 mMinWidth = INVALID_MIN_SIZE;
896 mMinHeight = INVALID_MIN_SIZE;
Andrii Kulian2e751b82016-03-16 16:59:32 -0700897 }
898 }
899
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800900 /**
Andrii Kulian206b9fa2016-06-02 13:18:01 -0700901 * Return true if the input activity has the same intent filter as the intent this task
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800902 * record is based on (normally the root activity intent).
903 */
Andrii Kulian206b9fa2016-06-02 13:18:01 -0700904 boolean isSameIntentFilter(ActivityRecord r) {
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800905 final Intent intent = new Intent(r.intent);
906 // Correct the activity intent for aliasing. The task record intent will always be based on
907 // the real activity that will be launched not the alias, so we need to use an intent with
908 // the component name pointing to the real activity not the alias in the activity record.
909 intent.setComponent(r.realActivity);
Bryce Lee1a990e52018-04-23 10:54:11 -0700910 return intent.filterEquals(this.intent);
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800911 }
912
Wale Ogunwale66e16852017-10-19 13:35:52 -0700913 boolean returnsToHomeStack() {
914 final int returnHomeFlags = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME;
Bryce Lee1a990e52018-04-23 10:54:11 -0700915 return intent != null && (intent.getFlags() & returnHomeFlags) == returnHomeFlags;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700916 }
917
Craig Mautnera228ae92014-07-09 05:44:55 -0700918 void setPrevAffiliate(TaskRecord prevAffiliate) {
919 mPrevAffiliate = prevAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800920 mPrevAffiliateTaskId = prevAffiliate == null ? INVALID_TASK_ID : prevAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700921 }
922
923 void setNextAffiliate(TaskRecord nextAffiliate) {
924 mNextAffiliate = nextAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800925 mNextAffiliateTaskId = nextAffiliate == null ? INVALID_TASK_ID : nextAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700926 }
927
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700928 <T extends ActivityStack> T getStack() {
929 return (T) mStack;
Andrii Kulian02b7a832016-10-06 23:11:56 -0700930 }
931
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800932 /**
933 * Must be used for setting parent stack because it performs configuration updates.
934 * Must be called after adding task as a child to the stack.
935 */
Andrii Kulian02b7a832016-10-06 23:11:56 -0700936 void setStack(ActivityStack stack) {
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800937 if (stack != null && !stack.isInStackLocked(this)) {
938 throw new IllegalStateException("Task must be added as a Stack child first.");
939 }
Bryce Lee84730a02018-04-03 14:10:04 -0700940 final ActivityStack oldStack = mStack;
Andrii Kulian02b7a832016-10-06 23:11:56 -0700941 mStack = stack;
Bryce Lee84730a02018-04-03 14:10:04 -0700942
943 // If the new {@link TaskRecord} is from a different {@link ActivityStack}, remove this
944 // {@link ActivityRecord} from its current {@link ActivityStack}.
945
946 if (oldStack != mStack) {
947 for (int i = getChildCount() - 1; i >= 0; --i) {
948 final ActivityRecord activity = getChildAt(i);
949
950 if (oldStack != null) {
951 oldStack.onActivityRemovedFromStack(activity);
952 }
953
954 if (mStack != null) {
955 stack.onActivityAddedToStack(activity);
956 }
957 }
958 }
959
Andrii Kulian1779e612016-10-12 21:58:25 -0700960 onParentChanged();
Andrii Kulian02b7a832016-10-06 23:11:56 -0700961 }
962
963 /**
964 * @return Id of current stack, {@link INVALID_STACK_ID} if no stack is set.
965 */
966 int getStackId() {
967 return mStack != null ? mStack.mStackId : INVALID_STACK_ID;
968 }
969
Andrii Kulian1779e612016-10-12 21:58:25 -0700970 @Override
971 protected int getChildCount() {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700972 return mActivities.size();
Andrii Kulian1779e612016-10-12 21:58:25 -0700973 }
974
975 @Override
chaviw82a0ba82018-03-15 14:26:29 -0700976 protected ActivityRecord getChildAt(int index) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700977 return mActivities.get(index);
Andrii Kulian1779e612016-10-12 21:58:25 -0700978 }
979
980 @Override
981 protected ConfigurationContainer getParent() {
982 return mStack;
983 }
984
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800985 @Override
Wale Ogunwale98d62312017-07-12 09:24:56 -0700986 protected void onParentChanged() {
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800987 super.onParentChanged();
988 mService.mStackSupervisor.updateUIDsPresentOnDisplay();
989 }
990
Craig Mautnera228ae92014-07-09 05:44:55 -0700991 // Close up recents linked list.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700992 private void closeRecentsChain() {
Craig Mautnera228ae92014-07-09 05:44:55 -0700993 if (mPrevAffiliate != null) {
994 mPrevAffiliate.setNextAffiliate(mNextAffiliate);
995 }
996 if (mNextAffiliate != null) {
997 mNextAffiliate.setPrevAffiliate(mPrevAffiliate);
998 }
999 setPrevAffiliate(null);
1000 setNextAffiliate(null);
1001 }
1002
Winson Chung740c3ac2014-11-12 16:14:38 -08001003 void removedFromRecents() {
Dianne Hackborn852975d2014-08-22 17:42:43 -07001004 closeRecentsChain();
1005 if (inRecents) {
1006 inRecents = false;
Winson Chung740c3ac2014-11-12 16:14:38 -08001007 mService.notifyTaskPersisterLocked(this, false);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001008 }
Jorim Jaggif9084ec2017-01-16 13:16:59 +01001009
Dianne Hackborn68a06332017-11-15 17:54:18 -08001010 clearRootProcess();
1011
Jorim Jaggif9084ec2017-01-16 13:16:59 +01001012 // TODO: Use window container controller once tasks are better synced between AM and WM
1013 mService.mWindowManager.notifyTaskRemovedFromRecents(taskId, userId);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001014 }
1015
Craig Mautnera228ae92014-07-09 05:44:55 -07001016 void setTaskToAffiliateWith(TaskRecord taskToAffiliateWith) {
1017 closeRecentsChain();
1018 mAffiliatedTaskId = taskToAffiliateWith.mAffiliatedTaskId;
Winson Chungec396d62014-08-06 17:08:00 -07001019 mAffiliatedTaskColor = taskToAffiliateWith.mAffiliatedTaskColor;
Craig Mautnera228ae92014-07-09 05:44:55 -07001020 // Find the end
1021 while (taskToAffiliateWith.mNextAffiliate != null) {
1022 final TaskRecord nextRecents = taskToAffiliateWith.mNextAffiliate;
1023 if (nextRecents.mAffiliatedTaskId != mAffiliatedTaskId) {
1024 Slog.e(TAG, "setTaskToAffiliateWith: nextRecents=" + nextRecents + " affilTaskId="
1025 + nextRecents.mAffiliatedTaskId + " should be " + mAffiliatedTaskId);
1026 if (nextRecents.mPrevAffiliate == taskToAffiliateWith) {
1027 nextRecents.setPrevAffiliate(null);
1028 }
1029 taskToAffiliateWith.setNextAffiliate(null);
1030 break;
1031 }
1032 taskToAffiliateWith = nextRecents;
1033 }
1034 taskToAffiliateWith.setNextAffiliate(this);
1035 setPrevAffiliate(taskToAffiliateWith);
1036 setNextAffiliate(null);
1037 }
1038
Winson Chung1147c402014-05-14 11:05:00 -07001039 /** Returns the intent for the root activity for this task */
1040 Intent getBaseIntent() {
1041 return intent != null ? intent : affinityIntent;
1042 }
1043
Winson Chung3b3f4642014-04-22 10:08:18 -07001044 /** Returns the first non-finishing activity from the root. */
1045 ActivityRecord getRootActivity() {
1046 for (int i = 0; i < mActivities.size(); i++) {
1047 final ActivityRecord r = mActivities.get(i);
1048 if (r.finishing) {
1049 continue;
1050 }
1051 return r;
1052 }
1053 return null;
1054 }
1055
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001056 ActivityRecord getTopActivity() {
Bryce Lee9f6affd2017-09-01 09:18:35 -07001057 return getTopActivity(true /* includeOverlays */);
1058 }
1059
1060 ActivityRecord getTopActivity(boolean includeOverlays) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001061 for (int i = mActivities.size() - 1; i >= 0; --i) {
1062 final ActivityRecord r = mActivities.get(i);
Bryce Lee9f6affd2017-09-01 09:18:35 -07001063 if (r.finishing || (!includeOverlays && r.mTaskOverlay)) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001064 continue;
1065 }
1066 return r;
1067 }
1068 return null;
1069 }
1070
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -07001071 ActivityRecord topRunningActivityLocked() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001072 if (mStack != null) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07001073 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1074 ActivityRecord r = mActivities.get(activityNdx);
Chong Zhang87761972016-08-22 13:53:24 -07001075 if (!r.finishing && r.okToShowLocked()) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07001076 return r;
1077 }
Craig Mautner6b74cb52013-09-27 17:02:21 -07001078 }
1079 }
1080 return null;
1081 }
1082
Jorim Jaggi172e99f2017-10-20 14:33:18 +02001083 boolean isVisible() {
1084 for (int i = mActivities.size() - 1; i >= 0; --i) {
1085 final ActivityRecord r = mActivities.get(i);
1086 if (r.visible) {
1087 return true;
1088 }
1089 }
1090 return false;
1091 }
1092
Jorim Jaggiea039a82017-08-02 14:37:49 +02001093 void getAllRunningVisibleActivitiesLocked(ArrayList<ActivityRecord> outActivities) {
1094 if (mStack != null) {
1095 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1096 ActivityRecord r = mActivities.get(activityNdx);
Jorim Jaggi02f1d2f2017-08-04 14:29:16 +02001097 if (!r.finishing && r.okToShowLocked() && r.visibleIgnoringKeyguard) {
Jorim Jaggiea039a82017-08-02 14:37:49 +02001098 outActivities.add(r);
1099 }
1100 }
1101 }
1102 }
1103
Wale Ogunwale3b232392016-05-13 15:37:13 -07001104 ActivityRecord topRunningActivityWithStartingWindowLocked() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001105 if (mStack != null) {
Wale Ogunwale3b232392016-05-13 15:37:13 -07001106 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1107 ActivityRecord r = mActivities.get(activityNdx);
1108 if (r.mStartingWindowState != STARTING_WINDOW_SHOWN
Chong Zhang87761972016-08-22 13:53:24 -07001109 || r.finishing || !r.okToShowLocked()) {
Wale Ogunwale3b232392016-05-13 15:37:13 -07001110 continue;
1111 }
1112 return r;
1113 }
1114 }
1115 return null;
1116 }
1117
Winson Chung61c9e5a2017-10-11 10:39:32 -07001118 /**
1119 * Return the number of running activities, and the number of non-finishing/initializing
1120 * activities in the provided {@param reportOut} respectively.
1121 */
1122 void getNumRunningActivities(TaskActivitiesReport reportOut) {
1123 reportOut.reset();
1124 for (int i = mActivities.size() - 1; i >= 0; --i) {
1125 final ActivityRecord r = mActivities.get(i);
1126 if (r.finishing) {
1127 continue;
1128 }
1129
1130 reportOut.base = r;
1131
1132 // Increment the total number of non-finishing activities
1133 reportOut.numActivities++;
1134
Bryce Lee7ace3952018-02-16 14:34:32 -08001135 if (reportOut.top == null || (reportOut.top.isState(ActivityState.INITIALIZING))) {
Winson Chung61c9e5a2017-10-11 10:39:32 -07001136 reportOut.top = r;
1137 // Reset the number of running activities until we hit the first non-initializing
1138 // activity
1139 reportOut.numRunning = 0;
1140 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001141 if (r.attachedToProcess()) {
Winson Chung61c9e5a2017-10-11 10:39:32 -07001142 // Increment the number of actually running activities
1143 reportOut.numRunning++;
1144 }
1145 }
1146 }
1147
Chong Zhang87761972016-08-22 13:53:24 -07001148 boolean okToShowLocked() {
1149 // NOTE: If {@link TaskRecord#topRunningActivityLocked} return is not null then it is
1150 // okay to show the activity when locked.
1151 return mService.mStackSupervisor.isCurrentProfileLocked(userId)
1152 || topRunningActivityLocked() != null;
1153 }
1154
Craig Mautner3b475fe2013-12-16 15:58:31 -08001155 /** Call after activity movement or finish to make sure that frontOfTask is set correctly */
Bryce Leed71317c2017-02-07 14:27:22 -08001156 final void setFrontOfTask() {
1157 boolean foundFront = false;
Craig Mautner3b475fe2013-12-16 15:58:31 -08001158 final int numActivities = mActivities.size();
Craig Mautner704e40b2013-12-18 16:43:51 -08001159 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
Craig Mautner3b475fe2013-12-16 15:58:31 -08001160 final ActivityRecord r = mActivities.get(activityNdx);
1161 if (foundFront || r.finishing) {
1162 r.frontOfTask = false;
1163 } else {
1164 r.frontOfTask = true;
1165 // Set frontOfTask false for every following activity.
1166 foundFront = true;
1167 }
1168 }
Craig Mautner9587ee02014-06-23 15:00:10 +00001169 if (!foundFront && numActivities > 0) {
1170 // All activities of this task are finishing. As we ought to have a frontOfTask
1171 // activity, make the bottom activity front.
1172 mActivities.get(0).frontOfTask = true;
1173 }
Craig Mautner3b475fe2013-12-16 15:58:31 -08001174 }
1175
Craig Mautnerde4ef022013-04-07 19:01:33 -07001176 /**
Craig Mautner3b475fe2013-12-16 15:58:31 -08001177 * Reorder the history stack so that the passed activity is brought to the front.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001178 */
1179 final void moveActivityToFrontLocked(ActivityRecord newTop) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07001180 if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE,
1181 "Removing and adding activity " + newTop
1182 + " to stack at top callers=" + Debug.getCallers(4));
Craig Mautnerde4ef022013-04-07 19:01:33 -07001183
Craig Mautnerde4ef022013-04-07 19:01:33 -07001184 mActivities.remove(newTop);
1185 mActivities.add(newTop);
Bryce Leed58d7b32017-09-08 15:55:22 -07001186
1187 // Make sure window manager is aware of the position change.
1188 mWindowContainerController.positionChildAtTop(newTop.mWindowContainerController);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001189 updateEffectiveIntent();
Craig Mautner3b475fe2013-12-16 15:58:31 -08001190
Bryce Leed71317c2017-02-07 14:27:22 -08001191 setFrontOfTask();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001192 }
1193
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001194 void addActivityAtBottom(ActivityRecord r) {
Craig Mautner77878772013-03-04 19:46:24 -08001195 addActivityAtIndex(0, r);
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001196 }
1197
1198 void addActivityToTop(ActivityRecord r) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001199 addActivityAtIndex(mActivities.size(), r);
1200 }
1201
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001202 @Override
Wale Ogunwaleeea34ee92017-08-31 20:07:45 -07001203 /*@WindowConfiguration.ActivityType*/
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001204 public int getActivityType() {
1205 final int applicationType = super.getActivityType();
1206 if (applicationType != ACTIVITY_TYPE_UNDEFINED || mActivities.isEmpty()) {
1207 return applicationType;
1208 }
1209 return mActivities.get(0).getActivityType();
1210 }
1211
Winson Chung30480042017-01-26 10:55:34 -08001212 /**
1213 * Adds an activity {@param r} at the given {@param index}. The activity {@param r} must either
1214 * be in the current task or unparented to any task.
1215 */
Craig Mautner1602ec22013-05-12 10:24:27 -07001216 void addActivityAtIndex(int index, ActivityRecord r) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001217 TaskRecord task = r.getTask();
1218 if (task != null && task != this) {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001219 throw new IllegalArgumentException("Can not add r=" + " to task=" + this
Bryce Leeaf691c02017-03-20 14:20:22 -07001220 + " current parent=" + task);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001221 }
Bryce Leeaf691c02017-03-20 14:20:22 -07001222
1223 r.setTask(this);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001224
Craig Mautner6170f732013-04-02 13:05:23 -07001225 // 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 -08001226 if (!mActivities.remove(r) && r.fullscreen) {
1227 // Was not previously in list.
1228 numFullscreen++;
1229 }
Craig Mautner2c1faed2013-07-23 12:56:02 -07001230 // Only set this based on the first activity
1231 if (mActivities.isEmpty()) {
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001232 if (r.getActivityType() == ACTIVITY_TYPE_UNDEFINED) {
1233 // Normally non-standard activity type for the activity record will be set when the
1234 // object is created, however we delay setting the standard application type until
1235 // this point so that the task can set the type for additional activities added in
1236 // the else condition below.
1237 r.setActivityType(ACTIVITY_TYPE_STANDARD);
1238 }
1239 setActivityType(r.getActivityType());
Craig Mautner21d24a22014-04-23 11:45:37 -07001240 isPersistable = r.isPersistable();
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001241 mCallingUid = r.launchedFromUid;
1242 mCallingPackage = r.launchedFromPackage;
Dianne Hackborn852975d2014-08-22 17:42:43 -07001243 // Clamp to [1, max].
1244 maxRecents = Math.min(Math.max(r.info.maxRecents, 1),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001245 ActivityTaskManager.getMaxAppRecentsLimitStatic());
Craig Mautner2c1faed2013-07-23 12:56:02 -07001246 } else {
1247 // Otherwise make all added activities match this one.
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001248 r.setActivityType(getActivityType());
Craig Mautner78733002013-06-10 13:54:49 -07001249 }
Wale Ogunwale3b232392016-05-13 15:37:13 -07001250
1251 final int size = mActivities.size();
1252
1253 if (index == size && size > 0) {
1254 final ActivityRecord top = mActivities.get(size - 1);
1255 if (top.mTaskOverlay) {
1256 // Place below the task overlay activity since the overlay activity should always
1257 // be on top.
1258 index--;
1259 }
1260 }
1261
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001262 index = Math.min(size, index);
Craig Mautner77878772013-03-04 19:46:24 -08001263 mActivities.add(index, r);
Bryce Lee84730a02018-04-03 14:10:04 -07001264
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001265 updateEffectiveIntent();
Craig Mautner21d24a22014-04-23 11:45:37 -07001266 if (r.isPersistable()) {
1267 mService.notifyTaskPersisterLocked(this, false);
1268 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001269
1270 // Sync. with window manager
1271 updateOverrideConfigurationFromLaunchBounds();
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001272 final AppWindowContainerController appController = r.getWindowContainerController();
1273 if (appController != null) {
1274 // Only attempt to move in WM if the child has a controller. It is possible we haven't
1275 // created controller for the activity we are starting yet.
1276 mWindowContainerController.positionChildAt(appController, index);
1277 }
David Stevens82ea6cb2017-03-03 16:18:50 -08001278
1279 // Make sure the list of display UID whitelists is updated
1280 // now that this record is in a new task.
1281 mService.mStackSupervisor.updateUIDsPresentOnDisplay();
Craig Mautner77878772013-03-04 19:46:24 -08001282 }
1283
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001284 /**
Bryce Leeaf691c02017-03-20 14:20:22 -07001285 * Removes the specified activity from this task.
1286 * @param r The {@link ActivityRecord} to remove.
1287 * @return true if this was the last activity in the task.
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001288 */
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001289 boolean removeActivity(ActivityRecord r) {
Bryce Lee84730a02018-04-03 14:10:04 -07001290 return removeActivity(r, false /* reparenting */);
Bryce Leeaf691c02017-03-20 14:20:22 -07001291 }
1292
1293 boolean removeActivity(ActivityRecord r, boolean reparenting) {
1294 if (r.getTask() != this) {
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001295 throw new IllegalArgumentException(
1296 "Activity=" + r + " does not belong to task=" + this);
1297 }
1298
Bryce Lee84730a02018-04-03 14:10:04 -07001299 r.setTask(null /* task */, reparenting /* reparenting */);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001300
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001301 if (mActivities.remove(r) && r.fullscreen) {
1302 // Was previously in list.
1303 numFullscreen--;
1304 }
Craig Mautner21d24a22014-04-23 11:45:37 -07001305 if (r.isPersistable()) {
1306 mService.notifyTaskPersisterLocked(this, false);
1307 }
Wale Ogunwale89182d52016-03-11 10:38:36 -08001308
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001309 if (inPinnedWindowingMode()) {
Wale Ogunwale89182d52016-03-11 10:38:36 -08001310 // We normally notify listeners of task stack changes on pause, however pinned stack
1311 // activities are normally in the paused state so no notification will be sent there
1312 // before the activity is removed. We send it here so instead.
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001313 mService.getTaskChangeNotificationController().notifyTaskStackChanged();
Wale Ogunwale89182d52016-03-11 10:38:36 -08001314 }
1315
Craig Mautner41326202014-06-20 14:38:21 -07001316 if (mActivities.isEmpty()) {
Craig Mautner5afcd4d2014-06-21 18:11:33 -07001317 return !mReuseTask;
Craig Mautner41326202014-06-20 14:38:21 -07001318 }
1319 updateEffectiveIntent();
1320 return false;
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001321 }
1322
Winson Chung6954fc92017-03-24 16:22:12 -07001323 /**
1324 * @return whether or not there are ONLY task overlay activities in the stack.
1325 * If {@param excludeFinishing} is set, then ignore finishing activities in the check.
1326 * If there are no task overlay activities, this call returns false.
1327 */
1328 boolean onlyHasTaskOverlayActivities(boolean excludeFinishing) {
1329 int count = 0;
1330 for (int i = mActivities.size() - 1; i >= 0; i--) {
1331 final ActivityRecord r = mActivities.get(i);
1332 if (excludeFinishing && r.finishing) {
1333 continue;
1334 }
1335 if (!r.mTaskOverlay) {
1336 return false;
1337 }
1338 count++;
1339 }
1340 return count > 0;
1341 }
1342
Craig Mautner41db4a72014-05-07 17:20:56 -07001343 boolean autoRemoveFromRecents() {
Dianne Hackbornd38aed82014-06-10 21:36:35 -07001344 // We will automatically remove the task either if it has explicitly asked for
1345 // this, or it is empty and has never contained an activity that got shown to
1346 // the user.
Dianne Hackborn13420f22014-07-18 15:43:56 -07001347 return autoRemoveRecents || (mActivities.isEmpty() && !hasBeenVisible);
Craig Mautner41db4a72014-05-07 17:20:56 -07001348 }
1349
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001350 /**
1351 * Completely remove all activities associated with an existing
1352 * task starting at a specified index.
1353 */
Winson Chung0ec2a352017-10-26 11:38:30 -07001354 final void performClearTaskAtIndexLocked(int activityNdx, boolean pauseImmediately,
1355 String reason) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001356 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001357 for ( ; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001358 final ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001359 if (r.finishing) {
1360 continue;
1361 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07001362 if (mStack == null) {
Craig Mautner21d24a22014-04-23 11:45:37 -07001363 // Task was restored from persistent storage.
1364 r.takeFromHistory();
1365 mActivities.remove(activityNdx);
1366 --activityNdx;
1367 --numActivities;
Winson Chung6954fc92017-03-24 16:22:12 -07001368 } else if (mStack.finishActivityLocked(r, Activity.RESULT_CANCELED, null,
Winson Chung0ec2a352017-10-26 11:38:30 -07001369 reason, false, pauseImmediately)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001370 --activityNdx;
1371 --numActivities;
1372 }
1373 }
1374 }
1375
1376 /**
1377 * Completely remove all activities associated with an existing task.
1378 */
Benjamin Franza83859f2017-07-03 16:34:14 +01001379 void performClearTaskLocked() {
Craig Mautner362449a2014-06-20 14:04:39 -07001380 mReuseTask = true;
Winson Chung0ec2a352017-10-26 11:38:30 -07001381 performClearTaskAtIndexLocked(0, !PAUSE_IMMEDIATELY, "clear-task-all");
Craig Mautner362449a2014-06-20 14:04:39 -07001382 mReuseTask = false;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001383 }
1384
Filip Gruszczynskibe9dabd2016-01-19 12:23:10 -08001385 ActivityRecord performClearTaskForReuseLocked(ActivityRecord newR, int launchFlags) {
1386 mReuseTask = true;
1387 final ActivityRecord result = performClearTaskLocked(newR, launchFlags);
1388 mReuseTask = false;
1389 return result;
1390 }
1391
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001392 /**
1393 * Perform clear operation as requested by
1394 * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the
1395 * stack to the given task, then look for
1396 * an instance of that activity in the stack and, if found, finish all
1397 * activities on top of it and return the instance.
1398 *
1399 * @param newR Description of the new activity being started.
1400 * @return Returns the old activity that should be continued to be used,
1401 * or null if none was found.
1402 */
1403 final ActivityRecord performClearTaskLocked(ActivityRecord newR, int launchFlags) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001404 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001405 for (int activityNdx = numActivities - 1; activityNdx >= 0; --activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001406 ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001407 if (r.finishing) {
1408 continue;
1409 }
1410 if (r.realActivity.equals(newR.realActivity)) {
1411 // Here it is! Now finish everything in front...
Craig Mautner1602ec22013-05-12 10:24:27 -07001412 final ActivityRecord ret = r;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001413
1414 for (++activityNdx; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001415 r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001416 if (r.finishing) {
1417 continue;
1418 }
1419 ActivityOptions opts = r.takeOptionsLocked();
1420 if (opts != null) {
1421 ret.updateOptionsLocked(opts);
1422 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07001423 if (mStack != null && mStack.finishActivityLocked(
Todd Kennedy539db512014-12-15 09:57:55 -08001424 r, Activity.RESULT_CANCELED, null, "clear-task-stack", false)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001425 --activityNdx;
1426 --numActivities;
1427 }
1428 }
1429
1430 // Finally, if this is a normal launch mode (that is, not
1431 // expecting onNewIntent()), then we will finish the current
1432 // instance of the activity so a new fresh one can be started.
1433 if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE
Daichi Hirono15a02992016-04-27 18:47:01 +09001434 && (launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0
1435 && !ActivityStarter.isDocumentLaunchesIntoExisting(launchFlags)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001436 if (!ret.finishing) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001437 if (mStack != null) {
1438 mStack.finishActivityLocked(
Wale Ogunwale7d701172015-03-11 15:36:30 -07001439 ret, Activity.RESULT_CANCELED, null, "clear-task-top", false);
1440 }
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001441 return null;
1442 }
1443 }
1444
1445 return ret;
1446 }
1447 }
1448
1449 return null;
1450 }
1451
Winson Chung0ec2a352017-10-26 11:38:30 -07001452 void removeTaskActivitiesLocked(boolean pauseImmediately, String reason) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001453 // Just remove the entire task.
Winson Chung0ec2a352017-10-26 11:38:30 -07001454 performClearTaskAtIndexLocked(0, pauseImmediately, reason);
Craig Mautner9db9a0b2013-04-29 17:05:56 -07001455 }
1456
Craig Mautner432f64e2015-05-20 14:59:57 -07001457 String lockTaskAuthToString() {
1458 switch (mLockTaskAuth) {
1459 case LOCK_TASK_AUTH_DONT_LOCK: return "LOCK_TASK_AUTH_DONT_LOCK";
1460 case LOCK_TASK_AUTH_PINNABLE: return "LOCK_TASK_AUTH_PINNABLE";
1461 case LOCK_TASK_AUTH_LAUNCHABLE: return "LOCK_TASK_AUTH_LAUNCHABLE";
1462 case LOCK_TASK_AUTH_WHITELISTED: return "LOCK_TASK_AUTH_WHITELISTED";
Benjamin Franz469dd582015-06-09 14:24:36 +01001463 case LOCK_TASK_AUTH_LAUNCHABLE_PRIV: return "LOCK_TASK_AUTH_LAUNCHABLE_PRIV";
Craig Mautner432f64e2015-05-20 14:59:57 -07001464 default: return "unknown=" + mLockTaskAuth;
1465 }
1466 }
1467
Craig Mautner15df08a2015-04-01 12:17:18 -07001468 void setLockTaskAuth() {
Charles He2bf28322017-10-12 22:24:49 +01001469 setLockTaskAuth(getRootActivity());
1470 }
1471
1472 private void setLockTaskAuth(@Nullable ActivityRecord r) {
1473 if (r == null) {
1474 mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE;
1475 return;
1476 }
1477
Charles He520b2832017-09-02 15:27:16 +01001478 final String pkg = (realActivity != null) ? realActivity.getPackageName() : null;
Bryce Lee2b8e0372018-04-05 17:01:37 -07001479 final LockTaskController lockTaskController = mService.getLockTaskController();
Charles He2bf28322017-10-12 22:24:49 +01001480 switch (r.lockTaskLaunchMode) {
Craig Mautner15df08a2015-04-01 12:17:18 -07001481 case LOCK_TASK_LAUNCH_MODE_DEFAULT:
Bryce Lee2b8e0372018-04-05 17:01:37 -07001482 mLockTaskAuth = lockTaskController.isPackageWhitelisted(userId, pkg)
Charles He520b2832017-09-02 15:27:16 +01001483 ? LOCK_TASK_AUTH_WHITELISTED : LOCK_TASK_AUTH_PINNABLE;
Craig Mautner15df08a2015-04-01 12:17:18 -07001484 break;
1485
1486 case LOCK_TASK_LAUNCH_MODE_NEVER:
Benjamin Franz469dd582015-06-09 14:24:36 +01001487 mLockTaskAuth = LOCK_TASK_AUTH_DONT_LOCK;
Craig Mautner15df08a2015-04-01 12:17:18 -07001488 break;
1489
1490 case LOCK_TASK_LAUNCH_MODE_ALWAYS:
Benjamin Franz469dd582015-06-09 14:24:36 +01001491 mLockTaskAuth = LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
Craig Mautner15df08a2015-04-01 12:17:18 -07001492 break;
1493
1494 case LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED:
Bryce Lee2b8e0372018-04-05 17:01:37 -07001495 mLockTaskAuth = lockTaskController.isPackageWhitelisted(userId, pkg)
Charles He520b2832017-09-02 15:27:16 +01001496 ? LOCK_TASK_AUTH_LAUNCHABLE : LOCK_TASK_AUTH_PINNABLE;
Craig Mautner15df08a2015-04-01 12:17:18 -07001497 break;
1498 }
Craig Mautner432f64e2015-05-20 14:59:57 -07001499 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
1500 " mLockTaskAuth=" + lockTaskAuthToString());
Craig Mautner15df08a2015-04-01 12:17:18 -07001501 }
1502
Winson Chungd3395382016-12-13 11:49:09 -08001503 private boolean isResizeable(boolean checkSupportsPip) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001504 return (mService.mForceResizableActivities || ActivityInfo.isResizeableMode(mResizeMode)
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -07001505 || (checkSupportsPip && mSupportsPictureInPicture));
Winson Chungd3395382016-12-13 11:49:09 -08001506 }
1507
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001508 boolean isResizeable() {
Winson Chungd3395382016-12-13 11:49:09 -08001509 return isResizeable(true /* checkSupportsPip */);
1510 }
1511
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001512 @Override
1513 public boolean supportsSplitScreenWindowingMode() {
Winson Chungd3395382016-12-13 11:49:09 -08001514 // A task can not be docked even if it is considered resizeable because it only supports
1515 // picture-in-picture mode but has a non-resizeable resizeMode
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001516 return super.supportsSplitScreenWindowingMode()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001517 && mService.mSupportsSplitScreenMultiWindow
1518 && (mService.mForceResizableActivities
Bryce Leec857a5b2017-08-16 10:04:52 -07001519 || (isResizeable(false /* checkSupportsPip */)
1520 && !ActivityInfo.isPreserveOrientationMode(mResizeMode)));
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001521 }
1522
skuhne@google.com322347b2016-12-02 12:54:03 -08001523 /**
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001524 * Check whether this task can be launched on the specified display.
Riddle Hsu16567132018-08-16 21:37:47 +08001525 *
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001526 * @param displayId Target display id.
Riddle Hsu16567132018-08-16 21:37:47 +08001527 * @return {@code true} if either it is the default display or this activity can be put on a
1528 * secondary display.
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001529 */
1530 boolean canBeLaunchedOnDisplay(int displayId) {
1531 return mService.mStackSupervisor.canPlaceEntityOnDisplay(displayId,
Riddle Hsu16567132018-08-16 21:37:47 +08001532 -1 /* don't check PID */, -1 /* don't check UID */, null /* activityInfo */);
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001533 }
1534
1535 /**
skuhne@google.com322347b2016-12-02 12:54:03 -08001536 * Check that a given bounds matches the application requested orientation.
1537 *
1538 * @param bounds The bounds to be tested.
1539 * @return True if the requested bounds are okay for a resizing request.
1540 */
Wale Ogunwale069bbd32017-02-03 07:58:14 -08001541 private boolean canResizeToBounds(Rect bounds) {
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001542 if (bounds == null || !inFreeformWindowingMode()) {
skuhne@google.com322347b2016-12-02 12:54:03 -08001543 // Note: If not on the freeform workspace, we ignore the bounds.
1544 return true;
1545 }
1546 final boolean landscape = bounds.width() > bounds.height();
Bryce Leef3c6a472017-11-14 14:53:06 -08001547 final Rect configBounds = getOverrideBounds();
skuhne@google.com322347b2016-12-02 12:54:03 -08001548 if (mResizeMode == RESIZE_MODE_FORCE_RESIZABLE_PRESERVE_ORIENTATION) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001549 return configBounds.isEmpty()
1550 || landscape == (configBounds.width() > configBounds.height());
skuhne@google.com322347b2016-12-02 12:54:03 -08001551 }
1552 return (mResizeMode != RESIZE_MODE_FORCE_RESIZABLE_PORTRAIT_ONLY || !landscape)
1553 && (mResizeMode != RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY || landscape);
1554 }
1555
Craig Mautner525f3d92013-05-07 14:01:50 -07001556 /**
Yorke Leebdef5372017-04-10 16:38:51 -07001557 * @return {@code true} if the task is being cleared for the purposes of being reused.
1558 */
1559 boolean isClearingToReuseTask() {
1560 return mReuseTask;
1561 }
1562
1563 /**
Craig Mautner525f3d92013-05-07 14:01:50 -07001564 * Find the activity in the history stack within the given task. Returns
1565 * the index within the history at which it's found, or < 0 if not found.
1566 */
1567 final ActivityRecord findActivityInHistoryLocked(ActivityRecord r) {
1568 final ComponentName realActivity = r.realActivity;
1569 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1570 ActivityRecord candidate = mActivities.get(activityNdx);
1571 if (candidate.finishing) {
1572 continue;
1573 }
1574 if (candidate.realActivity.equals(realActivity)) {
1575 return candidate;
1576 }
1577 }
1578 return null;
1579 }
1580
Winson Chunga449dc02014-05-16 11:15:04 -07001581 /** Updates the last task description values. */
1582 void updateTaskDescription() {
1583 // Traverse upwards looking for any break between main task activities and
1584 // utility activities.
1585 int activityNdx;
1586 final int numActivities = mActivities.size();
Wale Ogunwale3eadad72016-10-13 09:16:59 -07001587 final boolean relinquish = numActivities != 0 &&
1588 (mActivities.get(0).info.flags & FLAG_RELINQUISH_TASK_IDENTITY) != 0;
Winson Chunga449dc02014-05-16 11:15:04 -07001589 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
Craig Mautner21d24a22014-04-23 11:45:37 -07001590 ++activityNdx) {
Winson Chunga449dc02014-05-16 11:15:04 -07001591 final ActivityRecord r = mActivities.get(activityNdx);
Wale Ogunwale3eadad72016-10-13 09:16:59 -07001592 if (relinquish && (r.info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001593 // This will be the top activity for determining taskDescription. Pre-inc to
1594 // overcome initial decrement below.
1595 ++activityNdx;
1596 break;
1597 }
Winson Chunga449dc02014-05-16 11:15:04 -07001598 if (r.intent != null &&
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001599 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
Winson Chunga449dc02014-05-16 11:15:04 -07001600 break;
1601 }
1602 }
1603 if (activityNdx > 0) {
1604 // Traverse downwards starting below break looking for set label, icon.
1605 // Note that if there are activities in the task but none of them set the
1606 // recent activity values, then we do not fall back to the last set
1607 // values in the TaskRecord.
1608 String label = null;
Craig Mautner648f69b2014-09-18 14:16:26 -07001609 String iconFilename = null;
Matthew Ng54bc9422017-10-02 17:16:28 -07001610 int iconResource = -1;
Winson Chunga449dc02014-05-16 11:15:04 -07001611 int colorPrimary = 0;
Winson Chung1af8eda2016-02-05 17:55:56 +00001612 int colorBackground = 0;
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001613 int statusBarColor = 0;
1614 int navigationBarColor = 0;
1615 boolean topActivity = true;
Winson Chunga449dc02014-05-16 11:15:04 -07001616 for (--activityNdx; activityNdx >= 0; --activityNdx) {
1617 final ActivityRecord r = mActivities.get(activityNdx);
Winson Chung80f80db2018-05-30 21:13:25 -07001618 if (r.mTaskOverlay) {
1619 continue;
1620 }
Winson Chunga449dc02014-05-16 11:15:04 -07001621 if (r.taskDescription != null) {
1622 if (label == null) {
1623 label = r.taskDescription.getLabel();
1624 }
Matthew Ng54bc9422017-10-02 17:16:28 -07001625 if (iconResource == -1) {
1626 iconResource = r.taskDescription.getIconResource();
1627 }
Craig Mautner648f69b2014-09-18 14:16:26 -07001628 if (iconFilename == null) {
1629 iconFilename = r.taskDescription.getIconFilename();
Winson Chunga449dc02014-05-16 11:15:04 -07001630 }
1631 if (colorPrimary == 0) {
1632 colorPrimary = r.taskDescription.getPrimaryColor();
Winson Chunga449dc02014-05-16 11:15:04 -07001633 }
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001634 if (topActivity) {
Winson Chung1af8eda2016-02-05 17:55:56 +00001635 colorBackground = r.taskDescription.getBackgroundColor();
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001636 statusBarColor = r.taskDescription.getStatusBarColor();
1637 navigationBarColor = r.taskDescription.getNavigationBarColor();
Winson Chung1af8eda2016-02-05 17:55:56 +00001638 }
Winson Chunga449dc02014-05-16 11:15:04 -07001639 }
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001640 topActivity = false;
Winson Chunga449dc02014-05-16 11:15:04 -07001641 }
Matthew Ng54bc9422017-10-02 17:16:28 -07001642 lastTaskDescription = new TaskDescription(label, null, iconResource, iconFilename,
1643 colorPrimary, colorBackground, statusBarColor, navigationBarColor);
Jorim Jaggi829b9cd2017-01-23 16:20:53 +01001644 if (mWindowContainerController != null) {
1645 mWindowContainerController.setTaskDescription(lastTaskDescription);
1646 }
Winson Chungec396d62014-08-06 17:08:00 -07001647 // Update the task affiliation color if we are the parent of the group
1648 if (taskId == mAffiliatedTaskId) {
1649 mAffiliatedTaskColor = lastTaskDescription.getPrimaryColor();
1650 }
Winson Chunga449dc02014-05-16 11:15:04 -07001651 }
1652 }
1653
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001654 int findEffectiveRootIndex() {
Craig Mautner4767f4b2014-09-18 15:38:33 -07001655 int effectiveNdx = 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001656 final int topActivityNdx = mActivities.size() - 1;
Dianne Hackborn39569af2014-09-23 10:56:58 -07001657 for (int activityNdx = 0; activityNdx <= topActivityNdx; ++activityNdx) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001658 final ActivityRecord r = mActivities.get(activityNdx);
1659 if (r.finishing) {
1660 continue;
1661 }
Craig Mautner4767f4b2014-09-18 15:38:33 -07001662 effectiveNdx = activityNdx;
Wale Ogunwale3eadad72016-10-13 09:16:59 -07001663 if ((r.info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001664 break;
1665 }
1666 }
Craig Mautner4767f4b2014-09-18 15:38:33 -07001667 return effectiveNdx;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001668 }
1669
1670 void updateEffectiveIntent() {
1671 final int effectiveRootIndex = findEffectiveRootIndex();
1672 final ActivityRecord r = mActivities.get(effectiveRootIndex);
Winson Chungfee26772014-08-05 12:21:52 -07001673 setIntent(r);
Winson Chung8d9009e2017-11-16 15:43:05 -08001674
1675 // Update the task description when the activities change
1676 updateTaskDescription();
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001677 }
1678
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001679 private void adjustForMinimalTaskDimensions(Rect bounds) {
1680 if (bounds == null) {
1681 return;
1682 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001683 int minWidth = mMinWidth;
1684 int minHeight = mMinHeight;
Robert Carr9c5867d2016-03-10 15:52:46 -08001685 // If the task has no requested minimal size, we'd like to enforce a minimal size
1686 // so that the user can not render the task too small to manipulate. We don't need
1687 // to do this for the pinned stack as the bounds are controlled by the system.
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001688 if (!inPinnedWindowingMode()) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001689 if (minWidth == INVALID_MIN_SIZE) {
1690 minWidth = mService.mStackSupervisor.mDefaultMinSizeOfResizeableTask;
Andrii Kulian2e751b82016-03-16 16:59:32 -07001691 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001692 if (minHeight == INVALID_MIN_SIZE) {
1693 minHeight = mService.mStackSupervisor.mDefaultMinSizeOfResizeableTask;
Andrii Kulian2e751b82016-03-16 16:59:32 -07001694 }
Robert Carr9c5867d2016-03-10 15:52:46 -08001695 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001696 final boolean adjustWidth = minWidth > bounds.width();
1697 final boolean adjustHeight = minHeight > bounds.height();
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001698 if (!(adjustWidth || adjustHeight)) {
1699 return;
1700 }
1701
Bryce Leef3c6a472017-11-14 14:53:06 -08001702 final Rect configBounds = getOverrideBounds();
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001703 if (adjustWidth) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001704 if (!configBounds.isEmpty() && bounds.right == configBounds.right) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001705 bounds.left = bounds.right - minWidth;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001706 } else {
1707 // Either left bounds match, or neither match, or the previous bounds were
1708 // fullscreen and we default to keeping left.
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001709 bounds.right = bounds.left + minWidth;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001710 }
1711 }
1712 if (adjustHeight) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001713 if (!configBounds.isEmpty() && bounds.bottom == configBounds.bottom) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001714 bounds.top = bounds.bottom - minHeight;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001715 } else {
1716 // Either top bounds match, or neither match, or the previous bounds were
1717 // fullscreen and we default to keeping top.
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001718 bounds.bottom = bounds.top + minHeight;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001719 }
1720 }
1721 }
1722
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001723 /**
Winson Chung5af42fc2017-03-24 17:11:33 -07001724 * @return a new Configuration for this Task, given the provided {@param bounds} and
1725 * {@param insetBounds}.
1726 */
1727 Configuration computeNewOverrideConfigurationForBounds(Rect bounds, Rect insetBounds) {
1728 // Compute a new override configuration for the given bounds, if fullscreen bounds
1729 // (bounds == null), then leave the override config unset
1730 final Configuration newOverrideConfig = new Configuration();
1731 if (bounds != null) {
1732 newOverrideConfig.setTo(getOverrideConfiguration());
1733 mTmpRect.set(bounds);
1734 adjustForMinimalTaskDimensions(mTmpRect);
1735 computeOverrideConfiguration(newOverrideConfig, mTmpRect, insetBounds,
1736 mTmpRect.right != bounds.right, mTmpRect.bottom != bounds.bottom);
1737 }
1738
1739 return newOverrideConfig;
1740 }
1741
1742 /**
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001743 * Update task's override configuration based on the bounds.
Jorim Jaggi0a932142016-02-01 17:42:25 -08001744 * @param bounds The bounds of the task.
Andrii Kulian8072d112016-09-16 11:11:01 -07001745 * @return True if the override configuration was updated.
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001746 */
Andrii Kulian8072d112016-09-16 11:11:01 -07001747 boolean updateOverrideConfiguration(Rect bounds) {
Jorim Jaggi0a932142016-02-01 17:42:25 -08001748 return updateOverrideConfiguration(bounds, null /* insetBounds */);
1749 }
1750
Evan Rosky9ba524e2018-01-03 16:27:56 -08001751 void setLastNonFullscreenBounds(Rect bounds) {
1752 if (mLastNonFullscreenBounds == null) {
1753 mLastNonFullscreenBounds = new Rect(bounds);
1754 } else {
1755 mLastNonFullscreenBounds.set(bounds);
1756 }
1757 }
1758
Jorim Jaggi0a932142016-02-01 17:42:25 -08001759 /**
1760 * Update task's override configuration based on the bounds.
1761 * @param bounds The bounds of the task.
1762 * @param insetBounds The bounds used to calculate the system insets, which is used here to
1763 * subtract the navigation bar/status bar size from the screen size reported
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001764 * to the application. See {@link IActivityTaskManager#resizeDockedStack}.
Andrii Kulian8072d112016-09-16 11:11:01 -07001765 * @return True if the override configuration was updated.
Jorim Jaggi0a932142016-02-01 17:42:25 -08001766 */
Andrii Kulian8072d112016-09-16 11:11:01 -07001767 boolean updateOverrideConfiguration(Rect bounds, @Nullable Rect insetBounds) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001768 if (equivalentOverrideBounds(bounds)) {
Andrii Kulian8072d112016-09-16 11:11:01 -07001769 return false;
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001770 }
Bryce Leef3c6a472017-11-14 14:53:06 -08001771 final Rect currentBounds = getOverrideBounds();
1772
Andrii Kulian1779e612016-10-12 21:58:25 -07001773 mTmpConfig.setTo(getOverrideConfiguration());
Andrii Kulian1779e612016-10-12 21:58:25 -07001774 final Configuration newConfig = getOverrideConfiguration();
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001775
Bryce Leef3c6a472017-11-14 14:53:06 -08001776 final boolean matchParentBounds = bounds == null || bounds.isEmpty();
Wale Ogunwale3382ab12017-07-27 08:55:03 -07001777 final boolean persistBounds = getWindowConfiguration().persistTaskBounds();
Bryce Leef3c6a472017-11-14 14:53:06 -08001778 if (matchParentBounds) {
1779 if (!currentBounds.isEmpty() && persistBounds) {
Evan Rosky9ba524e2018-01-03 16:27:56 -08001780 setLastNonFullscreenBounds(currentBounds);
Wale Ogunwale706ed792015-08-02 10:29:44 -07001781 }
Bryce Leef3c6a472017-11-14 14:53:06 -08001782 setBounds(null);
Andrii Kulian1779e612016-10-12 21:58:25 -07001783 newConfig.unset();
Wale Ogunwale706ed792015-08-02 10:29:44 -07001784 } else {
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001785 mTmpRect.set(bounds);
1786 adjustForMinimalTaskDimensions(mTmpRect);
Bryce Leef3c6a472017-11-14 14:53:06 -08001787 setBounds(mTmpRect);
1788
Wale Ogunwale3382ab12017-07-27 08:55:03 -07001789 if (mStack == null || persistBounds) {
Evan Rosky9ba524e2018-01-03 16:27:56 -08001790 setLastNonFullscreenBounds(getOverrideBounds());
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -07001791 }
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07001792 computeOverrideConfiguration(newConfig, mTmpRect, insetBounds,
Andrii Kuliandaea3572016-04-08 13:20:51 -07001793 mTmpRect.right != bounds.right, mTmpRect.bottom != bounds.bottom);
Wale Ogunwale706ed792015-08-02 10:29:44 -07001794 }
Andrii Kulian1779e612016-10-12 21:58:25 -07001795 onOverrideConfigurationChanged(newConfig);
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08001796 return !mTmpConfig.equals(newConfig);
1797 }
Wale Ogunwale5f986092015-12-04 15:35:38 -08001798
Bryce Leec4ab62a2018-03-05 14:19:26 -08001799 /**
1800 * This should be called when an child activity changes state. This should only
1801 * be called from
1802 * {@link ActivityRecord#setState(ActivityState, String)} .
1803 * @param record The {@link ActivityRecord} whose state has changed.
1804 * @param state The new state.
1805 * @param reason The reason for the change.
1806 */
1807 void onActivityStateChanged(ActivityRecord record, ActivityState state, String reason) {
1808 final ActivityStack parent = getStack();
1809
1810 if (parent != null) {
1811 parent.onActivityStateChanged(record, state, reason);
1812 }
1813 }
1814
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08001815 @Override
1816 public void onConfigurationChanged(Configuration newParentConfig) {
1817 final boolean wasInMultiWindowMode = inMultiWindowMode();
1818 super.onConfigurationChanged(newParentConfig);
1819 if (wasInMultiWindowMode != inMultiWindowMode()) {
Winson Chung5af42fc2017-03-24 17:11:33 -07001820 mService.mStackSupervisor.scheduleUpdateMultiWindowMode(this);
Wale Ogunwale5f986092015-12-04 15:35:38 -08001821 }
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08001822 // TODO: Should also take care of Pip mode changes here.
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001823 }
1824
Andrii Kulian1779e612016-10-12 21:58:25 -07001825 /** Clears passed config and fills it with new override values. */
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07001826 // TODO(b/36505427): TaskRecord.computeOverrideConfiguration() is a utility method that doesn't
1827 // depend on task or stacks, but uses those object to get the display to base the calculation
1828 // on. Probably best to centralize calculations like this in ConfigurationContainer.
1829 void computeOverrideConfiguration(Configuration config, Rect bounds, Rect insetBounds,
Andrii Kuliana8a9bc52016-10-14 11:00:13 -07001830 boolean overrideWidth, boolean overrideHeight) {
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001831 mTmpNonDecorBounds.set(bounds);
1832 mTmpStableBounds.set(bounds);
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001833
Andrii Kulian1779e612016-10-12 21:58:25 -07001834 config.unset();
Winson Chungbdc646f2017-02-13 12:12:22 -08001835 final Configuration parentConfig = getParent().getConfiguration();
Bryce Lee7566d762017-03-30 09:34:15 -07001836
Andrii Kulian1779e612016-10-12 21:58:25 -07001837 final float density = parentConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001838
Winson Chungbdc646f2017-02-13 12:12:22 -08001839 if (mStack != null) {
1840 final StackWindowController stackController = mStack.getWindowContainerController();
1841 stackController.adjustConfigurationForBounds(bounds, insetBounds,
1842 mTmpNonDecorBounds, mTmpStableBounds, overrideWidth, overrideHeight, density,
Evan Roskyb0e38882018-04-25 12:48:54 -07001843 config, parentConfig, getWindowingMode());
Winson Chungbdc646f2017-02-13 12:12:22 -08001844 } else {
Bryce Lee7566d762017-03-30 09:34:15 -07001845 throw new IllegalArgumentException("Expected stack when calculating override config");
Winson Chungbdc646f2017-02-13 12:12:22 -08001846 }
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001847
Winson Chung60c1aba2017-03-14 17:47:42 -07001848 config.orientation = (config.screenWidthDp <= config.screenHeightDp)
1849 ? Configuration.ORIENTATION_PORTRAIT
1850 : Configuration.ORIENTATION_LANDSCAPE;
1851
Jorim Jaggi85639432016-05-06 17:27:55 -07001852 // For calculating screen layout, we need to use the non-decor inset screen area for the
1853 // calculation for compatibility reasons, i.e. screen area without system bars that could
1854 // never go away in Honeycomb.
Winson Chungbdc646f2017-02-13 12:12:22 -08001855 final int compatScreenWidthDp = (int) (mTmpNonDecorBounds.width() / density);
1856 final int compatScreenHeightDp = (int) (mTmpNonDecorBounds.height() / density);
Andrii Kulian1779e612016-10-12 21:58:25 -07001857 // We're only overriding LONG, SIZE and COMPAT parts of screenLayout, so we start override
1858 // calculation with partial default.
Louis Chang8b580162018-06-26 17:58:29 +08001859 // Reducing the screen layout starting from its parent config.
1860 final int sl = parentConfig.screenLayout &
1861 (Configuration.SCREENLAYOUT_LONG_MASK | Configuration.SCREENLAYOUT_SIZE_MASK);
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001862 final int longSize = Math.max(compatScreenHeightDp, compatScreenWidthDp);
Andrii Kulian1779e612016-10-12 21:58:25 -07001863 final int shortSize = Math.min(compatScreenHeightDp, compatScreenWidthDp);
Jorim Jaggi85639432016-05-06 17:27:55 -07001864 config.screenLayout = Configuration.reduceScreenLayout(sl, longSize, shortSize);
Jorim Jaggia95ca8d2016-01-15 22:54:46 -08001865 }
1866
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08001867 Rect updateOverrideConfigurationFromLaunchBounds() {
Bryce Leef3c6a472017-11-14 14:53:06 -08001868 final Rect bounds = getLaunchBounds();
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08001869 updateOverrideConfiguration(bounds);
Bryce Leef3c6a472017-11-14 14:53:06 -08001870 if (bounds != null && !bounds.isEmpty()) {
1871 // TODO: Review if we actually want to do this - we are setting the launch bounds
1872 // directly here.
1873 bounds.set(getOverrideBounds());
Andrii Kulian73336d812016-03-24 12:56:08 -07001874 }
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08001875 return bounds;
1876 }
1877
Wale Ogunwale935e5022015-11-10 12:36:10 -08001878 /** Updates the task's bounds and override configuration to match what is expected for the
1879 * input stack. */
1880 void updateOverrideConfigurationForStack(ActivityStack inStack) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001881 if (mStack != null && mStack == inStack) {
Wale Ogunwale935e5022015-11-10 12:36:10 -08001882 return;
1883 }
1884
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001885 if (inStack.inFreeformWindowingMode()) {
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001886 if (!isResizeable()) {
Wale Ogunwale935e5022015-11-10 12:36:10 -08001887 throw new IllegalArgumentException("Can not position non-resizeable task="
1888 + this + " in stack=" + inStack);
1889 }
Bryce Leef3c6a472017-11-14 14:53:06 -08001890 if (!matchParentBounds()) {
Wale Ogunwale935e5022015-11-10 12:36:10 -08001891 return;
1892 }
1893 if (mLastNonFullscreenBounds != null) {
1894 updateOverrideConfiguration(mLastNonFullscreenBounds);
1895 } else {
Bryce Leeec55eb02017-12-05 20:51:27 -08001896 mService.mStackSupervisor.getLaunchParamsController().layoutTask(this, null);
Wale Ogunwale935e5022015-11-10 12:36:10 -08001897 }
1898 } else {
Bryce Leef3c6a472017-11-14 14:53:06 -08001899 updateOverrideConfiguration(inStack.getOverrideBounds());
Wale Ogunwale935e5022015-11-10 12:36:10 -08001900 }
1901 }
1902
Wale Ogunwale706ed792015-08-02 10:29:44 -07001903 /** Returns the bounds that should be used to launch this task. */
Wale Ogunwale30e441d2017-11-09 08:28:45 -08001904 Rect getLaunchBounds() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001905 if (mStack == null) {
Chong Zhang7d5f5102016-01-13 10:29:24 -08001906 return null;
1907 }
1908
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001909 final int windowingMode = getWindowingMode();
1910 if (!isActivityTypeStandardOrUndefined()
1911 || windowingMode == WINDOWING_MODE_FULLSCREEN
1912 || (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY && !isResizeable())) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001913 return isResizeable() ? mStack.getOverrideBounds() : null;
Wale Ogunwale3382ab12017-07-27 08:55:03 -07001914 } else if (!getWindowConfiguration().persistTaskBounds()) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001915 return mStack.getOverrideBounds();
Wale Ogunwale706ed792015-08-02 10:29:44 -07001916 }
1917 return mLastNonFullscreenBounds;
1918 }
1919
Jorim Jaggi8b702ed2017-01-20 16:59:03 +01001920 void addStartingWindowsForVisibleActivities(boolean taskSwitch) {
1921 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1922 final ActivityRecord r = mActivities.get(activityNdx);
1923 if (r.visible) {
1924 r.showStartingWindow(null /* prev */, false /* newTask */, taskSwitch);
1925 }
1926 }
1927 }
1928
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001929 void setRootProcess(WindowProcessController proc) {
Dianne Hackborn68a06332017-11-15 17:54:18 -08001930 clearRootProcess();
1931 if (intent != null &&
1932 (intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0) {
1933 mRootProcess = proc;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001934 mRootProcess.addRecentTask(this);
Dianne Hackborn68a06332017-11-15 17:54:18 -08001935 }
1936 }
1937
1938 void clearRootProcess() {
1939 if (mRootProcess != null) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001940 mRootProcess.removeRecentTask(this);
Dianne Hackborn68a06332017-11-15 17:54:18 -08001941 mRootProcess = null;
1942 }
1943 }
1944
chaviw82a0ba82018-03-15 14:26:29 -07001945 void clearAllPendingOptions() {
1946 for (int i = getChildCount() - 1; i >= 0; i--) {
1947 getChildAt(i).clearOptionsLocked(false /* withAbort */);
1948 }
1949 }
1950
Winson Chungabfdcce2018-07-02 17:23:33 -07001951 /**
1952 * Fills in a {@link TaskInfo} with information from this task.
1953 * @param info the {@link TaskInfo} to fill in
1954 * @param reuseActivitiesReport a temporary activities report that we can reuse to fetch the
1955 * running activities
1956 */
1957 void fillTaskInfo(TaskInfo info, TaskActivitiesReport reuseActivitiesReport) {
1958 getNumRunningActivities(reuseActivitiesReport);
1959 info.userId = userId;
1960 info.stackId = getStackId();
1961 info.taskId = taskId;
1962 info.isRunning = getTopActivity() != null;
1963 info.baseIntent = getBaseIntent();
1964 info.baseActivity = reuseActivitiesReport.base != null
1965 ? reuseActivitiesReport.base.intent.getComponent()
1966 : null;
1967 info.topActivity = reuseActivitiesReport.top != null
1968 ? reuseActivitiesReport.top.intent.getComponent()
1969 : null;
1970 info.origActivity = origActivity;
1971 info.realActivity = realActivity;
1972 info.numActivities = reuseActivitiesReport.numActivities;
1973 info.lastActiveTime = lastActiveTime;
1974 info.taskDescription = new ActivityManager.TaskDescription(lastTaskDescription);
1975 info.supportsSplitScreenMultiWindow = supportsSplitScreenWindowingMode();
1976 info.resizeMode = mResizeMode;
1977 info.configuration.setTo(getConfiguration());
1978 }
1979
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001980 void dump(PrintWriter pw, String prefix) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001981 pw.print(prefix); pw.print("userId="); pw.print(userId);
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001982 pw.print(" effectiveUid="); UserHandle.formatUid(pw, effectiveUid);
1983 pw.print(" mCallingUid="); UserHandle.formatUid(pw, mCallingUid);
Suprabh Shukla7745c142016-03-07 18:21:10 -08001984 pw.print(" mUserSetupComplete="); pw.print(mUserSetupComplete);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001985 pw.print(" mCallingPackage="); pw.println(mCallingPackage);
Dianne Hackborn79228822014-09-16 11:11:23 -07001986 if (affinity != null || rootAffinity != null) {
1987 pw.print(prefix); pw.print("affinity="); pw.print(affinity);
1988 if (affinity == null || !affinity.equals(rootAffinity)) {
1989 pw.print(" root="); pw.println(rootAffinity);
1990 } else {
1991 pw.println();
1992 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001993 }
Dianne Hackborn91097de2014-04-04 18:02:06 -07001994 if (voiceSession != null || voiceInteractor != null) {
1995 pw.print(prefix); pw.print("VOICE: session=0x");
1996 pw.print(Integer.toHexString(System.identityHashCode(voiceSession)));
1997 pw.print(" interactor=0x");
1998 pw.println(Integer.toHexString(System.identityHashCode(voiceInteractor)));
1999 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002000 if (intent != null) {
2001 StringBuilder sb = new StringBuilder(128);
2002 sb.append(prefix); sb.append("intent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08002003 intent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002004 sb.append('}');
2005 pw.println(sb.toString());
2006 }
2007 if (affinityIntent != null) {
2008 StringBuilder sb = new StringBuilder(128);
2009 sb.append(prefix); sb.append("affinityIntent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08002010 affinityIntent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002011 sb.append('}');
2012 pw.println(sb.toString());
2013 }
2014 if (origActivity != null) {
2015 pw.print(prefix); pw.print("origActivity=");
2016 pw.println(origActivity.flattenToShortString());
2017 }
2018 if (realActivity != null) {
2019 pw.print(prefix); pw.print("realActivity=");
2020 pw.println(realActivity.flattenToShortString());
2021 }
Wale Ogunwale66e16852017-10-19 13:35:52 -07002022 if (autoRemoveRecents || isPersistable || !isActivityTypeStandard() || numFullscreen != 0) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002023 pw.print(prefix); pw.print("autoRemoveRecents="); pw.print(autoRemoveRecents);
Dianne Hackborn852975d2014-08-22 17:42:43 -07002024 pw.print(" isPersistable="); pw.print(isPersistable);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002025 pw.print(" numFullscreen="); pw.print(numFullscreen);
Wale Ogunwale66e16852017-10-19 13:35:52 -07002026 pw.print(" activityType="); pw.println(getActivityType());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002027 }
Craig Mautner432f64e2015-05-20 14:59:57 -07002028 if (rootWasReset || mNeverRelinquishIdentity || mReuseTask
2029 || mLockTaskAuth != LOCK_TASK_AUTH_PINNABLE) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002030 pw.print(prefix); pw.print("rootWasReset="); pw.print(rootWasReset);
2031 pw.print(" mNeverRelinquishIdentity="); pw.print(mNeverRelinquishIdentity);
Craig Mautner432f64e2015-05-20 14:59:57 -07002032 pw.print(" mReuseTask="); pw.print(mReuseTask);
2033 pw.print(" mLockTaskAuth="); pw.println(lockTaskAuthToString());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002034 }
Wale Ogunwale18795a22014-12-03 11:38:33 -08002035 if (mAffiliatedTaskId != taskId || mPrevAffiliateTaskId != INVALID_TASK_ID
2036 || mPrevAffiliate != null || mNextAffiliateTaskId != INVALID_TASK_ID
2037 || mNextAffiliate != null) {
Dianne Hackborn852975d2014-08-22 17:42:43 -07002038 pw.print(prefix); pw.print("affiliation="); pw.print(mAffiliatedTaskId);
2039 pw.print(" prevAffiliation="); pw.print(mPrevAffiliateTaskId);
2040 pw.print(" (");
2041 if (mPrevAffiliate == null) {
2042 pw.print("null");
2043 } else {
2044 pw.print(Integer.toHexString(System.identityHashCode(mPrevAffiliate)));
2045 }
2046 pw.print(") nextAffiliation="); pw.print(mNextAffiliateTaskId);
2047 pw.print(" (");
2048 if (mNextAffiliate == null) {
2049 pw.print("null");
2050 } else {
2051 pw.print(Integer.toHexString(System.identityHashCode(mNextAffiliate)));
2052 }
2053 pw.println(")");
2054 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002055 pw.print(prefix); pw.print("Activities="); pw.println(mActivities);
Dianne Hackborn852975d2014-08-22 17:42:43 -07002056 if (!askedCompatMode || !inRecents || !isAvailable) {
2057 pw.print(prefix); pw.print("askedCompatMode="); pw.print(askedCompatMode);
2058 pw.print(" inRecents="); pw.print(inRecents);
2059 pw.print(" isAvailable="); pw.println(isAvailable);
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002060 }
Dianne Hackborn852975d2014-08-22 17:42:43 -07002061 if (lastDescription != null) {
2062 pw.print(prefix); pw.print("lastDescription="); pw.println(lastDescription);
2063 }
Dianne Hackborn68a06332017-11-15 17:54:18 -08002064 if (mRootProcess != null) {
2065 pw.print(prefix); pw.print("mRootProcess="); pw.println(mRootProcess);
2066 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07002067 pw.print(prefix); pw.print("stackId="); pw.println(getStackId());
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002068 pw.print(prefix + "hasBeenVisible=" + hasBeenVisible);
2069 pw.print(" mResizeMode=" + ActivityInfo.resizeModeToString(mResizeMode));
Winson Chungd3395382016-12-13 11:49:09 -08002070 pw.print(" mSupportsPictureInPicture=" + mSupportsPictureInPicture);
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002071 pw.print(" isResizeable=" + isResizeable());
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002072 pw.print(" lastActiveTime=" + lastActiveTime);
2073 pw.println(" (inactive for " + (getInactiveDuration() / 1000) + "s)");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002074 }
2075
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002076 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002077 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002078 StringBuilder sb = new StringBuilder(128);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002079 if (stringName != null) {
2080 sb.append(stringName);
2081 sb.append(" U=");
2082 sb.append(userId);
Wale Ogunwale6c5eb1c2015-11-10 07:52:22 -08002083 sb.append(" StackId=");
Andrii Kulian02b7a832016-10-06 23:11:56 -07002084 sb.append(getStackId());
Craig Mautnerde4ef022013-04-07 19:01:33 -07002085 sb.append(" sz=");
2086 sb.append(mActivities.size());
2087 sb.append('}');
2088 return sb.toString();
2089 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002090 sb.append("TaskRecord{");
2091 sb.append(Integer.toHexString(System.identityHashCode(this)));
2092 sb.append(" #");
2093 sb.append(taskId);
2094 if (affinity != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002095 sb.append(" A=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002096 sb.append(affinity);
2097 } else if (intent != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002098 sb.append(" I=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002099 sb.append(intent.getComponent().flattenToShortString());
Bryce Leefbd263b42018-03-07 10:33:55 -08002100 } else if (affinityIntent != null && affinityIntent.getComponent() != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002101 sb.append(" aI=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002102 sb.append(affinityIntent.getComponent().flattenToShortString());
2103 } else {
2104 sb.append(" ??");
2105 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07002106 stringName = sb.toString();
2107 return toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002108 }
Steven Timotius4346f0a2017-09-12 11:07:21 -07002109
2110 public void writeToProto(ProtoOutputStream proto, long fieldId) {
2111 final long token = proto.start(fieldId);
Adrian Roos4921ccf2017-09-28 16:54:06 +02002112 super.writeToProto(proto, CONFIGURATION_CONTAINER, false /* trim */);
Steven Timotius4346f0a2017-09-12 11:07:21 -07002113 proto.write(ID, taskId);
2114 for (int i = mActivities.size() - 1; i >= 0; i--) {
2115 ActivityRecord activity = mActivities.get(i);
2116 activity.writeToProto(proto, ACTIVITIES);
2117 }
2118 proto.write(STACK_ID, mStack.mStackId);
2119 if (mLastNonFullscreenBounds != null) {
2120 mLastNonFullscreenBounds.writeToProto(proto, LAST_NON_FULLSCREEN_BOUNDS);
2121 }
2122 if (realActivity != null) {
2123 proto.write(REAL_ACTIVITY, realActivity.flattenToShortString());
2124 }
2125 if (origActivity != null) {
2126 proto.write(ORIG_ACTIVITY, origActivity.flattenToShortString());
2127 }
2128 proto.write(ACTIVITY_TYPE, getActivityType());
Steven Timotius4346f0a2017-09-12 11:07:21 -07002129 proto.write(RESIZE_MODE, mResizeMode);
Bryce Leef3c6a472017-11-14 14:53:06 -08002130 // TODO: Remove, no longer needed with windowingMode.
2131 proto.write(FULLSCREEN, matchParentBounds());
2132
2133 if (!matchParentBounds()) {
2134 final Rect bounds = getOverrideBounds();
2135 bounds.writeToProto(proto, BOUNDS);
Steven Timotius4346f0a2017-09-12 11:07:21 -07002136 }
2137 proto.write(MIN_WIDTH, mMinWidth);
2138 proto.write(MIN_HEIGHT, mMinHeight);
2139 proto.end(token);
2140 }
Winson Chung61c9e5a2017-10-11 10:39:32 -07002141
2142 /**
2143 * See {@link #getNumRunningActivities(TaskActivitiesReport)}.
2144 */
2145 static class TaskActivitiesReport {
2146 int numRunning;
2147 int numActivities;
2148 ActivityRecord top;
2149 ActivityRecord base;
2150
2151 void reset() {
2152 numRunning = numActivities = 0;
2153 top = base = null;
2154 }
2155 }
Garfield Tan9b1efea2017-12-05 16:43:46 -08002156
2157 /**
2158 * Saves this {@link TaskRecord} to XML using given serializer.
2159 */
2160 void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
2161 if (DEBUG_RECENTS) Slog.i(TAG_RECENTS, "Saving task=" + this);
2162
2163 out.attribute(null, ATTR_TASKID, String.valueOf(taskId));
2164 if (realActivity != null) {
2165 out.attribute(null, ATTR_REALACTIVITY, realActivity.flattenToShortString());
2166 }
2167 out.attribute(null, ATTR_REALACTIVITY_SUSPENDED, String.valueOf(realActivitySuspended));
2168 if (origActivity != null) {
2169 out.attribute(null, ATTR_ORIGACTIVITY, origActivity.flattenToShortString());
2170 }
2171 // Write affinity, and root affinity if it is different from affinity.
2172 // We use the special string "@" for a null root affinity, so we can identify
2173 // later whether we were given a root affinity or should just make it the
2174 // same as the affinity.
2175 if (affinity != null) {
2176 out.attribute(null, ATTR_AFFINITY, affinity);
2177 if (!affinity.equals(rootAffinity)) {
2178 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
2179 }
2180 } else if (rootAffinity != null) {
2181 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
2182 }
2183 out.attribute(null, ATTR_ROOTHASRESET, String.valueOf(rootWasReset));
2184 out.attribute(null, ATTR_AUTOREMOVERECENTS, String.valueOf(autoRemoveRecents));
2185 out.attribute(null, ATTR_ASKEDCOMPATMODE, String.valueOf(askedCompatMode));
2186 out.attribute(null, ATTR_USERID, String.valueOf(userId));
2187 out.attribute(null, ATTR_USER_SETUP_COMPLETE, String.valueOf(mUserSetupComplete));
2188 out.attribute(null, ATTR_EFFECTIVE_UID, String.valueOf(effectiveUid));
2189 out.attribute(null, ATTR_LASTTIMEMOVED, String.valueOf(mLastTimeMoved));
2190 out.attribute(null, ATTR_NEVERRELINQUISH, String.valueOf(mNeverRelinquishIdentity));
2191 if (lastDescription != null) {
2192 out.attribute(null, ATTR_LASTDESCRIPTION, lastDescription.toString());
2193 }
2194 if (lastTaskDescription != null) {
2195 lastTaskDescription.saveToXml(out);
2196 }
2197 out.attribute(null, ATTR_TASK_AFFILIATION_COLOR, String.valueOf(mAffiliatedTaskColor));
2198 out.attribute(null, ATTR_TASK_AFFILIATION, String.valueOf(mAffiliatedTaskId));
2199 out.attribute(null, ATTR_PREV_AFFILIATION, String.valueOf(mPrevAffiliateTaskId));
2200 out.attribute(null, ATTR_NEXT_AFFILIATION, String.valueOf(mNextAffiliateTaskId));
2201 out.attribute(null, ATTR_CALLING_UID, String.valueOf(mCallingUid));
2202 out.attribute(null, ATTR_CALLING_PACKAGE, mCallingPackage == null ? "" : mCallingPackage);
2203 out.attribute(null, ATTR_RESIZE_MODE, String.valueOf(mResizeMode));
2204 out.attribute(null, ATTR_SUPPORTS_PICTURE_IN_PICTURE,
2205 String.valueOf(mSupportsPictureInPicture));
2206 if (mLastNonFullscreenBounds != null) {
2207 out.attribute(
2208 null, ATTR_NON_FULLSCREEN_BOUNDS, mLastNonFullscreenBounds.flattenToString());
2209 }
2210 out.attribute(null, ATTR_MIN_WIDTH, String.valueOf(mMinWidth));
2211 out.attribute(null, ATTR_MIN_HEIGHT, String.valueOf(mMinHeight));
2212 out.attribute(null, ATTR_PERSIST_TASK_VERSION, String.valueOf(PERSIST_TASK_VERSION));
2213
2214 if (affinityIntent != null) {
2215 out.startTag(null, TAG_AFFINITYINTENT);
2216 affinityIntent.saveToXml(out);
2217 out.endTag(null, TAG_AFFINITYINTENT);
2218 }
2219
Bryce Lee1a990e52018-04-23 10:54:11 -07002220 if (intent != null) {
2221 out.startTag(null, TAG_INTENT);
2222 intent.saveToXml(out);
2223 out.endTag(null, TAG_INTENT);
2224 }
Garfield Tan9b1efea2017-12-05 16:43:46 -08002225
2226 final ArrayList<ActivityRecord> activities = mActivities;
2227 final int numActivities = activities.size();
2228 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
2229 final ActivityRecord r = activities.get(activityNdx);
2230 if (r.info.persistableMode == ActivityInfo.PERSIST_ROOT_ONLY || !r.isPersistable() ||
2231 ((r.intent.getFlags() & FLAG_ACTIVITY_NEW_DOCUMENT
2232 | FLAG_ACTIVITY_RETAIN_IN_RECENTS) == FLAG_ACTIVITY_NEW_DOCUMENT) &&
2233 activityNdx > 0) {
2234 // Stop at first non-persistable or first break in task (CLEAR_WHEN_TASK_RESET).
2235 break;
2236 }
2237 out.startTag(null, TAG_ACTIVITY);
2238 r.saveToXml(out);
2239 out.endTag(null, TAG_ACTIVITY);
2240 }
2241 }
2242
2243 @VisibleForTesting
2244 static TaskRecordFactory getTaskRecordFactory() {
2245 if (sTaskRecordFactory == null) {
2246 setTaskRecordFactory(new TaskRecordFactory());
2247 }
2248 return sTaskRecordFactory;
2249 }
2250
2251 static void setTaskRecordFactory(TaskRecordFactory factory) {
2252 sTaskRecordFactory = factory;
2253 }
2254
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002255 static TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002256 Intent intent, IVoiceInteractionSession voiceSession,
2257 IVoiceInteractor voiceInteractor) {
2258 return getTaskRecordFactory().create(
2259 service, taskId, info, intent, voiceSession, voiceInteractor);
2260 }
2261
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002262 static TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002263 Intent intent, TaskDescription taskDescription) {
2264 return getTaskRecordFactory().create(service, taskId, info, intent, taskDescription);
2265 }
2266
2267 static TaskRecord restoreFromXml(XmlPullParser in, ActivityStackSupervisor stackSupervisor)
2268 throws IOException, XmlPullParserException {
2269 return getTaskRecordFactory().restoreFromXml(in, stackSupervisor);
2270 }
2271
2272 /**
2273 * A factory class used to create {@link TaskRecord} or its subclass if any. This can be
2274 * specified when system boots by setting it with
2275 * {@link #setTaskRecordFactory(TaskRecordFactory)}.
2276 */
2277 static class TaskRecordFactory {
2278
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002279 TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002280 Intent intent, IVoiceInteractionSession voiceSession,
2281 IVoiceInteractor voiceInteractor) {
2282 return new TaskRecord(
2283 service, taskId, info, intent, voiceSession, voiceInteractor);
2284 }
2285
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002286 TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002287 Intent intent, TaskDescription taskDescription) {
2288 return new TaskRecord(service, taskId, info, intent, taskDescription);
2289 }
2290
2291 /**
2292 * Should only be used when we're restoring {@link TaskRecord} from storage.
2293 */
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002294 TaskRecord create(ActivityTaskManagerService service, int taskId, Intent intent,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002295 Intent affinityIntent, String affinity, String rootAffinity,
2296 ComponentName realActivity, ComponentName origActivity, boolean rootWasReset,
2297 boolean autoRemoveRecents, boolean askedCompatMode, int userId,
2298 int effectiveUid, String lastDescription, ArrayList<ActivityRecord> activities,
2299 long lastTimeMoved, boolean neverRelinquishIdentity,
2300 TaskDescription lastTaskDescription, int taskAffiliation, int prevTaskId,
2301 int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage,
2302 int resizeMode, boolean supportsPictureInPicture, boolean realActivitySuspended,
2303 boolean userSetupComplete, int minWidth, int minHeight) {
2304 return new TaskRecord(service, taskId, intent, affinityIntent, affinity,
2305 rootAffinity, realActivity, origActivity, rootWasReset, autoRemoveRecents,
2306 askedCompatMode, userId, effectiveUid, lastDescription, activities,
2307 lastTimeMoved, neverRelinquishIdentity, lastTaskDescription, taskAffiliation,
2308 prevTaskId, nextTaskId, taskAffiliationColor, callingUid, callingPackage,
2309 resizeMode, supportsPictureInPicture, realActivitySuspended, userSetupComplete,
2310 minWidth, minHeight);
2311 }
2312
2313 TaskRecord restoreFromXml(XmlPullParser in, ActivityStackSupervisor stackSupervisor)
2314 throws IOException, XmlPullParserException {
2315 Intent intent = null;
2316 Intent affinityIntent = null;
2317 ArrayList<ActivityRecord> activities = new ArrayList<>();
2318 ComponentName realActivity = null;
2319 boolean realActivitySuspended = false;
2320 ComponentName origActivity = null;
2321 String affinity = null;
2322 String rootAffinity = null;
2323 boolean hasRootAffinity = false;
2324 boolean rootHasReset = false;
2325 boolean autoRemoveRecents = false;
2326 boolean askedCompatMode = false;
2327 int taskType = 0;
2328 int userId = 0;
2329 boolean userSetupComplete = true;
2330 int effectiveUid = -1;
2331 String lastDescription = null;
2332 long lastTimeOnTop = 0;
2333 boolean neverRelinquishIdentity = true;
2334 int taskId = INVALID_TASK_ID;
2335 final int outerDepth = in.getDepth();
2336 TaskDescription taskDescription = new TaskDescription();
2337 int taskAffiliation = INVALID_TASK_ID;
2338 int taskAffiliationColor = 0;
2339 int prevTaskId = INVALID_TASK_ID;
2340 int nextTaskId = INVALID_TASK_ID;
2341 int callingUid = -1;
2342 String callingPackage = "";
2343 int resizeMode = RESIZE_MODE_FORCE_RESIZEABLE;
2344 boolean supportsPictureInPicture = false;
Garfield Tan367b35a2017-12-13 12:16:21 -08002345 Rect lastNonFullscreenBounds = null;
Garfield Tan9b1efea2017-12-05 16:43:46 -08002346 int minWidth = INVALID_MIN_SIZE;
2347 int minHeight = INVALID_MIN_SIZE;
2348 int persistTaskVersion = 0;
2349
2350 for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
2351 final String attrName = in.getAttributeName(attrNdx);
2352 final String attrValue = in.getAttributeValue(attrNdx);
2353 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: attribute name=" +
2354 attrName + " value=" + attrValue);
2355 switch (attrName) {
2356 case ATTR_TASKID:
2357 if (taskId == INVALID_TASK_ID) taskId = Integer.parseInt(attrValue);
2358 break;
2359 case ATTR_REALACTIVITY:
2360 realActivity = ComponentName.unflattenFromString(attrValue);
2361 break;
2362 case ATTR_REALACTIVITY_SUSPENDED:
2363 realActivitySuspended = Boolean.valueOf(attrValue);
2364 break;
2365 case ATTR_ORIGACTIVITY:
2366 origActivity = ComponentName.unflattenFromString(attrValue);
2367 break;
2368 case ATTR_AFFINITY:
2369 affinity = attrValue;
2370 break;
2371 case ATTR_ROOT_AFFINITY:
2372 rootAffinity = attrValue;
2373 hasRootAffinity = true;
2374 break;
2375 case ATTR_ROOTHASRESET:
2376 rootHasReset = Boolean.parseBoolean(attrValue);
2377 break;
2378 case ATTR_AUTOREMOVERECENTS:
2379 autoRemoveRecents = Boolean.parseBoolean(attrValue);
2380 break;
2381 case ATTR_ASKEDCOMPATMODE:
2382 askedCompatMode = Boolean.parseBoolean(attrValue);
2383 break;
2384 case ATTR_USERID:
2385 userId = Integer.parseInt(attrValue);
2386 break;
2387 case ATTR_USER_SETUP_COMPLETE:
2388 userSetupComplete = Boolean.parseBoolean(attrValue);
2389 break;
2390 case ATTR_EFFECTIVE_UID:
2391 effectiveUid = Integer.parseInt(attrValue);
2392 break;
2393 case ATTR_TASKTYPE:
2394 taskType = Integer.parseInt(attrValue);
2395 break;
2396 case ATTR_LASTDESCRIPTION:
2397 lastDescription = attrValue;
2398 break;
2399 case ATTR_LASTTIMEMOVED:
2400 lastTimeOnTop = Long.parseLong(attrValue);
2401 break;
2402 case ATTR_NEVERRELINQUISH:
2403 neverRelinquishIdentity = Boolean.parseBoolean(attrValue);
2404 break;
2405 case ATTR_TASK_AFFILIATION:
2406 taskAffiliation = Integer.parseInt(attrValue);
2407 break;
2408 case ATTR_PREV_AFFILIATION:
2409 prevTaskId = Integer.parseInt(attrValue);
2410 break;
2411 case ATTR_NEXT_AFFILIATION:
2412 nextTaskId = Integer.parseInt(attrValue);
2413 break;
2414 case ATTR_TASK_AFFILIATION_COLOR:
2415 taskAffiliationColor = Integer.parseInt(attrValue);
2416 break;
2417 case ATTR_CALLING_UID:
2418 callingUid = Integer.parseInt(attrValue);
2419 break;
2420 case ATTR_CALLING_PACKAGE:
2421 callingPackage = attrValue;
2422 break;
2423 case ATTR_RESIZE_MODE:
2424 resizeMode = Integer.parseInt(attrValue);
2425 break;
2426 case ATTR_SUPPORTS_PICTURE_IN_PICTURE:
2427 supportsPictureInPicture = Boolean.parseBoolean(attrValue);
2428 break;
2429 case ATTR_NON_FULLSCREEN_BOUNDS:
Garfield Tan367b35a2017-12-13 12:16:21 -08002430 lastNonFullscreenBounds = Rect.unflattenFromString(attrValue);
Garfield Tan9b1efea2017-12-05 16:43:46 -08002431 break;
2432 case ATTR_MIN_WIDTH:
2433 minWidth = Integer.parseInt(attrValue);
2434 break;
2435 case ATTR_MIN_HEIGHT:
2436 minHeight = Integer.parseInt(attrValue);
2437 break;
2438 case ATTR_PERSIST_TASK_VERSION:
2439 persistTaskVersion = Integer.parseInt(attrValue);
2440 break;
2441 default:
2442 if (attrName.startsWith(TaskDescription.ATTR_TASKDESCRIPTION_PREFIX)) {
2443 taskDescription.restoreFromXml(attrName, attrValue);
2444 } else {
2445 Slog.w(TAG, "TaskRecord: Unknown attribute=" + attrName);
2446 }
2447 }
2448 }
2449
2450 int event;
2451 while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
2452 (event != XmlPullParser.END_TAG || in.getDepth() >= outerDepth)) {
2453 if (event == XmlPullParser.START_TAG) {
2454 final String name = in.getName();
2455 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG,
2456 "TaskRecord: START_TAG name=" + name);
2457 if (TAG_AFFINITYINTENT.equals(name)) {
2458 affinityIntent = Intent.restoreFromXml(in);
2459 } else if (TAG_INTENT.equals(name)) {
2460 intent = Intent.restoreFromXml(in);
2461 } else if (TAG_ACTIVITY.equals(name)) {
2462 ActivityRecord activity =
2463 ActivityRecord.restoreFromXml(in, stackSupervisor);
2464 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: activity=" +
2465 activity);
2466 if (activity != null) {
2467 activities.add(activity);
2468 }
2469 } else {
Garfield Tan1e740192017-12-12 14:37:42 -08002470 handleUnknownTag(name, in);
Garfield Tan9b1efea2017-12-05 16:43:46 -08002471 }
2472 }
2473 }
2474 if (!hasRootAffinity) {
2475 rootAffinity = affinity;
2476 } else if ("@".equals(rootAffinity)) {
2477 rootAffinity = null;
2478 }
2479 if (effectiveUid <= 0) {
2480 Intent checkIntent = intent != null ? intent : affinityIntent;
2481 effectiveUid = 0;
2482 if (checkIntent != null) {
2483 IPackageManager pm = AppGlobals.getPackageManager();
2484 try {
2485 ApplicationInfo ai = pm.getApplicationInfo(
2486 checkIntent.getComponent().getPackageName(),
2487 PackageManager.MATCH_UNINSTALLED_PACKAGES
2488 | PackageManager.MATCH_DISABLED_COMPONENTS, userId);
2489 if (ai != null) {
2490 effectiveUid = ai.uid;
2491 }
2492 } catch (RemoteException e) {
2493 }
2494 }
2495 Slog.w(TAG, "Updating task #" + taskId + " for " + checkIntent
2496 + ": effectiveUid=" + effectiveUid);
2497 }
2498
2499 if (persistTaskVersion < 1) {
2500 // We need to convert the resize mode of home activities saved before version one if
2501 // they are marked as RESIZE_MODE_RESIZEABLE to
2502 // RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION since we didn't have that differentiation
2503 // before version 1 and the system didn't resize home activities before then.
2504 if (taskType == 1 /* old home type */ && resizeMode == RESIZE_MODE_RESIZEABLE) {
2505 resizeMode = RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
2506 }
2507 } else {
2508 // This activity has previously marked itself explicitly as both resizeable and
2509 // supporting picture-in-picture. Since there is no longer a requirement for
2510 // picture-in-picture activities to be resizeable, we can mark this simply as
2511 // resizeable and supporting picture-in-picture separately.
2512 if (resizeMode == RESIZE_MODE_RESIZEABLE_AND_PIPABLE_DEPRECATED) {
2513 resizeMode = RESIZE_MODE_RESIZEABLE;
2514 supportsPictureInPicture = true;
2515 }
2516 }
2517
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07002518 final TaskRecord task = create(stackSupervisor.mService,
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002519 taskId, intent, affinityIntent,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002520 affinity, rootAffinity, realActivity, origActivity, rootHasReset,
2521 autoRemoveRecents, askedCompatMode, userId, effectiveUid, lastDescription,
2522 activities, lastTimeOnTop, neverRelinquishIdentity, taskDescription,
2523 taskAffiliation, prevTaskId, nextTaskId, taskAffiliationColor, callingUid,
2524 callingPackage, resizeMode, supportsPictureInPicture, realActivitySuspended,
2525 userSetupComplete, minWidth, minHeight);
Garfield Tan367b35a2017-12-13 12:16:21 -08002526 task.mLastNonFullscreenBounds = lastNonFullscreenBounds;
2527 task.setBounds(lastNonFullscreenBounds);
Garfield Tan9b1efea2017-12-05 16:43:46 -08002528
2529 for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {
2530 activities.get(activityNdx).setTask(task);
2531 }
2532
2533 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Restored task=" + task);
2534 return task;
2535 }
Garfield Tan1e740192017-12-12 14:37:42 -08002536
2537 void handleUnknownTag(String name, XmlPullParser in)
2538 throws IOException, XmlPullParserException {
2539 Slog.e(TAG, "restoreTask: Unexpected name=" + name);
2540 XmlUtils.skipCurrentTag(in);
2541 }
Garfield Tan9b1efea2017-12-05 16:43:46 -08002542 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002543}