blob: 3fd4e83b94944602846e09b45fbe9ff30e233676 [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;
Riddle Hsu61987bc2019-04-03 13:08:47 +080025import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070026import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
27import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
28import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
29import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Wale Ogunwale44f036f2017-09-29 05:09:09 -070030import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Evan Rosky1ac84462018-11-13 11:25:30 -080031import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Jorim Jaggi0a932142016-02-01 17:42:25 -080032import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
Wale Ogunwale66e16852017-10-19 13:35:52 -070033import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
Jorim Jaggi0a932142016-02-01 17:42:25 -080034import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
Wale Ogunwale66e16852017-10-19 13:35:52 -070035import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
Wale Ogunwale3eadad72016-10-13 09:16:59 -070036import static android.content.pm.ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY;
Jorim Jaggi0a932142016-02-01 17:42:25 -080037import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
38import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
39import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
40import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER;
skuhne@google.com322347b2016-12-02 12:54:03 -080041import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY;
42import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PORTRAIT_ONLY;
43import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PRESERVE_ORIENTATION;
Wale Ogunwaled829d362016-02-10 19:24:49 -080044import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
Wale Ogunwale625ed0c2016-10-18 08:50:31 -070045import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
Winson Chungd3395382016-12-13 11:49:09 -080046import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_AND_PIPABLE_DEPRECATED;
Wale Ogunwale625ed0c2016-10-18 08:50:31 -070047import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
Evan Rosky730f6e82018-12-03 17:40:11 -080048import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
49import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
50import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -080051import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
Suprabh Shukla7745c142016-03-07 18:21:10 -080052import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
Andrii Kulian036e3ad2017-04-19 10:55:10 -070053import static android.view.Display.DEFAULT_DISPLAY;
Garfield Tan891146c2018-10-09 12:14:00 -070054
Yunfan Chen0e7aff92018-12-05 16:35:32 -080055import static com.android.server.EventLogTags.WM_TASK_CREATED;
Yi Jin6c6e9ca2018-03-20 16:53:35 -070056import static com.android.server.am.TaskRecordProto.ACTIVITIES;
Andrii Kulianab132ee2018-07-24 22:10:21 +080057import static com.android.server.am.TaskRecordProto.ACTIVITY_TYPE;
Yi Jin6c6e9ca2018-03-20 16:53:35 -070058import static com.android.server.am.TaskRecordProto.BOUNDS;
59import static com.android.server.am.TaskRecordProto.CONFIGURATION_CONTAINER;
60import static com.android.server.am.TaskRecordProto.FULLSCREEN;
61import static com.android.server.am.TaskRecordProto.ID;
62import static com.android.server.am.TaskRecordProto.LAST_NON_FULLSCREEN_BOUNDS;
63import static com.android.server.am.TaskRecordProto.MIN_HEIGHT;
64import static com.android.server.am.TaskRecordProto.MIN_WIDTH;
65import static com.android.server.am.TaskRecordProto.ORIG_ACTIVITY;
66import static com.android.server.am.TaskRecordProto.REAL_ACTIVITY;
67import static com.android.server.am.TaskRecordProto.RESIZE_MODE;
68import static com.android.server.am.TaskRecordProto.STACK_ID;
Garfield Tan891146c2018-10-09 12:14:00 -070069import static com.android.server.wm.ActivityRecord.STARTING_WINDOW_SHOWN;
70import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_MOVING;
71import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_MOVING_TO_TOP;
72import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
73import static com.android.server.wm.ActivityStackSupervisor.PAUSE_IMMEDIATELY;
74import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
75import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ADD_REMOVE;
76import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_LOCKTASK;
77import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
78import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
79import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_ADD_REMOVE;
80import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_LOCKTASK;
81import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS;
82import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS;
83import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
84import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
Yunfan Chen0e7aff92018-12-05 16:35:32 -080085import static com.android.server.wm.WindowContainer.POSITION_BOTTOM;
86import static com.android.server.wm.WindowContainer.POSITION_TOP;
87import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
88import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Garfield Tan891146c2018-10-09 12:14:00 -070089
Winson Chung74666102017-02-22 17:49:24 -080090import static java.lang.Integer.MAX_VALUE;
91
Jorim Jaggie7d2b852017-08-28 17:55:15 +020092import android.annotation.IntDef;
Evan Rosky1ac84462018-11-13 11:25:30 -080093import android.annotation.NonNull;
Jorim Jaggie7d2b852017-08-28 17:55:15 +020094import android.annotation.Nullable;
95import android.app.Activity;
96import android.app.ActivityManager;
Jorim Jaggie7d2b852017-08-28 17:55:15 +020097import android.app.ActivityManager.TaskDescription;
98import android.app.ActivityManager.TaskSnapshot;
99import android.app.ActivityOptions;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700100import android.app.ActivityTaskManager;
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200101import android.app.AppGlobals;
Winson Chungabfdcce2018-07-02 17:23:33 -0700102import android.app.TaskInfo;
Garfield Tan891146c2018-10-09 12:14:00 -0700103import android.app.WindowConfiguration;
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200104import android.content.ComponentName;
105import android.content.Intent;
106import android.content.pm.ActivityInfo;
107import android.content.pm.ApplicationInfo;
108import android.content.pm.IPackageManager;
109import android.content.pm.PackageManager;
110import android.content.res.Configuration;
111import android.graphics.Rect;
112import android.os.Debug;
113import android.os.RemoteException;
Winson Chungfb44d212017-10-04 11:39:10 -0700114import android.os.SystemClock;
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200115import android.os.Trace;
116import android.os.UserHandle;
117import android.provider.Settings;
118import android.service.voice.IVoiceInteractionSession;
119import android.util.DisplayMetrics;
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800120import android.util.EventLog;
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200121import android.util.Slog;
Steven Timotius4346f0a2017-09-12 11:07:21 -0700122import android.util.proto.ProtoOutputStream;
Mark Renoufb1abb552019-02-08 13:51:41 -0500123import android.view.Display;
Evan Rosky1ac84462018-11-13 11:25:30 -0800124import android.view.DisplayInfo;
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200125
126import com.android.internal.annotations.VisibleForTesting;
127import com.android.internal.app.IVoiceInteractor;
128import com.android.internal.util.XmlUtils;
Wale Ogunwale59507092018-10-29 09:00:30 -0700129import com.android.server.wm.ActivityStack.ActivityState;
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200130
131import org.xmlpull.v1.XmlPullParser;
132import org.xmlpull.v1.XmlPullParserException;
133import org.xmlpull.v1.XmlSerializer;
134
135import java.io.IOException;
136import java.io.PrintWriter;
137import java.lang.annotation.Retention;
138import java.lang.annotation.RetentionPolicy;
139import java.util.ArrayList;
140import java.util.Objects;
141
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800142class TaskRecord extends ConfigurationContainer {
Wale Ogunwale98875612018-10-12 07:53:02 -0700143 private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskRecord" : TAG_ATM;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -0700144 private static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700145 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
Craig Mautnere0570202015-05-13 13:06:11 -0700146 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700147 private static final String TAG_TASKS = TAG + POSTFIX_TASKS;
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800148
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700149 private static final String ATTR_TASKID = "task_id";
Craig Mautner21d24a22014-04-23 11:45:37 -0700150 private static final String TAG_INTENT = "intent";
151 private static final String TAG_AFFINITYINTENT = "affinity_intent";
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700152 private static final String ATTR_REALACTIVITY = "real_activity";
153 private static final String ATTR_REALACTIVITY_SUSPENDED = "real_activity_suspended";
Craig Mautner21d24a22014-04-23 11:45:37 -0700154 private static final String ATTR_ORIGACTIVITY = "orig_activity";
Stefan Kuhnee88d1e52015-05-18 10:33:45 -0700155 private static final String TAG_ACTIVITY = "activity";
Craig Mautner21d24a22014-04-23 11:45:37 -0700156 private static final String ATTR_AFFINITY = "affinity";
Dianne Hackborn79228822014-09-16 11:11:23 -0700157 private static final String ATTR_ROOT_AFFINITY = "root_affinity";
Craig Mautner21d24a22014-04-23 11:45:37 -0700158 private static final String ATTR_ROOTHASRESET = "root_has_reset";
Dianne Hackborn13420f22014-07-18 15:43:56 -0700159 private static final String ATTR_AUTOREMOVERECENTS = "auto_remove_recents";
Craig Mautner21d24a22014-04-23 11:45:37 -0700160 private static final String ATTR_ASKEDCOMPATMODE = "asked_compat_mode";
161 private static final String ATTR_USERID = "user_id";
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800162 private static final String ATTR_USER_SETUP_COMPLETE = "user_setup_complete";
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700163 private static final String ATTR_EFFECTIVE_UID = "effective_uid";
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700164 @Deprecated
Craig Mautner21d24a22014-04-23 11:45:37 -0700165 private static final String ATTR_TASKTYPE = "task_type";
Craig Mautner21d24a22014-04-23 11:45:37 -0700166 private static final String ATTR_LASTDESCRIPTION = "last_description";
167 private static final String ATTR_LASTTIMEMOVED = "last_time_moved";
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700168 private static final String ATTR_NEVERRELINQUISH = "never_relinquish_identity";
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700169 private static final String ATTR_TASK_AFFILIATION = "task_affiliation";
Craig Mautnera228ae92014-07-09 05:44:55 -0700170 private static final String ATTR_PREV_AFFILIATION = "prev_affiliation";
171 private static final String ATTR_NEXT_AFFILIATION = "next_affiliation";
Winson Chungec396d62014-08-06 17:08:00 -0700172 private static final String ATTR_TASK_AFFILIATION_COLOR = "task_affiliation_color";
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700173 private static final String ATTR_CALLING_UID = "calling_uid";
174 private static final String ATTR_CALLING_PACKAGE = "calling_package";
Winson Chungd3395382016-12-13 11:49:09 -0800175 private static final String ATTR_SUPPORTS_PICTURE_IN_PICTURE = "supports_picture_in_picture";
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800176 private static final String ATTR_RESIZE_MODE = "resize_mode";
Wale Ogunwale706ed792015-08-02 10:29:44 -0700177 private static final String ATTR_NON_FULLSCREEN_BOUNDS = "non_fullscreen_bounds";
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700178 private static final String ATTR_MIN_WIDTH = "min_width";
179 private static final String ATTR_MIN_HEIGHT = "min_height";
Wale Ogunwale625ed0c2016-10-18 08:50:31 -0700180 private static final String ATTR_PERSIST_TASK_VERSION = "persist_task_version";
Andrii Kulian18d75122016-03-27 20:20:28 -0700181
Wale Ogunwale625ed0c2016-10-18 08:50:31 -0700182 // Current version of the task record we persist. Used to check if we need to run any upgrade
183 // code.
184 private static final int PERSIST_TASK_VERSION = 1;
Craig Mautner21d24a22014-04-23 11:45:37 -0700185
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700186 private static final int INVALID_MIN_SIZE = -1;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800187
Winson Chung74666102017-02-22 17:49:24 -0800188 /**
189 * The modes to control how the stack is moved to the front when calling
190 * {@link TaskRecord#reparent}.
191 */
192 @Retention(RetentionPolicy.SOURCE)
193 @IntDef({
194 REPARENT_MOVE_STACK_TO_FRONT,
195 REPARENT_KEEP_STACK_AT_FRONT,
196 REPARENT_LEAVE_STACK_IN_PLACE
197 })
Wale Ogunwale66e16852017-10-19 13:35:52 -0700198 @interface ReparentMoveStackMode {}
Winson Chung74666102017-02-22 17:49:24 -0800199 // Moves the stack to the front if it was not at the front
Wale Ogunwale66e16852017-10-19 13:35:52 -0700200 static final int REPARENT_MOVE_STACK_TO_FRONT = 0;
Winson Chung74666102017-02-22 17:49:24 -0800201 // Only moves the stack to the front if it was focused or front most already
Wale Ogunwale66e16852017-10-19 13:35:52 -0700202 static final int REPARENT_KEEP_STACK_AT_FRONT = 1;
Winson Chung74666102017-02-22 17:49:24 -0800203 // Do not move the stack as a part of reparenting
Wale Ogunwale66e16852017-10-19 13:35:52 -0700204 static final int REPARENT_LEAVE_STACK_IN_PLACE = 2;
Winson Chung74666102017-02-22 17:49:24 -0800205
Garfield Tan9b1efea2017-12-05 16:43:46 -0800206 /**
207 * The factory used to create {@link TaskRecord}. This allows OEM subclass {@link TaskRecord}.
208 */
209 private static TaskRecordFactory sTaskRecordFactory;
210
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800211 final int taskId; // Unique identifier for this task.
Dianne Hackborn79228822014-09-16 11:11:23 -0700212 String affinity; // The affinity name for this task, or null; may change identity.
213 String rootAffinity; // Initial base affinity, or null; does not change from initial root.
Dianne Hackborn91097de2014-04-04 18:02:06 -0700214 final IVoiceInteractionSession voiceSession; // Voice interaction session driving task
215 final IVoiceInteractor voiceInteractor; // Associated interactor to provide to app
Bryce Lee1a990e52018-04-23 10:54:11 -0700216 Intent intent; // The original intent that started the task. Note that this value can
217 // be null.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800218 Intent affinityIntent; // Intent of affinity-moved activity that started this task.
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700219 int effectiveUid; // The current effective uid of the identity of this task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800220 ComponentName origActivity; // The non-alias activity component of the intent.
221 ComponentName realActivity; // The actual activity component that started the task.
Andrei Stingaceanu4ccec532016-01-13 12:10:21 +0000222 boolean realActivitySuspended; // True if the actual activity component that started the
223 // task is suspended.
Dianne Hackborn852975d2014-08-22 17:42:43 -0700224 boolean inRecents; // Actually in the recents list?
Winson Chungfb44d212017-10-04 11:39:10 -0700225 long lastActiveTime; // Last time this task was active in the current device session,
226 // including sleep. This time is initialized to the elapsed time when
227 // restored from disk.
Dianne Hackborn852975d2014-08-22 17:42:43 -0700228 boolean isAvailable; // Is the activity available to be launched?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800229 boolean rootWasReset; // True if the intent at the root of the task had
230 // the FLAG_ACTIVITY_RESET_TASK_IF_NEEDED flag.
Dianne Hackborn13420f22014-07-18 15:43:56 -0700231 boolean autoRemoveRecents; // If true, we should automatically remove the task from
232 // recents when activity finishes
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700233 boolean askedCompatMode;// Have asked the user about compat mode for this task.
Dianne Hackbornd38aed82014-06-10 21:36:35 -0700234 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 -0800235
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700236 String stringName; // caching of toString() result.
Dianne Hackborn9da2d402012-03-15 13:43:08 -0700237 int userId; // user for which this task was created
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800238 boolean mUserSetupComplete; // The user set-up is complete as of the last time the task activity
239 // was changed.
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800240
241 int numFullscreen; // Number of fullscreen activities.
242
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800243 int mResizeMode; // The resize mode of this task and its activities.
244 // Based on the {@link ActivityInfo#resizeMode} of the root activity.
Wale Ogunwale069bbd32017-02-03 07:58:14 -0800245 private boolean mSupportsPictureInPicture; // Whether or not this task and its activities
246 // support PiP. Based on the {@link ActivityInfo#FLAG_SUPPORTS_PICTURE_IN_PICTURE} flag
247 // of the root activity.
Craig Mautner15df08a2015-04-01 12:17:18 -0700248 /** Can't be put in lockTask mode. */
249 final static int LOCK_TASK_AUTH_DONT_LOCK = 0;
Benjamin Franz469dd582015-06-09 14:24:36 +0100250 /** Can enter app pinning with user approval. Can never start over existing lockTask task. */
Craig Mautner15df08a2015-04-01 12:17:18 -0700251 final static int LOCK_TASK_AUTH_PINNABLE = 1;
252 /** Starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing lockTask task. */
253 final static int LOCK_TASK_AUTH_LAUNCHABLE = 2;
Benjamin Franz469dd582015-06-09 14:24:36 +0100254 /** Can enter lockTask without user approval. Can start over existing lockTask task. */
Craig Mautner15df08a2015-04-01 12:17:18 -0700255 final static int LOCK_TASK_AUTH_WHITELISTED = 3;
Benjamin Franz469dd582015-06-09 14:24:36 +0100256 /** Priv-app that starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing
257 * lockTask task. */
258 final static int LOCK_TASK_AUTH_LAUNCHABLE_PRIV = 4;
Craig Mautner15df08a2015-04-01 12:17:18 -0700259 int mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE;
260
261 int mLockTaskUid = -1; // The uid of the application that called startLockTask().
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800262
Winson Chung03a9bae2014-05-02 09:56:12 -0700263 // This represents the last resolved activity values for this task
264 // NOTE: This value needs to be persisted with each task
Craig Mautner648f69b2014-09-18 14:16:26 -0700265 TaskDescription lastTaskDescription = new TaskDescription();
Winson Chung03a9bae2014-05-02 09:56:12 -0700266
Craig Mautnerd2328952013-03-05 12:46:26 -0800267 /** List of all activities in the task arranged in history order */
Craig Mautner21d24a22014-04-23 11:45:37 -0700268 final ArrayList<ActivityRecord> mActivities;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800269
Andrii Kulian02b7a832016-10-06 23:11:56 -0700270 /** Current stack. Setter must always be used to update the value. */
271 private ActivityStack mStack;
Craig Mautnerd2328952013-03-05 12:46:26 -0800272
Dianne Hackborn68a06332017-11-15 17:54:18 -0800273 /** The process that had previously hosted the root activity of this task.
274 * Used to know that we should try harder to keep this process around, in case the
275 * user wants to return to it. */
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700276 private WindowProcessController mRootProcess;
Dianne Hackborn68a06332017-11-15 17:54:18 -0800277
Craig Mautner21d24a22014-04-23 11:45:37 -0700278 /** Takes on same value as first root activity */
279 boolean isPersistable = false;
Craig Mautnerffcfcaa2014-06-05 09:54:38 -0700280 int maxRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700281
282 /** Only used for persistable tasks, otherwise 0. The last time this task was moved. Used for
283 * determining the order when restoring. Sign indicates whether last task movement was to front
284 * (positive) or back (negative). Absolute value indicates time. */
285 long mLastTimeMoved = System.currentTimeMillis();
286
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700287 /** If original intent did not allow relinquishing task identity, save that information */
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700288 private boolean mNeverRelinquishIdentity = true;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700289
Craig Mautner362449a2014-06-20 14:04:39 -0700290 // Used in the unique case where we are clearing the task in order to reuse it. In that case we
291 // do not want to delete the stack when the task goes empty.
Filip Gruszczynskibe9dabd2016-01-19 12:23:10 -0800292 private boolean mReuseTask = false;
Craig Mautner362449a2014-06-20 14:04:39 -0700293
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700294 CharSequence lastDescription; // Last description captured for this item.
295
Craig Mautnera228ae92014-07-09 05:44:55 -0700296 int mAffiliatedTaskId; // taskId of parent affiliation or self if no parent.
Winson Chungec396d62014-08-06 17:08:00 -0700297 int mAffiliatedTaskColor; // color of the parent task affiliation.
Craig Mautnera228ae92014-07-09 05:44:55 -0700298 TaskRecord mPrevAffiliate; // previous task in affiliated chain.
Wale Ogunwale18795a22014-12-03 11:38:33 -0800299 int mPrevAffiliateTaskId = INVALID_TASK_ID; // previous id for persistence.
Craig Mautnera228ae92014-07-09 05:44:55 -0700300 TaskRecord mNextAffiliate; // next task in affiliated chain.
Wale Ogunwale18795a22014-12-03 11:38:33 -0800301 int mNextAffiliateTaskId = INVALID_TASK_ID; // next id for persistence.
Craig Mautnera228ae92014-07-09 05:44:55 -0700302
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700303 // For relaunching the task from recents as though it was launched by the original launcher.
304 int mCallingUid;
305 String mCallingPackage;
306
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700307 final ActivityTaskManagerService mService;
Craig Mautner21d24a22014-04-23 11:45:37 -0700308
Jorim Jaggi82c9dc92016-02-05 15:10:33 -0800309 private final Rect mTmpStableBounds = new Rect();
310 private final Rect mTmpNonDecorBounds = new Rect();
Evan Rosky1ac84462018-11-13 11:25:30 -0800311 private final Rect mTmpBounds = new Rect();
312 private final Rect mTmpInsets = new Rect();
Jorim Jaggi0a932142016-02-01 17:42:25 -0800313
Wale Ogunwale706ed792015-08-02 10:29:44 -0700314 // Last non-fullscreen bounds the task was launched in or resized to.
315 // The information is persisted and used to determine the appropriate stack to launch the
316 // task into on restore.
317 Rect mLastNonFullscreenBounds = null;
Andrii Kulian2e751b82016-03-16 16:59:32 -0700318 // Minimal width and height of this task when it's resizeable. -1 means it should use the
319 // default minimal width/height.
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700320 int mMinWidth;
321 int mMinHeight;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700322
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700323 // Ranking (from top) of this task among all visible tasks. (-1 means it's not visible)
324 // This number will be assigned when we evaluate OOM scores for all visible tasks.
325 int mLayerRank = -1;
326
Evan Roskyed6767f2018-10-26 17:21:06 -0700327 // When non-empty, this represents the bounds this task will be drawn at. This gets set during
328 // transient operations such as split-divider dragging and animations.
329 // TODO(b/119687367): This member is temporary.
330 final Rect mDisplayedBounds = new Rect();
331
Andrii Kulian1779e612016-10-12 21:58:25 -0700332 /** Helper object used for updating override configuration. */
333 private Configuration mTmpConfig = new Configuration();
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700334
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800335 // TODO: remove after unification
336 Task mTask;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800337
Mark Renoufc808f062019-02-07 15:20:37 -0500338 /** Used by fillTaskInfo */
339 final TaskActivitiesReport mReuseActivitiesReport = new TaskActivitiesReport();
340
Garfield Tan9b1efea2017-12-05 16:43:46 -0800341 /**
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700342 * Don't use constructor directly. Use {@link #create(ActivityTaskManagerService, int,
343 * ActivityInfo, Intent, TaskDescription)} instead.
Garfield Tan9b1efea2017-12-05 16:43:46 -0800344 */
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700345 TaskRecord(ActivityTaskManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700346 IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700347 mService = service;
Suprabh Shukla23593142015-11-03 17:31:15 -0800348 userId = UserHandle.getUserId(info.applicationInfo.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800349 taskId = _taskId;
Winson Chungfb44d212017-10-04 11:39:10 -0700350 lastActiveTime = SystemClock.elapsedRealtime();
Craig Mautnera228ae92014-07-09 05:44:55 -0700351 mAffiliatedTaskId = _taskId;
Dianne Hackborn91097de2014-04-04 18:02:06 -0700352 voiceSession = _voiceSession;
353 voiceInteractor = _voiceInteractor;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700354 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800355 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700356 mCallingUid = info.applicationInfo.uid;
357 mCallingPackage = info.packageName;
Martijn Coenend4a69702014-06-30 11:12:17 -0700358 setIntent(_intent, info);
Andrii Kulian2e751b82016-03-16 16:59:32 -0700359 setMinDimensions(info);
Winson730bf062016-03-31 18:04:56 -0700360 touchActiveTime();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700361 mService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
Craig Mautner21d24a22014-04-23 11:45:37 -0700362 }
363
Garfield Tan9b1efea2017-12-05 16:43:46 -0800364 /**
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700365 * Don't use constructor directly.
366 * Use {@link #create(ActivityTaskManagerService, int, ActivityInfo,
Garfield Tan9b1efea2017-12-05 16:43:46 -0800367 * Intent, IVoiceInteractionSession, IVoiceInteractor)} instead.
368 */
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700369 TaskRecord(ActivityTaskManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200370 TaskDescription _taskDescription) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700371 mService = service;
Suprabh Shukla23593142015-11-03 17:31:15 -0800372 userId = UserHandle.getUserId(info.applicationInfo.uid);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700373 taskId = _taskId;
Winson Chungfb44d212017-10-04 11:39:10 -0700374 lastActiveTime = SystemClock.elapsedRealtime();
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700375 mAffiliatedTaskId = _taskId;
376 voiceSession = null;
377 voiceInteractor = null;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700378 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800379 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700380 mCallingUid = info.applicationInfo.uid;
381 mCallingPackage = info.packageName;
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700382 setIntent(_intent, info);
Andrii Kulian2e751b82016-03-16 16:59:32 -0700383 setMinDimensions(info);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700384
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700385 isPersistable = true;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700386 // Clamp to [1, max].
387 maxRecents = Math.min(Math.max(info.maxRecents, 1),
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700388 ActivityTaskManager.getMaxAppRecentsLimitStatic());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700389
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700390 lastTaskDescription = _taskDescription;
Winson730bf062016-03-31 18:04:56 -0700391 touchActiveTime();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700392 mService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700393 }
394
Garfield Tan9b1efea2017-12-05 16:43:46 -0800395 /**
396 * Don't use constructor directly. This is only used by XML parser.
397 */
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700398 TaskRecord(ActivityTaskManagerService service, int _taskId, Intent _intent,
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800399 Intent _affinityIntent, String _affinity, String _rootAffinity,
400 ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700401 boolean _autoRemoveRecents, boolean _askedCompatMode, int _userId,
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800402 int _effectiveUid, String _lastDescription, ArrayList<ActivityRecord> activities,
Winson Chungfb44d212017-10-04 11:39:10 -0700403 long lastTimeMoved, boolean neverRelinquishIdentity,
404 TaskDescription _lastTaskDescription, int taskAffiliation, int prevTaskId,
405 int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage,
Charles He2bf28322017-10-12 22:24:49 +0100406 int resizeMode, boolean supportsPictureInPicture, boolean _realActivitySuspended,
407 boolean userSetupComplete, int minWidth, int minHeight) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700408 mService = service;
409 taskId = _taskId;
410 intent = _intent;
411 affinityIntent = _affinityIntent;
412 affinity = _affinity;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800413 rootAffinity = _rootAffinity;
Craig Mautner21d24a22014-04-23 11:45:37 -0700414 voiceSession = null;
415 voiceInteractor = null;
416 realActivity = _realActivity;
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800417 realActivitySuspended = _realActivitySuspended;
Craig Mautner21d24a22014-04-23 11:45:37 -0700418 origActivity = _origActivity;
419 rootWasReset = _rootWasReset;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700420 isAvailable = true;
Dianne Hackborn13420f22014-07-18 15:43:56 -0700421 autoRemoveRecents = _autoRemoveRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700422 askedCompatMode = _askedCompatMode;
Craig Mautner21d24a22014-04-23 11:45:37 -0700423 userId = _userId;
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800424 mUserSetupComplete = userSetupComplete;
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700425 effectiveUid = _effectiveUid;
Winson Chungfb44d212017-10-04 11:39:10 -0700426 lastActiveTime = SystemClock.elapsedRealtime();
Craig Mautner21d24a22014-04-23 11:45:37 -0700427 lastDescription = _lastDescription;
428 mActivities = activities;
429 mLastTimeMoved = lastTimeMoved;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700430 mNeverRelinquishIdentity = neverRelinquishIdentity;
Winson Chung2cb86c72014-06-25 12:03:30 -0700431 lastTaskDescription = _lastTaskDescription;
Craig Mautnera228ae92014-07-09 05:44:55 -0700432 mAffiliatedTaskId = taskAffiliation;
Winson Chungec396d62014-08-06 17:08:00 -0700433 mAffiliatedTaskColor = taskAffiliationColor;
Craig Mautnera228ae92014-07-09 05:44:55 -0700434 mPrevAffiliateTaskId = prevTaskId;
435 mNextAffiliateTaskId = nextTaskId;
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700436 mCallingUid = callingUid;
437 mCallingPackage = callingPackage;
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800438 mResizeMode = resizeMode;
Winson Chungd3395382016-12-13 11:49:09 -0800439 mSupportsPictureInPicture = supportsPictureInPicture;
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700440 mMinWidth = minWidth;
441 mMinHeight = minHeight;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700442 mService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800443 }
444
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800445 Task getTask() {
446 return mTask;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800447 }
448
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800449 void createTask(boolean onTop, boolean showForAllUsers) {
450 if (mTask != null) {
451 throw new IllegalArgumentException("mTask=" + mTask
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800452 + " already created for task=" + this);
453 }
454
455 final Rect bounds = updateOverrideConfigurationFromLaunchBounds();
Yunfan Chen279f5582018-12-12 15:24:50 -0800456 final TaskStack stack = getStack().getTaskStack();
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800457
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800458 if (stack == null) {
Yunfan Chen279f5582018-12-12 15:24:50 -0800459 throw new IllegalArgumentException("TaskRecord: invalid stack=" + mStack);
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800460 }
461 EventLog.writeEvent(WM_TASK_CREATED, taskId, stack.mStackId);
462 mTask = new Task(taskId, stack, userId, mService.mWindowManager, mResizeMode,
463 mSupportsPictureInPicture, lastTaskDescription, this);
464 final int position = onTop ? POSITION_TOP : POSITION_BOTTOM;
465
466 if (!mDisplayedBounds.isEmpty()) {
467 mTask.setOverrideDisplayedBounds(mDisplayedBounds);
468 }
469 // We only want to move the parents to the parents if we are creating this task at the
470 // top of its stack.
471 stack.addTask(mTask, position, showForAllUsers, onTop /* moveParents */);
Bryce Lee04ab3462017-04-10 15:06:33 -0700472 }
473
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800474 void setTask(Task task) {
475 mTask = task;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800476 }
477
Garfield Tan347bd602018-12-21 15:11:12 -0800478 void cleanUpResourcesForDestroy() {
479 if (!mActivities.isEmpty()) {
480 return;
481 }
482
483 // This task is going away, so save the last state if necessary.
484 saveLaunchingStateIfNeeded();
485
486 // TODO: VI what about activity?
487 final boolean isVoiceSession = voiceSession != null;
488 if (isVoiceSession) {
489 try {
490 voiceSession.taskFinished(intent, taskId);
491 } catch (RemoteException e) {
492 }
493 }
494 if (autoRemoveFromRecents() || isVoiceSession) {
495 // Task creator asked to remove this when done, or this task was a voice
496 // interaction, so it should not remain on the recent tasks list.
497 mService.mStackSupervisor.mRecentTasks.remove(this);
498 }
499
500 removeWindowContainer();
501 }
502
503 @VisibleForTesting
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800504 void removeWindowContainer() {
Bryce Lee2b8e0372018-04-05 17:01:37 -0700505 mService.getLockTaskController().clearLockedTask(this);
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800506 if (mTask == null) {
507 if (DEBUG_STACK) Slog.i(TAG_WM, "removeTask: could not find taskId=" + taskId);
508 return;
509 }
510 mTask.removeIfPossible();
511 mTask = null;
Wale Ogunwale3382ab12017-07-27 08:55:03 -0700512 if (!getWindowConfiguration().persistTaskBounds()) {
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800513 // Reset current bounds for task whose bounds shouldn't be persisted so it uses
514 // default configuration the next time it launches.
515 updateOverrideConfiguration(null);
516 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700517 mService.getTaskChangeNotificationController().notifyTaskRemoved(taskId);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800518 }
519
Jorim Jaggifb9d78a2017-01-05 18:57:12 +0100520 public void onSnapshotChanged(TaskSnapshot snapshot) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700521 mService.getTaskChangeNotificationController().notifyTaskSnapshotChanged(taskId, snapshot);
Jorim Jaggifb9d78a2017-01-05 18:57:12 +0100522 }
523
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800524 void setResizeMode(int resizeMode) {
525 if (mResizeMode == resizeMode) {
526 return;
527 }
528 mResizeMode = resizeMode;
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800529 mTask.setResizeable(resizeMode);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800530 mService.mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
531 mService.mRootActivityContainer.resumeFocusedStacksTopActivities();
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800532 }
533
534 void setTaskDockedResizing(boolean resizing) {
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800535 if (mTask == null) {
536 Slog.w(TAG_WM, "setTaskDockedResizing: taskId " + taskId + " not found.");
537 return;
538 }
539 mTask.setTaskDockedResizing(resizing);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800540 }
541
Wale Ogunwale1666e312016-12-16 11:27:18 -0800542 // TODO: Consolidate this with the resize() method below.
Wale Ogunwale1666e312016-12-16 11:27:18 -0800543 public void requestResize(Rect bounds, int resizeMode) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700544 mService.resizeTask(taskId, bounds, resizeMode);
Wale Ogunwale1666e312016-12-16 11:27:18 -0800545 }
546
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800547 boolean resize(Rect bounds, int resizeMode, boolean preserveWindow, boolean deferResume) {
Bryce Leef3c6a472017-11-14 14:53:06 -0800548 mService.mWindowManager.deferSurfaceLayout();
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800549
Bryce Leef3c6a472017-11-14 14:53:06 -0800550 try {
551 if (!isResizeable()) {
552 Slog.w(TAG, "resizeTask: task " + this + " not resizeable.");
553 return true;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800554 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800555
Bryce Leef3c6a472017-11-14 14:53:06 -0800556 // If this is a forced resize, let it go through even if the bounds is not changing,
557 // as we might need a relayout due to surface size change (to/from fullscreen).
558 final boolean forced = (resizeMode & RESIZE_MODE_FORCED) != 0;
Evan Roskydfe3da72018-10-26 17:21:06 -0700559 if (equivalentRequestedOverrideBounds(bounds) && !forced) {
Bryce Leef3c6a472017-11-14 14:53:06 -0800560 // Nothing to do here...
561 return true;
562 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800563
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800564 if (mTask == null) {
Bryce Leef3c6a472017-11-14 14:53:06 -0800565 // Task doesn't exist in window manager yet (e.g. was restored from recents).
566 // All we can do for now is update the bounds so it can be used when the task is
567 // added to window manager.
568 updateOverrideConfiguration(bounds);
569 if (!inFreeformWindowingMode()) {
570 // re-restore the task so it can have the proper stack association.
571 mService.mStackSupervisor.restoreRecentTaskLocked(this, null, !ON_TOP);
572 }
573 return true;
574 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800575
Bryce Leef3c6a472017-11-14 14:53:06 -0800576 if (!canResizeToBounds(bounds)) {
577 throw new IllegalArgumentException("resizeTask: Can not resize task=" + this
578 + " to bounds=" + bounds + " resizeMode=" + mResizeMode);
579 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800580
Bryce Leef3c6a472017-11-14 14:53:06 -0800581 // Do not move the task to another stack here.
582 // This method assumes that the task is already placed in the right stack.
583 // we do not mess with that decision and we only do the resize!
584
585 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeTask_" + taskId);
586
587 final boolean updatedConfig = updateOverrideConfiguration(bounds);
588 // This variable holds information whether the configuration didn't change in a significant
589
590 // way and the activity was kept the way it was. If it's false, it means the activity
591 // had
592 // to be relaunched due to configuration change.
593 boolean kept = true;
594 if (updatedConfig) {
595 final ActivityRecord r = topRunningActivityLocked();
596 if (r != null && !deferResume) {
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -0800597 kept = r.ensureActivityConfiguration(0 /* globalChanges */,
Bryce Leef3c6a472017-11-14 14:53:06 -0800598 preserveWindow);
Garfield Tanb9151182018-06-25 16:29:21 -0700599 // Preserve other windows for resizing because if resizing happens when there
600 // is a dialog activity in the front, the activity that still shows some
601 // content to the user will become black and cause flickers. Note in most cases
602 // this won't cause tons of irrelevant windows being preserved because only
603 // activities in this task may experience a bounds change. Configs for other
604 // activities stay the same.
Wale Ogunwaled32da472018-11-16 07:19:28 -0800605 mService.mRootActivityContainer.ensureActivitiesVisible(r, 0, preserveWindow);
Bryce Leef3c6a472017-11-14 14:53:06 -0800606 if (!kept) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800607 mService.mRootActivityContainer.resumeFocusedStacksTopActivities();
Bryce Leef3c6a472017-11-14 14:53:06 -0800608 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800609 }
610 }
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800611 mTask.resize(kept, forced);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800612
Garfield Tan891146c2018-10-09 12:14:00 -0700613 saveLaunchingStateIfNeeded();
614
Bryce Leef3c6a472017-11-14 14:53:06 -0800615 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
616 return kept;
617 } finally {
618 mService.mWindowManager.continueSurfaceLayout();
619 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800620 }
621
622 // TODO: Investigate combining with the resize() method above.
623 void resizeWindowContainer() {
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800624 mTask.resize(false /* relayout */, false /* forced */);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800625 }
626
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800627 void getWindowContainerBounds(Rect bounds) {
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800628 if (mTask != null) {
629 mTask.getBounds(bounds);
630 } else {
631 bounds.setEmpty();
632 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800633 }
634
Winson Chung74666102017-02-22 17:49:24 -0800635 /**
636 * Convenience method to reparent a task to the top or bottom position of the stack.
637 */
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700638 boolean reparent(ActivityStack preferredStack, boolean toTop,
639 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
640 String reason) {
641 return reparent(preferredStack, toTop ? MAX_VALUE : 0, moveStackMode, animate, deferResume,
642 true /* schedulePictureInPictureModeChange */, reason);
Winson Chung5af42fc2017-03-24 17:11:33 -0700643 }
644
645 /**
646 * Convenience method to reparent a task to the top or bottom position of the stack, with
647 * an option to skip scheduling the picture-in-picture mode change.
648 */
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700649 boolean reparent(ActivityStack preferredStack, boolean toTop,
650 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
651 boolean schedulePictureInPictureModeChange, String reason) {
652 return reparent(preferredStack, toTop ? MAX_VALUE : 0, moveStackMode, animate,
Winson Chung5af42fc2017-03-24 17:11:33 -0700653 deferResume, schedulePictureInPictureModeChange, reason);
654 }
655
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700656 /** Convenience method to reparent a task to a specific position of the stack. */
657 boolean reparent(ActivityStack preferredStack, int position,
658 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
659 String reason) {
660 return reparent(preferredStack, position, moveStackMode, animate, deferResume,
Winson Chung5af42fc2017-03-24 17:11:33 -0700661 true /* schedulePictureInPictureModeChange */, reason);
Winson Chung74666102017-02-22 17:49:24 -0800662 }
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800663
Winson Chung74666102017-02-22 17:49:24 -0800664 /**
665 * Reparents the task into a preferred stack, creating it if necessary.
666 *
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700667 * @param preferredStack the target stack to move this task
Winson Chung74666102017-02-22 17:49:24 -0800668 * @param position the position to place this task in the new stack
669 * @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 -0700670 * reparenting to be drawn and animated in
Winson Chung74666102017-02-22 17:49:24 -0800671 * @param moveStackMode whether or not to move the stack to the front always, only if it was
Winson Chung5af42fc2017-03-24 17:11:33 -0700672 * previously focused & in front, or never
Winson Chung74666102017-02-22 17:49:24 -0800673 * @param deferResume whether or not to update the visibility of other tasks and stacks that may
Winson Chung5af42fc2017-03-24 17:11:33 -0700674 * have changed as a result of this reparenting
675 * @param schedulePictureInPictureModeChange specifies whether or not to schedule the PiP mode
676 * change. Callers may set this to false if they are explicitly scheduling PiP mode
677 * changes themselves, like during the PiP animation
Winson Chung74666102017-02-22 17:49:24 -0800678 * @param reason the caller of this reparenting
Winson Chung5af42fc2017-03-24 17:11:33 -0700679 * @return whether the task was reparented
Winson Chung74666102017-02-22 17:49:24 -0800680 */
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700681 // TODO: Inspect all call sites and change to just changing windowing mode of the stack vs.
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700682 // re-parenting the task. Can only be done when we are no longer using static stack Ids.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700683 boolean reparent(ActivityStack preferredStack, int position,
684 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
685 boolean schedulePictureInPictureModeChange, String reason) {
Winson Chung74666102017-02-22 17:49:24 -0800686 final ActivityStackSupervisor supervisor = mService.mStackSupervisor;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800687 final RootActivityContainer root = mService.mRootActivityContainer;
Winson Chung74666102017-02-22 17:49:24 -0800688 final WindowManagerService windowManager = mService.mWindowManager;
689 final ActivityStack sourceStack = getStack();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700690 final ActivityStack toStack = supervisor.getReparentTargetStack(this, preferredStack,
Winson Chung74666102017-02-22 17:49:24 -0800691 position == MAX_VALUE);
692 if (toStack == sourceStack) {
693 return false;
694 }
Andrii Kulianb850ea52017-12-12 23:49:10 -0800695 if (!canBeLaunchedOnDisplay(toStack.mDisplayId)) {
696 return false;
697 }
Winson Chung74666102017-02-22 17:49:24 -0800698
Andrii Kulian6b321512019-01-23 06:37:00 +0000699 final boolean toTopOfStack = position == MAX_VALUE;
700 if (toTopOfStack && toStack.getResumedActivity() != null
701 && toStack.topRunningActivityLocked() != null) {
702 // Pause the resumed activity on the target stack while re-parenting task on top of it.
703 toStack.startPausingLocked(false /* userLeaving */, false /* uiSleeping */,
704 null /* resuming */, false /* pauseImmediately */);
705 }
706
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700707 final int toStackWindowingMode = toStack.getWindowingMode();
Winson Chung74666102017-02-22 17:49:24 -0800708 final ActivityRecord topActivity = getTopActivity();
709
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800710 final boolean mightReplaceWindow = topActivity != null
711 && replaceWindowsOnTaskMove(getWindowingMode(), toStackWindowingMode);
Winson Chung74666102017-02-22 17:49:24 -0800712 if (mightReplaceWindow) {
713 // We are about to relaunch the activity because its configuration changed due to
714 // being maximized, i.e. size change. The activity will first remove the old window
715 // and then add a new one. This call will tell window manager about this, so it can
716 // preserve the old window until the new one is drawn. This prevents having a gap
717 // between the removal and addition, in which no window is visible. We also want the
718 // entrance of the new window to be properly animated.
719 // Note here we always set the replacing window first, as the flags might be needed
720 // during the relaunch. If we end up not doing any relaunch, we clear the flags later.
721 windowManager.setWillReplaceWindow(topActivity.appToken, animate);
722 }
723
724 windowManager.deferSurfaceLayout();
725 boolean kept = true;
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800726 try {
Winson Chung74666102017-02-22 17:49:24 -0800727 final ActivityRecord r = topRunningActivityLocked();
Wale Ogunwaled32da472018-11-16 07:19:28 -0800728 final boolean wasFocused = r != null && root.isTopDisplayFocusedStack(sourceStack)
Winson Chung74666102017-02-22 17:49:24 -0800729 && (topRunningActivityLocked() == r);
Bryce Leec4ab62a2018-03-05 14:19:26 -0800730 final boolean wasResumed = r != null && sourceStack.getResumedActivity() == r;
Winson Chung95f8f0e2017-03-24 09:20:17 -0700731 final boolean wasPaused = r != null && sourceStack.mPausingActivity == r;
Winson Chung74666102017-02-22 17:49:24 -0800732
733 // In some cases the focused stack isn't the front stack. E.g. pinned stack.
734 // Whenever we are moving the top activity from the front stack we want to make sure to
735 // move the stack to the front.
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -0700736 final boolean wasFront = r != null && sourceStack.isTopStackOnDisplay()
Winson Chung74666102017-02-22 17:49:24 -0800737 && (sourceStack.topRunningActivityLocked() == r);
738
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800739 // Adjust the position for the new parent stack as needed.
Winson Chung74666102017-02-22 17:49:24 -0800740 position = toStack.getAdjustedPositionForTask(this, position, null /* starting */);
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800741
742 // Must reparent first in window manager to avoid a situation where AM can delete the
743 // we are coming from in WM before we reparent because it became empty.
Yunfan Chen279f5582018-12-12 15:24:50 -0800744 mTask.reparent(toStack.getTaskStack(), position,
Wale Ogunwale2719cc12017-04-14 09:45:27 -0700745 moveStackMode == REPARENT_MOVE_STACK_TO_FRONT);
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800746
Wale Ogunwale56d8d162017-05-30 11:12:20 -0700747 final boolean moveStackToFront = moveStackMode == REPARENT_MOVE_STACK_TO_FRONT
748 || (moveStackMode == REPARENT_KEEP_STACK_AT_FRONT && (wasFocused || wasFront));
Winson Chung74666102017-02-22 17:49:24 -0800749 // Move the task
Wale Ogunwale56d8d162017-05-30 11:12:20 -0700750 sourceStack.removeTask(this, reason, moveStackToFront
751 ? REMOVE_TASK_MODE_MOVING_TO_TOP : REMOVE_TASK_MODE_MOVING);
Winson Chung5af42fc2017-03-24 17:11:33 -0700752 toStack.addTask(this, position, false /* schedulePictureInPictureModeChange */, reason);
Winson Chung74666102017-02-22 17:49:24 -0800753
Winson Chung5af42fc2017-03-24 17:11:33 -0700754 if (schedulePictureInPictureModeChange) {
755 // Notify of picture-in-picture mode changes
756 supervisor.scheduleUpdatePictureInPictureModeIfNeeded(this, sourceStack);
757 }
Winson Chung74666102017-02-22 17:49:24 -0800758
759 // TODO: Ensure that this is actually necessary here
760 // Notify the voice session if required
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800761 if (voiceSession != null) {
762 try {
763 voiceSession.taskStarted(intent, taskId);
764 } catch (RemoteException e) {
765 }
766 }
Winson Chung74666102017-02-22 17:49:24 -0800767
768 // If the task had focus before (or we're requested to move focus), move focus to the
769 // new stack by moving the stack to the front.
Winson Chung95f8f0e2017-03-24 09:20:17 -0700770 if (r != null) {
771 toStack.moveToFrontAndResumeStateIfNeeded(r, moveStackToFront, wasResumed,
772 wasPaused, reason);
773 }
Winson Chung74666102017-02-22 17:49:24 -0800774 if (!animate) {
Jorim Jaggifa9ed962018-01-25 00:16:49 +0100775 mService.mStackSupervisor.mNoAnimActivities.add(topActivity);
Winson Chung74666102017-02-22 17:49:24 -0800776 }
777
778 // We might trigger a configuration change. Save the current task bounds for freezing.
779 // TODO: Should this call be moved inside the resize method in WM?
780 toStack.prepareFreezingTaskBounds();
781
782 // Make sure the task has the appropriate bounds/size for the stack it is in.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700783 final boolean toStackSplitScreenPrimary =
784 toStackWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Evan Roskydfe3da72018-10-26 17:21:06 -0700785 final Rect configBounds = getRequestedOverrideBounds();
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700786 if ((toStackWindowingMode == WINDOWING_MODE_FULLSCREEN
787 || toStackWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY)
Evan Roskydfe3da72018-10-26 17:21:06 -0700788 && !Objects.equals(configBounds, toStack.getRequestedOverrideBounds())) {
789 kept = resize(toStack.getRequestedOverrideBounds(), RESIZE_MODE_SYSTEM,
790 !mightReplaceWindow, deferResume);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700791 } else if (toStackWindowingMode == WINDOWING_MODE_FREEFORM) {
Winson Chung74666102017-02-22 17:49:24 -0800792 Rect bounds = getLaunchBounds();
793 if (bounds == null) {
Bryce Leeec55eb02017-12-05 20:51:27 -0800794 mService.mStackSupervisor.getLaunchParamsController().layoutTask(this, null);
Bryce Leef3c6a472017-11-14 14:53:06 -0800795 bounds = configBounds;
Winson Chung74666102017-02-22 17:49:24 -0800796 }
797 kept = resize(bounds, RESIZE_MODE_FORCED, !mightReplaceWindow, deferResume);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700798 } else if (toStackSplitScreenPrimary || toStackWindowingMode == WINDOWING_MODE_PINNED) {
799 if (toStackSplitScreenPrimary && moveStackMode == REPARENT_KEEP_STACK_AT_FRONT) {
Matthew Ng330757d2017-02-28 14:19:17 -0800800 // Move recents to front so it is not behind home stack when going into docked
801 // mode
802 mService.mStackSupervisor.moveRecentsStackToFront(reason);
803 }
Evan Roskydfe3da72018-10-26 17:21:06 -0700804 kept = resize(toStack.getRequestedOverrideBounds(), RESIZE_MODE_SYSTEM,
805 !mightReplaceWindow, deferResume);
Winson Chung74666102017-02-22 17:49:24 -0800806 }
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800807 } finally {
Winson Chung74666102017-02-22 17:49:24 -0800808 windowManager.continueSurfaceLayout();
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800809 }
Winson Chung74666102017-02-22 17:49:24 -0800810
811 if (mightReplaceWindow) {
812 // If we didn't actual do a relaunch (indicated by kept==true meaning we kept the old
813 // window), we need to clear the replace window settings. Otherwise, we schedule a
814 // timeout to remove the old window if the replacing window is not coming in time.
815 windowManager.scheduleClearWillReplaceWindows(topActivity.appToken, !kept);
816 }
817
818 if (!deferResume) {
819 // The task might have already been running and its visibility needs to be synchronized
820 // with the visibility of the stack / windows.
Wale Ogunwaled32da472018-11-16 07:19:28 -0800821 root.ensureActivitiesVisible(null, 0, !mightReplaceWindow);
822 root.resumeFocusedStacksTopActivities();
Winson Chung74666102017-02-22 17:49:24 -0800823 }
824
Andrii Kulian036e3ad2017-04-19 10:55:10 -0700825 // TODO: Handle incorrect request to move before the actual move, not after.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700826 supervisor.handleNonResizableTaskIfNeeded(this, preferredStack.getWindowingMode(),
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -0700827 DEFAULT_DISPLAY, toStack);
Winson Chung74666102017-02-22 17:49:24 -0800828
Winson Chungdff7a732017-12-11 12:17:06 -0800829 return (preferredStack == toStack);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800830 }
831
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700832 /**
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800833 * @return True if the windows of tasks being moved to the target stack from the source stack
834 * should be replaced, meaning that window manager will keep the old window around until the new
835 * is ready.
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700836 */
837 private static boolean replaceWindowsOnTaskMove(
838 int sourceWindowingMode, int targetWindowingMode) {
839 return sourceWindowingMode == WINDOWING_MODE_FREEFORM
840 || targetWindowingMode == WINDOWING_MODE_FREEFORM;
841 }
842
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800843 void cancelWindowTransition() {
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800844 if (mTask == null) {
845 Slog.w(TAG_WM, "cancelWindowTransition: taskId " + taskId + " not found.");
846 return;
847 }
848 mTask.cancelTaskWindowTransition();
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800849 }
850
Jorim Jaggi7361bab2017-01-16 17:17:58 +0100851 /**
852 * DO NOT HOLD THE ACTIVITY MANAGER LOCK WHEN CALLING THIS METHOD!
853 */
Jorim Jaggi925bb3c2019-06-04 19:51:45 +0200854 TaskSnapshot getSnapshot(boolean reducedResolution, boolean restoreFromDisk) {
Jorim Jaggi7361bab2017-01-16 17:17:58 +0100855
856 // TODO: Move this to {@link TaskWindowContainerController} once recent tasks are more
857 // synchronized between AM and WM.
Jorim Jaggi925bb3c2019-06-04 19:51:45 +0200858 return mService.mWindowManager.getTaskSnapshot(taskId, userId, reducedResolution,
859 restoreFromDisk);
Jorim Jaggi02886a82016-12-06 09:10:06 -0800860 }
861
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800862 void touchActiveTime() {
Winson Chungfb44d212017-10-04 11:39:10 -0700863 lastActiveTime = SystemClock.elapsedRealtime();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800864 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700865
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800866 long getInactiveDuration() {
Winson Chungfb44d212017-10-04 11:39:10 -0700867 return SystemClock.elapsedRealtime() - lastActiveTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800868 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700869
Winson Chungfee26772014-08-05 12:21:52 -0700870 /** Sets the original intent, and the calling uid and package. */
871 void setIntent(ActivityRecord r) {
Winson Chungfee26772014-08-05 12:21:52 -0700872 mCallingUid = r.launchedFromUid;
873 mCallingPackage = r.launchedFromPackage;
Craig Mautner15df08a2015-04-01 12:17:18 -0700874 setIntent(r.intent, r.info);
Charles He2bf28322017-10-12 22:24:49 +0100875 setLockTaskAuth(r);
Winson Chungfee26772014-08-05 12:21:52 -0700876 }
877
878 /** Sets the original intent, _without_ updating the calling uid or package. */
879 private void setIntent(Intent _intent, ActivityInfo info) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700880 if (intent == null) {
881 mNeverRelinquishIdentity =
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700882 (info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700883 } else if (mNeverRelinquishIdentity) {
884 return;
885 }
886
887 affinity = info.taskAffinity;
Dianne Hackborn79228822014-09-16 11:11:23 -0700888 if (intent == null) {
889 // If this task already has an intent associated with it, don't set the root
890 // affinity -- we don't want it changing after initially set, but the initially
891 // set value may be null.
892 rootAffinity = affinity;
893 }
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700894 effectiveUid = info.applicationInfo.uid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700895 stringName = null;
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800896
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800897 if (info.targetActivity == null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800898 if (_intent != null) {
899 // If this Intent has a selector, we want to clear it for the
900 // recent task since it is not relevant if the user later wants
901 // to re-launch the app.
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700902 if (_intent.getSelector() != null || _intent.getSourceBounds() != null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800903 _intent = new Intent(_intent);
904 _intent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700905 _intent.setSourceBounds(null);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800906 }
907 }
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700908 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Setting Intent of " + this + " to " + _intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800909 intent = _intent;
910 realActivity = _intent != null ? _intent.getComponent() : null;
911 origActivity = null;
912 } else {
913 ComponentName targetComponent = new ComponentName(
914 info.packageName, info.targetActivity);
915 if (_intent != null) {
916 Intent targetIntent = new Intent(_intent);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800917 targetIntent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700918 targetIntent.setSourceBounds(null);
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700919 if (DEBUG_TASKS) Slog.v(TAG_TASKS,
Dianne Hackborn7f96b792012-05-29 18:46:45 -0700920 "Setting Intent of " + this + " to target " + targetIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800921 intent = targetIntent;
922 realActivity = targetComponent;
923 origActivity = _intent.getComponent();
924 } else {
925 intent = null;
926 realActivity = targetComponent;
927 origActivity = new ComponentName(info.packageName, info.name);
928 }
929 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700930
Craig Mautner47b20ba2014-09-17 17:23:44 -0700931 final int intentFlags = intent == null ? 0 : intent.getFlags();
932 if ((intentFlags & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800933 // Once we are set to an Intent with this flag, we count this
934 // task as having a true root activity.
935 rootWasReset = true;
936 }
Dianne Hackborn09233282014-04-30 11:33:59 -0700937 userId = UserHandle.getUserId(info.applicationInfo.uid);
Winson Chung36f3f032016-09-08 23:29:43 +0000938 mUserSetupComplete = Settings.Secure.getIntForUser(mService.mContext.getContentResolver(),
939 USER_SETUP_COMPLETE, 0, userId) != 0;
Craig Mautner41db4a72014-05-07 17:20:56 -0700940 if ((info.flags & ActivityInfo.FLAG_AUTO_REMOVE_FROM_RECENTS) != 0) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700941 // If the activity itself has requested auto-remove, then just always do it.
942 autoRemoveRecents = true;
Wale Ogunwale843bfb92015-03-27 11:06:48 -0700943 } else if ((intentFlags & (FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS))
944 == FLAG_ACTIVITY_NEW_DOCUMENT) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700945 // If the caller has not asked for the document to be retained, then we may
946 // want to turn on auto-remove, depending on whether the target has set its
947 // own document launch mode.
948 if (info.documentLaunchMode != ActivityInfo.DOCUMENT_LAUNCH_NONE) {
949 autoRemoveRecents = false;
950 } else {
951 autoRemoveRecents = true;
952 }
953 } else {
954 autoRemoveRecents = false;
Craig Mautner41db4a72014-05-07 17:20:56 -0700955 }
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800956 mResizeMode = info.resizeMode;
Winson Chungd3395382016-12-13 11:49:09 -0800957 mSupportsPictureInPicture = info.supportsPictureInPicture();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800958 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800959
Andrii Kulian2e751b82016-03-16 16:59:32 -0700960 /** Sets the original minimal width and height. */
961 private void setMinDimensions(ActivityInfo info) {
962 if (info != null && info.windowLayout != null) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700963 mMinWidth = info.windowLayout.minWidth;
964 mMinHeight = info.windowLayout.minHeight;
Andrii Kulian2e751b82016-03-16 16:59:32 -0700965 } else {
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700966 mMinWidth = INVALID_MIN_SIZE;
967 mMinHeight = INVALID_MIN_SIZE;
Andrii Kulian2e751b82016-03-16 16:59:32 -0700968 }
969 }
970
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800971 /**
Andrii Kulian206b9fa2016-06-02 13:18:01 -0700972 * Return true if the input activity has the same intent filter as the intent this task
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800973 * record is based on (normally the root activity intent).
974 */
Andrii Kulian206b9fa2016-06-02 13:18:01 -0700975 boolean isSameIntentFilter(ActivityRecord r) {
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800976 final Intent intent = new Intent(r.intent);
Louis Chang23df1a62019-01-09 15:10:49 +0800977 // Make sure the component are the same if the input activity has the same real activity
978 // as the one in the task because either one of them could be the alias activity.
979 if (Objects.equals(realActivity, r.mActivityComponent) && this.intent != null) {
980 intent.setComponent(this.intent.getComponent());
981 }
Bryce Lee1a990e52018-04-23 10:54:11 -0700982 return intent.filterEquals(this.intent);
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800983 }
984
Wale Ogunwale66e16852017-10-19 13:35:52 -0700985 boolean returnsToHomeStack() {
986 final int returnHomeFlags = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME;
Bryce Lee1a990e52018-04-23 10:54:11 -0700987 return intent != null && (intent.getFlags() & returnHomeFlags) == returnHomeFlags;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700988 }
989
Craig Mautnera228ae92014-07-09 05:44:55 -0700990 void setPrevAffiliate(TaskRecord prevAffiliate) {
991 mPrevAffiliate = prevAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800992 mPrevAffiliateTaskId = prevAffiliate == null ? INVALID_TASK_ID : prevAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700993 }
994
995 void setNextAffiliate(TaskRecord nextAffiliate) {
996 mNextAffiliate = nextAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800997 mNextAffiliateTaskId = nextAffiliate == null ? INVALID_TASK_ID : nextAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700998 }
999
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001000 <T extends ActivityStack> T getStack() {
1001 return (T) mStack;
Andrii Kulian02b7a832016-10-06 23:11:56 -07001002 }
1003
Andrii Kulianfb1bf692017-01-17 11:17:34 -08001004 /**
1005 * Must be used for setting parent stack because it performs configuration updates.
1006 * Must be called after adding task as a child to the stack.
1007 */
Andrii Kulian02b7a832016-10-06 23:11:56 -07001008 void setStack(ActivityStack stack) {
Andrii Kulianfb1bf692017-01-17 11:17:34 -08001009 if (stack != null && !stack.isInStackLocked(this)) {
1010 throw new IllegalStateException("Task must be added as a Stack child first.");
1011 }
Bryce Lee84730a02018-04-03 14:10:04 -07001012 final ActivityStack oldStack = mStack;
Andrii Kulian02b7a832016-10-06 23:11:56 -07001013 mStack = stack;
Bryce Lee84730a02018-04-03 14:10:04 -07001014
1015 // If the new {@link TaskRecord} is from a different {@link ActivityStack}, remove this
1016 // {@link ActivityRecord} from its current {@link ActivityStack}.
1017
1018 if (oldStack != mStack) {
1019 for (int i = getChildCount() - 1; i >= 0; --i) {
1020 final ActivityRecord activity = getChildAt(i);
1021
1022 if (oldStack != null) {
1023 oldStack.onActivityRemovedFromStack(activity);
1024 }
1025
1026 if (mStack != null) {
1027 stack.onActivityAddedToStack(activity);
1028 }
1029 }
1030 }
1031
Andrii Kulian1779e612016-10-12 21:58:25 -07001032 onParentChanged();
Andrii Kulian02b7a832016-10-06 23:11:56 -07001033 }
1034
1035 /**
1036 * @return Id of current stack, {@link INVALID_STACK_ID} if no stack is set.
1037 */
1038 int getStackId() {
1039 return mStack != null ? mStack.mStackId : INVALID_STACK_ID;
1040 }
1041
Andrii Kulian1779e612016-10-12 21:58:25 -07001042 @Override
1043 protected int getChildCount() {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07001044 return mActivities.size();
Andrii Kulian1779e612016-10-12 21:58:25 -07001045 }
1046
1047 @Override
chaviw82a0ba82018-03-15 14:26:29 -07001048 protected ActivityRecord getChildAt(int index) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07001049 return mActivities.get(index);
Andrii Kulian1779e612016-10-12 21:58:25 -07001050 }
1051
1052 @Override
1053 protected ConfigurationContainer getParent() {
1054 return mStack;
1055 }
1056
Andrii Kulianfb1bf692017-01-17 11:17:34 -08001057 @Override
Wale Ogunwale98d62312017-07-12 09:24:56 -07001058 protected void onParentChanged() {
Andrii Kulianfb1bf692017-01-17 11:17:34 -08001059 super.onParentChanged();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001060 mService.mRootActivityContainer.updateUIDsPresentOnDisplay();
Andrii Kulianfb1bf692017-01-17 11:17:34 -08001061 }
1062
Craig Mautnera228ae92014-07-09 05:44:55 -07001063 // Close up recents linked list.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07001064 private void closeRecentsChain() {
Craig Mautnera228ae92014-07-09 05:44:55 -07001065 if (mPrevAffiliate != null) {
1066 mPrevAffiliate.setNextAffiliate(mNextAffiliate);
1067 }
1068 if (mNextAffiliate != null) {
1069 mNextAffiliate.setPrevAffiliate(mPrevAffiliate);
1070 }
1071 setPrevAffiliate(null);
1072 setNextAffiliate(null);
1073 }
1074
Winson Chung740c3ac2014-11-12 16:14:38 -08001075 void removedFromRecents() {
Dianne Hackborn852975d2014-08-22 17:42:43 -07001076 closeRecentsChain();
1077 if (inRecents) {
1078 inRecents = false;
Winson Chung740c3ac2014-11-12 16:14:38 -08001079 mService.notifyTaskPersisterLocked(this, false);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001080 }
Jorim Jaggif9084ec2017-01-16 13:16:59 +01001081
Dianne Hackborn68a06332017-11-15 17:54:18 -08001082 clearRootProcess();
1083
Jorim Jaggif9084ec2017-01-16 13:16:59 +01001084 // TODO: Use window container controller once tasks are better synced between AM and WM
1085 mService.mWindowManager.notifyTaskRemovedFromRecents(taskId, userId);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001086 }
1087
Craig Mautnera228ae92014-07-09 05:44:55 -07001088 void setTaskToAffiliateWith(TaskRecord taskToAffiliateWith) {
1089 closeRecentsChain();
1090 mAffiliatedTaskId = taskToAffiliateWith.mAffiliatedTaskId;
Winson Chungec396d62014-08-06 17:08:00 -07001091 mAffiliatedTaskColor = taskToAffiliateWith.mAffiliatedTaskColor;
Craig Mautnera228ae92014-07-09 05:44:55 -07001092 // Find the end
1093 while (taskToAffiliateWith.mNextAffiliate != null) {
1094 final TaskRecord nextRecents = taskToAffiliateWith.mNextAffiliate;
1095 if (nextRecents.mAffiliatedTaskId != mAffiliatedTaskId) {
1096 Slog.e(TAG, "setTaskToAffiliateWith: nextRecents=" + nextRecents + " affilTaskId="
1097 + nextRecents.mAffiliatedTaskId + " should be " + mAffiliatedTaskId);
1098 if (nextRecents.mPrevAffiliate == taskToAffiliateWith) {
1099 nextRecents.setPrevAffiliate(null);
1100 }
1101 taskToAffiliateWith.setNextAffiliate(null);
1102 break;
1103 }
1104 taskToAffiliateWith = nextRecents;
1105 }
1106 taskToAffiliateWith.setNextAffiliate(this);
1107 setPrevAffiliate(taskToAffiliateWith);
1108 setNextAffiliate(null);
1109 }
1110
Winson Chung1147c402014-05-14 11:05:00 -07001111 /** Returns the intent for the root activity for this task */
1112 Intent getBaseIntent() {
1113 return intent != null ? intent : affinityIntent;
1114 }
1115
Winson Chung3b3f4642014-04-22 10:08:18 -07001116 /** Returns the first non-finishing activity from the root. */
1117 ActivityRecord getRootActivity() {
1118 for (int i = 0; i < mActivities.size(); i++) {
1119 final ActivityRecord r = mActivities.get(i);
1120 if (r.finishing) {
1121 continue;
1122 }
1123 return r;
1124 }
1125 return null;
1126 }
1127
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001128 ActivityRecord getTopActivity() {
Bryce Lee9f6affd2017-09-01 09:18:35 -07001129 return getTopActivity(true /* includeOverlays */);
1130 }
1131
1132 ActivityRecord getTopActivity(boolean includeOverlays) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001133 for (int i = mActivities.size() - 1; i >= 0; --i) {
1134 final ActivityRecord r = mActivities.get(i);
Bryce Lee9f6affd2017-09-01 09:18:35 -07001135 if (r.finishing || (!includeOverlays && r.mTaskOverlay)) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001136 continue;
1137 }
1138 return r;
1139 }
1140 return null;
1141 }
1142
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -07001143 ActivityRecord topRunningActivityLocked() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001144 if (mStack != null) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07001145 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1146 ActivityRecord r = mActivities.get(activityNdx);
Chong Zhang87761972016-08-22 13:53:24 -07001147 if (!r.finishing && r.okToShowLocked()) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07001148 return r;
1149 }
Craig Mautner6b74cb52013-09-27 17:02:21 -07001150 }
1151 }
1152 return null;
1153 }
1154
Jorim Jaggi172e99f2017-10-20 14:33:18 +02001155 boolean isVisible() {
1156 for (int i = mActivities.size() - 1; i >= 0; --i) {
1157 final ActivityRecord r = mActivities.get(i);
1158 if (r.visible) {
1159 return true;
1160 }
1161 }
1162 return false;
1163 }
1164
Ricky Waib147fa12019-04-25 16:08:30 +01001165 /**
1166 * Return true if any activities in this task belongs to input uid.
1167 */
1168 boolean containsAppUid(int uid) {
1169 for (int i = mActivities.size() - 1; i >= 0; --i) {
1170 final ActivityRecord r = mActivities.get(i);
1171 if (r.getUid() == uid) {
1172 return true;
1173 }
1174 }
1175 return false;
1176 }
1177
Jorim Jaggiea039a82017-08-02 14:37:49 +02001178 void getAllRunningVisibleActivitiesLocked(ArrayList<ActivityRecord> outActivities) {
1179 if (mStack != null) {
1180 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1181 ActivityRecord r = mActivities.get(activityNdx);
Jorim Jaggi02f1d2f2017-08-04 14:29:16 +02001182 if (!r.finishing && r.okToShowLocked() && r.visibleIgnoringKeyguard) {
Jorim Jaggiea039a82017-08-02 14:37:49 +02001183 outActivities.add(r);
1184 }
1185 }
1186 }
1187 }
1188
Wale Ogunwale3b232392016-05-13 15:37:13 -07001189 ActivityRecord topRunningActivityWithStartingWindowLocked() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001190 if (mStack != null) {
Wale Ogunwale3b232392016-05-13 15:37:13 -07001191 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1192 ActivityRecord r = mActivities.get(activityNdx);
1193 if (r.mStartingWindowState != STARTING_WINDOW_SHOWN
Chong Zhang87761972016-08-22 13:53:24 -07001194 || r.finishing || !r.okToShowLocked()) {
Wale Ogunwale3b232392016-05-13 15:37:13 -07001195 continue;
1196 }
1197 return r;
1198 }
1199 }
1200 return null;
1201 }
1202
Winson Chung61c9e5a2017-10-11 10:39:32 -07001203 /**
1204 * Return the number of running activities, and the number of non-finishing/initializing
1205 * activities in the provided {@param reportOut} respectively.
1206 */
1207 void getNumRunningActivities(TaskActivitiesReport reportOut) {
1208 reportOut.reset();
1209 for (int i = mActivities.size() - 1; i >= 0; --i) {
1210 final ActivityRecord r = mActivities.get(i);
1211 if (r.finishing) {
1212 continue;
1213 }
1214
1215 reportOut.base = r;
1216
1217 // Increment the total number of non-finishing activities
1218 reportOut.numActivities++;
1219
Bryce Lee7ace3952018-02-16 14:34:32 -08001220 if (reportOut.top == null || (reportOut.top.isState(ActivityState.INITIALIZING))) {
Winson Chung61c9e5a2017-10-11 10:39:32 -07001221 reportOut.top = r;
1222 // Reset the number of running activities until we hit the first non-initializing
1223 // activity
1224 reportOut.numRunning = 0;
1225 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001226 if (r.attachedToProcess()) {
Winson Chung61c9e5a2017-10-11 10:39:32 -07001227 // Increment the number of actually running activities
1228 reportOut.numRunning++;
1229 }
1230 }
1231 }
1232
Chong Zhang87761972016-08-22 13:53:24 -07001233 boolean okToShowLocked() {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001234 // NOTE: If {@link TaskRecord#topRunningActivity} return is not null then it is
Chong Zhang87761972016-08-22 13:53:24 -07001235 // okay to show the activity when locked.
1236 return mService.mStackSupervisor.isCurrentProfileLocked(userId)
1237 || topRunningActivityLocked() != null;
1238 }
1239
Craig Mautner3b475fe2013-12-16 15:58:31 -08001240 /** Call after activity movement or finish to make sure that frontOfTask is set correctly */
Bryce Leed71317c2017-02-07 14:27:22 -08001241 final void setFrontOfTask() {
1242 boolean foundFront = false;
Craig Mautner3b475fe2013-12-16 15:58:31 -08001243 final int numActivities = mActivities.size();
Craig Mautner704e40b2013-12-18 16:43:51 -08001244 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
Craig Mautner3b475fe2013-12-16 15:58:31 -08001245 final ActivityRecord r = mActivities.get(activityNdx);
1246 if (foundFront || r.finishing) {
1247 r.frontOfTask = false;
1248 } else {
1249 r.frontOfTask = true;
1250 // Set frontOfTask false for every following activity.
1251 foundFront = true;
1252 }
1253 }
Craig Mautner9587ee02014-06-23 15:00:10 +00001254 if (!foundFront && numActivities > 0) {
1255 // All activities of this task are finishing. As we ought to have a frontOfTask
1256 // activity, make the bottom activity front.
1257 mActivities.get(0).frontOfTask = true;
1258 }
Craig Mautner3b475fe2013-12-16 15:58:31 -08001259 }
1260
Craig Mautnerde4ef022013-04-07 19:01:33 -07001261 /**
Craig Mautner3b475fe2013-12-16 15:58:31 -08001262 * Reorder the history stack so that the passed activity is brought to the front.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001263 */
1264 final void moveActivityToFrontLocked(ActivityRecord newTop) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07001265 if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE,
1266 "Removing and adding activity " + newTop
1267 + " to stack at top callers=" + Debug.getCallers(4));
Craig Mautnerde4ef022013-04-07 19:01:33 -07001268
Craig Mautnerde4ef022013-04-07 19:01:33 -07001269 mActivities.remove(newTop);
1270 mActivities.add(newTop);
Bryce Leed58d7b32017-09-08 15:55:22 -07001271
1272 // Make sure window manager is aware of the position change.
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001273 mTask.positionChildAtTop(newTop.mAppWindowToken);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001274 updateEffectiveIntent();
Craig Mautner3b475fe2013-12-16 15:58:31 -08001275
Bryce Leed71317c2017-02-07 14:27:22 -08001276 setFrontOfTask();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001277 }
1278
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001279 void addActivityToTop(ActivityRecord r) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001280 addActivityAtIndex(mActivities.size(), r);
1281 }
1282
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001283 @Override
Wale Ogunwaleeea34ee92017-08-31 20:07:45 -07001284 /*@WindowConfiguration.ActivityType*/
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001285 public int getActivityType() {
1286 final int applicationType = super.getActivityType();
1287 if (applicationType != ACTIVITY_TYPE_UNDEFINED || mActivities.isEmpty()) {
1288 return applicationType;
1289 }
1290 return mActivities.get(0).getActivityType();
1291 }
1292
Winson Chung30480042017-01-26 10:55:34 -08001293 /**
1294 * Adds an activity {@param r} at the given {@param index}. The activity {@param r} must either
1295 * be in the current task or unparented to any task.
1296 */
Craig Mautner1602ec22013-05-12 10:24:27 -07001297 void addActivityAtIndex(int index, ActivityRecord r) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001298 TaskRecord task = r.getTaskRecord();
Bryce Leeaf691c02017-03-20 14:20:22 -07001299 if (task != null && task != this) {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001300 throw new IllegalArgumentException("Can not add r=" + " to task=" + this
Bryce Leeaf691c02017-03-20 14:20:22 -07001301 + " current parent=" + task);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001302 }
Bryce Leeaf691c02017-03-20 14:20:22 -07001303
1304 r.setTask(this);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001305
Craig Mautner6170f732013-04-02 13:05:23 -07001306 // 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 -08001307 if (!mActivities.remove(r) && r.fullscreen) {
1308 // Was not previously in list.
1309 numFullscreen++;
1310 }
Craig Mautner2c1faed2013-07-23 12:56:02 -07001311 // Only set this based on the first activity
1312 if (mActivities.isEmpty()) {
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001313 if (r.getActivityType() == ACTIVITY_TYPE_UNDEFINED) {
1314 // Normally non-standard activity type for the activity record will be set when the
1315 // object is created, however we delay setting the standard application type until
1316 // this point so that the task can set the type for additional activities added in
1317 // the else condition below.
1318 r.setActivityType(ACTIVITY_TYPE_STANDARD);
1319 }
1320 setActivityType(r.getActivityType());
Craig Mautner21d24a22014-04-23 11:45:37 -07001321 isPersistable = r.isPersistable();
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001322 mCallingUid = r.launchedFromUid;
1323 mCallingPackage = r.launchedFromPackage;
Dianne Hackborn852975d2014-08-22 17:42:43 -07001324 // Clamp to [1, max].
1325 maxRecents = Math.min(Math.max(r.info.maxRecents, 1),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001326 ActivityTaskManager.getMaxAppRecentsLimitStatic());
Craig Mautner2c1faed2013-07-23 12:56:02 -07001327 } else {
1328 // Otherwise make all added activities match this one.
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001329 r.setActivityType(getActivityType());
Craig Mautner78733002013-06-10 13:54:49 -07001330 }
Wale Ogunwale3b232392016-05-13 15:37:13 -07001331
1332 final int size = mActivities.size();
1333
1334 if (index == size && size > 0) {
1335 final ActivityRecord top = mActivities.get(size - 1);
1336 if (top.mTaskOverlay) {
1337 // Place below the task overlay activity since the overlay activity should always
1338 // be on top.
1339 index--;
1340 }
1341 }
1342
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001343 index = Math.min(size, index);
Craig Mautner77878772013-03-04 19:46:24 -08001344 mActivities.add(index, r);
Bryce Lee84730a02018-04-03 14:10:04 -07001345
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001346 updateEffectiveIntent();
Craig Mautner21d24a22014-04-23 11:45:37 -07001347 if (r.isPersistable()) {
1348 mService.notifyTaskPersisterLocked(this, false);
1349 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001350
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001351 if (r.mAppWindowToken != null) {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001352 // Only attempt to move in WM if the child has a controller. It is possible we haven't
1353 // created controller for the activity we are starting yet.
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001354 mTask.positionChildAt(r.mAppWindowToken, index);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001355 }
David Stevens82ea6cb2017-03-03 16:18:50 -08001356
1357 // Make sure the list of display UID whitelists is updated
1358 // now that this record is in a new task.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001359 mService.mRootActivityContainer.updateUIDsPresentOnDisplay();
Craig Mautner77878772013-03-04 19:46:24 -08001360 }
1361
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001362 /**
Bryce Leeaf691c02017-03-20 14:20:22 -07001363 * Removes the specified activity from this task.
1364 * @param r The {@link ActivityRecord} to remove.
1365 * @return true if this was the last activity in the task.
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001366 */
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001367 boolean removeActivity(ActivityRecord r) {
Bryce Lee84730a02018-04-03 14:10:04 -07001368 return removeActivity(r, false /* reparenting */);
Bryce Leeaf691c02017-03-20 14:20:22 -07001369 }
1370
1371 boolean removeActivity(ActivityRecord r, boolean reparenting) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001372 if (r.getTaskRecord() != this) {
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001373 throw new IllegalArgumentException(
1374 "Activity=" + r + " does not belong to task=" + this);
1375 }
1376
Bryce Lee84730a02018-04-03 14:10:04 -07001377 r.setTask(null /* task */, reparenting /* reparenting */);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001378
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001379 if (mActivities.remove(r) && r.fullscreen) {
1380 // Was previously in list.
1381 numFullscreen--;
1382 }
Craig Mautner21d24a22014-04-23 11:45:37 -07001383 if (r.isPersistable()) {
1384 mService.notifyTaskPersisterLocked(this, false);
1385 }
Wale Ogunwale89182d52016-03-11 10:38:36 -08001386
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001387 if (inPinnedWindowingMode()) {
Wale Ogunwale89182d52016-03-11 10:38:36 -08001388 // We normally notify listeners of task stack changes on pause, however pinned stack
1389 // activities are normally in the paused state so no notification will be sent there
1390 // before the activity is removed. We send it here so instead.
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001391 mService.getTaskChangeNotificationController().notifyTaskStackChanged();
Wale Ogunwale89182d52016-03-11 10:38:36 -08001392 }
1393
Craig Mautner41326202014-06-20 14:38:21 -07001394 if (mActivities.isEmpty()) {
Craig Mautner5afcd4d2014-06-21 18:11:33 -07001395 return !mReuseTask;
Craig Mautner41326202014-06-20 14:38:21 -07001396 }
1397 updateEffectiveIntent();
1398 return false;
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001399 }
1400
Winson Chung6954fc92017-03-24 16:22:12 -07001401 /**
1402 * @return whether or not there are ONLY task overlay activities in the stack.
1403 * If {@param excludeFinishing} is set, then ignore finishing activities in the check.
1404 * If there are no task overlay activities, this call returns false.
1405 */
1406 boolean onlyHasTaskOverlayActivities(boolean excludeFinishing) {
1407 int count = 0;
1408 for (int i = mActivities.size() - 1; i >= 0; i--) {
1409 final ActivityRecord r = mActivities.get(i);
1410 if (excludeFinishing && r.finishing) {
1411 continue;
1412 }
1413 if (!r.mTaskOverlay) {
1414 return false;
1415 }
1416 count++;
1417 }
1418 return count > 0;
1419 }
1420
Craig Mautner41db4a72014-05-07 17:20:56 -07001421 boolean autoRemoveFromRecents() {
Dianne Hackbornd38aed82014-06-10 21:36:35 -07001422 // We will automatically remove the task either if it has explicitly asked for
1423 // this, or it is empty and has never contained an activity that got shown to
1424 // the user.
Dianne Hackborn13420f22014-07-18 15:43:56 -07001425 return autoRemoveRecents || (mActivities.isEmpty() && !hasBeenVisible);
Craig Mautner41db4a72014-05-07 17:20:56 -07001426 }
1427
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001428 /**
1429 * Completely remove all activities associated with an existing
1430 * task starting at a specified index.
1431 */
Winson Chung0ec2a352017-10-26 11:38:30 -07001432 final void performClearTaskAtIndexLocked(int activityNdx, boolean pauseImmediately,
1433 String reason) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001434 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001435 for ( ; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001436 final ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001437 if (r.finishing) {
1438 continue;
1439 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07001440 if (mStack == null) {
Craig Mautner21d24a22014-04-23 11:45:37 -07001441 // Task was restored from persistent storage.
1442 r.takeFromHistory();
1443 mActivities.remove(activityNdx);
1444 --activityNdx;
1445 --numActivities;
Winson Chung6954fc92017-03-24 16:22:12 -07001446 } else if (mStack.finishActivityLocked(r, Activity.RESULT_CANCELED, null,
Winson Chung0ec2a352017-10-26 11:38:30 -07001447 reason, false, pauseImmediately)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001448 --activityNdx;
1449 --numActivities;
1450 }
1451 }
1452 }
1453
1454 /**
1455 * Completely remove all activities associated with an existing task.
1456 */
Benjamin Franza83859f2017-07-03 16:34:14 +01001457 void performClearTaskLocked() {
Craig Mautner362449a2014-06-20 14:04:39 -07001458 mReuseTask = true;
Winson Chung0ec2a352017-10-26 11:38:30 -07001459 performClearTaskAtIndexLocked(0, !PAUSE_IMMEDIATELY, "clear-task-all");
Craig Mautner362449a2014-06-20 14:04:39 -07001460 mReuseTask = false;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001461 }
1462
Filip Gruszczynskibe9dabd2016-01-19 12:23:10 -08001463 ActivityRecord performClearTaskForReuseLocked(ActivityRecord newR, int launchFlags) {
1464 mReuseTask = true;
1465 final ActivityRecord result = performClearTaskLocked(newR, launchFlags);
1466 mReuseTask = false;
1467 return result;
1468 }
1469
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001470 /**
1471 * Perform clear operation as requested by
1472 * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the
1473 * stack to the given task, then look for
1474 * an instance of that activity in the stack and, if found, finish all
1475 * activities on top of it and return the instance.
1476 *
1477 * @param newR Description of the new activity being started.
1478 * @return Returns the old activity that should be continued to be used,
1479 * or null if none was found.
1480 */
1481 final ActivityRecord performClearTaskLocked(ActivityRecord newR, int launchFlags) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001482 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001483 for (int activityNdx = numActivities - 1; activityNdx >= 0; --activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001484 ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001485 if (r.finishing) {
1486 continue;
1487 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001488 if (r.mActivityComponent.equals(newR.mActivityComponent)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001489 // Here it is! Now finish everything in front...
Craig Mautner1602ec22013-05-12 10:24:27 -07001490 final ActivityRecord ret = r;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001491
1492 for (++activityNdx; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001493 r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001494 if (r.finishing) {
1495 continue;
1496 }
Jorim Jaggi346702a2019-05-08 17:49:33 +02001497 ActivityOptions opts = r.takeOptionsLocked(false /* fromClient */);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001498 if (opts != null) {
1499 ret.updateOptionsLocked(opts);
1500 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07001501 if (mStack != null && mStack.finishActivityLocked(
Todd Kennedy539db512014-12-15 09:57:55 -08001502 r, Activity.RESULT_CANCELED, null, "clear-task-stack", false)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001503 --activityNdx;
1504 --numActivities;
1505 }
1506 }
1507
1508 // Finally, if this is a normal launch mode (that is, not
1509 // expecting onNewIntent()), then we will finish the current
1510 // instance of the activity so a new fresh one can be started.
1511 if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE
Daichi Hirono15a02992016-04-27 18:47:01 +09001512 && (launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0
1513 && !ActivityStarter.isDocumentLaunchesIntoExisting(launchFlags)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001514 if (!ret.finishing) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001515 if (mStack != null) {
1516 mStack.finishActivityLocked(
Wale Ogunwale7d701172015-03-11 15:36:30 -07001517 ret, Activity.RESULT_CANCELED, null, "clear-task-top", false);
1518 }
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001519 return null;
1520 }
1521 }
1522
1523 return ret;
1524 }
1525 }
1526
1527 return null;
1528 }
1529
Winson Chung0ec2a352017-10-26 11:38:30 -07001530 void removeTaskActivitiesLocked(boolean pauseImmediately, String reason) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001531 // Just remove the entire task.
Winson Chung0ec2a352017-10-26 11:38:30 -07001532 performClearTaskAtIndexLocked(0, pauseImmediately, reason);
Craig Mautner9db9a0b2013-04-29 17:05:56 -07001533 }
1534
Craig Mautner432f64e2015-05-20 14:59:57 -07001535 String lockTaskAuthToString() {
1536 switch (mLockTaskAuth) {
1537 case LOCK_TASK_AUTH_DONT_LOCK: return "LOCK_TASK_AUTH_DONT_LOCK";
1538 case LOCK_TASK_AUTH_PINNABLE: return "LOCK_TASK_AUTH_PINNABLE";
1539 case LOCK_TASK_AUTH_LAUNCHABLE: return "LOCK_TASK_AUTH_LAUNCHABLE";
1540 case LOCK_TASK_AUTH_WHITELISTED: return "LOCK_TASK_AUTH_WHITELISTED";
Benjamin Franz469dd582015-06-09 14:24:36 +01001541 case LOCK_TASK_AUTH_LAUNCHABLE_PRIV: return "LOCK_TASK_AUTH_LAUNCHABLE_PRIV";
Craig Mautner432f64e2015-05-20 14:59:57 -07001542 default: return "unknown=" + mLockTaskAuth;
1543 }
1544 }
1545
Craig Mautner15df08a2015-04-01 12:17:18 -07001546 void setLockTaskAuth() {
Charles He2bf28322017-10-12 22:24:49 +01001547 setLockTaskAuth(getRootActivity());
1548 }
1549
1550 private void setLockTaskAuth(@Nullable ActivityRecord r) {
1551 if (r == null) {
1552 mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE;
1553 return;
1554 }
1555
Charles He520b2832017-09-02 15:27:16 +01001556 final String pkg = (realActivity != null) ? realActivity.getPackageName() : null;
Bryce Lee2b8e0372018-04-05 17:01:37 -07001557 final LockTaskController lockTaskController = mService.getLockTaskController();
Charles He2bf28322017-10-12 22:24:49 +01001558 switch (r.lockTaskLaunchMode) {
Craig Mautner15df08a2015-04-01 12:17:18 -07001559 case LOCK_TASK_LAUNCH_MODE_DEFAULT:
Bryce Lee2b8e0372018-04-05 17:01:37 -07001560 mLockTaskAuth = lockTaskController.isPackageWhitelisted(userId, pkg)
Charles He520b2832017-09-02 15:27:16 +01001561 ? LOCK_TASK_AUTH_WHITELISTED : LOCK_TASK_AUTH_PINNABLE;
Craig Mautner15df08a2015-04-01 12:17:18 -07001562 break;
1563
1564 case LOCK_TASK_LAUNCH_MODE_NEVER:
Benjamin Franz469dd582015-06-09 14:24:36 +01001565 mLockTaskAuth = LOCK_TASK_AUTH_DONT_LOCK;
Craig Mautner15df08a2015-04-01 12:17:18 -07001566 break;
1567
1568 case LOCK_TASK_LAUNCH_MODE_ALWAYS:
Benjamin Franz469dd582015-06-09 14:24:36 +01001569 mLockTaskAuth = LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
Craig Mautner15df08a2015-04-01 12:17:18 -07001570 break;
1571
1572 case LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED:
Bryce Lee2b8e0372018-04-05 17:01:37 -07001573 mLockTaskAuth = lockTaskController.isPackageWhitelisted(userId, pkg)
Charles He520b2832017-09-02 15:27:16 +01001574 ? LOCK_TASK_AUTH_LAUNCHABLE : LOCK_TASK_AUTH_PINNABLE;
Craig Mautner15df08a2015-04-01 12:17:18 -07001575 break;
1576 }
Craig Mautner432f64e2015-05-20 14:59:57 -07001577 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
1578 " mLockTaskAuth=" + lockTaskAuthToString());
Craig Mautner15df08a2015-04-01 12:17:18 -07001579 }
1580
Winson Chungd3395382016-12-13 11:49:09 -08001581 private boolean isResizeable(boolean checkSupportsPip) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001582 return (mService.mForceResizableActivities || ActivityInfo.isResizeableMode(mResizeMode)
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -07001583 || (checkSupportsPip && mSupportsPictureInPicture));
Winson Chungd3395382016-12-13 11:49:09 -08001584 }
1585
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001586 boolean isResizeable() {
Winson Chungd3395382016-12-13 11:49:09 -08001587 return isResizeable(true /* checkSupportsPip */);
1588 }
1589
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001590 @Override
1591 public boolean supportsSplitScreenWindowingMode() {
Winson Chungd3395382016-12-13 11:49:09 -08001592 // A task can not be docked even if it is considered resizeable because it only supports
1593 // picture-in-picture mode but has a non-resizeable resizeMode
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001594 return super.supportsSplitScreenWindowingMode()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001595 && mService.mSupportsSplitScreenMultiWindow
1596 && (mService.mForceResizableActivities
Bryce Leec857a5b2017-08-16 10:04:52 -07001597 || (isResizeable(false /* checkSupportsPip */)
1598 && !ActivityInfo.isPreserveOrientationMode(mResizeMode)));
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001599 }
1600
skuhne@google.com322347b2016-12-02 12:54:03 -08001601 /**
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001602 * Check whether this task can be launched on the specified display.
Riddle Hsu16567132018-08-16 21:37:47 +08001603 *
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001604 * @param displayId Target display id.
Riddle Hsu16567132018-08-16 21:37:47 +08001605 * @return {@code true} if either it is the default display or this activity can be put on a
1606 * secondary display.
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001607 */
1608 boolean canBeLaunchedOnDisplay(int displayId) {
1609 return mService.mStackSupervisor.canPlaceEntityOnDisplay(displayId,
Riddle Hsu16567132018-08-16 21:37:47 +08001610 -1 /* don't check PID */, -1 /* don't check UID */, null /* activityInfo */);
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001611 }
1612
1613 /**
skuhne@google.com322347b2016-12-02 12:54:03 -08001614 * Check that a given bounds matches the application requested orientation.
1615 *
1616 * @param bounds The bounds to be tested.
1617 * @return True if the requested bounds are okay for a resizing request.
1618 */
Wale Ogunwale069bbd32017-02-03 07:58:14 -08001619 private boolean canResizeToBounds(Rect bounds) {
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001620 if (bounds == null || !inFreeformWindowingMode()) {
skuhne@google.com322347b2016-12-02 12:54:03 -08001621 // Note: If not on the freeform workspace, we ignore the bounds.
1622 return true;
1623 }
1624 final boolean landscape = bounds.width() > bounds.height();
Evan Roskydfe3da72018-10-26 17:21:06 -07001625 final Rect configBounds = getRequestedOverrideBounds();
skuhne@google.com322347b2016-12-02 12:54:03 -08001626 if (mResizeMode == RESIZE_MODE_FORCE_RESIZABLE_PRESERVE_ORIENTATION) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001627 return configBounds.isEmpty()
1628 || landscape == (configBounds.width() > configBounds.height());
skuhne@google.com322347b2016-12-02 12:54:03 -08001629 }
1630 return (mResizeMode != RESIZE_MODE_FORCE_RESIZABLE_PORTRAIT_ONLY || !landscape)
1631 && (mResizeMode != RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY || landscape);
1632 }
1633
Craig Mautner525f3d92013-05-07 14:01:50 -07001634 /**
Yorke Leebdef5372017-04-10 16:38:51 -07001635 * @return {@code true} if the task is being cleared for the purposes of being reused.
1636 */
1637 boolean isClearingToReuseTask() {
1638 return mReuseTask;
1639 }
1640
1641 /**
Craig Mautner525f3d92013-05-07 14:01:50 -07001642 * Find the activity in the history stack within the given task. Returns
1643 * the index within the history at which it's found, or < 0 if not found.
1644 */
1645 final ActivityRecord findActivityInHistoryLocked(ActivityRecord r) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001646 final ComponentName realActivity = r.mActivityComponent;
Craig Mautner525f3d92013-05-07 14:01:50 -07001647 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1648 ActivityRecord candidate = mActivities.get(activityNdx);
1649 if (candidate.finishing) {
1650 continue;
1651 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001652 if (candidate.mActivityComponent.equals(realActivity)) {
Craig Mautner525f3d92013-05-07 14:01:50 -07001653 return candidate;
1654 }
1655 }
1656 return null;
1657 }
1658
Winson Chunga449dc02014-05-16 11:15:04 -07001659 /** Updates the last task description values. */
1660 void updateTaskDescription() {
1661 // Traverse upwards looking for any break between main task activities and
1662 // utility activities.
1663 int activityNdx;
1664 final int numActivities = mActivities.size();
Wale Ogunwale3eadad72016-10-13 09:16:59 -07001665 final boolean relinquish = numActivities != 0 &&
1666 (mActivities.get(0).info.flags & FLAG_RELINQUISH_TASK_IDENTITY) != 0;
Winson Chunga449dc02014-05-16 11:15:04 -07001667 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
Craig Mautner21d24a22014-04-23 11:45:37 -07001668 ++activityNdx) {
Winson Chunga449dc02014-05-16 11:15:04 -07001669 final ActivityRecord r = mActivities.get(activityNdx);
Wale Ogunwale3eadad72016-10-13 09:16:59 -07001670 if (relinquish && (r.info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001671 // This will be the top activity for determining taskDescription. Pre-inc to
1672 // overcome initial decrement below.
1673 ++activityNdx;
1674 break;
1675 }
Winson Chunga449dc02014-05-16 11:15:04 -07001676 if (r.intent != null &&
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001677 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
Winson Chunga449dc02014-05-16 11:15:04 -07001678 break;
1679 }
1680 }
1681 if (activityNdx > 0) {
1682 // Traverse downwards starting below break looking for set label, icon.
1683 // Note that if there are activities in the task but none of them set the
1684 // recent activity values, then we do not fall back to the last set
1685 // values in the TaskRecord.
1686 String label = null;
Craig Mautner648f69b2014-09-18 14:16:26 -07001687 String iconFilename = null;
Matthew Ng54bc9422017-10-02 17:16:28 -07001688 int iconResource = -1;
Winson Chunga449dc02014-05-16 11:15:04 -07001689 int colorPrimary = 0;
Winson Chung1af8eda2016-02-05 17:55:56 +00001690 int colorBackground = 0;
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001691 int statusBarColor = 0;
1692 int navigationBarColor = 0;
Adrian Roos4c864592019-04-10 14:47:57 +02001693 boolean statusBarContrastWhenTransparent = false;
1694 boolean navigationBarContrastWhenTransparent = false;
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001695 boolean topActivity = true;
Winson Chunga449dc02014-05-16 11:15:04 -07001696 for (--activityNdx; activityNdx >= 0; --activityNdx) {
1697 final ActivityRecord r = mActivities.get(activityNdx);
Winson Chung80f80db2018-05-30 21:13:25 -07001698 if (r.mTaskOverlay) {
1699 continue;
1700 }
Winson Chunga449dc02014-05-16 11:15:04 -07001701 if (r.taskDescription != null) {
1702 if (label == null) {
1703 label = r.taskDescription.getLabel();
1704 }
Matthew Ng54bc9422017-10-02 17:16:28 -07001705 if (iconResource == -1) {
1706 iconResource = r.taskDescription.getIconResource();
1707 }
Craig Mautner648f69b2014-09-18 14:16:26 -07001708 if (iconFilename == null) {
1709 iconFilename = r.taskDescription.getIconFilename();
Winson Chunga449dc02014-05-16 11:15:04 -07001710 }
1711 if (colorPrimary == 0) {
1712 colorPrimary = r.taskDescription.getPrimaryColor();
Winson Chunga449dc02014-05-16 11:15:04 -07001713 }
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001714 if (topActivity) {
Winson Chung1af8eda2016-02-05 17:55:56 +00001715 colorBackground = r.taskDescription.getBackgroundColor();
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001716 statusBarColor = r.taskDescription.getStatusBarColor();
1717 navigationBarColor = r.taskDescription.getNavigationBarColor();
Adrian Roos4c864592019-04-10 14:47:57 +02001718 statusBarContrastWhenTransparent =
1719 r.taskDescription.getEnsureStatusBarContrastWhenTransparent();
1720 navigationBarContrastWhenTransparent =
1721 r.taskDescription.getEnsureNavigationBarContrastWhenTransparent();
Winson Chung1af8eda2016-02-05 17:55:56 +00001722 }
Winson Chunga449dc02014-05-16 11:15:04 -07001723 }
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001724 topActivity = false;
Winson Chunga449dc02014-05-16 11:15:04 -07001725 }
Matthew Ng54bc9422017-10-02 17:16:28 -07001726 lastTaskDescription = new TaskDescription(label, null, iconResource, iconFilename,
Adrian Roos4c864592019-04-10 14:47:57 +02001727 colorPrimary, colorBackground, statusBarColor, navigationBarColor,
1728 statusBarContrastWhenTransparent, navigationBarContrastWhenTransparent);
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001729 if (mTask != null) {
1730 mTask.setTaskDescription(lastTaskDescription);
Jorim Jaggi829b9cd2017-01-23 16:20:53 +01001731 }
Winson Chungec396d62014-08-06 17:08:00 -07001732 // Update the task affiliation color if we are the parent of the group
1733 if (taskId == mAffiliatedTaskId) {
1734 mAffiliatedTaskColor = lastTaskDescription.getPrimaryColor();
1735 }
Winson Chunga449dc02014-05-16 11:15:04 -07001736 }
1737 }
1738
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001739 int findEffectiveRootIndex() {
Craig Mautner4767f4b2014-09-18 15:38:33 -07001740 int effectiveNdx = 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001741 final int topActivityNdx = mActivities.size() - 1;
Dianne Hackborn39569af2014-09-23 10:56:58 -07001742 for (int activityNdx = 0; activityNdx <= topActivityNdx; ++activityNdx) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001743 final ActivityRecord r = mActivities.get(activityNdx);
1744 if (r.finishing) {
1745 continue;
1746 }
Craig Mautner4767f4b2014-09-18 15:38:33 -07001747 effectiveNdx = activityNdx;
Wale Ogunwale3eadad72016-10-13 09:16:59 -07001748 if ((r.info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001749 break;
1750 }
1751 }
Craig Mautner4767f4b2014-09-18 15:38:33 -07001752 return effectiveNdx;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001753 }
1754
1755 void updateEffectiveIntent() {
1756 final int effectiveRootIndex = findEffectiveRootIndex();
1757 final ActivityRecord r = mActivities.get(effectiveRootIndex);
Winson Chungfee26772014-08-05 12:21:52 -07001758 setIntent(r);
Winson Chung8d9009e2017-11-16 15:43:05 -08001759
1760 // Update the task description when the activities change
1761 updateTaskDescription();
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001762 }
1763
Evan Rosky730f6e82018-12-03 17:40:11 -08001764 void adjustForMinimalTaskDimensions(Rect bounds, Rect previousBounds) {
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001765 if (bounds == null) {
1766 return;
1767 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001768 int minWidth = mMinWidth;
1769 int minHeight = mMinHeight;
Robert Carr9c5867d2016-03-10 15:52:46 -08001770 // If the task has no requested minimal size, we'd like to enforce a minimal size
1771 // so that the user can not render the task too small to manipulate. We don't need
1772 // to do this for the pinned stack as the bounds are controlled by the system.
Evan Rosky1ac84462018-11-13 11:25:30 -08001773 if (!inPinnedWindowingMode() && mStack != null) {
Garfield Tan4a48a7f2018-10-02 14:23:55 -07001774 final int defaultMinSizeDp =
Wale Ogunwaled32da472018-11-16 07:19:28 -08001775 mService.mRootActivityContainer.mDefaultMinSizeOfResizeableTaskDp;
Garfield Tan4a48a7f2018-10-02 14:23:55 -07001776 final ActivityDisplay display =
Wale Ogunwaled32da472018-11-16 07:19:28 -08001777 mService.mRootActivityContainer.getActivityDisplay(mStack.mDisplayId);
Garfield Tan4a48a7f2018-10-02 14:23:55 -07001778 final float density =
1779 (float) display.getConfiguration().densityDpi / DisplayMetrics.DENSITY_DEFAULT;
1780 final int defaultMinSize = (int) (defaultMinSizeDp * density);
1781
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001782 if (minWidth == INVALID_MIN_SIZE) {
Garfield Tan4a48a7f2018-10-02 14:23:55 -07001783 minWidth = defaultMinSize;
Andrii Kulian2e751b82016-03-16 16:59:32 -07001784 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001785 if (minHeight == INVALID_MIN_SIZE) {
Garfield Tan4a48a7f2018-10-02 14:23:55 -07001786 minHeight = defaultMinSize;
Andrii Kulian2e751b82016-03-16 16:59:32 -07001787 }
Robert Carr9c5867d2016-03-10 15:52:46 -08001788 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001789 final boolean adjustWidth = minWidth > bounds.width();
1790 final boolean adjustHeight = minHeight > bounds.height();
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001791 if (!(adjustWidth || adjustHeight)) {
1792 return;
1793 }
1794
1795 if (adjustWidth) {
Garfield Tan020607d2018-12-17 17:01:58 -08001796 if (!previousBounds.isEmpty() && bounds.right == previousBounds.right) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001797 bounds.left = bounds.right - minWidth;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001798 } else {
1799 // Either left bounds match, or neither match, or the previous bounds were
1800 // fullscreen and we default to keeping left.
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001801 bounds.right = bounds.left + minWidth;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001802 }
1803 }
1804 if (adjustHeight) {
Garfield Tan020607d2018-12-17 17:01:58 -08001805 if (!previousBounds.isEmpty() && bounds.bottom == previousBounds.bottom) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001806 bounds.top = bounds.bottom - minHeight;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001807 } else {
1808 // Either top bounds match, or neither match, or the previous bounds were
1809 // fullscreen and we default to keeping top.
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001810 bounds.bottom = bounds.top + minHeight;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001811 }
1812 }
1813 }
1814
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001815 /**
1816 * Update task's override configuration based on the bounds.
Jorim Jaggi0a932142016-02-01 17:42:25 -08001817 * @param bounds The bounds of the task.
Andrii Kulian8072d112016-09-16 11:11:01 -07001818 * @return True if the override configuration was updated.
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001819 */
Andrii Kulian8072d112016-09-16 11:11:01 -07001820 boolean updateOverrideConfiguration(Rect bounds) {
Jorim Jaggi0a932142016-02-01 17:42:25 -08001821 return updateOverrideConfiguration(bounds, null /* insetBounds */);
1822 }
1823
Evan Rosky9ba524e2018-01-03 16:27:56 -08001824 void setLastNonFullscreenBounds(Rect bounds) {
1825 if (mLastNonFullscreenBounds == null) {
1826 mLastNonFullscreenBounds = new Rect(bounds);
1827 } else {
1828 mLastNonFullscreenBounds.set(bounds);
1829 }
1830 }
1831
Jorim Jaggi0a932142016-02-01 17:42:25 -08001832 /**
1833 * Update task's override configuration based on the bounds.
1834 * @param bounds The bounds of the task.
1835 * @param insetBounds The bounds used to calculate the system insets, which is used here to
1836 * subtract the navigation bar/status bar size from the screen size reported
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001837 * to the application. See {@link IActivityTaskManager#resizeDockedStack}.
Andrii Kulian8072d112016-09-16 11:11:01 -07001838 * @return True if the override configuration was updated.
Jorim Jaggi0a932142016-02-01 17:42:25 -08001839 */
Andrii Kulian8072d112016-09-16 11:11:01 -07001840 boolean updateOverrideConfiguration(Rect bounds, @Nullable Rect insetBounds) {
Evan Rosky1ac84462018-11-13 11:25:30 -08001841 final boolean hasSetDisplayedBounds = (insetBounds != null && !insetBounds.isEmpty());
1842 if (hasSetDisplayedBounds) {
1843 setDisplayedBounds(bounds);
1844 } else {
1845 setDisplayedBounds(null);
1846 }
1847 // "steady" bounds do not include any temporary offsets from animation or interaction.
1848 Rect steadyBounds = hasSetDisplayedBounds ? insetBounds : bounds;
1849 if (equivalentRequestedOverrideBounds(steadyBounds)) {
Andrii Kulian8072d112016-09-16 11:11:01 -07001850 return false;
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001851 }
Bryce Leef3c6a472017-11-14 14:53:06 -08001852
Evan Rosky1ac84462018-11-13 11:25:30 -08001853 mTmpConfig.setTo(getResolvedOverrideConfiguration());
1854 setBounds(steadyBounds);
1855 return !mTmpConfig.equals(getResolvedOverrideConfiguration());
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08001856 }
Wale Ogunwale5f986092015-12-04 15:35:38 -08001857
Bryce Leec4ab62a2018-03-05 14:19:26 -08001858 /**
1859 * This should be called when an child activity changes state. This should only
1860 * be called from
1861 * {@link ActivityRecord#setState(ActivityState, String)} .
1862 * @param record The {@link ActivityRecord} whose state has changed.
1863 * @param state The new state.
1864 * @param reason The reason for the change.
1865 */
1866 void onActivityStateChanged(ActivityRecord record, ActivityState state, String reason) {
1867 final ActivityStack parent = getStack();
1868
1869 if (parent != null) {
1870 parent.onActivityStateChanged(record, state, reason);
1871 }
1872 }
1873
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08001874 @Override
1875 public void onConfigurationChanged(Configuration newParentConfig) {
Evan Rosky730f6e82018-12-03 17:40:11 -08001876 // Check if the new configuration supports persistent bounds (eg. is Freeform) and if so
1877 // restore the last recorded non-fullscreen bounds.
1878 final boolean prevPersistTaskBounds = getWindowConfiguration().persistTaskBounds();
1879 final boolean nextPersistTaskBounds =
1880 getRequestedOverrideConfiguration().windowConfiguration.persistTaskBounds()
1881 || newParentConfig.windowConfiguration.persistTaskBounds();
1882 if (!prevPersistTaskBounds && nextPersistTaskBounds
1883 && mLastNonFullscreenBounds != null && !mLastNonFullscreenBounds.isEmpty()) {
1884 // Bypass onRequestedOverrideConfigurationChanged here to avoid infinite loop.
1885 getRequestedOverrideConfiguration().windowConfiguration
1886 .setBounds(mLastNonFullscreenBounds);
1887 }
1888
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08001889 final boolean wasInMultiWindowMode = inMultiWindowMode();
1890 super.onConfigurationChanged(newParentConfig);
1891 if (wasInMultiWindowMode != inMultiWindowMode()) {
Winson Chung5af42fc2017-03-24 17:11:33 -07001892 mService.mStackSupervisor.scheduleUpdateMultiWindowMode(this);
Wale Ogunwale5f986092015-12-04 15:35:38 -08001893 }
Evan Rosky730f6e82018-12-03 17:40:11 -08001894
1895 // If the configuration supports persistent bounds (eg. Freeform), keep track of the
1896 // current (non-fullscreen) bounds for persistence.
Evan Rosky1ac84462018-11-13 11:25:30 -08001897 if (getWindowConfiguration().persistTaskBounds()) {
1898 final Rect currentBounds = getRequestedOverrideBounds();
1899 if (!currentBounds.isEmpty()) {
1900 setLastNonFullscreenBounds(currentBounds);
1901 }
1902 }
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08001903 // TODO: Should also take care of Pip mode changes here.
Garfield Tan891146c2018-10-09 12:14:00 -07001904
1905 saveLaunchingStateIfNeeded();
1906 }
1907
1908 /**
1909 * Saves launching state if necessary so that we can launch the activity to its latest state.
1910 * It only saves state if this task has been shown to user and it's in fullscreen or freeform
1911 * mode.
1912 */
1913 void saveLaunchingStateIfNeeded() {
1914 if (!hasBeenVisible) {
1915 // Not ever visible to user.
1916 return;
1917 }
1918
1919 final int windowingMode = getWindowingMode();
1920 if (windowingMode != WindowConfiguration.WINDOWING_MODE_FULLSCREEN
1921 && windowingMode != WindowConfiguration.WINDOWING_MODE_FREEFORM) {
1922 return;
1923 }
1924
1925 // Saves the new state so that we can launch the activity at the same location.
1926 mService.mStackSupervisor.mLaunchParamsPersister.saveTask(this);
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001927 }
1928
Evan Roskyed6767f2018-10-26 17:21:06 -07001929 /**
Evan Rosky1ac84462018-11-13 11:25:30 -08001930 * Adjust bounds to stay within stack bounds.
1931 *
1932 * Since bounds might be outside of stack bounds, this method tries to move the bounds in a way
1933 * that keep them unchanged, but be contained within the stack bounds.
1934 *
1935 * @param bounds Bounds to be adjusted.
1936 * @param stackBounds Bounds within which the other bounds should remain.
Evan Rosky60dba2f2019-02-01 10:58:38 -08001937 * @param overlapPxX The amount of px required to be visible in the X dimension.
1938 * @param overlapPxY The amount of px required to be visible in the Y dimension.
Evan Rosky1ac84462018-11-13 11:25:30 -08001939 */
Evan Rosky60dba2f2019-02-01 10:58:38 -08001940 private static void fitWithinBounds(Rect bounds, Rect stackBounds, int overlapPxX,
1941 int overlapPxY) {
Evan Rosky1ac84462018-11-13 11:25:30 -08001942 if (stackBounds == null || stackBounds.isEmpty() || stackBounds.contains(bounds)) {
1943 return;
1944 }
1945
Evan Rosky60dba2f2019-02-01 10:58:38 -08001946 // For each side of the parent (eg. left), check if the opposing side of the window (eg.
1947 // right) is at least overlap pixels away. If less, offset the window by that difference.
1948 int horizontalDiff = 0;
1949 // If window is smaller than overlap, use it's smallest dimension instead
1950 int overlapLR = Math.min(overlapPxX, bounds.width());
1951 if (bounds.right < (stackBounds.left + overlapLR)) {
1952 horizontalDiff = overlapLR - (bounds.right - stackBounds.left);
1953 } else if (bounds.left > (stackBounds.right - overlapLR)) {
1954 horizontalDiff = -(overlapLR - (stackBounds.right - bounds.left));
Evan Rosky1ac84462018-11-13 11:25:30 -08001955 }
Evan Rosky60dba2f2019-02-01 10:58:38 -08001956 int verticalDiff = 0;
1957 int overlapTB = Math.min(overlapPxY, bounds.width());
1958 if (bounds.bottom < (stackBounds.top + overlapTB)) {
1959 verticalDiff = overlapTB - (bounds.bottom - stackBounds.top);
1960 } else if (bounds.top > (stackBounds.bottom - overlapTB)) {
1961 verticalDiff = -(overlapTB - (stackBounds.bottom - bounds.top));
Evan Rosky1ac84462018-11-13 11:25:30 -08001962 }
Evan Rosky60dba2f2019-02-01 10:58:38 -08001963 bounds.offset(horizontalDiff, verticalDiff);
Evan Rosky1ac84462018-11-13 11:25:30 -08001964 }
1965
1966 /**
Evan Roskyed6767f2018-10-26 17:21:06 -07001967 * Displayed bounds are used to set where the task is drawn at any given time. This is
1968 * separate from its actual bounds so that the app doesn't see any meaningful configuration
1969 * changes during transitionary periods.
1970 */
1971 void setDisplayedBounds(Rect bounds) {
1972 if (bounds == null) {
1973 mDisplayedBounds.setEmpty();
1974 } else {
1975 mDisplayedBounds.set(bounds);
1976 }
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001977 if (mTask != null) {
1978 mTask.setOverrideDisplayedBounds(
Evan Roskyed6767f2018-10-26 17:21:06 -07001979 mDisplayedBounds.isEmpty() ? null : mDisplayedBounds);
1980 }
1981 }
1982
1983 /**
1984 * Gets the current overridden displayed bounds. These will be empty if the task is not
1985 * currently overriding where it is displayed.
1986 */
1987 Rect getDisplayedBounds() {
1988 return mDisplayedBounds;
1989 }
1990
1991 /**
1992 * @return {@code true} if this has overridden displayed bounds.
1993 */
1994 boolean hasDisplayedBounds() {
1995 return !mDisplayedBounds.isEmpty();
1996 }
1997
Evan Rosky1ac84462018-11-13 11:25:30 -08001998 /**
1999 * Intersects inOutBounds with intersectBounds-intersectInsets. If inOutBounds is larger than
2000 * intersectBounds on a side, then the respective side will not be intersected.
2001 *
2002 * The assumption is that if inOutBounds is initially larger than intersectBounds, then the
2003 * inset on that side is no-longer applicable. This scenario happens when a task's minimal
2004 * bounds are larger than the provided parent/display bounds.
2005 *
2006 * @param inOutBounds the bounds to intersect.
2007 * @param intersectBounds the bounds to intersect with.
2008 * @param intersectInsets insets to apply to intersectBounds before intersecting.
2009 */
Riddle Hsu74826262019-04-17 14:57:42 +08002010 static void intersectWithInsetsIfFits(
Evan Rosky1ac84462018-11-13 11:25:30 -08002011 Rect inOutBounds, Rect intersectBounds, Rect intersectInsets) {
2012 if (inOutBounds.right <= intersectBounds.right) {
2013 inOutBounds.right =
2014 Math.min(intersectBounds.right - intersectInsets.right, inOutBounds.right);
2015 }
2016 if (inOutBounds.bottom <= intersectBounds.bottom) {
2017 inOutBounds.bottom =
2018 Math.min(intersectBounds.bottom - intersectInsets.bottom, inOutBounds.bottom);
2019 }
2020 if (inOutBounds.left >= intersectBounds.left) {
2021 inOutBounds.left =
2022 Math.max(intersectBounds.left + intersectInsets.left, inOutBounds.left);
2023 }
2024 if (inOutBounds.top >= intersectBounds.top) {
2025 inOutBounds.top =
2026 Math.max(intersectBounds.top + intersectInsets.top, inOutBounds.top);
2027 }
2028 }
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08002029
Evan Rosky1ac84462018-11-13 11:25:30 -08002030 /**
2031 * Gets bounds with non-decor and stable insets applied respectively.
2032 *
2033 * If bounds overhangs the display, those edges will not get insets. See
2034 * {@link #intersectWithInsetsIfFits}
2035 *
2036 * @param outNonDecorBounds where to place bounds with non-decor insets applied.
2037 * @param outStableBounds where to place bounds with stable insets applied.
2038 * @param bounds the bounds to inset.
2039 */
2040 private void calculateInsetFrames(Rect outNonDecorBounds, Rect outStableBounds, Rect bounds,
2041 DisplayInfo displayInfo) {
2042 outNonDecorBounds.set(bounds);
2043 outStableBounds.set(bounds);
2044 if (getStack() == null || getStack().getDisplay() == null) {
2045 return;
2046 }
2047 DisplayPolicy policy = getStack().getDisplay().mDisplayContent.getDisplayPolicy();
2048 if (policy == null) {
2049 return;
2050 }
2051 mTmpBounds.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight);
Bryce Lee7566d762017-03-30 09:34:15 -07002052
Riddle Hsu61987bc2019-04-03 13:08:47 +08002053 policy.getNonDecorInsetsLw(displayInfo.rotation, displayInfo.logicalWidth,
2054 displayInfo.logicalHeight, displayInfo.displayCutout, mTmpInsets);
Evan Rosky1ac84462018-11-13 11:25:30 -08002055 intersectWithInsetsIfFits(outNonDecorBounds, mTmpBounds, mTmpInsets);
Riddle Hsu61987bc2019-04-03 13:08:47 +08002056
2057 policy.convertNonDecorInsetsToStableInsets(mTmpInsets, displayInfo.rotation);
2058 intersectWithInsetsIfFits(outStableBounds, mTmpBounds, mTmpInsets);
Evan Rosky1ac84462018-11-13 11:25:30 -08002059 }
2060
2061 /**
2062 * Asks docked-divider controller for the smallestwidthdp given bounds.
2063 * @param bounds bounds to calculate smallestwidthdp for.
2064 */
2065 private int getSmallestScreenWidthDpForDockedBounds(Rect bounds) {
2066 DisplayContent dc = mStack.getDisplay().mDisplayContent;
2067 if (dc != null) {
2068 return dc.getDockedDividerController().getSmallestWidthDpForBounds(bounds);
2069 }
2070 return Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
2071 }
2072
Riddle Hsu0a343c32018-12-21 00:40:48 +08002073 void computeConfigResourceOverrides(@NonNull Configuration inOutConfig,
2074 @NonNull Configuration parentConfig) {
Riddle Hsu61987bc2019-04-03 13:08:47 +08002075 computeConfigResourceOverrides(inOutConfig, parentConfig, null /* compatInsets */);
Riddle Hsu0a343c32018-12-21 00:40:48 +08002076 }
2077
Evan Rosky1ac84462018-11-13 11:25:30 -08002078 /**
2079 * Calculates configuration values used by the client to get resources. This should be run
2080 * using app-facing bounds (bounds unmodified by animations or transient interactions).
2081 *
2082 * This assumes bounds are non-empty/null. For the null-bounds case, the caller is likely
2083 * configuring an "inherit-bounds" window which means that all configuration settings would
2084 * just be inherited from the parent configuration.
2085 **/
Evan Rosky730f6e82018-12-03 17:40:11 -08002086 void computeConfigResourceOverrides(@NonNull Configuration inOutConfig,
Riddle Hsu61987bc2019-04-03 13:08:47 +08002087 @NonNull Configuration parentConfig,
2088 @Nullable ActivityRecord.CompatDisplayInsets compatInsets) {
Evan Rosky1ac84462018-11-13 11:25:30 -08002089 int windowingMode = inOutConfig.windowConfiguration.getWindowingMode();
2090 if (windowingMode == WINDOWING_MODE_UNDEFINED) {
2091 windowingMode = parentConfig.windowConfiguration.getWindowingMode();
Winson Chungbdc646f2017-02-13 12:12:22 -08002092 }
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08002093
Evan Rosky1ac84462018-11-13 11:25:30 -08002094 float density = inOutConfig.densityDpi;
2095 if (density == Configuration.DENSITY_DPI_UNDEFINED) {
2096 density = parentConfig.densityDpi;
2097 }
2098 density *= DisplayMetrics.DENSITY_DEFAULT_SCALE;
Winson Chung60c1aba2017-03-14 17:47:42 -07002099
Evan Rosky730f6e82018-12-03 17:40:11 -08002100 final Rect bounds = inOutConfig.windowConfiguration.getBounds();
Evan Rosky1ac84462018-11-13 11:25:30 -08002101 Rect outAppBounds = inOutConfig.windowConfiguration.getAppBounds();
2102 if (outAppBounds == null || outAppBounds.isEmpty()) {
2103 inOutConfig.windowConfiguration.setAppBounds(bounds);
2104 outAppBounds = inOutConfig.windowConfiguration.getAppBounds();
2105 }
Riddle Hsu61987bc2019-04-03 13:08:47 +08002106 // Non-null compatibility insets means the activity prefers to keep its original size, so
2107 // the out bounds doesn't need to be restricted by the parent.
2108 final boolean insideParentBounds = compatInsets == null;
Riddle Hsu0a343c32018-12-21 00:40:48 +08002109 if (insideParentBounds && windowingMode != WINDOWING_MODE_FREEFORM) {
Evan Rosky1ac84462018-11-13 11:25:30 -08002110 final Rect parentAppBounds = parentConfig.windowConfiguration.getAppBounds();
2111 if (parentAppBounds != null && !parentAppBounds.isEmpty()) {
2112 outAppBounds.intersect(parentAppBounds);
2113 }
2114 }
2115
2116 if (inOutConfig.screenWidthDp == Configuration.SCREEN_WIDTH_DP_UNDEFINED
2117 || inOutConfig.screenHeightDp == Configuration.SCREEN_HEIGHT_DP_UNDEFINED) {
Riddle Hsu0a343c32018-12-21 00:40:48 +08002118 if (insideParentBounds && mStack != null) {
Evan Rosky1ac84462018-11-13 11:25:30 -08002119 final DisplayInfo di = new DisplayInfo();
2120 mStack.getDisplay().mDisplay.getDisplayInfo(di);
2121
2122 // For calculating screenWidthDp, screenWidthDp, we use the stable inset screen
2123 // area, i.e. the screen area without the system bars.
2124 // The non decor inset are areas that could never be removed in Honeycomb. See
2125 // {@link WindowManagerPolicy#getNonDecorInsetsLw}.
2126 calculateInsetFrames(mTmpNonDecorBounds, mTmpStableBounds, bounds, di);
2127 } else {
Riddle Hsu61987bc2019-04-03 13:08:47 +08002128 // Apply the given non-decor and stable insets to calculate the corresponding bounds
2129 // for screen size of configuration.
2130 final int rotation = parentConfig.windowConfiguration.getRotation();
2131 if (rotation != ROTATION_UNDEFINED && compatInsets != null) {
Riddle Hsu74826262019-04-17 14:57:42 +08002132 mTmpNonDecorBounds.set(bounds);
2133 mTmpStableBounds.set(bounds);
2134 compatInsets.getDisplayBoundsByRotation(mTmpBounds, rotation);
Riddle Hsu61987bc2019-04-03 13:08:47 +08002135 intersectWithInsetsIfFits(mTmpNonDecorBounds, mTmpBounds,
2136 compatInsets.mNonDecorInsets[rotation]);
2137 intersectWithInsetsIfFits(mTmpStableBounds, mTmpBounds,
2138 compatInsets.mStableInsets[rotation]);
Riddle Hsu74826262019-04-17 14:57:42 +08002139 outAppBounds.set(mTmpNonDecorBounds);
2140 } else {
2141 // Set to app bounds because it excludes decor insets.
2142 mTmpNonDecorBounds.set(outAppBounds);
2143 mTmpStableBounds.set(outAppBounds);
Riddle Hsu61987bc2019-04-03 13:08:47 +08002144 }
Evan Rosky1ac84462018-11-13 11:25:30 -08002145 }
2146
2147 if (inOutConfig.screenWidthDp == Configuration.SCREEN_WIDTH_DP_UNDEFINED) {
Riddle Hsu0a343c32018-12-21 00:40:48 +08002148 final int overrideScreenWidthDp = (int) (mTmpStableBounds.width() / density);
2149 inOutConfig.screenWidthDp = insideParentBounds
2150 ? Math.min(overrideScreenWidthDp, parentConfig.screenWidthDp)
2151 : overrideScreenWidthDp;
Evan Rosky1ac84462018-11-13 11:25:30 -08002152 }
2153 if (inOutConfig.screenHeightDp == Configuration.SCREEN_HEIGHT_DP_UNDEFINED) {
Riddle Hsu0a343c32018-12-21 00:40:48 +08002154 final int overrideScreenHeightDp = (int) (mTmpStableBounds.height() / density);
2155 inOutConfig.screenHeightDp = insideParentBounds
Riddle Hsu88e3c8732019-02-18 19:15:12 +08002156 ? Math.min(overrideScreenHeightDp, parentConfig.screenHeightDp)
Riddle Hsu0a343c32018-12-21 00:40:48 +08002157 : overrideScreenHeightDp;
Evan Rosky1ac84462018-11-13 11:25:30 -08002158 }
2159
2160 if (inOutConfig.smallestScreenWidthDp
2161 == Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
2162 if (WindowConfiguration.isFloating(windowingMode)) {
2163 // For floating tasks, calculate the smallest width from the bounds of the task
2164 inOutConfig.smallestScreenWidthDp = (int) (
2165 Math.min(bounds.width(), bounds.height()) / density);
2166 } else if (WindowConfiguration.isSplitScreenWindowingMode(windowingMode)) {
2167 // Iterating across all screen orientations, and return the minimum of the task
2168 // width taking into account that the bounds might change because the snap
2169 // algorithm snaps to a different value
Evan Rosky730f6e82018-12-03 17:40:11 -08002170 inOutConfig.smallestScreenWidthDp =
2171 getSmallestScreenWidthDpForDockedBounds(bounds);
Evan Rosky1ac84462018-11-13 11:25:30 -08002172 }
2173 // otherwise, it will just inherit
2174 }
2175 }
2176
Evan Rosky730f6e82018-12-03 17:40:11 -08002177 if (inOutConfig.orientation == ORIENTATION_UNDEFINED) {
Evan Rosky1ac84462018-11-13 11:25:30 -08002178 inOutConfig.orientation = (inOutConfig.screenWidthDp <= inOutConfig.screenHeightDp)
Riddle Hsu0a343c32018-12-21 00:40:48 +08002179 ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE;
Evan Rosky1ac84462018-11-13 11:25:30 -08002180 }
2181 if (inOutConfig.screenLayout == Configuration.SCREENLAYOUT_UNDEFINED) {
2182 // For calculating screen layout, we need to use the non-decor inset screen area for the
2183 // calculation for compatibility reasons, i.e. screen area without system bars that
2184 // could never go away in Honeycomb.
2185 final int compatScreenWidthDp = (int) (mTmpNonDecorBounds.width() / density);
2186 final int compatScreenHeightDp = (int) (mTmpNonDecorBounds.height() / density);
2187 // We're only overriding LONG, SIZE and COMPAT parts of screenLayout, so we start
2188 // override calculation with partial default.
2189 // Reducing the screen layout starting from its parent config.
2190 final int sl = parentConfig.screenLayout
2191 & (Configuration.SCREENLAYOUT_LONG_MASK | Configuration.SCREENLAYOUT_SIZE_MASK);
2192 final int longSize = Math.max(compatScreenHeightDp, compatScreenWidthDp);
2193 final int shortSize = Math.min(compatScreenHeightDp, compatScreenWidthDp);
2194 inOutConfig.screenLayout = Configuration.reduceScreenLayout(sl, longSize, shortSize);
2195 }
2196 }
2197
Evan Rosky1ac84462018-11-13 11:25:30 -08002198 @Override
2199 void resolveOverrideConfiguration(Configuration newParentConfig) {
Evan Rosky730f6e82018-12-03 17:40:11 -08002200 mTmpBounds.set(getResolvedOverrideConfiguration().windowConfiguration.getBounds());
2201 super.resolveOverrideConfiguration(newParentConfig);
2202 int windowingMode =
2203 getRequestedOverrideConfiguration().windowConfiguration.getWindowingMode();
2204 if (windowingMode == WINDOWING_MODE_UNDEFINED) {
2205 windowingMode = newParentConfig.windowConfiguration.getWindowingMode();
2206 }
2207 Rect outOverrideBounds =
2208 getResolvedOverrideConfiguration().windowConfiguration.getBounds();
2209
2210 if (windowingMode == WINDOWING_MODE_FULLSCREEN) {
Riddle Hsu74826262019-04-17 14:57:42 +08002211 computeFullscreenBounds(outOverrideBounds, null /* refActivity */,
2212 newParentConfig.windowConfiguration.getBounds(),
2213 newParentConfig.orientation);
Evan Rosky730f6e82018-12-03 17:40:11 -08002214 }
2215
2216 if (outOverrideBounds.isEmpty()) {
2217 // If the task fills the parent, just inherit all the other configs from parent.
2218 return;
2219 }
2220
2221 adjustForMinimalTaskDimensions(outOverrideBounds, mTmpBounds);
2222 if (windowingMode == WINDOWING_MODE_FREEFORM) {
2223 // by policy, make sure the window remains within parent somewhere
Evan Rosky60dba2f2019-02-01 10:58:38 -08002224 final float density =
2225 ((float) newParentConfig.densityDpi) / DisplayMetrics.DENSITY_DEFAULT;
GyeHun Jeon84b30d22019-04-24 14:20:15 -07002226 final Rect parentBounds =
2227 new Rect(newParentConfig.windowConfiguration.getBounds());
2228 final ActivityDisplay display = mStack.getDisplay();
2229 if (display != null && display.mDisplayContent != null) {
2230 // If a freeform window moves below system bar, there is no way to move it again
2231 // by touch. Because its caption is covered by system bar. So we exclude them
2232 // from stack bounds. and then caption will be shown inside stable area.
2233 final Rect stableBounds = new Rect();
2234 display.mDisplayContent.getStableRect(stableBounds);
2235 parentBounds.intersect(stableBounds);
2236 }
2237
2238 fitWithinBounds(outOverrideBounds, parentBounds,
Evan Rosky60dba2f2019-02-01 10:58:38 -08002239 (int) (density * WindowState.MINIMUM_VISIBLE_WIDTH_IN_DP),
2240 (int) (density * WindowState.MINIMUM_VISIBLE_HEIGHT_IN_DP));
GyeHun Jeon84b30d22019-04-24 14:20:15 -07002241
2242 // Prevent to overlap caption with stable insets.
2243 final int offsetTop = parentBounds.top - outOverrideBounds.top;
2244 if (offsetTop > 0) {
2245 outOverrideBounds.offset(0, offsetTop);
2246 }
Evan Rosky730f6e82018-12-03 17:40:11 -08002247 }
2248 computeConfigResourceOverrides(getResolvedOverrideConfiguration(), newParentConfig);
Jorim Jaggia95ca8d2016-01-15 22:54:46 -08002249 }
2250
Riddle Hsu74826262019-04-17 14:57:42 +08002251 /** @see WindowContainer#handlesOrientationChangeFromDescendant */
2252 boolean handlesOrientationChangeFromDescendant() {
2253 return mTask != null && mTask.getParent() != null
2254 && mTask.getParent().handlesOrientationChangeFromDescendant();
2255 }
2256
2257 /**
2258 * Compute bounds (letterbox or pillarbox) for {@link #WINDOWING_MODE_FULLSCREEN} when the
2259 * parent doesn't handle the orientation change and the requested orientation is different from
2260 * the parent.
2261 */
2262 void computeFullscreenBounds(@NonNull Rect outBounds, @Nullable ActivityRecord refActivity,
2263 @NonNull Rect parentBounds, int parentOrientation) {
2264 // In FULLSCREEN mode, always start with empty bounds to indicate "fill parent".
2265 outBounds.setEmpty();
2266 if (handlesOrientationChangeFromDescendant()) {
2267 return;
2268 }
2269 if (refActivity == null) {
2270 // Use the top activity as the reference of orientation. Don't include overlays because
2271 // it is usually not the actual content or just temporarily shown.
2272 // E.g. ForcedResizableInfoActivity.
2273 refActivity = getTopActivity(false /* includeOverlays */);
2274 }
2275
2276 // If the task or the reference activity requires a different orientation (either by
2277 // override or activityInfo), make it fit the available bounds by scaling down its bounds.
2278 final int overrideOrientation = getRequestedOverrideConfiguration().orientation;
2279 final int forcedOrientation =
2280 (overrideOrientation != ORIENTATION_UNDEFINED || refActivity == null)
2281 ? overrideOrientation : refActivity.getRequestedConfigurationOrientation();
2282 if (forcedOrientation == ORIENTATION_UNDEFINED || forcedOrientation == parentOrientation) {
2283 return;
2284 }
2285
2286 final int parentWidth = parentBounds.width();
2287 final int parentHeight = parentBounds.height();
2288 final float aspect = ((float) parentHeight) / parentWidth;
2289 if (forcedOrientation == ORIENTATION_LANDSCAPE) {
2290 final int height = (int) (parentWidth / aspect);
2291 final int top = parentBounds.centerY() - height / 2;
2292 outBounds.set(parentBounds.left, top, parentBounds.right, top + height);
2293 } else {
2294 final int width = (int) (parentHeight * aspect);
2295 final int left = parentBounds.centerX() - width / 2;
2296 outBounds.set(left, parentBounds.top, left + width, parentBounds.bottom);
2297 }
2298 }
2299
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08002300 Rect updateOverrideConfigurationFromLaunchBounds() {
Bryce Leef3c6a472017-11-14 14:53:06 -08002301 final Rect bounds = getLaunchBounds();
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08002302 updateOverrideConfiguration(bounds);
Bryce Leef3c6a472017-11-14 14:53:06 -08002303 if (bounds != null && !bounds.isEmpty()) {
2304 // TODO: Review if we actually want to do this - we are setting the launch bounds
2305 // directly here.
Evan Roskydfe3da72018-10-26 17:21:06 -07002306 bounds.set(getRequestedOverrideBounds());
Andrii Kulian73336d812016-03-24 12:56:08 -07002307 }
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08002308 return bounds;
2309 }
2310
Wale Ogunwale935e5022015-11-10 12:36:10 -08002311 /** Updates the task's bounds and override configuration to match what is expected for the
2312 * input stack. */
2313 void updateOverrideConfigurationForStack(ActivityStack inStack) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07002314 if (mStack != null && mStack == inStack) {
Wale Ogunwale935e5022015-11-10 12:36:10 -08002315 return;
2316 }
2317
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002318 if (inStack.inFreeformWindowingMode()) {
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002319 if (!isResizeable()) {
Wale Ogunwale935e5022015-11-10 12:36:10 -08002320 throw new IllegalArgumentException("Can not position non-resizeable task="
2321 + this + " in stack=" + inStack);
2322 }
Bryce Leef3c6a472017-11-14 14:53:06 -08002323 if (!matchParentBounds()) {
Wale Ogunwale935e5022015-11-10 12:36:10 -08002324 return;
2325 }
2326 if (mLastNonFullscreenBounds != null) {
2327 updateOverrideConfiguration(mLastNonFullscreenBounds);
2328 } else {
Bryce Leeec55eb02017-12-05 20:51:27 -08002329 mService.mStackSupervisor.getLaunchParamsController().layoutTask(this, null);
Wale Ogunwale935e5022015-11-10 12:36:10 -08002330 }
2331 } else {
Evan Roskydfe3da72018-10-26 17:21:06 -07002332 updateOverrideConfiguration(inStack.getRequestedOverrideBounds());
Wale Ogunwale935e5022015-11-10 12:36:10 -08002333 }
2334 }
2335
Wale Ogunwale706ed792015-08-02 10:29:44 -07002336 /** Returns the bounds that should be used to launch this task. */
Wale Ogunwale30e441d2017-11-09 08:28:45 -08002337 Rect getLaunchBounds() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07002338 if (mStack == null) {
Chong Zhang7d5f5102016-01-13 10:29:24 -08002339 return null;
2340 }
2341
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002342 final int windowingMode = getWindowingMode();
2343 if (!isActivityTypeStandardOrUndefined()
2344 || windowingMode == WINDOWING_MODE_FULLSCREEN
2345 || (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY && !isResizeable())) {
Evan Roskydfe3da72018-10-26 17:21:06 -07002346 return isResizeable() ? mStack.getRequestedOverrideBounds() : null;
Wale Ogunwale3382ab12017-07-27 08:55:03 -07002347 } else if (!getWindowConfiguration().persistTaskBounds()) {
Evan Roskydfe3da72018-10-26 17:21:06 -07002348 return mStack.getRequestedOverrideBounds();
Wale Ogunwale706ed792015-08-02 10:29:44 -07002349 }
2350 return mLastNonFullscreenBounds;
2351 }
2352
Jorim Jaggi8b702ed2017-01-20 16:59:03 +01002353 void addStartingWindowsForVisibleActivities(boolean taskSwitch) {
2354 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
2355 final ActivityRecord r = mActivities.get(activityNdx);
2356 if (r.visible) {
2357 r.showStartingWindow(null /* prev */, false /* newTask */, taskSwitch);
2358 }
2359 }
2360 }
2361
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002362 void setRootProcess(WindowProcessController proc) {
Dianne Hackborn68a06332017-11-15 17:54:18 -08002363 clearRootProcess();
2364 if (intent != null &&
2365 (intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0) {
2366 mRootProcess = proc;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002367 mRootProcess.addRecentTask(this);
Dianne Hackborn68a06332017-11-15 17:54:18 -08002368 }
2369 }
2370
2371 void clearRootProcess() {
2372 if (mRootProcess != null) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002373 mRootProcess.removeRecentTask(this);
Dianne Hackborn68a06332017-11-15 17:54:18 -08002374 mRootProcess = null;
2375 }
2376 }
2377
chaviw82a0ba82018-03-15 14:26:29 -07002378 void clearAllPendingOptions() {
2379 for (int i = getChildCount() - 1; i >= 0; i--) {
2380 getChildAt(i).clearOptionsLocked(false /* withAbort */);
2381 }
2382 }
2383
Winson Chungabfdcce2018-07-02 17:23:33 -07002384 /**
2385 * Fills in a {@link TaskInfo} with information from this task.
2386 * @param info the {@link TaskInfo} to fill in
Winson Chungabfdcce2018-07-02 17:23:33 -07002387 */
Mark Renoufc808f062019-02-07 15:20:37 -05002388 void fillTaskInfo(TaskInfo info) {
2389 getNumRunningActivities(mReuseActivitiesReport);
Winson Chungabfdcce2018-07-02 17:23:33 -07002390 info.userId = userId;
2391 info.stackId = getStackId();
2392 info.taskId = taskId;
Mark Renoufb1abb552019-02-08 13:51:41 -05002393 info.displayId = mStack == null ? Display.INVALID_DISPLAY : mStack.mDisplayId;
Winson Chungabfdcce2018-07-02 17:23:33 -07002394 info.isRunning = getTopActivity() != null;
Riddle Hsu2f9acd22018-11-06 23:44:43 +08002395 info.baseIntent = new Intent(getBaseIntent());
Mark Renoufc808f062019-02-07 15:20:37 -05002396 info.baseActivity = mReuseActivitiesReport.base != null
2397 ? mReuseActivitiesReport.base.intent.getComponent()
Winson Chungabfdcce2018-07-02 17:23:33 -07002398 : null;
Mark Renoufc808f062019-02-07 15:20:37 -05002399 info.topActivity = mReuseActivitiesReport.top != null
2400 ? mReuseActivitiesReport.top.mActivityComponent
Winson Chungabfdcce2018-07-02 17:23:33 -07002401 : null;
2402 info.origActivity = origActivity;
2403 info.realActivity = realActivity;
Mark Renoufc808f062019-02-07 15:20:37 -05002404 info.numActivities = mReuseActivitiesReport.numActivities;
Winson Chungabfdcce2018-07-02 17:23:33 -07002405 info.lastActiveTime = lastActiveTime;
2406 info.taskDescription = new ActivityManager.TaskDescription(lastTaskDescription);
2407 info.supportsSplitScreenMultiWindow = supportsSplitScreenWindowingMode();
2408 info.resizeMode = mResizeMode;
2409 info.configuration.setTo(getConfiguration());
2410 }
2411
Mark Renoufc808f062019-02-07 15:20:37 -05002412 /**
2413 * Returns a {@link TaskInfo} with information from this task.
2414 */
2415 ActivityManager.RunningTaskInfo getTaskInfo() {
2416 ActivityManager.RunningTaskInfo info = new ActivityManager.RunningTaskInfo();
2417 fillTaskInfo(info);
2418 return info;
2419 }
2420
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002421 void dump(PrintWriter pw, String prefix) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002422 pw.print(prefix); pw.print("userId="); pw.print(userId);
Dianne Hackborn885fbe52014-08-23 15:23:58 -07002423 pw.print(" effectiveUid="); UserHandle.formatUid(pw, effectiveUid);
2424 pw.print(" mCallingUid="); UserHandle.formatUid(pw, mCallingUid);
Suprabh Shukla7745c142016-03-07 18:21:10 -08002425 pw.print(" mUserSetupComplete="); pw.print(mUserSetupComplete);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002426 pw.print(" mCallingPackage="); pw.println(mCallingPackage);
Dianne Hackborn79228822014-09-16 11:11:23 -07002427 if (affinity != null || rootAffinity != null) {
2428 pw.print(prefix); pw.print("affinity="); pw.print(affinity);
2429 if (affinity == null || !affinity.equals(rootAffinity)) {
2430 pw.print(" root="); pw.println(rootAffinity);
2431 } else {
2432 pw.println();
2433 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002434 }
Dianne Hackborn91097de2014-04-04 18:02:06 -07002435 if (voiceSession != null || voiceInteractor != null) {
2436 pw.print(prefix); pw.print("VOICE: session=0x");
2437 pw.print(Integer.toHexString(System.identityHashCode(voiceSession)));
2438 pw.print(" interactor=0x");
2439 pw.println(Integer.toHexString(System.identityHashCode(voiceInteractor)));
2440 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002441 if (intent != null) {
2442 StringBuilder sb = new StringBuilder(128);
2443 sb.append(prefix); sb.append("intent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08002444 intent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002445 sb.append('}');
2446 pw.println(sb.toString());
2447 }
2448 if (affinityIntent != null) {
2449 StringBuilder sb = new StringBuilder(128);
2450 sb.append(prefix); sb.append("affinityIntent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08002451 affinityIntent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002452 sb.append('}');
2453 pw.println(sb.toString());
2454 }
2455 if (origActivity != null) {
2456 pw.print(prefix); pw.print("origActivity=");
2457 pw.println(origActivity.flattenToShortString());
2458 }
2459 if (realActivity != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002460 pw.print(prefix); pw.print("mActivityComponent=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002461 pw.println(realActivity.flattenToShortString());
2462 }
Wale Ogunwale66e16852017-10-19 13:35:52 -07002463 if (autoRemoveRecents || isPersistable || !isActivityTypeStandard() || numFullscreen != 0) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002464 pw.print(prefix); pw.print("autoRemoveRecents="); pw.print(autoRemoveRecents);
Dianne Hackborn852975d2014-08-22 17:42:43 -07002465 pw.print(" isPersistable="); pw.print(isPersistable);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002466 pw.print(" numFullscreen="); pw.print(numFullscreen);
Wale Ogunwale66e16852017-10-19 13:35:52 -07002467 pw.print(" activityType="); pw.println(getActivityType());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002468 }
Craig Mautner432f64e2015-05-20 14:59:57 -07002469 if (rootWasReset || mNeverRelinquishIdentity || mReuseTask
2470 || mLockTaskAuth != LOCK_TASK_AUTH_PINNABLE) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002471 pw.print(prefix); pw.print("rootWasReset="); pw.print(rootWasReset);
2472 pw.print(" mNeverRelinquishIdentity="); pw.print(mNeverRelinquishIdentity);
Craig Mautner432f64e2015-05-20 14:59:57 -07002473 pw.print(" mReuseTask="); pw.print(mReuseTask);
2474 pw.print(" mLockTaskAuth="); pw.println(lockTaskAuthToString());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002475 }
Wale Ogunwale18795a22014-12-03 11:38:33 -08002476 if (mAffiliatedTaskId != taskId || mPrevAffiliateTaskId != INVALID_TASK_ID
2477 || mPrevAffiliate != null || mNextAffiliateTaskId != INVALID_TASK_ID
2478 || mNextAffiliate != null) {
Dianne Hackborn852975d2014-08-22 17:42:43 -07002479 pw.print(prefix); pw.print("affiliation="); pw.print(mAffiliatedTaskId);
2480 pw.print(" prevAffiliation="); pw.print(mPrevAffiliateTaskId);
2481 pw.print(" (");
2482 if (mPrevAffiliate == null) {
2483 pw.print("null");
2484 } else {
2485 pw.print(Integer.toHexString(System.identityHashCode(mPrevAffiliate)));
2486 }
2487 pw.print(") nextAffiliation="); pw.print(mNextAffiliateTaskId);
2488 pw.print(" (");
2489 if (mNextAffiliate == null) {
2490 pw.print("null");
2491 } else {
2492 pw.print(Integer.toHexString(System.identityHashCode(mNextAffiliate)));
2493 }
2494 pw.println(")");
2495 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002496 pw.print(prefix); pw.print("Activities="); pw.println(mActivities);
Dianne Hackborn852975d2014-08-22 17:42:43 -07002497 if (!askedCompatMode || !inRecents || !isAvailable) {
2498 pw.print(prefix); pw.print("askedCompatMode="); pw.print(askedCompatMode);
2499 pw.print(" inRecents="); pw.print(inRecents);
2500 pw.print(" isAvailable="); pw.println(isAvailable);
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002501 }
Dianne Hackborn852975d2014-08-22 17:42:43 -07002502 if (lastDescription != null) {
2503 pw.print(prefix); pw.print("lastDescription="); pw.println(lastDescription);
2504 }
Dianne Hackborn68a06332017-11-15 17:54:18 -08002505 if (mRootProcess != null) {
2506 pw.print(prefix); pw.print("mRootProcess="); pw.println(mRootProcess);
2507 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07002508 pw.print(prefix); pw.print("stackId="); pw.println(getStackId());
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002509 pw.print(prefix + "hasBeenVisible=" + hasBeenVisible);
2510 pw.print(" mResizeMode=" + ActivityInfo.resizeModeToString(mResizeMode));
Winson Chungd3395382016-12-13 11:49:09 -08002511 pw.print(" mSupportsPictureInPicture=" + mSupportsPictureInPicture);
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002512 pw.print(" isResizeable=" + isResizeable());
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002513 pw.print(" lastActiveTime=" + lastActiveTime);
2514 pw.println(" (inactive for " + (getInactiveDuration() / 1000) + "s)");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002515 }
2516
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002517 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002518 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002519 StringBuilder sb = new StringBuilder(128);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002520 if (stringName != null) {
2521 sb.append(stringName);
2522 sb.append(" U=");
2523 sb.append(userId);
Wale Ogunwale6c5eb1c2015-11-10 07:52:22 -08002524 sb.append(" StackId=");
Andrii Kulian02b7a832016-10-06 23:11:56 -07002525 sb.append(getStackId());
Craig Mautnerde4ef022013-04-07 19:01:33 -07002526 sb.append(" sz=");
2527 sb.append(mActivities.size());
2528 sb.append('}');
2529 return sb.toString();
2530 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002531 sb.append("TaskRecord{");
2532 sb.append(Integer.toHexString(System.identityHashCode(this)));
2533 sb.append(" #");
2534 sb.append(taskId);
2535 if (affinity != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002536 sb.append(" A=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002537 sb.append(affinity);
2538 } else if (intent != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002539 sb.append(" I=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002540 sb.append(intent.getComponent().flattenToShortString());
Bryce Leefbd263b42018-03-07 10:33:55 -08002541 } else if (affinityIntent != null && affinityIntent.getComponent() != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002542 sb.append(" aI=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002543 sb.append(affinityIntent.getComponent().flattenToShortString());
2544 } else {
2545 sb.append(" ??");
2546 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07002547 stringName = sb.toString();
2548 return toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002549 }
Steven Timotius4346f0a2017-09-12 11:07:21 -07002550
Nataniel Borges023ecb52019-01-16 14:15:43 -08002551 public void writeToProto(ProtoOutputStream proto, long fieldId,
2552 @WindowTraceLogLevel int logLevel) {
2553 if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) {
2554 return;
2555 }
2556
Steven Timotius4346f0a2017-09-12 11:07:21 -07002557 final long token = proto.start(fieldId);
Nataniel Borges023ecb52019-01-16 14:15:43 -08002558 super.writeToProto(proto, CONFIGURATION_CONTAINER, logLevel);
Steven Timotius4346f0a2017-09-12 11:07:21 -07002559 proto.write(ID, taskId);
2560 for (int i = mActivities.size() - 1; i >= 0; i--) {
2561 ActivityRecord activity = mActivities.get(i);
2562 activity.writeToProto(proto, ACTIVITIES);
2563 }
2564 proto.write(STACK_ID, mStack.mStackId);
2565 if (mLastNonFullscreenBounds != null) {
2566 mLastNonFullscreenBounds.writeToProto(proto, LAST_NON_FULLSCREEN_BOUNDS);
2567 }
2568 if (realActivity != null) {
2569 proto.write(REAL_ACTIVITY, realActivity.flattenToShortString());
2570 }
2571 if (origActivity != null) {
2572 proto.write(ORIG_ACTIVITY, origActivity.flattenToShortString());
2573 }
2574 proto.write(ACTIVITY_TYPE, getActivityType());
Steven Timotius4346f0a2017-09-12 11:07:21 -07002575 proto.write(RESIZE_MODE, mResizeMode);
Bryce Leef3c6a472017-11-14 14:53:06 -08002576 // TODO: Remove, no longer needed with windowingMode.
2577 proto.write(FULLSCREEN, matchParentBounds());
2578
2579 if (!matchParentBounds()) {
Evan Roskydfe3da72018-10-26 17:21:06 -07002580 final Rect bounds = getRequestedOverrideBounds();
Bryce Leef3c6a472017-11-14 14:53:06 -08002581 bounds.writeToProto(proto, BOUNDS);
Steven Timotius4346f0a2017-09-12 11:07:21 -07002582 }
2583 proto.write(MIN_WIDTH, mMinWidth);
2584 proto.write(MIN_HEIGHT, mMinHeight);
2585 proto.end(token);
2586 }
Winson Chung61c9e5a2017-10-11 10:39:32 -07002587
2588 /**
2589 * See {@link #getNumRunningActivities(TaskActivitiesReport)}.
2590 */
2591 static class TaskActivitiesReport {
2592 int numRunning;
2593 int numActivities;
2594 ActivityRecord top;
2595 ActivityRecord base;
2596
2597 void reset() {
2598 numRunning = numActivities = 0;
2599 top = base = null;
2600 }
2601 }
Garfield Tan9b1efea2017-12-05 16:43:46 -08002602
2603 /**
2604 * Saves this {@link TaskRecord} to XML using given serializer.
2605 */
2606 void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
2607 if (DEBUG_RECENTS) Slog.i(TAG_RECENTS, "Saving task=" + this);
2608
2609 out.attribute(null, ATTR_TASKID, String.valueOf(taskId));
2610 if (realActivity != null) {
2611 out.attribute(null, ATTR_REALACTIVITY, realActivity.flattenToShortString());
2612 }
2613 out.attribute(null, ATTR_REALACTIVITY_SUSPENDED, String.valueOf(realActivitySuspended));
2614 if (origActivity != null) {
2615 out.attribute(null, ATTR_ORIGACTIVITY, origActivity.flattenToShortString());
2616 }
2617 // Write affinity, and root affinity if it is different from affinity.
2618 // We use the special string "@" for a null root affinity, so we can identify
2619 // later whether we were given a root affinity or should just make it the
2620 // same as the affinity.
2621 if (affinity != null) {
2622 out.attribute(null, ATTR_AFFINITY, affinity);
2623 if (!affinity.equals(rootAffinity)) {
2624 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
2625 }
2626 } else if (rootAffinity != null) {
2627 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
2628 }
2629 out.attribute(null, ATTR_ROOTHASRESET, String.valueOf(rootWasReset));
2630 out.attribute(null, ATTR_AUTOREMOVERECENTS, String.valueOf(autoRemoveRecents));
2631 out.attribute(null, ATTR_ASKEDCOMPATMODE, String.valueOf(askedCompatMode));
2632 out.attribute(null, ATTR_USERID, String.valueOf(userId));
2633 out.attribute(null, ATTR_USER_SETUP_COMPLETE, String.valueOf(mUserSetupComplete));
2634 out.attribute(null, ATTR_EFFECTIVE_UID, String.valueOf(effectiveUid));
2635 out.attribute(null, ATTR_LASTTIMEMOVED, String.valueOf(mLastTimeMoved));
2636 out.attribute(null, ATTR_NEVERRELINQUISH, String.valueOf(mNeverRelinquishIdentity));
2637 if (lastDescription != null) {
2638 out.attribute(null, ATTR_LASTDESCRIPTION, lastDescription.toString());
2639 }
2640 if (lastTaskDescription != null) {
2641 lastTaskDescription.saveToXml(out);
2642 }
2643 out.attribute(null, ATTR_TASK_AFFILIATION_COLOR, String.valueOf(mAffiliatedTaskColor));
2644 out.attribute(null, ATTR_TASK_AFFILIATION, String.valueOf(mAffiliatedTaskId));
2645 out.attribute(null, ATTR_PREV_AFFILIATION, String.valueOf(mPrevAffiliateTaskId));
2646 out.attribute(null, ATTR_NEXT_AFFILIATION, String.valueOf(mNextAffiliateTaskId));
2647 out.attribute(null, ATTR_CALLING_UID, String.valueOf(mCallingUid));
2648 out.attribute(null, ATTR_CALLING_PACKAGE, mCallingPackage == null ? "" : mCallingPackage);
2649 out.attribute(null, ATTR_RESIZE_MODE, String.valueOf(mResizeMode));
2650 out.attribute(null, ATTR_SUPPORTS_PICTURE_IN_PICTURE,
2651 String.valueOf(mSupportsPictureInPicture));
2652 if (mLastNonFullscreenBounds != null) {
2653 out.attribute(
2654 null, ATTR_NON_FULLSCREEN_BOUNDS, mLastNonFullscreenBounds.flattenToString());
2655 }
2656 out.attribute(null, ATTR_MIN_WIDTH, String.valueOf(mMinWidth));
2657 out.attribute(null, ATTR_MIN_HEIGHT, String.valueOf(mMinHeight));
2658 out.attribute(null, ATTR_PERSIST_TASK_VERSION, String.valueOf(PERSIST_TASK_VERSION));
2659
2660 if (affinityIntent != null) {
2661 out.startTag(null, TAG_AFFINITYINTENT);
2662 affinityIntent.saveToXml(out);
2663 out.endTag(null, TAG_AFFINITYINTENT);
2664 }
2665
Bryce Lee1a990e52018-04-23 10:54:11 -07002666 if (intent != null) {
2667 out.startTag(null, TAG_INTENT);
2668 intent.saveToXml(out);
2669 out.endTag(null, TAG_INTENT);
2670 }
Garfield Tan9b1efea2017-12-05 16:43:46 -08002671
2672 final ArrayList<ActivityRecord> activities = mActivities;
2673 final int numActivities = activities.size();
2674 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
2675 final ActivityRecord r = activities.get(activityNdx);
2676 if (r.info.persistableMode == ActivityInfo.PERSIST_ROOT_ONLY || !r.isPersistable() ||
2677 ((r.intent.getFlags() & FLAG_ACTIVITY_NEW_DOCUMENT
2678 | FLAG_ACTIVITY_RETAIN_IN_RECENTS) == FLAG_ACTIVITY_NEW_DOCUMENT) &&
2679 activityNdx > 0) {
2680 // Stop at first non-persistable or first break in task (CLEAR_WHEN_TASK_RESET).
2681 break;
2682 }
2683 out.startTag(null, TAG_ACTIVITY);
2684 r.saveToXml(out);
2685 out.endTag(null, TAG_ACTIVITY);
2686 }
2687 }
2688
2689 @VisibleForTesting
2690 static TaskRecordFactory getTaskRecordFactory() {
2691 if (sTaskRecordFactory == null) {
2692 setTaskRecordFactory(new TaskRecordFactory());
2693 }
2694 return sTaskRecordFactory;
2695 }
2696
2697 static void setTaskRecordFactory(TaskRecordFactory factory) {
2698 sTaskRecordFactory = factory;
2699 }
2700
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002701 static TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002702 Intent intent, IVoiceInteractionSession voiceSession,
2703 IVoiceInteractor voiceInteractor) {
2704 return getTaskRecordFactory().create(
2705 service, taskId, info, intent, voiceSession, voiceInteractor);
2706 }
2707
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002708 static TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002709 Intent intent, TaskDescription taskDescription) {
2710 return getTaskRecordFactory().create(service, taskId, info, intent, taskDescription);
2711 }
2712
2713 static TaskRecord restoreFromXml(XmlPullParser in, ActivityStackSupervisor stackSupervisor)
2714 throws IOException, XmlPullParserException {
2715 return getTaskRecordFactory().restoreFromXml(in, stackSupervisor);
2716 }
2717
2718 /**
2719 * A factory class used to create {@link TaskRecord} or its subclass if any. This can be
2720 * specified when system boots by setting it with
2721 * {@link #setTaskRecordFactory(TaskRecordFactory)}.
2722 */
2723 static class TaskRecordFactory {
2724
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002725 TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002726 Intent intent, IVoiceInteractionSession voiceSession,
2727 IVoiceInteractor voiceInteractor) {
2728 return new TaskRecord(
2729 service, taskId, info, intent, voiceSession, voiceInteractor);
2730 }
2731
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002732 TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002733 Intent intent, TaskDescription taskDescription) {
2734 return new TaskRecord(service, taskId, info, intent, taskDescription);
2735 }
2736
2737 /**
2738 * Should only be used when we're restoring {@link TaskRecord} from storage.
2739 */
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002740 TaskRecord create(ActivityTaskManagerService service, int taskId, Intent intent,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002741 Intent affinityIntent, String affinity, String rootAffinity,
2742 ComponentName realActivity, ComponentName origActivity, boolean rootWasReset,
2743 boolean autoRemoveRecents, boolean askedCompatMode, int userId,
2744 int effectiveUid, String lastDescription, ArrayList<ActivityRecord> activities,
2745 long lastTimeMoved, boolean neverRelinquishIdentity,
2746 TaskDescription lastTaskDescription, int taskAffiliation, int prevTaskId,
2747 int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage,
2748 int resizeMode, boolean supportsPictureInPicture, boolean realActivitySuspended,
2749 boolean userSetupComplete, int minWidth, int minHeight) {
2750 return new TaskRecord(service, taskId, intent, affinityIntent, affinity,
2751 rootAffinity, realActivity, origActivity, rootWasReset, autoRemoveRecents,
2752 askedCompatMode, userId, effectiveUid, lastDescription, activities,
2753 lastTimeMoved, neverRelinquishIdentity, lastTaskDescription, taskAffiliation,
2754 prevTaskId, nextTaskId, taskAffiliationColor, callingUid, callingPackage,
2755 resizeMode, supportsPictureInPicture, realActivitySuspended, userSetupComplete,
2756 minWidth, minHeight);
2757 }
2758
2759 TaskRecord restoreFromXml(XmlPullParser in, ActivityStackSupervisor stackSupervisor)
2760 throws IOException, XmlPullParserException {
2761 Intent intent = null;
2762 Intent affinityIntent = null;
2763 ArrayList<ActivityRecord> activities = new ArrayList<>();
2764 ComponentName realActivity = null;
2765 boolean realActivitySuspended = false;
2766 ComponentName origActivity = null;
2767 String affinity = null;
2768 String rootAffinity = null;
2769 boolean hasRootAffinity = false;
2770 boolean rootHasReset = false;
2771 boolean autoRemoveRecents = false;
2772 boolean askedCompatMode = false;
2773 int taskType = 0;
2774 int userId = 0;
2775 boolean userSetupComplete = true;
2776 int effectiveUid = -1;
2777 String lastDescription = null;
2778 long lastTimeOnTop = 0;
2779 boolean neverRelinquishIdentity = true;
2780 int taskId = INVALID_TASK_ID;
2781 final int outerDepth = in.getDepth();
2782 TaskDescription taskDescription = new TaskDescription();
2783 int taskAffiliation = INVALID_TASK_ID;
2784 int taskAffiliationColor = 0;
2785 int prevTaskId = INVALID_TASK_ID;
2786 int nextTaskId = INVALID_TASK_ID;
2787 int callingUid = -1;
2788 String callingPackage = "";
2789 int resizeMode = RESIZE_MODE_FORCE_RESIZEABLE;
2790 boolean supportsPictureInPicture = false;
Garfield Tan367b35a2017-12-13 12:16:21 -08002791 Rect lastNonFullscreenBounds = null;
Garfield Tan9b1efea2017-12-05 16:43:46 -08002792 int minWidth = INVALID_MIN_SIZE;
2793 int minHeight = INVALID_MIN_SIZE;
2794 int persistTaskVersion = 0;
2795
2796 for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
2797 final String attrName = in.getAttributeName(attrNdx);
2798 final String attrValue = in.getAttributeValue(attrNdx);
2799 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: attribute name=" +
2800 attrName + " value=" + attrValue);
2801 switch (attrName) {
2802 case ATTR_TASKID:
2803 if (taskId == INVALID_TASK_ID) taskId = Integer.parseInt(attrValue);
2804 break;
2805 case ATTR_REALACTIVITY:
2806 realActivity = ComponentName.unflattenFromString(attrValue);
2807 break;
2808 case ATTR_REALACTIVITY_SUSPENDED:
2809 realActivitySuspended = Boolean.valueOf(attrValue);
2810 break;
2811 case ATTR_ORIGACTIVITY:
2812 origActivity = ComponentName.unflattenFromString(attrValue);
2813 break;
2814 case ATTR_AFFINITY:
2815 affinity = attrValue;
2816 break;
2817 case ATTR_ROOT_AFFINITY:
2818 rootAffinity = attrValue;
2819 hasRootAffinity = true;
2820 break;
2821 case ATTR_ROOTHASRESET:
2822 rootHasReset = Boolean.parseBoolean(attrValue);
2823 break;
2824 case ATTR_AUTOREMOVERECENTS:
2825 autoRemoveRecents = Boolean.parseBoolean(attrValue);
2826 break;
2827 case ATTR_ASKEDCOMPATMODE:
2828 askedCompatMode = Boolean.parseBoolean(attrValue);
2829 break;
2830 case ATTR_USERID:
2831 userId = Integer.parseInt(attrValue);
2832 break;
2833 case ATTR_USER_SETUP_COMPLETE:
2834 userSetupComplete = Boolean.parseBoolean(attrValue);
2835 break;
2836 case ATTR_EFFECTIVE_UID:
2837 effectiveUid = Integer.parseInt(attrValue);
2838 break;
2839 case ATTR_TASKTYPE:
2840 taskType = Integer.parseInt(attrValue);
2841 break;
2842 case ATTR_LASTDESCRIPTION:
2843 lastDescription = attrValue;
2844 break;
2845 case ATTR_LASTTIMEMOVED:
2846 lastTimeOnTop = Long.parseLong(attrValue);
2847 break;
2848 case ATTR_NEVERRELINQUISH:
2849 neverRelinquishIdentity = Boolean.parseBoolean(attrValue);
2850 break;
2851 case ATTR_TASK_AFFILIATION:
2852 taskAffiliation = Integer.parseInt(attrValue);
2853 break;
2854 case ATTR_PREV_AFFILIATION:
2855 prevTaskId = Integer.parseInt(attrValue);
2856 break;
2857 case ATTR_NEXT_AFFILIATION:
2858 nextTaskId = Integer.parseInt(attrValue);
2859 break;
2860 case ATTR_TASK_AFFILIATION_COLOR:
2861 taskAffiliationColor = Integer.parseInt(attrValue);
2862 break;
2863 case ATTR_CALLING_UID:
2864 callingUid = Integer.parseInt(attrValue);
2865 break;
2866 case ATTR_CALLING_PACKAGE:
2867 callingPackage = attrValue;
2868 break;
2869 case ATTR_RESIZE_MODE:
2870 resizeMode = Integer.parseInt(attrValue);
2871 break;
2872 case ATTR_SUPPORTS_PICTURE_IN_PICTURE:
2873 supportsPictureInPicture = Boolean.parseBoolean(attrValue);
2874 break;
2875 case ATTR_NON_FULLSCREEN_BOUNDS:
Garfield Tan367b35a2017-12-13 12:16:21 -08002876 lastNonFullscreenBounds = Rect.unflattenFromString(attrValue);
Garfield Tan9b1efea2017-12-05 16:43:46 -08002877 break;
2878 case ATTR_MIN_WIDTH:
2879 minWidth = Integer.parseInt(attrValue);
2880 break;
2881 case ATTR_MIN_HEIGHT:
2882 minHeight = Integer.parseInt(attrValue);
2883 break;
2884 case ATTR_PERSIST_TASK_VERSION:
2885 persistTaskVersion = Integer.parseInt(attrValue);
2886 break;
2887 default:
2888 if (attrName.startsWith(TaskDescription.ATTR_TASKDESCRIPTION_PREFIX)) {
2889 taskDescription.restoreFromXml(attrName, attrValue);
2890 } else {
2891 Slog.w(TAG, "TaskRecord: Unknown attribute=" + attrName);
2892 }
2893 }
2894 }
2895
2896 int event;
2897 while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
2898 (event != XmlPullParser.END_TAG || in.getDepth() >= outerDepth)) {
2899 if (event == XmlPullParser.START_TAG) {
2900 final String name = in.getName();
2901 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG,
2902 "TaskRecord: START_TAG name=" + name);
2903 if (TAG_AFFINITYINTENT.equals(name)) {
2904 affinityIntent = Intent.restoreFromXml(in);
2905 } else if (TAG_INTENT.equals(name)) {
2906 intent = Intent.restoreFromXml(in);
2907 } else if (TAG_ACTIVITY.equals(name)) {
2908 ActivityRecord activity =
2909 ActivityRecord.restoreFromXml(in, stackSupervisor);
2910 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: activity=" +
2911 activity);
2912 if (activity != null) {
2913 activities.add(activity);
2914 }
2915 } else {
Garfield Tan1e740192017-12-12 14:37:42 -08002916 handleUnknownTag(name, in);
Garfield Tan9b1efea2017-12-05 16:43:46 -08002917 }
2918 }
2919 }
2920 if (!hasRootAffinity) {
2921 rootAffinity = affinity;
2922 } else if ("@".equals(rootAffinity)) {
2923 rootAffinity = null;
2924 }
2925 if (effectiveUid <= 0) {
2926 Intent checkIntent = intent != null ? intent : affinityIntent;
2927 effectiveUid = 0;
2928 if (checkIntent != null) {
2929 IPackageManager pm = AppGlobals.getPackageManager();
2930 try {
2931 ApplicationInfo ai = pm.getApplicationInfo(
2932 checkIntent.getComponent().getPackageName(),
2933 PackageManager.MATCH_UNINSTALLED_PACKAGES
2934 | PackageManager.MATCH_DISABLED_COMPONENTS, userId);
2935 if (ai != null) {
2936 effectiveUid = ai.uid;
2937 }
2938 } catch (RemoteException e) {
2939 }
2940 }
2941 Slog.w(TAG, "Updating task #" + taskId + " for " + checkIntent
2942 + ": effectiveUid=" + effectiveUid);
2943 }
2944
2945 if (persistTaskVersion < 1) {
2946 // We need to convert the resize mode of home activities saved before version one if
2947 // they are marked as RESIZE_MODE_RESIZEABLE to
2948 // RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION since we didn't have that differentiation
2949 // before version 1 and the system didn't resize home activities before then.
2950 if (taskType == 1 /* old home type */ && resizeMode == RESIZE_MODE_RESIZEABLE) {
2951 resizeMode = RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
2952 }
2953 } else {
2954 // This activity has previously marked itself explicitly as both resizeable and
2955 // supporting picture-in-picture. Since there is no longer a requirement for
2956 // picture-in-picture activities to be resizeable, we can mark this simply as
2957 // resizeable and supporting picture-in-picture separately.
2958 if (resizeMode == RESIZE_MODE_RESIZEABLE_AND_PIPABLE_DEPRECATED) {
2959 resizeMode = RESIZE_MODE_RESIZEABLE;
2960 supportsPictureInPicture = true;
2961 }
2962 }
2963
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07002964 final TaskRecord task = create(stackSupervisor.mService,
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002965 taskId, intent, affinityIntent,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002966 affinity, rootAffinity, realActivity, origActivity, rootHasReset,
2967 autoRemoveRecents, askedCompatMode, userId, effectiveUid, lastDescription,
2968 activities, lastTimeOnTop, neverRelinquishIdentity, taskDescription,
2969 taskAffiliation, prevTaskId, nextTaskId, taskAffiliationColor, callingUid,
2970 callingPackage, resizeMode, supportsPictureInPicture, realActivitySuspended,
2971 userSetupComplete, minWidth, minHeight);
Garfield Tan367b35a2017-12-13 12:16:21 -08002972 task.mLastNonFullscreenBounds = lastNonFullscreenBounds;
2973 task.setBounds(lastNonFullscreenBounds);
Garfield Tan9b1efea2017-12-05 16:43:46 -08002974
2975 for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {
2976 activities.get(activityNdx).setTask(task);
2977 }
2978
2979 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Restored task=" + task);
2980 return task;
2981 }
Garfield Tan1e740192017-12-12 14:37:42 -08002982
2983 void handleUnknownTag(String name, XmlPullParser in)
2984 throws IOException, XmlPullParserException {
2985 Slog.e(TAG, "restoreTask: Unexpected name=" + name);
2986 XmlUtils.skipCurrentTag(in);
2987 }
Garfield Tan9b1efea2017-12-05 16:43:46 -08002988 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002989}