blob: 4aca9c8a1520a923f11bf31ae8540d5a9a206f3e [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
Garfield Tan9b1efea2017-12-05 16:43:46 -0800344 /**
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700345 * Don't use constructor directly. Use {@link #create(ActivityTaskManagerService, int,
346 * ActivityInfo, Intent, TaskDescription)} instead.
Garfield Tan9b1efea2017-12-05 16:43:46 -0800347 */
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700348 TaskRecord(ActivityTaskManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700349 IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700350 mService = service;
Suprabh Shukla23593142015-11-03 17:31:15 -0800351 userId = UserHandle.getUserId(info.applicationInfo.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800352 taskId = _taskId;
Winson Chungfb44d212017-10-04 11:39:10 -0700353 lastActiveTime = SystemClock.elapsedRealtime();
Craig Mautnera228ae92014-07-09 05:44:55 -0700354 mAffiliatedTaskId = _taskId;
Dianne Hackborn91097de2014-04-04 18:02:06 -0700355 voiceSession = _voiceSession;
356 voiceInteractor = _voiceInteractor;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700357 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800358 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700359 mCallingUid = info.applicationInfo.uid;
360 mCallingPackage = info.packageName;
Martijn Coenend4a69702014-06-30 11:12:17 -0700361 setIntent(_intent, info);
Andrii Kulian2e751b82016-03-16 16:59:32 -0700362 setMinDimensions(info);
Winson730bf062016-03-31 18:04:56 -0700363 touchActiveTime();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700364 mService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
Craig Mautner21d24a22014-04-23 11:45:37 -0700365 }
366
Garfield Tan9b1efea2017-12-05 16:43:46 -0800367 /**
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700368 * Don't use constructor directly.
369 * Use {@link #create(ActivityTaskManagerService, int, ActivityInfo,
Garfield Tan9b1efea2017-12-05 16:43:46 -0800370 * Intent, IVoiceInteractionSession, IVoiceInteractor)} instead.
371 */
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700372 TaskRecord(ActivityTaskManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200373 TaskDescription _taskDescription) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700374 mService = service;
Suprabh Shukla23593142015-11-03 17:31:15 -0800375 userId = UserHandle.getUserId(info.applicationInfo.uid);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700376 taskId = _taskId;
Winson Chungfb44d212017-10-04 11:39:10 -0700377 lastActiveTime = SystemClock.elapsedRealtime();
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700378 mAffiliatedTaskId = _taskId;
379 voiceSession = null;
380 voiceInteractor = null;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700381 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800382 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700383 mCallingUid = info.applicationInfo.uid;
384 mCallingPackage = info.packageName;
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700385 setIntent(_intent, info);
Andrii Kulian2e751b82016-03-16 16:59:32 -0700386 setMinDimensions(info);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700387
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700388 isPersistable = true;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700389 // Clamp to [1, max].
390 maxRecents = Math.min(Math.max(info.maxRecents, 1),
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700391 ActivityTaskManager.getMaxAppRecentsLimitStatic());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700392
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700393 lastTaskDescription = _taskDescription;
Winson730bf062016-03-31 18:04:56 -0700394 touchActiveTime();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700395 mService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700396 }
397
Garfield Tan9b1efea2017-12-05 16:43:46 -0800398 /**
399 * Don't use constructor directly. This is only used by XML parser.
400 */
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700401 TaskRecord(ActivityTaskManagerService service, int _taskId, Intent _intent,
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800402 Intent _affinityIntent, String _affinity, String _rootAffinity,
403 ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700404 boolean _autoRemoveRecents, boolean _askedCompatMode, int _userId,
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800405 int _effectiveUid, String _lastDescription, ArrayList<ActivityRecord> activities,
Winson Chungfb44d212017-10-04 11:39:10 -0700406 long lastTimeMoved, boolean neverRelinquishIdentity,
407 TaskDescription _lastTaskDescription, int taskAffiliation, int prevTaskId,
408 int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage,
Charles He2bf28322017-10-12 22:24:49 +0100409 int resizeMode, boolean supportsPictureInPicture, boolean _realActivitySuspended,
410 boolean userSetupComplete, int minWidth, int minHeight) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700411 mService = service;
412 taskId = _taskId;
413 intent = _intent;
414 affinityIntent = _affinityIntent;
415 affinity = _affinity;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800416 rootAffinity = _rootAffinity;
Craig Mautner21d24a22014-04-23 11:45:37 -0700417 voiceSession = null;
418 voiceInteractor = null;
419 realActivity = _realActivity;
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800420 realActivitySuspended = _realActivitySuspended;
Craig Mautner21d24a22014-04-23 11:45:37 -0700421 origActivity = _origActivity;
422 rootWasReset = _rootWasReset;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700423 isAvailable = true;
Dianne Hackborn13420f22014-07-18 15:43:56 -0700424 autoRemoveRecents = _autoRemoveRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700425 askedCompatMode = _askedCompatMode;
Craig Mautner21d24a22014-04-23 11:45:37 -0700426 userId = _userId;
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800427 mUserSetupComplete = userSetupComplete;
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700428 effectiveUid = _effectiveUid;
Winson Chungfb44d212017-10-04 11:39:10 -0700429 lastActiveTime = SystemClock.elapsedRealtime();
Craig Mautner21d24a22014-04-23 11:45:37 -0700430 lastDescription = _lastDescription;
431 mActivities = activities;
432 mLastTimeMoved = lastTimeMoved;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700433 mNeverRelinquishIdentity = neverRelinquishIdentity;
Winson Chung2cb86c72014-06-25 12:03:30 -0700434 lastTaskDescription = _lastTaskDescription;
Craig Mautnera228ae92014-07-09 05:44:55 -0700435 mAffiliatedTaskId = taskAffiliation;
Winson Chungec396d62014-08-06 17:08:00 -0700436 mAffiliatedTaskColor = taskAffiliationColor;
Craig Mautnera228ae92014-07-09 05:44:55 -0700437 mPrevAffiliateTaskId = prevTaskId;
438 mNextAffiliateTaskId = nextTaskId;
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700439 mCallingUid = callingUid;
440 mCallingPackage = callingPackage;
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800441 mResizeMode = resizeMode;
Winson Chungd3395382016-12-13 11:49:09 -0800442 mSupportsPictureInPicture = supportsPictureInPicture;
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700443 mMinWidth = minWidth;
444 mMinHeight = minHeight;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700445 mService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800446 }
447
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800448 Task getTask() {
449 return mTask;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800450 }
451
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800452 void createTask(boolean onTop, boolean showForAllUsers) {
453 if (mTask != null) {
454 throw new IllegalArgumentException("mTask=" + mTask
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800455 + " already created for task=" + this);
456 }
457
458 final Rect bounds = updateOverrideConfigurationFromLaunchBounds();
Yunfan Chen279f5582018-12-12 15:24:50 -0800459 final TaskStack stack = getStack().getTaskStack();
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800460
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800461 if (stack == null) {
Yunfan Chen279f5582018-12-12 15:24:50 -0800462 throw new IllegalArgumentException("TaskRecord: invalid stack=" + mStack);
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800463 }
464 EventLog.writeEvent(WM_TASK_CREATED, taskId, stack.mStackId);
465 mTask = new Task(taskId, stack, userId, mService.mWindowManager, mResizeMode,
466 mSupportsPictureInPicture, lastTaskDescription, this);
467 final int position = onTop ? POSITION_TOP : POSITION_BOTTOM;
468
469 if (!mDisplayedBounds.isEmpty()) {
470 mTask.setOverrideDisplayedBounds(mDisplayedBounds);
471 }
472 // We only want to move the parents to the parents if we are creating this task at the
473 // top of its stack.
474 stack.addTask(mTask, position, showForAllUsers, onTop /* moveParents */);
Bryce Lee04ab3462017-04-10 15:06:33 -0700475 }
476
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800477 void setTask(Task task) {
478 mTask = task;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800479 }
480
Garfield Tan347bd602018-12-21 15:11:12 -0800481 void cleanUpResourcesForDestroy() {
482 if (!mActivities.isEmpty()) {
483 return;
484 }
485
486 // This task is going away, so save the last state if necessary.
487 saveLaunchingStateIfNeeded();
488
489 // TODO: VI what about activity?
490 final boolean isVoiceSession = voiceSession != null;
491 if (isVoiceSession) {
492 try {
493 voiceSession.taskFinished(intent, taskId);
494 } catch (RemoteException e) {
495 }
496 }
497 if (autoRemoveFromRecents() || isVoiceSession) {
498 // Task creator asked to remove this when done, or this task was a voice
499 // interaction, so it should not remain on the recent tasks list.
500 mService.mStackSupervisor.mRecentTasks.remove(this);
501 }
502
503 removeWindowContainer();
504 }
505
506 @VisibleForTesting
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800507 void removeWindowContainer() {
Bryce Lee2b8e0372018-04-05 17:01:37 -0700508 mService.getLockTaskController().clearLockedTask(this);
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800509 if (mTask == null) {
510 if (DEBUG_STACK) Slog.i(TAG_WM, "removeTask: could not find taskId=" + taskId);
511 return;
512 }
513 mTask.removeIfPossible();
514 mTask = null;
Wale Ogunwale3382ab12017-07-27 08:55:03 -0700515 if (!getWindowConfiguration().persistTaskBounds()) {
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800516 // Reset current bounds for task whose bounds shouldn't be persisted so it uses
517 // default configuration the next time it launches.
518 updateOverrideConfiguration(null);
519 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700520 mService.getTaskChangeNotificationController().notifyTaskRemoved(taskId);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800521 }
522
Jorim Jaggifb9d78a2017-01-05 18:57:12 +0100523 public void onSnapshotChanged(TaskSnapshot snapshot) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700524 mService.getTaskChangeNotificationController().notifyTaskSnapshotChanged(taskId, snapshot);
Jorim Jaggifb9d78a2017-01-05 18:57:12 +0100525 }
526
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800527 void setResizeMode(int resizeMode) {
528 if (mResizeMode == resizeMode) {
529 return;
530 }
531 mResizeMode = resizeMode;
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800532 mTask.setResizeable(resizeMode);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800533 mService.mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
534 mService.mRootActivityContainer.resumeFocusedStacksTopActivities();
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800535 }
536
537 void setTaskDockedResizing(boolean resizing) {
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800538 if (mTask == null) {
539 Slog.w(TAG_WM, "setTaskDockedResizing: taskId " + taskId + " not found.");
540 return;
541 }
542 mTask.setTaskDockedResizing(resizing);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800543 }
544
Wale Ogunwale1666e312016-12-16 11:27:18 -0800545 // TODO: Consolidate this with the resize() method below.
Wale Ogunwale1666e312016-12-16 11:27:18 -0800546 public void requestResize(Rect bounds, int resizeMode) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700547 mService.resizeTask(taskId, bounds, resizeMode);
Wale Ogunwale1666e312016-12-16 11:27:18 -0800548 }
549
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800550 boolean resize(Rect bounds, int resizeMode, boolean preserveWindow, boolean deferResume) {
Bryce Leef3c6a472017-11-14 14:53:06 -0800551 mService.mWindowManager.deferSurfaceLayout();
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800552
Bryce Leef3c6a472017-11-14 14:53:06 -0800553 try {
554 if (!isResizeable()) {
555 Slog.w(TAG, "resizeTask: task " + this + " not resizeable.");
556 return true;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800557 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800558
Bryce Leef3c6a472017-11-14 14:53:06 -0800559 // If this is a forced resize, let it go through even if the bounds is not changing,
560 // as we might need a relayout due to surface size change (to/from fullscreen).
561 final boolean forced = (resizeMode & RESIZE_MODE_FORCED) != 0;
Evan Roskydfe3da72018-10-26 17:21:06 -0700562 if (equivalentRequestedOverrideBounds(bounds) && !forced) {
Bryce Leef3c6a472017-11-14 14:53:06 -0800563 // Nothing to do here...
564 return true;
565 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800566
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800567 if (mTask == null) {
Bryce Leef3c6a472017-11-14 14:53:06 -0800568 // Task doesn't exist in window manager yet (e.g. was restored from recents).
569 // All we can do for now is update the bounds so it can be used when the task is
570 // added to window manager.
571 updateOverrideConfiguration(bounds);
572 if (!inFreeformWindowingMode()) {
573 // re-restore the task so it can have the proper stack association.
574 mService.mStackSupervisor.restoreRecentTaskLocked(this, null, !ON_TOP);
575 }
576 return true;
577 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800578
Bryce Leef3c6a472017-11-14 14:53:06 -0800579 if (!canResizeToBounds(bounds)) {
580 throw new IllegalArgumentException("resizeTask: Can not resize task=" + this
581 + " to bounds=" + bounds + " resizeMode=" + mResizeMode);
582 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800583
Bryce Leef3c6a472017-11-14 14:53:06 -0800584 // Do not move the task to another stack here.
585 // This method assumes that the task is already placed in the right stack.
586 // we do not mess with that decision and we only do the resize!
587
588 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeTask_" + taskId);
589
590 final boolean updatedConfig = updateOverrideConfiguration(bounds);
591 // This variable holds information whether the configuration didn't change in a significant
592
593 // way and the activity was kept the way it was. If it's false, it means the activity
594 // had
595 // to be relaunched due to configuration change.
596 boolean kept = true;
597 if (updatedConfig) {
598 final ActivityRecord r = topRunningActivityLocked();
599 if (r != null && !deferResume) {
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -0800600 kept = r.ensureActivityConfiguration(0 /* globalChanges */,
Bryce Leef3c6a472017-11-14 14:53:06 -0800601 preserveWindow);
Garfield Tanb9151182018-06-25 16:29:21 -0700602 // Preserve other windows for resizing because if resizing happens when there
603 // is a dialog activity in the front, the activity that still shows some
604 // content to the user will become black and cause flickers. Note in most cases
605 // this won't cause tons of irrelevant windows being preserved because only
606 // activities in this task may experience a bounds change. Configs for other
607 // activities stay the same.
Wale Ogunwaled32da472018-11-16 07:19:28 -0800608 mService.mRootActivityContainer.ensureActivitiesVisible(r, 0, preserveWindow);
Bryce Leef3c6a472017-11-14 14:53:06 -0800609 if (!kept) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800610 mService.mRootActivityContainer.resumeFocusedStacksTopActivities();
Bryce Leef3c6a472017-11-14 14:53:06 -0800611 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800612 }
613 }
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800614 mTask.resize(kept, forced);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800615
Garfield Tan891146c2018-10-09 12:14:00 -0700616 saveLaunchingStateIfNeeded();
617
Bryce Leef3c6a472017-11-14 14:53:06 -0800618 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
619 return kept;
620 } finally {
621 mService.mWindowManager.continueSurfaceLayout();
622 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800623 }
624
625 // TODO: Investigate combining with the resize() method above.
626 void resizeWindowContainer() {
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800627 mTask.resize(false /* relayout */, false /* forced */);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800628 }
629
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800630 void getWindowContainerBounds(Rect bounds) {
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800631 if (mTask != null) {
632 mTask.getBounds(bounds);
633 } else {
634 bounds.setEmpty();
635 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800636 }
637
Winson Chung74666102017-02-22 17:49:24 -0800638 /**
639 * Convenience method to reparent a task to the top or bottom position of the stack.
640 */
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700641 boolean reparent(ActivityStack preferredStack, boolean toTop,
642 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
643 String reason) {
644 return reparent(preferredStack, toTop ? MAX_VALUE : 0, moveStackMode, animate, deferResume,
645 true /* schedulePictureInPictureModeChange */, reason);
Winson Chung5af42fc2017-03-24 17:11:33 -0700646 }
647
648 /**
649 * Convenience method to reparent a task to the top or bottom position of the stack, with
650 * an option to skip scheduling the picture-in-picture mode change.
651 */
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700652 boolean reparent(ActivityStack preferredStack, boolean toTop,
653 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
654 boolean schedulePictureInPictureModeChange, String reason) {
655 return reparent(preferredStack, toTop ? MAX_VALUE : 0, moveStackMode, animate,
Winson Chung5af42fc2017-03-24 17:11:33 -0700656 deferResume, schedulePictureInPictureModeChange, reason);
657 }
658
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700659 /** Convenience method to reparent a task to a specific position of the stack. */
660 boolean reparent(ActivityStack preferredStack, int position,
661 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
662 String reason) {
663 return reparent(preferredStack, position, moveStackMode, animate, deferResume,
Winson Chung5af42fc2017-03-24 17:11:33 -0700664 true /* schedulePictureInPictureModeChange */, reason);
Winson Chung74666102017-02-22 17:49:24 -0800665 }
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800666
Winson Chung74666102017-02-22 17:49:24 -0800667 /**
668 * Reparents the task into a preferred stack, creating it if necessary.
669 *
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700670 * @param preferredStack the target stack to move this task
Winson Chung74666102017-02-22 17:49:24 -0800671 * @param position the position to place this task in the new stack
672 * @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 -0700673 * reparenting to be drawn and animated in
Winson Chung74666102017-02-22 17:49:24 -0800674 * @param moveStackMode whether or not to move the stack to the front always, only if it was
Winson Chung5af42fc2017-03-24 17:11:33 -0700675 * previously focused & in front, or never
Winson Chung74666102017-02-22 17:49:24 -0800676 * @param deferResume whether or not to update the visibility of other tasks and stacks that may
Winson Chung5af42fc2017-03-24 17:11:33 -0700677 * have changed as a result of this reparenting
678 * @param schedulePictureInPictureModeChange specifies whether or not to schedule the PiP mode
679 * change. Callers may set this to false if they are explicitly scheduling PiP mode
680 * changes themselves, like during the PiP animation
Winson Chung74666102017-02-22 17:49:24 -0800681 * @param reason the caller of this reparenting
Winson Chung5af42fc2017-03-24 17:11:33 -0700682 * @return whether the task was reparented
Winson Chung74666102017-02-22 17:49:24 -0800683 */
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700684 // TODO: Inspect all call sites and change to just changing windowing mode of the stack vs.
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700685 // re-parenting the task. Can only be done when we are no longer using static stack Ids.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700686 boolean reparent(ActivityStack preferredStack, int position,
687 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
688 boolean schedulePictureInPictureModeChange, String reason) {
Winson Chung74666102017-02-22 17:49:24 -0800689 final ActivityStackSupervisor supervisor = mService.mStackSupervisor;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800690 final RootActivityContainer root = mService.mRootActivityContainer;
Winson Chung74666102017-02-22 17:49:24 -0800691 final WindowManagerService windowManager = mService.mWindowManager;
692 final ActivityStack sourceStack = getStack();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700693 final ActivityStack toStack = supervisor.getReparentTargetStack(this, preferredStack,
Winson Chung74666102017-02-22 17:49:24 -0800694 position == MAX_VALUE);
695 if (toStack == sourceStack) {
696 return false;
697 }
Andrii Kulianb850ea52017-12-12 23:49:10 -0800698 if (!canBeLaunchedOnDisplay(toStack.mDisplayId)) {
699 return false;
700 }
Winson Chung74666102017-02-22 17:49:24 -0800701
Andrii Kulian6b321512019-01-23 06:37:00 +0000702 final boolean toTopOfStack = position == MAX_VALUE;
703 if (toTopOfStack && toStack.getResumedActivity() != null
704 && toStack.topRunningActivityLocked() != null) {
705 // Pause the resumed activity on the target stack while re-parenting task on top of it.
706 toStack.startPausingLocked(false /* userLeaving */, false /* uiSleeping */,
707 null /* resuming */, false /* pauseImmediately */);
708 }
709
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700710 final int toStackWindowingMode = toStack.getWindowingMode();
Winson Chung74666102017-02-22 17:49:24 -0800711 final ActivityRecord topActivity = getTopActivity();
712
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800713 final boolean mightReplaceWindow = topActivity != null
714 && replaceWindowsOnTaskMove(getWindowingMode(), toStackWindowingMode);
Winson Chung74666102017-02-22 17:49:24 -0800715 if (mightReplaceWindow) {
716 // We are about to relaunch the activity because its configuration changed due to
717 // being maximized, i.e. size change. The activity will first remove the old window
718 // and then add a new one. This call will tell window manager about this, so it can
719 // preserve the old window until the new one is drawn. This prevents having a gap
720 // between the removal and addition, in which no window is visible. We also want the
721 // entrance of the new window to be properly animated.
722 // Note here we always set the replacing window first, as the flags might be needed
723 // during the relaunch. If we end up not doing any relaunch, we clear the flags later.
724 windowManager.setWillReplaceWindow(topActivity.appToken, animate);
725 }
726
727 windowManager.deferSurfaceLayout();
728 boolean kept = true;
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800729 try {
Winson Chung74666102017-02-22 17:49:24 -0800730 final ActivityRecord r = topRunningActivityLocked();
Wale Ogunwaled32da472018-11-16 07:19:28 -0800731 final boolean wasFocused = r != null && root.isTopDisplayFocusedStack(sourceStack)
Winson Chung74666102017-02-22 17:49:24 -0800732 && (topRunningActivityLocked() == r);
Bryce Leec4ab62a2018-03-05 14:19:26 -0800733 final boolean wasResumed = r != null && sourceStack.getResumedActivity() == r;
Winson Chung95f8f0e2017-03-24 09:20:17 -0700734 final boolean wasPaused = r != null && sourceStack.mPausingActivity == r;
Winson Chung74666102017-02-22 17:49:24 -0800735
736 // In some cases the focused stack isn't the front stack. E.g. pinned stack.
737 // Whenever we are moving the top activity from the front stack we want to make sure to
738 // move the stack to the front.
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -0700739 final boolean wasFront = r != null && sourceStack.isTopStackOnDisplay()
Winson Chung74666102017-02-22 17:49:24 -0800740 && (sourceStack.topRunningActivityLocked() == r);
741
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800742 // Adjust the position for the new parent stack as needed.
Winson Chung74666102017-02-22 17:49:24 -0800743 position = toStack.getAdjustedPositionForTask(this, position, null /* starting */);
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800744
745 // Must reparent first in window manager to avoid a situation where AM can delete the
746 // we are coming from in WM before we reparent because it became empty.
Yunfan Chen279f5582018-12-12 15:24:50 -0800747 mTask.reparent(toStack.getTaskStack(), position,
Wale Ogunwale2719cc12017-04-14 09:45:27 -0700748 moveStackMode == REPARENT_MOVE_STACK_TO_FRONT);
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800749
Wale Ogunwale56d8d162017-05-30 11:12:20 -0700750 final boolean moveStackToFront = moveStackMode == REPARENT_MOVE_STACK_TO_FRONT
751 || (moveStackMode == REPARENT_KEEP_STACK_AT_FRONT && (wasFocused || wasFront));
Winson Chung74666102017-02-22 17:49:24 -0800752 // Move the task
Wale Ogunwale56d8d162017-05-30 11:12:20 -0700753 sourceStack.removeTask(this, reason, moveStackToFront
754 ? REMOVE_TASK_MODE_MOVING_TO_TOP : REMOVE_TASK_MODE_MOVING);
Winson Chung5af42fc2017-03-24 17:11:33 -0700755 toStack.addTask(this, position, false /* schedulePictureInPictureModeChange */, reason);
Winson Chung74666102017-02-22 17:49:24 -0800756
Winson Chung5af42fc2017-03-24 17:11:33 -0700757 if (schedulePictureInPictureModeChange) {
758 // Notify of picture-in-picture mode changes
759 supervisor.scheduleUpdatePictureInPictureModeIfNeeded(this, sourceStack);
760 }
Winson Chung74666102017-02-22 17:49:24 -0800761
762 // TODO: Ensure that this is actually necessary here
763 // Notify the voice session if required
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800764 if (voiceSession != null) {
765 try {
766 voiceSession.taskStarted(intent, taskId);
767 } catch (RemoteException e) {
768 }
769 }
Winson Chung74666102017-02-22 17:49:24 -0800770
771 // If the task had focus before (or we're requested to move focus), move focus to the
772 // new stack by moving the stack to the front.
Winson Chung95f8f0e2017-03-24 09:20:17 -0700773 if (r != null) {
774 toStack.moveToFrontAndResumeStateIfNeeded(r, moveStackToFront, wasResumed,
775 wasPaused, reason);
776 }
Winson Chung74666102017-02-22 17:49:24 -0800777 if (!animate) {
Jorim Jaggifa9ed962018-01-25 00:16:49 +0100778 mService.mStackSupervisor.mNoAnimActivities.add(topActivity);
Winson Chung74666102017-02-22 17:49:24 -0800779 }
780
781 // We might trigger a configuration change. Save the current task bounds for freezing.
782 // TODO: Should this call be moved inside the resize method in WM?
783 toStack.prepareFreezingTaskBounds();
784
785 // Make sure the task has the appropriate bounds/size for the stack it is in.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700786 final boolean toStackSplitScreenPrimary =
787 toStackWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Evan Roskydfe3da72018-10-26 17:21:06 -0700788 final Rect configBounds = getRequestedOverrideBounds();
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700789 if ((toStackWindowingMode == WINDOWING_MODE_FULLSCREEN
790 || toStackWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY)
Evan Roskydfe3da72018-10-26 17:21:06 -0700791 && !Objects.equals(configBounds, toStack.getRequestedOverrideBounds())) {
792 kept = resize(toStack.getRequestedOverrideBounds(), RESIZE_MODE_SYSTEM,
793 !mightReplaceWindow, deferResume);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700794 } else if (toStackWindowingMode == WINDOWING_MODE_FREEFORM) {
Winson Chung74666102017-02-22 17:49:24 -0800795 Rect bounds = getLaunchBounds();
796 if (bounds == null) {
Bryce Leeec55eb02017-12-05 20:51:27 -0800797 mService.mStackSupervisor.getLaunchParamsController().layoutTask(this, null);
Bryce Leef3c6a472017-11-14 14:53:06 -0800798 bounds = configBounds;
Winson Chung74666102017-02-22 17:49:24 -0800799 }
800 kept = resize(bounds, RESIZE_MODE_FORCED, !mightReplaceWindow, deferResume);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700801 } else if (toStackSplitScreenPrimary || toStackWindowingMode == WINDOWING_MODE_PINNED) {
802 if (toStackSplitScreenPrimary && moveStackMode == REPARENT_KEEP_STACK_AT_FRONT) {
Matthew Ng330757d2017-02-28 14:19:17 -0800803 // Move recents to front so it is not behind home stack when going into docked
804 // mode
805 mService.mStackSupervisor.moveRecentsStackToFront(reason);
806 }
Evan Roskydfe3da72018-10-26 17:21:06 -0700807 kept = resize(toStack.getRequestedOverrideBounds(), RESIZE_MODE_SYSTEM,
808 !mightReplaceWindow, deferResume);
Winson Chung74666102017-02-22 17:49:24 -0800809 }
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800810 } finally {
Winson Chung74666102017-02-22 17:49:24 -0800811 windowManager.continueSurfaceLayout();
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800812 }
Winson Chung74666102017-02-22 17:49:24 -0800813
814 if (mightReplaceWindow) {
815 // If we didn't actual do a relaunch (indicated by kept==true meaning we kept the old
816 // window), we need to clear the replace window settings. Otherwise, we schedule a
817 // timeout to remove the old window if the replacing window is not coming in time.
818 windowManager.scheduleClearWillReplaceWindows(topActivity.appToken, !kept);
819 }
820
821 if (!deferResume) {
822 // The task might have already been running and its visibility needs to be synchronized
823 // with the visibility of the stack / windows.
Wale Ogunwaled32da472018-11-16 07:19:28 -0800824 root.ensureActivitiesVisible(null, 0, !mightReplaceWindow);
825 root.resumeFocusedStacksTopActivities();
Winson Chung74666102017-02-22 17:49:24 -0800826 }
827
Andrii Kulian036e3ad2017-04-19 10:55:10 -0700828 // TODO: Handle incorrect request to move before the actual move, not after.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700829 supervisor.handleNonResizableTaskIfNeeded(this, preferredStack.getWindowingMode(),
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -0700830 DEFAULT_DISPLAY, toStack);
Winson Chung74666102017-02-22 17:49:24 -0800831
Winson Chungdff7a732017-12-11 12:17:06 -0800832 return (preferredStack == toStack);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800833 }
834
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700835 /**
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800836 * @return True if the windows of tasks being moved to the target stack from the source stack
837 * should be replaced, meaning that window manager will keep the old window around until the new
838 * is ready.
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700839 */
840 private static boolean replaceWindowsOnTaskMove(
841 int sourceWindowingMode, int targetWindowingMode) {
842 return sourceWindowingMode == WINDOWING_MODE_FREEFORM
843 || targetWindowingMode == WINDOWING_MODE_FREEFORM;
844 }
845
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800846 void cancelWindowTransition() {
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800847 if (mTask == null) {
848 Slog.w(TAG_WM, "cancelWindowTransition: taskId " + taskId + " not found.");
849 return;
850 }
851 mTask.cancelTaskWindowTransition();
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800852 }
853
Jorim Jaggi7361bab2017-01-16 17:17:58 +0100854 /**
855 * DO NOT HOLD THE ACTIVITY MANAGER LOCK WHEN CALLING THIS METHOD!
856 */
Jorim Jaggi35e3f532017-03-17 17:06:50 +0100857 TaskSnapshot getSnapshot(boolean reducedResolution) {
Jorim Jaggi7361bab2017-01-16 17:17:58 +0100858
859 // TODO: Move this to {@link TaskWindowContainerController} once recent tasks are more
860 // synchronized between AM and WM.
Jorim Jaggi35e3f532017-03-17 17:06:50 +0100861 return mService.mWindowManager.getTaskSnapshot(taskId, userId, reducedResolution);
Jorim Jaggi02886a82016-12-06 09:10:06 -0800862 }
863
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800864 void touchActiveTime() {
Winson Chungfb44d212017-10-04 11:39:10 -0700865 lastActiveTime = SystemClock.elapsedRealtime();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800866 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700867
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800868 long getInactiveDuration() {
Winson Chungfb44d212017-10-04 11:39:10 -0700869 return SystemClock.elapsedRealtime() - lastActiveTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800870 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700871
Winson Chungfee26772014-08-05 12:21:52 -0700872 /** Sets the original intent, and the calling uid and package. */
873 void setIntent(ActivityRecord r) {
Winson Chungfee26772014-08-05 12:21:52 -0700874 mCallingUid = r.launchedFromUid;
875 mCallingPackage = r.launchedFromPackage;
Craig Mautner15df08a2015-04-01 12:17:18 -0700876 setIntent(r.intent, r.info);
Charles He2bf28322017-10-12 22:24:49 +0100877 setLockTaskAuth(r);
Winson Chungfee26772014-08-05 12:21:52 -0700878 }
879
880 /** Sets the original intent, _without_ updating the calling uid or package. */
881 private void setIntent(Intent _intent, ActivityInfo info) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700882 if (intent == null) {
883 mNeverRelinquishIdentity =
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700884 (info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700885 } else if (mNeverRelinquishIdentity) {
886 return;
887 }
888
889 affinity = info.taskAffinity;
Dianne Hackborn79228822014-09-16 11:11:23 -0700890 if (intent == null) {
891 // If this task already has an intent associated with it, don't set the root
892 // affinity -- we don't want it changing after initially set, but the initially
893 // set value may be null.
894 rootAffinity = affinity;
895 }
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700896 effectiveUid = info.applicationInfo.uid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700897 stringName = null;
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800898
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800899 if (info.targetActivity == null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800900 if (_intent != null) {
901 // If this Intent has a selector, we want to clear it for the
902 // recent task since it is not relevant if the user later wants
903 // to re-launch the app.
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700904 if (_intent.getSelector() != null || _intent.getSourceBounds() != null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800905 _intent = new Intent(_intent);
906 _intent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700907 _intent.setSourceBounds(null);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800908 }
909 }
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700910 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Setting Intent of " + this + " to " + _intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800911 intent = _intent;
912 realActivity = _intent != null ? _intent.getComponent() : null;
913 origActivity = null;
914 } else {
915 ComponentName targetComponent = new ComponentName(
916 info.packageName, info.targetActivity);
917 if (_intent != null) {
918 Intent targetIntent = new Intent(_intent);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800919 targetIntent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700920 targetIntent.setSourceBounds(null);
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700921 if (DEBUG_TASKS) Slog.v(TAG_TASKS,
Dianne Hackborn7f96b792012-05-29 18:46:45 -0700922 "Setting Intent of " + this + " to target " + targetIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800923 intent = targetIntent;
924 realActivity = targetComponent;
925 origActivity = _intent.getComponent();
926 } else {
927 intent = null;
928 realActivity = targetComponent;
929 origActivity = new ComponentName(info.packageName, info.name);
930 }
931 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700932
Craig Mautner47b20ba2014-09-17 17:23:44 -0700933 final int intentFlags = intent == null ? 0 : intent.getFlags();
934 if ((intentFlags & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800935 // Once we are set to an Intent with this flag, we count this
936 // task as having a true root activity.
937 rootWasReset = true;
938 }
Dianne Hackborn09233282014-04-30 11:33:59 -0700939 userId = UserHandle.getUserId(info.applicationInfo.uid);
Winson Chung36f3f032016-09-08 23:29:43 +0000940 mUserSetupComplete = Settings.Secure.getIntForUser(mService.mContext.getContentResolver(),
941 USER_SETUP_COMPLETE, 0, userId) != 0;
Craig Mautner41db4a72014-05-07 17:20:56 -0700942 if ((info.flags & ActivityInfo.FLAG_AUTO_REMOVE_FROM_RECENTS) != 0) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700943 // If the activity itself has requested auto-remove, then just always do it.
944 autoRemoveRecents = true;
Wale Ogunwale843bfb92015-03-27 11:06:48 -0700945 } else if ((intentFlags & (FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS))
946 == FLAG_ACTIVITY_NEW_DOCUMENT) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700947 // If the caller has not asked for the document to be retained, then we may
948 // want to turn on auto-remove, depending on whether the target has set its
949 // own document launch mode.
950 if (info.documentLaunchMode != ActivityInfo.DOCUMENT_LAUNCH_NONE) {
951 autoRemoveRecents = false;
952 } else {
953 autoRemoveRecents = true;
954 }
955 } else {
956 autoRemoveRecents = false;
Craig Mautner41db4a72014-05-07 17:20:56 -0700957 }
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800958 mResizeMode = info.resizeMode;
Winson Chungd3395382016-12-13 11:49:09 -0800959 mSupportsPictureInPicture = info.supportsPictureInPicture();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800960 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800961
Andrii Kulian2e751b82016-03-16 16:59:32 -0700962 /** Sets the original minimal width and height. */
963 private void setMinDimensions(ActivityInfo info) {
964 if (info != null && info.windowLayout != null) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700965 mMinWidth = info.windowLayout.minWidth;
966 mMinHeight = info.windowLayout.minHeight;
Andrii Kulian2e751b82016-03-16 16:59:32 -0700967 } else {
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700968 mMinWidth = INVALID_MIN_SIZE;
969 mMinHeight = INVALID_MIN_SIZE;
Andrii Kulian2e751b82016-03-16 16:59:32 -0700970 }
971 }
972
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800973 /**
Andrii Kulian206b9fa2016-06-02 13:18:01 -0700974 * Return true if the input activity has the same intent filter as the intent this task
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800975 * record is based on (normally the root activity intent).
976 */
Andrii Kulian206b9fa2016-06-02 13:18:01 -0700977 boolean isSameIntentFilter(ActivityRecord r) {
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800978 final Intent intent = new Intent(r.intent);
Louis Chang23df1a62019-01-09 15:10:49 +0800979 // Make sure the component are the same if the input activity has the same real activity
980 // as the one in the task because either one of them could be the alias activity.
981 if (Objects.equals(realActivity, r.mActivityComponent) && this.intent != null) {
982 intent.setComponent(this.intent.getComponent());
983 }
Bryce Lee1a990e52018-04-23 10:54:11 -0700984 return intent.filterEquals(this.intent);
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800985 }
986
Wale Ogunwale66e16852017-10-19 13:35:52 -0700987 boolean returnsToHomeStack() {
988 final int returnHomeFlags = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME;
Bryce Lee1a990e52018-04-23 10:54:11 -0700989 return intent != null && (intent.getFlags() & returnHomeFlags) == returnHomeFlags;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700990 }
991
Craig Mautnera228ae92014-07-09 05:44:55 -0700992 void setPrevAffiliate(TaskRecord prevAffiliate) {
993 mPrevAffiliate = prevAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800994 mPrevAffiliateTaskId = prevAffiliate == null ? INVALID_TASK_ID : prevAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700995 }
996
997 void setNextAffiliate(TaskRecord nextAffiliate) {
998 mNextAffiliate = nextAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800999 mNextAffiliateTaskId = nextAffiliate == null ? INVALID_TASK_ID : nextAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -07001000 }
1001
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001002 <T extends ActivityStack> T getStack() {
1003 return (T) mStack;
Andrii Kulian02b7a832016-10-06 23:11:56 -07001004 }
1005
Andrii Kulianfb1bf692017-01-17 11:17:34 -08001006 /**
1007 * Must be used for setting parent stack because it performs configuration updates.
1008 * Must be called after adding task as a child to the stack.
1009 */
Andrii Kulian02b7a832016-10-06 23:11:56 -07001010 void setStack(ActivityStack stack) {
Andrii Kulianfb1bf692017-01-17 11:17:34 -08001011 if (stack != null && !stack.isInStackLocked(this)) {
1012 throw new IllegalStateException("Task must be added as a Stack child first.");
1013 }
Bryce Lee84730a02018-04-03 14:10:04 -07001014 final ActivityStack oldStack = mStack;
Andrii Kulian02b7a832016-10-06 23:11:56 -07001015 mStack = stack;
Bryce Lee84730a02018-04-03 14:10:04 -07001016
1017 // If the new {@link TaskRecord} is from a different {@link ActivityStack}, remove this
1018 // {@link ActivityRecord} from its current {@link ActivityStack}.
1019
1020 if (oldStack != mStack) {
1021 for (int i = getChildCount() - 1; i >= 0; --i) {
1022 final ActivityRecord activity = getChildAt(i);
1023
1024 if (oldStack != null) {
1025 oldStack.onActivityRemovedFromStack(activity);
1026 }
1027
1028 if (mStack != null) {
1029 stack.onActivityAddedToStack(activity);
1030 }
1031 }
1032 }
1033
Andrii Kulian1779e612016-10-12 21:58:25 -07001034 onParentChanged();
Andrii Kulian02b7a832016-10-06 23:11:56 -07001035 }
1036
1037 /**
1038 * @return Id of current stack, {@link INVALID_STACK_ID} if no stack is set.
1039 */
1040 int getStackId() {
1041 return mStack != null ? mStack.mStackId : INVALID_STACK_ID;
1042 }
1043
Andrii Kulian1779e612016-10-12 21:58:25 -07001044 @Override
1045 protected int getChildCount() {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07001046 return mActivities.size();
Andrii Kulian1779e612016-10-12 21:58:25 -07001047 }
1048
1049 @Override
chaviw82a0ba82018-03-15 14:26:29 -07001050 protected ActivityRecord getChildAt(int index) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07001051 return mActivities.get(index);
Andrii Kulian1779e612016-10-12 21:58:25 -07001052 }
1053
1054 @Override
1055 protected ConfigurationContainer getParent() {
1056 return mStack;
1057 }
1058
Andrii Kulianfb1bf692017-01-17 11:17:34 -08001059 @Override
Wale Ogunwale98d62312017-07-12 09:24:56 -07001060 protected void onParentChanged() {
Andrii Kulianfb1bf692017-01-17 11:17:34 -08001061 super.onParentChanged();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001062 mService.mRootActivityContainer.updateUIDsPresentOnDisplay();
Andrii Kulianfb1bf692017-01-17 11:17:34 -08001063 }
1064
Craig Mautnera228ae92014-07-09 05:44:55 -07001065 // Close up recents linked list.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07001066 private void closeRecentsChain() {
Craig Mautnera228ae92014-07-09 05:44:55 -07001067 if (mPrevAffiliate != null) {
1068 mPrevAffiliate.setNextAffiliate(mNextAffiliate);
1069 }
1070 if (mNextAffiliate != null) {
1071 mNextAffiliate.setPrevAffiliate(mPrevAffiliate);
1072 }
1073 setPrevAffiliate(null);
1074 setNextAffiliate(null);
1075 }
1076
Winson Chung740c3ac2014-11-12 16:14:38 -08001077 void removedFromRecents() {
Dianne Hackborn852975d2014-08-22 17:42:43 -07001078 closeRecentsChain();
1079 if (inRecents) {
1080 inRecents = false;
Winson Chung740c3ac2014-11-12 16:14:38 -08001081 mService.notifyTaskPersisterLocked(this, false);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001082 }
Jorim Jaggif9084ec2017-01-16 13:16:59 +01001083
Dianne Hackborn68a06332017-11-15 17:54:18 -08001084 clearRootProcess();
1085
Jorim Jaggif9084ec2017-01-16 13:16:59 +01001086 // TODO: Use window container controller once tasks are better synced between AM and WM
1087 mService.mWindowManager.notifyTaskRemovedFromRecents(taskId, userId);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001088 }
1089
Craig Mautnera228ae92014-07-09 05:44:55 -07001090 void setTaskToAffiliateWith(TaskRecord taskToAffiliateWith) {
1091 closeRecentsChain();
1092 mAffiliatedTaskId = taskToAffiliateWith.mAffiliatedTaskId;
Winson Chungec396d62014-08-06 17:08:00 -07001093 mAffiliatedTaskColor = taskToAffiliateWith.mAffiliatedTaskColor;
Craig Mautnera228ae92014-07-09 05:44:55 -07001094 // Find the end
1095 while (taskToAffiliateWith.mNextAffiliate != null) {
1096 final TaskRecord nextRecents = taskToAffiliateWith.mNextAffiliate;
1097 if (nextRecents.mAffiliatedTaskId != mAffiliatedTaskId) {
1098 Slog.e(TAG, "setTaskToAffiliateWith: nextRecents=" + nextRecents + " affilTaskId="
1099 + nextRecents.mAffiliatedTaskId + " should be " + mAffiliatedTaskId);
1100 if (nextRecents.mPrevAffiliate == taskToAffiliateWith) {
1101 nextRecents.setPrevAffiliate(null);
1102 }
1103 taskToAffiliateWith.setNextAffiliate(null);
1104 break;
1105 }
1106 taskToAffiliateWith = nextRecents;
1107 }
1108 taskToAffiliateWith.setNextAffiliate(this);
1109 setPrevAffiliate(taskToAffiliateWith);
1110 setNextAffiliate(null);
1111 }
1112
Winson Chung1147c402014-05-14 11:05:00 -07001113 /** Returns the intent for the root activity for this task */
1114 Intent getBaseIntent() {
1115 return intent != null ? intent : affinityIntent;
1116 }
1117
Winson Chung3b3f4642014-04-22 10:08:18 -07001118 /** Returns the first non-finishing activity from the root. */
1119 ActivityRecord getRootActivity() {
1120 for (int i = 0; i < mActivities.size(); i++) {
1121 final ActivityRecord r = mActivities.get(i);
1122 if (r.finishing) {
1123 continue;
1124 }
1125 return r;
1126 }
1127 return null;
1128 }
1129
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001130 ActivityRecord getTopActivity() {
Bryce Lee9f6affd2017-09-01 09:18:35 -07001131 return getTopActivity(true /* includeOverlays */);
1132 }
1133
1134 ActivityRecord getTopActivity(boolean includeOverlays) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001135 for (int i = mActivities.size() - 1; i >= 0; --i) {
1136 final ActivityRecord r = mActivities.get(i);
Bryce Lee9f6affd2017-09-01 09:18:35 -07001137 if (r.finishing || (!includeOverlays && r.mTaskOverlay)) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001138 continue;
1139 }
1140 return r;
1141 }
1142 return null;
1143 }
1144
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -07001145 ActivityRecord topRunningActivityLocked() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001146 if (mStack != null) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07001147 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1148 ActivityRecord r = mActivities.get(activityNdx);
Chong Zhang87761972016-08-22 13:53:24 -07001149 if (!r.finishing && r.okToShowLocked()) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07001150 return r;
1151 }
Craig Mautner6b74cb52013-09-27 17:02:21 -07001152 }
1153 }
1154 return null;
1155 }
1156
Jorim Jaggi172e99f2017-10-20 14:33:18 +02001157 boolean isVisible() {
1158 for (int i = mActivities.size() - 1; i >= 0; --i) {
1159 final ActivityRecord r = mActivities.get(i);
1160 if (r.visible) {
1161 return true;
1162 }
1163 }
1164 return false;
1165 }
1166
Jorim Jaggiea039a82017-08-02 14:37:49 +02001167 void getAllRunningVisibleActivitiesLocked(ArrayList<ActivityRecord> outActivities) {
1168 if (mStack != null) {
1169 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1170 ActivityRecord r = mActivities.get(activityNdx);
Jorim Jaggi02f1d2f2017-08-04 14:29:16 +02001171 if (!r.finishing && r.okToShowLocked() && r.visibleIgnoringKeyguard) {
Jorim Jaggiea039a82017-08-02 14:37:49 +02001172 outActivities.add(r);
1173 }
1174 }
1175 }
1176 }
1177
Wale Ogunwale3b232392016-05-13 15:37:13 -07001178 ActivityRecord topRunningActivityWithStartingWindowLocked() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001179 if (mStack != null) {
Wale Ogunwale3b232392016-05-13 15:37:13 -07001180 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1181 ActivityRecord r = mActivities.get(activityNdx);
1182 if (r.mStartingWindowState != STARTING_WINDOW_SHOWN
Chong Zhang87761972016-08-22 13:53:24 -07001183 || r.finishing || !r.okToShowLocked()) {
Wale Ogunwale3b232392016-05-13 15:37:13 -07001184 continue;
1185 }
1186 return r;
1187 }
1188 }
1189 return null;
1190 }
1191
Winson Chung61c9e5a2017-10-11 10:39:32 -07001192 /**
1193 * Return the number of running activities, and the number of non-finishing/initializing
1194 * activities in the provided {@param reportOut} respectively.
1195 */
1196 void getNumRunningActivities(TaskActivitiesReport reportOut) {
1197 reportOut.reset();
1198 for (int i = mActivities.size() - 1; i >= 0; --i) {
1199 final ActivityRecord r = mActivities.get(i);
1200 if (r.finishing) {
1201 continue;
1202 }
1203
1204 reportOut.base = r;
1205
1206 // Increment the total number of non-finishing activities
1207 reportOut.numActivities++;
1208
Bryce Lee7ace3952018-02-16 14:34:32 -08001209 if (reportOut.top == null || (reportOut.top.isState(ActivityState.INITIALIZING))) {
Winson Chung61c9e5a2017-10-11 10:39:32 -07001210 reportOut.top = r;
1211 // Reset the number of running activities until we hit the first non-initializing
1212 // activity
1213 reportOut.numRunning = 0;
1214 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001215 if (r.attachedToProcess()) {
Winson Chung61c9e5a2017-10-11 10:39:32 -07001216 // Increment the number of actually running activities
1217 reportOut.numRunning++;
1218 }
1219 }
1220 }
1221
Chong Zhang87761972016-08-22 13:53:24 -07001222 boolean okToShowLocked() {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001223 // NOTE: If {@link TaskRecord#topRunningActivity} return is not null then it is
Chong Zhang87761972016-08-22 13:53:24 -07001224 // okay to show the activity when locked.
1225 return mService.mStackSupervisor.isCurrentProfileLocked(userId)
1226 || topRunningActivityLocked() != null;
1227 }
1228
Craig Mautner3b475fe2013-12-16 15:58:31 -08001229 /** Call after activity movement or finish to make sure that frontOfTask is set correctly */
Bryce Leed71317c2017-02-07 14:27:22 -08001230 final void setFrontOfTask() {
1231 boolean foundFront = false;
Craig Mautner3b475fe2013-12-16 15:58:31 -08001232 final int numActivities = mActivities.size();
Craig Mautner704e40b2013-12-18 16:43:51 -08001233 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
Craig Mautner3b475fe2013-12-16 15:58:31 -08001234 final ActivityRecord r = mActivities.get(activityNdx);
1235 if (foundFront || r.finishing) {
1236 r.frontOfTask = false;
1237 } else {
1238 r.frontOfTask = true;
1239 // Set frontOfTask false for every following activity.
1240 foundFront = true;
1241 }
1242 }
Craig Mautner9587ee02014-06-23 15:00:10 +00001243 if (!foundFront && numActivities > 0) {
1244 // All activities of this task are finishing. As we ought to have a frontOfTask
1245 // activity, make the bottom activity front.
1246 mActivities.get(0).frontOfTask = true;
1247 }
Craig Mautner3b475fe2013-12-16 15:58:31 -08001248 }
1249
Craig Mautnerde4ef022013-04-07 19:01:33 -07001250 /**
Craig Mautner3b475fe2013-12-16 15:58:31 -08001251 * Reorder the history stack so that the passed activity is brought to the front.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001252 */
1253 final void moveActivityToFrontLocked(ActivityRecord newTop) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07001254 if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE,
1255 "Removing and adding activity " + newTop
1256 + " to stack at top callers=" + Debug.getCallers(4));
Craig Mautnerde4ef022013-04-07 19:01:33 -07001257
Craig Mautnerde4ef022013-04-07 19:01:33 -07001258 mActivities.remove(newTop);
1259 mActivities.add(newTop);
Bryce Leed58d7b32017-09-08 15:55:22 -07001260
1261 // Make sure window manager is aware of the position change.
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001262 mTask.positionChildAtTop(newTop.mAppWindowToken);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001263 updateEffectiveIntent();
Craig Mautner3b475fe2013-12-16 15:58:31 -08001264
Bryce Leed71317c2017-02-07 14:27:22 -08001265 setFrontOfTask();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001266 }
1267
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001268 void addActivityToTop(ActivityRecord r) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001269 addActivityAtIndex(mActivities.size(), r);
1270 }
1271
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001272 @Override
Wale Ogunwaleeea34ee92017-08-31 20:07:45 -07001273 /*@WindowConfiguration.ActivityType*/
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001274 public int getActivityType() {
1275 final int applicationType = super.getActivityType();
1276 if (applicationType != ACTIVITY_TYPE_UNDEFINED || mActivities.isEmpty()) {
1277 return applicationType;
1278 }
1279 return mActivities.get(0).getActivityType();
1280 }
1281
Winson Chung30480042017-01-26 10:55:34 -08001282 /**
Evan Rosky130d94f2019-01-15 10:18:17 -08001283 * Checks if the top activity requires a particular orientation (either by override or
Evan Rosky730f6e82018-12-03 17:40:11 -08001284 * activityInfo) and returns that. Otherwise, this returns ORIENTATION_UNDEFINED.
1285 */
Evan Rosky130d94f2019-01-15 10:18:17 -08001286 private int getTopActivityRequestedOrientation() {
1287 ActivityRecord top = getTopActivity();
Evan Rosky730f6e82018-12-03 17:40:11 -08001288 if (getRequestedOverrideConfiguration().orientation != ORIENTATION_UNDEFINED
Evan Rosky130d94f2019-01-15 10:18:17 -08001289 || top == null) {
Evan Rosky730f6e82018-12-03 17:40:11 -08001290 return getRequestedOverrideConfiguration().orientation;
1291 }
Evan Rosky130d94f2019-01-15 10:18:17 -08001292 int screenOrientation = top.getOrientation();
1293 if (screenOrientation == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) {
Evan Rosky730f6e82018-12-03 17:40:11 -08001294 // NOSENSOR means the display's "natural" orientation, so return that.
1295 ActivityDisplay display = mStack != null ? mStack.getDisplay() : null;
1296 if (display != null && display.mDisplayContent != null) {
1297 return mStack.getDisplay().mDisplayContent.getNaturalOrientation();
1298 }
Evan Rosky130d94f2019-01-15 10:18:17 -08001299 } else if (screenOrientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED) {
Evan Rosky730f6e82018-12-03 17:40:11 -08001300 // LOCKED means the activity's orientation remains unchanged, so return existing value.
Evan Rosky130d94f2019-01-15 10:18:17 -08001301 return top.getConfiguration().orientation;
1302 } else if (ActivityInfo.isFixedOrientationLandscape(screenOrientation)) {
Evan Rosky730f6e82018-12-03 17:40:11 -08001303 return ORIENTATION_LANDSCAPE;
Evan Rosky130d94f2019-01-15 10:18:17 -08001304 } else if (ActivityInfo.isFixedOrientationPortrait(screenOrientation)) {
Evan Rosky730f6e82018-12-03 17:40:11 -08001305 return ORIENTATION_PORTRAIT;
1306 }
1307 return ORIENTATION_UNDEFINED;
1308 }
1309
1310 /**
Winson Chung30480042017-01-26 10:55:34 -08001311 * Adds an activity {@param r} at the given {@param index}. The activity {@param r} must either
1312 * be in the current task or unparented to any task.
1313 */
Craig Mautner1602ec22013-05-12 10:24:27 -07001314 void addActivityAtIndex(int index, ActivityRecord r) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001315 TaskRecord task = r.getTaskRecord();
Bryce Leeaf691c02017-03-20 14:20:22 -07001316 if (task != null && task != this) {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001317 throw new IllegalArgumentException("Can not add r=" + " to task=" + this
Bryce Leeaf691c02017-03-20 14:20:22 -07001318 + " current parent=" + task);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001319 }
Bryce Leeaf691c02017-03-20 14:20:22 -07001320
1321 r.setTask(this);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001322
Craig Mautner6170f732013-04-02 13:05:23 -07001323 // 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 -08001324 if (!mActivities.remove(r) && r.fullscreen) {
1325 // Was not previously in list.
1326 numFullscreen++;
1327 }
Craig Mautner2c1faed2013-07-23 12:56:02 -07001328 // Only set this based on the first activity
1329 if (mActivities.isEmpty()) {
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001330 if (r.getActivityType() == ACTIVITY_TYPE_UNDEFINED) {
1331 // Normally non-standard activity type for the activity record will be set when the
1332 // object is created, however we delay setting the standard application type until
1333 // this point so that the task can set the type for additional activities added in
1334 // the else condition below.
1335 r.setActivityType(ACTIVITY_TYPE_STANDARD);
1336 }
1337 setActivityType(r.getActivityType());
Craig Mautner21d24a22014-04-23 11:45:37 -07001338 isPersistable = r.isPersistable();
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001339 mCallingUid = r.launchedFromUid;
1340 mCallingPackage = r.launchedFromPackage;
Dianne Hackborn852975d2014-08-22 17:42:43 -07001341 // Clamp to [1, max].
1342 maxRecents = Math.min(Math.max(r.info.maxRecents, 1),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001343 ActivityTaskManager.getMaxAppRecentsLimitStatic());
Craig Mautner2c1faed2013-07-23 12:56:02 -07001344 } else {
1345 // Otherwise make all added activities match this one.
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001346 r.setActivityType(getActivityType());
Craig Mautner78733002013-06-10 13:54:49 -07001347 }
Wale Ogunwale3b232392016-05-13 15:37:13 -07001348
1349 final int size = mActivities.size();
1350
1351 if (index == size && size > 0) {
1352 final ActivityRecord top = mActivities.get(size - 1);
1353 if (top.mTaskOverlay) {
1354 // Place below the task overlay activity since the overlay activity should always
1355 // be on top.
1356 index--;
1357 }
1358 }
1359
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001360 index = Math.min(size, index);
Craig Mautner77878772013-03-04 19:46:24 -08001361 mActivities.add(index, r);
Bryce Lee84730a02018-04-03 14:10:04 -07001362
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001363 updateEffectiveIntent();
Craig Mautner21d24a22014-04-23 11:45:37 -07001364 if (r.isPersistable()) {
1365 mService.notifyTaskPersisterLocked(this, false);
1366 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001367
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001368 if (r.mAppWindowToken != null) {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001369 // Only attempt to move in WM if the child has a controller. It is possible we haven't
1370 // created controller for the activity we are starting yet.
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001371 mTask.positionChildAt(r.mAppWindowToken, index);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001372 }
David Stevens82ea6cb2017-03-03 16:18:50 -08001373
1374 // Make sure the list of display UID whitelists is updated
1375 // now that this record is in a new task.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001376 mService.mRootActivityContainer.updateUIDsPresentOnDisplay();
Craig Mautner77878772013-03-04 19:46:24 -08001377 }
1378
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001379 /**
Bryce Leeaf691c02017-03-20 14:20:22 -07001380 * Removes the specified activity from this task.
1381 * @param r The {@link ActivityRecord} to remove.
1382 * @return true if this was the last activity in the task.
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001383 */
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001384 boolean removeActivity(ActivityRecord r) {
Bryce Lee84730a02018-04-03 14:10:04 -07001385 return removeActivity(r, false /* reparenting */);
Bryce Leeaf691c02017-03-20 14:20:22 -07001386 }
1387
1388 boolean removeActivity(ActivityRecord r, boolean reparenting) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001389 if (r.getTaskRecord() != this) {
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001390 throw new IllegalArgumentException(
1391 "Activity=" + r + " does not belong to task=" + this);
1392 }
1393
Bryce Lee84730a02018-04-03 14:10:04 -07001394 r.setTask(null /* task */, reparenting /* reparenting */);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001395
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001396 if (mActivities.remove(r) && r.fullscreen) {
1397 // Was previously in list.
1398 numFullscreen--;
1399 }
Craig Mautner21d24a22014-04-23 11:45:37 -07001400 if (r.isPersistable()) {
1401 mService.notifyTaskPersisterLocked(this, false);
1402 }
Wale Ogunwale89182d52016-03-11 10:38:36 -08001403
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001404 if (inPinnedWindowingMode()) {
Wale Ogunwale89182d52016-03-11 10:38:36 -08001405 // We normally notify listeners of task stack changes on pause, however pinned stack
1406 // activities are normally in the paused state so no notification will be sent there
1407 // before the activity is removed. We send it here so instead.
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001408 mService.getTaskChangeNotificationController().notifyTaskStackChanged();
Wale Ogunwale89182d52016-03-11 10:38:36 -08001409 }
1410
Craig Mautner41326202014-06-20 14:38:21 -07001411 if (mActivities.isEmpty()) {
Craig Mautner5afcd4d2014-06-21 18:11:33 -07001412 return !mReuseTask;
Craig Mautner41326202014-06-20 14:38:21 -07001413 }
1414 updateEffectiveIntent();
1415 return false;
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001416 }
1417
Winson Chung6954fc92017-03-24 16:22:12 -07001418 /**
1419 * @return whether or not there are ONLY task overlay activities in the stack.
1420 * If {@param excludeFinishing} is set, then ignore finishing activities in the check.
1421 * If there are no task overlay activities, this call returns false.
1422 */
1423 boolean onlyHasTaskOverlayActivities(boolean excludeFinishing) {
1424 int count = 0;
1425 for (int i = mActivities.size() - 1; i >= 0; i--) {
1426 final ActivityRecord r = mActivities.get(i);
1427 if (excludeFinishing && r.finishing) {
1428 continue;
1429 }
1430 if (!r.mTaskOverlay) {
1431 return false;
1432 }
1433 count++;
1434 }
1435 return count > 0;
1436 }
1437
Craig Mautner41db4a72014-05-07 17:20:56 -07001438 boolean autoRemoveFromRecents() {
Dianne Hackbornd38aed82014-06-10 21:36:35 -07001439 // We will automatically remove the task either if it has explicitly asked for
1440 // this, or it is empty and has never contained an activity that got shown to
1441 // the user.
Dianne Hackborn13420f22014-07-18 15:43:56 -07001442 return autoRemoveRecents || (mActivities.isEmpty() && !hasBeenVisible);
Craig Mautner41db4a72014-05-07 17:20:56 -07001443 }
1444
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001445 /**
1446 * Completely remove all activities associated with an existing
1447 * task starting at a specified index.
1448 */
Winson Chung0ec2a352017-10-26 11:38:30 -07001449 final void performClearTaskAtIndexLocked(int activityNdx, boolean pauseImmediately,
1450 String reason) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001451 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001452 for ( ; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001453 final ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001454 if (r.finishing) {
1455 continue;
1456 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07001457 if (mStack == null) {
Craig Mautner21d24a22014-04-23 11:45:37 -07001458 // Task was restored from persistent storage.
1459 r.takeFromHistory();
1460 mActivities.remove(activityNdx);
1461 --activityNdx;
1462 --numActivities;
Winson Chung6954fc92017-03-24 16:22:12 -07001463 } else if (mStack.finishActivityLocked(r, Activity.RESULT_CANCELED, null,
Winson Chung0ec2a352017-10-26 11:38:30 -07001464 reason, false, pauseImmediately)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001465 --activityNdx;
1466 --numActivities;
1467 }
1468 }
1469 }
1470
1471 /**
1472 * Completely remove all activities associated with an existing task.
1473 */
Benjamin Franza83859f2017-07-03 16:34:14 +01001474 void performClearTaskLocked() {
Craig Mautner362449a2014-06-20 14:04:39 -07001475 mReuseTask = true;
Winson Chung0ec2a352017-10-26 11:38:30 -07001476 performClearTaskAtIndexLocked(0, !PAUSE_IMMEDIATELY, "clear-task-all");
Craig Mautner362449a2014-06-20 14:04:39 -07001477 mReuseTask = false;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001478 }
1479
Filip Gruszczynskibe9dabd2016-01-19 12:23:10 -08001480 ActivityRecord performClearTaskForReuseLocked(ActivityRecord newR, int launchFlags) {
1481 mReuseTask = true;
1482 final ActivityRecord result = performClearTaskLocked(newR, launchFlags);
1483 mReuseTask = false;
1484 return result;
1485 }
1486
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001487 /**
1488 * Perform clear operation as requested by
1489 * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the
1490 * stack to the given task, then look for
1491 * an instance of that activity in the stack and, if found, finish all
1492 * activities on top of it and return the instance.
1493 *
1494 * @param newR Description of the new activity being started.
1495 * @return Returns the old activity that should be continued to be used,
1496 * or null if none was found.
1497 */
1498 final ActivityRecord performClearTaskLocked(ActivityRecord newR, int launchFlags) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001499 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001500 for (int activityNdx = numActivities - 1; activityNdx >= 0; --activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001501 ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001502 if (r.finishing) {
1503 continue;
1504 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001505 if (r.mActivityComponent.equals(newR.mActivityComponent)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001506 // Here it is! Now finish everything in front...
Craig Mautner1602ec22013-05-12 10:24:27 -07001507 final ActivityRecord ret = r;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001508
1509 for (++activityNdx; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001510 r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001511 if (r.finishing) {
1512 continue;
1513 }
1514 ActivityOptions opts = r.takeOptionsLocked();
1515 if (opts != null) {
1516 ret.updateOptionsLocked(opts);
1517 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07001518 if (mStack != null && mStack.finishActivityLocked(
Todd Kennedy539db512014-12-15 09:57:55 -08001519 r, Activity.RESULT_CANCELED, null, "clear-task-stack", false)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001520 --activityNdx;
1521 --numActivities;
1522 }
1523 }
1524
1525 // Finally, if this is a normal launch mode (that is, not
1526 // expecting onNewIntent()), then we will finish the current
1527 // instance of the activity so a new fresh one can be started.
1528 if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE
Daichi Hirono15a02992016-04-27 18:47:01 +09001529 && (launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0
1530 && !ActivityStarter.isDocumentLaunchesIntoExisting(launchFlags)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001531 if (!ret.finishing) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001532 if (mStack != null) {
1533 mStack.finishActivityLocked(
Wale Ogunwale7d701172015-03-11 15:36:30 -07001534 ret, Activity.RESULT_CANCELED, null, "clear-task-top", false);
1535 }
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001536 return null;
1537 }
1538 }
1539
1540 return ret;
1541 }
1542 }
1543
1544 return null;
1545 }
1546
Winson Chung0ec2a352017-10-26 11:38:30 -07001547 void removeTaskActivitiesLocked(boolean pauseImmediately, String reason) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001548 // Just remove the entire task.
Winson Chung0ec2a352017-10-26 11:38:30 -07001549 performClearTaskAtIndexLocked(0, pauseImmediately, reason);
Craig Mautner9db9a0b2013-04-29 17:05:56 -07001550 }
1551
Craig Mautner432f64e2015-05-20 14:59:57 -07001552 String lockTaskAuthToString() {
1553 switch (mLockTaskAuth) {
1554 case LOCK_TASK_AUTH_DONT_LOCK: return "LOCK_TASK_AUTH_DONT_LOCK";
1555 case LOCK_TASK_AUTH_PINNABLE: return "LOCK_TASK_AUTH_PINNABLE";
1556 case LOCK_TASK_AUTH_LAUNCHABLE: return "LOCK_TASK_AUTH_LAUNCHABLE";
1557 case LOCK_TASK_AUTH_WHITELISTED: return "LOCK_TASK_AUTH_WHITELISTED";
Benjamin Franz469dd582015-06-09 14:24:36 +01001558 case LOCK_TASK_AUTH_LAUNCHABLE_PRIV: return "LOCK_TASK_AUTH_LAUNCHABLE_PRIV";
Craig Mautner432f64e2015-05-20 14:59:57 -07001559 default: return "unknown=" + mLockTaskAuth;
1560 }
1561 }
1562
Craig Mautner15df08a2015-04-01 12:17:18 -07001563 void setLockTaskAuth() {
Charles He2bf28322017-10-12 22:24:49 +01001564 setLockTaskAuth(getRootActivity());
1565 }
1566
1567 private void setLockTaskAuth(@Nullable ActivityRecord r) {
1568 if (r == null) {
1569 mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE;
1570 return;
1571 }
1572
Charles He520b2832017-09-02 15:27:16 +01001573 final String pkg = (realActivity != null) ? realActivity.getPackageName() : null;
Bryce Lee2b8e0372018-04-05 17:01:37 -07001574 final LockTaskController lockTaskController = mService.getLockTaskController();
Charles He2bf28322017-10-12 22:24:49 +01001575 switch (r.lockTaskLaunchMode) {
Craig Mautner15df08a2015-04-01 12:17:18 -07001576 case LOCK_TASK_LAUNCH_MODE_DEFAULT:
Bryce Lee2b8e0372018-04-05 17:01:37 -07001577 mLockTaskAuth = lockTaskController.isPackageWhitelisted(userId, pkg)
Charles He520b2832017-09-02 15:27:16 +01001578 ? LOCK_TASK_AUTH_WHITELISTED : LOCK_TASK_AUTH_PINNABLE;
Craig Mautner15df08a2015-04-01 12:17:18 -07001579 break;
1580
1581 case LOCK_TASK_LAUNCH_MODE_NEVER:
Benjamin Franz469dd582015-06-09 14:24:36 +01001582 mLockTaskAuth = LOCK_TASK_AUTH_DONT_LOCK;
Craig Mautner15df08a2015-04-01 12:17:18 -07001583 break;
1584
1585 case LOCK_TASK_LAUNCH_MODE_ALWAYS:
Benjamin Franz469dd582015-06-09 14:24:36 +01001586 mLockTaskAuth = LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
Craig Mautner15df08a2015-04-01 12:17:18 -07001587 break;
1588
1589 case LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED:
Bryce Lee2b8e0372018-04-05 17:01:37 -07001590 mLockTaskAuth = lockTaskController.isPackageWhitelisted(userId, pkg)
Charles He520b2832017-09-02 15:27:16 +01001591 ? LOCK_TASK_AUTH_LAUNCHABLE : LOCK_TASK_AUTH_PINNABLE;
Craig Mautner15df08a2015-04-01 12:17:18 -07001592 break;
1593 }
Craig Mautner432f64e2015-05-20 14:59:57 -07001594 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
1595 " mLockTaskAuth=" + lockTaskAuthToString());
Craig Mautner15df08a2015-04-01 12:17:18 -07001596 }
1597
Winson Chungd3395382016-12-13 11:49:09 -08001598 private boolean isResizeable(boolean checkSupportsPip) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001599 return (mService.mForceResizableActivities || ActivityInfo.isResizeableMode(mResizeMode)
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -07001600 || (checkSupportsPip && mSupportsPictureInPicture));
Winson Chungd3395382016-12-13 11:49:09 -08001601 }
1602
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001603 boolean isResizeable() {
Winson Chungd3395382016-12-13 11:49:09 -08001604 return isResizeable(true /* checkSupportsPip */);
1605 }
1606
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001607 @Override
1608 public boolean supportsSplitScreenWindowingMode() {
Winson Chungd3395382016-12-13 11:49:09 -08001609 // A task can not be docked even if it is considered resizeable because it only supports
1610 // picture-in-picture mode but has a non-resizeable resizeMode
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001611 return super.supportsSplitScreenWindowingMode()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001612 && mService.mSupportsSplitScreenMultiWindow
1613 && (mService.mForceResizableActivities
Bryce Leec857a5b2017-08-16 10:04:52 -07001614 || (isResizeable(false /* checkSupportsPip */)
1615 && !ActivityInfo.isPreserveOrientationMode(mResizeMode)));
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001616 }
1617
skuhne@google.com322347b2016-12-02 12:54:03 -08001618 /**
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001619 * Check whether this task can be launched on the specified display.
Riddle Hsu16567132018-08-16 21:37:47 +08001620 *
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001621 * @param displayId Target display id.
Riddle Hsu16567132018-08-16 21:37:47 +08001622 * @return {@code true} if either it is the default display or this activity can be put on a
1623 * secondary display.
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001624 */
1625 boolean canBeLaunchedOnDisplay(int displayId) {
1626 return mService.mStackSupervisor.canPlaceEntityOnDisplay(displayId,
Riddle Hsu16567132018-08-16 21:37:47 +08001627 -1 /* don't check PID */, -1 /* don't check UID */, null /* activityInfo */);
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001628 }
1629
1630 /**
skuhne@google.com322347b2016-12-02 12:54:03 -08001631 * Check that a given bounds matches the application requested orientation.
1632 *
1633 * @param bounds The bounds to be tested.
1634 * @return True if the requested bounds are okay for a resizing request.
1635 */
Wale Ogunwale069bbd32017-02-03 07:58:14 -08001636 private boolean canResizeToBounds(Rect bounds) {
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001637 if (bounds == null || !inFreeformWindowingMode()) {
skuhne@google.com322347b2016-12-02 12:54:03 -08001638 // Note: If not on the freeform workspace, we ignore the bounds.
1639 return true;
1640 }
1641 final boolean landscape = bounds.width() > bounds.height();
Evan Roskydfe3da72018-10-26 17:21:06 -07001642 final Rect configBounds = getRequestedOverrideBounds();
skuhne@google.com322347b2016-12-02 12:54:03 -08001643 if (mResizeMode == RESIZE_MODE_FORCE_RESIZABLE_PRESERVE_ORIENTATION) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001644 return configBounds.isEmpty()
1645 || landscape == (configBounds.width() > configBounds.height());
skuhne@google.com322347b2016-12-02 12:54:03 -08001646 }
1647 return (mResizeMode != RESIZE_MODE_FORCE_RESIZABLE_PORTRAIT_ONLY || !landscape)
1648 && (mResizeMode != RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY || landscape);
1649 }
1650
Craig Mautner525f3d92013-05-07 14:01:50 -07001651 /**
Yorke Leebdef5372017-04-10 16:38:51 -07001652 * @return {@code true} if the task is being cleared for the purposes of being reused.
1653 */
1654 boolean isClearingToReuseTask() {
1655 return mReuseTask;
1656 }
1657
1658 /**
Craig Mautner525f3d92013-05-07 14:01:50 -07001659 * Find the activity in the history stack within the given task. Returns
1660 * the index within the history at which it's found, or < 0 if not found.
1661 */
1662 final ActivityRecord findActivityInHistoryLocked(ActivityRecord r) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001663 final ComponentName realActivity = r.mActivityComponent;
Craig Mautner525f3d92013-05-07 14:01:50 -07001664 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1665 ActivityRecord candidate = mActivities.get(activityNdx);
1666 if (candidate.finishing) {
1667 continue;
1668 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001669 if (candidate.mActivityComponent.equals(realActivity)) {
Craig Mautner525f3d92013-05-07 14:01:50 -07001670 return candidate;
1671 }
1672 }
1673 return null;
1674 }
1675
Winson Chunga449dc02014-05-16 11:15:04 -07001676 /** Updates the last task description values. */
1677 void updateTaskDescription() {
1678 // Traverse upwards looking for any break between main task activities and
1679 // utility activities.
1680 int activityNdx;
1681 final int numActivities = mActivities.size();
Wale Ogunwale3eadad72016-10-13 09:16:59 -07001682 final boolean relinquish = numActivities != 0 &&
1683 (mActivities.get(0).info.flags & FLAG_RELINQUISH_TASK_IDENTITY) != 0;
Winson Chunga449dc02014-05-16 11:15:04 -07001684 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
Craig Mautner21d24a22014-04-23 11:45:37 -07001685 ++activityNdx) {
Winson Chunga449dc02014-05-16 11:15:04 -07001686 final ActivityRecord r = mActivities.get(activityNdx);
Wale Ogunwale3eadad72016-10-13 09:16:59 -07001687 if (relinquish && (r.info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001688 // This will be the top activity for determining taskDescription. Pre-inc to
1689 // overcome initial decrement below.
1690 ++activityNdx;
1691 break;
1692 }
Winson Chunga449dc02014-05-16 11:15:04 -07001693 if (r.intent != null &&
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001694 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
Winson Chunga449dc02014-05-16 11:15:04 -07001695 break;
1696 }
1697 }
1698 if (activityNdx > 0) {
1699 // Traverse downwards starting below break looking for set label, icon.
1700 // Note that if there are activities in the task but none of them set the
1701 // recent activity values, then we do not fall back to the last set
1702 // values in the TaskRecord.
1703 String label = null;
Craig Mautner648f69b2014-09-18 14:16:26 -07001704 String iconFilename = null;
Matthew Ng54bc9422017-10-02 17:16:28 -07001705 int iconResource = -1;
Winson Chunga449dc02014-05-16 11:15:04 -07001706 int colorPrimary = 0;
Winson Chung1af8eda2016-02-05 17:55:56 +00001707 int colorBackground = 0;
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001708 int statusBarColor = 0;
1709 int navigationBarColor = 0;
1710 boolean topActivity = true;
Winson Chunga449dc02014-05-16 11:15:04 -07001711 for (--activityNdx; activityNdx >= 0; --activityNdx) {
1712 final ActivityRecord r = mActivities.get(activityNdx);
Winson Chung80f80db2018-05-30 21:13:25 -07001713 if (r.mTaskOverlay) {
1714 continue;
1715 }
Winson Chunga449dc02014-05-16 11:15:04 -07001716 if (r.taskDescription != null) {
1717 if (label == null) {
1718 label = r.taskDescription.getLabel();
1719 }
Matthew Ng54bc9422017-10-02 17:16:28 -07001720 if (iconResource == -1) {
1721 iconResource = r.taskDescription.getIconResource();
1722 }
Craig Mautner648f69b2014-09-18 14:16:26 -07001723 if (iconFilename == null) {
1724 iconFilename = r.taskDescription.getIconFilename();
Winson Chunga449dc02014-05-16 11:15:04 -07001725 }
1726 if (colorPrimary == 0) {
1727 colorPrimary = r.taskDescription.getPrimaryColor();
Winson Chunga449dc02014-05-16 11:15:04 -07001728 }
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001729 if (topActivity) {
Winson Chung1af8eda2016-02-05 17:55:56 +00001730 colorBackground = r.taskDescription.getBackgroundColor();
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001731 statusBarColor = r.taskDescription.getStatusBarColor();
1732 navigationBarColor = r.taskDescription.getNavigationBarColor();
Winson Chung1af8eda2016-02-05 17:55:56 +00001733 }
Winson Chunga449dc02014-05-16 11:15:04 -07001734 }
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001735 topActivity = false;
Winson Chunga449dc02014-05-16 11:15:04 -07001736 }
Matthew Ng54bc9422017-10-02 17:16:28 -07001737 lastTaskDescription = new TaskDescription(label, null, iconResource, iconFilename,
1738 colorPrimary, colorBackground, statusBarColor, navigationBarColor);
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001739 if (mTask != null) {
1740 mTask.setTaskDescription(lastTaskDescription);
Jorim Jaggi829b9cd2017-01-23 16:20:53 +01001741 }
Winson Chungec396d62014-08-06 17:08:00 -07001742 // Update the task affiliation color if we are the parent of the group
1743 if (taskId == mAffiliatedTaskId) {
1744 mAffiliatedTaskColor = lastTaskDescription.getPrimaryColor();
1745 }
Winson Chunga449dc02014-05-16 11:15:04 -07001746 }
1747 }
1748
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001749 int findEffectiveRootIndex() {
Craig Mautner4767f4b2014-09-18 15:38:33 -07001750 int effectiveNdx = 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001751 final int topActivityNdx = mActivities.size() - 1;
Dianne Hackborn39569af2014-09-23 10:56:58 -07001752 for (int activityNdx = 0; activityNdx <= topActivityNdx; ++activityNdx) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001753 final ActivityRecord r = mActivities.get(activityNdx);
1754 if (r.finishing) {
1755 continue;
1756 }
Craig Mautner4767f4b2014-09-18 15:38:33 -07001757 effectiveNdx = activityNdx;
Wale Ogunwale3eadad72016-10-13 09:16:59 -07001758 if ((r.info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001759 break;
1760 }
1761 }
Craig Mautner4767f4b2014-09-18 15:38:33 -07001762 return effectiveNdx;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001763 }
1764
1765 void updateEffectiveIntent() {
1766 final int effectiveRootIndex = findEffectiveRootIndex();
1767 final ActivityRecord r = mActivities.get(effectiveRootIndex);
Winson Chungfee26772014-08-05 12:21:52 -07001768 setIntent(r);
Winson Chung8d9009e2017-11-16 15:43:05 -08001769
1770 // Update the task description when the activities change
1771 updateTaskDescription();
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001772 }
1773
Evan Rosky730f6e82018-12-03 17:40:11 -08001774 void adjustForMinimalTaskDimensions(Rect bounds, Rect previousBounds) {
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001775 if (bounds == null) {
1776 return;
1777 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001778 int minWidth = mMinWidth;
1779 int minHeight = mMinHeight;
Robert Carr9c5867d2016-03-10 15:52:46 -08001780 // If the task has no requested minimal size, we'd like to enforce a minimal size
1781 // so that the user can not render the task too small to manipulate. We don't need
1782 // to do this for the pinned stack as the bounds are controlled by the system.
Evan Rosky1ac84462018-11-13 11:25:30 -08001783 if (!inPinnedWindowingMode() && mStack != null) {
Garfield Tan4a48a7f2018-10-02 14:23:55 -07001784 final int defaultMinSizeDp =
Wale Ogunwaled32da472018-11-16 07:19:28 -08001785 mService.mRootActivityContainer.mDefaultMinSizeOfResizeableTaskDp;
Garfield Tan4a48a7f2018-10-02 14:23:55 -07001786 final ActivityDisplay display =
Wale Ogunwaled32da472018-11-16 07:19:28 -08001787 mService.mRootActivityContainer.getActivityDisplay(mStack.mDisplayId);
Garfield Tan4a48a7f2018-10-02 14:23:55 -07001788 final float density =
1789 (float) display.getConfiguration().densityDpi / DisplayMetrics.DENSITY_DEFAULT;
1790 final int defaultMinSize = (int) (defaultMinSizeDp * density);
1791
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001792 if (minWidth == INVALID_MIN_SIZE) {
Garfield Tan4a48a7f2018-10-02 14:23:55 -07001793 minWidth = defaultMinSize;
Andrii Kulian2e751b82016-03-16 16:59:32 -07001794 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001795 if (minHeight == INVALID_MIN_SIZE) {
Garfield Tan4a48a7f2018-10-02 14:23:55 -07001796 minHeight = defaultMinSize;
Andrii Kulian2e751b82016-03-16 16:59:32 -07001797 }
Robert Carr9c5867d2016-03-10 15:52:46 -08001798 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001799 final boolean adjustWidth = minWidth > bounds.width();
1800 final boolean adjustHeight = minHeight > bounds.height();
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001801 if (!(adjustWidth || adjustHeight)) {
1802 return;
1803 }
1804
1805 if (adjustWidth) {
Garfield Tan020607d2018-12-17 17:01:58 -08001806 if (!previousBounds.isEmpty() && bounds.right == previousBounds.right) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001807 bounds.left = bounds.right - minWidth;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001808 } else {
1809 // Either left bounds match, or neither match, or the previous bounds were
1810 // fullscreen and we default to keeping left.
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001811 bounds.right = bounds.left + minWidth;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001812 }
1813 }
1814 if (adjustHeight) {
Garfield Tan020607d2018-12-17 17:01:58 -08001815 if (!previousBounds.isEmpty() && bounds.bottom == previousBounds.bottom) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001816 bounds.top = bounds.bottom - minHeight;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001817 } else {
1818 // Either top bounds match, or neither match, or the previous bounds were
1819 // fullscreen and we default to keeping top.
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001820 bounds.bottom = bounds.top + minHeight;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001821 }
1822 }
1823 }
1824
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001825 /**
1826 * Update task's override configuration based on the bounds.
Jorim Jaggi0a932142016-02-01 17:42:25 -08001827 * @param bounds The bounds of the task.
Andrii Kulian8072d112016-09-16 11:11:01 -07001828 * @return True if the override configuration was updated.
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001829 */
Andrii Kulian8072d112016-09-16 11:11:01 -07001830 boolean updateOverrideConfiguration(Rect bounds) {
Jorim Jaggi0a932142016-02-01 17:42:25 -08001831 return updateOverrideConfiguration(bounds, null /* insetBounds */);
1832 }
1833
Evan Rosky9ba524e2018-01-03 16:27:56 -08001834 void setLastNonFullscreenBounds(Rect bounds) {
1835 if (mLastNonFullscreenBounds == null) {
1836 mLastNonFullscreenBounds = new Rect(bounds);
1837 } else {
1838 mLastNonFullscreenBounds.set(bounds);
1839 }
1840 }
1841
Jorim Jaggi0a932142016-02-01 17:42:25 -08001842 /**
1843 * Update task's override configuration based on the bounds.
1844 * @param bounds The bounds of the task.
1845 * @param insetBounds The bounds used to calculate the system insets, which is used here to
1846 * subtract the navigation bar/status bar size from the screen size reported
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001847 * to the application. See {@link IActivityTaskManager#resizeDockedStack}.
Andrii Kulian8072d112016-09-16 11:11:01 -07001848 * @return True if the override configuration was updated.
Jorim Jaggi0a932142016-02-01 17:42:25 -08001849 */
Andrii Kulian8072d112016-09-16 11:11:01 -07001850 boolean updateOverrideConfiguration(Rect bounds, @Nullable Rect insetBounds) {
Evan Rosky1ac84462018-11-13 11:25:30 -08001851 final boolean hasSetDisplayedBounds = (insetBounds != null && !insetBounds.isEmpty());
1852 if (hasSetDisplayedBounds) {
1853 setDisplayedBounds(bounds);
1854 } else {
1855 setDisplayedBounds(null);
1856 }
1857 // "steady" bounds do not include any temporary offsets from animation or interaction.
1858 Rect steadyBounds = hasSetDisplayedBounds ? insetBounds : bounds;
1859 if (equivalentRequestedOverrideBounds(steadyBounds)) {
Andrii Kulian8072d112016-09-16 11:11:01 -07001860 return false;
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001861 }
Bryce Leef3c6a472017-11-14 14:53:06 -08001862
Evan Rosky1ac84462018-11-13 11:25:30 -08001863 mTmpConfig.setTo(getResolvedOverrideConfiguration());
1864 setBounds(steadyBounds);
1865 return !mTmpConfig.equals(getResolvedOverrideConfiguration());
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08001866 }
Wale Ogunwale5f986092015-12-04 15:35:38 -08001867
Bryce Leec4ab62a2018-03-05 14:19:26 -08001868 /**
1869 * This should be called when an child activity changes state. This should only
1870 * be called from
1871 * {@link ActivityRecord#setState(ActivityState, String)} .
1872 * @param record The {@link ActivityRecord} whose state has changed.
1873 * @param state The new state.
1874 * @param reason The reason for the change.
1875 */
1876 void onActivityStateChanged(ActivityRecord record, ActivityState state, String reason) {
1877 final ActivityStack parent = getStack();
1878
1879 if (parent != null) {
1880 parent.onActivityStateChanged(record, state, reason);
1881 }
1882 }
1883
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08001884 @Override
1885 public void onConfigurationChanged(Configuration newParentConfig) {
Evan Rosky730f6e82018-12-03 17:40:11 -08001886 // Check if the new configuration supports persistent bounds (eg. is Freeform) and if so
1887 // restore the last recorded non-fullscreen bounds.
1888 final boolean prevPersistTaskBounds = getWindowConfiguration().persistTaskBounds();
1889 final boolean nextPersistTaskBounds =
1890 getRequestedOverrideConfiguration().windowConfiguration.persistTaskBounds()
1891 || newParentConfig.windowConfiguration.persistTaskBounds();
1892 if (!prevPersistTaskBounds && nextPersistTaskBounds
1893 && mLastNonFullscreenBounds != null && !mLastNonFullscreenBounds.isEmpty()) {
1894 // Bypass onRequestedOverrideConfigurationChanged here to avoid infinite loop.
1895 getRequestedOverrideConfiguration().windowConfiguration
1896 .setBounds(mLastNonFullscreenBounds);
1897 }
1898
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08001899 final boolean wasInMultiWindowMode = inMultiWindowMode();
1900 super.onConfigurationChanged(newParentConfig);
1901 if (wasInMultiWindowMode != inMultiWindowMode()) {
Winson Chung5af42fc2017-03-24 17:11:33 -07001902 mService.mStackSupervisor.scheduleUpdateMultiWindowMode(this);
Wale Ogunwale5f986092015-12-04 15:35:38 -08001903 }
Evan Rosky730f6e82018-12-03 17:40:11 -08001904
1905 // If the configuration supports persistent bounds (eg. Freeform), keep track of the
1906 // current (non-fullscreen) bounds for persistence.
Evan Rosky1ac84462018-11-13 11:25:30 -08001907 if (getWindowConfiguration().persistTaskBounds()) {
1908 final Rect currentBounds = getRequestedOverrideBounds();
1909 if (!currentBounds.isEmpty()) {
1910 setLastNonFullscreenBounds(currentBounds);
1911 }
1912 }
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08001913 // TODO: Should also take care of Pip mode changes here.
Garfield Tan891146c2018-10-09 12:14:00 -07001914
1915 saveLaunchingStateIfNeeded();
1916 }
1917
1918 /**
1919 * Saves launching state if necessary so that we can launch the activity to its latest state.
1920 * It only saves state if this task has been shown to user and it's in fullscreen or freeform
1921 * mode.
1922 */
1923 void saveLaunchingStateIfNeeded() {
1924 if (!hasBeenVisible) {
1925 // Not ever visible to user.
1926 return;
1927 }
1928
1929 final int windowingMode = getWindowingMode();
1930 if (windowingMode != WindowConfiguration.WINDOWING_MODE_FULLSCREEN
1931 && windowingMode != WindowConfiguration.WINDOWING_MODE_FREEFORM) {
1932 return;
1933 }
1934
1935 // Saves the new state so that we can launch the activity at the same location.
1936 mService.mStackSupervisor.mLaunchParamsPersister.saveTask(this);
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001937 }
1938
Evan Roskyed6767f2018-10-26 17:21:06 -07001939 /**
Evan Rosky1ac84462018-11-13 11:25:30 -08001940 * Adjust bounds to stay within stack bounds.
1941 *
1942 * Since bounds might be outside of stack bounds, this method tries to move the bounds in a way
1943 * that keep them unchanged, but be contained within the stack bounds.
1944 *
1945 * @param bounds Bounds to be adjusted.
1946 * @param stackBounds Bounds within which the other bounds should remain.
1947 */
1948 private static void fitWithinBounds(Rect bounds, Rect stackBounds) {
1949 if (stackBounds == null || stackBounds.isEmpty() || stackBounds.contains(bounds)) {
1950 return;
1951 }
1952
1953 if (bounds.left < stackBounds.left || bounds.right > stackBounds.right) {
1954 final int maxRight = stackBounds.right
1955 - (stackBounds.width() / FIT_WITHIN_BOUNDS_DIVIDER);
1956 int horizontalDiff = stackBounds.left - bounds.left;
1957 if ((horizontalDiff < 0 && bounds.left >= maxRight)
1958 || (bounds.left + horizontalDiff >= maxRight)) {
1959 horizontalDiff = maxRight - bounds.left;
1960 }
1961 bounds.left += horizontalDiff;
1962 bounds.right += horizontalDiff;
1963 }
1964
1965 if (bounds.top < stackBounds.top || bounds.bottom > stackBounds.bottom) {
1966 final int maxBottom = stackBounds.bottom
1967 - (stackBounds.height() / FIT_WITHIN_BOUNDS_DIVIDER);
1968 int verticalDiff = stackBounds.top - bounds.top;
1969 if ((verticalDiff < 0 && bounds.top >= maxBottom)
1970 || (bounds.top + verticalDiff >= maxBottom)) {
1971 verticalDiff = maxBottom - bounds.top;
1972 }
1973 bounds.top += verticalDiff;
1974 bounds.bottom += verticalDiff;
1975 }
1976 }
1977
1978 /**
Evan Roskyed6767f2018-10-26 17:21:06 -07001979 * Displayed bounds are used to set where the task is drawn at any given time. This is
1980 * separate from its actual bounds so that the app doesn't see any meaningful configuration
1981 * changes during transitionary periods.
1982 */
1983 void setDisplayedBounds(Rect bounds) {
1984 if (bounds == null) {
1985 mDisplayedBounds.setEmpty();
1986 } else {
1987 mDisplayedBounds.set(bounds);
1988 }
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001989 if (mTask != null) {
1990 mTask.setOverrideDisplayedBounds(
Evan Roskyed6767f2018-10-26 17:21:06 -07001991 mDisplayedBounds.isEmpty() ? null : mDisplayedBounds);
1992 }
1993 }
1994
1995 /**
1996 * Gets the current overridden displayed bounds. These will be empty if the task is not
1997 * currently overriding where it is displayed.
1998 */
1999 Rect getDisplayedBounds() {
2000 return mDisplayedBounds;
2001 }
2002
2003 /**
2004 * @return {@code true} if this has overridden displayed bounds.
2005 */
2006 boolean hasDisplayedBounds() {
2007 return !mDisplayedBounds.isEmpty();
2008 }
2009
Evan Rosky1ac84462018-11-13 11:25:30 -08002010 /**
2011 * Intersects inOutBounds with intersectBounds-intersectInsets. If inOutBounds is larger than
2012 * intersectBounds on a side, then the respective side will not be intersected.
2013 *
2014 * The assumption is that if inOutBounds is initially larger than intersectBounds, then the
2015 * inset on that side is no-longer applicable. This scenario happens when a task's minimal
2016 * bounds are larger than the provided parent/display bounds.
2017 *
2018 * @param inOutBounds the bounds to intersect.
2019 * @param intersectBounds the bounds to intersect with.
2020 * @param intersectInsets insets to apply to intersectBounds before intersecting.
2021 */
2022 private static void intersectWithInsetsIfFits(
2023 Rect inOutBounds, Rect intersectBounds, Rect intersectInsets) {
2024 if (inOutBounds.right <= intersectBounds.right) {
2025 inOutBounds.right =
2026 Math.min(intersectBounds.right - intersectInsets.right, inOutBounds.right);
2027 }
2028 if (inOutBounds.bottom <= intersectBounds.bottom) {
2029 inOutBounds.bottom =
2030 Math.min(intersectBounds.bottom - intersectInsets.bottom, inOutBounds.bottom);
2031 }
2032 if (inOutBounds.left >= intersectBounds.left) {
2033 inOutBounds.left =
2034 Math.max(intersectBounds.left + intersectInsets.left, inOutBounds.left);
2035 }
2036 if (inOutBounds.top >= intersectBounds.top) {
2037 inOutBounds.top =
2038 Math.max(intersectBounds.top + intersectInsets.top, inOutBounds.top);
2039 }
2040 }
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08002041
Evan Rosky1ac84462018-11-13 11:25:30 -08002042 /**
2043 * Gets bounds with non-decor and stable insets applied respectively.
2044 *
2045 * If bounds overhangs the display, those edges will not get insets. See
2046 * {@link #intersectWithInsetsIfFits}
2047 *
2048 * @param outNonDecorBounds where to place bounds with non-decor insets applied.
2049 * @param outStableBounds where to place bounds with stable insets applied.
2050 * @param bounds the bounds to inset.
2051 */
2052 private void calculateInsetFrames(Rect outNonDecorBounds, Rect outStableBounds, Rect bounds,
2053 DisplayInfo displayInfo) {
2054 outNonDecorBounds.set(bounds);
2055 outStableBounds.set(bounds);
2056 if (getStack() == null || getStack().getDisplay() == null) {
2057 return;
2058 }
2059 DisplayPolicy policy = getStack().getDisplay().mDisplayContent.getDisplayPolicy();
2060 if (policy == null) {
2061 return;
2062 }
2063 mTmpBounds.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight);
Bryce Lee7566d762017-03-30 09:34:15 -07002064
Evan Rosky1ac84462018-11-13 11:25:30 -08002065 policy.getStableInsetsLw(displayInfo.rotation,
2066 displayInfo.logicalWidth, displayInfo.logicalHeight, displayInfo.displayCutout,
2067 mTmpInsets);
2068 intersectWithInsetsIfFits(outStableBounds, mTmpBounds, mTmpInsets);
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08002069
Evan Rosky1ac84462018-11-13 11:25:30 -08002070 policy.getNonDecorInsetsLw(displayInfo.rotation,
2071 displayInfo.logicalWidth, displayInfo.logicalHeight, displayInfo.displayCutout,
2072 mTmpInsets);
2073 intersectWithInsetsIfFits(outNonDecorBounds, mTmpBounds, mTmpInsets);
2074 }
2075
2076 /**
2077 * Asks docked-divider controller for the smallestwidthdp given bounds.
2078 * @param bounds bounds to calculate smallestwidthdp for.
2079 */
2080 private int getSmallestScreenWidthDpForDockedBounds(Rect bounds) {
2081 DisplayContent dc = mStack.getDisplay().mDisplayContent;
2082 if (dc != null) {
2083 return dc.getDockedDividerController().getSmallestWidthDpForBounds(bounds);
2084 }
2085 return Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
2086 }
2087
2088 /**
2089 * Calculates configuration values used by the client to get resources. This should be run
2090 * using app-facing bounds (bounds unmodified by animations or transient interactions).
2091 *
2092 * This assumes bounds are non-empty/null. For the null-bounds case, the caller is likely
2093 * configuring an "inherit-bounds" window which means that all configuration settings would
2094 * just be inherited from the parent configuration.
2095 **/
Evan Rosky730f6e82018-12-03 17:40:11 -08002096 void computeConfigResourceOverrides(@NonNull Configuration inOutConfig,
Evan Rosky1ac84462018-11-13 11:25:30 -08002097 @NonNull Configuration parentConfig) {
2098 int windowingMode = inOutConfig.windowConfiguration.getWindowingMode();
2099 if (windowingMode == WINDOWING_MODE_UNDEFINED) {
2100 windowingMode = parentConfig.windowConfiguration.getWindowingMode();
Winson Chungbdc646f2017-02-13 12:12:22 -08002101 }
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08002102
Evan Rosky1ac84462018-11-13 11:25:30 -08002103 float density = inOutConfig.densityDpi;
2104 if (density == Configuration.DENSITY_DPI_UNDEFINED) {
2105 density = parentConfig.densityDpi;
2106 }
2107 density *= DisplayMetrics.DENSITY_DEFAULT_SCALE;
Winson Chung60c1aba2017-03-14 17:47:42 -07002108
Evan Rosky730f6e82018-12-03 17:40:11 -08002109 final Rect bounds = inOutConfig.windowConfiguration.getBounds();
Evan Rosky1ac84462018-11-13 11:25:30 -08002110 Rect outAppBounds = inOutConfig.windowConfiguration.getAppBounds();
2111 if (outAppBounds == null || outAppBounds.isEmpty()) {
2112 inOutConfig.windowConfiguration.setAppBounds(bounds);
2113 outAppBounds = inOutConfig.windowConfiguration.getAppBounds();
2114 }
2115 if (windowingMode != WINDOWING_MODE_FREEFORM) {
2116 final Rect parentAppBounds = parentConfig.windowConfiguration.getAppBounds();
2117 if (parentAppBounds != null && !parentAppBounds.isEmpty()) {
2118 outAppBounds.intersect(parentAppBounds);
2119 }
2120 }
2121
2122 if (inOutConfig.screenWidthDp == Configuration.SCREEN_WIDTH_DP_UNDEFINED
2123 || inOutConfig.screenHeightDp == Configuration.SCREEN_HEIGHT_DP_UNDEFINED) {
2124 if (mStack != null) {
2125 final DisplayInfo di = new DisplayInfo();
2126 mStack.getDisplay().mDisplay.getDisplayInfo(di);
2127
2128 // For calculating screenWidthDp, screenWidthDp, we use the stable inset screen
2129 // area, i.e. the screen area without the system bars.
2130 // The non decor inset are areas that could never be removed in Honeycomb. See
2131 // {@link WindowManagerPolicy#getNonDecorInsetsLw}.
2132 calculateInsetFrames(mTmpNonDecorBounds, mTmpStableBounds, bounds, di);
2133 } else {
2134 mTmpNonDecorBounds.set(bounds);
2135 mTmpStableBounds.set(bounds);
2136 }
2137
2138 if (inOutConfig.screenWidthDp == Configuration.SCREEN_WIDTH_DP_UNDEFINED) {
2139 inOutConfig.screenWidthDp = Math.min((int) (mTmpStableBounds.width() / density),
2140 parentConfig.screenWidthDp);
2141 }
2142 if (inOutConfig.screenHeightDp == Configuration.SCREEN_HEIGHT_DP_UNDEFINED) {
2143 inOutConfig.screenHeightDp = Math.min((int) (mTmpStableBounds.height() / density),
2144 parentConfig.screenHeightDp);
2145 }
2146
2147 if (inOutConfig.smallestScreenWidthDp
2148 == Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
2149 if (WindowConfiguration.isFloating(windowingMode)) {
2150 // For floating tasks, calculate the smallest width from the bounds of the task
2151 inOutConfig.smallestScreenWidthDp = (int) (
2152 Math.min(bounds.width(), bounds.height()) / density);
2153 } else if (WindowConfiguration.isSplitScreenWindowingMode(windowingMode)) {
2154 // Iterating across all screen orientations, and return the minimum of the task
2155 // width taking into account that the bounds might change because the snap
2156 // algorithm snaps to a different value
Evan Rosky730f6e82018-12-03 17:40:11 -08002157 inOutConfig.smallestScreenWidthDp =
2158 getSmallestScreenWidthDpForDockedBounds(bounds);
Evan Rosky1ac84462018-11-13 11:25:30 -08002159 }
2160 // otherwise, it will just inherit
2161 }
2162 }
2163
Evan Rosky730f6e82018-12-03 17:40:11 -08002164 if (inOutConfig.orientation == ORIENTATION_UNDEFINED) {
Evan Rosky1ac84462018-11-13 11:25:30 -08002165 inOutConfig.orientation = (inOutConfig.screenWidthDp <= inOutConfig.screenHeightDp)
2166 ? Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;
2167 }
2168 if (inOutConfig.screenLayout == Configuration.SCREENLAYOUT_UNDEFINED) {
2169 // For calculating screen layout, we need to use the non-decor inset screen area for the
2170 // calculation for compatibility reasons, i.e. screen area without system bars that
2171 // could never go away in Honeycomb.
2172 final int compatScreenWidthDp = (int) (mTmpNonDecorBounds.width() / density);
2173 final int compatScreenHeightDp = (int) (mTmpNonDecorBounds.height() / density);
2174 // We're only overriding LONG, SIZE and COMPAT parts of screenLayout, so we start
2175 // override calculation with partial default.
2176 // Reducing the screen layout starting from its parent config.
2177 final int sl = parentConfig.screenLayout
2178 & (Configuration.SCREENLAYOUT_LONG_MASK | Configuration.SCREENLAYOUT_SIZE_MASK);
2179 final int longSize = Math.max(compatScreenHeightDp, compatScreenWidthDp);
2180 final int shortSize = Math.min(compatScreenHeightDp, compatScreenWidthDp);
2181 inOutConfig.screenLayout = Configuration.reduceScreenLayout(sl, longSize, shortSize);
2182 }
2183 }
2184
Evan Rosky1ac84462018-11-13 11:25:30 -08002185 @Override
2186 void resolveOverrideConfiguration(Configuration newParentConfig) {
Evan Rosky730f6e82018-12-03 17:40:11 -08002187 mTmpBounds.set(getResolvedOverrideConfiguration().windowConfiguration.getBounds());
2188 super.resolveOverrideConfiguration(newParentConfig);
2189 int windowingMode =
2190 getRequestedOverrideConfiguration().windowConfiguration.getWindowingMode();
2191 if (windowingMode == WINDOWING_MODE_UNDEFINED) {
2192 windowingMode = newParentConfig.windowConfiguration.getWindowingMode();
2193 }
2194 Rect outOverrideBounds =
2195 getResolvedOverrideConfiguration().windowConfiguration.getBounds();
2196
2197 if (windowingMode == WINDOWING_MODE_FULLSCREEN) {
2198 // In FULLSCREEN mode, always start with empty bounds to indicate "fill parent"
2199 outOverrideBounds.setEmpty();
2200
Garfield Tan49dae102019-02-04 09:51:59 -08002201 final boolean parentHandlesOrientationChange = mTask != null
2202 && mTask.getParent() != null
2203 && mTask.getParent().handlesOrientationChangeFromDescendant();
Evan Rosky130d94f2019-01-15 10:18:17 -08002204 // If the task or its top activity requires a different orientation, make it fit the
Evan Rosky730f6e82018-12-03 17:40:11 -08002205 // available bounds by scaling down its bounds.
Evan Rosky130d94f2019-01-15 10:18:17 -08002206 int forcedOrientation = getTopActivityRequestedOrientation();
Evan Rosky730f6e82018-12-03 17:40:11 -08002207 if (forcedOrientation != ORIENTATION_UNDEFINED
Garfield Tan49dae102019-02-04 09:51:59 -08002208 && forcedOrientation != newParentConfig.orientation
2209 && !parentHandlesOrientationChange) {
Evan Rosky730f6e82018-12-03 17:40:11 -08002210 final Rect parentBounds = newParentConfig.windowConfiguration.getBounds();
2211 final int parentWidth = parentBounds.width();
2212 final int parentHeight = parentBounds.height();
2213 final float aspect = ((float) parentHeight) / parentWidth;
2214 if (forcedOrientation == ORIENTATION_LANDSCAPE) {
2215 final int height = (int) (parentWidth / aspect);
2216 final int top = parentBounds.centerY() - height / 2;
2217 outOverrideBounds.set(
2218 parentBounds.left, top, parentBounds.right, top + height);
2219 } else {
2220 final int width = (int) (parentHeight * aspect);
2221 final int left = parentBounds.centerX() - width / 2;
2222 outOverrideBounds.set(
2223 left, parentBounds.top, left + width, parentBounds.bottom);
2224 }
2225 }
2226 }
2227
2228 if (outOverrideBounds.isEmpty()) {
2229 // If the task fills the parent, just inherit all the other configs from parent.
2230 return;
2231 }
2232
2233 adjustForMinimalTaskDimensions(outOverrideBounds, mTmpBounds);
2234 if (windowingMode == WINDOWING_MODE_FREEFORM) {
2235 // by policy, make sure the window remains within parent somewhere
2236 fitWithinBounds(outOverrideBounds, newParentConfig.windowConfiguration.getBounds());
2237 }
2238 computeConfigResourceOverrides(getResolvedOverrideConfiguration(), newParentConfig);
Jorim Jaggia95ca8d2016-01-15 22:54:46 -08002239 }
2240
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08002241 Rect updateOverrideConfigurationFromLaunchBounds() {
Bryce Leef3c6a472017-11-14 14:53:06 -08002242 final Rect bounds = getLaunchBounds();
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08002243 updateOverrideConfiguration(bounds);
Bryce Leef3c6a472017-11-14 14:53:06 -08002244 if (bounds != null && !bounds.isEmpty()) {
2245 // TODO: Review if we actually want to do this - we are setting the launch bounds
2246 // directly here.
Evan Roskydfe3da72018-10-26 17:21:06 -07002247 bounds.set(getRequestedOverrideBounds());
Andrii Kulian73336d812016-03-24 12:56:08 -07002248 }
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08002249 return bounds;
2250 }
2251
Wale Ogunwale935e5022015-11-10 12:36:10 -08002252 /** Updates the task's bounds and override configuration to match what is expected for the
2253 * input stack. */
2254 void updateOverrideConfigurationForStack(ActivityStack inStack) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07002255 if (mStack != null && mStack == inStack) {
Wale Ogunwale935e5022015-11-10 12:36:10 -08002256 return;
2257 }
2258
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002259 if (inStack.inFreeformWindowingMode()) {
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002260 if (!isResizeable()) {
Wale Ogunwale935e5022015-11-10 12:36:10 -08002261 throw new IllegalArgumentException("Can not position non-resizeable task="
2262 + this + " in stack=" + inStack);
2263 }
Bryce Leef3c6a472017-11-14 14:53:06 -08002264 if (!matchParentBounds()) {
Wale Ogunwale935e5022015-11-10 12:36:10 -08002265 return;
2266 }
2267 if (mLastNonFullscreenBounds != null) {
2268 updateOverrideConfiguration(mLastNonFullscreenBounds);
2269 } else {
Bryce Leeec55eb02017-12-05 20:51:27 -08002270 mService.mStackSupervisor.getLaunchParamsController().layoutTask(this, null);
Wale Ogunwale935e5022015-11-10 12:36:10 -08002271 }
2272 } else {
Evan Roskydfe3da72018-10-26 17:21:06 -07002273 updateOverrideConfiguration(inStack.getRequestedOverrideBounds());
Wale Ogunwale935e5022015-11-10 12:36:10 -08002274 }
2275 }
2276
Wale Ogunwale706ed792015-08-02 10:29:44 -07002277 /** Returns the bounds that should be used to launch this task. */
Wale Ogunwale30e441d2017-11-09 08:28:45 -08002278 Rect getLaunchBounds() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07002279 if (mStack == null) {
Chong Zhang7d5f5102016-01-13 10:29:24 -08002280 return null;
2281 }
2282
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002283 final int windowingMode = getWindowingMode();
2284 if (!isActivityTypeStandardOrUndefined()
2285 || windowingMode == WINDOWING_MODE_FULLSCREEN
2286 || (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY && !isResizeable())) {
Evan Roskydfe3da72018-10-26 17:21:06 -07002287 return isResizeable() ? mStack.getRequestedOverrideBounds() : null;
Wale Ogunwale3382ab12017-07-27 08:55:03 -07002288 } else if (!getWindowConfiguration().persistTaskBounds()) {
Evan Roskydfe3da72018-10-26 17:21:06 -07002289 return mStack.getRequestedOverrideBounds();
Wale Ogunwale706ed792015-08-02 10:29:44 -07002290 }
2291 return mLastNonFullscreenBounds;
2292 }
2293
Jorim Jaggi8b702ed2017-01-20 16:59:03 +01002294 void addStartingWindowsForVisibleActivities(boolean taskSwitch) {
2295 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
2296 final ActivityRecord r = mActivities.get(activityNdx);
2297 if (r.visible) {
2298 r.showStartingWindow(null /* prev */, false /* newTask */, taskSwitch);
2299 }
2300 }
2301 }
2302
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002303 void setRootProcess(WindowProcessController proc) {
Dianne Hackborn68a06332017-11-15 17:54:18 -08002304 clearRootProcess();
2305 if (intent != null &&
2306 (intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0) {
2307 mRootProcess = proc;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002308 mRootProcess.addRecentTask(this);
Dianne Hackborn68a06332017-11-15 17:54:18 -08002309 }
2310 }
2311
2312 void clearRootProcess() {
2313 if (mRootProcess != null) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002314 mRootProcess.removeRecentTask(this);
Dianne Hackborn68a06332017-11-15 17:54:18 -08002315 mRootProcess = null;
2316 }
2317 }
2318
chaviw82a0ba82018-03-15 14:26:29 -07002319 void clearAllPendingOptions() {
2320 for (int i = getChildCount() - 1; i >= 0; i--) {
2321 getChildAt(i).clearOptionsLocked(false /* withAbort */);
2322 }
2323 }
2324
Winson Chungabfdcce2018-07-02 17:23:33 -07002325 /**
2326 * Fills in a {@link TaskInfo} with information from this task.
2327 * @param info the {@link TaskInfo} to fill in
2328 * @param reuseActivitiesReport a temporary activities report that we can reuse to fetch the
2329 * running activities
2330 */
2331 void fillTaskInfo(TaskInfo info, TaskActivitiesReport reuseActivitiesReport) {
2332 getNumRunningActivities(reuseActivitiesReport);
2333 info.userId = userId;
2334 info.stackId = getStackId();
2335 info.taskId = taskId;
Mark Renoufb1abb552019-02-08 13:51:41 -05002336 info.displayId = mStack == null ? Display.INVALID_DISPLAY : mStack.mDisplayId;
Winson Chungabfdcce2018-07-02 17:23:33 -07002337 info.isRunning = getTopActivity() != null;
Riddle Hsu2f9acd22018-11-06 23:44:43 +08002338 info.baseIntent = new Intent(getBaseIntent());
Winson Chungabfdcce2018-07-02 17:23:33 -07002339 info.baseActivity = reuseActivitiesReport.base != null
2340 ? reuseActivitiesReport.base.intent.getComponent()
2341 : null;
2342 info.topActivity = reuseActivitiesReport.top != null
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002343 ? reuseActivitiesReport.top.mActivityComponent
Winson Chungabfdcce2018-07-02 17:23:33 -07002344 : null;
2345 info.origActivity = origActivity;
2346 info.realActivity = realActivity;
2347 info.numActivities = reuseActivitiesReport.numActivities;
2348 info.lastActiveTime = lastActiveTime;
2349 info.taskDescription = new ActivityManager.TaskDescription(lastTaskDescription);
2350 info.supportsSplitScreenMultiWindow = supportsSplitScreenWindowingMode();
2351 info.resizeMode = mResizeMode;
2352 info.configuration.setTo(getConfiguration());
2353 }
2354
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002355 void dump(PrintWriter pw, String prefix) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002356 pw.print(prefix); pw.print("userId="); pw.print(userId);
Dianne Hackborn885fbe52014-08-23 15:23:58 -07002357 pw.print(" effectiveUid="); UserHandle.formatUid(pw, effectiveUid);
2358 pw.print(" mCallingUid="); UserHandle.formatUid(pw, mCallingUid);
Suprabh Shukla7745c142016-03-07 18:21:10 -08002359 pw.print(" mUserSetupComplete="); pw.print(mUserSetupComplete);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002360 pw.print(" mCallingPackage="); pw.println(mCallingPackage);
Dianne Hackborn79228822014-09-16 11:11:23 -07002361 if (affinity != null || rootAffinity != null) {
2362 pw.print(prefix); pw.print("affinity="); pw.print(affinity);
2363 if (affinity == null || !affinity.equals(rootAffinity)) {
2364 pw.print(" root="); pw.println(rootAffinity);
2365 } else {
2366 pw.println();
2367 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002368 }
Dianne Hackborn91097de2014-04-04 18:02:06 -07002369 if (voiceSession != null || voiceInteractor != null) {
2370 pw.print(prefix); pw.print("VOICE: session=0x");
2371 pw.print(Integer.toHexString(System.identityHashCode(voiceSession)));
2372 pw.print(" interactor=0x");
2373 pw.println(Integer.toHexString(System.identityHashCode(voiceInteractor)));
2374 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002375 if (intent != null) {
2376 StringBuilder sb = new StringBuilder(128);
2377 sb.append(prefix); sb.append("intent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08002378 intent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002379 sb.append('}');
2380 pw.println(sb.toString());
2381 }
2382 if (affinityIntent != null) {
2383 StringBuilder sb = new StringBuilder(128);
2384 sb.append(prefix); sb.append("affinityIntent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08002385 affinityIntent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002386 sb.append('}');
2387 pw.println(sb.toString());
2388 }
2389 if (origActivity != null) {
2390 pw.print(prefix); pw.print("origActivity=");
2391 pw.println(origActivity.flattenToShortString());
2392 }
2393 if (realActivity != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002394 pw.print(prefix); pw.print("mActivityComponent=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002395 pw.println(realActivity.flattenToShortString());
2396 }
Wale Ogunwale66e16852017-10-19 13:35:52 -07002397 if (autoRemoveRecents || isPersistable || !isActivityTypeStandard() || numFullscreen != 0) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002398 pw.print(prefix); pw.print("autoRemoveRecents="); pw.print(autoRemoveRecents);
Dianne Hackborn852975d2014-08-22 17:42:43 -07002399 pw.print(" isPersistable="); pw.print(isPersistable);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002400 pw.print(" numFullscreen="); pw.print(numFullscreen);
Wale Ogunwale66e16852017-10-19 13:35:52 -07002401 pw.print(" activityType="); pw.println(getActivityType());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002402 }
Craig Mautner432f64e2015-05-20 14:59:57 -07002403 if (rootWasReset || mNeverRelinquishIdentity || mReuseTask
2404 || mLockTaskAuth != LOCK_TASK_AUTH_PINNABLE) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002405 pw.print(prefix); pw.print("rootWasReset="); pw.print(rootWasReset);
2406 pw.print(" mNeverRelinquishIdentity="); pw.print(mNeverRelinquishIdentity);
Craig Mautner432f64e2015-05-20 14:59:57 -07002407 pw.print(" mReuseTask="); pw.print(mReuseTask);
2408 pw.print(" mLockTaskAuth="); pw.println(lockTaskAuthToString());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002409 }
Wale Ogunwale18795a22014-12-03 11:38:33 -08002410 if (mAffiliatedTaskId != taskId || mPrevAffiliateTaskId != INVALID_TASK_ID
2411 || mPrevAffiliate != null || mNextAffiliateTaskId != INVALID_TASK_ID
2412 || mNextAffiliate != null) {
Dianne Hackborn852975d2014-08-22 17:42:43 -07002413 pw.print(prefix); pw.print("affiliation="); pw.print(mAffiliatedTaskId);
2414 pw.print(" prevAffiliation="); pw.print(mPrevAffiliateTaskId);
2415 pw.print(" (");
2416 if (mPrevAffiliate == null) {
2417 pw.print("null");
2418 } else {
2419 pw.print(Integer.toHexString(System.identityHashCode(mPrevAffiliate)));
2420 }
2421 pw.print(") nextAffiliation="); pw.print(mNextAffiliateTaskId);
2422 pw.print(" (");
2423 if (mNextAffiliate == null) {
2424 pw.print("null");
2425 } else {
2426 pw.print(Integer.toHexString(System.identityHashCode(mNextAffiliate)));
2427 }
2428 pw.println(")");
2429 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002430 pw.print(prefix); pw.print("Activities="); pw.println(mActivities);
Dianne Hackborn852975d2014-08-22 17:42:43 -07002431 if (!askedCompatMode || !inRecents || !isAvailable) {
2432 pw.print(prefix); pw.print("askedCompatMode="); pw.print(askedCompatMode);
2433 pw.print(" inRecents="); pw.print(inRecents);
2434 pw.print(" isAvailable="); pw.println(isAvailable);
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002435 }
Dianne Hackborn852975d2014-08-22 17:42:43 -07002436 if (lastDescription != null) {
2437 pw.print(prefix); pw.print("lastDescription="); pw.println(lastDescription);
2438 }
Dianne Hackborn68a06332017-11-15 17:54:18 -08002439 if (mRootProcess != null) {
2440 pw.print(prefix); pw.print("mRootProcess="); pw.println(mRootProcess);
2441 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07002442 pw.print(prefix); pw.print("stackId="); pw.println(getStackId());
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002443 pw.print(prefix + "hasBeenVisible=" + hasBeenVisible);
2444 pw.print(" mResizeMode=" + ActivityInfo.resizeModeToString(mResizeMode));
Winson Chungd3395382016-12-13 11:49:09 -08002445 pw.print(" mSupportsPictureInPicture=" + mSupportsPictureInPicture);
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002446 pw.print(" isResizeable=" + isResizeable());
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002447 pw.print(" lastActiveTime=" + lastActiveTime);
2448 pw.println(" (inactive for " + (getInactiveDuration() / 1000) + "s)");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002449 }
2450
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002451 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002452 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002453 StringBuilder sb = new StringBuilder(128);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002454 if (stringName != null) {
2455 sb.append(stringName);
2456 sb.append(" U=");
2457 sb.append(userId);
Wale Ogunwale6c5eb1c2015-11-10 07:52:22 -08002458 sb.append(" StackId=");
Andrii Kulian02b7a832016-10-06 23:11:56 -07002459 sb.append(getStackId());
Craig Mautnerde4ef022013-04-07 19:01:33 -07002460 sb.append(" sz=");
2461 sb.append(mActivities.size());
2462 sb.append('}');
2463 return sb.toString();
2464 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002465 sb.append("TaskRecord{");
2466 sb.append(Integer.toHexString(System.identityHashCode(this)));
2467 sb.append(" #");
2468 sb.append(taskId);
2469 if (affinity != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002470 sb.append(" A=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002471 sb.append(affinity);
2472 } else if (intent != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002473 sb.append(" I=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002474 sb.append(intent.getComponent().flattenToShortString());
Bryce Leefbd263b42018-03-07 10:33:55 -08002475 } else if (affinityIntent != null && affinityIntent.getComponent() != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002476 sb.append(" aI=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002477 sb.append(affinityIntent.getComponent().flattenToShortString());
2478 } else {
2479 sb.append(" ??");
2480 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07002481 stringName = sb.toString();
2482 return toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002483 }
Steven Timotius4346f0a2017-09-12 11:07:21 -07002484
Nataniel Borges023ecb52019-01-16 14:15:43 -08002485 public void writeToProto(ProtoOutputStream proto, long fieldId,
2486 @WindowTraceLogLevel int logLevel) {
2487 if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) {
2488 return;
2489 }
2490
Steven Timotius4346f0a2017-09-12 11:07:21 -07002491 final long token = proto.start(fieldId);
Nataniel Borges023ecb52019-01-16 14:15:43 -08002492 super.writeToProto(proto, CONFIGURATION_CONTAINER, logLevel);
Steven Timotius4346f0a2017-09-12 11:07:21 -07002493 proto.write(ID, taskId);
2494 for (int i = mActivities.size() - 1; i >= 0; i--) {
2495 ActivityRecord activity = mActivities.get(i);
2496 activity.writeToProto(proto, ACTIVITIES);
2497 }
2498 proto.write(STACK_ID, mStack.mStackId);
2499 if (mLastNonFullscreenBounds != null) {
2500 mLastNonFullscreenBounds.writeToProto(proto, LAST_NON_FULLSCREEN_BOUNDS);
2501 }
2502 if (realActivity != null) {
2503 proto.write(REAL_ACTIVITY, realActivity.flattenToShortString());
2504 }
2505 if (origActivity != null) {
2506 proto.write(ORIG_ACTIVITY, origActivity.flattenToShortString());
2507 }
2508 proto.write(ACTIVITY_TYPE, getActivityType());
Steven Timotius4346f0a2017-09-12 11:07:21 -07002509 proto.write(RESIZE_MODE, mResizeMode);
Bryce Leef3c6a472017-11-14 14:53:06 -08002510 // TODO: Remove, no longer needed with windowingMode.
2511 proto.write(FULLSCREEN, matchParentBounds());
2512
2513 if (!matchParentBounds()) {
Evan Roskydfe3da72018-10-26 17:21:06 -07002514 final Rect bounds = getRequestedOverrideBounds();
Bryce Leef3c6a472017-11-14 14:53:06 -08002515 bounds.writeToProto(proto, BOUNDS);
Steven Timotius4346f0a2017-09-12 11:07:21 -07002516 }
2517 proto.write(MIN_WIDTH, mMinWidth);
2518 proto.write(MIN_HEIGHT, mMinHeight);
2519 proto.end(token);
2520 }
Winson Chung61c9e5a2017-10-11 10:39:32 -07002521
2522 /**
2523 * See {@link #getNumRunningActivities(TaskActivitiesReport)}.
2524 */
2525 static class TaskActivitiesReport {
2526 int numRunning;
2527 int numActivities;
2528 ActivityRecord top;
2529 ActivityRecord base;
2530
2531 void reset() {
2532 numRunning = numActivities = 0;
2533 top = base = null;
2534 }
2535 }
Garfield Tan9b1efea2017-12-05 16:43:46 -08002536
2537 /**
2538 * Saves this {@link TaskRecord} to XML using given serializer.
2539 */
2540 void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
2541 if (DEBUG_RECENTS) Slog.i(TAG_RECENTS, "Saving task=" + this);
2542
2543 out.attribute(null, ATTR_TASKID, String.valueOf(taskId));
2544 if (realActivity != null) {
2545 out.attribute(null, ATTR_REALACTIVITY, realActivity.flattenToShortString());
2546 }
2547 out.attribute(null, ATTR_REALACTIVITY_SUSPENDED, String.valueOf(realActivitySuspended));
2548 if (origActivity != null) {
2549 out.attribute(null, ATTR_ORIGACTIVITY, origActivity.flattenToShortString());
2550 }
2551 // Write affinity, and root affinity if it is different from affinity.
2552 // We use the special string "@" for a null root affinity, so we can identify
2553 // later whether we were given a root affinity or should just make it the
2554 // same as the affinity.
2555 if (affinity != null) {
2556 out.attribute(null, ATTR_AFFINITY, affinity);
2557 if (!affinity.equals(rootAffinity)) {
2558 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
2559 }
2560 } else if (rootAffinity != null) {
2561 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
2562 }
2563 out.attribute(null, ATTR_ROOTHASRESET, String.valueOf(rootWasReset));
2564 out.attribute(null, ATTR_AUTOREMOVERECENTS, String.valueOf(autoRemoveRecents));
2565 out.attribute(null, ATTR_ASKEDCOMPATMODE, String.valueOf(askedCompatMode));
2566 out.attribute(null, ATTR_USERID, String.valueOf(userId));
2567 out.attribute(null, ATTR_USER_SETUP_COMPLETE, String.valueOf(mUserSetupComplete));
2568 out.attribute(null, ATTR_EFFECTIVE_UID, String.valueOf(effectiveUid));
2569 out.attribute(null, ATTR_LASTTIMEMOVED, String.valueOf(mLastTimeMoved));
2570 out.attribute(null, ATTR_NEVERRELINQUISH, String.valueOf(mNeverRelinquishIdentity));
2571 if (lastDescription != null) {
2572 out.attribute(null, ATTR_LASTDESCRIPTION, lastDescription.toString());
2573 }
2574 if (lastTaskDescription != null) {
2575 lastTaskDescription.saveToXml(out);
2576 }
2577 out.attribute(null, ATTR_TASK_AFFILIATION_COLOR, String.valueOf(mAffiliatedTaskColor));
2578 out.attribute(null, ATTR_TASK_AFFILIATION, String.valueOf(mAffiliatedTaskId));
2579 out.attribute(null, ATTR_PREV_AFFILIATION, String.valueOf(mPrevAffiliateTaskId));
2580 out.attribute(null, ATTR_NEXT_AFFILIATION, String.valueOf(mNextAffiliateTaskId));
2581 out.attribute(null, ATTR_CALLING_UID, String.valueOf(mCallingUid));
2582 out.attribute(null, ATTR_CALLING_PACKAGE, mCallingPackage == null ? "" : mCallingPackage);
2583 out.attribute(null, ATTR_RESIZE_MODE, String.valueOf(mResizeMode));
2584 out.attribute(null, ATTR_SUPPORTS_PICTURE_IN_PICTURE,
2585 String.valueOf(mSupportsPictureInPicture));
2586 if (mLastNonFullscreenBounds != null) {
2587 out.attribute(
2588 null, ATTR_NON_FULLSCREEN_BOUNDS, mLastNonFullscreenBounds.flattenToString());
2589 }
2590 out.attribute(null, ATTR_MIN_WIDTH, String.valueOf(mMinWidth));
2591 out.attribute(null, ATTR_MIN_HEIGHT, String.valueOf(mMinHeight));
2592 out.attribute(null, ATTR_PERSIST_TASK_VERSION, String.valueOf(PERSIST_TASK_VERSION));
2593
2594 if (affinityIntent != null) {
2595 out.startTag(null, TAG_AFFINITYINTENT);
2596 affinityIntent.saveToXml(out);
2597 out.endTag(null, TAG_AFFINITYINTENT);
2598 }
2599
Bryce Lee1a990e52018-04-23 10:54:11 -07002600 if (intent != null) {
2601 out.startTag(null, TAG_INTENT);
2602 intent.saveToXml(out);
2603 out.endTag(null, TAG_INTENT);
2604 }
Garfield Tan9b1efea2017-12-05 16:43:46 -08002605
2606 final ArrayList<ActivityRecord> activities = mActivities;
2607 final int numActivities = activities.size();
2608 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
2609 final ActivityRecord r = activities.get(activityNdx);
2610 if (r.info.persistableMode == ActivityInfo.PERSIST_ROOT_ONLY || !r.isPersistable() ||
2611 ((r.intent.getFlags() & FLAG_ACTIVITY_NEW_DOCUMENT
2612 | FLAG_ACTIVITY_RETAIN_IN_RECENTS) == FLAG_ACTIVITY_NEW_DOCUMENT) &&
2613 activityNdx > 0) {
2614 // Stop at first non-persistable or first break in task (CLEAR_WHEN_TASK_RESET).
2615 break;
2616 }
2617 out.startTag(null, TAG_ACTIVITY);
2618 r.saveToXml(out);
2619 out.endTag(null, TAG_ACTIVITY);
2620 }
2621 }
2622
2623 @VisibleForTesting
2624 static TaskRecordFactory getTaskRecordFactory() {
2625 if (sTaskRecordFactory == null) {
2626 setTaskRecordFactory(new TaskRecordFactory());
2627 }
2628 return sTaskRecordFactory;
2629 }
2630
2631 static void setTaskRecordFactory(TaskRecordFactory factory) {
2632 sTaskRecordFactory = factory;
2633 }
2634
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002635 static TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002636 Intent intent, IVoiceInteractionSession voiceSession,
2637 IVoiceInteractor voiceInteractor) {
2638 return getTaskRecordFactory().create(
2639 service, taskId, info, intent, voiceSession, voiceInteractor);
2640 }
2641
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002642 static TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002643 Intent intent, TaskDescription taskDescription) {
2644 return getTaskRecordFactory().create(service, taskId, info, intent, taskDescription);
2645 }
2646
2647 static TaskRecord restoreFromXml(XmlPullParser in, ActivityStackSupervisor stackSupervisor)
2648 throws IOException, XmlPullParserException {
2649 return getTaskRecordFactory().restoreFromXml(in, stackSupervisor);
2650 }
2651
2652 /**
2653 * A factory class used to create {@link TaskRecord} or its subclass if any. This can be
2654 * specified when system boots by setting it with
2655 * {@link #setTaskRecordFactory(TaskRecordFactory)}.
2656 */
2657 static class TaskRecordFactory {
2658
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002659 TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002660 Intent intent, IVoiceInteractionSession voiceSession,
2661 IVoiceInteractor voiceInteractor) {
2662 return new TaskRecord(
2663 service, taskId, info, intent, voiceSession, voiceInteractor);
2664 }
2665
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002666 TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002667 Intent intent, TaskDescription taskDescription) {
2668 return new TaskRecord(service, taskId, info, intent, taskDescription);
2669 }
2670
2671 /**
2672 * Should only be used when we're restoring {@link TaskRecord} from storage.
2673 */
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002674 TaskRecord create(ActivityTaskManagerService service, int taskId, Intent intent,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002675 Intent affinityIntent, String affinity, String rootAffinity,
2676 ComponentName realActivity, ComponentName origActivity, boolean rootWasReset,
2677 boolean autoRemoveRecents, boolean askedCompatMode, int userId,
2678 int effectiveUid, String lastDescription, ArrayList<ActivityRecord> activities,
2679 long lastTimeMoved, boolean neverRelinquishIdentity,
2680 TaskDescription lastTaskDescription, int taskAffiliation, int prevTaskId,
2681 int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage,
2682 int resizeMode, boolean supportsPictureInPicture, boolean realActivitySuspended,
2683 boolean userSetupComplete, int minWidth, int minHeight) {
2684 return new TaskRecord(service, taskId, intent, affinityIntent, affinity,
2685 rootAffinity, realActivity, origActivity, rootWasReset, autoRemoveRecents,
2686 askedCompatMode, userId, effectiveUid, lastDescription, activities,
2687 lastTimeMoved, neverRelinquishIdentity, lastTaskDescription, taskAffiliation,
2688 prevTaskId, nextTaskId, taskAffiliationColor, callingUid, callingPackage,
2689 resizeMode, supportsPictureInPicture, realActivitySuspended, userSetupComplete,
2690 minWidth, minHeight);
2691 }
2692
2693 TaskRecord restoreFromXml(XmlPullParser in, ActivityStackSupervisor stackSupervisor)
2694 throws IOException, XmlPullParserException {
2695 Intent intent = null;
2696 Intent affinityIntent = null;
2697 ArrayList<ActivityRecord> activities = new ArrayList<>();
2698 ComponentName realActivity = null;
2699 boolean realActivitySuspended = false;
2700 ComponentName origActivity = null;
2701 String affinity = null;
2702 String rootAffinity = null;
2703 boolean hasRootAffinity = false;
2704 boolean rootHasReset = false;
2705 boolean autoRemoveRecents = false;
2706 boolean askedCompatMode = false;
2707 int taskType = 0;
2708 int userId = 0;
2709 boolean userSetupComplete = true;
2710 int effectiveUid = -1;
2711 String lastDescription = null;
2712 long lastTimeOnTop = 0;
2713 boolean neverRelinquishIdentity = true;
2714 int taskId = INVALID_TASK_ID;
2715 final int outerDepth = in.getDepth();
2716 TaskDescription taskDescription = new TaskDescription();
2717 int taskAffiliation = INVALID_TASK_ID;
2718 int taskAffiliationColor = 0;
2719 int prevTaskId = INVALID_TASK_ID;
2720 int nextTaskId = INVALID_TASK_ID;
2721 int callingUid = -1;
2722 String callingPackage = "";
2723 int resizeMode = RESIZE_MODE_FORCE_RESIZEABLE;
2724 boolean supportsPictureInPicture = false;
Garfield Tan367b35a2017-12-13 12:16:21 -08002725 Rect lastNonFullscreenBounds = null;
Garfield Tan9b1efea2017-12-05 16:43:46 -08002726 int minWidth = INVALID_MIN_SIZE;
2727 int minHeight = INVALID_MIN_SIZE;
2728 int persistTaskVersion = 0;
2729
2730 for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
2731 final String attrName = in.getAttributeName(attrNdx);
2732 final String attrValue = in.getAttributeValue(attrNdx);
2733 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: attribute name=" +
2734 attrName + " value=" + attrValue);
2735 switch (attrName) {
2736 case ATTR_TASKID:
2737 if (taskId == INVALID_TASK_ID) taskId = Integer.parseInt(attrValue);
2738 break;
2739 case ATTR_REALACTIVITY:
2740 realActivity = ComponentName.unflattenFromString(attrValue);
2741 break;
2742 case ATTR_REALACTIVITY_SUSPENDED:
2743 realActivitySuspended = Boolean.valueOf(attrValue);
2744 break;
2745 case ATTR_ORIGACTIVITY:
2746 origActivity = ComponentName.unflattenFromString(attrValue);
2747 break;
2748 case ATTR_AFFINITY:
2749 affinity = attrValue;
2750 break;
2751 case ATTR_ROOT_AFFINITY:
2752 rootAffinity = attrValue;
2753 hasRootAffinity = true;
2754 break;
2755 case ATTR_ROOTHASRESET:
2756 rootHasReset = Boolean.parseBoolean(attrValue);
2757 break;
2758 case ATTR_AUTOREMOVERECENTS:
2759 autoRemoveRecents = Boolean.parseBoolean(attrValue);
2760 break;
2761 case ATTR_ASKEDCOMPATMODE:
2762 askedCompatMode = Boolean.parseBoolean(attrValue);
2763 break;
2764 case ATTR_USERID:
2765 userId = Integer.parseInt(attrValue);
2766 break;
2767 case ATTR_USER_SETUP_COMPLETE:
2768 userSetupComplete = Boolean.parseBoolean(attrValue);
2769 break;
2770 case ATTR_EFFECTIVE_UID:
2771 effectiveUid = Integer.parseInt(attrValue);
2772 break;
2773 case ATTR_TASKTYPE:
2774 taskType = Integer.parseInt(attrValue);
2775 break;
2776 case ATTR_LASTDESCRIPTION:
2777 lastDescription = attrValue;
2778 break;
2779 case ATTR_LASTTIMEMOVED:
2780 lastTimeOnTop = Long.parseLong(attrValue);
2781 break;
2782 case ATTR_NEVERRELINQUISH:
2783 neverRelinquishIdentity = Boolean.parseBoolean(attrValue);
2784 break;
2785 case ATTR_TASK_AFFILIATION:
2786 taskAffiliation = Integer.parseInt(attrValue);
2787 break;
2788 case ATTR_PREV_AFFILIATION:
2789 prevTaskId = Integer.parseInt(attrValue);
2790 break;
2791 case ATTR_NEXT_AFFILIATION:
2792 nextTaskId = Integer.parseInt(attrValue);
2793 break;
2794 case ATTR_TASK_AFFILIATION_COLOR:
2795 taskAffiliationColor = Integer.parseInt(attrValue);
2796 break;
2797 case ATTR_CALLING_UID:
2798 callingUid = Integer.parseInt(attrValue);
2799 break;
2800 case ATTR_CALLING_PACKAGE:
2801 callingPackage = attrValue;
2802 break;
2803 case ATTR_RESIZE_MODE:
2804 resizeMode = Integer.parseInt(attrValue);
2805 break;
2806 case ATTR_SUPPORTS_PICTURE_IN_PICTURE:
2807 supportsPictureInPicture = Boolean.parseBoolean(attrValue);
2808 break;
2809 case ATTR_NON_FULLSCREEN_BOUNDS:
Garfield Tan367b35a2017-12-13 12:16:21 -08002810 lastNonFullscreenBounds = Rect.unflattenFromString(attrValue);
Garfield Tan9b1efea2017-12-05 16:43:46 -08002811 break;
2812 case ATTR_MIN_WIDTH:
2813 minWidth = Integer.parseInt(attrValue);
2814 break;
2815 case ATTR_MIN_HEIGHT:
2816 minHeight = Integer.parseInt(attrValue);
2817 break;
2818 case ATTR_PERSIST_TASK_VERSION:
2819 persistTaskVersion = Integer.parseInt(attrValue);
2820 break;
2821 default:
2822 if (attrName.startsWith(TaskDescription.ATTR_TASKDESCRIPTION_PREFIX)) {
2823 taskDescription.restoreFromXml(attrName, attrValue);
2824 } else {
2825 Slog.w(TAG, "TaskRecord: Unknown attribute=" + attrName);
2826 }
2827 }
2828 }
2829
2830 int event;
2831 while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
2832 (event != XmlPullParser.END_TAG || in.getDepth() >= outerDepth)) {
2833 if (event == XmlPullParser.START_TAG) {
2834 final String name = in.getName();
2835 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG,
2836 "TaskRecord: START_TAG name=" + name);
2837 if (TAG_AFFINITYINTENT.equals(name)) {
2838 affinityIntent = Intent.restoreFromXml(in);
2839 } else if (TAG_INTENT.equals(name)) {
2840 intent = Intent.restoreFromXml(in);
2841 } else if (TAG_ACTIVITY.equals(name)) {
2842 ActivityRecord activity =
2843 ActivityRecord.restoreFromXml(in, stackSupervisor);
2844 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: activity=" +
2845 activity);
2846 if (activity != null) {
2847 activities.add(activity);
2848 }
2849 } else {
Garfield Tan1e740192017-12-12 14:37:42 -08002850 handleUnknownTag(name, in);
Garfield Tan9b1efea2017-12-05 16:43:46 -08002851 }
2852 }
2853 }
2854 if (!hasRootAffinity) {
2855 rootAffinity = affinity;
2856 } else if ("@".equals(rootAffinity)) {
2857 rootAffinity = null;
2858 }
2859 if (effectiveUid <= 0) {
2860 Intent checkIntent = intent != null ? intent : affinityIntent;
2861 effectiveUid = 0;
2862 if (checkIntent != null) {
2863 IPackageManager pm = AppGlobals.getPackageManager();
2864 try {
2865 ApplicationInfo ai = pm.getApplicationInfo(
2866 checkIntent.getComponent().getPackageName(),
2867 PackageManager.MATCH_UNINSTALLED_PACKAGES
2868 | PackageManager.MATCH_DISABLED_COMPONENTS, userId);
2869 if (ai != null) {
2870 effectiveUid = ai.uid;
2871 }
2872 } catch (RemoteException e) {
2873 }
2874 }
2875 Slog.w(TAG, "Updating task #" + taskId + " for " + checkIntent
2876 + ": effectiveUid=" + effectiveUid);
2877 }
2878
2879 if (persistTaskVersion < 1) {
2880 // We need to convert the resize mode of home activities saved before version one if
2881 // they are marked as RESIZE_MODE_RESIZEABLE to
2882 // RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION since we didn't have that differentiation
2883 // before version 1 and the system didn't resize home activities before then.
2884 if (taskType == 1 /* old home type */ && resizeMode == RESIZE_MODE_RESIZEABLE) {
2885 resizeMode = RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
2886 }
2887 } else {
2888 // This activity has previously marked itself explicitly as both resizeable and
2889 // supporting picture-in-picture. Since there is no longer a requirement for
2890 // picture-in-picture activities to be resizeable, we can mark this simply as
2891 // resizeable and supporting picture-in-picture separately.
2892 if (resizeMode == RESIZE_MODE_RESIZEABLE_AND_PIPABLE_DEPRECATED) {
2893 resizeMode = RESIZE_MODE_RESIZEABLE;
2894 supportsPictureInPicture = true;
2895 }
2896 }
2897
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07002898 final TaskRecord task = create(stackSupervisor.mService,
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002899 taskId, intent, affinityIntent,
Garfield Tan9b1efea2017-12-05 16:43:46 -08002900 affinity, rootAffinity, realActivity, origActivity, rootHasReset,
2901 autoRemoveRecents, askedCompatMode, userId, effectiveUid, lastDescription,
2902 activities, lastTimeOnTop, neverRelinquishIdentity, taskDescription,
2903 taskAffiliation, prevTaskId, nextTaskId, taskAffiliationColor, callingUid,
2904 callingPackage, resizeMode, supportsPictureInPicture, realActivitySuspended,
2905 userSetupComplete, minWidth, minHeight);
Garfield Tan367b35a2017-12-13 12:16:21 -08002906 task.mLastNonFullscreenBounds = lastNonFullscreenBounds;
2907 task.setBounds(lastNonFullscreenBounds);
Garfield Tan9b1efea2017-12-05 16:43:46 -08002908
2909 for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {
2910 activities.get(activityNdx).setTask(task);
2911 }
2912
2913 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Restored task=" + task);
2914 return task;
2915 }
Garfield Tan1e740192017-12-12 14:37:42 -08002916
2917 void handleUnknownTag(String name, XmlPullParser in)
2918 throws IOException, XmlPullParserException {
2919 Slog.e(TAG, "restoreTask: Unexpected name=" + name);
2920 XmlUtils.skipCurrentTag(in);
2921 }
Garfield Tan9b1efea2017-12-05 16:43:46 -08002922 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002923}