blob: fe42de10011db44a9db60ffb63142186dfb35bce [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Wale Ogunwale59507092018-10-29 09:00:30 -070017package com.android.server.wm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080018
Andrii Kulianab132ee2018-07-24 22:10:21 +080019import static android.app.ActivityTaskManager.INVALID_STACK_ID;
Wale Ogunwale98875612018-10-12 07:53:02 -070020import static android.app.ActivityTaskManager.INVALID_TASK_ID;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070021import static android.app.ActivityTaskManager.RESIZE_MODE_FORCED;
22import static android.app.ActivityTaskManager.RESIZE_MODE_SYSTEM;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -070023import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
24import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070025import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
26import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
27import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
28import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Wale Ogunwale44f036f2017-09-29 05:09:09 -070029import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Evan Rosky1ac84462018-11-13 11:25:30 -080030import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Jorim Jaggi0a932142016-02-01 17:42:25 -080031import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
Wale Ogunwale66e16852017-10-19 13:35:52 -070032import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
Jorim Jaggi0a932142016-02-01 17:42:25 -080033import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
Wale Ogunwale66e16852017-10-19 13:35:52 -070034import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
Wale Ogunwale3eadad72016-10-13 09:16:59 -070035import static android.content.pm.ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY;
Jorim Jaggi0a932142016-02-01 17:42:25 -080036import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
37import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
38import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
39import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER;
skuhne@google.com322347b2016-12-02 12:54:03 -080040import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY;
41import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PORTRAIT_ONLY;
42import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PRESERVE_ORIENTATION;
Wale Ogunwaled829d362016-02-10 19:24:49 -080043import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
Wale Ogunwale625ed0c2016-10-18 08:50:31 -070044import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
Winson Chungd3395382016-12-13 11:49:09 -080045import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_AND_PIPABLE_DEPRECATED;
Wale Ogunwale625ed0c2016-10-18 08:50:31 -070046import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
Evan Rosky730f6e82018-12-03 17:40:11 -080047import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
48import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
49import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -080050import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
Suprabh Shukla7745c142016-03-07 18:21:10 -080051import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
Andrii Kulian036e3ad2017-04-19 10:55:10 -070052import static android.view.Display.DEFAULT_DISPLAY;
Garfield Tan891146c2018-10-09 12:14:00 -070053
Yunfan Chen0e7aff92018-12-05 16:35:32 -080054import static com.android.server.EventLogTags.WM_TASK_CREATED;
Yi Jin6c6e9ca2018-03-20 16:53:35 -070055import static com.android.server.am.TaskRecordProto.ACTIVITIES;
Andrii Kulianab132ee2018-07-24 22:10:21 +080056import static com.android.server.am.TaskRecordProto.ACTIVITY_TYPE;
Yi Jin6c6e9ca2018-03-20 16:53:35 -070057import static com.android.server.am.TaskRecordProto.BOUNDS;
58import static com.android.server.am.TaskRecordProto.CONFIGURATION_CONTAINER;
59import static com.android.server.am.TaskRecordProto.FULLSCREEN;
60import static com.android.server.am.TaskRecordProto.ID;
61import static com.android.server.am.TaskRecordProto.LAST_NON_FULLSCREEN_BOUNDS;
62import static com.android.server.am.TaskRecordProto.MIN_HEIGHT;
63import static com.android.server.am.TaskRecordProto.MIN_WIDTH;
64import static com.android.server.am.TaskRecordProto.ORIG_ACTIVITY;
65import static com.android.server.am.TaskRecordProto.REAL_ACTIVITY;
66import static com.android.server.am.TaskRecordProto.RESIZE_MODE;
67import static com.android.server.am.TaskRecordProto.STACK_ID;
Garfield Tan891146c2018-10-09 12:14:00 -070068import static com.android.server.wm.ActivityRecord.STARTING_WINDOW_SHOWN;
69import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_MOVING;
70import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_MOVING_TO_TOP;
71import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
72import static com.android.server.wm.ActivityStackSupervisor.PAUSE_IMMEDIATELY;
73import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
74import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ADD_REMOVE;
75import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_LOCKTASK;
76import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
77import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
78import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_ADD_REMOVE;
79import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_LOCKTASK;
80import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS;
81import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS;
82import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
83import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
Yunfan Chen0e7aff92018-12-05 16:35:32 -080084import static com.android.server.wm.WindowContainer.POSITION_BOTTOM;
85import static com.android.server.wm.WindowContainer.POSITION_TOP;
86import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
87import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Garfield Tan891146c2018-10-09 12:14:00 -070088
Winson Chung74666102017-02-22 17:49:24 -080089import static java.lang.Integer.MAX_VALUE;
90
Jorim Jaggie7d2b852017-08-28 17:55:15 +020091import android.annotation.IntDef;
Evan Rosky1ac84462018-11-13 11:25:30 -080092import android.annotation.NonNull;
Jorim Jaggie7d2b852017-08-28 17:55:15 +020093import android.annotation.Nullable;
94import android.app.Activity;
95import android.app.ActivityManager;
Jorim Jaggie7d2b852017-08-28 17:55:15 +020096import android.app.ActivityManager.TaskDescription;
97import android.app.ActivityManager.TaskSnapshot;
98import android.app.ActivityOptions;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070099import android.app.ActivityTaskManager;
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200100import android.app.AppGlobals;
Winson Chungabfdcce2018-07-02 17:23:33 -0700101import android.app.TaskInfo;
Garfield Tan891146c2018-10-09 12:14:00 -0700102import android.app.WindowConfiguration;
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200103import android.content.ComponentName;
104import android.content.Intent;
105import android.content.pm.ActivityInfo;
106import android.content.pm.ApplicationInfo;
107import android.content.pm.IPackageManager;
108import android.content.pm.PackageManager;
109import android.content.res.Configuration;
110import android.graphics.Rect;
111import android.os.Debug;
112import android.os.RemoteException;
Winson Chungfb44d212017-10-04 11:39:10 -0700113import android.os.SystemClock;
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200114import android.os.Trace;
115import android.os.UserHandle;
116import android.provider.Settings;
117import android.service.voice.IVoiceInteractionSession;
118import android.util.DisplayMetrics;
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800119import android.util.EventLog;
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200120import android.util.Slog;
Steven Timotius4346f0a2017-09-12 11:07:21 -0700121import android.util.proto.ProtoOutputStream;
Evan Rosky1ac84462018-11-13 11:25:30 -0800122import android.view.DisplayInfo;
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200123
124import com.android.internal.annotations.VisibleForTesting;
125import com.android.internal.app.IVoiceInteractor;
126import com.android.internal.util.XmlUtils;
Wale Ogunwale59507092018-10-29 09:00:30 -0700127import com.android.server.wm.ActivityStack.ActivityState;
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200128
129import org.xmlpull.v1.XmlPullParser;
130import org.xmlpull.v1.XmlPullParserException;
131import org.xmlpull.v1.XmlSerializer;
132
133import java.io.IOException;
134import java.io.PrintWriter;
135import java.lang.annotation.Retention;
136import java.lang.annotation.RetentionPolicy;
137import java.util.ArrayList;
138import java.util.Objects;
139
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800140class TaskRecord extends ConfigurationContainer {
Wale Ogunwale98875612018-10-12 07:53:02 -0700141 private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskRecord" : TAG_ATM;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -0700142 private static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700143 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
Craig Mautnere0570202015-05-13 13:06:11 -0700144 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700145 private static final String TAG_TASKS = TAG + POSTFIX_TASKS;
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800146
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700147 private static final String ATTR_TASKID = "task_id";
Craig Mautner21d24a22014-04-23 11:45:37 -0700148 private static final String TAG_INTENT = "intent";
149 private static final String TAG_AFFINITYINTENT = "affinity_intent";
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700150 private static final String ATTR_REALACTIVITY = "real_activity";
151 private static final String ATTR_REALACTIVITY_SUSPENDED = "real_activity_suspended";
Craig Mautner21d24a22014-04-23 11:45:37 -0700152 private static final String ATTR_ORIGACTIVITY = "orig_activity";
Stefan Kuhnee88d1e52015-05-18 10:33:45 -0700153 private static final String TAG_ACTIVITY = "activity";
Craig Mautner21d24a22014-04-23 11:45:37 -0700154 private static final String ATTR_AFFINITY = "affinity";
Dianne Hackborn79228822014-09-16 11:11:23 -0700155 private static final String ATTR_ROOT_AFFINITY = "root_affinity";
Craig Mautner21d24a22014-04-23 11:45:37 -0700156 private static final String ATTR_ROOTHASRESET = "root_has_reset";
Dianne Hackborn13420f22014-07-18 15:43:56 -0700157 private static final String ATTR_AUTOREMOVERECENTS = "auto_remove_recents";
Craig Mautner21d24a22014-04-23 11:45:37 -0700158 private static final String ATTR_ASKEDCOMPATMODE = "asked_compat_mode";
159 private static final String ATTR_USERID = "user_id";
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800160 private static final String ATTR_USER_SETUP_COMPLETE = "user_setup_complete";
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700161 private static final String ATTR_EFFECTIVE_UID = "effective_uid";
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700162 @Deprecated
Craig Mautner21d24a22014-04-23 11:45:37 -0700163 private static final String ATTR_TASKTYPE = "task_type";
Craig Mautner21d24a22014-04-23 11:45:37 -0700164 private static final String ATTR_LASTDESCRIPTION = "last_description";
165 private static final String ATTR_LASTTIMEMOVED = "last_time_moved";
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700166 private static final String ATTR_NEVERRELINQUISH = "never_relinquish_identity";
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700167 private static final String ATTR_TASK_AFFILIATION = "task_affiliation";
Craig Mautnera228ae92014-07-09 05:44:55 -0700168 private static final String ATTR_PREV_AFFILIATION = "prev_affiliation";
169 private static final String ATTR_NEXT_AFFILIATION = "next_affiliation";
Winson Chungec396d62014-08-06 17:08:00 -0700170 private static final String ATTR_TASK_AFFILIATION_COLOR = "task_affiliation_color";
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700171 private static final String ATTR_CALLING_UID = "calling_uid";
172 private static final String ATTR_CALLING_PACKAGE = "calling_package";
Winson Chungd3395382016-12-13 11:49:09 -0800173 private static final String ATTR_SUPPORTS_PICTURE_IN_PICTURE = "supports_picture_in_picture";
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800174 private static final String ATTR_RESIZE_MODE = "resize_mode";
Wale Ogunwale706ed792015-08-02 10:29:44 -0700175 private static final String ATTR_NON_FULLSCREEN_BOUNDS = "non_fullscreen_bounds";
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700176 private static final String ATTR_MIN_WIDTH = "min_width";
177 private static final String ATTR_MIN_HEIGHT = "min_height";
Wale Ogunwale625ed0c2016-10-18 08:50:31 -0700178 private static final String ATTR_PERSIST_TASK_VERSION = "persist_task_version";
Andrii Kulian18d75122016-03-27 20:20:28 -0700179
Wale Ogunwale625ed0c2016-10-18 08:50:31 -0700180 // Current version of the task record we persist. Used to check if we need to run any upgrade
181 // code.
182 private static final int PERSIST_TASK_VERSION = 1;
Craig Mautner21d24a22014-04-23 11:45:37 -0700183
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700184 private static final int INVALID_MIN_SIZE = -1;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800185
Winson Chung74666102017-02-22 17:49:24 -0800186 /**
187 * The modes to control how the stack is moved to the front when calling
188 * {@link TaskRecord#reparent}.
189 */
190 @Retention(RetentionPolicy.SOURCE)
191 @IntDef({
192 REPARENT_MOVE_STACK_TO_FRONT,
193 REPARENT_KEEP_STACK_AT_FRONT,
194 REPARENT_LEAVE_STACK_IN_PLACE
195 })
Wale Ogunwale66e16852017-10-19 13:35:52 -0700196 @interface ReparentMoveStackMode {}
Winson Chung74666102017-02-22 17:49:24 -0800197 // Moves the stack to the front if it was not at the front
Wale Ogunwale66e16852017-10-19 13:35:52 -0700198 static final int REPARENT_MOVE_STACK_TO_FRONT = 0;
Winson Chung74666102017-02-22 17:49:24 -0800199 // Only moves the stack to the front if it was focused or front most already
Wale Ogunwale66e16852017-10-19 13:35:52 -0700200 static final int REPARENT_KEEP_STACK_AT_FRONT = 1;
Winson Chung74666102017-02-22 17:49:24 -0800201 // Do not move the stack as a part of reparenting
Wale Ogunwale66e16852017-10-19 13:35:52 -0700202 static final int REPARENT_LEAVE_STACK_IN_PLACE = 2;
Winson Chung74666102017-02-22 17:49:24 -0800203
Evan Rosky1ac84462018-11-13 11:25:30 -0800204 // The height/width divide used when fitting a task within a bounds with method
205 // {@link #fitWithinBounds}.
206 // We always want the task to to be visible in the bounds without affecting its size when
207 // fitting. To make sure this is the case, we don't adjust the task left or top side pass
208 // the input bounds right or bottom side minus the width or height divided by this value.
209 private static final int FIT_WITHIN_BOUNDS_DIVIDER = 3;
210
Garfield Tan9b1efea2017-12-05 16:43:46 -0800211 /**
212 * The factory used to create {@link TaskRecord}. This allows OEM subclass {@link TaskRecord}.
213 */
214 private static TaskRecordFactory sTaskRecordFactory;
215
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800216 final int taskId; // Unique identifier for this task.
Dianne Hackborn79228822014-09-16 11:11:23 -0700217 String affinity; // The affinity name for this task, or null; may change identity.
218 String rootAffinity; // Initial base affinity, or null; does not change from initial root.
Dianne Hackborn91097de2014-04-04 18:02:06 -0700219 final IVoiceInteractionSession voiceSession; // Voice interaction session driving task
220 final IVoiceInteractor voiceInteractor; // Associated interactor to provide to app
Bryce Lee1a990e52018-04-23 10:54:11 -0700221 Intent intent; // The original intent that started the task. Note that this value can
222 // be null.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800223 Intent affinityIntent; // Intent of affinity-moved activity that started this task.
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700224 int effectiveUid; // The current effective uid of the identity of this task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800225 ComponentName origActivity; // The non-alias activity component of the intent.
226 ComponentName realActivity; // The actual activity component that started the task.
Andrei Stingaceanu4ccec532016-01-13 12:10:21 +0000227 boolean realActivitySuspended; // True if the actual activity component that started the
228 // task is suspended.
Dianne Hackborn852975d2014-08-22 17:42:43 -0700229 boolean inRecents; // Actually in the recents list?
Winson Chungfb44d212017-10-04 11:39:10 -0700230 long lastActiveTime; // Last time this task was active in the current device session,
231 // including sleep. This time is initialized to the elapsed time when
232 // restored from disk.
Dianne Hackborn852975d2014-08-22 17:42:43 -0700233 boolean isAvailable; // Is the activity available to be launched?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800234 boolean rootWasReset; // True if the intent at the root of the task had
235 // the FLAG_ACTIVITY_RESET_TASK_IF_NEEDED flag.
Dianne Hackborn13420f22014-07-18 15:43:56 -0700236 boolean autoRemoveRecents; // If true, we should automatically remove the task from
237 // recents when activity finishes
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700238 boolean askedCompatMode;// Have asked the user about compat mode for this task.
Dianne Hackbornd38aed82014-06-10 21:36:35 -0700239 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 -0800240
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700241 String stringName; // caching of toString() result.
Dianne Hackborn9da2d402012-03-15 13:43:08 -0700242 int userId; // user for which this task was created
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800243 boolean mUserSetupComplete; // The user set-up is complete as of the last time the task activity
244 // was changed.
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800245
246 int numFullscreen; // Number of fullscreen activities.
247
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800248 int mResizeMode; // The resize mode of this task and its activities.
249 // Based on the {@link ActivityInfo#resizeMode} of the root activity.
Wale Ogunwale069bbd32017-02-03 07:58:14 -0800250 private boolean mSupportsPictureInPicture; // Whether or not this task and its activities
251 // support PiP. Based on the {@link ActivityInfo#FLAG_SUPPORTS_PICTURE_IN_PICTURE} flag
252 // of the root activity.
Craig Mautner15df08a2015-04-01 12:17:18 -0700253 /** Can't be put in lockTask mode. */
254 final static int LOCK_TASK_AUTH_DONT_LOCK = 0;
Benjamin Franz469dd582015-06-09 14:24:36 +0100255 /** Can enter app pinning with user approval. Can never start over existing lockTask task. */
Craig Mautner15df08a2015-04-01 12:17:18 -0700256 final static int LOCK_TASK_AUTH_PINNABLE = 1;
257 /** Starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing lockTask task. */
258 final static int LOCK_TASK_AUTH_LAUNCHABLE = 2;
Benjamin Franz469dd582015-06-09 14:24:36 +0100259 /** Can enter lockTask without user approval. Can start over existing lockTask task. */
Craig Mautner15df08a2015-04-01 12:17:18 -0700260 final static int LOCK_TASK_AUTH_WHITELISTED = 3;
Benjamin Franz469dd582015-06-09 14:24:36 +0100261 /** Priv-app that starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing
262 * lockTask task. */
263 final static int LOCK_TASK_AUTH_LAUNCHABLE_PRIV = 4;
Craig Mautner15df08a2015-04-01 12:17:18 -0700264 int mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE;
265
266 int mLockTaskUid = -1; // The uid of the application that called startLockTask().
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800267
Winson Chung03a9bae2014-05-02 09:56:12 -0700268 // This represents the last resolved activity values for this task
269 // NOTE: This value needs to be persisted with each task
Craig Mautner648f69b2014-09-18 14:16:26 -0700270 TaskDescription lastTaskDescription = new TaskDescription();
Winson Chung03a9bae2014-05-02 09:56:12 -0700271
Craig Mautnerd2328952013-03-05 12:46:26 -0800272 /** List of all activities in the task arranged in history order */
Craig Mautner21d24a22014-04-23 11:45:37 -0700273 final ArrayList<ActivityRecord> mActivities;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800274
Andrii Kulian02b7a832016-10-06 23:11:56 -0700275 /** Current stack. Setter must always be used to update the value. */
276 private ActivityStack mStack;
Craig Mautnerd2328952013-03-05 12:46:26 -0800277
Dianne Hackborn68a06332017-11-15 17:54:18 -0800278 /** The process that had previously hosted the root activity of this task.
279 * Used to know that we should try harder to keep this process around, in case the
280 * user wants to return to it. */
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700281 private WindowProcessController mRootProcess;
Dianne Hackborn68a06332017-11-15 17:54:18 -0800282
Craig Mautner21d24a22014-04-23 11:45:37 -0700283 /** Takes on same value as first root activity */
284 boolean isPersistable = false;
Craig Mautnerffcfcaa2014-06-05 09:54:38 -0700285 int maxRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700286
287 /** Only used for persistable tasks, otherwise 0. The last time this task was moved. Used for
288 * determining the order when restoring. Sign indicates whether last task movement was to front
289 * (positive) or back (negative). Absolute value indicates time. */
290 long mLastTimeMoved = System.currentTimeMillis();
291
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700292 /** If original intent did not allow relinquishing task identity, save that information */
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700293 private boolean mNeverRelinquishIdentity = true;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700294
Craig Mautner362449a2014-06-20 14:04:39 -0700295 // Used in the unique case where we are clearing the task in order to reuse it. In that case we
296 // do not want to delete the stack when the task goes empty.
Filip Gruszczynskibe9dabd2016-01-19 12:23:10 -0800297 private boolean mReuseTask = false;
Craig Mautner362449a2014-06-20 14:04:39 -0700298
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700299 CharSequence lastDescription; // Last description captured for this item.
300
Craig Mautnera228ae92014-07-09 05:44:55 -0700301 int mAffiliatedTaskId; // taskId of parent affiliation or self if no parent.
Winson Chungec396d62014-08-06 17:08:00 -0700302 int mAffiliatedTaskColor; // color of the parent task affiliation.
Craig Mautnera228ae92014-07-09 05:44:55 -0700303 TaskRecord mPrevAffiliate; // previous task in affiliated chain.
Wale Ogunwale18795a22014-12-03 11:38:33 -0800304 int mPrevAffiliateTaskId = INVALID_TASK_ID; // previous id for persistence.
Craig Mautnera228ae92014-07-09 05:44:55 -0700305 TaskRecord mNextAffiliate; // next task in affiliated chain.
Wale Ogunwale18795a22014-12-03 11:38:33 -0800306 int mNextAffiliateTaskId = INVALID_TASK_ID; // next id for persistence.
Craig Mautnera228ae92014-07-09 05:44:55 -0700307
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700308 // For relaunching the task from recents as though it was launched by the original launcher.
309 int mCallingUid;
310 String mCallingPackage;
311
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700312 final ActivityTaskManagerService mService;
Craig Mautner21d24a22014-04-23 11:45:37 -0700313
Jorim Jaggi82c9dc92016-02-05 15:10:33 -0800314 private final Rect mTmpStableBounds = new Rect();
315 private final Rect mTmpNonDecorBounds = new Rect();
Evan Rosky1ac84462018-11-13 11:25:30 -0800316 private final Rect mTmpBounds = new Rect();
317 private final Rect mTmpInsets = new Rect();
Jorim Jaggi0a932142016-02-01 17:42:25 -0800318
Wale Ogunwale706ed792015-08-02 10:29:44 -0700319 // Last non-fullscreen bounds the task was launched in or resized to.
320 // The information is persisted and used to determine the appropriate stack to launch the
321 // task into on restore.
322 Rect mLastNonFullscreenBounds = null;
Andrii Kulian2e751b82016-03-16 16:59:32 -0700323 // Minimal width and height of this task when it's resizeable. -1 means it should use the
324 // default minimal width/height.
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700325 int mMinWidth;
326 int mMinHeight;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700327
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700328 // Ranking (from top) of this task among all visible tasks. (-1 means it's not visible)
329 // This number will be assigned when we evaluate OOM scores for all visible tasks.
330 int mLayerRank = -1;
331
Evan Roskyed6767f2018-10-26 17:21:06 -0700332 // When non-empty, this represents the bounds this task will be drawn at. This gets set during
333 // transient operations such as split-divider dragging and animations.
334 // TODO(b/119687367): This member is temporary.
335 final Rect mDisplayedBounds = new Rect();
336
Andrii Kulian1779e612016-10-12 21:58:25 -0700337 /** Helper object used for updating override configuration. */
338 private Configuration mTmpConfig = new Configuration();
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700339
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800340 // TODO: remove after unification
341 Task mTask;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800342
Garfield Tan9b1efea2017-12-05 16:43:46 -0800343 /**
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700344 * Don't use constructor directly. Use {@link #create(ActivityTaskManagerService, int,
345 * ActivityInfo, Intent, TaskDescription)} instead.
Garfield Tan9b1efea2017-12-05 16:43:46 -0800346 */
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700347 TaskRecord(ActivityTaskManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700348 IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700349 mService = service;
Suprabh Shukla23593142015-11-03 17:31:15 -0800350 userId = UserHandle.getUserId(info.applicationInfo.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800351 taskId = _taskId;
Winson Chungfb44d212017-10-04 11:39:10 -0700352 lastActiveTime = SystemClock.elapsedRealtime();
Craig Mautnera228ae92014-07-09 05:44:55 -0700353 mAffiliatedTaskId = _taskId;
Dianne Hackborn91097de2014-04-04 18:02:06 -0700354 voiceSession = _voiceSession;
355 voiceInteractor = _voiceInteractor;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700356 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800357 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700358 mCallingUid = info.applicationInfo.uid;
359 mCallingPackage = info.packageName;
Martijn Coenend4a69702014-06-30 11:12:17 -0700360 setIntent(_intent, info);
Andrii Kulian2e751b82016-03-16 16:59:32 -0700361 setMinDimensions(info);
Winson730bf062016-03-31 18:04:56 -0700362 touchActiveTime();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700363 mService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
Craig Mautner21d24a22014-04-23 11:45:37 -0700364 }
365
Garfield Tan9b1efea2017-12-05 16:43:46 -0800366 /**
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700367 * Don't use constructor directly.
368 * Use {@link #create(ActivityTaskManagerService, int, ActivityInfo,
Garfield Tan9b1efea2017-12-05 16:43:46 -0800369 * Intent, IVoiceInteractionSession, IVoiceInteractor)} instead.
370 */
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700371 TaskRecord(ActivityTaskManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200372 TaskDescription _taskDescription) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700373 mService = service;
Suprabh Shukla23593142015-11-03 17:31:15 -0800374 userId = UserHandle.getUserId(info.applicationInfo.uid);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700375 taskId = _taskId;
Winson Chungfb44d212017-10-04 11:39:10 -0700376 lastActiveTime = SystemClock.elapsedRealtime();
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700377 mAffiliatedTaskId = _taskId;
378 voiceSession = null;
379 voiceInteractor = null;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700380 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800381 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700382 mCallingUid = info.applicationInfo.uid;
383 mCallingPackage = info.packageName;
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700384 setIntent(_intent, info);
Andrii Kulian2e751b82016-03-16 16:59:32 -0700385 setMinDimensions(info);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700386
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700387 isPersistable = true;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700388 // Clamp to [1, max].
389 maxRecents = Math.min(Math.max(info.maxRecents, 1),
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700390 ActivityTaskManager.getMaxAppRecentsLimitStatic());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700391
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700392 lastTaskDescription = _taskDescription;
Winson730bf062016-03-31 18:04:56 -0700393 touchActiveTime();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700394 mService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700395 }
396
Garfield Tan9b1efea2017-12-05 16:43:46 -0800397 /**
398 * Don't use constructor directly. This is only used by XML parser.
399 */
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700400 TaskRecord(ActivityTaskManagerService service, int _taskId, Intent _intent,
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800401 Intent _affinityIntent, String _affinity, String _rootAffinity,
402 ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700403 boolean _autoRemoveRecents, boolean _askedCompatMode, int _userId,
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800404 int _effectiveUid, String _lastDescription, ArrayList<ActivityRecord> activities,
Winson Chungfb44d212017-10-04 11:39:10 -0700405 long lastTimeMoved, boolean neverRelinquishIdentity,
406 TaskDescription _lastTaskDescription, int taskAffiliation, int prevTaskId,
407 int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage,
Charles He2bf28322017-10-12 22:24:49 +0100408 int resizeMode, boolean supportsPictureInPicture, boolean _realActivitySuspended,
409 boolean userSetupComplete, int minWidth, int minHeight) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700410 mService = service;
411 taskId = _taskId;
412 intent = _intent;
413 affinityIntent = _affinityIntent;
414 affinity = _affinity;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800415 rootAffinity = _rootAffinity;
Craig Mautner21d24a22014-04-23 11:45:37 -0700416 voiceSession = null;
417 voiceInteractor = null;
418 realActivity = _realActivity;
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800419 realActivitySuspended = _realActivitySuspended;
Craig Mautner21d24a22014-04-23 11:45:37 -0700420 origActivity = _origActivity;
421 rootWasReset = _rootWasReset;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700422 isAvailable = true;
Dianne Hackborn13420f22014-07-18 15:43:56 -0700423 autoRemoveRecents = _autoRemoveRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700424 askedCompatMode = _askedCompatMode;
Craig Mautner21d24a22014-04-23 11:45:37 -0700425 userId = _userId;
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800426 mUserSetupComplete = userSetupComplete;
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700427 effectiveUid = _effectiveUid;
Winson Chungfb44d212017-10-04 11:39:10 -0700428 lastActiveTime = SystemClock.elapsedRealtime();
Craig Mautner21d24a22014-04-23 11:45:37 -0700429 lastDescription = _lastDescription;
430 mActivities = activities;
431 mLastTimeMoved = lastTimeMoved;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700432 mNeverRelinquishIdentity = neverRelinquishIdentity;
Winson Chung2cb86c72014-06-25 12:03:30 -0700433 lastTaskDescription = _lastTaskDescription;
Craig Mautnera228ae92014-07-09 05:44:55 -0700434 mAffiliatedTaskId = taskAffiliation;
Winson Chungec396d62014-08-06 17:08:00 -0700435 mAffiliatedTaskColor = taskAffiliationColor;
Craig Mautnera228ae92014-07-09 05:44:55 -0700436 mPrevAffiliateTaskId = prevTaskId;
437 mNextAffiliateTaskId = nextTaskId;
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700438 mCallingUid = callingUid;
439 mCallingPackage = callingPackage;
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800440 mResizeMode = resizeMode;
Winson Chungd3395382016-12-13 11:49:09 -0800441 mSupportsPictureInPicture = supportsPictureInPicture;
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700442 mMinWidth = minWidth;
443 mMinHeight = minHeight;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700444 mService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800445 }
446
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800447 Task getTask() {
448 return mTask;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800449 }
450
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800451 void createTask(boolean onTop, boolean showForAllUsers) {
452 if (mTask != null) {
453 throw new IllegalArgumentException("mTask=" + mTask
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800454 + " already created for task=" + this);
455 }
456
457 final Rect bounds = updateOverrideConfigurationFromLaunchBounds();
Yunfan Chen279f5582018-12-12 15:24:50 -0800458 final TaskStack stack = getStack().getTaskStack();
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800459
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800460 if (stack == null) {
Yunfan Chen279f5582018-12-12 15:24:50 -0800461 throw new IllegalArgumentException("TaskRecord: invalid stack=" + mStack);
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800462 }
463 EventLog.writeEvent(WM_TASK_CREATED, taskId, stack.mStackId);
464 mTask = new Task(taskId, stack, userId, mService.mWindowManager, mResizeMode,
465 mSupportsPictureInPicture, lastTaskDescription, this);
466 final int position = onTop ? POSITION_TOP : POSITION_BOTTOM;
467
468 if (!mDisplayedBounds.isEmpty()) {
469 mTask.setOverrideDisplayedBounds(mDisplayedBounds);
470 }
471 // We only want to move the parents to the parents if we are creating this task at the
472 // top of its stack.
473 stack.addTask(mTask, position, showForAllUsers, onTop /* moveParents */);
Bryce Lee04ab3462017-04-10 15:06:33 -0700474 }
475
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800476 void setTask(Task task) {
477 mTask = task;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800478 }
479
Garfield Tan347bd602018-12-21 15:11:12 -0800480 void cleanUpResourcesForDestroy() {
481 if (!mActivities.isEmpty()) {
482 return;
483 }
484
485 // This task is going away, so save the last state if necessary.
486 saveLaunchingStateIfNeeded();
487
488 // TODO: VI what about activity?
489 final boolean isVoiceSession = voiceSession != null;
490 if (isVoiceSession) {
491 try {
492 voiceSession.taskFinished(intent, taskId);
493 } catch (RemoteException e) {
494 }
495 }
496 if (autoRemoveFromRecents() || isVoiceSession) {
497 // Task creator asked to remove this when done, or this task was a voice
498 // interaction, so it should not remain on the recent tasks list.
499 mService.mStackSupervisor.mRecentTasks.remove(this);
500 }
501
502 removeWindowContainer();
503 }
504
505 @VisibleForTesting
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800506 void removeWindowContainer() {
Bryce Lee2b8e0372018-04-05 17:01:37 -0700507 mService.getLockTaskController().clearLockedTask(this);
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800508 if (mTask == null) {
509 if (DEBUG_STACK) Slog.i(TAG_WM, "removeTask: could not find taskId=" + taskId);
510 return;
511 }
512 mTask.removeIfPossible();
513 mTask = null;
Wale Ogunwale3382ab12017-07-27 08:55:03 -0700514 if (!getWindowConfiguration().persistTaskBounds()) {
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800515 // Reset current bounds for task whose bounds shouldn't be persisted so it uses
516 // default configuration the next time it launches.
517 updateOverrideConfiguration(null);
518 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700519 mService.getTaskChangeNotificationController().notifyTaskRemoved(taskId);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800520 }
521
Jorim Jaggifb9d78a2017-01-05 18:57:12 +0100522 public void onSnapshotChanged(TaskSnapshot snapshot) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700523 mService.getTaskChangeNotificationController().notifyTaskSnapshotChanged(taskId, snapshot);
Jorim Jaggifb9d78a2017-01-05 18:57:12 +0100524 }
525
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800526 void setResizeMode(int resizeMode) {
527 if (mResizeMode == resizeMode) {
528 return;
529 }
530 mResizeMode = resizeMode;
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800531 mTask.setResizeable(resizeMode);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800532 mService.mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
533 mService.mRootActivityContainer.resumeFocusedStacksTopActivities();
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800534 }
535
536 void setTaskDockedResizing(boolean resizing) {
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800537 if (mTask == null) {
538 Slog.w(TAG_WM, "setTaskDockedResizing: taskId " + taskId + " not found.");
539 return;
540 }
541 mTask.setTaskDockedResizing(resizing);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800542 }
543
Wale Ogunwale1666e312016-12-16 11:27:18 -0800544 // TODO: Consolidate this with the resize() method below.
Wale Ogunwale1666e312016-12-16 11:27:18 -0800545 public void requestResize(Rect bounds, int resizeMode) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700546 mService.resizeTask(taskId, bounds, resizeMode);
Wale Ogunwale1666e312016-12-16 11:27:18 -0800547 }
548
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800549 boolean resize(Rect bounds, int resizeMode, boolean preserveWindow, boolean deferResume) {
Bryce Leef3c6a472017-11-14 14:53:06 -0800550 mService.mWindowManager.deferSurfaceLayout();
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800551
Bryce Leef3c6a472017-11-14 14:53:06 -0800552 try {
553 if (!isResizeable()) {
554 Slog.w(TAG, "resizeTask: task " + this + " not resizeable.");
555 return true;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800556 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800557
Bryce Leef3c6a472017-11-14 14:53:06 -0800558 // If this is a forced resize, let it go through even if the bounds is not changing,
559 // as we might need a relayout due to surface size change (to/from fullscreen).
560 final boolean forced = (resizeMode & RESIZE_MODE_FORCED) != 0;
Evan Roskydfe3da72018-10-26 17:21:06 -0700561 if (equivalentRequestedOverrideBounds(bounds) && !forced) {
Bryce Leef3c6a472017-11-14 14:53:06 -0800562 // Nothing to do here...
563 return true;
564 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800565
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800566 if (mTask == null) {
Bryce Leef3c6a472017-11-14 14:53:06 -0800567 // Task doesn't exist in window manager yet (e.g. was restored from recents).
568 // All we can do for now is update the bounds so it can be used when the task is
569 // added to window manager.
570 updateOverrideConfiguration(bounds);
571 if (!inFreeformWindowingMode()) {
572 // re-restore the task so it can have the proper stack association.
573 mService.mStackSupervisor.restoreRecentTaskLocked(this, null, !ON_TOP);
574 }
575 return true;
576 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800577
Bryce Leef3c6a472017-11-14 14:53:06 -0800578 if (!canResizeToBounds(bounds)) {
579 throw new IllegalArgumentException("resizeTask: Can not resize task=" + this
580 + " to bounds=" + bounds + " resizeMode=" + mResizeMode);
581 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800582
Bryce Leef3c6a472017-11-14 14:53:06 -0800583 // Do not move the task to another stack here.
584 // This method assumes that the task is already placed in the right stack.
585 // we do not mess with that decision and we only do the resize!
586
587 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeTask_" + taskId);
588
589 final boolean updatedConfig = updateOverrideConfiguration(bounds);
590 // This variable holds information whether the configuration didn't change in a significant
591
592 // way and the activity was kept the way it was. If it's false, it means the activity
593 // had
594 // to be relaunched due to configuration change.
595 boolean kept = true;
596 if (updatedConfig) {
597 final ActivityRecord r = topRunningActivityLocked();
598 if (r != null && !deferResume) {
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -0800599 kept = r.ensureActivityConfiguration(0 /* globalChanges */,
Bryce Leef3c6a472017-11-14 14:53:06 -0800600 preserveWindow);
Garfield Tanb9151182018-06-25 16:29:21 -0700601 // Preserve other windows for resizing because if resizing happens when there
602 // is a dialog activity in the front, the activity that still shows some
603 // content to the user will become black and cause flickers. Note in most cases
604 // this won't cause tons of irrelevant windows being preserved because only
605 // activities in this task may experience a bounds change. Configs for other
606 // activities stay the same.
Wale Ogunwaled32da472018-11-16 07:19:28 -0800607 mService.mRootActivityContainer.ensureActivitiesVisible(r, 0, preserveWindow);
Bryce Leef3c6a472017-11-14 14:53:06 -0800608 if (!kept) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800609 mService.mRootActivityContainer.resumeFocusedStacksTopActivities();
Bryce Leef3c6a472017-11-14 14:53:06 -0800610 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800611 }
612 }
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800613 mTask.resize(kept, forced);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800614
Garfield Tan891146c2018-10-09 12:14:00 -0700615 saveLaunchingStateIfNeeded();
616
Bryce Leef3c6a472017-11-14 14:53:06 -0800617 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
618 return kept;
619 } finally {
620 mService.mWindowManager.continueSurfaceLayout();
621 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800622 }
623
624 // TODO: Investigate combining with the resize() method above.
625 void resizeWindowContainer() {
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800626 mTask.resize(false /* relayout */, false /* forced */);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800627 }
628
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800629 void getWindowContainerBounds(Rect bounds) {
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800630 if (mTask != null) {
631 mTask.getBounds(bounds);
632 } else {
633 bounds.setEmpty();
634 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800635 }
636
Winson Chung74666102017-02-22 17:49:24 -0800637 /**
638 * Convenience method to reparent a task to the top or bottom position of the stack.
639 */
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700640 boolean reparent(ActivityStack preferredStack, boolean toTop,
641 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
642 String reason) {
643 return reparent(preferredStack, toTop ? MAX_VALUE : 0, moveStackMode, animate, deferResume,
644 true /* schedulePictureInPictureModeChange */, reason);
Winson Chung5af42fc2017-03-24 17:11:33 -0700645 }
646
647 /**
648 * Convenience method to reparent a task to the top or bottom position of the stack, with
649 * an option to skip scheduling the picture-in-picture mode change.
650 */
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700651 boolean reparent(ActivityStack preferredStack, boolean toTop,
652 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
653 boolean schedulePictureInPictureModeChange, String reason) {
654 return reparent(preferredStack, toTop ? MAX_VALUE : 0, moveStackMode, animate,
Winson Chung5af42fc2017-03-24 17:11:33 -0700655 deferResume, schedulePictureInPictureModeChange, reason);
656 }
657
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700658 /** Convenience method to reparent a task to a specific position of the stack. */
659 boolean reparent(ActivityStack preferredStack, int position,
660 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
661 String reason) {
662 return reparent(preferredStack, position, moveStackMode, animate, deferResume,
Winson Chung5af42fc2017-03-24 17:11:33 -0700663 true /* schedulePictureInPictureModeChange */, reason);
Winson Chung74666102017-02-22 17:49:24 -0800664 }
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800665
Winson Chung74666102017-02-22 17:49:24 -0800666 /**
667 * Reparents the task into a preferred stack, creating it if necessary.
668 *
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700669 * @param preferredStack the target stack to move this task
Winson Chung74666102017-02-22 17:49:24 -0800670 * @param position the position to place this task in the new stack
671 * @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 -0700672 * reparenting to be drawn and animated in
Winson Chung74666102017-02-22 17:49:24 -0800673 * @param moveStackMode whether or not to move the stack to the front always, only if it was
Winson Chung5af42fc2017-03-24 17:11:33 -0700674 * previously focused & in front, or never
Winson Chung74666102017-02-22 17:49:24 -0800675 * @param deferResume whether or not to update the visibility of other tasks and stacks that may
Winson Chung5af42fc2017-03-24 17:11:33 -0700676 * have changed as a result of this reparenting
677 * @param schedulePictureInPictureModeChange specifies whether or not to schedule the PiP mode
678 * change. Callers may set this to false if they are explicitly scheduling PiP mode
679 * changes themselves, like during the PiP animation
Winson Chung74666102017-02-22 17:49:24 -0800680 * @param reason the caller of this reparenting
Winson Chung5af42fc2017-03-24 17:11:33 -0700681 * @return whether the task was reparented
Winson Chung74666102017-02-22 17:49:24 -0800682 */
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700683 // TODO: Inspect all call sites and change to just changing windowing mode of the stack vs.
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700684 // re-parenting the task. Can only be done when we are no longer using static stack Ids.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700685 boolean reparent(ActivityStack preferredStack, int position,
686 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
687 boolean schedulePictureInPictureModeChange, String reason) {
Winson Chung74666102017-02-22 17:49:24 -0800688 final ActivityStackSupervisor supervisor = mService.mStackSupervisor;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800689 final RootActivityContainer root = mService.mRootActivityContainer;
Winson Chung74666102017-02-22 17:49:24 -0800690 final WindowManagerService windowManager = mService.mWindowManager;
691 final ActivityStack sourceStack = getStack();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700692 final ActivityStack toStack = supervisor.getReparentTargetStack(this, preferredStack,
Winson Chung74666102017-02-22 17:49:24 -0800693 position == MAX_VALUE);
694 if (toStack == sourceStack) {
695 return false;
696 }
Andrii Kulianb850ea52017-12-12 23:49:10 -0800697 if (!canBeLaunchedOnDisplay(toStack.mDisplayId)) {
698 return false;
699 }
Winson Chung74666102017-02-22 17:49:24 -0800700
Andrii Kulian6b321512019-01-23 06:37:00 +0000701 final boolean toTopOfStack = position == MAX_VALUE;
702 if (toTopOfStack && toStack.getResumedActivity() != null
703 && toStack.topRunningActivityLocked() != null) {
704 // Pause the resumed activity on the target stack while re-parenting task on top of it.
705 toStack.startPausingLocked(false /* userLeaving */, false /* uiSleeping */,
706 null /* resuming */, false /* pauseImmediately */);
707 }
708
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700709 final int toStackWindowingMode = toStack.getWindowingMode();
Winson Chung74666102017-02-22 17:49:24 -0800710 final ActivityRecord topActivity = getTopActivity();
711
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800712 final boolean mightReplaceWindow = topActivity != null
713 && replaceWindowsOnTaskMove(getWindowingMode(), toStackWindowingMode);
Winson Chung74666102017-02-22 17:49:24 -0800714 if (mightReplaceWindow) {
715 // We are about to relaunch the activity because its configuration changed due to
716 // being maximized, i.e. size change. The activity will first remove the old window
717 // and then add a new one. This call will tell window manager about this, so it can
718 // preserve the old window until the new one is drawn. This prevents having a gap
719 // between the removal and addition, in which no window is visible. We also want the
720 // entrance of the new window to be properly animated.
721 // Note here we always set the replacing window first, as the flags might be needed
722 // during the relaunch. If we end up not doing any relaunch, we clear the flags later.
723 windowManager.setWillReplaceWindow(topActivity.appToken, animate);
724 }
725
726 windowManager.deferSurfaceLayout();
727 boolean kept = true;
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800728 try {
Winson Chung74666102017-02-22 17:49:24 -0800729 final ActivityRecord r = topRunningActivityLocked();
Wale Ogunwaled32da472018-11-16 07:19:28 -0800730 final boolean wasFocused = r != null && root.isTopDisplayFocusedStack(sourceStack)
Winson Chung74666102017-02-22 17:49:24 -0800731 && (topRunningActivityLocked() == r);
Bryce Leec4ab62a2018-03-05 14:19:26 -0800732 final boolean wasResumed = r != null && sourceStack.getResumedActivity() == r;
Winson Chung95f8f0e2017-03-24 09:20:17 -0700733 final boolean wasPaused = r != null && sourceStack.mPausingActivity == r;
Winson Chung74666102017-02-22 17:49:24 -0800734
735 // In some cases the focused stack isn't the front stack. E.g. pinned stack.
736 // Whenever we are moving the top activity from the front stack we want to make sure to
737 // move the stack to the front.
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -0700738 final boolean wasFront = r != null && sourceStack.isTopStackOnDisplay()
Winson Chung74666102017-02-22 17:49:24 -0800739 && (sourceStack.topRunningActivityLocked() == r);
740
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800741 // Adjust the position for the new parent stack as needed.
Winson Chung74666102017-02-22 17:49:24 -0800742 position = toStack.getAdjustedPositionForTask(this, position, null /* starting */);
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800743
744 // Must reparent first in window manager to avoid a situation where AM can delete the
745 // we are coming from in WM before we reparent because it became empty.
Yunfan Chen279f5582018-12-12 15:24:50 -0800746 mTask.reparent(toStack.getTaskStack(), position,
Wale Ogunwale2719cc12017-04-14 09:45:27 -0700747 moveStackMode == REPARENT_MOVE_STACK_TO_FRONT);
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800748
Wale Ogunwale56d8d162017-05-30 11:12:20 -0700749 final boolean moveStackToFront = moveStackMode == REPARENT_MOVE_STACK_TO_FRONT
750 || (moveStackMode == REPARENT_KEEP_STACK_AT_FRONT && (wasFocused || wasFront));
Winson Chung74666102017-02-22 17:49:24 -0800751 // Move the task
Wale Ogunwale56d8d162017-05-30 11:12:20 -0700752 sourceStack.removeTask(this, reason, moveStackToFront
753 ? REMOVE_TASK_MODE_MOVING_TO_TOP : REMOVE_TASK_MODE_MOVING);
Winson Chung5af42fc2017-03-24 17:11:33 -0700754 toStack.addTask(this, position, false /* schedulePictureInPictureModeChange */, reason);
Winson Chung74666102017-02-22 17:49:24 -0800755
Winson Chung5af42fc2017-03-24 17:11:33 -0700756 if (schedulePictureInPictureModeChange) {
757 // Notify of picture-in-picture mode changes
758 supervisor.scheduleUpdatePictureInPictureModeIfNeeded(this, sourceStack);
759 }
Winson Chung74666102017-02-22 17:49:24 -0800760
761 // TODO: Ensure that this is actually necessary here
762 // Notify the voice session if required
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800763 if (voiceSession != null) {
764 try {
765 voiceSession.taskStarted(intent, taskId);
766 } catch (RemoteException e) {
767 }
768 }
Winson Chung74666102017-02-22 17:49:24 -0800769
770 // If the task had focus before (or we're requested to move focus), move focus to the
771 // new stack by moving the stack to the front.
Winson Chung95f8f0e2017-03-24 09:20:17 -0700772 if (r != null) {
773 toStack.moveToFrontAndResumeStateIfNeeded(r, moveStackToFront, wasResumed,
774 wasPaused, reason);
775 }
Winson Chung74666102017-02-22 17:49:24 -0800776 if (!animate) {
Jorim Jaggifa9ed962018-01-25 00:16:49 +0100777 mService.mStackSupervisor.mNoAnimActivities.add(topActivity);
Winson Chung74666102017-02-22 17:49:24 -0800778 }
779
780 // We might trigger a configuration change. Save the current task bounds for freezing.
781 // TODO: Should this call be moved inside the resize method in WM?
782 toStack.prepareFreezingTaskBounds();
783
784 // Make sure the task has the appropriate bounds/size for the stack it is in.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700785 final boolean toStackSplitScreenPrimary =
786 toStackWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Evan Roskydfe3da72018-10-26 17:21:06 -0700787 final Rect configBounds = getRequestedOverrideBounds();
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700788 if ((toStackWindowingMode == WINDOWING_MODE_FULLSCREEN
789 || toStackWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY)
Evan Roskydfe3da72018-10-26 17:21:06 -0700790 && !Objects.equals(configBounds, toStack.getRequestedOverrideBounds())) {
791 kept = resize(toStack.getRequestedOverrideBounds(), RESIZE_MODE_SYSTEM,
792 !mightReplaceWindow, deferResume);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700793 } else if (toStackWindowingMode == WINDOWING_MODE_FREEFORM) {
Winson Chung74666102017-02-22 17:49:24 -0800794 Rect bounds = getLaunchBounds();
795 if (bounds == null) {
Bryce Leeec55eb02017-12-05 20:51:27 -0800796 mService.mStackSupervisor.getLaunchParamsController().layoutTask(this, null);
Bryce Leef3c6a472017-11-14 14:53:06 -0800797 bounds = configBounds;
Winson Chung74666102017-02-22 17:49:24 -0800798 }
799 kept = resize(bounds, RESIZE_MODE_FORCED, !mightReplaceWindow, deferResume);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700800 } else if (toStackSplitScreenPrimary || toStackWindowingMode == WINDOWING_MODE_PINNED) {
801 if (toStackSplitScreenPrimary && moveStackMode == REPARENT_KEEP_STACK_AT_FRONT) {
Matthew Ng330757d2017-02-28 14:19:17 -0800802 // Move recents to front so it is not behind home stack when going into docked
803 // mode
804 mService.mStackSupervisor.moveRecentsStackToFront(reason);
805 }
Evan Roskydfe3da72018-10-26 17:21:06 -0700806 kept = resize(toStack.getRequestedOverrideBounds(), RESIZE_MODE_SYSTEM,
807 !mightReplaceWindow, deferResume);
Winson Chung74666102017-02-22 17:49:24 -0800808 }
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800809 } finally {
Winson Chung74666102017-02-22 17:49:24 -0800810 windowManager.continueSurfaceLayout();
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800811 }
Winson Chung74666102017-02-22 17:49:24 -0800812
813 if (mightReplaceWindow) {
814 // If we didn't actual do a relaunch (indicated by kept==true meaning we kept the old
815 // window), we need to clear the replace window settings. Otherwise, we schedule a
816 // timeout to remove the old window if the replacing window is not coming in time.
817 windowManager.scheduleClearWillReplaceWindows(topActivity.appToken, !kept);
818 }
819
820 if (!deferResume) {
821 // The task might have already been running and its visibility needs to be synchronized
822 // with the visibility of the stack / windows.
Wale Ogunwaled32da472018-11-16 07:19:28 -0800823 root.ensureActivitiesVisible(null, 0, !mightReplaceWindow);
824 root.resumeFocusedStacksTopActivities();
Winson Chung74666102017-02-22 17:49:24 -0800825 }
826
Andrii Kulian036e3ad2017-04-19 10:55:10 -0700827 // TODO: Handle incorrect request to move before the actual move, not after.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700828 supervisor.handleNonResizableTaskIfNeeded(this, preferredStack.getWindowingMode(),
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -0700829 DEFAULT_DISPLAY, toStack);
Winson Chung74666102017-02-22 17:49:24 -0800830
Winson Chungdff7a732017-12-11 12:17:06 -0800831 return (preferredStack == toStack);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800832 }
833
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700834 /**
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800835 * @return True if the windows of tasks being moved to the target stack from the source stack
836 * should be replaced, meaning that window manager will keep the old window around until the new
837 * is ready.
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700838 */
839 private static boolean replaceWindowsOnTaskMove(
840 int sourceWindowingMode, int targetWindowingMode) {
841 return sourceWindowingMode == WINDOWING_MODE_FREEFORM
842 || targetWindowingMode == WINDOWING_MODE_FREEFORM;
843 }
844
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800845 void cancelWindowTransition() {
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800846 if (mTask == null) {
847 Slog.w(TAG_WM, "cancelWindowTransition: taskId " + taskId + " not found.");
848 return;
849 }
850 mTask.cancelTaskWindowTransition();
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800851 }
852
Jorim Jaggi7361bab2017-01-16 17:17:58 +0100853 /**
854 * DO NOT HOLD THE ACTIVITY MANAGER LOCK WHEN CALLING THIS METHOD!
855 */
Jorim Jaggi35e3f532017-03-17 17:06:50 +0100856 TaskSnapshot getSnapshot(boolean reducedResolution) {
Jorim Jaggi7361bab2017-01-16 17:17:58 +0100857
858 // TODO: Move this to {@link TaskWindowContainerController} once recent tasks are more
859 // synchronized between AM and WM.
Jorim Jaggi35e3f532017-03-17 17:06:50 +0100860 return mService.mWindowManager.getTaskSnapshot(taskId, userId, reducedResolution);
Jorim Jaggi02886a82016-12-06 09:10:06 -0800861 }
862
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800863 void touchActiveTime() {
Winson Chungfb44d212017-10-04 11:39:10 -0700864 lastActiveTime = SystemClock.elapsedRealtime();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800865 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700866
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800867 long getInactiveDuration() {
Winson Chungfb44d212017-10-04 11:39:10 -0700868 return SystemClock.elapsedRealtime() - lastActiveTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800869 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700870
Winson Chungfee26772014-08-05 12:21:52 -0700871 /** Sets the original intent, and the calling uid and package. */
872 void setIntent(ActivityRecord r) {
Winson Chungfee26772014-08-05 12:21:52 -0700873 mCallingUid = r.launchedFromUid;
874 mCallingPackage = r.launchedFromPackage;
Craig Mautner15df08a2015-04-01 12:17:18 -0700875 setIntent(r.intent, r.info);
Charles He2bf28322017-10-12 22:24:49 +0100876 setLockTaskAuth(r);
Winson Chungfee26772014-08-05 12:21:52 -0700877 }
878
879 /** Sets the original intent, _without_ updating the calling uid or package. */
880 private void setIntent(Intent _intent, ActivityInfo info) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700881 if (intent == null) {
882 mNeverRelinquishIdentity =
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700883 (info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700884 } else if (mNeverRelinquishIdentity) {
885 return;
886 }
887
888 affinity = info.taskAffinity;
Dianne Hackborn79228822014-09-16 11:11:23 -0700889 if (intent == null) {
890 // If this task already has an intent associated with it, don't set the root
891 // affinity -- we don't want it changing after initially set, but the initially
892 // set value may be null.
893 rootAffinity = affinity;
894 }
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700895 effectiveUid = info.applicationInfo.uid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700896 stringName = null;
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800897
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800898 if (info.targetActivity == null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800899 if (_intent != null) {
900 // If this Intent has a selector, we want to clear it for the
901 // recent task since it is not relevant if the user later wants
902 // to re-launch the app.
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700903 if (_intent.getSelector() != null || _intent.getSourceBounds() != null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800904 _intent = new Intent(_intent);
905 _intent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700906 _intent.setSourceBounds(null);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800907 }
908 }
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700909 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Setting Intent of " + this + " to " + _intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800910 intent = _intent;
911 realActivity = _intent != null ? _intent.getComponent() : null;
912 origActivity = null;
913 } else {
914 ComponentName targetComponent = new ComponentName(
915 info.packageName, info.targetActivity);
916 if (_intent != null) {
917 Intent targetIntent = new Intent(_intent);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800918 targetIntent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700919 targetIntent.setSourceBounds(null);
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700920 if (DEBUG_TASKS) Slog.v(TAG_TASKS,
Dianne Hackborn7f96b792012-05-29 18:46:45 -0700921 "Setting Intent of " + this + " to target " + targetIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800922 intent = targetIntent;
923 realActivity = targetComponent;
924 origActivity = _intent.getComponent();
925 } else {
926 intent = null;
927 realActivity = targetComponent;
928 origActivity = new ComponentName(info.packageName, info.name);
929 }
930 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700931
Craig Mautner47b20ba2014-09-17 17:23:44 -0700932 final int intentFlags = intent == null ? 0 : intent.getFlags();
933 if ((intentFlags & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800934 // Once we are set to an Intent with this flag, we count this
935 // task as having a true root activity.
936 rootWasReset = true;
937 }
Dianne Hackborn09233282014-04-30 11:33:59 -0700938 userId = UserHandle.getUserId(info.applicationInfo.uid);
Winson Chung36f3f032016-09-08 23:29:43 +0000939 mUserSetupComplete = Settings.Secure.getIntForUser(mService.mContext.getContentResolver(),
940 USER_SETUP_COMPLETE, 0, userId) != 0;
Craig Mautner41db4a72014-05-07 17:20:56 -0700941 if ((info.flags & ActivityInfo.FLAG_AUTO_REMOVE_FROM_RECENTS) != 0) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700942 // If the activity itself has requested auto-remove, then just always do it.
943 autoRemoveRecents = true;
Wale Ogunwale843bfb92015-03-27 11:06:48 -0700944 } else if ((intentFlags & (FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS))
945 == FLAG_ACTIVITY_NEW_DOCUMENT) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700946 // If the caller has not asked for the document to be retained, then we may
947 // want to turn on auto-remove, depending on whether the target has set its
948 // own document launch mode.
949 if (info.documentLaunchMode != ActivityInfo.DOCUMENT_LAUNCH_NONE) {
950 autoRemoveRecents = false;
951 } else {
952 autoRemoveRecents = true;
953 }
954 } else {
955 autoRemoveRecents = false;
Craig Mautner41db4a72014-05-07 17:20:56 -0700956 }
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800957 mResizeMode = info.resizeMode;
Winson Chungd3395382016-12-13 11:49:09 -0800958 mSupportsPictureInPicture = info.supportsPictureInPicture();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800959 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800960
Andrii Kulian2e751b82016-03-16 16:59:32 -0700961 /** Sets the original minimal width and height. */
962 private void setMinDimensions(ActivityInfo info) {
963 if (info != null && info.windowLayout != null) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700964 mMinWidth = info.windowLayout.minWidth;
965 mMinHeight = info.windowLayout.minHeight;
Andrii Kulian2e751b82016-03-16 16:59:32 -0700966 } else {
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700967 mMinWidth = INVALID_MIN_SIZE;
968 mMinHeight = INVALID_MIN_SIZE;
Andrii Kulian2e751b82016-03-16 16:59:32 -0700969 }
970 }
971
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800972 /**
Andrii Kulian206b9fa2016-06-02 13:18:01 -0700973 * Return true if the input activity has the same intent filter as the intent this task
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800974 * record is based on (normally the root activity intent).
975 */
Andrii Kulian206b9fa2016-06-02 13:18:01 -0700976 boolean isSameIntentFilter(ActivityRecord r) {
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800977 final Intent intent = new Intent(r.intent);
Louis Chang23df1a62019-01-09 15:10:49 +0800978 // Make sure the component are the same if the input activity has the same real activity
979 // as the one in the task because either one of them could be the alias activity.
980 if (Objects.equals(realActivity, r.mActivityComponent) && this.intent != null) {
981 intent.setComponent(this.intent.getComponent());
982 }
Bryce Lee1a990e52018-04-23 10:54:11 -0700983 return intent.filterEquals(this.intent);
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800984 }
985
Wale Ogunwale66e16852017-10-19 13:35:52 -0700986 boolean returnsToHomeStack() {
987 final int returnHomeFlags = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME;
Bryce Lee1a990e52018-04-23 10:54:11 -0700988 return intent != null && (intent.getFlags() & returnHomeFlags) == returnHomeFlags;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700989 }
990
Craig Mautnera228ae92014-07-09 05:44:55 -0700991 void setPrevAffiliate(TaskRecord prevAffiliate) {
992 mPrevAffiliate = prevAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800993 mPrevAffiliateTaskId = prevAffiliate == null ? INVALID_TASK_ID : prevAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700994 }
995
996 void setNextAffiliate(TaskRecord nextAffiliate) {
997 mNextAffiliate = nextAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800998 mNextAffiliateTaskId = nextAffiliate == null ? INVALID_TASK_ID : nextAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700999 }
1000
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001001 <T extends ActivityStack> T getStack() {
1002 return (T) mStack;
Andrii Kulian02b7a832016-10-06 23:11:56 -07001003 }
1004
Andrii Kulianfb1bf692017-01-17 11:17:34 -08001005 /**
1006 * Must be used for setting parent stack because it performs configuration updates.
1007 * Must be called after adding task as a child to the stack.
1008 */
Andrii Kulian02b7a832016-10-06 23:11:56 -07001009 void setStack(ActivityStack stack) {
Andrii Kulianfb1bf692017-01-17 11:17:34 -08001010 if (stack != null && !stack.isInStackLocked(this)) {
1011 throw new IllegalStateException("Task must be added as a Stack child first.");
1012 }
Bryce Lee84730a02018-04-03 14:10:04 -07001013 final ActivityStack oldStack = mStack;
Andrii Kulian02b7a832016-10-06 23:11:56 -07001014 mStack = stack;
Bryce Lee84730a02018-04-03 14:10:04 -07001015
1016 // If the new {@link TaskRecord} is from a different {@link ActivityStack}, remove this
1017 // {@link ActivityRecord} from its current {@link ActivityStack}.
1018
1019 if (oldStack != mStack) {
1020 for (int i = getChildCount() - 1; i >= 0; --i) {
1021 final ActivityRecord activity = getChildAt(i);
1022
1023 if (oldStack != null) {
1024 oldStack.onActivityRemovedFromStack(activity);
1025 }
1026
1027 if (mStack != null) {
1028 stack.onActivityAddedToStack(activity);
1029 }
1030 }
1031 }
1032
Andrii Kulian1779e612016-10-12 21:58:25 -07001033 onParentChanged();
Andrii Kulian02b7a832016-10-06 23:11:56 -07001034 }
1035
1036 /**
1037 * @return Id of current stack, {@link INVALID_STACK_ID} if no stack is set.
1038 */
1039 int getStackId() {
1040 return mStack != null ? mStack.mStackId : INVALID_STACK_ID;
1041 }
1042
Andrii Kulian1779e612016-10-12 21:58:25 -07001043 @Override
1044 protected int getChildCount() {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07001045 return mActivities.size();
Andrii Kulian1779e612016-10-12 21:58:25 -07001046 }
1047
1048 @Override
chaviw82a0ba82018-03-15 14:26:29 -07001049 protected ActivityRecord getChildAt(int index) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07001050 return mActivities.get(index);
Andrii Kulian1779e612016-10-12 21:58:25 -07001051 }
1052
1053 @Override
1054 protected ConfigurationContainer getParent() {
1055 return mStack;
1056 }
1057
Andrii Kulianfb1bf692017-01-17 11:17:34 -08001058 @Override
Wale Ogunwale98d62312017-07-12 09:24:56 -07001059 protected void onParentChanged() {
Andrii Kulianfb1bf692017-01-17 11:17:34 -08001060 super.onParentChanged();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001061 mService.mRootActivityContainer.updateUIDsPresentOnDisplay();
Andrii Kulianfb1bf692017-01-17 11:17:34 -08001062 }
1063
Craig Mautnera228ae92014-07-09 05:44:55 -07001064 // Close up recents linked list.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07001065 private void closeRecentsChain() {
Craig Mautnera228ae92014-07-09 05:44:55 -07001066 if (mPrevAffiliate != null) {
1067 mPrevAffiliate.setNextAffiliate(mNextAffiliate);
1068 }
1069 if (mNextAffiliate != null) {
1070 mNextAffiliate.setPrevAffiliate(mPrevAffiliate);
1071 }
1072 setPrevAffiliate(null);
1073 setNextAffiliate(null);
1074 }
1075
Winson Chung740c3ac2014-11-12 16:14:38 -08001076 void removedFromRecents() {
Dianne Hackborn852975d2014-08-22 17:42:43 -07001077 closeRecentsChain();
1078 if (inRecents) {
1079 inRecents = false;
Winson Chung740c3ac2014-11-12 16:14:38 -08001080 mService.notifyTaskPersisterLocked(this, false);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001081 }
Jorim Jaggif9084ec2017-01-16 13:16:59 +01001082
Dianne Hackborn68a06332017-11-15 17:54:18 -08001083 clearRootProcess();
1084
Jorim Jaggif9084ec2017-01-16 13:16:59 +01001085 // TODO: Use window container controller once tasks are better synced between AM and WM
1086 mService.mWindowManager.notifyTaskRemovedFromRecents(taskId, userId);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001087 }
1088
Craig Mautnera228ae92014-07-09 05:44:55 -07001089 void setTaskToAffiliateWith(TaskRecord taskToAffiliateWith) {
1090 closeRecentsChain();
1091 mAffiliatedTaskId = taskToAffiliateWith.mAffiliatedTaskId;
Winson Chungec396d62014-08-06 17:08:00 -07001092 mAffiliatedTaskColor = taskToAffiliateWith.mAffiliatedTaskColor;
Craig Mautnera228ae92014-07-09 05:44:55 -07001093 // Find the end
1094 while (taskToAffiliateWith.mNextAffiliate != null) {
1095 final TaskRecord nextRecents = taskToAffiliateWith.mNextAffiliate;
1096 if (nextRecents.mAffiliatedTaskId != mAffiliatedTaskId) {
1097 Slog.e(TAG, "setTaskToAffiliateWith: nextRecents=" + nextRecents + " affilTaskId="
1098 + nextRecents.mAffiliatedTaskId + " should be " + mAffiliatedTaskId);
1099 if (nextRecents.mPrevAffiliate == taskToAffiliateWith) {
1100 nextRecents.setPrevAffiliate(null);
1101 }
1102 taskToAffiliateWith.setNextAffiliate(null);
1103 break;
1104 }
1105 taskToAffiliateWith = nextRecents;
1106 }
1107 taskToAffiliateWith.setNextAffiliate(this);
1108 setPrevAffiliate(taskToAffiliateWith);
1109 setNextAffiliate(null);
1110 }
1111
Winson Chung1147c402014-05-14 11:05:00 -07001112 /** Returns the intent for the root activity for this task */
1113 Intent getBaseIntent() {
1114 return intent != null ? intent : affinityIntent;
1115 }
1116
Winson Chung3b3f4642014-04-22 10:08:18 -07001117 /** Returns the first non-finishing activity from the root. */
1118 ActivityRecord getRootActivity() {
1119 for (int i = 0; i < mActivities.size(); i++) {
1120 final ActivityRecord r = mActivities.get(i);
1121 if (r.finishing) {
1122 continue;
1123 }
1124 return r;
1125 }
1126 return null;
1127 }
1128
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001129 ActivityRecord getTopActivity() {
Bryce Lee9f6affd2017-09-01 09:18:35 -07001130 return getTopActivity(true /* includeOverlays */);
1131 }
1132
1133 ActivityRecord getTopActivity(boolean includeOverlays) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001134 for (int i = mActivities.size() - 1; i >= 0; --i) {
1135 final ActivityRecord r = mActivities.get(i);
Bryce Lee9f6affd2017-09-01 09:18:35 -07001136 if (r.finishing || (!includeOverlays && r.mTaskOverlay)) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001137 continue;
1138 }
1139 return r;
1140 }
1141 return null;
1142 }
1143
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -07001144 ActivityRecord topRunningActivityLocked() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001145 if (mStack != null) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07001146 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1147 ActivityRecord r = mActivities.get(activityNdx);
Chong Zhang87761972016-08-22 13:53:24 -07001148 if (!r.finishing && r.okToShowLocked()) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07001149 return r;
1150 }
Craig Mautner6b74cb52013-09-27 17:02:21 -07001151 }
1152 }
1153 return null;
1154 }
1155
Jorim Jaggi172e99f2017-10-20 14:33:18 +02001156 boolean isVisible() {
1157 for (int i = mActivities.size() - 1; i >= 0; --i) {
1158 final ActivityRecord r = mActivities.get(i);
1159 if (r.visible) {
1160 return true;
1161 }
1162 }
1163 return false;
1164 }
1165
Jorim Jaggiea039a82017-08-02 14:37:49 +02001166 void getAllRunningVisibleActivitiesLocked(ArrayList<ActivityRecord> outActivities) {
1167 if (mStack != null) {
1168 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1169 ActivityRecord r = mActivities.get(activityNdx);
Jorim Jaggi02f1d2f2017-08-04 14:29:16 +02001170 if (!r.finishing && r.okToShowLocked() && r.visibleIgnoringKeyguard) {
Jorim Jaggiea039a82017-08-02 14:37:49 +02001171 outActivities.add(r);
1172 }
1173 }
1174 }
1175 }
1176
Wale Ogunwale3b232392016-05-13 15:37:13 -07001177 ActivityRecord topRunningActivityWithStartingWindowLocked() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001178 if (mStack != null) {
Wale Ogunwale3b232392016-05-13 15:37:13 -07001179 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1180 ActivityRecord r = mActivities.get(activityNdx);
1181 if (r.mStartingWindowState != STARTING_WINDOW_SHOWN
Chong Zhang87761972016-08-22 13:53:24 -07001182 || r.finishing || !r.okToShowLocked()) {
Wale Ogunwale3b232392016-05-13 15:37:13 -07001183 continue;
1184 }
1185 return r;
1186 }
1187 }
1188 return null;
1189 }
1190
Winson Chung61c9e5a2017-10-11 10:39:32 -07001191 /**
1192 * Return the number of running activities, and the number of non-finishing/initializing
1193 * activities in the provided {@param reportOut} respectively.
1194 */
1195 void getNumRunningActivities(TaskActivitiesReport reportOut) {
1196 reportOut.reset();
1197 for (int i = mActivities.size() - 1; i >= 0; --i) {
1198 final ActivityRecord r = mActivities.get(i);
1199 if (r.finishing) {
1200 continue;
1201 }
1202
1203 reportOut.base = r;
1204
1205 // Increment the total number of non-finishing activities
1206 reportOut.numActivities++;
1207
Bryce Lee7ace3952018-02-16 14:34:32 -08001208 if (reportOut.top == null || (reportOut.top.isState(ActivityState.INITIALIZING))) {
Winson Chung61c9e5a2017-10-11 10:39:32 -07001209 reportOut.top = r;
1210 // Reset the number of running activities until we hit the first non-initializing
1211 // activity
1212 reportOut.numRunning = 0;
1213 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001214 if (r.attachedToProcess()) {
Winson Chung61c9e5a2017-10-11 10:39:32 -07001215 // Increment the number of actually running activities
1216 reportOut.numRunning++;
1217 }
1218 }
1219 }
1220
Chong Zhang87761972016-08-22 13:53:24 -07001221 boolean okToShowLocked() {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001222 // NOTE: If {@link TaskRecord#topRunningActivity} return is not null then it is
Chong Zhang87761972016-08-22 13:53:24 -07001223 // okay to show the activity when locked.
1224 return mService.mStackSupervisor.isCurrentProfileLocked(userId)
1225 || topRunningActivityLocked() != null;
1226 }
1227
Craig Mautner3b475fe2013-12-16 15:58:31 -08001228 /** Call after activity movement or finish to make sure that frontOfTask is set correctly */
Bryce Leed71317c2017-02-07 14:27:22 -08001229 final void setFrontOfTask() {
1230 boolean foundFront = false;
Craig Mautner3b475fe2013-12-16 15:58:31 -08001231 final int numActivities = mActivities.size();
Craig Mautner704e40b2013-12-18 16:43:51 -08001232 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
Craig Mautner3b475fe2013-12-16 15:58:31 -08001233 final ActivityRecord r = mActivities.get(activityNdx);
1234 if (foundFront || r.finishing) {
1235 r.frontOfTask = false;
1236 } else {
1237 r.frontOfTask = true;
1238 // Set frontOfTask false for every following activity.
1239 foundFront = true;
1240 }
1241 }
Craig Mautner9587ee02014-06-23 15:00:10 +00001242 if (!foundFront && numActivities > 0) {
1243 // All activities of this task are finishing. As we ought to have a frontOfTask
1244 // activity, make the bottom activity front.
1245 mActivities.get(0).frontOfTask = true;
1246 }
Craig Mautner3b475fe2013-12-16 15:58:31 -08001247 }
1248
Craig Mautnerde4ef022013-04-07 19:01:33 -07001249 /**
Craig Mautner3b475fe2013-12-16 15:58:31 -08001250 * Reorder the history stack so that the passed activity is brought to the front.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001251 */
1252 final void moveActivityToFrontLocked(ActivityRecord newTop) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07001253 if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE,
1254 "Removing and adding activity " + newTop
1255 + " to stack at top callers=" + Debug.getCallers(4));
Craig Mautnerde4ef022013-04-07 19:01:33 -07001256
Craig Mautnerde4ef022013-04-07 19:01:33 -07001257 mActivities.remove(newTop);
1258 mActivities.add(newTop);
Bryce Leed58d7b32017-09-08 15:55:22 -07001259
1260 // Make sure window manager is aware of the position change.
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001261 mTask.positionChildAtTop(newTop.mAppWindowToken);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001262 updateEffectiveIntent();
Craig Mautner3b475fe2013-12-16 15:58:31 -08001263
Bryce Leed71317c2017-02-07 14:27:22 -08001264 setFrontOfTask();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001265 }
1266
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001267 void addActivityToTop(ActivityRecord r) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001268 addActivityAtIndex(mActivities.size(), r);
1269 }
1270
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001271 @Override
Wale Ogunwaleeea34ee92017-08-31 20:07:45 -07001272 /*@WindowConfiguration.ActivityType*/
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001273 public int getActivityType() {
1274 final int applicationType = super.getActivityType();
1275 if (applicationType != ACTIVITY_TYPE_UNDEFINED || mActivities.isEmpty()) {
1276 return applicationType;
1277 }
1278 return mActivities.get(0).getActivityType();
1279 }
1280
Winson Chung30480042017-01-26 10:55:34 -08001281 /**
Evan Rosky130d94f2019-01-15 10:18:17 -08001282 * Checks if the top activity requires a particular orientation (either by override or
Evan Rosky730f6e82018-12-03 17:40:11 -08001283 * activityInfo) and returns that. Otherwise, this returns ORIENTATION_UNDEFINED.
1284 */
Evan Rosky130d94f2019-01-15 10:18:17 -08001285 private int getTopActivityRequestedOrientation() {
1286 ActivityRecord top = getTopActivity();
Evan Rosky730f6e82018-12-03 17:40:11 -08001287 if (getRequestedOverrideConfiguration().orientation != ORIENTATION_UNDEFINED
Evan Rosky130d94f2019-01-15 10:18:17 -08001288 || top == null) {
Evan Rosky730f6e82018-12-03 17:40:11 -08001289 return getRequestedOverrideConfiguration().orientation;
1290 }
Riddle Hsu0a343c32018-12-21 00:40:48 +08001291 return top.getRequestedConfigurationOrientation();
Evan Rosky730f6e82018-12-03 17:40:11 -08001292 }
1293
1294 /**
Winson Chung30480042017-01-26 10:55:34 -08001295 * Adds an activity {@param r} at the given {@param index}. The activity {@param r} must either
1296 * be in the current task or unparented to any task.
1297 */
Craig Mautner1602ec22013-05-12 10:24:27 -07001298 void addActivityAtIndex(int index, ActivityRecord r) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001299 TaskRecord task = r.getTaskRecord();
Bryce Leeaf691c02017-03-20 14:20:22 -07001300 if (task != null && task != this) {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001301 throw new IllegalArgumentException("Can not add r=" + " to task=" + this
Bryce Leeaf691c02017-03-20 14:20:22 -07001302 + " current parent=" + task);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001303 }
Bryce Leeaf691c02017-03-20 14:20:22 -07001304
1305 r.setTask(this);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001306
Craig Mautner6170f732013-04-02 13:05:23 -07001307 // 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 -08001308 if (!mActivities.remove(r) && r.fullscreen) {
1309 // Was not previously in list.
1310 numFullscreen++;
1311 }
Craig Mautner2c1faed2013-07-23 12:56:02 -07001312 // Only set this based on the first activity
1313 if (mActivities.isEmpty()) {
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001314 if (r.getActivityType() == ACTIVITY_TYPE_UNDEFINED) {
1315 // Normally non-standard activity type for the activity record will be set when the
1316 // object is created, however we delay setting the standard application type until
1317 // this point so that the task can set the type for additional activities added in
1318 // the else condition below.
1319 r.setActivityType(ACTIVITY_TYPE_STANDARD);
1320 }
1321 setActivityType(r.getActivityType());
Craig Mautner21d24a22014-04-23 11:45:37 -07001322 isPersistable = r.isPersistable();
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001323 mCallingUid = r.launchedFromUid;
1324 mCallingPackage = r.launchedFromPackage;
Dianne Hackborn852975d2014-08-22 17:42:43 -07001325 // Clamp to [1, max].
1326 maxRecents = Math.min(Math.max(r.info.maxRecents, 1),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001327 ActivityTaskManager.getMaxAppRecentsLimitStatic());
Craig Mautner2c1faed2013-07-23 12:56:02 -07001328 } else {
1329 // Otherwise make all added activities match this one.
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001330 r.setActivityType(getActivityType());
Craig Mautner78733002013-06-10 13:54:49 -07001331 }
Wale Ogunwale3b232392016-05-13 15:37:13 -07001332
1333 final int size = mActivities.size();
1334
1335 if (index == size && size > 0) {
1336 final ActivityRecord top = mActivities.get(size - 1);
1337 if (top.mTaskOverlay) {
1338 // Place below the task overlay activity since the overlay activity should always
1339 // be on top.
1340 index--;
1341 }
1342 }
1343
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001344 index = Math.min(size, index);
Craig Mautner77878772013-03-04 19:46:24 -08001345 mActivities.add(index, r);
Bryce Lee84730a02018-04-03 14:10:04 -07001346
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001347 updateEffectiveIntent();
Craig Mautner21d24a22014-04-23 11:45:37 -07001348 if (r.isPersistable()) {
1349 mService.notifyTaskPersisterLocked(this, false);
1350 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001351
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001352 if (r.mAppWindowToken != null) {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001353 // Only attempt to move in WM if the child has a controller. It is possible we haven't
1354 // created controller for the activity we are starting yet.
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001355 mTask.positionChildAt(r.mAppWindowToken, index);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001356 }
David Stevens82ea6cb2017-03-03 16:18:50 -08001357
1358 // Make sure the list of display UID whitelists is updated
1359 // now that this record is in a new task.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001360 mService.mRootActivityContainer.updateUIDsPresentOnDisplay();
Craig Mautner77878772013-03-04 19:46:24 -08001361 }
1362
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001363 /**
Bryce Leeaf691c02017-03-20 14:20:22 -07001364 * Removes the specified activity from this task.
1365 * @param r The {@link ActivityRecord} to remove.
1366 * @return true if this was the last activity in the task.
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001367 */
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001368 boolean removeActivity(ActivityRecord r) {
Bryce Lee84730a02018-04-03 14:10:04 -07001369 return removeActivity(r, false /* reparenting */);
Bryce Leeaf691c02017-03-20 14:20:22 -07001370 }
1371
1372 boolean removeActivity(ActivityRecord r, boolean reparenting) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001373 if (r.getTaskRecord() != this) {
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001374 throw new IllegalArgumentException(
1375 "Activity=" + r + " does not belong to task=" + this);
1376 }
1377
Bryce Lee84730a02018-04-03 14:10:04 -07001378 r.setTask(null /* task */, reparenting /* reparenting */);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001379
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001380 if (mActivities.remove(r) && r.fullscreen) {
1381 // Was previously in list.
1382 numFullscreen--;
1383 }
Craig Mautner21d24a22014-04-23 11:45:37 -07001384 if (r.isPersistable()) {
1385 mService.notifyTaskPersisterLocked(this, false);
1386 }
Wale Ogunwale89182d52016-03-11 10:38:36 -08001387
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001388 if (inPinnedWindowingMode()) {
Wale Ogunwale89182d52016-03-11 10:38:36 -08001389 // We normally notify listeners of task stack changes on pause, however pinned stack
1390 // activities are normally in the paused state so no notification will be sent there
1391 // before the activity is removed. We send it here so instead.
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001392 mService.getTaskChangeNotificationController().notifyTaskStackChanged();
Wale Ogunwale89182d52016-03-11 10:38:36 -08001393 }
1394
Craig Mautner41326202014-06-20 14:38:21 -07001395 if (mActivities.isEmpty()) {
Craig Mautner5afcd4d2014-06-21 18:11:33 -07001396 return !mReuseTask;
Craig Mautner41326202014-06-20 14:38:21 -07001397 }
1398 updateEffectiveIntent();
1399 return false;
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001400 }
1401
Winson Chung6954fc92017-03-24 16:22:12 -07001402 /**
1403 * @return whether or not there are ONLY task overlay activities in the stack.
1404 * If {@param excludeFinishing} is set, then ignore finishing activities in the check.
1405 * If there are no task overlay activities, this call returns false.
1406 */
1407 boolean onlyHasTaskOverlayActivities(boolean excludeFinishing) {
1408 int count = 0;
1409 for (int i = mActivities.size() - 1; i >= 0; i--) {
1410 final ActivityRecord r = mActivities.get(i);
1411 if (excludeFinishing && r.finishing) {
1412 continue;
1413 }
1414 if (!r.mTaskOverlay) {
1415 return false;
1416 }
1417 count++;
1418 }
1419 return count > 0;
1420 }
1421
Craig Mautner41db4a72014-05-07 17:20:56 -07001422 boolean autoRemoveFromRecents() {
Dianne Hackbornd38aed82014-06-10 21:36:35 -07001423 // We will automatically remove the task either if it has explicitly asked for
1424 // this, or it is empty and has never contained an activity that got shown to
1425 // the user.
Dianne Hackborn13420f22014-07-18 15:43:56 -07001426 return autoRemoveRecents || (mActivities.isEmpty() && !hasBeenVisible);
Craig Mautner41db4a72014-05-07 17:20:56 -07001427 }
1428
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001429 /**
1430 * Completely remove all activities associated with an existing
1431 * task starting at a specified index.
1432 */
Winson Chung0ec2a352017-10-26 11:38:30 -07001433 final void performClearTaskAtIndexLocked(int activityNdx, boolean pauseImmediately,
1434 String reason) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001435 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001436 for ( ; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001437 final ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001438 if (r.finishing) {
1439 continue;
1440 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07001441 if (mStack == null) {
Craig Mautner21d24a22014-04-23 11:45:37 -07001442 // Task was restored from persistent storage.
1443 r.takeFromHistory();
1444 mActivities.remove(activityNdx);
1445 --activityNdx;
1446 --numActivities;
Winson Chung6954fc92017-03-24 16:22:12 -07001447 } else if (mStack.finishActivityLocked(r, Activity.RESULT_CANCELED, null,
Winson Chung0ec2a352017-10-26 11:38:30 -07001448 reason, false, pauseImmediately)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001449 --activityNdx;
1450 --numActivities;
1451 }
1452 }
1453 }
1454
1455 /**
1456 * Completely remove all activities associated with an existing task.
1457 */
Benjamin Franza83859f2017-07-03 16:34:14 +01001458 void performClearTaskLocked() {
Craig Mautner362449a2014-06-20 14:04:39 -07001459 mReuseTask = true;
Winson Chung0ec2a352017-10-26 11:38:30 -07001460 performClearTaskAtIndexLocked(0, !PAUSE_IMMEDIATELY, "clear-task-all");
Craig Mautner362449a2014-06-20 14:04:39 -07001461 mReuseTask = false;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001462 }
1463
Filip Gruszczynskibe9dabd2016-01-19 12:23:10 -08001464 ActivityRecord performClearTaskForReuseLocked(ActivityRecord newR, int launchFlags) {
1465 mReuseTask = true;
1466 final ActivityRecord result = performClearTaskLocked(newR, launchFlags);
1467 mReuseTask = false;
1468 return result;
1469 }
1470
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001471 /**
1472 * Perform clear operation as requested by
1473 * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the
1474 * stack to the given task, then look for
1475 * an instance of that activity in the stack and, if found, finish all
1476 * activities on top of it and return the instance.
1477 *
1478 * @param newR Description of the new activity being started.
1479 * @return Returns the old activity that should be continued to be used,
1480 * or null if none was found.
1481 */
1482 final ActivityRecord performClearTaskLocked(ActivityRecord newR, int launchFlags) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001483 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001484 for (int activityNdx = numActivities - 1; activityNdx >= 0; --activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001485 ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001486 if (r.finishing) {
1487 continue;
1488 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001489 if (r.mActivityComponent.equals(newR.mActivityComponent)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001490 // Here it is! Now finish everything in front...
Craig Mautner1602ec22013-05-12 10:24:27 -07001491 final ActivityRecord ret = r;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001492
1493 for (++activityNdx; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001494 r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001495 if (r.finishing) {
1496 continue;
1497 }
1498 ActivityOptions opts = r.takeOptionsLocked();
1499 if (opts != null) {
1500 ret.updateOptionsLocked(opts);
1501 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07001502 if (mStack != null && mStack.finishActivityLocked(
Todd Kennedy539db512014-12-15 09:57:55 -08001503 r, Activity.RESULT_CANCELED, null, "clear-task-stack", false)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001504 --activityNdx;
1505 --numActivities;
1506 }
1507 }
1508
1509 // Finally, if this is a normal launch mode (that is, not
1510 // expecting onNewIntent()), then we will finish the current
1511 // instance of the activity so a new fresh one can be started.
1512 if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE
Daichi Hirono15a02992016-04-27 18:47:01 +09001513 && (launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0
1514 && !ActivityStarter.isDocumentLaunchesIntoExisting(launchFlags)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001515 if (!ret.finishing) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001516 if (mStack != null) {
1517 mStack.finishActivityLocked(
Wale Ogunwale7d701172015-03-11 15:36:30 -07001518 ret, Activity.RESULT_CANCELED, null, "clear-task-top", false);
1519 }
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001520 return null;
1521 }
1522 }
1523
1524 return ret;
1525 }
1526 }
1527
1528 return null;
1529 }
1530
Winson Chung0ec2a352017-10-26 11:38:30 -07001531 void removeTaskActivitiesLocked(boolean pauseImmediately, String reason) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001532 // Just remove the entire task.
Winson Chung0ec2a352017-10-26 11:38:30 -07001533 performClearTaskAtIndexLocked(0, pauseImmediately, reason);
Craig Mautner9db9a0b2013-04-29 17:05:56 -07001534 }
1535
Craig Mautner432f64e2015-05-20 14:59:57 -07001536 String lockTaskAuthToString() {
1537 switch (mLockTaskAuth) {
1538 case LOCK_TASK_AUTH_DONT_LOCK: return "LOCK_TASK_AUTH_DONT_LOCK";
1539 case LOCK_TASK_AUTH_PINNABLE: return "LOCK_TASK_AUTH_PINNABLE";
1540 case LOCK_TASK_AUTH_LAUNCHABLE: return "LOCK_TASK_AUTH_LAUNCHABLE";
1541 case LOCK_TASK_AUTH_WHITELISTED: return "LOCK_TASK_AUTH_WHITELISTED";
Benjamin Franz469dd582015-06-09 14:24:36 +01001542 case LOCK_TASK_AUTH_LAUNCHABLE_PRIV: return "LOCK_TASK_AUTH_LAUNCHABLE_PRIV";
Craig Mautner432f64e2015-05-20 14:59:57 -07001543 default: return "unknown=" + mLockTaskAuth;
1544 }
1545 }
1546
Craig Mautner15df08a2015-04-01 12:17:18 -07001547 void setLockTaskAuth() {
Charles He2bf28322017-10-12 22:24:49 +01001548 setLockTaskAuth(getRootActivity());
1549 }
1550
1551 private void setLockTaskAuth(@Nullable ActivityRecord r) {
1552 if (r == null) {
1553 mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE;
1554 return;
1555 }
1556
Charles He520b2832017-09-02 15:27:16 +01001557 final String pkg = (realActivity != null) ? realActivity.getPackageName() : null;
Bryce Lee2b8e0372018-04-05 17:01:37 -07001558 final LockTaskController lockTaskController = mService.getLockTaskController();
Charles He2bf28322017-10-12 22:24:49 +01001559 switch (r.lockTaskLaunchMode) {
Craig Mautner15df08a2015-04-01 12:17:18 -07001560 case LOCK_TASK_LAUNCH_MODE_DEFAULT:
Bryce Lee2b8e0372018-04-05 17:01:37 -07001561 mLockTaskAuth = lockTaskController.isPackageWhitelisted(userId, pkg)
Charles He520b2832017-09-02 15:27:16 +01001562 ? LOCK_TASK_AUTH_WHITELISTED : LOCK_TASK_AUTH_PINNABLE;
Craig Mautner15df08a2015-04-01 12:17:18 -07001563 break;
1564
1565 case LOCK_TASK_LAUNCH_MODE_NEVER:
Benjamin Franz469dd582015-06-09 14:24:36 +01001566 mLockTaskAuth = LOCK_TASK_AUTH_DONT_LOCK;
Craig Mautner15df08a2015-04-01 12:17:18 -07001567 break;
1568
1569 case LOCK_TASK_LAUNCH_MODE_ALWAYS:
Benjamin Franz469dd582015-06-09 14:24:36 +01001570 mLockTaskAuth = LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
Craig Mautner15df08a2015-04-01 12:17:18 -07001571 break;
1572
1573 case LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED:
Bryce Lee2b8e0372018-04-05 17:01:37 -07001574 mLockTaskAuth = lockTaskController.isPackageWhitelisted(userId, pkg)
Charles He520b2832017-09-02 15:27:16 +01001575 ? LOCK_TASK_AUTH_LAUNCHABLE : LOCK_TASK_AUTH_PINNABLE;
Craig Mautner15df08a2015-04-01 12:17:18 -07001576 break;
1577 }
Craig Mautner432f64e2015-05-20 14:59:57 -07001578 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
1579 " mLockTaskAuth=" + lockTaskAuthToString());
Craig Mautner15df08a2015-04-01 12:17:18 -07001580 }
1581
Winson Chungd3395382016-12-13 11:49:09 -08001582 private boolean isResizeable(boolean checkSupportsPip) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001583 return (mService.mForceResizableActivities || ActivityInfo.isResizeableMode(mResizeMode)
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -07001584 || (checkSupportsPip && mSupportsPictureInPicture));
Winson Chungd3395382016-12-13 11:49:09 -08001585 }
1586
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001587 boolean isResizeable() {
Winson Chungd3395382016-12-13 11:49:09 -08001588 return isResizeable(true /* checkSupportsPip */);
1589 }
1590
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001591 @Override
1592 public boolean supportsSplitScreenWindowingMode() {
Winson Chungd3395382016-12-13 11:49:09 -08001593 // A task can not be docked even if it is considered resizeable because it only supports
1594 // picture-in-picture mode but has a non-resizeable resizeMode
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001595 return super.supportsSplitScreenWindowingMode()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001596 && mService.mSupportsSplitScreenMultiWindow
1597 && (mService.mForceResizableActivities
Bryce Leec857a5b2017-08-16 10:04:52 -07001598 || (isResizeable(false /* checkSupportsPip */)
1599 && !ActivityInfo.isPreserveOrientationMode(mResizeMode)));
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001600 }
1601
skuhne@google.com322347b2016-12-02 12:54:03 -08001602 /**
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001603 * Check whether this task can be launched on the specified display.
Riddle Hsu16567132018-08-16 21:37:47 +08001604 *
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001605 * @param displayId Target display id.
Riddle Hsu16567132018-08-16 21:37:47 +08001606 * @return {@code true} if either it is the default display or this activity can be put on a
1607 * secondary display.
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001608 */
1609 boolean canBeLaunchedOnDisplay(int displayId) {
1610 return mService.mStackSupervisor.canPlaceEntityOnDisplay(displayId,
Riddle Hsu16567132018-08-16 21:37:47 +08001611 -1 /* don't check PID */, -1 /* don't check UID */, null /* activityInfo */);
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001612 }
1613
1614 /**
skuhne@google.com322347b2016-12-02 12:54:03 -08001615 * Check that a given bounds matches the application requested orientation.
1616 *
1617 * @param bounds The bounds to be tested.
1618 * @return True if the requested bounds are okay for a resizing request.
1619 */
Wale Ogunwale069bbd32017-02-03 07:58:14 -08001620 private boolean canResizeToBounds(Rect bounds) {
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001621 if (bounds == null || !inFreeformWindowingMode()) {
skuhne@google.com322347b2016-12-02 12:54:03 -08001622 // Note: If not on the freeform workspace, we ignore the bounds.
1623 return true;
1624 }
1625 final boolean landscape = bounds.width() > bounds.height();
Evan Roskydfe3da72018-10-26 17:21:06 -07001626 final Rect configBounds = getRequestedOverrideBounds();
skuhne@google.com322347b2016-12-02 12:54:03 -08001627 if (mResizeMode == RESIZE_MODE_FORCE_RESIZABLE_PRESERVE_ORIENTATION) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001628 return configBounds.isEmpty()
1629 || landscape == (configBounds.width() > configBounds.height());
skuhne@google.com322347b2016-12-02 12:54:03 -08001630 }
1631 return (mResizeMode != RESIZE_MODE_FORCE_RESIZABLE_PORTRAIT_ONLY || !landscape)
1632 && (mResizeMode != RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY || landscape);
1633 }
1634
Craig Mautner525f3d92013-05-07 14:01:50 -07001635 /**
Yorke Leebdef5372017-04-10 16:38:51 -07001636 * @return {@code true} if the task is being cleared for the purposes of being reused.
1637 */
1638 boolean isClearingToReuseTask() {
1639 return mReuseTask;
1640 }
1641
1642 /**
Craig Mautner525f3d92013-05-07 14:01:50 -07001643 * Find the activity in the history stack within the given task. Returns
1644 * the index within the history at which it's found, or < 0 if not found.
1645 */
1646 final ActivityRecord findActivityInHistoryLocked(ActivityRecord r) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001647 final ComponentName realActivity = r.mActivityComponent;
Craig Mautner525f3d92013-05-07 14:01:50 -07001648 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1649 ActivityRecord candidate = mActivities.get(activityNdx);
1650 if (candidate.finishing) {
1651 continue;
1652 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001653 if (candidate.mActivityComponent.equals(realActivity)) {
Craig Mautner525f3d92013-05-07 14:01:50 -07001654 return candidate;
1655 }
1656 }
1657 return null;
1658 }
1659
Winson Chunga449dc02014-05-16 11:15:04 -07001660 /** Updates the last task description values. */
1661 void updateTaskDescription() {
1662 // Traverse upwards looking for any break between main task activities and
1663 // utility activities.
1664 int activityNdx;
1665 final int numActivities = mActivities.size();
Wale Ogunwale3eadad72016-10-13 09:16:59 -07001666 final boolean relinquish = numActivities != 0 &&
1667 (mActivities.get(0).info.flags & FLAG_RELINQUISH_TASK_IDENTITY) != 0;
Winson Chunga449dc02014-05-16 11:15:04 -07001668 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
Craig Mautner21d24a22014-04-23 11:45:37 -07001669 ++activityNdx) {
Winson Chunga449dc02014-05-16 11:15:04 -07001670 final ActivityRecord r = mActivities.get(activityNdx);
Wale Ogunwale3eadad72016-10-13 09:16:59 -07001671 if (relinquish && (r.info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001672 // This will be the top activity for determining taskDescription. Pre-inc to
1673 // overcome initial decrement below.
1674 ++activityNdx;
1675 break;
1676 }
Winson Chunga449dc02014-05-16 11:15:04 -07001677 if (r.intent != null &&
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001678 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
Winson Chunga449dc02014-05-16 11:15:04 -07001679 break;
1680 }
1681 }
1682 if (activityNdx > 0) {
1683 // Traverse downwards starting below break looking for set label, icon.
1684 // Note that if there are activities in the task but none of them set the
1685 // recent activity values, then we do not fall back to the last set
1686 // values in the TaskRecord.
1687 String label = null;
Craig Mautner648f69b2014-09-18 14:16:26 -07001688 String iconFilename = null;
Matthew Ng54bc9422017-10-02 17:16:28 -07001689 int iconResource = -1;
Winson Chunga449dc02014-05-16 11:15:04 -07001690 int colorPrimary = 0;
Winson Chung1af8eda2016-02-05 17:55:56 +00001691 int colorBackground = 0;
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001692 int statusBarColor = 0;
1693 int navigationBarColor = 0;
1694 boolean topActivity = true;
Winson Chunga449dc02014-05-16 11:15:04 -07001695 for (--activityNdx; activityNdx >= 0; --activityNdx) {
1696 final ActivityRecord r = mActivities.get(activityNdx);
Winson Chung80f80db2018-05-30 21:13:25 -07001697 if (r.mTaskOverlay) {
1698 continue;
1699 }
Winson Chunga449dc02014-05-16 11:15:04 -07001700 if (r.taskDescription != null) {
1701 if (label == null) {
1702 label = r.taskDescription.getLabel();
1703 }
Matthew Ng54bc9422017-10-02 17:16:28 -07001704 if (iconResource == -1) {
1705 iconResource = r.taskDescription.getIconResource();
1706 }
Craig Mautner648f69b2014-09-18 14:16:26 -07001707 if (iconFilename == null) {
1708 iconFilename = r.taskDescription.getIconFilename();
Winson Chunga449dc02014-05-16 11:15:04 -07001709 }
1710 if (colorPrimary == 0) {
1711 colorPrimary = r.taskDescription.getPrimaryColor();
Winson Chunga449dc02014-05-16 11:15:04 -07001712 }
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001713 if (topActivity) {
Winson Chung1af8eda2016-02-05 17:55:56 +00001714 colorBackground = r.taskDescription.getBackgroundColor();
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001715 statusBarColor = r.taskDescription.getStatusBarColor();
1716 navigationBarColor = r.taskDescription.getNavigationBarColor();
Winson Chung1af8eda2016-02-05 17:55:56 +00001717 }
Winson Chunga449dc02014-05-16 11:15:04 -07001718 }
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001719 topActivity = false;
Winson Chunga449dc02014-05-16 11:15:04 -07001720 }
Matthew Ng54bc9422017-10-02 17:16:28 -07001721 lastTaskDescription = new TaskDescription(label, null, iconResource, iconFilename,
1722 colorPrimary, colorBackground, statusBarColor, navigationBarColor);
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001723 if (mTask != null) {
1724 mTask.setTaskDescription(lastTaskDescription);
Jorim Jaggi829b9cd2017-01-23 16:20:53 +01001725 }
Winson Chungec396d62014-08-06 17:08:00 -07001726 // Update the task affiliation color if we are the parent of the group
1727 if (taskId == mAffiliatedTaskId) {
1728 mAffiliatedTaskColor = lastTaskDescription.getPrimaryColor();
1729 }
Winson Chunga449dc02014-05-16 11:15:04 -07001730 }
1731 }
1732
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001733 int findEffectiveRootIndex() {
Craig Mautner4767f4b2014-09-18 15:38:33 -07001734 int effectiveNdx = 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001735 final int topActivityNdx = mActivities.size() - 1;
Dianne Hackborn39569af2014-09-23 10:56:58 -07001736 for (int activityNdx = 0; activityNdx <= topActivityNdx; ++activityNdx) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001737 final ActivityRecord r = mActivities.get(activityNdx);
1738 if (r.finishing) {
1739 continue;
1740 }
Craig Mautner4767f4b2014-09-18 15:38:33 -07001741 effectiveNdx = activityNdx;
Wale Ogunwale3eadad72016-10-13 09:16:59 -07001742 if ((r.info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001743 break;
1744 }
1745 }
Craig Mautner4767f4b2014-09-18 15:38:33 -07001746 return effectiveNdx;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001747 }
1748
1749 void updateEffectiveIntent() {
1750 final int effectiveRootIndex = findEffectiveRootIndex();
1751 final ActivityRecord r = mActivities.get(effectiveRootIndex);
Winson Chungfee26772014-08-05 12:21:52 -07001752 setIntent(r);
Winson Chung8d9009e2017-11-16 15:43:05 -08001753
1754 // Update the task description when the activities change
1755 updateTaskDescription();
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001756 }
1757
Evan Rosky730f6e82018-12-03 17:40:11 -08001758 void adjustForMinimalTaskDimensions(Rect bounds, Rect previousBounds) {
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001759 if (bounds == null) {
1760 return;
1761 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001762 int minWidth = mMinWidth;
1763 int minHeight = mMinHeight;
Robert Carr9c5867d2016-03-10 15:52:46 -08001764 // If the task has no requested minimal size, we'd like to enforce a minimal size
1765 // so that the user can not render the task too small to manipulate. We don't need
1766 // to do this for the pinned stack as the bounds are controlled by the system.
Evan Rosky1ac84462018-11-13 11:25:30 -08001767 if (!inPinnedWindowingMode() && mStack != null) {
Garfield Tan4a48a7f2018-10-02 14:23:55 -07001768 final int defaultMinSizeDp =
Wale Ogunwaled32da472018-11-16 07:19:28 -08001769 mService.mRootActivityContainer.mDefaultMinSizeOfResizeableTaskDp;
Garfield Tan4a48a7f2018-10-02 14:23:55 -07001770 final ActivityDisplay display =
Wale Ogunwaled32da472018-11-16 07:19:28 -08001771 mService.mRootActivityContainer.getActivityDisplay(mStack.mDisplayId);
Garfield Tan4a48a7f2018-10-02 14:23:55 -07001772 final float density =
1773 (float) display.getConfiguration().densityDpi / DisplayMetrics.DENSITY_DEFAULT;
1774 final int defaultMinSize = (int) (defaultMinSizeDp * density);
1775
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001776 if (minWidth == INVALID_MIN_SIZE) {
Garfield Tan4a48a7f2018-10-02 14:23:55 -07001777 minWidth = defaultMinSize;
Andrii Kulian2e751b82016-03-16 16:59:32 -07001778 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001779 if (minHeight == INVALID_MIN_SIZE) {
Garfield Tan4a48a7f2018-10-02 14:23:55 -07001780 minHeight = defaultMinSize;
Andrii Kulian2e751b82016-03-16 16:59:32 -07001781 }
Robert Carr9c5867d2016-03-10 15:52:46 -08001782 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001783 final boolean adjustWidth = minWidth > bounds.width();
1784 final boolean adjustHeight = minHeight > bounds.height();
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001785 if (!(adjustWidth || adjustHeight)) {
1786 return;
1787 }
1788
1789 if (adjustWidth) {
Garfield Tan020607d2018-12-17 17:01:58 -08001790 if (!previousBounds.isEmpty() && bounds.right == previousBounds.right) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001791 bounds.left = bounds.right - minWidth;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001792 } else {
1793 // Either left bounds match, or neither match, or the previous bounds were
1794 // fullscreen and we default to keeping left.
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001795 bounds.right = bounds.left + minWidth;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001796 }
1797 }
1798 if (adjustHeight) {
Garfield Tan020607d2018-12-17 17:01:58 -08001799 if (!previousBounds.isEmpty() && bounds.bottom == previousBounds.bottom) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001800 bounds.top = bounds.bottom - minHeight;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001801 } else {
1802 // Either top bounds match, or neither match, or the previous bounds were
1803 // fullscreen and we default to keeping top.
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001804 bounds.bottom = bounds.top + minHeight;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001805 }
1806 }
1807 }
1808
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001809 /**
1810 * Update task's override configuration based on the bounds.
Jorim Jaggi0a932142016-02-01 17:42:25 -08001811 * @param bounds The bounds of the task.
Andrii Kulian8072d112016-09-16 11:11:01 -07001812 * @return True if the override configuration was updated.
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001813 */
Andrii Kulian8072d112016-09-16 11:11:01 -07001814 boolean updateOverrideConfiguration(Rect bounds) {
Jorim Jaggi0a932142016-02-01 17:42:25 -08001815 return updateOverrideConfiguration(bounds, null /* insetBounds */);
1816 }
1817
Evan Rosky9ba524e2018-01-03 16:27:56 -08001818 void setLastNonFullscreenBounds(Rect bounds) {
1819 if (mLastNonFullscreenBounds == null) {
1820 mLastNonFullscreenBounds = new Rect(bounds);
1821 } else {
1822 mLastNonFullscreenBounds.set(bounds);
1823 }
1824 }
1825
Jorim Jaggi0a932142016-02-01 17:42:25 -08001826 /**
1827 * Update task's override configuration based on the bounds.
1828 * @param bounds The bounds of the task.
1829 * @param insetBounds The bounds used to calculate the system insets, which is used here to
1830 * subtract the navigation bar/status bar size from the screen size reported
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001831 * to the application. See {@link IActivityTaskManager#resizeDockedStack}.
Andrii Kulian8072d112016-09-16 11:11:01 -07001832 * @return True if the override configuration was updated.
Jorim Jaggi0a932142016-02-01 17:42:25 -08001833 */
Andrii Kulian8072d112016-09-16 11:11:01 -07001834 boolean updateOverrideConfiguration(Rect bounds, @Nullable Rect insetBounds) {
Evan Rosky1ac84462018-11-13 11:25:30 -08001835 final boolean hasSetDisplayedBounds = (insetBounds != null && !insetBounds.isEmpty());
1836 if (hasSetDisplayedBounds) {
1837 setDisplayedBounds(bounds);
1838 } else {
1839 setDisplayedBounds(null);
1840 }
1841 // "steady" bounds do not include any temporary offsets from animation or interaction.
1842 Rect steadyBounds = hasSetDisplayedBounds ? insetBounds : bounds;
1843 if (equivalentRequestedOverrideBounds(steadyBounds)) {
Andrii Kulian8072d112016-09-16 11:11:01 -07001844 return false;
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001845 }
Bryce Leef3c6a472017-11-14 14:53:06 -08001846
Evan Rosky1ac84462018-11-13 11:25:30 -08001847 mTmpConfig.setTo(getResolvedOverrideConfiguration());
1848 setBounds(steadyBounds);
1849 return !mTmpConfig.equals(getResolvedOverrideConfiguration());
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08001850 }
Wale Ogunwale5f986092015-12-04 15:35:38 -08001851
Bryce Leec4ab62a2018-03-05 14:19:26 -08001852 /**
1853 * This should be called when an child activity changes state. This should only
1854 * be called from
1855 * {@link ActivityRecord#setState(ActivityState, String)} .
1856 * @param record The {@link ActivityRecord} whose state has changed.
1857 * @param state The new state.
1858 * @param reason The reason for the change.
1859 */
1860 void onActivityStateChanged(ActivityRecord record, ActivityState state, String reason) {
1861 final ActivityStack parent = getStack();
1862
1863 if (parent != null) {
1864 parent.onActivityStateChanged(record, state, reason);
1865 }
1866 }
1867
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08001868 @Override
1869 public void onConfigurationChanged(Configuration newParentConfig) {
Evan Rosky730f6e82018-12-03 17:40:11 -08001870 // Check if the new configuration supports persistent bounds (eg. is Freeform) and if so
1871 // restore the last recorded non-fullscreen bounds.
1872 final boolean prevPersistTaskBounds = getWindowConfiguration().persistTaskBounds();
1873 final boolean nextPersistTaskBounds =
1874 getRequestedOverrideConfiguration().windowConfiguration.persistTaskBounds()
1875 || newParentConfig.windowConfiguration.persistTaskBounds();
1876 if (!prevPersistTaskBounds && nextPersistTaskBounds
1877 && mLastNonFullscreenBounds != null && !mLastNonFullscreenBounds.isEmpty()) {
1878 // Bypass onRequestedOverrideConfigurationChanged here to avoid infinite loop.
1879 getRequestedOverrideConfiguration().windowConfiguration
1880 .setBounds(mLastNonFullscreenBounds);
1881 }
1882
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08001883 final boolean wasInMultiWindowMode = inMultiWindowMode();
1884 super.onConfigurationChanged(newParentConfig);
1885 if (wasInMultiWindowMode != inMultiWindowMode()) {
Winson Chung5af42fc2017-03-24 17:11:33 -07001886 mService.mStackSupervisor.scheduleUpdateMultiWindowMode(this);
Wale Ogunwale5f986092015-12-04 15:35:38 -08001887 }
Evan Rosky730f6e82018-12-03 17:40:11 -08001888
1889 // If the configuration supports persistent bounds (eg. Freeform), keep track of the
1890 // current (non-fullscreen) bounds for persistence.
Evan Rosky1ac84462018-11-13 11:25:30 -08001891 if (getWindowConfiguration().persistTaskBounds()) {
1892 final Rect currentBounds = getRequestedOverrideBounds();
1893 if (!currentBounds.isEmpty()) {
1894 setLastNonFullscreenBounds(currentBounds);
1895 }
1896 }
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08001897 // TODO: Should also take care of Pip mode changes here.
Garfield Tan891146c2018-10-09 12:14:00 -07001898
1899 saveLaunchingStateIfNeeded();
1900 }
1901
1902 /**
1903 * Saves launching state if necessary so that we can launch the activity to its latest state.
1904 * It only saves state if this task has been shown to user and it's in fullscreen or freeform
1905 * mode.
1906 */
1907 void saveLaunchingStateIfNeeded() {
1908 if (!hasBeenVisible) {
1909 // Not ever visible to user.
1910 return;
1911 }
1912
1913 final int windowingMode = getWindowingMode();
1914 if (windowingMode != WindowConfiguration.WINDOWING_MODE_FULLSCREEN
1915 && windowingMode != WindowConfiguration.WINDOWING_MODE_FREEFORM) {
1916 return;
1917 }
1918
1919 // Saves the new state so that we can launch the activity at the same location.
1920 mService.mStackSupervisor.mLaunchParamsPersister.saveTask(this);
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001921 }
1922
Evan Roskyed6767f2018-10-26 17:21:06 -07001923 /**
Evan Rosky1ac84462018-11-13 11:25:30 -08001924 * Adjust bounds to stay within stack bounds.
1925 *
1926 * Since bounds might be outside of stack bounds, this method tries to move the bounds in a way
1927 * that keep them unchanged, but be contained within the stack bounds.
1928 *
1929 * @param bounds Bounds to be adjusted.
1930 * @param stackBounds Bounds within which the other bounds should remain.
1931 */
1932 private static void fitWithinBounds(Rect bounds, Rect stackBounds) {
1933 if (stackBounds == null || stackBounds.isEmpty() || stackBounds.contains(bounds)) {
1934 return;
1935 }
1936
1937 if (bounds.left < stackBounds.left || bounds.right > stackBounds.right) {
1938 final int maxRight = stackBounds.right
1939 - (stackBounds.width() / FIT_WITHIN_BOUNDS_DIVIDER);
1940 int horizontalDiff = stackBounds.left - bounds.left;
1941 if ((horizontalDiff < 0 && bounds.left >= maxRight)
1942 || (bounds.left + horizontalDiff >= maxRight)) {
1943 horizontalDiff = maxRight - bounds.left;
1944 }
1945 bounds.left += horizontalDiff;
1946 bounds.right += horizontalDiff;
1947 }
1948
1949 if (bounds.top < stackBounds.top || bounds.bottom > stackBounds.bottom) {
1950 final int maxBottom = stackBounds.bottom
1951 - (stackBounds.height() / FIT_WITHIN_BOUNDS_DIVIDER);
1952 int verticalDiff = stackBounds.top - bounds.top;
1953 if ((verticalDiff < 0 && bounds.top >= maxBottom)
1954 || (bounds.top + verticalDiff >= maxBottom)) {
1955 verticalDiff = maxBottom - bounds.top;
1956 }
1957 bounds.top += verticalDiff;
1958 bounds.bottom += verticalDiff;
1959 }
1960 }
1961
1962 /**
Evan Roskyed6767f2018-10-26 17:21:06 -07001963 * Displayed bounds are used to set where the task is drawn at any given time. This is
1964 * separate from its actual bounds so that the app doesn't see any meaningful configuration
1965 * changes during transitionary periods.
1966 */
1967 void setDisplayedBounds(Rect bounds) {
1968 if (bounds == null) {
1969 mDisplayedBounds.setEmpty();
1970 } else {
1971 mDisplayedBounds.set(bounds);
1972 }
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001973 if (mTask != null) {
1974 mTask.setOverrideDisplayedBounds(
Evan Roskyed6767f2018-10-26 17:21:06 -07001975 mDisplayedBounds.isEmpty() ? null : mDisplayedBounds);
1976 }
1977 }
1978
1979 /**
1980 * Gets the current overridden displayed bounds. These will be empty if the task is not
1981 * currently overriding where it is displayed.
1982 */
1983 Rect getDisplayedBounds() {
1984 return mDisplayedBounds;
1985 }
1986
1987 /**
1988 * @return {@code true} if this has overridden displayed bounds.
1989 */
1990 boolean hasDisplayedBounds() {
1991 return !mDisplayedBounds.isEmpty();
1992 }
1993
Evan Rosky1ac84462018-11-13 11:25:30 -08001994 /**
1995 * Intersects inOutBounds with intersectBounds-intersectInsets. If inOutBounds is larger than
1996 * intersectBounds on a side, then the respective side will not be intersected.
1997 *
1998 * The assumption is that if inOutBounds is initially larger than intersectBounds, then the
1999 * inset on that side is no-longer applicable. This scenario happens when a task's minimal
2000 * bounds are larger than the provided parent/display bounds.
2001 *
2002 * @param inOutBounds the bounds to intersect.
2003 * @param intersectBounds the bounds to intersect with.
2004 * @param intersectInsets insets to apply to intersectBounds before intersecting.
2005 */
2006 private static void intersectWithInsetsIfFits(
2007 Rect inOutBounds, Rect intersectBounds, Rect intersectInsets) {
2008 if (inOutBounds.right <= intersectBounds.right) {
2009 inOutBounds.right =
2010 Math.min(intersectBounds.right - intersectInsets.right, inOutBounds.right);
2011 }
2012 if (inOutBounds.bottom <= intersectBounds.bottom) {
2013 inOutBounds.bottom =
2014 Math.min(intersectBounds.bottom - intersectInsets.bottom, inOutBounds.bottom);
2015 }
2016 if (inOutBounds.left >= intersectBounds.left) {
2017 inOutBounds.left =
2018 Math.max(intersectBounds.left + intersectInsets.left, inOutBounds.left);
2019 }
2020 if (inOutBounds.top >= intersectBounds.top) {
2021 inOutBounds.top =
2022 Math.max(intersectBounds.top + intersectInsets.top, inOutBounds.top);
2023 }
2024 }
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08002025
Evan Rosky1ac84462018-11-13 11:25:30 -08002026 /**
2027 * Gets bounds with non-decor and stable insets applied respectively.
2028 *
2029 * If bounds overhangs the display, those edges will not get insets. See
2030 * {@link #intersectWithInsetsIfFits}
2031 *
2032 * @param outNonDecorBounds where to place bounds with non-decor insets applied.
2033 * @param outStableBounds where to place bounds with stable insets applied.
2034 * @param bounds the bounds to inset.
2035 */
2036 private void calculateInsetFrames(Rect outNonDecorBounds, Rect outStableBounds, Rect bounds,
2037 DisplayInfo displayInfo) {
2038 outNonDecorBounds.set(bounds);
2039 outStableBounds.set(bounds);
2040 if (getStack() == null || getStack().getDisplay() == null) {
2041 return;
2042 }
2043 DisplayPolicy policy = getStack().getDisplay().mDisplayContent.getDisplayPolicy();
2044 if (policy == null) {
2045 return;
2046 }
2047 mTmpBounds.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight);
Bryce Lee7566d762017-03-30 09:34:15 -07002048
Evan Rosky1ac84462018-11-13 11:25:30 -08002049 policy.getStableInsetsLw(displayInfo.rotation,
2050 displayInfo.logicalWidth, displayInfo.logicalHeight, displayInfo.displayCutout,
2051 mTmpInsets);
2052 intersectWithInsetsIfFits(outStableBounds, mTmpBounds, mTmpInsets);
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08002053
Evan Rosky1ac84462018-11-13 11:25:30 -08002054 policy.getNonDecorInsetsLw(displayInfo.rotation,
2055 displayInfo.logicalWidth, displayInfo.logicalHeight, displayInfo.displayCutout,
2056 mTmpInsets);
2057 intersectWithInsetsIfFits(outNonDecorBounds, mTmpBounds, mTmpInsets);
2058 }
2059
2060 /**
2061 * Asks docked-divider controller for the smallestwidthdp given bounds.
2062 * @param bounds bounds to calculate smallestwidthdp for.
2063 */
2064 private int getSmallestScreenWidthDpForDockedBounds(Rect bounds) {
2065 DisplayContent dc = mStack.getDisplay().mDisplayContent;
2066 if (dc != null) {
2067 return dc.getDockedDividerController().getSmallestWidthDpForBounds(bounds);
2068 }
2069 return Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
2070 }
2071
Riddle Hsu0a343c32018-12-21 00:40:48 +08002072 void computeConfigResourceOverrides(@NonNull Configuration inOutConfig,
2073 @NonNull Configuration parentConfig) {
2074 computeConfigResourceOverrides(inOutConfig, parentConfig, true /* insideParentBounds */);
2075 }
2076
Evan Rosky1ac84462018-11-13 11:25:30 -08002077 /**
2078 * Calculates configuration values used by the client to get resources. This should be run
2079 * using app-facing bounds (bounds unmodified by animations or transient interactions).
2080 *
2081 * This assumes bounds are non-empty/null. For the null-bounds case, the caller is likely
2082 * configuring an "inherit-bounds" window which means that all configuration settings would
2083 * just be inherited from the parent configuration.
2084 **/
Evan Rosky730f6e82018-12-03 17:40:11 -08002085 void computeConfigResourceOverrides(@NonNull Configuration inOutConfig,
Riddle Hsu0a343c32018-12-21 00:40:48 +08002086 @NonNull Configuration parentConfig, boolean insideParentBounds) {
Evan Rosky1ac84462018-11-13 11:25:30 -08002087 int windowingMode = inOutConfig.windowConfiguration.getWindowingMode();
2088 if (windowingMode == WINDOWING_MODE_UNDEFINED) {
2089 windowingMode = parentConfig.windowConfiguration.getWindowingMode();
Winson Chungbdc646f2017-02-13 12:12:22 -08002090 }
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08002091
Evan Rosky1ac84462018-11-13 11:25:30 -08002092 float density = inOutConfig.densityDpi;
2093 if (density == Configuration.DENSITY_DPI_UNDEFINED) {
2094 density = parentConfig.densityDpi;
2095 }
2096 density *= DisplayMetrics.DENSITY_DEFAULT_SCALE;
Winson Chung60c1aba2017-03-14 17:47:42 -07002097
Evan Rosky730f6e82018-12-03 17:40:11 -08002098 final Rect bounds = inOutConfig.windowConfiguration.getBounds();
Evan Rosky1ac84462018-11-13 11:25:30 -08002099 Rect outAppBounds = inOutConfig.windowConfiguration.getAppBounds();
2100 if (outAppBounds == null || outAppBounds.isEmpty()) {
2101 inOutConfig.windowConfiguration.setAppBounds(bounds);
2102 outAppBounds = inOutConfig.windowConfiguration.getAppBounds();
2103 }
Riddle Hsu0a343c32018-12-21 00:40:48 +08002104 if (insideParentBounds && windowingMode != WINDOWING_MODE_FREEFORM) {
Evan Rosky1ac84462018-11-13 11:25:30 -08002105 final Rect parentAppBounds = parentConfig.windowConfiguration.getAppBounds();
2106 if (parentAppBounds != null && !parentAppBounds.isEmpty()) {
2107 outAppBounds.intersect(parentAppBounds);
2108 }
2109 }
2110
2111 if (inOutConfig.screenWidthDp == Configuration.SCREEN_WIDTH_DP_UNDEFINED
2112 || inOutConfig.screenHeightDp == Configuration.SCREEN_HEIGHT_DP_UNDEFINED) {
Riddle Hsu0a343c32018-12-21 00:40:48 +08002113 if (insideParentBounds && mStack != null) {
Evan Rosky1ac84462018-11-13 11:25:30 -08002114 final DisplayInfo di = new DisplayInfo();
2115 mStack.getDisplay().mDisplay.getDisplayInfo(di);
2116
2117 // For calculating screenWidthDp, screenWidthDp, we use the stable inset screen
2118 // area, i.e. the screen area without the system bars.
2119 // The non decor inset are areas that could never be removed in Honeycomb. See
2120 // {@link WindowManagerPolicy#getNonDecorInsetsLw}.
2121 calculateInsetFrames(mTmpNonDecorBounds, mTmpStableBounds, bounds, di);
2122 } else {
2123 mTmpNonDecorBounds.set(bounds);
2124 mTmpStableBounds.set(bounds);
2125 }
2126
2127 if (inOutConfig.screenWidthDp == Configuration.SCREEN_WIDTH_DP_UNDEFINED) {
Riddle Hsu0a343c32018-12-21 00:40:48 +08002128 final int overrideScreenWidthDp = (int) (mTmpStableBounds.width() / density);
2129 inOutConfig.screenWidthDp = insideParentBounds
2130 ? Math.min(overrideScreenWidthDp, parentConfig.screenWidthDp)
2131 : overrideScreenWidthDp;
Evan Rosky1ac84462018-11-13 11:25:30 -08002132 }
2133 if (inOutConfig.screenHeightDp == Configuration.SCREEN_HEIGHT_DP_UNDEFINED) {
Riddle Hsu0a343c32018-12-21 00:40:48 +08002134 final int overrideScreenHeightDp = (int) (mTmpStableBounds.height() / density);
2135 inOutConfig.screenHeightDp = insideParentBounds
2136 ? Math.min(overrideScreenHeightDp, parentConfig.screenWidthDp)
2137 : overrideScreenHeightDp;
Evan Rosky1ac84462018-11-13 11:25:30 -08002138 }
2139
2140 if (inOutConfig.smallestScreenWidthDp
2141 == Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
2142 if (WindowConfiguration.isFloating(windowingMode)) {
2143 // For floating tasks, calculate the smallest width from the bounds of the task
2144 inOutConfig.smallestScreenWidthDp = (int) (
2145 Math.min(bounds.width(), bounds.height()) / density);
2146 } else if (WindowConfiguration.isSplitScreenWindowingMode(windowingMode)) {
2147 // Iterating across all screen orientations, and return the minimum of the task
2148 // width taking into account that the bounds might change because the snap
2149 // algorithm snaps to a different value
Evan Rosky730f6e82018-12-03 17:40:11 -08002150 inOutConfig.smallestScreenWidthDp =
2151 getSmallestScreenWidthDpForDockedBounds(bounds);
Evan Rosky1ac84462018-11-13 11:25:30 -08002152 }
2153 // otherwise, it will just inherit
2154 }
2155 }
2156
Evan Rosky730f6e82018-12-03 17:40:11 -08002157 if (inOutConfig.orientation == ORIENTATION_UNDEFINED) {
Evan Rosky1ac84462018-11-13 11:25:30 -08002158 inOutConfig.orientation = (inOutConfig.screenWidthDp <= inOutConfig.screenHeightDp)
Riddle Hsu0a343c32018-12-21 00:40:48 +08002159 ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE;
Evan Rosky1ac84462018-11-13 11:25:30 -08002160 }
2161 if (inOutConfig.screenLayout == Configuration.SCREENLAYOUT_UNDEFINED) {
2162 // For calculating screen layout, we need to use the non-decor inset screen area for the
2163 // calculation for compatibility reasons, i.e. screen area without system bars that
2164 // could never go away in Honeycomb.
2165 final int compatScreenWidthDp = (int) (mTmpNonDecorBounds.width() / density);
2166 final int compatScreenHeightDp = (int) (mTmpNonDecorBounds.height() / density);
2167 // We're only overriding LONG, SIZE and COMPAT parts of screenLayout, so we start
2168 // override calculation with partial default.
2169 // Reducing the screen layout starting from its parent config.
2170 final int sl = parentConfig.screenLayout
2171 & (Configuration.SCREENLAYOUT_LONG_MASK | Configuration.SCREENLAYOUT_SIZE_MASK);
2172 final int longSize = Math.max(compatScreenHeightDp, compatScreenWidthDp);
2173 final int shortSize = Math.min(compatScreenHeightDp, compatScreenWidthDp);
2174 inOutConfig.screenLayout = Configuration.reduceScreenLayout(sl, longSize, shortSize);
2175 }
2176 }
2177
Evan Rosky1ac84462018-11-13 11:25:30 -08002178 @Override
2179 void resolveOverrideConfiguration(Configuration newParentConfig) {
Evan Rosky730f6e82018-12-03 17:40:11 -08002180 mTmpBounds.set(getResolvedOverrideConfiguration().windowConfiguration.getBounds());
2181 super.resolveOverrideConfiguration(newParentConfig);
2182 int windowingMode =
2183 getRequestedOverrideConfiguration().windowConfiguration.getWindowingMode();
2184 if (windowingMode == WINDOWING_MODE_UNDEFINED) {
2185 windowingMode = newParentConfig.windowConfiguration.getWindowingMode();
2186 }
2187 Rect outOverrideBounds =
2188 getResolvedOverrideConfiguration().windowConfiguration.getBounds();
2189
2190 if (windowingMode == WINDOWING_MODE_FULLSCREEN) {
2191 // In FULLSCREEN mode, always start with empty bounds to indicate "fill parent"
2192 outOverrideBounds.setEmpty();
2193
Garfield Tan49dae102019-02-04 09:51:59 -08002194 final boolean parentHandlesOrientationChange = mTask != null
2195 && mTask.getParent() != null
2196 && mTask.getParent().handlesOrientationChangeFromDescendant();
Evan Rosky130d94f2019-01-15 10:18:17 -08002197 // If the task or its top activity requires a different orientation, make it fit the
Evan Rosky730f6e82018-12-03 17:40:11 -08002198 // available bounds by scaling down its bounds.
Evan Rosky130d94f2019-01-15 10:18:17 -08002199 int forcedOrientation = getTopActivityRequestedOrientation();
Evan Rosky730f6e82018-12-03 17:40:11 -08002200 if (forcedOrientation != ORIENTATION_UNDEFINED
Garfield Tan49dae102019-02-04 09:51:59 -08002201 && forcedOrientation != newParentConfig.orientation
2202 && !parentHandlesOrientationChange) {
Evan Rosky730f6e82018-12-03 17:40:11 -08002203 final Rect parentBounds = newParentConfig.windowConfiguration.getBounds();
2204 final int parentWidth = parentBounds.width();
2205 final int parentHeight = parentBounds.height();
2206 final float aspect = ((float) parentHeight) / parentWidth;
2207 if (forcedOrientation == ORIENTATION_LANDSCAPE) {
2208 final int height = (int) (parentWidth / aspect);
2209 final int top = parentBounds.centerY() - height / 2;
2210 outOverrideBounds.set(
2211 parentBounds.left, top, parentBounds.right, top + height);
2212 } else {
2213 final int width = (int) (parentHeight * aspect);
2214 final int left = parentBounds.centerX() - width / 2;
2215 outOverrideBounds.set(
2216 left, parentBounds.top, left + width, parentBounds.bottom);
2217 }
2218 }
2219 }
2220
2221 if (outOverrideBounds.isEmpty()) {
2222 // If the task fills the parent, just inherit all the other configs from parent.
2223 return;
2224 }
2225
2226 adjustForMinimalTaskDimensions(outOverrideBounds, mTmpBounds);
2227 if (windowingMode == WINDOWING_MODE_FREEFORM) {
2228 // by policy, make sure the window remains within parent somewhere
2229 fitWithinBounds(outOverrideBounds, newParentConfig.windowConfiguration.getBounds());
2230 }
2231 computeConfigResourceOverrides(getResolvedOverrideConfiguration(), newParentConfig);
Jorim Jaggia95ca8d2016-01-15 22:54:46 -08002232 }
2233
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08002234 Rect updateOverrideConfigurationFromLaunchBounds() {
Bryce Leef3c6a472017-11-14 14:53:06 -08002235 final Rect bounds = getLaunchBounds();
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08002236 updateOverrideConfiguration(bounds);
Bryce Leef3c6a472017-11-14 14:53:06 -08002237 if (bounds != null && !bounds.isEmpty()) {
2238 // TODO: Review if we actually want to do this - we are setting the launch bounds
2239 // directly here.
Evan Roskydfe3da72018-10-26 17:21:06 -07002240 bounds.set(getRequestedOverrideBounds());
Andrii Kulian73336d812016-03-24 12:56:08 -07002241 }
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08002242 return bounds;
2243 }
2244
Wale Ogunwale935e5022015-11-10 12:36:10 -08002245 /** Updates the task's bounds and override configuration to match what is expected for the
2246 * input stack. */
2247 void updateOverrideConfigurationForStack(ActivityStack inStack) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07002248 if (mStack != null && mStack == inStack) {
Wale Ogunwale935e5022015-11-10 12:36:10 -08002249 return;
2250 }
2251
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002252 if (inStack.inFreeformWindowingMode()) {
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002253 if (!isResizeable()) {
Wale Ogunwale935e5022015-11-10 12:36:10 -08002254 throw new IllegalArgumentException("Can not position non-resizeable task="
2255 + this + " in stack=" + inStack);
2256 }
Bryce Leef3c6a472017-11-14 14:53:06 -08002257 if (!matchParentBounds()) {
Wale Ogunwale935e5022015-11-10 12:36:10 -08002258 return;
2259 }
2260 if (mLastNonFullscreenBounds != null) {
2261 updateOverrideConfiguration(mLastNonFullscreenBounds);
2262 } else {
Bryce Leeec55eb02017-12-05 20:51:27 -08002263 mService.mStackSupervisor.getLaunchParamsController().layoutTask(this, null);
Wale Ogunwale935e5022015-11-10 12:36:10 -08002264 }
2265 } else {
Evan Roskydfe3da72018-10-26 17:21:06 -07002266 updateOverrideConfiguration(inStack.getRequestedOverrideBounds());
Wale Ogunwale935e5022015-11-10 12:36:10 -08002267 }
2268 }
2269
Wale Ogunwale706ed792015-08-02 10:29:44 -07002270 /** Returns the bounds that should be used to launch this task. */
Wale Ogunwale30e441d2017-11-09 08:28:45 -08002271 Rect getLaunchBounds() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07002272 if (mStack == null) {
Chong Zhang7d5f5102016-01-13 10:29:24 -08002273 return null;
2274 }
2275
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002276 final int windowingMode = getWindowingMode();
2277 if (!isActivityTypeStandardOrUndefined()
2278 || windowingMode == WINDOWING_MODE_FULLSCREEN
2279 || (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY && !isResizeable())) {
Evan Roskydfe3da72018-10-26 17:21:06 -07002280 return isResizeable() ? mStack.getRequestedOverrideBounds() : null;
Wale Ogunwale3382ab12017-07-27 08:55:03 -07002281 } else if (!getWindowConfiguration().persistTaskBounds()) {
Evan Roskydfe3da72018-10-26 17:21:06 -07002282 return mStack.getRequestedOverrideBounds();
Wale Ogunwale706ed792015-08-02 10:29:44 -07002283 }
2284 return mLastNonFullscreenBounds;
2285 }
2286
Jorim Jaggi8b702ed2017-01-20 16:59:03 +01002287 void addStartingWindowsForVisibleActivities(boolean taskSwitch) {
2288 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
2289 final ActivityRecord r = mActivities.get(activityNdx);
2290 if (r.visible) {
2291 r.showStartingWindow(null /* prev */, false /* newTask */, taskSwitch);
2292 }
2293 }
2294 }
2295
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002296 void setRootProcess(WindowProcessController proc) {
Dianne Hackborn68a06332017-11-15 17:54:18 -08002297 clearRootProcess();
2298 if (intent != null &&
2299 (intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0) {
2300 mRootProcess = proc;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002301 mRootProcess.addRecentTask(this);
Dianne Hackborn68a06332017-11-15 17:54:18 -08002302 }
2303 }
2304
2305 void clearRootProcess() {
2306 if (mRootProcess != null) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002307 mRootProcess.removeRecentTask(this);
Dianne Hackborn68a06332017-11-15 17:54:18 -08002308 mRootProcess = null;
2309 }
2310 }
2311
chaviw82a0ba82018-03-15 14:26:29 -07002312 void clearAllPendingOptions() {
2313 for (int i = getChildCount() - 1; i >= 0; i--) {
2314 getChildAt(i).clearOptionsLocked(false /* withAbort */);
2315 }
2316 }
2317
Winson Chungabfdcce2018-07-02 17:23:33 -07002318 /**
2319 * Fills in a {@link TaskInfo} with information from this task.
2320 * @param info the {@link TaskInfo} to fill in
2321 * @param reuseActivitiesReport a temporary activities report that we can reuse to fetch the
2322 * running activities
2323 */
2324 void fillTaskInfo(TaskInfo info, TaskActivitiesReport reuseActivitiesReport) {
2325 getNumRunningActivities(reuseActivitiesReport);
2326 info.userId = userId;
2327 info.stackId = getStackId();
2328 info.taskId = taskId;
2329 info.isRunning = getTopActivity() != null;
Riddle Hsu2f9acd22018-11-06 23:44:43 +08002330 info.baseIntent = new Intent(getBaseIntent());
Winson Chungabfdcce2018-07-02 17:23:33 -07002331 info.baseActivity = reuseActivitiesReport.base != null
2332 ? reuseActivitiesReport.base.intent.getComponent()
2333 : null;
2334 info.topActivity = reuseActivitiesReport.top != null
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002335 ? reuseActivitiesReport.top.mActivityComponent
Winson Chungabfdcce2018-07-02 17:23:33 -07002336 : null;
2337 info.origActivity = origActivity;
2338 info.realActivity = realActivity;
2339 info.numActivities = reuseActivitiesReport.numActivities;
2340 info.lastActiveTime = lastActiveTime;
2341 info.taskDescription = new ActivityManager.TaskDescription(lastTaskDescription);
2342 info.supportsSplitScreenMultiWindow = supportsSplitScreenWindowingMode();
2343 info.resizeMode = mResizeMode;
2344 info.configuration.setTo(getConfiguration());
2345 }
2346
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002347 void dump(PrintWriter pw, String prefix) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002348 pw.print(prefix); pw.print("userId="); pw.print(userId);
Dianne Hackborn885fbe52014-08-23 15:23:58 -07002349 pw.print(" effectiveUid="); UserHandle.formatUid(pw, effectiveUid);
2350 pw.print(" mCallingUid="); UserHandle.formatUid(pw, mCallingUid);
Suprabh Shukla7745c142016-03-07 18:21:10 -08002351 pw.print(" mUserSetupComplete="); pw.print(mUserSetupComplete);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002352 pw.print(" mCallingPackage="); pw.println(mCallingPackage);
Dianne Hackborn79228822014-09-16 11:11:23 -07002353 if (affinity != null || rootAffinity != null) {
2354 pw.print(prefix); pw.print("affinity="); pw.print(affinity);
2355 if (affinity == null || !affinity.equals(rootAffinity)) {
2356 pw.print(" root="); pw.println(rootAffinity);
2357 } else {
2358 pw.println();
2359 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002360 }
Dianne Hackborn91097de2014-04-04 18:02:06 -07002361 if (voiceSession != null || voiceInteractor != null) {
2362 pw.print(prefix); pw.print("VOICE: session=0x");
2363 pw.print(Integer.toHexString(System.identityHashCode(voiceSession)));
2364 pw.print(" interactor=0x");
2365 pw.println(Integer.toHexString(System.identityHashCode(voiceInteractor)));
2366 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002367 if (intent != null) {
2368 StringBuilder sb = new StringBuilder(128);
2369 sb.append(prefix); sb.append("intent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08002370 intent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002371 sb.append('}');
2372 pw.println(sb.toString());
2373 }
2374 if (affinityIntent != null) {
2375 StringBuilder sb = new StringBuilder(128);
2376 sb.append(prefix); sb.append("affinityIntent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08002377 affinityIntent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002378 sb.append('}');
2379 pw.println(sb.toString());
2380 }
2381 if (origActivity != null) {
2382 pw.print(prefix); pw.print("origActivity=");
2383 pw.println(origActivity.flattenToShortString());
2384 }
2385 if (realActivity != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002386 pw.print(prefix); pw.print("mActivityComponent=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002387 pw.println(realActivity.flattenToShortString());
2388 }
Wale Ogunwale66e16852017-10-19 13:35:52 -07002389 if (autoRemoveRecents || isPersistable || !isActivityTypeStandard() || numFullscreen != 0) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002390 pw.print(prefix); pw.print("autoRemoveRecents="); pw.print(autoRemoveRecents);
Dianne Hackborn852975d2014-08-22 17:42:43 -07002391 pw.print(" isPersistable="); pw.print(isPersistable);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002392 pw.print(" numFullscreen="); pw.print(numFullscreen);
Wale Ogunwale66e16852017-10-19 13:35:52 -07002393 pw.print(" activityType="); pw.println(getActivityType());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002394 }
Craig Mautner432f64e2015-05-20 14:59:57 -07002395 if (rootWasReset || mNeverRelinquishIdentity || mReuseTask
2396 || mLockTaskAuth != LOCK_TASK_AUTH_PINNABLE) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002397 pw.print(prefix); pw.print("rootWasReset="); pw.print(rootWasReset);
2398 pw.print(" mNeverRelinquishIdentity="); pw.print(mNeverRelinquishIdentity);
Craig Mautner432f64e2015-05-20 14:59:57 -07002399 pw.print(" mReuseTask="); pw.print(mReuseTask);
2400 pw.print(" mLockTaskAuth="); pw.println(lockTaskAuthToString());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002401 }
Wale Ogunwale18795a22014-12-03 11:38:33 -08002402 if (mAffiliatedTaskId != taskId || mPrevAffiliateTaskId != INVALID_TASK_ID
2403 || mPrevAffiliate != null || mNextAffiliateTaskId != INVALID_TASK_ID
2404 || mNextAffiliate != null) {
Dianne Hackborn852975d2014-08-22 17:42:43 -07002405 pw.print(prefix); pw.print("affiliation="); pw.print(mAffiliatedTaskId);
2406 pw.print(" prevAffiliation="); pw.print(mPrevAffiliateTaskId);
2407 pw.print(" (");
2408 if (mPrevAffiliate == null) {
2409 pw.print("null");
2410 } else {
2411 pw.print(Integer.toHexString(System.identityHashCode(mPrevAffiliate)));
2412 }
2413 pw.print(") nextAffiliation="); pw.print(mNextAffiliateTaskId);
2414 pw.print(" (");
2415 if (mNextAffiliate == null) {
2416 pw.print("null");
2417 } else {
2418 pw.print(Integer.toHexString(System.identityHashCode(mNextAffiliate)));
2419 }
2420 pw.println(")");
2421 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002422 pw.print(prefix); pw.print("Activities="); pw.println(mActivities);
Dianne Hackborn852975d2014-08-22 17:42:43 -07002423 if (!askedCompatMode || !inRecents || !isAvailable) {
2424 pw.print(prefix); pw.print("askedCompatMode="); pw.print(askedCompatMode);
2425 pw.print(" inRecents="); pw.print(inRecents);
2426 pw.print(" isAvailable="); pw.println(isAvailable);
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002427 }
Dianne Hackborn852975d2014-08-22 17:42:43 -07002428 if (lastDescription != null) {
2429 pw.print(prefix); pw.print("lastDescription="); pw.println(lastDescription);
2430 }
Dianne Hackborn68a06332017-11-15 17:54:18 -08002431 if (mRootProcess != null) {
2432 pw.print(prefix); pw.print("mRootProcess="); pw.println(mRootProcess);
2433 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07002434 pw.print(prefix); pw.print("stackId="); pw.println(getStackId());
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002435 pw.print(prefix + "hasBeenVisible=" + hasBeenVisible);
2436 pw.print(" mResizeMode=" + ActivityInfo.resizeModeToString(mResizeMode));
Winson Chungd3395382016-12-13 11:49:09 -08002437 pw.print(" mSupportsPictureInPicture=" + mSupportsPictureInPicture);
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002438 pw.print(" isResizeable=" + isResizeable());
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002439 pw.print(" lastActiveTime=" + lastActiveTime);
2440 pw.println(" (inactive for " + (getInactiveDuration() / 1000) + "s)");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002441 }
2442
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002443 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002444 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002445 StringBuilder sb = new StringBuilder(128);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002446 if (stringName != null) {
2447 sb.append(stringName);
2448 sb.append(" U=");
2449 sb.append(userId);
Wale Ogunwale6c5eb1c2015-11-10 07:52:22 -08002450 sb.append(" StackId=");
Andrii Kulian02b7a832016-10-06 23:11:56 -07002451 sb.append(getStackId());
Craig Mautnerde4ef022013-04-07 19:01:33 -07002452 sb.append(" sz=");
2453 sb.append(mActivities.size());
2454 sb.append('}');
2455 return sb.toString();
2456 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002457 sb.append("TaskRecord{");
2458 sb.append(Integer.toHexString(System.identityHashCode(this)));
2459 sb.append(" #");
2460 sb.append(taskId);
2461 if (affinity != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002462 sb.append(" A=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002463 sb.append(affinity);
2464 } else if (intent != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002465 sb.append(" I=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002466 sb.append(intent.getComponent().flattenToShortString());
Bryce Leefbd263b42018-03-07 10:33:55 -08002467 } else if (affinityIntent != null && affinityIntent.getComponent() != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002468 sb.append(" aI=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002469 sb.append(affinityIntent.getComponent().flattenToShortString());
2470 } else {
2471 sb.append(" ??");
2472 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07002473 stringName = sb.toString();
2474 return toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002475 }
Steven Timotius4346f0a2017-09-12 11:07:21 -07002476
Nataniel Borges023ecb52019-01-16 14:15:43 -08002477 public void writeToProto(ProtoOutputStream proto, long fieldId,
2478 @WindowTraceLogLevel int logLevel) {
2479 if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) {
2480 return;
2481 }
2482
Steven Timotius4346f0a2017-09-12 11:07:21 -07002483 final long token = proto.start(fieldId);
Nataniel Borges023ecb52019-01-16 14:15:43 -08002484 super.writeToProto(proto, CONFIGURATION_CONTAINER, logLevel);
Steven Timotius4346f0a2017-09-12 11:07:21 -07002485 proto.write(ID, taskId);
2486 for (int i = mActivities.size() - 1; i >= 0; i--) {
2487 ActivityRecord activity = mActivities.get(i);
2488 activity.writeToProto(proto, ACTIVITIES);
2489 }
2490 proto.write(STACK_ID, mStack.mStackId);
2491 if (mLastNonFullscreenBounds != null) {
2492 mLastNonFullscreenBounds.writeToProto(proto, LAST_NON_FULLSCREEN_BOUNDS);
2493 }
2494 if (realActivity != null) {
2495 proto.write(REAL_ACTIVITY, realActivity.flattenToShortString());
2496 }
2497 if (origActivity != null) {
2498 proto.write(ORIG_ACTIVITY, origActivity.flattenToShortString());
2499 }
2500 proto.write(ACTIVITY_TYPE, getActivityType());
Steven Timotius4346f0a2017-09-12 11:07:21 -07002501 proto.write(RESIZE_MODE, mResizeMode);
Bryce Leef3c6a472017-11-14 14:53:06 -08002502 // TODO: Remove, no longer needed with windowingMode.
2503 proto.write(FULLSCREEN, matchParentBounds());
2504
2505 if (!matchParentBounds()) {
Evan Roskydfe3da72018-10-26 17:21:06 -07002506 final Rect bounds = getRequestedOverrideBounds();
Bryce Leef3c6a472017-11-14 14:53:06 -08002507 bounds.writeToProto(proto, BOUNDS);
Steven Timotius4346f0a2017-09-12 11:07:21 -07002508 }
2509 proto.write(MIN_WIDTH, mMinWidth);
2510 proto.write(MIN_HEIGHT, mMinHeight);
2511 proto.end(token);
2512 }
Winson Chung61c9e5a2017-10-11 10:39:32 -07002513
2514 /**
2515 * See {@link #getNumRunningActivities(TaskActivitiesReport)}.
2516 */
2517 static class TaskActivitiesReport {
2518 int numRunning;
2519 int numActivities;
2520 ActivityRecord top;
2521 ActivityRecord base;
2522
2523 void reset() {
2524 numRunning = numActivities = 0;
2525 top = base = null;
2526 }
2527 }
Garfield Tan9b1efea2017-12-05 16:43:46 -08002528
2529 /**
2530 * Saves this {@link TaskRecord} to XML using given serializer.
2531 */
2532 void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
2533 if (DEBUG_RECENTS) Slog.i(TAG_RECENTS, "Saving task=" + this);
2534
2535 out.attribute(null, ATTR_TASKID, String.valueOf(taskId));
2536 if (realActivity != null) {
2537 out.attribute(null, ATTR_REALACTIVITY, realActivity.flattenToShortString());
2538 }
2539 out.attribute(null, ATTR_REALACTIVITY_SUSPENDED, String.valueOf(realActivitySuspended));
2540 if (origActivity != null) {
2541 out.attribute(null, ATTR_ORIGACTIVITY, origActivity.flattenToShortString());
2542 }
2543 // Write affinity, and root affinity if it is different from affinity.
2544 // We use the special string "@" for a null root affinity, so we can identify
2545 // later whether we were given a root affinity or should just make it the
2546 // same as the affinity.
2547 if (affinity != null) {
2548 out.attribute(null, ATTR_AFFINITY, affinity);
2549 if (!affinity.equals(rootAffinity)) {
2550 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
2551 }
2552 } else if (rootAffinity != null) {
2553 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
2554 }
2555 out.attribute(null, ATTR_ROOTHASRESET, String.valueOf(rootWasReset));
2556 out.attribute(null, ATTR_AUTOREMOVERECENTS, String.valueOf(autoRemoveRecents));
2557 out.attribute(null, ATTR_ASKEDCOMPATMODE, String.valueOf(askedCompatMode));
2558 out.attribute(null, ATTR_USERID, String.valueOf(userId));
2559 out.attribute(null, ATTR_USER_SETUP_COMPLETE, String.valueOf(mUserSetupComplete));
2560 out.attribute(null, ATTR_EFFECTIVE_UID, String.valueOf(effectiveUid));
2561 out.attribute(null, ATTR_LASTTIMEMOVED, String.valueOf(mLastTimeMoved));
2562 out.attribute(null, ATTR_NEVERRELINQUISH, String.valueOf(mNeverRelinquishIdentity));
2563 if (lastDescription != null) {
2564 out.attribute(null, ATTR_LASTDESCRIPTION, lastDescription.toString());
2565 }
2566 if (lastTaskDescription != null) {
2567 lastTaskDescription.saveToXml(out);
2568 }
2569 out.attribute(null, ATTR_TASK_AFFILIATION_COLOR, String.valueOf(mAffiliatedTaskColor));
2570 out.attribute(null, ATTR_TASK_AFFILIATION, String.valueOf(mAffiliatedTaskId));
2571 out.attribute(null, ATTR_PREV_AFFILIATION, String.valueOf(mPrevAffiliateTaskId));
2572 out.attribute(null, ATTR_NEXT_AFFILIATION, String.valueOf(mNextAffiliateTaskId));
2573 out.attribute(null, ATTR_CALLING_UID, String.valueOf(mCallingUid));
2574 out.attribute(null, ATTR_CALLING_PACKAGE, mCallingPackage == null ? "" : mCallingPackage);
2575 out.attribute(null, ATTR_RESIZE_MODE, String.valueOf(mResizeMode));
2576 out.attribute(null, ATTR_SUPPORTS_PICTURE_IN_PICTURE,
2577 String.valueOf(mSupportsPictureInPicture));
2578 if (mLastNonFullscreenBounds != null) {
2579 out.attribute(
2580 null, ATTR_NON_FULLSCREEN_BOUNDS, mLastNonFullscreenBounds.flattenToString());
2581 }
2582 out.attribute(null, ATTR_MIN_WIDTH, String.valueOf(mMinWidth));
2583 out.attribute(null, ATTR_MIN_HEIGHT, String.valueOf(mMinHeight));
2584 out.attribute(null, ATTR_PERSIST_TASK_VERSION, String.valueOf(PERSIST_TASK_VERSION));
2585
2586 if (affinityIntent != null) {
2587 out.startTag(null, TAG_AFFINITYINTENT);
2588 affinityIntent.saveToXml(out);
2589 out.endTag(null, TAG_AFFINITYINTENT);
2590 }
2591
Bryce Lee1a990e52018-04-23 10:54:11 -07002592 if (intent != null) {
2593 out.startTag(null, TAG_INTENT);
2594 intent.saveToXml(out);
2595 out.endTag(null, TAG_INTENT);
2596 }
Garfield Tan9b1efea2017-12-05 16:43:46 -08002597
2598 final ArrayList<ActivityRecord> activities = mActivities;
2599 final int numActivities = activities.size();
2600 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
2601 final ActivityRecord r = activities.get(activityNdx);
2602 if (r.info.persistableMode == ActivityInfo.PERSIST_ROOT_ONLY || !r.isPersistable() ||
2603 ((r.intent.getFlags() & FLAG_ACTIVITY_NEW_DOCUMENT
2604 | FLAG_ACTIVITY_RETAIN_IN_RECENTS) == FLAG_ACTIVITY_NEW_DOCUMENT) &&
2605 activityNdx > 0) {
2606 // Stop at first non-persistable or first break in task (CLEAR_WHEN_TASK_RESET).
2607 break;
2608 }
2609 out.startTag(null, TAG_ACTIVITY);
2610 r.saveToXml(out);
2611 out.endTag(null, TAG_ACTIVITY);
2612 }
2613 }
2614
2615 @VisibleForTesting
2616 static TaskRecordFactory getTaskRecordFactory() {
2617 if (sTaskRecordFactory == null) {
2618 setTaskRecordFactory(new TaskRecordFactory());
2619 }
2620 return sTaskRecordFactory;
2621 }
2622
2623 static void setTaskRecordFactory(TaskRecordFactory factory) {
2624 sTaskRecordFactory = factory;
2625 }
2626
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002627 static TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002628 Intent intent, IVoiceInteractionSession voiceSession,
2629 IVoiceInteractor voiceInteractor) {
2630 return getTaskRecordFactory().create(
2631 service, taskId, info, intent, voiceSession, voiceInteractor);
2632 }
2633
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002634 static TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002635 Intent intent, TaskDescription taskDescription) {
2636 return getTaskRecordFactory().create(service, taskId, info, intent, taskDescription);
2637 }
2638
2639 static TaskRecord restoreFromXml(XmlPullParser in, ActivityStackSupervisor stackSupervisor)
2640 throws IOException, XmlPullParserException {
2641 return getTaskRecordFactory().restoreFromXml(in, stackSupervisor);
2642 }
2643
2644 /**
2645 * A factory class used to create {@link TaskRecord} or its subclass if any. This can be
2646 * specified when system boots by setting it with
2647 * {@link #setTaskRecordFactory(TaskRecordFactory)}.
2648 */
2649 static class TaskRecordFactory {
2650
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002651 TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002652 Intent intent, IVoiceInteractionSession voiceSession,
2653 IVoiceInteractor voiceInteractor) {
2654 return new TaskRecord(
2655 service, taskId, info, intent, voiceSession, voiceInteractor);
2656 }
2657
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002658 TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002659 Intent intent, TaskDescription taskDescription) {
2660 return new TaskRecord(service, taskId, info, intent, taskDescription);
2661 }
2662
2663 /**
2664 * Should only be used when we're restoring {@link TaskRecord} from storage.
2665 */
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002666 TaskRecord create(ActivityTaskManagerService service, int taskId, Intent intent,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002667 Intent affinityIntent, String affinity, String rootAffinity,
2668 ComponentName realActivity, ComponentName origActivity, boolean rootWasReset,
2669 boolean autoRemoveRecents, boolean askedCompatMode, int userId,
2670 int effectiveUid, String lastDescription, ArrayList<ActivityRecord> activities,
2671 long lastTimeMoved, boolean neverRelinquishIdentity,
2672 TaskDescription lastTaskDescription, int taskAffiliation, int prevTaskId,
2673 int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage,
2674 int resizeMode, boolean supportsPictureInPicture, boolean realActivitySuspended,
2675 boolean userSetupComplete, int minWidth, int minHeight) {
2676 return new TaskRecord(service, taskId, intent, affinityIntent, affinity,
2677 rootAffinity, realActivity, origActivity, rootWasReset, autoRemoveRecents,
2678 askedCompatMode, userId, effectiveUid, lastDescription, activities,
2679 lastTimeMoved, neverRelinquishIdentity, lastTaskDescription, taskAffiliation,
2680 prevTaskId, nextTaskId, taskAffiliationColor, callingUid, callingPackage,
2681 resizeMode, supportsPictureInPicture, realActivitySuspended, userSetupComplete,
2682 minWidth, minHeight);
2683 }
2684
2685 TaskRecord restoreFromXml(XmlPullParser in, ActivityStackSupervisor stackSupervisor)
2686 throws IOException, XmlPullParserException {
2687 Intent intent = null;
2688 Intent affinityIntent = null;
2689 ArrayList<ActivityRecord> activities = new ArrayList<>();
2690 ComponentName realActivity = null;
2691 boolean realActivitySuspended = false;
2692 ComponentName origActivity = null;
2693 String affinity = null;
2694 String rootAffinity = null;
2695 boolean hasRootAffinity = false;
2696 boolean rootHasReset = false;
2697 boolean autoRemoveRecents = false;
2698 boolean askedCompatMode = false;
2699 int taskType = 0;
2700 int userId = 0;
2701 boolean userSetupComplete = true;
2702 int effectiveUid = -1;
2703 String lastDescription = null;
2704 long lastTimeOnTop = 0;
2705 boolean neverRelinquishIdentity = true;
2706 int taskId = INVALID_TASK_ID;
2707 final int outerDepth = in.getDepth();
2708 TaskDescription taskDescription = new TaskDescription();
2709 int taskAffiliation = INVALID_TASK_ID;
2710 int taskAffiliationColor = 0;
2711 int prevTaskId = INVALID_TASK_ID;
2712 int nextTaskId = INVALID_TASK_ID;
2713 int callingUid = -1;
2714 String callingPackage = "";
2715 int resizeMode = RESIZE_MODE_FORCE_RESIZEABLE;
2716 boolean supportsPictureInPicture = false;
Garfield Tan367b35a2017-12-13 12:16:21 -08002717 Rect lastNonFullscreenBounds = null;
Garfield Tan9b1efea2017-12-05 16:43:46 -08002718 int minWidth = INVALID_MIN_SIZE;
2719 int minHeight = INVALID_MIN_SIZE;
2720 int persistTaskVersion = 0;
2721
2722 for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
2723 final String attrName = in.getAttributeName(attrNdx);
2724 final String attrValue = in.getAttributeValue(attrNdx);
2725 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: attribute name=" +
2726 attrName + " value=" + attrValue);
2727 switch (attrName) {
2728 case ATTR_TASKID:
2729 if (taskId == INVALID_TASK_ID) taskId = Integer.parseInt(attrValue);
2730 break;
2731 case ATTR_REALACTIVITY:
2732 realActivity = ComponentName.unflattenFromString(attrValue);
2733 break;
2734 case ATTR_REALACTIVITY_SUSPENDED:
2735 realActivitySuspended = Boolean.valueOf(attrValue);
2736 break;
2737 case ATTR_ORIGACTIVITY:
2738 origActivity = ComponentName.unflattenFromString(attrValue);
2739 break;
2740 case ATTR_AFFINITY:
2741 affinity = attrValue;
2742 break;
2743 case ATTR_ROOT_AFFINITY:
2744 rootAffinity = attrValue;
2745 hasRootAffinity = true;
2746 break;
2747 case ATTR_ROOTHASRESET:
2748 rootHasReset = Boolean.parseBoolean(attrValue);
2749 break;
2750 case ATTR_AUTOREMOVERECENTS:
2751 autoRemoveRecents = Boolean.parseBoolean(attrValue);
2752 break;
2753 case ATTR_ASKEDCOMPATMODE:
2754 askedCompatMode = Boolean.parseBoolean(attrValue);
2755 break;
2756 case ATTR_USERID:
2757 userId = Integer.parseInt(attrValue);
2758 break;
2759 case ATTR_USER_SETUP_COMPLETE:
2760 userSetupComplete = Boolean.parseBoolean(attrValue);
2761 break;
2762 case ATTR_EFFECTIVE_UID:
2763 effectiveUid = Integer.parseInt(attrValue);
2764 break;
2765 case ATTR_TASKTYPE:
2766 taskType = Integer.parseInt(attrValue);
2767 break;
2768 case ATTR_LASTDESCRIPTION:
2769 lastDescription = attrValue;
2770 break;
2771 case ATTR_LASTTIMEMOVED:
2772 lastTimeOnTop = Long.parseLong(attrValue);
2773 break;
2774 case ATTR_NEVERRELINQUISH:
2775 neverRelinquishIdentity = Boolean.parseBoolean(attrValue);
2776 break;
2777 case ATTR_TASK_AFFILIATION:
2778 taskAffiliation = Integer.parseInt(attrValue);
2779 break;
2780 case ATTR_PREV_AFFILIATION:
2781 prevTaskId = Integer.parseInt(attrValue);
2782 break;
2783 case ATTR_NEXT_AFFILIATION:
2784 nextTaskId = Integer.parseInt(attrValue);
2785 break;
2786 case ATTR_TASK_AFFILIATION_COLOR:
2787 taskAffiliationColor = Integer.parseInt(attrValue);
2788 break;
2789 case ATTR_CALLING_UID:
2790 callingUid = Integer.parseInt(attrValue);
2791 break;
2792 case ATTR_CALLING_PACKAGE:
2793 callingPackage = attrValue;
2794 break;
2795 case ATTR_RESIZE_MODE:
2796 resizeMode = Integer.parseInt(attrValue);
2797 break;
2798 case ATTR_SUPPORTS_PICTURE_IN_PICTURE:
2799 supportsPictureInPicture = Boolean.parseBoolean(attrValue);
2800 break;
2801 case ATTR_NON_FULLSCREEN_BOUNDS:
Garfield Tan367b35a2017-12-13 12:16:21 -08002802 lastNonFullscreenBounds = Rect.unflattenFromString(attrValue);
Garfield Tan9b1efea2017-12-05 16:43:46 -08002803 break;
2804 case ATTR_MIN_WIDTH:
2805 minWidth = Integer.parseInt(attrValue);
2806 break;
2807 case ATTR_MIN_HEIGHT:
2808 minHeight = Integer.parseInt(attrValue);
2809 break;
2810 case ATTR_PERSIST_TASK_VERSION:
2811 persistTaskVersion = Integer.parseInt(attrValue);
2812 break;
2813 default:
2814 if (attrName.startsWith(TaskDescription.ATTR_TASKDESCRIPTION_PREFIX)) {
2815 taskDescription.restoreFromXml(attrName, attrValue);
2816 } else {
2817 Slog.w(TAG, "TaskRecord: Unknown attribute=" + attrName);
2818 }
2819 }
2820 }
2821
2822 int event;
2823 while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
2824 (event != XmlPullParser.END_TAG || in.getDepth() >= outerDepth)) {
2825 if (event == XmlPullParser.START_TAG) {
2826 final String name = in.getName();
2827 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG,
2828 "TaskRecord: START_TAG name=" + name);
2829 if (TAG_AFFINITYINTENT.equals(name)) {
2830 affinityIntent = Intent.restoreFromXml(in);
2831 } else if (TAG_INTENT.equals(name)) {
2832 intent = Intent.restoreFromXml(in);
2833 } else if (TAG_ACTIVITY.equals(name)) {
2834 ActivityRecord activity =
2835 ActivityRecord.restoreFromXml(in, stackSupervisor);
2836 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: activity=" +
2837 activity);
2838 if (activity != null) {
2839 activities.add(activity);
2840 }
2841 } else {
Garfield Tan1e740192017-12-12 14:37:42 -08002842 handleUnknownTag(name, in);
Garfield Tan9b1efea2017-12-05 16:43:46 -08002843 }
2844 }
2845 }
2846 if (!hasRootAffinity) {
2847 rootAffinity = affinity;
2848 } else if ("@".equals(rootAffinity)) {
2849 rootAffinity = null;
2850 }
2851 if (effectiveUid <= 0) {
2852 Intent checkIntent = intent != null ? intent : affinityIntent;
2853 effectiveUid = 0;
2854 if (checkIntent != null) {
2855 IPackageManager pm = AppGlobals.getPackageManager();
2856 try {
2857 ApplicationInfo ai = pm.getApplicationInfo(
2858 checkIntent.getComponent().getPackageName(),
2859 PackageManager.MATCH_UNINSTALLED_PACKAGES
2860 | PackageManager.MATCH_DISABLED_COMPONENTS, userId);
2861 if (ai != null) {
2862 effectiveUid = ai.uid;
2863 }
2864 } catch (RemoteException e) {
2865 }
2866 }
2867 Slog.w(TAG, "Updating task #" + taskId + " for " + checkIntent
2868 + ": effectiveUid=" + effectiveUid);
2869 }
2870
2871 if (persistTaskVersion < 1) {
2872 // We need to convert the resize mode of home activities saved before version one if
2873 // they are marked as RESIZE_MODE_RESIZEABLE to
2874 // RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION since we didn't have that differentiation
2875 // before version 1 and the system didn't resize home activities before then.
2876 if (taskType == 1 /* old home type */ && resizeMode == RESIZE_MODE_RESIZEABLE) {
2877 resizeMode = RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
2878 }
2879 } else {
2880 // This activity has previously marked itself explicitly as both resizeable and
2881 // supporting picture-in-picture. Since there is no longer a requirement for
2882 // picture-in-picture activities to be resizeable, we can mark this simply as
2883 // resizeable and supporting picture-in-picture separately.
2884 if (resizeMode == RESIZE_MODE_RESIZEABLE_AND_PIPABLE_DEPRECATED) {
2885 resizeMode = RESIZE_MODE_RESIZEABLE;
2886 supportsPictureInPicture = true;
2887 }
2888 }
2889
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07002890 final TaskRecord task = create(stackSupervisor.mService,
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002891 taskId, intent, affinityIntent,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002892 affinity, rootAffinity, realActivity, origActivity, rootHasReset,
2893 autoRemoveRecents, askedCompatMode, userId, effectiveUid, lastDescription,
2894 activities, lastTimeOnTop, neverRelinquishIdentity, taskDescription,
2895 taskAffiliation, prevTaskId, nextTaskId, taskAffiliationColor, callingUid,
2896 callingPackage, resizeMode, supportsPictureInPicture, realActivitySuspended,
2897 userSetupComplete, minWidth, minHeight);
Garfield Tan367b35a2017-12-13 12:16:21 -08002898 task.mLastNonFullscreenBounds = lastNonFullscreenBounds;
2899 task.setBounds(lastNonFullscreenBounds);
Garfield Tan9b1efea2017-12-05 16:43:46 -08002900
2901 for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {
2902 activities.get(activityNdx).setTask(task);
2903 }
2904
2905 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Restored task=" + task);
2906 return task;
2907 }
Garfield Tan1e740192017-12-12 14:37:42 -08002908
2909 void handleUnknownTag(String name, XmlPullParser in)
2910 throws IOException, XmlPullParserException {
2911 Slog.e(TAG, "restoreTask: Unexpected name=" + name);
2912 XmlUtils.skipCurrentTag(in);
2913 }
Garfield Tan9b1efea2017-12-05 16:43:46 -08002914 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002915}