blob: d697f28a66eb20bb0ab39178fb6b0180504da007 [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;
Wale Ogunwale59507092018-10-29 09:00:30 -070049import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ADD_REMOVE;
50import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_LOCKTASK;
51import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
52import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
53import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_ADD_REMOVE;
54import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_LOCKTASK;
55import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS;
56import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS;
57import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
58import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
59import static com.android.server.wm.ActivityRecord.STARTING_WINDOW_SHOWN;
60import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_MOVING;
61import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_MOVING_TO_TOP;
62import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
63import static com.android.server.wm.ActivityStackSupervisor.PAUSE_IMMEDIATELY;
64import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
Yi Jin6c6e9ca2018-03-20 16:53:35 -070065import static com.android.server.am.TaskRecordProto.ACTIVITIES;
Andrii Kulianab132ee2018-07-24 22:10:21 +080066import static com.android.server.am.TaskRecordProto.ACTIVITY_TYPE;
Yi Jin6c6e9ca2018-03-20 16:53:35 -070067import static com.android.server.am.TaskRecordProto.BOUNDS;
68import static com.android.server.am.TaskRecordProto.CONFIGURATION_CONTAINER;
69import static com.android.server.am.TaskRecordProto.FULLSCREEN;
70import static com.android.server.am.TaskRecordProto.ID;
71import static com.android.server.am.TaskRecordProto.LAST_NON_FULLSCREEN_BOUNDS;
72import static com.android.server.am.TaskRecordProto.MIN_HEIGHT;
73import static com.android.server.am.TaskRecordProto.MIN_WIDTH;
74import static com.android.server.am.TaskRecordProto.ORIG_ACTIVITY;
75import static com.android.server.am.TaskRecordProto.REAL_ACTIVITY;
76import static com.android.server.am.TaskRecordProto.RESIZE_MODE;
77import static com.android.server.am.TaskRecordProto.STACK_ID;
Winson Chung74666102017-02-22 17:49:24 -080078import static java.lang.Integer.MAX_VALUE;
79
Jorim Jaggie7d2b852017-08-28 17:55:15 +020080import android.annotation.IntDef;
81import android.annotation.Nullable;
82import android.app.Activity;
83import android.app.ActivityManager;
Jorim Jaggie7d2b852017-08-28 17:55:15 +020084import android.app.ActivityManager.TaskDescription;
85import android.app.ActivityManager.TaskSnapshot;
86import android.app.ActivityOptions;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070087import android.app.ActivityTaskManager;
Jorim Jaggie7d2b852017-08-28 17:55:15 +020088import android.app.AppGlobals;
Winson Chungabfdcce2018-07-02 17:23:33 -070089import android.app.TaskInfo;
Jorim Jaggie7d2b852017-08-28 17:55:15 +020090import android.content.ComponentName;
91import android.content.Intent;
92import android.content.pm.ActivityInfo;
93import android.content.pm.ApplicationInfo;
94import android.content.pm.IPackageManager;
95import android.content.pm.PackageManager;
96import android.content.res.Configuration;
97import android.graphics.Rect;
98import android.os.Debug;
99import android.os.RemoteException;
Winson Chungfb44d212017-10-04 11:39:10 -0700100import android.os.SystemClock;
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200101import android.os.Trace;
102import android.os.UserHandle;
103import android.provider.Settings;
104import android.service.voice.IVoiceInteractionSession;
105import android.util.DisplayMetrics;
106import android.util.Slog;
Steven Timotius4346f0a2017-09-12 11:07:21 -0700107import android.util.proto.ProtoOutputStream;
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200108
109import com.android.internal.annotations.VisibleForTesting;
110import com.android.internal.app.IVoiceInteractor;
111import com.android.internal.util.XmlUtils;
Wale Ogunwale59507092018-10-29 09:00:30 -0700112import com.android.server.wm.ActivityStack.ActivityState;
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200113
114import org.xmlpull.v1.XmlPullParser;
115import org.xmlpull.v1.XmlPullParserException;
116import org.xmlpull.v1.XmlSerializer;
117
118import java.io.IOException;
119import java.io.PrintWriter;
120import java.lang.annotation.Retention;
121import java.lang.annotation.RetentionPolicy;
122import java.util.ArrayList;
123import java.util.Objects;
124
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700125// TODO: Make package private again once move to WM package is complete.
126public class TaskRecord extends ConfigurationContainer implements TaskWindowContainerListener {
Wale Ogunwale98875612018-10-12 07:53:02 -0700127 private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskRecord" : TAG_ATM;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -0700128 private static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700129 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
Craig Mautnere0570202015-05-13 13:06:11 -0700130 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700131 private static final String TAG_TASKS = TAG + POSTFIX_TASKS;
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800132
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700133 private static final String ATTR_TASKID = "task_id";
Craig Mautner21d24a22014-04-23 11:45:37 -0700134 private static final String TAG_INTENT = "intent";
135 private static final String TAG_AFFINITYINTENT = "affinity_intent";
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700136 private static final String ATTR_REALACTIVITY = "real_activity";
137 private static final String ATTR_REALACTIVITY_SUSPENDED = "real_activity_suspended";
Craig Mautner21d24a22014-04-23 11:45:37 -0700138 private static final String ATTR_ORIGACTIVITY = "orig_activity";
Stefan Kuhnee88d1e52015-05-18 10:33:45 -0700139 private static final String TAG_ACTIVITY = "activity";
Craig Mautner21d24a22014-04-23 11:45:37 -0700140 private static final String ATTR_AFFINITY = "affinity";
Dianne Hackborn79228822014-09-16 11:11:23 -0700141 private static final String ATTR_ROOT_AFFINITY = "root_affinity";
Craig Mautner21d24a22014-04-23 11:45:37 -0700142 private static final String ATTR_ROOTHASRESET = "root_has_reset";
Dianne Hackborn13420f22014-07-18 15:43:56 -0700143 private static final String ATTR_AUTOREMOVERECENTS = "auto_remove_recents";
Craig Mautner21d24a22014-04-23 11:45:37 -0700144 private static final String ATTR_ASKEDCOMPATMODE = "asked_compat_mode";
145 private static final String ATTR_USERID = "user_id";
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800146 private static final String ATTR_USER_SETUP_COMPLETE = "user_setup_complete";
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700147 private static final String ATTR_EFFECTIVE_UID = "effective_uid";
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700148 @Deprecated
Craig Mautner21d24a22014-04-23 11:45:37 -0700149 private static final String ATTR_TASKTYPE = "task_type";
Craig Mautner21d24a22014-04-23 11:45:37 -0700150 private static final String ATTR_LASTDESCRIPTION = "last_description";
151 private static final String ATTR_LASTTIMEMOVED = "last_time_moved";
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700152 private static final String ATTR_NEVERRELINQUISH = "never_relinquish_identity";
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700153 private static final String ATTR_TASK_AFFILIATION = "task_affiliation";
Craig Mautnera228ae92014-07-09 05:44:55 -0700154 private static final String ATTR_PREV_AFFILIATION = "prev_affiliation";
155 private static final String ATTR_NEXT_AFFILIATION = "next_affiliation";
Winson Chungec396d62014-08-06 17:08:00 -0700156 private static final String ATTR_TASK_AFFILIATION_COLOR = "task_affiliation_color";
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700157 private static final String ATTR_CALLING_UID = "calling_uid";
158 private static final String ATTR_CALLING_PACKAGE = "calling_package";
Winson Chungd3395382016-12-13 11:49:09 -0800159 private static final String ATTR_SUPPORTS_PICTURE_IN_PICTURE = "supports_picture_in_picture";
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800160 private static final String ATTR_RESIZE_MODE = "resize_mode";
Wale Ogunwale706ed792015-08-02 10:29:44 -0700161 private static final String ATTR_NON_FULLSCREEN_BOUNDS = "non_fullscreen_bounds";
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700162 private static final String ATTR_MIN_WIDTH = "min_width";
163 private static final String ATTR_MIN_HEIGHT = "min_height";
Wale Ogunwale625ed0c2016-10-18 08:50:31 -0700164 private static final String ATTR_PERSIST_TASK_VERSION = "persist_task_version";
Andrii Kulian18d75122016-03-27 20:20:28 -0700165
Wale Ogunwale625ed0c2016-10-18 08:50:31 -0700166 // Current version of the task record we persist. Used to check if we need to run any upgrade
167 // code.
168 private static final int PERSIST_TASK_VERSION = 1;
Craig Mautner21d24a22014-04-23 11:45:37 -0700169
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700170 private static final int INVALID_MIN_SIZE = -1;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800171
Winson Chung74666102017-02-22 17:49:24 -0800172 /**
173 * The modes to control how the stack is moved to the front when calling
174 * {@link TaskRecord#reparent}.
175 */
176 @Retention(RetentionPolicy.SOURCE)
177 @IntDef({
178 REPARENT_MOVE_STACK_TO_FRONT,
179 REPARENT_KEEP_STACK_AT_FRONT,
180 REPARENT_LEAVE_STACK_IN_PLACE
181 })
Wale Ogunwale66e16852017-10-19 13:35:52 -0700182 @interface ReparentMoveStackMode {}
Winson Chung74666102017-02-22 17:49:24 -0800183 // Moves the stack to the front if it was not at the front
Wale Ogunwale66e16852017-10-19 13:35:52 -0700184 static final int REPARENT_MOVE_STACK_TO_FRONT = 0;
Winson Chung74666102017-02-22 17:49:24 -0800185 // Only moves the stack to the front if it was focused or front most already
Wale Ogunwale66e16852017-10-19 13:35:52 -0700186 static final int REPARENT_KEEP_STACK_AT_FRONT = 1;
Winson Chung74666102017-02-22 17:49:24 -0800187 // Do not move the stack as a part of reparenting
Wale Ogunwale66e16852017-10-19 13:35:52 -0700188 static final int REPARENT_LEAVE_STACK_IN_PLACE = 2;
Winson Chung74666102017-02-22 17:49:24 -0800189
Garfield Tan9b1efea2017-12-05 16:43:46 -0800190 /**
191 * The factory used to create {@link TaskRecord}. This allows OEM subclass {@link TaskRecord}.
192 */
193 private static TaskRecordFactory sTaskRecordFactory;
194
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800195 final int taskId; // Unique identifier for this task.
Dianne Hackborn79228822014-09-16 11:11:23 -0700196 String affinity; // The affinity name for this task, or null; may change identity.
197 String rootAffinity; // Initial base affinity, or null; does not change from initial root.
Dianne Hackborn91097de2014-04-04 18:02:06 -0700198 final IVoiceInteractionSession voiceSession; // Voice interaction session driving task
199 final IVoiceInteractor voiceInteractor; // Associated interactor to provide to app
Bryce Lee1a990e52018-04-23 10:54:11 -0700200 Intent intent; // The original intent that started the task. Note that this value can
201 // be null.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800202 Intent affinityIntent; // Intent of affinity-moved activity that started this task.
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700203 int effectiveUid; // The current effective uid of the identity of this task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800204 ComponentName origActivity; // The non-alias activity component of the intent.
205 ComponentName realActivity; // The actual activity component that started the task.
Andrei Stingaceanu4ccec532016-01-13 12:10:21 +0000206 boolean realActivitySuspended; // True if the actual activity component that started the
207 // task is suspended.
Dianne Hackborn852975d2014-08-22 17:42:43 -0700208 boolean inRecents; // Actually in the recents list?
Winson Chungfb44d212017-10-04 11:39:10 -0700209 long lastActiveTime; // Last time this task was active in the current device session,
210 // including sleep. This time is initialized to the elapsed time when
211 // restored from disk.
Dianne Hackborn852975d2014-08-22 17:42:43 -0700212 boolean isAvailable; // Is the activity available to be launched?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800213 boolean rootWasReset; // True if the intent at the root of the task had
214 // the FLAG_ACTIVITY_RESET_TASK_IF_NEEDED flag.
Dianne Hackborn13420f22014-07-18 15:43:56 -0700215 boolean autoRemoveRecents; // If true, we should automatically remove the task from
216 // recents when activity finishes
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700217 boolean askedCompatMode;// Have asked the user about compat mode for this task.
Dianne Hackbornd38aed82014-06-10 21:36:35 -0700218 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 -0800219
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700220 String stringName; // caching of toString() result.
Dianne Hackborn9da2d402012-03-15 13:43:08 -0700221 int userId; // user for which this task was created
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800222 boolean mUserSetupComplete; // The user set-up is complete as of the last time the task activity
223 // was changed.
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800224
225 int numFullscreen; // Number of fullscreen activities.
226
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800227 int mResizeMode; // The resize mode of this task and its activities.
228 // Based on the {@link ActivityInfo#resizeMode} of the root activity.
Wale Ogunwale069bbd32017-02-03 07:58:14 -0800229 private boolean mSupportsPictureInPicture; // Whether or not this task and its activities
230 // support PiP. Based on the {@link ActivityInfo#FLAG_SUPPORTS_PICTURE_IN_PICTURE} flag
231 // of the root activity.
Craig Mautner15df08a2015-04-01 12:17:18 -0700232 /** Can't be put in lockTask mode. */
233 final static int LOCK_TASK_AUTH_DONT_LOCK = 0;
Benjamin Franz469dd582015-06-09 14:24:36 +0100234 /** Can enter app pinning with user approval. Can never start over existing lockTask task. */
Craig Mautner15df08a2015-04-01 12:17:18 -0700235 final static int LOCK_TASK_AUTH_PINNABLE = 1;
236 /** Starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing lockTask task. */
237 final static int LOCK_TASK_AUTH_LAUNCHABLE = 2;
Benjamin Franz469dd582015-06-09 14:24:36 +0100238 /** Can enter lockTask without user approval. Can start over existing lockTask task. */
Craig Mautner15df08a2015-04-01 12:17:18 -0700239 final static int LOCK_TASK_AUTH_WHITELISTED = 3;
Benjamin Franz469dd582015-06-09 14:24:36 +0100240 /** Priv-app that starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing
241 * lockTask task. */
242 final static int LOCK_TASK_AUTH_LAUNCHABLE_PRIV = 4;
Craig Mautner15df08a2015-04-01 12:17:18 -0700243 int mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE;
244
245 int mLockTaskUid = -1; // The uid of the application that called startLockTask().
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800246
Winson Chung03a9bae2014-05-02 09:56:12 -0700247 // This represents the last resolved activity values for this task
248 // NOTE: This value needs to be persisted with each task
Craig Mautner648f69b2014-09-18 14:16:26 -0700249 TaskDescription lastTaskDescription = new TaskDescription();
Winson Chung03a9bae2014-05-02 09:56:12 -0700250
Craig Mautnerd2328952013-03-05 12:46:26 -0800251 /** List of all activities in the task arranged in history order */
Craig Mautner21d24a22014-04-23 11:45:37 -0700252 final ArrayList<ActivityRecord> mActivities;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800253
Andrii Kulian02b7a832016-10-06 23:11:56 -0700254 /** Current stack. Setter must always be used to update the value. */
255 private ActivityStack mStack;
Craig Mautnerd2328952013-03-05 12:46:26 -0800256
Dianne Hackborn68a06332017-11-15 17:54:18 -0800257 /** The process that had previously hosted the root activity of this task.
258 * Used to know that we should try harder to keep this process around, in case the
259 * user wants to return to it. */
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700260 private WindowProcessController mRootProcess;
Dianne Hackborn68a06332017-11-15 17:54:18 -0800261
Craig Mautner21d24a22014-04-23 11:45:37 -0700262 /** Takes on same value as first root activity */
263 boolean isPersistable = false;
Craig Mautnerffcfcaa2014-06-05 09:54:38 -0700264 int maxRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700265
266 /** Only used for persistable tasks, otherwise 0. The last time this task was moved. Used for
267 * determining the order when restoring. Sign indicates whether last task movement was to front
268 * (positive) or back (negative). Absolute value indicates time. */
269 long mLastTimeMoved = System.currentTimeMillis();
270
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700271 /** If original intent did not allow relinquishing task identity, save that information */
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700272 private boolean mNeverRelinquishIdentity = true;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700273
Craig Mautner362449a2014-06-20 14:04:39 -0700274 // Used in the unique case where we are clearing the task in order to reuse it. In that case we
275 // do not want to delete the stack when the task goes empty.
Filip Gruszczynskibe9dabd2016-01-19 12:23:10 -0800276 private boolean mReuseTask = false;
Craig Mautner362449a2014-06-20 14:04:39 -0700277
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700278 CharSequence lastDescription; // Last description captured for this item.
279
Craig Mautnera228ae92014-07-09 05:44:55 -0700280 int mAffiliatedTaskId; // taskId of parent affiliation or self if no parent.
Winson Chungec396d62014-08-06 17:08:00 -0700281 int mAffiliatedTaskColor; // color of the parent task affiliation.
Craig Mautnera228ae92014-07-09 05:44:55 -0700282 TaskRecord mPrevAffiliate; // previous task in affiliated chain.
Wale Ogunwale18795a22014-12-03 11:38:33 -0800283 int mPrevAffiliateTaskId = INVALID_TASK_ID; // previous id for persistence.
Craig Mautnera228ae92014-07-09 05:44:55 -0700284 TaskRecord mNextAffiliate; // next task in affiliated chain.
Wale Ogunwale18795a22014-12-03 11:38:33 -0800285 int mNextAffiliateTaskId = INVALID_TASK_ID; // next id for persistence.
Craig Mautnera228ae92014-07-09 05:44:55 -0700286
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700287 // For relaunching the task from recents as though it was launched by the original launcher.
288 int mCallingUid;
289 String mCallingPackage;
290
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700291 final ActivityTaskManagerService mService;
Craig Mautner21d24a22014-04-23 11:45:37 -0700292
Jorim Jaggi82c9dc92016-02-05 15:10:33 -0800293 private final Rect mTmpStableBounds = new Rect();
294 private final Rect mTmpNonDecorBounds = new Rect();
Wale Ogunwale9a08f822016-02-17 19:03:58 -0800295 private final Rect mTmpRect = new Rect();
Jorim Jaggi0a932142016-02-01 17:42:25 -0800296
Wale Ogunwale706ed792015-08-02 10:29:44 -0700297 // Last non-fullscreen bounds the task was launched in or resized to.
298 // The information is persisted and used to determine the appropriate stack to launch the
299 // task into on restore.
300 Rect mLastNonFullscreenBounds = null;
Andrii Kulian2e751b82016-03-16 16:59:32 -0700301 // Minimal width and height of this task when it's resizeable. -1 means it should use the
302 // default minimal width/height.
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700303 int mMinWidth;
304 int mMinHeight;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700305
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700306 // Ranking (from top) of this task among all visible tasks. (-1 means it's not visible)
307 // This number will be assigned when we evaluate OOM scores for all visible tasks.
308 int mLayerRank = -1;
309
Andrii Kulian1779e612016-10-12 21:58:25 -0700310 /** Helper object used for updating override configuration. */
311 private Configuration mTmpConfig = new Configuration();
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700312
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800313 private TaskWindowContainerController mWindowContainerController;
314
Garfield Tan9b1efea2017-12-05 16:43:46 -0800315 /**
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700316 * Don't use constructor directly. Use {@link #create(ActivityTaskManagerService, int,
317 * ActivityInfo, Intent, TaskDescription)} instead.
Garfield Tan9b1efea2017-12-05 16:43:46 -0800318 */
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700319 TaskRecord(ActivityTaskManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700320 IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700321 mService = service;
Suprabh Shukla23593142015-11-03 17:31:15 -0800322 userId = UserHandle.getUserId(info.applicationInfo.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800323 taskId = _taskId;
Winson Chungfb44d212017-10-04 11:39:10 -0700324 lastActiveTime = SystemClock.elapsedRealtime();
Craig Mautnera228ae92014-07-09 05:44:55 -0700325 mAffiliatedTaskId = _taskId;
Dianne Hackborn91097de2014-04-04 18:02:06 -0700326 voiceSession = _voiceSession;
327 voiceInteractor = _voiceInteractor;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700328 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800329 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700330 mCallingUid = info.applicationInfo.uid;
331 mCallingPackage = info.packageName;
Martijn Coenend4a69702014-06-30 11:12:17 -0700332 setIntent(_intent, info);
Andrii Kulian2e751b82016-03-16 16:59:32 -0700333 setMinDimensions(info);
Winson730bf062016-03-31 18:04:56 -0700334 touchActiveTime();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700335 mService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
Craig Mautner21d24a22014-04-23 11:45:37 -0700336 }
337
Garfield Tan9b1efea2017-12-05 16:43:46 -0800338 /**
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700339 * Don't use constructor directly.
340 * Use {@link #create(ActivityTaskManagerService, int, ActivityInfo,
Garfield Tan9b1efea2017-12-05 16:43:46 -0800341 * Intent, IVoiceInteractionSession, IVoiceInteractor)} instead.
342 */
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700343 TaskRecord(ActivityTaskManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200344 TaskDescription _taskDescription) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700345 mService = service;
Suprabh Shukla23593142015-11-03 17:31:15 -0800346 userId = UserHandle.getUserId(info.applicationInfo.uid);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700347 taskId = _taskId;
Winson Chungfb44d212017-10-04 11:39:10 -0700348 lastActiveTime = SystemClock.elapsedRealtime();
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700349 mAffiliatedTaskId = _taskId;
350 voiceSession = null;
351 voiceInteractor = null;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700352 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800353 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700354 mCallingUid = info.applicationInfo.uid;
355 mCallingPackage = info.packageName;
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700356 setIntent(_intent, info);
Andrii Kulian2e751b82016-03-16 16:59:32 -0700357 setMinDimensions(info);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700358
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700359 isPersistable = true;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700360 // Clamp to [1, max].
361 maxRecents = Math.min(Math.max(info.maxRecents, 1),
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700362 ActivityTaskManager.getMaxAppRecentsLimitStatic());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700363
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700364 lastTaskDescription = _taskDescription;
Winson730bf062016-03-31 18:04:56 -0700365 touchActiveTime();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700366 mService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700367 }
368
Garfield Tan9b1efea2017-12-05 16:43:46 -0800369 /**
370 * Don't use constructor directly. This is only used by XML parser.
371 */
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700372 TaskRecord(ActivityTaskManagerService service, int _taskId, Intent _intent,
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800373 Intent _affinityIntent, String _affinity, String _rootAffinity,
374 ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700375 boolean _autoRemoveRecents, boolean _askedCompatMode, int _userId,
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800376 int _effectiveUid, String _lastDescription, ArrayList<ActivityRecord> activities,
Winson Chungfb44d212017-10-04 11:39:10 -0700377 long lastTimeMoved, boolean neverRelinquishIdentity,
378 TaskDescription _lastTaskDescription, int taskAffiliation, int prevTaskId,
379 int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage,
Charles He2bf28322017-10-12 22:24:49 +0100380 int resizeMode, boolean supportsPictureInPicture, boolean _realActivitySuspended,
381 boolean userSetupComplete, int minWidth, int minHeight) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700382 mService = service;
383 taskId = _taskId;
384 intent = _intent;
385 affinityIntent = _affinityIntent;
386 affinity = _affinity;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800387 rootAffinity = _rootAffinity;
Craig Mautner21d24a22014-04-23 11:45:37 -0700388 voiceSession = null;
389 voiceInteractor = null;
390 realActivity = _realActivity;
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800391 realActivitySuspended = _realActivitySuspended;
Craig Mautner21d24a22014-04-23 11:45:37 -0700392 origActivity = _origActivity;
393 rootWasReset = _rootWasReset;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700394 isAvailable = true;
Dianne Hackborn13420f22014-07-18 15:43:56 -0700395 autoRemoveRecents = _autoRemoveRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700396 askedCompatMode = _askedCompatMode;
Craig Mautner21d24a22014-04-23 11:45:37 -0700397 userId = _userId;
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800398 mUserSetupComplete = userSetupComplete;
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700399 effectiveUid = _effectiveUid;
Winson Chungfb44d212017-10-04 11:39:10 -0700400 lastActiveTime = SystemClock.elapsedRealtime();
Craig Mautner21d24a22014-04-23 11:45:37 -0700401 lastDescription = _lastDescription;
402 mActivities = activities;
403 mLastTimeMoved = lastTimeMoved;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700404 mNeverRelinquishIdentity = neverRelinquishIdentity;
Winson Chung2cb86c72014-06-25 12:03:30 -0700405 lastTaskDescription = _lastTaskDescription;
Craig Mautnera228ae92014-07-09 05:44:55 -0700406 mAffiliatedTaskId = taskAffiliation;
Winson Chungec396d62014-08-06 17:08:00 -0700407 mAffiliatedTaskColor = taskAffiliationColor;
Craig Mautnera228ae92014-07-09 05:44:55 -0700408 mPrevAffiliateTaskId = prevTaskId;
409 mNextAffiliateTaskId = nextTaskId;
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700410 mCallingUid = callingUid;
411 mCallingPackage = callingPackage;
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800412 mResizeMode = resizeMode;
Winson Chungd3395382016-12-13 11:49:09 -0800413 mSupportsPictureInPicture = supportsPictureInPicture;
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700414 mMinWidth = minWidth;
415 mMinHeight = minHeight;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700416 mService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800417 }
418
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800419 TaskWindowContainerController getWindowContainerController() {
420 return mWindowContainerController;
421 }
422
423 void createWindowContainer(boolean onTop, boolean showForAllUsers) {
424 if (mWindowContainerController != null) {
425 throw new IllegalArgumentException("Window container=" + mWindowContainerController
426 + " already created for task=" + this);
427 }
428
429 final Rect bounds = updateOverrideConfigurationFromLaunchBounds();
Bryce Lee04ab3462017-04-10 15:06:33 -0700430 setWindowContainerController(new TaskWindowContainerController(taskId, this,
Wale Ogunwale034a8ec2017-09-02 17:14:40 -0700431 getStack().getWindowContainerController(), userId, bounds,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700432 mResizeMode, mSupportsPictureInPicture, onTop,
433 showForAllUsers, lastTaskDescription));
Bryce Lee04ab3462017-04-10 15:06:33 -0700434 }
435
436 /**
437 * Should only be invoked from {@link #createWindowContainer(boolean, boolean)}.
438 */
439 @VisibleForTesting
440 protected void setWindowContainerController(TaskWindowContainerController controller) {
441 if (mWindowContainerController != null) {
442 throw new IllegalArgumentException("Window container=" + mWindowContainerController
443 + " already created for task=" + this);
444 }
445
446 mWindowContainerController = controller;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800447 }
448
449 void removeWindowContainer() {
Bryce Lee2b8e0372018-04-05 17:01:37 -0700450 mService.getLockTaskController().clearLockedTask(this);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800451 mWindowContainerController.removeContainer();
Wale Ogunwale3382ab12017-07-27 08:55:03 -0700452 if (!getWindowConfiguration().persistTaskBounds()) {
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800453 // Reset current bounds for task whose bounds shouldn't be persisted so it uses
454 // default configuration the next time it launches.
455 updateOverrideConfiguration(null);
456 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700457 mService.getTaskChangeNotificationController().notifyTaskRemoved(taskId);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800458 mWindowContainerController = null;
459 }
460
Jorim Jaggifb9d78a2017-01-05 18:57:12 +0100461 @Override
462 public void onSnapshotChanged(TaskSnapshot snapshot) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700463 mService.getTaskChangeNotificationController().notifyTaskSnapshotChanged(taskId, snapshot);
Jorim Jaggifb9d78a2017-01-05 18:57:12 +0100464 }
465
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800466 void setResizeMode(int resizeMode) {
467 if (mResizeMode == resizeMode) {
468 return;
469 }
470 mResizeMode = resizeMode;
471 mWindowContainerController.setResizeable(resizeMode);
472 mService.mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Andrii Kulianab132ee2018-07-24 22:10:21 +0800473 mService.mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800474 }
475
476 void setTaskDockedResizing(boolean resizing) {
477 mWindowContainerController.setTaskDockedResizing(resizing);
478 }
479
Wale Ogunwale1666e312016-12-16 11:27:18 -0800480 // TODO: Consolidate this with the resize() method below.
481 @Override
482 public void requestResize(Rect bounds, int resizeMode) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700483 mService.resizeTask(taskId, bounds, resizeMode);
Wale Ogunwale1666e312016-12-16 11:27:18 -0800484 }
485
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800486 boolean resize(Rect bounds, int resizeMode, boolean preserveWindow, boolean deferResume) {
Bryce Leef3c6a472017-11-14 14:53:06 -0800487 mService.mWindowManager.deferSurfaceLayout();
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800488
Bryce Leef3c6a472017-11-14 14:53:06 -0800489 try {
490 if (!isResizeable()) {
491 Slog.w(TAG, "resizeTask: task " + this + " not resizeable.");
492 return true;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800493 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800494
Bryce Leef3c6a472017-11-14 14:53:06 -0800495 // If this is a forced resize, let it go through even if the bounds is not changing,
496 // as we might need a relayout due to surface size change (to/from fullscreen).
497 final boolean forced = (resizeMode & RESIZE_MODE_FORCED) != 0;
498 if (equivalentOverrideBounds(bounds) && !forced) {
499 // Nothing to do here...
500 return true;
501 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800502
Bryce Leef3c6a472017-11-14 14:53:06 -0800503 if (mWindowContainerController == null) {
504 // Task doesn't exist in window manager yet (e.g. was restored from recents).
505 // All we can do for now is update the bounds so it can be used when the task is
506 // added to window manager.
507 updateOverrideConfiguration(bounds);
508 if (!inFreeformWindowingMode()) {
509 // re-restore the task so it can have the proper stack association.
510 mService.mStackSupervisor.restoreRecentTaskLocked(this, null, !ON_TOP);
511 }
512 return true;
513 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800514
Bryce Leef3c6a472017-11-14 14:53:06 -0800515 if (!canResizeToBounds(bounds)) {
516 throw new IllegalArgumentException("resizeTask: Can not resize task=" + this
517 + " to bounds=" + bounds + " resizeMode=" + mResizeMode);
518 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800519
Bryce Leef3c6a472017-11-14 14:53:06 -0800520 // Do not move the task to another stack here.
521 // This method assumes that the task is already placed in the right stack.
522 // we do not mess with that decision and we only do the resize!
523
524 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeTask_" + taskId);
525
526 final boolean updatedConfig = updateOverrideConfiguration(bounds);
527 // This variable holds information whether the configuration didn't change in a significant
528
529 // way and the activity was kept the way it was. If it's false, it means the activity
530 // had
531 // to be relaunched due to configuration change.
532 boolean kept = true;
533 if (updatedConfig) {
534 final ActivityRecord r = topRunningActivityLocked();
535 if (r != null && !deferResume) {
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -0800536 kept = r.ensureActivityConfiguration(0 /* globalChanges */,
Bryce Leef3c6a472017-11-14 14:53:06 -0800537 preserveWindow);
Garfield Tanb9151182018-06-25 16:29:21 -0700538 // Preserve other windows for resizing because if resizing happens when there
539 // is a dialog activity in the front, the activity that still shows some
540 // content to the user will become black and cause flickers. Note in most cases
541 // this won't cause tons of irrelevant windows being preserved because only
542 // activities in this task may experience a bounds change. Configs for other
543 // activities stay the same.
Bryce Leef3c6a472017-11-14 14:53:06 -0800544 mService.mStackSupervisor.ensureActivitiesVisibleLocked(r, 0,
Garfield Tanb9151182018-06-25 16:29:21 -0700545 preserveWindow);
Bryce Leef3c6a472017-11-14 14:53:06 -0800546 if (!kept) {
Andrii Kulianab132ee2018-07-24 22:10:21 +0800547 mService.mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Bryce Leef3c6a472017-11-14 14:53:06 -0800548 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800549 }
550 }
Bryce Leef3c6a472017-11-14 14:53:06 -0800551 mWindowContainerController.resize(kept, forced);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800552
Bryce Leef3c6a472017-11-14 14:53:06 -0800553 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
554 return kept;
555 } finally {
556 mService.mWindowManager.continueSurfaceLayout();
557 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800558 }
559
560 // TODO: Investigate combining with the resize() method above.
561 void resizeWindowContainer() {
Bryce Leef3c6a472017-11-14 14:53:06 -0800562 mWindowContainerController.resize(false /* relayout */, false /* forced */);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800563 }
564
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800565 void getWindowContainerBounds(Rect bounds) {
566 mWindowContainerController.getBounds(bounds);
567 }
568
Winson Chung74666102017-02-22 17:49:24 -0800569 /**
570 * Convenience method to reparent a task to the top or bottom position of the stack.
571 */
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700572 boolean reparent(ActivityStack preferredStack, boolean toTop,
573 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
574 String reason) {
575 return reparent(preferredStack, toTop ? MAX_VALUE : 0, moveStackMode, animate, deferResume,
576 true /* schedulePictureInPictureModeChange */, reason);
Winson Chung5af42fc2017-03-24 17:11:33 -0700577 }
578
579 /**
580 * Convenience method to reparent a task to the top or bottom position of the stack, with
581 * an option to skip scheduling the picture-in-picture mode change.
582 */
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700583 boolean reparent(ActivityStack preferredStack, boolean toTop,
584 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
585 boolean schedulePictureInPictureModeChange, String reason) {
586 return reparent(preferredStack, toTop ? MAX_VALUE : 0, moveStackMode, animate,
Winson Chung5af42fc2017-03-24 17:11:33 -0700587 deferResume, schedulePictureInPictureModeChange, reason);
588 }
589
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700590 /** Convenience method to reparent a task to a specific position of the stack. */
591 boolean reparent(ActivityStack preferredStack, int position,
592 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
593 String reason) {
594 return reparent(preferredStack, position, moveStackMode, animate, deferResume,
Winson Chung5af42fc2017-03-24 17:11:33 -0700595 true /* schedulePictureInPictureModeChange */, reason);
Winson Chung74666102017-02-22 17:49:24 -0800596 }
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800597
Winson Chung74666102017-02-22 17:49:24 -0800598 /**
599 * Reparents the task into a preferred stack, creating it if necessary.
600 *
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700601 * @param preferredStack the target stack to move this task
Winson Chung74666102017-02-22 17:49:24 -0800602 * @param position the position to place this task in the new stack
603 * @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 -0700604 * reparenting to be drawn and animated in
Winson Chung74666102017-02-22 17:49:24 -0800605 * @param moveStackMode whether or not to move the stack to the front always, only if it was
Winson Chung5af42fc2017-03-24 17:11:33 -0700606 * previously focused & in front, or never
Winson Chung74666102017-02-22 17:49:24 -0800607 * @param deferResume whether or not to update the visibility of other tasks and stacks that may
Winson Chung5af42fc2017-03-24 17:11:33 -0700608 * have changed as a result of this reparenting
609 * @param schedulePictureInPictureModeChange specifies whether or not to schedule the PiP mode
610 * change. Callers may set this to false if they are explicitly scheduling PiP mode
611 * changes themselves, like during the PiP animation
Winson Chung74666102017-02-22 17:49:24 -0800612 * @param reason the caller of this reparenting
Winson Chung5af42fc2017-03-24 17:11:33 -0700613 * @return whether the task was reparented
Winson Chung74666102017-02-22 17:49:24 -0800614 */
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700615 // TODO: Inspect all call sites and change to just changing windowing mode of the stack vs.
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700616 // re-parenting the task. Can only be done when we are no longer using static stack Ids.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700617 boolean reparent(ActivityStack preferredStack, int position,
618 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
619 boolean schedulePictureInPictureModeChange, String reason) {
Winson Chung74666102017-02-22 17:49:24 -0800620 final ActivityStackSupervisor supervisor = mService.mStackSupervisor;
621 final WindowManagerService windowManager = mService.mWindowManager;
622 final ActivityStack sourceStack = getStack();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700623 final ActivityStack toStack = supervisor.getReparentTargetStack(this, preferredStack,
Winson Chung74666102017-02-22 17:49:24 -0800624 position == MAX_VALUE);
625 if (toStack == sourceStack) {
626 return false;
627 }
Andrii Kulianb850ea52017-12-12 23:49:10 -0800628 if (!canBeLaunchedOnDisplay(toStack.mDisplayId)) {
629 return false;
630 }
Winson Chung74666102017-02-22 17:49:24 -0800631
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700632 final int toStackWindowingMode = toStack.getWindowingMode();
Winson Chung74666102017-02-22 17:49:24 -0800633 final ActivityRecord topActivity = getTopActivity();
634
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800635 final boolean mightReplaceWindow = topActivity != null
636 && replaceWindowsOnTaskMove(getWindowingMode(), toStackWindowingMode);
Winson Chung74666102017-02-22 17:49:24 -0800637 if (mightReplaceWindow) {
638 // We are about to relaunch the activity because its configuration changed due to
639 // being maximized, i.e. size change. The activity will first remove the old window
640 // and then add a new one. This call will tell window manager about this, so it can
641 // preserve the old window until the new one is drawn. This prevents having a gap
642 // between the removal and addition, in which no window is visible. We also want the
643 // entrance of the new window to be properly animated.
644 // Note here we always set the replacing window first, as the flags might be needed
645 // during the relaunch. If we end up not doing any relaunch, we clear the flags later.
646 windowManager.setWillReplaceWindow(topActivity.appToken, animate);
647 }
648
649 windowManager.deferSurfaceLayout();
650 boolean kept = true;
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800651 try {
Winson Chung74666102017-02-22 17:49:24 -0800652 final ActivityRecord r = topRunningActivityLocked();
Andrii Kulian5f750bc2018-07-17 08:57:23 -0700653 final boolean wasFocused = r != null && supervisor.isTopDisplayFocusedStack(sourceStack)
Winson Chung74666102017-02-22 17:49:24 -0800654 && (topRunningActivityLocked() == r);
Bryce Leec4ab62a2018-03-05 14:19:26 -0800655 final boolean wasResumed = r != null && sourceStack.getResumedActivity() == r;
Winson Chung95f8f0e2017-03-24 09:20:17 -0700656 final boolean wasPaused = r != null && sourceStack.mPausingActivity == r;
Winson Chung74666102017-02-22 17:49:24 -0800657
658 // In some cases the focused stack isn't the front stack. E.g. pinned stack.
659 // Whenever we are moving the top activity from the front stack we want to make sure to
660 // move the stack to the front.
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -0700661 final boolean wasFront = r != null && sourceStack.isTopStackOnDisplay()
Winson Chung74666102017-02-22 17:49:24 -0800662 && (sourceStack.topRunningActivityLocked() == r);
663
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800664 // Adjust the position for the new parent stack as needed.
Winson Chung74666102017-02-22 17:49:24 -0800665 position = toStack.getAdjustedPositionForTask(this, position, null /* starting */);
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800666
667 // Must reparent first in window manager to avoid a situation where AM can delete the
668 // we are coming from in WM before we reparent because it became empty.
Wale Ogunwale2719cc12017-04-14 09:45:27 -0700669 mWindowContainerController.reparent(toStack.getWindowContainerController(), position,
670 moveStackMode == REPARENT_MOVE_STACK_TO_FRONT);
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800671
Wale Ogunwale56d8d162017-05-30 11:12:20 -0700672 final boolean moveStackToFront = moveStackMode == REPARENT_MOVE_STACK_TO_FRONT
673 || (moveStackMode == REPARENT_KEEP_STACK_AT_FRONT && (wasFocused || wasFront));
Winson Chung74666102017-02-22 17:49:24 -0800674 // Move the task
Wale Ogunwale56d8d162017-05-30 11:12:20 -0700675 sourceStack.removeTask(this, reason, moveStackToFront
676 ? REMOVE_TASK_MODE_MOVING_TO_TOP : REMOVE_TASK_MODE_MOVING);
Winson Chung5af42fc2017-03-24 17:11:33 -0700677 toStack.addTask(this, position, false /* schedulePictureInPictureModeChange */, reason);
Winson Chung74666102017-02-22 17:49:24 -0800678
Winson Chung5af42fc2017-03-24 17:11:33 -0700679 if (schedulePictureInPictureModeChange) {
680 // Notify of picture-in-picture mode changes
681 supervisor.scheduleUpdatePictureInPictureModeIfNeeded(this, sourceStack);
682 }
Winson Chung74666102017-02-22 17:49:24 -0800683
684 // TODO: Ensure that this is actually necessary here
685 // Notify the voice session if required
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800686 if (voiceSession != null) {
687 try {
688 voiceSession.taskStarted(intent, taskId);
689 } catch (RemoteException e) {
690 }
691 }
Winson Chung74666102017-02-22 17:49:24 -0800692
693 // If the task had focus before (or we're requested to move focus), move focus to the
694 // new stack by moving the stack to the front.
Winson Chung95f8f0e2017-03-24 09:20:17 -0700695 if (r != null) {
696 toStack.moveToFrontAndResumeStateIfNeeded(r, moveStackToFront, wasResumed,
697 wasPaused, reason);
698 }
Winson Chung74666102017-02-22 17:49:24 -0800699 if (!animate) {
Jorim Jaggifa9ed962018-01-25 00:16:49 +0100700 mService.mStackSupervisor.mNoAnimActivities.add(topActivity);
Winson Chung74666102017-02-22 17:49:24 -0800701 }
702
703 // We might trigger a configuration change. Save the current task bounds for freezing.
704 // TODO: Should this call be moved inside the resize method in WM?
705 toStack.prepareFreezingTaskBounds();
706
707 // Make sure the task has the appropriate bounds/size for the stack it is in.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700708 final boolean toStackSplitScreenPrimary =
709 toStackWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Bryce Leef3c6a472017-11-14 14:53:06 -0800710 final Rect configBounds = getOverrideBounds();
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700711 if ((toStackWindowingMode == WINDOWING_MODE_FULLSCREEN
712 || toStackWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY)
Bryce Leef3c6a472017-11-14 14:53:06 -0800713 && !Objects.equals(configBounds, toStack.getOverrideBounds())) {
714 kept = resize(toStack.getOverrideBounds(), RESIZE_MODE_SYSTEM, !mightReplaceWindow,
Winson Chung74666102017-02-22 17:49:24 -0800715 deferResume);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700716 } else if (toStackWindowingMode == WINDOWING_MODE_FREEFORM) {
Winson Chung74666102017-02-22 17:49:24 -0800717 Rect bounds = getLaunchBounds();
718 if (bounds == null) {
Bryce Leeec55eb02017-12-05 20:51:27 -0800719 mService.mStackSupervisor.getLaunchParamsController().layoutTask(this, null);
Bryce Leef3c6a472017-11-14 14:53:06 -0800720 bounds = configBounds;
Winson Chung74666102017-02-22 17:49:24 -0800721 }
722 kept = resize(bounds, RESIZE_MODE_FORCED, !mightReplaceWindow, deferResume);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700723 } else if (toStackSplitScreenPrimary || toStackWindowingMode == WINDOWING_MODE_PINNED) {
724 if (toStackSplitScreenPrimary && moveStackMode == REPARENT_KEEP_STACK_AT_FRONT) {
Matthew Ng330757d2017-02-28 14:19:17 -0800725 // Move recents to front so it is not behind home stack when going into docked
726 // mode
727 mService.mStackSupervisor.moveRecentsStackToFront(reason);
728 }
Bryce Leef3c6a472017-11-14 14:53:06 -0800729 kept = resize(toStack.getOverrideBounds(), RESIZE_MODE_SYSTEM, !mightReplaceWindow,
Winson Chung74666102017-02-22 17:49:24 -0800730 deferResume);
731 }
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800732 } finally {
Winson Chung74666102017-02-22 17:49:24 -0800733 windowManager.continueSurfaceLayout();
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800734 }
Winson Chung74666102017-02-22 17:49:24 -0800735
736 if (mightReplaceWindow) {
737 // If we didn't actual do a relaunch (indicated by kept==true meaning we kept the old
738 // window), we need to clear the replace window settings. Otherwise, we schedule a
739 // timeout to remove the old window if the replacing window is not coming in time.
740 windowManager.scheduleClearWillReplaceWindows(topActivity.appToken, !kept);
741 }
742
743 if (!deferResume) {
744 // The task might have already been running and its visibility needs to be synchronized
745 // with the visibility of the stack / windows.
746 supervisor.ensureActivitiesVisibleLocked(null, 0, !mightReplaceWindow);
Andrii Kulianab132ee2018-07-24 22:10:21 +0800747 supervisor.resumeFocusedStacksTopActivitiesLocked();
Winson Chung74666102017-02-22 17:49:24 -0800748 }
749
Andrii Kulian036e3ad2017-04-19 10:55:10 -0700750 // TODO: Handle incorrect request to move before the actual move, not after.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700751 supervisor.handleNonResizableTaskIfNeeded(this, preferredStack.getWindowingMode(),
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -0700752 DEFAULT_DISPLAY, toStack);
Winson Chung74666102017-02-22 17:49:24 -0800753
Winson Chungdff7a732017-12-11 12:17:06 -0800754 return (preferredStack == toStack);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800755 }
756
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700757 /**
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800758 * @return True if the windows of tasks being moved to the target stack from the source stack
759 * should be replaced, meaning that window manager will keep the old window around until the new
760 * is ready.
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700761 */
762 private static boolean replaceWindowsOnTaskMove(
763 int sourceWindowingMode, int targetWindowingMode) {
764 return sourceWindowingMode == WINDOWING_MODE_FREEFORM
765 || targetWindowingMode == WINDOWING_MODE_FREEFORM;
766 }
767
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800768 void cancelWindowTransition() {
769 mWindowContainerController.cancelWindowTransition();
770 }
771
Jorim Jaggi7361bab2017-01-16 17:17:58 +0100772 /**
773 * DO NOT HOLD THE ACTIVITY MANAGER LOCK WHEN CALLING THIS METHOD!
774 */
Jorim Jaggi35e3f532017-03-17 17:06:50 +0100775 TaskSnapshot getSnapshot(boolean reducedResolution) {
Jorim Jaggi7361bab2017-01-16 17:17:58 +0100776
777 // TODO: Move this to {@link TaskWindowContainerController} once recent tasks are more
778 // synchronized between AM and WM.
Jorim Jaggi35e3f532017-03-17 17:06:50 +0100779 return mService.mWindowManager.getTaskSnapshot(taskId, userId, reducedResolution);
Jorim Jaggi02886a82016-12-06 09:10:06 -0800780 }
781
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800782 void touchActiveTime() {
Winson Chungfb44d212017-10-04 11:39:10 -0700783 lastActiveTime = SystemClock.elapsedRealtime();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800784 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700785
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800786 long getInactiveDuration() {
Winson Chungfb44d212017-10-04 11:39:10 -0700787 return SystemClock.elapsedRealtime() - lastActiveTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800788 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700789
Winson Chungfee26772014-08-05 12:21:52 -0700790 /** Sets the original intent, and the calling uid and package. */
791 void setIntent(ActivityRecord r) {
Winson Chungfee26772014-08-05 12:21:52 -0700792 mCallingUid = r.launchedFromUid;
793 mCallingPackage = r.launchedFromPackage;
Craig Mautner15df08a2015-04-01 12:17:18 -0700794 setIntent(r.intent, r.info);
Charles He2bf28322017-10-12 22:24:49 +0100795 setLockTaskAuth(r);
Winson Chungfee26772014-08-05 12:21:52 -0700796 }
797
798 /** Sets the original intent, _without_ updating the calling uid or package. */
799 private void setIntent(Intent _intent, ActivityInfo info) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700800 if (intent == null) {
801 mNeverRelinquishIdentity =
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700802 (info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700803 } else if (mNeverRelinquishIdentity) {
804 return;
805 }
806
807 affinity = info.taskAffinity;
Dianne Hackborn79228822014-09-16 11:11:23 -0700808 if (intent == null) {
809 // If this task already has an intent associated with it, don't set the root
810 // affinity -- we don't want it changing after initially set, but the initially
811 // set value may be null.
812 rootAffinity = affinity;
813 }
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700814 effectiveUid = info.applicationInfo.uid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700815 stringName = null;
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800816
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800817 if (info.targetActivity == null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800818 if (_intent != null) {
819 // If this Intent has a selector, we want to clear it for the
820 // recent task since it is not relevant if the user later wants
821 // to re-launch the app.
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700822 if (_intent.getSelector() != null || _intent.getSourceBounds() != null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800823 _intent = new Intent(_intent);
824 _intent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700825 _intent.setSourceBounds(null);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800826 }
827 }
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700828 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Setting Intent of " + this + " to " + _intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800829 intent = _intent;
830 realActivity = _intent != null ? _intent.getComponent() : null;
831 origActivity = null;
832 } else {
833 ComponentName targetComponent = new ComponentName(
834 info.packageName, info.targetActivity);
835 if (_intent != null) {
836 Intent targetIntent = new Intent(_intent);
837 targetIntent.setComponent(targetComponent);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800838 targetIntent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700839 targetIntent.setSourceBounds(null);
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700840 if (DEBUG_TASKS) Slog.v(TAG_TASKS,
Dianne Hackborn7f96b792012-05-29 18:46:45 -0700841 "Setting Intent of " + this + " to target " + targetIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800842 intent = targetIntent;
843 realActivity = targetComponent;
844 origActivity = _intent.getComponent();
845 } else {
846 intent = null;
847 realActivity = targetComponent;
848 origActivity = new ComponentName(info.packageName, info.name);
849 }
850 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700851
Craig Mautner47b20ba2014-09-17 17:23:44 -0700852 final int intentFlags = intent == null ? 0 : intent.getFlags();
853 if ((intentFlags & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800854 // Once we are set to an Intent with this flag, we count this
855 // task as having a true root activity.
856 rootWasReset = true;
857 }
Dianne Hackborn09233282014-04-30 11:33:59 -0700858 userId = UserHandle.getUserId(info.applicationInfo.uid);
Winson Chung36f3f032016-09-08 23:29:43 +0000859 mUserSetupComplete = Settings.Secure.getIntForUser(mService.mContext.getContentResolver(),
860 USER_SETUP_COMPLETE, 0, userId) != 0;
Craig Mautner41db4a72014-05-07 17:20:56 -0700861 if ((info.flags & ActivityInfo.FLAG_AUTO_REMOVE_FROM_RECENTS) != 0) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700862 // If the activity itself has requested auto-remove, then just always do it.
863 autoRemoveRecents = true;
Wale Ogunwale843bfb92015-03-27 11:06:48 -0700864 } else if ((intentFlags & (FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS))
865 == FLAG_ACTIVITY_NEW_DOCUMENT) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700866 // If the caller has not asked for the document to be retained, then we may
867 // want to turn on auto-remove, depending on whether the target has set its
868 // own document launch mode.
869 if (info.documentLaunchMode != ActivityInfo.DOCUMENT_LAUNCH_NONE) {
870 autoRemoveRecents = false;
871 } else {
872 autoRemoveRecents = true;
873 }
874 } else {
875 autoRemoveRecents = false;
Craig Mautner41db4a72014-05-07 17:20:56 -0700876 }
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800877 mResizeMode = info.resizeMode;
Winson Chungd3395382016-12-13 11:49:09 -0800878 mSupportsPictureInPicture = info.supportsPictureInPicture();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800879 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800880
Andrii Kulian2e751b82016-03-16 16:59:32 -0700881 /** Sets the original minimal width and height. */
882 private void setMinDimensions(ActivityInfo info) {
883 if (info != null && info.windowLayout != null) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700884 mMinWidth = info.windowLayout.minWidth;
885 mMinHeight = info.windowLayout.minHeight;
Andrii Kulian2e751b82016-03-16 16:59:32 -0700886 } else {
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700887 mMinWidth = INVALID_MIN_SIZE;
888 mMinHeight = INVALID_MIN_SIZE;
Andrii Kulian2e751b82016-03-16 16:59:32 -0700889 }
890 }
891
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800892 /**
Andrii Kulian206b9fa2016-06-02 13:18:01 -0700893 * Return true if the input activity has the same intent filter as the intent this task
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800894 * record is based on (normally the root activity intent).
895 */
Andrii Kulian206b9fa2016-06-02 13:18:01 -0700896 boolean isSameIntentFilter(ActivityRecord r) {
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800897 final Intent intent = new Intent(r.intent);
898 // Correct the activity intent for aliasing. The task record intent will always be based on
899 // the real activity that will be launched not the alias, so we need to use an intent with
900 // the component name pointing to the real activity not the alias in the activity record.
901 intent.setComponent(r.realActivity);
Bryce Lee1a990e52018-04-23 10:54:11 -0700902 return intent.filterEquals(this.intent);
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800903 }
904
Wale Ogunwale66e16852017-10-19 13:35:52 -0700905 boolean returnsToHomeStack() {
906 final int returnHomeFlags = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME;
Bryce Lee1a990e52018-04-23 10:54:11 -0700907 return intent != null && (intent.getFlags() & returnHomeFlags) == returnHomeFlags;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700908 }
909
Craig Mautnera228ae92014-07-09 05:44:55 -0700910 void setPrevAffiliate(TaskRecord prevAffiliate) {
911 mPrevAffiliate = prevAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800912 mPrevAffiliateTaskId = prevAffiliate == null ? INVALID_TASK_ID : prevAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700913 }
914
915 void setNextAffiliate(TaskRecord nextAffiliate) {
916 mNextAffiliate = nextAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800917 mNextAffiliateTaskId = nextAffiliate == null ? INVALID_TASK_ID : nextAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700918 }
919
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700920 <T extends ActivityStack> T getStack() {
921 return (T) mStack;
Andrii Kulian02b7a832016-10-06 23:11:56 -0700922 }
923
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800924 /**
925 * Must be used for setting parent stack because it performs configuration updates.
926 * Must be called after adding task as a child to the stack.
927 */
Andrii Kulian02b7a832016-10-06 23:11:56 -0700928 void setStack(ActivityStack stack) {
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800929 if (stack != null && !stack.isInStackLocked(this)) {
930 throw new IllegalStateException("Task must be added as a Stack child first.");
931 }
Bryce Lee84730a02018-04-03 14:10:04 -0700932 final ActivityStack oldStack = mStack;
Andrii Kulian02b7a832016-10-06 23:11:56 -0700933 mStack = stack;
Bryce Lee84730a02018-04-03 14:10:04 -0700934
935 // If the new {@link TaskRecord} is from a different {@link ActivityStack}, remove this
936 // {@link ActivityRecord} from its current {@link ActivityStack}.
937
938 if (oldStack != mStack) {
939 for (int i = getChildCount() - 1; i >= 0; --i) {
940 final ActivityRecord activity = getChildAt(i);
941
942 if (oldStack != null) {
943 oldStack.onActivityRemovedFromStack(activity);
944 }
945
946 if (mStack != null) {
947 stack.onActivityAddedToStack(activity);
948 }
949 }
950 }
951
Andrii Kulian1779e612016-10-12 21:58:25 -0700952 onParentChanged();
Andrii Kulian02b7a832016-10-06 23:11:56 -0700953 }
954
955 /**
956 * @return Id of current stack, {@link INVALID_STACK_ID} if no stack is set.
957 */
958 int getStackId() {
959 return mStack != null ? mStack.mStackId : INVALID_STACK_ID;
960 }
961
Andrii Kulian1779e612016-10-12 21:58:25 -0700962 @Override
963 protected int getChildCount() {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700964 return mActivities.size();
Andrii Kulian1779e612016-10-12 21:58:25 -0700965 }
966
967 @Override
chaviw82a0ba82018-03-15 14:26:29 -0700968 protected ActivityRecord getChildAt(int index) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700969 return mActivities.get(index);
Andrii Kulian1779e612016-10-12 21:58:25 -0700970 }
971
972 @Override
973 protected ConfigurationContainer getParent() {
974 return mStack;
975 }
976
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800977 @Override
Wale Ogunwale98d62312017-07-12 09:24:56 -0700978 protected void onParentChanged() {
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800979 super.onParentChanged();
980 mService.mStackSupervisor.updateUIDsPresentOnDisplay();
981 }
982
Craig Mautnera228ae92014-07-09 05:44:55 -0700983 // Close up recents linked list.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700984 private void closeRecentsChain() {
Craig Mautnera228ae92014-07-09 05:44:55 -0700985 if (mPrevAffiliate != null) {
986 mPrevAffiliate.setNextAffiliate(mNextAffiliate);
987 }
988 if (mNextAffiliate != null) {
989 mNextAffiliate.setPrevAffiliate(mPrevAffiliate);
990 }
991 setPrevAffiliate(null);
992 setNextAffiliate(null);
993 }
994
Winson Chung740c3ac2014-11-12 16:14:38 -0800995 void removedFromRecents() {
Dianne Hackborn852975d2014-08-22 17:42:43 -0700996 closeRecentsChain();
997 if (inRecents) {
998 inRecents = false;
Winson Chung740c3ac2014-11-12 16:14:38 -0800999 mService.notifyTaskPersisterLocked(this, false);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001000 }
Jorim Jaggif9084ec2017-01-16 13:16:59 +01001001
Dianne Hackborn68a06332017-11-15 17:54:18 -08001002 clearRootProcess();
1003
Jorim Jaggif9084ec2017-01-16 13:16:59 +01001004 // TODO: Use window container controller once tasks are better synced between AM and WM
1005 mService.mWindowManager.notifyTaskRemovedFromRecents(taskId, userId);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001006 }
1007
Craig Mautnera228ae92014-07-09 05:44:55 -07001008 void setTaskToAffiliateWith(TaskRecord taskToAffiliateWith) {
1009 closeRecentsChain();
1010 mAffiliatedTaskId = taskToAffiliateWith.mAffiliatedTaskId;
Winson Chungec396d62014-08-06 17:08:00 -07001011 mAffiliatedTaskColor = taskToAffiliateWith.mAffiliatedTaskColor;
Craig Mautnera228ae92014-07-09 05:44:55 -07001012 // Find the end
1013 while (taskToAffiliateWith.mNextAffiliate != null) {
1014 final TaskRecord nextRecents = taskToAffiliateWith.mNextAffiliate;
1015 if (nextRecents.mAffiliatedTaskId != mAffiliatedTaskId) {
1016 Slog.e(TAG, "setTaskToAffiliateWith: nextRecents=" + nextRecents + " affilTaskId="
1017 + nextRecents.mAffiliatedTaskId + " should be " + mAffiliatedTaskId);
1018 if (nextRecents.mPrevAffiliate == taskToAffiliateWith) {
1019 nextRecents.setPrevAffiliate(null);
1020 }
1021 taskToAffiliateWith.setNextAffiliate(null);
1022 break;
1023 }
1024 taskToAffiliateWith = nextRecents;
1025 }
1026 taskToAffiliateWith.setNextAffiliate(this);
1027 setPrevAffiliate(taskToAffiliateWith);
1028 setNextAffiliate(null);
1029 }
1030
Winson Chung1147c402014-05-14 11:05:00 -07001031 /** Returns the intent for the root activity for this task */
1032 Intent getBaseIntent() {
1033 return intent != null ? intent : affinityIntent;
1034 }
1035
Winson Chung3b3f4642014-04-22 10:08:18 -07001036 /** Returns the first non-finishing activity from the root. */
1037 ActivityRecord getRootActivity() {
1038 for (int i = 0; i < mActivities.size(); i++) {
1039 final ActivityRecord r = mActivities.get(i);
1040 if (r.finishing) {
1041 continue;
1042 }
1043 return r;
1044 }
1045 return null;
1046 }
1047
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001048 ActivityRecord getTopActivity() {
Bryce Lee9f6affd2017-09-01 09:18:35 -07001049 return getTopActivity(true /* includeOverlays */);
1050 }
1051
1052 ActivityRecord getTopActivity(boolean includeOverlays) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001053 for (int i = mActivities.size() - 1; i >= 0; --i) {
1054 final ActivityRecord r = mActivities.get(i);
Bryce Lee9f6affd2017-09-01 09:18:35 -07001055 if (r.finishing || (!includeOverlays && r.mTaskOverlay)) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001056 continue;
1057 }
1058 return r;
1059 }
1060 return null;
1061 }
1062
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -07001063 ActivityRecord topRunningActivityLocked() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001064 if (mStack != null) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07001065 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1066 ActivityRecord r = mActivities.get(activityNdx);
Chong Zhang87761972016-08-22 13:53:24 -07001067 if (!r.finishing && r.okToShowLocked()) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07001068 return r;
1069 }
Craig Mautner6b74cb52013-09-27 17:02:21 -07001070 }
1071 }
1072 return null;
1073 }
1074
Jorim Jaggi172e99f2017-10-20 14:33:18 +02001075 boolean isVisible() {
1076 for (int i = mActivities.size() - 1; i >= 0; --i) {
1077 final ActivityRecord r = mActivities.get(i);
1078 if (r.visible) {
1079 return true;
1080 }
1081 }
1082 return false;
1083 }
1084
Jorim Jaggiea039a82017-08-02 14:37:49 +02001085 void getAllRunningVisibleActivitiesLocked(ArrayList<ActivityRecord> outActivities) {
1086 if (mStack != null) {
1087 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1088 ActivityRecord r = mActivities.get(activityNdx);
Jorim Jaggi02f1d2f2017-08-04 14:29:16 +02001089 if (!r.finishing && r.okToShowLocked() && r.visibleIgnoringKeyguard) {
Jorim Jaggiea039a82017-08-02 14:37:49 +02001090 outActivities.add(r);
1091 }
1092 }
1093 }
1094 }
1095
Wale Ogunwale3b232392016-05-13 15:37:13 -07001096 ActivityRecord topRunningActivityWithStartingWindowLocked() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001097 if (mStack != null) {
Wale Ogunwale3b232392016-05-13 15:37:13 -07001098 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1099 ActivityRecord r = mActivities.get(activityNdx);
1100 if (r.mStartingWindowState != STARTING_WINDOW_SHOWN
Chong Zhang87761972016-08-22 13:53:24 -07001101 || r.finishing || !r.okToShowLocked()) {
Wale Ogunwale3b232392016-05-13 15:37:13 -07001102 continue;
1103 }
1104 return r;
1105 }
1106 }
1107 return null;
1108 }
1109
Winson Chung61c9e5a2017-10-11 10:39:32 -07001110 /**
1111 * Return the number of running activities, and the number of non-finishing/initializing
1112 * activities in the provided {@param reportOut} respectively.
1113 */
1114 void getNumRunningActivities(TaskActivitiesReport reportOut) {
1115 reportOut.reset();
1116 for (int i = mActivities.size() - 1; i >= 0; --i) {
1117 final ActivityRecord r = mActivities.get(i);
1118 if (r.finishing) {
1119 continue;
1120 }
1121
1122 reportOut.base = r;
1123
1124 // Increment the total number of non-finishing activities
1125 reportOut.numActivities++;
1126
Bryce Lee7ace3952018-02-16 14:34:32 -08001127 if (reportOut.top == null || (reportOut.top.isState(ActivityState.INITIALIZING))) {
Winson Chung61c9e5a2017-10-11 10:39:32 -07001128 reportOut.top = r;
1129 // Reset the number of running activities until we hit the first non-initializing
1130 // activity
1131 reportOut.numRunning = 0;
1132 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001133 if (r.attachedToProcess()) {
Winson Chung61c9e5a2017-10-11 10:39:32 -07001134 // Increment the number of actually running activities
1135 reportOut.numRunning++;
1136 }
1137 }
1138 }
1139
Chong Zhang87761972016-08-22 13:53:24 -07001140 boolean okToShowLocked() {
1141 // NOTE: If {@link TaskRecord#topRunningActivityLocked} return is not null then it is
1142 // okay to show the activity when locked.
1143 return mService.mStackSupervisor.isCurrentProfileLocked(userId)
1144 || topRunningActivityLocked() != null;
1145 }
1146
Craig Mautner3b475fe2013-12-16 15:58:31 -08001147 /** Call after activity movement or finish to make sure that frontOfTask is set correctly */
Bryce Leed71317c2017-02-07 14:27:22 -08001148 final void setFrontOfTask() {
1149 boolean foundFront = false;
Craig Mautner3b475fe2013-12-16 15:58:31 -08001150 final int numActivities = mActivities.size();
Craig Mautner704e40b2013-12-18 16:43:51 -08001151 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
Craig Mautner3b475fe2013-12-16 15:58:31 -08001152 final ActivityRecord r = mActivities.get(activityNdx);
1153 if (foundFront || r.finishing) {
1154 r.frontOfTask = false;
1155 } else {
1156 r.frontOfTask = true;
1157 // Set frontOfTask false for every following activity.
1158 foundFront = true;
1159 }
1160 }
Craig Mautner9587ee02014-06-23 15:00:10 +00001161 if (!foundFront && numActivities > 0) {
1162 // All activities of this task are finishing. As we ought to have a frontOfTask
1163 // activity, make the bottom activity front.
1164 mActivities.get(0).frontOfTask = true;
1165 }
Craig Mautner3b475fe2013-12-16 15:58:31 -08001166 }
1167
Craig Mautnerde4ef022013-04-07 19:01:33 -07001168 /**
Craig Mautner3b475fe2013-12-16 15:58:31 -08001169 * Reorder the history stack so that the passed activity is brought to the front.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001170 */
1171 final void moveActivityToFrontLocked(ActivityRecord newTop) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07001172 if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE,
1173 "Removing and adding activity " + newTop
1174 + " to stack at top callers=" + Debug.getCallers(4));
Craig Mautnerde4ef022013-04-07 19:01:33 -07001175
Craig Mautnerde4ef022013-04-07 19:01:33 -07001176 mActivities.remove(newTop);
1177 mActivities.add(newTop);
Bryce Leed58d7b32017-09-08 15:55:22 -07001178
1179 // Make sure window manager is aware of the position change.
1180 mWindowContainerController.positionChildAtTop(newTop.mWindowContainerController);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001181 updateEffectiveIntent();
Craig Mautner3b475fe2013-12-16 15:58:31 -08001182
Bryce Leed71317c2017-02-07 14:27:22 -08001183 setFrontOfTask();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001184 }
1185
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001186 void addActivityAtBottom(ActivityRecord r) {
Craig Mautner77878772013-03-04 19:46:24 -08001187 addActivityAtIndex(0, r);
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001188 }
1189
1190 void addActivityToTop(ActivityRecord r) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001191 addActivityAtIndex(mActivities.size(), r);
1192 }
1193
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001194 @Override
Wale Ogunwaleeea34ee92017-08-31 20:07:45 -07001195 /*@WindowConfiguration.ActivityType*/
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001196 public int getActivityType() {
1197 final int applicationType = super.getActivityType();
1198 if (applicationType != ACTIVITY_TYPE_UNDEFINED || mActivities.isEmpty()) {
1199 return applicationType;
1200 }
1201 return mActivities.get(0).getActivityType();
1202 }
1203
Winson Chung30480042017-01-26 10:55:34 -08001204 /**
1205 * Adds an activity {@param r} at the given {@param index}. The activity {@param r} must either
1206 * be in the current task or unparented to any task.
1207 */
Craig Mautner1602ec22013-05-12 10:24:27 -07001208 void addActivityAtIndex(int index, ActivityRecord r) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001209 TaskRecord task = r.getTask();
1210 if (task != null && task != this) {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001211 throw new IllegalArgumentException("Can not add r=" + " to task=" + this
Bryce Leeaf691c02017-03-20 14:20:22 -07001212 + " current parent=" + task);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001213 }
Bryce Leeaf691c02017-03-20 14:20:22 -07001214
1215 r.setTask(this);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001216
Craig Mautner6170f732013-04-02 13:05:23 -07001217 // 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 -08001218 if (!mActivities.remove(r) && r.fullscreen) {
1219 // Was not previously in list.
1220 numFullscreen++;
1221 }
Craig Mautner2c1faed2013-07-23 12:56:02 -07001222 // Only set this based on the first activity
1223 if (mActivities.isEmpty()) {
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001224 if (r.getActivityType() == ACTIVITY_TYPE_UNDEFINED) {
1225 // Normally non-standard activity type for the activity record will be set when the
1226 // object is created, however we delay setting the standard application type until
1227 // this point so that the task can set the type for additional activities added in
1228 // the else condition below.
1229 r.setActivityType(ACTIVITY_TYPE_STANDARD);
1230 }
1231 setActivityType(r.getActivityType());
Craig Mautner21d24a22014-04-23 11:45:37 -07001232 isPersistable = r.isPersistable();
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001233 mCallingUid = r.launchedFromUid;
1234 mCallingPackage = r.launchedFromPackage;
Dianne Hackborn852975d2014-08-22 17:42:43 -07001235 // Clamp to [1, max].
1236 maxRecents = Math.min(Math.max(r.info.maxRecents, 1),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001237 ActivityTaskManager.getMaxAppRecentsLimitStatic());
Craig Mautner2c1faed2013-07-23 12:56:02 -07001238 } else {
1239 // Otherwise make all added activities match this one.
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001240 r.setActivityType(getActivityType());
Craig Mautner78733002013-06-10 13:54:49 -07001241 }
Wale Ogunwale3b232392016-05-13 15:37:13 -07001242
1243 final int size = mActivities.size();
1244
1245 if (index == size && size > 0) {
1246 final ActivityRecord top = mActivities.get(size - 1);
1247 if (top.mTaskOverlay) {
1248 // Place below the task overlay activity since the overlay activity should always
1249 // be on top.
1250 index--;
1251 }
1252 }
1253
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001254 index = Math.min(size, index);
Craig Mautner77878772013-03-04 19:46:24 -08001255 mActivities.add(index, r);
Bryce Lee84730a02018-04-03 14:10:04 -07001256
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001257 updateEffectiveIntent();
Craig Mautner21d24a22014-04-23 11:45:37 -07001258 if (r.isPersistable()) {
1259 mService.notifyTaskPersisterLocked(this, false);
1260 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001261
1262 // Sync. with window manager
1263 updateOverrideConfigurationFromLaunchBounds();
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001264 final AppWindowContainerController appController = r.getWindowContainerController();
1265 if (appController != null) {
1266 // Only attempt to move in WM if the child has a controller. It is possible we haven't
1267 // created controller for the activity we are starting yet.
1268 mWindowContainerController.positionChildAt(appController, index);
1269 }
David Stevens82ea6cb2017-03-03 16:18:50 -08001270
1271 // Make sure the list of display UID whitelists is updated
1272 // now that this record is in a new task.
1273 mService.mStackSupervisor.updateUIDsPresentOnDisplay();
Craig Mautner77878772013-03-04 19:46:24 -08001274 }
1275
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001276 /**
Bryce Leeaf691c02017-03-20 14:20:22 -07001277 * Removes the specified activity from this task.
1278 * @param r The {@link ActivityRecord} to remove.
1279 * @return true if this was the last activity in the task.
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001280 */
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001281 boolean removeActivity(ActivityRecord r) {
Bryce Lee84730a02018-04-03 14:10:04 -07001282 return removeActivity(r, false /* reparenting */);
Bryce Leeaf691c02017-03-20 14:20:22 -07001283 }
1284
1285 boolean removeActivity(ActivityRecord r, boolean reparenting) {
1286 if (r.getTask() != this) {
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001287 throw new IllegalArgumentException(
1288 "Activity=" + r + " does not belong to task=" + this);
1289 }
1290
Bryce Lee84730a02018-04-03 14:10:04 -07001291 r.setTask(null /* task */, reparenting /* reparenting */);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001292
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001293 if (mActivities.remove(r) && r.fullscreen) {
1294 // Was previously in list.
1295 numFullscreen--;
1296 }
Craig Mautner21d24a22014-04-23 11:45:37 -07001297 if (r.isPersistable()) {
1298 mService.notifyTaskPersisterLocked(this, false);
1299 }
Wale Ogunwale89182d52016-03-11 10:38:36 -08001300
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001301 if (inPinnedWindowingMode()) {
Wale Ogunwale89182d52016-03-11 10:38:36 -08001302 // We normally notify listeners of task stack changes on pause, however pinned stack
1303 // activities are normally in the paused state so no notification will be sent there
1304 // before the activity is removed. We send it here so instead.
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001305 mService.getTaskChangeNotificationController().notifyTaskStackChanged();
Wale Ogunwale89182d52016-03-11 10:38:36 -08001306 }
1307
Craig Mautner41326202014-06-20 14:38:21 -07001308 if (mActivities.isEmpty()) {
Craig Mautner5afcd4d2014-06-21 18:11:33 -07001309 return !mReuseTask;
Craig Mautner41326202014-06-20 14:38:21 -07001310 }
1311 updateEffectiveIntent();
1312 return false;
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001313 }
1314
Winson Chung6954fc92017-03-24 16:22:12 -07001315 /**
1316 * @return whether or not there are ONLY task overlay activities in the stack.
1317 * If {@param excludeFinishing} is set, then ignore finishing activities in the check.
1318 * If there are no task overlay activities, this call returns false.
1319 */
1320 boolean onlyHasTaskOverlayActivities(boolean excludeFinishing) {
1321 int count = 0;
1322 for (int i = mActivities.size() - 1; i >= 0; i--) {
1323 final ActivityRecord r = mActivities.get(i);
1324 if (excludeFinishing && r.finishing) {
1325 continue;
1326 }
1327 if (!r.mTaskOverlay) {
1328 return false;
1329 }
1330 count++;
1331 }
1332 return count > 0;
1333 }
1334
Craig Mautner41db4a72014-05-07 17:20:56 -07001335 boolean autoRemoveFromRecents() {
Dianne Hackbornd38aed82014-06-10 21:36:35 -07001336 // We will automatically remove the task either if it has explicitly asked for
1337 // this, or it is empty and has never contained an activity that got shown to
1338 // the user.
Dianne Hackborn13420f22014-07-18 15:43:56 -07001339 return autoRemoveRecents || (mActivities.isEmpty() && !hasBeenVisible);
Craig Mautner41db4a72014-05-07 17:20:56 -07001340 }
1341
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001342 /**
1343 * Completely remove all activities associated with an existing
1344 * task starting at a specified index.
1345 */
Winson Chung0ec2a352017-10-26 11:38:30 -07001346 final void performClearTaskAtIndexLocked(int activityNdx, boolean pauseImmediately,
1347 String reason) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001348 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001349 for ( ; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001350 final ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001351 if (r.finishing) {
1352 continue;
1353 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07001354 if (mStack == null) {
Craig Mautner21d24a22014-04-23 11:45:37 -07001355 // Task was restored from persistent storage.
1356 r.takeFromHistory();
1357 mActivities.remove(activityNdx);
1358 --activityNdx;
1359 --numActivities;
Winson Chung6954fc92017-03-24 16:22:12 -07001360 } else if (mStack.finishActivityLocked(r, Activity.RESULT_CANCELED, null,
Winson Chung0ec2a352017-10-26 11:38:30 -07001361 reason, false, pauseImmediately)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001362 --activityNdx;
1363 --numActivities;
1364 }
1365 }
1366 }
1367
1368 /**
1369 * Completely remove all activities associated with an existing task.
1370 */
Benjamin Franza83859f2017-07-03 16:34:14 +01001371 void performClearTaskLocked() {
Craig Mautner362449a2014-06-20 14:04:39 -07001372 mReuseTask = true;
Winson Chung0ec2a352017-10-26 11:38:30 -07001373 performClearTaskAtIndexLocked(0, !PAUSE_IMMEDIATELY, "clear-task-all");
Craig Mautner362449a2014-06-20 14:04:39 -07001374 mReuseTask = false;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001375 }
1376
Filip Gruszczynskibe9dabd2016-01-19 12:23:10 -08001377 ActivityRecord performClearTaskForReuseLocked(ActivityRecord newR, int launchFlags) {
1378 mReuseTask = true;
1379 final ActivityRecord result = performClearTaskLocked(newR, launchFlags);
1380 mReuseTask = false;
1381 return result;
1382 }
1383
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001384 /**
1385 * Perform clear operation as requested by
1386 * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the
1387 * stack to the given task, then look for
1388 * an instance of that activity in the stack and, if found, finish all
1389 * activities on top of it and return the instance.
1390 *
1391 * @param newR Description of the new activity being started.
1392 * @return Returns the old activity that should be continued to be used,
1393 * or null if none was found.
1394 */
1395 final ActivityRecord performClearTaskLocked(ActivityRecord newR, int launchFlags) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001396 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001397 for (int activityNdx = numActivities - 1; activityNdx >= 0; --activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001398 ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001399 if (r.finishing) {
1400 continue;
1401 }
1402 if (r.realActivity.equals(newR.realActivity)) {
1403 // Here it is! Now finish everything in front...
Craig Mautner1602ec22013-05-12 10:24:27 -07001404 final ActivityRecord ret = r;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001405
1406 for (++activityNdx; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001407 r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001408 if (r.finishing) {
1409 continue;
1410 }
1411 ActivityOptions opts = r.takeOptionsLocked();
1412 if (opts != null) {
1413 ret.updateOptionsLocked(opts);
1414 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07001415 if (mStack != null && mStack.finishActivityLocked(
Todd Kennedy539db512014-12-15 09:57:55 -08001416 r, Activity.RESULT_CANCELED, null, "clear-task-stack", false)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001417 --activityNdx;
1418 --numActivities;
1419 }
1420 }
1421
1422 // Finally, if this is a normal launch mode (that is, not
1423 // expecting onNewIntent()), then we will finish the current
1424 // instance of the activity so a new fresh one can be started.
1425 if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE
Daichi Hirono15a02992016-04-27 18:47:01 +09001426 && (launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0
1427 && !ActivityStarter.isDocumentLaunchesIntoExisting(launchFlags)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001428 if (!ret.finishing) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001429 if (mStack != null) {
1430 mStack.finishActivityLocked(
Wale Ogunwale7d701172015-03-11 15:36:30 -07001431 ret, Activity.RESULT_CANCELED, null, "clear-task-top", false);
1432 }
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001433 return null;
1434 }
1435 }
1436
1437 return ret;
1438 }
1439 }
1440
1441 return null;
1442 }
1443
Winson Chung0ec2a352017-10-26 11:38:30 -07001444 void removeTaskActivitiesLocked(boolean pauseImmediately, String reason) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001445 // Just remove the entire task.
Winson Chung0ec2a352017-10-26 11:38:30 -07001446 performClearTaskAtIndexLocked(0, pauseImmediately, reason);
Craig Mautner9db9a0b2013-04-29 17:05:56 -07001447 }
1448
Craig Mautner432f64e2015-05-20 14:59:57 -07001449 String lockTaskAuthToString() {
1450 switch (mLockTaskAuth) {
1451 case LOCK_TASK_AUTH_DONT_LOCK: return "LOCK_TASK_AUTH_DONT_LOCK";
1452 case LOCK_TASK_AUTH_PINNABLE: return "LOCK_TASK_AUTH_PINNABLE";
1453 case LOCK_TASK_AUTH_LAUNCHABLE: return "LOCK_TASK_AUTH_LAUNCHABLE";
1454 case LOCK_TASK_AUTH_WHITELISTED: return "LOCK_TASK_AUTH_WHITELISTED";
Benjamin Franz469dd582015-06-09 14:24:36 +01001455 case LOCK_TASK_AUTH_LAUNCHABLE_PRIV: return "LOCK_TASK_AUTH_LAUNCHABLE_PRIV";
Craig Mautner432f64e2015-05-20 14:59:57 -07001456 default: return "unknown=" + mLockTaskAuth;
1457 }
1458 }
1459
Craig Mautner15df08a2015-04-01 12:17:18 -07001460 void setLockTaskAuth() {
Charles He2bf28322017-10-12 22:24:49 +01001461 setLockTaskAuth(getRootActivity());
1462 }
1463
1464 private void setLockTaskAuth(@Nullable ActivityRecord r) {
1465 if (r == null) {
1466 mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE;
1467 return;
1468 }
1469
Charles He520b2832017-09-02 15:27:16 +01001470 final String pkg = (realActivity != null) ? realActivity.getPackageName() : null;
Bryce Lee2b8e0372018-04-05 17:01:37 -07001471 final LockTaskController lockTaskController = mService.getLockTaskController();
Charles He2bf28322017-10-12 22:24:49 +01001472 switch (r.lockTaskLaunchMode) {
Craig Mautner15df08a2015-04-01 12:17:18 -07001473 case LOCK_TASK_LAUNCH_MODE_DEFAULT:
Bryce Lee2b8e0372018-04-05 17:01:37 -07001474 mLockTaskAuth = lockTaskController.isPackageWhitelisted(userId, pkg)
Charles He520b2832017-09-02 15:27:16 +01001475 ? LOCK_TASK_AUTH_WHITELISTED : LOCK_TASK_AUTH_PINNABLE;
Craig Mautner15df08a2015-04-01 12:17:18 -07001476 break;
1477
1478 case LOCK_TASK_LAUNCH_MODE_NEVER:
Benjamin Franz469dd582015-06-09 14:24:36 +01001479 mLockTaskAuth = LOCK_TASK_AUTH_DONT_LOCK;
Craig Mautner15df08a2015-04-01 12:17:18 -07001480 break;
1481
1482 case LOCK_TASK_LAUNCH_MODE_ALWAYS:
Benjamin Franz469dd582015-06-09 14:24:36 +01001483 mLockTaskAuth = LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
Craig Mautner15df08a2015-04-01 12:17:18 -07001484 break;
1485
1486 case LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED:
Bryce Lee2b8e0372018-04-05 17:01:37 -07001487 mLockTaskAuth = lockTaskController.isPackageWhitelisted(userId, pkg)
Charles He520b2832017-09-02 15:27:16 +01001488 ? LOCK_TASK_AUTH_LAUNCHABLE : LOCK_TASK_AUTH_PINNABLE;
Craig Mautner15df08a2015-04-01 12:17:18 -07001489 break;
1490 }
Craig Mautner432f64e2015-05-20 14:59:57 -07001491 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
1492 " mLockTaskAuth=" + lockTaskAuthToString());
Craig Mautner15df08a2015-04-01 12:17:18 -07001493 }
1494
Winson Chungd3395382016-12-13 11:49:09 -08001495 private boolean isResizeable(boolean checkSupportsPip) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001496 return (mService.mForceResizableActivities || ActivityInfo.isResizeableMode(mResizeMode)
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -07001497 || (checkSupportsPip && mSupportsPictureInPicture));
Winson Chungd3395382016-12-13 11:49:09 -08001498 }
1499
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001500 boolean isResizeable() {
Winson Chungd3395382016-12-13 11:49:09 -08001501 return isResizeable(true /* checkSupportsPip */);
1502 }
1503
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001504 @Override
1505 public boolean supportsSplitScreenWindowingMode() {
Winson Chungd3395382016-12-13 11:49:09 -08001506 // A task can not be docked even if it is considered resizeable because it only supports
1507 // picture-in-picture mode but has a non-resizeable resizeMode
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001508 return super.supportsSplitScreenWindowingMode()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001509 && mService.mSupportsSplitScreenMultiWindow
1510 && (mService.mForceResizableActivities
Bryce Leec857a5b2017-08-16 10:04:52 -07001511 || (isResizeable(false /* checkSupportsPip */)
1512 && !ActivityInfo.isPreserveOrientationMode(mResizeMode)));
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001513 }
1514
skuhne@google.com322347b2016-12-02 12:54:03 -08001515 /**
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001516 * Check whether this task can be launched on the specified display.
Riddle Hsu16567132018-08-16 21:37:47 +08001517 *
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001518 * @param displayId Target display id.
Riddle Hsu16567132018-08-16 21:37:47 +08001519 * @return {@code true} if either it is the default display or this activity can be put on a
1520 * secondary display.
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001521 */
1522 boolean canBeLaunchedOnDisplay(int displayId) {
1523 return mService.mStackSupervisor.canPlaceEntityOnDisplay(displayId,
Riddle Hsu16567132018-08-16 21:37:47 +08001524 -1 /* don't check PID */, -1 /* don't check UID */, null /* activityInfo */);
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001525 }
1526
1527 /**
skuhne@google.com322347b2016-12-02 12:54:03 -08001528 * Check that a given bounds matches the application requested orientation.
1529 *
1530 * @param bounds The bounds to be tested.
1531 * @return True if the requested bounds are okay for a resizing request.
1532 */
Wale Ogunwale069bbd32017-02-03 07:58:14 -08001533 private boolean canResizeToBounds(Rect bounds) {
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001534 if (bounds == null || !inFreeformWindowingMode()) {
skuhne@google.com322347b2016-12-02 12:54:03 -08001535 // Note: If not on the freeform workspace, we ignore the bounds.
1536 return true;
1537 }
1538 final boolean landscape = bounds.width() > bounds.height();
Bryce Leef3c6a472017-11-14 14:53:06 -08001539 final Rect configBounds = getOverrideBounds();
skuhne@google.com322347b2016-12-02 12:54:03 -08001540 if (mResizeMode == RESIZE_MODE_FORCE_RESIZABLE_PRESERVE_ORIENTATION) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001541 return configBounds.isEmpty()
1542 || landscape == (configBounds.width() > configBounds.height());
skuhne@google.com322347b2016-12-02 12:54:03 -08001543 }
1544 return (mResizeMode != RESIZE_MODE_FORCE_RESIZABLE_PORTRAIT_ONLY || !landscape)
1545 && (mResizeMode != RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY || landscape);
1546 }
1547
Craig Mautner525f3d92013-05-07 14:01:50 -07001548 /**
Yorke Leebdef5372017-04-10 16:38:51 -07001549 * @return {@code true} if the task is being cleared for the purposes of being reused.
1550 */
1551 boolean isClearingToReuseTask() {
1552 return mReuseTask;
1553 }
1554
1555 /**
Craig Mautner525f3d92013-05-07 14:01:50 -07001556 * Find the activity in the history stack within the given task. Returns
1557 * the index within the history at which it's found, or < 0 if not found.
1558 */
1559 final ActivityRecord findActivityInHistoryLocked(ActivityRecord r) {
1560 final ComponentName realActivity = r.realActivity;
1561 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1562 ActivityRecord candidate = mActivities.get(activityNdx);
1563 if (candidate.finishing) {
1564 continue;
1565 }
1566 if (candidate.realActivity.equals(realActivity)) {
1567 return candidate;
1568 }
1569 }
1570 return null;
1571 }
1572
Winson Chunga449dc02014-05-16 11:15:04 -07001573 /** Updates the last task description values. */
1574 void updateTaskDescription() {
1575 // Traverse upwards looking for any break between main task activities and
1576 // utility activities.
1577 int activityNdx;
1578 final int numActivities = mActivities.size();
Wale Ogunwale3eadad72016-10-13 09:16:59 -07001579 final boolean relinquish = numActivities != 0 &&
1580 (mActivities.get(0).info.flags & FLAG_RELINQUISH_TASK_IDENTITY) != 0;
Winson Chunga449dc02014-05-16 11:15:04 -07001581 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
Craig Mautner21d24a22014-04-23 11:45:37 -07001582 ++activityNdx) {
Winson Chunga449dc02014-05-16 11:15:04 -07001583 final ActivityRecord r = mActivities.get(activityNdx);
Wale Ogunwale3eadad72016-10-13 09:16:59 -07001584 if (relinquish && (r.info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001585 // This will be the top activity for determining taskDescription. Pre-inc to
1586 // overcome initial decrement below.
1587 ++activityNdx;
1588 break;
1589 }
Winson Chunga449dc02014-05-16 11:15:04 -07001590 if (r.intent != null &&
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001591 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
Winson Chunga449dc02014-05-16 11:15:04 -07001592 break;
1593 }
1594 }
1595 if (activityNdx > 0) {
1596 // Traverse downwards starting below break looking for set label, icon.
1597 // Note that if there are activities in the task but none of them set the
1598 // recent activity values, then we do not fall back to the last set
1599 // values in the TaskRecord.
1600 String label = null;
Craig Mautner648f69b2014-09-18 14:16:26 -07001601 String iconFilename = null;
Matthew Ng54bc9422017-10-02 17:16:28 -07001602 int iconResource = -1;
Winson Chunga449dc02014-05-16 11:15:04 -07001603 int colorPrimary = 0;
Winson Chung1af8eda2016-02-05 17:55:56 +00001604 int colorBackground = 0;
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001605 int statusBarColor = 0;
1606 int navigationBarColor = 0;
1607 boolean topActivity = true;
Winson Chunga449dc02014-05-16 11:15:04 -07001608 for (--activityNdx; activityNdx >= 0; --activityNdx) {
1609 final ActivityRecord r = mActivities.get(activityNdx);
Winson Chung80f80db2018-05-30 21:13:25 -07001610 if (r.mTaskOverlay) {
1611 continue;
1612 }
Winson Chunga449dc02014-05-16 11:15:04 -07001613 if (r.taskDescription != null) {
1614 if (label == null) {
1615 label = r.taskDescription.getLabel();
1616 }
Matthew Ng54bc9422017-10-02 17:16:28 -07001617 if (iconResource == -1) {
1618 iconResource = r.taskDescription.getIconResource();
1619 }
Craig Mautner648f69b2014-09-18 14:16:26 -07001620 if (iconFilename == null) {
1621 iconFilename = r.taskDescription.getIconFilename();
Winson Chunga449dc02014-05-16 11:15:04 -07001622 }
1623 if (colorPrimary == 0) {
1624 colorPrimary = r.taskDescription.getPrimaryColor();
Winson Chunga449dc02014-05-16 11:15:04 -07001625 }
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001626 if (topActivity) {
Winson Chung1af8eda2016-02-05 17:55:56 +00001627 colorBackground = r.taskDescription.getBackgroundColor();
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001628 statusBarColor = r.taskDescription.getStatusBarColor();
1629 navigationBarColor = r.taskDescription.getNavigationBarColor();
Winson Chung1af8eda2016-02-05 17:55:56 +00001630 }
Winson Chunga449dc02014-05-16 11:15:04 -07001631 }
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001632 topActivity = false;
Winson Chunga449dc02014-05-16 11:15:04 -07001633 }
Matthew Ng54bc9422017-10-02 17:16:28 -07001634 lastTaskDescription = new TaskDescription(label, null, iconResource, iconFilename,
1635 colorPrimary, colorBackground, statusBarColor, navigationBarColor);
Jorim Jaggi829b9cd2017-01-23 16:20:53 +01001636 if (mWindowContainerController != null) {
1637 mWindowContainerController.setTaskDescription(lastTaskDescription);
1638 }
Winson Chungec396d62014-08-06 17:08:00 -07001639 // Update the task affiliation color if we are the parent of the group
1640 if (taskId == mAffiliatedTaskId) {
1641 mAffiliatedTaskColor = lastTaskDescription.getPrimaryColor();
1642 }
Winson Chunga449dc02014-05-16 11:15:04 -07001643 }
1644 }
1645
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001646 int findEffectiveRootIndex() {
Craig Mautner4767f4b2014-09-18 15:38:33 -07001647 int effectiveNdx = 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001648 final int topActivityNdx = mActivities.size() - 1;
Dianne Hackborn39569af2014-09-23 10:56:58 -07001649 for (int activityNdx = 0; activityNdx <= topActivityNdx; ++activityNdx) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001650 final ActivityRecord r = mActivities.get(activityNdx);
1651 if (r.finishing) {
1652 continue;
1653 }
Craig Mautner4767f4b2014-09-18 15:38:33 -07001654 effectiveNdx = activityNdx;
Wale Ogunwale3eadad72016-10-13 09:16:59 -07001655 if ((r.info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001656 break;
1657 }
1658 }
Craig Mautner4767f4b2014-09-18 15:38:33 -07001659 return effectiveNdx;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001660 }
1661
1662 void updateEffectiveIntent() {
1663 final int effectiveRootIndex = findEffectiveRootIndex();
1664 final ActivityRecord r = mActivities.get(effectiveRootIndex);
Winson Chungfee26772014-08-05 12:21:52 -07001665 setIntent(r);
Winson Chung8d9009e2017-11-16 15:43:05 -08001666
1667 // Update the task description when the activities change
1668 updateTaskDescription();
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001669 }
1670
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001671 private void adjustForMinimalTaskDimensions(Rect bounds) {
1672 if (bounds == null) {
1673 return;
1674 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001675 int minWidth = mMinWidth;
1676 int minHeight = mMinHeight;
Robert Carr9c5867d2016-03-10 15:52:46 -08001677 // If the task has no requested minimal size, we'd like to enforce a minimal size
1678 // so that the user can not render the task too small to manipulate. We don't need
1679 // to do this for the pinned stack as the bounds are controlled by the system.
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001680 if (!inPinnedWindowingMode()) {
Garfield Tan4a48a7f2018-10-02 14:23:55 -07001681 final int defaultMinSizeDp =
1682 mService.mStackSupervisor.mDefaultMinSizeOfResizeableTaskDp;
1683 final ActivityDisplay display =
1684 mService.mStackSupervisor.getActivityDisplay(mStack.mDisplayId);
1685 final float density =
1686 (float) display.getConfiguration().densityDpi / DisplayMetrics.DENSITY_DEFAULT;
1687 final int defaultMinSize = (int) (defaultMinSizeDp * density);
1688
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001689 if (minWidth == INVALID_MIN_SIZE) {
Garfield Tan4a48a7f2018-10-02 14:23:55 -07001690 minWidth = defaultMinSize;
Andrii Kulian2e751b82016-03-16 16:59:32 -07001691 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001692 if (minHeight == INVALID_MIN_SIZE) {
Garfield Tan4a48a7f2018-10-02 14:23:55 -07001693 minHeight = defaultMinSize;
Andrii Kulian2e751b82016-03-16 16:59:32 -07001694 }
Robert Carr9c5867d2016-03-10 15:52:46 -08001695 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001696 final boolean adjustWidth = minWidth > bounds.width();
1697 final boolean adjustHeight = minHeight > bounds.height();
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001698 if (!(adjustWidth || adjustHeight)) {
1699 return;
1700 }
1701
Bryce Leef3c6a472017-11-14 14:53:06 -08001702 final Rect configBounds = getOverrideBounds();
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001703 if (adjustWidth) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001704 if (!configBounds.isEmpty() && bounds.right == configBounds.right) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001705 bounds.left = bounds.right - minWidth;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001706 } else {
1707 // Either left bounds match, or neither match, or the previous bounds were
1708 // fullscreen and we default to keeping left.
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001709 bounds.right = bounds.left + minWidth;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001710 }
1711 }
1712 if (adjustHeight) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001713 if (!configBounds.isEmpty() && bounds.bottom == configBounds.bottom) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001714 bounds.top = bounds.bottom - minHeight;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001715 } else {
1716 // Either top bounds match, or neither match, or the previous bounds were
1717 // fullscreen and we default to keeping top.
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001718 bounds.bottom = bounds.top + minHeight;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001719 }
1720 }
1721 }
1722
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001723 /**
Winson Chung5af42fc2017-03-24 17:11:33 -07001724 * @return a new Configuration for this Task, given the provided {@param bounds} and
1725 * {@param insetBounds}.
1726 */
1727 Configuration computeNewOverrideConfigurationForBounds(Rect bounds, Rect insetBounds) {
1728 // Compute a new override configuration for the given bounds, if fullscreen bounds
1729 // (bounds == null), then leave the override config unset
1730 final Configuration newOverrideConfig = new Configuration();
1731 if (bounds != null) {
1732 newOverrideConfig.setTo(getOverrideConfiguration());
1733 mTmpRect.set(bounds);
1734 adjustForMinimalTaskDimensions(mTmpRect);
1735 computeOverrideConfiguration(newOverrideConfig, mTmpRect, insetBounds,
1736 mTmpRect.right != bounds.right, mTmpRect.bottom != bounds.bottom);
1737 }
1738
1739 return newOverrideConfig;
1740 }
1741
1742 /**
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001743 * Update task's override configuration based on the bounds.
Jorim Jaggi0a932142016-02-01 17:42:25 -08001744 * @param bounds The bounds of the task.
Andrii Kulian8072d112016-09-16 11:11:01 -07001745 * @return True if the override configuration was updated.
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001746 */
Andrii Kulian8072d112016-09-16 11:11:01 -07001747 boolean updateOverrideConfiguration(Rect bounds) {
Jorim Jaggi0a932142016-02-01 17:42:25 -08001748 return updateOverrideConfiguration(bounds, null /* insetBounds */);
1749 }
1750
Evan Rosky9ba524e2018-01-03 16:27:56 -08001751 void setLastNonFullscreenBounds(Rect bounds) {
1752 if (mLastNonFullscreenBounds == null) {
1753 mLastNonFullscreenBounds = new Rect(bounds);
1754 } else {
1755 mLastNonFullscreenBounds.set(bounds);
1756 }
1757 }
1758
Jorim Jaggi0a932142016-02-01 17:42:25 -08001759 /**
1760 * Update task's override configuration based on the bounds.
1761 * @param bounds The bounds of the task.
1762 * @param insetBounds The bounds used to calculate the system insets, which is used here to
1763 * subtract the navigation bar/status bar size from the screen size reported
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001764 * to the application. See {@link IActivityTaskManager#resizeDockedStack}.
Andrii Kulian8072d112016-09-16 11:11:01 -07001765 * @return True if the override configuration was updated.
Jorim Jaggi0a932142016-02-01 17:42:25 -08001766 */
Andrii Kulian8072d112016-09-16 11:11:01 -07001767 boolean updateOverrideConfiguration(Rect bounds, @Nullable Rect insetBounds) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001768 if (equivalentOverrideBounds(bounds)) {
Andrii Kulian8072d112016-09-16 11:11:01 -07001769 return false;
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001770 }
Bryce Leef3c6a472017-11-14 14:53:06 -08001771 final Rect currentBounds = getOverrideBounds();
1772
Andrii Kulian1779e612016-10-12 21:58:25 -07001773 mTmpConfig.setTo(getOverrideConfiguration());
Andrii Kulian1779e612016-10-12 21:58:25 -07001774 final Configuration newConfig = getOverrideConfiguration();
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001775
Bryce Leef3c6a472017-11-14 14:53:06 -08001776 final boolean matchParentBounds = bounds == null || bounds.isEmpty();
Wale Ogunwale3382ab12017-07-27 08:55:03 -07001777 final boolean persistBounds = getWindowConfiguration().persistTaskBounds();
Bryce Leef3c6a472017-11-14 14:53:06 -08001778 if (matchParentBounds) {
1779 if (!currentBounds.isEmpty() && persistBounds) {
Evan Rosky9ba524e2018-01-03 16:27:56 -08001780 setLastNonFullscreenBounds(currentBounds);
Wale Ogunwale706ed792015-08-02 10:29:44 -07001781 }
Bryce Leef3c6a472017-11-14 14:53:06 -08001782 setBounds(null);
Andrii Kulian1779e612016-10-12 21:58:25 -07001783 newConfig.unset();
Wale Ogunwale706ed792015-08-02 10:29:44 -07001784 } else {
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001785 mTmpRect.set(bounds);
1786 adjustForMinimalTaskDimensions(mTmpRect);
Bryce Leef3c6a472017-11-14 14:53:06 -08001787 setBounds(mTmpRect);
1788
Wale Ogunwale3382ab12017-07-27 08:55:03 -07001789 if (mStack == null || persistBounds) {
Evan Rosky9ba524e2018-01-03 16:27:56 -08001790 setLastNonFullscreenBounds(getOverrideBounds());
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -07001791 }
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07001792 computeOverrideConfiguration(newConfig, mTmpRect, insetBounds,
Andrii Kuliandaea3572016-04-08 13:20:51 -07001793 mTmpRect.right != bounds.right, mTmpRect.bottom != bounds.bottom);
Wale Ogunwale706ed792015-08-02 10:29:44 -07001794 }
Andrii Kulian1779e612016-10-12 21:58:25 -07001795 onOverrideConfigurationChanged(newConfig);
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08001796 return !mTmpConfig.equals(newConfig);
1797 }
Wale Ogunwale5f986092015-12-04 15:35:38 -08001798
Bryce Leec4ab62a2018-03-05 14:19:26 -08001799 /**
1800 * This should be called when an child activity changes state. This should only
1801 * be called from
1802 * {@link ActivityRecord#setState(ActivityState, String)} .
1803 * @param record The {@link ActivityRecord} whose state has changed.
1804 * @param state The new state.
1805 * @param reason The reason for the change.
1806 */
1807 void onActivityStateChanged(ActivityRecord record, ActivityState state, String reason) {
1808 final ActivityStack parent = getStack();
1809
1810 if (parent != null) {
1811 parent.onActivityStateChanged(record, state, reason);
1812 }
1813 }
1814
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08001815 @Override
1816 public void onConfigurationChanged(Configuration newParentConfig) {
1817 final boolean wasInMultiWindowMode = inMultiWindowMode();
1818 super.onConfigurationChanged(newParentConfig);
1819 if (wasInMultiWindowMode != inMultiWindowMode()) {
Winson Chung5af42fc2017-03-24 17:11:33 -07001820 mService.mStackSupervisor.scheduleUpdateMultiWindowMode(this);
Wale Ogunwale5f986092015-12-04 15:35:38 -08001821 }
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08001822 // TODO: Should also take care of Pip mode changes here.
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001823 }
1824
Andrii Kulian1779e612016-10-12 21:58:25 -07001825 /** Clears passed config and fills it with new override values. */
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07001826 // TODO(b/36505427): TaskRecord.computeOverrideConfiguration() is a utility method that doesn't
1827 // depend on task or stacks, but uses those object to get the display to base the calculation
1828 // on. Probably best to centralize calculations like this in ConfigurationContainer.
1829 void computeOverrideConfiguration(Configuration config, Rect bounds, Rect insetBounds,
Andrii Kuliana8a9bc52016-10-14 11:00:13 -07001830 boolean overrideWidth, boolean overrideHeight) {
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001831 mTmpNonDecorBounds.set(bounds);
1832 mTmpStableBounds.set(bounds);
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001833
Andrii Kulian1779e612016-10-12 21:58:25 -07001834 config.unset();
Winson Chungbdc646f2017-02-13 12:12:22 -08001835 final Configuration parentConfig = getParent().getConfiguration();
Bryce Lee7566d762017-03-30 09:34:15 -07001836
Andrii Kulian1779e612016-10-12 21:58:25 -07001837 final float density = parentConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001838
Winson Chungbdc646f2017-02-13 12:12:22 -08001839 if (mStack != null) {
1840 final StackWindowController stackController = mStack.getWindowContainerController();
1841 stackController.adjustConfigurationForBounds(bounds, insetBounds,
1842 mTmpNonDecorBounds, mTmpStableBounds, overrideWidth, overrideHeight, density,
Evan Roskyb0e38882018-04-25 12:48:54 -07001843 config, parentConfig, getWindowingMode());
Winson Chungbdc646f2017-02-13 12:12:22 -08001844 } else {
Bryce Lee7566d762017-03-30 09:34:15 -07001845 throw new IllegalArgumentException("Expected stack when calculating override config");
Winson Chungbdc646f2017-02-13 12:12:22 -08001846 }
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001847
Winson Chung60c1aba2017-03-14 17:47:42 -07001848 config.orientation = (config.screenWidthDp <= config.screenHeightDp)
1849 ? Configuration.ORIENTATION_PORTRAIT
1850 : Configuration.ORIENTATION_LANDSCAPE;
1851
Jorim Jaggi85639432016-05-06 17:27:55 -07001852 // For calculating screen layout, we need to use the non-decor inset screen area for the
1853 // calculation for compatibility reasons, i.e. screen area without system bars that could
1854 // never go away in Honeycomb.
Winson Chungbdc646f2017-02-13 12:12:22 -08001855 final int compatScreenWidthDp = (int) (mTmpNonDecorBounds.width() / density);
1856 final int compatScreenHeightDp = (int) (mTmpNonDecorBounds.height() / density);
Andrii Kulian1779e612016-10-12 21:58:25 -07001857 // We're only overriding LONG, SIZE and COMPAT parts of screenLayout, so we start override
1858 // calculation with partial default.
Louis Chang8b580162018-06-26 17:58:29 +08001859 // Reducing the screen layout starting from its parent config.
1860 final int sl = parentConfig.screenLayout &
1861 (Configuration.SCREENLAYOUT_LONG_MASK | Configuration.SCREENLAYOUT_SIZE_MASK);
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001862 final int longSize = Math.max(compatScreenHeightDp, compatScreenWidthDp);
Andrii Kulian1779e612016-10-12 21:58:25 -07001863 final int shortSize = Math.min(compatScreenHeightDp, compatScreenWidthDp);
Jorim Jaggi85639432016-05-06 17:27:55 -07001864 config.screenLayout = Configuration.reduceScreenLayout(sl, longSize, shortSize);
Jorim Jaggia95ca8d2016-01-15 22:54:46 -08001865 }
1866
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08001867 Rect updateOverrideConfigurationFromLaunchBounds() {
Bryce Leef3c6a472017-11-14 14:53:06 -08001868 final Rect bounds = getLaunchBounds();
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08001869 updateOverrideConfiguration(bounds);
Bryce Leef3c6a472017-11-14 14:53:06 -08001870 if (bounds != null && !bounds.isEmpty()) {
1871 // TODO: Review if we actually want to do this - we are setting the launch bounds
1872 // directly here.
1873 bounds.set(getOverrideBounds());
Andrii Kulian73336d812016-03-24 12:56:08 -07001874 }
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08001875 return bounds;
1876 }
1877
Wale Ogunwale935e5022015-11-10 12:36:10 -08001878 /** Updates the task's bounds and override configuration to match what is expected for the
1879 * input stack. */
1880 void updateOverrideConfigurationForStack(ActivityStack inStack) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001881 if (mStack != null && mStack == inStack) {
Wale Ogunwale935e5022015-11-10 12:36:10 -08001882 return;
1883 }
1884
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001885 if (inStack.inFreeformWindowingMode()) {
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001886 if (!isResizeable()) {
Wale Ogunwale935e5022015-11-10 12:36:10 -08001887 throw new IllegalArgumentException("Can not position non-resizeable task="
1888 + this + " in stack=" + inStack);
1889 }
Bryce Leef3c6a472017-11-14 14:53:06 -08001890 if (!matchParentBounds()) {
Wale Ogunwale935e5022015-11-10 12:36:10 -08001891 return;
1892 }
1893 if (mLastNonFullscreenBounds != null) {
1894 updateOverrideConfiguration(mLastNonFullscreenBounds);
1895 } else {
Bryce Leeec55eb02017-12-05 20:51:27 -08001896 mService.mStackSupervisor.getLaunchParamsController().layoutTask(this, null);
Wale Ogunwale935e5022015-11-10 12:36:10 -08001897 }
1898 } else {
Bryce Leef3c6a472017-11-14 14:53:06 -08001899 updateOverrideConfiguration(inStack.getOverrideBounds());
Wale Ogunwale935e5022015-11-10 12:36:10 -08001900 }
1901 }
1902
Wale Ogunwale706ed792015-08-02 10:29:44 -07001903 /** Returns the bounds that should be used to launch this task. */
Wale Ogunwale30e441d2017-11-09 08:28:45 -08001904 Rect getLaunchBounds() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001905 if (mStack == null) {
Chong Zhang7d5f5102016-01-13 10:29:24 -08001906 return null;
1907 }
1908
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001909 final int windowingMode = getWindowingMode();
1910 if (!isActivityTypeStandardOrUndefined()
1911 || windowingMode == WINDOWING_MODE_FULLSCREEN
1912 || (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY && !isResizeable())) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001913 return isResizeable() ? mStack.getOverrideBounds() : null;
Wale Ogunwale3382ab12017-07-27 08:55:03 -07001914 } else if (!getWindowConfiguration().persistTaskBounds()) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001915 return mStack.getOverrideBounds();
Wale Ogunwale706ed792015-08-02 10:29:44 -07001916 }
1917 return mLastNonFullscreenBounds;
1918 }
1919
Jorim Jaggi8b702ed2017-01-20 16:59:03 +01001920 void addStartingWindowsForVisibleActivities(boolean taskSwitch) {
1921 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1922 final ActivityRecord r = mActivities.get(activityNdx);
1923 if (r.visible) {
1924 r.showStartingWindow(null /* prev */, false /* newTask */, taskSwitch);
1925 }
1926 }
1927 }
1928
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001929 void setRootProcess(WindowProcessController proc) {
Dianne Hackborn68a06332017-11-15 17:54:18 -08001930 clearRootProcess();
1931 if (intent != null &&
1932 (intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0) {
1933 mRootProcess = proc;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001934 mRootProcess.addRecentTask(this);
Dianne Hackborn68a06332017-11-15 17:54:18 -08001935 }
1936 }
1937
1938 void clearRootProcess() {
1939 if (mRootProcess != null) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001940 mRootProcess.removeRecentTask(this);
Dianne Hackborn68a06332017-11-15 17:54:18 -08001941 mRootProcess = null;
1942 }
1943 }
1944
chaviw82a0ba82018-03-15 14:26:29 -07001945 void clearAllPendingOptions() {
1946 for (int i = getChildCount() - 1; i >= 0; i--) {
1947 getChildAt(i).clearOptionsLocked(false /* withAbort */);
1948 }
1949 }
1950
Winson Chungabfdcce2018-07-02 17:23:33 -07001951 /**
1952 * Fills in a {@link TaskInfo} with information from this task.
1953 * @param info the {@link TaskInfo} to fill in
1954 * @param reuseActivitiesReport a temporary activities report that we can reuse to fetch the
1955 * running activities
1956 */
1957 void fillTaskInfo(TaskInfo info, TaskActivitiesReport reuseActivitiesReport) {
1958 getNumRunningActivities(reuseActivitiesReport);
1959 info.userId = userId;
1960 info.stackId = getStackId();
1961 info.taskId = taskId;
1962 info.isRunning = getTopActivity() != null;
1963 info.baseIntent = getBaseIntent();
1964 info.baseActivity = reuseActivitiesReport.base != null
1965 ? reuseActivitiesReport.base.intent.getComponent()
1966 : null;
1967 info.topActivity = reuseActivitiesReport.top != null
1968 ? reuseActivitiesReport.top.intent.getComponent()
1969 : null;
1970 info.origActivity = origActivity;
1971 info.realActivity = realActivity;
1972 info.numActivities = reuseActivitiesReport.numActivities;
1973 info.lastActiveTime = lastActiveTime;
1974 info.taskDescription = new ActivityManager.TaskDescription(lastTaskDescription);
1975 info.supportsSplitScreenMultiWindow = supportsSplitScreenWindowingMode();
1976 info.resizeMode = mResizeMode;
1977 info.configuration.setTo(getConfiguration());
1978 }
1979
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001980 void dump(PrintWriter pw, String prefix) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001981 pw.print(prefix); pw.print("userId="); pw.print(userId);
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001982 pw.print(" effectiveUid="); UserHandle.formatUid(pw, effectiveUid);
1983 pw.print(" mCallingUid="); UserHandle.formatUid(pw, mCallingUid);
Suprabh Shukla7745c142016-03-07 18:21:10 -08001984 pw.print(" mUserSetupComplete="); pw.print(mUserSetupComplete);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001985 pw.print(" mCallingPackage="); pw.println(mCallingPackage);
Dianne Hackborn79228822014-09-16 11:11:23 -07001986 if (affinity != null || rootAffinity != null) {
1987 pw.print(prefix); pw.print("affinity="); pw.print(affinity);
1988 if (affinity == null || !affinity.equals(rootAffinity)) {
1989 pw.print(" root="); pw.println(rootAffinity);
1990 } else {
1991 pw.println();
1992 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001993 }
Dianne Hackborn91097de2014-04-04 18:02:06 -07001994 if (voiceSession != null || voiceInteractor != null) {
1995 pw.print(prefix); pw.print("VOICE: session=0x");
1996 pw.print(Integer.toHexString(System.identityHashCode(voiceSession)));
1997 pw.print(" interactor=0x");
1998 pw.println(Integer.toHexString(System.identityHashCode(voiceInteractor)));
1999 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002000 if (intent != null) {
2001 StringBuilder sb = new StringBuilder(128);
2002 sb.append(prefix); sb.append("intent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08002003 intent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002004 sb.append('}');
2005 pw.println(sb.toString());
2006 }
2007 if (affinityIntent != null) {
2008 StringBuilder sb = new StringBuilder(128);
2009 sb.append(prefix); sb.append("affinityIntent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08002010 affinityIntent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002011 sb.append('}');
2012 pw.println(sb.toString());
2013 }
2014 if (origActivity != null) {
2015 pw.print(prefix); pw.print("origActivity=");
2016 pw.println(origActivity.flattenToShortString());
2017 }
2018 if (realActivity != null) {
2019 pw.print(prefix); pw.print("realActivity=");
2020 pw.println(realActivity.flattenToShortString());
2021 }
Wale Ogunwale66e16852017-10-19 13:35:52 -07002022 if (autoRemoveRecents || isPersistable || !isActivityTypeStandard() || numFullscreen != 0) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002023 pw.print(prefix); pw.print("autoRemoveRecents="); pw.print(autoRemoveRecents);
Dianne Hackborn852975d2014-08-22 17:42:43 -07002024 pw.print(" isPersistable="); pw.print(isPersistable);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002025 pw.print(" numFullscreen="); pw.print(numFullscreen);
Wale Ogunwale66e16852017-10-19 13:35:52 -07002026 pw.print(" activityType="); pw.println(getActivityType());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002027 }
Craig Mautner432f64e2015-05-20 14:59:57 -07002028 if (rootWasReset || mNeverRelinquishIdentity || mReuseTask
2029 || mLockTaskAuth != LOCK_TASK_AUTH_PINNABLE) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002030 pw.print(prefix); pw.print("rootWasReset="); pw.print(rootWasReset);
2031 pw.print(" mNeverRelinquishIdentity="); pw.print(mNeverRelinquishIdentity);
Craig Mautner432f64e2015-05-20 14:59:57 -07002032 pw.print(" mReuseTask="); pw.print(mReuseTask);
2033 pw.print(" mLockTaskAuth="); pw.println(lockTaskAuthToString());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002034 }
Wale Ogunwale18795a22014-12-03 11:38:33 -08002035 if (mAffiliatedTaskId != taskId || mPrevAffiliateTaskId != INVALID_TASK_ID
2036 || mPrevAffiliate != null || mNextAffiliateTaskId != INVALID_TASK_ID
2037 || mNextAffiliate != null) {
Dianne Hackborn852975d2014-08-22 17:42:43 -07002038 pw.print(prefix); pw.print("affiliation="); pw.print(mAffiliatedTaskId);
2039 pw.print(" prevAffiliation="); pw.print(mPrevAffiliateTaskId);
2040 pw.print(" (");
2041 if (mPrevAffiliate == null) {
2042 pw.print("null");
2043 } else {
2044 pw.print(Integer.toHexString(System.identityHashCode(mPrevAffiliate)));
2045 }
2046 pw.print(") nextAffiliation="); pw.print(mNextAffiliateTaskId);
2047 pw.print(" (");
2048 if (mNextAffiliate == null) {
2049 pw.print("null");
2050 } else {
2051 pw.print(Integer.toHexString(System.identityHashCode(mNextAffiliate)));
2052 }
2053 pw.println(")");
2054 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002055 pw.print(prefix); pw.print("Activities="); pw.println(mActivities);
Dianne Hackborn852975d2014-08-22 17:42:43 -07002056 if (!askedCompatMode || !inRecents || !isAvailable) {
2057 pw.print(prefix); pw.print("askedCompatMode="); pw.print(askedCompatMode);
2058 pw.print(" inRecents="); pw.print(inRecents);
2059 pw.print(" isAvailable="); pw.println(isAvailable);
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002060 }
Dianne Hackborn852975d2014-08-22 17:42:43 -07002061 if (lastDescription != null) {
2062 pw.print(prefix); pw.print("lastDescription="); pw.println(lastDescription);
2063 }
Dianne Hackborn68a06332017-11-15 17:54:18 -08002064 if (mRootProcess != null) {
2065 pw.print(prefix); pw.print("mRootProcess="); pw.println(mRootProcess);
2066 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07002067 pw.print(prefix); pw.print("stackId="); pw.println(getStackId());
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002068 pw.print(prefix + "hasBeenVisible=" + hasBeenVisible);
2069 pw.print(" mResizeMode=" + ActivityInfo.resizeModeToString(mResizeMode));
Winson Chungd3395382016-12-13 11:49:09 -08002070 pw.print(" mSupportsPictureInPicture=" + mSupportsPictureInPicture);
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002071 pw.print(" isResizeable=" + isResizeable());
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002072 pw.print(" lastActiveTime=" + lastActiveTime);
2073 pw.println(" (inactive for " + (getInactiveDuration() / 1000) + "s)");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002074 }
2075
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002076 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002077 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002078 StringBuilder sb = new StringBuilder(128);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002079 if (stringName != null) {
2080 sb.append(stringName);
2081 sb.append(" U=");
2082 sb.append(userId);
Wale Ogunwale6c5eb1c2015-11-10 07:52:22 -08002083 sb.append(" StackId=");
Andrii Kulian02b7a832016-10-06 23:11:56 -07002084 sb.append(getStackId());
Craig Mautnerde4ef022013-04-07 19:01:33 -07002085 sb.append(" sz=");
2086 sb.append(mActivities.size());
2087 sb.append('}');
2088 return sb.toString();
2089 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002090 sb.append("TaskRecord{");
2091 sb.append(Integer.toHexString(System.identityHashCode(this)));
2092 sb.append(" #");
2093 sb.append(taskId);
2094 if (affinity != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002095 sb.append(" A=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002096 sb.append(affinity);
2097 } else if (intent != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002098 sb.append(" I=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002099 sb.append(intent.getComponent().flattenToShortString());
Bryce Leefbd263b42018-03-07 10:33:55 -08002100 } else if (affinityIntent != null && affinityIntent.getComponent() != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002101 sb.append(" aI=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002102 sb.append(affinityIntent.getComponent().flattenToShortString());
2103 } else {
2104 sb.append(" ??");
2105 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07002106 stringName = sb.toString();
2107 return toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002108 }
Steven Timotius4346f0a2017-09-12 11:07:21 -07002109
2110 public void writeToProto(ProtoOutputStream proto, long fieldId) {
2111 final long token = proto.start(fieldId);
Adrian Roos4921ccf2017-09-28 16:54:06 +02002112 super.writeToProto(proto, CONFIGURATION_CONTAINER, false /* trim */);
Steven Timotius4346f0a2017-09-12 11:07:21 -07002113 proto.write(ID, taskId);
2114 for (int i = mActivities.size() - 1; i >= 0; i--) {
2115 ActivityRecord activity = mActivities.get(i);
2116 activity.writeToProto(proto, ACTIVITIES);
2117 }
2118 proto.write(STACK_ID, mStack.mStackId);
2119 if (mLastNonFullscreenBounds != null) {
2120 mLastNonFullscreenBounds.writeToProto(proto, LAST_NON_FULLSCREEN_BOUNDS);
2121 }
2122 if (realActivity != null) {
2123 proto.write(REAL_ACTIVITY, realActivity.flattenToShortString());
2124 }
2125 if (origActivity != null) {
2126 proto.write(ORIG_ACTIVITY, origActivity.flattenToShortString());
2127 }
2128 proto.write(ACTIVITY_TYPE, getActivityType());
Steven Timotius4346f0a2017-09-12 11:07:21 -07002129 proto.write(RESIZE_MODE, mResizeMode);
Bryce Leef3c6a472017-11-14 14:53:06 -08002130 // TODO: Remove, no longer needed with windowingMode.
2131 proto.write(FULLSCREEN, matchParentBounds());
2132
2133 if (!matchParentBounds()) {
2134 final Rect bounds = getOverrideBounds();
2135 bounds.writeToProto(proto, BOUNDS);
Steven Timotius4346f0a2017-09-12 11:07:21 -07002136 }
2137 proto.write(MIN_WIDTH, mMinWidth);
2138 proto.write(MIN_HEIGHT, mMinHeight);
2139 proto.end(token);
2140 }
Winson Chung61c9e5a2017-10-11 10:39:32 -07002141
2142 /**
2143 * See {@link #getNumRunningActivities(TaskActivitiesReport)}.
2144 */
2145 static class TaskActivitiesReport {
2146 int numRunning;
2147 int numActivities;
2148 ActivityRecord top;
2149 ActivityRecord base;
2150
2151 void reset() {
2152 numRunning = numActivities = 0;
2153 top = base = null;
2154 }
2155 }
Garfield Tan9b1efea2017-12-05 16:43:46 -08002156
2157 /**
2158 * Saves this {@link TaskRecord} to XML using given serializer.
2159 */
2160 void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
2161 if (DEBUG_RECENTS) Slog.i(TAG_RECENTS, "Saving task=" + this);
2162
2163 out.attribute(null, ATTR_TASKID, String.valueOf(taskId));
2164 if (realActivity != null) {
2165 out.attribute(null, ATTR_REALACTIVITY, realActivity.flattenToShortString());
2166 }
2167 out.attribute(null, ATTR_REALACTIVITY_SUSPENDED, String.valueOf(realActivitySuspended));
2168 if (origActivity != null) {
2169 out.attribute(null, ATTR_ORIGACTIVITY, origActivity.flattenToShortString());
2170 }
2171 // Write affinity, and root affinity if it is different from affinity.
2172 // We use the special string "@" for a null root affinity, so we can identify
2173 // later whether we were given a root affinity or should just make it the
2174 // same as the affinity.
2175 if (affinity != null) {
2176 out.attribute(null, ATTR_AFFINITY, affinity);
2177 if (!affinity.equals(rootAffinity)) {
2178 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
2179 }
2180 } else if (rootAffinity != null) {
2181 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
2182 }
2183 out.attribute(null, ATTR_ROOTHASRESET, String.valueOf(rootWasReset));
2184 out.attribute(null, ATTR_AUTOREMOVERECENTS, String.valueOf(autoRemoveRecents));
2185 out.attribute(null, ATTR_ASKEDCOMPATMODE, String.valueOf(askedCompatMode));
2186 out.attribute(null, ATTR_USERID, String.valueOf(userId));
2187 out.attribute(null, ATTR_USER_SETUP_COMPLETE, String.valueOf(mUserSetupComplete));
2188 out.attribute(null, ATTR_EFFECTIVE_UID, String.valueOf(effectiveUid));
2189 out.attribute(null, ATTR_LASTTIMEMOVED, String.valueOf(mLastTimeMoved));
2190 out.attribute(null, ATTR_NEVERRELINQUISH, String.valueOf(mNeverRelinquishIdentity));
2191 if (lastDescription != null) {
2192 out.attribute(null, ATTR_LASTDESCRIPTION, lastDescription.toString());
2193 }
2194 if (lastTaskDescription != null) {
2195 lastTaskDescription.saveToXml(out);
2196 }
2197 out.attribute(null, ATTR_TASK_AFFILIATION_COLOR, String.valueOf(mAffiliatedTaskColor));
2198 out.attribute(null, ATTR_TASK_AFFILIATION, String.valueOf(mAffiliatedTaskId));
2199 out.attribute(null, ATTR_PREV_AFFILIATION, String.valueOf(mPrevAffiliateTaskId));
2200 out.attribute(null, ATTR_NEXT_AFFILIATION, String.valueOf(mNextAffiliateTaskId));
2201 out.attribute(null, ATTR_CALLING_UID, String.valueOf(mCallingUid));
2202 out.attribute(null, ATTR_CALLING_PACKAGE, mCallingPackage == null ? "" : mCallingPackage);
2203 out.attribute(null, ATTR_RESIZE_MODE, String.valueOf(mResizeMode));
2204 out.attribute(null, ATTR_SUPPORTS_PICTURE_IN_PICTURE,
2205 String.valueOf(mSupportsPictureInPicture));
2206 if (mLastNonFullscreenBounds != null) {
2207 out.attribute(
2208 null, ATTR_NON_FULLSCREEN_BOUNDS, mLastNonFullscreenBounds.flattenToString());
2209 }
2210 out.attribute(null, ATTR_MIN_WIDTH, String.valueOf(mMinWidth));
2211 out.attribute(null, ATTR_MIN_HEIGHT, String.valueOf(mMinHeight));
2212 out.attribute(null, ATTR_PERSIST_TASK_VERSION, String.valueOf(PERSIST_TASK_VERSION));
2213
2214 if (affinityIntent != null) {
2215 out.startTag(null, TAG_AFFINITYINTENT);
2216 affinityIntent.saveToXml(out);
2217 out.endTag(null, TAG_AFFINITYINTENT);
2218 }
2219
Bryce Lee1a990e52018-04-23 10:54:11 -07002220 if (intent != null) {
2221 out.startTag(null, TAG_INTENT);
2222 intent.saveToXml(out);
2223 out.endTag(null, TAG_INTENT);
2224 }
Garfield Tan9b1efea2017-12-05 16:43:46 -08002225
2226 final ArrayList<ActivityRecord> activities = mActivities;
2227 final int numActivities = activities.size();
2228 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
2229 final ActivityRecord r = activities.get(activityNdx);
2230 if (r.info.persistableMode == ActivityInfo.PERSIST_ROOT_ONLY || !r.isPersistable() ||
2231 ((r.intent.getFlags() & FLAG_ACTIVITY_NEW_DOCUMENT
2232 | FLAG_ACTIVITY_RETAIN_IN_RECENTS) == FLAG_ACTIVITY_NEW_DOCUMENT) &&
2233 activityNdx > 0) {
2234 // Stop at first non-persistable or first break in task (CLEAR_WHEN_TASK_RESET).
2235 break;
2236 }
2237 out.startTag(null, TAG_ACTIVITY);
2238 r.saveToXml(out);
2239 out.endTag(null, TAG_ACTIVITY);
2240 }
2241 }
2242
2243 @VisibleForTesting
2244 static TaskRecordFactory getTaskRecordFactory() {
2245 if (sTaskRecordFactory == null) {
2246 setTaskRecordFactory(new TaskRecordFactory());
2247 }
2248 return sTaskRecordFactory;
2249 }
2250
2251 static void setTaskRecordFactory(TaskRecordFactory factory) {
2252 sTaskRecordFactory = factory;
2253 }
2254
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002255 static TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002256 Intent intent, IVoiceInteractionSession voiceSession,
2257 IVoiceInteractor voiceInteractor) {
2258 return getTaskRecordFactory().create(
2259 service, taskId, info, intent, voiceSession, voiceInteractor);
2260 }
2261
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002262 static TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002263 Intent intent, TaskDescription taskDescription) {
2264 return getTaskRecordFactory().create(service, taskId, info, intent, taskDescription);
2265 }
2266
2267 static TaskRecord restoreFromXml(XmlPullParser in, ActivityStackSupervisor stackSupervisor)
2268 throws IOException, XmlPullParserException {
2269 return getTaskRecordFactory().restoreFromXml(in, stackSupervisor);
2270 }
2271
2272 /**
2273 * A factory class used to create {@link TaskRecord} or its subclass if any. This can be
2274 * specified when system boots by setting it with
2275 * {@link #setTaskRecordFactory(TaskRecordFactory)}.
2276 */
2277 static class TaskRecordFactory {
2278
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002279 TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002280 Intent intent, IVoiceInteractionSession voiceSession,
2281 IVoiceInteractor voiceInteractor) {
2282 return new TaskRecord(
2283 service, taskId, info, intent, voiceSession, voiceInteractor);
2284 }
2285
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002286 TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002287 Intent intent, TaskDescription taskDescription) {
2288 return new TaskRecord(service, taskId, info, intent, taskDescription);
2289 }
2290
2291 /**
2292 * Should only be used when we're restoring {@link TaskRecord} from storage.
2293 */
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002294 TaskRecord create(ActivityTaskManagerService service, int taskId, Intent intent,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002295 Intent affinityIntent, String affinity, String rootAffinity,
2296 ComponentName realActivity, ComponentName origActivity, boolean rootWasReset,
2297 boolean autoRemoveRecents, boolean askedCompatMode, int userId,
2298 int effectiveUid, String lastDescription, ArrayList<ActivityRecord> activities,
2299 long lastTimeMoved, boolean neverRelinquishIdentity,
2300 TaskDescription lastTaskDescription, int taskAffiliation, int prevTaskId,
2301 int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage,
2302 int resizeMode, boolean supportsPictureInPicture, boolean realActivitySuspended,
2303 boolean userSetupComplete, int minWidth, int minHeight) {
2304 return new TaskRecord(service, taskId, intent, affinityIntent, affinity,
2305 rootAffinity, realActivity, origActivity, rootWasReset, autoRemoveRecents,
2306 askedCompatMode, userId, effectiveUid, lastDescription, activities,
2307 lastTimeMoved, neverRelinquishIdentity, lastTaskDescription, taskAffiliation,
2308 prevTaskId, nextTaskId, taskAffiliationColor, callingUid, callingPackage,
2309 resizeMode, supportsPictureInPicture, realActivitySuspended, userSetupComplete,
2310 minWidth, minHeight);
2311 }
2312
2313 TaskRecord restoreFromXml(XmlPullParser in, ActivityStackSupervisor stackSupervisor)
2314 throws IOException, XmlPullParserException {
2315 Intent intent = null;
2316 Intent affinityIntent = null;
2317 ArrayList<ActivityRecord> activities = new ArrayList<>();
2318 ComponentName realActivity = null;
2319 boolean realActivitySuspended = false;
2320 ComponentName origActivity = null;
2321 String affinity = null;
2322 String rootAffinity = null;
2323 boolean hasRootAffinity = false;
2324 boolean rootHasReset = false;
2325 boolean autoRemoveRecents = false;
2326 boolean askedCompatMode = false;
2327 int taskType = 0;
2328 int userId = 0;
2329 boolean userSetupComplete = true;
2330 int effectiveUid = -1;
2331 String lastDescription = null;
2332 long lastTimeOnTop = 0;
2333 boolean neverRelinquishIdentity = true;
2334 int taskId = INVALID_TASK_ID;
2335 final int outerDepth = in.getDepth();
2336 TaskDescription taskDescription = new TaskDescription();
2337 int taskAffiliation = INVALID_TASK_ID;
2338 int taskAffiliationColor = 0;
2339 int prevTaskId = INVALID_TASK_ID;
2340 int nextTaskId = INVALID_TASK_ID;
2341 int callingUid = -1;
2342 String callingPackage = "";
2343 int resizeMode = RESIZE_MODE_FORCE_RESIZEABLE;
2344 boolean supportsPictureInPicture = false;
Garfield Tan367b35a2017-12-13 12:16:21 -08002345 Rect lastNonFullscreenBounds = null;
Garfield Tan9b1efea2017-12-05 16:43:46 -08002346 int minWidth = INVALID_MIN_SIZE;
2347 int minHeight = INVALID_MIN_SIZE;
2348 int persistTaskVersion = 0;
2349
2350 for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
2351 final String attrName = in.getAttributeName(attrNdx);
2352 final String attrValue = in.getAttributeValue(attrNdx);
2353 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: attribute name=" +
2354 attrName + " value=" + attrValue);
2355 switch (attrName) {
2356 case ATTR_TASKID:
2357 if (taskId == INVALID_TASK_ID) taskId = Integer.parseInt(attrValue);
2358 break;
2359 case ATTR_REALACTIVITY:
2360 realActivity = ComponentName.unflattenFromString(attrValue);
2361 break;
2362 case ATTR_REALACTIVITY_SUSPENDED:
2363 realActivitySuspended = Boolean.valueOf(attrValue);
2364 break;
2365 case ATTR_ORIGACTIVITY:
2366 origActivity = ComponentName.unflattenFromString(attrValue);
2367 break;
2368 case ATTR_AFFINITY:
2369 affinity = attrValue;
2370 break;
2371 case ATTR_ROOT_AFFINITY:
2372 rootAffinity = attrValue;
2373 hasRootAffinity = true;
2374 break;
2375 case ATTR_ROOTHASRESET:
2376 rootHasReset = Boolean.parseBoolean(attrValue);
2377 break;
2378 case ATTR_AUTOREMOVERECENTS:
2379 autoRemoveRecents = Boolean.parseBoolean(attrValue);
2380 break;
2381 case ATTR_ASKEDCOMPATMODE:
2382 askedCompatMode = Boolean.parseBoolean(attrValue);
2383 break;
2384 case ATTR_USERID:
2385 userId = Integer.parseInt(attrValue);
2386 break;
2387 case ATTR_USER_SETUP_COMPLETE:
2388 userSetupComplete = Boolean.parseBoolean(attrValue);
2389 break;
2390 case ATTR_EFFECTIVE_UID:
2391 effectiveUid = Integer.parseInt(attrValue);
2392 break;
2393 case ATTR_TASKTYPE:
2394 taskType = Integer.parseInt(attrValue);
2395 break;
2396 case ATTR_LASTDESCRIPTION:
2397 lastDescription = attrValue;
2398 break;
2399 case ATTR_LASTTIMEMOVED:
2400 lastTimeOnTop = Long.parseLong(attrValue);
2401 break;
2402 case ATTR_NEVERRELINQUISH:
2403 neverRelinquishIdentity = Boolean.parseBoolean(attrValue);
2404 break;
2405 case ATTR_TASK_AFFILIATION:
2406 taskAffiliation = Integer.parseInt(attrValue);
2407 break;
2408 case ATTR_PREV_AFFILIATION:
2409 prevTaskId = Integer.parseInt(attrValue);
2410 break;
2411 case ATTR_NEXT_AFFILIATION:
2412 nextTaskId = Integer.parseInt(attrValue);
2413 break;
2414 case ATTR_TASK_AFFILIATION_COLOR:
2415 taskAffiliationColor = Integer.parseInt(attrValue);
2416 break;
2417 case ATTR_CALLING_UID:
2418 callingUid = Integer.parseInt(attrValue);
2419 break;
2420 case ATTR_CALLING_PACKAGE:
2421 callingPackage = attrValue;
2422 break;
2423 case ATTR_RESIZE_MODE:
2424 resizeMode = Integer.parseInt(attrValue);
2425 break;
2426 case ATTR_SUPPORTS_PICTURE_IN_PICTURE:
2427 supportsPictureInPicture = Boolean.parseBoolean(attrValue);
2428 break;
2429 case ATTR_NON_FULLSCREEN_BOUNDS:
Garfield Tan367b35a2017-12-13 12:16:21 -08002430 lastNonFullscreenBounds = Rect.unflattenFromString(attrValue);
Garfield Tan9b1efea2017-12-05 16:43:46 -08002431 break;
2432 case ATTR_MIN_WIDTH:
2433 minWidth = Integer.parseInt(attrValue);
2434 break;
2435 case ATTR_MIN_HEIGHT:
2436 minHeight = Integer.parseInt(attrValue);
2437 break;
2438 case ATTR_PERSIST_TASK_VERSION:
2439 persistTaskVersion = Integer.parseInt(attrValue);
2440 break;
2441 default:
2442 if (attrName.startsWith(TaskDescription.ATTR_TASKDESCRIPTION_PREFIX)) {
2443 taskDescription.restoreFromXml(attrName, attrValue);
2444 } else {
2445 Slog.w(TAG, "TaskRecord: Unknown attribute=" + attrName);
2446 }
2447 }
2448 }
2449
2450 int event;
2451 while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
2452 (event != XmlPullParser.END_TAG || in.getDepth() >= outerDepth)) {
2453 if (event == XmlPullParser.START_TAG) {
2454 final String name = in.getName();
2455 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG,
2456 "TaskRecord: START_TAG name=" + name);
2457 if (TAG_AFFINITYINTENT.equals(name)) {
2458 affinityIntent = Intent.restoreFromXml(in);
2459 } else if (TAG_INTENT.equals(name)) {
2460 intent = Intent.restoreFromXml(in);
2461 } else if (TAG_ACTIVITY.equals(name)) {
2462 ActivityRecord activity =
2463 ActivityRecord.restoreFromXml(in, stackSupervisor);
2464 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: activity=" +
2465 activity);
2466 if (activity != null) {
2467 activities.add(activity);
2468 }
2469 } else {
Garfield Tan1e740192017-12-12 14:37:42 -08002470 handleUnknownTag(name, in);
Garfield Tan9b1efea2017-12-05 16:43:46 -08002471 }
2472 }
2473 }
2474 if (!hasRootAffinity) {
2475 rootAffinity = affinity;
2476 } else if ("@".equals(rootAffinity)) {
2477 rootAffinity = null;
2478 }
2479 if (effectiveUid <= 0) {
2480 Intent checkIntent = intent != null ? intent : affinityIntent;
2481 effectiveUid = 0;
2482 if (checkIntent != null) {
2483 IPackageManager pm = AppGlobals.getPackageManager();
2484 try {
2485 ApplicationInfo ai = pm.getApplicationInfo(
2486 checkIntent.getComponent().getPackageName(),
2487 PackageManager.MATCH_UNINSTALLED_PACKAGES
2488 | PackageManager.MATCH_DISABLED_COMPONENTS, userId);
2489 if (ai != null) {
2490 effectiveUid = ai.uid;
2491 }
2492 } catch (RemoteException e) {
2493 }
2494 }
2495 Slog.w(TAG, "Updating task #" + taskId + " for " + checkIntent
2496 + ": effectiveUid=" + effectiveUid);
2497 }
2498
2499 if (persistTaskVersion < 1) {
2500 // We need to convert the resize mode of home activities saved before version one if
2501 // they are marked as RESIZE_MODE_RESIZEABLE to
2502 // RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION since we didn't have that differentiation
2503 // before version 1 and the system didn't resize home activities before then.
2504 if (taskType == 1 /* old home type */ && resizeMode == RESIZE_MODE_RESIZEABLE) {
2505 resizeMode = RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
2506 }
2507 } else {
2508 // This activity has previously marked itself explicitly as both resizeable and
2509 // supporting picture-in-picture. Since there is no longer a requirement for
2510 // picture-in-picture activities to be resizeable, we can mark this simply as
2511 // resizeable and supporting picture-in-picture separately.
2512 if (resizeMode == RESIZE_MODE_RESIZEABLE_AND_PIPABLE_DEPRECATED) {
2513 resizeMode = RESIZE_MODE_RESIZEABLE;
2514 supportsPictureInPicture = true;
2515 }
2516 }
2517
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07002518 final TaskRecord task = create(stackSupervisor.mService,
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002519 taskId, intent, affinityIntent,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002520 affinity, rootAffinity, realActivity, origActivity, rootHasReset,
2521 autoRemoveRecents, askedCompatMode, userId, effectiveUid, lastDescription,
2522 activities, lastTimeOnTop, neverRelinquishIdentity, taskDescription,
2523 taskAffiliation, prevTaskId, nextTaskId, taskAffiliationColor, callingUid,
2524 callingPackage, resizeMode, supportsPictureInPicture, realActivitySuspended,
2525 userSetupComplete, minWidth, minHeight);
Garfield Tan367b35a2017-12-13 12:16:21 -08002526 task.mLastNonFullscreenBounds = lastNonFullscreenBounds;
2527 task.setBounds(lastNonFullscreenBounds);
Garfield Tan9b1efea2017-12-05 16:43:46 -08002528
2529 for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {
2530 activities.get(activityNdx).setTask(task);
2531 }
2532
2533 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Restored task=" + task);
2534 return task;
2535 }
Garfield Tan1e740192017-12-12 14:37:42 -08002536
2537 void handleUnknownTag(String name, XmlPullParser in)
2538 throws IOException, XmlPullParserException {
2539 Slog.e(TAG, "restoreTask: Unexpected name=" + name);
2540 XmlUtils.skipCurrentTag(in);
2541 }
Garfield Tan9b1efea2017-12-05 16:43:46 -08002542 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002543}