blob: a28b8759fb5b73b052d6583dbb184b02dce8206e [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
Wale Ogunwale59507092018-10-29 09:00:30 -070017package com.android.server.wm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080018
Andrii Kulianab132ee2018-07-24 22:10:21 +080019import static android.app.ActivityTaskManager.INVALID_STACK_ID;
Wale Ogunwale98875612018-10-12 07:53:02 -070020import static android.app.ActivityTaskManager.INVALID_TASK_ID;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070021import static android.app.ActivityTaskManager.RESIZE_MODE_FORCED;
22import static android.app.ActivityTaskManager.RESIZE_MODE_SYSTEM;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -070023import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
24import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070025import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
26import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
27import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
28import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Wale Ogunwale44f036f2017-09-29 05:09:09 -070029import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Jorim Jaggi0a932142016-02-01 17:42:25 -080030import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
Wale Ogunwale66e16852017-10-19 13:35:52 -070031import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
Jorim Jaggi0a932142016-02-01 17:42:25 -080032import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
Wale Ogunwale66e16852017-10-19 13:35:52 -070033import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
Wale Ogunwale3eadad72016-10-13 09:16:59 -070034import static android.content.pm.ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY;
Jorim Jaggi0a932142016-02-01 17:42:25 -080035import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
36import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
37import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
38import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER;
skuhne@google.com322347b2016-12-02 12:54:03 -080039import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY;
40import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PORTRAIT_ONLY;
41import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PRESERVE_ORIENTATION;
Wale Ogunwaled829d362016-02-10 19:24:49 -080042import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
Wale Ogunwale625ed0c2016-10-18 08:50:31 -070043import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
Winson Chungd3395382016-12-13 11:49:09 -080044import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_AND_PIPABLE_DEPRECATED;
Wale Ogunwale625ed0c2016-10-18 08:50:31 -070045import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -080046import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
Suprabh Shukla7745c142016-03-07 18:21:10 -080047import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
Andrii Kulian036e3ad2017-04-19 10:55:10 -070048import static android.view.Display.DEFAULT_DISPLAY;
Garfield Tan891146c2018-10-09 12:14:00 -070049
Yi Jin6c6e9ca2018-03-20 16:53:35 -070050import static com.android.server.am.TaskRecordProto.ACTIVITIES;
Andrii Kulianab132ee2018-07-24 22:10:21 +080051import static com.android.server.am.TaskRecordProto.ACTIVITY_TYPE;
Yi Jin6c6e9ca2018-03-20 16:53:35 -070052import static com.android.server.am.TaskRecordProto.BOUNDS;
53import static com.android.server.am.TaskRecordProto.CONFIGURATION_CONTAINER;
54import static com.android.server.am.TaskRecordProto.FULLSCREEN;
55import static com.android.server.am.TaskRecordProto.ID;
56import static com.android.server.am.TaskRecordProto.LAST_NON_FULLSCREEN_BOUNDS;
57import static com.android.server.am.TaskRecordProto.MIN_HEIGHT;
58import static com.android.server.am.TaskRecordProto.MIN_WIDTH;
59import static com.android.server.am.TaskRecordProto.ORIG_ACTIVITY;
60import static com.android.server.am.TaskRecordProto.REAL_ACTIVITY;
61import static com.android.server.am.TaskRecordProto.RESIZE_MODE;
62import static com.android.server.am.TaskRecordProto.STACK_ID;
Garfield Tan891146c2018-10-09 12:14:00 -070063import static com.android.server.wm.ActivityRecord.STARTING_WINDOW_SHOWN;
64import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_MOVING;
65import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_MOVING_TO_TOP;
66import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
67import static com.android.server.wm.ActivityStackSupervisor.PAUSE_IMMEDIATELY;
68import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
69import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ADD_REMOVE;
70import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_LOCKTASK;
71import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
72import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
73import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_ADD_REMOVE;
74import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_LOCKTASK;
75import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS;
76import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS;
77import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
78import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
79
Winson Chung74666102017-02-22 17:49:24 -080080import static java.lang.Integer.MAX_VALUE;
81
Jorim Jaggie7d2b852017-08-28 17:55:15 +020082import android.annotation.IntDef;
83import android.annotation.Nullable;
84import android.app.Activity;
85import android.app.ActivityManager;
Jorim Jaggie7d2b852017-08-28 17:55:15 +020086import android.app.ActivityManager.TaskDescription;
87import android.app.ActivityManager.TaskSnapshot;
88import android.app.ActivityOptions;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070089import android.app.ActivityTaskManager;
Jorim Jaggie7d2b852017-08-28 17:55:15 +020090import android.app.AppGlobals;
Winson Chungabfdcce2018-07-02 17:23:33 -070091import android.app.TaskInfo;
Garfield Tan891146c2018-10-09 12:14:00 -070092import android.app.WindowConfiguration;
Jorim Jaggie7d2b852017-08-28 17:55:15 +020093import android.content.ComponentName;
94import android.content.Intent;
95import android.content.pm.ActivityInfo;
96import android.content.pm.ApplicationInfo;
97import android.content.pm.IPackageManager;
98import android.content.pm.PackageManager;
99import android.content.res.Configuration;
100import android.graphics.Rect;
101import android.os.Debug;
102import android.os.RemoteException;
Winson Chungfb44d212017-10-04 11:39:10 -0700103import android.os.SystemClock;
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200104import android.os.Trace;
105import android.os.UserHandle;
106import android.provider.Settings;
107import android.service.voice.IVoiceInteractionSession;
108import android.util.DisplayMetrics;
109import android.util.Slog;
Steven Timotius4346f0a2017-09-12 11:07:21 -0700110import android.util.proto.ProtoOutputStream;
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200111
112import com.android.internal.annotations.VisibleForTesting;
113import com.android.internal.app.IVoiceInteractor;
114import com.android.internal.util.XmlUtils;
Wale Ogunwale59507092018-10-29 09:00:30 -0700115import com.android.server.wm.ActivityStack.ActivityState;
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200116
117import org.xmlpull.v1.XmlPullParser;
118import org.xmlpull.v1.XmlPullParserException;
119import org.xmlpull.v1.XmlSerializer;
120
121import java.io.IOException;
122import java.io.PrintWriter;
123import java.lang.annotation.Retention;
124import java.lang.annotation.RetentionPolicy;
125import java.util.ArrayList;
126import java.util.Objects;
127
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700128// TODO: Make package private again once move to WM package is complete.
129public class TaskRecord extends ConfigurationContainer implements TaskWindowContainerListener {
Wale Ogunwale98875612018-10-12 07:53:02 -0700130 private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskRecord" : TAG_ATM;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -0700131 private static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700132 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
Craig Mautnere0570202015-05-13 13:06:11 -0700133 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700134 private static final String TAG_TASKS = TAG + POSTFIX_TASKS;
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800135
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700136 private static final String ATTR_TASKID = "task_id";
Craig Mautner21d24a22014-04-23 11:45:37 -0700137 private static final String TAG_INTENT = "intent";
138 private static final String TAG_AFFINITYINTENT = "affinity_intent";
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700139 private static final String ATTR_REALACTIVITY = "real_activity";
140 private static final String ATTR_REALACTIVITY_SUSPENDED = "real_activity_suspended";
Craig Mautner21d24a22014-04-23 11:45:37 -0700141 private static final String ATTR_ORIGACTIVITY = "orig_activity";
Stefan Kuhnee88d1e52015-05-18 10:33:45 -0700142 private static final String TAG_ACTIVITY = "activity";
Craig Mautner21d24a22014-04-23 11:45:37 -0700143 private static final String ATTR_AFFINITY = "affinity";
Dianne Hackborn79228822014-09-16 11:11:23 -0700144 private static final String ATTR_ROOT_AFFINITY = "root_affinity";
Craig Mautner21d24a22014-04-23 11:45:37 -0700145 private static final String ATTR_ROOTHASRESET = "root_has_reset";
Dianne Hackborn13420f22014-07-18 15:43:56 -0700146 private static final String ATTR_AUTOREMOVERECENTS = "auto_remove_recents";
Craig Mautner21d24a22014-04-23 11:45:37 -0700147 private static final String ATTR_ASKEDCOMPATMODE = "asked_compat_mode";
148 private static final String ATTR_USERID = "user_id";
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800149 private static final String ATTR_USER_SETUP_COMPLETE = "user_setup_complete";
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700150 private static final String ATTR_EFFECTIVE_UID = "effective_uid";
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700151 @Deprecated
Craig Mautner21d24a22014-04-23 11:45:37 -0700152 private static final String ATTR_TASKTYPE = "task_type";
Craig Mautner21d24a22014-04-23 11:45:37 -0700153 private static final String ATTR_LASTDESCRIPTION = "last_description";
154 private static final String ATTR_LASTTIMEMOVED = "last_time_moved";
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700155 private static final String ATTR_NEVERRELINQUISH = "never_relinquish_identity";
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700156 private static final String ATTR_TASK_AFFILIATION = "task_affiliation";
Craig Mautnera228ae92014-07-09 05:44:55 -0700157 private static final String ATTR_PREV_AFFILIATION = "prev_affiliation";
158 private static final String ATTR_NEXT_AFFILIATION = "next_affiliation";
Winson Chungec396d62014-08-06 17:08:00 -0700159 private static final String ATTR_TASK_AFFILIATION_COLOR = "task_affiliation_color";
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700160 private static final String ATTR_CALLING_UID = "calling_uid";
161 private static final String ATTR_CALLING_PACKAGE = "calling_package";
Winson Chungd3395382016-12-13 11:49:09 -0800162 private static final String ATTR_SUPPORTS_PICTURE_IN_PICTURE = "supports_picture_in_picture";
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800163 private static final String ATTR_RESIZE_MODE = "resize_mode";
Wale Ogunwale706ed792015-08-02 10:29:44 -0700164 private static final String ATTR_NON_FULLSCREEN_BOUNDS = "non_fullscreen_bounds";
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700165 private static final String ATTR_MIN_WIDTH = "min_width";
166 private static final String ATTR_MIN_HEIGHT = "min_height";
Wale Ogunwale625ed0c2016-10-18 08:50:31 -0700167 private static final String ATTR_PERSIST_TASK_VERSION = "persist_task_version";
Andrii Kulian18d75122016-03-27 20:20:28 -0700168
Wale Ogunwale625ed0c2016-10-18 08:50:31 -0700169 // Current version of the task record we persist. Used to check if we need to run any upgrade
170 // code.
171 private static final int PERSIST_TASK_VERSION = 1;
Craig Mautner21d24a22014-04-23 11:45:37 -0700172
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700173 private static final int INVALID_MIN_SIZE = -1;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800174
Winson Chung74666102017-02-22 17:49:24 -0800175 /**
176 * The modes to control how the stack is moved to the front when calling
177 * {@link TaskRecord#reparent}.
178 */
179 @Retention(RetentionPolicy.SOURCE)
180 @IntDef({
181 REPARENT_MOVE_STACK_TO_FRONT,
182 REPARENT_KEEP_STACK_AT_FRONT,
183 REPARENT_LEAVE_STACK_IN_PLACE
184 })
Wale Ogunwale66e16852017-10-19 13:35:52 -0700185 @interface ReparentMoveStackMode {}
Winson Chung74666102017-02-22 17:49:24 -0800186 // Moves the stack to the front if it was not at the front
Wale Ogunwale66e16852017-10-19 13:35:52 -0700187 static final int REPARENT_MOVE_STACK_TO_FRONT = 0;
Winson Chung74666102017-02-22 17:49:24 -0800188 // Only moves the stack to the front if it was focused or front most already
Wale Ogunwale66e16852017-10-19 13:35:52 -0700189 static final int REPARENT_KEEP_STACK_AT_FRONT = 1;
Winson Chung74666102017-02-22 17:49:24 -0800190 // Do not move the stack as a part of reparenting
Wale Ogunwale66e16852017-10-19 13:35:52 -0700191 static final int REPARENT_LEAVE_STACK_IN_PLACE = 2;
Winson Chung74666102017-02-22 17:49:24 -0800192
Garfield Tan9b1efea2017-12-05 16:43:46 -0800193 /**
194 * The factory used to create {@link TaskRecord}. This allows OEM subclass {@link TaskRecord}.
195 */
196 private static TaskRecordFactory sTaskRecordFactory;
197
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800198 final int taskId; // Unique identifier for this task.
Dianne Hackborn79228822014-09-16 11:11:23 -0700199 String affinity; // The affinity name for this task, or null; may change identity.
200 String rootAffinity; // Initial base affinity, or null; does not change from initial root.
Dianne Hackborn91097de2014-04-04 18:02:06 -0700201 final IVoiceInteractionSession voiceSession; // Voice interaction session driving task
202 final IVoiceInteractor voiceInteractor; // Associated interactor to provide to app
Bryce Lee1a990e52018-04-23 10:54:11 -0700203 Intent intent; // The original intent that started the task. Note that this value can
204 // be null.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800205 Intent affinityIntent; // Intent of affinity-moved activity that started this task.
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700206 int effectiveUid; // The current effective uid of the identity of this task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207 ComponentName origActivity; // The non-alias activity component of the intent.
208 ComponentName realActivity; // The actual activity component that started the task.
Andrei Stingaceanu4ccec532016-01-13 12:10:21 +0000209 boolean realActivitySuspended; // True if the actual activity component that started the
210 // task is suspended.
Dianne Hackborn852975d2014-08-22 17:42:43 -0700211 boolean inRecents; // Actually in the recents list?
Winson Chungfb44d212017-10-04 11:39:10 -0700212 long lastActiveTime; // Last time this task was active in the current device session,
213 // including sleep. This time is initialized to the elapsed time when
214 // restored from disk.
Dianne Hackborn852975d2014-08-22 17:42:43 -0700215 boolean isAvailable; // Is the activity available to be launched?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800216 boolean rootWasReset; // True if the intent at the root of the task had
217 // the FLAG_ACTIVITY_RESET_TASK_IF_NEEDED flag.
Dianne Hackborn13420f22014-07-18 15:43:56 -0700218 boolean autoRemoveRecents; // If true, we should automatically remove the task from
219 // recents when activity finishes
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700220 boolean askedCompatMode;// Have asked the user about compat mode for this task.
Dianne Hackbornd38aed82014-06-10 21:36:35 -0700221 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 -0800222
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700223 String stringName; // caching of toString() result.
Dianne Hackborn9da2d402012-03-15 13:43:08 -0700224 int userId; // user for which this task was created
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800225 boolean mUserSetupComplete; // The user set-up is complete as of the last time the task activity
226 // was changed.
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800227
228 int numFullscreen; // Number of fullscreen activities.
229
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800230 int mResizeMode; // The resize mode of this task and its activities.
231 // Based on the {@link ActivityInfo#resizeMode} of the root activity.
Wale Ogunwale069bbd32017-02-03 07:58:14 -0800232 private boolean mSupportsPictureInPicture; // Whether or not this task and its activities
233 // support PiP. Based on the {@link ActivityInfo#FLAG_SUPPORTS_PICTURE_IN_PICTURE} flag
234 // of the root activity.
Craig Mautner15df08a2015-04-01 12:17:18 -0700235 /** Can't be put in lockTask mode. */
236 final static int LOCK_TASK_AUTH_DONT_LOCK = 0;
Benjamin Franz469dd582015-06-09 14:24:36 +0100237 /** Can enter app pinning with user approval. Can never start over existing lockTask task. */
Craig Mautner15df08a2015-04-01 12:17:18 -0700238 final static int LOCK_TASK_AUTH_PINNABLE = 1;
239 /** Starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing lockTask task. */
240 final static int LOCK_TASK_AUTH_LAUNCHABLE = 2;
Benjamin Franz469dd582015-06-09 14:24:36 +0100241 /** Can enter lockTask without user approval. Can start over existing lockTask task. */
Craig Mautner15df08a2015-04-01 12:17:18 -0700242 final static int LOCK_TASK_AUTH_WHITELISTED = 3;
Benjamin Franz469dd582015-06-09 14:24:36 +0100243 /** Priv-app that starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing
244 * lockTask task. */
245 final static int LOCK_TASK_AUTH_LAUNCHABLE_PRIV = 4;
Craig Mautner15df08a2015-04-01 12:17:18 -0700246 int mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE;
247
248 int mLockTaskUid = -1; // The uid of the application that called startLockTask().
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800249
Winson Chung03a9bae2014-05-02 09:56:12 -0700250 // This represents the last resolved activity values for this task
251 // NOTE: This value needs to be persisted with each task
Craig Mautner648f69b2014-09-18 14:16:26 -0700252 TaskDescription lastTaskDescription = new TaskDescription();
Winson Chung03a9bae2014-05-02 09:56:12 -0700253
Craig Mautnerd2328952013-03-05 12:46:26 -0800254 /** List of all activities in the task arranged in history order */
Craig Mautner21d24a22014-04-23 11:45:37 -0700255 final ArrayList<ActivityRecord> mActivities;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800256
Andrii Kulian02b7a832016-10-06 23:11:56 -0700257 /** Current stack. Setter must always be used to update the value. */
258 private ActivityStack mStack;
Craig Mautnerd2328952013-03-05 12:46:26 -0800259
Dianne Hackborn68a06332017-11-15 17:54:18 -0800260 /** The process that had previously hosted the root activity of this task.
261 * Used to know that we should try harder to keep this process around, in case the
262 * user wants to return to it. */
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700263 private WindowProcessController mRootProcess;
Dianne Hackborn68a06332017-11-15 17:54:18 -0800264
Craig Mautner21d24a22014-04-23 11:45:37 -0700265 /** Takes on same value as first root activity */
266 boolean isPersistable = false;
Craig Mautnerffcfcaa2014-06-05 09:54:38 -0700267 int maxRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700268
269 /** Only used for persistable tasks, otherwise 0. The last time this task was moved. Used for
270 * determining the order when restoring. Sign indicates whether last task movement was to front
271 * (positive) or back (negative). Absolute value indicates time. */
272 long mLastTimeMoved = System.currentTimeMillis();
273
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700274 /** If original intent did not allow relinquishing task identity, save that information */
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700275 private boolean mNeverRelinquishIdentity = true;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700276
Craig Mautner362449a2014-06-20 14:04:39 -0700277 // Used in the unique case where we are clearing the task in order to reuse it. In that case we
278 // do not want to delete the stack when the task goes empty.
Filip Gruszczynskibe9dabd2016-01-19 12:23:10 -0800279 private boolean mReuseTask = false;
Craig Mautner362449a2014-06-20 14:04:39 -0700280
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700281 CharSequence lastDescription; // Last description captured for this item.
282
Craig Mautnera228ae92014-07-09 05:44:55 -0700283 int mAffiliatedTaskId; // taskId of parent affiliation or self if no parent.
Winson Chungec396d62014-08-06 17:08:00 -0700284 int mAffiliatedTaskColor; // color of the parent task affiliation.
Craig Mautnera228ae92014-07-09 05:44:55 -0700285 TaskRecord mPrevAffiliate; // previous task in affiliated chain.
Wale Ogunwale18795a22014-12-03 11:38:33 -0800286 int mPrevAffiliateTaskId = INVALID_TASK_ID; // previous id for persistence.
Craig Mautnera228ae92014-07-09 05:44:55 -0700287 TaskRecord mNextAffiliate; // next task in affiliated chain.
Wale Ogunwale18795a22014-12-03 11:38:33 -0800288 int mNextAffiliateTaskId = INVALID_TASK_ID; // next id for persistence.
Craig Mautnera228ae92014-07-09 05:44:55 -0700289
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700290 // For relaunching the task from recents as though it was launched by the original launcher.
291 int mCallingUid;
292 String mCallingPackage;
293
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700294 final ActivityTaskManagerService mService;
Craig Mautner21d24a22014-04-23 11:45:37 -0700295
Jorim Jaggi82c9dc92016-02-05 15:10:33 -0800296 private final Rect mTmpStableBounds = new Rect();
297 private final Rect mTmpNonDecorBounds = new Rect();
Wale Ogunwale9a08f822016-02-17 19:03:58 -0800298 private final Rect mTmpRect = new Rect();
Jorim Jaggi0a932142016-02-01 17:42:25 -0800299
Wale Ogunwale706ed792015-08-02 10:29:44 -0700300 // Last non-fullscreen bounds the task was launched in or resized to.
301 // The information is persisted and used to determine the appropriate stack to launch the
302 // task into on restore.
303 Rect mLastNonFullscreenBounds = null;
Andrii Kulian2e751b82016-03-16 16:59:32 -0700304 // Minimal width and height of this task when it's resizeable. -1 means it should use the
305 // default minimal width/height.
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700306 int mMinWidth;
307 int mMinHeight;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700308
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700309 // Ranking (from top) of this task among all visible tasks. (-1 means it's not visible)
310 // This number will be assigned when we evaluate OOM scores for all visible tasks.
311 int mLayerRank = -1;
312
Andrii Kulian1779e612016-10-12 21:58:25 -0700313 /** Helper object used for updating override configuration. */
314 private Configuration mTmpConfig = new Configuration();
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700315
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800316 private TaskWindowContainerController mWindowContainerController;
317
Garfield Tan9b1efea2017-12-05 16:43:46 -0800318 /**
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700319 * Don't use constructor directly. Use {@link #create(ActivityTaskManagerService, int,
320 * ActivityInfo, Intent, TaskDescription)} instead.
Garfield Tan9b1efea2017-12-05 16:43:46 -0800321 */
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700322 TaskRecord(ActivityTaskManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700323 IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700324 mService = service;
Suprabh Shukla23593142015-11-03 17:31:15 -0800325 userId = UserHandle.getUserId(info.applicationInfo.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800326 taskId = _taskId;
Winson Chungfb44d212017-10-04 11:39:10 -0700327 lastActiveTime = SystemClock.elapsedRealtime();
Craig Mautnera228ae92014-07-09 05:44:55 -0700328 mAffiliatedTaskId = _taskId;
Dianne Hackborn91097de2014-04-04 18:02:06 -0700329 voiceSession = _voiceSession;
330 voiceInteractor = _voiceInteractor;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700331 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800332 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700333 mCallingUid = info.applicationInfo.uid;
334 mCallingPackage = info.packageName;
Martijn Coenend4a69702014-06-30 11:12:17 -0700335 setIntent(_intent, info);
Andrii Kulian2e751b82016-03-16 16:59:32 -0700336 setMinDimensions(info);
Winson730bf062016-03-31 18:04:56 -0700337 touchActiveTime();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700338 mService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
Craig Mautner21d24a22014-04-23 11:45:37 -0700339 }
340
Garfield Tan9b1efea2017-12-05 16:43:46 -0800341 /**
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700342 * Don't use constructor directly.
343 * Use {@link #create(ActivityTaskManagerService, int, ActivityInfo,
Garfield Tan9b1efea2017-12-05 16:43:46 -0800344 * Intent, IVoiceInteractionSession, IVoiceInteractor)} instead.
345 */
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700346 TaskRecord(ActivityTaskManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200347 TaskDescription _taskDescription) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700348 mService = service;
Suprabh Shukla23593142015-11-03 17:31:15 -0800349 userId = UserHandle.getUserId(info.applicationInfo.uid);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700350 taskId = _taskId;
Winson Chungfb44d212017-10-04 11:39:10 -0700351 lastActiveTime = SystemClock.elapsedRealtime();
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700352 mAffiliatedTaskId = _taskId;
353 voiceSession = null;
354 voiceInteractor = null;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700355 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800356 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700357 mCallingUid = info.applicationInfo.uid;
358 mCallingPackage = info.packageName;
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700359 setIntent(_intent, info);
Andrii Kulian2e751b82016-03-16 16:59:32 -0700360 setMinDimensions(info);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700361
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700362 isPersistable = true;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700363 // Clamp to [1, max].
364 maxRecents = Math.min(Math.max(info.maxRecents, 1),
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700365 ActivityTaskManager.getMaxAppRecentsLimitStatic());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700366
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700367 lastTaskDescription = _taskDescription;
Winson730bf062016-03-31 18:04:56 -0700368 touchActiveTime();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700369 mService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700370 }
371
Garfield Tan9b1efea2017-12-05 16:43:46 -0800372 /**
373 * Don't use constructor directly. This is only used by XML parser.
374 */
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700375 TaskRecord(ActivityTaskManagerService service, int _taskId, Intent _intent,
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800376 Intent _affinityIntent, String _affinity, String _rootAffinity,
377 ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700378 boolean _autoRemoveRecents, boolean _askedCompatMode, int _userId,
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800379 int _effectiveUid, String _lastDescription, ArrayList<ActivityRecord> activities,
Winson Chungfb44d212017-10-04 11:39:10 -0700380 long lastTimeMoved, boolean neverRelinquishIdentity,
381 TaskDescription _lastTaskDescription, int taskAffiliation, int prevTaskId,
382 int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage,
Charles He2bf28322017-10-12 22:24:49 +0100383 int resizeMode, boolean supportsPictureInPicture, boolean _realActivitySuspended,
384 boolean userSetupComplete, int minWidth, int minHeight) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700385 mService = service;
386 taskId = _taskId;
387 intent = _intent;
388 affinityIntent = _affinityIntent;
389 affinity = _affinity;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800390 rootAffinity = _rootAffinity;
Craig Mautner21d24a22014-04-23 11:45:37 -0700391 voiceSession = null;
392 voiceInteractor = null;
393 realActivity = _realActivity;
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800394 realActivitySuspended = _realActivitySuspended;
Craig Mautner21d24a22014-04-23 11:45:37 -0700395 origActivity = _origActivity;
396 rootWasReset = _rootWasReset;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700397 isAvailable = true;
Dianne Hackborn13420f22014-07-18 15:43:56 -0700398 autoRemoveRecents = _autoRemoveRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700399 askedCompatMode = _askedCompatMode;
Craig Mautner21d24a22014-04-23 11:45:37 -0700400 userId = _userId;
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800401 mUserSetupComplete = userSetupComplete;
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700402 effectiveUid = _effectiveUid;
Winson Chungfb44d212017-10-04 11:39:10 -0700403 lastActiveTime = SystemClock.elapsedRealtime();
Craig Mautner21d24a22014-04-23 11:45:37 -0700404 lastDescription = _lastDescription;
405 mActivities = activities;
406 mLastTimeMoved = lastTimeMoved;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700407 mNeverRelinquishIdentity = neverRelinquishIdentity;
Winson Chung2cb86c72014-06-25 12:03:30 -0700408 lastTaskDescription = _lastTaskDescription;
Craig Mautnera228ae92014-07-09 05:44:55 -0700409 mAffiliatedTaskId = taskAffiliation;
Winson Chungec396d62014-08-06 17:08:00 -0700410 mAffiliatedTaskColor = taskAffiliationColor;
Craig Mautnera228ae92014-07-09 05:44:55 -0700411 mPrevAffiliateTaskId = prevTaskId;
412 mNextAffiliateTaskId = nextTaskId;
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700413 mCallingUid = callingUid;
414 mCallingPackage = callingPackage;
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800415 mResizeMode = resizeMode;
Winson Chungd3395382016-12-13 11:49:09 -0800416 mSupportsPictureInPicture = supportsPictureInPicture;
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700417 mMinWidth = minWidth;
418 mMinHeight = minHeight;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700419 mService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800420 }
421
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800422 TaskWindowContainerController getWindowContainerController() {
423 return mWindowContainerController;
424 }
425
426 void createWindowContainer(boolean onTop, boolean showForAllUsers) {
427 if (mWindowContainerController != null) {
428 throw new IllegalArgumentException("Window container=" + mWindowContainerController
429 + " already created for task=" + this);
430 }
431
432 final Rect bounds = updateOverrideConfigurationFromLaunchBounds();
Bryce Lee04ab3462017-04-10 15:06:33 -0700433 setWindowContainerController(new TaskWindowContainerController(taskId, this,
Wale Ogunwale034a8ec2017-09-02 17:14:40 -0700434 getStack().getWindowContainerController(), userId, bounds,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700435 mResizeMode, mSupportsPictureInPicture, onTop,
436 showForAllUsers, lastTaskDescription));
Bryce Lee04ab3462017-04-10 15:06:33 -0700437 }
438
439 /**
440 * Should only be invoked from {@link #createWindowContainer(boolean, boolean)}.
441 */
442 @VisibleForTesting
443 protected void setWindowContainerController(TaskWindowContainerController controller) {
444 if (mWindowContainerController != null) {
445 throw new IllegalArgumentException("Window container=" + mWindowContainerController
446 + " already created for task=" + this);
447 }
448
449 mWindowContainerController = controller;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800450 }
451
452 void removeWindowContainer() {
Bryce Lee2b8e0372018-04-05 17:01:37 -0700453 mService.getLockTaskController().clearLockedTask(this);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800454 mWindowContainerController.removeContainer();
Evan Roskyc5abbd82018-10-05 16:02:19 -0700455 mWindowContainerController = null;
Wale Ogunwale3382ab12017-07-27 08:55:03 -0700456 if (!getWindowConfiguration().persistTaskBounds()) {
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800457 // Reset current bounds for task whose bounds shouldn't be persisted so it uses
458 // default configuration the next time it launches.
459 updateOverrideConfiguration(null);
460 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700461 mService.getTaskChangeNotificationController().notifyTaskRemoved(taskId);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800462 }
463
Jorim Jaggifb9d78a2017-01-05 18:57:12 +0100464 @Override
465 public void onSnapshotChanged(TaskSnapshot snapshot) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700466 mService.getTaskChangeNotificationController().notifyTaskSnapshotChanged(taskId, snapshot);
Jorim Jaggifb9d78a2017-01-05 18:57:12 +0100467 }
468
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800469 void setResizeMode(int resizeMode) {
470 if (mResizeMode == resizeMode) {
471 return;
472 }
473 mResizeMode = resizeMode;
474 mWindowContainerController.setResizeable(resizeMode);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800475 mService.mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
476 mService.mRootActivityContainer.resumeFocusedStacksTopActivities();
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800477 }
478
479 void setTaskDockedResizing(boolean resizing) {
480 mWindowContainerController.setTaskDockedResizing(resizing);
481 }
482
Wale Ogunwale1666e312016-12-16 11:27:18 -0800483 // TODO: Consolidate this with the resize() method below.
484 @Override
485 public void requestResize(Rect bounds, int resizeMode) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700486 mService.resizeTask(taskId, bounds, resizeMode);
Wale Ogunwale1666e312016-12-16 11:27:18 -0800487 }
488
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800489 boolean resize(Rect bounds, int resizeMode, boolean preserveWindow, boolean deferResume) {
Bryce Leef3c6a472017-11-14 14:53:06 -0800490 mService.mWindowManager.deferSurfaceLayout();
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800491
Bryce Leef3c6a472017-11-14 14:53:06 -0800492 try {
493 if (!isResizeable()) {
494 Slog.w(TAG, "resizeTask: task " + this + " not resizeable.");
495 return true;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800496 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800497
Bryce Leef3c6a472017-11-14 14:53:06 -0800498 // If this is a forced resize, let it go through even if the bounds is not changing,
499 // as we might need a relayout due to surface size change (to/from fullscreen).
500 final boolean forced = (resizeMode & RESIZE_MODE_FORCED) != 0;
501 if (equivalentOverrideBounds(bounds) && !forced) {
502 // Nothing to do here...
503 return true;
504 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800505
Bryce Leef3c6a472017-11-14 14:53:06 -0800506 if (mWindowContainerController == null) {
507 // Task doesn't exist in window manager yet (e.g. was restored from recents).
508 // All we can do for now is update the bounds so it can be used when the task is
509 // added to window manager.
510 updateOverrideConfiguration(bounds);
511 if (!inFreeformWindowingMode()) {
512 // re-restore the task so it can have the proper stack association.
513 mService.mStackSupervisor.restoreRecentTaskLocked(this, null, !ON_TOP);
514 }
515 return true;
516 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800517
Bryce Leef3c6a472017-11-14 14:53:06 -0800518 if (!canResizeToBounds(bounds)) {
519 throw new IllegalArgumentException("resizeTask: Can not resize task=" + this
520 + " to bounds=" + bounds + " resizeMode=" + mResizeMode);
521 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800522
Bryce Leef3c6a472017-11-14 14:53:06 -0800523 // Do not move the task to another stack here.
524 // This method assumes that the task is already placed in the right stack.
525 // we do not mess with that decision and we only do the resize!
526
527 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeTask_" + taskId);
528
529 final boolean updatedConfig = updateOverrideConfiguration(bounds);
530 // This variable holds information whether the configuration didn't change in a significant
531
532 // way and the activity was kept the way it was. If it's false, it means the activity
533 // had
534 // to be relaunched due to configuration change.
535 boolean kept = true;
536 if (updatedConfig) {
537 final ActivityRecord r = topRunningActivityLocked();
538 if (r != null && !deferResume) {
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -0800539 kept = r.ensureActivityConfiguration(0 /* globalChanges */,
Bryce Leef3c6a472017-11-14 14:53:06 -0800540 preserveWindow);
Garfield Tanb9151182018-06-25 16:29:21 -0700541 // Preserve other windows for resizing because if resizing happens when there
542 // is a dialog activity in the front, the activity that still shows some
543 // content to the user will become black and cause flickers. Note in most cases
544 // this won't cause tons of irrelevant windows being preserved because only
545 // activities in this task may experience a bounds change. Configs for other
546 // activities stay the same.
Wale Ogunwaled32da472018-11-16 07:19:28 -0800547 mService.mRootActivityContainer.ensureActivitiesVisible(r, 0, preserveWindow);
Bryce Leef3c6a472017-11-14 14:53:06 -0800548 if (!kept) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800549 mService.mRootActivityContainer.resumeFocusedStacksTopActivities();
Bryce Leef3c6a472017-11-14 14:53:06 -0800550 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800551 }
552 }
Bryce Leef3c6a472017-11-14 14:53:06 -0800553 mWindowContainerController.resize(kept, forced);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800554
Garfield Tan891146c2018-10-09 12:14:00 -0700555 saveLaunchingStateIfNeeded();
556
Bryce Leef3c6a472017-11-14 14:53:06 -0800557 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
558 return kept;
559 } finally {
560 mService.mWindowManager.continueSurfaceLayout();
561 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800562 }
563
564 // TODO: Investigate combining with the resize() method above.
565 void resizeWindowContainer() {
Bryce Leef3c6a472017-11-14 14:53:06 -0800566 mWindowContainerController.resize(false /* relayout */, false /* forced */);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800567 }
568
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800569 void getWindowContainerBounds(Rect bounds) {
570 mWindowContainerController.getBounds(bounds);
571 }
572
Winson Chung74666102017-02-22 17:49:24 -0800573 /**
574 * Convenience method to reparent a task to the top or bottom position of the stack.
575 */
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700576 boolean reparent(ActivityStack preferredStack, boolean toTop,
577 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
578 String reason) {
579 return reparent(preferredStack, toTop ? MAX_VALUE : 0, moveStackMode, animate, deferResume,
580 true /* schedulePictureInPictureModeChange */, reason);
Winson Chung5af42fc2017-03-24 17:11:33 -0700581 }
582
583 /**
584 * Convenience method to reparent a task to the top or bottom position of the stack, with
585 * an option to skip scheduling the picture-in-picture mode change.
586 */
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700587 boolean reparent(ActivityStack preferredStack, boolean toTop,
588 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
589 boolean schedulePictureInPictureModeChange, String reason) {
590 return reparent(preferredStack, toTop ? MAX_VALUE : 0, moveStackMode, animate,
Winson Chung5af42fc2017-03-24 17:11:33 -0700591 deferResume, schedulePictureInPictureModeChange, reason);
592 }
593
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700594 /** Convenience method to reparent a task to a specific position of the stack. */
595 boolean reparent(ActivityStack preferredStack, int position,
596 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
597 String reason) {
598 return reparent(preferredStack, position, moveStackMode, animate, deferResume,
Winson Chung5af42fc2017-03-24 17:11:33 -0700599 true /* schedulePictureInPictureModeChange */, reason);
Winson Chung74666102017-02-22 17:49:24 -0800600 }
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800601
Winson Chung74666102017-02-22 17:49:24 -0800602 /**
603 * Reparents the task into a preferred stack, creating it if necessary.
604 *
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700605 * @param preferredStack the target stack to move this task
Winson Chung74666102017-02-22 17:49:24 -0800606 * @param position the position to place this task in the new stack
607 * @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 -0700608 * reparenting to be drawn and animated in
Winson Chung74666102017-02-22 17:49:24 -0800609 * @param moveStackMode whether or not to move the stack to the front always, only if it was
Winson Chung5af42fc2017-03-24 17:11:33 -0700610 * previously focused & in front, or never
Winson Chung74666102017-02-22 17:49:24 -0800611 * @param deferResume whether or not to update the visibility of other tasks and stacks that may
Winson Chung5af42fc2017-03-24 17:11:33 -0700612 * have changed as a result of this reparenting
613 * @param schedulePictureInPictureModeChange specifies whether or not to schedule the PiP mode
614 * change. Callers may set this to false if they are explicitly scheduling PiP mode
615 * changes themselves, like during the PiP animation
Winson Chung74666102017-02-22 17:49:24 -0800616 * @param reason the caller of this reparenting
Winson Chung5af42fc2017-03-24 17:11:33 -0700617 * @return whether the task was reparented
Winson Chung74666102017-02-22 17:49:24 -0800618 */
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700619 // TODO: Inspect all call sites and change to just changing windowing mode of the stack vs.
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700620 // re-parenting the task. Can only be done when we are no longer using static stack Ids.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700621 boolean reparent(ActivityStack preferredStack, int position,
622 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
623 boolean schedulePictureInPictureModeChange, String reason) {
Winson Chung74666102017-02-22 17:49:24 -0800624 final ActivityStackSupervisor supervisor = mService.mStackSupervisor;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800625 final RootActivityContainer root = mService.mRootActivityContainer;
Winson Chung74666102017-02-22 17:49:24 -0800626 final WindowManagerService windowManager = mService.mWindowManager;
627 final ActivityStack sourceStack = getStack();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700628 final ActivityStack toStack = supervisor.getReparentTargetStack(this, preferredStack,
Winson Chung74666102017-02-22 17:49:24 -0800629 position == MAX_VALUE);
630 if (toStack == sourceStack) {
631 return false;
632 }
Andrii Kulianb850ea52017-12-12 23:49:10 -0800633 if (!canBeLaunchedOnDisplay(toStack.mDisplayId)) {
634 return false;
635 }
Winson Chung74666102017-02-22 17:49:24 -0800636
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700637 final int toStackWindowingMode = toStack.getWindowingMode();
Winson Chung74666102017-02-22 17:49:24 -0800638 final ActivityRecord topActivity = getTopActivity();
639
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800640 final boolean mightReplaceWindow = topActivity != null
641 && replaceWindowsOnTaskMove(getWindowingMode(), toStackWindowingMode);
Winson Chung74666102017-02-22 17:49:24 -0800642 if (mightReplaceWindow) {
643 // We are about to relaunch the activity because its configuration changed due to
644 // being maximized, i.e. size change. The activity will first remove the old window
645 // and then add a new one. This call will tell window manager about this, so it can
646 // preserve the old window until the new one is drawn. This prevents having a gap
647 // between the removal and addition, in which no window is visible. We also want the
648 // entrance of the new window to be properly animated.
649 // Note here we always set the replacing window first, as the flags might be needed
650 // during the relaunch. If we end up not doing any relaunch, we clear the flags later.
651 windowManager.setWillReplaceWindow(topActivity.appToken, animate);
652 }
653
654 windowManager.deferSurfaceLayout();
655 boolean kept = true;
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800656 try {
Winson Chung74666102017-02-22 17:49:24 -0800657 final ActivityRecord r = topRunningActivityLocked();
Wale Ogunwaled32da472018-11-16 07:19:28 -0800658 final boolean wasFocused = r != null && root.isTopDisplayFocusedStack(sourceStack)
Winson Chung74666102017-02-22 17:49:24 -0800659 && (topRunningActivityLocked() == r);
Bryce Leec4ab62a2018-03-05 14:19:26 -0800660 final boolean wasResumed = r != null && sourceStack.getResumedActivity() == r;
Winson Chung95f8f0e2017-03-24 09:20:17 -0700661 final boolean wasPaused = r != null && sourceStack.mPausingActivity == r;
Winson Chung74666102017-02-22 17:49:24 -0800662
663 // In some cases the focused stack isn't the front stack. E.g. pinned stack.
664 // Whenever we are moving the top activity from the front stack we want to make sure to
665 // move the stack to the front.
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -0700666 final boolean wasFront = r != null && sourceStack.isTopStackOnDisplay()
Winson Chung74666102017-02-22 17:49:24 -0800667 && (sourceStack.topRunningActivityLocked() == r);
668
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800669 // Adjust the position for the new parent stack as needed.
Winson Chung74666102017-02-22 17:49:24 -0800670 position = toStack.getAdjustedPositionForTask(this, position, null /* starting */);
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800671
672 // Must reparent first in window manager to avoid a situation where AM can delete the
673 // we are coming from in WM before we reparent because it became empty.
Wale Ogunwale2719cc12017-04-14 09:45:27 -0700674 mWindowContainerController.reparent(toStack.getWindowContainerController(), position,
675 moveStackMode == REPARENT_MOVE_STACK_TO_FRONT);
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800676
Wale Ogunwale56d8d162017-05-30 11:12:20 -0700677 final boolean moveStackToFront = moveStackMode == REPARENT_MOVE_STACK_TO_FRONT
678 || (moveStackMode == REPARENT_KEEP_STACK_AT_FRONT && (wasFocused || wasFront));
Winson Chung74666102017-02-22 17:49:24 -0800679 // Move the task
Wale Ogunwale56d8d162017-05-30 11:12:20 -0700680 sourceStack.removeTask(this, reason, moveStackToFront
681 ? REMOVE_TASK_MODE_MOVING_TO_TOP : REMOVE_TASK_MODE_MOVING);
Winson Chung5af42fc2017-03-24 17:11:33 -0700682 toStack.addTask(this, position, false /* schedulePictureInPictureModeChange */, reason);
Winson Chung74666102017-02-22 17:49:24 -0800683
Winson Chung5af42fc2017-03-24 17:11:33 -0700684 if (schedulePictureInPictureModeChange) {
685 // Notify of picture-in-picture mode changes
686 supervisor.scheduleUpdatePictureInPictureModeIfNeeded(this, sourceStack);
687 }
Winson Chung74666102017-02-22 17:49:24 -0800688
689 // TODO: Ensure that this is actually necessary here
690 // Notify the voice session if required
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800691 if (voiceSession != null) {
692 try {
693 voiceSession.taskStarted(intent, taskId);
694 } catch (RemoteException e) {
695 }
696 }
Winson Chung74666102017-02-22 17:49:24 -0800697
698 // If the task had focus before (or we're requested to move focus), move focus to the
699 // new stack by moving the stack to the front.
Winson Chung95f8f0e2017-03-24 09:20:17 -0700700 if (r != null) {
701 toStack.moveToFrontAndResumeStateIfNeeded(r, moveStackToFront, wasResumed,
702 wasPaused, reason);
703 }
Winson Chung74666102017-02-22 17:49:24 -0800704 if (!animate) {
Jorim Jaggifa9ed962018-01-25 00:16:49 +0100705 mService.mStackSupervisor.mNoAnimActivities.add(topActivity);
Winson Chung74666102017-02-22 17:49:24 -0800706 }
707
708 // We might trigger a configuration change. Save the current task bounds for freezing.
709 // TODO: Should this call be moved inside the resize method in WM?
710 toStack.prepareFreezingTaskBounds();
711
712 // Make sure the task has the appropriate bounds/size for the stack it is in.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700713 final boolean toStackSplitScreenPrimary =
714 toStackWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Bryce Leef3c6a472017-11-14 14:53:06 -0800715 final Rect configBounds = getOverrideBounds();
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700716 if ((toStackWindowingMode == WINDOWING_MODE_FULLSCREEN
717 || toStackWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY)
Bryce Leef3c6a472017-11-14 14:53:06 -0800718 && !Objects.equals(configBounds, toStack.getOverrideBounds())) {
719 kept = resize(toStack.getOverrideBounds(), RESIZE_MODE_SYSTEM, !mightReplaceWindow,
Winson Chung74666102017-02-22 17:49:24 -0800720 deferResume);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700721 } else if (toStackWindowingMode == WINDOWING_MODE_FREEFORM) {
Winson Chung74666102017-02-22 17:49:24 -0800722 Rect bounds = getLaunchBounds();
723 if (bounds == null) {
Bryce Leeec55eb02017-12-05 20:51:27 -0800724 mService.mStackSupervisor.getLaunchParamsController().layoutTask(this, null);
Bryce Leef3c6a472017-11-14 14:53:06 -0800725 bounds = configBounds;
Winson Chung74666102017-02-22 17:49:24 -0800726 }
727 kept = resize(bounds, RESIZE_MODE_FORCED, !mightReplaceWindow, deferResume);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700728 } else if (toStackSplitScreenPrimary || toStackWindowingMode == WINDOWING_MODE_PINNED) {
729 if (toStackSplitScreenPrimary && moveStackMode == REPARENT_KEEP_STACK_AT_FRONT) {
Matthew Ng330757d2017-02-28 14:19:17 -0800730 // Move recents to front so it is not behind home stack when going into docked
731 // mode
732 mService.mStackSupervisor.moveRecentsStackToFront(reason);
733 }
Bryce Leef3c6a472017-11-14 14:53:06 -0800734 kept = resize(toStack.getOverrideBounds(), RESIZE_MODE_SYSTEM, !mightReplaceWindow,
Winson Chung74666102017-02-22 17:49:24 -0800735 deferResume);
736 }
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800737 } finally {
Winson Chung74666102017-02-22 17:49:24 -0800738 windowManager.continueSurfaceLayout();
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800739 }
Winson Chung74666102017-02-22 17:49:24 -0800740
741 if (mightReplaceWindow) {
742 // If we didn't actual do a relaunch (indicated by kept==true meaning we kept the old
743 // window), we need to clear the replace window settings. Otherwise, we schedule a
744 // timeout to remove the old window if the replacing window is not coming in time.
745 windowManager.scheduleClearWillReplaceWindows(topActivity.appToken, !kept);
746 }
747
748 if (!deferResume) {
749 // The task might have already been running and its visibility needs to be synchronized
750 // with the visibility of the stack / windows.
Wale Ogunwaled32da472018-11-16 07:19:28 -0800751 root.ensureActivitiesVisible(null, 0, !mightReplaceWindow);
752 root.resumeFocusedStacksTopActivities();
Winson Chung74666102017-02-22 17:49:24 -0800753 }
754
Andrii Kulian036e3ad2017-04-19 10:55:10 -0700755 // TODO: Handle incorrect request to move before the actual move, not after.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700756 supervisor.handleNonResizableTaskIfNeeded(this, preferredStack.getWindowingMode(),
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -0700757 DEFAULT_DISPLAY, toStack);
Winson Chung74666102017-02-22 17:49:24 -0800758
Winson Chungdff7a732017-12-11 12:17:06 -0800759 return (preferredStack == toStack);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800760 }
761
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700762 /**
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800763 * @return True if the windows of tasks being moved to the target stack from the source stack
764 * should be replaced, meaning that window manager will keep the old window around until the new
765 * is ready.
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700766 */
767 private static boolean replaceWindowsOnTaskMove(
768 int sourceWindowingMode, int targetWindowingMode) {
769 return sourceWindowingMode == WINDOWING_MODE_FREEFORM
770 || targetWindowingMode == WINDOWING_MODE_FREEFORM;
771 }
772
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800773 void cancelWindowTransition() {
774 mWindowContainerController.cancelWindowTransition();
775 }
776
Jorim Jaggi7361bab2017-01-16 17:17:58 +0100777 /**
778 * DO NOT HOLD THE ACTIVITY MANAGER LOCK WHEN CALLING THIS METHOD!
779 */
Jorim Jaggi35e3f532017-03-17 17:06:50 +0100780 TaskSnapshot getSnapshot(boolean reducedResolution) {
Jorim Jaggi7361bab2017-01-16 17:17:58 +0100781
782 // TODO: Move this to {@link TaskWindowContainerController} once recent tasks are more
783 // synchronized between AM and WM.
Jorim Jaggi35e3f532017-03-17 17:06:50 +0100784 return mService.mWindowManager.getTaskSnapshot(taskId, userId, reducedResolution);
Jorim Jaggi02886a82016-12-06 09:10:06 -0800785 }
786
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800787 void touchActiveTime() {
Winson Chungfb44d212017-10-04 11:39:10 -0700788 lastActiveTime = SystemClock.elapsedRealtime();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800789 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700790
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800791 long getInactiveDuration() {
Winson Chungfb44d212017-10-04 11:39:10 -0700792 return SystemClock.elapsedRealtime() - lastActiveTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800793 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700794
Winson Chungfee26772014-08-05 12:21:52 -0700795 /** Sets the original intent, and the calling uid and package. */
796 void setIntent(ActivityRecord r) {
Winson Chungfee26772014-08-05 12:21:52 -0700797 mCallingUid = r.launchedFromUid;
798 mCallingPackage = r.launchedFromPackage;
Craig Mautner15df08a2015-04-01 12:17:18 -0700799 setIntent(r.intent, r.info);
Charles He2bf28322017-10-12 22:24:49 +0100800 setLockTaskAuth(r);
Winson Chungfee26772014-08-05 12:21:52 -0700801 }
802
803 /** Sets the original intent, _without_ updating the calling uid or package. */
804 private void setIntent(Intent _intent, ActivityInfo info) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700805 if (intent == null) {
806 mNeverRelinquishIdentity =
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700807 (info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700808 } else if (mNeverRelinquishIdentity) {
809 return;
810 }
811
812 affinity = info.taskAffinity;
Dianne Hackborn79228822014-09-16 11:11:23 -0700813 if (intent == null) {
814 // If this task already has an intent associated with it, don't set the root
815 // affinity -- we don't want it changing after initially set, but the initially
816 // set value may be null.
817 rootAffinity = affinity;
818 }
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700819 effectiveUid = info.applicationInfo.uid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700820 stringName = null;
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800821
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800822 if (info.targetActivity == null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800823 if (_intent != null) {
824 // If this Intent has a selector, we want to clear it for the
825 // recent task since it is not relevant if the user later wants
826 // to re-launch the app.
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700827 if (_intent.getSelector() != null || _intent.getSourceBounds() != null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800828 _intent = new Intent(_intent);
829 _intent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700830 _intent.setSourceBounds(null);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800831 }
832 }
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700833 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Setting Intent of " + this + " to " + _intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800834 intent = _intent;
835 realActivity = _intent != null ? _intent.getComponent() : null;
836 origActivity = null;
837 } else {
838 ComponentName targetComponent = new ComponentName(
839 info.packageName, info.targetActivity);
840 if (_intent != null) {
841 Intent targetIntent = new Intent(_intent);
842 targetIntent.setComponent(targetComponent);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800843 targetIntent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700844 targetIntent.setSourceBounds(null);
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700845 if (DEBUG_TASKS) Slog.v(TAG_TASKS,
Dianne Hackborn7f96b792012-05-29 18:46:45 -0700846 "Setting Intent of " + this + " to target " + targetIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800847 intent = targetIntent;
848 realActivity = targetComponent;
849 origActivity = _intent.getComponent();
850 } else {
851 intent = null;
852 realActivity = targetComponent;
853 origActivity = new ComponentName(info.packageName, info.name);
854 }
855 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700856
Craig Mautner47b20ba2014-09-17 17:23:44 -0700857 final int intentFlags = intent == null ? 0 : intent.getFlags();
858 if ((intentFlags & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800859 // Once we are set to an Intent with this flag, we count this
860 // task as having a true root activity.
861 rootWasReset = true;
862 }
Dianne Hackborn09233282014-04-30 11:33:59 -0700863 userId = UserHandle.getUserId(info.applicationInfo.uid);
Winson Chung36f3f032016-09-08 23:29:43 +0000864 mUserSetupComplete = Settings.Secure.getIntForUser(mService.mContext.getContentResolver(),
865 USER_SETUP_COMPLETE, 0, userId) != 0;
Craig Mautner41db4a72014-05-07 17:20:56 -0700866 if ((info.flags & ActivityInfo.FLAG_AUTO_REMOVE_FROM_RECENTS) != 0) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700867 // If the activity itself has requested auto-remove, then just always do it.
868 autoRemoveRecents = true;
Wale Ogunwale843bfb92015-03-27 11:06:48 -0700869 } else if ((intentFlags & (FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS))
870 == FLAG_ACTIVITY_NEW_DOCUMENT) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700871 // If the caller has not asked for the document to be retained, then we may
872 // want to turn on auto-remove, depending on whether the target has set its
873 // own document launch mode.
874 if (info.documentLaunchMode != ActivityInfo.DOCUMENT_LAUNCH_NONE) {
875 autoRemoveRecents = false;
876 } else {
877 autoRemoveRecents = true;
878 }
879 } else {
880 autoRemoveRecents = false;
Craig Mautner41db4a72014-05-07 17:20:56 -0700881 }
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800882 mResizeMode = info.resizeMode;
Winson Chungd3395382016-12-13 11:49:09 -0800883 mSupportsPictureInPicture = info.supportsPictureInPicture();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800884 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800885
Andrii Kulian2e751b82016-03-16 16:59:32 -0700886 /** Sets the original minimal width and height. */
887 private void setMinDimensions(ActivityInfo info) {
888 if (info != null && info.windowLayout != null) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700889 mMinWidth = info.windowLayout.minWidth;
890 mMinHeight = info.windowLayout.minHeight;
Andrii Kulian2e751b82016-03-16 16:59:32 -0700891 } else {
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700892 mMinWidth = INVALID_MIN_SIZE;
893 mMinHeight = INVALID_MIN_SIZE;
Andrii Kulian2e751b82016-03-16 16:59:32 -0700894 }
895 }
896
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800897 /**
Andrii Kulian206b9fa2016-06-02 13:18:01 -0700898 * Return true if the input activity has the same intent filter as the intent this task
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800899 * record is based on (normally the root activity intent).
900 */
Andrii Kulian206b9fa2016-06-02 13:18:01 -0700901 boolean isSameIntentFilter(ActivityRecord r) {
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800902 final Intent intent = new Intent(r.intent);
903 // Correct the activity intent for aliasing. The task record intent will always be based on
904 // the real activity that will be launched not the alias, so we need to use an intent with
905 // the component name pointing to the real activity not the alias in the activity record.
906 intent.setComponent(r.realActivity);
Bryce Lee1a990e52018-04-23 10:54:11 -0700907 return intent.filterEquals(this.intent);
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800908 }
909
Wale Ogunwale66e16852017-10-19 13:35:52 -0700910 boolean returnsToHomeStack() {
911 final int returnHomeFlags = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME;
Bryce Lee1a990e52018-04-23 10:54:11 -0700912 return intent != null && (intent.getFlags() & returnHomeFlags) == returnHomeFlags;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700913 }
914
Craig Mautnera228ae92014-07-09 05:44:55 -0700915 void setPrevAffiliate(TaskRecord prevAffiliate) {
916 mPrevAffiliate = prevAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800917 mPrevAffiliateTaskId = prevAffiliate == null ? INVALID_TASK_ID : prevAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700918 }
919
920 void setNextAffiliate(TaskRecord nextAffiliate) {
921 mNextAffiliate = nextAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800922 mNextAffiliateTaskId = nextAffiliate == null ? INVALID_TASK_ID : nextAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700923 }
924
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700925 <T extends ActivityStack> T getStack() {
926 return (T) mStack;
Andrii Kulian02b7a832016-10-06 23:11:56 -0700927 }
928
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800929 /**
930 * Must be used for setting parent stack because it performs configuration updates.
931 * Must be called after adding task as a child to the stack.
932 */
Andrii Kulian02b7a832016-10-06 23:11:56 -0700933 void setStack(ActivityStack stack) {
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800934 if (stack != null && !stack.isInStackLocked(this)) {
935 throw new IllegalStateException("Task must be added as a Stack child first.");
936 }
Bryce Lee84730a02018-04-03 14:10:04 -0700937 final ActivityStack oldStack = mStack;
Andrii Kulian02b7a832016-10-06 23:11:56 -0700938 mStack = stack;
Bryce Lee84730a02018-04-03 14:10:04 -0700939
940 // If the new {@link TaskRecord} is from a different {@link ActivityStack}, remove this
941 // {@link ActivityRecord} from its current {@link ActivityStack}.
942
943 if (oldStack != mStack) {
944 for (int i = getChildCount() - 1; i >= 0; --i) {
945 final ActivityRecord activity = getChildAt(i);
946
947 if (oldStack != null) {
948 oldStack.onActivityRemovedFromStack(activity);
949 }
950
951 if (mStack != null) {
952 stack.onActivityAddedToStack(activity);
953 }
954 }
955 }
956
Andrii Kulian1779e612016-10-12 21:58:25 -0700957 onParentChanged();
Andrii Kulian02b7a832016-10-06 23:11:56 -0700958 }
959
960 /**
961 * @return Id of current stack, {@link INVALID_STACK_ID} if no stack is set.
962 */
963 int getStackId() {
964 return mStack != null ? mStack.mStackId : INVALID_STACK_ID;
965 }
966
Andrii Kulian1779e612016-10-12 21:58:25 -0700967 @Override
968 protected int getChildCount() {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700969 return mActivities.size();
Andrii Kulian1779e612016-10-12 21:58:25 -0700970 }
971
972 @Override
chaviw82a0ba82018-03-15 14:26:29 -0700973 protected ActivityRecord getChildAt(int index) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700974 return mActivities.get(index);
Andrii Kulian1779e612016-10-12 21:58:25 -0700975 }
976
977 @Override
978 protected ConfigurationContainer getParent() {
979 return mStack;
980 }
981
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800982 @Override
Wale Ogunwale98d62312017-07-12 09:24:56 -0700983 protected void onParentChanged() {
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800984 super.onParentChanged();
Wale Ogunwaled32da472018-11-16 07:19:28 -0800985 mService.mRootActivityContainer.updateUIDsPresentOnDisplay();
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800986 }
987
Craig Mautnera228ae92014-07-09 05:44:55 -0700988 // Close up recents linked list.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700989 private void closeRecentsChain() {
Craig Mautnera228ae92014-07-09 05:44:55 -0700990 if (mPrevAffiliate != null) {
991 mPrevAffiliate.setNextAffiliate(mNextAffiliate);
992 }
993 if (mNextAffiliate != null) {
994 mNextAffiliate.setPrevAffiliate(mPrevAffiliate);
995 }
996 setPrevAffiliate(null);
997 setNextAffiliate(null);
998 }
999
Winson Chung740c3ac2014-11-12 16:14:38 -08001000 void removedFromRecents() {
Dianne Hackborn852975d2014-08-22 17:42:43 -07001001 closeRecentsChain();
1002 if (inRecents) {
1003 inRecents = false;
Winson Chung740c3ac2014-11-12 16:14:38 -08001004 mService.notifyTaskPersisterLocked(this, false);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001005 }
Jorim Jaggif9084ec2017-01-16 13:16:59 +01001006
Dianne Hackborn68a06332017-11-15 17:54:18 -08001007 clearRootProcess();
1008
Jorim Jaggif9084ec2017-01-16 13:16:59 +01001009 // TODO: Use window container controller once tasks are better synced between AM and WM
1010 mService.mWindowManager.notifyTaskRemovedFromRecents(taskId, userId);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001011 }
1012
Craig Mautnera228ae92014-07-09 05:44:55 -07001013 void setTaskToAffiliateWith(TaskRecord taskToAffiliateWith) {
1014 closeRecentsChain();
1015 mAffiliatedTaskId = taskToAffiliateWith.mAffiliatedTaskId;
Winson Chungec396d62014-08-06 17:08:00 -07001016 mAffiliatedTaskColor = taskToAffiliateWith.mAffiliatedTaskColor;
Craig Mautnera228ae92014-07-09 05:44:55 -07001017 // Find the end
1018 while (taskToAffiliateWith.mNextAffiliate != null) {
1019 final TaskRecord nextRecents = taskToAffiliateWith.mNextAffiliate;
1020 if (nextRecents.mAffiliatedTaskId != mAffiliatedTaskId) {
1021 Slog.e(TAG, "setTaskToAffiliateWith: nextRecents=" + nextRecents + " affilTaskId="
1022 + nextRecents.mAffiliatedTaskId + " should be " + mAffiliatedTaskId);
1023 if (nextRecents.mPrevAffiliate == taskToAffiliateWith) {
1024 nextRecents.setPrevAffiliate(null);
1025 }
1026 taskToAffiliateWith.setNextAffiliate(null);
1027 break;
1028 }
1029 taskToAffiliateWith = nextRecents;
1030 }
1031 taskToAffiliateWith.setNextAffiliate(this);
1032 setPrevAffiliate(taskToAffiliateWith);
1033 setNextAffiliate(null);
1034 }
1035
Winson Chung1147c402014-05-14 11:05:00 -07001036 /** Returns the intent for the root activity for this task */
1037 Intent getBaseIntent() {
1038 return intent != null ? intent : affinityIntent;
1039 }
1040
Winson Chung3b3f4642014-04-22 10:08:18 -07001041 /** Returns the first non-finishing activity from the root. */
1042 ActivityRecord getRootActivity() {
1043 for (int i = 0; i < mActivities.size(); i++) {
1044 final ActivityRecord r = mActivities.get(i);
1045 if (r.finishing) {
1046 continue;
1047 }
1048 return r;
1049 }
1050 return null;
1051 }
1052
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001053 ActivityRecord getTopActivity() {
Bryce Lee9f6affd2017-09-01 09:18:35 -07001054 return getTopActivity(true /* includeOverlays */);
1055 }
1056
1057 ActivityRecord getTopActivity(boolean includeOverlays) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001058 for (int i = mActivities.size() - 1; i >= 0; --i) {
1059 final ActivityRecord r = mActivities.get(i);
Bryce Lee9f6affd2017-09-01 09:18:35 -07001060 if (r.finishing || (!includeOverlays && r.mTaskOverlay)) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001061 continue;
1062 }
1063 return r;
1064 }
1065 return null;
1066 }
1067
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -07001068 ActivityRecord topRunningActivityLocked() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001069 if (mStack != null) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07001070 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1071 ActivityRecord r = mActivities.get(activityNdx);
Chong Zhang87761972016-08-22 13:53:24 -07001072 if (!r.finishing && r.okToShowLocked()) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07001073 return r;
1074 }
Craig Mautner6b74cb52013-09-27 17:02:21 -07001075 }
1076 }
1077 return null;
1078 }
1079
Jorim Jaggi172e99f2017-10-20 14:33:18 +02001080 boolean isVisible() {
1081 for (int i = mActivities.size() - 1; i >= 0; --i) {
1082 final ActivityRecord r = mActivities.get(i);
1083 if (r.visible) {
1084 return true;
1085 }
1086 }
1087 return false;
1088 }
1089
Jorim Jaggiea039a82017-08-02 14:37:49 +02001090 void getAllRunningVisibleActivitiesLocked(ArrayList<ActivityRecord> outActivities) {
1091 if (mStack != null) {
1092 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1093 ActivityRecord r = mActivities.get(activityNdx);
Jorim Jaggi02f1d2f2017-08-04 14:29:16 +02001094 if (!r.finishing && r.okToShowLocked() && r.visibleIgnoringKeyguard) {
Jorim Jaggiea039a82017-08-02 14:37:49 +02001095 outActivities.add(r);
1096 }
1097 }
1098 }
1099 }
1100
Wale Ogunwale3b232392016-05-13 15:37:13 -07001101 ActivityRecord topRunningActivityWithStartingWindowLocked() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001102 if (mStack != null) {
Wale Ogunwale3b232392016-05-13 15:37:13 -07001103 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1104 ActivityRecord r = mActivities.get(activityNdx);
1105 if (r.mStartingWindowState != STARTING_WINDOW_SHOWN
Chong Zhang87761972016-08-22 13:53:24 -07001106 || r.finishing || !r.okToShowLocked()) {
Wale Ogunwale3b232392016-05-13 15:37:13 -07001107 continue;
1108 }
1109 return r;
1110 }
1111 }
1112 return null;
1113 }
1114
Winson Chung61c9e5a2017-10-11 10:39:32 -07001115 /**
1116 * Return the number of running activities, and the number of non-finishing/initializing
1117 * activities in the provided {@param reportOut} respectively.
1118 */
1119 void getNumRunningActivities(TaskActivitiesReport reportOut) {
1120 reportOut.reset();
1121 for (int i = mActivities.size() - 1; i >= 0; --i) {
1122 final ActivityRecord r = mActivities.get(i);
1123 if (r.finishing) {
1124 continue;
1125 }
1126
1127 reportOut.base = r;
1128
1129 // Increment the total number of non-finishing activities
1130 reportOut.numActivities++;
1131
Bryce Lee7ace3952018-02-16 14:34:32 -08001132 if (reportOut.top == null || (reportOut.top.isState(ActivityState.INITIALIZING))) {
Winson Chung61c9e5a2017-10-11 10:39:32 -07001133 reportOut.top = r;
1134 // Reset the number of running activities until we hit the first non-initializing
1135 // activity
1136 reportOut.numRunning = 0;
1137 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001138 if (r.attachedToProcess()) {
Winson Chung61c9e5a2017-10-11 10:39:32 -07001139 // Increment the number of actually running activities
1140 reportOut.numRunning++;
1141 }
1142 }
1143 }
1144
Chong Zhang87761972016-08-22 13:53:24 -07001145 boolean okToShowLocked() {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001146 // NOTE: If {@link TaskRecord#topRunningActivity} return is not null then it is
Chong Zhang87761972016-08-22 13:53:24 -07001147 // okay to show the activity when locked.
1148 return mService.mStackSupervisor.isCurrentProfileLocked(userId)
1149 || topRunningActivityLocked() != null;
1150 }
1151
Craig Mautner3b475fe2013-12-16 15:58:31 -08001152 /** Call after activity movement or finish to make sure that frontOfTask is set correctly */
Bryce Leed71317c2017-02-07 14:27:22 -08001153 final void setFrontOfTask() {
1154 boolean foundFront = false;
Craig Mautner3b475fe2013-12-16 15:58:31 -08001155 final int numActivities = mActivities.size();
Craig Mautner704e40b2013-12-18 16:43:51 -08001156 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
Craig Mautner3b475fe2013-12-16 15:58:31 -08001157 final ActivityRecord r = mActivities.get(activityNdx);
1158 if (foundFront || r.finishing) {
1159 r.frontOfTask = false;
1160 } else {
1161 r.frontOfTask = true;
1162 // Set frontOfTask false for every following activity.
1163 foundFront = true;
1164 }
1165 }
Craig Mautner9587ee02014-06-23 15:00:10 +00001166 if (!foundFront && numActivities > 0) {
1167 // All activities of this task are finishing. As we ought to have a frontOfTask
1168 // activity, make the bottom activity front.
1169 mActivities.get(0).frontOfTask = true;
1170 }
Craig Mautner3b475fe2013-12-16 15:58:31 -08001171 }
1172
Craig Mautnerde4ef022013-04-07 19:01:33 -07001173 /**
Craig Mautner3b475fe2013-12-16 15:58:31 -08001174 * Reorder the history stack so that the passed activity is brought to the front.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001175 */
1176 final void moveActivityToFrontLocked(ActivityRecord newTop) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07001177 if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE,
1178 "Removing and adding activity " + newTop
1179 + " to stack at top callers=" + Debug.getCallers(4));
Craig Mautnerde4ef022013-04-07 19:01:33 -07001180
Craig Mautnerde4ef022013-04-07 19:01:33 -07001181 mActivities.remove(newTop);
1182 mActivities.add(newTop);
Bryce Leed58d7b32017-09-08 15:55:22 -07001183
1184 // Make sure window manager is aware of the position change.
1185 mWindowContainerController.positionChildAtTop(newTop.mWindowContainerController);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001186 updateEffectiveIntent();
Craig Mautner3b475fe2013-12-16 15:58:31 -08001187
Bryce Leed71317c2017-02-07 14:27:22 -08001188 setFrontOfTask();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001189 }
1190
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001191 void addActivityAtBottom(ActivityRecord r) {
Craig Mautner77878772013-03-04 19:46:24 -08001192 addActivityAtIndex(0, r);
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001193 }
1194
1195 void addActivityToTop(ActivityRecord r) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001196 addActivityAtIndex(mActivities.size(), r);
1197 }
1198
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001199 @Override
Wale Ogunwaleeea34ee92017-08-31 20:07:45 -07001200 /*@WindowConfiguration.ActivityType*/
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001201 public int getActivityType() {
1202 final int applicationType = super.getActivityType();
1203 if (applicationType != ACTIVITY_TYPE_UNDEFINED || mActivities.isEmpty()) {
1204 return applicationType;
1205 }
1206 return mActivities.get(0).getActivityType();
1207 }
1208
Winson Chung30480042017-01-26 10:55:34 -08001209 /**
1210 * Adds an activity {@param r} at the given {@param index}. The activity {@param r} must either
1211 * be in the current task or unparented to any task.
1212 */
Craig Mautner1602ec22013-05-12 10:24:27 -07001213 void addActivityAtIndex(int index, ActivityRecord r) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001214 TaskRecord task = r.getTask();
1215 if (task != null && task != this) {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001216 throw new IllegalArgumentException("Can not add r=" + " to task=" + this
Bryce Leeaf691c02017-03-20 14:20:22 -07001217 + " current parent=" + task);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001218 }
Bryce Leeaf691c02017-03-20 14:20:22 -07001219
1220 r.setTask(this);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001221
Craig Mautner6170f732013-04-02 13:05:23 -07001222 // 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 -08001223 if (!mActivities.remove(r) && r.fullscreen) {
1224 // Was not previously in list.
1225 numFullscreen++;
1226 }
Craig Mautner2c1faed2013-07-23 12:56:02 -07001227 // Only set this based on the first activity
1228 if (mActivities.isEmpty()) {
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001229 if (r.getActivityType() == ACTIVITY_TYPE_UNDEFINED) {
1230 // Normally non-standard activity type for the activity record will be set when the
1231 // object is created, however we delay setting the standard application type until
1232 // this point so that the task can set the type for additional activities added in
1233 // the else condition below.
1234 r.setActivityType(ACTIVITY_TYPE_STANDARD);
1235 }
1236 setActivityType(r.getActivityType());
Craig Mautner21d24a22014-04-23 11:45:37 -07001237 isPersistable = r.isPersistable();
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001238 mCallingUid = r.launchedFromUid;
1239 mCallingPackage = r.launchedFromPackage;
Dianne Hackborn852975d2014-08-22 17:42:43 -07001240 // Clamp to [1, max].
1241 maxRecents = Math.min(Math.max(r.info.maxRecents, 1),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001242 ActivityTaskManager.getMaxAppRecentsLimitStatic());
Craig Mautner2c1faed2013-07-23 12:56:02 -07001243 } else {
1244 // Otherwise make all added activities match this one.
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001245 r.setActivityType(getActivityType());
Craig Mautner78733002013-06-10 13:54:49 -07001246 }
Wale Ogunwale3b232392016-05-13 15:37:13 -07001247
1248 final int size = mActivities.size();
1249
1250 if (index == size && size > 0) {
1251 final ActivityRecord top = mActivities.get(size - 1);
1252 if (top.mTaskOverlay) {
1253 // Place below the task overlay activity since the overlay activity should always
1254 // be on top.
1255 index--;
1256 }
1257 }
1258
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001259 index = Math.min(size, index);
Craig Mautner77878772013-03-04 19:46:24 -08001260 mActivities.add(index, r);
Bryce Lee84730a02018-04-03 14:10:04 -07001261
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001262 updateEffectiveIntent();
Craig Mautner21d24a22014-04-23 11:45:37 -07001263 if (r.isPersistable()) {
1264 mService.notifyTaskPersisterLocked(this, false);
1265 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001266
1267 // Sync. with window manager
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001268 final AppWindowContainerController appController = r.getWindowContainerController();
1269 if (appController != null) {
1270 // Only attempt to move in WM if the child has a controller. It is possible we haven't
1271 // created controller for the activity we are starting yet.
1272 mWindowContainerController.positionChildAt(appController, index);
1273 }
David Stevens82ea6cb2017-03-03 16:18:50 -08001274
1275 // Make sure the list of display UID whitelists is updated
1276 // now that this record is in a new task.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001277 mService.mRootActivityContainer.updateUIDsPresentOnDisplay();
Craig Mautner77878772013-03-04 19:46:24 -08001278 }
1279
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001280 /**
Bryce Leeaf691c02017-03-20 14:20:22 -07001281 * Removes the specified activity from this task.
1282 * @param r The {@link ActivityRecord} to remove.
1283 * @return true if this was the last activity in the task.
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001284 */
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001285 boolean removeActivity(ActivityRecord r) {
Bryce Lee84730a02018-04-03 14:10:04 -07001286 return removeActivity(r, false /* reparenting */);
Bryce Leeaf691c02017-03-20 14:20:22 -07001287 }
1288
1289 boolean removeActivity(ActivityRecord r, boolean reparenting) {
1290 if (r.getTask() != this) {
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001291 throw new IllegalArgumentException(
1292 "Activity=" + r + " does not belong to task=" + this);
1293 }
1294
Bryce Lee84730a02018-04-03 14:10:04 -07001295 r.setTask(null /* task */, reparenting /* reparenting */);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001296
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001297 if (mActivities.remove(r) && r.fullscreen) {
1298 // Was previously in list.
1299 numFullscreen--;
1300 }
Craig Mautner21d24a22014-04-23 11:45:37 -07001301 if (r.isPersistable()) {
1302 mService.notifyTaskPersisterLocked(this, false);
1303 }
Wale Ogunwale89182d52016-03-11 10:38:36 -08001304
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001305 if (inPinnedWindowingMode()) {
Wale Ogunwale89182d52016-03-11 10:38:36 -08001306 // We normally notify listeners of task stack changes on pause, however pinned stack
1307 // activities are normally in the paused state so no notification will be sent there
1308 // before the activity is removed. We send it here so instead.
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001309 mService.getTaskChangeNotificationController().notifyTaskStackChanged();
Wale Ogunwale89182d52016-03-11 10:38:36 -08001310 }
1311
Craig Mautner41326202014-06-20 14:38:21 -07001312 if (mActivities.isEmpty()) {
Craig Mautner5afcd4d2014-06-21 18:11:33 -07001313 return !mReuseTask;
Craig Mautner41326202014-06-20 14:38:21 -07001314 }
1315 updateEffectiveIntent();
1316 return false;
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001317 }
1318
Winson Chung6954fc92017-03-24 16:22:12 -07001319 /**
1320 * @return whether or not there are ONLY task overlay activities in the stack.
1321 * If {@param excludeFinishing} is set, then ignore finishing activities in the check.
1322 * If there are no task overlay activities, this call returns false.
1323 */
1324 boolean onlyHasTaskOverlayActivities(boolean excludeFinishing) {
1325 int count = 0;
1326 for (int i = mActivities.size() - 1; i >= 0; i--) {
1327 final ActivityRecord r = mActivities.get(i);
1328 if (excludeFinishing && r.finishing) {
1329 continue;
1330 }
1331 if (!r.mTaskOverlay) {
1332 return false;
1333 }
1334 count++;
1335 }
1336 return count > 0;
1337 }
1338
Craig Mautner41db4a72014-05-07 17:20:56 -07001339 boolean autoRemoveFromRecents() {
Dianne Hackbornd38aed82014-06-10 21:36:35 -07001340 // We will automatically remove the task either if it has explicitly asked for
1341 // this, or it is empty and has never contained an activity that got shown to
1342 // the user.
Dianne Hackborn13420f22014-07-18 15:43:56 -07001343 return autoRemoveRecents || (mActivities.isEmpty() && !hasBeenVisible);
Craig Mautner41db4a72014-05-07 17:20:56 -07001344 }
1345
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001346 /**
1347 * Completely remove all activities associated with an existing
1348 * task starting at a specified index.
1349 */
Winson Chung0ec2a352017-10-26 11:38:30 -07001350 final void performClearTaskAtIndexLocked(int activityNdx, boolean pauseImmediately,
1351 String reason) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001352 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001353 for ( ; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001354 final ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001355 if (r.finishing) {
1356 continue;
1357 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07001358 if (mStack == null) {
Craig Mautner21d24a22014-04-23 11:45:37 -07001359 // Task was restored from persistent storage.
1360 r.takeFromHistory();
1361 mActivities.remove(activityNdx);
1362 --activityNdx;
1363 --numActivities;
Winson Chung6954fc92017-03-24 16:22:12 -07001364 } else if (mStack.finishActivityLocked(r, Activity.RESULT_CANCELED, null,
Winson Chung0ec2a352017-10-26 11:38:30 -07001365 reason, false, pauseImmediately)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001366 --activityNdx;
1367 --numActivities;
1368 }
1369 }
1370 }
1371
1372 /**
1373 * Completely remove all activities associated with an existing task.
1374 */
Benjamin Franza83859f2017-07-03 16:34:14 +01001375 void performClearTaskLocked() {
Craig Mautner362449a2014-06-20 14:04:39 -07001376 mReuseTask = true;
Winson Chung0ec2a352017-10-26 11:38:30 -07001377 performClearTaskAtIndexLocked(0, !PAUSE_IMMEDIATELY, "clear-task-all");
Craig Mautner362449a2014-06-20 14:04:39 -07001378 mReuseTask = false;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001379 }
1380
Filip Gruszczynskibe9dabd2016-01-19 12:23:10 -08001381 ActivityRecord performClearTaskForReuseLocked(ActivityRecord newR, int launchFlags) {
1382 mReuseTask = true;
1383 final ActivityRecord result = performClearTaskLocked(newR, launchFlags);
1384 mReuseTask = false;
1385 return result;
1386 }
1387
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001388 /**
1389 * Perform clear operation as requested by
1390 * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the
1391 * stack to the given task, then look for
1392 * an instance of that activity in the stack and, if found, finish all
1393 * activities on top of it and return the instance.
1394 *
1395 * @param newR Description of the new activity being started.
1396 * @return Returns the old activity that should be continued to be used,
1397 * or null if none was found.
1398 */
1399 final ActivityRecord performClearTaskLocked(ActivityRecord newR, int launchFlags) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001400 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001401 for (int activityNdx = numActivities - 1; activityNdx >= 0; --activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001402 ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001403 if (r.finishing) {
1404 continue;
1405 }
1406 if (r.realActivity.equals(newR.realActivity)) {
1407 // Here it is! Now finish everything in front...
Craig Mautner1602ec22013-05-12 10:24:27 -07001408 final ActivityRecord ret = r;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001409
1410 for (++activityNdx; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001411 r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001412 if (r.finishing) {
1413 continue;
1414 }
1415 ActivityOptions opts = r.takeOptionsLocked();
1416 if (opts != null) {
1417 ret.updateOptionsLocked(opts);
1418 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07001419 if (mStack != null && mStack.finishActivityLocked(
Todd Kennedy539db512014-12-15 09:57:55 -08001420 r, Activity.RESULT_CANCELED, null, "clear-task-stack", false)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001421 --activityNdx;
1422 --numActivities;
1423 }
1424 }
1425
1426 // Finally, if this is a normal launch mode (that is, not
1427 // expecting onNewIntent()), then we will finish the current
1428 // instance of the activity so a new fresh one can be started.
1429 if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE
Daichi Hirono15a02992016-04-27 18:47:01 +09001430 && (launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0
1431 && !ActivityStarter.isDocumentLaunchesIntoExisting(launchFlags)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001432 if (!ret.finishing) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001433 if (mStack != null) {
1434 mStack.finishActivityLocked(
Wale Ogunwale7d701172015-03-11 15:36:30 -07001435 ret, Activity.RESULT_CANCELED, null, "clear-task-top", false);
1436 }
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001437 return null;
1438 }
1439 }
1440
1441 return ret;
1442 }
1443 }
1444
1445 return null;
1446 }
1447
Winson Chung0ec2a352017-10-26 11:38:30 -07001448 void removeTaskActivitiesLocked(boolean pauseImmediately, String reason) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001449 // Just remove the entire task.
Winson Chung0ec2a352017-10-26 11:38:30 -07001450 performClearTaskAtIndexLocked(0, pauseImmediately, reason);
Craig Mautner9db9a0b2013-04-29 17:05:56 -07001451 }
1452
Craig Mautner432f64e2015-05-20 14:59:57 -07001453 String lockTaskAuthToString() {
1454 switch (mLockTaskAuth) {
1455 case LOCK_TASK_AUTH_DONT_LOCK: return "LOCK_TASK_AUTH_DONT_LOCK";
1456 case LOCK_TASK_AUTH_PINNABLE: return "LOCK_TASK_AUTH_PINNABLE";
1457 case LOCK_TASK_AUTH_LAUNCHABLE: return "LOCK_TASK_AUTH_LAUNCHABLE";
1458 case LOCK_TASK_AUTH_WHITELISTED: return "LOCK_TASK_AUTH_WHITELISTED";
Benjamin Franz469dd582015-06-09 14:24:36 +01001459 case LOCK_TASK_AUTH_LAUNCHABLE_PRIV: return "LOCK_TASK_AUTH_LAUNCHABLE_PRIV";
Craig Mautner432f64e2015-05-20 14:59:57 -07001460 default: return "unknown=" + mLockTaskAuth;
1461 }
1462 }
1463
Craig Mautner15df08a2015-04-01 12:17:18 -07001464 void setLockTaskAuth() {
Charles He2bf28322017-10-12 22:24:49 +01001465 setLockTaskAuth(getRootActivity());
1466 }
1467
1468 private void setLockTaskAuth(@Nullable ActivityRecord r) {
1469 if (r == null) {
1470 mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE;
1471 return;
1472 }
1473
Charles He520b2832017-09-02 15:27:16 +01001474 final String pkg = (realActivity != null) ? realActivity.getPackageName() : null;
Bryce Lee2b8e0372018-04-05 17:01:37 -07001475 final LockTaskController lockTaskController = mService.getLockTaskController();
Charles He2bf28322017-10-12 22:24:49 +01001476 switch (r.lockTaskLaunchMode) {
Craig Mautner15df08a2015-04-01 12:17:18 -07001477 case LOCK_TASK_LAUNCH_MODE_DEFAULT:
Bryce Lee2b8e0372018-04-05 17:01:37 -07001478 mLockTaskAuth = lockTaskController.isPackageWhitelisted(userId, pkg)
Charles He520b2832017-09-02 15:27:16 +01001479 ? LOCK_TASK_AUTH_WHITELISTED : LOCK_TASK_AUTH_PINNABLE;
Craig Mautner15df08a2015-04-01 12:17:18 -07001480 break;
1481
1482 case LOCK_TASK_LAUNCH_MODE_NEVER:
Benjamin Franz469dd582015-06-09 14:24:36 +01001483 mLockTaskAuth = LOCK_TASK_AUTH_DONT_LOCK;
Craig Mautner15df08a2015-04-01 12:17:18 -07001484 break;
1485
1486 case LOCK_TASK_LAUNCH_MODE_ALWAYS:
Benjamin Franz469dd582015-06-09 14:24:36 +01001487 mLockTaskAuth = LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
Craig Mautner15df08a2015-04-01 12:17:18 -07001488 break;
1489
1490 case LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED:
Bryce Lee2b8e0372018-04-05 17:01:37 -07001491 mLockTaskAuth = lockTaskController.isPackageWhitelisted(userId, pkg)
Charles He520b2832017-09-02 15:27:16 +01001492 ? LOCK_TASK_AUTH_LAUNCHABLE : LOCK_TASK_AUTH_PINNABLE;
Craig Mautner15df08a2015-04-01 12:17:18 -07001493 break;
1494 }
Craig Mautner432f64e2015-05-20 14:59:57 -07001495 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
1496 " mLockTaskAuth=" + lockTaskAuthToString());
Craig Mautner15df08a2015-04-01 12:17:18 -07001497 }
1498
Winson Chungd3395382016-12-13 11:49:09 -08001499 private boolean isResizeable(boolean checkSupportsPip) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001500 return (mService.mForceResizableActivities || ActivityInfo.isResizeableMode(mResizeMode)
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -07001501 || (checkSupportsPip && mSupportsPictureInPicture));
Winson Chungd3395382016-12-13 11:49:09 -08001502 }
1503
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001504 boolean isResizeable() {
Winson Chungd3395382016-12-13 11:49:09 -08001505 return isResizeable(true /* checkSupportsPip */);
1506 }
1507
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001508 @Override
1509 public boolean supportsSplitScreenWindowingMode() {
Winson Chungd3395382016-12-13 11:49:09 -08001510 // A task can not be docked even if it is considered resizeable because it only supports
1511 // picture-in-picture mode but has a non-resizeable resizeMode
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001512 return super.supportsSplitScreenWindowingMode()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001513 && mService.mSupportsSplitScreenMultiWindow
1514 && (mService.mForceResizableActivities
Bryce Leec857a5b2017-08-16 10:04:52 -07001515 || (isResizeable(false /* checkSupportsPip */)
1516 && !ActivityInfo.isPreserveOrientationMode(mResizeMode)));
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001517 }
1518
skuhne@google.com322347b2016-12-02 12:54:03 -08001519 /**
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001520 * Check whether this task can be launched on the specified display.
Riddle Hsu16567132018-08-16 21:37:47 +08001521 *
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001522 * @param displayId Target display id.
Riddle Hsu16567132018-08-16 21:37:47 +08001523 * @return {@code true} if either it is the default display or this activity can be put on a
1524 * secondary display.
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001525 */
1526 boolean canBeLaunchedOnDisplay(int displayId) {
1527 return mService.mStackSupervisor.canPlaceEntityOnDisplay(displayId,
Riddle Hsu16567132018-08-16 21:37:47 +08001528 -1 /* don't check PID */, -1 /* don't check UID */, null /* activityInfo */);
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001529 }
1530
1531 /**
skuhne@google.com322347b2016-12-02 12:54:03 -08001532 * Check that a given bounds matches the application requested orientation.
1533 *
1534 * @param bounds The bounds to be tested.
1535 * @return True if the requested bounds are okay for a resizing request.
1536 */
Wale Ogunwale069bbd32017-02-03 07:58:14 -08001537 private boolean canResizeToBounds(Rect bounds) {
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001538 if (bounds == null || !inFreeformWindowingMode()) {
skuhne@google.com322347b2016-12-02 12:54:03 -08001539 // Note: If not on the freeform workspace, we ignore the bounds.
1540 return true;
1541 }
1542 final boolean landscape = bounds.width() > bounds.height();
Bryce Leef3c6a472017-11-14 14:53:06 -08001543 final Rect configBounds = getOverrideBounds();
skuhne@google.com322347b2016-12-02 12:54:03 -08001544 if (mResizeMode == RESIZE_MODE_FORCE_RESIZABLE_PRESERVE_ORIENTATION) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001545 return configBounds.isEmpty()
1546 || landscape == (configBounds.width() > configBounds.height());
skuhne@google.com322347b2016-12-02 12:54:03 -08001547 }
1548 return (mResizeMode != RESIZE_MODE_FORCE_RESIZABLE_PORTRAIT_ONLY || !landscape)
1549 && (mResizeMode != RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY || landscape);
1550 }
1551
Craig Mautner525f3d92013-05-07 14:01:50 -07001552 /**
Yorke Leebdef5372017-04-10 16:38:51 -07001553 * @return {@code true} if the task is being cleared for the purposes of being reused.
1554 */
1555 boolean isClearingToReuseTask() {
1556 return mReuseTask;
1557 }
1558
1559 /**
Craig Mautner525f3d92013-05-07 14:01:50 -07001560 * Find the activity in the history stack within the given task. Returns
1561 * the index within the history at which it's found, or < 0 if not found.
1562 */
1563 final ActivityRecord findActivityInHistoryLocked(ActivityRecord r) {
1564 final ComponentName realActivity = r.realActivity;
1565 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1566 ActivityRecord candidate = mActivities.get(activityNdx);
1567 if (candidate.finishing) {
1568 continue;
1569 }
1570 if (candidate.realActivity.equals(realActivity)) {
1571 return candidate;
1572 }
1573 }
1574 return null;
1575 }
1576
Winson Chunga449dc02014-05-16 11:15:04 -07001577 /** Updates the last task description values. */
1578 void updateTaskDescription() {
1579 // Traverse upwards looking for any break between main task activities and
1580 // utility activities.
1581 int activityNdx;
1582 final int numActivities = mActivities.size();
Wale Ogunwale3eadad72016-10-13 09:16:59 -07001583 final boolean relinquish = numActivities != 0 &&
1584 (mActivities.get(0).info.flags & FLAG_RELINQUISH_TASK_IDENTITY) != 0;
Winson Chunga449dc02014-05-16 11:15:04 -07001585 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
Craig Mautner21d24a22014-04-23 11:45:37 -07001586 ++activityNdx) {
Winson Chunga449dc02014-05-16 11:15:04 -07001587 final ActivityRecord r = mActivities.get(activityNdx);
Wale Ogunwale3eadad72016-10-13 09:16:59 -07001588 if (relinquish && (r.info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001589 // This will be the top activity for determining taskDescription. Pre-inc to
1590 // overcome initial decrement below.
1591 ++activityNdx;
1592 break;
1593 }
Winson Chunga449dc02014-05-16 11:15:04 -07001594 if (r.intent != null &&
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001595 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
Winson Chunga449dc02014-05-16 11:15:04 -07001596 break;
1597 }
1598 }
1599 if (activityNdx > 0) {
1600 // Traverse downwards starting below break looking for set label, icon.
1601 // Note that if there are activities in the task but none of them set the
1602 // recent activity values, then we do not fall back to the last set
1603 // values in the TaskRecord.
1604 String label = null;
Craig Mautner648f69b2014-09-18 14:16:26 -07001605 String iconFilename = null;
Matthew Ng54bc9422017-10-02 17:16:28 -07001606 int iconResource = -1;
Winson Chunga449dc02014-05-16 11:15:04 -07001607 int colorPrimary = 0;
Winson Chung1af8eda2016-02-05 17:55:56 +00001608 int colorBackground = 0;
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001609 int statusBarColor = 0;
1610 int navigationBarColor = 0;
1611 boolean topActivity = true;
Winson Chunga449dc02014-05-16 11:15:04 -07001612 for (--activityNdx; activityNdx >= 0; --activityNdx) {
1613 final ActivityRecord r = mActivities.get(activityNdx);
Winson Chung80f80db2018-05-30 21:13:25 -07001614 if (r.mTaskOverlay) {
1615 continue;
1616 }
Winson Chunga449dc02014-05-16 11:15:04 -07001617 if (r.taskDescription != null) {
1618 if (label == null) {
1619 label = r.taskDescription.getLabel();
1620 }
Matthew Ng54bc9422017-10-02 17:16:28 -07001621 if (iconResource == -1) {
1622 iconResource = r.taskDescription.getIconResource();
1623 }
Craig Mautner648f69b2014-09-18 14:16:26 -07001624 if (iconFilename == null) {
1625 iconFilename = r.taskDescription.getIconFilename();
Winson Chunga449dc02014-05-16 11:15:04 -07001626 }
1627 if (colorPrimary == 0) {
1628 colorPrimary = r.taskDescription.getPrimaryColor();
Winson Chunga449dc02014-05-16 11:15:04 -07001629 }
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001630 if (topActivity) {
Winson Chung1af8eda2016-02-05 17:55:56 +00001631 colorBackground = r.taskDescription.getBackgroundColor();
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001632 statusBarColor = r.taskDescription.getStatusBarColor();
1633 navigationBarColor = r.taskDescription.getNavigationBarColor();
Winson Chung1af8eda2016-02-05 17:55:56 +00001634 }
Winson Chunga449dc02014-05-16 11:15:04 -07001635 }
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001636 topActivity = false;
Winson Chunga449dc02014-05-16 11:15:04 -07001637 }
Matthew Ng54bc9422017-10-02 17:16:28 -07001638 lastTaskDescription = new TaskDescription(label, null, iconResource, iconFilename,
1639 colorPrimary, colorBackground, statusBarColor, navigationBarColor);
Jorim Jaggi829b9cd2017-01-23 16:20:53 +01001640 if (mWindowContainerController != null) {
1641 mWindowContainerController.setTaskDescription(lastTaskDescription);
1642 }
Winson Chungec396d62014-08-06 17:08:00 -07001643 // Update the task affiliation color if we are the parent of the group
1644 if (taskId == mAffiliatedTaskId) {
1645 mAffiliatedTaskColor = lastTaskDescription.getPrimaryColor();
1646 }
Winson Chunga449dc02014-05-16 11:15:04 -07001647 }
1648 }
1649
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001650 int findEffectiveRootIndex() {
Craig Mautner4767f4b2014-09-18 15:38:33 -07001651 int effectiveNdx = 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001652 final int topActivityNdx = mActivities.size() - 1;
Dianne Hackborn39569af2014-09-23 10:56:58 -07001653 for (int activityNdx = 0; activityNdx <= topActivityNdx; ++activityNdx) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001654 final ActivityRecord r = mActivities.get(activityNdx);
1655 if (r.finishing) {
1656 continue;
1657 }
Craig Mautner4767f4b2014-09-18 15:38:33 -07001658 effectiveNdx = activityNdx;
Wale Ogunwale3eadad72016-10-13 09:16:59 -07001659 if ((r.info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001660 break;
1661 }
1662 }
Craig Mautner4767f4b2014-09-18 15:38:33 -07001663 return effectiveNdx;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001664 }
1665
1666 void updateEffectiveIntent() {
1667 final int effectiveRootIndex = findEffectiveRootIndex();
1668 final ActivityRecord r = mActivities.get(effectiveRootIndex);
Winson Chungfee26772014-08-05 12:21:52 -07001669 setIntent(r);
Winson Chung8d9009e2017-11-16 15:43:05 -08001670
1671 // Update the task description when the activities change
1672 updateTaskDescription();
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001673 }
1674
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001675 private void adjustForMinimalTaskDimensions(Rect bounds) {
1676 if (bounds == null) {
1677 return;
1678 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001679 int minWidth = mMinWidth;
1680 int minHeight = mMinHeight;
Robert Carr9c5867d2016-03-10 15:52:46 -08001681 // If the task has no requested minimal size, we'd like to enforce a minimal size
1682 // so that the user can not render the task too small to manipulate. We don't need
1683 // to do this for the pinned stack as the bounds are controlled by the system.
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001684 if (!inPinnedWindowingMode()) {
Garfield Tan4a48a7f2018-10-02 14:23:55 -07001685 final int defaultMinSizeDp =
Wale Ogunwaled32da472018-11-16 07:19:28 -08001686 mService.mRootActivityContainer.mDefaultMinSizeOfResizeableTaskDp;
Garfield Tan4a48a7f2018-10-02 14:23:55 -07001687 final ActivityDisplay display =
Wale Ogunwaled32da472018-11-16 07:19:28 -08001688 mService.mRootActivityContainer.getActivityDisplay(mStack.mDisplayId);
Garfield Tan4a48a7f2018-10-02 14:23:55 -07001689 final float density =
1690 (float) display.getConfiguration().densityDpi / DisplayMetrics.DENSITY_DEFAULT;
1691 final int defaultMinSize = (int) (defaultMinSizeDp * density);
1692
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001693 if (minWidth == INVALID_MIN_SIZE) {
Garfield Tan4a48a7f2018-10-02 14:23:55 -07001694 minWidth = defaultMinSize;
Andrii Kulian2e751b82016-03-16 16:59:32 -07001695 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001696 if (minHeight == INVALID_MIN_SIZE) {
Garfield Tan4a48a7f2018-10-02 14:23:55 -07001697 minHeight = defaultMinSize;
Andrii Kulian2e751b82016-03-16 16:59:32 -07001698 }
Robert Carr9c5867d2016-03-10 15:52:46 -08001699 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001700 final boolean adjustWidth = minWidth > bounds.width();
1701 final boolean adjustHeight = minHeight > bounds.height();
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001702 if (!(adjustWidth || adjustHeight)) {
1703 return;
1704 }
1705
Bryce Leef3c6a472017-11-14 14:53:06 -08001706 final Rect configBounds = getOverrideBounds();
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001707 if (adjustWidth) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001708 if (!configBounds.isEmpty() && bounds.right == configBounds.right) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001709 bounds.left = bounds.right - minWidth;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001710 } else {
1711 // Either left bounds match, or neither match, or the previous bounds were
1712 // fullscreen and we default to keeping left.
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001713 bounds.right = bounds.left + minWidth;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001714 }
1715 }
1716 if (adjustHeight) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001717 if (!configBounds.isEmpty() && bounds.bottom == configBounds.bottom) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001718 bounds.top = bounds.bottom - minHeight;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001719 } else {
1720 // Either top bounds match, or neither match, or the previous bounds were
1721 // fullscreen and we default to keeping top.
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001722 bounds.bottom = bounds.top + minHeight;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001723 }
1724 }
1725 }
1726
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001727 /**
Winson Chung5af42fc2017-03-24 17:11:33 -07001728 * @return a new Configuration for this Task, given the provided {@param bounds} and
1729 * {@param insetBounds}.
1730 */
1731 Configuration computeNewOverrideConfigurationForBounds(Rect bounds, Rect insetBounds) {
1732 // Compute a new override configuration for the given bounds, if fullscreen bounds
1733 // (bounds == null), then leave the override config unset
1734 final Configuration newOverrideConfig = new Configuration();
1735 if (bounds != null) {
1736 newOverrideConfig.setTo(getOverrideConfiguration());
1737 mTmpRect.set(bounds);
1738 adjustForMinimalTaskDimensions(mTmpRect);
1739 computeOverrideConfiguration(newOverrideConfig, mTmpRect, insetBounds,
1740 mTmpRect.right != bounds.right, mTmpRect.bottom != bounds.bottom);
1741 }
1742
1743 return newOverrideConfig;
1744 }
1745
1746 /**
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001747 * Update task's override configuration based on the bounds.
Jorim Jaggi0a932142016-02-01 17:42:25 -08001748 * @param bounds The bounds of the task.
Andrii Kulian8072d112016-09-16 11:11:01 -07001749 * @return True if the override configuration was updated.
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001750 */
Andrii Kulian8072d112016-09-16 11:11:01 -07001751 boolean updateOverrideConfiguration(Rect bounds) {
Jorim Jaggi0a932142016-02-01 17:42:25 -08001752 return updateOverrideConfiguration(bounds, null /* insetBounds */);
1753 }
1754
Evan Rosky9ba524e2018-01-03 16:27:56 -08001755 void setLastNonFullscreenBounds(Rect bounds) {
1756 if (mLastNonFullscreenBounds == null) {
1757 mLastNonFullscreenBounds = new Rect(bounds);
1758 } else {
1759 mLastNonFullscreenBounds.set(bounds);
1760 }
1761 }
1762
Jorim Jaggi0a932142016-02-01 17:42:25 -08001763 /**
1764 * Update task's override configuration based on the bounds.
1765 * @param bounds The bounds of the task.
1766 * @param insetBounds The bounds used to calculate the system insets, which is used here to
1767 * subtract the navigation bar/status bar size from the screen size reported
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001768 * to the application. See {@link IActivityTaskManager#resizeDockedStack}.
Andrii Kulian8072d112016-09-16 11:11:01 -07001769 * @return True if the override configuration was updated.
Jorim Jaggi0a932142016-02-01 17:42:25 -08001770 */
Andrii Kulian8072d112016-09-16 11:11:01 -07001771 boolean updateOverrideConfiguration(Rect bounds, @Nullable Rect insetBounds) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001772 if (equivalentOverrideBounds(bounds)) {
Andrii Kulian8072d112016-09-16 11:11:01 -07001773 return false;
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001774 }
Bryce Leef3c6a472017-11-14 14:53:06 -08001775 final Rect currentBounds = getOverrideBounds();
1776
Andrii Kulian1779e612016-10-12 21:58:25 -07001777 mTmpConfig.setTo(getOverrideConfiguration());
Andrii Kulian1779e612016-10-12 21:58:25 -07001778 final Configuration newConfig = getOverrideConfiguration();
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001779
Bryce Leef3c6a472017-11-14 14:53:06 -08001780 final boolean matchParentBounds = bounds == null || bounds.isEmpty();
Wale Ogunwale3382ab12017-07-27 08:55:03 -07001781 final boolean persistBounds = getWindowConfiguration().persistTaskBounds();
Bryce Leef3c6a472017-11-14 14:53:06 -08001782 if (matchParentBounds) {
1783 if (!currentBounds.isEmpty() && persistBounds) {
Evan Rosky9ba524e2018-01-03 16:27:56 -08001784 setLastNonFullscreenBounds(currentBounds);
Wale Ogunwale706ed792015-08-02 10:29:44 -07001785 }
Bryce Leef3c6a472017-11-14 14:53:06 -08001786 setBounds(null);
Andrii Kulian1779e612016-10-12 21:58:25 -07001787 newConfig.unset();
Wale Ogunwale706ed792015-08-02 10:29:44 -07001788 } else {
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001789 mTmpRect.set(bounds);
1790 adjustForMinimalTaskDimensions(mTmpRect);
Bryce Leef3c6a472017-11-14 14:53:06 -08001791 setBounds(mTmpRect);
1792
Wale Ogunwale3382ab12017-07-27 08:55:03 -07001793 if (mStack == null || persistBounds) {
Evan Rosky9ba524e2018-01-03 16:27:56 -08001794 setLastNonFullscreenBounds(getOverrideBounds());
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -07001795 }
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07001796 computeOverrideConfiguration(newConfig, mTmpRect, insetBounds,
Andrii Kuliandaea3572016-04-08 13:20:51 -07001797 mTmpRect.right != bounds.right, mTmpRect.bottom != bounds.bottom);
Wale Ogunwale706ed792015-08-02 10:29:44 -07001798 }
Andrii Kulian1779e612016-10-12 21:58:25 -07001799 onOverrideConfigurationChanged(newConfig);
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08001800 return !mTmpConfig.equals(newConfig);
1801 }
Wale Ogunwale5f986092015-12-04 15:35:38 -08001802
Bryce Leec4ab62a2018-03-05 14:19:26 -08001803 /**
1804 * This should be called when an child activity changes state. This should only
1805 * be called from
1806 * {@link ActivityRecord#setState(ActivityState, String)} .
1807 * @param record The {@link ActivityRecord} whose state has changed.
1808 * @param state The new state.
1809 * @param reason The reason for the change.
1810 */
1811 void onActivityStateChanged(ActivityRecord record, ActivityState state, String reason) {
1812 final ActivityStack parent = getStack();
1813
1814 if (parent != null) {
1815 parent.onActivityStateChanged(record, state, reason);
1816 }
1817 }
1818
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08001819 @Override
1820 public void onConfigurationChanged(Configuration newParentConfig) {
1821 final boolean wasInMultiWindowMode = inMultiWindowMode();
1822 super.onConfigurationChanged(newParentConfig);
1823 if (wasInMultiWindowMode != inMultiWindowMode()) {
Winson Chung5af42fc2017-03-24 17:11:33 -07001824 mService.mStackSupervisor.scheduleUpdateMultiWindowMode(this);
Wale Ogunwale5f986092015-12-04 15:35:38 -08001825 }
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08001826 // TODO: Should also take care of Pip mode changes here.
Garfield Tan891146c2018-10-09 12:14:00 -07001827
1828 saveLaunchingStateIfNeeded();
1829 }
1830
1831 /**
1832 * Saves launching state if necessary so that we can launch the activity to its latest state.
1833 * It only saves state if this task has been shown to user and it's in fullscreen or freeform
1834 * mode.
1835 */
1836 void saveLaunchingStateIfNeeded() {
1837 if (!hasBeenVisible) {
1838 // Not ever visible to user.
1839 return;
1840 }
1841
1842 final int windowingMode = getWindowingMode();
1843 if (windowingMode != WindowConfiguration.WINDOWING_MODE_FULLSCREEN
1844 && windowingMode != WindowConfiguration.WINDOWING_MODE_FREEFORM) {
1845 return;
1846 }
1847
1848 // Saves the new state so that we can launch the activity at the same location.
1849 mService.mStackSupervisor.mLaunchParamsPersister.saveTask(this);
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001850 }
1851
Andrii Kulian1779e612016-10-12 21:58:25 -07001852 /** Clears passed config and fills it with new override values. */
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07001853 // TODO(b/36505427): TaskRecord.computeOverrideConfiguration() is a utility method that doesn't
1854 // depend on task or stacks, but uses those object to get the display to base the calculation
1855 // on. Probably best to centralize calculations like this in ConfigurationContainer.
1856 void computeOverrideConfiguration(Configuration config, Rect bounds, Rect insetBounds,
Andrii Kuliana8a9bc52016-10-14 11:00:13 -07001857 boolean overrideWidth, boolean overrideHeight) {
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001858 mTmpNonDecorBounds.set(bounds);
1859 mTmpStableBounds.set(bounds);
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001860
Andrii Kulian1779e612016-10-12 21:58:25 -07001861 config.unset();
Winson Chungbdc646f2017-02-13 12:12:22 -08001862 final Configuration parentConfig = getParent().getConfiguration();
Bryce Lee7566d762017-03-30 09:34:15 -07001863
Andrii Kulian1779e612016-10-12 21:58:25 -07001864 final float density = parentConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001865
Winson Chungbdc646f2017-02-13 12:12:22 -08001866 if (mStack != null) {
1867 final StackWindowController stackController = mStack.getWindowContainerController();
1868 stackController.adjustConfigurationForBounds(bounds, insetBounds,
1869 mTmpNonDecorBounds, mTmpStableBounds, overrideWidth, overrideHeight, density,
Evan Roskyb0e38882018-04-25 12:48:54 -07001870 config, parentConfig, getWindowingMode());
Winson Chungbdc646f2017-02-13 12:12:22 -08001871 } else {
Bryce Lee7566d762017-03-30 09:34:15 -07001872 throw new IllegalArgumentException("Expected stack when calculating override config");
Winson Chungbdc646f2017-02-13 12:12:22 -08001873 }
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001874
Winson Chung60c1aba2017-03-14 17:47:42 -07001875 config.orientation = (config.screenWidthDp <= config.screenHeightDp)
1876 ? Configuration.ORIENTATION_PORTRAIT
1877 : Configuration.ORIENTATION_LANDSCAPE;
1878
Jorim Jaggi85639432016-05-06 17:27:55 -07001879 // For calculating screen layout, we need to use the non-decor inset screen area for the
1880 // calculation for compatibility reasons, i.e. screen area without system bars that could
1881 // never go away in Honeycomb.
Winson Chungbdc646f2017-02-13 12:12:22 -08001882 final int compatScreenWidthDp = (int) (mTmpNonDecorBounds.width() / density);
1883 final int compatScreenHeightDp = (int) (mTmpNonDecorBounds.height() / density);
Andrii Kulian1779e612016-10-12 21:58:25 -07001884 // We're only overriding LONG, SIZE and COMPAT parts of screenLayout, so we start override
1885 // calculation with partial default.
Louis Chang8b580162018-06-26 17:58:29 +08001886 // Reducing the screen layout starting from its parent config.
1887 final int sl = parentConfig.screenLayout &
1888 (Configuration.SCREENLAYOUT_LONG_MASK | Configuration.SCREENLAYOUT_SIZE_MASK);
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001889 final int longSize = Math.max(compatScreenHeightDp, compatScreenWidthDp);
Andrii Kulian1779e612016-10-12 21:58:25 -07001890 final int shortSize = Math.min(compatScreenHeightDp, compatScreenWidthDp);
Jorim Jaggi85639432016-05-06 17:27:55 -07001891 config.screenLayout = Configuration.reduceScreenLayout(sl, longSize, shortSize);
Jorim Jaggia95ca8d2016-01-15 22:54:46 -08001892 }
1893
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08001894 Rect updateOverrideConfigurationFromLaunchBounds() {
Bryce Leef3c6a472017-11-14 14:53:06 -08001895 final Rect bounds = getLaunchBounds();
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08001896 updateOverrideConfiguration(bounds);
Bryce Leef3c6a472017-11-14 14:53:06 -08001897 if (bounds != null && !bounds.isEmpty()) {
1898 // TODO: Review if we actually want to do this - we are setting the launch bounds
1899 // directly here.
1900 bounds.set(getOverrideBounds());
Andrii Kulian73336d812016-03-24 12:56:08 -07001901 }
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08001902 return bounds;
1903 }
1904
Wale Ogunwale935e5022015-11-10 12:36:10 -08001905 /** Updates the task's bounds and override configuration to match what is expected for the
1906 * input stack. */
1907 void updateOverrideConfigurationForStack(ActivityStack inStack) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001908 if (mStack != null && mStack == inStack) {
Wale Ogunwale935e5022015-11-10 12:36:10 -08001909 return;
1910 }
1911
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001912 if (inStack.inFreeformWindowingMode()) {
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001913 if (!isResizeable()) {
Wale Ogunwale935e5022015-11-10 12:36:10 -08001914 throw new IllegalArgumentException("Can not position non-resizeable task="
1915 + this + " in stack=" + inStack);
1916 }
Bryce Leef3c6a472017-11-14 14:53:06 -08001917 if (!matchParentBounds()) {
Wale Ogunwale935e5022015-11-10 12:36:10 -08001918 return;
1919 }
1920 if (mLastNonFullscreenBounds != null) {
1921 updateOverrideConfiguration(mLastNonFullscreenBounds);
1922 } else {
Bryce Leeec55eb02017-12-05 20:51:27 -08001923 mService.mStackSupervisor.getLaunchParamsController().layoutTask(this, null);
Wale Ogunwale935e5022015-11-10 12:36:10 -08001924 }
1925 } else {
Bryce Leef3c6a472017-11-14 14:53:06 -08001926 updateOverrideConfiguration(inStack.getOverrideBounds());
Wale Ogunwale935e5022015-11-10 12:36:10 -08001927 }
1928 }
1929
Wale Ogunwale706ed792015-08-02 10:29:44 -07001930 /** Returns the bounds that should be used to launch this task. */
Wale Ogunwale30e441d2017-11-09 08:28:45 -08001931 Rect getLaunchBounds() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001932 if (mStack == null) {
Chong Zhang7d5f5102016-01-13 10:29:24 -08001933 return null;
1934 }
1935
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001936 final int windowingMode = getWindowingMode();
1937 if (!isActivityTypeStandardOrUndefined()
1938 || windowingMode == WINDOWING_MODE_FULLSCREEN
1939 || (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY && !isResizeable())) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001940 return isResizeable() ? mStack.getOverrideBounds() : null;
Wale Ogunwale3382ab12017-07-27 08:55:03 -07001941 } else if (!getWindowConfiguration().persistTaskBounds()) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001942 return mStack.getOverrideBounds();
Wale Ogunwale706ed792015-08-02 10:29:44 -07001943 }
1944 return mLastNonFullscreenBounds;
1945 }
1946
Jorim Jaggi8b702ed2017-01-20 16:59:03 +01001947 void addStartingWindowsForVisibleActivities(boolean taskSwitch) {
1948 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1949 final ActivityRecord r = mActivities.get(activityNdx);
1950 if (r.visible) {
1951 r.showStartingWindow(null /* prev */, false /* newTask */, taskSwitch);
1952 }
1953 }
1954 }
1955
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001956 void setRootProcess(WindowProcessController proc) {
Dianne Hackborn68a06332017-11-15 17:54:18 -08001957 clearRootProcess();
1958 if (intent != null &&
1959 (intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0) {
1960 mRootProcess = proc;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001961 mRootProcess.addRecentTask(this);
Dianne Hackborn68a06332017-11-15 17:54:18 -08001962 }
1963 }
1964
1965 void clearRootProcess() {
1966 if (mRootProcess != null) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001967 mRootProcess.removeRecentTask(this);
Dianne Hackborn68a06332017-11-15 17:54:18 -08001968 mRootProcess = null;
1969 }
1970 }
1971
chaviw82a0ba82018-03-15 14:26:29 -07001972 void clearAllPendingOptions() {
1973 for (int i = getChildCount() - 1; i >= 0; i--) {
1974 getChildAt(i).clearOptionsLocked(false /* withAbort */);
1975 }
1976 }
1977
Winson Chungabfdcce2018-07-02 17:23:33 -07001978 /**
1979 * Fills in a {@link TaskInfo} with information from this task.
1980 * @param info the {@link TaskInfo} to fill in
1981 * @param reuseActivitiesReport a temporary activities report that we can reuse to fetch the
1982 * running activities
1983 */
1984 void fillTaskInfo(TaskInfo info, TaskActivitiesReport reuseActivitiesReport) {
1985 getNumRunningActivities(reuseActivitiesReport);
1986 info.userId = userId;
1987 info.stackId = getStackId();
1988 info.taskId = taskId;
1989 info.isRunning = getTopActivity() != null;
Riddle Hsu2f9acd22018-11-06 23:44:43 +08001990 info.baseIntent = new Intent(getBaseIntent());
Winson Chungabfdcce2018-07-02 17:23:33 -07001991 info.baseActivity = reuseActivitiesReport.base != null
1992 ? reuseActivitiesReport.base.intent.getComponent()
1993 : null;
1994 info.topActivity = reuseActivitiesReport.top != null
Winson Chung48b25652018-10-22 14:04:30 -07001995 ? reuseActivitiesReport.top.realActivity
Winson Chungabfdcce2018-07-02 17:23:33 -07001996 : null;
1997 info.origActivity = origActivity;
1998 info.realActivity = realActivity;
1999 info.numActivities = reuseActivitiesReport.numActivities;
2000 info.lastActiveTime = lastActiveTime;
2001 info.taskDescription = new ActivityManager.TaskDescription(lastTaskDescription);
2002 info.supportsSplitScreenMultiWindow = supportsSplitScreenWindowingMode();
2003 info.resizeMode = mResizeMode;
2004 info.configuration.setTo(getConfiguration());
2005 }
2006
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002007 void dump(PrintWriter pw, String prefix) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002008 pw.print(prefix); pw.print("userId="); pw.print(userId);
Dianne Hackborn885fbe52014-08-23 15:23:58 -07002009 pw.print(" effectiveUid="); UserHandle.formatUid(pw, effectiveUid);
2010 pw.print(" mCallingUid="); UserHandle.formatUid(pw, mCallingUid);
Suprabh Shukla7745c142016-03-07 18:21:10 -08002011 pw.print(" mUserSetupComplete="); pw.print(mUserSetupComplete);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002012 pw.print(" mCallingPackage="); pw.println(mCallingPackage);
Dianne Hackborn79228822014-09-16 11:11:23 -07002013 if (affinity != null || rootAffinity != null) {
2014 pw.print(prefix); pw.print("affinity="); pw.print(affinity);
2015 if (affinity == null || !affinity.equals(rootAffinity)) {
2016 pw.print(" root="); pw.println(rootAffinity);
2017 } else {
2018 pw.println();
2019 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002020 }
Dianne Hackborn91097de2014-04-04 18:02:06 -07002021 if (voiceSession != null || voiceInteractor != null) {
2022 pw.print(prefix); pw.print("VOICE: session=0x");
2023 pw.print(Integer.toHexString(System.identityHashCode(voiceSession)));
2024 pw.print(" interactor=0x");
2025 pw.println(Integer.toHexString(System.identityHashCode(voiceInteractor)));
2026 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002027 if (intent != null) {
2028 StringBuilder sb = new StringBuilder(128);
2029 sb.append(prefix); sb.append("intent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08002030 intent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002031 sb.append('}');
2032 pw.println(sb.toString());
2033 }
2034 if (affinityIntent != null) {
2035 StringBuilder sb = new StringBuilder(128);
2036 sb.append(prefix); sb.append("affinityIntent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08002037 affinityIntent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002038 sb.append('}');
2039 pw.println(sb.toString());
2040 }
2041 if (origActivity != null) {
2042 pw.print(prefix); pw.print("origActivity=");
2043 pw.println(origActivity.flattenToShortString());
2044 }
2045 if (realActivity != null) {
2046 pw.print(prefix); pw.print("realActivity=");
2047 pw.println(realActivity.flattenToShortString());
2048 }
Wale Ogunwale66e16852017-10-19 13:35:52 -07002049 if (autoRemoveRecents || isPersistable || !isActivityTypeStandard() || numFullscreen != 0) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002050 pw.print(prefix); pw.print("autoRemoveRecents="); pw.print(autoRemoveRecents);
Dianne Hackborn852975d2014-08-22 17:42:43 -07002051 pw.print(" isPersistable="); pw.print(isPersistable);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002052 pw.print(" numFullscreen="); pw.print(numFullscreen);
Wale Ogunwale66e16852017-10-19 13:35:52 -07002053 pw.print(" activityType="); pw.println(getActivityType());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002054 }
Craig Mautner432f64e2015-05-20 14:59:57 -07002055 if (rootWasReset || mNeverRelinquishIdentity || mReuseTask
2056 || mLockTaskAuth != LOCK_TASK_AUTH_PINNABLE) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002057 pw.print(prefix); pw.print("rootWasReset="); pw.print(rootWasReset);
2058 pw.print(" mNeverRelinquishIdentity="); pw.print(mNeverRelinquishIdentity);
Craig Mautner432f64e2015-05-20 14:59:57 -07002059 pw.print(" mReuseTask="); pw.print(mReuseTask);
2060 pw.print(" mLockTaskAuth="); pw.println(lockTaskAuthToString());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002061 }
Wale Ogunwale18795a22014-12-03 11:38:33 -08002062 if (mAffiliatedTaskId != taskId || mPrevAffiliateTaskId != INVALID_TASK_ID
2063 || mPrevAffiliate != null || mNextAffiliateTaskId != INVALID_TASK_ID
2064 || mNextAffiliate != null) {
Dianne Hackborn852975d2014-08-22 17:42:43 -07002065 pw.print(prefix); pw.print("affiliation="); pw.print(mAffiliatedTaskId);
2066 pw.print(" prevAffiliation="); pw.print(mPrevAffiliateTaskId);
2067 pw.print(" (");
2068 if (mPrevAffiliate == null) {
2069 pw.print("null");
2070 } else {
2071 pw.print(Integer.toHexString(System.identityHashCode(mPrevAffiliate)));
2072 }
2073 pw.print(") nextAffiliation="); pw.print(mNextAffiliateTaskId);
2074 pw.print(" (");
2075 if (mNextAffiliate == null) {
2076 pw.print("null");
2077 } else {
2078 pw.print(Integer.toHexString(System.identityHashCode(mNextAffiliate)));
2079 }
2080 pw.println(")");
2081 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002082 pw.print(prefix); pw.print("Activities="); pw.println(mActivities);
Dianne Hackborn852975d2014-08-22 17:42:43 -07002083 if (!askedCompatMode || !inRecents || !isAvailable) {
2084 pw.print(prefix); pw.print("askedCompatMode="); pw.print(askedCompatMode);
2085 pw.print(" inRecents="); pw.print(inRecents);
2086 pw.print(" isAvailable="); pw.println(isAvailable);
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002087 }
Dianne Hackborn852975d2014-08-22 17:42:43 -07002088 if (lastDescription != null) {
2089 pw.print(prefix); pw.print("lastDescription="); pw.println(lastDescription);
2090 }
Dianne Hackborn68a06332017-11-15 17:54:18 -08002091 if (mRootProcess != null) {
2092 pw.print(prefix); pw.print("mRootProcess="); pw.println(mRootProcess);
2093 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07002094 pw.print(prefix); pw.print("stackId="); pw.println(getStackId());
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002095 pw.print(prefix + "hasBeenVisible=" + hasBeenVisible);
2096 pw.print(" mResizeMode=" + ActivityInfo.resizeModeToString(mResizeMode));
Winson Chungd3395382016-12-13 11:49:09 -08002097 pw.print(" mSupportsPictureInPicture=" + mSupportsPictureInPicture);
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002098 pw.print(" isResizeable=" + isResizeable());
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002099 pw.print(" lastActiveTime=" + lastActiveTime);
2100 pw.println(" (inactive for " + (getInactiveDuration() / 1000) + "s)");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002101 }
2102
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002103 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002104 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002105 StringBuilder sb = new StringBuilder(128);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002106 if (stringName != null) {
2107 sb.append(stringName);
2108 sb.append(" U=");
2109 sb.append(userId);
Wale Ogunwale6c5eb1c2015-11-10 07:52:22 -08002110 sb.append(" StackId=");
Andrii Kulian02b7a832016-10-06 23:11:56 -07002111 sb.append(getStackId());
Craig Mautnerde4ef022013-04-07 19:01:33 -07002112 sb.append(" sz=");
2113 sb.append(mActivities.size());
2114 sb.append('}');
2115 return sb.toString();
2116 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002117 sb.append("TaskRecord{");
2118 sb.append(Integer.toHexString(System.identityHashCode(this)));
2119 sb.append(" #");
2120 sb.append(taskId);
2121 if (affinity != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002122 sb.append(" A=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002123 sb.append(affinity);
2124 } else if (intent != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002125 sb.append(" I=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002126 sb.append(intent.getComponent().flattenToShortString());
Bryce Leefbd263b42018-03-07 10:33:55 -08002127 } else if (affinityIntent != null && affinityIntent.getComponent() != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002128 sb.append(" aI=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002129 sb.append(affinityIntent.getComponent().flattenToShortString());
2130 } else {
2131 sb.append(" ??");
2132 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07002133 stringName = sb.toString();
2134 return toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002135 }
Steven Timotius4346f0a2017-09-12 11:07:21 -07002136
2137 public void writeToProto(ProtoOutputStream proto, long fieldId) {
2138 final long token = proto.start(fieldId);
Adrian Roos4921ccf2017-09-28 16:54:06 +02002139 super.writeToProto(proto, CONFIGURATION_CONTAINER, false /* trim */);
Steven Timotius4346f0a2017-09-12 11:07:21 -07002140 proto.write(ID, taskId);
2141 for (int i = mActivities.size() - 1; i >= 0; i--) {
2142 ActivityRecord activity = mActivities.get(i);
2143 activity.writeToProto(proto, ACTIVITIES);
2144 }
2145 proto.write(STACK_ID, mStack.mStackId);
2146 if (mLastNonFullscreenBounds != null) {
2147 mLastNonFullscreenBounds.writeToProto(proto, LAST_NON_FULLSCREEN_BOUNDS);
2148 }
2149 if (realActivity != null) {
2150 proto.write(REAL_ACTIVITY, realActivity.flattenToShortString());
2151 }
2152 if (origActivity != null) {
2153 proto.write(ORIG_ACTIVITY, origActivity.flattenToShortString());
2154 }
2155 proto.write(ACTIVITY_TYPE, getActivityType());
Steven Timotius4346f0a2017-09-12 11:07:21 -07002156 proto.write(RESIZE_MODE, mResizeMode);
Bryce Leef3c6a472017-11-14 14:53:06 -08002157 // TODO: Remove, no longer needed with windowingMode.
2158 proto.write(FULLSCREEN, matchParentBounds());
2159
2160 if (!matchParentBounds()) {
2161 final Rect bounds = getOverrideBounds();
2162 bounds.writeToProto(proto, BOUNDS);
Steven Timotius4346f0a2017-09-12 11:07:21 -07002163 }
2164 proto.write(MIN_WIDTH, mMinWidth);
2165 proto.write(MIN_HEIGHT, mMinHeight);
2166 proto.end(token);
2167 }
Winson Chung61c9e5a2017-10-11 10:39:32 -07002168
2169 /**
2170 * See {@link #getNumRunningActivities(TaskActivitiesReport)}.
2171 */
2172 static class TaskActivitiesReport {
2173 int numRunning;
2174 int numActivities;
2175 ActivityRecord top;
2176 ActivityRecord base;
2177
2178 void reset() {
2179 numRunning = numActivities = 0;
2180 top = base = null;
2181 }
2182 }
Garfield Tan9b1efea2017-12-05 16:43:46 -08002183
2184 /**
2185 * Saves this {@link TaskRecord} to XML using given serializer.
2186 */
2187 void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
2188 if (DEBUG_RECENTS) Slog.i(TAG_RECENTS, "Saving task=" + this);
2189
2190 out.attribute(null, ATTR_TASKID, String.valueOf(taskId));
2191 if (realActivity != null) {
2192 out.attribute(null, ATTR_REALACTIVITY, realActivity.flattenToShortString());
2193 }
2194 out.attribute(null, ATTR_REALACTIVITY_SUSPENDED, String.valueOf(realActivitySuspended));
2195 if (origActivity != null) {
2196 out.attribute(null, ATTR_ORIGACTIVITY, origActivity.flattenToShortString());
2197 }
2198 // Write affinity, and root affinity if it is different from affinity.
2199 // We use the special string "@" for a null root affinity, so we can identify
2200 // later whether we were given a root affinity or should just make it the
2201 // same as the affinity.
2202 if (affinity != null) {
2203 out.attribute(null, ATTR_AFFINITY, affinity);
2204 if (!affinity.equals(rootAffinity)) {
2205 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
2206 }
2207 } else if (rootAffinity != null) {
2208 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
2209 }
2210 out.attribute(null, ATTR_ROOTHASRESET, String.valueOf(rootWasReset));
2211 out.attribute(null, ATTR_AUTOREMOVERECENTS, String.valueOf(autoRemoveRecents));
2212 out.attribute(null, ATTR_ASKEDCOMPATMODE, String.valueOf(askedCompatMode));
2213 out.attribute(null, ATTR_USERID, String.valueOf(userId));
2214 out.attribute(null, ATTR_USER_SETUP_COMPLETE, String.valueOf(mUserSetupComplete));
2215 out.attribute(null, ATTR_EFFECTIVE_UID, String.valueOf(effectiveUid));
2216 out.attribute(null, ATTR_LASTTIMEMOVED, String.valueOf(mLastTimeMoved));
2217 out.attribute(null, ATTR_NEVERRELINQUISH, String.valueOf(mNeverRelinquishIdentity));
2218 if (lastDescription != null) {
2219 out.attribute(null, ATTR_LASTDESCRIPTION, lastDescription.toString());
2220 }
2221 if (lastTaskDescription != null) {
2222 lastTaskDescription.saveToXml(out);
2223 }
2224 out.attribute(null, ATTR_TASK_AFFILIATION_COLOR, String.valueOf(mAffiliatedTaskColor));
2225 out.attribute(null, ATTR_TASK_AFFILIATION, String.valueOf(mAffiliatedTaskId));
2226 out.attribute(null, ATTR_PREV_AFFILIATION, String.valueOf(mPrevAffiliateTaskId));
2227 out.attribute(null, ATTR_NEXT_AFFILIATION, String.valueOf(mNextAffiliateTaskId));
2228 out.attribute(null, ATTR_CALLING_UID, String.valueOf(mCallingUid));
2229 out.attribute(null, ATTR_CALLING_PACKAGE, mCallingPackage == null ? "" : mCallingPackage);
2230 out.attribute(null, ATTR_RESIZE_MODE, String.valueOf(mResizeMode));
2231 out.attribute(null, ATTR_SUPPORTS_PICTURE_IN_PICTURE,
2232 String.valueOf(mSupportsPictureInPicture));
2233 if (mLastNonFullscreenBounds != null) {
2234 out.attribute(
2235 null, ATTR_NON_FULLSCREEN_BOUNDS, mLastNonFullscreenBounds.flattenToString());
2236 }
2237 out.attribute(null, ATTR_MIN_WIDTH, String.valueOf(mMinWidth));
2238 out.attribute(null, ATTR_MIN_HEIGHT, String.valueOf(mMinHeight));
2239 out.attribute(null, ATTR_PERSIST_TASK_VERSION, String.valueOf(PERSIST_TASK_VERSION));
2240
2241 if (affinityIntent != null) {
2242 out.startTag(null, TAG_AFFINITYINTENT);
2243 affinityIntent.saveToXml(out);
2244 out.endTag(null, TAG_AFFINITYINTENT);
2245 }
2246
Bryce Lee1a990e52018-04-23 10:54:11 -07002247 if (intent != null) {
2248 out.startTag(null, TAG_INTENT);
2249 intent.saveToXml(out);
2250 out.endTag(null, TAG_INTENT);
2251 }
Garfield Tan9b1efea2017-12-05 16:43:46 -08002252
2253 final ArrayList<ActivityRecord> activities = mActivities;
2254 final int numActivities = activities.size();
2255 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
2256 final ActivityRecord r = activities.get(activityNdx);
2257 if (r.info.persistableMode == ActivityInfo.PERSIST_ROOT_ONLY || !r.isPersistable() ||
2258 ((r.intent.getFlags() & FLAG_ACTIVITY_NEW_DOCUMENT
2259 | FLAG_ACTIVITY_RETAIN_IN_RECENTS) == FLAG_ACTIVITY_NEW_DOCUMENT) &&
2260 activityNdx > 0) {
2261 // Stop at first non-persistable or first break in task (CLEAR_WHEN_TASK_RESET).
2262 break;
2263 }
2264 out.startTag(null, TAG_ACTIVITY);
2265 r.saveToXml(out);
2266 out.endTag(null, TAG_ACTIVITY);
2267 }
2268 }
2269
2270 @VisibleForTesting
2271 static TaskRecordFactory getTaskRecordFactory() {
2272 if (sTaskRecordFactory == null) {
2273 setTaskRecordFactory(new TaskRecordFactory());
2274 }
2275 return sTaskRecordFactory;
2276 }
2277
2278 static void setTaskRecordFactory(TaskRecordFactory factory) {
2279 sTaskRecordFactory = factory;
2280 }
2281
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002282 static TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002283 Intent intent, IVoiceInteractionSession voiceSession,
2284 IVoiceInteractor voiceInteractor) {
2285 return getTaskRecordFactory().create(
2286 service, taskId, info, intent, voiceSession, voiceInteractor);
2287 }
2288
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002289 static TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002290 Intent intent, TaskDescription taskDescription) {
2291 return getTaskRecordFactory().create(service, taskId, info, intent, taskDescription);
2292 }
2293
2294 static TaskRecord restoreFromXml(XmlPullParser in, ActivityStackSupervisor stackSupervisor)
2295 throws IOException, XmlPullParserException {
2296 return getTaskRecordFactory().restoreFromXml(in, stackSupervisor);
2297 }
2298
2299 /**
2300 * A factory class used to create {@link TaskRecord} or its subclass if any. This can be
2301 * specified when system boots by setting it with
2302 * {@link #setTaskRecordFactory(TaskRecordFactory)}.
2303 */
2304 static class TaskRecordFactory {
2305
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002306 TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002307 Intent intent, IVoiceInteractionSession voiceSession,
2308 IVoiceInteractor voiceInteractor) {
2309 return new TaskRecord(
2310 service, taskId, info, intent, voiceSession, voiceInteractor);
2311 }
2312
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002313 TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002314 Intent intent, TaskDescription taskDescription) {
2315 return new TaskRecord(service, taskId, info, intent, taskDescription);
2316 }
2317
2318 /**
2319 * Should only be used when we're restoring {@link TaskRecord} from storage.
2320 */
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002321 TaskRecord create(ActivityTaskManagerService service, int taskId, Intent intent,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002322 Intent affinityIntent, String affinity, String rootAffinity,
2323 ComponentName realActivity, ComponentName origActivity, boolean rootWasReset,
2324 boolean autoRemoveRecents, boolean askedCompatMode, int userId,
2325 int effectiveUid, String lastDescription, ArrayList<ActivityRecord> activities,
2326 long lastTimeMoved, boolean neverRelinquishIdentity,
2327 TaskDescription lastTaskDescription, int taskAffiliation, int prevTaskId,
2328 int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage,
2329 int resizeMode, boolean supportsPictureInPicture, boolean realActivitySuspended,
2330 boolean userSetupComplete, int minWidth, int minHeight) {
2331 return new TaskRecord(service, taskId, intent, affinityIntent, affinity,
2332 rootAffinity, realActivity, origActivity, rootWasReset, autoRemoveRecents,
2333 askedCompatMode, userId, effectiveUid, lastDescription, activities,
2334 lastTimeMoved, neverRelinquishIdentity, lastTaskDescription, taskAffiliation,
2335 prevTaskId, nextTaskId, taskAffiliationColor, callingUid, callingPackage,
2336 resizeMode, supportsPictureInPicture, realActivitySuspended, userSetupComplete,
2337 minWidth, minHeight);
2338 }
2339
2340 TaskRecord restoreFromXml(XmlPullParser in, ActivityStackSupervisor stackSupervisor)
2341 throws IOException, XmlPullParserException {
2342 Intent intent = null;
2343 Intent affinityIntent = null;
2344 ArrayList<ActivityRecord> activities = new ArrayList<>();
2345 ComponentName realActivity = null;
2346 boolean realActivitySuspended = false;
2347 ComponentName origActivity = null;
2348 String affinity = null;
2349 String rootAffinity = null;
2350 boolean hasRootAffinity = false;
2351 boolean rootHasReset = false;
2352 boolean autoRemoveRecents = false;
2353 boolean askedCompatMode = false;
2354 int taskType = 0;
2355 int userId = 0;
2356 boolean userSetupComplete = true;
2357 int effectiveUid = -1;
2358 String lastDescription = null;
2359 long lastTimeOnTop = 0;
2360 boolean neverRelinquishIdentity = true;
2361 int taskId = INVALID_TASK_ID;
2362 final int outerDepth = in.getDepth();
2363 TaskDescription taskDescription = new TaskDescription();
2364 int taskAffiliation = INVALID_TASK_ID;
2365 int taskAffiliationColor = 0;
2366 int prevTaskId = INVALID_TASK_ID;
2367 int nextTaskId = INVALID_TASK_ID;
2368 int callingUid = -1;
2369 String callingPackage = "";
2370 int resizeMode = RESIZE_MODE_FORCE_RESIZEABLE;
2371 boolean supportsPictureInPicture = false;
Garfield Tan367b35a2017-12-13 12:16:21 -08002372 Rect lastNonFullscreenBounds = null;
Garfield Tan9b1efea2017-12-05 16:43:46 -08002373 int minWidth = INVALID_MIN_SIZE;
2374 int minHeight = INVALID_MIN_SIZE;
2375 int persistTaskVersion = 0;
2376
2377 for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
2378 final String attrName = in.getAttributeName(attrNdx);
2379 final String attrValue = in.getAttributeValue(attrNdx);
2380 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: attribute name=" +
2381 attrName + " value=" + attrValue);
2382 switch (attrName) {
2383 case ATTR_TASKID:
2384 if (taskId == INVALID_TASK_ID) taskId = Integer.parseInt(attrValue);
2385 break;
2386 case ATTR_REALACTIVITY:
2387 realActivity = ComponentName.unflattenFromString(attrValue);
2388 break;
2389 case ATTR_REALACTIVITY_SUSPENDED:
2390 realActivitySuspended = Boolean.valueOf(attrValue);
2391 break;
2392 case ATTR_ORIGACTIVITY:
2393 origActivity = ComponentName.unflattenFromString(attrValue);
2394 break;
2395 case ATTR_AFFINITY:
2396 affinity = attrValue;
2397 break;
2398 case ATTR_ROOT_AFFINITY:
2399 rootAffinity = attrValue;
2400 hasRootAffinity = true;
2401 break;
2402 case ATTR_ROOTHASRESET:
2403 rootHasReset = Boolean.parseBoolean(attrValue);
2404 break;
2405 case ATTR_AUTOREMOVERECENTS:
2406 autoRemoveRecents = Boolean.parseBoolean(attrValue);
2407 break;
2408 case ATTR_ASKEDCOMPATMODE:
2409 askedCompatMode = Boolean.parseBoolean(attrValue);
2410 break;
2411 case ATTR_USERID:
2412 userId = Integer.parseInt(attrValue);
2413 break;
2414 case ATTR_USER_SETUP_COMPLETE:
2415 userSetupComplete = Boolean.parseBoolean(attrValue);
2416 break;
2417 case ATTR_EFFECTIVE_UID:
2418 effectiveUid = Integer.parseInt(attrValue);
2419 break;
2420 case ATTR_TASKTYPE:
2421 taskType = Integer.parseInt(attrValue);
2422 break;
2423 case ATTR_LASTDESCRIPTION:
2424 lastDescription = attrValue;
2425 break;
2426 case ATTR_LASTTIMEMOVED:
2427 lastTimeOnTop = Long.parseLong(attrValue);
2428 break;
2429 case ATTR_NEVERRELINQUISH:
2430 neverRelinquishIdentity = Boolean.parseBoolean(attrValue);
2431 break;
2432 case ATTR_TASK_AFFILIATION:
2433 taskAffiliation = Integer.parseInt(attrValue);
2434 break;
2435 case ATTR_PREV_AFFILIATION:
2436 prevTaskId = Integer.parseInt(attrValue);
2437 break;
2438 case ATTR_NEXT_AFFILIATION:
2439 nextTaskId = Integer.parseInt(attrValue);
2440 break;
2441 case ATTR_TASK_AFFILIATION_COLOR:
2442 taskAffiliationColor = Integer.parseInt(attrValue);
2443 break;
2444 case ATTR_CALLING_UID:
2445 callingUid = Integer.parseInt(attrValue);
2446 break;
2447 case ATTR_CALLING_PACKAGE:
2448 callingPackage = attrValue;
2449 break;
2450 case ATTR_RESIZE_MODE:
2451 resizeMode = Integer.parseInt(attrValue);
2452 break;
2453 case ATTR_SUPPORTS_PICTURE_IN_PICTURE:
2454 supportsPictureInPicture = Boolean.parseBoolean(attrValue);
2455 break;
2456 case ATTR_NON_FULLSCREEN_BOUNDS:
Garfield Tan367b35a2017-12-13 12:16:21 -08002457 lastNonFullscreenBounds = Rect.unflattenFromString(attrValue);
Garfield Tan9b1efea2017-12-05 16:43:46 -08002458 break;
2459 case ATTR_MIN_WIDTH:
2460 minWidth = Integer.parseInt(attrValue);
2461 break;
2462 case ATTR_MIN_HEIGHT:
2463 minHeight = Integer.parseInt(attrValue);
2464 break;
2465 case ATTR_PERSIST_TASK_VERSION:
2466 persistTaskVersion = Integer.parseInt(attrValue);
2467 break;
2468 default:
2469 if (attrName.startsWith(TaskDescription.ATTR_TASKDESCRIPTION_PREFIX)) {
2470 taskDescription.restoreFromXml(attrName, attrValue);
2471 } else {
2472 Slog.w(TAG, "TaskRecord: Unknown attribute=" + attrName);
2473 }
2474 }
2475 }
2476
2477 int event;
2478 while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
2479 (event != XmlPullParser.END_TAG || in.getDepth() >= outerDepth)) {
2480 if (event == XmlPullParser.START_TAG) {
2481 final String name = in.getName();
2482 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG,
2483 "TaskRecord: START_TAG name=" + name);
2484 if (TAG_AFFINITYINTENT.equals(name)) {
2485 affinityIntent = Intent.restoreFromXml(in);
2486 } else if (TAG_INTENT.equals(name)) {
2487 intent = Intent.restoreFromXml(in);
2488 } else if (TAG_ACTIVITY.equals(name)) {
2489 ActivityRecord activity =
2490 ActivityRecord.restoreFromXml(in, stackSupervisor);
2491 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: activity=" +
2492 activity);
2493 if (activity != null) {
2494 activities.add(activity);
2495 }
2496 } else {
Garfield Tan1e740192017-12-12 14:37:42 -08002497 handleUnknownTag(name, in);
Garfield Tan9b1efea2017-12-05 16:43:46 -08002498 }
2499 }
2500 }
2501 if (!hasRootAffinity) {
2502 rootAffinity = affinity;
2503 } else if ("@".equals(rootAffinity)) {
2504 rootAffinity = null;
2505 }
2506 if (effectiveUid <= 0) {
2507 Intent checkIntent = intent != null ? intent : affinityIntent;
2508 effectiveUid = 0;
2509 if (checkIntent != null) {
2510 IPackageManager pm = AppGlobals.getPackageManager();
2511 try {
2512 ApplicationInfo ai = pm.getApplicationInfo(
2513 checkIntent.getComponent().getPackageName(),
2514 PackageManager.MATCH_UNINSTALLED_PACKAGES
2515 | PackageManager.MATCH_DISABLED_COMPONENTS, userId);
2516 if (ai != null) {
2517 effectiveUid = ai.uid;
2518 }
2519 } catch (RemoteException e) {
2520 }
2521 }
2522 Slog.w(TAG, "Updating task #" + taskId + " for " + checkIntent
2523 + ": effectiveUid=" + effectiveUid);
2524 }
2525
2526 if (persistTaskVersion < 1) {
2527 // We need to convert the resize mode of home activities saved before version one if
2528 // they are marked as RESIZE_MODE_RESIZEABLE to
2529 // RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION since we didn't have that differentiation
2530 // before version 1 and the system didn't resize home activities before then.
2531 if (taskType == 1 /* old home type */ && resizeMode == RESIZE_MODE_RESIZEABLE) {
2532 resizeMode = RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
2533 }
2534 } else {
2535 // This activity has previously marked itself explicitly as both resizeable and
2536 // supporting picture-in-picture. Since there is no longer a requirement for
2537 // picture-in-picture activities to be resizeable, we can mark this simply as
2538 // resizeable and supporting picture-in-picture separately.
2539 if (resizeMode == RESIZE_MODE_RESIZEABLE_AND_PIPABLE_DEPRECATED) {
2540 resizeMode = RESIZE_MODE_RESIZEABLE;
2541 supportsPictureInPicture = true;
2542 }
2543 }
2544
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07002545 final TaskRecord task = create(stackSupervisor.mService,
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002546 taskId, intent, affinityIntent,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002547 affinity, rootAffinity, realActivity, origActivity, rootHasReset,
2548 autoRemoveRecents, askedCompatMode, userId, effectiveUid, lastDescription,
2549 activities, lastTimeOnTop, neverRelinquishIdentity, taskDescription,
2550 taskAffiliation, prevTaskId, nextTaskId, taskAffiliationColor, callingUid,
2551 callingPackage, resizeMode, supportsPictureInPicture, realActivitySuspended,
2552 userSetupComplete, minWidth, minHeight);
Garfield Tan367b35a2017-12-13 12:16:21 -08002553 task.mLastNonFullscreenBounds = lastNonFullscreenBounds;
2554 task.setBounds(lastNonFullscreenBounds);
Garfield Tan9b1efea2017-12-05 16:43:46 -08002555
2556 for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {
2557 activities.get(activityNdx).setTask(task);
2558 }
2559
2560 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Restored task=" + task);
2561 return task;
2562 }
Garfield Tan1e740192017-12-12 14:37:42 -08002563
2564 void handleUnknownTag(String name, XmlPullParser in)
2565 throws IOException, XmlPullParserException {
2566 Slog.e(TAG, "restoreTask: Unexpected name=" + name);
2567 XmlUtils.skipCurrentTag(in);
2568 }
Garfield Tan9b1efea2017-12-05 16:43:46 -08002569 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002570}