blob: 5c0d587a1202a0203acfbfc35273344b16243de3 [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
17package com.android.server.am;
18
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -080019import static android.app.ActivityManager.RESIZE_MODE_FORCED;
Winson Chung74666102017-02-22 17:49:24 -080020import static android.app.ActivityManager.RESIZE_MODE_SYSTEM;
Winson Chung83471632016-12-13 11:02:12 -080021import static android.app.ActivityManager.StackId.ASSISTANT_STACK_ID;
Jorim Jaggi0a932142016-02-01 17:42:25 -080022import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
23import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
24import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
25import static android.app.ActivityManager.StackId.HOME_STACK_ID;
26import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
27import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
Matthew Ngae1ff4f2016-11-10 15:49:14 -080028import static android.app.ActivityManager.StackId.RECENTS_STACK_ID;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -070029import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
30import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
31import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
32import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
33import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
Jorim Jaggi0a932142016-02-01 17:42:25 -080034import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
35import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
Wale Ogunwale3eadad72016-10-13 09:16:59 -070036import static android.content.pm.ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY;
Jorim Jaggi0a932142016-02-01 17:42:25 -080037import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
38import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
39import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
40import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER;
skuhne@google.com322347b2016-12-02 12:54:03 -080041import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY;
42import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PORTRAIT_ONLY;
43import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PRESERVE_ORIENTATION;
Wale Ogunwaled829d362016-02-10 19:24:49 -080044import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
Wale Ogunwale625ed0c2016-10-18 08:50:31 -070045import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
Winson Chungd3395382016-12-13 11:49:09 -080046import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_AND_PIPABLE_DEPRECATED;
Wale Ogunwale625ed0c2016-10-18 08:50:31 -070047import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
Jorim Jaggi0a932142016-02-01 17:42:25 -080048import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -080049import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
Suprabh Shukla7745c142016-03-07 18:21:10 -080050import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
Andrii Kulian036e3ad2017-04-19 10:55:10 -070051import static android.view.Display.DEFAULT_DISPLAY;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -070052
Jorim Jaggi0a932142016-02-01 17:42:25 -080053import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ADD_REMOVE;
54import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
55import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
56import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
57import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_ADD_REMOVE;
58import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
59import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
60import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS;
61import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
62import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
Wale Ogunwale3b232392016-05-13 15:37:13 -070063import static com.android.server.am.ActivityRecord.STARTING_WINDOW_SHOWN;
Wale Ogunwalec5cc3012017-01-13 13:26:16 -080064import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING;
Wale Ogunwale56d8d162017-05-30 11:12:20 -070065import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING_TO_TOP;
Winson Chung6954fc92017-03-24 16:22:12 -070066import static com.android.server.am.ActivityStackSupervisor.PAUSE_IMMEDIATELY;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -080067import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -070068
Winson Chung74666102017-02-22 17:49:24 -080069import static java.lang.Integer.MAX_VALUE;
70
Jorim Jaggie7d2b852017-08-28 17:55:15 +020071import android.annotation.IntDef;
72import android.annotation.Nullable;
73import android.app.Activity;
74import android.app.ActivityManager;
75import android.app.ActivityManager.StackId;
76import android.app.ActivityManager.TaskDescription;
77import android.app.ActivityManager.TaskSnapshot;
78import android.app.ActivityOptions;
79import android.app.AppGlobals;
80import android.app.IActivityManager;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -070081import android.app.WindowConfiguration;
Jorim Jaggie7d2b852017-08-28 17:55:15 +020082import android.content.ComponentName;
83import android.content.Intent;
84import android.content.pm.ActivityInfo;
85import android.content.pm.ApplicationInfo;
86import android.content.pm.IPackageManager;
87import android.content.pm.PackageManager;
88import android.content.res.Configuration;
89import android.graphics.Rect;
90import android.os.Debug;
91import android.os.RemoteException;
92import android.os.Trace;
93import android.os.UserHandle;
94import android.provider.Settings;
95import android.service.voice.IVoiceInteractionSession;
96import android.util.DisplayMetrics;
97import android.util.Slog;
98
99import com.android.internal.annotations.VisibleForTesting;
100import com.android.internal.app.IVoiceInteractor;
101import com.android.internal.util.XmlUtils;
102import com.android.server.wm.AppWindowContainerController;
103import com.android.server.wm.ConfigurationContainer;
104import com.android.server.wm.StackWindowController;
105import com.android.server.wm.TaskWindowContainerController;
106import com.android.server.wm.TaskWindowContainerListener;
107import com.android.server.wm.WindowManagerService;
108
109import org.xmlpull.v1.XmlPullParser;
110import org.xmlpull.v1.XmlPullParserException;
111import org.xmlpull.v1.XmlSerializer;
112
113import java.io.IOException;
114import java.io.PrintWriter;
115import java.lang.annotation.Retention;
116import java.lang.annotation.RetentionPolicy;
117import java.util.ArrayList;
118import java.util.Objects;
119
Benjamin Franza83859f2017-07-03 16:34:14 +0100120class TaskRecord extends ConfigurationContainer implements TaskWindowContainerListener {
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800121 private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskRecord" : TAG_AM;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -0700122 private static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700123 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
Craig Mautnere0570202015-05-13 13:06:11 -0700124 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700125 private static final String TAG_TASKS = TAG + POSTFIX_TASKS;
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800126
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700127 private static final String ATTR_TASKID = "task_id";
Craig Mautner21d24a22014-04-23 11:45:37 -0700128 private static final String TAG_INTENT = "intent";
129 private static final String TAG_AFFINITYINTENT = "affinity_intent";
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700130 private static final String ATTR_REALACTIVITY = "real_activity";
131 private static final String ATTR_REALACTIVITY_SUSPENDED = "real_activity_suspended";
Craig Mautner21d24a22014-04-23 11:45:37 -0700132 private static final String ATTR_ORIGACTIVITY = "orig_activity";
Stefan Kuhnee88d1e52015-05-18 10:33:45 -0700133 private static final String TAG_ACTIVITY = "activity";
Craig Mautner21d24a22014-04-23 11:45:37 -0700134 private static final String ATTR_AFFINITY = "affinity";
Dianne Hackborn79228822014-09-16 11:11:23 -0700135 private static final String ATTR_ROOT_AFFINITY = "root_affinity";
Craig Mautner21d24a22014-04-23 11:45:37 -0700136 private static final String ATTR_ROOTHASRESET = "root_has_reset";
Dianne Hackborn13420f22014-07-18 15:43:56 -0700137 private static final String ATTR_AUTOREMOVERECENTS = "auto_remove_recents";
Craig Mautner21d24a22014-04-23 11:45:37 -0700138 private static final String ATTR_ASKEDCOMPATMODE = "asked_compat_mode";
139 private static final String ATTR_USERID = "user_id";
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800140 private static final String ATTR_USER_SETUP_COMPLETE = "user_setup_complete";
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700141 private static final String ATTR_EFFECTIVE_UID = "effective_uid";
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700142 @Deprecated
Craig Mautner21d24a22014-04-23 11:45:37 -0700143 private static final String ATTR_TASKTYPE = "task_type";
Winson Chungffa2ec62014-07-03 15:54:42 -0700144 private static final String ATTR_FIRSTACTIVETIME = "first_active_time";
Winson Chungf1fbd772014-06-24 18:06:58 -0700145 private static final String ATTR_LASTACTIVETIME = "last_active_time";
Craig Mautner21d24a22014-04-23 11:45:37 -0700146 private static final String ATTR_LASTDESCRIPTION = "last_description";
147 private static final String ATTR_LASTTIMEMOVED = "last_time_moved";
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700148 private static final String ATTR_NEVERRELINQUISH = "never_relinquish_identity";
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700149 private static final String ATTR_TASK_AFFILIATION = "task_affiliation";
Craig Mautnera228ae92014-07-09 05:44:55 -0700150 private static final String ATTR_PREV_AFFILIATION = "prev_affiliation";
151 private static final String ATTR_NEXT_AFFILIATION = "next_affiliation";
Winson Chungec396d62014-08-06 17:08:00 -0700152 private static final String ATTR_TASK_AFFILIATION_COLOR = "task_affiliation_color";
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700153 private static final String ATTR_CALLING_UID = "calling_uid";
154 private static final String ATTR_CALLING_PACKAGE = "calling_package";
Winson Chungd3395382016-12-13 11:49:09 -0800155 private static final String ATTR_SUPPORTS_PICTURE_IN_PICTURE = "supports_picture_in_picture";
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800156 private static final String ATTR_RESIZE_MODE = "resize_mode";
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700157 private static final String ATTR_PRIVILEGED = "privileged";
Wale Ogunwale706ed792015-08-02 10:29:44 -0700158 private static final String ATTR_NON_FULLSCREEN_BOUNDS = "non_fullscreen_bounds";
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700159 private static final String ATTR_MIN_WIDTH = "min_width";
160 private static final String ATTR_MIN_HEIGHT = "min_height";
Wale Ogunwale625ed0c2016-10-18 08:50:31 -0700161 private static final String ATTR_PERSIST_TASK_VERSION = "persist_task_version";
Andrii Kulian18d75122016-03-27 20:20:28 -0700162
Wale Ogunwale625ed0c2016-10-18 08:50:31 -0700163 // Current version of the task record we persist. Used to check if we need to run any upgrade
164 // code.
165 private static final int PERSIST_TASK_VERSION = 1;
Craig Mautner21d24a22014-04-23 11:45:37 -0700166 private static final String TASK_THUMBNAIL_SUFFIX = "_task_thumbnail";
167
Wale Ogunwale18795a22014-12-03 11:38:33 -0800168 static final int INVALID_TASK_ID = -1;
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700169 private static final int INVALID_MIN_SIZE = -1;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800170
Winson Chung74666102017-02-22 17:49:24 -0800171 /**
172 * The modes to control how the stack is moved to the front when calling
173 * {@link TaskRecord#reparent}.
174 */
175 @Retention(RetentionPolicy.SOURCE)
176 @IntDef({
177 REPARENT_MOVE_STACK_TO_FRONT,
178 REPARENT_KEEP_STACK_AT_FRONT,
179 REPARENT_LEAVE_STACK_IN_PLACE
180 })
181 public @interface ReparentMoveStackMode {}
182 // Moves the stack to the front if it was not at the front
183 public static final int REPARENT_MOVE_STACK_TO_FRONT = 0;
184 // Only moves the stack to the front if it was focused or front most already
185 public static final int REPARENT_KEEP_STACK_AT_FRONT = 1;
186 // Do not move the stack as a part of reparenting
187 public static final int REPARENT_LEAVE_STACK_IN_PLACE = 2;
188
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800189 final int taskId; // Unique identifier for this task.
Dianne Hackborn79228822014-09-16 11:11:23 -0700190 String affinity; // The affinity name for this task, or null; may change identity.
191 String rootAffinity; // Initial base affinity, or null; does not change from initial root.
Dianne Hackborn91097de2014-04-04 18:02:06 -0700192 final IVoiceInteractionSession voiceSession; // Voice interaction session driving task
193 final IVoiceInteractor voiceInteractor; // Associated interactor to provide to app
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800194 Intent intent; // The original intent that started the task.
195 Intent affinityIntent; // Intent of affinity-moved activity that started this task.
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700196 int effectiveUid; // The current effective uid of the identity of this task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800197 ComponentName origActivity; // The non-alias activity component of the intent.
198 ComponentName realActivity; // The actual activity component that started the task.
Andrei Stingaceanu4ccec532016-01-13 12:10:21 +0000199 boolean realActivitySuspended; // True if the actual activity component that started the
200 // task is suspended.
Winson Chung36f3f032016-09-08 23:29:43 +0000201 long firstActiveTime; // First time this task was active.
202 long lastActiveTime; // Last time this task was active, including sleep.
Dianne Hackborn852975d2014-08-22 17:42:43 -0700203 boolean inRecents; // Actually in the recents list?
204 boolean isAvailable; // Is the activity available to be launched?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800205 boolean rootWasReset; // True if the intent at the root of the task had
206 // the FLAG_ACTIVITY_RESET_TASK_IF_NEEDED flag.
Dianne Hackborn13420f22014-07-18 15:43:56 -0700207 boolean autoRemoveRecents; // If true, we should automatically remove the task from
208 // recents when activity finishes
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700209 boolean askedCompatMode;// Have asked the user about compat mode for this task.
Dianne Hackbornd38aed82014-06-10 21:36:35 -0700210 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 -0800211
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700212 String stringName; // caching of toString() result.
Dianne Hackborn9da2d402012-03-15 13:43:08 -0700213 int userId; // user for which this task was created
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800214 boolean mUserSetupComplete; // The user set-up is complete as of the last time the task activity
215 // was changed.
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800216
217 int numFullscreen; // Number of fullscreen activities.
218
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800219 int mResizeMode; // The resize mode of this task and its activities.
220 // Based on the {@link ActivityInfo#resizeMode} of the root activity.
Wale Ogunwale069bbd32017-02-03 07:58:14 -0800221 private boolean mSupportsPictureInPicture; // Whether or not this task and its activities
222 // support PiP. Based on the {@link ActivityInfo#FLAG_SUPPORTS_PICTURE_IN_PICTURE} flag
223 // of the root activity.
Jorim Jaggi8202b2a2016-02-03 19:24:31 -0800224 boolean mTemporarilyUnresizable; // Separate flag from mResizeMode used to suppress resize
225 // changes on a temporary basis.
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700226 private int mLockTaskMode; // Which tasklock mode to launch this task in. One of
227 // ActivityManager.LOCK_TASK_LAUNCH_MODE_*
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700228 private boolean mPrivileged; // The root activity application of this task holds
229 // privileged permissions.
230
Craig Mautner15df08a2015-04-01 12:17:18 -0700231 /** Can't be put in lockTask mode. */
232 final static int LOCK_TASK_AUTH_DONT_LOCK = 0;
Benjamin Franz469dd582015-06-09 14:24:36 +0100233 /** Can enter app pinning with user approval. Can never start over existing lockTask task. */
Craig Mautner15df08a2015-04-01 12:17:18 -0700234 final static int LOCK_TASK_AUTH_PINNABLE = 1;
235 /** Starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing lockTask task. */
236 final static int LOCK_TASK_AUTH_LAUNCHABLE = 2;
Benjamin Franz469dd582015-06-09 14:24:36 +0100237 /** Can enter lockTask without user approval. Can start over existing lockTask task. */
Craig Mautner15df08a2015-04-01 12:17:18 -0700238 final static int LOCK_TASK_AUTH_WHITELISTED = 3;
Benjamin Franz469dd582015-06-09 14:24:36 +0100239 /** Priv-app that starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing
240 * lockTask task. */
241 final static int LOCK_TASK_AUTH_LAUNCHABLE_PRIV = 4;
Craig Mautner15df08a2015-04-01 12:17:18 -0700242 int mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE;
243
244 int mLockTaskUid = -1; // The uid of the application that called startLockTask().
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800245
Winson Chung03a9bae2014-05-02 09:56:12 -0700246 // This represents the last resolved activity values for this task
247 // NOTE: This value needs to be persisted with each task
Craig Mautner648f69b2014-09-18 14:16:26 -0700248 TaskDescription lastTaskDescription = new TaskDescription();
Winson Chung03a9bae2014-05-02 09:56:12 -0700249
Craig Mautnerd2328952013-03-05 12:46:26 -0800250 /** List of all activities in the task arranged in history order */
Craig Mautner21d24a22014-04-23 11:45:37 -0700251 final ArrayList<ActivityRecord> mActivities;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800252
Andrii Kulian02b7a832016-10-06 23:11:56 -0700253 /** Current stack. Setter must always be used to update the value. */
254 private ActivityStack mStack;
Craig Mautnerd2328952013-03-05 12:46:26 -0800255
Craig Mautner21d24a22014-04-23 11:45:37 -0700256 /** Takes on same value as first root activity */
257 boolean isPersistable = false;
Craig Mautnerffcfcaa2014-06-05 09:54:38 -0700258 int maxRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700259
260 /** Only used for persistable tasks, otherwise 0. The last time this task was moved. Used for
261 * determining the order when restoring. Sign indicates whether last task movement was to front
262 * (positive) or back (negative). Absolute value indicates time. */
263 long mLastTimeMoved = System.currentTimeMillis();
264
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700265 /** Indication of what to run next when task exits. */
266 // TODO: Shouldn't be needed if we have things in visual order. I.e. we stop using stacks or
267 // have a stack per standard application type...
Wale Ogunwaleeea34ee92017-08-31 20:07:45 -0700268 /*@WindowConfiguration.ActivityType*/
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700269 private int mTaskToReturnTo = ACTIVITY_TYPE_STANDARD;
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700270
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700271 /** If original intent did not allow relinquishing task identity, save that information */
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700272 private boolean mNeverRelinquishIdentity = true;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700273
Craig Mautner362449a2014-06-20 14:04:39 -0700274 // Used in the unique case where we are clearing the task in order to reuse it. In that case we
275 // do not want to delete the stack when the task goes empty.
Filip Gruszczynskibe9dabd2016-01-19 12:23:10 -0800276 private boolean mReuseTask = false;
Craig Mautner362449a2014-06-20 14:04:39 -0700277
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700278 private final String mFilename;
279 CharSequence lastDescription; // Last description captured for this item.
280
Craig Mautnera228ae92014-07-09 05:44:55 -0700281 int mAffiliatedTaskId; // taskId of parent affiliation or self if no parent.
Winson Chungec396d62014-08-06 17:08:00 -0700282 int mAffiliatedTaskColor; // color of the parent task affiliation.
Craig Mautnera228ae92014-07-09 05:44:55 -0700283 TaskRecord mPrevAffiliate; // previous task in affiliated chain.
Wale Ogunwale18795a22014-12-03 11:38:33 -0800284 int mPrevAffiliateTaskId = INVALID_TASK_ID; // previous id for persistence.
Craig Mautnera228ae92014-07-09 05:44:55 -0700285 TaskRecord mNextAffiliate; // next task in affiliated chain.
Wale Ogunwale18795a22014-12-03 11:38:33 -0800286 int mNextAffiliateTaskId = INVALID_TASK_ID; // next id for persistence.
Craig Mautnera228ae92014-07-09 05:44:55 -0700287
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700288 // For relaunching the task from recents as though it was launched by the original launcher.
289 int mCallingUid;
290 String mCallingPackage;
291
Craig Mautner21d24a22014-04-23 11:45:37 -0700292 final ActivityManagerService mService;
293
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700294 // Whether or not this task covers the entire screen; by default tasks are fullscreen.
295 boolean mFullscreen = true;
296
297 // Bounds of the Task. null for fullscreen tasks.
298 Rect mBounds = null;
Jorim Jaggi82c9dc92016-02-05 15:10:33 -0800299 private final Rect mTmpStableBounds = new Rect();
300 private final Rect mTmpNonDecorBounds = new Rect();
Wale Ogunwale9a08f822016-02-17 19:03:58 -0800301 private final Rect mTmpRect = new Rect();
Jorim Jaggi0a932142016-02-01 17:42:25 -0800302
Wale Ogunwale706ed792015-08-02 10:29:44 -0700303 // Last non-fullscreen bounds the task was launched in or resized to.
304 // The information is persisted and used to determine the appropriate stack to launch the
305 // task into on restore.
306 Rect mLastNonFullscreenBounds = null;
Andrii Kulian2e751b82016-03-16 16:59:32 -0700307 // Minimal width and height of this task when it's resizeable. -1 means it should use the
308 // default minimal width/height.
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700309 int mMinWidth;
310 int mMinHeight;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700311
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700312 // Ranking (from top) of this task among all visible tasks. (-1 means it's not visible)
313 // This number will be assigned when we evaluate OOM scores for all visible tasks.
314 int mLayerRank = -1;
315
Andrii Kulian1779e612016-10-12 21:58:25 -0700316 /** Helper object used for updating override configuration. */
317 private Configuration mTmpConfig = new Configuration();
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700318
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800319 private TaskWindowContainerController mWindowContainerController;
320
Craig Mautner21d24a22014-04-23 11:45:37 -0700321 TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700322 IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700323 mService = service;
Craig Mautnera228ae92014-07-09 05:44:55 -0700324 mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
325 TaskPersister.IMAGE_EXTENSION;
Suprabh Shukla23593142015-11-03 17:31:15 -0800326 userId = UserHandle.getUserId(info.applicationInfo.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800327 taskId = _taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700328 mAffiliatedTaskId = _taskId;
Dianne Hackborn91097de2014-04-04 18:02:06 -0700329 voiceSession = _voiceSession;
330 voiceInteractor = _voiceInteractor;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700331 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800332 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700333 mCallingUid = info.applicationInfo.uid;
334 mCallingPackage = info.packageName;
Martijn Coenend4a69702014-06-30 11:12:17 -0700335 setIntent(_intent, info);
Andrii Kulian2e751b82016-03-16 16:59:32 -0700336 setMinDimensions(info);
Winson730bf062016-03-31 18:04:56 -0700337 touchActiveTime();
Yorke Leebd54c2a2016-10-25 13:49:23 -0700338 mService.mTaskChangeNotificationController.notifyTaskCreated(_taskId, realActivity);
Craig Mautner21d24a22014-04-23 11:45:37 -0700339 }
340
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700341 TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200342 TaskDescription _taskDescription) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700343 mService = service;
344 mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
345 TaskPersister.IMAGE_EXTENSION;
Suprabh Shukla23593142015-11-03 17:31:15 -0800346 userId = UserHandle.getUserId(info.applicationInfo.uid);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700347 taskId = _taskId;
348 mAffiliatedTaskId = _taskId;
349 voiceSession = null;
350 voiceInteractor = null;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700351 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800352 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700353 mCallingUid = info.applicationInfo.uid;
354 mCallingPackage = info.packageName;
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700355 setIntent(_intent, info);
Andrii Kulian2e751b82016-03-16 16:59:32 -0700356 setMinDimensions(info);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700357
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700358 isPersistable = true;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700359 // Clamp to [1, max].
360 maxRecents = Math.min(Math.max(info.maxRecents, 1),
361 ActivityManager.getMaxAppRecentsLimitStatic());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700362
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700363 mTaskToReturnTo = ACTIVITY_TYPE_HOME;
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700364 lastTaskDescription = _taskDescription;
Winson730bf062016-03-31 18:04:56 -0700365 touchActiveTime();
Yorke Leebd54c2a2016-10-25 13:49:23 -0700366 mService.mTaskChangeNotificationController.notifyTaskCreated(_taskId, realActivity);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700367 }
368
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800369 private TaskRecord(ActivityManagerService service, int _taskId, Intent _intent,
370 Intent _affinityIntent, String _affinity, String _rootAffinity,
371 ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700372 boolean _autoRemoveRecents, boolean _askedCompatMode, int _userId,
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800373 int _effectiveUid, String _lastDescription, ArrayList<ActivityRecord> activities,
374 long _firstActiveTime, long _lastActiveTime, long lastTimeMoved,
375 boolean neverRelinquishIdentity, TaskDescription _lastTaskDescription,
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200376 int taskAffiliation, int prevTaskId, int nextTaskId, int taskAffiliationColor,
377 int callingUid, String callingPackage, int resizeMode, boolean supportsPictureInPicture,
378 boolean privileged, boolean _realActivitySuspended, boolean userSetupComplete,
379 int minWidth, int minHeight) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700380 mService = service;
Craig Mautnera228ae92014-07-09 05:44:55 -0700381 mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
382 TaskPersister.IMAGE_EXTENSION;
Craig Mautner21d24a22014-04-23 11:45:37 -0700383 taskId = _taskId;
384 intent = _intent;
385 affinityIntent = _affinityIntent;
386 affinity = _affinity;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800387 rootAffinity = _rootAffinity;
Craig Mautner21d24a22014-04-23 11:45:37 -0700388 voiceSession = null;
389 voiceInteractor = null;
390 realActivity = _realActivity;
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800391 realActivitySuspended = _realActivitySuspended;
Craig Mautner21d24a22014-04-23 11:45:37 -0700392 origActivity = _origActivity;
393 rootWasReset = _rootWasReset;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700394 isAvailable = true;
Dianne Hackborn13420f22014-07-18 15:43:56 -0700395 autoRemoveRecents = _autoRemoveRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700396 askedCompatMode = _askedCompatMode;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700397 mTaskToReturnTo = ACTIVITY_TYPE_HOME;
Craig Mautner21d24a22014-04-23 11:45:37 -0700398 userId = _userId;
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800399 mUserSetupComplete = userSetupComplete;
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700400 effectiveUid = _effectiveUid;
Winson Chungffa2ec62014-07-03 15:54:42 -0700401 firstActiveTime = _firstActiveTime;
Winson Chungf1fbd772014-06-24 18:06:58 -0700402 lastActiveTime = _lastActiveTime;
Craig Mautner21d24a22014-04-23 11:45:37 -0700403 lastDescription = _lastDescription;
404 mActivities = activities;
405 mLastTimeMoved = lastTimeMoved;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700406 mNeverRelinquishIdentity = neverRelinquishIdentity;
Winson Chung2cb86c72014-06-25 12:03:30 -0700407 lastTaskDescription = _lastTaskDescription;
Craig Mautnera228ae92014-07-09 05:44:55 -0700408 mAffiliatedTaskId = taskAffiliation;
Winson Chungec396d62014-08-06 17:08:00 -0700409 mAffiliatedTaskColor = taskAffiliationColor;
Craig Mautnera228ae92014-07-09 05:44:55 -0700410 mPrevAffiliateTaskId = prevTaskId;
411 mNextAffiliateTaskId = nextTaskId;
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700412 mCallingUid = callingUid;
413 mCallingPackage = callingPackage;
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800414 mResizeMode = resizeMode;
Winson Chungd3395382016-12-13 11:49:09 -0800415 mSupportsPictureInPicture = supportsPictureInPicture;
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700416 mPrivileged = privileged;
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700417 mMinWidth = minWidth;
418 mMinHeight = minHeight;
Yorke Leebd54c2a2016-10-25 13:49:23 -0700419 mService.mTaskChangeNotificationController.notifyTaskCreated(_taskId, realActivity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800420 }
421
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800422 TaskWindowContainerController getWindowContainerController() {
423 return mWindowContainerController;
424 }
425
426 void createWindowContainer(boolean onTop, boolean showForAllUsers) {
427 if (mWindowContainerController != null) {
428 throw new IllegalArgumentException("Window container=" + mWindowContainerController
429 + " already created for task=" + this);
430 }
431
432 final Rect bounds = updateOverrideConfigurationFromLaunchBounds();
433 final Configuration overrideConfig = getOverrideConfiguration();
Bryce Lee04ab3462017-04-10 15:06:33 -0700434 setWindowContainerController(new TaskWindowContainerController(taskId, this,
Wale Ogunwale1666e312016-12-16 11:27:18 -0800435 getStack().getWindowContainerController(), userId, bounds, overrideConfig,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700436 mResizeMode, mSupportsPictureInPicture, onTop,
437 showForAllUsers, lastTaskDescription));
Bryce Lee04ab3462017-04-10 15:06:33 -0700438 }
439
440 /**
441 * Should only be invoked from {@link #createWindowContainer(boolean, boolean)}.
442 */
443 @VisibleForTesting
444 protected void setWindowContainerController(TaskWindowContainerController controller) {
445 if (mWindowContainerController != null) {
446 throw new IllegalArgumentException("Window container=" + mWindowContainerController
447 + " already created for task=" + this);
448 }
449
450 mWindowContainerController = controller;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800451 }
452
453 void removeWindowContainer() {
Benjamin Franza83859f2017-07-03 16:34:14 +0100454 mService.mLockTaskController.removeLockedTask(this);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800455 mWindowContainerController.removeContainer();
Wale Ogunwale3382ab12017-07-27 08:55:03 -0700456 if (!getWindowConfiguration().persistTaskBounds()) {
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800457 // Reset current bounds for task whose bounds shouldn't be persisted so it uses
458 // default configuration the next time it launches.
459 updateOverrideConfiguration(null);
460 }
461 mService.mTaskChangeNotificationController.notifyTaskRemoved(taskId);
462 mWindowContainerController = null;
463 }
464
Jorim Jaggifb9d78a2017-01-05 18:57:12 +0100465 @Override
466 public void onSnapshotChanged(TaskSnapshot snapshot) {
467 mService.mTaskChangeNotificationController.notifyTaskSnapshotChanged(taskId, snapshot);
468 }
469
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800470 void setResizeMode(int resizeMode) {
471 if (mResizeMode == resizeMode) {
472 return;
473 }
474 mResizeMode = resizeMode;
475 mWindowContainerController.setResizeable(resizeMode);
476 mService.mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
477 mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
478 }
479
480 void setTaskDockedResizing(boolean resizing) {
481 mWindowContainerController.setTaskDockedResizing(resizing);
482 }
483
Wale Ogunwale1666e312016-12-16 11:27:18 -0800484 // TODO: Consolidate this with the resize() method below.
485 @Override
486 public void requestResize(Rect bounds, int resizeMode) {
487 mService.resizeTask(taskId, bounds, resizeMode);
488 }
489
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800490 boolean resize(Rect bounds, int resizeMode, boolean preserveWindow, boolean deferResume) {
491 if (!isResizeable()) {
492 Slog.w(TAG, "resizeTask: task " + this + " not resizeable.");
493 return true;
494 }
495
496 // If this is a forced resize, let it go through even if the bounds is not changing,
497 // as we might need a relayout due to surface size change (to/from fullscreen).
498 final boolean forced = (resizeMode & RESIZE_MODE_FORCED) != 0;
499 if (Objects.equals(mBounds, bounds) && !forced) {
500 // Nothing to do here...
501 return true;
502 }
503 bounds = validateBounds(bounds);
504
505 if (mWindowContainerController == null) {
506 // Task doesn't exist in window manager yet (e.g. was restored from recents).
507 // All we can do for now is update the bounds so it can be used when the task is
508 // added to window manager.
509 updateOverrideConfiguration(bounds);
510 if (getStackId() != FREEFORM_WORKSPACE_STACK_ID) {
511 // re-restore the task so it can have the proper stack association.
512 mService.mStackSupervisor.restoreRecentTaskLocked(this,
513 FREEFORM_WORKSPACE_STACK_ID);
514 }
515 return true;
516 }
517
518 if (!canResizeToBounds(bounds)) {
519 throw new IllegalArgumentException("resizeTask: Can not resize task=" + this
520 + " to bounds=" + bounds + " resizeMode=" + mResizeMode);
521 }
522
523 // Do not move the task to another stack here.
524 // This method assumes that the task is already placed in the right stack.
525 // we do not mess with that decision and we only do the resize!
526
527 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeTask_" + taskId);
528
529 final boolean updatedConfig = updateOverrideConfiguration(bounds);
530 // This variable holds information whether the configuration didn't change in a significant
531 // way and the activity was kept the way it was. If it's false, it means the activity had
532 // to be relaunched due to configuration change.
533 boolean kept = true;
534 if (updatedConfig) {
535 final ActivityRecord r = topRunningActivityLocked();
Wale Ogunwaleea3d3fd2017-05-01 07:41:08 -0700536 if (r != null && !deferResume) {
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800537 kept = r.ensureActivityConfigurationLocked(0 /* globalChanges */, preserveWindow);
Wale Ogunwaleea3d3fd2017-05-01 07:41:08 -0700538 mService.mStackSupervisor.ensureActivitiesVisibleLocked(r, 0, !PRESERVE_WINDOWS);
539 if (!kept) {
540 mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800541 }
542 }
543 }
544 mWindowContainerController.resize(mBounds, getOverrideConfiguration(), kept, forced);
545
546 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
547 return kept;
548 }
549
550 // TODO: Investigate combining with the resize() method above.
551 void resizeWindowContainer() {
552 mWindowContainerController.resize(mBounds, getOverrideConfiguration(), false /* relayout */,
553 false /* forced */);
554 }
555
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800556 void getWindowContainerBounds(Rect bounds) {
557 mWindowContainerController.getBounds(bounds);
558 }
559
Winson Chung74666102017-02-22 17:49:24 -0800560 /**
561 * Convenience method to reparent a task to the top or bottom position of the stack.
562 */
563 boolean reparent(int preferredStackId, boolean toTop, @ReparentMoveStackMode int moveStackMode,
564 boolean animate, boolean deferResume, String reason) {
565 return reparent(preferredStackId, toTop ? MAX_VALUE : 0, moveStackMode, animate,
Winson Chung5af42fc2017-03-24 17:11:33 -0700566 deferResume, true /* schedulePictureInPictureModeChange */, reason);
567 }
568
569 /**
570 * Convenience method to reparent a task to the top or bottom position of the stack, with
571 * an option to skip scheduling the picture-in-picture mode change.
572 */
573 boolean reparent(int preferredStackId, boolean toTop, @ReparentMoveStackMode int moveStackMode,
574 boolean animate, boolean deferResume, boolean schedulePictureInPictureModeChange,
575 String reason) {
576 return reparent(preferredStackId, toTop ? MAX_VALUE : 0, moveStackMode, animate,
577 deferResume, schedulePictureInPictureModeChange, reason);
578 }
579
580 /**
581 * Convenience method to reparent a task to a specific position of the stack.
582 */
583 boolean reparent(int preferredStackId, int position, @ReparentMoveStackMode int moveStackMode,
584 boolean animate, boolean deferResume, String reason) {
585 return reparent(preferredStackId, position, moveStackMode, animate, deferResume,
586 true /* schedulePictureInPictureModeChange */, reason);
Winson Chung74666102017-02-22 17:49:24 -0800587 }
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800588
Winson Chung74666102017-02-22 17:49:24 -0800589 /**
590 * Reparents the task into a preferred stack, creating it if necessary.
591 *
592 * @param preferredStackId the stack id of the target stack to move this task
593 * @param position the position to place this task in the new stack
594 * @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 -0700595 * reparenting to be drawn and animated in
Winson Chung74666102017-02-22 17:49:24 -0800596 * @param moveStackMode whether or not to move the stack to the front always, only if it was
Winson Chung5af42fc2017-03-24 17:11:33 -0700597 * previously focused & in front, or never
Winson Chung74666102017-02-22 17:49:24 -0800598 * @param deferResume whether or not to update the visibility of other tasks and stacks that may
Winson Chung5af42fc2017-03-24 17:11:33 -0700599 * have changed as a result of this reparenting
600 * @param schedulePictureInPictureModeChange specifies whether or not to schedule the PiP mode
601 * change. Callers may set this to false if they are explicitly scheduling PiP mode
602 * changes themselves, like during the PiP animation
Winson Chung74666102017-02-22 17:49:24 -0800603 * @param reason the caller of this reparenting
Winson Chung5af42fc2017-03-24 17:11:33 -0700604 * @return whether the task was reparented
Winson Chung74666102017-02-22 17:49:24 -0800605 */
606 boolean reparent(int preferredStackId, int position, @ReparentMoveStackMode int moveStackMode,
Winson Chung5af42fc2017-03-24 17:11:33 -0700607 boolean animate, boolean deferResume, boolean schedulePictureInPictureModeChange,
608 String reason) {
Winson Chung74666102017-02-22 17:49:24 -0800609 final ActivityStackSupervisor supervisor = mService.mStackSupervisor;
610 final WindowManagerService windowManager = mService.mWindowManager;
611 final ActivityStack sourceStack = getStack();
612 final ActivityStack toStack = supervisor.getReparentTargetStack(this, preferredStackId,
613 position == MAX_VALUE);
614 if (toStack == sourceStack) {
615 return false;
616 }
617
618 final int sourceStackId = getStackId();
619 final int stackId = toStack.getStackId();
620 final ActivityRecord topActivity = getTopActivity();
621
622 final boolean mightReplaceWindow = StackId.replaceWindowsOnTaskMove(sourceStackId, stackId)
623 && topActivity != null;
624 if (mightReplaceWindow) {
625 // We are about to relaunch the activity because its configuration changed due to
626 // being maximized, i.e. size change. The activity will first remove the old window
627 // and then add a new one. This call will tell window manager about this, so it can
628 // preserve the old window until the new one is drawn. This prevents having a gap
629 // between the removal and addition, in which no window is visible. We also want the
630 // entrance of the new window to be properly animated.
631 // Note here we always set the replacing window first, as the flags might be needed
632 // during the relaunch. If we end up not doing any relaunch, we clear the flags later.
633 windowManager.setWillReplaceWindow(topActivity.appToken, animate);
634 }
635
636 windowManager.deferSurfaceLayout();
637 boolean kept = true;
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800638 try {
Winson Chung74666102017-02-22 17:49:24 -0800639 final ActivityRecord r = topRunningActivityLocked();
Winson Chung95f8f0e2017-03-24 09:20:17 -0700640 final boolean wasFocused = r != null && supervisor.isFocusedStack(sourceStack)
Winson Chung74666102017-02-22 17:49:24 -0800641 && (topRunningActivityLocked() == r);
Winson Chung95f8f0e2017-03-24 09:20:17 -0700642 final boolean wasResumed = r != null && sourceStack.mResumedActivity == r;
643 final boolean wasPaused = r != null && sourceStack.mPausingActivity == r;
Winson Chung74666102017-02-22 17:49:24 -0800644
645 // In some cases the focused stack isn't the front stack. E.g. pinned stack.
646 // Whenever we are moving the top activity from the front stack we want to make sure to
647 // move the stack to the front.
Winson Chung95f8f0e2017-03-24 09:20:17 -0700648 final boolean wasFront = r != null && supervisor.isFrontStackOnDisplay(sourceStack)
Winson Chung74666102017-02-22 17:49:24 -0800649 && (sourceStack.topRunningActivityLocked() == r);
650
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800651 // Adjust the position for the new parent stack as needed.
Winson Chung74666102017-02-22 17:49:24 -0800652 position = toStack.getAdjustedPositionForTask(this, position, null /* starting */);
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800653
654 // Must reparent first in window manager to avoid a situation where AM can delete the
655 // we are coming from in WM before we reparent because it became empty.
Wale Ogunwale2719cc12017-04-14 09:45:27 -0700656 mWindowContainerController.reparent(toStack.getWindowContainerController(), position,
657 moveStackMode == REPARENT_MOVE_STACK_TO_FRONT);
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800658
Wale Ogunwale56d8d162017-05-30 11:12:20 -0700659 final boolean moveStackToFront = moveStackMode == REPARENT_MOVE_STACK_TO_FRONT
660 || (moveStackMode == REPARENT_KEEP_STACK_AT_FRONT && (wasFocused || wasFront));
Winson Chung74666102017-02-22 17:49:24 -0800661 // Move the task
Wale Ogunwale56d8d162017-05-30 11:12:20 -0700662 sourceStack.removeTask(this, reason, moveStackToFront
663 ? REMOVE_TASK_MODE_MOVING_TO_TOP : REMOVE_TASK_MODE_MOVING);
Winson Chung5af42fc2017-03-24 17:11:33 -0700664 toStack.addTask(this, position, false /* schedulePictureInPictureModeChange */, reason);
Winson Chung74666102017-02-22 17:49:24 -0800665
Winson Chung5af42fc2017-03-24 17:11:33 -0700666 if (schedulePictureInPictureModeChange) {
667 // Notify of picture-in-picture mode changes
668 supervisor.scheduleUpdatePictureInPictureModeIfNeeded(this, sourceStack);
669 }
Winson Chung74666102017-02-22 17:49:24 -0800670
671 // TODO: Ensure that this is actually necessary here
672 // Notify the voice session if required
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800673 if (voiceSession != null) {
674 try {
675 voiceSession.taskStarted(intent, taskId);
676 } catch (RemoteException e) {
677 }
678 }
Winson Chung74666102017-02-22 17:49:24 -0800679
680 // If the task had focus before (or we're requested to move focus), move focus to the
681 // new stack by moving the stack to the front.
Winson Chung95f8f0e2017-03-24 09:20:17 -0700682 if (r != null) {
683 toStack.moveToFrontAndResumeStateIfNeeded(r, moveStackToFront, wasResumed,
684 wasPaused, reason);
685 }
Winson Chung74666102017-02-22 17:49:24 -0800686 if (!animate) {
687 toStack.mNoAnimActivities.add(topActivity);
688 }
689
690 // We might trigger a configuration change. Save the current task bounds for freezing.
691 // TODO: Should this call be moved inside the resize method in WM?
692 toStack.prepareFreezingTaskBounds();
693
694 // Make sure the task has the appropriate bounds/size for the stack it is in.
695 if (stackId == FULLSCREEN_WORKSPACE_STACK_ID
696 && !Objects.equals(mBounds, toStack.mBounds)) {
697 kept = resize(toStack.mBounds, RESIZE_MODE_SYSTEM, !mightReplaceWindow,
698 deferResume);
699 } else if (stackId == FREEFORM_WORKSPACE_STACK_ID) {
700 Rect bounds = getLaunchBounds();
701 if (bounds == null) {
702 toStack.layoutTaskInStack(this, null);
703 bounds = mBounds;
704 }
705 kept = resize(bounds, RESIZE_MODE_FORCED, !mightReplaceWindow, deferResume);
706 } else if (stackId == DOCKED_STACK_ID || stackId == PINNED_STACK_ID) {
Matthew Ng330757d2017-02-28 14:19:17 -0800707 if (stackId == DOCKED_STACK_ID && moveStackMode == REPARENT_KEEP_STACK_AT_FRONT) {
708 // Move recents to front so it is not behind home stack when going into docked
709 // mode
710 mService.mStackSupervisor.moveRecentsStackToFront(reason);
711 }
Winson Chung74666102017-02-22 17:49:24 -0800712 kept = resize(toStack.mBounds, RESIZE_MODE_SYSTEM, !mightReplaceWindow,
713 deferResume);
714 }
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800715 } finally {
Winson Chung74666102017-02-22 17:49:24 -0800716 windowManager.continueSurfaceLayout();
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800717 }
Winson Chung74666102017-02-22 17:49:24 -0800718
719 if (mightReplaceWindow) {
720 // If we didn't actual do a relaunch (indicated by kept==true meaning we kept the old
721 // window), we need to clear the replace window settings. Otherwise, we schedule a
722 // timeout to remove the old window if the replacing window is not coming in time.
723 windowManager.scheduleClearWillReplaceWindows(topActivity.appToken, !kept);
724 }
725
726 if (!deferResume) {
727 // The task might have already been running and its visibility needs to be synchronized
728 // with the visibility of the stack / windows.
729 supervisor.ensureActivitiesVisibleLocked(null, 0, !mightReplaceWindow);
730 supervisor.resumeFocusedStackTopActivityLocked();
731 }
732
Andrii Kulian036e3ad2017-04-19 10:55:10 -0700733 // TODO: Handle incorrect request to move before the actual move, not after.
734 supervisor.handleNonResizableTaskIfNeeded(this, preferredStackId, DEFAULT_DISPLAY, stackId);
Winson Chung74666102017-02-22 17:49:24 -0800735
Matthew Ng330757d2017-02-28 14:19:17 -0800736 boolean successful = (preferredStackId == stackId);
737 if (successful && stackId == DOCKED_STACK_ID) {
738 // If task moved to docked stack - show recents if needed.
739 mService.mWindowManager.showRecentApps(false /* fromHome */);
740 }
741 return successful;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800742 }
743
744 void cancelWindowTransition() {
745 mWindowContainerController.cancelWindowTransition();
746 }
747
748 void cancelThumbnailTransition() {
749 mWindowContainerController.cancelThumbnailTransition();
750 }
751
Jorim Jaggi7361bab2017-01-16 17:17:58 +0100752 /**
753 * DO NOT HOLD THE ACTIVITY MANAGER LOCK WHEN CALLING THIS METHOD!
754 */
Jorim Jaggi35e3f532017-03-17 17:06:50 +0100755 TaskSnapshot getSnapshot(boolean reducedResolution) {
Jorim Jaggi7361bab2017-01-16 17:17:58 +0100756
757 // TODO: Move this to {@link TaskWindowContainerController} once recent tasks are more
758 // synchronized between AM and WM.
Jorim Jaggi35e3f532017-03-17 17:06:50 +0100759 return mService.mWindowManager.getTaskSnapshot(taskId, userId, reducedResolution);
Jorim Jaggi02886a82016-12-06 09:10:06 -0800760 }
761
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800762 void touchActiveTime() {
Winson Chung36f3f032016-09-08 23:29:43 +0000763 lastActiveTime = System.currentTimeMillis();
Winson Chungffa2ec62014-07-03 15:54:42 -0700764 if (firstActiveTime == 0) {
765 firstActiveTime = lastActiveTime;
766 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800767 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700768
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800769 long getInactiveDuration() {
Winson Chung36f3f032016-09-08 23:29:43 +0000770 return System.currentTimeMillis() - lastActiveTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800771 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700772
Winson Chungfee26772014-08-05 12:21:52 -0700773 /** Sets the original intent, and the calling uid and package. */
774 void setIntent(ActivityRecord r) {
Winson Chungfee26772014-08-05 12:21:52 -0700775 mCallingUid = r.launchedFromUid;
776 mCallingPackage = r.launchedFromPackage;
Craig Mautner15df08a2015-04-01 12:17:18 -0700777 setIntent(r.intent, r.info);
Winson Chungfee26772014-08-05 12:21:52 -0700778 }
779
780 /** Sets the original intent, _without_ updating the calling uid or package. */
781 private void setIntent(Intent _intent, ActivityInfo info) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700782 if (intent == null) {
783 mNeverRelinquishIdentity =
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700784 (info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700785 } else if (mNeverRelinquishIdentity) {
786 return;
787 }
788
789 affinity = info.taskAffinity;
Dianne Hackborn79228822014-09-16 11:11:23 -0700790 if (intent == null) {
791 // If this task already has an intent associated with it, don't set the root
792 // affinity -- we don't want it changing after initially set, but the initially
793 // set value may be null.
794 rootAffinity = affinity;
795 }
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700796 effectiveUid = info.applicationInfo.uid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700797 stringName = null;
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800798
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800799 if (info.targetActivity == null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800800 if (_intent != null) {
801 // If this Intent has a selector, we want to clear it for the
802 // recent task since it is not relevant if the user later wants
803 // to re-launch the app.
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700804 if (_intent.getSelector() != null || _intent.getSourceBounds() != null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800805 _intent = new Intent(_intent);
806 _intent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700807 _intent.setSourceBounds(null);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800808 }
809 }
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700810 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Setting Intent of " + this + " to " + _intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800811 intent = _intent;
812 realActivity = _intent != null ? _intent.getComponent() : null;
813 origActivity = null;
814 } else {
815 ComponentName targetComponent = new ComponentName(
816 info.packageName, info.targetActivity);
817 if (_intent != null) {
818 Intent targetIntent = new Intent(_intent);
819 targetIntent.setComponent(targetComponent);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800820 targetIntent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700821 targetIntent.setSourceBounds(null);
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700822 if (DEBUG_TASKS) Slog.v(TAG_TASKS,
Dianne Hackborn7f96b792012-05-29 18:46:45 -0700823 "Setting Intent of " + this + " to target " + targetIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800824 intent = targetIntent;
825 realActivity = targetComponent;
826 origActivity = _intent.getComponent();
827 } else {
828 intent = null;
829 realActivity = targetComponent;
830 origActivity = new ComponentName(info.packageName, info.name);
831 }
832 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700833
Craig Mautner47b20ba2014-09-17 17:23:44 -0700834 final int intentFlags = intent == null ? 0 : intent.getFlags();
835 if ((intentFlags & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800836 // Once we are set to an Intent with this flag, we count this
837 // task as having a true root activity.
838 rootWasReset = true;
839 }
Dianne Hackborn09233282014-04-30 11:33:59 -0700840 userId = UserHandle.getUserId(info.applicationInfo.uid);
Winson Chung36f3f032016-09-08 23:29:43 +0000841 mUserSetupComplete = Settings.Secure.getIntForUser(mService.mContext.getContentResolver(),
842 USER_SETUP_COMPLETE, 0, userId) != 0;
Craig Mautner41db4a72014-05-07 17:20:56 -0700843 if ((info.flags & ActivityInfo.FLAG_AUTO_REMOVE_FROM_RECENTS) != 0) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700844 // If the activity itself has requested auto-remove, then just always do it.
845 autoRemoveRecents = true;
Wale Ogunwale843bfb92015-03-27 11:06:48 -0700846 } else if ((intentFlags & (FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS))
847 == FLAG_ACTIVITY_NEW_DOCUMENT) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700848 // If the caller has not asked for the document to be retained, then we may
849 // want to turn on auto-remove, depending on whether the target has set its
850 // own document launch mode.
851 if (info.documentLaunchMode != ActivityInfo.DOCUMENT_LAUNCH_NONE) {
852 autoRemoveRecents = false;
853 } else {
854 autoRemoveRecents = true;
855 }
856 } else {
857 autoRemoveRecents = false;
Craig Mautner41db4a72014-05-07 17:20:56 -0700858 }
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800859 mResizeMode = info.resizeMode;
Winson Chungd3395382016-12-13 11:49:09 -0800860 mSupportsPictureInPicture = info.supportsPictureInPicture();
Craig Mautner15df08a2015-04-01 12:17:18 -0700861 mLockTaskMode = info.lockTaskLaunchMode;
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700862 mPrivileged = (info.applicationInfo.privateFlags & PRIVATE_FLAG_PRIVILEGED) != 0;
Craig Mautner15df08a2015-04-01 12:17:18 -0700863 setLockTaskAuth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800864 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800865
Andrii Kulian2e751b82016-03-16 16:59:32 -0700866 /** Sets the original minimal width and height. */
867 private void setMinDimensions(ActivityInfo info) {
868 if (info != null && info.windowLayout != null) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700869 mMinWidth = info.windowLayout.minWidth;
870 mMinHeight = info.windowLayout.minHeight;
Andrii Kulian2e751b82016-03-16 16:59:32 -0700871 } else {
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700872 mMinWidth = INVALID_MIN_SIZE;
873 mMinHeight = INVALID_MIN_SIZE;
Andrii Kulian2e751b82016-03-16 16:59:32 -0700874 }
875 }
876
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800877 /**
Andrii Kulian206b9fa2016-06-02 13:18:01 -0700878 * Return true if the input activity has the same intent filter as the intent this task
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800879 * record is based on (normally the root activity intent).
880 */
Andrii Kulian206b9fa2016-06-02 13:18:01 -0700881 boolean isSameIntentFilter(ActivityRecord r) {
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800882 final Intent intent = new Intent(r.intent);
883 // Correct the activity intent for aliasing. The task record intent will always be based on
884 // the real activity that will be launched not the alias, so we need to use an intent with
885 // the component name pointing to the real activity not the alias in the activity record.
886 intent.setComponent(r.realActivity);
887 return this.intent.filterEquals(intent);
888 }
889
Wale Ogunwaleeea34ee92017-08-31 20:07:45 -0700890 void setTaskToReturnTo(/*@WindowConfiguration.ActivityType*/ int taskToReturnTo) {
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700891 mTaskToReturnTo = taskToReturnTo == ACTIVITY_TYPE_RECENTS
892 ? ACTIVITY_TYPE_HOME : taskToReturnTo;
Craig Mautner84984fa2014-06-19 11:19:20 -0700893 }
894
Winson Chung83471632016-12-13 11:02:12 -0800895 void setTaskToReturnTo(ActivityRecord source) {
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700896 if (source.isActivityTypeRecents()) {
897 setTaskToReturnTo(ACTIVITY_TYPE_RECENTS);
898 } else if (source.isActivityTypeAssistant()) {
899 setTaskToReturnTo(ACTIVITY_TYPE_ASSISTANT);
Winson Chung83471632016-12-13 11:02:12 -0800900 }
901 }
902
Craig Mautner84984fa2014-06-19 11:19:20 -0700903 int getTaskToReturnTo() {
904 return mTaskToReturnTo;
905 }
906
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700907 boolean returnsToHomeTask() {
908 return mTaskToReturnTo == ACTIVITY_TYPE_HOME;
909 }
910
911 boolean returnsToStandardTask() {
912 return mTaskToReturnTo == ACTIVITY_TYPE_STANDARD;
913 }
914
Craig Mautnera228ae92014-07-09 05:44:55 -0700915 void setPrevAffiliate(TaskRecord prevAffiliate) {
916 mPrevAffiliate = prevAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800917 mPrevAffiliateTaskId = prevAffiliate == null ? INVALID_TASK_ID : prevAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700918 }
919
920 void setNextAffiliate(TaskRecord nextAffiliate) {
921 mNextAffiliate = nextAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800922 mNextAffiliateTaskId = nextAffiliate == null ? INVALID_TASK_ID : nextAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700923 }
924
Andrii Kulian02b7a832016-10-06 23:11:56 -0700925 ActivityStack getStack() {
926 return mStack;
927 }
928
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800929 /**
930 * Must be used for setting parent stack because it performs configuration updates.
931 * Must be called after adding task as a child to the stack.
932 */
Andrii Kulian02b7a832016-10-06 23:11:56 -0700933 void setStack(ActivityStack stack) {
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800934 if (stack != null && !stack.isInStackLocked(this)) {
935 throw new IllegalStateException("Task must be added as a Stack child first.");
936 }
Andrii Kulian02b7a832016-10-06 23:11:56 -0700937 mStack = stack;
Andrii Kulian1779e612016-10-12 21:58:25 -0700938 onParentChanged();
Andrii Kulian02b7a832016-10-06 23:11:56 -0700939 }
940
941 /**
942 * @return Id of current stack, {@link INVALID_STACK_ID} if no stack is set.
943 */
944 int getStackId() {
945 return mStack != null ? mStack.mStackId : INVALID_STACK_ID;
946 }
947
Andrii Kulian1779e612016-10-12 21:58:25 -0700948 @Override
949 protected int getChildCount() {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700950 return mActivities.size();
Andrii Kulian1779e612016-10-12 21:58:25 -0700951 }
952
953 @Override
954 protected ConfigurationContainer getChildAt(int index) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700955 return mActivities.get(index);
Andrii Kulian1779e612016-10-12 21:58:25 -0700956 }
957
958 @Override
959 protected ConfigurationContainer getParent() {
960 return mStack;
961 }
962
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800963 @Override
Wale Ogunwale98d62312017-07-12 09:24:56 -0700964 protected void onParentChanged() {
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800965 super.onParentChanged();
966 mService.mStackSupervisor.updateUIDsPresentOnDisplay();
967 }
968
Craig Mautnera228ae92014-07-09 05:44:55 -0700969 // Close up recents linked list.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700970 private void closeRecentsChain() {
Craig Mautnera228ae92014-07-09 05:44:55 -0700971 if (mPrevAffiliate != null) {
972 mPrevAffiliate.setNextAffiliate(mNextAffiliate);
973 }
974 if (mNextAffiliate != null) {
975 mNextAffiliate.setPrevAffiliate(mPrevAffiliate);
976 }
977 setPrevAffiliate(null);
978 setNextAffiliate(null);
979 }
980
Winson Chung740c3ac2014-11-12 16:14:38 -0800981 void removedFromRecents() {
Dianne Hackborn852975d2014-08-22 17:42:43 -0700982 closeRecentsChain();
983 if (inRecents) {
984 inRecents = false;
Winson Chung740c3ac2014-11-12 16:14:38 -0800985 mService.notifyTaskPersisterLocked(this, false);
Dianne Hackborn852975d2014-08-22 17:42:43 -0700986 }
Jorim Jaggif9084ec2017-01-16 13:16:59 +0100987
988 // TODO: Use window container controller once tasks are better synced between AM and WM
989 mService.mWindowManager.notifyTaskRemovedFromRecents(taskId, userId);
Dianne Hackborn852975d2014-08-22 17:42:43 -0700990 }
991
Craig Mautnera228ae92014-07-09 05:44:55 -0700992 void setTaskToAffiliateWith(TaskRecord taskToAffiliateWith) {
993 closeRecentsChain();
994 mAffiliatedTaskId = taskToAffiliateWith.mAffiliatedTaskId;
Winson Chungec396d62014-08-06 17:08:00 -0700995 mAffiliatedTaskColor = taskToAffiliateWith.mAffiliatedTaskColor;
Craig Mautnera228ae92014-07-09 05:44:55 -0700996 // Find the end
997 while (taskToAffiliateWith.mNextAffiliate != null) {
998 final TaskRecord nextRecents = taskToAffiliateWith.mNextAffiliate;
999 if (nextRecents.mAffiliatedTaskId != mAffiliatedTaskId) {
1000 Slog.e(TAG, "setTaskToAffiliateWith: nextRecents=" + nextRecents + " affilTaskId="
1001 + nextRecents.mAffiliatedTaskId + " should be " + mAffiliatedTaskId);
1002 if (nextRecents.mPrevAffiliate == taskToAffiliateWith) {
1003 nextRecents.setPrevAffiliate(null);
1004 }
1005 taskToAffiliateWith.setNextAffiliate(null);
1006 break;
1007 }
1008 taskToAffiliateWith = nextRecents;
1009 }
1010 taskToAffiliateWith.setNextAffiliate(this);
1011 setPrevAffiliate(taskToAffiliateWith);
1012 setNextAffiliate(null);
1013 }
1014
Winson Chung1147c402014-05-14 11:05:00 -07001015 /** Returns the intent for the root activity for this task */
1016 Intent getBaseIntent() {
1017 return intent != null ? intent : affinityIntent;
1018 }
1019
Winson Chung942a85c2017-07-11 15:07:45 -07001020 /**
1021 * @return Whether there are only fullscreen activities in this task.
1022 */
1023 boolean containsOnlyFullscreenActivities() {
1024 for (int i = 0; i < mActivities.size(); i++) {
1025 final ActivityRecord r = mActivities.get(i);
1026 if (!r.finishing && !r.fullscreen) {
1027 return false;
1028 }
1029 }
1030 return true;
1031 }
1032
Winson Chung3b3f4642014-04-22 10:08:18 -07001033 /** Returns the first non-finishing activity from the root. */
1034 ActivityRecord getRootActivity() {
1035 for (int i = 0; i < mActivities.size(); i++) {
1036 final ActivityRecord r = mActivities.get(i);
1037 if (r.finishing) {
1038 continue;
1039 }
1040 return r;
1041 }
1042 return null;
1043 }
1044
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001045 ActivityRecord getTopActivity() {
1046 for (int i = mActivities.size() - 1; i >= 0; --i) {
1047 final ActivityRecord r = mActivities.get(i);
1048 if (r.finishing) {
1049 continue;
1050 }
1051 return r;
1052 }
1053 return null;
1054 }
1055
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -07001056 ActivityRecord topRunningActivityLocked() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001057 if (mStack != null) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07001058 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1059 ActivityRecord r = mActivities.get(activityNdx);
Chong Zhang87761972016-08-22 13:53:24 -07001060 if (!r.finishing && r.okToShowLocked()) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07001061 return r;
1062 }
Craig Mautner6b74cb52013-09-27 17:02:21 -07001063 }
1064 }
1065 return null;
1066 }
1067
Jorim Jaggiea039a82017-08-02 14:37:49 +02001068 void getAllRunningVisibleActivitiesLocked(ArrayList<ActivityRecord> outActivities) {
1069 if (mStack != null) {
1070 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1071 ActivityRecord r = mActivities.get(activityNdx);
Jorim Jaggi02f1d2f2017-08-04 14:29:16 +02001072 if (!r.finishing && r.okToShowLocked() && r.visibleIgnoringKeyguard) {
Jorim Jaggiea039a82017-08-02 14:37:49 +02001073 outActivities.add(r);
1074 }
1075 }
1076 }
1077 }
1078
Wale Ogunwale3b232392016-05-13 15:37:13 -07001079 ActivityRecord topRunningActivityWithStartingWindowLocked() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001080 if (mStack != null) {
Wale Ogunwale3b232392016-05-13 15:37:13 -07001081 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1082 ActivityRecord r = mActivities.get(activityNdx);
1083 if (r.mStartingWindowState != STARTING_WINDOW_SHOWN
Chong Zhang87761972016-08-22 13:53:24 -07001084 || r.finishing || !r.okToShowLocked()) {
Wale Ogunwale3b232392016-05-13 15:37:13 -07001085 continue;
1086 }
1087 return r;
1088 }
1089 }
1090 return null;
1091 }
1092
Chong Zhang87761972016-08-22 13:53:24 -07001093 boolean okToShowLocked() {
1094 // NOTE: If {@link TaskRecord#topRunningActivityLocked} return is not null then it is
1095 // okay to show the activity when locked.
1096 return mService.mStackSupervisor.isCurrentProfileLocked(userId)
1097 || topRunningActivityLocked() != null;
1098 }
1099
Craig Mautner3b475fe2013-12-16 15:58:31 -08001100 /** Call after activity movement or finish to make sure that frontOfTask is set correctly */
Bryce Leed71317c2017-02-07 14:27:22 -08001101 final void setFrontOfTask() {
1102 boolean foundFront = false;
Craig Mautner3b475fe2013-12-16 15:58:31 -08001103 final int numActivities = mActivities.size();
Craig Mautner704e40b2013-12-18 16:43:51 -08001104 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
Craig Mautner3b475fe2013-12-16 15:58:31 -08001105 final ActivityRecord r = mActivities.get(activityNdx);
1106 if (foundFront || r.finishing) {
1107 r.frontOfTask = false;
1108 } else {
1109 r.frontOfTask = true;
1110 // Set frontOfTask false for every following activity.
1111 foundFront = true;
1112 }
1113 }
Craig Mautner9587ee02014-06-23 15:00:10 +00001114 if (!foundFront && numActivities > 0) {
1115 // All activities of this task are finishing. As we ought to have a frontOfTask
1116 // activity, make the bottom activity front.
1117 mActivities.get(0).frontOfTask = true;
1118 }
Craig Mautner3b475fe2013-12-16 15:58:31 -08001119 }
1120
Craig Mautnerde4ef022013-04-07 19:01:33 -07001121 /**
Craig Mautner3b475fe2013-12-16 15:58:31 -08001122 * Reorder the history stack so that the passed activity is brought to the front.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001123 */
1124 final void moveActivityToFrontLocked(ActivityRecord newTop) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07001125 if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE,
1126 "Removing and adding activity " + newTop
1127 + " to stack at top callers=" + Debug.getCallers(4));
Craig Mautnerde4ef022013-04-07 19:01:33 -07001128
Craig Mautnerde4ef022013-04-07 19:01:33 -07001129 mActivities.remove(newTop);
1130 mActivities.add(newTop);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001131 updateEffectiveIntent();
Craig Mautner3b475fe2013-12-16 15:58:31 -08001132
Bryce Leed71317c2017-02-07 14:27:22 -08001133 setFrontOfTask();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001134 }
1135
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001136 void addActivityAtBottom(ActivityRecord r) {
Craig Mautner77878772013-03-04 19:46:24 -08001137 addActivityAtIndex(0, r);
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001138 }
1139
1140 void addActivityToTop(ActivityRecord r) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001141 addActivityAtIndex(mActivities.size(), r);
1142 }
1143
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001144 @Override
Wale Ogunwaleeea34ee92017-08-31 20:07:45 -07001145 /*@WindowConfiguration.ActivityType*/
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001146 public int getActivityType() {
1147 final int applicationType = super.getActivityType();
1148 if (applicationType != ACTIVITY_TYPE_UNDEFINED || mActivities.isEmpty()) {
1149 return applicationType;
1150 }
1151 return mActivities.get(0).getActivityType();
1152 }
1153
Winson Chung30480042017-01-26 10:55:34 -08001154 /**
1155 * Adds an activity {@param r} at the given {@param index}. The activity {@param r} must either
1156 * be in the current task or unparented to any task.
1157 */
Craig Mautner1602ec22013-05-12 10:24:27 -07001158 void addActivityAtIndex(int index, ActivityRecord r) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001159 TaskRecord task = r.getTask();
1160 if (task != null && task != this) {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001161 throw new IllegalArgumentException("Can not add r=" + " to task=" + this
Bryce Leeaf691c02017-03-20 14:20:22 -07001162 + " current parent=" + task);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001163 }
Bryce Leeaf691c02017-03-20 14:20:22 -07001164
1165 r.setTask(this);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001166
Craig Mautner6170f732013-04-02 13:05:23 -07001167 // 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 -08001168 if (!mActivities.remove(r) && r.fullscreen) {
1169 // Was not previously in list.
1170 numFullscreen++;
1171 }
Craig Mautner2c1faed2013-07-23 12:56:02 -07001172 // Only set this based on the first activity
1173 if (mActivities.isEmpty()) {
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001174 // TODO: propagating this change to the WM side...Should probably be done by having
1175 // ConfigurationContainer change listener that the WindowContainerController registers
1176 // for.
1177 if (r.getActivityType() == ACTIVITY_TYPE_UNDEFINED) {
1178 // Normally non-standard activity type for the activity record will be set when the
1179 // object is created, however we delay setting the standard application type until
1180 // this point so that the task can set the type for additional activities added in
1181 // the else condition below.
1182 r.setActivityType(ACTIVITY_TYPE_STANDARD);
1183 }
1184 setActivityType(r.getActivityType());
Craig Mautner21d24a22014-04-23 11:45:37 -07001185 isPersistable = r.isPersistable();
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001186 mCallingUid = r.launchedFromUid;
1187 mCallingPackage = r.launchedFromPackage;
Dianne Hackborn852975d2014-08-22 17:42:43 -07001188 // Clamp to [1, max].
1189 maxRecents = Math.min(Math.max(r.info.maxRecents, 1),
1190 ActivityManager.getMaxAppRecentsLimitStatic());
Craig Mautner2c1faed2013-07-23 12:56:02 -07001191 } else {
1192 // Otherwise make all added activities match this one.
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001193 r.setActivityType(getActivityType());
Craig Mautner78733002013-06-10 13:54:49 -07001194 }
Wale Ogunwale3b232392016-05-13 15:37:13 -07001195
1196 final int size = mActivities.size();
1197
1198 if (index == size && size > 0) {
1199 final ActivityRecord top = mActivities.get(size - 1);
1200 if (top.mTaskOverlay) {
1201 // Place below the task overlay activity since the overlay activity should always
1202 // be on top.
1203 index--;
1204 }
1205 }
1206
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001207 index = Math.min(size, index);
Craig Mautner77878772013-03-04 19:46:24 -08001208 mActivities.add(index, r);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001209 updateEffectiveIntent();
Craig Mautner21d24a22014-04-23 11:45:37 -07001210 if (r.isPersistable()) {
1211 mService.notifyTaskPersisterLocked(this, false);
1212 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001213
1214 // Sync. with window manager
1215 updateOverrideConfigurationFromLaunchBounds();
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001216 final AppWindowContainerController appController = r.getWindowContainerController();
1217 if (appController != null) {
1218 // Only attempt to move in WM if the child has a controller. It is possible we haven't
1219 // created controller for the activity we are starting yet.
1220 mWindowContainerController.positionChildAt(appController, index);
1221 }
David Stevens82ea6cb2017-03-03 16:18:50 -08001222
1223 // Make sure the list of display UID whitelists is updated
1224 // now that this record is in a new task.
1225 mService.mStackSupervisor.updateUIDsPresentOnDisplay();
Craig Mautner77878772013-03-04 19:46:24 -08001226 }
1227
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001228 /**
Bryce Leeaf691c02017-03-20 14:20:22 -07001229 * Removes the specified activity from this task.
1230 * @param r The {@link ActivityRecord} to remove.
1231 * @return true if this was the last activity in the task.
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001232 */
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001233 boolean removeActivity(ActivityRecord r) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001234 return removeActivity(r, false /*reparenting*/);
1235 }
1236
1237 boolean removeActivity(ActivityRecord r, boolean reparenting) {
1238 if (r.getTask() != this) {
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001239 throw new IllegalArgumentException(
1240 "Activity=" + r + " does not belong to task=" + this);
1241 }
1242
Bryce Leeaf691c02017-03-20 14:20:22 -07001243 r.setTask(null /*task*/, reparenting);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001244
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001245 if (mActivities.remove(r) && r.fullscreen) {
1246 // Was previously in list.
1247 numFullscreen--;
1248 }
Craig Mautner21d24a22014-04-23 11:45:37 -07001249 if (r.isPersistable()) {
1250 mService.notifyTaskPersisterLocked(this, false);
1251 }
Wale Ogunwale89182d52016-03-11 10:38:36 -08001252
Andrii Kulian02b7a832016-10-06 23:11:56 -07001253 if (getStackId() == PINNED_STACK_ID) {
Wale Ogunwale89182d52016-03-11 10:38:36 -08001254 // We normally notify listeners of task stack changes on pause, however pinned stack
1255 // activities are normally in the paused state so no notification will be sent there
1256 // before the activity is removed. We send it here so instead.
Yorke Leebd54c2a2016-10-25 13:49:23 -07001257 mService.mTaskChangeNotificationController.notifyTaskStackChanged();
Wale Ogunwale89182d52016-03-11 10:38:36 -08001258 }
1259
Craig Mautner41326202014-06-20 14:38:21 -07001260 if (mActivities.isEmpty()) {
Craig Mautner5afcd4d2014-06-21 18:11:33 -07001261 return !mReuseTask;
Craig Mautner41326202014-06-20 14:38:21 -07001262 }
1263 updateEffectiveIntent();
1264 return false;
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001265 }
1266
Winson Chung6954fc92017-03-24 16:22:12 -07001267 /**
1268 * @return whether or not there are ONLY task overlay activities in the stack.
1269 * If {@param excludeFinishing} is set, then ignore finishing activities in the check.
1270 * If there are no task overlay activities, this call returns false.
1271 */
1272 boolean onlyHasTaskOverlayActivities(boolean excludeFinishing) {
1273 int count = 0;
1274 for (int i = mActivities.size() - 1; i >= 0; i--) {
1275 final ActivityRecord r = mActivities.get(i);
1276 if (excludeFinishing && r.finishing) {
1277 continue;
1278 }
1279 if (!r.mTaskOverlay) {
1280 return false;
1281 }
1282 count++;
1283 }
1284 return count > 0;
1285 }
1286
Craig Mautner41db4a72014-05-07 17:20:56 -07001287 boolean autoRemoveFromRecents() {
Dianne Hackbornd38aed82014-06-10 21:36:35 -07001288 // We will automatically remove the task either if it has explicitly asked for
1289 // this, or it is empty and has never contained an activity that got shown to
1290 // the user.
Dianne Hackborn13420f22014-07-18 15:43:56 -07001291 return autoRemoveRecents || (mActivities.isEmpty() && !hasBeenVisible);
Craig Mautner41db4a72014-05-07 17:20:56 -07001292 }
1293
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001294 /**
1295 * Completely remove all activities associated with an existing
1296 * task starting at a specified index.
1297 */
Winson Chung6954fc92017-03-24 16:22:12 -07001298 final void performClearTaskAtIndexLocked(int activityNdx, boolean pauseImmediately) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001299 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001300 for ( ; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001301 final ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001302 if (r.finishing) {
1303 continue;
1304 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07001305 if (mStack == null) {
Craig Mautner21d24a22014-04-23 11:45:37 -07001306 // Task was restored from persistent storage.
1307 r.takeFromHistory();
1308 mActivities.remove(activityNdx);
1309 --activityNdx;
1310 --numActivities;
Winson Chung6954fc92017-03-24 16:22:12 -07001311 } else if (mStack.finishActivityLocked(r, Activity.RESULT_CANCELED, null,
1312 "clear-task-index", false, pauseImmediately)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001313 --activityNdx;
1314 --numActivities;
1315 }
1316 }
1317 }
1318
1319 /**
1320 * Completely remove all activities associated with an existing task.
1321 */
Benjamin Franza83859f2017-07-03 16:34:14 +01001322 void performClearTaskLocked() {
Craig Mautner362449a2014-06-20 14:04:39 -07001323 mReuseTask = true;
Winson Chung6954fc92017-03-24 16:22:12 -07001324 performClearTaskAtIndexLocked(0, !PAUSE_IMMEDIATELY);
Craig Mautner362449a2014-06-20 14:04:39 -07001325 mReuseTask = false;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001326 }
1327
Filip Gruszczynskibe9dabd2016-01-19 12:23:10 -08001328 ActivityRecord performClearTaskForReuseLocked(ActivityRecord newR, int launchFlags) {
1329 mReuseTask = true;
1330 final ActivityRecord result = performClearTaskLocked(newR, launchFlags);
1331 mReuseTask = false;
1332 return result;
1333 }
1334
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001335 /**
1336 * Perform clear operation as requested by
1337 * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the
1338 * stack to the given task, then look for
1339 * an instance of that activity in the stack and, if found, finish all
1340 * activities on top of it and return the instance.
1341 *
1342 * @param newR Description of the new activity being started.
1343 * @return Returns the old activity that should be continued to be used,
1344 * or null if none was found.
1345 */
1346 final ActivityRecord performClearTaskLocked(ActivityRecord newR, int launchFlags) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001347 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001348 for (int activityNdx = numActivities - 1; activityNdx >= 0; --activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001349 ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001350 if (r.finishing) {
1351 continue;
1352 }
1353 if (r.realActivity.equals(newR.realActivity)) {
1354 // Here it is! Now finish everything in front...
Craig Mautner1602ec22013-05-12 10:24:27 -07001355 final ActivityRecord ret = r;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001356
1357 for (++activityNdx; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001358 r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001359 if (r.finishing) {
1360 continue;
1361 }
1362 ActivityOptions opts = r.takeOptionsLocked();
1363 if (opts != null) {
1364 ret.updateOptionsLocked(opts);
1365 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07001366 if (mStack != null && mStack.finishActivityLocked(
Todd Kennedy539db512014-12-15 09:57:55 -08001367 r, Activity.RESULT_CANCELED, null, "clear-task-stack", false)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001368 --activityNdx;
1369 --numActivities;
1370 }
1371 }
1372
1373 // Finally, if this is a normal launch mode (that is, not
1374 // expecting onNewIntent()), then we will finish the current
1375 // instance of the activity so a new fresh one can be started.
1376 if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE
Daichi Hirono15a02992016-04-27 18:47:01 +09001377 && (launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0
1378 && !ActivityStarter.isDocumentLaunchesIntoExisting(launchFlags)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001379 if (!ret.finishing) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001380 if (mStack != null) {
1381 mStack.finishActivityLocked(
Wale Ogunwale7d701172015-03-11 15:36:30 -07001382 ret, Activity.RESULT_CANCELED, null, "clear-task-top", false);
1383 }
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001384 return null;
1385 }
1386 }
1387
1388 return ret;
1389 }
1390 }
1391
1392 return null;
1393 }
1394
Winson Chung6954fc92017-03-24 16:22:12 -07001395 void removeTaskActivitiesLocked(boolean pauseImmediately) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001396 // Just remove the entire task.
Winson Chung6954fc92017-03-24 16:22:12 -07001397 performClearTaskAtIndexLocked(0, pauseImmediately);
Craig Mautner9db9a0b2013-04-29 17:05:56 -07001398 }
1399
Craig Mautner432f64e2015-05-20 14:59:57 -07001400 String lockTaskAuthToString() {
1401 switch (mLockTaskAuth) {
1402 case LOCK_TASK_AUTH_DONT_LOCK: return "LOCK_TASK_AUTH_DONT_LOCK";
1403 case LOCK_TASK_AUTH_PINNABLE: return "LOCK_TASK_AUTH_PINNABLE";
1404 case LOCK_TASK_AUTH_LAUNCHABLE: return "LOCK_TASK_AUTH_LAUNCHABLE";
1405 case LOCK_TASK_AUTH_WHITELISTED: return "LOCK_TASK_AUTH_WHITELISTED";
Benjamin Franz469dd582015-06-09 14:24:36 +01001406 case LOCK_TASK_AUTH_LAUNCHABLE_PRIV: return "LOCK_TASK_AUTH_LAUNCHABLE_PRIV";
Craig Mautner432f64e2015-05-20 14:59:57 -07001407 default: return "unknown=" + mLockTaskAuth;
1408 }
1409 }
1410
Craig Mautner15df08a2015-04-01 12:17:18 -07001411 void setLockTaskAuth() {
Benjamin Franz469dd582015-06-09 14:24:36 +01001412 if (!mPrivileged &&
1413 (mLockTaskMode == LOCK_TASK_LAUNCH_MODE_ALWAYS ||
1414 mLockTaskMode == LOCK_TASK_LAUNCH_MODE_NEVER)) {
1415 // Non-priv apps are not allowed to use always or never, fall back to default
1416 mLockTaskMode = LOCK_TASK_LAUNCH_MODE_DEFAULT;
1417 }
Craig Mautner15df08a2015-04-01 12:17:18 -07001418 switch (mLockTaskMode) {
1419 case LOCK_TASK_LAUNCH_MODE_DEFAULT:
1420 mLockTaskAuth = isLockTaskWhitelistedLocked() ?
1421 LOCK_TASK_AUTH_WHITELISTED : LOCK_TASK_AUTH_PINNABLE;
1422 break;
1423
1424 case LOCK_TASK_LAUNCH_MODE_NEVER:
Benjamin Franz469dd582015-06-09 14:24:36 +01001425 mLockTaskAuth = LOCK_TASK_AUTH_DONT_LOCK;
Craig Mautner15df08a2015-04-01 12:17:18 -07001426 break;
1427
1428 case LOCK_TASK_LAUNCH_MODE_ALWAYS:
Benjamin Franz469dd582015-06-09 14:24:36 +01001429 mLockTaskAuth = LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
Craig Mautner15df08a2015-04-01 12:17:18 -07001430 break;
1431
1432 case LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED:
1433 mLockTaskAuth = isLockTaskWhitelistedLocked() ?
1434 LOCK_TASK_AUTH_LAUNCHABLE : LOCK_TASK_AUTH_PINNABLE;
1435 break;
1436 }
Craig Mautner432f64e2015-05-20 14:59:57 -07001437 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
1438 " mLockTaskAuth=" + lockTaskAuthToString());
Craig Mautner15df08a2015-04-01 12:17:18 -07001439 }
1440
Benjamin Franza83859f2017-07-03 16:34:14 +01001441 private boolean isLockTaskWhitelistedLocked() {
Benjamin Franz6fd84cc2015-08-06 18:09:03 +01001442 String pkg = (realActivity != null) ? realActivity.getPackageName() : null;
1443 if (pkg == null) {
Craig Mautner15df08a2015-04-01 12:17:18 -07001444 return false;
1445 }
1446 String[] packages = mService.mLockTaskPackages.get(userId);
1447 if (packages == null) {
1448 return false;
1449 }
1450 for (int i = packages.length - 1; i >= 0; --i) {
Benjamin Franz6fd84cc2015-08-06 18:09:03 +01001451 if (pkg.equals(packages[i])) {
Craig Mautner15df08a2015-04-01 12:17:18 -07001452 return true;
1453 }
1454 }
1455 return false;
1456 }
Wale Ogunwale74e26592016-02-05 11:48:37 -08001457
Craig Mautner84984fa2014-06-19 11:19:20 -07001458 boolean isOverHomeStack() {
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001459 return mTaskToReturnTo == ACTIVITY_TYPE_HOME;
Craig Mautner1602ec22013-05-12 10:24:27 -07001460 }
1461
Winson Chung83471632016-12-13 11:02:12 -08001462 boolean isOverAssistantStack() {
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001463 return mTaskToReturnTo == ACTIVITY_TYPE_ASSISTANT;
Winson Chung83471632016-12-13 11:02:12 -08001464 }
1465
Winson Chungd3395382016-12-13 11:49:09 -08001466 private boolean isResizeable(boolean checkSupportsPip) {
1467 return (mService.mForceResizableActivities || ActivityInfo.isResizeableMode(mResizeMode)
1468 || (checkSupportsPip && mSupportsPictureInPicture)) && !mTemporarilyUnresizable;
1469 }
1470
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001471 boolean isResizeable() {
Winson Chungd3395382016-12-13 11:49:09 -08001472 return isResizeable(true /* checkSupportsPip */);
1473 }
1474
1475 boolean supportsSplitScreen() {
1476 // A task can not be docked even if it is considered resizeable because it only supports
1477 // picture-in-picture mode but has a non-resizeable resizeMode
1478 return mService.mSupportsSplitScreenMultiWindow
Bryce Leec857a5b2017-08-16 10:04:52 -07001479 && (mService.mForceResizableActivities
1480 || (isResizeable(false /* checkSupportsPip */)
1481 && !ActivityInfo.isPreserveOrientationMode(mResizeMode)));
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001482 }
1483
skuhne@google.com322347b2016-12-02 12:54:03 -08001484 /**
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001485 * Check whether this task can be launched on the specified display.
1486 * @param displayId Target display id.
1487 * @return {@code true} if either it is the default display or this activity is resizeable and
1488 * can be put a secondary screen.
1489 */
1490 boolean canBeLaunchedOnDisplay(int displayId) {
1491 return mService.mStackSupervisor.canPlaceEntityOnDisplay(displayId,
Andrii Kulian02689a72017-07-06 14:28:59 -07001492 isResizeable(false /* checkSupportsPip */), -1 /* don't check PID */,
1493 -1 /* don't check UID */, null /* activityInfo */);
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001494 }
1495
1496 /**
skuhne@google.com322347b2016-12-02 12:54:03 -08001497 * Check that a given bounds matches the application requested orientation.
1498 *
1499 * @param bounds The bounds to be tested.
1500 * @return True if the requested bounds are okay for a resizing request.
1501 */
Wale Ogunwale069bbd32017-02-03 07:58:14 -08001502 private boolean canResizeToBounds(Rect bounds) {
skuhne@google.com322347b2016-12-02 12:54:03 -08001503 if (bounds == null || getStackId() != FREEFORM_WORKSPACE_STACK_ID) {
1504 // Note: If not on the freeform workspace, we ignore the bounds.
1505 return true;
1506 }
1507 final boolean landscape = bounds.width() > bounds.height();
1508 if (mResizeMode == RESIZE_MODE_FORCE_RESIZABLE_PRESERVE_ORIENTATION) {
1509 return mBounds == null || landscape == (mBounds.width() > mBounds.height());
1510 }
1511 return (mResizeMode != RESIZE_MODE_FORCE_RESIZABLE_PORTRAIT_ONLY || !landscape)
1512 && (mResizeMode != RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY || landscape);
1513 }
1514
Craig Mautner525f3d92013-05-07 14:01:50 -07001515 /**
Yorke Leebdef5372017-04-10 16:38:51 -07001516 * @return {@code true} if the task is being cleared for the purposes of being reused.
1517 */
1518 boolean isClearingToReuseTask() {
1519 return mReuseTask;
1520 }
1521
1522 /**
Craig Mautner525f3d92013-05-07 14:01:50 -07001523 * Find the activity in the history stack within the given task. Returns
1524 * the index within the history at which it's found, or < 0 if not found.
1525 */
1526 final ActivityRecord findActivityInHistoryLocked(ActivityRecord r) {
1527 final ComponentName realActivity = r.realActivity;
1528 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1529 ActivityRecord candidate = mActivities.get(activityNdx);
1530 if (candidate.finishing) {
1531 continue;
1532 }
1533 if (candidate.realActivity.equals(realActivity)) {
1534 return candidate;
1535 }
1536 }
1537 return null;
1538 }
1539
Winson Chunga449dc02014-05-16 11:15:04 -07001540 /** Updates the last task description values. */
1541 void updateTaskDescription() {
1542 // Traverse upwards looking for any break between main task activities and
1543 // utility activities.
1544 int activityNdx;
1545 final int numActivities = mActivities.size();
Wale Ogunwale3eadad72016-10-13 09:16:59 -07001546 final boolean relinquish = numActivities != 0 &&
1547 (mActivities.get(0).info.flags & FLAG_RELINQUISH_TASK_IDENTITY) != 0;
Winson Chunga449dc02014-05-16 11:15:04 -07001548 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
Craig Mautner21d24a22014-04-23 11:45:37 -07001549 ++activityNdx) {
Winson Chunga449dc02014-05-16 11:15:04 -07001550 final ActivityRecord r = mActivities.get(activityNdx);
Wale Ogunwale3eadad72016-10-13 09:16:59 -07001551 if (relinquish && (r.info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001552 // This will be the top activity for determining taskDescription. Pre-inc to
1553 // overcome initial decrement below.
1554 ++activityNdx;
1555 break;
1556 }
Winson Chunga449dc02014-05-16 11:15:04 -07001557 if (r.intent != null &&
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001558 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
Winson Chunga449dc02014-05-16 11:15:04 -07001559 break;
1560 }
1561 }
1562 if (activityNdx > 0) {
1563 // Traverse downwards starting below break looking for set label, icon.
1564 // Note that if there are activities in the task but none of them set the
1565 // recent activity values, then we do not fall back to the last set
1566 // values in the TaskRecord.
1567 String label = null;
Craig Mautner648f69b2014-09-18 14:16:26 -07001568 String iconFilename = null;
Winson Chunga449dc02014-05-16 11:15:04 -07001569 int colorPrimary = 0;
Winson Chung1af8eda2016-02-05 17:55:56 +00001570 int colorBackground = 0;
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001571 int statusBarColor = 0;
1572 int navigationBarColor = 0;
1573 boolean topActivity = true;
Winson Chunga449dc02014-05-16 11:15:04 -07001574 for (--activityNdx; activityNdx >= 0; --activityNdx) {
1575 final ActivityRecord r = mActivities.get(activityNdx);
1576 if (r.taskDescription != null) {
1577 if (label == null) {
1578 label = r.taskDescription.getLabel();
1579 }
Craig Mautner648f69b2014-09-18 14:16:26 -07001580 if (iconFilename == null) {
1581 iconFilename = r.taskDescription.getIconFilename();
Winson Chunga449dc02014-05-16 11:15:04 -07001582 }
1583 if (colorPrimary == 0) {
1584 colorPrimary = r.taskDescription.getPrimaryColor();
Winson Chunga449dc02014-05-16 11:15:04 -07001585 }
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001586 if (topActivity) {
Winson Chung1af8eda2016-02-05 17:55:56 +00001587 colorBackground = r.taskDescription.getBackgroundColor();
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001588 statusBarColor = r.taskDescription.getStatusBarColor();
1589 navigationBarColor = r.taskDescription.getNavigationBarColor();
Winson Chung1af8eda2016-02-05 17:55:56 +00001590 }
Winson Chunga449dc02014-05-16 11:15:04 -07001591 }
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001592 topActivity = false;
Winson Chunga449dc02014-05-16 11:15:04 -07001593 }
Winson Chung1af8eda2016-02-05 17:55:56 +00001594 lastTaskDescription = new TaskDescription(label, null, iconFilename, colorPrimary,
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001595 colorBackground, statusBarColor, navigationBarColor);
Jorim Jaggi829b9cd2017-01-23 16:20:53 +01001596 if (mWindowContainerController != null) {
1597 mWindowContainerController.setTaskDescription(lastTaskDescription);
1598 }
Winson Chungec396d62014-08-06 17:08:00 -07001599 // Update the task affiliation color if we are the parent of the group
1600 if (taskId == mAffiliatedTaskId) {
1601 mAffiliatedTaskColor = lastTaskDescription.getPrimaryColor();
1602 }
Winson Chunga449dc02014-05-16 11:15:04 -07001603 }
1604 }
1605
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001606 int findEffectiveRootIndex() {
Craig Mautner4767f4b2014-09-18 15:38:33 -07001607 int effectiveNdx = 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001608 final int topActivityNdx = mActivities.size() - 1;
Dianne Hackborn39569af2014-09-23 10:56:58 -07001609 for (int activityNdx = 0; activityNdx <= topActivityNdx; ++activityNdx) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001610 final ActivityRecord r = mActivities.get(activityNdx);
1611 if (r.finishing) {
1612 continue;
1613 }
Craig Mautner4767f4b2014-09-18 15:38:33 -07001614 effectiveNdx = activityNdx;
Wale Ogunwale3eadad72016-10-13 09:16:59 -07001615 if ((r.info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001616 break;
1617 }
1618 }
Craig Mautner4767f4b2014-09-18 15:38:33 -07001619 return effectiveNdx;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001620 }
1621
1622 void updateEffectiveIntent() {
1623 final int effectiveRootIndex = findEffectiveRootIndex();
1624 final ActivityRecord r = mActivities.get(effectiveRootIndex);
Winson Chungfee26772014-08-05 12:21:52 -07001625 setIntent(r);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001626 }
1627
Craig Mautner21d24a22014-04-23 11:45:37 -07001628 void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001629 if (DEBUG_RECENTS) Slog.i(TAG_RECENTS, "Saving task=" + this);
Craig Mautner21d24a22014-04-23 11:45:37 -07001630
1631 out.attribute(null, ATTR_TASKID, String.valueOf(taskId));
1632 if (realActivity != null) {
1633 out.attribute(null, ATTR_REALACTIVITY, realActivity.flattenToShortString());
1634 }
Andrei Stingaceanu4ccec532016-01-13 12:10:21 +00001635 out.attribute(null, ATTR_REALACTIVITY_SUSPENDED, String.valueOf(realActivitySuspended));
Craig Mautner21d24a22014-04-23 11:45:37 -07001636 if (origActivity != null) {
1637 out.attribute(null, ATTR_ORIGACTIVITY, origActivity.flattenToShortString());
1638 }
Dianne Hackborn79228822014-09-16 11:11:23 -07001639 // Write affinity, and root affinity if it is different from affinity.
1640 // We use the special string "@" for a null root affinity, so we can identify
1641 // later whether we were given a root affinity or should just make it the
1642 // same as the affinity.
Craig Mautner21d24a22014-04-23 11:45:37 -07001643 if (affinity != null) {
1644 out.attribute(null, ATTR_AFFINITY, affinity);
Dianne Hackborn79228822014-09-16 11:11:23 -07001645 if (!affinity.equals(rootAffinity)) {
1646 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
1647 }
1648 } else if (rootAffinity != null) {
1649 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
Craig Mautner21d24a22014-04-23 11:45:37 -07001650 }
1651 out.attribute(null, ATTR_ROOTHASRESET, String.valueOf(rootWasReset));
Dianne Hackborn13420f22014-07-18 15:43:56 -07001652 out.attribute(null, ATTR_AUTOREMOVERECENTS, String.valueOf(autoRemoveRecents));
Craig Mautner21d24a22014-04-23 11:45:37 -07001653 out.attribute(null, ATTR_ASKEDCOMPATMODE, String.valueOf(askedCompatMode));
1654 out.attribute(null, ATTR_USERID, String.valueOf(userId));
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001655 out.attribute(null, ATTR_USER_SETUP_COMPLETE, String.valueOf(mUserSetupComplete));
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001656 out.attribute(null, ATTR_EFFECTIVE_UID, String.valueOf(effectiveUid));
Winson Chungffa2ec62014-07-03 15:54:42 -07001657 out.attribute(null, ATTR_FIRSTACTIVETIME, String.valueOf(firstActiveTime));
Winson Chungf1fbd772014-06-24 18:06:58 -07001658 out.attribute(null, ATTR_LASTACTIVETIME, String.valueOf(lastActiveTime));
Craig Mautner21d24a22014-04-23 11:45:37 -07001659 out.attribute(null, ATTR_LASTTIMEMOVED, String.valueOf(mLastTimeMoved));
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001660 out.attribute(null, ATTR_NEVERRELINQUISH, String.valueOf(mNeverRelinquishIdentity));
Craig Mautner21d24a22014-04-23 11:45:37 -07001661 if (lastDescription != null) {
1662 out.attribute(null, ATTR_LASTDESCRIPTION, lastDescription.toString());
1663 }
Winson Chung2cb86c72014-06-25 12:03:30 -07001664 if (lastTaskDescription != null) {
Craig Mautner648f69b2014-09-18 14:16:26 -07001665 lastTaskDescription.saveToXml(out);
Winson Chung2cb86c72014-06-25 12:03:30 -07001666 }
Winson Chungec396d62014-08-06 17:08:00 -07001667 out.attribute(null, ATTR_TASK_AFFILIATION_COLOR, String.valueOf(mAffiliatedTaskColor));
Craig Mautnera228ae92014-07-09 05:44:55 -07001668 out.attribute(null, ATTR_TASK_AFFILIATION, String.valueOf(mAffiliatedTaskId));
1669 out.attribute(null, ATTR_PREV_AFFILIATION, String.valueOf(mPrevAffiliateTaskId));
1670 out.attribute(null, ATTR_NEXT_AFFILIATION, String.valueOf(mNextAffiliateTaskId));
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001671 out.attribute(null, ATTR_CALLING_UID, String.valueOf(mCallingUid));
1672 out.attribute(null, ATTR_CALLING_PACKAGE, mCallingPackage == null ? "" : mCallingPackage);
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001673 out.attribute(null, ATTR_RESIZE_MODE, String.valueOf(mResizeMode));
Winson Chungd3395382016-12-13 11:49:09 -08001674 out.attribute(null, ATTR_SUPPORTS_PICTURE_IN_PICTURE,
1675 String.valueOf(mSupportsPictureInPicture));
Wale Ogunwalea7afaa22015-05-01 20:39:18 -07001676 out.attribute(null, ATTR_PRIVILEGED, String.valueOf(mPrivileged));
Wale Ogunwale706ed792015-08-02 10:29:44 -07001677 if (mLastNonFullscreenBounds != null) {
1678 out.attribute(
1679 null, ATTR_NON_FULLSCREEN_BOUNDS, mLastNonFullscreenBounds.flattenToString());
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001680 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001681 out.attribute(null, ATTR_MIN_WIDTH, String.valueOf(mMinWidth));
1682 out.attribute(null, ATTR_MIN_HEIGHT, String.valueOf(mMinHeight));
Wale Ogunwale625ed0c2016-10-18 08:50:31 -07001683 out.attribute(null, ATTR_PERSIST_TASK_VERSION, String.valueOf(PERSIST_TASK_VERSION));
Winson Chung2cb86c72014-06-25 12:03:30 -07001684
Craig Mautner21d24a22014-04-23 11:45:37 -07001685 if (affinityIntent != null) {
1686 out.startTag(null, TAG_AFFINITYINTENT);
1687 affinityIntent.saveToXml(out);
1688 out.endTag(null, TAG_AFFINITYINTENT);
1689 }
1690
Winson Chung36f3f032016-09-08 23:29:43 +00001691 out.startTag(null, TAG_INTENT);
1692 intent.saveToXml(out);
1693 out.endTag(null, TAG_INTENT);
Craig Mautner21d24a22014-04-23 11:45:37 -07001694
1695 final ArrayList<ActivityRecord> activities = mActivities;
1696 final int numActivities = activities.size();
1697 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
1698 final ActivityRecord r = activities.get(activityNdx);
Craig Mautner43e52ed2014-06-16 17:18:52 -07001699 if (r.info.persistableMode == ActivityInfo.PERSIST_ROOT_ONLY || !r.isPersistable() ||
Wale Ogunwale843bfb92015-03-27 11:06:48 -07001700 ((r.intent.getFlags() & FLAG_ACTIVITY_NEW_DOCUMENT
1701 | FLAG_ACTIVITY_RETAIN_IN_RECENTS) == FLAG_ACTIVITY_NEW_DOCUMENT) &&
Craig Mautner43e52ed2014-06-16 17:18:52 -07001702 activityNdx > 0) {
Craig Mautnerf357c0c2014-06-09 09:23:27 -07001703 // Stop at first non-persistable or first break in task (CLEAR_WHEN_TASK_RESET).
Craig Mautner21d24a22014-04-23 11:45:37 -07001704 break;
1705 }
1706 out.startTag(null, TAG_ACTIVITY);
1707 r.saveToXml(out);
1708 out.endTag(null, TAG_ACTIVITY);
1709 }
Craig Mautner21d24a22014-04-23 11:45:37 -07001710 }
1711
Winson Chung36f3f032016-09-08 23:29:43 +00001712 static TaskRecord restoreFromXml(XmlPullParser in, ActivityStackSupervisor stackSupervisor)
1713 throws IOException, XmlPullParserException {
Craig Mautner21d24a22014-04-23 11:45:37 -07001714 Intent intent = null;
1715 Intent affinityIntent = null;
Winsonc809cbb2015-11-02 12:06:15 -08001716 ArrayList<ActivityRecord> activities = new ArrayList<>();
Craig Mautner21d24a22014-04-23 11:45:37 -07001717 ComponentName realActivity = null;
Andrei Stingaceanu4ccec532016-01-13 12:10:21 +00001718 boolean realActivitySuspended = false;
Craig Mautner21d24a22014-04-23 11:45:37 -07001719 ComponentName origActivity = null;
1720 String affinity = null;
Dianne Hackborn79228822014-09-16 11:11:23 -07001721 String rootAffinity = null;
1722 boolean hasRootAffinity = false;
Craig Mautner21d24a22014-04-23 11:45:37 -07001723 boolean rootHasReset = false;
Dianne Hackborn13420f22014-07-18 15:43:56 -07001724 boolean autoRemoveRecents = false;
Craig Mautner21d24a22014-04-23 11:45:37 -07001725 boolean askedCompatMode = false;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001726 int taskType = 0;
Craig Mautner21d24a22014-04-23 11:45:37 -07001727 int userId = 0;
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001728 boolean userSetupComplete = true;
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001729 int effectiveUid = -1;
Craig Mautner21d24a22014-04-23 11:45:37 -07001730 String lastDescription = null;
Winson Chungffa2ec62014-07-03 15:54:42 -07001731 long firstActiveTime = -1;
Winson Chung2cb86c72014-06-25 12:03:30 -07001732 long lastActiveTime = -1;
Craig Mautner21d24a22014-04-23 11:45:37 -07001733 long lastTimeOnTop = 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001734 boolean neverRelinquishIdentity = true;
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001735 int taskId = INVALID_TASK_ID;
Craig Mautner21d24a22014-04-23 11:45:37 -07001736 final int outerDepth = in.getDepth();
Craig Mautner648f69b2014-09-18 14:16:26 -07001737 TaskDescription taskDescription = new TaskDescription();
Wale Ogunwale18795a22014-12-03 11:38:33 -08001738 int taskAffiliation = INVALID_TASK_ID;
Winson Chungec396d62014-08-06 17:08:00 -07001739 int taskAffiliationColor = 0;
Wale Ogunwale18795a22014-12-03 11:38:33 -08001740 int prevTaskId = INVALID_TASK_ID;
1741 int nextTaskId = INVALID_TASK_ID;
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001742 int callingUid = -1;
1743 String callingPackage = "";
Wale Ogunwaled829d362016-02-10 19:24:49 -08001744 int resizeMode = RESIZE_MODE_FORCE_RESIZEABLE;
Winson Chungd3395382016-12-13 11:49:09 -08001745 boolean supportsPictureInPicture = false;
Wale Ogunwalea7afaa22015-05-01 20:39:18 -07001746 boolean privileged = false;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001747 Rect bounds = null;
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001748 int minWidth = INVALID_MIN_SIZE;
1749 int minHeight = INVALID_MIN_SIZE;
Wale Ogunwale625ed0c2016-10-18 08:50:31 -07001750 int persistTaskVersion = 0;
Craig Mautner21d24a22014-04-23 11:45:37 -07001751
1752 for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
1753 final String attrName = in.getAttributeName(attrNdx);
1754 final String attrValue = in.getAttributeValue(attrNdx);
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001755 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: attribute name=" +
1756 attrName + " value=" + attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001757 if (ATTR_TASKID.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001758 if (taskId == INVALID_TASK_ID) taskId = Integer.parseInt(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001759 } else if (ATTR_REALACTIVITY.equals(attrName)) {
1760 realActivity = ComponentName.unflattenFromString(attrValue);
Andrei Stingaceanu4ccec532016-01-13 12:10:21 +00001761 } else if (ATTR_REALACTIVITY_SUSPENDED.equals(attrName)) {
1762 realActivitySuspended = Boolean.valueOf(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001763 } else if (ATTR_ORIGACTIVITY.equals(attrName)) {
1764 origActivity = ComponentName.unflattenFromString(attrValue);
1765 } else if (ATTR_AFFINITY.equals(attrName)) {
1766 affinity = attrValue;
Dianne Hackborn79228822014-09-16 11:11:23 -07001767 } else if (ATTR_ROOT_AFFINITY.equals(attrName)) {
1768 rootAffinity = attrValue;
1769 hasRootAffinity = true;
Craig Mautner21d24a22014-04-23 11:45:37 -07001770 } else if (ATTR_ROOTHASRESET.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01001771 rootHasReset = Boolean.parseBoolean(attrValue);
Dianne Hackborn13420f22014-07-18 15:43:56 -07001772 } else if (ATTR_AUTOREMOVERECENTS.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01001773 autoRemoveRecents = Boolean.parseBoolean(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001774 } else if (ATTR_ASKEDCOMPATMODE.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01001775 askedCompatMode = Boolean.parseBoolean(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001776 } else if (ATTR_USERID.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001777 userId = Integer.parseInt(attrValue);
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001778 } else if (ATTR_USER_SETUP_COMPLETE.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01001779 userSetupComplete = Boolean.parseBoolean(attrValue);
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001780 } else if (ATTR_EFFECTIVE_UID.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001781 effectiveUid = Integer.parseInt(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001782 } else if (ATTR_TASKTYPE.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001783 taskType = Integer.parseInt(attrValue);
Winson Chungffa2ec62014-07-03 15:54:42 -07001784 } else if (ATTR_FIRSTACTIVETIME.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01001785 firstActiveTime = Long.parseLong(attrValue);
Winson Chungf1fbd772014-06-24 18:06:58 -07001786 } else if (ATTR_LASTACTIVETIME.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01001787 lastActiveTime = Long.parseLong(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001788 } else if (ATTR_LASTDESCRIPTION.equals(attrName)) {
1789 lastDescription = attrValue;
1790 } else if (ATTR_LASTTIMEMOVED.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01001791 lastTimeOnTop = Long.parseLong(attrValue);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001792 } else if (ATTR_NEVERRELINQUISH.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01001793 neverRelinquishIdentity = Boolean.parseBoolean(attrValue);
Craig Mautner648f69b2014-09-18 14:16:26 -07001794 } else if (attrName.startsWith(TaskDescription.ATTR_TASKDESCRIPTION_PREFIX)) {
1795 taskDescription.restoreFromXml(attrName, attrValue);
Craig Mautnera228ae92014-07-09 05:44:55 -07001796 } else if (ATTR_TASK_AFFILIATION.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001797 taskAffiliation = Integer.parseInt(attrValue);
Craig Mautnera228ae92014-07-09 05:44:55 -07001798 } else if (ATTR_PREV_AFFILIATION.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001799 prevTaskId = Integer.parseInt(attrValue);
Craig Mautnera228ae92014-07-09 05:44:55 -07001800 } else if (ATTR_NEXT_AFFILIATION.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001801 nextTaskId = Integer.parseInt(attrValue);
Winson Chungec396d62014-08-06 17:08:00 -07001802 } else if (ATTR_TASK_AFFILIATION_COLOR.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001803 taskAffiliationColor = Integer.parseInt(attrValue);
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001804 } else if (ATTR_CALLING_UID.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001805 callingUid = Integer.parseInt(attrValue);
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001806 } else if (ATTR_CALLING_PACKAGE.equals(attrName)) {
1807 callingPackage = attrValue;
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001808 } else if (ATTR_RESIZE_MODE.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001809 resizeMode = Integer.parseInt(attrValue);
Winson Chungd3395382016-12-13 11:49:09 -08001810 } else if (ATTR_SUPPORTS_PICTURE_IN_PICTURE.equals(attrName)) {
1811 supportsPictureInPicture = Boolean.parseBoolean(attrValue);
Wale Ogunwalea7afaa22015-05-01 20:39:18 -07001812 } else if (ATTR_PRIVILEGED.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01001813 privileged = Boolean.parseBoolean(attrValue);
Wale Ogunwale706ed792015-08-02 10:29:44 -07001814 } else if (ATTR_NON_FULLSCREEN_BOUNDS.equals(attrName)) {
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001815 bounds = Rect.unflattenFromString(attrValue);
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001816 } else if (ATTR_MIN_WIDTH.equals(attrName)) {
1817 minWidth = Integer.parseInt(attrValue);
1818 } else if (ATTR_MIN_HEIGHT.equals(attrName)) {
1819 minHeight = Integer.parseInt(attrValue);
Wale Ogunwale625ed0c2016-10-18 08:50:31 -07001820 } else if (ATTR_PERSIST_TASK_VERSION.equals(attrName)) {
1821 persistTaskVersion = Integer.parseInt(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001822 } else {
1823 Slog.w(TAG, "TaskRecord: Unknown attribute=" + attrName);
1824 }
1825 }
1826
1827 int event;
1828 while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
Ben Kwa8814cf42015-07-08 10:54:56 -07001829 (event != XmlPullParser.END_TAG || in.getDepth() >= outerDepth)) {
Craig Mautner21d24a22014-04-23 11:45:37 -07001830 if (event == XmlPullParser.START_TAG) {
1831 final String name = in.getName();
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001832 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: START_TAG name=" +
1833 name);
Craig Mautner21d24a22014-04-23 11:45:37 -07001834 if (TAG_AFFINITYINTENT.equals(name)) {
1835 affinityIntent = Intent.restoreFromXml(in);
1836 } else if (TAG_INTENT.equals(name)) {
1837 intent = Intent.restoreFromXml(in);
1838 } else if (TAG_ACTIVITY.equals(name)) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08001839 ActivityRecord activity = ActivityRecord.restoreFromXml(in, stackSupervisor);
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001840 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: activity=" +
1841 activity);
Craig Mautner21d24a22014-04-23 11:45:37 -07001842 if (activity != null) {
1843 activities.add(activity);
1844 }
1845 } else {
1846 Slog.e(TAG, "restoreTask: Unexpected name=" + name);
1847 XmlUtils.skipCurrentTag(in);
1848 }
1849 }
1850 }
Dianne Hackborn79228822014-09-16 11:11:23 -07001851 if (!hasRootAffinity) {
1852 rootAffinity = affinity;
1853 } else if ("@".equals(rootAffinity)) {
1854 rootAffinity = null;
1855 }
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001856 if (effectiveUid <= 0) {
1857 Intent checkIntent = intent != null ? intent : affinityIntent;
1858 effectiveUid = 0;
1859 if (checkIntent != null) {
1860 IPackageManager pm = AppGlobals.getPackageManager();
1861 try {
1862 ApplicationInfo ai = pm.getApplicationInfo(
1863 checkIntent.getComponent().getPackageName(),
Amith Yamasani0d1fd8d2016-10-12 14:21:51 -07001864 PackageManager.MATCH_UNINSTALLED_PACKAGES
1865 | PackageManager.MATCH_DISABLED_COMPONENTS, userId);
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001866 if (ai != null) {
1867 effectiveUid = ai.uid;
1868 }
1869 } catch (RemoteException e) {
1870 }
1871 }
1872 Slog.w(TAG, "Updating task #" + taskId + " for " + checkIntent
1873 + ": effectiveUid=" + effectiveUid);
1874 }
1875
Wale Ogunwale625ed0c2016-10-18 08:50:31 -07001876 if (persistTaskVersion < 1) {
1877 // We need to convert the resize mode of home activities saved before version one if
1878 // they are marked as RESIZE_MODE_RESIZEABLE to RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION
1879 // since we didn't have that differentiation before version 1 and the system didn't
1880 // resize home activities before then.
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001881 if (taskType == 1 /* old home type */ && resizeMode == RESIZE_MODE_RESIZEABLE) {
Wale Ogunwale625ed0c2016-10-18 08:50:31 -07001882 resizeMode = RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
1883 }
Winson Chungd3395382016-12-13 11:49:09 -08001884 } else {
1885 // This activity has previously marked itself explicitly as both resizeable and
1886 // supporting picture-in-picture. Since there is no longer a requirement for
1887 // picture-in-picture activities to be resizeable, we can mark this simply as
1888 // resizeable and supporting picture-in-picture separately.
1889 if (resizeMode == RESIZE_MODE_RESIZEABLE_AND_PIPABLE_DEPRECATED) {
1890 resizeMode = RESIZE_MODE_RESIZEABLE;
1891 supportsPictureInPicture = true;
1892 }
Wale Ogunwale625ed0c2016-10-18 08:50:31 -07001893 }
1894
Winson Chung36f3f032016-09-08 23:29:43 +00001895 final TaskRecord task = new TaskRecord(stackSupervisor.mService, taskId, intent,
Dianne Hackborn79228822014-09-16 11:11:23 -07001896 affinityIntent, affinity, rootAffinity, realActivity, origActivity, rootHasReset,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001897 autoRemoveRecents, askedCompatMode, userId, effectiveUid, lastDescription,
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001898 activities, firstActiveTime, lastActiveTime, lastTimeOnTop, neverRelinquishIdentity,
Jorim Jaggie7d2b852017-08-28 17:55:15 +02001899 taskDescription, taskAffiliation, prevTaskId, nextTaskId, taskAffiliationColor,
1900 callingUid, callingPackage, resizeMode, supportsPictureInPicture, privileged,
1901 realActivitySuspended, userSetupComplete, minWidth, minHeight);
Filip Gruszczynskiaff7f132015-09-02 17:21:21 -07001902 task.updateOverrideConfiguration(bounds);
Craig Mautner21d24a22014-04-23 11:45:37 -07001903
1904 for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001905 activities.get(activityNdx).setTask(task);
Craig Mautner21d24a22014-04-23 11:45:37 -07001906 }
1907
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001908 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Restored task=" + task);
Craig Mautner21d24a22014-04-23 11:45:37 -07001909 return task;
1910 }
1911
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001912 private void adjustForMinimalTaskDimensions(Rect bounds) {
1913 if (bounds == null) {
1914 return;
1915 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001916 int minWidth = mMinWidth;
1917 int minHeight = mMinHeight;
Robert Carr9c5867d2016-03-10 15:52:46 -08001918 // If the task has no requested minimal size, we'd like to enforce a minimal size
1919 // so that the user can not render the task too small to manipulate. We don't need
1920 // to do this for the pinned stack as the bounds are controlled by the system.
Andrii Kulian02b7a832016-10-06 23:11:56 -07001921 if (getStackId() != PINNED_STACK_ID) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001922 if (minWidth == INVALID_MIN_SIZE) {
1923 minWidth = mService.mStackSupervisor.mDefaultMinSizeOfResizeableTask;
Andrii Kulian2e751b82016-03-16 16:59:32 -07001924 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001925 if (minHeight == INVALID_MIN_SIZE) {
1926 minHeight = mService.mStackSupervisor.mDefaultMinSizeOfResizeableTask;
Andrii Kulian2e751b82016-03-16 16:59:32 -07001927 }
Robert Carr9c5867d2016-03-10 15:52:46 -08001928 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001929 final boolean adjustWidth = minWidth > bounds.width();
1930 final boolean adjustHeight = minHeight > bounds.height();
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001931 if (!(adjustWidth || adjustHeight)) {
1932 return;
1933 }
1934
1935 if (adjustWidth) {
1936 if (mBounds != null && bounds.right == mBounds.right) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001937 bounds.left = bounds.right - minWidth;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001938 } else {
1939 // Either left bounds match, or neither match, or the previous bounds were
1940 // fullscreen and we default to keeping left.
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001941 bounds.right = bounds.left + minWidth;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001942 }
1943 }
1944 if (adjustHeight) {
1945 if (mBounds != null && bounds.bottom == mBounds.bottom) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001946 bounds.top = bounds.bottom - minHeight;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001947 } else {
1948 // Either top bounds match, or neither match, or the previous bounds were
1949 // fullscreen and we default to keeping top.
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001950 bounds.bottom = bounds.top + minHeight;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001951 }
1952 }
1953 }
1954
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001955 /**
Winson Chung5af42fc2017-03-24 17:11:33 -07001956 * @return a new Configuration for this Task, given the provided {@param bounds} and
1957 * {@param insetBounds}.
1958 */
1959 Configuration computeNewOverrideConfigurationForBounds(Rect bounds, Rect insetBounds) {
1960 // Compute a new override configuration for the given bounds, if fullscreen bounds
1961 // (bounds == null), then leave the override config unset
1962 final Configuration newOverrideConfig = new Configuration();
1963 if (bounds != null) {
1964 newOverrideConfig.setTo(getOverrideConfiguration());
1965 mTmpRect.set(bounds);
1966 adjustForMinimalTaskDimensions(mTmpRect);
1967 computeOverrideConfiguration(newOverrideConfig, mTmpRect, insetBounds,
1968 mTmpRect.right != bounds.right, mTmpRect.bottom != bounds.bottom);
1969 }
1970
1971 return newOverrideConfig;
1972 }
1973
1974 /**
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001975 * Update task's override configuration based on the bounds.
Jorim Jaggi0a932142016-02-01 17:42:25 -08001976 * @param bounds The bounds of the task.
Andrii Kulian8072d112016-09-16 11:11:01 -07001977 * @return True if the override configuration was updated.
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001978 */
Andrii Kulian8072d112016-09-16 11:11:01 -07001979 boolean updateOverrideConfiguration(Rect bounds) {
Jorim Jaggi0a932142016-02-01 17:42:25 -08001980 return updateOverrideConfiguration(bounds, null /* insetBounds */);
1981 }
1982
1983 /**
1984 * Update task's override configuration based on the bounds.
1985 * @param bounds The bounds of the task.
1986 * @param insetBounds The bounds used to calculate the system insets, which is used here to
1987 * subtract the navigation bar/status bar size from the screen size reported
1988 * to the application. See {@link IActivityManager#resizeDockedStack}.
Andrii Kulian8072d112016-09-16 11:11:01 -07001989 * @return True if the override configuration was updated.
Jorim Jaggi0a932142016-02-01 17:42:25 -08001990 */
Andrii Kulian8072d112016-09-16 11:11:01 -07001991 boolean updateOverrideConfiguration(Rect bounds, @Nullable Rect insetBounds) {
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001992 if (Objects.equals(mBounds, bounds)) {
Andrii Kulian8072d112016-09-16 11:11:01 -07001993 return false;
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001994 }
Andrii Kulian1779e612016-10-12 21:58:25 -07001995 mTmpConfig.setTo(getOverrideConfiguration());
Wale Ogunwale5f986092015-12-04 15:35:38 -08001996 final boolean oldFullscreen = mFullscreen;
Andrii Kulian1779e612016-10-12 21:58:25 -07001997 final Configuration newConfig = getOverrideConfiguration();
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001998
1999 mFullscreen = bounds == null;
Wale Ogunwale3382ab12017-07-27 08:55:03 -07002000 final boolean persistBounds = getWindowConfiguration().persistTaskBounds();
Wale Ogunwale706ed792015-08-02 10:29:44 -07002001 if (mFullscreen) {
Wale Ogunwale3382ab12017-07-27 08:55:03 -07002002 if (mBounds != null && persistBounds) {
Wale Ogunwale706ed792015-08-02 10:29:44 -07002003 mLastNonFullscreenBounds = mBounds;
2004 }
2005 mBounds = null;
Andrii Kulian1779e612016-10-12 21:58:25 -07002006 newConfig.unset();
Wale Ogunwale706ed792015-08-02 10:29:44 -07002007 } else {
Wale Ogunwale9a08f822016-02-17 19:03:58 -08002008 mTmpRect.set(bounds);
2009 adjustForMinimalTaskDimensions(mTmpRect);
Chong Zhangb15758a2015-11-17 12:12:03 -08002010 if (mBounds == null) {
Wale Ogunwale9a08f822016-02-17 19:03:58 -08002011 mBounds = new Rect(mTmpRect);
Chong Zhangb15758a2015-11-17 12:12:03 -08002012 } else {
Wale Ogunwale9a08f822016-02-17 19:03:58 -08002013 mBounds.set(mTmpRect);
Chong Zhangb15758a2015-11-17 12:12:03 -08002014 }
Wale Ogunwale3382ab12017-07-27 08:55:03 -07002015 if (mStack == null || persistBounds) {
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -07002016 mLastNonFullscreenBounds = mBounds;
2017 }
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002018 computeOverrideConfiguration(newConfig, mTmpRect, insetBounds,
Andrii Kuliandaea3572016-04-08 13:20:51 -07002019 mTmpRect.right != bounds.right, mTmpRect.bottom != bounds.bottom);
Wale Ogunwale706ed792015-08-02 10:29:44 -07002020 }
Andrii Kulian1779e612016-10-12 21:58:25 -07002021 onOverrideConfigurationChanged(newConfig);
Wale Ogunwale5f986092015-12-04 15:35:38 -08002022
2023 if (mFullscreen != oldFullscreen) {
Winson Chung5af42fc2017-03-24 17:11:33 -07002024 mService.mStackSupervisor.scheduleUpdateMultiWindowMode(this);
Wale Ogunwale5f986092015-12-04 15:35:38 -08002025 }
2026
Andrii Kulian1779e612016-10-12 21:58:25 -07002027 return !mTmpConfig.equals(newConfig);
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07002028 }
2029
Andrii Kulian1779e612016-10-12 21:58:25 -07002030 /** Clears passed config and fills it with new override values. */
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002031 // TODO(b/36505427): TaskRecord.computeOverrideConfiguration() is a utility method that doesn't
2032 // depend on task or stacks, but uses those object to get the display to base the calculation
2033 // on. Probably best to centralize calculations like this in ConfigurationContainer.
2034 void computeOverrideConfiguration(Configuration config, Rect bounds, Rect insetBounds,
Andrii Kuliana8a9bc52016-10-14 11:00:13 -07002035 boolean overrideWidth, boolean overrideHeight) {
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08002036 mTmpNonDecorBounds.set(bounds);
2037 mTmpStableBounds.set(bounds);
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08002038
Andrii Kulian1779e612016-10-12 21:58:25 -07002039 config.unset();
Winson Chungbdc646f2017-02-13 12:12:22 -08002040 final Configuration parentConfig = getParent().getConfiguration();
Bryce Lee7566d762017-03-30 09:34:15 -07002041
Andrii Kulian1779e612016-10-12 21:58:25 -07002042 final float density = parentConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08002043
Winson Chungbdc646f2017-02-13 12:12:22 -08002044 if (mStack != null) {
2045 final StackWindowController stackController = mStack.getWindowContainerController();
2046 stackController.adjustConfigurationForBounds(bounds, insetBounds,
2047 mTmpNonDecorBounds, mTmpStableBounds, overrideWidth, overrideHeight, density,
2048 config, parentConfig);
2049 } else {
Bryce Lee7566d762017-03-30 09:34:15 -07002050 throw new IllegalArgumentException("Expected stack when calculating override config");
Winson Chungbdc646f2017-02-13 12:12:22 -08002051 }
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08002052
Winson Chung60c1aba2017-03-14 17:47:42 -07002053 config.orientation = (config.screenWidthDp <= config.screenHeightDp)
2054 ? Configuration.ORIENTATION_PORTRAIT
2055 : Configuration.ORIENTATION_LANDSCAPE;
2056
Jorim Jaggi85639432016-05-06 17:27:55 -07002057 // For calculating screen layout, we need to use the non-decor inset screen area for the
2058 // calculation for compatibility reasons, i.e. screen area without system bars that could
2059 // never go away in Honeycomb.
Winson Chungbdc646f2017-02-13 12:12:22 -08002060 final int compatScreenWidthDp = (int) (mTmpNonDecorBounds.width() / density);
2061 final int compatScreenHeightDp = (int) (mTmpNonDecorBounds.height() / density);
Andrii Kulian1779e612016-10-12 21:58:25 -07002062 // We're only overriding LONG, SIZE and COMPAT parts of screenLayout, so we start override
2063 // calculation with partial default.
2064 final int sl = Configuration.SCREENLAYOUT_LONG_YES | Configuration.SCREENLAYOUT_SIZE_XLARGE;
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08002065 final int longSize = Math.max(compatScreenHeightDp, compatScreenWidthDp);
Andrii Kulian1779e612016-10-12 21:58:25 -07002066 final int shortSize = Math.min(compatScreenHeightDp, compatScreenWidthDp);
Jorim Jaggi85639432016-05-06 17:27:55 -07002067 config.screenLayout = Configuration.reduceScreenLayout(sl, longSize, shortSize);
2068
Jorim Jaggia95ca8d2016-01-15 22:54:46 -08002069 }
2070
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08002071 Rect updateOverrideConfigurationFromLaunchBounds() {
2072 final Rect bounds = validateBounds(getLaunchBounds());
2073 updateOverrideConfiguration(bounds);
Andrii Kulian73336d812016-03-24 12:56:08 -07002074 if (bounds != null) {
2075 bounds.set(mBounds);
2076 }
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08002077 return bounds;
2078 }
2079
2080 static Rect validateBounds(Rect bounds) {
2081 if (bounds != null && bounds.isEmpty()) {
2082 Slog.wtf(TAG, "Received strange task bounds: " + bounds, new Throwable());
2083 return null;
2084 }
2085 return bounds;
2086 }
2087
Wale Ogunwale935e5022015-11-10 12:36:10 -08002088 /** Updates the task's bounds and override configuration to match what is expected for the
2089 * input stack. */
2090 void updateOverrideConfigurationForStack(ActivityStack inStack) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07002091 if (mStack != null && mStack == inStack) {
Wale Ogunwale935e5022015-11-10 12:36:10 -08002092 return;
2093 }
2094
2095 if (inStack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002096 if (!isResizeable()) {
Wale Ogunwale935e5022015-11-10 12:36:10 -08002097 throw new IllegalArgumentException("Can not position non-resizeable task="
2098 + this + " in stack=" + inStack);
2099 }
2100 if (mBounds != null) {
2101 return;
2102 }
2103 if (mLastNonFullscreenBounds != null) {
2104 updateOverrideConfiguration(mLastNonFullscreenBounds);
2105 } else {
2106 inStack.layoutTaskInStack(this, null);
2107 }
2108 } else {
2109 updateOverrideConfiguration(inStack.mBounds);
2110 }
2111 }
2112
Chong Zhang0fa656b2015-08-31 15:17:21 -07002113 /**
2114 * Returns the correct stack to use based on task type and currently set bounds,
2115 * regardless of the focused stack and current stack association of the task.
2116 * The task will be moved (and stack focus changed) later if necessary.
2117 */
2118 int getLaunchStackId() {
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07002119 if (isActivityTypeRecents()) {
Matthew Ngae1ff4f2016-11-10 15:49:14 -08002120 return RECENTS_STACK_ID;
2121 }
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07002122 if (isActivityTypeHome()) {
Wale Ogunwale706ed792015-08-02 10:29:44 -07002123 return HOME_STACK_ID;
2124 }
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07002125 if (isActivityTypeAssistant()) {
Winson Chung83471632016-12-13 11:02:12 -08002126 return ASSISTANT_STACK_ID;
2127 }
Chong Zhang0fa656b2015-08-31 15:17:21 -07002128 if (mBounds != null) {
Wale Ogunwale706ed792015-08-02 10:29:44 -07002129 return FREEFORM_WORKSPACE_STACK_ID;
2130 }
2131 return FULLSCREEN_WORKSPACE_STACK_ID;
2132 }
2133
2134 /** Returns the bounds that should be used to launch this task. */
Wale Ogunwale3382ab12017-07-27 08:55:03 -07002135 private Rect getLaunchBounds() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07002136 if (mStack == null) {
Chong Zhang7d5f5102016-01-13 10:29:24 -08002137 return null;
2138 }
2139
Andrii Kulian02b7a832016-10-06 23:11:56 -07002140 final int stackId = mStack.mStackId;
Chong Zhang7d5f5102016-01-13 10:29:24 -08002141 if (stackId == HOME_STACK_ID
Matthew Ngae1ff4f2016-11-10 15:49:14 -08002142 || stackId == RECENTS_STACK_ID
Winson Chung83471632016-12-13 11:02:12 -08002143 || stackId == ASSISTANT_STACK_ID
Chong Zhang7d5f5102016-01-13 10:29:24 -08002144 || stackId == FULLSCREEN_WORKSPACE_STACK_ID
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002145 || (stackId == DOCKED_STACK_ID && !isResizeable())) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07002146 return isResizeable() ? mStack.mBounds : null;
Wale Ogunwale3382ab12017-07-27 08:55:03 -07002147 } else if (!getWindowConfiguration().persistTaskBounds()) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07002148 return mStack.mBounds;
Wale Ogunwale706ed792015-08-02 10:29:44 -07002149 }
2150 return mLastNonFullscreenBounds;
2151 }
2152
Jorim Jaggi8b702ed2017-01-20 16:59:03 +01002153 void addStartingWindowsForVisibleActivities(boolean taskSwitch) {
2154 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
2155 final ActivityRecord r = mActivities.get(activityNdx);
2156 if (r.visible) {
2157 r.showStartingWindow(null /* prev */, false /* newTask */, taskSwitch);
2158 }
2159 }
2160 }
2161
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002162 void dump(PrintWriter pw, String prefix) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002163 pw.print(prefix); pw.print("userId="); pw.print(userId);
Dianne Hackborn885fbe52014-08-23 15:23:58 -07002164 pw.print(" effectiveUid="); UserHandle.formatUid(pw, effectiveUid);
2165 pw.print(" mCallingUid="); UserHandle.formatUid(pw, mCallingUid);
Suprabh Shukla7745c142016-03-07 18:21:10 -08002166 pw.print(" mUserSetupComplete="); pw.print(mUserSetupComplete);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002167 pw.print(" mCallingPackage="); pw.println(mCallingPackage);
Dianne Hackborn79228822014-09-16 11:11:23 -07002168 if (affinity != null || rootAffinity != null) {
2169 pw.print(prefix); pw.print("affinity="); pw.print(affinity);
2170 if (affinity == null || !affinity.equals(rootAffinity)) {
2171 pw.print(" root="); pw.println(rootAffinity);
2172 } else {
2173 pw.println();
2174 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002175 }
Dianne Hackborn91097de2014-04-04 18:02:06 -07002176 if (voiceSession != null || voiceInteractor != null) {
2177 pw.print(prefix); pw.print("VOICE: session=0x");
2178 pw.print(Integer.toHexString(System.identityHashCode(voiceSession)));
2179 pw.print(" interactor=0x");
2180 pw.println(Integer.toHexString(System.identityHashCode(voiceInteractor)));
2181 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002182 if (intent != null) {
2183 StringBuilder sb = new StringBuilder(128);
2184 sb.append(prefix); sb.append("intent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08002185 intent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002186 sb.append('}');
2187 pw.println(sb.toString());
2188 }
2189 if (affinityIntent != null) {
2190 StringBuilder sb = new StringBuilder(128);
2191 sb.append(prefix); sb.append("affinityIntent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08002192 affinityIntent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002193 sb.append('}');
2194 pw.println(sb.toString());
2195 }
2196 if (origActivity != null) {
2197 pw.print(prefix); pw.print("origActivity=");
2198 pw.println(origActivity.flattenToShortString());
2199 }
2200 if (realActivity != null) {
2201 pw.print(prefix); pw.print("realActivity=");
2202 pw.println(realActivity.flattenToShortString());
2203 }
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07002204 if (autoRemoveRecents || isPersistable || !isActivityTypeStandard()
2205 || mTaskToReturnTo != ACTIVITY_TYPE_STANDARD || numFullscreen != 0) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002206 pw.print(prefix); pw.print("autoRemoveRecents="); pw.print(autoRemoveRecents);
Dianne Hackborn852975d2014-08-22 17:42:43 -07002207 pw.print(" isPersistable="); pw.print(isPersistable);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002208 pw.print(" numFullscreen="); pw.print(numFullscreen);
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07002209 pw.print(" activityType="); pw.print(getActivityType());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002210 pw.print(" mTaskToReturnTo="); pw.println(mTaskToReturnTo);
2211 }
Craig Mautner432f64e2015-05-20 14:59:57 -07002212 if (rootWasReset || mNeverRelinquishIdentity || mReuseTask
2213 || mLockTaskAuth != LOCK_TASK_AUTH_PINNABLE) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002214 pw.print(prefix); pw.print("rootWasReset="); pw.print(rootWasReset);
2215 pw.print(" mNeverRelinquishIdentity="); pw.print(mNeverRelinquishIdentity);
Craig Mautner432f64e2015-05-20 14:59:57 -07002216 pw.print(" mReuseTask="); pw.print(mReuseTask);
2217 pw.print(" mLockTaskAuth="); pw.println(lockTaskAuthToString());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002218 }
Wale Ogunwale18795a22014-12-03 11:38:33 -08002219 if (mAffiliatedTaskId != taskId || mPrevAffiliateTaskId != INVALID_TASK_ID
2220 || mPrevAffiliate != null || mNextAffiliateTaskId != INVALID_TASK_ID
2221 || mNextAffiliate != null) {
Dianne Hackborn852975d2014-08-22 17:42:43 -07002222 pw.print(prefix); pw.print("affiliation="); pw.print(mAffiliatedTaskId);
2223 pw.print(" prevAffiliation="); pw.print(mPrevAffiliateTaskId);
2224 pw.print(" (");
2225 if (mPrevAffiliate == null) {
2226 pw.print("null");
2227 } else {
2228 pw.print(Integer.toHexString(System.identityHashCode(mPrevAffiliate)));
2229 }
2230 pw.print(") nextAffiliation="); pw.print(mNextAffiliateTaskId);
2231 pw.print(" (");
2232 if (mNextAffiliate == null) {
2233 pw.print("null");
2234 } else {
2235 pw.print(Integer.toHexString(System.identityHashCode(mNextAffiliate)));
2236 }
2237 pw.println(")");
2238 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002239 pw.print(prefix); pw.print("Activities="); pw.println(mActivities);
Dianne Hackborn852975d2014-08-22 17:42:43 -07002240 if (!askedCompatMode || !inRecents || !isAvailable) {
2241 pw.print(prefix); pw.print("askedCompatMode="); pw.print(askedCompatMode);
2242 pw.print(" inRecents="); pw.print(inRecents);
2243 pw.print(" isAvailable="); pw.println(isAvailable);
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002244 }
Dianne Hackborn852975d2014-08-22 17:42:43 -07002245 if (lastDescription != null) {
2246 pw.print(prefix); pw.print("lastDescription="); pw.println(lastDescription);
2247 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07002248 pw.print(prefix); pw.print("stackId="); pw.println(getStackId());
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002249 pw.print(prefix + "hasBeenVisible=" + hasBeenVisible);
2250 pw.print(" mResizeMode=" + ActivityInfo.resizeModeToString(mResizeMode));
Winson Chungd3395382016-12-13 11:49:09 -08002251 pw.print(" mSupportsPictureInPicture=" + mSupportsPictureInPicture);
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002252 pw.print(" isResizeable=" + isResizeable());
daqi961e50e2017-05-30 15:37:23 +08002253 pw.print(" firstActiveTime=" + firstActiveTime);
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002254 pw.print(" lastActiveTime=" + lastActiveTime);
2255 pw.println(" (inactive for " + (getInactiveDuration() / 1000) + "s)");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002256 }
2257
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002258 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002259 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002260 StringBuilder sb = new StringBuilder(128);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002261 if (stringName != null) {
2262 sb.append(stringName);
2263 sb.append(" U=");
2264 sb.append(userId);
Wale Ogunwale6c5eb1c2015-11-10 07:52:22 -08002265 sb.append(" StackId=");
Andrii Kulian02b7a832016-10-06 23:11:56 -07002266 sb.append(getStackId());
Craig Mautnerde4ef022013-04-07 19:01:33 -07002267 sb.append(" sz=");
2268 sb.append(mActivities.size());
2269 sb.append('}');
2270 return sb.toString();
2271 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002272 sb.append("TaskRecord{");
2273 sb.append(Integer.toHexString(System.identityHashCode(this)));
2274 sb.append(" #");
2275 sb.append(taskId);
2276 if (affinity != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002277 sb.append(" A=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002278 sb.append(affinity);
2279 } else if (intent != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002280 sb.append(" I=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002281 sb.append(intent.getComponent().flattenToShortString());
2282 } else if (affinityIntent != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002283 sb.append(" aI=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002284 sb.append(affinityIntent.getComponent().flattenToShortString());
2285 } else {
2286 sb.append(" ??");
2287 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07002288 stringName = sb.toString();
2289 return toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002290 }
2291}