blob: bef325ca038c5cf0f97868750356a98e1111bf95 [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;
Jorim Jaggi0a932142016-02-01 17:42:25 -080021import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -070022import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
23import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
24import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
25import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
26import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070027import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
28import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
29import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
30import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Wale Ogunwale44f036f2017-09-29 05:09:09 -070031import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Jorim Jaggi0a932142016-02-01 17:42:25 -080032import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
Wale Ogunwale66e16852017-10-19 13:35:52 -070033import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
Jorim Jaggi0a932142016-02-01 17:42:25 -080034import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
Wale Ogunwale66e16852017-10-19 13:35:52 -070035import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
Wale Ogunwale3eadad72016-10-13 09:16:59 -070036import static android.content.pm.ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY;
Jorim Jaggi0a932142016-02-01 17:42:25 -080037import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
38import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
39import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
40import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER;
skuhne@google.com322347b2016-12-02 12:54:03 -080041import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY;
42import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PORTRAIT_ONLY;
43import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PRESERVE_ORIENTATION;
Wale Ogunwaled829d362016-02-10 19:24:49 -080044import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
Wale Ogunwale625ed0c2016-10-18 08:50:31 -070045import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
Winson Chungd3395382016-12-13 11:49:09 -080046import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_AND_PIPABLE_DEPRECATED;
Wale Ogunwale625ed0c2016-10-18 08:50:31 -070047import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -080048import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
Suprabh Shukla7745c142016-03-07 18:21:10 -080049import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
Andrii Kulian036e3ad2017-04-19 10:55:10 -070050import static android.view.Display.DEFAULT_DISPLAY;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -070051
Jorim Jaggi0a932142016-02-01 17:42:25 -080052import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ADD_REMOVE;
53import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
54import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
55import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
56import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_ADD_REMOVE;
57import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
58import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
59import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS;
60import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
61import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
Wale Ogunwale3b232392016-05-13 15:37:13 -070062import static com.android.server.am.ActivityRecord.STARTING_WINDOW_SHOWN;
Wale Ogunwalec5cc3012017-01-13 13:26:16 -080063import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING;
Wale Ogunwale56d8d162017-05-30 11:12:20 -070064import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING_TO_TOP;
Wale Ogunwaleab5de372017-10-18 06:46:31 -070065import static com.android.server.am.ActivityStackSupervisor.ON_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;
Steven Timotius4346f0a2017-09-12 11:07:21 -070068import static com.android.server.am.proto.TaskRecordProto.ACTIVITIES;
69import static com.android.server.am.proto.TaskRecordProto.BOUNDS;
70import static com.android.server.am.proto.TaskRecordProto.CONFIGURATION_CONTAINER;
71import static com.android.server.am.proto.TaskRecordProto.FULLSCREEN;
72import static com.android.server.am.proto.TaskRecordProto.ID;
73import static com.android.server.am.proto.TaskRecordProto.LAST_NON_FULLSCREEN_BOUNDS;
74import static com.android.server.am.proto.TaskRecordProto.MIN_HEIGHT;
75import static com.android.server.am.proto.TaskRecordProto.MIN_WIDTH;
76import static com.android.server.am.proto.TaskRecordProto.ORIG_ACTIVITY;
77import static com.android.server.am.proto.TaskRecordProto.REAL_ACTIVITY;
78import static com.android.server.am.proto.TaskRecordProto.RESIZE_MODE;
Steven Timotius4346f0a2017-09-12 11:07:21 -070079import static com.android.server.am.proto.TaskRecordProto.STACK_ID;
80import static com.android.server.am.proto.TaskRecordProto.ACTIVITY_TYPE;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -070081
Winson Chung74666102017-02-22 17:49:24 -080082import static java.lang.Integer.MAX_VALUE;
83
Jorim Jaggie7d2b852017-08-28 17:55:15 +020084import android.annotation.IntDef;
85import android.annotation.Nullable;
86import android.app.Activity;
87import android.app.ActivityManager;
Jorim Jaggie7d2b852017-08-28 17:55:15 +020088import android.app.ActivityManager.TaskDescription;
89import android.app.ActivityManager.TaskSnapshot;
90import android.app.ActivityOptions;
91import android.app.AppGlobals;
92import android.app.IActivityManager;
93import android.content.ComponentName;
94import android.content.Intent;
95import android.content.pm.ActivityInfo;
96import android.content.pm.ApplicationInfo;
97import android.content.pm.IPackageManager;
98import android.content.pm.PackageManager;
99import android.content.res.Configuration;
100import android.graphics.Rect;
101import android.os.Debug;
102import android.os.RemoteException;
Winson Chungfb44d212017-10-04 11:39:10 -0700103import android.os.SystemClock;
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200104import android.os.Trace;
105import android.os.UserHandle;
106import android.provider.Settings;
107import android.service.voice.IVoiceInteractionSession;
108import android.util.DisplayMetrics;
109import android.util.Slog;
Steven Timotius4346f0a2017-09-12 11:07:21 -0700110import android.util.proto.ProtoOutputStream;
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200111
112import com.android.internal.annotations.VisibleForTesting;
113import com.android.internal.app.IVoiceInteractor;
114import com.android.internal.util.XmlUtils;
Winson Chung61c9e5a2017-10-11 10:39:32 -0700115import com.android.server.am.ActivityStack.ActivityState;
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200116import com.android.server.wm.AppWindowContainerController;
117import com.android.server.wm.ConfigurationContainer;
118import com.android.server.wm.StackWindowController;
119import com.android.server.wm.TaskWindowContainerController;
120import com.android.server.wm.TaskWindowContainerListener;
121import com.android.server.wm.WindowManagerService;
122
123import org.xmlpull.v1.XmlPullParser;
124import org.xmlpull.v1.XmlPullParserException;
125import org.xmlpull.v1.XmlSerializer;
126
127import java.io.IOException;
128import java.io.PrintWriter;
129import java.lang.annotation.Retention;
130import java.lang.annotation.RetentionPolicy;
131import java.util.ArrayList;
132import java.util.Objects;
133
Benjamin Franza83859f2017-07-03 16:34:14 +0100134class TaskRecord extends ConfigurationContainer implements TaskWindowContainerListener {
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800135 private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskRecord" : TAG_AM;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -0700136 private static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700137 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
Craig Mautnere0570202015-05-13 13:06:11 -0700138 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700139 private static final String TAG_TASKS = TAG + POSTFIX_TASKS;
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800140
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700141 private static final String ATTR_TASKID = "task_id";
Craig Mautner21d24a22014-04-23 11:45:37 -0700142 private static final String TAG_INTENT = "intent";
143 private static final String TAG_AFFINITYINTENT = "affinity_intent";
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700144 private static final String ATTR_REALACTIVITY = "real_activity";
145 private static final String ATTR_REALACTIVITY_SUSPENDED = "real_activity_suspended";
Craig Mautner21d24a22014-04-23 11:45:37 -0700146 private static final String ATTR_ORIGACTIVITY = "orig_activity";
Stefan Kuhnee88d1e52015-05-18 10:33:45 -0700147 private static final String TAG_ACTIVITY = "activity";
Craig Mautner21d24a22014-04-23 11:45:37 -0700148 private static final String ATTR_AFFINITY = "affinity";
Dianne Hackborn79228822014-09-16 11:11:23 -0700149 private static final String ATTR_ROOT_AFFINITY = "root_affinity";
Craig Mautner21d24a22014-04-23 11:45:37 -0700150 private static final String ATTR_ROOTHASRESET = "root_has_reset";
Dianne Hackborn13420f22014-07-18 15:43:56 -0700151 private static final String ATTR_AUTOREMOVERECENTS = "auto_remove_recents";
Craig Mautner21d24a22014-04-23 11:45:37 -0700152 private static final String ATTR_ASKEDCOMPATMODE = "asked_compat_mode";
153 private static final String ATTR_USERID = "user_id";
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800154 private static final String ATTR_USER_SETUP_COMPLETE = "user_setup_complete";
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700155 private static final String ATTR_EFFECTIVE_UID = "effective_uid";
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700156 @Deprecated
Craig Mautner21d24a22014-04-23 11:45:37 -0700157 private static final String ATTR_TASKTYPE = "task_type";
Craig Mautner21d24a22014-04-23 11:45:37 -0700158 private static final String ATTR_LASTDESCRIPTION = "last_description";
159 private static final String ATTR_LASTTIMEMOVED = "last_time_moved";
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700160 private static final String ATTR_NEVERRELINQUISH = "never_relinquish_identity";
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700161 private static final String ATTR_TASK_AFFILIATION = "task_affiliation";
Craig Mautnera228ae92014-07-09 05:44:55 -0700162 private static final String ATTR_PREV_AFFILIATION = "prev_affiliation";
163 private static final String ATTR_NEXT_AFFILIATION = "next_affiliation";
Winson Chungec396d62014-08-06 17:08:00 -0700164 private static final String ATTR_TASK_AFFILIATION_COLOR = "task_affiliation_color";
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700165 private static final String ATTR_CALLING_UID = "calling_uid";
166 private static final String ATTR_CALLING_PACKAGE = "calling_package";
Winson Chungd3395382016-12-13 11:49:09 -0800167 private static final String ATTR_SUPPORTS_PICTURE_IN_PICTURE = "supports_picture_in_picture";
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800168 private static final String ATTR_RESIZE_MODE = "resize_mode";
Wale Ogunwale706ed792015-08-02 10:29:44 -0700169 private static final String ATTR_NON_FULLSCREEN_BOUNDS = "non_fullscreen_bounds";
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700170 private static final String ATTR_MIN_WIDTH = "min_width";
171 private static final String ATTR_MIN_HEIGHT = "min_height";
Wale Ogunwale625ed0c2016-10-18 08:50:31 -0700172 private static final String ATTR_PERSIST_TASK_VERSION = "persist_task_version";
Andrii Kulian18d75122016-03-27 20:20:28 -0700173
Wale Ogunwale625ed0c2016-10-18 08:50:31 -0700174 // Current version of the task record we persist. Used to check if we need to run any upgrade
175 // code.
176 private static final int PERSIST_TASK_VERSION = 1;
Craig Mautner21d24a22014-04-23 11:45:37 -0700177
Wale Ogunwale18795a22014-12-03 11:38:33 -0800178 static final int INVALID_TASK_ID = -1;
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700179 private static final int INVALID_MIN_SIZE = -1;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800180
Winson Chung74666102017-02-22 17:49:24 -0800181 /**
182 * The modes to control how the stack is moved to the front when calling
183 * {@link TaskRecord#reparent}.
184 */
185 @Retention(RetentionPolicy.SOURCE)
186 @IntDef({
187 REPARENT_MOVE_STACK_TO_FRONT,
188 REPARENT_KEEP_STACK_AT_FRONT,
189 REPARENT_LEAVE_STACK_IN_PLACE
190 })
Wale Ogunwale66e16852017-10-19 13:35:52 -0700191 @interface ReparentMoveStackMode {}
Winson Chung74666102017-02-22 17:49:24 -0800192 // Moves the stack to the front if it was not at the front
Wale Ogunwale66e16852017-10-19 13:35:52 -0700193 static final int REPARENT_MOVE_STACK_TO_FRONT = 0;
Winson Chung74666102017-02-22 17:49:24 -0800194 // Only moves the stack to the front if it was focused or front most already
Wale Ogunwale66e16852017-10-19 13:35:52 -0700195 static final int REPARENT_KEEP_STACK_AT_FRONT = 1;
Winson Chung74666102017-02-22 17:49:24 -0800196 // Do not move the stack as a part of reparenting
Wale Ogunwale66e16852017-10-19 13:35:52 -0700197 static final int REPARENT_LEAVE_STACK_IN_PLACE = 2;
Winson Chung74666102017-02-22 17:49:24 -0800198
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800199 final int taskId; // Unique identifier for this task.
Dianne Hackborn79228822014-09-16 11:11:23 -0700200 String affinity; // The affinity name for this task, or null; may change identity.
201 String rootAffinity; // Initial base affinity, or null; does not change from initial root.
Dianne Hackborn91097de2014-04-04 18:02:06 -0700202 final IVoiceInteractionSession voiceSession; // Voice interaction session driving task
203 final IVoiceInteractor voiceInteractor; // Associated interactor to provide to app
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800204 Intent intent; // The original intent that started the task.
205 Intent affinityIntent; // Intent of affinity-moved activity that started this task.
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700206 int effectiveUid; // The current effective uid of the identity of this task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207 ComponentName origActivity; // The non-alias activity component of the intent.
208 ComponentName realActivity; // The actual activity component that started the task.
Andrei Stingaceanu4ccec532016-01-13 12:10:21 +0000209 boolean realActivitySuspended; // True if the actual activity component that started the
210 // task is suspended.
Dianne Hackborn852975d2014-08-22 17:42:43 -0700211 boolean inRecents; // Actually in the recents list?
Winson Chungfb44d212017-10-04 11:39:10 -0700212 long lastActiveTime; // Last time this task was active in the current device session,
213 // including sleep. This time is initialized to the elapsed time when
214 // restored from disk.
Dianne Hackborn852975d2014-08-22 17:42:43 -0700215 boolean isAvailable; // Is the activity available to be launched?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800216 boolean rootWasReset; // True if the intent at the root of the task had
217 // the FLAG_ACTIVITY_RESET_TASK_IF_NEEDED flag.
Dianne Hackborn13420f22014-07-18 15:43:56 -0700218 boolean autoRemoveRecents; // If true, we should automatically remove the task from
219 // recents when activity finishes
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700220 boolean askedCompatMode;// Have asked the user about compat mode for this task.
Dianne Hackbornd38aed82014-06-10 21:36:35 -0700221 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 -0800222
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700223 String stringName; // caching of toString() result.
Dianne Hackborn9da2d402012-03-15 13:43:08 -0700224 int userId; // user for which this task was created
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800225 boolean mUserSetupComplete; // The user set-up is complete as of the last time the task activity
226 // was changed.
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800227
228 int numFullscreen; // Number of fullscreen activities.
229
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800230 int mResizeMode; // The resize mode of this task and its activities.
231 // Based on the {@link ActivityInfo#resizeMode} of the root activity.
Wale Ogunwale069bbd32017-02-03 07:58:14 -0800232 private boolean mSupportsPictureInPicture; // Whether or not this task and its activities
233 // support PiP. Based on the {@link ActivityInfo#FLAG_SUPPORTS_PICTURE_IN_PICTURE} flag
234 // of the root activity.
Craig Mautner15df08a2015-04-01 12:17:18 -0700235 /** Can't be put in lockTask mode. */
236 final static int LOCK_TASK_AUTH_DONT_LOCK = 0;
Benjamin Franz469dd582015-06-09 14:24:36 +0100237 /** Can enter app pinning with user approval. Can never start over existing lockTask task. */
Craig Mautner15df08a2015-04-01 12:17:18 -0700238 final static int LOCK_TASK_AUTH_PINNABLE = 1;
239 /** Starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing lockTask task. */
240 final static int LOCK_TASK_AUTH_LAUNCHABLE = 2;
Benjamin Franz469dd582015-06-09 14:24:36 +0100241 /** Can enter lockTask without user approval. Can start over existing lockTask task. */
Craig Mautner15df08a2015-04-01 12:17:18 -0700242 final static int LOCK_TASK_AUTH_WHITELISTED = 3;
Benjamin Franz469dd582015-06-09 14:24:36 +0100243 /** Priv-app that starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing
244 * lockTask task. */
245 final static int LOCK_TASK_AUTH_LAUNCHABLE_PRIV = 4;
Craig Mautner15df08a2015-04-01 12:17:18 -0700246 int mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE;
247
248 int mLockTaskUid = -1; // The uid of the application that called startLockTask().
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800249
Winson Chung03a9bae2014-05-02 09:56:12 -0700250 // This represents the last resolved activity values for this task
251 // NOTE: This value needs to be persisted with each task
Craig Mautner648f69b2014-09-18 14:16:26 -0700252 TaskDescription lastTaskDescription = new TaskDescription();
Winson Chung03a9bae2014-05-02 09:56:12 -0700253
Craig Mautnerd2328952013-03-05 12:46:26 -0800254 /** List of all activities in the task arranged in history order */
Craig Mautner21d24a22014-04-23 11:45:37 -0700255 final ArrayList<ActivityRecord> mActivities;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800256
Andrii Kulian02b7a832016-10-06 23:11:56 -0700257 /** Current stack. Setter must always be used to update the value. */
258 private ActivityStack mStack;
Craig Mautnerd2328952013-03-05 12:46:26 -0800259
Craig Mautner21d24a22014-04-23 11:45:37 -0700260 /** Takes on same value as first root activity */
261 boolean isPersistable = false;
Craig Mautnerffcfcaa2014-06-05 09:54:38 -0700262 int maxRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700263
264 /** Only used for persistable tasks, otherwise 0. The last time this task was moved. Used for
265 * determining the order when restoring. Sign indicates whether last task movement was to front
266 * (positive) or back (negative). Absolute value indicates time. */
267 long mLastTimeMoved = System.currentTimeMillis();
268
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700269 /** If original intent did not allow relinquishing task identity, save that information */
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700270 private boolean mNeverRelinquishIdentity = true;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700271
Craig Mautner362449a2014-06-20 14:04:39 -0700272 // Used in the unique case where we are clearing the task in order to reuse it. In that case we
273 // do not want to delete the stack when the task goes empty.
Filip Gruszczynskibe9dabd2016-01-19 12:23:10 -0800274 private boolean mReuseTask = false;
Craig Mautner362449a2014-06-20 14:04:39 -0700275
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700276 CharSequence lastDescription; // Last description captured for this item.
277
Craig Mautnera228ae92014-07-09 05:44:55 -0700278 int mAffiliatedTaskId; // taskId of parent affiliation or self if no parent.
Winson Chungec396d62014-08-06 17:08:00 -0700279 int mAffiliatedTaskColor; // color of the parent task affiliation.
Craig Mautnera228ae92014-07-09 05:44:55 -0700280 TaskRecord mPrevAffiliate; // previous task in affiliated chain.
Wale Ogunwale18795a22014-12-03 11:38:33 -0800281 int mPrevAffiliateTaskId = INVALID_TASK_ID; // previous id for persistence.
Craig Mautnera228ae92014-07-09 05:44:55 -0700282 TaskRecord mNextAffiliate; // next task in affiliated chain.
Wale Ogunwale18795a22014-12-03 11:38:33 -0800283 int mNextAffiliateTaskId = INVALID_TASK_ID; // next id for persistence.
Craig Mautnera228ae92014-07-09 05:44:55 -0700284
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700285 // For relaunching the task from recents as though it was launched by the original launcher.
286 int mCallingUid;
287 String mCallingPackage;
288
Craig Mautner21d24a22014-04-23 11:45:37 -0700289 final ActivityManagerService mService;
290
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700291 // Whether or not this task covers the entire screen; by default tasks are fullscreen.
292 boolean mFullscreen = true;
293
294 // Bounds of the Task. null for fullscreen tasks.
295 Rect mBounds = null;
Jorim Jaggi82c9dc92016-02-05 15:10:33 -0800296 private final Rect mTmpStableBounds = new Rect();
297 private final Rect mTmpNonDecorBounds = new Rect();
Wale Ogunwale9a08f822016-02-17 19:03:58 -0800298 private final Rect mTmpRect = new Rect();
Jorim Jaggi0a932142016-02-01 17:42:25 -0800299
Wale Ogunwale706ed792015-08-02 10:29:44 -0700300 // Last non-fullscreen bounds the task was launched in or resized to.
301 // The information is persisted and used to determine the appropriate stack to launch the
302 // task into on restore.
303 Rect mLastNonFullscreenBounds = null;
Andrii Kulian2e751b82016-03-16 16:59:32 -0700304 // Minimal width and height of this task when it's resizeable. -1 means it should use the
305 // default minimal width/height.
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700306 int mMinWidth;
307 int mMinHeight;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700308
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700309 // Ranking (from top) of this task among all visible tasks. (-1 means it's not visible)
310 // This number will be assigned when we evaluate OOM scores for all visible tasks.
311 int mLayerRank = -1;
312
Andrii Kulian1779e612016-10-12 21:58:25 -0700313 /** Helper object used for updating override configuration. */
314 private Configuration mTmpConfig = new Configuration();
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700315
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800316 private TaskWindowContainerController mWindowContainerController;
317
Craig Mautner21d24a22014-04-23 11:45:37 -0700318 TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700319 IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700320 mService = service;
Suprabh Shukla23593142015-11-03 17:31:15 -0800321 userId = UserHandle.getUserId(info.applicationInfo.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800322 taskId = _taskId;
Winson Chungfb44d212017-10-04 11:39:10 -0700323 lastActiveTime = SystemClock.elapsedRealtime();
Craig Mautnera228ae92014-07-09 05:44:55 -0700324 mAffiliatedTaskId = _taskId;
Dianne Hackborn91097de2014-04-04 18:02:06 -0700325 voiceSession = _voiceSession;
326 voiceInteractor = _voiceInteractor;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700327 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800328 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700329 mCallingUid = info.applicationInfo.uid;
330 mCallingPackage = info.packageName;
Martijn Coenend4a69702014-06-30 11:12:17 -0700331 setIntent(_intent, info);
Andrii Kulian2e751b82016-03-16 16:59:32 -0700332 setMinDimensions(info);
Winson730bf062016-03-31 18:04:56 -0700333 touchActiveTime();
Yorke Leebd54c2a2016-10-25 13:49:23 -0700334 mService.mTaskChangeNotificationController.notifyTaskCreated(_taskId, realActivity);
Craig Mautner21d24a22014-04-23 11:45:37 -0700335 }
336
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700337 TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200338 TaskDescription _taskDescription) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700339 mService = service;
Suprabh Shukla23593142015-11-03 17:31:15 -0800340 userId = UserHandle.getUserId(info.applicationInfo.uid);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700341 taskId = _taskId;
Winson Chungfb44d212017-10-04 11:39:10 -0700342 lastActiveTime = SystemClock.elapsedRealtime();
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700343 mAffiliatedTaskId = _taskId;
344 voiceSession = null;
345 voiceInteractor = null;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700346 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800347 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700348 mCallingUid = info.applicationInfo.uid;
349 mCallingPackage = info.packageName;
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700350 setIntent(_intent, info);
Andrii Kulian2e751b82016-03-16 16:59:32 -0700351 setMinDimensions(info);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700352
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700353 isPersistable = true;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700354 // Clamp to [1, max].
355 maxRecents = Math.min(Math.max(info.maxRecents, 1),
356 ActivityManager.getMaxAppRecentsLimitStatic());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700357
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700358 lastTaskDescription = _taskDescription;
Winson730bf062016-03-31 18:04:56 -0700359 touchActiveTime();
Yorke Leebd54c2a2016-10-25 13:49:23 -0700360 mService.mTaskChangeNotificationController.notifyTaskCreated(_taskId, realActivity);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700361 }
362
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800363 private TaskRecord(ActivityManagerService service, int _taskId, Intent _intent,
364 Intent _affinityIntent, String _affinity, String _rootAffinity,
365 ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700366 boolean _autoRemoveRecents, boolean _askedCompatMode, int _userId,
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800367 int _effectiveUid, String _lastDescription, ArrayList<ActivityRecord> activities,
Winson Chungfb44d212017-10-04 11:39:10 -0700368 long lastTimeMoved, boolean neverRelinquishIdentity,
369 TaskDescription _lastTaskDescription, int taskAffiliation, int prevTaskId,
370 int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage,
Charles He2bf28322017-10-12 22:24:49 +0100371 int resizeMode, boolean supportsPictureInPicture, boolean _realActivitySuspended,
372 boolean userSetupComplete, int minWidth, int minHeight) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700373 mService = service;
374 taskId = _taskId;
375 intent = _intent;
376 affinityIntent = _affinityIntent;
377 affinity = _affinity;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800378 rootAffinity = _rootAffinity;
Craig Mautner21d24a22014-04-23 11:45:37 -0700379 voiceSession = null;
380 voiceInteractor = null;
381 realActivity = _realActivity;
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800382 realActivitySuspended = _realActivitySuspended;
Craig Mautner21d24a22014-04-23 11:45:37 -0700383 origActivity = _origActivity;
384 rootWasReset = _rootWasReset;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700385 isAvailable = true;
Dianne Hackborn13420f22014-07-18 15:43:56 -0700386 autoRemoveRecents = _autoRemoveRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700387 askedCompatMode = _askedCompatMode;
Craig Mautner21d24a22014-04-23 11:45:37 -0700388 userId = _userId;
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800389 mUserSetupComplete = userSetupComplete;
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700390 effectiveUid = _effectiveUid;
Winson Chungfb44d212017-10-04 11:39:10 -0700391 lastActiveTime = SystemClock.elapsedRealtime();
Craig Mautner21d24a22014-04-23 11:45:37 -0700392 lastDescription = _lastDescription;
393 mActivities = activities;
394 mLastTimeMoved = lastTimeMoved;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700395 mNeverRelinquishIdentity = neverRelinquishIdentity;
Winson Chung2cb86c72014-06-25 12:03:30 -0700396 lastTaskDescription = _lastTaskDescription;
Craig Mautnera228ae92014-07-09 05:44:55 -0700397 mAffiliatedTaskId = taskAffiliation;
Winson Chungec396d62014-08-06 17:08:00 -0700398 mAffiliatedTaskColor = taskAffiliationColor;
Craig Mautnera228ae92014-07-09 05:44:55 -0700399 mPrevAffiliateTaskId = prevTaskId;
400 mNextAffiliateTaskId = nextTaskId;
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700401 mCallingUid = callingUid;
402 mCallingPackage = callingPackage;
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800403 mResizeMode = resizeMode;
Winson Chungd3395382016-12-13 11:49:09 -0800404 mSupportsPictureInPicture = supportsPictureInPicture;
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700405 mMinWidth = minWidth;
406 mMinHeight = minHeight;
Yorke Leebd54c2a2016-10-25 13:49:23 -0700407 mService.mTaskChangeNotificationController.notifyTaskCreated(_taskId, realActivity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800408 }
409
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800410 TaskWindowContainerController getWindowContainerController() {
411 return mWindowContainerController;
412 }
413
414 void createWindowContainer(boolean onTop, boolean showForAllUsers) {
415 if (mWindowContainerController != null) {
416 throw new IllegalArgumentException("Window container=" + mWindowContainerController
417 + " already created for task=" + this);
418 }
419
420 final Rect bounds = updateOverrideConfigurationFromLaunchBounds();
Bryce Lee04ab3462017-04-10 15:06:33 -0700421 setWindowContainerController(new TaskWindowContainerController(taskId, this,
Wale Ogunwale034a8ec2017-09-02 17:14:40 -0700422 getStack().getWindowContainerController(), userId, bounds,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700423 mResizeMode, mSupportsPictureInPicture, onTop,
424 showForAllUsers, lastTaskDescription));
Bryce Lee04ab3462017-04-10 15:06:33 -0700425 }
426
427 /**
428 * Should only be invoked from {@link #createWindowContainer(boolean, boolean)}.
429 */
430 @VisibleForTesting
431 protected void setWindowContainerController(TaskWindowContainerController controller) {
432 if (mWindowContainerController != null) {
433 throw new IllegalArgumentException("Window container=" + mWindowContainerController
434 + " already created for task=" + this);
435 }
436
437 mWindowContainerController = controller;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800438 }
439
440 void removeWindowContainer() {
Benjamin Franza83859f2017-07-03 16:34:14 +0100441 mService.mLockTaskController.removeLockedTask(this);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800442 mWindowContainerController.removeContainer();
Wale Ogunwale3382ab12017-07-27 08:55:03 -0700443 if (!getWindowConfiguration().persistTaskBounds()) {
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800444 // Reset current bounds for task whose bounds shouldn't be persisted so it uses
445 // default configuration the next time it launches.
446 updateOverrideConfiguration(null);
447 }
448 mService.mTaskChangeNotificationController.notifyTaskRemoved(taskId);
449 mWindowContainerController = null;
450 }
451
Jorim Jaggifb9d78a2017-01-05 18:57:12 +0100452 @Override
453 public void onSnapshotChanged(TaskSnapshot snapshot) {
454 mService.mTaskChangeNotificationController.notifyTaskSnapshotChanged(taskId, snapshot);
455 }
456
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800457 void setResizeMode(int resizeMode) {
458 if (mResizeMode == resizeMode) {
459 return;
460 }
461 mResizeMode = resizeMode;
462 mWindowContainerController.setResizeable(resizeMode);
463 mService.mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
464 mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
465 }
466
467 void setTaskDockedResizing(boolean resizing) {
468 mWindowContainerController.setTaskDockedResizing(resizing);
469 }
470
Wale Ogunwale1666e312016-12-16 11:27:18 -0800471 // TODO: Consolidate this with the resize() method below.
472 @Override
473 public void requestResize(Rect bounds, int resizeMode) {
474 mService.resizeTask(taskId, bounds, resizeMode);
475 }
476
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800477 boolean resize(Rect bounds, int resizeMode, boolean preserveWindow, boolean deferResume) {
478 if (!isResizeable()) {
479 Slog.w(TAG, "resizeTask: task " + this + " not resizeable.");
480 return true;
481 }
482
483 // If this is a forced resize, let it go through even if the bounds is not changing,
484 // as we might need a relayout due to surface size change (to/from fullscreen).
485 final boolean forced = (resizeMode & RESIZE_MODE_FORCED) != 0;
486 if (Objects.equals(mBounds, bounds) && !forced) {
487 // Nothing to do here...
488 return true;
489 }
490 bounds = validateBounds(bounds);
491
492 if (mWindowContainerController == null) {
493 // Task doesn't exist in window manager yet (e.g. was restored from recents).
494 // All we can do for now is update the bounds so it can be used when the task is
495 // added to window manager.
496 updateOverrideConfiguration(bounds);
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700497 if (!inFreeformWindowingMode()) {
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800498 // re-restore the task so it can have the proper stack association.
Wale Ogunwaleab5de372017-10-18 06:46:31 -0700499 mService.mStackSupervisor.restoreRecentTaskLocked(this, null, !ON_TOP);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800500 }
501 return true;
502 }
503
504 if (!canResizeToBounds(bounds)) {
505 throw new IllegalArgumentException("resizeTask: Can not resize task=" + this
506 + " to bounds=" + bounds + " resizeMode=" + mResizeMode);
507 }
508
509 // Do not move the task to another stack here.
510 // This method assumes that the task is already placed in the right stack.
511 // we do not mess with that decision and we only do the resize!
512
513 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeTask_" + taskId);
514
515 final boolean updatedConfig = updateOverrideConfiguration(bounds);
516 // This variable holds information whether the configuration didn't change in a significant
517 // way and the activity was kept the way it was. If it's false, it means the activity had
518 // to be relaunched due to configuration change.
519 boolean kept = true;
520 if (updatedConfig) {
521 final ActivityRecord r = topRunningActivityLocked();
Wale Ogunwaleea3d3fd2017-05-01 07:41:08 -0700522 if (r != null && !deferResume) {
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800523 kept = r.ensureActivityConfigurationLocked(0 /* globalChanges */, preserveWindow);
Wale Ogunwaleea3d3fd2017-05-01 07:41:08 -0700524 mService.mStackSupervisor.ensureActivitiesVisibleLocked(r, 0, !PRESERVE_WINDOWS);
525 if (!kept) {
526 mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800527 }
528 }
529 }
530 mWindowContainerController.resize(mBounds, getOverrideConfiguration(), kept, forced);
531
532 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
533 return kept;
534 }
535
536 // TODO: Investigate combining with the resize() method above.
537 void resizeWindowContainer() {
538 mWindowContainerController.resize(mBounds, getOverrideConfiguration(), false /* relayout */,
539 false /* forced */);
540 }
541
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800542 void getWindowContainerBounds(Rect bounds) {
543 mWindowContainerController.getBounds(bounds);
544 }
545
Winson Chung74666102017-02-22 17:49:24 -0800546 /**
547 * Convenience method to reparent a task to the top or bottom position of the stack.
548 */
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700549 boolean reparent(ActivityStack preferredStack, boolean toTop,
550 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
551 String reason) {
552 return reparent(preferredStack, toTop ? MAX_VALUE : 0, moveStackMode, animate, deferResume,
553 true /* schedulePictureInPictureModeChange */, reason);
Winson Chung5af42fc2017-03-24 17:11:33 -0700554 }
555
556 /**
557 * Convenience method to reparent a task to the top or bottom position of the stack, with
558 * an option to skip scheduling the picture-in-picture mode change.
559 */
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700560 boolean reparent(ActivityStack preferredStack, boolean toTop,
561 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
562 boolean schedulePictureInPictureModeChange, String reason) {
563 return reparent(preferredStack, toTop ? MAX_VALUE : 0, moveStackMode, animate,
Winson Chung5af42fc2017-03-24 17:11:33 -0700564 deferResume, schedulePictureInPictureModeChange, reason);
565 }
566
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700567 /** Convenience method to reparent a task to a specific position of the stack. */
568 boolean reparent(ActivityStack preferredStack, int position,
569 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
570 String reason) {
571 return reparent(preferredStack, position, moveStackMode, animate, deferResume,
Winson Chung5af42fc2017-03-24 17:11:33 -0700572 true /* schedulePictureInPictureModeChange */, reason);
Winson Chung74666102017-02-22 17:49:24 -0800573 }
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800574
Winson Chung74666102017-02-22 17:49:24 -0800575 /**
576 * Reparents the task into a preferred stack, creating it if necessary.
577 *
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700578 * @param preferredStack the target stack to move this task
Winson Chung74666102017-02-22 17:49:24 -0800579 * @param position the position to place this task in the new stack
580 * @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 -0700581 * reparenting to be drawn and animated in
Winson Chung74666102017-02-22 17:49:24 -0800582 * @param moveStackMode whether or not to move the stack to the front always, only if it was
Winson Chung5af42fc2017-03-24 17:11:33 -0700583 * previously focused & in front, or never
Winson Chung74666102017-02-22 17:49:24 -0800584 * @param deferResume whether or not to update the visibility of other tasks and stacks that may
Winson Chung5af42fc2017-03-24 17:11:33 -0700585 * have changed as a result of this reparenting
586 * @param schedulePictureInPictureModeChange specifies whether or not to schedule the PiP mode
587 * change. Callers may set this to false if they are explicitly scheduling PiP mode
588 * changes themselves, like during the PiP animation
Winson Chung74666102017-02-22 17:49:24 -0800589 * @param reason the caller of this reparenting
Winson Chung5af42fc2017-03-24 17:11:33 -0700590 * @return whether the task was reparented
Winson Chung74666102017-02-22 17:49:24 -0800591 */
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700592 // TODO: Inspect all call sites and change to just changing windowing mode of the stack vs.
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700593 // re-parenting the task. Can only be done when we are no longer using static stack Ids.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700594 boolean reparent(ActivityStack preferredStack, int position,
595 @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
596 boolean schedulePictureInPictureModeChange, String reason) {
Winson Chung74666102017-02-22 17:49:24 -0800597 final ActivityStackSupervisor supervisor = mService.mStackSupervisor;
598 final WindowManagerService windowManager = mService.mWindowManager;
599 final ActivityStack sourceStack = getStack();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700600 final ActivityStack toStack = supervisor.getReparentTargetStack(this, preferredStack,
Winson Chung74666102017-02-22 17:49:24 -0800601 position == MAX_VALUE);
602 if (toStack == sourceStack) {
603 return false;
604 }
605
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700606 final int toStackWindowingMode = toStack.getWindowingMode();
Winson Chung74666102017-02-22 17:49:24 -0800607 final ActivityRecord topActivity = getTopActivity();
608
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700609 final boolean mightReplaceWindow =
610 replaceWindowsOnTaskMove(getWindowingMode(), toStackWindowingMode)
611 && topActivity != null;
Winson Chung74666102017-02-22 17:49:24 -0800612 if (mightReplaceWindow) {
613 // We are about to relaunch the activity because its configuration changed due to
614 // being maximized, i.e. size change. The activity will first remove the old window
615 // and then add a new one. This call will tell window manager about this, so it can
616 // preserve the old window until the new one is drawn. This prevents having a gap
617 // between the removal and addition, in which no window is visible. We also want the
618 // entrance of the new window to be properly animated.
619 // Note here we always set the replacing window first, as the flags might be needed
620 // during the relaunch. If we end up not doing any relaunch, we clear the flags later.
621 windowManager.setWillReplaceWindow(topActivity.appToken, animate);
622 }
623
624 windowManager.deferSurfaceLayout();
625 boolean kept = true;
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800626 try {
Winson Chung74666102017-02-22 17:49:24 -0800627 final ActivityRecord r = topRunningActivityLocked();
Winson Chung95f8f0e2017-03-24 09:20:17 -0700628 final boolean wasFocused = r != null && supervisor.isFocusedStack(sourceStack)
Winson Chung74666102017-02-22 17:49:24 -0800629 && (topRunningActivityLocked() == r);
Winson Chung95f8f0e2017-03-24 09:20:17 -0700630 final boolean wasResumed = r != null && sourceStack.mResumedActivity == r;
631 final boolean wasPaused = r != null && sourceStack.mPausingActivity == r;
Winson Chung74666102017-02-22 17:49:24 -0800632
633 // In some cases the focused stack isn't the front stack. E.g. pinned stack.
634 // Whenever we are moving the top activity from the front stack we want to make sure to
635 // move the stack to the front.
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -0700636 final boolean wasFront = r != null && sourceStack.isTopStackOnDisplay()
Winson Chung74666102017-02-22 17:49:24 -0800637 && (sourceStack.topRunningActivityLocked() == r);
638
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800639 // Adjust the position for the new parent stack as needed.
Winson Chung74666102017-02-22 17:49:24 -0800640 position = toStack.getAdjustedPositionForTask(this, position, null /* starting */);
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800641
642 // Must reparent first in window manager to avoid a situation where AM can delete the
643 // we are coming from in WM before we reparent because it became empty.
Wale Ogunwale2719cc12017-04-14 09:45:27 -0700644 mWindowContainerController.reparent(toStack.getWindowContainerController(), position,
645 moveStackMode == REPARENT_MOVE_STACK_TO_FRONT);
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800646
Wale Ogunwale56d8d162017-05-30 11:12:20 -0700647 final boolean moveStackToFront = moveStackMode == REPARENT_MOVE_STACK_TO_FRONT
648 || (moveStackMode == REPARENT_KEEP_STACK_AT_FRONT && (wasFocused || wasFront));
Winson Chung74666102017-02-22 17:49:24 -0800649 // Move the task
Wale Ogunwale56d8d162017-05-30 11:12:20 -0700650 sourceStack.removeTask(this, reason, moveStackToFront
651 ? REMOVE_TASK_MODE_MOVING_TO_TOP : REMOVE_TASK_MODE_MOVING);
Winson Chung5af42fc2017-03-24 17:11:33 -0700652 toStack.addTask(this, position, false /* schedulePictureInPictureModeChange */, reason);
Winson Chung74666102017-02-22 17:49:24 -0800653
Winson Chung5af42fc2017-03-24 17:11:33 -0700654 if (schedulePictureInPictureModeChange) {
655 // Notify of picture-in-picture mode changes
656 supervisor.scheduleUpdatePictureInPictureModeIfNeeded(this, sourceStack);
657 }
Winson Chung74666102017-02-22 17:49:24 -0800658
659 // TODO: Ensure that this is actually necessary here
660 // Notify the voice session if required
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800661 if (voiceSession != null) {
662 try {
663 voiceSession.taskStarted(intent, taskId);
664 } catch (RemoteException e) {
665 }
666 }
Winson Chung74666102017-02-22 17:49:24 -0800667
668 // If the task had focus before (or we're requested to move focus), move focus to the
669 // new stack by moving the stack to the front.
Winson Chung95f8f0e2017-03-24 09:20:17 -0700670 if (r != null) {
671 toStack.moveToFrontAndResumeStateIfNeeded(r, moveStackToFront, wasResumed,
672 wasPaused, reason);
673 }
Winson Chung74666102017-02-22 17:49:24 -0800674 if (!animate) {
675 toStack.mNoAnimActivities.add(topActivity);
676 }
677
678 // We might trigger a configuration change. Save the current task bounds for freezing.
679 // TODO: Should this call be moved inside the resize method in WM?
680 toStack.prepareFreezingTaskBounds();
681
682 // Make sure the task has the appropriate bounds/size for the stack it is in.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700683 final boolean toStackSplitScreenPrimary =
684 toStackWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700685 if ((toStackWindowingMode == WINDOWING_MODE_FULLSCREEN
686 || toStackWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY)
Winson Chung74666102017-02-22 17:49:24 -0800687 && !Objects.equals(mBounds, toStack.mBounds)) {
688 kept = resize(toStack.mBounds, RESIZE_MODE_SYSTEM, !mightReplaceWindow,
689 deferResume);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700690 } else if (toStackWindowingMode == WINDOWING_MODE_FREEFORM) {
Winson Chung74666102017-02-22 17:49:24 -0800691 Rect bounds = getLaunchBounds();
692 if (bounds == null) {
Bryce Leedacefc42017-10-10 12:56:02 -0700693 mService.mStackSupervisor.getLaunchingBoundsController().layoutTask(this, null);
Winson Chung74666102017-02-22 17:49:24 -0800694 bounds = mBounds;
695 }
696 kept = resize(bounds, RESIZE_MODE_FORCED, !mightReplaceWindow, deferResume);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700697 } else if (toStackSplitScreenPrimary || toStackWindowingMode == WINDOWING_MODE_PINNED) {
698 if (toStackSplitScreenPrimary && moveStackMode == REPARENT_KEEP_STACK_AT_FRONT) {
Matthew Ng330757d2017-02-28 14:19:17 -0800699 // Move recents to front so it is not behind home stack when going into docked
700 // mode
701 mService.mStackSupervisor.moveRecentsStackToFront(reason);
702 }
Winson Chung74666102017-02-22 17:49:24 -0800703 kept = resize(toStack.mBounds, RESIZE_MODE_SYSTEM, !mightReplaceWindow,
704 deferResume);
705 }
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800706 } finally {
Winson Chung74666102017-02-22 17:49:24 -0800707 windowManager.continueSurfaceLayout();
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800708 }
Winson Chung74666102017-02-22 17:49:24 -0800709
710 if (mightReplaceWindow) {
711 // If we didn't actual do a relaunch (indicated by kept==true meaning we kept the old
712 // window), we need to clear the replace window settings. Otherwise, we schedule a
713 // timeout to remove the old window if the replacing window is not coming in time.
714 windowManager.scheduleClearWillReplaceWindows(topActivity.appToken, !kept);
715 }
716
717 if (!deferResume) {
718 // The task might have already been running and its visibility needs to be synchronized
719 // with the visibility of the stack / windows.
720 supervisor.ensureActivitiesVisibleLocked(null, 0, !mightReplaceWindow);
721 supervisor.resumeFocusedStackTopActivityLocked();
722 }
723
Andrii Kulian036e3ad2017-04-19 10:55:10 -0700724 // TODO: Handle incorrect request to move before the actual move, not after.
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -0700725 final boolean inSplitScreenMode = supervisor.getDefaultDisplay().hasSplitScreenPrimaryStack();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700726 supervisor.handleNonResizableTaskIfNeeded(this, preferredStack.getWindowingMode(),
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -0700727 DEFAULT_DISPLAY, toStack);
Winson Chung74666102017-02-22 17:49:24 -0800728
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700729 boolean successful = (preferredStack == toStack);
730 if (successful && toStack.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
Matthew Ng330757d2017-02-28 14:19:17 -0800731 // If task moved to docked stack - show recents if needed.
732 mService.mWindowManager.showRecentApps(false /* fromHome */);
733 }
734 return successful;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800735 }
736
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700737 /**
738 * Returns true if the windows of tasks being moved to the target stack from the source
739 * stack should be replaced, meaning that window manager will keep the old window around
740 * until the new is ready.
741 * @hide
742 */
743 private static boolean replaceWindowsOnTaskMove(
744 int sourceWindowingMode, int targetWindowingMode) {
745 return sourceWindowingMode == WINDOWING_MODE_FREEFORM
746 || targetWindowingMode == WINDOWING_MODE_FREEFORM;
747 }
748
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800749 void cancelWindowTransition() {
750 mWindowContainerController.cancelWindowTransition();
751 }
752
753 void cancelThumbnailTransition() {
754 mWindowContainerController.cancelThumbnailTransition();
755 }
756
Jorim Jaggi7361bab2017-01-16 17:17:58 +0100757 /**
758 * DO NOT HOLD THE ACTIVITY MANAGER LOCK WHEN CALLING THIS METHOD!
759 */
Jorim Jaggi35e3f532017-03-17 17:06:50 +0100760 TaskSnapshot getSnapshot(boolean reducedResolution) {
Jorim Jaggi7361bab2017-01-16 17:17:58 +0100761
762 // TODO: Move this to {@link TaskWindowContainerController} once recent tasks are more
763 // synchronized between AM and WM.
Jorim Jaggi35e3f532017-03-17 17:06:50 +0100764 return mService.mWindowManager.getTaskSnapshot(taskId, userId, reducedResolution);
Jorim Jaggi02886a82016-12-06 09:10:06 -0800765 }
766
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800767 void touchActiveTime() {
Winson Chungfb44d212017-10-04 11:39:10 -0700768 lastActiveTime = SystemClock.elapsedRealtime();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800769 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700770
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800771 long getInactiveDuration() {
Winson Chungfb44d212017-10-04 11:39:10 -0700772 return SystemClock.elapsedRealtime() - lastActiveTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800773 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700774
Winson Chungfee26772014-08-05 12:21:52 -0700775 /** Sets the original intent, and the calling uid and package. */
776 void setIntent(ActivityRecord r) {
Winson Chungfee26772014-08-05 12:21:52 -0700777 mCallingUid = r.launchedFromUid;
778 mCallingPackage = r.launchedFromPackage;
Craig Mautner15df08a2015-04-01 12:17:18 -0700779 setIntent(r.intent, r.info);
Charles He2bf28322017-10-12 22:24:49 +0100780 setLockTaskAuth(r);
Winson Chungfee26772014-08-05 12:21:52 -0700781 }
782
783 /** Sets the original intent, _without_ updating the calling uid or package. */
784 private void setIntent(Intent _intent, ActivityInfo info) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700785 if (intent == null) {
786 mNeverRelinquishIdentity =
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700787 (info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700788 } else if (mNeverRelinquishIdentity) {
789 return;
790 }
791
792 affinity = info.taskAffinity;
Dianne Hackborn79228822014-09-16 11:11:23 -0700793 if (intent == null) {
794 // If this task already has an intent associated with it, don't set the root
795 // affinity -- we don't want it changing after initially set, but the initially
796 // set value may be null.
797 rootAffinity = affinity;
798 }
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700799 effectiveUid = info.applicationInfo.uid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700800 stringName = null;
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800801
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800802 if (info.targetActivity == null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800803 if (_intent != null) {
804 // If this Intent has a selector, we want to clear it for the
805 // recent task since it is not relevant if the user later wants
806 // to re-launch the app.
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700807 if (_intent.getSelector() != null || _intent.getSourceBounds() != null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800808 _intent = new Intent(_intent);
809 _intent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700810 _intent.setSourceBounds(null);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800811 }
812 }
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700813 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Setting Intent of " + this + " to " + _intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800814 intent = _intent;
815 realActivity = _intent != null ? _intent.getComponent() : null;
816 origActivity = null;
817 } else {
818 ComponentName targetComponent = new ComponentName(
819 info.packageName, info.targetActivity);
820 if (_intent != null) {
821 Intent targetIntent = new Intent(_intent);
822 targetIntent.setComponent(targetComponent);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800823 targetIntent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700824 targetIntent.setSourceBounds(null);
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700825 if (DEBUG_TASKS) Slog.v(TAG_TASKS,
Dianne Hackborn7f96b792012-05-29 18:46:45 -0700826 "Setting Intent of " + this + " to target " + targetIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800827 intent = targetIntent;
828 realActivity = targetComponent;
829 origActivity = _intent.getComponent();
830 } else {
831 intent = null;
832 realActivity = targetComponent;
833 origActivity = new ComponentName(info.packageName, info.name);
834 }
835 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700836
Craig Mautner47b20ba2014-09-17 17:23:44 -0700837 final int intentFlags = intent == null ? 0 : intent.getFlags();
838 if ((intentFlags & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800839 // Once we are set to an Intent with this flag, we count this
840 // task as having a true root activity.
841 rootWasReset = true;
842 }
Dianne Hackborn09233282014-04-30 11:33:59 -0700843 userId = UserHandle.getUserId(info.applicationInfo.uid);
Winson Chung36f3f032016-09-08 23:29:43 +0000844 mUserSetupComplete = Settings.Secure.getIntForUser(mService.mContext.getContentResolver(),
845 USER_SETUP_COMPLETE, 0, userId) != 0;
Craig Mautner41db4a72014-05-07 17:20:56 -0700846 if ((info.flags & ActivityInfo.FLAG_AUTO_REMOVE_FROM_RECENTS) != 0) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700847 // If the activity itself has requested auto-remove, then just always do it.
848 autoRemoveRecents = true;
Wale Ogunwale843bfb92015-03-27 11:06:48 -0700849 } else if ((intentFlags & (FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS))
850 == FLAG_ACTIVITY_NEW_DOCUMENT) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700851 // If the caller has not asked for the document to be retained, then we may
852 // want to turn on auto-remove, depending on whether the target has set its
853 // own document launch mode.
854 if (info.documentLaunchMode != ActivityInfo.DOCUMENT_LAUNCH_NONE) {
855 autoRemoveRecents = false;
856 } else {
857 autoRemoveRecents = true;
858 }
859 } else {
860 autoRemoveRecents = false;
Craig Mautner41db4a72014-05-07 17:20:56 -0700861 }
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800862 mResizeMode = info.resizeMode;
Winson Chungd3395382016-12-13 11:49:09 -0800863 mSupportsPictureInPicture = info.supportsPictureInPicture();
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 Ogunwale66e16852017-10-19 13:35:52 -0700890 boolean returnsToHomeStack() {
891 final int returnHomeFlags = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME;
892 return (intent.getFlags() & returnHomeFlags) == returnHomeFlags;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700893 }
894
Craig Mautnera228ae92014-07-09 05:44:55 -0700895 void setPrevAffiliate(TaskRecord prevAffiliate) {
896 mPrevAffiliate = prevAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800897 mPrevAffiliateTaskId = prevAffiliate == null ? INVALID_TASK_ID : prevAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700898 }
899
900 void setNextAffiliate(TaskRecord nextAffiliate) {
901 mNextAffiliate = nextAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800902 mNextAffiliateTaskId = nextAffiliate == null ? INVALID_TASK_ID : nextAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700903 }
904
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700905 <T extends ActivityStack> T getStack() {
906 return (T) mStack;
Andrii Kulian02b7a832016-10-06 23:11:56 -0700907 }
908
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800909 /**
910 * Must be used for setting parent stack because it performs configuration updates.
911 * Must be called after adding task as a child to the stack.
912 */
Andrii Kulian02b7a832016-10-06 23:11:56 -0700913 void setStack(ActivityStack stack) {
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800914 if (stack != null && !stack.isInStackLocked(this)) {
915 throw new IllegalStateException("Task must be added as a Stack child first.");
916 }
Andrii Kulian02b7a832016-10-06 23:11:56 -0700917 mStack = stack;
Andrii Kulian1779e612016-10-12 21:58:25 -0700918 onParentChanged();
Andrii Kulian02b7a832016-10-06 23:11:56 -0700919 }
920
921 /**
922 * @return Id of current stack, {@link INVALID_STACK_ID} if no stack is set.
923 */
924 int getStackId() {
925 return mStack != null ? mStack.mStackId : INVALID_STACK_ID;
926 }
927
Andrii Kulian1779e612016-10-12 21:58:25 -0700928 @Override
929 protected int getChildCount() {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700930 return mActivities.size();
Andrii Kulian1779e612016-10-12 21:58:25 -0700931 }
932
933 @Override
934 protected ConfigurationContainer getChildAt(int index) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700935 return mActivities.get(index);
Andrii Kulian1779e612016-10-12 21:58:25 -0700936 }
937
938 @Override
939 protected ConfigurationContainer getParent() {
940 return mStack;
941 }
942
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800943 @Override
Wale Ogunwale98d62312017-07-12 09:24:56 -0700944 protected void onParentChanged() {
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800945 super.onParentChanged();
946 mService.mStackSupervisor.updateUIDsPresentOnDisplay();
947 }
948
Craig Mautnera228ae92014-07-09 05:44:55 -0700949 // Close up recents linked list.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700950 private void closeRecentsChain() {
Craig Mautnera228ae92014-07-09 05:44:55 -0700951 if (mPrevAffiliate != null) {
952 mPrevAffiliate.setNextAffiliate(mNextAffiliate);
953 }
954 if (mNextAffiliate != null) {
955 mNextAffiliate.setPrevAffiliate(mPrevAffiliate);
956 }
957 setPrevAffiliate(null);
958 setNextAffiliate(null);
959 }
960
Winson Chung740c3ac2014-11-12 16:14:38 -0800961 void removedFromRecents() {
Dianne Hackborn852975d2014-08-22 17:42:43 -0700962 closeRecentsChain();
963 if (inRecents) {
964 inRecents = false;
Winson Chung740c3ac2014-11-12 16:14:38 -0800965 mService.notifyTaskPersisterLocked(this, false);
Dianne Hackborn852975d2014-08-22 17:42:43 -0700966 }
Jorim Jaggif9084ec2017-01-16 13:16:59 +0100967
968 // TODO: Use window container controller once tasks are better synced between AM and WM
969 mService.mWindowManager.notifyTaskRemovedFromRecents(taskId, userId);
Dianne Hackborn852975d2014-08-22 17:42:43 -0700970 }
971
Craig Mautnera228ae92014-07-09 05:44:55 -0700972 void setTaskToAffiliateWith(TaskRecord taskToAffiliateWith) {
973 closeRecentsChain();
974 mAffiliatedTaskId = taskToAffiliateWith.mAffiliatedTaskId;
Winson Chungec396d62014-08-06 17:08:00 -0700975 mAffiliatedTaskColor = taskToAffiliateWith.mAffiliatedTaskColor;
Craig Mautnera228ae92014-07-09 05:44:55 -0700976 // Find the end
977 while (taskToAffiliateWith.mNextAffiliate != null) {
978 final TaskRecord nextRecents = taskToAffiliateWith.mNextAffiliate;
979 if (nextRecents.mAffiliatedTaskId != mAffiliatedTaskId) {
980 Slog.e(TAG, "setTaskToAffiliateWith: nextRecents=" + nextRecents + " affilTaskId="
981 + nextRecents.mAffiliatedTaskId + " should be " + mAffiliatedTaskId);
982 if (nextRecents.mPrevAffiliate == taskToAffiliateWith) {
983 nextRecents.setPrevAffiliate(null);
984 }
985 taskToAffiliateWith.setNextAffiliate(null);
986 break;
987 }
988 taskToAffiliateWith = nextRecents;
989 }
990 taskToAffiliateWith.setNextAffiliate(this);
991 setPrevAffiliate(taskToAffiliateWith);
992 setNextAffiliate(null);
993 }
994
Winson Chung1147c402014-05-14 11:05:00 -0700995 /** Returns the intent for the root activity for this task */
996 Intent getBaseIntent() {
997 return intent != null ? intent : affinityIntent;
998 }
999
Winson Chung3b3f4642014-04-22 10:08:18 -07001000 /** Returns the first non-finishing activity from the root. */
1001 ActivityRecord getRootActivity() {
1002 for (int i = 0; i < mActivities.size(); i++) {
1003 final ActivityRecord r = mActivities.get(i);
1004 if (r.finishing) {
1005 continue;
1006 }
1007 return r;
1008 }
1009 return null;
1010 }
1011
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001012 ActivityRecord getTopActivity() {
Bryce Lee9f6affd2017-09-01 09:18:35 -07001013 return getTopActivity(true /* includeOverlays */);
1014 }
1015
1016 ActivityRecord getTopActivity(boolean includeOverlays) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001017 for (int i = mActivities.size() - 1; i >= 0; --i) {
1018 final ActivityRecord r = mActivities.get(i);
Bryce Lee9f6affd2017-09-01 09:18:35 -07001019 if (r.finishing || (!includeOverlays && r.mTaskOverlay)) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001020 continue;
1021 }
1022 return r;
1023 }
1024 return null;
1025 }
1026
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -07001027 ActivityRecord topRunningActivityLocked() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001028 if (mStack != null) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07001029 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1030 ActivityRecord r = mActivities.get(activityNdx);
Chong Zhang87761972016-08-22 13:53:24 -07001031 if (!r.finishing && r.okToShowLocked()) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07001032 return r;
1033 }
Craig Mautner6b74cb52013-09-27 17:02:21 -07001034 }
1035 }
1036 return null;
1037 }
1038
Jorim Jaggi172e99f2017-10-20 14:33:18 +02001039 boolean isVisible() {
1040 for (int i = mActivities.size() - 1; i >= 0; --i) {
1041 final ActivityRecord r = mActivities.get(i);
1042 if (r.visible) {
1043 return true;
1044 }
1045 }
1046 return false;
1047 }
1048
Jorim Jaggiea039a82017-08-02 14:37:49 +02001049 void getAllRunningVisibleActivitiesLocked(ArrayList<ActivityRecord> outActivities) {
1050 if (mStack != null) {
1051 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1052 ActivityRecord r = mActivities.get(activityNdx);
Jorim Jaggi02f1d2f2017-08-04 14:29:16 +02001053 if (!r.finishing && r.okToShowLocked() && r.visibleIgnoringKeyguard) {
Jorim Jaggiea039a82017-08-02 14:37:49 +02001054 outActivities.add(r);
1055 }
1056 }
1057 }
1058 }
1059
Wale Ogunwale3b232392016-05-13 15:37:13 -07001060 ActivityRecord topRunningActivityWithStartingWindowLocked() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001061 if (mStack != null) {
Wale Ogunwale3b232392016-05-13 15:37:13 -07001062 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1063 ActivityRecord r = mActivities.get(activityNdx);
1064 if (r.mStartingWindowState != STARTING_WINDOW_SHOWN
Chong Zhang87761972016-08-22 13:53:24 -07001065 || r.finishing || !r.okToShowLocked()) {
Wale Ogunwale3b232392016-05-13 15:37:13 -07001066 continue;
1067 }
1068 return r;
1069 }
1070 }
1071 return null;
1072 }
1073
Winson Chung61c9e5a2017-10-11 10:39:32 -07001074 /**
1075 * Return the number of running activities, and the number of non-finishing/initializing
1076 * activities in the provided {@param reportOut} respectively.
1077 */
1078 void getNumRunningActivities(TaskActivitiesReport reportOut) {
1079 reportOut.reset();
1080 for (int i = mActivities.size() - 1; i >= 0; --i) {
1081 final ActivityRecord r = mActivities.get(i);
1082 if (r.finishing) {
1083 continue;
1084 }
1085
1086 reportOut.base = r;
1087
1088 // Increment the total number of non-finishing activities
1089 reportOut.numActivities++;
1090
1091 if (reportOut.top == null || (reportOut.top.state == ActivityState.INITIALIZING)) {
1092 reportOut.top = r;
1093 // Reset the number of running activities until we hit the first non-initializing
1094 // activity
1095 reportOut.numRunning = 0;
1096 }
1097 if (r.app != null && r.app.thread != null) {
1098 // Increment the number of actually running activities
1099 reportOut.numRunning++;
1100 }
1101 }
1102 }
1103
Chong Zhang87761972016-08-22 13:53:24 -07001104 boolean okToShowLocked() {
1105 // NOTE: If {@link TaskRecord#topRunningActivityLocked} return is not null then it is
1106 // okay to show the activity when locked.
1107 return mService.mStackSupervisor.isCurrentProfileLocked(userId)
1108 || topRunningActivityLocked() != null;
1109 }
1110
Craig Mautner3b475fe2013-12-16 15:58:31 -08001111 /** Call after activity movement or finish to make sure that frontOfTask is set correctly */
Bryce Leed71317c2017-02-07 14:27:22 -08001112 final void setFrontOfTask() {
1113 boolean foundFront = false;
Craig Mautner3b475fe2013-12-16 15:58:31 -08001114 final int numActivities = mActivities.size();
Craig Mautner704e40b2013-12-18 16:43:51 -08001115 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
Craig Mautner3b475fe2013-12-16 15:58:31 -08001116 final ActivityRecord r = mActivities.get(activityNdx);
1117 if (foundFront || r.finishing) {
1118 r.frontOfTask = false;
1119 } else {
1120 r.frontOfTask = true;
1121 // Set frontOfTask false for every following activity.
1122 foundFront = true;
1123 }
1124 }
Craig Mautner9587ee02014-06-23 15:00:10 +00001125 if (!foundFront && numActivities > 0) {
1126 // All activities of this task are finishing. As we ought to have a frontOfTask
1127 // activity, make the bottom activity front.
1128 mActivities.get(0).frontOfTask = true;
1129 }
Craig Mautner3b475fe2013-12-16 15:58:31 -08001130 }
1131
Craig Mautnerde4ef022013-04-07 19:01:33 -07001132 /**
Craig Mautner3b475fe2013-12-16 15:58:31 -08001133 * Reorder the history stack so that the passed activity is brought to the front.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001134 */
1135 final void moveActivityToFrontLocked(ActivityRecord newTop) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07001136 if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE,
1137 "Removing and adding activity " + newTop
1138 + " to stack at top callers=" + Debug.getCallers(4));
Craig Mautnerde4ef022013-04-07 19:01:33 -07001139
Craig Mautnerde4ef022013-04-07 19:01:33 -07001140 mActivities.remove(newTop);
1141 mActivities.add(newTop);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001142 updateEffectiveIntent();
Craig Mautner3b475fe2013-12-16 15:58:31 -08001143
Bryce Leed71317c2017-02-07 14:27:22 -08001144 setFrontOfTask();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001145 }
1146
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001147 void addActivityAtBottom(ActivityRecord r) {
Craig Mautner77878772013-03-04 19:46:24 -08001148 addActivityAtIndex(0, r);
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001149 }
1150
1151 void addActivityToTop(ActivityRecord r) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001152 addActivityAtIndex(mActivities.size(), r);
1153 }
1154
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001155 @Override
Wale Ogunwaleeea34ee92017-08-31 20:07:45 -07001156 /*@WindowConfiguration.ActivityType*/
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001157 public int getActivityType() {
1158 final int applicationType = super.getActivityType();
1159 if (applicationType != ACTIVITY_TYPE_UNDEFINED || mActivities.isEmpty()) {
1160 return applicationType;
1161 }
1162 return mActivities.get(0).getActivityType();
1163 }
1164
Winson Chung30480042017-01-26 10:55:34 -08001165 /**
1166 * Adds an activity {@param r} at the given {@param index}. The activity {@param r} must either
1167 * be in the current task or unparented to any task.
1168 */
Craig Mautner1602ec22013-05-12 10:24:27 -07001169 void addActivityAtIndex(int index, ActivityRecord r) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001170 TaskRecord task = r.getTask();
1171 if (task != null && task != this) {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001172 throw new IllegalArgumentException("Can not add r=" + " to task=" + this
Bryce Leeaf691c02017-03-20 14:20:22 -07001173 + " current parent=" + task);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001174 }
Bryce Leeaf691c02017-03-20 14:20:22 -07001175
1176 r.setTask(this);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001177
Craig Mautner6170f732013-04-02 13:05:23 -07001178 // 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 -08001179 if (!mActivities.remove(r) && r.fullscreen) {
1180 // Was not previously in list.
1181 numFullscreen++;
1182 }
Craig Mautner2c1faed2013-07-23 12:56:02 -07001183 // Only set this based on the first activity
1184 if (mActivities.isEmpty()) {
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001185 if (r.getActivityType() == ACTIVITY_TYPE_UNDEFINED) {
1186 // Normally non-standard activity type for the activity record will be set when the
1187 // object is created, however we delay setting the standard application type until
1188 // this point so that the task can set the type for additional activities added in
1189 // the else condition below.
1190 r.setActivityType(ACTIVITY_TYPE_STANDARD);
1191 }
1192 setActivityType(r.getActivityType());
Craig Mautner21d24a22014-04-23 11:45:37 -07001193 isPersistable = r.isPersistable();
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001194 mCallingUid = r.launchedFromUid;
1195 mCallingPackage = r.launchedFromPackage;
Dianne Hackborn852975d2014-08-22 17:42:43 -07001196 // Clamp to [1, max].
1197 maxRecents = Math.min(Math.max(r.info.maxRecents, 1),
1198 ActivityManager.getMaxAppRecentsLimitStatic());
Craig Mautner2c1faed2013-07-23 12:56:02 -07001199 } else {
1200 // Otherwise make all added activities match this one.
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001201 r.setActivityType(getActivityType());
Craig Mautner78733002013-06-10 13:54:49 -07001202 }
Wale Ogunwale3b232392016-05-13 15:37:13 -07001203
1204 final int size = mActivities.size();
1205
1206 if (index == size && size > 0) {
1207 final ActivityRecord top = mActivities.get(size - 1);
1208 if (top.mTaskOverlay) {
1209 // Place below the task overlay activity since the overlay activity should always
1210 // be on top.
1211 index--;
1212 }
1213 }
1214
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001215 index = Math.min(size, index);
Craig Mautner77878772013-03-04 19:46:24 -08001216 mActivities.add(index, r);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001217 updateEffectiveIntent();
Craig Mautner21d24a22014-04-23 11:45:37 -07001218 if (r.isPersistable()) {
1219 mService.notifyTaskPersisterLocked(this, false);
1220 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001221
1222 // Sync. with window manager
1223 updateOverrideConfigurationFromLaunchBounds();
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001224 final AppWindowContainerController appController = r.getWindowContainerController();
1225 if (appController != null) {
1226 // Only attempt to move in WM if the child has a controller. It is possible we haven't
1227 // created controller for the activity we are starting yet.
1228 mWindowContainerController.positionChildAt(appController, index);
1229 }
David Stevens82ea6cb2017-03-03 16:18:50 -08001230
1231 // Make sure the list of display UID whitelists is updated
1232 // now that this record is in a new task.
1233 mService.mStackSupervisor.updateUIDsPresentOnDisplay();
Craig Mautner77878772013-03-04 19:46:24 -08001234 }
1235
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001236 /**
Bryce Leeaf691c02017-03-20 14:20:22 -07001237 * Removes the specified activity from this task.
1238 * @param r The {@link ActivityRecord} to remove.
1239 * @return true if this was the last activity in the task.
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001240 */
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001241 boolean removeActivity(ActivityRecord r) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001242 return removeActivity(r, false /*reparenting*/);
1243 }
1244
1245 boolean removeActivity(ActivityRecord r, boolean reparenting) {
1246 if (r.getTask() != this) {
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001247 throw new IllegalArgumentException(
1248 "Activity=" + r + " does not belong to task=" + this);
1249 }
1250
Bryce Leeaf691c02017-03-20 14:20:22 -07001251 r.setTask(null /*task*/, reparenting);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001252
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001253 if (mActivities.remove(r) && r.fullscreen) {
1254 // Was previously in list.
1255 numFullscreen--;
1256 }
Craig Mautner21d24a22014-04-23 11:45:37 -07001257 if (r.isPersistable()) {
1258 mService.notifyTaskPersisterLocked(this, false);
1259 }
Wale Ogunwale89182d52016-03-11 10:38:36 -08001260
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001261 if (inPinnedWindowingMode()) {
Wale Ogunwale89182d52016-03-11 10:38:36 -08001262 // We normally notify listeners of task stack changes on pause, however pinned stack
1263 // activities are normally in the paused state so no notification will be sent there
1264 // before the activity is removed. We send it here so instead.
Yorke Leebd54c2a2016-10-25 13:49:23 -07001265 mService.mTaskChangeNotificationController.notifyTaskStackChanged();
Wale Ogunwale89182d52016-03-11 10:38:36 -08001266 }
1267
Craig Mautner41326202014-06-20 14:38:21 -07001268 if (mActivities.isEmpty()) {
Craig Mautner5afcd4d2014-06-21 18:11:33 -07001269 return !mReuseTask;
Craig Mautner41326202014-06-20 14:38:21 -07001270 }
1271 updateEffectiveIntent();
1272 return false;
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001273 }
1274
Winson Chung6954fc92017-03-24 16:22:12 -07001275 /**
1276 * @return whether or not there are ONLY task overlay activities in the stack.
1277 * If {@param excludeFinishing} is set, then ignore finishing activities in the check.
1278 * If there are no task overlay activities, this call returns false.
1279 */
1280 boolean onlyHasTaskOverlayActivities(boolean excludeFinishing) {
1281 int count = 0;
1282 for (int i = mActivities.size() - 1; i >= 0; i--) {
1283 final ActivityRecord r = mActivities.get(i);
1284 if (excludeFinishing && r.finishing) {
1285 continue;
1286 }
1287 if (!r.mTaskOverlay) {
1288 return false;
1289 }
1290 count++;
1291 }
1292 return count > 0;
1293 }
1294
Craig Mautner41db4a72014-05-07 17:20:56 -07001295 boolean autoRemoveFromRecents() {
Dianne Hackbornd38aed82014-06-10 21:36:35 -07001296 // We will automatically remove the task either if it has explicitly asked for
1297 // this, or it is empty and has never contained an activity that got shown to
1298 // the user.
Dianne Hackborn13420f22014-07-18 15:43:56 -07001299 return autoRemoveRecents || (mActivities.isEmpty() && !hasBeenVisible);
Craig Mautner41db4a72014-05-07 17:20:56 -07001300 }
1301
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001302 /**
1303 * Completely remove all activities associated with an existing
1304 * task starting at a specified index.
1305 */
Winson Chung6954fc92017-03-24 16:22:12 -07001306 final void performClearTaskAtIndexLocked(int activityNdx, boolean pauseImmediately) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001307 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001308 for ( ; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001309 final ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001310 if (r.finishing) {
1311 continue;
1312 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07001313 if (mStack == null) {
Craig Mautner21d24a22014-04-23 11:45:37 -07001314 // Task was restored from persistent storage.
1315 r.takeFromHistory();
1316 mActivities.remove(activityNdx);
1317 --activityNdx;
1318 --numActivities;
Winson Chung6954fc92017-03-24 16:22:12 -07001319 } else if (mStack.finishActivityLocked(r, Activity.RESULT_CANCELED, null,
1320 "clear-task-index", false, pauseImmediately)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001321 --activityNdx;
1322 --numActivities;
1323 }
1324 }
1325 }
1326
1327 /**
1328 * Completely remove all activities associated with an existing task.
1329 */
Benjamin Franza83859f2017-07-03 16:34:14 +01001330 void performClearTaskLocked() {
Craig Mautner362449a2014-06-20 14:04:39 -07001331 mReuseTask = true;
Winson Chung6954fc92017-03-24 16:22:12 -07001332 performClearTaskAtIndexLocked(0, !PAUSE_IMMEDIATELY);
Craig Mautner362449a2014-06-20 14:04:39 -07001333 mReuseTask = false;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001334 }
1335
Filip Gruszczynskibe9dabd2016-01-19 12:23:10 -08001336 ActivityRecord performClearTaskForReuseLocked(ActivityRecord newR, int launchFlags) {
1337 mReuseTask = true;
1338 final ActivityRecord result = performClearTaskLocked(newR, launchFlags);
1339 mReuseTask = false;
1340 return result;
1341 }
1342
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001343 /**
1344 * Perform clear operation as requested by
1345 * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the
1346 * stack to the given task, then look for
1347 * an instance of that activity in the stack and, if found, finish all
1348 * activities on top of it and return the instance.
1349 *
1350 * @param newR Description of the new activity being started.
1351 * @return Returns the old activity that should be continued to be used,
1352 * or null if none was found.
1353 */
1354 final ActivityRecord performClearTaskLocked(ActivityRecord newR, int launchFlags) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001355 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001356 for (int activityNdx = numActivities - 1; activityNdx >= 0; --activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001357 ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001358 if (r.finishing) {
1359 continue;
1360 }
1361 if (r.realActivity.equals(newR.realActivity)) {
1362 // Here it is! Now finish everything in front...
Craig Mautner1602ec22013-05-12 10:24:27 -07001363 final ActivityRecord ret = r;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001364
1365 for (++activityNdx; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001366 r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001367 if (r.finishing) {
1368 continue;
1369 }
1370 ActivityOptions opts = r.takeOptionsLocked();
1371 if (opts != null) {
1372 ret.updateOptionsLocked(opts);
1373 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07001374 if (mStack != null && mStack.finishActivityLocked(
Todd Kennedy539db512014-12-15 09:57:55 -08001375 r, Activity.RESULT_CANCELED, null, "clear-task-stack", false)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001376 --activityNdx;
1377 --numActivities;
1378 }
1379 }
1380
1381 // Finally, if this is a normal launch mode (that is, not
1382 // expecting onNewIntent()), then we will finish the current
1383 // instance of the activity so a new fresh one can be started.
1384 if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE
Daichi Hirono15a02992016-04-27 18:47:01 +09001385 && (launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0
1386 && !ActivityStarter.isDocumentLaunchesIntoExisting(launchFlags)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001387 if (!ret.finishing) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001388 if (mStack != null) {
1389 mStack.finishActivityLocked(
Wale Ogunwale7d701172015-03-11 15:36:30 -07001390 ret, Activity.RESULT_CANCELED, null, "clear-task-top", false);
1391 }
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001392 return null;
1393 }
1394 }
1395
1396 return ret;
1397 }
1398 }
1399
1400 return null;
1401 }
1402
Winson Chung6954fc92017-03-24 16:22:12 -07001403 void removeTaskActivitiesLocked(boolean pauseImmediately) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001404 // Just remove the entire task.
Winson Chung6954fc92017-03-24 16:22:12 -07001405 performClearTaskAtIndexLocked(0, pauseImmediately);
Craig Mautner9db9a0b2013-04-29 17:05:56 -07001406 }
1407
Craig Mautner432f64e2015-05-20 14:59:57 -07001408 String lockTaskAuthToString() {
1409 switch (mLockTaskAuth) {
1410 case LOCK_TASK_AUTH_DONT_LOCK: return "LOCK_TASK_AUTH_DONT_LOCK";
1411 case LOCK_TASK_AUTH_PINNABLE: return "LOCK_TASK_AUTH_PINNABLE";
1412 case LOCK_TASK_AUTH_LAUNCHABLE: return "LOCK_TASK_AUTH_LAUNCHABLE";
1413 case LOCK_TASK_AUTH_WHITELISTED: return "LOCK_TASK_AUTH_WHITELISTED";
Benjamin Franz469dd582015-06-09 14:24:36 +01001414 case LOCK_TASK_AUTH_LAUNCHABLE_PRIV: return "LOCK_TASK_AUTH_LAUNCHABLE_PRIV";
Craig Mautner432f64e2015-05-20 14:59:57 -07001415 default: return "unknown=" + mLockTaskAuth;
1416 }
1417 }
1418
Craig Mautner15df08a2015-04-01 12:17:18 -07001419 void setLockTaskAuth() {
Charles He2bf28322017-10-12 22:24:49 +01001420 setLockTaskAuth(getRootActivity());
1421 }
1422
1423 private void setLockTaskAuth(@Nullable ActivityRecord r) {
1424 if (r == null) {
1425 mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE;
1426 return;
1427 }
1428
Charles He520b2832017-09-02 15:27:16 +01001429 final String pkg = (realActivity != null) ? realActivity.getPackageName() : null;
Charles He2bf28322017-10-12 22:24:49 +01001430 switch (r.lockTaskLaunchMode) {
Craig Mautner15df08a2015-04-01 12:17:18 -07001431 case LOCK_TASK_LAUNCH_MODE_DEFAULT:
Charles He520b2832017-09-02 15:27:16 +01001432 mLockTaskAuth = mService.mLockTaskController.isPackageWhitelisted(userId, pkg)
1433 ? LOCK_TASK_AUTH_WHITELISTED : LOCK_TASK_AUTH_PINNABLE;
Craig Mautner15df08a2015-04-01 12:17:18 -07001434 break;
1435
1436 case LOCK_TASK_LAUNCH_MODE_NEVER:
Benjamin Franz469dd582015-06-09 14:24:36 +01001437 mLockTaskAuth = LOCK_TASK_AUTH_DONT_LOCK;
Craig Mautner15df08a2015-04-01 12:17:18 -07001438 break;
1439
1440 case LOCK_TASK_LAUNCH_MODE_ALWAYS:
Benjamin Franz469dd582015-06-09 14:24:36 +01001441 mLockTaskAuth = LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
Craig Mautner15df08a2015-04-01 12:17:18 -07001442 break;
1443
1444 case LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED:
Charles He520b2832017-09-02 15:27:16 +01001445 mLockTaskAuth = mService.mLockTaskController.isPackageWhitelisted(userId, pkg)
1446 ? LOCK_TASK_AUTH_LAUNCHABLE : LOCK_TASK_AUTH_PINNABLE;
Craig Mautner15df08a2015-04-01 12:17:18 -07001447 break;
1448 }
Craig Mautner432f64e2015-05-20 14:59:57 -07001449 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
1450 " mLockTaskAuth=" + lockTaskAuthToString());
Craig Mautner15df08a2015-04-01 12:17:18 -07001451 }
1452
Winson Chungd3395382016-12-13 11:49:09 -08001453 private boolean isResizeable(boolean checkSupportsPip) {
1454 return (mService.mForceResizableActivities || ActivityInfo.isResizeableMode(mResizeMode)
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -07001455 || (checkSupportsPip && mSupportsPictureInPicture));
Winson Chungd3395382016-12-13 11:49:09 -08001456 }
1457
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001458 boolean isResizeable() {
Winson Chungd3395382016-12-13 11:49:09 -08001459 return isResizeable(true /* checkSupportsPip */);
1460 }
1461
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001462 @Override
1463 public boolean supportsSplitScreenWindowingMode() {
Winson Chungd3395382016-12-13 11:49:09 -08001464 // A task can not be docked even if it is considered resizeable because it only supports
1465 // picture-in-picture mode but has a non-resizeable resizeMode
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001466 return super.supportsSplitScreenWindowingMode()
1467 && mService.mSupportsSplitScreenMultiWindow
Bryce Leec857a5b2017-08-16 10:04:52 -07001468 && (mService.mForceResizableActivities
1469 || (isResizeable(false /* checkSupportsPip */)
1470 && !ActivityInfo.isPreserveOrientationMode(mResizeMode)));
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001471 }
1472
skuhne@google.com322347b2016-12-02 12:54:03 -08001473 /**
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001474 * Check whether this task can be launched on the specified display.
1475 * @param displayId Target display id.
1476 * @return {@code true} if either it is the default display or this activity is resizeable and
1477 * can be put a secondary screen.
1478 */
1479 boolean canBeLaunchedOnDisplay(int displayId) {
1480 return mService.mStackSupervisor.canPlaceEntityOnDisplay(displayId,
Andrii Kulian02689a72017-07-06 14:28:59 -07001481 isResizeable(false /* checkSupportsPip */), -1 /* don't check PID */,
1482 -1 /* don't check UID */, null /* activityInfo */);
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001483 }
1484
1485 /**
skuhne@google.com322347b2016-12-02 12:54:03 -08001486 * Check that a given bounds matches the application requested orientation.
1487 *
1488 * @param bounds The bounds to be tested.
1489 * @return True if the requested bounds are okay for a resizing request.
1490 */
Wale Ogunwale069bbd32017-02-03 07:58:14 -08001491 private boolean canResizeToBounds(Rect bounds) {
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001492 if (bounds == null || !inFreeformWindowingMode()) {
skuhne@google.com322347b2016-12-02 12:54:03 -08001493 // Note: If not on the freeform workspace, we ignore the bounds.
1494 return true;
1495 }
1496 final boolean landscape = bounds.width() > bounds.height();
1497 if (mResizeMode == RESIZE_MODE_FORCE_RESIZABLE_PRESERVE_ORIENTATION) {
1498 return mBounds == null || landscape == (mBounds.width() > mBounds.height());
1499 }
1500 return (mResizeMode != RESIZE_MODE_FORCE_RESIZABLE_PORTRAIT_ONLY || !landscape)
1501 && (mResizeMode != RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY || landscape);
1502 }
1503
Craig Mautner525f3d92013-05-07 14:01:50 -07001504 /**
Yorke Leebdef5372017-04-10 16:38:51 -07001505 * @return {@code true} if the task is being cleared for the purposes of being reused.
1506 */
1507 boolean isClearingToReuseTask() {
1508 return mReuseTask;
1509 }
1510
1511 /**
Craig Mautner525f3d92013-05-07 14:01:50 -07001512 * Find the activity in the history stack within the given task. Returns
1513 * the index within the history at which it's found, or < 0 if not found.
1514 */
1515 final ActivityRecord findActivityInHistoryLocked(ActivityRecord r) {
1516 final ComponentName realActivity = r.realActivity;
1517 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1518 ActivityRecord candidate = mActivities.get(activityNdx);
1519 if (candidate.finishing) {
1520 continue;
1521 }
1522 if (candidate.realActivity.equals(realActivity)) {
1523 return candidate;
1524 }
1525 }
1526 return null;
1527 }
1528
Winson Chunga449dc02014-05-16 11:15:04 -07001529 /** Updates the last task description values. */
1530 void updateTaskDescription() {
1531 // Traverse upwards looking for any break between main task activities and
1532 // utility activities.
1533 int activityNdx;
1534 final int numActivities = mActivities.size();
Wale Ogunwale3eadad72016-10-13 09:16:59 -07001535 final boolean relinquish = numActivities != 0 &&
1536 (mActivities.get(0).info.flags & FLAG_RELINQUISH_TASK_IDENTITY) != 0;
Winson Chunga449dc02014-05-16 11:15:04 -07001537 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
Craig Mautner21d24a22014-04-23 11:45:37 -07001538 ++activityNdx) {
Winson Chunga449dc02014-05-16 11:15:04 -07001539 final ActivityRecord r = mActivities.get(activityNdx);
Wale Ogunwale3eadad72016-10-13 09:16:59 -07001540 if (relinquish && (r.info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001541 // This will be the top activity for determining taskDescription. Pre-inc to
1542 // overcome initial decrement below.
1543 ++activityNdx;
1544 break;
1545 }
Winson Chunga449dc02014-05-16 11:15:04 -07001546 if (r.intent != null &&
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001547 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
Winson Chunga449dc02014-05-16 11:15:04 -07001548 break;
1549 }
1550 }
1551 if (activityNdx > 0) {
1552 // Traverse downwards starting below break looking for set label, icon.
1553 // Note that if there are activities in the task but none of them set the
1554 // recent activity values, then we do not fall back to the last set
1555 // values in the TaskRecord.
1556 String label = null;
Craig Mautner648f69b2014-09-18 14:16:26 -07001557 String iconFilename = null;
Matthew Ng54bc9422017-10-02 17:16:28 -07001558 int iconResource = -1;
Winson Chunga449dc02014-05-16 11:15:04 -07001559 int colorPrimary = 0;
Winson Chung1af8eda2016-02-05 17:55:56 +00001560 int colorBackground = 0;
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001561 int statusBarColor = 0;
1562 int navigationBarColor = 0;
1563 boolean topActivity = true;
Winson Chunga449dc02014-05-16 11:15:04 -07001564 for (--activityNdx; activityNdx >= 0; --activityNdx) {
1565 final ActivityRecord r = mActivities.get(activityNdx);
1566 if (r.taskDescription != null) {
1567 if (label == null) {
1568 label = r.taskDescription.getLabel();
1569 }
Matthew Ng54bc9422017-10-02 17:16:28 -07001570 if (iconResource == -1) {
1571 iconResource = r.taskDescription.getIconResource();
1572 }
Craig Mautner648f69b2014-09-18 14:16:26 -07001573 if (iconFilename == null) {
1574 iconFilename = r.taskDescription.getIconFilename();
Winson Chunga449dc02014-05-16 11:15:04 -07001575 }
1576 if (colorPrimary == 0) {
1577 colorPrimary = r.taskDescription.getPrimaryColor();
Winson Chunga449dc02014-05-16 11:15:04 -07001578 }
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001579 if (topActivity) {
Winson Chung1af8eda2016-02-05 17:55:56 +00001580 colorBackground = r.taskDescription.getBackgroundColor();
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001581 statusBarColor = r.taskDescription.getStatusBarColor();
1582 navigationBarColor = r.taskDescription.getNavigationBarColor();
Winson Chung1af8eda2016-02-05 17:55:56 +00001583 }
Winson Chunga449dc02014-05-16 11:15:04 -07001584 }
Jorim Jaggi30d64f32017-04-07 16:33:17 +02001585 topActivity = false;
Winson Chunga449dc02014-05-16 11:15:04 -07001586 }
Matthew Ng54bc9422017-10-02 17:16:28 -07001587 lastTaskDescription = new TaskDescription(label, null, iconResource, iconFilename,
1588 colorPrimary, colorBackground, statusBarColor, navigationBarColor);
Jorim Jaggi829b9cd2017-01-23 16:20:53 +01001589 if (mWindowContainerController != null) {
1590 mWindowContainerController.setTaskDescription(lastTaskDescription);
1591 }
Winson Chungec396d62014-08-06 17:08:00 -07001592 // Update the task affiliation color if we are the parent of the group
1593 if (taskId == mAffiliatedTaskId) {
1594 mAffiliatedTaskColor = lastTaskDescription.getPrimaryColor();
1595 }
Winson Chunga449dc02014-05-16 11:15:04 -07001596 }
1597 }
1598
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001599 int findEffectiveRootIndex() {
Craig Mautner4767f4b2014-09-18 15:38:33 -07001600 int effectiveNdx = 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001601 final int topActivityNdx = mActivities.size() - 1;
Dianne Hackborn39569af2014-09-23 10:56:58 -07001602 for (int activityNdx = 0; activityNdx <= topActivityNdx; ++activityNdx) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001603 final ActivityRecord r = mActivities.get(activityNdx);
1604 if (r.finishing) {
1605 continue;
1606 }
Craig Mautner4767f4b2014-09-18 15:38:33 -07001607 effectiveNdx = activityNdx;
Wale Ogunwale3eadad72016-10-13 09:16:59 -07001608 if ((r.info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001609 break;
1610 }
1611 }
Craig Mautner4767f4b2014-09-18 15:38:33 -07001612 return effectiveNdx;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001613 }
1614
1615 void updateEffectiveIntent() {
1616 final int effectiveRootIndex = findEffectiveRootIndex();
1617 final ActivityRecord r = mActivities.get(effectiveRootIndex);
Winson Chungfee26772014-08-05 12:21:52 -07001618 setIntent(r);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001619 }
1620
Craig Mautner21d24a22014-04-23 11:45:37 -07001621 void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001622 if (DEBUG_RECENTS) Slog.i(TAG_RECENTS, "Saving task=" + this);
Craig Mautner21d24a22014-04-23 11:45:37 -07001623
1624 out.attribute(null, ATTR_TASKID, String.valueOf(taskId));
1625 if (realActivity != null) {
1626 out.attribute(null, ATTR_REALACTIVITY, realActivity.flattenToShortString());
1627 }
Andrei Stingaceanu4ccec532016-01-13 12:10:21 +00001628 out.attribute(null, ATTR_REALACTIVITY_SUSPENDED, String.valueOf(realActivitySuspended));
Craig Mautner21d24a22014-04-23 11:45:37 -07001629 if (origActivity != null) {
1630 out.attribute(null, ATTR_ORIGACTIVITY, origActivity.flattenToShortString());
1631 }
Dianne Hackborn79228822014-09-16 11:11:23 -07001632 // Write affinity, and root affinity if it is different from affinity.
1633 // We use the special string "@" for a null root affinity, so we can identify
1634 // later whether we were given a root affinity or should just make it the
1635 // same as the affinity.
Craig Mautner21d24a22014-04-23 11:45:37 -07001636 if (affinity != null) {
1637 out.attribute(null, ATTR_AFFINITY, affinity);
Dianne Hackborn79228822014-09-16 11:11:23 -07001638 if (!affinity.equals(rootAffinity)) {
1639 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
1640 }
1641 } else if (rootAffinity != null) {
1642 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
Craig Mautner21d24a22014-04-23 11:45:37 -07001643 }
1644 out.attribute(null, ATTR_ROOTHASRESET, String.valueOf(rootWasReset));
Dianne Hackborn13420f22014-07-18 15:43:56 -07001645 out.attribute(null, ATTR_AUTOREMOVERECENTS, String.valueOf(autoRemoveRecents));
Craig Mautner21d24a22014-04-23 11:45:37 -07001646 out.attribute(null, ATTR_ASKEDCOMPATMODE, String.valueOf(askedCompatMode));
1647 out.attribute(null, ATTR_USERID, String.valueOf(userId));
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001648 out.attribute(null, ATTR_USER_SETUP_COMPLETE, String.valueOf(mUserSetupComplete));
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001649 out.attribute(null, ATTR_EFFECTIVE_UID, String.valueOf(effectiveUid));
Craig Mautner21d24a22014-04-23 11:45:37 -07001650 out.attribute(null, ATTR_LASTTIMEMOVED, String.valueOf(mLastTimeMoved));
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001651 out.attribute(null, ATTR_NEVERRELINQUISH, String.valueOf(mNeverRelinquishIdentity));
Craig Mautner21d24a22014-04-23 11:45:37 -07001652 if (lastDescription != null) {
1653 out.attribute(null, ATTR_LASTDESCRIPTION, lastDescription.toString());
1654 }
Winson Chung2cb86c72014-06-25 12:03:30 -07001655 if (lastTaskDescription != null) {
Craig Mautner648f69b2014-09-18 14:16:26 -07001656 lastTaskDescription.saveToXml(out);
Winson Chung2cb86c72014-06-25 12:03:30 -07001657 }
Winson Chungec396d62014-08-06 17:08:00 -07001658 out.attribute(null, ATTR_TASK_AFFILIATION_COLOR, String.valueOf(mAffiliatedTaskColor));
Craig Mautnera228ae92014-07-09 05:44:55 -07001659 out.attribute(null, ATTR_TASK_AFFILIATION, String.valueOf(mAffiliatedTaskId));
1660 out.attribute(null, ATTR_PREV_AFFILIATION, String.valueOf(mPrevAffiliateTaskId));
1661 out.attribute(null, ATTR_NEXT_AFFILIATION, String.valueOf(mNextAffiliateTaskId));
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001662 out.attribute(null, ATTR_CALLING_UID, String.valueOf(mCallingUid));
1663 out.attribute(null, ATTR_CALLING_PACKAGE, mCallingPackage == null ? "" : mCallingPackage);
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001664 out.attribute(null, ATTR_RESIZE_MODE, String.valueOf(mResizeMode));
Winson Chungd3395382016-12-13 11:49:09 -08001665 out.attribute(null, ATTR_SUPPORTS_PICTURE_IN_PICTURE,
1666 String.valueOf(mSupportsPictureInPicture));
Wale Ogunwale706ed792015-08-02 10:29:44 -07001667 if (mLastNonFullscreenBounds != null) {
1668 out.attribute(
1669 null, ATTR_NON_FULLSCREEN_BOUNDS, mLastNonFullscreenBounds.flattenToString());
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001670 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001671 out.attribute(null, ATTR_MIN_WIDTH, String.valueOf(mMinWidth));
1672 out.attribute(null, ATTR_MIN_HEIGHT, String.valueOf(mMinHeight));
Wale Ogunwale625ed0c2016-10-18 08:50:31 -07001673 out.attribute(null, ATTR_PERSIST_TASK_VERSION, String.valueOf(PERSIST_TASK_VERSION));
Winson Chung2cb86c72014-06-25 12:03:30 -07001674
Craig Mautner21d24a22014-04-23 11:45:37 -07001675 if (affinityIntent != null) {
1676 out.startTag(null, TAG_AFFINITYINTENT);
1677 affinityIntent.saveToXml(out);
1678 out.endTag(null, TAG_AFFINITYINTENT);
1679 }
1680
Winson Chung36f3f032016-09-08 23:29:43 +00001681 out.startTag(null, TAG_INTENT);
1682 intent.saveToXml(out);
1683 out.endTag(null, TAG_INTENT);
Craig Mautner21d24a22014-04-23 11:45:37 -07001684
1685 final ArrayList<ActivityRecord> activities = mActivities;
1686 final int numActivities = activities.size();
1687 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
1688 final ActivityRecord r = activities.get(activityNdx);
Craig Mautner43e52ed2014-06-16 17:18:52 -07001689 if (r.info.persistableMode == ActivityInfo.PERSIST_ROOT_ONLY || !r.isPersistable() ||
Wale Ogunwale843bfb92015-03-27 11:06:48 -07001690 ((r.intent.getFlags() & FLAG_ACTIVITY_NEW_DOCUMENT
1691 | FLAG_ACTIVITY_RETAIN_IN_RECENTS) == FLAG_ACTIVITY_NEW_DOCUMENT) &&
Craig Mautner43e52ed2014-06-16 17:18:52 -07001692 activityNdx > 0) {
Craig Mautnerf357c0c2014-06-09 09:23:27 -07001693 // Stop at first non-persistable or first break in task (CLEAR_WHEN_TASK_RESET).
Craig Mautner21d24a22014-04-23 11:45:37 -07001694 break;
1695 }
1696 out.startTag(null, TAG_ACTIVITY);
1697 r.saveToXml(out);
1698 out.endTag(null, TAG_ACTIVITY);
1699 }
Craig Mautner21d24a22014-04-23 11:45:37 -07001700 }
1701
Winson Chung36f3f032016-09-08 23:29:43 +00001702 static TaskRecord restoreFromXml(XmlPullParser in, ActivityStackSupervisor stackSupervisor)
1703 throws IOException, XmlPullParserException {
Craig Mautner21d24a22014-04-23 11:45:37 -07001704 Intent intent = null;
1705 Intent affinityIntent = null;
Winsonc809cbb2015-11-02 12:06:15 -08001706 ArrayList<ActivityRecord> activities = new ArrayList<>();
Craig Mautner21d24a22014-04-23 11:45:37 -07001707 ComponentName realActivity = null;
Andrei Stingaceanu4ccec532016-01-13 12:10:21 +00001708 boolean realActivitySuspended = false;
Craig Mautner21d24a22014-04-23 11:45:37 -07001709 ComponentName origActivity = null;
1710 String affinity = null;
Dianne Hackborn79228822014-09-16 11:11:23 -07001711 String rootAffinity = null;
1712 boolean hasRootAffinity = false;
Craig Mautner21d24a22014-04-23 11:45:37 -07001713 boolean rootHasReset = false;
Dianne Hackborn13420f22014-07-18 15:43:56 -07001714 boolean autoRemoveRecents = false;
Craig Mautner21d24a22014-04-23 11:45:37 -07001715 boolean askedCompatMode = false;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001716 int taskType = 0;
Craig Mautner21d24a22014-04-23 11:45:37 -07001717 int userId = 0;
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001718 boolean userSetupComplete = true;
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001719 int effectiveUid = -1;
Craig Mautner21d24a22014-04-23 11:45:37 -07001720 String lastDescription = null;
1721 long lastTimeOnTop = 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001722 boolean neverRelinquishIdentity = true;
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001723 int taskId = INVALID_TASK_ID;
Craig Mautner21d24a22014-04-23 11:45:37 -07001724 final int outerDepth = in.getDepth();
Craig Mautner648f69b2014-09-18 14:16:26 -07001725 TaskDescription taskDescription = new TaskDescription();
Wale Ogunwale18795a22014-12-03 11:38:33 -08001726 int taskAffiliation = INVALID_TASK_ID;
Winson Chungec396d62014-08-06 17:08:00 -07001727 int taskAffiliationColor = 0;
Wale Ogunwale18795a22014-12-03 11:38:33 -08001728 int prevTaskId = INVALID_TASK_ID;
1729 int nextTaskId = INVALID_TASK_ID;
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001730 int callingUid = -1;
1731 String callingPackage = "";
Wale Ogunwaled829d362016-02-10 19:24:49 -08001732 int resizeMode = RESIZE_MODE_FORCE_RESIZEABLE;
Winson Chungd3395382016-12-13 11:49:09 -08001733 boolean supportsPictureInPicture = false;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001734 Rect bounds = null;
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001735 int minWidth = INVALID_MIN_SIZE;
1736 int minHeight = INVALID_MIN_SIZE;
Wale Ogunwale625ed0c2016-10-18 08:50:31 -07001737 int persistTaskVersion = 0;
Craig Mautner21d24a22014-04-23 11:45:37 -07001738
1739 for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
1740 final String attrName = in.getAttributeName(attrNdx);
1741 final String attrValue = in.getAttributeValue(attrNdx);
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001742 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: attribute name=" +
1743 attrName + " value=" + attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001744 if (ATTR_TASKID.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001745 if (taskId == INVALID_TASK_ID) taskId = Integer.parseInt(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001746 } else if (ATTR_REALACTIVITY.equals(attrName)) {
1747 realActivity = ComponentName.unflattenFromString(attrValue);
Andrei Stingaceanu4ccec532016-01-13 12:10:21 +00001748 } else if (ATTR_REALACTIVITY_SUSPENDED.equals(attrName)) {
1749 realActivitySuspended = Boolean.valueOf(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001750 } else if (ATTR_ORIGACTIVITY.equals(attrName)) {
1751 origActivity = ComponentName.unflattenFromString(attrValue);
1752 } else if (ATTR_AFFINITY.equals(attrName)) {
1753 affinity = attrValue;
Dianne Hackborn79228822014-09-16 11:11:23 -07001754 } else if (ATTR_ROOT_AFFINITY.equals(attrName)) {
1755 rootAffinity = attrValue;
1756 hasRootAffinity = true;
Craig Mautner21d24a22014-04-23 11:45:37 -07001757 } else if (ATTR_ROOTHASRESET.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01001758 rootHasReset = Boolean.parseBoolean(attrValue);
Dianne Hackborn13420f22014-07-18 15:43:56 -07001759 } else if (ATTR_AUTOREMOVERECENTS.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01001760 autoRemoveRecents = Boolean.parseBoolean(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001761 } else if (ATTR_ASKEDCOMPATMODE.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01001762 askedCompatMode = Boolean.parseBoolean(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001763 } else if (ATTR_USERID.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001764 userId = Integer.parseInt(attrValue);
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001765 } else if (ATTR_USER_SETUP_COMPLETE.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01001766 userSetupComplete = Boolean.parseBoolean(attrValue);
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001767 } else if (ATTR_EFFECTIVE_UID.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001768 effectiveUid = Integer.parseInt(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001769 } else if (ATTR_TASKTYPE.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001770 taskType = Integer.parseInt(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001771 } else if (ATTR_LASTDESCRIPTION.equals(attrName)) {
1772 lastDescription = attrValue;
1773 } else if (ATTR_LASTTIMEMOVED.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01001774 lastTimeOnTop = Long.parseLong(attrValue);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001775 } else if (ATTR_NEVERRELINQUISH.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01001776 neverRelinquishIdentity = Boolean.parseBoolean(attrValue);
Craig Mautner648f69b2014-09-18 14:16:26 -07001777 } else if (attrName.startsWith(TaskDescription.ATTR_TASKDESCRIPTION_PREFIX)) {
1778 taskDescription.restoreFromXml(attrName, attrValue);
Craig Mautnera228ae92014-07-09 05:44:55 -07001779 } else if (ATTR_TASK_AFFILIATION.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001780 taskAffiliation = Integer.parseInt(attrValue);
Craig Mautnera228ae92014-07-09 05:44:55 -07001781 } else if (ATTR_PREV_AFFILIATION.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001782 prevTaskId = Integer.parseInt(attrValue);
Craig Mautnera228ae92014-07-09 05:44:55 -07001783 } else if (ATTR_NEXT_AFFILIATION.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001784 nextTaskId = Integer.parseInt(attrValue);
Winson Chungec396d62014-08-06 17:08:00 -07001785 } else if (ATTR_TASK_AFFILIATION_COLOR.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001786 taskAffiliationColor = Integer.parseInt(attrValue);
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001787 } else if (ATTR_CALLING_UID.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001788 callingUid = Integer.parseInt(attrValue);
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001789 } else if (ATTR_CALLING_PACKAGE.equals(attrName)) {
1790 callingPackage = attrValue;
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001791 } else if (ATTR_RESIZE_MODE.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001792 resizeMode = Integer.parseInt(attrValue);
Winson Chungd3395382016-12-13 11:49:09 -08001793 } else if (ATTR_SUPPORTS_PICTURE_IN_PICTURE.equals(attrName)) {
1794 supportsPictureInPicture = Boolean.parseBoolean(attrValue);
Wale Ogunwale706ed792015-08-02 10:29:44 -07001795 } else if (ATTR_NON_FULLSCREEN_BOUNDS.equals(attrName)) {
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001796 bounds = Rect.unflattenFromString(attrValue);
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001797 } else if (ATTR_MIN_WIDTH.equals(attrName)) {
1798 minWidth = Integer.parseInt(attrValue);
1799 } else if (ATTR_MIN_HEIGHT.equals(attrName)) {
1800 minHeight = Integer.parseInt(attrValue);
Wale Ogunwale625ed0c2016-10-18 08:50:31 -07001801 } else if (ATTR_PERSIST_TASK_VERSION.equals(attrName)) {
1802 persistTaskVersion = Integer.parseInt(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001803 } else {
1804 Slog.w(TAG, "TaskRecord: Unknown attribute=" + attrName);
1805 }
1806 }
1807
1808 int event;
1809 while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
Ben Kwa8814cf42015-07-08 10:54:56 -07001810 (event != XmlPullParser.END_TAG || in.getDepth() >= outerDepth)) {
Craig Mautner21d24a22014-04-23 11:45:37 -07001811 if (event == XmlPullParser.START_TAG) {
1812 final String name = in.getName();
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001813 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: START_TAG name=" +
1814 name);
Craig Mautner21d24a22014-04-23 11:45:37 -07001815 if (TAG_AFFINITYINTENT.equals(name)) {
1816 affinityIntent = Intent.restoreFromXml(in);
1817 } else if (TAG_INTENT.equals(name)) {
1818 intent = Intent.restoreFromXml(in);
1819 } else if (TAG_ACTIVITY.equals(name)) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08001820 ActivityRecord activity = ActivityRecord.restoreFromXml(in, stackSupervisor);
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001821 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: activity=" +
1822 activity);
Craig Mautner21d24a22014-04-23 11:45:37 -07001823 if (activity != null) {
1824 activities.add(activity);
1825 }
1826 } else {
1827 Slog.e(TAG, "restoreTask: Unexpected name=" + name);
1828 XmlUtils.skipCurrentTag(in);
1829 }
1830 }
1831 }
Dianne Hackborn79228822014-09-16 11:11:23 -07001832 if (!hasRootAffinity) {
1833 rootAffinity = affinity;
1834 } else if ("@".equals(rootAffinity)) {
1835 rootAffinity = null;
1836 }
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001837 if (effectiveUid <= 0) {
1838 Intent checkIntent = intent != null ? intent : affinityIntent;
1839 effectiveUid = 0;
1840 if (checkIntent != null) {
1841 IPackageManager pm = AppGlobals.getPackageManager();
1842 try {
1843 ApplicationInfo ai = pm.getApplicationInfo(
1844 checkIntent.getComponent().getPackageName(),
Amith Yamasani0d1fd8d2016-10-12 14:21:51 -07001845 PackageManager.MATCH_UNINSTALLED_PACKAGES
1846 | PackageManager.MATCH_DISABLED_COMPONENTS, userId);
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001847 if (ai != null) {
1848 effectiveUid = ai.uid;
1849 }
1850 } catch (RemoteException e) {
1851 }
1852 }
1853 Slog.w(TAG, "Updating task #" + taskId + " for " + checkIntent
1854 + ": effectiveUid=" + effectiveUid);
1855 }
1856
Wale Ogunwale625ed0c2016-10-18 08:50:31 -07001857 if (persistTaskVersion < 1) {
1858 // We need to convert the resize mode of home activities saved before version one if
1859 // they are marked as RESIZE_MODE_RESIZEABLE to RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION
1860 // since we didn't have that differentiation before version 1 and the system didn't
1861 // resize home activities before then.
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001862 if (taskType == 1 /* old home type */ && resizeMode == RESIZE_MODE_RESIZEABLE) {
Wale Ogunwale625ed0c2016-10-18 08:50:31 -07001863 resizeMode = RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
1864 }
Winson Chungd3395382016-12-13 11:49:09 -08001865 } else {
1866 // This activity has previously marked itself explicitly as both resizeable and
1867 // supporting picture-in-picture. Since there is no longer a requirement for
1868 // picture-in-picture activities to be resizeable, we can mark this simply as
1869 // resizeable and supporting picture-in-picture separately.
1870 if (resizeMode == RESIZE_MODE_RESIZEABLE_AND_PIPABLE_DEPRECATED) {
1871 resizeMode = RESIZE_MODE_RESIZEABLE;
1872 supportsPictureInPicture = true;
1873 }
Wale Ogunwale625ed0c2016-10-18 08:50:31 -07001874 }
1875
Winson Chung36f3f032016-09-08 23:29:43 +00001876 final TaskRecord task = new TaskRecord(stackSupervisor.mService, taskId, intent,
Dianne Hackborn79228822014-09-16 11:11:23 -07001877 affinityIntent, affinity, rootAffinity, realActivity, origActivity, rootHasReset,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001878 autoRemoveRecents, askedCompatMode, userId, effectiveUid, lastDescription,
Winson Chungfb44d212017-10-04 11:39:10 -07001879 activities, lastTimeOnTop, neverRelinquishIdentity, taskDescription,
1880 taskAffiliation, prevTaskId, nextTaskId, taskAffiliationColor, callingUid,
Charles He2bf28322017-10-12 22:24:49 +01001881 callingPackage, resizeMode, supportsPictureInPicture, realActivitySuspended,
1882 userSetupComplete, minWidth, minHeight);
Filip Gruszczynskiaff7f132015-09-02 17:21:21 -07001883 task.updateOverrideConfiguration(bounds);
Craig Mautner21d24a22014-04-23 11:45:37 -07001884
1885 for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001886 activities.get(activityNdx).setTask(task);
Craig Mautner21d24a22014-04-23 11:45:37 -07001887 }
1888
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001889 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Restored task=" + task);
Craig Mautner21d24a22014-04-23 11:45:37 -07001890 return task;
1891 }
1892
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001893 private void adjustForMinimalTaskDimensions(Rect bounds) {
1894 if (bounds == null) {
1895 return;
1896 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001897 int minWidth = mMinWidth;
1898 int minHeight = mMinHeight;
Robert Carr9c5867d2016-03-10 15:52:46 -08001899 // If the task has no requested minimal size, we'd like to enforce a minimal size
1900 // so that the user can not render the task too small to manipulate. We don't need
1901 // to do this for the pinned stack as the bounds are controlled by the system.
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001902 if (!inPinnedWindowingMode()) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001903 if (minWidth == INVALID_MIN_SIZE) {
1904 minWidth = mService.mStackSupervisor.mDefaultMinSizeOfResizeableTask;
Andrii Kulian2e751b82016-03-16 16:59:32 -07001905 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001906 if (minHeight == INVALID_MIN_SIZE) {
1907 minHeight = mService.mStackSupervisor.mDefaultMinSizeOfResizeableTask;
Andrii Kulian2e751b82016-03-16 16:59:32 -07001908 }
Robert Carr9c5867d2016-03-10 15:52:46 -08001909 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001910 final boolean adjustWidth = minWidth > bounds.width();
1911 final boolean adjustHeight = minHeight > bounds.height();
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001912 if (!(adjustWidth || adjustHeight)) {
1913 return;
1914 }
1915
1916 if (adjustWidth) {
1917 if (mBounds != null && bounds.right == mBounds.right) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001918 bounds.left = bounds.right - minWidth;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001919 } else {
1920 // Either left bounds match, or neither match, or the previous bounds were
1921 // fullscreen and we default to keeping left.
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001922 bounds.right = bounds.left + minWidth;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001923 }
1924 }
1925 if (adjustHeight) {
1926 if (mBounds != null && bounds.bottom == mBounds.bottom) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001927 bounds.top = bounds.bottom - minHeight;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001928 } else {
1929 // Either top bounds match, or neither match, or the previous bounds were
1930 // fullscreen and we default to keeping top.
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001931 bounds.bottom = bounds.top + minHeight;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001932 }
1933 }
1934 }
1935
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001936 /**
Winson Chung5af42fc2017-03-24 17:11:33 -07001937 * @return a new Configuration for this Task, given the provided {@param bounds} and
1938 * {@param insetBounds}.
1939 */
1940 Configuration computeNewOverrideConfigurationForBounds(Rect bounds, Rect insetBounds) {
1941 // Compute a new override configuration for the given bounds, if fullscreen bounds
1942 // (bounds == null), then leave the override config unset
1943 final Configuration newOverrideConfig = new Configuration();
1944 if (bounds != null) {
1945 newOverrideConfig.setTo(getOverrideConfiguration());
1946 mTmpRect.set(bounds);
1947 adjustForMinimalTaskDimensions(mTmpRect);
1948 computeOverrideConfiguration(newOverrideConfig, mTmpRect, insetBounds,
1949 mTmpRect.right != bounds.right, mTmpRect.bottom != bounds.bottom);
1950 }
1951
1952 return newOverrideConfig;
1953 }
1954
1955 /**
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001956 * Update task's override configuration based on the bounds.
Jorim Jaggi0a932142016-02-01 17:42:25 -08001957 * @param bounds The bounds of the task.
Andrii Kulian8072d112016-09-16 11:11:01 -07001958 * @return True if the override configuration was updated.
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001959 */
Andrii Kulian8072d112016-09-16 11:11:01 -07001960 boolean updateOverrideConfiguration(Rect bounds) {
Jorim Jaggi0a932142016-02-01 17:42:25 -08001961 return updateOverrideConfiguration(bounds, null /* insetBounds */);
1962 }
1963
1964 /**
1965 * Update task's override configuration based on the bounds.
1966 * @param bounds The bounds of the task.
1967 * @param insetBounds The bounds used to calculate the system insets, which is used here to
1968 * subtract the navigation bar/status bar size from the screen size reported
1969 * to the application. See {@link IActivityManager#resizeDockedStack}.
Andrii Kulian8072d112016-09-16 11:11:01 -07001970 * @return True if the override configuration was updated.
Jorim Jaggi0a932142016-02-01 17:42:25 -08001971 */
Andrii Kulian8072d112016-09-16 11:11:01 -07001972 boolean updateOverrideConfiguration(Rect bounds, @Nullable Rect insetBounds) {
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001973 if (Objects.equals(mBounds, bounds)) {
Andrii Kulian8072d112016-09-16 11:11:01 -07001974 return false;
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001975 }
Andrii Kulian1779e612016-10-12 21:58:25 -07001976 mTmpConfig.setTo(getOverrideConfiguration());
Wale Ogunwale5f986092015-12-04 15:35:38 -08001977 final boolean oldFullscreen = mFullscreen;
Andrii Kulian1779e612016-10-12 21:58:25 -07001978 final Configuration newConfig = getOverrideConfiguration();
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001979
1980 mFullscreen = bounds == null;
Wale Ogunwale3382ab12017-07-27 08:55:03 -07001981 final boolean persistBounds = getWindowConfiguration().persistTaskBounds();
Wale Ogunwale706ed792015-08-02 10:29:44 -07001982 if (mFullscreen) {
Wale Ogunwale3382ab12017-07-27 08:55:03 -07001983 if (mBounds != null && persistBounds) {
Wale Ogunwale706ed792015-08-02 10:29:44 -07001984 mLastNonFullscreenBounds = mBounds;
1985 }
1986 mBounds = null;
Andrii Kulian1779e612016-10-12 21:58:25 -07001987 newConfig.unset();
Wale Ogunwale706ed792015-08-02 10:29:44 -07001988 } else {
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001989 mTmpRect.set(bounds);
1990 adjustForMinimalTaskDimensions(mTmpRect);
Chong Zhangb15758a2015-11-17 12:12:03 -08001991 if (mBounds == null) {
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001992 mBounds = new Rect(mTmpRect);
Chong Zhangb15758a2015-11-17 12:12:03 -08001993 } else {
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001994 mBounds.set(mTmpRect);
Chong Zhangb15758a2015-11-17 12:12:03 -08001995 }
Wale Ogunwale3382ab12017-07-27 08:55:03 -07001996 if (mStack == null || persistBounds) {
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -07001997 mLastNonFullscreenBounds = mBounds;
1998 }
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07001999 computeOverrideConfiguration(newConfig, mTmpRect, insetBounds,
Andrii Kuliandaea3572016-04-08 13:20:51 -07002000 mTmpRect.right != bounds.right, mTmpRect.bottom != bounds.bottom);
Wale Ogunwale706ed792015-08-02 10:29:44 -07002001 }
Andrii Kulian1779e612016-10-12 21:58:25 -07002002 onOverrideConfigurationChanged(newConfig);
Wale Ogunwale5f986092015-12-04 15:35:38 -08002003
2004 if (mFullscreen != oldFullscreen) {
Winson Chung5af42fc2017-03-24 17:11:33 -07002005 mService.mStackSupervisor.scheduleUpdateMultiWindowMode(this);
Wale Ogunwale5f986092015-12-04 15:35:38 -08002006 }
2007
Andrii Kulian1779e612016-10-12 21:58:25 -07002008 return !mTmpConfig.equals(newConfig);
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07002009 }
2010
Andrii Kulian1779e612016-10-12 21:58:25 -07002011 /** Clears passed config and fills it with new override values. */
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002012 // TODO(b/36505427): TaskRecord.computeOverrideConfiguration() is a utility method that doesn't
2013 // depend on task or stacks, but uses those object to get the display to base the calculation
2014 // on. Probably best to centralize calculations like this in ConfigurationContainer.
2015 void computeOverrideConfiguration(Configuration config, Rect bounds, Rect insetBounds,
Andrii Kuliana8a9bc52016-10-14 11:00:13 -07002016 boolean overrideWidth, boolean overrideHeight) {
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08002017 mTmpNonDecorBounds.set(bounds);
2018 mTmpStableBounds.set(bounds);
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08002019
Andrii Kulian1779e612016-10-12 21:58:25 -07002020 config.unset();
Winson Chungbdc646f2017-02-13 12:12:22 -08002021 final Configuration parentConfig = getParent().getConfiguration();
Bryce Lee7566d762017-03-30 09:34:15 -07002022
Andrii Kulian1779e612016-10-12 21:58:25 -07002023 final float density = parentConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08002024
Winson Chungbdc646f2017-02-13 12:12:22 -08002025 if (mStack != null) {
2026 final StackWindowController stackController = mStack.getWindowContainerController();
2027 stackController.adjustConfigurationForBounds(bounds, insetBounds,
2028 mTmpNonDecorBounds, mTmpStableBounds, overrideWidth, overrideHeight, density,
2029 config, parentConfig);
2030 } else {
Bryce Lee7566d762017-03-30 09:34:15 -07002031 throw new IllegalArgumentException("Expected stack when calculating override config");
Winson Chungbdc646f2017-02-13 12:12:22 -08002032 }
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08002033
Winson Chung60c1aba2017-03-14 17:47:42 -07002034 config.orientation = (config.screenWidthDp <= config.screenHeightDp)
2035 ? Configuration.ORIENTATION_PORTRAIT
2036 : Configuration.ORIENTATION_LANDSCAPE;
2037
Jorim Jaggi85639432016-05-06 17:27:55 -07002038 // For calculating screen layout, we need to use the non-decor inset screen area for the
2039 // calculation for compatibility reasons, i.e. screen area without system bars that could
2040 // never go away in Honeycomb.
Winson Chungbdc646f2017-02-13 12:12:22 -08002041 final int compatScreenWidthDp = (int) (mTmpNonDecorBounds.width() / density);
2042 final int compatScreenHeightDp = (int) (mTmpNonDecorBounds.height() / density);
Andrii Kulian1779e612016-10-12 21:58:25 -07002043 // We're only overriding LONG, SIZE and COMPAT parts of screenLayout, so we start override
2044 // calculation with partial default.
2045 final int sl = Configuration.SCREENLAYOUT_LONG_YES | Configuration.SCREENLAYOUT_SIZE_XLARGE;
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08002046 final int longSize = Math.max(compatScreenHeightDp, compatScreenWidthDp);
Andrii Kulian1779e612016-10-12 21:58:25 -07002047 final int shortSize = Math.min(compatScreenHeightDp, compatScreenWidthDp);
Jorim Jaggi85639432016-05-06 17:27:55 -07002048 config.screenLayout = Configuration.reduceScreenLayout(sl, longSize, shortSize);
2049
Jorim Jaggia95ca8d2016-01-15 22:54:46 -08002050 }
2051
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08002052 Rect updateOverrideConfigurationFromLaunchBounds() {
2053 final Rect bounds = validateBounds(getLaunchBounds());
2054 updateOverrideConfiguration(bounds);
Andrii Kulian73336d812016-03-24 12:56:08 -07002055 if (bounds != null) {
2056 bounds.set(mBounds);
2057 }
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08002058 return bounds;
2059 }
2060
2061 static Rect validateBounds(Rect bounds) {
2062 if (bounds != null && bounds.isEmpty()) {
2063 Slog.wtf(TAG, "Received strange task bounds: " + bounds, new Throwable());
2064 return null;
2065 }
2066 return bounds;
2067 }
2068
Wale Ogunwale935e5022015-11-10 12:36:10 -08002069 /** Updates the task's bounds and override configuration to match what is expected for the
2070 * input stack. */
2071 void updateOverrideConfigurationForStack(ActivityStack inStack) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07002072 if (mStack != null && mStack == inStack) {
Wale Ogunwale935e5022015-11-10 12:36:10 -08002073 return;
2074 }
2075
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002076 if (inStack.inFreeformWindowingMode()) {
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002077 if (!isResizeable()) {
Wale Ogunwale935e5022015-11-10 12:36:10 -08002078 throw new IllegalArgumentException("Can not position non-resizeable task="
2079 + this + " in stack=" + inStack);
2080 }
2081 if (mBounds != null) {
2082 return;
2083 }
2084 if (mLastNonFullscreenBounds != null) {
2085 updateOverrideConfiguration(mLastNonFullscreenBounds);
2086 } else {
Bryce Leedacefc42017-10-10 12:56:02 -07002087 mService.mStackSupervisor.getLaunchingBoundsController().layoutTask(this, null);
Wale Ogunwale935e5022015-11-10 12:36:10 -08002088 }
2089 } else {
2090 updateOverrideConfiguration(inStack.mBounds);
2091 }
2092 }
2093
Wale Ogunwale706ed792015-08-02 10:29:44 -07002094 /** Returns the bounds that should be used to launch this task. */
Wale Ogunwale3382ab12017-07-27 08:55:03 -07002095 private Rect getLaunchBounds() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07002096 if (mStack == null) {
Chong Zhang7d5f5102016-01-13 10:29:24 -08002097 return null;
2098 }
2099
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002100 final int windowingMode = getWindowingMode();
2101 if (!isActivityTypeStandardOrUndefined()
2102 || windowingMode == WINDOWING_MODE_FULLSCREEN
2103 || (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY && !isResizeable())) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07002104 return isResizeable() ? mStack.mBounds : null;
Wale Ogunwale3382ab12017-07-27 08:55:03 -07002105 } else if (!getWindowConfiguration().persistTaskBounds()) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07002106 return mStack.mBounds;
Wale Ogunwale706ed792015-08-02 10:29:44 -07002107 }
2108 return mLastNonFullscreenBounds;
2109 }
2110
Jorim Jaggi8b702ed2017-01-20 16:59:03 +01002111 void addStartingWindowsForVisibleActivities(boolean taskSwitch) {
2112 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
2113 final ActivityRecord r = mActivities.get(activityNdx);
2114 if (r.visible) {
2115 r.showStartingWindow(null /* prev */, false /* newTask */, taskSwitch);
2116 }
2117 }
2118 }
2119
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002120 void dump(PrintWriter pw, String prefix) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002121 pw.print(prefix); pw.print("userId="); pw.print(userId);
Dianne Hackborn885fbe52014-08-23 15:23:58 -07002122 pw.print(" effectiveUid="); UserHandle.formatUid(pw, effectiveUid);
2123 pw.print(" mCallingUid="); UserHandle.formatUid(pw, mCallingUid);
Suprabh Shukla7745c142016-03-07 18:21:10 -08002124 pw.print(" mUserSetupComplete="); pw.print(mUserSetupComplete);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002125 pw.print(" mCallingPackage="); pw.println(mCallingPackage);
Dianne Hackborn79228822014-09-16 11:11:23 -07002126 if (affinity != null || rootAffinity != null) {
2127 pw.print(prefix); pw.print("affinity="); pw.print(affinity);
2128 if (affinity == null || !affinity.equals(rootAffinity)) {
2129 pw.print(" root="); pw.println(rootAffinity);
2130 } else {
2131 pw.println();
2132 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002133 }
Dianne Hackborn91097de2014-04-04 18:02:06 -07002134 if (voiceSession != null || voiceInteractor != null) {
2135 pw.print(prefix); pw.print("VOICE: session=0x");
2136 pw.print(Integer.toHexString(System.identityHashCode(voiceSession)));
2137 pw.print(" interactor=0x");
2138 pw.println(Integer.toHexString(System.identityHashCode(voiceInteractor)));
2139 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002140 if (intent != null) {
2141 StringBuilder sb = new StringBuilder(128);
2142 sb.append(prefix); sb.append("intent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08002143 intent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002144 sb.append('}');
2145 pw.println(sb.toString());
2146 }
2147 if (affinityIntent != null) {
2148 StringBuilder sb = new StringBuilder(128);
2149 sb.append(prefix); sb.append("affinityIntent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08002150 affinityIntent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002151 sb.append('}');
2152 pw.println(sb.toString());
2153 }
2154 if (origActivity != null) {
2155 pw.print(prefix); pw.print("origActivity=");
2156 pw.println(origActivity.flattenToShortString());
2157 }
2158 if (realActivity != null) {
2159 pw.print(prefix); pw.print("realActivity=");
2160 pw.println(realActivity.flattenToShortString());
2161 }
Wale Ogunwale66e16852017-10-19 13:35:52 -07002162 if (autoRemoveRecents || isPersistable || !isActivityTypeStandard() || numFullscreen != 0) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002163 pw.print(prefix); pw.print("autoRemoveRecents="); pw.print(autoRemoveRecents);
Dianne Hackborn852975d2014-08-22 17:42:43 -07002164 pw.print(" isPersistable="); pw.print(isPersistable);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002165 pw.print(" numFullscreen="); pw.print(numFullscreen);
Wale Ogunwale66e16852017-10-19 13:35:52 -07002166 pw.print(" activityType="); pw.println(getActivityType());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002167 }
Craig Mautner432f64e2015-05-20 14:59:57 -07002168 if (rootWasReset || mNeverRelinquishIdentity || mReuseTask
2169 || mLockTaskAuth != LOCK_TASK_AUTH_PINNABLE) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002170 pw.print(prefix); pw.print("rootWasReset="); pw.print(rootWasReset);
2171 pw.print(" mNeverRelinquishIdentity="); pw.print(mNeverRelinquishIdentity);
Craig Mautner432f64e2015-05-20 14:59:57 -07002172 pw.print(" mReuseTask="); pw.print(mReuseTask);
2173 pw.print(" mLockTaskAuth="); pw.println(lockTaskAuthToString());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002174 }
Wale Ogunwale18795a22014-12-03 11:38:33 -08002175 if (mAffiliatedTaskId != taskId || mPrevAffiliateTaskId != INVALID_TASK_ID
2176 || mPrevAffiliate != null || mNextAffiliateTaskId != INVALID_TASK_ID
2177 || mNextAffiliate != null) {
Dianne Hackborn852975d2014-08-22 17:42:43 -07002178 pw.print(prefix); pw.print("affiliation="); pw.print(mAffiliatedTaskId);
2179 pw.print(" prevAffiliation="); pw.print(mPrevAffiliateTaskId);
2180 pw.print(" (");
2181 if (mPrevAffiliate == null) {
2182 pw.print("null");
2183 } else {
2184 pw.print(Integer.toHexString(System.identityHashCode(mPrevAffiliate)));
2185 }
2186 pw.print(") nextAffiliation="); pw.print(mNextAffiliateTaskId);
2187 pw.print(" (");
2188 if (mNextAffiliate == null) {
2189 pw.print("null");
2190 } else {
2191 pw.print(Integer.toHexString(System.identityHashCode(mNextAffiliate)));
2192 }
2193 pw.println(")");
2194 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002195 pw.print(prefix); pw.print("Activities="); pw.println(mActivities);
Dianne Hackborn852975d2014-08-22 17:42:43 -07002196 if (!askedCompatMode || !inRecents || !isAvailable) {
2197 pw.print(prefix); pw.print("askedCompatMode="); pw.print(askedCompatMode);
2198 pw.print(" inRecents="); pw.print(inRecents);
2199 pw.print(" isAvailable="); pw.println(isAvailable);
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002200 }
Dianne Hackborn852975d2014-08-22 17:42:43 -07002201 if (lastDescription != null) {
2202 pw.print(prefix); pw.print("lastDescription="); pw.println(lastDescription);
2203 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07002204 pw.print(prefix); pw.print("stackId="); pw.println(getStackId());
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002205 pw.print(prefix + "hasBeenVisible=" + hasBeenVisible);
2206 pw.print(" mResizeMode=" + ActivityInfo.resizeModeToString(mResizeMode));
Winson Chungd3395382016-12-13 11:49:09 -08002207 pw.print(" mSupportsPictureInPicture=" + mSupportsPictureInPicture);
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002208 pw.print(" isResizeable=" + isResizeable());
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002209 pw.print(" lastActiveTime=" + lastActiveTime);
2210 pw.println(" (inactive for " + (getInactiveDuration() / 1000) + "s)");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002211 }
2212
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002213 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002214 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002215 StringBuilder sb = new StringBuilder(128);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002216 if (stringName != null) {
2217 sb.append(stringName);
2218 sb.append(" U=");
2219 sb.append(userId);
Wale Ogunwale6c5eb1c2015-11-10 07:52:22 -08002220 sb.append(" StackId=");
Andrii Kulian02b7a832016-10-06 23:11:56 -07002221 sb.append(getStackId());
Craig Mautnerde4ef022013-04-07 19:01:33 -07002222 sb.append(" sz=");
2223 sb.append(mActivities.size());
2224 sb.append('}');
2225 return sb.toString();
2226 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002227 sb.append("TaskRecord{");
2228 sb.append(Integer.toHexString(System.identityHashCode(this)));
2229 sb.append(" #");
2230 sb.append(taskId);
2231 if (affinity != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002232 sb.append(" A=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002233 sb.append(affinity);
2234 } else if (intent != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002235 sb.append(" I=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002236 sb.append(intent.getComponent().flattenToShortString());
2237 } else if (affinityIntent != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002238 sb.append(" aI=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002239 sb.append(affinityIntent.getComponent().flattenToShortString());
2240 } else {
2241 sb.append(" ??");
2242 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07002243 stringName = sb.toString();
2244 return toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002245 }
Steven Timotius4346f0a2017-09-12 11:07:21 -07002246
2247 public void writeToProto(ProtoOutputStream proto, long fieldId) {
2248 final long token = proto.start(fieldId);
Adrian Roos4921ccf2017-09-28 16:54:06 +02002249 super.writeToProto(proto, CONFIGURATION_CONTAINER, false /* trim */);
Steven Timotius4346f0a2017-09-12 11:07:21 -07002250 proto.write(ID, taskId);
2251 for (int i = mActivities.size() - 1; i >= 0; i--) {
2252 ActivityRecord activity = mActivities.get(i);
2253 activity.writeToProto(proto, ACTIVITIES);
2254 }
2255 proto.write(STACK_ID, mStack.mStackId);
2256 if (mLastNonFullscreenBounds != null) {
2257 mLastNonFullscreenBounds.writeToProto(proto, LAST_NON_FULLSCREEN_BOUNDS);
2258 }
2259 if (realActivity != null) {
2260 proto.write(REAL_ACTIVITY, realActivity.flattenToShortString());
2261 }
2262 if (origActivity != null) {
2263 proto.write(ORIG_ACTIVITY, origActivity.flattenToShortString());
2264 }
2265 proto.write(ACTIVITY_TYPE, getActivityType());
Steven Timotius4346f0a2017-09-12 11:07:21 -07002266 proto.write(RESIZE_MODE, mResizeMode);
2267 proto.write(FULLSCREEN, mFullscreen);
2268 if (mBounds != null) {
2269 mBounds.writeToProto(proto, BOUNDS);
2270 }
2271 proto.write(MIN_WIDTH, mMinWidth);
2272 proto.write(MIN_HEIGHT, mMinHeight);
2273 proto.end(token);
2274 }
Winson Chung61c9e5a2017-10-11 10:39:32 -07002275
2276 /**
2277 * See {@link #getNumRunningActivities(TaskActivitiesReport)}.
2278 */
2279 static class TaskActivitiesReport {
2280 int numRunning;
2281 int numActivities;
2282 ActivityRecord top;
2283 ActivityRecord base;
2284
2285 void reset() {
2286 numRunning = numActivities = 0;
2287 top = base = null;
2288 }
2289 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002290}