blob: 1392762fca66ce44272bb8b85db0a88757fe97f3 [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;
Mark Renoufb1abb552019-02-08 13:51:41 -0500122import android.view.Display;
Evan Rosky1ac84462018-11-13 11:25:30 -0800123import android.view.DisplayInfo;
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200124
125import com.android.internal.annotations.VisibleForTesting;
126import com.android.internal.app.IVoiceInteractor;
127import com.android.internal.util.XmlUtils;
Wale Ogunwale59507092018-10-29 09:00:30 -0700128import com.android.server.wm.ActivityStack.ActivityState;
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200129
130import org.xmlpull.v1.XmlPullParser;
131import org.xmlpull.v1.XmlPullParserException;
132import org.xmlpull.v1.XmlSerializer;
133
134import java.io.IOException;
135import java.io.PrintWriter;
136import java.lang.annotation.Retention;
137import java.lang.annotation.RetentionPolicy;
138import java.util.ArrayList;
139import java.util.Objects;
140
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800141class TaskRecord extends ConfigurationContainer {
Wale Ogunwale98875612018-10-12 07:53:02 -0700142 private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskRecord" : TAG_ATM;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -0700143 private static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700144 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
Craig Mautnere0570202015-05-13 13:06:11 -0700145 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700146 private static final String TAG_TASKS = TAG + POSTFIX_TASKS;
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800147
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700148 private static final String ATTR_TASKID = "task_id";
Craig Mautner21d24a22014-04-23 11:45:37 -0700149 private static final String TAG_INTENT = "intent";
150 private static final String TAG_AFFINITYINTENT = "affinity_intent";
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700151 private static final String ATTR_REALACTIVITY = "real_activity";
152 private static final String ATTR_REALACTIVITY_SUSPENDED = "real_activity_suspended";
Craig Mautner21d24a22014-04-23 11:45:37 -0700153 private static final String ATTR_ORIGACTIVITY = "orig_activity";
Stefan Kuhnee88d1e52015-05-18 10:33:45 -0700154 private static final String TAG_ACTIVITY = "activity";
Craig Mautner21d24a22014-04-23 11:45:37 -0700155 private static final String ATTR_AFFINITY = "affinity";
Dianne Hackborn79228822014-09-16 11:11:23 -0700156 private static final String ATTR_ROOT_AFFINITY = "root_affinity";
Craig Mautner21d24a22014-04-23 11:45:37 -0700157 private static final String ATTR_ROOTHASRESET = "root_has_reset";
Dianne Hackborn13420f22014-07-18 15:43:56 -0700158 private static final String ATTR_AUTOREMOVERECENTS = "auto_remove_recents";
Craig Mautner21d24a22014-04-23 11:45:37 -0700159 private static final String ATTR_ASKEDCOMPATMODE = "asked_compat_mode";
160 private static final String ATTR_USERID = "user_id";
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800161 private static final String ATTR_USER_SETUP_COMPLETE = "user_setup_complete";
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700162 private static final String ATTR_EFFECTIVE_UID = "effective_uid";
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700163 @Deprecated
Craig Mautner21d24a22014-04-23 11:45:37 -0700164 private static final String ATTR_TASKTYPE = "task_type";
Craig Mautner21d24a22014-04-23 11:45:37 -0700165 private static final String ATTR_LASTDESCRIPTION = "last_description";
166 private static final String ATTR_LASTTIMEMOVED = "last_time_moved";
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700167 private static final String ATTR_NEVERRELINQUISH = "never_relinquish_identity";
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700168 private static final String ATTR_TASK_AFFILIATION = "task_affiliation";
Craig Mautnera228ae92014-07-09 05:44:55 -0700169 private static final String ATTR_PREV_AFFILIATION = "prev_affiliation";
170 private static final String ATTR_NEXT_AFFILIATION = "next_affiliation";
Winson Chungec396d62014-08-06 17:08:00 -0700171 private static final String ATTR_TASK_AFFILIATION_COLOR = "task_affiliation_color";
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700172 private static final String ATTR_CALLING_UID = "calling_uid";
173 private static final String ATTR_CALLING_PACKAGE = "calling_package";
Winson Chungd3395382016-12-13 11:49:09 -0800174 private static final String ATTR_SUPPORTS_PICTURE_IN_PICTURE = "supports_picture_in_picture";
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800175 private static final String ATTR_RESIZE_MODE = "resize_mode";
Wale Ogunwale706ed792015-08-02 10:29:44 -0700176 private static final String ATTR_NON_FULLSCREEN_BOUNDS = "non_fullscreen_bounds";
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700177 private static final String ATTR_MIN_WIDTH = "min_width";
178 private static final String ATTR_MIN_HEIGHT = "min_height";
Wale Ogunwale625ed0c2016-10-18 08:50:31 -0700179 private static final String ATTR_PERSIST_TASK_VERSION = "persist_task_version";
Andrii Kulian18d75122016-03-27 20:20:28 -0700180
Wale Ogunwale625ed0c2016-10-18 08:50:31 -0700181 // Current version of the task record we persist. Used to check if we need to run any upgrade
182 // code.
183 private static final int PERSIST_TASK_VERSION = 1;
Craig Mautner21d24a22014-04-23 11:45:37 -0700184
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700185 private static final int INVALID_MIN_SIZE = -1;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800186
Winson Chung74666102017-02-22 17:49:24 -0800187 /**
188 * The modes to control how the stack is moved to the front when calling
189 * {@link TaskRecord#reparent}.
190 */
191 @Retention(RetentionPolicy.SOURCE)
192 @IntDef({
193 REPARENT_MOVE_STACK_TO_FRONT,
194 REPARENT_KEEP_STACK_AT_FRONT,
195 REPARENT_LEAVE_STACK_IN_PLACE
196 })
Wale Ogunwale66e16852017-10-19 13:35:52 -0700197 @interface ReparentMoveStackMode {}
Winson Chung74666102017-02-22 17:49:24 -0800198 // Moves the stack to the front if it was not at the front
Wale Ogunwale66e16852017-10-19 13:35:52 -0700199 static final int REPARENT_MOVE_STACK_TO_FRONT = 0;
Winson Chung74666102017-02-22 17:49:24 -0800200 // Only moves the stack to the front if it was focused or front most already
Wale Ogunwale66e16852017-10-19 13:35:52 -0700201 static final int REPARENT_KEEP_STACK_AT_FRONT = 1;
Winson Chung74666102017-02-22 17:49:24 -0800202 // Do not move the stack as a part of reparenting
Wale Ogunwale66e16852017-10-19 13:35:52 -0700203 static final int REPARENT_LEAVE_STACK_IN_PLACE = 2;
Winson Chung74666102017-02-22 17:49:24 -0800204
Evan Rosky1ac84462018-11-13 11:25:30 -0800205 // The height/width divide used when fitting a task within a bounds with method
206 // {@link #fitWithinBounds}.
207 // We always want the task to to be visible in the bounds without affecting its size when
208 // fitting. To make sure this is the case, we don't adjust the task left or top side pass
209 // the input bounds right or bottom side minus the width or height divided by this value.
210 private static final int FIT_WITHIN_BOUNDS_DIVIDER = 3;
211
Garfield Tan9b1efea2017-12-05 16:43:46 -0800212 /**
213 * The factory used to create {@link TaskRecord}. This allows OEM subclass {@link TaskRecord}.
214 */
215 private static TaskRecordFactory sTaskRecordFactory;
216
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800217 final int taskId; // Unique identifier for this task.
Dianne Hackborn79228822014-09-16 11:11:23 -0700218 String affinity; // The affinity name for this task, or null; may change identity.
219 String rootAffinity; // Initial base affinity, or null; does not change from initial root.
Dianne Hackborn91097de2014-04-04 18:02:06 -0700220 final IVoiceInteractionSession voiceSession; // Voice interaction session driving task
221 final IVoiceInteractor voiceInteractor; // Associated interactor to provide to app
Bryce Lee1a990e52018-04-23 10:54:11 -0700222 Intent intent; // The original intent that started the task. Note that this value can
223 // be null.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800224 Intent affinityIntent; // Intent of affinity-moved activity that started this task.
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700225 int effectiveUid; // The current effective uid of the identity of this task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800226 ComponentName origActivity; // The non-alias activity component of the intent.
227 ComponentName realActivity; // The actual activity component that started the task.
Andrei Stingaceanu4ccec532016-01-13 12:10:21 +0000228 boolean realActivitySuspended; // True if the actual activity component that started the
229 // task is suspended.
Dianne Hackborn852975d2014-08-22 17:42:43 -0700230 boolean inRecents; // Actually in the recents list?
Winson Chungfb44d212017-10-04 11:39:10 -0700231 long lastActiveTime; // Last time this task was active in the current device session,
232 // including sleep. This time is initialized to the elapsed time when
233 // restored from disk.
Dianne Hackborn852975d2014-08-22 17:42:43 -0700234 boolean isAvailable; // Is the activity available to be launched?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800235 boolean rootWasReset; // True if the intent at the root of the task had
236 // the FLAG_ACTIVITY_RESET_TASK_IF_NEEDED flag.
Dianne Hackborn13420f22014-07-18 15:43:56 -0700237 boolean autoRemoveRecents; // If true, we should automatically remove the task from
238 // recents when activity finishes
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700239 boolean askedCompatMode;// Have asked the user about compat mode for this task.
Dianne Hackbornd38aed82014-06-10 21:36:35 -0700240 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 -0800241
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700242 String stringName; // caching of toString() result.
Dianne Hackborn9da2d402012-03-15 13:43:08 -0700243 int userId; // user for which this task was created
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800244 boolean mUserSetupComplete; // The user set-up is complete as of the last time the task activity
245 // was changed.
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800246
247 int numFullscreen; // Number of fullscreen activities.
248
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800249 int mResizeMode; // The resize mode of this task and its activities.
250 // Based on the {@link ActivityInfo#resizeMode} of the root activity.
Wale Ogunwale069bbd32017-02-03 07:58:14 -0800251 private boolean mSupportsPictureInPicture; // Whether or not this task and its activities
252 // support PiP. Based on the {@link ActivityInfo#FLAG_SUPPORTS_PICTURE_IN_PICTURE} flag
253 // of the root activity.
Craig Mautner15df08a2015-04-01 12:17:18 -0700254 /** Can't be put in lockTask mode. */
255 final static int LOCK_TASK_AUTH_DONT_LOCK = 0;
Benjamin Franz469dd582015-06-09 14:24:36 +0100256 /** Can enter app pinning with user approval. Can never start over existing lockTask task. */
Craig Mautner15df08a2015-04-01 12:17:18 -0700257 final static int LOCK_TASK_AUTH_PINNABLE = 1;
258 /** Starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing lockTask task. */
259 final static int LOCK_TASK_AUTH_LAUNCHABLE = 2;
Benjamin Franz469dd582015-06-09 14:24:36 +0100260 /** Can enter lockTask without user approval. Can start over existing lockTask task. */
Craig Mautner15df08a2015-04-01 12:17:18 -0700261 final static int LOCK_TASK_AUTH_WHITELISTED = 3;
Benjamin Franz469dd582015-06-09 14:24:36 +0100262 /** Priv-app that starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing
263 * lockTask task. */
264 final static int LOCK_TASK_AUTH_LAUNCHABLE_PRIV = 4;
Craig Mautner15df08a2015-04-01 12:17:18 -0700265 int mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE;
266
267 int mLockTaskUid = -1; // The uid of the application that called startLockTask().
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800268
Winson Chung03a9bae2014-05-02 09:56:12 -0700269 // This represents the last resolved activity values for this task
270 // NOTE: This value needs to be persisted with each task
Craig Mautner648f69b2014-09-18 14:16:26 -0700271 TaskDescription lastTaskDescription = new TaskDescription();
Winson Chung03a9bae2014-05-02 09:56:12 -0700272
Craig Mautnerd2328952013-03-05 12:46:26 -0800273 /** List of all activities in the task arranged in history order */
Craig Mautner21d24a22014-04-23 11:45:37 -0700274 final ArrayList<ActivityRecord> mActivities;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800275
Andrii Kulian02b7a832016-10-06 23:11:56 -0700276 /** Current stack. Setter must always be used to update the value. */
277 private ActivityStack mStack;
Craig Mautnerd2328952013-03-05 12:46:26 -0800278
Dianne Hackborn68a06332017-11-15 17:54:18 -0800279 /** The process that had previously hosted the root activity of this task.
280 * Used to know that we should try harder to keep this process around, in case the
281 * user wants to return to it. */
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700282 private WindowProcessController mRootProcess;
Dianne Hackborn68a06332017-11-15 17:54:18 -0800283
Craig Mautner21d24a22014-04-23 11:45:37 -0700284 /** Takes on same value as first root activity */
285 boolean isPersistable = false;
Craig Mautnerffcfcaa2014-06-05 09:54:38 -0700286 int maxRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700287
288 /** Only used for persistable tasks, otherwise 0. The last time this task was moved. Used for
289 * determining the order when restoring. Sign indicates whether last task movement was to front
290 * (positive) or back (negative). Absolute value indicates time. */
291 long mLastTimeMoved = System.currentTimeMillis();
292
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700293 /** If original intent did not allow relinquishing task identity, save that information */
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700294 private boolean mNeverRelinquishIdentity = true;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700295
Craig Mautner362449a2014-06-20 14:04:39 -0700296 // Used in the unique case where we are clearing the task in order to reuse it. In that case we
297 // do not want to delete the stack when the task goes empty.
Filip Gruszczynskibe9dabd2016-01-19 12:23:10 -0800298 private boolean mReuseTask = false;
Craig Mautner362449a2014-06-20 14:04:39 -0700299
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700300 CharSequence lastDescription; // Last description captured for this item.
301
Craig Mautnera228ae92014-07-09 05:44:55 -0700302 int mAffiliatedTaskId; // taskId of parent affiliation or self if no parent.
Winson Chungec396d62014-08-06 17:08:00 -0700303 int mAffiliatedTaskColor; // color of the parent task affiliation.
Craig Mautnera228ae92014-07-09 05:44:55 -0700304 TaskRecord mPrevAffiliate; // previous task in affiliated chain.
Wale Ogunwale18795a22014-12-03 11:38:33 -0800305 int mPrevAffiliateTaskId = INVALID_TASK_ID; // previous id for persistence.
Craig Mautnera228ae92014-07-09 05:44:55 -0700306 TaskRecord mNextAffiliate; // next task in affiliated chain.
Wale Ogunwale18795a22014-12-03 11:38:33 -0800307 int mNextAffiliateTaskId = INVALID_TASK_ID; // next id for persistence.
Craig Mautnera228ae92014-07-09 05:44:55 -0700308
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700309 // For relaunching the task from recents as though it was launched by the original launcher.
310 int mCallingUid;
311 String mCallingPackage;
312
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700313 final ActivityTaskManagerService mService;
Craig Mautner21d24a22014-04-23 11:45:37 -0700314
Jorim Jaggi82c9dc92016-02-05 15:10:33 -0800315 private final Rect mTmpStableBounds = new Rect();
316 private final Rect mTmpNonDecorBounds = new Rect();
Evan Rosky1ac84462018-11-13 11:25:30 -0800317 private final Rect mTmpBounds = new Rect();
318 private final Rect mTmpInsets = new Rect();
Jorim Jaggi0a932142016-02-01 17:42:25 -0800319
Wale Ogunwale706ed792015-08-02 10:29:44 -0700320 // Last non-fullscreen bounds the task was launched in or resized to.
321 // The information is persisted and used to determine the appropriate stack to launch the
322 // task into on restore.
323 Rect mLastNonFullscreenBounds = null;
Andrii Kulian2e751b82016-03-16 16:59:32 -0700324 // Minimal width and height of this task when it's resizeable. -1 means it should use the
325 // default minimal width/height.
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700326 int mMinWidth;
327 int mMinHeight;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700328
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700329 // Ranking (from top) of this task among all visible tasks. (-1 means it's not visible)
330 // This number will be assigned when we evaluate OOM scores for all visible tasks.
331 int mLayerRank = -1;
332
Evan Roskyed6767f2018-10-26 17:21:06 -0700333 // When non-empty, this represents the bounds this task will be drawn at. This gets set during
334 // transient operations such as split-divider dragging and animations.
335 // TODO(b/119687367): This member is temporary.
336 final Rect mDisplayedBounds = new Rect();
337
Andrii Kulian1779e612016-10-12 21:58:25 -0700338 /** Helper object used for updating override configuration. */
339 private Configuration mTmpConfig = new Configuration();
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700340
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800341 // TODO: remove after unification
342 Task mTask;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800343
Mark Renoufc808f062019-02-07 15:20:37 -0500344 /** Used by fillTaskInfo */
345 final TaskActivitiesReport mReuseActivitiesReport = new TaskActivitiesReport();
346
Garfield Tan9b1efea2017-12-05 16:43:46 -0800347 /**
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700348 * Don't use constructor directly. Use {@link #create(ActivityTaskManagerService, int,
349 * ActivityInfo, Intent, TaskDescription)} instead.
Garfield Tan9b1efea2017-12-05 16:43:46 -0800350 */
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700351 TaskRecord(ActivityTaskManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700352 IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700353 mService = service;
Suprabh Shukla23593142015-11-03 17:31:15 -0800354 userId = UserHandle.getUserId(info.applicationInfo.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800355 taskId = _taskId;
Winson Chungfb44d212017-10-04 11:39:10 -0700356 lastActiveTime = SystemClock.elapsedRealtime();
Craig Mautnera228ae92014-07-09 05:44:55 -0700357 mAffiliatedTaskId = _taskId;
Dianne Hackborn91097de2014-04-04 18:02:06 -0700358 voiceSession = _voiceSession;
359 voiceInteractor = _voiceInteractor;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700360 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800361 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700362 mCallingUid = info.applicationInfo.uid;
363 mCallingPackage = info.packageName;
Martijn Coenend4a69702014-06-30 11:12:17 -0700364 setIntent(_intent, info);
Andrii Kulian2e751b82016-03-16 16:59:32 -0700365 setMinDimensions(info);
Winson730bf062016-03-31 18:04:56 -0700366 touchActiveTime();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700367 mService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
Craig Mautner21d24a22014-04-23 11:45:37 -0700368 }
369
Garfield Tan9b1efea2017-12-05 16:43:46 -0800370 /**
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700371 * Don't use constructor directly.
372 * Use {@link #create(ActivityTaskManagerService, int, ActivityInfo,
Garfield Tan9b1efea2017-12-05 16:43:46 -0800373 * Intent, IVoiceInteractionSession, IVoiceInteractor)} instead.
374 */
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700375 TaskRecord(ActivityTaskManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200376 TaskDescription _taskDescription) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700377 mService = service;
Suprabh Shukla23593142015-11-03 17:31:15 -0800378 userId = UserHandle.getUserId(info.applicationInfo.uid);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700379 taskId = _taskId;
Winson Chungfb44d212017-10-04 11:39:10 -0700380 lastActiveTime = SystemClock.elapsedRealtime();
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700381 mAffiliatedTaskId = _taskId;
382 voiceSession = null;
383 voiceInteractor = null;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700384 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800385 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700386 mCallingUid = info.applicationInfo.uid;
387 mCallingPackage = info.packageName;
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700388 setIntent(_intent, info);
Andrii Kulian2e751b82016-03-16 16:59:32 -0700389 setMinDimensions(info);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700390
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700391 isPersistable = true;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700392 // Clamp to [1, max].
393 maxRecents = Math.min(Math.max(info.maxRecents, 1),
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700394 ActivityTaskManager.getMaxAppRecentsLimitStatic());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700395
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700396 lastTaskDescription = _taskDescription;
Winson730bf062016-03-31 18:04:56 -0700397 touchActiveTime();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700398 mService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700399 }
400
Garfield Tan9b1efea2017-12-05 16:43:46 -0800401 /**
402 * Don't use constructor directly. This is only used by XML parser.
403 */
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700404 TaskRecord(ActivityTaskManagerService service, int _taskId, Intent _intent,
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800405 Intent _affinityIntent, String _affinity, String _rootAffinity,
406 ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700407 boolean _autoRemoveRecents, boolean _askedCompatMode, int _userId,
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800408 int _effectiveUid, String _lastDescription, ArrayList<ActivityRecord> activities,
Winson Chungfb44d212017-10-04 11:39:10 -0700409 long lastTimeMoved, boolean neverRelinquishIdentity,
410 TaskDescription _lastTaskDescription, int taskAffiliation, int prevTaskId,
411 int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage,
Charles He2bf28322017-10-12 22:24:49 +0100412 int resizeMode, boolean supportsPictureInPicture, boolean _realActivitySuspended,
413 boolean userSetupComplete, int minWidth, int minHeight) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700414 mService = service;
415 taskId = _taskId;
416 intent = _intent;
417 affinityIntent = _affinityIntent;
418 affinity = _affinity;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800419 rootAffinity = _rootAffinity;
Craig Mautner21d24a22014-04-23 11:45:37 -0700420 voiceSession = null;
421 voiceInteractor = null;
422 realActivity = _realActivity;
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800423 realActivitySuspended = _realActivitySuspended;
Craig Mautner21d24a22014-04-23 11:45:37 -0700424 origActivity = _origActivity;
425 rootWasReset = _rootWasReset;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700426 isAvailable = true;
Dianne Hackborn13420f22014-07-18 15:43:56 -0700427 autoRemoveRecents = _autoRemoveRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700428 askedCompatMode = _askedCompatMode;
Craig Mautner21d24a22014-04-23 11:45:37 -0700429 userId = _userId;
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800430 mUserSetupComplete = userSetupComplete;
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700431 effectiveUid = _effectiveUid;
Winson Chungfb44d212017-10-04 11:39:10 -0700432 lastActiveTime = SystemClock.elapsedRealtime();
Craig Mautner21d24a22014-04-23 11:45:37 -0700433 lastDescription = _lastDescription;
434 mActivities = activities;
435 mLastTimeMoved = lastTimeMoved;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700436 mNeverRelinquishIdentity = neverRelinquishIdentity;
Winson Chung2cb86c72014-06-25 12:03:30 -0700437 lastTaskDescription = _lastTaskDescription;
Craig Mautnera228ae92014-07-09 05:44:55 -0700438 mAffiliatedTaskId = taskAffiliation;
Winson Chungec396d62014-08-06 17:08:00 -0700439 mAffiliatedTaskColor = taskAffiliationColor;
Craig Mautnera228ae92014-07-09 05:44:55 -0700440 mPrevAffiliateTaskId = prevTaskId;
441 mNextAffiliateTaskId = nextTaskId;
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700442 mCallingUid = callingUid;
443 mCallingPackage = callingPackage;
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800444 mResizeMode = resizeMode;
Winson Chungd3395382016-12-13 11:49:09 -0800445 mSupportsPictureInPicture = supportsPictureInPicture;
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700446 mMinWidth = minWidth;
447 mMinHeight = minHeight;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700448 mService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800449 }
450
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800451 Task getTask() {
452 return mTask;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800453 }
454
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800455 void createTask(boolean onTop, boolean showForAllUsers) {
456 if (mTask != null) {
457 throw new IllegalArgumentException("mTask=" + mTask
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800458 + " already created for task=" + this);
459 }
460
461 final Rect bounds = updateOverrideConfigurationFromLaunchBounds();
Yunfan Chen279f5582018-12-12 15:24:50 -0800462 final TaskStack stack = getStack().getTaskStack();
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800463
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800464 if (stack == null) {
Yunfan Chen279f5582018-12-12 15:24:50 -0800465 throw new IllegalArgumentException("TaskRecord: invalid stack=" + mStack);
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800466 }
467 EventLog.writeEvent(WM_TASK_CREATED, taskId, stack.mStackId);
468 mTask = new Task(taskId, stack, userId, mService.mWindowManager, mResizeMode,
469 mSupportsPictureInPicture, lastTaskDescription, this);
470 final int position = onTop ? POSITION_TOP : POSITION_BOTTOM;
471
472 if (!mDisplayedBounds.isEmpty()) {
473 mTask.setOverrideDisplayedBounds(mDisplayedBounds);
474 }
475 // We only want to move the parents to the parents if we are creating this task at the
476 // top of its stack.
477 stack.addTask(mTask, position, showForAllUsers, onTop /* moveParents */);
Bryce Lee04ab3462017-04-10 15:06:33 -0700478 }
479
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800480 void setTask(Task task) {
481 mTask = task;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800482 }
483
Garfield Tan347bd602018-12-21 15:11:12 -0800484 void cleanUpResourcesForDestroy() {
485 if (!mActivities.isEmpty()) {
486 return;
487 }
488
489 // This task is going away, so save the last state if necessary.
490 saveLaunchingStateIfNeeded();
491
492 // TODO: VI what about activity?
493 final boolean isVoiceSession = voiceSession != null;
494 if (isVoiceSession) {
495 try {
496 voiceSession.taskFinished(intent, taskId);
497 } catch (RemoteException e) {
498 }
499 }
500 if (autoRemoveFromRecents() || isVoiceSession) {
501 // Task creator asked to remove this when done, or this task was a voice
502 // interaction, so it should not remain on the recent tasks list.
503 mService.mStackSupervisor.mRecentTasks.remove(this);
504 }
505
506 removeWindowContainer();
507 }
508
509 @VisibleForTesting
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800510 void removeWindowContainer() {
Bryce Lee2b8e0372018-04-05 17:01:37 -0700511 mService.getLockTaskController().clearLockedTask(this);
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800512 if (mTask == null) {
513 if (DEBUG_STACK) Slog.i(TAG_WM, "removeTask: could not find taskId=" + taskId);
514 return;
515 }
516 mTask.removeIfPossible();
517 mTask = null;
Wale Ogunwale3382ab12017-07-27 08:55:03 -0700518 if (!getWindowConfiguration().persistTaskBounds()) {
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800519 // Reset current bounds for task whose bounds shouldn't be persisted so it uses
520 // default configuration the next time it launches.
521 updateOverrideConfiguration(null);
522 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700523 mService.getTaskChangeNotificationController().notifyTaskRemoved(taskId);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800524 }
525
Jorim Jaggifb9d78a2017-01-05 18:57:12 +0100526 public void onSnapshotChanged(TaskSnapshot snapshot) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700527 mService.getTaskChangeNotificationController().notifyTaskSnapshotChanged(taskId, snapshot);
Jorim Jaggifb9d78a2017-01-05 18:57:12 +0100528 }
529
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800530 void setResizeMode(int resizeMode) {
531 if (mResizeMode == resizeMode) {
532 return;
533 }
534 mResizeMode = resizeMode;
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800535 mTask.setResizeable(resizeMode);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800536 mService.mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
537 mService.mRootActivityContainer.resumeFocusedStacksTopActivities();
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800538 }
539
540 void setTaskDockedResizing(boolean resizing) {
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800541 if (mTask == null) {
542 Slog.w(TAG_WM, "setTaskDockedResizing: taskId " + taskId + " not found.");
543 return;
544 }
545 mTask.setTaskDockedResizing(resizing);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800546 }
547
Wale Ogunwale1666e312016-12-16 11:27:18 -0800548 // TODO: Consolidate this with the resize() method below.
Wale Ogunwale1666e312016-12-16 11:27:18 -0800549 public void requestResize(Rect bounds, int resizeMode) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700550 mService.resizeTask(taskId, bounds, resizeMode);
Wale Ogunwale1666e312016-12-16 11:27:18 -0800551 }
552
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800553 boolean resize(Rect bounds, int resizeMode, boolean preserveWindow, boolean deferResume) {
Bryce Leef3c6a472017-11-14 14:53:06 -0800554 mService.mWindowManager.deferSurfaceLayout();
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800555
Bryce Leef3c6a472017-11-14 14:53:06 -0800556 try {
557 if (!isResizeable()) {
558 Slog.w(TAG, "resizeTask: task " + this + " not resizeable.");
559 return true;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800560 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800561
Bryce Leef3c6a472017-11-14 14:53:06 -0800562 // If this is a forced resize, let it go through even if the bounds is not changing,
563 // as we might need a relayout due to surface size change (to/from fullscreen).
564 final boolean forced = (resizeMode & RESIZE_MODE_FORCED) != 0;
Evan Roskydfe3da72018-10-26 17:21:06 -0700565 if (equivalentRequestedOverrideBounds(bounds) && !forced) {
Bryce Leef3c6a472017-11-14 14:53:06 -0800566 // Nothing to do here...
567 return true;
568 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800569
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800570 if (mTask == null) {
Bryce Leef3c6a472017-11-14 14:53:06 -0800571 // Task doesn't exist in window manager yet (e.g. was restored from recents).
572 // All we can do for now is update the bounds so it can be used when the task is
573 // added to window manager.
574 updateOverrideConfiguration(bounds);
575 if (!inFreeformWindowingMode()) {
576 // re-restore the task so it can have the proper stack association.
577 mService.mStackSupervisor.restoreRecentTaskLocked(this, null, !ON_TOP);
578 }
579 return true;
580 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800581
Bryce Leef3c6a472017-11-14 14:53:06 -0800582 if (!canResizeToBounds(bounds)) {
583 throw new IllegalArgumentException("resizeTask: Can not resize task=" + this
584 + " to bounds=" + bounds + " resizeMode=" + mResizeMode);
585 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800586
Bryce Leef3c6a472017-11-14 14:53:06 -0800587 // Do not move the task to another stack here.
588 // This method assumes that the task is already placed in the right stack.
589 // we do not mess with that decision and we only do the resize!
590
591 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeTask_" + taskId);
592
593 final boolean updatedConfig = updateOverrideConfiguration(bounds);
594 // This variable holds information whether the configuration didn't change in a significant
595
596 // way and the activity was kept the way it was. If it's false, it means the activity
597 // had
598 // to be relaunched due to configuration change.
599 boolean kept = true;
600 if (updatedConfig) {
601 final ActivityRecord r = topRunningActivityLocked();
602 if (r != null && !deferResume) {
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -0800603 kept = r.ensureActivityConfiguration(0 /* globalChanges */,
Bryce Leef3c6a472017-11-14 14:53:06 -0800604 preserveWindow);
Garfield Tanb9151182018-06-25 16:29:21 -0700605 // Preserve other windows for resizing because if resizing happens when there
606 // is a dialog activity in the front, the activity that still shows some
607 // content to the user will become black and cause flickers. Note in most cases
608 // this won't cause tons of irrelevant windows being preserved because only
609 // activities in this task may experience a bounds change. Configs for other
610 // activities stay the same.
Wale Ogunwaled32da472018-11-16 07:19:28 -0800611 mService.mRootActivityContainer.ensureActivitiesVisible(r, 0, preserveWindow);
Bryce Leef3c6a472017-11-14 14:53:06 -0800612 if (!kept) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800613 mService.mRootActivityContainer.resumeFocusedStacksTopActivities();
Bryce Leef3c6a472017-11-14 14:53:06 -0800614 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800615 }
616 }
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800617 mTask.resize(kept, forced);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800618
Garfield Tan891146c2018-10-09 12:14:00 -0700619 saveLaunchingStateIfNeeded();
620
Bryce Leef3c6a472017-11-14 14:53:06 -0800621 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
622 return kept;
623 } finally {
624 mService.mWindowManager.continueSurfaceLayout();
625 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800626 }
627
628 // TODO: Investigate combining with the resize() method above.
629 void resizeWindowContainer() {
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800630 mTask.resize(false /* relayout */, false /* forced */);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800631 }
632
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800633 void getWindowContainerBounds(Rect bounds) {
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800634 if (mTask != null) {
635 mTask.getBounds(bounds);
636 } else {
637 bounds.setEmpty();
638 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800639 }
640
Winson Chung74666102017-02-22 17:49:24 -0800641 /**
642 * Convenience method to reparent a task to the top or bottom position of the stack.
643 */
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700644 boolean reparent(ActivityStack preferredStack, boolean toTop,
645 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
646 String reason) {
647 return reparent(preferredStack, toTop ? MAX_VALUE : 0, moveStackMode, animate, deferResume,
648 true /* schedulePictureInPictureModeChange */, reason);
Winson Chung5af42fc2017-03-24 17:11:33 -0700649 }
650
651 /**
652 * Convenience method to reparent a task to the top or bottom position of the stack, with
653 * an option to skip scheduling the picture-in-picture mode change.
654 */
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700655 boolean reparent(ActivityStack preferredStack, boolean toTop,
656 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
657 boolean schedulePictureInPictureModeChange, String reason) {
658 return reparent(preferredStack, toTop ? MAX_VALUE : 0, moveStackMode, animate,
Winson Chung5af42fc2017-03-24 17:11:33 -0700659 deferResume, schedulePictureInPictureModeChange, reason);
660 }
661
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700662 /** Convenience method to reparent a task to a specific position of the stack. */
663 boolean reparent(ActivityStack preferredStack, int position,
664 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
665 String reason) {
666 return reparent(preferredStack, position, moveStackMode, animate, deferResume,
Winson Chung5af42fc2017-03-24 17:11:33 -0700667 true /* schedulePictureInPictureModeChange */, reason);
Winson Chung74666102017-02-22 17:49:24 -0800668 }
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800669
Winson Chung74666102017-02-22 17:49:24 -0800670 /**
671 * Reparents the task into a preferred stack, creating it if necessary.
672 *
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700673 * @param preferredStack the target stack to move this task
Winson Chung74666102017-02-22 17:49:24 -0800674 * @param position the position to place this task in the new stack
675 * @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 -0700676 * reparenting to be drawn and animated in
Winson Chung74666102017-02-22 17:49:24 -0800677 * @param moveStackMode whether or not to move the stack to the front always, only if it was
Winson Chung5af42fc2017-03-24 17:11:33 -0700678 * previously focused & in front, or never
Winson Chung74666102017-02-22 17:49:24 -0800679 * @param deferResume whether or not to update the visibility of other tasks and stacks that may
Winson Chung5af42fc2017-03-24 17:11:33 -0700680 * have changed as a result of this reparenting
681 * @param schedulePictureInPictureModeChange specifies whether or not to schedule the PiP mode
682 * change. Callers may set this to false if they are explicitly scheduling PiP mode
683 * changes themselves, like during the PiP animation
Winson Chung74666102017-02-22 17:49:24 -0800684 * @param reason the caller of this reparenting
Winson Chung5af42fc2017-03-24 17:11:33 -0700685 * @return whether the task was reparented
Winson Chung74666102017-02-22 17:49:24 -0800686 */
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700687 // TODO: Inspect all call sites and change to just changing windowing mode of the stack vs.
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700688 // re-parenting the task. Can only be done when we are no longer using static stack Ids.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700689 boolean reparent(ActivityStack preferredStack, int position,
690 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
691 boolean schedulePictureInPictureModeChange, String reason) {
Winson Chung74666102017-02-22 17:49:24 -0800692 final ActivityStackSupervisor supervisor = mService.mStackSupervisor;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800693 final RootActivityContainer root = mService.mRootActivityContainer;
Winson Chung74666102017-02-22 17:49:24 -0800694 final WindowManagerService windowManager = mService.mWindowManager;
695 final ActivityStack sourceStack = getStack();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700696 final ActivityStack toStack = supervisor.getReparentTargetStack(this, preferredStack,
Winson Chung74666102017-02-22 17:49:24 -0800697 position == MAX_VALUE);
698 if (toStack == sourceStack) {
699 return false;
700 }
Andrii Kulianb850ea52017-12-12 23:49:10 -0800701 if (!canBeLaunchedOnDisplay(toStack.mDisplayId)) {
702 return false;
703 }
Winson Chung74666102017-02-22 17:49:24 -0800704
Andrii Kulian6b321512019-01-23 06:37:00 +0000705 final boolean toTopOfStack = position == MAX_VALUE;
706 if (toTopOfStack && toStack.getResumedActivity() != null
707 && toStack.topRunningActivityLocked() != null) {
708 // Pause the resumed activity on the target stack while re-parenting task on top of it.
709 toStack.startPausingLocked(false /* userLeaving */, false /* uiSleeping */,
710 null /* resuming */, false /* pauseImmediately */);
711 }
712
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700713 final int toStackWindowingMode = toStack.getWindowingMode();
Winson Chung74666102017-02-22 17:49:24 -0800714 final ActivityRecord topActivity = getTopActivity();
715
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800716 final boolean mightReplaceWindow = topActivity != null
717 && replaceWindowsOnTaskMove(getWindowingMode(), toStackWindowingMode);
Winson Chung74666102017-02-22 17:49:24 -0800718 if (mightReplaceWindow) {
719 // We are about to relaunch the activity because its configuration changed due to
720 // being maximized, i.e. size change. The activity will first remove the old window
721 // and then add a new one. This call will tell window manager about this, so it can
722 // preserve the old window until the new one is drawn. This prevents having a gap
723 // between the removal and addition, in which no window is visible. We also want the
724 // entrance of the new window to be properly animated.
725 // Note here we always set the replacing window first, as the flags might be needed
726 // during the relaunch. If we end up not doing any relaunch, we clear the flags later.
727 windowManager.setWillReplaceWindow(topActivity.appToken, animate);
728 }
729
730 windowManager.deferSurfaceLayout();
731 boolean kept = true;
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800732 try {
Winson Chung74666102017-02-22 17:49:24 -0800733 final ActivityRecord r = topRunningActivityLocked();
Wale Ogunwaled32da472018-11-16 07:19:28 -0800734 final boolean wasFocused = r != null && root.isTopDisplayFocusedStack(sourceStack)
Winson Chung74666102017-02-22 17:49:24 -0800735 && (topRunningActivityLocked() == r);
Bryce Leec4ab62a2018-03-05 14:19:26 -0800736 final boolean wasResumed = r != null && sourceStack.getResumedActivity() == r;
Winson Chung95f8f0e2017-03-24 09:20:17 -0700737 final boolean wasPaused = r != null && sourceStack.mPausingActivity == r;
Winson Chung74666102017-02-22 17:49:24 -0800738
739 // In some cases the focused stack isn't the front stack. E.g. pinned stack.
740 // Whenever we are moving the top activity from the front stack we want to make sure to
741 // move the stack to the front.
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -0700742 final boolean wasFront = r != null && sourceStack.isTopStackOnDisplay()
Winson Chung74666102017-02-22 17:49:24 -0800743 && (sourceStack.topRunningActivityLocked() == r);
744
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800745 // Adjust the position for the new parent stack as needed.
Winson Chung74666102017-02-22 17:49:24 -0800746 position = toStack.getAdjustedPositionForTask(this, position, null /* starting */);
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800747
748 // Must reparent first in window manager to avoid a situation where AM can delete the
749 // we are coming from in WM before we reparent because it became empty.
Yunfan Chen279f5582018-12-12 15:24:50 -0800750 mTask.reparent(toStack.getTaskStack(), position,
Wale Ogunwale2719cc12017-04-14 09:45:27 -0700751 moveStackMode == REPARENT_MOVE_STACK_TO_FRONT);
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800752
Wale Ogunwale56d8d162017-05-30 11:12:20 -0700753 final boolean moveStackToFront = moveStackMode == REPARENT_MOVE_STACK_TO_FRONT
754 || (moveStackMode == REPARENT_KEEP_STACK_AT_FRONT && (wasFocused || wasFront));
Winson Chung74666102017-02-22 17:49:24 -0800755 // Move the task
Wale Ogunwale56d8d162017-05-30 11:12:20 -0700756 sourceStack.removeTask(this, reason, moveStackToFront
757 ? REMOVE_TASK_MODE_MOVING_TO_TOP : REMOVE_TASK_MODE_MOVING);
Winson Chung5af42fc2017-03-24 17:11:33 -0700758 toStack.addTask(this, position, false /* schedulePictureInPictureModeChange */, reason);
Winson Chung74666102017-02-22 17:49:24 -0800759
Winson Chung5af42fc2017-03-24 17:11:33 -0700760 if (schedulePictureInPictureModeChange) {
761 // Notify of picture-in-picture mode changes
762 supervisor.scheduleUpdatePictureInPictureModeIfNeeded(this, sourceStack);
763 }
Winson Chung74666102017-02-22 17:49:24 -0800764
765 // TODO: Ensure that this is actually necessary here
766 // Notify the voice session if required
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800767 if (voiceSession != null) {
768 try {
769 voiceSession.taskStarted(intent, taskId);
770 } catch (RemoteException e) {
771 }
772 }
Winson Chung74666102017-02-22 17:49:24 -0800773
774 // If the task had focus before (or we're requested to move focus), move focus to the
775 // new stack by moving the stack to the front.
Winson Chung95f8f0e2017-03-24 09:20:17 -0700776 if (r != null) {
777 toStack.moveToFrontAndResumeStateIfNeeded(r, moveStackToFront, wasResumed,
778 wasPaused, reason);
779 }
Winson Chung74666102017-02-22 17:49:24 -0800780 if (!animate) {
Jorim Jaggifa9ed962018-01-25 00:16:49 +0100781 mService.mStackSupervisor.mNoAnimActivities.add(topActivity);
Winson Chung74666102017-02-22 17:49:24 -0800782 }
783
784 // We might trigger a configuration change. Save the current task bounds for freezing.
785 // TODO: Should this call be moved inside the resize method in WM?
786 toStack.prepareFreezingTaskBounds();
787
788 // Make sure the task has the appropriate bounds/size for the stack it is in.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700789 final boolean toStackSplitScreenPrimary =
790 toStackWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Evan Roskydfe3da72018-10-26 17:21:06 -0700791 final Rect configBounds = getRequestedOverrideBounds();
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700792 if ((toStackWindowingMode == WINDOWING_MODE_FULLSCREEN
793 || toStackWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY)
Evan Roskydfe3da72018-10-26 17:21:06 -0700794 && !Objects.equals(configBounds, toStack.getRequestedOverrideBounds())) {
795 kept = resize(toStack.getRequestedOverrideBounds(), RESIZE_MODE_SYSTEM,
796 !mightReplaceWindow, deferResume);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700797 } else if (toStackWindowingMode == WINDOWING_MODE_FREEFORM) {
Winson Chung74666102017-02-22 17:49:24 -0800798 Rect bounds = getLaunchBounds();
799 if (bounds == null) {
Bryce Leeec55eb02017-12-05 20:51:27 -0800800 mService.mStackSupervisor.getLaunchParamsController().layoutTask(this, null);
Bryce Leef3c6a472017-11-14 14:53:06 -0800801 bounds = configBounds;
Winson Chung74666102017-02-22 17:49:24 -0800802 }
803 kept = resize(bounds, RESIZE_MODE_FORCED, !mightReplaceWindow, deferResume);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700804 } else if (toStackSplitScreenPrimary || toStackWindowingMode == WINDOWING_MODE_PINNED) {
805 if (toStackSplitScreenPrimary && moveStackMode == REPARENT_KEEP_STACK_AT_FRONT) {
Matthew Ng330757d2017-02-28 14:19:17 -0800806 // Move recents to front so it is not behind home stack when going into docked
807 // mode
808 mService.mStackSupervisor.moveRecentsStackToFront(reason);
809 }
Evan Roskydfe3da72018-10-26 17:21:06 -0700810 kept = resize(toStack.getRequestedOverrideBounds(), RESIZE_MODE_SYSTEM,
811 !mightReplaceWindow, deferResume);
Winson Chung74666102017-02-22 17:49:24 -0800812 }
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800813 } finally {
Winson Chung74666102017-02-22 17:49:24 -0800814 windowManager.continueSurfaceLayout();
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800815 }
Winson Chung74666102017-02-22 17:49:24 -0800816
817 if (mightReplaceWindow) {
818 // If we didn't actual do a relaunch (indicated by kept==true meaning we kept the old
819 // window), we need to clear the replace window settings. Otherwise, we schedule a
820 // timeout to remove the old window if the replacing window is not coming in time.
821 windowManager.scheduleClearWillReplaceWindows(topActivity.appToken, !kept);
822 }
823
824 if (!deferResume) {
825 // The task might have already been running and its visibility needs to be synchronized
826 // with the visibility of the stack / windows.
Wale Ogunwaled32da472018-11-16 07:19:28 -0800827 root.ensureActivitiesVisible(null, 0, !mightReplaceWindow);
828 root.resumeFocusedStacksTopActivities();
Winson Chung74666102017-02-22 17:49:24 -0800829 }
830
Andrii Kulian036e3ad2017-04-19 10:55:10 -0700831 // TODO: Handle incorrect request to move before the actual move, not after.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700832 supervisor.handleNonResizableTaskIfNeeded(this, preferredStack.getWindowingMode(),
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -0700833 DEFAULT_DISPLAY, toStack);
Winson Chung74666102017-02-22 17:49:24 -0800834
Winson Chungdff7a732017-12-11 12:17:06 -0800835 return (preferredStack == toStack);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800836 }
837
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700838 /**
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800839 * @return True if the windows of tasks being moved to the target stack from the source stack
840 * should be replaced, meaning that window manager will keep the old window around until the new
841 * is ready.
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700842 */
843 private static boolean replaceWindowsOnTaskMove(
844 int sourceWindowingMode, int targetWindowingMode) {
845 return sourceWindowingMode == WINDOWING_MODE_FREEFORM
846 || targetWindowingMode == WINDOWING_MODE_FREEFORM;
847 }
848
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800849 void cancelWindowTransition() {
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800850 if (mTask == null) {
851 Slog.w(TAG_WM, "cancelWindowTransition: taskId " + taskId + " not found.");
852 return;
853 }
854 mTask.cancelTaskWindowTransition();
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800855 }
856
Jorim Jaggi7361bab2017-01-16 17:17:58 +0100857 /**
858 * DO NOT HOLD THE ACTIVITY MANAGER LOCK WHEN CALLING THIS METHOD!
859 */
Jorim Jaggi35e3f532017-03-17 17:06:50 +0100860 TaskSnapshot getSnapshot(boolean reducedResolution) {
Jorim Jaggi7361bab2017-01-16 17:17:58 +0100861
862 // TODO: Move this to {@link TaskWindowContainerController} once recent tasks are more
863 // synchronized between AM and WM.
Jorim Jaggi35e3f532017-03-17 17:06:50 +0100864 return mService.mWindowManager.getTaskSnapshot(taskId, userId, reducedResolution);
Jorim Jaggi02886a82016-12-06 09:10:06 -0800865 }
866
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800867 void touchActiveTime() {
Winson Chungfb44d212017-10-04 11:39:10 -0700868 lastActiveTime = SystemClock.elapsedRealtime();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800869 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700870
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800871 long getInactiveDuration() {
Winson Chungfb44d212017-10-04 11:39:10 -0700872 return SystemClock.elapsedRealtime() - lastActiveTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800873 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700874
Winson Chungfee26772014-08-05 12:21:52 -0700875 /** Sets the original intent, and the calling uid and package. */
876 void setIntent(ActivityRecord r) {
Winson Chungfee26772014-08-05 12:21:52 -0700877 mCallingUid = r.launchedFromUid;
878 mCallingPackage = r.launchedFromPackage;
Craig Mautner15df08a2015-04-01 12:17:18 -0700879 setIntent(r.intent, r.info);
Charles He2bf28322017-10-12 22:24:49 +0100880 setLockTaskAuth(r);
Winson Chungfee26772014-08-05 12:21:52 -0700881 }
882
883 /** Sets the original intent, _without_ updating the calling uid or package. */
884 private void setIntent(Intent _intent, ActivityInfo info) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700885 if (intent == null) {
886 mNeverRelinquishIdentity =
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700887 (info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700888 } else if (mNeverRelinquishIdentity) {
889 return;
890 }
891
892 affinity = info.taskAffinity;
Dianne Hackborn79228822014-09-16 11:11:23 -0700893 if (intent == null) {
894 // If this task already has an intent associated with it, don't set the root
895 // affinity -- we don't want it changing after initially set, but the initially
896 // set value may be null.
897 rootAffinity = affinity;
898 }
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700899 effectiveUid = info.applicationInfo.uid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700900 stringName = null;
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800901
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800902 if (info.targetActivity == null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800903 if (_intent != null) {
904 // If this Intent has a selector, we want to clear it for the
905 // recent task since it is not relevant if the user later wants
906 // to re-launch the app.
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700907 if (_intent.getSelector() != null || _intent.getSourceBounds() != null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800908 _intent = new Intent(_intent);
909 _intent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700910 _intent.setSourceBounds(null);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800911 }
912 }
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700913 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Setting Intent of " + this + " to " + _intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800914 intent = _intent;
915 realActivity = _intent != null ? _intent.getComponent() : null;
916 origActivity = null;
917 } else {
918 ComponentName targetComponent = new ComponentName(
919 info.packageName, info.targetActivity);
920 if (_intent != null) {
921 Intent targetIntent = new Intent(_intent);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800922 targetIntent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700923 targetIntent.setSourceBounds(null);
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700924 if (DEBUG_TASKS) Slog.v(TAG_TASKS,
Dianne Hackborn7f96b792012-05-29 18:46:45 -0700925 "Setting Intent of " + this + " to target " + targetIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800926 intent = targetIntent;
927 realActivity = targetComponent;
928 origActivity = _intent.getComponent();
929 } else {
930 intent = null;
931 realActivity = targetComponent;
932 origActivity = new ComponentName(info.packageName, info.name);
933 }
934 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700935
Craig Mautner47b20ba2014-09-17 17:23:44 -0700936 final int intentFlags = intent == null ? 0 : intent.getFlags();
937 if ((intentFlags & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800938 // Once we are set to an Intent with this flag, we count this
939 // task as having a true root activity.
940 rootWasReset = true;
941 }
Dianne Hackborn09233282014-04-30 11:33:59 -0700942 userId = UserHandle.getUserId(info.applicationInfo.uid);
Winson Chung36f3f032016-09-08 23:29:43 +0000943 mUserSetupComplete = Settings.Secure.getIntForUser(mService.mContext.getContentResolver(),
944 USER_SETUP_COMPLETE, 0, userId) != 0;
Craig Mautner41db4a72014-05-07 17:20:56 -0700945 if ((info.flags & ActivityInfo.FLAG_AUTO_REMOVE_FROM_RECENTS) != 0) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700946 // If the activity itself has requested auto-remove, then just always do it.
947 autoRemoveRecents = true;
Wale Ogunwale843bfb92015-03-27 11:06:48 -0700948 } else if ((intentFlags & (FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS))
949 == FLAG_ACTIVITY_NEW_DOCUMENT) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700950 // If the caller has not asked for the document to be retained, then we may
951 // want to turn on auto-remove, depending on whether the target has set its
952 // own document launch mode.
953 if (info.documentLaunchMode != ActivityInfo.DOCUMENT_LAUNCH_NONE) {
954 autoRemoveRecents = false;
955 } else {
956 autoRemoveRecents = true;
957 }
958 } else {
959 autoRemoveRecents = false;
Craig Mautner41db4a72014-05-07 17:20:56 -0700960 }
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800961 mResizeMode = info.resizeMode;
Winson Chungd3395382016-12-13 11:49:09 -0800962 mSupportsPictureInPicture = info.supportsPictureInPicture();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800963 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800964
Andrii Kulian2e751b82016-03-16 16:59:32 -0700965 /** Sets the original minimal width and height. */
966 private void setMinDimensions(ActivityInfo info) {
967 if (info != null && info.windowLayout != null) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700968 mMinWidth = info.windowLayout.minWidth;
969 mMinHeight = info.windowLayout.minHeight;
Andrii Kulian2e751b82016-03-16 16:59:32 -0700970 } else {
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700971 mMinWidth = INVALID_MIN_SIZE;
972 mMinHeight = INVALID_MIN_SIZE;
Andrii Kulian2e751b82016-03-16 16:59:32 -0700973 }
974 }
975
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800976 /**
Andrii Kulian206b9fa2016-06-02 13:18:01 -0700977 * Return true if the input activity has the same intent filter as the intent this task
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800978 * record is based on (normally the root activity intent).
979 */
Andrii Kulian206b9fa2016-06-02 13:18:01 -0700980 boolean isSameIntentFilter(ActivityRecord r) {
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800981 final Intent intent = new Intent(r.intent);
Louis Chang23df1a62019-01-09 15:10:49 +0800982 // Make sure the component are the same if the input activity has the same real activity
983 // as the one in the task because either one of them could be the alias activity.
984 if (Objects.equals(realActivity, r.mActivityComponent) && this.intent != null) {
985 intent.setComponent(this.intent.getComponent());
986 }
Bryce Lee1a990e52018-04-23 10:54:11 -0700987 return intent.filterEquals(this.intent);
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800988 }
989
Wale Ogunwale66e16852017-10-19 13:35:52 -0700990 boolean returnsToHomeStack() {
991 final int returnHomeFlags = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME;
Bryce Lee1a990e52018-04-23 10:54:11 -0700992 return intent != null && (intent.getFlags() & returnHomeFlags) == returnHomeFlags;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700993 }
994
Craig Mautnera228ae92014-07-09 05:44:55 -0700995 void setPrevAffiliate(TaskRecord prevAffiliate) {
996 mPrevAffiliate = prevAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800997 mPrevAffiliateTaskId = prevAffiliate == null ? INVALID_TASK_ID : prevAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700998 }
999
1000 void setNextAffiliate(TaskRecord nextAffiliate) {
1001 mNextAffiliate = nextAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -08001002 mNextAffiliateTaskId = nextAffiliate == null ? INVALID_TASK_ID : nextAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -07001003 }
1004
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001005 <T extends ActivityStack> T getStack() {
1006 return (T) mStack;
Andrii Kulian02b7a832016-10-06 23:11:56 -07001007 }
1008
Andrii Kulianfb1bf692017-01-17 11:17:34 -08001009 /**
1010 * Must be used for setting parent stack because it performs configuration updates.
1011 * Must be called after adding task as a child to the stack.
1012 */
Andrii Kulian02b7a832016-10-06 23:11:56 -07001013 void setStack(ActivityStack stack) {
Andrii Kulianfb1bf692017-01-17 11:17:34 -08001014 if (stack != null && !stack.isInStackLocked(this)) {
1015 throw new IllegalStateException("Task must be added as a Stack child first.");
1016 }
Bryce Lee84730a02018-04-03 14:10:04 -07001017 final ActivityStack oldStack = mStack;
Andrii Kulian02b7a832016-10-06 23:11:56 -07001018 mStack = stack;
Bryce Lee84730a02018-04-03 14:10:04 -07001019
1020 // If the new {@link TaskRecord} is from a different {@link ActivityStack}, remove this
1021 // {@link ActivityRecord} from its current {@link ActivityStack}.
1022
1023 if (oldStack != mStack) {
1024 for (int i = getChildCount() - 1; i >= 0; --i) {
1025 final ActivityRecord activity = getChildAt(i);
1026
1027 if (oldStack != null) {
1028 oldStack.onActivityRemovedFromStack(activity);
1029 }
1030
1031 if (mStack != null) {
1032 stack.onActivityAddedToStack(activity);
1033 }
1034 }
1035 }
1036
Andrii Kulian1779e612016-10-12 21:58:25 -07001037 onParentChanged();
Andrii Kulian02b7a832016-10-06 23:11:56 -07001038 }
1039
1040 /**
1041 * @return Id of current stack, {@link INVALID_STACK_ID} if no stack is set.
1042 */
1043 int getStackId() {
1044 return mStack != null ? mStack.mStackId : INVALID_STACK_ID;
1045 }
1046
Andrii Kulian1779e612016-10-12 21:58:25 -07001047 @Override
1048 protected int getChildCount() {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07001049 return mActivities.size();
Andrii Kulian1779e612016-10-12 21:58:25 -07001050 }
1051
1052 @Override
chaviw82a0ba82018-03-15 14:26:29 -07001053 protected ActivityRecord getChildAt(int index) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07001054 return mActivities.get(index);
Andrii Kulian1779e612016-10-12 21:58:25 -07001055 }
1056
1057 @Override
1058 protected ConfigurationContainer getParent() {
1059 return mStack;
1060 }
1061
Andrii Kulianfb1bf692017-01-17 11:17:34 -08001062 @Override
Wale Ogunwale98d62312017-07-12 09:24:56 -07001063 protected void onParentChanged() {
Andrii Kulianfb1bf692017-01-17 11:17:34 -08001064 super.onParentChanged();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001065 mService.mRootActivityContainer.updateUIDsPresentOnDisplay();
Andrii Kulianfb1bf692017-01-17 11:17:34 -08001066 }
1067
Craig Mautnera228ae92014-07-09 05:44:55 -07001068 // Close up recents linked list.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07001069 private void closeRecentsChain() {
Craig Mautnera228ae92014-07-09 05:44:55 -07001070 if (mPrevAffiliate != null) {
1071 mPrevAffiliate.setNextAffiliate(mNextAffiliate);
1072 }
1073 if (mNextAffiliate != null) {
1074 mNextAffiliate.setPrevAffiliate(mPrevAffiliate);
1075 }
1076 setPrevAffiliate(null);
1077 setNextAffiliate(null);
1078 }
1079
Winson Chung740c3ac2014-11-12 16:14:38 -08001080 void removedFromRecents() {
Dianne Hackborn852975d2014-08-22 17:42:43 -07001081 closeRecentsChain();
1082 if (inRecents) {
1083 inRecents = false;
Winson Chung740c3ac2014-11-12 16:14:38 -08001084 mService.notifyTaskPersisterLocked(this, false);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001085 }
Jorim Jaggif9084ec2017-01-16 13:16:59 +01001086
Dianne Hackborn68a06332017-11-15 17:54:18 -08001087 clearRootProcess();
1088
Jorim Jaggif9084ec2017-01-16 13:16:59 +01001089 // TODO: Use window container controller once tasks are better synced between AM and WM
1090 mService.mWindowManager.notifyTaskRemovedFromRecents(taskId, userId);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001091 }
1092
Craig Mautnera228ae92014-07-09 05:44:55 -07001093 void setTaskToAffiliateWith(TaskRecord taskToAffiliateWith) {
1094 closeRecentsChain();
1095 mAffiliatedTaskId = taskToAffiliateWith.mAffiliatedTaskId;
Winson Chungec396d62014-08-06 17:08:00 -07001096 mAffiliatedTaskColor = taskToAffiliateWith.mAffiliatedTaskColor;
Craig Mautnera228ae92014-07-09 05:44:55 -07001097 // Find the end
1098 while (taskToAffiliateWith.mNextAffiliate != null) {
1099 final TaskRecord nextRecents = taskToAffiliateWith.mNextAffiliate;
1100 if (nextRecents.mAffiliatedTaskId != mAffiliatedTaskId) {
1101 Slog.e(TAG, "setTaskToAffiliateWith: nextRecents=" + nextRecents + " affilTaskId="
1102 + nextRecents.mAffiliatedTaskId + " should be " + mAffiliatedTaskId);
1103 if (nextRecents.mPrevAffiliate == taskToAffiliateWith) {
1104 nextRecents.setPrevAffiliate(null);
1105 }
1106 taskToAffiliateWith.setNextAffiliate(null);
1107 break;
1108 }
1109 taskToAffiliateWith = nextRecents;
1110 }
1111 taskToAffiliateWith.setNextAffiliate(this);
1112 setPrevAffiliate(taskToAffiliateWith);
1113 setNextAffiliate(null);
1114 }
1115
Winson Chung1147c402014-05-14 11:05:00 -07001116 /** Returns the intent for the root activity for this task */
1117 Intent getBaseIntent() {
1118 return intent != null ? intent : affinityIntent;
1119 }
1120
Winson Chung3b3f4642014-04-22 10:08:18 -07001121 /** Returns the first non-finishing activity from the root. */
1122 ActivityRecord getRootActivity() {
1123 for (int i = 0; i < mActivities.size(); i++) {
1124 final ActivityRecord r = mActivities.get(i);
1125 if (r.finishing) {
1126 continue;
1127 }
1128 return r;
1129 }
1130 return null;
1131 }
1132
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001133 ActivityRecord getTopActivity() {
Bryce Lee9f6affd2017-09-01 09:18:35 -07001134 return getTopActivity(true /* includeOverlays */);
1135 }
1136
1137 ActivityRecord getTopActivity(boolean includeOverlays) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001138 for (int i = mActivities.size() - 1; i >= 0; --i) {
1139 final ActivityRecord r = mActivities.get(i);
Bryce Lee9f6affd2017-09-01 09:18:35 -07001140 if (r.finishing || (!includeOverlays && r.mTaskOverlay)) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001141 continue;
1142 }
1143 return r;
1144 }
1145 return null;
1146 }
1147
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -07001148 ActivityRecord topRunningActivityLocked() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001149 if (mStack != null) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07001150 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1151 ActivityRecord r = mActivities.get(activityNdx);
Chong Zhang87761972016-08-22 13:53:24 -07001152 if (!r.finishing && r.okToShowLocked()) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07001153 return r;
1154 }
Craig Mautner6b74cb52013-09-27 17:02:21 -07001155 }
1156 }
1157 return null;
1158 }
1159
Jorim Jaggi172e99f2017-10-20 14:33:18 +02001160 boolean isVisible() {
1161 for (int i = mActivities.size() - 1; i >= 0; --i) {
1162 final ActivityRecord r = mActivities.get(i);
1163 if (r.visible) {
1164 return true;
1165 }
1166 }
1167 return false;
1168 }
1169
Jorim Jaggiea039a82017-08-02 14:37:49 +02001170 void getAllRunningVisibleActivitiesLocked(ArrayList<ActivityRecord> outActivities) {
1171 if (mStack != null) {
1172 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1173 ActivityRecord r = mActivities.get(activityNdx);
Jorim Jaggi02f1d2f2017-08-04 14:29:16 +02001174 if (!r.finishing && r.okToShowLocked() && r.visibleIgnoringKeyguard) {
Jorim Jaggiea039a82017-08-02 14:37:49 +02001175 outActivities.add(r);
1176 }
1177 }
1178 }
1179 }
1180
Wale Ogunwale3b232392016-05-13 15:37:13 -07001181 ActivityRecord topRunningActivityWithStartingWindowLocked() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001182 if (mStack != null) {
Wale Ogunwale3b232392016-05-13 15:37:13 -07001183 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1184 ActivityRecord r = mActivities.get(activityNdx);
1185 if (r.mStartingWindowState != STARTING_WINDOW_SHOWN
Chong Zhang87761972016-08-22 13:53:24 -07001186 || r.finishing || !r.okToShowLocked()) {
Wale Ogunwale3b232392016-05-13 15:37:13 -07001187 continue;
1188 }
1189 return r;
1190 }
1191 }
1192 return null;
1193 }
1194
Winson Chung61c9e5a2017-10-11 10:39:32 -07001195 /**
1196 * Return the number of running activities, and the number of non-finishing/initializing
1197 * activities in the provided {@param reportOut} respectively.
1198 */
1199 void getNumRunningActivities(TaskActivitiesReport reportOut) {
1200 reportOut.reset();
1201 for (int i = mActivities.size() - 1; i >= 0; --i) {
1202 final ActivityRecord r = mActivities.get(i);
1203 if (r.finishing) {
1204 continue;
1205 }
1206
1207 reportOut.base = r;
1208
1209 // Increment the total number of non-finishing activities
1210 reportOut.numActivities++;
1211
Bryce Lee7ace3952018-02-16 14:34:32 -08001212 if (reportOut.top == null || (reportOut.top.isState(ActivityState.INITIALIZING))) {
Winson Chung61c9e5a2017-10-11 10:39:32 -07001213 reportOut.top = r;
1214 // Reset the number of running activities until we hit the first non-initializing
1215 // activity
1216 reportOut.numRunning = 0;
1217 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001218 if (r.attachedToProcess()) {
Winson Chung61c9e5a2017-10-11 10:39:32 -07001219 // Increment the number of actually running activities
1220 reportOut.numRunning++;
1221 }
1222 }
1223 }
1224
Chong Zhang87761972016-08-22 13:53:24 -07001225 boolean okToShowLocked() {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001226 // NOTE: If {@link TaskRecord#topRunningActivity} return is not null then it is
Chong Zhang87761972016-08-22 13:53:24 -07001227 // okay to show the activity when locked.
1228 return mService.mStackSupervisor.isCurrentProfileLocked(userId)
1229 || topRunningActivityLocked() != null;
1230 }
1231
Craig Mautner3b475fe2013-12-16 15:58:31 -08001232 /** Call after activity movement or finish to make sure that frontOfTask is set correctly */
Bryce Leed71317c2017-02-07 14:27:22 -08001233 final void setFrontOfTask() {
1234 boolean foundFront = false;
Craig Mautner3b475fe2013-12-16 15:58:31 -08001235 final int numActivities = mActivities.size();
Craig Mautner704e40b2013-12-18 16:43:51 -08001236 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
Craig Mautner3b475fe2013-12-16 15:58:31 -08001237 final ActivityRecord r = mActivities.get(activityNdx);
1238 if (foundFront || r.finishing) {
1239 r.frontOfTask = false;
1240 } else {
1241 r.frontOfTask = true;
1242 // Set frontOfTask false for every following activity.
1243 foundFront = true;
1244 }
1245 }
Craig Mautner9587ee02014-06-23 15:00:10 +00001246 if (!foundFront && numActivities > 0) {
1247 // All activities of this task are finishing. As we ought to have a frontOfTask
1248 // activity, make the bottom activity front.
1249 mActivities.get(0).frontOfTask = true;
1250 }
Craig Mautner3b475fe2013-12-16 15:58:31 -08001251 }
1252
Craig Mautnerde4ef022013-04-07 19:01:33 -07001253 /**
Craig Mautner3b475fe2013-12-16 15:58:31 -08001254 * Reorder the history stack so that the passed activity is brought to the front.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001255 */
1256 final void moveActivityToFrontLocked(ActivityRecord newTop) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07001257 if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE,
1258 "Removing and adding activity " + newTop
1259 + " to stack at top callers=" + Debug.getCallers(4));
Craig Mautnerde4ef022013-04-07 19:01:33 -07001260
Craig Mautnerde4ef022013-04-07 19:01:33 -07001261 mActivities.remove(newTop);
1262 mActivities.add(newTop);
Bryce Leed58d7b32017-09-08 15:55:22 -07001263
1264 // Make sure window manager is aware of the position change.
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001265 mTask.positionChildAtTop(newTop.mAppWindowToken);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001266 updateEffectiveIntent();
Craig Mautner3b475fe2013-12-16 15:58:31 -08001267
Bryce Leed71317c2017-02-07 14:27:22 -08001268 setFrontOfTask();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001269 }
1270
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001271 void addActivityToTop(ActivityRecord r) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001272 addActivityAtIndex(mActivities.size(), r);
1273 }
1274
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001275 @Override
Wale Ogunwaleeea34ee92017-08-31 20:07:45 -07001276 /*@WindowConfiguration.ActivityType*/
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001277 public int getActivityType() {
1278 final int applicationType = super.getActivityType();
1279 if (applicationType != ACTIVITY_TYPE_UNDEFINED || mActivities.isEmpty()) {
1280 return applicationType;
1281 }
1282 return mActivities.get(0).getActivityType();
1283 }
1284
Winson Chung30480042017-01-26 10:55:34 -08001285 /**
Evan Rosky130d94f2019-01-15 10:18:17 -08001286 * Checks if the top activity requires a particular orientation (either by override or
Evan Rosky730f6e82018-12-03 17:40:11 -08001287 * activityInfo) and returns that. Otherwise, this returns ORIENTATION_UNDEFINED.
1288 */
Evan Rosky130d94f2019-01-15 10:18:17 -08001289 private int getTopActivityRequestedOrientation() {
1290 ActivityRecord top = getTopActivity();
Evan Rosky730f6e82018-12-03 17:40:11 -08001291 if (getRequestedOverrideConfiguration().orientation != ORIENTATION_UNDEFINED
Evan Rosky130d94f2019-01-15 10:18:17 -08001292 || top == null) {
Evan Rosky730f6e82018-12-03 17:40:11 -08001293 return getRequestedOverrideConfiguration().orientation;
1294 }
Riddle Hsu0a343c32018-12-21 00:40:48 +08001295 return top.getRequestedConfigurationOrientation();
Evan Rosky730f6e82018-12-03 17:40:11 -08001296 }
1297
1298 /**
Winson Chung30480042017-01-26 10:55:34 -08001299 * Adds an activity {@param r} at the given {@param index}. The activity {@param r} must either
1300 * be in the current task or unparented to any task.
1301 */
Craig Mautner1602ec22013-05-12 10:24:27 -07001302 void addActivityAtIndex(int index, ActivityRecord r) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001303 TaskRecord task = r.getTaskRecord();
Bryce Leeaf691c02017-03-20 14:20:22 -07001304 if (task != null && task != this) {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001305 throw new IllegalArgumentException("Can not add r=" + " to task=" + this
Bryce Leeaf691c02017-03-20 14:20:22 -07001306 + " current parent=" + task);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001307 }
Bryce Leeaf691c02017-03-20 14:20:22 -07001308
1309 r.setTask(this);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001310
Craig Mautner6170f732013-04-02 13:05:23 -07001311 // 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 -08001312 if (!mActivities.remove(r) && r.fullscreen) {
1313 // Was not previously in list.
1314 numFullscreen++;
1315 }
Craig Mautner2c1faed2013-07-23 12:56:02 -07001316 // Only set this based on the first activity
1317 if (mActivities.isEmpty()) {
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001318 if (r.getActivityType() == ACTIVITY_TYPE_UNDEFINED) {
1319 // Normally non-standard activity type for the activity record will be set when the
1320 // object is created, however we delay setting the standard application type until
1321 // this point so that the task can set the type for additional activities added in
1322 // the else condition below.
1323 r.setActivityType(ACTIVITY_TYPE_STANDARD);
1324 }
1325 setActivityType(r.getActivityType());
Craig Mautner21d24a22014-04-23 11:45:37 -07001326 isPersistable = r.isPersistable();
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001327 mCallingUid = r.launchedFromUid;
1328 mCallingPackage = r.launchedFromPackage;
Dianne Hackborn852975d2014-08-22 17:42:43 -07001329 // Clamp to [1, max].
1330 maxRecents = Math.min(Math.max(r.info.maxRecents, 1),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001331 ActivityTaskManager.getMaxAppRecentsLimitStatic());
Craig Mautner2c1faed2013-07-23 12:56:02 -07001332 } else {
1333 // Otherwise make all added activities match this one.
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001334 r.setActivityType(getActivityType());
Craig Mautner78733002013-06-10 13:54:49 -07001335 }
Wale Ogunwale3b232392016-05-13 15:37:13 -07001336
1337 final int size = mActivities.size();
1338
1339 if (index == size && size > 0) {
1340 final ActivityRecord top = mActivities.get(size - 1);
1341 if (top.mTaskOverlay) {
1342 // Place below the task overlay activity since the overlay activity should always
1343 // be on top.
1344 index--;
1345 }
1346 }
1347
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001348 index = Math.min(size, index);
Craig Mautner77878772013-03-04 19:46:24 -08001349 mActivities.add(index, r);
Bryce Lee84730a02018-04-03 14:10:04 -07001350
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001351 updateEffectiveIntent();
Craig Mautner21d24a22014-04-23 11:45:37 -07001352 if (r.isPersistable()) {
1353 mService.notifyTaskPersisterLocked(this, false);
1354 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001355
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001356 if (r.mAppWindowToken != null) {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001357 // Only attempt to move in WM if the child has a controller. It is possible we haven't
1358 // created controller for the activity we are starting yet.
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001359 mTask.positionChildAt(r.mAppWindowToken, index);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001360 }
David Stevens82ea6cb2017-03-03 16:18:50 -08001361
1362 // Make sure the list of display UID whitelists is updated
1363 // now that this record is in a new task.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001364 mService.mRootActivityContainer.updateUIDsPresentOnDisplay();
Craig Mautner77878772013-03-04 19:46:24 -08001365 }
1366
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001367 /**
Bryce Leeaf691c02017-03-20 14:20:22 -07001368 * Removes the specified activity from this task.
1369 * @param r The {@link ActivityRecord} to remove.
1370 * @return true if this was the last activity in the task.
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001371 */
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001372 boolean removeActivity(ActivityRecord r) {
Bryce Lee84730a02018-04-03 14:10:04 -07001373 return removeActivity(r, false /* reparenting */);
Bryce Leeaf691c02017-03-20 14:20:22 -07001374 }
1375
1376 boolean removeActivity(ActivityRecord r, boolean reparenting) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001377 if (r.getTaskRecord() != this) {
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001378 throw new IllegalArgumentException(
1379 "Activity=" + r + " does not belong to task=" + this);
1380 }
1381
Bryce Lee84730a02018-04-03 14:10:04 -07001382 r.setTask(null /* task */, reparenting /* reparenting */);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001383
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001384 if (mActivities.remove(r) && r.fullscreen) {
1385 // Was previously in list.
1386 numFullscreen--;
1387 }
Craig Mautner21d24a22014-04-23 11:45:37 -07001388 if (r.isPersistable()) {
1389 mService.notifyTaskPersisterLocked(this, false);
1390 }
Wale Ogunwale89182d52016-03-11 10:38:36 -08001391
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001392 if (inPinnedWindowingMode()) {
Wale Ogunwale89182d52016-03-11 10:38:36 -08001393 // We normally notify listeners of task stack changes on pause, however pinned stack
1394 // activities are normally in the paused state so no notification will be sent there
1395 // before the activity is removed. We send it here so instead.
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001396 mService.getTaskChangeNotificationController().notifyTaskStackChanged();
Wale Ogunwale89182d52016-03-11 10:38:36 -08001397 }
1398
Craig Mautner41326202014-06-20 14:38:21 -07001399 if (mActivities.isEmpty()) {
Craig Mautner5afcd4d2014-06-21 18:11:33 -07001400 return !mReuseTask;
Craig Mautner41326202014-06-20 14:38:21 -07001401 }
1402 updateEffectiveIntent();
1403 return false;
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001404 }
1405
Winson Chung6954fc92017-03-24 16:22:12 -07001406 /**
1407 * @return whether or not there are ONLY task overlay activities in the stack.
1408 * If {@param excludeFinishing} is set, then ignore finishing activities in the check.
1409 * If there are no task overlay activities, this call returns false.
1410 */
1411 boolean onlyHasTaskOverlayActivities(boolean excludeFinishing) {
1412 int count = 0;
1413 for (int i = mActivities.size() - 1; i >= 0; i--) {
1414 final ActivityRecord r = mActivities.get(i);
1415 if (excludeFinishing && r.finishing) {
1416 continue;
1417 }
1418 if (!r.mTaskOverlay) {
1419 return false;
1420 }
1421 count++;
1422 }
1423 return count > 0;
1424 }
1425
Craig Mautner41db4a72014-05-07 17:20:56 -07001426 boolean autoRemoveFromRecents() {
Dianne Hackbornd38aed82014-06-10 21:36:35 -07001427 // We will automatically remove the task either if it has explicitly asked for
1428 // this, or it is empty and has never contained an activity that got shown to
1429 // the user.
Dianne Hackborn13420f22014-07-18 15:43:56 -07001430 return autoRemoveRecents || (mActivities.isEmpty() && !hasBeenVisible);
Craig Mautner41db4a72014-05-07 17:20:56 -07001431 }
1432
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001433 /**
1434 * Completely remove all activities associated with an existing
1435 * task starting at a specified index.
1436 */
Winson Chung0ec2a352017-10-26 11:38:30 -07001437 final void performClearTaskAtIndexLocked(int activityNdx, boolean pauseImmediately,
1438 String reason) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001439 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001440 for ( ; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001441 final ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001442 if (r.finishing) {
1443 continue;
1444 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07001445 if (mStack == null) {
Craig Mautner21d24a22014-04-23 11:45:37 -07001446 // Task was restored from persistent storage.
1447 r.takeFromHistory();
1448 mActivities.remove(activityNdx);
1449 --activityNdx;
1450 --numActivities;
Winson Chung6954fc92017-03-24 16:22:12 -07001451 } else if (mStack.finishActivityLocked(r, Activity.RESULT_CANCELED, null,
Winson Chung0ec2a352017-10-26 11:38:30 -07001452 reason, false, pauseImmediately)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001453 --activityNdx;
1454 --numActivities;
1455 }
1456 }
1457 }
1458
1459 /**
1460 * Completely remove all activities associated with an existing task.
1461 */
Benjamin Franza83859f2017-07-03 16:34:14 +01001462 void performClearTaskLocked() {
Craig Mautner362449a2014-06-20 14:04:39 -07001463 mReuseTask = true;
Winson Chung0ec2a352017-10-26 11:38:30 -07001464 performClearTaskAtIndexLocked(0, !PAUSE_IMMEDIATELY, "clear-task-all");
Craig Mautner362449a2014-06-20 14:04:39 -07001465 mReuseTask = false;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001466 }
1467
Filip Gruszczynskibe9dabd2016-01-19 12:23:10 -08001468 ActivityRecord performClearTaskForReuseLocked(ActivityRecord newR, int launchFlags) {
1469 mReuseTask = true;
1470 final ActivityRecord result = performClearTaskLocked(newR, launchFlags);
1471 mReuseTask = false;
1472 return result;
1473 }
1474
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001475 /**
1476 * Perform clear operation as requested by
1477 * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the
1478 * stack to the given task, then look for
1479 * an instance of that activity in the stack and, if found, finish all
1480 * activities on top of it and return the instance.
1481 *
1482 * @param newR Description of the new activity being started.
1483 * @return Returns the old activity that should be continued to be used,
1484 * or null if none was found.
1485 */
1486 final ActivityRecord performClearTaskLocked(ActivityRecord newR, int launchFlags) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001487 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001488 for (int activityNdx = numActivities - 1; activityNdx >= 0; --activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001489 ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001490 if (r.finishing) {
1491 continue;
1492 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001493 if (r.mActivityComponent.equals(newR.mActivityComponent)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001494 // Here it is! Now finish everything in front...
Craig Mautner1602ec22013-05-12 10:24:27 -07001495 final ActivityRecord ret = r;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001496
1497 for (++activityNdx; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001498 r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001499 if (r.finishing) {
1500 continue;
1501 }
1502 ActivityOptions opts = r.takeOptionsLocked();
1503 if (opts != null) {
1504 ret.updateOptionsLocked(opts);
1505 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07001506 if (mStack != null && mStack.finishActivityLocked(
Todd Kennedy539db512014-12-15 09:57:55 -08001507 r, Activity.RESULT_CANCELED, null, "clear-task-stack", false)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001508 --activityNdx;
1509 --numActivities;
1510 }
1511 }
1512
1513 // Finally, if this is a normal launch mode (that is, not
1514 // expecting onNewIntent()), then we will finish the current
1515 // instance of the activity so a new fresh one can be started.
1516 if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE
Daichi Hirono15a02992016-04-27 18:47:01 +09001517 && (launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0
1518 && !ActivityStarter.isDocumentLaunchesIntoExisting(launchFlags)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001519 if (!ret.finishing) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001520 if (mStack != null) {
1521 mStack.finishActivityLocked(
Wale Ogunwale7d701172015-03-11 15:36:30 -07001522 ret, Activity.RESULT_CANCELED, null, "clear-task-top", false);
1523 }
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001524 return null;
1525 }
1526 }
1527
1528 return ret;
1529 }
1530 }
1531
1532 return null;
1533 }
1534
Winson Chung0ec2a352017-10-26 11:38:30 -07001535 void removeTaskActivitiesLocked(boolean pauseImmediately, String reason) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001536 // Just remove the entire task.
Winson Chung0ec2a352017-10-26 11:38:30 -07001537 performClearTaskAtIndexLocked(0, pauseImmediately, reason);
Craig Mautner9db9a0b2013-04-29 17:05:56 -07001538 }
1539
Craig Mautner432f64e2015-05-20 14:59:57 -07001540 String lockTaskAuthToString() {
1541 switch (mLockTaskAuth) {
1542 case LOCK_TASK_AUTH_DONT_LOCK: return "LOCK_TASK_AUTH_DONT_LOCK";
1543 case LOCK_TASK_AUTH_PINNABLE: return "LOCK_TASK_AUTH_PINNABLE";
1544 case LOCK_TASK_AUTH_LAUNCHABLE: return "LOCK_TASK_AUTH_LAUNCHABLE";
1545 case LOCK_TASK_AUTH_WHITELISTED: return "LOCK_TASK_AUTH_WHITELISTED";
Benjamin Franz469dd582015-06-09 14:24:36 +01001546 case LOCK_TASK_AUTH_LAUNCHABLE_PRIV: return "LOCK_TASK_AUTH_LAUNCHABLE_PRIV";
Craig Mautner432f64e2015-05-20 14:59:57 -07001547 default: return "unknown=" + mLockTaskAuth;
1548 }
1549 }
1550
Craig Mautner15df08a2015-04-01 12:17:18 -07001551 void setLockTaskAuth() {
Charles He2bf28322017-10-12 22:24:49 +01001552 setLockTaskAuth(getRootActivity());
1553 }
1554
1555 private void setLockTaskAuth(@Nullable ActivityRecord r) {
1556 if (r == null) {
1557 mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE;
1558 return;
1559 }
1560
Charles He520b2832017-09-02 15:27:16 +01001561 final String pkg = (realActivity != null) ? realActivity.getPackageName() : null;
Bryce Lee2b8e0372018-04-05 17:01:37 -07001562 final LockTaskController lockTaskController = mService.getLockTaskController();
Charles He2bf28322017-10-12 22:24:49 +01001563 switch (r.lockTaskLaunchMode) {
Craig Mautner15df08a2015-04-01 12:17:18 -07001564 case LOCK_TASK_LAUNCH_MODE_DEFAULT:
Bryce Lee2b8e0372018-04-05 17:01:37 -07001565 mLockTaskAuth = lockTaskController.isPackageWhitelisted(userId, pkg)
Charles He520b2832017-09-02 15:27:16 +01001566 ? LOCK_TASK_AUTH_WHITELISTED : LOCK_TASK_AUTH_PINNABLE;
Craig Mautner15df08a2015-04-01 12:17:18 -07001567 break;
1568
1569 case LOCK_TASK_LAUNCH_MODE_NEVER:
Benjamin Franz469dd582015-06-09 14:24:36 +01001570 mLockTaskAuth = LOCK_TASK_AUTH_DONT_LOCK;
Craig Mautner15df08a2015-04-01 12:17:18 -07001571 break;
1572
1573 case LOCK_TASK_LAUNCH_MODE_ALWAYS:
Benjamin Franz469dd582015-06-09 14:24:36 +01001574 mLockTaskAuth = LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
Craig Mautner15df08a2015-04-01 12:17:18 -07001575 break;
1576
1577 case LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED:
Bryce Lee2b8e0372018-04-05 17:01:37 -07001578 mLockTaskAuth = lockTaskController.isPackageWhitelisted(userId, pkg)
Charles He520b2832017-09-02 15:27:16 +01001579 ? LOCK_TASK_AUTH_LAUNCHABLE : LOCK_TASK_AUTH_PINNABLE;
Craig Mautner15df08a2015-04-01 12:17:18 -07001580 break;
1581 }
Craig Mautner432f64e2015-05-20 14:59:57 -07001582 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
1583 " mLockTaskAuth=" + lockTaskAuthToString());
Craig Mautner15df08a2015-04-01 12:17:18 -07001584 }
1585
Winson Chungd3395382016-12-13 11:49:09 -08001586 private boolean isResizeable(boolean checkSupportsPip) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001587 return (mService.mForceResizableActivities || ActivityInfo.isResizeableMode(mResizeMode)
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -07001588 || (checkSupportsPip && mSupportsPictureInPicture));
Winson Chungd3395382016-12-13 11:49:09 -08001589 }
1590
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001591 boolean isResizeable() {
Winson Chungd3395382016-12-13 11:49:09 -08001592 return isResizeable(true /* checkSupportsPip */);
1593 }
1594
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001595 @Override
1596 public boolean supportsSplitScreenWindowingMode() {
Winson Chungd3395382016-12-13 11:49:09 -08001597 // A task can not be docked even if it is considered resizeable because it only supports
1598 // picture-in-picture mode but has a non-resizeable resizeMode
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001599 return super.supportsSplitScreenWindowingMode()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001600 && mService.mSupportsSplitScreenMultiWindow
1601 && (mService.mForceResizableActivities
Bryce Leec857a5b2017-08-16 10:04:52 -07001602 || (isResizeable(false /* checkSupportsPip */)
1603 && !ActivityInfo.isPreserveOrientationMode(mResizeMode)));
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001604 }
1605
skuhne@google.com322347b2016-12-02 12:54:03 -08001606 /**
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001607 * Check whether this task can be launched on the specified display.
Riddle Hsu16567132018-08-16 21:37:47 +08001608 *
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001609 * @param displayId Target display id.
Riddle Hsu16567132018-08-16 21:37:47 +08001610 * @return {@code true} if either it is the default display or this activity can be put on a
1611 * secondary display.
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001612 */
1613 boolean canBeLaunchedOnDisplay(int displayId) {
1614 return mService.mStackSupervisor.canPlaceEntityOnDisplay(displayId,
Riddle Hsu16567132018-08-16 21:37:47 +08001615 -1 /* don't check PID */, -1 /* don't check UID */, null /* activityInfo */);
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001616 }
1617
1618 /**
skuhne@google.com322347b2016-12-02 12:54:03 -08001619 * Check that a given bounds matches the application requested orientation.
1620 *
1621 * @param bounds The bounds to be tested.
1622 * @return True if the requested bounds are okay for a resizing request.
1623 */
Wale Ogunwale069bbd32017-02-03 07:58:14 -08001624 private boolean canResizeToBounds(Rect bounds) {
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001625 if (bounds == null || !inFreeformWindowingMode()) {
skuhne@google.com322347b2016-12-02 12:54:03 -08001626 // Note: If not on the freeform workspace, we ignore the bounds.
1627 return true;
1628 }
1629 final boolean landscape = bounds.width() > bounds.height();
Evan Roskydfe3da72018-10-26 17:21:06 -07001630 final Rect configBounds = getRequestedOverrideBounds();
skuhne@google.com322347b2016-12-02 12:54:03 -08001631 if (mResizeMode == RESIZE_MODE_FORCE_RESIZABLE_PRESERVE_ORIENTATION) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001632 return configBounds.isEmpty()
1633 || landscape == (configBounds.width() > configBounds.height());
skuhne@google.com322347b2016-12-02 12:54:03 -08001634 }
1635 return (mResizeMode != RESIZE_MODE_FORCE_RESIZABLE_PORTRAIT_ONLY || !landscape)
1636 && (mResizeMode != RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY || landscape);
1637 }
1638
Craig Mautner525f3d92013-05-07 14:01:50 -07001639 /**
Yorke Leebdef5372017-04-10 16:38:51 -07001640 * @return {@code true} if the task is being cleared for the purposes of being reused.
1641 */
1642 boolean isClearingToReuseTask() {
1643 return mReuseTask;
1644 }
1645
1646 /**
Craig Mautner525f3d92013-05-07 14:01:50 -07001647 * Find the activity in the history stack within the given task. Returns
1648 * the index within the history at which it's found, or < 0 if not found.
1649 */
1650 final ActivityRecord findActivityInHistoryLocked(ActivityRecord r) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001651 final ComponentName realActivity = r.mActivityComponent;
Craig Mautner525f3d92013-05-07 14:01:50 -07001652 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1653 ActivityRecord candidate = mActivities.get(activityNdx);
1654 if (candidate.finishing) {
1655 continue;
1656 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001657 if (candidate.mActivityComponent.equals(realActivity)) {
Craig Mautner525f3d92013-05-07 14:01:50 -07001658 return candidate;
1659 }
1660 }
1661 return null;
1662 }
1663
Winson Chunga449dc02014-05-16 11:15:04 -07001664 /** Updates the last task description values. */
1665 void updateTaskDescription() {
1666 // Traverse upwards looking for any break between main task activities and
1667 // utility activities.
1668 int activityNdx;
1669 final int numActivities = mActivities.size();
Wale Ogunwale3eadad72016-10-13 09:16:59 -07001670 final boolean relinquish = numActivities != 0 &&
1671 (mActivities.get(0).info.flags & FLAG_RELINQUISH_TASK_IDENTITY) != 0;
Winson Chunga449dc02014-05-16 11:15:04 -07001672 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
Craig Mautner21d24a22014-04-23 11:45:37 -07001673 ++activityNdx) {
Winson Chunga449dc02014-05-16 11:15:04 -07001674 final ActivityRecord r = mActivities.get(activityNdx);
Wale Ogunwale3eadad72016-10-13 09:16:59 -07001675 if (relinquish && (r.info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001676 // This will be the top activity for determining taskDescription. Pre-inc to
1677 // overcome initial decrement below.
1678 ++activityNdx;
1679 break;
1680 }
Winson Chunga449dc02014-05-16 11:15:04 -07001681 if (r.intent != null &&
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001682 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
Winson Chunga449dc02014-05-16 11:15:04 -07001683 break;
1684 }
1685 }
1686 if (activityNdx > 0) {
1687 // Traverse downwards starting below break looking for set label, icon.
1688 // Note that if there are activities in the task but none of them set the
1689 // recent activity values, then we do not fall back to the last set
1690 // values in the TaskRecord.
1691 String label = null;
Craig Mautner648f69b2014-09-18 14:16:26 -07001692 String iconFilename = null;
Matthew Ng54bc9422017-10-02 17:16:28 -07001693 int iconResource = -1;
Winson Chunga449dc02014-05-16 11:15:04 -07001694 int colorPrimary = 0;
Winson Chung1af8eda2016-02-05 17:55:56 +00001695 int colorBackground = 0;
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001696 int statusBarColor = 0;
1697 int navigationBarColor = 0;
1698 boolean topActivity = true;
Winson Chunga449dc02014-05-16 11:15:04 -07001699 for (--activityNdx; activityNdx >= 0; --activityNdx) {
1700 final ActivityRecord r = mActivities.get(activityNdx);
Winson Chung80f80db2018-05-30 21:13:25 -07001701 if (r.mTaskOverlay) {
1702 continue;
1703 }
Winson Chunga449dc02014-05-16 11:15:04 -07001704 if (r.taskDescription != null) {
1705 if (label == null) {
1706 label = r.taskDescription.getLabel();
1707 }
Matthew Ng54bc9422017-10-02 17:16:28 -07001708 if (iconResource == -1) {
1709 iconResource = r.taskDescription.getIconResource();
1710 }
Craig Mautner648f69b2014-09-18 14:16:26 -07001711 if (iconFilename == null) {
1712 iconFilename = r.taskDescription.getIconFilename();
Winson Chunga449dc02014-05-16 11:15:04 -07001713 }
1714 if (colorPrimary == 0) {
1715 colorPrimary = r.taskDescription.getPrimaryColor();
Winson Chunga449dc02014-05-16 11:15:04 -07001716 }
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001717 if (topActivity) {
Winson Chung1af8eda2016-02-05 17:55:56 +00001718 colorBackground = r.taskDescription.getBackgroundColor();
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001719 statusBarColor = r.taskDescription.getStatusBarColor();
1720 navigationBarColor = r.taskDescription.getNavigationBarColor();
Winson Chung1af8eda2016-02-05 17:55:56 +00001721 }
Winson Chunga449dc02014-05-16 11:15:04 -07001722 }
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001723 topActivity = false;
Winson Chunga449dc02014-05-16 11:15:04 -07001724 }
Matthew Ng54bc9422017-10-02 17:16:28 -07001725 lastTaskDescription = new TaskDescription(label, null, iconResource, iconFilename,
1726 colorPrimary, colorBackground, statusBarColor, navigationBarColor);
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001727 if (mTask != null) {
1728 mTask.setTaskDescription(lastTaskDescription);
Jorim Jaggi829b9cd2017-01-23 16:20:53 +01001729 }
Winson Chungec396d62014-08-06 17:08:00 -07001730 // Update the task affiliation color if we are the parent of the group
1731 if (taskId == mAffiliatedTaskId) {
1732 mAffiliatedTaskColor = lastTaskDescription.getPrimaryColor();
1733 }
Winson Chunga449dc02014-05-16 11:15:04 -07001734 }
1735 }
1736
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001737 int findEffectiveRootIndex() {
Craig Mautner4767f4b2014-09-18 15:38:33 -07001738 int effectiveNdx = 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001739 final int topActivityNdx = mActivities.size() - 1;
Dianne Hackborn39569af2014-09-23 10:56:58 -07001740 for (int activityNdx = 0; activityNdx <= topActivityNdx; ++activityNdx) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001741 final ActivityRecord r = mActivities.get(activityNdx);
1742 if (r.finishing) {
1743 continue;
1744 }
Craig Mautner4767f4b2014-09-18 15:38:33 -07001745 effectiveNdx = activityNdx;
Wale Ogunwale3eadad72016-10-13 09:16:59 -07001746 if ((r.info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001747 break;
1748 }
1749 }
Craig Mautner4767f4b2014-09-18 15:38:33 -07001750 return effectiveNdx;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001751 }
1752
1753 void updateEffectiveIntent() {
1754 final int effectiveRootIndex = findEffectiveRootIndex();
1755 final ActivityRecord r = mActivities.get(effectiveRootIndex);
Winson Chungfee26772014-08-05 12:21:52 -07001756 setIntent(r);
Winson Chung8d9009e2017-11-16 15:43:05 -08001757
1758 // Update the task description when the activities change
1759 updateTaskDescription();
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001760 }
1761
Evan Rosky730f6e82018-12-03 17:40:11 -08001762 void adjustForMinimalTaskDimensions(Rect bounds, Rect previousBounds) {
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001763 if (bounds == null) {
1764 return;
1765 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001766 int minWidth = mMinWidth;
1767 int minHeight = mMinHeight;
Robert Carr9c5867d2016-03-10 15:52:46 -08001768 // If the task has no requested minimal size, we'd like to enforce a minimal size
1769 // so that the user can not render the task too small to manipulate. We don't need
1770 // to do this for the pinned stack as the bounds are controlled by the system.
Evan Rosky1ac84462018-11-13 11:25:30 -08001771 if (!inPinnedWindowingMode() && mStack != null) {
Garfield Tan4a48a7f2018-10-02 14:23:55 -07001772 final int defaultMinSizeDp =
Wale Ogunwaled32da472018-11-16 07:19:28 -08001773 mService.mRootActivityContainer.mDefaultMinSizeOfResizeableTaskDp;
Garfield Tan4a48a7f2018-10-02 14:23:55 -07001774 final ActivityDisplay display =
Wale Ogunwaled32da472018-11-16 07:19:28 -08001775 mService.mRootActivityContainer.getActivityDisplay(mStack.mDisplayId);
Garfield Tan4a48a7f2018-10-02 14:23:55 -07001776 final float density =
1777 (float) display.getConfiguration().densityDpi / DisplayMetrics.DENSITY_DEFAULT;
1778 final int defaultMinSize = (int) (defaultMinSizeDp * density);
1779
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001780 if (minWidth == INVALID_MIN_SIZE) {
Garfield Tan4a48a7f2018-10-02 14:23:55 -07001781 minWidth = defaultMinSize;
Andrii Kulian2e751b82016-03-16 16:59:32 -07001782 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001783 if (minHeight == INVALID_MIN_SIZE) {
Garfield Tan4a48a7f2018-10-02 14:23:55 -07001784 minHeight = defaultMinSize;
Andrii Kulian2e751b82016-03-16 16:59:32 -07001785 }
Robert Carr9c5867d2016-03-10 15:52:46 -08001786 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001787 final boolean adjustWidth = minWidth > bounds.width();
1788 final boolean adjustHeight = minHeight > bounds.height();
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001789 if (!(adjustWidth || adjustHeight)) {
1790 return;
1791 }
1792
1793 if (adjustWidth) {
Garfield Tan020607d2018-12-17 17:01:58 -08001794 if (!previousBounds.isEmpty() && bounds.right == previousBounds.right) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001795 bounds.left = bounds.right - minWidth;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001796 } else {
1797 // Either left bounds match, or neither match, or the previous bounds were
1798 // fullscreen and we default to keeping left.
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001799 bounds.right = bounds.left + minWidth;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001800 }
1801 }
1802 if (adjustHeight) {
Garfield Tan020607d2018-12-17 17:01:58 -08001803 if (!previousBounds.isEmpty() && bounds.bottom == previousBounds.bottom) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001804 bounds.top = bounds.bottom - minHeight;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001805 } else {
1806 // Either top bounds match, or neither match, or the previous bounds were
1807 // fullscreen and we default to keeping top.
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001808 bounds.bottom = bounds.top + minHeight;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001809 }
1810 }
1811 }
1812
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001813 /**
1814 * Update task's override configuration based on the bounds.
Jorim Jaggi0a932142016-02-01 17:42:25 -08001815 * @param bounds The bounds of the task.
Andrii Kulian8072d112016-09-16 11:11:01 -07001816 * @return True if the override configuration was updated.
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001817 */
Andrii Kulian8072d112016-09-16 11:11:01 -07001818 boolean updateOverrideConfiguration(Rect bounds) {
Jorim Jaggi0a932142016-02-01 17:42:25 -08001819 return updateOverrideConfiguration(bounds, null /* insetBounds */);
1820 }
1821
Evan Rosky9ba524e2018-01-03 16:27:56 -08001822 void setLastNonFullscreenBounds(Rect bounds) {
1823 if (mLastNonFullscreenBounds == null) {
1824 mLastNonFullscreenBounds = new Rect(bounds);
1825 } else {
1826 mLastNonFullscreenBounds.set(bounds);
1827 }
1828 }
1829
Jorim Jaggi0a932142016-02-01 17:42:25 -08001830 /**
1831 * Update task's override configuration based on the bounds.
1832 * @param bounds The bounds of the task.
1833 * @param insetBounds The bounds used to calculate the system insets, which is used here to
1834 * subtract the navigation bar/status bar size from the screen size reported
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001835 * to the application. See {@link IActivityTaskManager#resizeDockedStack}.
Andrii Kulian8072d112016-09-16 11:11:01 -07001836 * @return True if the override configuration was updated.
Jorim Jaggi0a932142016-02-01 17:42:25 -08001837 */
Andrii Kulian8072d112016-09-16 11:11:01 -07001838 boolean updateOverrideConfiguration(Rect bounds, @Nullable Rect insetBounds) {
Evan Rosky1ac84462018-11-13 11:25:30 -08001839 final boolean hasSetDisplayedBounds = (insetBounds != null && !insetBounds.isEmpty());
1840 if (hasSetDisplayedBounds) {
1841 setDisplayedBounds(bounds);
1842 } else {
1843 setDisplayedBounds(null);
1844 }
1845 // "steady" bounds do not include any temporary offsets from animation or interaction.
1846 Rect steadyBounds = hasSetDisplayedBounds ? insetBounds : bounds;
1847 if (equivalentRequestedOverrideBounds(steadyBounds)) {
Andrii Kulian8072d112016-09-16 11:11:01 -07001848 return false;
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001849 }
Bryce Leef3c6a472017-11-14 14:53:06 -08001850
Evan Rosky1ac84462018-11-13 11:25:30 -08001851 mTmpConfig.setTo(getResolvedOverrideConfiguration());
1852 setBounds(steadyBounds);
1853 return !mTmpConfig.equals(getResolvedOverrideConfiguration());
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08001854 }
Wale Ogunwale5f986092015-12-04 15:35:38 -08001855
Bryce Leec4ab62a2018-03-05 14:19:26 -08001856 /**
1857 * This should be called when an child activity changes state. This should only
1858 * be called from
1859 * {@link ActivityRecord#setState(ActivityState, String)} .
1860 * @param record The {@link ActivityRecord} whose state has changed.
1861 * @param state The new state.
1862 * @param reason The reason for the change.
1863 */
1864 void onActivityStateChanged(ActivityRecord record, ActivityState state, String reason) {
1865 final ActivityStack parent = getStack();
1866
1867 if (parent != null) {
1868 parent.onActivityStateChanged(record, state, reason);
1869 }
1870 }
1871
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08001872 @Override
1873 public void onConfigurationChanged(Configuration newParentConfig) {
Evan Rosky730f6e82018-12-03 17:40:11 -08001874 // Check if the new configuration supports persistent bounds (eg. is Freeform) and if so
1875 // restore the last recorded non-fullscreen bounds.
1876 final boolean prevPersistTaskBounds = getWindowConfiguration().persistTaskBounds();
1877 final boolean nextPersistTaskBounds =
1878 getRequestedOverrideConfiguration().windowConfiguration.persistTaskBounds()
1879 || newParentConfig.windowConfiguration.persistTaskBounds();
1880 if (!prevPersistTaskBounds && nextPersistTaskBounds
1881 && mLastNonFullscreenBounds != null && !mLastNonFullscreenBounds.isEmpty()) {
1882 // Bypass onRequestedOverrideConfigurationChanged here to avoid infinite loop.
1883 getRequestedOverrideConfiguration().windowConfiguration
1884 .setBounds(mLastNonFullscreenBounds);
1885 }
1886
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08001887 final boolean wasInMultiWindowMode = inMultiWindowMode();
1888 super.onConfigurationChanged(newParentConfig);
1889 if (wasInMultiWindowMode != inMultiWindowMode()) {
Winson Chung5af42fc2017-03-24 17:11:33 -07001890 mService.mStackSupervisor.scheduleUpdateMultiWindowMode(this);
Wale Ogunwale5f986092015-12-04 15:35:38 -08001891 }
Evan Rosky730f6e82018-12-03 17:40:11 -08001892
1893 // If the configuration supports persistent bounds (eg. Freeform), keep track of the
1894 // current (non-fullscreen) bounds for persistence.
Evan Rosky1ac84462018-11-13 11:25:30 -08001895 if (getWindowConfiguration().persistTaskBounds()) {
1896 final Rect currentBounds = getRequestedOverrideBounds();
1897 if (!currentBounds.isEmpty()) {
1898 setLastNonFullscreenBounds(currentBounds);
1899 }
1900 }
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08001901 // TODO: Should also take care of Pip mode changes here.
Garfield Tan891146c2018-10-09 12:14:00 -07001902
1903 saveLaunchingStateIfNeeded();
1904 }
1905
1906 /**
1907 * Saves launching state if necessary so that we can launch the activity to its latest state.
1908 * It only saves state if this task has been shown to user and it's in fullscreen or freeform
1909 * mode.
1910 */
1911 void saveLaunchingStateIfNeeded() {
1912 if (!hasBeenVisible) {
1913 // Not ever visible to user.
1914 return;
1915 }
1916
1917 final int windowingMode = getWindowingMode();
1918 if (windowingMode != WindowConfiguration.WINDOWING_MODE_FULLSCREEN
1919 && windowingMode != WindowConfiguration.WINDOWING_MODE_FREEFORM) {
1920 return;
1921 }
1922
1923 // Saves the new state so that we can launch the activity at the same location.
1924 mService.mStackSupervisor.mLaunchParamsPersister.saveTask(this);
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001925 }
1926
Evan Roskyed6767f2018-10-26 17:21:06 -07001927 /**
Evan Rosky1ac84462018-11-13 11:25:30 -08001928 * Adjust bounds to stay within stack bounds.
1929 *
1930 * Since bounds might be outside of stack bounds, this method tries to move the bounds in a way
1931 * that keep them unchanged, but be contained within the stack bounds.
1932 *
1933 * @param bounds Bounds to be adjusted.
1934 * @param stackBounds Bounds within which the other bounds should remain.
1935 */
1936 private static void fitWithinBounds(Rect bounds, Rect stackBounds) {
1937 if (stackBounds == null || stackBounds.isEmpty() || stackBounds.contains(bounds)) {
1938 return;
1939 }
1940
1941 if (bounds.left < stackBounds.left || bounds.right > stackBounds.right) {
1942 final int maxRight = stackBounds.right
1943 - (stackBounds.width() / FIT_WITHIN_BOUNDS_DIVIDER);
1944 int horizontalDiff = stackBounds.left - bounds.left;
1945 if ((horizontalDiff < 0 && bounds.left >= maxRight)
1946 || (bounds.left + horizontalDiff >= maxRight)) {
1947 horizontalDiff = maxRight - bounds.left;
1948 }
1949 bounds.left += horizontalDiff;
1950 bounds.right += horizontalDiff;
1951 }
1952
1953 if (bounds.top < stackBounds.top || bounds.bottom > stackBounds.bottom) {
1954 final int maxBottom = stackBounds.bottom
1955 - (stackBounds.height() / FIT_WITHIN_BOUNDS_DIVIDER);
1956 int verticalDiff = stackBounds.top - bounds.top;
1957 if ((verticalDiff < 0 && bounds.top >= maxBottom)
1958 || (bounds.top + verticalDiff >= maxBottom)) {
1959 verticalDiff = maxBottom - bounds.top;
1960 }
1961 bounds.top += verticalDiff;
1962 bounds.bottom += verticalDiff;
1963 }
1964 }
1965
1966 /**
Evan Roskyed6767f2018-10-26 17:21:06 -07001967 * Displayed bounds are used to set where the task is drawn at any given time. This is
1968 * separate from its actual bounds so that the app doesn't see any meaningful configuration
1969 * changes during transitionary periods.
1970 */
1971 void setDisplayedBounds(Rect bounds) {
1972 if (bounds == null) {
1973 mDisplayedBounds.setEmpty();
1974 } else {
1975 mDisplayedBounds.set(bounds);
1976 }
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001977 if (mTask != null) {
1978 mTask.setOverrideDisplayedBounds(
Evan Roskyed6767f2018-10-26 17:21:06 -07001979 mDisplayedBounds.isEmpty() ? null : mDisplayedBounds);
1980 }
1981 }
1982
1983 /**
1984 * Gets the current overridden displayed bounds. These will be empty if the task is not
1985 * currently overriding where it is displayed.
1986 */
1987 Rect getDisplayedBounds() {
1988 return mDisplayedBounds;
1989 }
1990
1991 /**
1992 * @return {@code true} if this has overridden displayed bounds.
1993 */
1994 boolean hasDisplayedBounds() {
1995 return !mDisplayedBounds.isEmpty();
1996 }
1997
Evan Rosky1ac84462018-11-13 11:25:30 -08001998 /**
1999 * Intersects inOutBounds with intersectBounds-intersectInsets. If inOutBounds is larger than
2000 * intersectBounds on a side, then the respective side will not be intersected.
2001 *
2002 * The assumption is that if inOutBounds is initially larger than intersectBounds, then the
2003 * inset on that side is no-longer applicable. This scenario happens when a task's minimal
2004 * bounds are larger than the provided parent/display bounds.
2005 *
2006 * @param inOutBounds the bounds to intersect.
2007 * @param intersectBounds the bounds to intersect with.
2008 * @param intersectInsets insets to apply to intersectBounds before intersecting.
2009 */
2010 private static void intersectWithInsetsIfFits(
2011 Rect inOutBounds, Rect intersectBounds, Rect intersectInsets) {
2012 if (inOutBounds.right <= intersectBounds.right) {
2013 inOutBounds.right =
2014 Math.min(intersectBounds.right - intersectInsets.right, inOutBounds.right);
2015 }
2016 if (inOutBounds.bottom <= intersectBounds.bottom) {
2017 inOutBounds.bottom =
2018 Math.min(intersectBounds.bottom - intersectInsets.bottom, inOutBounds.bottom);
2019 }
2020 if (inOutBounds.left >= intersectBounds.left) {
2021 inOutBounds.left =
2022 Math.max(intersectBounds.left + intersectInsets.left, inOutBounds.left);
2023 }
2024 if (inOutBounds.top >= intersectBounds.top) {
2025 inOutBounds.top =
2026 Math.max(intersectBounds.top + intersectInsets.top, inOutBounds.top);
2027 }
2028 }
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08002029
Evan Rosky1ac84462018-11-13 11:25:30 -08002030 /**
2031 * Gets bounds with non-decor and stable insets applied respectively.
2032 *
2033 * If bounds overhangs the display, those edges will not get insets. See
2034 * {@link #intersectWithInsetsIfFits}
2035 *
2036 * @param outNonDecorBounds where to place bounds with non-decor insets applied.
2037 * @param outStableBounds where to place bounds with stable insets applied.
2038 * @param bounds the bounds to inset.
2039 */
2040 private void calculateInsetFrames(Rect outNonDecorBounds, Rect outStableBounds, Rect bounds,
2041 DisplayInfo displayInfo) {
2042 outNonDecorBounds.set(bounds);
2043 outStableBounds.set(bounds);
2044 if (getStack() == null || getStack().getDisplay() == null) {
2045 return;
2046 }
2047 DisplayPolicy policy = getStack().getDisplay().mDisplayContent.getDisplayPolicy();
2048 if (policy == null) {
2049 return;
2050 }
2051 mTmpBounds.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight);
Bryce Lee7566d762017-03-30 09:34:15 -07002052
Evan Rosky1ac84462018-11-13 11:25:30 -08002053 policy.getStableInsetsLw(displayInfo.rotation,
2054 displayInfo.logicalWidth, displayInfo.logicalHeight, displayInfo.displayCutout,
2055 mTmpInsets);
2056 intersectWithInsetsIfFits(outStableBounds, mTmpBounds, mTmpInsets);
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08002057
Evan Rosky1ac84462018-11-13 11:25:30 -08002058 policy.getNonDecorInsetsLw(displayInfo.rotation,
2059 displayInfo.logicalWidth, displayInfo.logicalHeight, displayInfo.displayCutout,
2060 mTmpInsets);
2061 intersectWithInsetsIfFits(outNonDecorBounds, mTmpBounds, mTmpInsets);
2062 }
2063
2064 /**
2065 * Asks docked-divider controller for the smallestwidthdp given bounds.
2066 * @param bounds bounds to calculate smallestwidthdp for.
2067 */
2068 private int getSmallestScreenWidthDpForDockedBounds(Rect bounds) {
2069 DisplayContent dc = mStack.getDisplay().mDisplayContent;
2070 if (dc != null) {
2071 return dc.getDockedDividerController().getSmallestWidthDpForBounds(bounds);
2072 }
2073 return Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
2074 }
2075
Riddle Hsu0a343c32018-12-21 00:40:48 +08002076 void computeConfigResourceOverrides(@NonNull Configuration inOutConfig,
2077 @NonNull Configuration parentConfig) {
2078 computeConfigResourceOverrides(inOutConfig, parentConfig, true /* insideParentBounds */);
2079 }
2080
Evan Rosky1ac84462018-11-13 11:25:30 -08002081 /**
2082 * Calculates configuration values used by the client to get resources. This should be run
2083 * using app-facing bounds (bounds unmodified by animations or transient interactions).
2084 *
2085 * This assumes bounds are non-empty/null. For the null-bounds case, the caller is likely
2086 * configuring an "inherit-bounds" window which means that all configuration settings would
2087 * just be inherited from the parent configuration.
2088 **/
Evan Rosky730f6e82018-12-03 17:40:11 -08002089 void computeConfigResourceOverrides(@NonNull Configuration inOutConfig,
Riddle Hsu0a343c32018-12-21 00:40:48 +08002090 @NonNull Configuration parentConfig, boolean insideParentBounds) {
Evan Rosky1ac84462018-11-13 11:25:30 -08002091 int windowingMode = inOutConfig.windowConfiguration.getWindowingMode();
2092 if (windowingMode == WINDOWING_MODE_UNDEFINED) {
2093 windowingMode = parentConfig.windowConfiguration.getWindowingMode();
Winson Chungbdc646f2017-02-13 12:12:22 -08002094 }
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08002095
Evan Rosky1ac84462018-11-13 11:25:30 -08002096 float density = inOutConfig.densityDpi;
2097 if (density == Configuration.DENSITY_DPI_UNDEFINED) {
2098 density = parentConfig.densityDpi;
2099 }
2100 density *= DisplayMetrics.DENSITY_DEFAULT_SCALE;
Winson Chung60c1aba2017-03-14 17:47:42 -07002101
Evan Rosky730f6e82018-12-03 17:40:11 -08002102 final Rect bounds = inOutConfig.windowConfiguration.getBounds();
Evan Rosky1ac84462018-11-13 11:25:30 -08002103 Rect outAppBounds = inOutConfig.windowConfiguration.getAppBounds();
2104 if (outAppBounds == null || outAppBounds.isEmpty()) {
2105 inOutConfig.windowConfiguration.setAppBounds(bounds);
2106 outAppBounds = inOutConfig.windowConfiguration.getAppBounds();
2107 }
Riddle Hsu0a343c32018-12-21 00:40:48 +08002108 if (insideParentBounds && windowingMode != WINDOWING_MODE_FREEFORM) {
Evan Rosky1ac84462018-11-13 11:25:30 -08002109 final Rect parentAppBounds = parentConfig.windowConfiguration.getAppBounds();
2110 if (parentAppBounds != null && !parentAppBounds.isEmpty()) {
2111 outAppBounds.intersect(parentAppBounds);
2112 }
2113 }
2114
2115 if (inOutConfig.screenWidthDp == Configuration.SCREEN_WIDTH_DP_UNDEFINED
2116 || inOutConfig.screenHeightDp == Configuration.SCREEN_HEIGHT_DP_UNDEFINED) {
Riddle Hsu0a343c32018-12-21 00:40:48 +08002117 if (insideParentBounds && mStack != null) {
Evan Rosky1ac84462018-11-13 11:25:30 -08002118 final DisplayInfo di = new DisplayInfo();
2119 mStack.getDisplay().mDisplay.getDisplayInfo(di);
2120
2121 // For calculating screenWidthDp, screenWidthDp, we use the stable inset screen
2122 // area, i.e. the screen area without the system bars.
2123 // The non decor inset are areas that could never be removed in Honeycomb. See
2124 // {@link WindowManagerPolicy#getNonDecorInsetsLw}.
2125 calculateInsetFrames(mTmpNonDecorBounds, mTmpStableBounds, bounds, di);
2126 } else {
2127 mTmpNonDecorBounds.set(bounds);
2128 mTmpStableBounds.set(bounds);
2129 }
2130
2131 if (inOutConfig.screenWidthDp == Configuration.SCREEN_WIDTH_DP_UNDEFINED) {
Riddle Hsu0a343c32018-12-21 00:40:48 +08002132 final int overrideScreenWidthDp = (int) (mTmpStableBounds.width() / density);
2133 inOutConfig.screenWidthDp = insideParentBounds
2134 ? Math.min(overrideScreenWidthDp, parentConfig.screenWidthDp)
2135 : overrideScreenWidthDp;
Evan Rosky1ac84462018-11-13 11:25:30 -08002136 }
2137 if (inOutConfig.screenHeightDp == Configuration.SCREEN_HEIGHT_DP_UNDEFINED) {
Riddle Hsu0a343c32018-12-21 00:40:48 +08002138 final int overrideScreenHeightDp = (int) (mTmpStableBounds.height() / density);
2139 inOutConfig.screenHeightDp = insideParentBounds
Riddle Hsu88e3c8732019-02-18 19:15:12 +08002140 ? Math.min(overrideScreenHeightDp, parentConfig.screenHeightDp)
Riddle Hsu0a343c32018-12-21 00:40:48 +08002141 : overrideScreenHeightDp;
Evan Rosky1ac84462018-11-13 11:25:30 -08002142 }
2143
2144 if (inOutConfig.smallestScreenWidthDp
2145 == Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
2146 if (WindowConfiguration.isFloating(windowingMode)) {
2147 // For floating tasks, calculate the smallest width from the bounds of the task
2148 inOutConfig.smallestScreenWidthDp = (int) (
2149 Math.min(bounds.width(), bounds.height()) / density);
2150 } else if (WindowConfiguration.isSplitScreenWindowingMode(windowingMode)) {
2151 // Iterating across all screen orientations, and return the minimum of the task
2152 // width taking into account that the bounds might change because the snap
2153 // algorithm snaps to a different value
Evan Rosky730f6e82018-12-03 17:40:11 -08002154 inOutConfig.smallestScreenWidthDp =
2155 getSmallestScreenWidthDpForDockedBounds(bounds);
Evan Rosky1ac84462018-11-13 11:25:30 -08002156 }
2157 // otherwise, it will just inherit
2158 }
2159 }
2160
Evan Rosky730f6e82018-12-03 17:40:11 -08002161 if (inOutConfig.orientation == ORIENTATION_UNDEFINED) {
Evan Rosky1ac84462018-11-13 11:25:30 -08002162 inOutConfig.orientation = (inOutConfig.screenWidthDp <= inOutConfig.screenHeightDp)
Riddle Hsu0a343c32018-12-21 00:40:48 +08002163 ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE;
Evan Rosky1ac84462018-11-13 11:25:30 -08002164 }
2165 if (inOutConfig.screenLayout == Configuration.SCREENLAYOUT_UNDEFINED) {
2166 // For calculating screen layout, we need to use the non-decor inset screen area for the
2167 // calculation for compatibility reasons, i.e. screen area without system bars that
2168 // could never go away in Honeycomb.
2169 final int compatScreenWidthDp = (int) (mTmpNonDecorBounds.width() / density);
2170 final int compatScreenHeightDp = (int) (mTmpNonDecorBounds.height() / density);
2171 // We're only overriding LONG, SIZE and COMPAT parts of screenLayout, so we start
2172 // override calculation with partial default.
2173 // Reducing the screen layout starting from its parent config.
2174 final int sl = parentConfig.screenLayout
2175 & (Configuration.SCREENLAYOUT_LONG_MASK | Configuration.SCREENLAYOUT_SIZE_MASK);
2176 final int longSize = Math.max(compatScreenHeightDp, compatScreenWidthDp);
2177 final int shortSize = Math.min(compatScreenHeightDp, compatScreenWidthDp);
2178 inOutConfig.screenLayout = Configuration.reduceScreenLayout(sl, longSize, shortSize);
2179 }
2180 }
2181
Evan Rosky1ac84462018-11-13 11:25:30 -08002182 @Override
2183 void resolveOverrideConfiguration(Configuration newParentConfig) {
Evan Rosky730f6e82018-12-03 17:40:11 -08002184 mTmpBounds.set(getResolvedOverrideConfiguration().windowConfiguration.getBounds());
2185 super.resolveOverrideConfiguration(newParentConfig);
2186 int windowingMode =
2187 getRequestedOverrideConfiguration().windowConfiguration.getWindowingMode();
2188 if (windowingMode == WINDOWING_MODE_UNDEFINED) {
2189 windowingMode = newParentConfig.windowConfiguration.getWindowingMode();
2190 }
2191 Rect outOverrideBounds =
2192 getResolvedOverrideConfiguration().windowConfiguration.getBounds();
2193
2194 if (windowingMode == WINDOWING_MODE_FULLSCREEN) {
2195 // In FULLSCREEN mode, always start with empty bounds to indicate "fill parent"
2196 outOverrideBounds.setEmpty();
2197
Garfield Tan49dae102019-02-04 09:51:59 -08002198 final boolean parentHandlesOrientationChange = mTask != null
2199 && mTask.getParent() != null
2200 && mTask.getParent().handlesOrientationChangeFromDescendant();
Evan Rosky130d94f2019-01-15 10:18:17 -08002201 // If the task or its top activity requires a different orientation, make it fit the
Evan Rosky730f6e82018-12-03 17:40:11 -08002202 // available bounds by scaling down its bounds.
Evan Rosky130d94f2019-01-15 10:18:17 -08002203 int forcedOrientation = getTopActivityRequestedOrientation();
Evan Rosky730f6e82018-12-03 17:40:11 -08002204 if (forcedOrientation != ORIENTATION_UNDEFINED
Garfield Tan49dae102019-02-04 09:51:59 -08002205 && forcedOrientation != newParentConfig.orientation
2206 && !parentHandlesOrientationChange) {
Evan Rosky730f6e82018-12-03 17:40:11 -08002207 final Rect parentBounds = newParentConfig.windowConfiguration.getBounds();
2208 final int parentWidth = parentBounds.width();
2209 final int parentHeight = parentBounds.height();
2210 final float aspect = ((float) parentHeight) / parentWidth;
2211 if (forcedOrientation == ORIENTATION_LANDSCAPE) {
2212 final int height = (int) (parentWidth / aspect);
2213 final int top = parentBounds.centerY() - height / 2;
2214 outOverrideBounds.set(
2215 parentBounds.left, top, parentBounds.right, top + height);
2216 } else {
2217 final int width = (int) (parentHeight * aspect);
2218 final int left = parentBounds.centerX() - width / 2;
2219 outOverrideBounds.set(
2220 left, parentBounds.top, left + width, parentBounds.bottom);
2221 }
2222 }
2223 }
2224
2225 if (outOverrideBounds.isEmpty()) {
2226 // If the task fills the parent, just inherit all the other configs from parent.
2227 return;
2228 }
2229
2230 adjustForMinimalTaskDimensions(outOverrideBounds, mTmpBounds);
2231 if (windowingMode == WINDOWING_MODE_FREEFORM) {
2232 // by policy, make sure the window remains within parent somewhere
2233 fitWithinBounds(outOverrideBounds, newParentConfig.windowConfiguration.getBounds());
2234 }
2235 computeConfigResourceOverrides(getResolvedOverrideConfiguration(), newParentConfig);
Jorim Jaggia95ca8d2016-01-15 22:54:46 -08002236 }
2237
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08002238 Rect updateOverrideConfigurationFromLaunchBounds() {
Bryce Leef3c6a472017-11-14 14:53:06 -08002239 final Rect bounds = getLaunchBounds();
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08002240 updateOverrideConfiguration(bounds);
Bryce Leef3c6a472017-11-14 14:53:06 -08002241 if (bounds != null && !bounds.isEmpty()) {
2242 // TODO: Review if we actually want to do this - we are setting the launch bounds
2243 // directly here.
Evan Roskydfe3da72018-10-26 17:21:06 -07002244 bounds.set(getRequestedOverrideBounds());
Andrii Kulian73336d812016-03-24 12:56:08 -07002245 }
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08002246 return bounds;
2247 }
2248
Wale Ogunwale935e5022015-11-10 12:36:10 -08002249 /** Updates the task's bounds and override configuration to match what is expected for the
2250 * input stack. */
2251 void updateOverrideConfigurationForStack(ActivityStack inStack) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07002252 if (mStack != null && mStack == inStack) {
Wale Ogunwale935e5022015-11-10 12:36:10 -08002253 return;
2254 }
2255
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002256 if (inStack.inFreeformWindowingMode()) {
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002257 if (!isResizeable()) {
Wale Ogunwale935e5022015-11-10 12:36:10 -08002258 throw new IllegalArgumentException("Can not position non-resizeable task="
2259 + this + " in stack=" + inStack);
2260 }
Bryce Leef3c6a472017-11-14 14:53:06 -08002261 if (!matchParentBounds()) {
Wale Ogunwale935e5022015-11-10 12:36:10 -08002262 return;
2263 }
2264 if (mLastNonFullscreenBounds != null) {
2265 updateOverrideConfiguration(mLastNonFullscreenBounds);
2266 } else {
Bryce Leeec55eb02017-12-05 20:51:27 -08002267 mService.mStackSupervisor.getLaunchParamsController().layoutTask(this, null);
Wale Ogunwale935e5022015-11-10 12:36:10 -08002268 }
2269 } else {
Evan Roskydfe3da72018-10-26 17:21:06 -07002270 updateOverrideConfiguration(inStack.getRequestedOverrideBounds());
Wale Ogunwale935e5022015-11-10 12:36:10 -08002271 }
2272 }
2273
Wale Ogunwale706ed792015-08-02 10:29:44 -07002274 /** Returns the bounds that should be used to launch this task. */
Wale Ogunwale30e441d2017-11-09 08:28:45 -08002275 Rect getLaunchBounds() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07002276 if (mStack == null) {
Chong Zhang7d5f5102016-01-13 10:29:24 -08002277 return null;
2278 }
2279
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002280 final int windowingMode = getWindowingMode();
2281 if (!isActivityTypeStandardOrUndefined()
2282 || windowingMode == WINDOWING_MODE_FULLSCREEN
2283 || (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY && !isResizeable())) {
Evan Roskydfe3da72018-10-26 17:21:06 -07002284 return isResizeable() ? mStack.getRequestedOverrideBounds() : null;
Wale Ogunwale3382ab12017-07-27 08:55:03 -07002285 } else if (!getWindowConfiguration().persistTaskBounds()) {
Evan Roskydfe3da72018-10-26 17:21:06 -07002286 return mStack.getRequestedOverrideBounds();
Wale Ogunwale706ed792015-08-02 10:29:44 -07002287 }
2288 return mLastNonFullscreenBounds;
2289 }
2290
Jorim Jaggi8b702ed2017-01-20 16:59:03 +01002291 void addStartingWindowsForVisibleActivities(boolean taskSwitch) {
2292 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
2293 final ActivityRecord r = mActivities.get(activityNdx);
2294 if (r.visible) {
2295 r.showStartingWindow(null /* prev */, false /* newTask */, taskSwitch);
2296 }
2297 }
2298 }
2299
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002300 void setRootProcess(WindowProcessController proc) {
Dianne Hackborn68a06332017-11-15 17:54:18 -08002301 clearRootProcess();
2302 if (intent != null &&
2303 (intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0) {
2304 mRootProcess = proc;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002305 mRootProcess.addRecentTask(this);
Dianne Hackborn68a06332017-11-15 17:54:18 -08002306 }
2307 }
2308
2309 void clearRootProcess() {
2310 if (mRootProcess != null) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002311 mRootProcess.removeRecentTask(this);
Dianne Hackborn68a06332017-11-15 17:54:18 -08002312 mRootProcess = null;
2313 }
2314 }
2315
chaviw82a0ba82018-03-15 14:26:29 -07002316 void clearAllPendingOptions() {
2317 for (int i = getChildCount() - 1; i >= 0; i--) {
2318 getChildAt(i).clearOptionsLocked(false /* withAbort */);
2319 }
2320 }
2321
Winson Chungabfdcce2018-07-02 17:23:33 -07002322 /**
2323 * Fills in a {@link TaskInfo} with information from this task.
2324 * @param info the {@link TaskInfo} to fill in
Winson Chungabfdcce2018-07-02 17:23:33 -07002325 */
Mark Renoufc808f062019-02-07 15:20:37 -05002326 void fillTaskInfo(TaskInfo info) {
2327 getNumRunningActivities(mReuseActivitiesReport);
Winson Chungabfdcce2018-07-02 17:23:33 -07002328 info.userId = userId;
2329 info.stackId = getStackId();
2330 info.taskId = taskId;
Mark Renoufb1abb552019-02-08 13:51:41 -05002331 info.displayId = mStack == null ? Display.INVALID_DISPLAY : mStack.mDisplayId;
Winson Chungabfdcce2018-07-02 17:23:33 -07002332 info.isRunning = getTopActivity() != null;
Riddle Hsu2f9acd22018-11-06 23:44:43 +08002333 info.baseIntent = new Intent(getBaseIntent());
Mark Renoufc808f062019-02-07 15:20:37 -05002334 info.baseActivity = mReuseActivitiesReport.base != null
2335 ? mReuseActivitiesReport.base.intent.getComponent()
Winson Chungabfdcce2018-07-02 17:23:33 -07002336 : null;
Mark Renoufc808f062019-02-07 15:20:37 -05002337 info.topActivity = mReuseActivitiesReport.top != null
2338 ? mReuseActivitiesReport.top.mActivityComponent
Winson Chungabfdcce2018-07-02 17:23:33 -07002339 : null;
2340 info.origActivity = origActivity;
2341 info.realActivity = realActivity;
Mark Renoufc808f062019-02-07 15:20:37 -05002342 info.numActivities = mReuseActivitiesReport.numActivities;
Winson Chungabfdcce2018-07-02 17:23:33 -07002343 info.lastActiveTime = lastActiveTime;
2344 info.taskDescription = new ActivityManager.TaskDescription(lastTaskDescription);
2345 info.supportsSplitScreenMultiWindow = supportsSplitScreenWindowingMode();
2346 info.resizeMode = mResizeMode;
2347 info.configuration.setTo(getConfiguration());
2348 }
2349
Mark Renoufc808f062019-02-07 15:20:37 -05002350 /**
2351 * Returns a {@link TaskInfo} with information from this task.
2352 */
2353 ActivityManager.RunningTaskInfo getTaskInfo() {
2354 ActivityManager.RunningTaskInfo info = new ActivityManager.RunningTaskInfo();
2355 fillTaskInfo(info);
2356 return info;
2357 }
2358
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002359 void dump(PrintWriter pw, String prefix) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002360 pw.print(prefix); pw.print("userId="); pw.print(userId);
Dianne Hackborn885fbe52014-08-23 15:23:58 -07002361 pw.print(" effectiveUid="); UserHandle.formatUid(pw, effectiveUid);
2362 pw.print(" mCallingUid="); UserHandle.formatUid(pw, mCallingUid);
Suprabh Shukla7745c142016-03-07 18:21:10 -08002363 pw.print(" mUserSetupComplete="); pw.print(mUserSetupComplete);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002364 pw.print(" mCallingPackage="); pw.println(mCallingPackage);
Dianne Hackborn79228822014-09-16 11:11:23 -07002365 if (affinity != null || rootAffinity != null) {
2366 pw.print(prefix); pw.print("affinity="); pw.print(affinity);
2367 if (affinity == null || !affinity.equals(rootAffinity)) {
2368 pw.print(" root="); pw.println(rootAffinity);
2369 } else {
2370 pw.println();
2371 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002372 }
Dianne Hackborn91097de2014-04-04 18:02:06 -07002373 if (voiceSession != null || voiceInteractor != null) {
2374 pw.print(prefix); pw.print("VOICE: session=0x");
2375 pw.print(Integer.toHexString(System.identityHashCode(voiceSession)));
2376 pw.print(" interactor=0x");
2377 pw.println(Integer.toHexString(System.identityHashCode(voiceInteractor)));
2378 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002379 if (intent != null) {
2380 StringBuilder sb = new StringBuilder(128);
2381 sb.append(prefix); sb.append("intent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08002382 intent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002383 sb.append('}');
2384 pw.println(sb.toString());
2385 }
2386 if (affinityIntent != null) {
2387 StringBuilder sb = new StringBuilder(128);
2388 sb.append(prefix); sb.append("affinityIntent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08002389 affinityIntent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002390 sb.append('}');
2391 pw.println(sb.toString());
2392 }
2393 if (origActivity != null) {
2394 pw.print(prefix); pw.print("origActivity=");
2395 pw.println(origActivity.flattenToShortString());
2396 }
2397 if (realActivity != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002398 pw.print(prefix); pw.print("mActivityComponent=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002399 pw.println(realActivity.flattenToShortString());
2400 }
Wale Ogunwale66e16852017-10-19 13:35:52 -07002401 if (autoRemoveRecents || isPersistable || !isActivityTypeStandard() || numFullscreen != 0) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002402 pw.print(prefix); pw.print("autoRemoveRecents="); pw.print(autoRemoveRecents);
Dianne Hackborn852975d2014-08-22 17:42:43 -07002403 pw.print(" isPersistable="); pw.print(isPersistable);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002404 pw.print(" numFullscreen="); pw.print(numFullscreen);
Wale Ogunwale66e16852017-10-19 13:35:52 -07002405 pw.print(" activityType="); pw.println(getActivityType());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002406 }
Craig Mautner432f64e2015-05-20 14:59:57 -07002407 if (rootWasReset || mNeverRelinquishIdentity || mReuseTask
2408 || mLockTaskAuth != LOCK_TASK_AUTH_PINNABLE) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002409 pw.print(prefix); pw.print("rootWasReset="); pw.print(rootWasReset);
2410 pw.print(" mNeverRelinquishIdentity="); pw.print(mNeverRelinquishIdentity);
Craig Mautner432f64e2015-05-20 14:59:57 -07002411 pw.print(" mReuseTask="); pw.print(mReuseTask);
2412 pw.print(" mLockTaskAuth="); pw.println(lockTaskAuthToString());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002413 }
Wale Ogunwale18795a22014-12-03 11:38:33 -08002414 if (mAffiliatedTaskId != taskId || mPrevAffiliateTaskId != INVALID_TASK_ID
2415 || mPrevAffiliate != null || mNextAffiliateTaskId != INVALID_TASK_ID
2416 || mNextAffiliate != null) {
Dianne Hackborn852975d2014-08-22 17:42:43 -07002417 pw.print(prefix); pw.print("affiliation="); pw.print(mAffiliatedTaskId);
2418 pw.print(" prevAffiliation="); pw.print(mPrevAffiliateTaskId);
2419 pw.print(" (");
2420 if (mPrevAffiliate == null) {
2421 pw.print("null");
2422 } else {
2423 pw.print(Integer.toHexString(System.identityHashCode(mPrevAffiliate)));
2424 }
2425 pw.print(") nextAffiliation="); pw.print(mNextAffiliateTaskId);
2426 pw.print(" (");
2427 if (mNextAffiliate == null) {
2428 pw.print("null");
2429 } else {
2430 pw.print(Integer.toHexString(System.identityHashCode(mNextAffiliate)));
2431 }
2432 pw.println(")");
2433 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002434 pw.print(prefix); pw.print("Activities="); pw.println(mActivities);
Dianne Hackborn852975d2014-08-22 17:42:43 -07002435 if (!askedCompatMode || !inRecents || !isAvailable) {
2436 pw.print(prefix); pw.print("askedCompatMode="); pw.print(askedCompatMode);
2437 pw.print(" inRecents="); pw.print(inRecents);
2438 pw.print(" isAvailable="); pw.println(isAvailable);
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002439 }
Dianne Hackborn852975d2014-08-22 17:42:43 -07002440 if (lastDescription != null) {
2441 pw.print(prefix); pw.print("lastDescription="); pw.println(lastDescription);
2442 }
Dianne Hackborn68a06332017-11-15 17:54:18 -08002443 if (mRootProcess != null) {
2444 pw.print(prefix); pw.print("mRootProcess="); pw.println(mRootProcess);
2445 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07002446 pw.print(prefix); pw.print("stackId="); pw.println(getStackId());
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002447 pw.print(prefix + "hasBeenVisible=" + hasBeenVisible);
2448 pw.print(" mResizeMode=" + ActivityInfo.resizeModeToString(mResizeMode));
Winson Chungd3395382016-12-13 11:49:09 -08002449 pw.print(" mSupportsPictureInPicture=" + mSupportsPictureInPicture);
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002450 pw.print(" isResizeable=" + isResizeable());
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002451 pw.print(" lastActiveTime=" + lastActiveTime);
2452 pw.println(" (inactive for " + (getInactiveDuration() / 1000) + "s)");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002453 }
2454
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002455 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002456 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002457 StringBuilder sb = new StringBuilder(128);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002458 if (stringName != null) {
2459 sb.append(stringName);
2460 sb.append(" U=");
2461 sb.append(userId);
Wale Ogunwale6c5eb1c2015-11-10 07:52:22 -08002462 sb.append(" StackId=");
Andrii Kulian02b7a832016-10-06 23:11:56 -07002463 sb.append(getStackId());
Craig Mautnerde4ef022013-04-07 19:01:33 -07002464 sb.append(" sz=");
2465 sb.append(mActivities.size());
2466 sb.append('}');
2467 return sb.toString();
2468 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002469 sb.append("TaskRecord{");
2470 sb.append(Integer.toHexString(System.identityHashCode(this)));
2471 sb.append(" #");
2472 sb.append(taskId);
2473 if (affinity != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002474 sb.append(" A=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002475 sb.append(affinity);
2476 } else if (intent != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002477 sb.append(" I=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002478 sb.append(intent.getComponent().flattenToShortString());
Bryce Leefbd263b42018-03-07 10:33:55 -08002479 } else if (affinityIntent != null && affinityIntent.getComponent() != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002480 sb.append(" aI=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002481 sb.append(affinityIntent.getComponent().flattenToShortString());
2482 } else {
2483 sb.append(" ??");
2484 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07002485 stringName = sb.toString();
2486 return toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002487 }
Steven Timotius4346f0a2017-09-12 11:07:21 -07002488
Nataniel Borges023ecb52019-01-16 14:15:43 -08002489 public void writeToProto(ProtoOutputStream proto, long fieldId,
2490 @WindowTraceLogLevel int logLevel) {
2491 if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) {
2492 return;
2493 }
2494
Steven Timotius4346f0a2017-09-12 11:07:21 -07002495 final long token = proto.start(fieldId);
Nataniel Borges023ecb52019-01-16 14:15:43 -08002496 super.writeToProto(proto, CONFIGURATION_CONTAINER, logLevel);
Steven Timotius4346f0a2017-09-12 11:07:21 -07002497 proto.write(ID, taskId);
2498 for (int i = mActivities.size() - 1; i >= 0; i--) {
2499 ActivityRecord activity = mActivities.get(i);
2500 activity.writeToProto(proto, ACTIVITIES);
2501 }
2502 proto.write(STACK_ID, mStack.mStackId);
2503 if (mLastNonFullscreenBounds != null) {
2504 mLastNonFullscreenBounds.writeToProto(proto, LAST_NON_FULLSCREEN_BOUNDS);
2505 }
2506 if (realActivity != null) {
2507 proto.write(REAL_ACTIVITY, realActivity.flattenToShortString());
2508 }
2509 if (origActivity != null) {
2510 proto.write(ORIG_ACTIVITY, origActivity.flattenToShortString());
2511 }
2512 proto.write(ACTIVITY_TYPE, getActivityType());
Steven Timotius4346f0a2017-09-12 11:07:21 -07002513 proto.write(RESIZE_MODE, mResizeMode);
Bryce Leef3c6a472017-11-14 14:53:06 -08002514 // TODO: Remove, no longer needed with windowingMode.
2515 proto.write(FULLSCREEN, matchParentBounds());
2516
2517 if (!matchParentBounds()) {
Evan Roskydfe3da72018-10-26 17:21:06 -07002518 final Rect bounds = getRequestedOverrideBounds();
Bryce Leef3c6a472017-11-14 14:53:06 -08002519 bounds.writeToProto(proto, BOUNDS);
Steven Timotius4346f0a2017-09-12 11:07:21 -07002520 }
2521 proto.write(MIN_WIDTH, mMinWidth);
2522 proto.write(MIN_HEIGHT, mMinHeight);
2523 proto.end(token);
2524 }
Winson Chung61c9e5a2017-10-11 10:39:32 -07002525
2526 /**
2527 * See {@link #getNumRunningActivities(TaskActivitiesReport)}.
2528 */
2529 static class TaskActivitiesReport {
2530 int numRunning;
2531 int numActivities;
2532 ActivityRecord top;
2533 ActivityRecord base;
2534
2535 void reset() {
2536 numRunning = numActivities = 0;
2537 top = base = null;
2538 }
2539 }
Garfield Tan9b1efea2017-12-05 16:43:46 -08002540
2541 /**
2542 * Saves this {@link TaskRecord} to XML using given serializer.
2543 */
2544 void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
2545 if (DEBUG_RECENTS) Slog.i(TAG_RECENTS, "Saving task=" + this);
2546
2547 out.attribute(null, ATTR_TASKID, String.valueOf(taskId));
2548 if (realActivity != null) {
2549 out.attribute(null, ATTR_REALACTIVITY, realActivity.flattenToShortString());
2550 }
2551 out.attribute(null, ATTR_REALACTIVITY_SUSPENDED, String.valueOf(realActivitySuspended));
2552 if (origActivity != null) {
2553 out.attribute(null, ATTR_ORIGACTIVITY, origActivity.flattenToShortString());
2554 }
2555 // Write affinity, and root affinity if it is different from affinity.
2556 // We use the special string "@" for a null root affinity, so we can identify
2557 // later whether we were given a root affinity or should just make it the
2558 // same as the affinity.
2559 if (affinity != null) {
2560 out.attribute(null, ATTR_AFFINITY, affinity);
2561 if (!affinity.equals(rootAffinity)) {
2562 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
2563 }
2564 } else if (rootAffinity != null) {
2565 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
2566 }
2567 out.attribute(null, ATTR_ROOTHASRESET, String.valueOf(rootWasReset));
2568 out.attribute(null, ATTR_AUTOREMOVERECENTS, String.valueOf(autoRemoveRecents));
2569 out.attribute(null, ATTR_ASKEDCOMPATMODE, String.valueOf(askedCompatMode));
2570 out.attribute(null, ATTR_USERID, String.valueOf(userId));
2571 out.attribute(null, ATTR_USER_SETUP_COMPLETE, String.valueOf(mUserSetupComplete));
2572 out.attribute(null, ATTR_EFFECTIVE_UID, String.valueOf(effectiveUid));
2573 out.attribute(null, ATTR_LASTTIMEMOVED, String.valueOf(mLastTimeMoved));
2574 out.attribute(null, ATTR_NEVERRELINQUISH, String.valueOf(mNeverRelinquishIdentity));
2575 if (lastDescription != null) {
2576 out.attribute(null, ATTR_LASTDESCRIPTION, lastDescription.toString());
2577 }
2578 if (lastTaskDescription != null) {
2579 lastTaskDescription.saveToXml(out);
2580 }
2581 out.attribute(null, ATTR_TASK_AFFILIATION_COLOR, String.valueOf(mAffiliatedTaskColor));
2582 out.attribute(null, ATTR_TASK_AFFILIATION, String.valueOf(mAffiliatedTaskId));
2583 out.attribute(null, ATTR_PREV_AFFILIATION, String.valueOf(mPrevAffiliateTaskId));
2584 out.attribute(null, ATTR_NEXT_AFFILIATION, String.valueOf(mNextAffiliateTaskId));
2585 out.attribute(null, ATTR_CALLING_UID, String.valueOf(mCallingUid));
2586 out.attribute(null, ATTR_CALLING_PACKAGE, mCallingPackage == null ? "" : mCallingPackage);
2587 out.attribute(null, ATTR_RESIZE_MODE, String.valueOf(mResizeMode));
2588 out.attribute(null, ATTR_SUPPORTS_PICTURE_IN_PICTURE,
2589 String.valueOf(mSupportsPictureInPicture));
2590 if (mLastNonFullscreenBounds != null) {
2591 out.attribute(
2592 null, ATTR_NON_FULLSCREEN_BOUNDS, mLastNonFullscreenBounds.flattenToString());
2593 }
2594 out.attribute(null, ATTR_MIN_WIDTH, String.valueOf(mMinWidth));
2595 out.attribute(null, ATTR_MIN_HEIGHT, String.valueOf(mMinHeight));
2596 out.attribute(null, ATTR_PERSIST_TASK_VERSION, String.valueOf(PERSIST_TASK_VERSION));
2597
2598 if (affinityIntent != null) {
2599 out.startTag(null, TAG_AFFINITYINTENT);
2600 affinityIntent.saveToXml(out);
2601 out.endTag(null, TAG_AFFINITYINTENT);
2602 }
2603
Bryce Lee1a990e52018-04-23 10:54:11 -07002604 if (intent != null) {
2605 out.startTag(null, TAG_INTENT);
2606 intent.saveToXml(out);
2607 out.endTag(null, TAG_INTENT);
2608 }
Garfield Tan9b1efea2017-12-05 16:43:46 -08002609
2610 final ArrayList<ActivityRecord> activities = mActivities;
2611 final int numActivities = activities.size();
2612 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
2613 final ActivityRecord r = activities.get(activityNdx);
2614 if (r.info.persistableMode == ActivityInfo.PERSIST_ROOT_ONLY || !r.isPersistable() ||
2615 ((r.intent.getFlags() & FLAG_ACTIVITY_NEW_DOCUMENT
2616 | FLAG_ACTIVITY_RETAIN_IN_RECENTS) == FLAG_ACTIVITY_NEW_DOCUMENT) &&
2617 activityNdx > 0) {
2618 // Stop at first non-persistable or first break in task (CLEAR_WHEN_TASK_RESET).
2619 break;
2620 }
2621 out.startTag(null, TAG_ACTIVITY);
2622 r.saveToXml(out);
2623 out.endTag(null, TAG_ACTIVITY);
2624 }
2625 }
2626
2627 @VisibleForTesting
2628 static TaskRecordFactory getTaskRecordFactory() {
2629 if (sTaskRecordFactory == null) {
2630 setTaskRecordFactory(new TaskRecordFactory());
2631 }
2632 return sTaskRecordFactory;
2633 }
2634
2635 static void setTaskRecordFactory(TaskRecordFactory factory) {
2636 sTaskRecordFactory = factory;
2637 }
2638
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002639 static TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002640 Intent intent, IVoiceInteractionSession voiceSession,
2641 IVoiceInteractor voiceInteractor) {
2642 return getTaskRecordFactory().create(
2643 service, taskId, info, intent, voiceSession, voiceInteractor);
2644 }
2645
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002646 static TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002647 Intent intent, TaskDescription taskDescription) {
2648 return getTaskRecordFactory().create(service, taskId, info, intent, taskDescription);
2649 }
2650
2651 static TaskRecord restoreFromXml(XmlPullParser in, ActivityStackSupervisor stackSupervisor)
2652 throws IOException, XmlPullParserException {
2653 return getTaskRecordFactory().restoreFromXml(in, stackSupervisor);
2654 }
2655
2656 /**
2657 * A factory class used to create {@link TaskRecord} or its subclass if any. This can be
2658 * specified when system boots by setting it with
2659 * {@link #setTaskRecordFactory(TaskRecordFactory)}.
2660 */
2661 static class TaskRecordFactory {
2662
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002663 TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002664 Intent intent, IVoiceInteractionSession voiceSession,
2665 IVoiceInteractor voiceInteractor) {
2666 return new TaskRecord(
2667 service, taskId, info, intent, voiceSession, voiceInteractor);
2668 }
2669
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002670 TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002671 Intent intent, TaskDescription taskDescription) {
2672 return new TaskRecord(service, taskId, info, intent, taskDescription);
2673 }
2674
2675 /**
2676 * Should only be used when we're restoring {@link TaskRecord} from storage.
2677 */
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002678 TaskRecord create(ActivityTaskManagerService service, int taskId, Intent intent,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002679 Intent affinityIntent, String affinity, String rootAffinity,
2680 ComponentName realActivity, ComponentName origActivity, boolean rootWasReset,
2681 boolean autoRemoveRecents, boolean askedCompatMode, int userId,
2682 int effectiveUid, String lastDescription, ArrayList<ActivityRecord> activities,
2683 long lastTimeMoved, boolean neverRelinquishIdentity,
2684 TaskDescription lastTaskDescription, int taskAffiliation, int prevTaskId,
2685 int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage,
2686 int resizeMode, boolean supportsPictureInPicture, boolean realActivitySuspended,
2687 boolean userSetupComplete, int minWidth, int minHeight) {
2688 return new TaskRecord(service, taskId, intent, affinityIntent, affinity,
2689 rootAffinity, realActivity, origActivity, rootWasReset, autoRemoveRecents,
2690 askedCompatMode, userId, effectiveUid, lastDescription, activities,
2691 lastTimeMoved, neverRelinquishIdentity, lastTaskDescription, taskAffiliation,
2692 prevTaskId, nextTaskId, taskAffiliationColor, callingUid, callingPackage,
2693 resizeMode, supportsPictureInPicture, realActivitySuspended, userSetupComplete,
2694 minWidth, minHeight);
2695 }
2696
2697 TaskRecord restoreFromXml(XmlPullParser in, ActivityStackSupervisor stackSupervisor)
2698 throws IOException, XmlPullParserException {
2699 Intent intent = null;
2700 Intent affinityIntent = null;
2701 ArrayList<ActivityRecord> activities = new ArrayList<>();
2702 ComponentName realActivity = null;
2703 boolean realActivitySuspended = false;
2704 ComponentName origActivity = null;
2705 String affinity = null;
2706 String rootAffinity = null;
2707 boolean hasRootAffinity = false;
2708 boolean rootHasReset = false;
2709 boolean autoRemoveRecents = false;
2710 boolean askedCompatMode = false;
2711 int taskType = 0;
2712 int userId = 0;
2713 boolean userSetupComplete = true;
2714 int effectiveUid = -1;
2715 String lastDescription = null;
2716 long lastTimeOnTop = 0;
2717 boolean neverRelinquishIdentity = true;
2718 int taskId = INVALID_TASK_ID;
2719 final int outerDepth = in.getDepth();
2720 TaskDescription taskDescription = new TaskDescription();
2721 int taskAffiliation = INVALID_TASK_ID;
2722 int taskAffiliationColor = 0;
2723 int prevTaskId = INVALID_TASK_ID;
2724 int nextTaskId = INVALID_TASK_ID;
2725 int callingUid = -1;
2726 String callingPackage = "";
2727 int resizeMode = RESIZE_MODE_FORCE_RESIZEABLE;
2728 boolean supportsPictureInPicture = false;
Garfield Tan367b35a2017-12-13 12:16:21 -08002729 Rect lastNonFullscreenBounds = null;
Garfield Tan9b1efea2017-12-05 16:43:46 -08002730 int minWidth = INVALID_MIN_SIZE;
2731 int minHeight = INVALID_MIN_SIZE;
2732 int persistTaskVersion = 0;
2733
2734 for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
2735 final String attrName = in.getAttributeName(attrNdx);
2736 final String attrValue = in.getAttributeValue(attrNdx);
2737 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: attribute name=" +
2738 attrName + " value=" + attrValue);
2739 switch (attrName) {
2740 case ATTR_TASKID:
2741 if (taskId == INVALID_TASK_ID) taskId = Integer.parseInt(attrValue);
2742 break;
2743 case ATTR_REALACTIVITY:
2744 realActivity = ComponentName.unflattenFromString(attrValue);
2745 break;
2746 case ATTR_REALACTIVITY_SUSPENDED:
2747 realActivitySuspended = Boolean.valueOf(attrValue);
2748 break;
2749 case ATTR_ORIGACTIVITY:
2750 origActivity = ComponentName.unflattenFromString(attrValue);
2751 break;
2752 case ATTR_AFFINITY:
2753 affinity = attrValue;
2754 break;
2755 case ATTR_ROOT_AFFINITY:
2756 rootAffinity = attrValue;
2757 hasRootAffinity = true;
2758 break;
2759 case ATTR_ROOTHASRESET:
2760 rootHasReset = Boolean.parseBoolean(attrValue);
2761 break;
2762 case ATTR_AUTOREMOVERECENTS:
2763 autoRemoveRecents = Boolean.parseBoolean(attrValue);
2764 break;
2765 case ATTR_ASKEDCOMPATMODE:
2766 askedCompatMode = Boolean.parseBoolean(attrValue);
2767 break;
2768 case ATTR_USERID:
2769 userId = Integer.parseInt(attrValue);
2770 break;
2771 case ATTR_USER_SETUP_COMPLETE:
2772 userSetupComplete = Boolean.parseBoolean(attrValue);
2773 break;
2774 case ATTR_EFFECTIVE_UID:
2775 effectiveUid = Integer.parseInt(attrValue);
2776 break;
2777 case ATTR_TASKTYPE:
2778 taskType = Integer.parseInt(attrValue);
2779 break;
2780 case ATTR_LASTDESCRIPTION:
2781 lastDescription = attrValue;
2782 break;
2783 case ATTR_LASTTIMEMOVED:
2784 lastTimeOnTop = Long.parseLong(attrValue);
2785 break;
2786 case ATTR_NEVERRELINQUISH:
2787 neverRelinquishIdentity = Boolean.parseBoolean(attrValue);
2788 break;
2789 case ATTR_TASK_AFFILIATION:
2790 taskAffiliation = Integer.parseInt(attrValue);
2791 break;
2792 case ATTR_PREV_AFFILIATION:
2793 prevTaskId = Integer.parseInt(attrValue);
2794 break;
2795 case ATTR_NEXT_AFFILIATION:
2796 nextTaskId = Integer.parseInt(attrValue);
2797 break;
2798 case ATTR_TASK_AFFILIATION_COLOR:
2799 taskAffiliationColor = Integer.parseInt(attrValue);
2800 break;
2801 case ATTR_CALLING_UID:
2802 callingUid = Integer.parseInt(attrValue);
2803 break;
2804 case ATTR_CALLING_PACKAGE:
2805 callingPackage = attrValue;
2806 break;
2807 case ATTR_RESIZE_MODE:
2808 resizeMode = Integer.parseInt(attrValue);
2809 break;
2810 case ATTR_SUPPORTS_PICTURE_IN_PICTURE:
2811 supportsPictureInPicture = Boolean.parseBoolean(attrValue);
2812 break;
2813 case ATTR_NON_FULLSCREEN_BOUNDS:
Garfield Tan367b35a2017-12-13 12:16:21 -08002814 lastNonFullscreenBounds = Rect.unflattenFromString(attrValue);
Garfield Tan9b1efea2017-12-05 16:43:46 -08002815 break;
2816 case ATTR_MIN_WIDTH:
2817 minWidth = Integer.parseInt(attrValue);
2818 break;
2819 case ATTR_MIN_HEIGHT:
2820 minHeight = Integer.parseInt(attrValue);
2821 break;
2822 case ATTR_PERSIST_TASK_VERSION:
2823 persistTaskVersion = Integer.parseInt(attrValue);
2824 break;
2825 default:
2826 if (attrName.startsWith(TaskDescription.ATTR_TASKDESCRIPTION_PREFIX)) {
2827 taskDescription.restoreFromXml(attrName, attrValue);
2828 } else {
2829 Slog.w(TAG, "TaskRecord: Unknown attribute=" + attrName);
2830 }
2831 }
2832 }
2833
2834 int event;
2835 while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
2836 (event != XmlPullParser.END_TAG || in.getDepth() >= outerDepth)) {
2837 if (event == XmlPullParser.START_TAG) {
2838 final String name = in.getName();
2839 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG,
2840 "TaskRecord: START_TAG name=" + name);
2841 if (TAG_AFFINITYINTENT.equals(name)) {
2842 affinityIntent = Intent.restoreFromXml(in);
2843 } else if (TAG_INTENT.equals(name)) {
2844 intent = Intent.restoreFromXml(in);
2845 } else if (TAG_ACTIVITY.equals(name)) {
2846 ActivityRecord activity =
2847 ActivityRecord.restoreFromXml(in, stackSupervisor);
2848 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: activity=" +
2849 activity);
2850 if (activity != null) {
2851 activities.add(activity);
2852 }
2853 } else {
Garfield Tan1e740192017-12-12 14:37:42 -08002854 handleUnknownTag(name, in);
Garfield Tan9b1efea2017-12-05 16:43:46 -08002855 }
2856 }
2857 }
2858 if (!hasRootAffinity) {
2859 rootAffinity = affinity;
2860 } else if ("@".equals(rootAffinity)) {
2861 rootAffinity = null;
2862 }
2863 if (effectiveUid <= 0) {
2864 Intent checkIntent = intent != null ? intent : affinityIntent;
2865 effectiveUid = 0;
2866 if (checkIntent != null) {
2867 IPackageManager pm = AppGlobals.getPackageManager();
2868 try {
2869 ApplicationInfo ai = pm.getApplicationInfo(
2870 checkIntent.getComponent().getPackageName(),
2871 PackageManager.MATCH_UNINSTALLED_PACKAGES
2872 | PackageManager.MATCH_DISABLED_COMPONENTS, userId);
2873 if (ai != null) {
2874 effectiveUid = ai.uid;
2875 }
2876 } catch (RemoteException e) {
2877 }
2878 }
2879 Slog.w(TAG, "Updating task #" + taskId + " for " + checkIntent
2880 + ": effectiveUid=" + effectiveUid);
2881 }
2882
2883 if (persistTaskVersion < 1) {
2884 // We need to convert the resize mode of home activities saved before version one if
2885 // they are marked as RESIZE_MODE_RESIZEABLE to
2886 // RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION since we didn't have that differentiation
2887 // before version 1 and the system didn't resize home activities before then.
2888 if (taskType == 1 /* old home type */ && resizeMode == RESIZE_MODE_RESIZEABLE) {
2889 resizeMode = RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
2890 }
2891 } else {
2892 // This activity has previously marked itself explicitly as both resizeable and
2893 // supporting picture-in-picture. Since there is no longer a requirement for
2894 // picture-in-picture activities to be resizeable, we can mark this simply as
2895 // resizeable and supporting picture-in-picture separately.
2896 if (resizeMode == RESIZE_MODE_RESIZEABLE_AND_PIPABLE_DEPRECATED) {
2897 resizeMode = RESIZE_MODE_RESIZEABLE;
2898 supportsPictureInPicture = true;
2899 }
2900 }
2901
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07002902 final TaskRecord task = create(stackSupervisor.mService,
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002903 taskId, intent, affinityIntent,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002904 affinity, rootAffinity, realActivity, origActivity, rootHasReset,
2905 autoRemoveRecents, askedCompatMode, userId, effectiveUid, lastDescription,
2906 activities, lastTimeOnTop, neverRelinquishIdentity, taskDescription,
2907 taskAffiliation, prevTaskId, nextTaskId, taskAffiliationColor, callingUid,
2908 callingPackage, resizeMode, supportsPictureInPicture, realActivitySuspended,
2909 userSetupComplete, minWidth, minHeight);
Garfield Tan367b35a2017-12-13 12:16:21 -08002910 task.mLastNonFullscreenBounds = lastNonFullscreenBounds;
2911 task.setBounds(lastNonFullscreenBounds);
Garfield Tan9b1efea2017-12-05 16:43:46 -08002912
2913 for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {
2914 activities.get(activityNdx).setTask(task);
2915 }
2916
2917 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Restored task=" + task);
2918 return task;
2919 }
Garfield Tan1e740192017-12-12 14:37:42 -08002920
2921 void handleUnknownTag(String name, XmlPullParser in)
2922 throws IOException, XmlPullParserException {
2923 Slog.e(TAG, "restoreTask: Unexpected name=" + name);
2924 XmlUtils.skipCurrentTag(in);
2925 }
Garfield Tan9b1efea2017-12-05 16:43:46 -08002926 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002927}