blob: 9e09cbbfb0c7fbc13b6e4d3596974004fffe5500 [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
Jorim Jaggi0a932142016-02-01 17:42:25 -080019import android.annotation.Nullable;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -070020import android.app.Activity;
Craig Mautner9db9a0b2013-04-29 17:05:56 -070021import android.app.ActivityManager;
Wale Ogunwale3797c222015-10-27 14:21:58 -070022import android.app.ActivityManager.StackId;
Craig Mautner648f69b2014-09-18 14:16:26 -070023import android.app.ActivityManager.TaskDescription;
Jorim Jaggie2c77f92016-12-29 14:57:22 +010024import android.app.ActivityManager.TaskSnapshot;
Wale Ogunwaleff3c66c2015-11-18 19:22:49 -080025import android.app.ActivityManager.TaskThumbnail;
Winsonc809cbb2015-11-02 12:06:15 -080026import android.app.ActivityManager.TaskThumbnailInfo;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -070027import android.app.ActivityOptions;
Dianne Hackborn885fbe52014-08-23 15:23:58 -070028import android.app.AppGlobals;
Jorim Jaggi0a932142016-02-01 17:42:25 -080029import android.app.IActivityManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import android.content.ComponentName;
31import android.content.Intent;
32import android.content.pm.ActivityInfo;
Dianne Hackborn885fbe52014-08-23 15:23:58 -070033import android.content.pm.ApplicationInfo;
34import android.content.pm.IPackageManager;
35import android.content.pm.PackageManager;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -070036import android.content.res.Configuration;
Craig Mautner9db9a0b2013-04-29 17:05:56 -070037import android.graphics.Bitmap;
Jorim Jaggi02886a82016-12-06 09:10:06 -080038import android.graphics.GraphicBuffer;
Winsonc809cbb2015-11-02 12:06:15 -080039import android.graphics.Point;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -070040import android.graphics.Rect;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -070041import android.os.Debug;
Craig Mautnerc0ffce52014-07-01 12:38:52 -070042import android.os.ParcelFileDescriptor;
Dianne Hackborn885fbe52014-08-23 15:23:58 -070043import android.os.RemoteException;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -080044import android.os.Trace;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070045import android.os.UserHandle;
Suprabh Shukla7745c142016-03-07 18:21:10 -080046import android.provider.Settings;
Dianne Hackborn91097de2014-04-04 18:02:06 -070047import android.service.voice.IVoiceInteractionSession;
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -070048import android.util.DisplayMetrics;
Dianne Hackborn7f96b792012-05-29 18:46:45 -070049import android.util.Slog;
Suprabh Shukla23593142015-11-03 17:31:15 -080050
Dianne Hackborn91097de2014-04-04 18:02:06 -070051import com.android.internal.app.IVoiceInteractor;
Craig Mautner21d24a22014-04-23 11:45:37 -070052import com.android.internal.util.XmlUtils;
Suprabh Shukla23593142015-11-03 17:31:15 -080053
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -080054import com.android.server.wm.AppWindowContainerController;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -080055import com.android.server.wm.TaskWindowContainerController;
Jorim Jaggifb9d78a2017-01-05 18:57:12 +010056import com.android.server.wm.TaskWindowContainerListener;
57
Craig Mautner21d24a22014-04-23 11:45:37 -070058import org.xmlpull.v1.XmlPullParser;
59import org.xmlpull.v1.XmlPullParserException;
60import org.xmlpull.v1.XmlSerializer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061
Craig Mautnerc0ffce52014-07-01 12:38:52 -070062import java.io.File;
Craig Mautner21d24a22014-04-23 11:45:37 -070063import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064import java.io.PrintWriter;
Craig Mautner5d9c7be2013-02-15 14:02:56 -080065import java.util.ArrayList;
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -070066import java.util.Objects;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -080068import static android.app.ActivityManager.RESIZE_MODE_FORCED;
Jorim Jaggi0a932142016-02-01 17:42:25 -080069import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
70import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
71import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
72import static android.app.ActivityManager.StackId.HOME_STACK_ID;
73import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
74import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
Matthew Ngae1ff4f2016-11-10 15:49:14 -080075import static android.app.ActivityManager.StackId.RECENTS_STACK_ID;
Jorim Jaggi0a932142016-02-01 17:42:25 -080076import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
77import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
Jiaquan Hedd1e66f2016-06-15 15:15:12 -070078import static android.content.pm.ActivityInfo.FLAG_ON_TOP_LAUNCHER;
Wale Ogunwale3eadad72016-10-13 09:16:59 -070079import static android.content.pm.ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY;
Jorim Jaggi0a932142016-02-01 17:42:25 -080080import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
81import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
82import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
83import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER;
skuhne@google.com322347b2016-12-02 12:54:03 -080084import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY;
85import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PORTRAIT_ONLY;
86import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PRESERVE_ORIENTATION;
Wale Ogunwaled829d362016-02-10 19:24:49 -080087import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
Wale Ogunwale625ed0c2016-10-18 08:50:31 -070088import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
Winson Chungd3395382016-12-13 11:49:09 -080089import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_AND_PIPABLE_DEPRECATED;
Wale Ogunwale625ed0c2016-10-18 08:50:31 -070090import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
Jorim Jaggi0a932142016-02-01 17:42:25 -080091import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -080092import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
Suprabh Shukla7745c142016-03-07 18:21:10 -080093import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
Jorim Jaggi0a932142016-02-01 17:42:25 -080094import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ADD_REMOVE;
95import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
96import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
97import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
98import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_ADD_REMOVE;
99import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
100import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
101import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS;
102import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
103import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
Jorim Jaggi0a932142016-02-01 17:42:25 -0800104import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
105import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
106import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
Wale Ogunwale3b232392016-05-13 15:37:13 -0700107import static com.android.server.am.ActivityRecord.STARTING_WINDOW_SHOWN;
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800108import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING;
109import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800110import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
Jorim Jaggi0a932142016-02-01 17:42:25 -0800111
Jorim Jaggifb9d78a2017-01-05 18:57:12 +0100112final class TaskRecord extends ConfigurationContainer implements TaskWindowContainerListener {
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800113 private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskRecord" : TAG_AM;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -0700114 private static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700115 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
Craig Mautnere0570202015-05-13 13:06:11 -0700116 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700117 private static final String TAG_TASKS = TAG + POSTFIX_TASKS;
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800118
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700119 private static final String ATTR_TASKID = "task_id";
Craig Mautner21d24a22014-04-23 11:45:37 -0700120 private static final String TAG_INTENT = "intent";
121 private static final String TAG_AFFINITYINTENT = "affinity_intent";
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700122 private static final String ATTR_REALACTIVITY = "real_activity";
123 private static final String ATTR_REALACTIVITY_SUSPENDED = "real_activity_suspended";
Craig Mautner21d24a22014-04-23 11:45:37 -0700124 private static final String ATTR_ORIGACTIVITY = "orig_activity";
Stefan Kuhnee88d1e52015-05-18 10:33:45 -0700125 private static final String TAG_ACTIVITY = "activity";
Craig Mautner21d24a22014-04-23 11:45:37 -0700126 private static final String ATTR_AFFINITY = "affinity";
Dianne Hackborn79228822014-09-16 11:11:23 -0700127 private static final String ATTR_ROOT_AFFINITY = "root_affinity";
Craig Mautner21d24a22014-04-23 11:45:37 -0700128 private static final String ATTR_ROOTHASRESET = "root_has_reset";
Dianne Hackborn13420f22014-07-18 15:43:56 -0700129 private static final String ATTR_AUTOREMOVERECENTS = "auto_remove_recents";
Craig Mautner21d24a22014-04-23 11:45:37 -0700130 private static final String ATTR_ASKEDCOMPATMODE = "asked_compat_mode";
131 private static final String ATTR_USERID = "user_id";
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800132 private static final String ATTR_USER_SETUP_COMPLETE = "user_setup_complete";
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700133 private static final String ATTR_EFFECTIVE_UID = "effective_uid";
Craig Mautner21d24a22014-04-23 11:45:37 -0700134 private static final String ATTR_TASKTYPE = "task_type";
Winson Chungffa2ec62014-07-03 15:54:42 -0700135 private static final String ATTR_FIRSTACTIVETIME = "first_active_time";
Winson Chungf1fbd772014-06-24 18:06:58 -0700136 private static final String ATTR_LASTACTIVETIME = "last_active_time";
Craig Mautner21d24a22014-04-23 11:45:37 -0700137 private static final String ATTR_LASTDESCRIPTION = "last_description";
138 private static final String ATTR_LASTTIMEMOVED = "last_time_moved";
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700139 private static final String ATTR_NEVERRELINQUISH = "never_relinquish_identity";
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700140 private static final String ATTR_TASK_AFFILIATION = "task_affiliation";
Craig Mautnera228ae92014-07-09 05:44:55 -0700141 private static final String ATTR_PREV_AFFILIATION = "prev_affiliation";
142 private static final String ATTR_NEXT_AFFILIATION = "next_affiliation";
Winson Chungec396d62014-08-06 17:08:00 -0700143 private static final String ATTR_TASK_AFFILIATION_COLOR = "task_affiliation_color";
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700144 private static final String ATTR_CALLING_UID = "calling_uid";
145 private static final String ATTR_CALLING_PACKAGE = "calling_package";
Winson Chungd3395382016-12-13 11:49:09 -0800146 private static final String ATTR_SUPPORTS_PICTURE_IN_PICTURE = "supports_picture_in_picture";
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800147 private static final String ATTR_RESIZE_MODE = "resize_mode";
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700148 private static final String ATTR_PRIVILEGED = "privileged";
Wale Ogunwale706ed792015-08-02 10:29:44 -0700149 private static final String ATTR_NON_FULLSCREEN_BOUNDS = "non_fullscreen_bounds";
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700150 private static final String ATTR_MIN_WIDTH = "min_width";
151 private static final String ATTR_MIN_HEIGHT = "min_height";
Wale Ogunwale625ed0c2016-10-18 08:50:31 -0700152 private static final String ATTR_PERSIST_TASK_VERSION = "persist_task_version";
Andrii Kulian18d75122016-03-27 20:20:28 -0700153
Wale Ogunwale625ed0c2016-10-18 08:50:31 -0700154 // Current version of the task record we persist. Used to check if we need to run any upgrade
155 // code.
156 private static final int PERSIST_TASK_VERSION = 1;
Craig Mautner21d24a22014-04-23 11:45:37 -0700157 private static final String TASK_THUMBNAIL_SUFFIX = "_task_thumbnail";
158
Wale Ogunwale18795a22014-12-03 11:38:33 -0800159 static final int INVALID_TASK_ID = -1;
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700160 private static final int INVALID_MIN_SIZE = -1;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800161
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162 final int taskId; // Unique identifier for this task.
Dianne Hackborn79228822014-09-16 11:11:23 -0700163 String affinity; // The affinity name for this task, or null; may change identity.
164 String rootAffinity; // Initial base affinity, or null; does not change from initial root.
Dianne Hackborn91097de2014-04-04 18:02:06 -0700165 final IVoiceInteractionSession voiceSession; // Voice interaction session driving task
166 final IVoiceInteractor voiceInteractor; // Associated interactor to provide to app
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800167 Intent intent; // The original intent that started the task.
168 Intent affinityIntent; // Intent of affinity-moved activity that started this task.
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700169 int effectiveUid; // The current effective uid of the identity of this task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170 ComponentName origActivity; // The non-alias activity component of the intent.
171 ComponentName realActivity; // The actual activity component that started the task.
Andrei Stingaceanu4ccec532016-01-13 12:10:21 +0000172 boolean realActivitySuspended; // True if the actual activity component that started the
173 // task is suspended.
Winson Chung36f3f032016-09-08 23:29:43 +0000174 long firstActiveTime; // First time this task was active.
175 long lastActiveTime; // Last time this task was active, including sleep.
Dianne Hackborn852975d2014-08-22 17:42:43 -0700176 boolean inRecents; // Actually in the recents list?
177 boolean isAvailable; // Is the activity available to be launched?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800178 boolean rootWasReset; // True if the intent at the root of the task had
179 // the FLAG_ACTIVITY_RESET_TASK_IF_NEEDED flag.
Dianne Hackborn13420f22014-07-18 15:43:56 -0700180 boolean autoRemoveRecents; // If true, we should automatically remove the task from
181 // recents when activity finishes
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700182 boolean askedCompatMode;// Have asked the user about compat mode for this task.
Dianne Hackbornd38aed82014-06-10 21:36:35 -0700183 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 -0800184
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700185 String stringName; // caching of toString() result.
Dianne Hackborn9da2d402012-03-15 13:43:08 -0700186 int userId; // user for which this task was created
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800187 boolean mUserSetupComplete; // The user set-up is complete as of the last time the task activity
188 // was changed.
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800189
190 int numFullscreen; // Number of fullscreen activities.
191
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800192 int mResizeMode; // The resize mode of this task and its activities.
193 // Based on the {@link ActivityInfo#resizeMode} of the root activity.
Winson Chungd3395382016-12-13 11:49:09 -0800194 boolean mSupportsPictureInPicture; // Whether or not this task and its activities support PiP.
195 // Based on the {@link ActivityInfo#FLAG_SUPPORTS_PICTURE_IN_PICTURE} flag of the root
196 // activity.
Jorim Jaggi8202b2a2016-02-03 19:24:31 -0800197 boolean mTemporarilyUnresizable; // Separate flag from mResizeMode used to suppress resize
198 // changes on a temporary basis.
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700199 private int mLockTaskMode; // Which tasklock mode to launch this task in. One of
200 // ActivityManager.LOCK_TASK_LAUNCH_MODE_*
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700201 private boolean mPrivileged; // The root activity application of this task holds
202 // privileged permissions.
Jiaquan Hedd1e66f2016-06-15 15:15:12 -0700203 private boolean mIsOnTopLauncher; // Whether this task is an on-top launcher. See
204 // android.R.attr#onTopLauncher.
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700205
Craig Mautner15df08a2015-04-01 12:17:18 -0700206 /** Can't be put in lockTask mode. */
207 final static int LOCK_TASK_AUTH_DONT_LOCK = 0;
Benjamin Franz469dd582015-06-09 14:24:36 +0100208 /** Can enter app pinning with user approval. Can never start over existing lockTask task. */
Craig Mautner15df08a2015-04-01 12:17:18 -0700209 final static int LOCK_TASK_AUTH_PINNABLE = 1;
210 /** Starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing lockTask task. */
211 final static int LOCK_TASK_AUTH_LAUNCHABLE = 2;
Benjamin Franz469dd582015-06-09 14:24:36 +0100212 /** Can enter lockTask without user approval. Can start over existing lockTask task. */
Craig Mautner15df08a2015-04-01 12:17:18 -0700213 final static int LOCK_TASK_AUTH_WHITELISTED = 3;
Benjamin Franz469dd582015-06-09 14:24:36 +0100214 /** Priv-app that starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing
215 * lockTask task. */
216 final static int LOCK_TASK_AUTH_LAUNCHABLE_PRIV = 4;
Craig Mautner15df08a2015-04-01 12:17:18 -0700217 int mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE;
218
219 int mLockTaskUid = -1; // The uid of the application that called startLockTask().
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800220
Winson Chung03a9bae2014-05-02 09:56:12 -0700221 // This represents the last resolved activity values for this task
222 // NOTE: This value needs to be persisted with each task
Craig Mautner648f69b2014-09-18 14:16:26 -0700223 TaskDescription lastTaskDescription = new TaskDescription();
Winson Chung03a9bae2014-05-02 09:56:12 -0700224
Craig Mautnerd2328952013-03-05 12:46:26 -0800225 /** List of all activities in the task arranged in history order */
Craig Mautner21d24a22014-04-23 11:45:37 -0700226 final ArrayList<ActivityRecord> mActivities;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800227
Andrii Kulian02b7a832016-10-06 23:11:56 -0700228 /** Current stack. Setter must always be used to update the value. */
229 private ActivityStack mStack;
Craig Mautnerd2328952013-03-05 12:46:26 -0800230
Craig Mautner2c1faed2013-07-23 12:56:02 -0700231 /** Takes on same set of values as ActivityRecord.mActivityType */
Craig Mautner21d24a22014-04-23 11:45:37 -0700232 int taskType;
Craig Mautner1602ec22013-05-12 10:24:27 -0700233
Craig Mautner21d24a22014-04-23 11:45:37 -0700234 /** Takes on same value as first root activity */
235 boolean isPersistable = false;
Craig Mautnerffcfcaa2014-06-05 09:54:38 -0700236 int maxRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700237
238 /** Only used for persistable tasks, otherwise 0. The last time this task was moved. Used for
239 * determining the order when restoring. Sign indicates whether last task movement was to front
240 * (positive) or back (negative). Absolute value indicates time. */
241 long mLastTimeMoved = System.currentTimeMillis();
242
Craig Mautner84984fa2014-06-19 11:19:20 -0700243 /** Indication of what to run next when task exits. Use ActivityRecord types.
244 * ActivityRecord.APPLICATION_ACTIVITY_TYPE indicates to resume the task below this one in the
245 * task stack. */
246 private int mTaskToReturnTo = APPLICATION_ACTIVITY_TYPE;
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700247
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700248 /** If original intent did not allow relinquishing task identity, save that information */
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700249 private boolean mNeverRelinquishIdentity = true;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700250
Craig Mautner362449a2014-06-20 14:04:39 -0700251 // Used in the unique case where we are clearing the task in order to reuse it. In that case we
252 // do not want to delete the stack when the task goes empty.
Filip Gruszczynskibe9dabd2016-01-19 12:23:10 -0800253 private boolean mReuseTask = false;
Craig Mautner362449a2014-06-20 14:04:39 -0700254
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700255 private Bitmap mLastThumbnail; // Last thumbnail captured for this item.
Wale Ogunwalebe23ff42014-10-21 16:29:51 -0700256 private final File mLastThumbnailFile; // File containing last thumbnail.
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700257 private final String mFilename;
Winsonc809cbb2015-11-02 12:06:15 -0800258 private TaskThumbnailInfo mLastThumbnailInfo;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700259 CharSequence lastDescription; // Last description captured for this item.
260
Craig Mautnera228ae92014-07-09 05:44:55 -0700261 int mAffiliatedTaskId; // taskId of parent affiliation or self if no parent.
Winson Chungec396d62014-08-06 17:08:00 -0700262 int mAffiliatedTaskColor; // color of the parent task affiliation.
Craig Mautnera228ae92014-07-09 05:44:55 -0700263 TaskRecord mPrevAffiliate; // previous task in affiliated chain.
Wale Ogunwale18795a22014-12-03 11:38:33 -0800264 int mPrevAffiliateTaskId = INVALID_TASK_ID; // previous id for persistence.
Craig Mautnera228ae92014-07-09 05:44:55 -0700265 TaskRecord mNextAffiliate; // next task in affiliated chain.
Wale Ogunwale18795a22014-12-03 11:38:33 -0800266 int mNextAffiliateTaskId = INVALID_TASK_ID; // next id for persistence.
Craig Mautnera228ae92014-07-09 05:44:55 -0700267
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700268 // For relaunching the task from recents as though it was launched by the original launcher.
269 int mCallingUid;
270 String mCallingPackage;
271
Craig Mautner21d24a22014-04-23 11:45:37 -0700272 final ActivityManagerService mService;
273
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700274 // Whether or not this task covers the entire screen; by default tasks are fullscreen.
275 boolean mFullscreen = true;
276
277 // Bounds of the Task. null for fullscreen tasks.
278 Rect mBounds = null;
Jorim Jaggi82c9dc92016-02-05 15:10:33 -0800279 private final Rect mTmpStableBounds = new Rect();
280 private final Rect mTmpNonDecorBounds = new Rect();
Wale Ogunwale9a08f822016-02-17 19:03:58 -0800281 private final Rect mTmpRect = new Rect();
Jorim Jaggi0a932142016-02-01 17:42:25 -0800282 private final Rect mTmpRect2 = new Rect();
283
Wale Ogunwale706ed792015-08-02 10:29:44 -0700284 // Last non-fullscreen bounds the task was launched in or resized to.
285 // The information is persisted and used to determine the appropriate stack to launch the
286 // task into on restore.
287 Rect mLastNonFullscreenBounds = null;
Andrii Kulian2e751b82016-03-16 16:59:32 -0700288 // Minimal width and height of this task when it's resizeable. -1 means it should use the
289 // default minimal width/height.
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700290 int mMinWidth;
291 int mMinHeight;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700292
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700293 // Ranking (from top) of this task among all visible tasks. (-1 means it's not visible)
294 // This number will be assigned when we evaluate OOM scores for all visible tasks.
295 int mLayerRank = -1;
296
Andrii Kulian1779e612016-10-12 21:58:25 -0700297 /** Helper object used for updating override configuration. */
298 private Configuration mTmpConfig = new Configuration();
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700299
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800300 private TaskWindowContainerController mWindowContainerController;
301
Craig Mautner21d24a22014-04-23 11:45:37 -0700302 TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Wale Ogunwale72919d22016-12-08 18:58:50 -0800303 IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor, int type) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700304 mService = service;
Craig Mautnera228ae92014-07-09 05:44:55 -0700305 mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
306 TaskPersister.IMAGE_EXTENSION;
Suprabh Shukla23593142015-11-03 17:31:15 -0800307 userId = UserHandle.getUserId(info.applicationInfo.uid);
308 mLastThumbnailFile = new File(TaskPersister.getUserImagesDir(userId), mFilename);
Winsonc809cbb2015-11-02 12:06:15 -0800309 mLastThumbnailInfo = new TaskThumbnailInfo();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800310 taskId = _taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700311 mAffiliatedTaskId = _taskId;
Dianne Hackborn91097de2014-04-04 18:02:06 -0700312 voiceSession = _voiceSession;
313 voiceInteractor = _voiceInteractor;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700314 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800315 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700316 mCallingUid = info.applicationInfo.uid;
317 mCallingPackage = info.packageName;
Wale Ogunwale72919d22016-12-08 18:58:50 -0800318 taskType = type;
Martijn Coenend4a69702014-06-30 11:12:17 -0700319 setIntent(_intent, info);
Andrii Kulian2e751b82016-03-16 16:59:32 -0700320 setMinDimensions(info);
Winson730bf062016-03-31 18:04:56 -0700321 touchActiveTime();
Yorke Leebd54c2a2016-10-25 13:49:23 -0700322 mService.mTaskChangeNotificationController.notifyTaskCreated(_taskId, realActivity);
Craig Mautner21d24a22014-04-23 11:45:37 -0700323 }
324
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700325 TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Winsonc809cbb2015-11-02 12:06:15 -0800326 TaskDescription _taskDescription, TaskThumbnailInfo thumbnailInfo) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700327 mService = service;
328 mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
329 TaskPersister.IMAGE_EXTENSION;
Suprabh Shukla23593142015-11-03 17:31:15 -0800330 userId = UserHandle.getUserId(info.applicationInfo.uid);
331 mLastThumbnailFile = new File(TaskPersister.getUserImagesDir(userId), mFilename);
Winsonc809cbb2015-11-02 12:06:15 -0800332 mLastThumbnailInfo = thumbnailInfo;
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700333 taskId = _taskId;
334 mAffiliatedTaskId = _taskId;
335 voiceSession = null;
336 voiceInteractor = null;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700337 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800338 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700339 mCallingUid = info.applicationInfo.uid;
340 mCallingPackage = info.packageName;
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700341 setIntent(_intent, info);
Andrii Kulian2e751b82016-03-16 16:59:32 -0700342 setMinDimensions(info);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700343
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700344 isPersistable = true;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700345 // Clamp to [1, max].
346 maxRecents = Math.min(Math.max(info.maxRecents, 1),
347 ActivityManager.getMaxAppRecentsLimitStatic());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700348
349 taskType = APPLICATION_ACTIVITY_TYPE;
350 mTaskToReturnTo = HOME_ACTIVITY_TYPE;
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700351 lastTaskDescription = _taskDescription;
Winson730bf062016-03-31 18:04:56 -0700352 touchActiveTime();
Yorke Leebd54c2a2016-10-25 13:49:23 -0700353 mService.mTaskChangeNotificationController.notifyTaskCreated(_taskId, realActivity);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700354 }
355
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800356 private TaskRecord(ActivityManagerService service, int _taskId, Intent _intent,
357 Intent _affinityIntent, String _affinity, String _rootAffinity,
358 ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset,
359 boolean _autoRemoveRecents, boolean _askedCompatMode, int _taskType, int _userId,
360 int _effectiveUid, String _lastDescription, ArrayList<ActivityRecord> activities,
361 long _firstActiveTime, long _lastActiveTime, long lastTimeMoved,
362 boolean neverRelinquishIdentity, TaskDescription _lastTaskDescription,
Winsonc809cbb2015-11-02 12:06:15 -0800363 TaskThumbnailInfo lastThumbnailInfo, int taskAffiliation, int prevTaskId,
364 int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage,
Winson Chungd3395382016-12-13 11:49:09 -0800365 int resizeMode, boolean supportsPictureInPicture, boolean privileged,
366 boolean _realActivitySuspended, boolean userSetupComplete, int minWidth,
367 int minHeight) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700368 mService = service;
Craig Mautnera228ae92014-07-09 05:44:55 -0700369 mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
370 TaskPersister.IMAGE_EXTENSION;
Suprabh Shukla23593142015-11-03 17:31:15 -0800371 mLastThumbnailFile = new File(TaskPersister.getUserImagesDir(_userId), mFilename);
Winsonc809cbb2015-11-02 12:06:15 -0800372 mLastThumbnailInfo = lastThumbnailInfo;
Craig Mautner21d24a22014-04-23 11:45:37 -0700373 taskId = _taskId;
374 intent = _intent;
375 affinityIntent = _affinityIntent;
376 affinity = _affinity;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800377 rootAffinity = _rootAffinity;
Craig Mautner21d24a22014-04-23 11:45:37 -0700378 voiceSession = null;
379 voiceInteractor = null;
380 realActivity = _realActivity;
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800381 realActivitySuspended = _realActivitySuspended;
Craig Mautner21d24a22014-04-23 11:45:37 -0700382 origActivity = _origActivity;
383 rootWasReset = _rootWasReset;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700384 isAvailable = true;
Dianne Hackborn13420f22014-07-18 15:43:56 -0700385 autoRemoveRecents = _autoRemoveRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700386 askedCompatMode = _askedCompatMode;
387 taskType = _taskType;
Craig Mautner84984fa2014-06-19 11:19:20 -0700388 mTaskToReturnTo = HOME_ACTIVITY_TYPE;
Craig Mautner21d24a22014-04-23 11:45:37 -0700389 userId = _userId;
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800390 mUserSetupComplete = userSetupComplete;
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700391 effectiveUid = _effectiveUid;
Winson Chungffa2ec62014-07-03 15:54:42 -0700392 firstActiveTime = _firstActiveTime;
Winson Chungf1fbd772014-06-24 18:06:58 -0700393 lastActiveTime = _lastActiveTime;
Craig Mautner21d24a22014-04-23 11:45:37 -0700394 lastDescription = _lastDescription;
395 mActivities = activities;
396 mLastTimeMoved = lastTimeMoved;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700397 mNeverRelinquishIdentity = neverRelinquishIdentity;
Winson Chung2cb86c72014-06-25 12:03:30 -0700398 lastTaskDescription = _lastTaskDescription;
Craig Mautnera228ae92014-07-09 05:44:55 -0700399 mAffiliatedTaskId = taskAffiliation;
Winson Chungec396d62014-08-06 17:08:00 -0700400 mAffiliatedTaskColor = taskAffiliationColor;
Craig Mautnera228ae92014-07-09 05:44:55 -0700401 mPrevAffiliateTaskId = prevTaskId;
402 mNextAffiliateTaskId = nextTaskId;
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700403 mCallingUid = callingUid;
404 mCallingPackage = callingPackage;
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800405 mResizeMode = resizeMode;
Winson Chungd3395382016-12-13 11:49:09 -0800406 mSupportsPictureInPicture = supportsPictureInPicture;
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700407 mPrivileged = privileged;
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700408 mMinWidth = minWidth;
409 mMinHeight = minHeight;
Yorke Leebd54c2a2016-10-25 13:49:23 -0700410 mService.mTaskChangeNotificationController.notifyTaskCreated(_taskId, realActivity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800411 }
412
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800413 TaskWindowContainerController getWindowContainerController() {
414 return mWindowContainerController;
415 }
416
417 void createWindowContainer(boolean onTop, boolean showForAllUsers) {
418 if (mWindowContainerController != null) {
419 throw new IllegalArgumentException("Window container=" + mWindowContainerController
420 + " already created for task=" + this);
421 }
422
423 final Rect bounds = updateOverrideConfigurationFromLaunchBounds();
424 final Configuration overrideConfig = getOverrideConfiguration();
Wale Ogunwale1666e312016-12-16 11:27:18 -0800425 mWindowContainerController = new TaskWindowContainerController(taskId, this,
426 getStack().getWindowContainerController(), userId, bounds, overrideConfig,
427 mResizeMode, mSupportsPictureInPicture, isHomeTask(), isOnTopLauncher(),
428 onTop, showForAllUsers, lastTaskDescription);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800429 }
430
431 void removeWindowContainer() {
432 mService.mStackSupervisor.removeLockedTaskLocked(this);
433 mWindowContainerController.removeContainer();
434 if (!StackId.persistTaskBounds(getStackId())) {
435 // Reset current bounds for task whose bounds shouldn't be persisted so it uses
436 // default configuration the next time it launches.
437 updateOverrideConfiguration(null);
438 }
439 mService.mTaskChangeNotificationController.notifyTaskRemoved(taskId);
440 mWindowContainerController = null;
441 }
442
Jorim Jaggifb9d78a2017-01-05 18:57:12 +0100443 @Override
444 public void onSnapshotChanged(TaskSnapshot snapshot) {
445 mService.mTaskChangeNotificationController.notifyTaskSnapshotChanged(taskId, snapshot);
446 }
447
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800448 void setResizeMode(int resizeMode) {
449 if (mResizeMode == resizeMode) {
450 return;
451 }
452 mResizeMode = resizeMode;
453 mWindowContainerController.setResizeable(resizeMode);
454 mService.mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
455 mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
456 }
457
458 void setTaskDockedResizing(boolean resizing) {
459 mWindowContainerController.setTaskDockedResizing(resizing);
460 }
461
Wale Ogunwale1666e312016-12-16 11:27:18 -0800462 // TODO: Consolidate this with the resize() method below.
463 @Override
464 public void requestResize(Rect bounds, int resizeMode) {
465 mService.resizeTask(taskId, bounds, resizeMode);
466 }
467
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800468 boolean resize(Rect bounds, int resizeMode, boolean preserveWindow, boolean deferResume) {
469 if (!isResizeable()) {
470 Slog.w(TAG, "resizeTask: task " + this + " not resizeable.");
471 return true;
472 }
473
474 // If this is a forced resize, let it go through even if the bounds is not changing,
475 // as we might need a relayout due to surface size change (to/from fullscreen).
476 final boolean forced = (resizeMode & RESIZE_MODE_FORCED) != 0;
477 if (Objects.equals(mBounds, bounds) && !forced) {
478 // Nothing to do here...
479 return true;
480 }
481 bounds = validateBounds(bounds);
482
483 if (mWindowContainerController == null) {
484 // Task doesn't exist in window manager yet (e.g. was restored from recents).
485 // All we can do for now is update the bounds so it can be used when the task is
486 // added to window manager.
487 updateOverrideConfiguration(bounds);
488 if (getStackId() != FREEFORM_WORKSPACE_STACK_ID) {
489 // re-restore the task so it can have the proper stack association.
490 mService.mStackSupervisor.restoreRecentTaskLocked(this,
491 FREEFORM_WORKSPACE_STACK_ID);
492 }
493 return true;
494 }
495
496 if (!canResizeToBounds(bounds)) {
497 throw new IllegalArgumentException("resizeTask: Can not resize task=" + this
498 + " to bounds=" + bounds + " resizeMode=" + mResizeMode);
499 }
500
501 // Do not move the task to another stack here.
502 // This method assumes that the task is already placed in the right stack.
503 // we do not mess with that decision and we only do the resize!
504
505 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeTask_" + taskId);
506
507 final boolean updatedConfig = updateOverrideConfiguration(bounds);
508 // This variable holds information whether the configuration didn't change in a significant
509 // way and the activity was kept the way it was. If it's false, it means the activity had
510 // to be relaunched due to configuration change.
511 boolean kept = true;
512 if (updatedConfig) {
513 final ActivityRecord r = topRunningActivityLocked();
514 if (r != null) {
515 kept = r.ensureActivityConfigurationLocked(0 /* globalChanges */, preserveWindow);
516
517 if (!deferResume) {
518 // All other activities must be made visible with their correct configuration.
519 mService.mStackSupervisor.ensureActivitiesVisibleLocked(r, 0, !PRESERVE_WINDOWS);
520 if (!kept) {
521 mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
522 }
523 }
524 }
525 }
526 mWindowContainerController.resize(mBounds, getOverrideConfiguration(), kept, forced);
527
528 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
529 return kept;
530 }
531
532 // TODO: Investigate combining with the resize() method above.
533 void resizeWindowContainer() {
534 mWindowContainerController.resize(mBounds, getOverrideConfiguration(), false /* relayout */,
535 false /* forced */);
536 }
537
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800538 void getWindowContainerBounds(Rect bounds) {
539 mWindowContainerController.getBounds(bounds);
540 }
541
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800542 // TODO: Should we be doing all the stuff in ASS.moveTaskToStackLocked?
543 void reparent(int stackId, int position, String reason) {
544 mService.mWindowManager.deferSurfaceLayout();
545
546 try {
547 final ActivityStackSupervisor supervisor = mService.mStackSupervisor;
548 final ActivityStack newStack = supervisor.getStack(stackId,
549 CREATE_IF_NEEDED, false /* toTop */);
550 // Adjust the position for the new parent stack as needed.
551 position = newStack.getAdjustedPositionForTask(this, position, null /* starting */);
552
553 // Must reparent first in window manager to avoid a situation where AM can delete the
554 // we are coming from in WM before we reparent because it became empty.
Wale Ogunwale1666e312016-12-16 11:27:18 -0800555 mWindowContainerController.reparent(newStack.getWindowContainerController(), position);
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800556
557 final ActivityStack prevStack = mStack;
558 prevStack.removeTask(this, reason, REMOVE_TASK_MODE_MOVING);
559 newStack.addTask(this, position, reason);
560
561 supervisor.scheduleReportPictureInPictureModeChangedIfNeeded(this, prevStack);
562
563 if (voiceSession != null) {
564 try {
565 voiceSession.taskStarted(intent, taskId);
566 } catch (RemoteException e) {
567 }
568 }
569 } finally {
570 mService.mWindowManager.continueSurfaceLayout();
571 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800572 }
573
574 void cancelWindowTransition() {
575 mWindowContainerController.cancelWindowTransition();
576 }
577
578 void cancelThumbnailTransition() {
579 mWindowContainerController.cancelThumbnailTransition();
580 }
581
Jorim Jaggi7361bab2017-01-16 17:17:58 +0100582 /**
583 * DO NOT HOLD THE ACTIVITY MANAGER LOCK WHEN CALLING THIS METHOD!
584 */
585 TaskSnapshot getSnapshot() {
586
587 // TODO: Move this to {@link TaskWindowContainerController} once recent tasks are more
588 // synchronized between AM and WM.
589 return mService.mWindowManager.getTaskSnapshot(taskId, userId);
Jorim Jaggi02886a82016-12-06 09:10:06 -0800590 }
591
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800592 void touchActiveTime() {
Winson Chung36f3f032016-09-08 23:29:43 +0000593 lastActiveTime = System.currentTimeMillis();
Winson Chungffa2ec62014-07-03 15:54:42 -0700594 if (firstActiveTime == 0) {
595 firstActiveTime = lastActiveTime;
596 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800597 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700598
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800599 long getInactiveDuration() {
Winson Chung36f3f032016-09-08 23:29:43 +0000600 return System.currentTimeMillis() - lastActiveTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800601 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700602
Winson Chungfee26772014-08-05 12:21:52 -0700603 /** Sets the original intent, and the calling uid and package. */
604 void setIntent(ActivityRecord r) {
Winson Chungfee26772014-08-05 12:21:52 -0700605 mCallingUid = r.launchedFromUid;
606 mCallingPackage = r.launchedFromPackage;
Craig Mautner15df08a2015-04-01 12:17:18 -0700607 setIntent(r.intent, r.info);
Winson Chungfee26772014-08-05 12:21:52 -0700608 }
609
610 /** Sets the original intent, _without_ updating the calling uid or package. */
611 private void setIntent(Intent _intent, ActivityInfo info) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700612 if (intent == null) {
613 mNeverRelinquishIdentity =
Wale Ogunwale3eadad72016-10-13 09:16:59 -0700614 (info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700615 } else if (mNeverRelinquishIdentity) {
616 return;
617 }
618
619 affinity = info.taskAffinity;
Dianne Hackborn79228822014-09-16 11:11:23 -0700620 if (intent == null) {
621 // If this task already has an intent associated with it, don't set the root
622 // affinity -- we don't want it changing after initially set, but the initially
623 // set value may be null.
624 rootAffinity = affinity;
625 }
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700626 effectiveUid = info.applicationInfo.uid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700627 stringName = null;
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800628
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800629 if (info.targetActivity == null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800630 if (_intent != null) {
631 // If this Intent has a selector, we want to clear it for the
632 // recent task since it is not relevant if the user later wants
633 // to re-launch the app.
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700634 if (_intent.getSelector() != null || _intent.getSourceBounds() != null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800635 _intent = new Intent(_intent);
636 _intent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700637 _intent.setSourceBounds(null);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800638 }
639 }
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700640 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Setting Intent of " + this + " to " + _intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800641 intent = _intent;
642 realActivity = _intent != null ? _intent.getComponent() : null;
643 origActivity = null;
644 } else {
645 ComponentName targetComponent = new ComponentName(
646 info.packageName, info.targetActivity);
647 if (_intent != null) {
648 Intent targetIntent = new Intent(_intent);
649 targetIntent.setComponent(targetComponent);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800650 targetIntent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700651 targetIntent.setSourceBounds(null);
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700652 if (DEBUG_TASKS) Slog.v(TAG_TASKS,
Dianne Hackborn7f96b792012-05-29 18:46:45 -0700653 "Setting Intent of " + this + " to target " + targetIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800654 intent = targetIntent;
655 realActivity = targetComponent;
656 origActivity = _intent.getComponent();
657 } else {
658 intent = null;
659 realActivity = targetComponent;
660 origActivity = new ComponentName(info.packageName, info.name);
661 }
662 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700663
Craig Mautner47b20ba2014-09-17 17:23:44 -0700664 final int intentFlags = intent == null ? 0 : intent.getFlags();
665 if ((intentFlags & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800666 // Once we are set to an Intent with this flag, we count this
667 // task as having a true root activity.
668 rootWasReset = true;
669 }
Dianne Hackborn09233282014-04-30 11:33:59 -0700670 userId = UserHandle.getUserId(info.applicationInfo.uid);
Winson Chung36f3f032016-09-08 23:29:43 +0000671 mUserSetupComplete = Settings.Secure.getIntForUser(mService.mContext.getContentResolver(),
672 USER_SETUP_COMPLETE, 0, userId) != 0;
Craig Mautner41db4a72014-05-07 17:20:56 -0700673 if ((info.flags & ActivityInfo.FLAG_AUTO_REMOVE_FROM_RECENTS) != 0) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700674 // If the activity itself has requested auto-remove, then just always do it.
675 autoRemoveRecents = true;
Wale Ogunwale843bfb92015-03-27 11:06:48 -0700676 } else if ((intentFlags & (FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS))
677 == FLAG_ACTIVITY_NEW_DOCUMENT) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700678 // If the caller has not asked for the document to be retained, then we may
679 // want to turn on auto-remove, depending on whether the target has set its
680 // own document launch mode.
681 if (info.documentLaunchMode != ActivityInfo.DOCUMENT_LAUNCH_NONE) {
682 autoRemoveRecents = false;
683 } else {
684 autoRemoveRecents = true;
685 }
686 } else {
687 autoRemoveRecents = false;
Craig Mautner41db4a72014-05-07 17:20:56 -0700688 }
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800689 mResizeMode = info.resizeMode;
Winson Chungd3395382016-12-13 11:49:09 -0800690 mSupportsPictureInPicture = info.supportsPictureInPicture();
Jiaquan Hedd1e66f2016-06-15 15:15:12 -0700691 mIsOnTopLauncher = (info.flags & FLAG_ON_TOP_LAUNCHER) != 0;
Craig Mautner15df08a2015-04-01 12:17:18 -0700692 mLockTaskMode = info.lockTaskLaunchMode;
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700693 mPrivileged = (info.applicationInfo.privateFlags & PRIVATE_FLAG_PRIVILEGED) != 0;
Craig Mautner15df08a2015-04-01 12:17:18 -0700694 setLockTaskAuth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800695 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800696
Andrii Kulian2e751b82016-03-16 16:59:32 -0700697 /** Sets the original minimal width and height. */
698 private void setMinDimensions(ActivityInfo info) {
699 if (info != null && info.windowLayout != null) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700700 mMinWidth = info.windowLayout.minWidth;
701 mMinHeight = info.windowLayout.minHeight;
Andrii Kulian2e751b82016-03-16 16:59:32 -0700702 } else {
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700703 mMinWidth = INVALID_MIN_SIZE;
704 mMinHeight = INVALID_MIN_SIZE;
Andrii Kulian2e751b82016-03-16 16:59:32 -0700705 }
706 }
707
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800708 /**
Andrii Kulian206b9fa2016-06-02 13:18:01 -0700709 * Return true if the input activity has the same intent filter as the intent this task
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800710 * record is based on (normally the root activity intent).
711 */
Andrii Kulian206b9fa2016-06-02 13:18:01 -0700712 boolean isSameIntentFilter(ActivityRecord r) {
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800713 final Intent intent = new Intent(r.intent);
714 // Correct the activity intent for aliasing. The task record intent will always be based on
715 // the real activity that will be launched not the alias, so we need to use an intent with
716 // the component name pointing to the real activity not the alias in the activity record.
717 intent.setComponent(r.realActivity);
718 return this.intent.filterEquals(intent);
719 }
720
Craig Mautner84984fa2014-06-19 11:19:20 -0700721 void setTaskToReturnTo(int taskToReturnTo) {
Wale Ogunwale673cbd22016-01-30 18:30:55 -0800722 mTaskToReturnTo = (taskToReturnTo == RECENTS_ACTIVITY_TYPE)
723 ? HOME_ACTIVITY_TYPE : taskToReturnTo;
Craig Mautner84984fa2014-06-19 11:19:20 -0700724 }
725
726 int getTaskToReturnTo() {
727 return mTaskToReturnTo;
728 }
729
Craig Mautnera228ae92014-07-09 05:44:55 -0700730 void setPrevAffiliate(TaskRecord prevAffiliate) {
731 mPrevAffiliate = prevAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800732 mPrevAffiliateTaskId = prevAffiliate == null ? INVALID_TASK_ID : prevAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700733 }
734
735 void setNextAffiliate(TaskRecord nextAffiliate) {
736 mNextAffiliate = nextAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800737 mNextAffiliateTaskId = nextAffiliate == null ? INVALID_TASK_ID : nextAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700738 }
739
Andrii Kulian02b7a832016-10-06 23:11:56 -0700740 ActivityStack getStack() {
741 return mStack;
742 }
743
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800744 /**
745 * Must be used for setting parent stack because it performs configuration updates.
746 * Must be called after adding task as a child to the stack.
747 */
Andrii Kulian02b7a832016-10-06 23:11:56 -0700748 void setStack(ActivityStack stack) {
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800749 if (stack != null && !stack.isInStackLocked(this)) {
750 throw new IllegalStateException("Task must be added as a Stack child first.");
751 }
Andrii Kulian02b7a832016-10-06 23:11:56 -0700752 mStack = stack;
Andrii Kulian1779e612016-10-12 21:58:25 -0700753 onParentChanged();
Andrii Kulian02b7a832016-10-06 23:11:56 -0700754 }
755
756 /**
757 * @return Id of current stack, {@link INVALID_STACK_ID} if no stack is set.
758 */
759 int getStackId() {
760 return mStack != null ? mStack.mStackId : INVALID_STACK_ID;
761 }
762
Andrii Kulian1779e612016-10-12 21:58:25 -0700763 @Override
764 protected int getChildCount() {
765 return 0;
766 }
767
768 @Override
769 protected ConfigurationContainer getChildAt(int index) {
770 return null;
771 }
772
773 @Override
774 protected ConfigurationContainer getParent() {
775 return mStack;
776 }
777
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800778 @Override
779 void onParentChanged() {
780 super.onParentChanged();
781 mService.mStackSupervisor.updateUIDsPresentOnDisplay();
782 }
783
Craig Mautnera228ae92014-07-09 05:44:55 -0700784 // Close up recents linked list.
785 void closeRecentsChain() {
786 if (mPrevAffiliate != null) {
787 mPrevAffiliate.setNextAffiliate(mNextAffiliate);
788 }
789 if (mNextAffiliate != null) {
790 mNextAffiliate.setPrevAffiliate(mPrevAffiliate);
791 }
792 setPrevAffiliate(null);
793 setNextAffiliate(null);
794 }
795
Winson Chung740c3ac2014-11-12 16:14:38 -0800796 void removedFromRecents() {
Dianne Hackborn852975d2014-08-22 17:42:43 -0700797 disposeThumbnail();
798 closeRecentsChain();
799 if (inRecents) {
800 inRecents = false;
Winson Chung740c3ac2014-11-12 16:14:38 -0800801 mService.notifyTaskPersisterLocked(this, false);
Dianne Hackborn852975d2014-08-22 17:42:43 -0700802 }
Jorim Jaggif9084ec2017-01-16 13:16:59 +0100803
804 // TODO: Use window container controller once tasks are better synced between AM and WM
805 mService.mWindowManager.notifyTaskRemovedFromRecents(taskId, userId);
Dianne Hackborn852975d2014-08-22 17:42:43 -0700806 }
807
Craig Mautnera228ae92014-07-09 05:44:55 -0700808 void setTaskToAffiliateWith(TaskRecord taskToAffiliateWith) {
809 closeRecentsChain();
810 mAffiliatedTaskId = taskToAffiliateWith.mAffiliatedTaskId;
Winson Chungec396d62014-08-06 17:08:00 -0700811 mAffiliatedTaskColor = taskToAffiliateWith.mAffiliatedTaskColor;
Craig Mautnera228ae92014-07-09 05:44:55 -0700812 // Find the end
813 while (taskToAffiliateWith.mNextAffiliate != null) {
814 final TaskRecord nextRecents = taskToAffiliateWith.mNextAffiliate;
815 if (nextRecents.mAffiliatedTaskId != mAffiliatedTaskId) {
816 Slog.e(TAG, "setTaskToAffiliateWith: nextRecents=" + nextRecents + " affilTaskId="
817 + nextRecents.mAffiliatedTaskId + " should be " + mAffiliatedTaskId);
818 if (nextRecents.mPrevAffiliate == taskToAffiliateWith) {
819 nextRecents.setPrevAffiliate(null);
820 }
821 taskToAffiliateWith.setNextAffiliate(null);
822 break;
823 }
824 taskToAffiliateWith = nextRecents;
825 }
826 taskToAffiliateWith.setNextAffiliate(this);
827 setPrevAffiliate(taskToAffiliateWith);
828 setNextAffiliate(null);
829 }
830
Winson Chung096f36b2014-08-20 15:39:01 -0700831 /**
Winsonc809cbb2015-11-02 12:06:15 -0800832 * Sets the last thumbnail with the current task bounds and the system orientation.
Winson Chung096f36b2014-08-20 15:39:01 -0700833 * @return whether the thumbnail was set
834 */
Winsonc809cbb2015-11-02 12:06:15 -0800835 boolean setLastThumbnailLocked(Bitmap thumbnail) {
Winsonc809cbb2015-11-02 12:06:15 -0800836 int taskWidth = 0;
837 int taskHeight = 0;
838 if (mBounds != null) {
839 // Non-fullscreen tasks
840 taskWidth = mBounds.width();
841 taskHeight = mBounds.height();
Andrii Kulian02b7a832016-10-06 23:11:56 -0700842 } else if (mStack != null) {
Winsonc809cbb2015-11-02 12:06:15 -0800843 // Fullscreen tasks
844 final Point displaySize = new Point();
Andrii Kulian02b7a832016-10-06 23:11:56 -0700845 mStack.getDisplaySize(displaySize);
Winsonc809cbb2015-11-02 12:06:15 -0800846 taskWidth = displaySize.x;
847 taskHeight = displaySize.y;
848 } else {
849 Slog.e(TAG, "setLastThumbnailLocked() called on Task without stack");
850 }
Andrii Kulian1779e612016-10-12 21:58:25 -0700851 // We need to provide the current orientation of the display on which this task resides,
852 // not the orientation of the task.
853 final int orientation =
854 getStack().mActivityContainer.mActivityDisplay.getConfiguration().orientation;
855 return setLastThumbnailLocked(thumbnail, taskWidth, taskHeight, orientation);
Winsonc809cbb2015-11-02 12:06:15 -0800856 }
857
858 /**
859 * Sets the last thumbnail with the current task bounds.
860 * @return whether the thumbnail was set
861 */
862 private boolean setLastThumbnailLocked(Bitmap thumbnail, int taskWidth, int taskHeight,
863 int screenOrientation) {
Winson Chung096f36b2014-08-20 15:39:01 -0700864 if (mLastThumbnail != thumbnail) {
865 mLastThumbnail = thumbnail;
Winsonc809cbb2015-11-02 12:06:15 -0800866 mLastThumbnailInfo.taskWidth = taskWidth;
867 mLastThumbnailInfo.taskHeight = taskHeight;
868 mLastThumbnailInfo.screenOrientation = screenOrientation;
Winson Chung096f36b2014-08-20 15:39:01 -0700869 if (thumbnail == null) {
870 if (mLastThumbnailFile != null) {
871 mLastThumbnailFile.delete();
872 }
873 } else {
Suprabh Shukla09a88f52015-12-02 14:36:31 -0800874 mService.mRecentTasks.saveImage(thumbnail, mLastThumbnailFile.getAbsolutePath());
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700875 }
Winson Chung096f36b2014-08-20 15:39:01 -0700876 return true;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700877 }
Winson Chung096f36b2014-08-20 15:39:01 -0700878 return false;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700879 }
880
881 void getLastThumbnail(TaskThumbnail thumbs) {
882 thumbs.mainThumbnail = mLastThumbnail;
Winsonc809cbb2015-11-02 12:06:15 -0800883 thumbs.thumbnailInfo = mLastThumbnailInfo;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700884 thumbs.thumbnailFileDescriptor = null;
Craig Mautnerf4f8bb72014-07-29 10:41:40 -0700885 if (mLastThumbnail == null) {
Suprabh Shukla09a88f52015-12-02 14:36:31 -0800886 thumbs.mainThumbnail = mService.mRecentTasks.getImageFromWriteQueue(
Suprabh Shukla23593142015-11-03 17:31:15 -0800887 mLastThumbnailFile.getAbsolutePath());
Craig Mautnerf4f8bb72014-07-29 10:41:40 -0700888 }
Winson Chung096f36b2014-08-20 15:39:01 -0700889 // Only load the thumbnail file if we don't have a thumbnail
890 if (thumbs.mainThumbnail == null && mLastThumbnailFile.exists()) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700891 try {
892 thumbs.thumbnailFileDescriptor = ParcelFileDescriptor.open(mLastThumbnailFile,
893 ParcelFileDescriptor.MODE_READ_ONLY);
894 } catch (IOException e) {
Dianne Hackborn9844d292013-10-04 16:44:22 -0700895 }
896 }
897 }
898
Winsonc809cbb2015-11-02 12:06:15 -0800899 /**
900 * Removes in-memory thumbnail data when the max number of in-memory task thumbnails is reached.
901 */
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700902 void freeLastThumbnail() {
903 mLastThumbnail = null;
904 }
905
Winsonc809cbb2015-11-02 12:06:15 -0800906 /**
907 * Removes all associated thumbnail data when a task is removed or pruned from recents.
908 */
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700909 void disposeThumbnail() {
Winsonc6a2da02015-11-11 18:11:59 -0800910 mLastThumbnailInfo.reset();
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700911 mLastThumbnail = null;
912 lastDescription = null;
913 }
914
Winson Chung1147c402014-05-14 11:05:00 -0700915 /** Returns the intent for the root activity for this task */
916 Intent getBaseIntent() {
917 return intent != null ? intent : affinityIntent;
918 }
919
Winson Chung3b3f4642014-04-22 10:08:18 -0700920 /** Returns the first non-finishing activity from the root. */
921 ActivityRecord getRootActivity() {
922 for (int i = 0; i < mActivities.size(); i++) {
923 final ActivityRecord r = mActivities.get(i);
924 if (r.finishing) {
925 continue;
926 }
927 return r;
928 }
929 return null;
930 }
931
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800932 ActivityRecord getTopActivity() {
933 for (int i = mActivities.size() - 1; i >= 0; --i) {
934 final ActivityRecord r = mActivities.get(i);
935 if (r.finishing) {
936 continue;
937 }
938 return r;
939 }
940 return null;
941 }
942
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -0700943 ActivityRecord topRunningActivityLocked() {
Andrii Kulian02b7a832016-10-06 23:11:56 -0700944 if (mStack != null) {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700945 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
946 ActivityRecord r = mActivities.get(activityNdx);
Chong Zhang87761972016-08-22 13:53:24 -0700947 if (!r.finishing && r.okToShowLocked()) {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700948 return r;
949 }
Craig Mautner6b74cb52013-09-27 17:02:21 -0700950 }
951 }
952 return null;
953 }
954
Wale Ogunwale3b232392016-05-13 15:37:13 -0700955 ActivityRecord topRunningActivityWithStartingWindowLocked() {
Andrii Kulian02b7a832016-10-06 23:11:56 -0700956 if (mStack != null) {
Wale Ogunwale3b232392016-05-13 15:37:13 -0700957 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
958 ActivityRecord r = mActivities.get(activityNdx);
959 if (r.mStartingWindowState != STARTING_WINDOW_SHOWN
Chong Zhang87761972016-08-22 13:53:24 -0700960 || r.finishing || !r.okToShowLocked()) {
Wale Ogunwale3b232392016-05-13 15:37:13 -0700961 continue;
962 }
963 return r;
964 }
965 }
966 return null;
967 }
968
Chong Zhang87761972016-08-22 13:53:24 -0700969 boolean okToShowLocked() {
970 // NOTE: If {@link TaskRecord#topRunningActivityLocked} return is not null then it is
971 // okay to show the activity when locked.
972 return mService.mStackSupervisor.isCurrentProfileLocked(userId)
973 || topRunningActivityLocked() != null;
974 }
975
Wale Ogunwale6d42df62015-11-05 09:50:55 -0800976 void setFrontOfTask() {
977 setFrontOfTask(null);
978 }
979
Craig Mautner3b475fe2013-12-16 15:58:31 -0800980 /** Call after activity movement or finish to make sure that frontOfTask is set correctly */
Wale Ogunwale6d42df62015-11-05 09:50:55 -0800981 void setFrontOfTask(ActivityRecord newTop) {
982 // If a top candidate is suggested by the caller, go ahead and use it and mark all others
983 // as not front. This is needed in situations where the current front activity in the
984 // task isn't finished yet and we want to set the front to the activity moved to the front
985 // of the task.
986 boolean foundFront = newTop != null ? true : false;
987
Craig Mautner3b475fe2013-12-16 15:58:31 -0800988 final int numActivities = mActivities.size();
Craig Mautner704e40b2013-12-18 16:43:51 -0800989 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
Craig Mautner3b475fe2013-12-16 15:58:31 -0800990 final ActivityRecord r = mActivities.get(activityNdx);
991 if (foundFront || r.finishing) {
992 r.frontOfTask = false;
993 } else {
994 r.frontOfTask = true;
995 // Set frontOfTask false for every following activity.
996 foundFront = true;
997 }
998 }
Craig Mautner9587ee02014-06-23 15:00:10 +0000999 if (!foundFront && numActivities > 0) {
1000 // All activities of this task are finishing. As we ought to have a frontOfTask
1001 // activity, make the bottom activity front.
1002 mActivities.get(0).frontOfTask = true;
1003 }
Wale Ogunwale6d42df62015-11-05 09:50:55 -08001004 if (newTop != null) {
1005 newTop.frontOfTask = true;
1006 }
Craig Mautner3b475fe2013-12-16 15:58:31 -08001007 }
1008
Craig Mautnerde4ef022013-04-07 19:01:33 -07001009 /**
Craig Mautner3b475fe2013-12-16 15:58:31 -08001010 * Reorder the history stack so that the passed activity is brought to the front.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001011 */
1012 final void moveActivityToFrontLocked(ActivityRecord newTop) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -07001013 if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE,
1014 "Removing and adding activity " + newTop
1015 + " to stack at top callers=" + Debug.getCallers(4));
Craig Mautnerde4ef022013-04-07 19:01:33 -07001016
Craig Mautnerde4ef022013-04-07 19:01:33 -07001017 mActivities.remove(newTop);
1018 mActivities.add(newTop);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001019 updateEffectiveIntent();
Craig Mautner3b475fe2013-12-16 15:58:31 -08001020
Wale Ogunwale6d42df62015-11-05 09:50:55 -08001021 setFrontOfTask(newTop);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001022 }
1023
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001024 void addActivityAtBottom(ActivityRecord r) {
Craig Mautner77878772013-03-04 19:46:24 -08001025 addActivityAtIndex(0, r);
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001026 }
1027
1028 void addActivityToTop(ActivityRecord r) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001029 addActivityAtIndex(mActivities.size(), r);
1030 }
1031
Winson Chung30480042017-01-26 10:55:34 -08001032 /**
1033 * Adds an activity {@param r} at the given {@param index}. The activity {@param r} must either
1034 * be in the current task or unparented to any task.
1035 */
Craig Mautner1602ec22013-05-12 10:24:27 -07001036 void addActivityAtIndex(int index, ActivityRecord r) {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001037 if (r.task != null && r.task != this) {
1038 throw new IllegalArgumentException("Can not add r=" + " to task=" + this
1039 + " current parent=" + r.task);
1040 }
1041 r.task = this;
1042
Craig Mautner6170f732013-04-02 13:05:23 -07001043 // 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 -08001044 if (!mActivities.remove(r) && r.fullscreen) {
1045 // Was not previously in list.
1046 numFullscreen++;
1047 }
Craig Mautner2c1faed2013-07-23 12:56:02 -07001048 // Only set this based on the first activity
1049 if (mActivities.isEmpty()) {
Craig Mautner21d24a22014-04-23 11:45:37 -07001050 taskType = r.mActivityType;
1051 isPersistable = r.isPersistable();
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001052 mCallingUid = r.launchedFromUid;
1053 mCallingPackage = r.launchedFromPackage;
Dianne Hackborn852975d2014-08-22 17:42:43 -07001054 // Clamp to [1, max].
1055 maxRecents = Math.min(Math.max(r.info.maxRecents, 1),
1056 ActivityManager.getMaxAppRecentsLimitStatic());
Craig Mautner2c1faed2013-07-23 12:56:02 -07001057 } else {
1058 // Otherwise make all added activities match this one.
Craig Mautner21d24a22014-04-23 11:45:37 -07001059 r.mActivityType = taskType;
Craig Mautner78733002013-06-10 13:54:49 -07001060 }
Wale Ogunwale3b232392016-05-13 15:37:13 -07001061
1062 final int size = mActivities.size();
1063
1064 if (index == size && size > 0) {
1065 final ActivityRecord top = mActivities.get(size - 1);
1066 if (top.mTaskOverlay) {
1067 // Place below the task overlay activity since the overlay activity should always
1068 // be on top.
1069 index--;
1070 }
1071 }
1072
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001073 index = Math.min(size, index);
Craig Mautner77878772013-03-04 19:46:24 -08001074 mActivities.add(index, r);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001075 updateEffectiveIntent();
Craig Mautner21d24a22014-04-23 11:45:37 -07001076 if (r.isPersistable()) {
1077 mService.notifyTaskPersisterLocked(this, false);
1078 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001079
1080 // Sync. with window manager
1081 updateOverrideConfigurationFromLaunchBounds();
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001082 final AppWindowContainerController appController = r.getWindowContainerController();
1083 if (appController != null) {
1084 // Only attempt to move in WM if the child has a controller. It is possible we haven't
1085 // created controller for the activity we are starting yet.
1086 mWindowContainerController.positionChildAt(appController, index);
1087 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001088 r.onOverrideConfigurationSent();
Craig Mautner77878772013-03-04 19:46:24 -08001089 }
1090
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001091 /** @return true if this was the last activity in the task */
1092 boolean removeActivity(ActivityRecord r) {
1093 if (mActivities.remove(r) && r.fullscreen) {
1094 // Was previously in list.
1095 numFullscreen--;
1096 }
Craig Mautner21d24a22014-04-23 11:45:37 -07001097 if (r.isPersistable()) {
1098 mService.notifyTaskPersisterLocked(this, false);
1099 }
Wale Ogunwale89182d52016-03-11 10:38:36 -08001100
Andrii Kulian02b7a832016-10-06 23:11:56 -07001101 if (getStackId() == PINNED_STACK_ID) {
Wale Ogunwale89182d52016-03-11 10:38:36 -08001102 // We normally notify listeners of task stack changes on pause, however pinned stack
1103 // activities are normally in the paused state so no notification will be sent there
1104 // before the activity is removed. We send it here so instead.
Yorke Leebd54c2a2016-10-25 13:49:23 -07001105 mService.mTaskChangeNotificationController.notifyTaskStackChanged();
Wale Ogunwale89182d52016-03-11 10:38:36 -08001106 }
1107
Craig Mautner41326202014-06-20 14:38:21 -07001108 if (mActivities.isEmpty()) {
Craig Mautner5afcd4d2014-06-21 18:11:33 -07001109 return !mReuseTask;
Craig Mautner41326202014-06-20 14:38:21 -07001110 }
1111 updateEffectiveIntent();
1112 return false;
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001113 }
1114
Craig Mautner41db4a72014-05-07 17:20:56 -07001115 boolean autoRemoveFromRecents() {
Dianne Hackbornd38aed82014-06-10 21:36:35 -07001116 // We will automatically remove the task either if it has explicitly asked for
1117 // this, or it is empty and has never contained an activity that got shown to
1118 // the user.
Dianne Hackborn13420f22014-07-18 15:43:56 -07001119 return autoRemoveRecents || (mActivities.isEmpty() && !hasBeenVisible);
Craig Mautner41db4a72014-05-07 17:20:56 -07001120 }
1121
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001122 /**
1123 * Completely remove all activities associated with an existing
1124 * task starting at a specified index.
1125 */
1126 final void performClearTaskAtIndexLocked(int activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001127 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001128 for ( ; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001129 final ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001130 if (r.finishing) {
1131 continue;
1132 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07001133 if (mStack == null) {
Craig Mautner21d24a22014-04-23 11:45:37 -07001134 // Task was restored from persistent storage.
1135 r.takeFromHistory();
1136 mActivities.remove(activityNdx);
1137 --activityNdx;
1138 --numActivities;
Andrii Kulian02b7a832016-10-06 23:11:56 -07001139 } else if (mStack.finishActivityLocked(
Todd Kennedy539db512014-12-15 09:57:55 -08001140 r, Activity.RESULT_CANCELED, null, "clear-task-index", false)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001141 --activityNdx;
1142 --numActivities;
1143 }
1144 }
1145 }
1146
1147 /**
1148 * Completely remove all activities associated with an existing task.
1149 */
1150 final void performClearTaskLocked() {
Craig Mautner362449a2014-06-20 14:04:39 -07001151 mReuseTask = true;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001152 performClearTaskAtIndexLocked(0);
Craig Mautner362449a2014-06-20 14:04:39 -07001153 mReuseTask = false;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001154 }
1155
Filip Gruszczynskibe9dabd2016-01-19 12:23:10 -08001156 ActivityRecord performClearTaskForReuseLocked(ActivityRecord newR, int launchFlags) {
1157 mReuseTask = true;
1158 final ActivityRecord result = performClearTaskLocked(newR, launchFlags);
1159 mReuseTask = false;
1160 return result;
1161 }
1162
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001163 /**
1164 * Perform clear operation as requested by
1165 * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the
1166 * stack to the given task, then look for
1167 * an instance of that activity in the stack and, if found, finish all
1168 * activities on top of it and return the instance.
1169 *
1170 * @param newR Description of the new activity being started.
1171 * @return Returns the old activity that should be continued to be used,
1172 * or null if none was found.
1173 */
1174 final ActivityRecord performClearTaskLocked(ActivityRecord newR, int launchFlags) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001175 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001176 for (int activityNdx = numActivities - 1; activityNdx >= 0; --activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001177 ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001178 if (r.finishing) {
1179 continue;
1180 }
1181 if (r.realActivity.equals(newR.realActivity)) {
1182 // Here it is! Now finish everything in front...
Craig Mautner1602ec22013-05-12 10:24:27 -07001183 final ActivityRecord ret = r;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001184
1185 for (++activityNdx; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -07001186 r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001187 if (r.finishing) {
1188 continue;
1189 }
1190 ActivityOptions opts = r.takeOptionsLocked();
1191 if (opts != null) {
1192 ret.updateOptionsLocked(opts);
1193 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07001194 if (mStack != null && mStack.finishActivityLocked(
Todd Kennedy539db512014-12-15 09:57:55 -08001195 r, Activity.RESULT_CANCELED, null, "clear-task-stack", false)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001196 --activityNdx;
1197 --numActivities;
1198 }
1199 }
1200
1201 // Finally, if this is a normal launch mode (that is, not
1202 // expecting onNewIntent()), then we will finish the current
1203 // instance of the activity so a new fresh one can be started.
1204 if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE
Daichi Hirono15a02992016-04-27 18:47:01 +09001205 && (launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0
1206 && !ActivityStarter.isDocumentLaunchesIntoExisting(launchFlags)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001207 if (!ret.finishing) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001208 if (mStack != null) {
1209 mStack.finishActivityLocked(
Wale Ogunwale7d701172015-03-11 15:36:30 -07001210 ret, Activity.RESULT_CANCELED, null, "clear-task-top", false);
1211 }
Craig Mautnerb0f7dc72013-04-01 16:34:45 -07001212 return null;
1213 }
1214 }
1215
1216 return ret;
1217 }
1218 }
1219
1220 return null;
1221 }
1222
Andrii Kulian21713ac2016-10-12 22:05:05 -07001223 TaskThumbnail getTaskThumbnailLocked() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001224 if (mStack != null) {
1225 final ActivityRecord resumedActivity = mStack.mResumedActivity;
Craig Mautner21d24a22014-04-23 11:45:37 -07001226 if (resumedActivity != null && resumedActivity.task == this) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07001227 final Bitmap thumbnail = resumedActivity.screenshotActivityLocked();
Winsonc809cbb2015-11-02 12:06:15 -08001228 setLastThumbnailLocked(thumbnail);
Craig Mautner21d24a22014-04-23 11:45:37 -07001229 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -07001230 }
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001231 final TaskThumbnail taskThumbnail = new TaskThumbnail();
1232 getLastThumbnail(taskThumbnail);
1233 return taskThumbnail;
Craig Mautner9db9a0b2013-04-29 17:05:56 -07001234 }
1235
Andrii Kulian21713ac2016-10-12 22:05:05 -07001236 void removeTaskActivitiesLocked() {
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001237 // Just remove the entire task.
1238 performClearTaskAtIndexLocked(0);
Craig Mautner9db9a0b2013-04-29 17:05:56 -07001239 }
1240
Craig Mautner432f64e2015-05-20 14:59:57 -07001241 String lockTaskAuthToString() {
1242 switch (mLockTaskAuth) {
1243 case LOCK_TASK_AUTH_DONT_LOCK: return "LOCK_TASK_AUTH_DONT_LOCK";
1244 case LOCK_TASK_AUTH_PINNABLE: return "LOCK_TASK_AUTH_PINNABLE";
1245 case LOCK_TASK_AUTH_LAUNCHABLE: return "LOCK_TASK_AUTH_LAUNCHABLE";
1246 case LOCK_TASK_AUTH_WHITELISTED: return "LOCK_TASK_AUTH_WHITELISTED";
Benjamin Franz469dd582015-06-09 14:24:36 +01001247 case LOCK_TASK_AUTH_LAUNCHABLE_PRIV: return "LOCK_TASK_AUTH_LAUNCHABLE_PRIV";
Craig Mautner432f64e2015-05-20 14:59:57 -07001248 default: return "unknown=" + mLockTaskAuth;
1249 }
1250 }
1251
Craig Mautner15df08a2015-04-01 12:17:18 -07001252 void setLockTaskAuth() {
Benjamin Franz469dd582015-06-09 14:24:36 +01001253 if (!mPrivileged &&
1254 (mLockTaskMode == LOCK_TASK_LAUNCH_MODE_ALWAYS ||
1255 mLockTaskMode == LOCK_TASK_LAUNCH_MODE_NEVER)) {
1256 // Non-priv apps are not allowed to use always or never, fall back to default
1257 mLockTaskMode = LOCK_TASK_LAUNCH_MODE_DEFAULT;
1258 }
Craig Mautner15df08a2015-04-01 12:17:18 -07001259 switch (mLockTaskMode) {
1260 case LOCK_TASK_LAUNCH_MODE_DEFAULT:
1261 mLockTaskAuth = isLockTaskWhitelistedLocked() ?
1262 LOCK_TASK_AUTH_WHITELISTED : LOCK_TASK_AUTH_PINNABLE;
1263 break;
1264
1265 case LOCK_TASK_LAUNCH_MODE_NEVER:
Benjamin Franz469dd582015-06-09 14:24:36 +01001266 mLockTaskAuth = LOCK_TASK_AUTH_DONT_LOCK;
Craig Mautner15df08a2015-04-01 12:17:18 -07001267 break;
1268
1269 case LOCK_TASK_LAUNCH_MODE_ALWAYS:
Benjamin Franz469dd582015-06-09 14:24:36 +01001270 mLockTaskAuth = LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
Craig Mautner15df08a2015-04-01 12:17:18 -07001271 break;
1272
1273 case LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED:
1274 mLockTaskAuth = isLockTaskWhitelistedLocked() ?
1275 LOCK_TASK_AUTH_LAUNCHABLE : LOCK_TASK_AUTH_PINNABLE;
1276 break;
1277 }
Craig Mautner432f64e2015-05-20 14:59:57 -07001278 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
1279 " mLockTaskAuth=" + lockTaskAuthToString());
Craig Mautner15df08a2015-04-01 12:17:18 -07001280 }
1281
1282 boolean isLockTaskWhitelistedLocked() {
Benjamin Franz6fd84cc2015-08-06 18:09:03 +01001283 String pkg = (realActivity != null) ? realActivity.getPackageName() : null;
1284 if (pkg == null) {
Craig Mautner15df08a2015-04-01 12:17:18 -07001285 return false;
1286 }
1287 String[] packages = mService.mLockTaskPackages.get(userId);
1288 if (packages == null) {
1289 return false;
1290 }
1291 for (int i = packages.length - 1; i >= 0; --i) {
Benjamin Franz6fd84cc2015-08-06 18:09:03 +01001292 if (pkg.equals(packages[i])) {
Craig Mautner15df08a2015-04-01 12:17:18 -07001293 return true;
1294 }
1295 }
1296 return false;
1297 }
Wale Ogunwale74e26592016-02-05 11:48:37 -08001298
Craig Mautnera82aa092013-09-13 15:34:08 -07001299 boolean isHomeTask() {
Craig Mautner84984fa2014-06-19 11:19:20 -07001300 return taskType == HOME_ACTIVITY_TYPE;
Craig Mautnera82aa092013-09-13 15:34:08 -07001301 }
1302
Wale Ogunwale74e26592016-02-05 11:48:37 -08001303 boolean isRecentsTask() {
1304 return taskType == RECENTS_ACTIVITY_TYPE;
1305 }
1306
Craig Mautner86d67a42013-05-14 10:34:38 -07001307 boolean isApplicationTask() {
Craig Mautner84984fa2014-06-19 11:19:20 -07001308 return taskType == APPLICATION_ACTIVITY_TYPE;
1309 }
1310
1311 boolean isOverHomeStack() {
Matthew Ngae1ff4f2016-11-10 15:49:14 -08001312 return mTaskToReturnTo == HOME_ACTIVITY_TYPE;
Craig Mautner1602ec22013-05-12 10:24:27 -07001313 }
1314
Winson Chungd3395382016-12-13 11:49:09 -08001315 private boolean isResizeable(boolean checkSupportsPip) {
1316 return (mService.mForceResizableActivities || ActivityInfo.isResizeableMode(mResizeMode)
1317 || (checkSupportsPip && mSupportsPictureInPicture)) && !mTemporarilyUnresizable;
1318 }
1319
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001320 boolean isResizeable() {
Winson Chungd3395382016-12-13 11:49:09 -08001321 return isResizeable(true /* checkSupportsPip */);
1322 }
1323
1324 boolean supportsSplitScreen() {
1325 // A task can not be docked even if it is considered resizeable because it only supports
1326 // picture-in-picture mode but has a non-resizeable resizeMode
1327 return mService.mSupportsSplitScreenMultiWindow
1328 && isResizeable(false /* checkSupportsPip */)
1329 && !ActivityInfo.isPreserveOrientationMode(mResizeMode);
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001330 }
1331
skuhne@google.com322347b2016-12-02 12:54:03 -08001332 /**
1333 * Check that a given bounds matches the application requested orientation.
1334 *
1335 * @param bounds The bounds to be tested.
1336 * @return True if the requested bounds are okay for a resizing request.
1337 */
1338 boolean canResizeToBounds(Rect bounds) {
1339 if (bounds == null || getStackId() != FREEFORM_WORKSPACE_STACK_ID) {
1340 // Note: If not on the freeform workspace, we ignore the bounds.
1341 return true;
1342 }
1343 final boolean landscape = bounds.width() > bounds.height();
1344 if (mResizeMode == RESIZE_MODE_FORCE_RESIZABLE_PRESERVE_ORIENTATION) {
1345 return mBounds == null || landscape == (mBounds.width() > mBounds.height());
1346 }
1347 return (mResizeMode != RESIZE_MODE_FORCE_RESIZABLE_PORTRAIT_ONLY || !landscape)
1348 && (mResizeMode != RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY || landscape);
1349 }
1350
Jiaquan Hedd1e66f2016-06-15 15:15:12 -07001351 boolean isOnTopLauncher() {
1352 return isHomeTask() && mIsOnTopLauncher;
1353 }
1354
Craig Mautner525f3d92013-05-07 14:01:50 -07001355 /**
1356 * Find the activity in the history stack within the given task. Returns
1357 * the index within the history at which it's found, or < 0 if not found.
1358 */
1359 final ActivityRecord findActivityInHistoryLocked(ActivityRecord r) {
1360 final ComponentName realActivity = r.realActivity;
1361 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1362 ActivityRecord candidate = mActivities.get(activityNdx);
1363 if (candidate.finishing) {
1364 continue;
1365 }
1366 if (candidate.realActivity.equals(realActivity)) {
1367 return candidate;
1368 }
1369 }
1370 return null;
1371 }
1372
Winson Chunga449dc02014-05-16 11:15:04 -07001373 /** Updates the last task description values. */
1374 void updateTaskDescription() {
1375 // Traverse upwards looking for any break between main task activities and
1376 // utility activities.
1377 int activityNdx;
1378 final int numActivities = mActivities.size();
Wale Ogunwale3eadad72016-10-13 09:16:59 -07001379 final boolean relinquish = numActivities != 0 &&
1380 (mActivities.get(0).info.flags & FLAG_RELINQUISH_TASK_IDENTITY) != 0;
Winson Chunga449dc02014-05-16 11:15:04 -07001381 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
Craig Mautner21d24a22014-04-23 11:45:37 -07001382 ++activityNdx) {
Winson Chunga449dc02014-05-16 11:15:04 -07001383 final ActivityRecord r = mActivities.get(activityNdx);
Wale Ogunwale3eadad72016-10-13 09:16:59 -07001384 if (relinquish && (r.info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001385 // This will be the top activity for determining taskDescription. Pre-inc to
1386 // overcome initial decrement below.
1387 ++activityNdx;
1388 break;
1389 }
Winson Chunga449dc02014-05-16 11:15:04 -07001390 if (r.intent != null &&
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001391 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
Winson Chunga449dc02014-05-16 11:15:04 -07001392 break;
1393 }
1394 }
1395 if (activityNdx > 0) {
1396 // Traverse downwards starting below break looking for set label, icon.
1397 // Note that if there are activities in the task but none of them set the
1398 // recent activity values, then we do not fall back to the last set
1399 // values in the TaskRecord.
1400 String label = null;
Craig Mautner648f69b2014-09-18 14:16:26 -07001401 String iconFilename = null;
Winson Chunga449dc02014-05-16 11:15:04 -07001402 int colorPrimary = 0;
Winson Chung1af8eda2016-02-05 17:55:56 +00001403 int colorBackground = 0;
Winson Chunga449dc02014-05-16 11:15:04 -07001404 for (--activityNdx; activityNdx >= 0; --activityNdx) {
1405 final ActivityRecord r = mActivities.get(activityNdx);
1406 if (r.taskDescription != null) {
1407 if (label == null) {
1408 label = r.taskDescription.getLabel();
1409 }
Craig Mautner648f69b2014-09-18 14:16:26 -07001410 if (iconFilename == null) {
1411 iconFilename = r.taskDescription.getIconFilename();
Winson Chunga449dc02014-05-16 11:15:04 -07001412 }
1413 if (colorPrimary == 0) {
1414 colorPrimary = r.taskDescription.getPrimaryColor();
Winson Chunga449dc02014-05-16 11:15:04 -07001415 }
Winson Chung1af8eda2016-02-05 17:55:56 +00001416 if (colorBackground == 0) {
1417 colorBackground = r.taskDescription.getBackgroundColor();
1418 }
Winson Chunga449dc02014-05-16 11:15:04 -07001419 }
1420 }
Winson Chung1af8eda2016-02-05 17:55:56 +00001421 lastTaskDescription = new TaskDescription(label, null, iconFilename, colorPrimary,
1422 colorBackground);
Jorim Jaggi829b9cd2017-01-23 16:20:53 +01001423 if (mWindowContainerController != null) {
1424 mWindowContainerController.setTaskDescription(lastTaskDescription);
1425 }
Winson Chungec396d62014-08-06 17:08:00 -07001426 // Update the task affiliation color if we are the parent of the group
1427 if (taskId == mAffiliatedTaskId) {
1428 mAffiliatedTaskColor = lastTaskDescription.getPrimaryColor();
1429 }
Winson Chunga449dc02014-05-16 11:15:04 -07001430 }
1431 }
1432
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001433 int findEffectiveRootIndex() {
Craig Mautner4767f4b2014-09-18 15:38:33 -07001434 int effectiveNdx = 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001435 final int topActivityNdx = mActivities.size() - 1;
Dianne Hackborn39569af2014-09-23 10:56:58 -07001436 for (int activityNdx = 0; activityNdx <= topActivityNdx; ++activityNdx) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001437 final ActivityRecord r = mActivities.get(activityNdx);
1438 if (r.finishing) {
1439 continue;
1440 }
Craig Mautner4767f4b2014-09-18 15:38:33 -07001441 effectiveNdx = activityNdx;
Wale Ogunwale3eadad72016-10-13 09:16:59 -07001442 if ((r.info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001443 break;
1444 }
1445 }
Craig Mautner4767f4b2014-09-18 15:38:33 -07001446 return effectiveNdx;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001447 }
1448
1449 void updateEffectiveIntent() {
1450 final int effectiveRootIndex = findEffectiveRootIndex();
1451 final ActivityRecord r = mActivities.get(effectiveRootIndex);
Winson Chungfee26772014-08-05 12:21:52 -07001452 setIntent(r);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001453 }
1454
Craig Mautner21d24a22014-04-23 11:45:37 -07001455 void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001456 if (DEBUG_RECENTS) Slog.i(TAG_RECENTS, "Saving task=" + this);
Craig Mautner21d24a22014-04-23 11:45:37 -07001457
1458 out.attribute(null, ATTR_TASKID, String.valueOf(taskId));
1459 if (realActivity != null) {
1460 out.attribute(null, ATTR_REALACTIVITY, realActivity.flattenToShortString());
1461 }
Andrei Stingaceanu4ccec532016-01-13 12:10:21 +00001462 out.attribute(null, ATTR_REALACTIVITY_SUSPENDED, String.valueOf(realActivitySuspended));
Craig Mautner21d24a22014-04-23 11:45:37 -07001463 if (origActivity != null) {
1464 out.attribute(null, ATTR_ORIGACTIVITY, origActivity.flattenToShortString());
1465 }
Dianne Hackborn79228822014-09-16 11:11:23 -07001466 // Write affinity, and root affinity if it is different from affinity.
1467 // We use the special string "@" for a null root affinity, so we can identify
1468 // later whether we were given a root affinity or should just make it the
1469 // same as the affinity.
Craig Mautner21d24a22014-04-23 11:45:37 -07001470 if (affinity != null) {
1471 out.attribute(null, ATTR_AFFINITY, affinity);
Dianne Hackborn79228822014-09-16 11:11:23 -07001472 if (!affinity.equals(rootAffinity)) {
1473 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
1474 }
1475 } else if (rootAffinity != null) {
1476 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
Craig Mautner21d24a22014-04-23 11:45:37 -07001477 }
1478 out.attribute(null, ATTR_ROOTHASRESET, String.valueOf(rootWasReset));
Dianne Hackborn13420f22014-07-18 15:43:56 -07001479 out.attribute(null, ATTR_AUTOREMOVERECENTS, String.valueOf(autoRemoveRecents));
Craig Mautner21d24a22014-04-23 11:45:37 -07001480 out.attribute(null, ATTR_ASKEDCOMPATMODE, String.valueOf(askedCompatMode));
1481 out.attribute(null, ATTR_USERID, String.valueOf(userId));
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001482 out.attribute(null, ATTR_USER_SETUP_COMPLETE, String.valueOf(mUserSetupComplete));
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001483 out.attribute(null, ATTR_EFFECTIVE_UID, String.valueOf(effectiveUid));
Craig Mautner21d24a22014-04-23 11:45:37 -07001484 out.attribute(null, ATTR_TASKTYPE, String.valueOf(taskType));
Winson Chungffa2ec62014-07-03 15:54:42 -07001485 out.attribute(null, ATTR_FIRSTACTIVETIME, String.valueOf(firstActiveTime));
Winson Chungf1fbd772014-06-24 18:06:58 -07001486 out.attribute(null, ATTR_LASTACTIVETIME, String.valueOf(lastActiveTime));
Craig Mautner21d24a22014-04-23 11:45:37 -07001487 out.attribute(null, ATTR_LASTTIMEMOVED, String.valueOf(mLastTimeMoved));
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001488 out.attribute(null, ATTR_NEVERRELINQUISH, String.valueOf(mNeverRelinquishIdentity));
Craig Mautner21d24a22014-04-23 11:45:37 -07001489 if (lastDescription != null) {
1490 out.attribute(null, ATTR_LASTDESCRIPTION, lastDescription.toString());
1491 }
Winson Chung2cb86c72014-06-25 12:03:30 -07001492 if (lastTaskDescription != null) {
Craig Mautner648f69b2014-09-18 14:16:26 -07001493 lastTaskDescription.saveToXml(out);
Winson Chung2cb86c72014-06-25 12:03:30 -07001494 }
Winson Chung36f3f032016-09-08 23:29:43 +00001495 mLastThumbnailInfo.saveToXml(out);
Winson Chungec396d62014-08-06 17:08:00 -07001496 out.attribute(null, ATTR_TASK_AFFILIATION_COLOR, String.valueOf(mAffiliatedTaskColor));
Craig Mautnera228ae92014-07-09 05:44:55 -07001497 out.attribute(null, ATTR_TASK_AFFILIATION, String.valueOf(mAffiliatedTaskId));
1498 out.attribute(null, ATTR_PREV_AFFILIATION, String.valueOf(mPrevAffiliateTaskId));
1499 out.attribute(null, ATTR_NEXT_AFFILIATION, String.valueOf(mNextAffiliateTaskId));
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001500 out.attribute(null, ATTR_CALLING_UID, String.valueOf(mCallingUid));
1501 out.attribute(null, ATTR_CALLING_PACKAGE, mCallingPackage == null ? "" : mCallingPackage);
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001502 out.attribute(null, ATTR_RESIZE_MODE, String.valueOf(mResizeMode));
Winson Chungd3395382016-12-13 11:49:09 -08001503 out.attribute(null, ATTR_SUPPORTS_PICTURE_IN_PICTURE,
1504 String.valueOf(mSupportsPictureInPicture));
Wale Ogunwalea7afaa22015-05-01 20:39:18 -07001505 out.attribute(null, ATTR_PRIVILEGED, String.valueOf(mPrivileged));
Wale Ogunwale706ed792015-08-02 10:29:44 -07001506 if (mLastNonFullscreenBounds != null) {
1507 out.attribute(
1508 null, ATTR_NON_FULLSCREEN_BOUNDS, mLastNonFullscreenBounds.flattenToString());
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001509 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001510 out.attribute(null, ATTR_MIN_WIDTH, String.valueOf(mMinWidth));
1511 out.attribute(null, ATTR_MIN_HEIGHT, String.valueOf(mMinHeight));
Wale Ogunwale625ed0c2016-10-18 08:50:31 -07001512 out.attribute(null, ATTR_PERSIST_TASK_VERSION, String.valueOf(PERSIST_TASK_VERSION));
Winson Chung2cb86c72014-06-25 12:03:30 -07001513
Craig Mautner21d24a22014-04-23 11:45:37 -07001514 if (affinityIntent != null) {
1515 out.startTag(null, TAG_AFFINITYINTENT);
1516 affinityIntent.saveToXml(out);
1517 out.endTag(null, TAG_AFFINITYINTENT);
1518 }
1519
Winson Chung36f3f032016-09-08 23:29:43 +00001520 out.startTag(null, TAG_INTENT);
1521 intent.saveToXml(out);
1522 out.endTag(null, TAG_INTENT);
Craig Mautner21d24a22014-04-23 11:45:37 -07001523
1524 final ArrayList<ActivityRecord> activities = mActivities;
1525 final int numActivities = activities.size();
1526 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
1527 final ActivityRecord r = activities.get(activityNdx);
Craig Mautner43e52ed2014-06-16 17:18:52 -07001528 if (r.info.persistableMode == ActivityInfo.PERSIST_ROOT_ONLY || !r.isPersistable() ||
Wale Ogunwale843bfb92015-03-27 11:06:48 -07001529 ((r.intent.getFlags() & FLAG_ACTIVITY_NEW_DOCUMENT
1530 | FLAG_ACTIVITY_RETAIN_IN_RECENTS) == FLAG_ACTIVITY_NEW_DOCUMENT) &&
Craig Mautner43e52ed2014-06-16 17:18:52 -07001531 activityNdx > 0) {
Craig Mautnerf357c0c2014-06-09 09:23:27 -07001532 // Stop at first non-persistable or first break in task (CLEAR_WHEN_TASK_RESET).
Craig Mautner21d24a22014-04-23 11:45:37 -07001533 break;
1534 }
1535 out.startTag(null, TAG_ACTIVITY);
1536 r.saveToXml(out);
1537 out.endTag(null, TAG_ACTIVITY);
1538 }
Craig Mautner21d24a22014-04-23 11:45:37 -07001539 }
1540
Winson Chung36f3f032016-09-08 23:29:43 +00001541 static TaskRecord restoreFromXml(XmlPullParser in, ActivityStackSupervisor stackSupervisor)
1542 throws IOException, XmlPullParserException {
Craig Mautner21d24a22014-04-23 11:45:37 -07001543 Intent intent = null;
1544 Intent affinityIntent = null;
Winsonc809cbb2015-11-02 12:06:15 -08001545 ArrayList<ActivityRecord> activities = new ArrayList<>();
Craig Mautner21d24a22014-04-23 11:45:37 -07001546 ComponentName realActivity = null;
Andrei Stingaceanu4ccec532016-01-13 12:10:21 +00001547 boolean realActivitySuspended = false;
Craig Mautner21d24a22014-04-23 11:45:37 -07001548 ComponentName origActivity = null;
1549 String affinity = null;
Dianne Hackborn79228822014-09-16 11:11:23 -07001550 String rootAffinity = null;
1551 boolean hasRootAffinity = false;
Craig Mautner21d24a22014-04-23 11:45:37 -07001552 boolean rootHasReset = false;
Dianne Hackborn13420f22014-07-18 15:43:56 -07001553 boolean autoRemoveRecents = false;
Craig Mautner21d24a22014-04-23 11:45:37 -07001554 boolean askedCompatMode = false;
1555 int taskType = ActivityRecord.APPLICATION_ACTIVITY_TYPE;
Craig Mautner21d24a22014-04-23 11:45:37 -07001556 int userId = 0;
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001557 boolean userSetupComplete = true;
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001558 int effectiveUid = -1;
Craig Mautner21d24a22014-04-23 11:45:37 -07001559 String lastDescription = null;
Winson Chungffa2ec62014-07-03 15:54:42 -07001560 long firstActiveTime = -1;
Winson Chung2cb86c72014-06-25 12:03:30 -07001561 long lastActiveTime = -1;
Craig Mautner21d24a22014-04-23 11:45:37 -07001562 long lastTimeOnTop = 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001563 boolean neverRelinquishIdentity = true;
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001564 int taskId = INVALID_TASK_ID;
Craig Mautner21d24a22014-04-23 11:45:37 -07001565 final int outerDepth = in.getDepth();
Craig Mautner648f69b2014-09-18 14:16:26 -07001566 TaskDescription taskDescription = new TaskDescription();
Winsonc809cbb2015-11-02 12:06:15 -08001567 TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
Wale Ogunwale18795a22014-12-03 11:38:33 -08001568 int taskAffiliation = INVALID_TASK_ID;
Winson Chungec396d62014-08-06 17:08:00 -07001569 int taskAffiliationColor = 0;
Wale Ogunwale18795a22014-12-03 11:38:33 -08001570 int prevTaskId = INVALID_TASK_ID;
1571 int nextTaskId = INVALID_TASK_ID;
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001572 int callingUid = -1;
1573 String callingPackage = "";
Wale Ogunwaled829d362016-02-10 19:24:49 -08001574 int resizeMode = RESIZE_MODE_FORCE_RESIZEABLE;
Winson Chungd3395382016-12-13 11:49:09 -08001575 boolean supportsPictureInPicture = false;
Wale Ogunwalea7afaa22015-05-01 20:39:18 -07001576 boolean privileged = false;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001577 Rect bounds = null;
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001578 int minWidth = INVALID_MIN_SIZE;
1579 int minHeight = INVALID_MIN_SIZE;
Wale Ogunwale625ed0c2016-10-18 08:50:31 -07001580 int persistTaskVersion = 0;
Craig Mautner21d24a22014-04-23 11:45:37 -07001581
1582 for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
1583 final String attrName = in.getAttributeName(attrNdx);
1584 final String attrValue = in.getAttributeValue(attrNdx);
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001585 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: attribute name=" +
1586 attrName + " value=" + attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001587 if (ATTR_TASKID.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001588 if (taskId == INVALID_TASK_ID) taskId = Integer.parseInt(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001589 } else if (ATTR_REALACTIVITY.equals(attrName)) {
1590 realActivity = ComponentName.unflattenFromString(attrValue);
Andrei Stingaceanu4ccec532016-01-13 12:10:21 +00001591 } else if (ATTR_REALACTIVITY_SUSPENDED.equals(attrName)) {
1592 realActivitySuspended = Boolean.valueOf(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001593 } else if (ATTR_ORIGACTIVITY.equals(attrName)) {
1594 origActivity = ComponentName.unflattenFromString(attrValue);
1595 } else if (ATTR_AFFINITY.equals(attrName)) {
1596 affinity = attrValue;
Dianne Hackborn79228822014-09-16 11:11:23 -07001597 } else if (ATTR_ROOT_AFFINITY.equals(attrName)) {
1598 rootAffinity = attrValue;
1599 hasRootAffinity = true;
Craig Mautner21d24a22014-04-23 11:45:37 -07001600 } else if (ATTR_ROOTHASRESET.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01001601 rootHasReset = Boolean.parseBoolean(attrValue);
Dianne Hackborn13420f22014-07-18 15:43:56 -07001602 } else if (ATTR_AUTOREMOVERECENTS.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01001603 autoRemoveRecents = Boolean.parseBoolean(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001604 } else if (ATTR_ASKEDCOMPATMODE.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01001605 askedCompatMode = Boolean.parseBoolean(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001606 } else if (ATTR_USERID.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001607 userId = Integer.parseInt(attrValue);
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001608 } else if (ATTR_USER_SETUP_COMPLETE.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01001609 userSetupComplete = Boolean.parseBoolean(attrValue);
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001610 } else if (ATTR_EFFECTIVE_UID.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001611 effectiveUid = Integer.parseInt(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001612 } else if (ATTR_TASKTYPE.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001613 taskType = Integer.parseInt(attrValue);
Winson Chungffa2ec62014-07-03 15:54:42 -07001614 } else if (ATTR_FIRSTACTIVETIME.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01001615 firstActiveTime = Long.parseLong(attrValue);
Winson Chungf1fbd772014-06-24 18:06:58 -07001616 } else if (ATTR_LASTACTIVETIME.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01001617 lastActiveTime = Long.parseLong(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001618 } else if (ATTR_LASTDESCRIPTION.equals(attrName)) {
1619 lastDescription = attrValue;
1620 } else if (ATTR_LASTTIMEMOVED.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01001621 lastTimeOnTop = Long.parseLong(attrValue);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001622 } else if (ATTR_NEVERRELINQUISH.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01001623 neverRelinquishIdentity = Boolean.parseBoolean(attrValue);
Winsonc809cbb2015-11-02 12:06:15 -08001624 } else if (attrName.startsWith(TaskThumbnailInfo.ATTR_TASK_THUMBNAILINFO_PREFIX)) {
1625 thumbnailInfo.restoreFromXml(attrName, attrValue);
Craig Mautner648f69b2014-09-18 14:16:26 -07001626 } else if (attrName.startsWith(TaskDescription.ATTR_TASKDESCRIPTION_PREFIX)) {
1627 taskDescription.restoreFromXml(attrName, attrValue);
Craig Mautnera228ae92014-07-09 05:44:55 -07001628 } else if (ATTR_TASK_AFFILIATION.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001629 taskAffiliation = Integer.parseInt(attrValue);
Craig Mautnera228ae92014-07-09 05:44:55 -07001630 } else if (ATTR_PREV_AFFILIATION.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001631 prevTaskId = Integer.parseInt(attrValue);
Craig Mautnera228ae92014-07-09 05:44:55 -07001632 } else if (ATTR_NEXT_AFFILIATION.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001633 nextTaskId = Integer.parseInt(attrValue);
Winson Chungec396d62014-08-06 17:08:00 -07001634 } else if (ATTR_TASK_AFFILIATION_COLOR.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001635 taskAffiliationColor = Integer.parseInt(attrValue);
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001636 } else if (ATTR_CALLING_UID.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001637 callingUid = Integer.parseInt(attrValue);
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001638 } else if (ATTR_CALLING_PACKAGE.equals(attrName)) {
1639 callingPackage = attrValue;
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001640 } else if (ATTR_RESIZE_MODE.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001641 resizeMode = Integer.parseInt(attrValue);
Winson Chungd3395382016-12-13 11:49:09 -08001642 } else if (ATTR_SUPPORTS_PICTURE_IN_PICTURE.equals(attrName)) {
1643 supportsPictureInPicture = Boolean.parseBoolean(attrValue);
Wale Ogunwalea7afaa22015-05-01 20:39:18 -07001644 } else if (ATTR_PRIVILEGED.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01001645 privileged = Boolean.parseBoolean(attrValue);
Wale Ogunwale706ed792015-08-02 10:29:44 -07001646 } else if (ATTR_NON_FULLSCREEN_BOUNDS.equals(attrName)) {
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001647 bounds = Rect.unflattenFromString(attrValue);
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001648 } else if (ATTR_MIN_WIDTH.equals(attrName)) {
1649 minWidth = Integer.parseInt(attrValue);
1650 } else if (ATTR_MIN_HEIGHT.equals(attrName)) {
1651 minHeight = Integer.parseInt(attrValue);
Wale Ogunwale625ed0c2016-10-18 08:50:31 -07001652 } else if (ATTR_PERSIST_TASK_VERSION.equals(attrName)) {
1653 persistTaskVersion = Integer.parseInt(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001654 } else {
1655 Slog.w(TAG, "TaskRecord: Unknown attribute=" + attrName);
1656 }
1657 }
1658
1659 int event;
1660 while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
Ben Kwa8814cf42015-07-08 10:54:56 -07001661 (event != XmlPullParser.END_TAG || in.getDepth() >= outerDepth)) {
Craig Mautner21d24a22014-04-23 11:45:37 -07001662 if (event == XmlPullParser.START_TAG) {
1663 final String name = in.getName();
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001664 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: START_TAG name=" +
1665 name);
Craig Mautner21d24a22014-04-23 11:45:37 -07001666 if (TAG_AFFINITYINTENT.equals(name)) {
1667 affinityIntent = Intent.restoreFromXml(in);
1668 } else if (TAG_INTENT.equals(name)) {
1669 intent = Intent.restoreFromXml(in);
1670 } else if (TAG_ACTIVITY.equals(name)) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08001671 ActivityRecord activity = ActivityRecord.restoreFromXml(in, stackSupervisor);
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001672 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: activity=" +
1673 activity);
Craig Mautner21d24a22014-04-23 11:45:37 -07001674 if (activity != null) {
1675 activities.add(activity);
1676 }
1677 } else {
1678 Slog.e(TAG, "restoreTask: Unexpected name=" + name);
1679 XmlUtils.skipCurrentTag(in);
1680 }
1681 }
1682 }
Dianne Hackborn79228822014-09-16 11:11:23 -07001683 if (!hasRootAffinity) {
1684 rootAffinity = affinity;
1685 } else if ("@".equals(rootAffinity)) {
1686 rootAffinity = null;
1687 }
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001688 if (effectiveUid <= 0) {
1689 Intent checkIntent = intent != null ? intent : affinityIntent;
1690 effectiveUid = 0;
1691 if (checkIntent != null) {
1692 IPackageManager pm = AppGlobals.getPackageManager();
1693 try {
1694 ApplicationInfo ai = pm.getApplicationInfo(
1695 checkIntent.getComponent().getPackageName(),
Amith Yamasani0d1fd8d2016-10-12 14:21:51 -07001696 PackageManager.MATCH_UNINSTALLED_PACKAGES
1697 | PackageManager.MATCH_DISABLED_COMPONENTS, userId);
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001698 if (ai != null) {
1699 effectiveUid = ai.uid;
1700 }
1701 } catch (RemoteException e) {
1702 }
1703 }
1704 Slog.w(TAG, "Updating task #" + taskId + " for " + checkIntent
1705 + ": effectiveUid=" + effectiveUid);
1706 }
1707
Wale Ogunwale625ed0c2016-10-18 08:50:31 -07001708 if (persistTaskVersion < 1) {
1709 // We need to convert the resize mode of home activities saved before version one if
1710 // they are marked as RESIZE_MODE_RESIZEABLE to RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION
1711 // since we didn't have that differentiation before version 1 and the system didn't
1712 // resize home activities before then.
1713 if (taskType == HOME_ACTIVITY_TYPE && resizeMode == RESIZE_MODE_RESIZEABLE) {
1714 resizeMode = RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
1715 }
Winson Chungd3395382016-12-13 11:49:09 -08001716 } else {
1717 // This activity has previously marked itself explicitly as both resizeable and
1718 // supporting picture-in-picture. Since there is no longer a requirement for
1719 // picture-in-picture activities to be resizeable, we can mark this simply as
1720 // resizeable and supporting picture-in-picture separately.
1721 if (resizeMode == RESIZE_MODE_RESIZEABLE_AND_PIPABLE_DEPRECATED) {
1722 resizeMode = RESIZE_MODE_RESIZEABLE;
1723 supportsPictureInPicture = true;
1724 }
Wale Ogunwale625ed0c2016-10-18 08:50:31 -07001725 }
1726
Winson Chung36f3f032016-09-08 23:29:43 +00001727 final TaskRecord task = new TaskRecord(stackSupervisor.mService, taskId, intent,
Dianne Hackborn79228822014-09-16 11:11:23 -07001728 affinityIntent, affinity, rootAffinity, realActivity, origActivity, rootHasReset,
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001729 autoRemoveRecents, askedCompatMode, taskType, userId, effectiveUid, lastDescription,
1730 activities, firstActiveTime, lastActiveTime, lastTimeOnTop, neverRelinquishIdentity,
Winsonc809cbb2015-11-02 12:06:15 -08001731 taskDescription, thumbnailInfo, taskAffiliation, prevTaskId, nextTaskId,
Winson Chungd3395382016-12-13 11:49:09 -08001732 taskAffiliationColor, callingUid, callingPackage, resizeMode,
1733 supportsPictureInPicture, privileged, realActivitySuspended, userSetupComplete,
1734 minWidth, minHeight);
Filip Gruszczynskiaff7f132015-09-02 17:21:21 -07001735 task.updateOverrideConfiguration(bounds);
Craig Mautner21d24a22014-04-23 11:45:37 -07001736
1737 for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001738 activities.get(activityNdx).task = task;
Craig Mautner21d24a22014-04-23 11:45:37 -07001739 }
1740
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001741 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Restored task=" + task);
Craig Mautner21d24a22014-04-23 11:45:37 -07001742 return task;
1743 }
1744
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001745 private void adjustForMinimalTaskDimensions(Rect bounds) {
1746 if (bounds == null) {
1747 return;
1748 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001749 int minWidth = mMinWidth;
1750 int minHeight = mMinHeight;
Robert Carr9c5867d2016-03-10 15:52:46 -08001751 // If the task has no requested minimal size, we'd like to enforce a minimal size
1752 // so that the user can not render the task too small to manipulate. We don't need
1753 // to do this for the pinned stack as the bounds are controlled by the system.
Andrii Kulian02b7a832016-10-06 23:11:56 -07001754 if (getStackId() != PINNED_STACK_ID) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001755 if (minWidth == INVALID_MIN_SIZE) {
1756 minWidth = mService.mStackSupervisor.mDefaultMinSizeOfResizeableTask;
Andrii Kulian2e751b82016-03-16 16:59:32 -07001757 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001758 if (minHeight == INVALID_MIN_SIZE) {
1759 minHeight = mService.mStackSupervisor.mDefaultMinSizeOfResizeableTask;
Andrii Kulian2e751b82016-03-16 16:59:32 -07001760 }
Robert Carr9c5867d2016-03-10 15:52:46 -08001761 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001762 final boolean adjustWidth = minWidth > bounds.width();
1763 final boolean adjustHeight = minHeight > bounds.height();
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001764 if (!(adjustWidth || adjustHeight)) {
1765 return;
1766 }
1767
1768 if (adjustWidth) {
1769 if (mBounds != null && bounds.right == mBounds.right) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001770 bounds.left = bounds.right - minWidth;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001771 } else {
1772 // Either left bounds match, or neither match, or the previous bounds were
1773 // fullscreen and we default to keeping left.
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001774 bounds.right = bounds.left + minWidth;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001775 }
1776 }
1777 if (adjustHeight) {
1778 if (mBounds != null && bounds.bottom == mBounds.bottom) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001779 bounds.top = bounds.bottom - minHeight;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001780 } else {
1781 // Either top bounds match, or neither match, or the previous bounds were
1782 // fullscreen and we default to keeping top.
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001783 bounds.bottom = bounds.top + minHeight;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001784 }
1785 }
1786 }
1787
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001788 /**
1789 * Update task's override configuration based on the bounds.
Jorim Jaggi0a932142016-02-01 17:42:25 -08001790 * @param bounds The bounds of the task.
Andrii Kulian8072d112016-09-16 11:11:01 -07001791 * @return True if the override configuration was updated.
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001792 */
Andrii Kulian8072d112016-09-16 11:11:01 -07001793 boolean updateOverrideConfiguration(Rect bounds) {
Jorim Jaggi0a932142016-02-01 17:42:25 -08001794 return updateOverrideConfiguration(bounds, null /* insetBounds */);
1795 }
1796
1797 /**
1798 * Update task's override configuration based on the bounds.
1799 * @param bounds The bounds of the task.
1800 * @param insetBounds The bounds used to calculate the system insets, which is used here to
1801 * subtract the navigation bar/status bar size from the screen size reported
1802 * to the application. See {@link IActivityManager#resizeDockedStack}.
Andrii Kulian8072d112016-09-16 11:11:01 -07001803 * @return True if the override configuration was updated.
Jorim Jaggi0a932142016-02-01 17:42:25 -08001804 */
Andrii Kulian8072d112016-09-16 11:11:01 -07001805 boolean updateOverrideConfiguration(Rect bounds, @Nullable Rect insetBounds) {
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001806 if (Objects.equals(mBounds, bounds)) {
Andrii Kulian8072d112016-09-16 11:11:01 -07001807 return false;
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001808 }
Andrii Kulian1779e612016-10-12 21:58:25 -07001809 mTmpConfig.setTo(getOverrideConfiguration());
Wale Ogunwale5f986092015-12-04 15:35:38 -08001810 final boolean oldFullscreen = mFullscreen;
Andrii Kulian1779e612016-10-12 21:58:25 -07001811 final Configuration newConfig = getOverrideConfiguration();
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001812
1813 mFullscreen = bounds == null;
Wale Ogunwale706ed792015-08-02 10:29:44 -07001814 if (mFullscreen) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001815 if (mBounds != null && StackId.persistTaskBounds(mStack.mStackId)) {
Wale Ogunwale706ed792015-08-02 10:29:44 -07001816 mLastNonFullscreenBounds = mBounds;
1817 }
1818 mBounds = null;
Andrii Kulian1779e612016-10-12 21:58:25 -07001819 newConfig.unset();
Wale Ogunwale706ed792015-08-02 10:29:44 -07001820 } else {
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001821 mTmpRect.set(bounds);
1822 adjustForMinimalTaskDimensions(mTmpRect);
Chong Zhangb15758a2015-11-17 12:12:03 -08001823 if (mBounds == null) {
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001824 mBounds = new Rect(mTmpRect);
Chong Zhangb15758a2015-11-17 12:12:03 -08001825 } else {
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001826 mBounds.set(mTmpRect);
Chong Zhangb15758a2015-11-17 12:12:03 -08001827 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07001828 if (mStack == null || StackId.persistTaskBounds(mStack.mStackId)) {
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -07001829 mLastNonFullscreenBounds = mBounds;
1830 }
Andrii Kulian1779e612016-10-12 21:58:25 -07001831 calculateOverrideConfig(newConfig, mTmpRect, insetBounds,
Andrii Kuliandaea3572016-04-08 13:20:51 -07001832 mTmpRect.right != bounds.right, mTmpRect.bottom != bounds.bottom);
Wale Ogunwale706ed792015-08-02 10:29:44 -07001833 }
Andrii Kulian1779e612016-10-12 21:58:25 -07001834 onOverrideConfigurationChanged(newConfig);
Wale Ogunwale5f986092015-12-04 15:35:38 -08001835
1836 if (mFullscreen != oldFullscreen) {
Andrii Kulian933076d2016-03-29 17:04:42 -07001837 mService.mStackSupervisor.scheduleReportMultiWindowModeChanged(this);
Wale Ogunwale5f986092015-12-04 15:35:38 -08001838 }
1839
Andrii Kulian1779e612016-10-12 21:58:25 -07001840 return !mTmpConfig.equals(newConfig);
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001841 }
1842
Andrii Kuliandaea3572016-04-08 13:20:51 -07001843 private void subtractNonDecorInsets(Rect inOutBounds, Rect inInsetBounds,
1844 boolean overrideWidth, boolean overrideHeight) {
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001845 mTmpRect2.set(inInsetBounds);
1846 mService.mWindowManager.subtractNonDecorInsets(mTmpRect2);
1847 int leftInset = mTmpRect2.left - inInsetBounds.left;
1848 int topInset = mTmpRect2.top - inInsetBounds.top;
Andrii Kuliandaea3572016-04-08 13:20:51 -07001849 int rightInset = overrideWidth ? 0 : inInsetBounds.right - mTmpRect2.right;
1850 int bottomInset = overrideHeight ? 0 : inInsetBounds.bottom - mTmpRect2.bottom;
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001851 inOutBounds.inset(leftInset, topInset, rightInset, bottomInset);
1852 }
1853
Andrii Kuliandaea3572016-04-08 13:20:51 -07001854 private void subtractStableInsets(Rect inOutBounds, Rect inInsetBounds,
1855 boolean overrideWidth, boolean overrideHeight) {
Jorim Jaggi0a932142016-02-01 17:42:25 -08001856 mTmpRect2.set(inInsetBounds);
1857 mService.mWindowManager.subtractStableInsets(mTmpRect2);
1858 int leftInset = mTmpRect2.left - inInsetBounds.left;
1859 int topInset = mTmpRect2.top - inInsetBounds.top;
Andrii Kuliandaea3572016-04-08 13:20:51 -07001860 int rightInset = overrideWidth ? 0 : inInsetBounds.right - mTmpRect2.right;
1861 int bottomInset = overrideHeight ? 0 : inInsetBounds.bottom - mTmpRect2.bottom;
Jorim Jaggi0a932142016-02-01 17:42:25 -08001862 inOutBounds.inset(leftInset, topInset, rightInset, bottomInset);
1863 }
1864
Andrii Kulian1779e612016-10-12 21:58:25 -07001865 /** Clears passed config and fills it with new override values. */
Andrii Kuliana8a9bc52016-10-14 11:00:13 -07001866 private void calculateOverrideConfig(Configuration config, Rect bounds, Rect insetBounds,
1867 boolean overrideWidth, boolean overrideHeight) {
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001868 mTmpNonDecorBounds.set(bounds);
1869 mTmpStableBounds.set(bounds);
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001870
Andrii Kulian1779e612016-10-12 21:58:25 -07001871 final Configuration parentConfig = getParent().getConfiguration();
1872 config.unset();
1873 final float density = parentConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
Yorke Leef54f9da2017-01-10 07:58:59 -08001874 final boolean isFloatingTask = mStack != null && StackId.tasksAreFloating(mStack.mStackId);
1875 if (isFloatingTask) {
1876 // Floating tasks should not be resized to the screen's bounds.
1877 config.screenWidthDp = (int) (mTmpStableBounds.width() / density);
1878 config.screenHeightDp = (int) (mTmpStableBounds.height() / density);
1879 } else {
1880 // For calculating screenWidthDp, screenWidthDp, we use the stable inset screen area,
1881 // i.e. the screen area without the system bars.
1882 // Additionally task dimensions should not be bigger than its parents dimensions.
1883 subtractNonDecorInsets(mTmpNonDecorBounds, insetBounds != null ? insetBounds : bounds,
1884 overrideWidth, overrideHeight);
1885 subtractStableInsets(mTmpStableBounds, insetBounds != null ? insetBounds : bounds,
1886 overrideWidth, overrideHeight);
1887 config.screenWidthDp = Math.min(
1888 (int) (mTmpStableBounds.width() / density), parentConfig.screenWidthDp);
1889 config.screenHeightDp = Math.min(
1890 (int) (mTmpStableBounds.height() / density), parentConfig.screenHeightDp);
1891 }
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001892
1893 // TODO: Orientation?
Jorim Jaggia95ca8d2016-01-15 22:54:46 -08001894 config.orientation = (config.screenWidthDp <= config.screenHeightDp)
1895 ? Configuration.ORIENTATION_PORTRAIT
1896 : Configuration.ORIENTATION_LANDSCAPE;
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001897
Jorim Jaggi85639432016-05-06 17:27:55 -07001898 // For calculating screen layout, we need to use the non-decor inset screen area for the
1899 // calculation for compatibility reasons, i.e. screen area without system bars that could
1900 // never go away in Honeycomb.
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001901 final int compatScreenWidthDp = (int)(mTmpNonDecorBounds.width() / density);
1902 final int compatScreenHeightDp = (int)(mTmpNonDecorBounds.height() / density);
Andrii Kulian1779e612016-10-12 21:58:25 -07001903 // We're only overriding LONG, SIZE and COMPAT parts of screenLayout, so we start override
1904 // calculation with partial default.
1905 final int sl = Configuration.SCREENLAYOUT_LONG_YES | Configuration.SCREENLAYOUT_SIZE_XLARGE;
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001906 final int longSize = Math.max(compatScreenHeightDp, compatScreenWidthDp);
Andrii Kulian1779e612016-10-12 21:58:25 -07001907 final int shortSize = Math.min(compatScreenHeightDp, compatScreenWidthDp);
Jorim Jaggi85639432016-05-06 17:27:55 -07001908 config.screenLayout = Configuration.reduceScreenLayout(sl, longSize, shortSize);
1909
1910 config.smallestScreenWidthDp = mService.mWindowManager.getSmallestWidthForTaskBounds(
1911 insetBounds != null ? insetBounds : bounds);
Jorim Jaggia95ca8d2016-01-15 22:54:46 -08001912 }
1913
1914 /**
1915 * Using the existing configuration {@param config}, creates a new task override config such
1916 * that all the fields that are usually set in an override config are set to the ones in
1917 * {@param config}.
1918 */
1919 Configuration extractOverrideConfig(Configuration config) {
Andrii Kulian1779e612016-10-12 21:58:25 -07001920 final Configuration extracted = new Configuration();
Jorim Jaggia95ca8d2016-01-15 22:54:46 -08001921 extracted.screenWidthDp = config.screenWidthDp;
1922 extracted.screenHeightDp = config.screenHeightDp;
1923 extracted.smallestScreenWidthDp = config.smallestScreenWidthDp;
1924 extracted.orientation = config.orientation;
Andrii Kulian1779e612016-10-12 21:58:25 -07001925 // We're only overriding LONG, SIZE and COMPAT parts of screenLayout.
1926 extracted.screenLayout = config.screenLayout & (Configuration.SCREENLAYOUT_LONG_MASK
1927 | Configuration.SCREENLAYOUT_SIZE_MASK | Configuration.SCREENLAYOUT_COMPAT_NEEDED);
Jorim Jaggia95ca8d2016-01-15 22:54:46 -08001928 return extracted;
1929 }
1930
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08001931 Rect updateOverrideConfigurationFromLaunchBounds() {
1932 final Rect bounds = validateBounds(getLaunchBounds());
1933 updateOverrideConfiguration(bounds);
Andrii Kulian73336d812016-03-24 12:56:08 -07001934 if (bounds != null) {
1935 bounds.set(mBounds);
1936 }
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08001937 return bounds;
1938 }
1939
1940 static Rect validateBounds(Rect bounds) {
1941 if (bounds != null && bounds.isEmpty()) {
1942 Slog.wtf(TAG, "Received strange task bounds: " + bounds, new Throwable());
1943 return null;
1944 }
1945 return bounds;
1946 }
1947
Wale Ogunwale935e5022015-11-10 12:36:10 -08001948 /** Updates the task's bounds and override configuration to match what is expected for the
1949 * input stack. */
1950 void updateOverrideConfigurationForStack(ActivityStack inStack) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001951 if (mStack != null && mStack == inStack) {
Wale Ogunwale935e5022015-11-10 12:36:10 -08001952 return;
1953 }
1954
1955 if (inStack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001956 if (!isResizeable()) {
Wale Ogunwale935e5022015-11-10 12:36:10 -08001957 throw new IllegalArgumentException("Can not position non-resizeable task="
1958 + this + " in stack=" + inStack);
1959 }
1960 if (mBounds != null) {
1961 return;
1962 }
1963 if (mLastNonFullscreenBounds != null) {
1964 updateOverrideConfiguration(mLastNonFullscreenBounds);
1965 } else {
1966 inStack.layoutTaskInStack(this, null);
1967 }
1968 } else {
1969 updateOverrideConfiguration(inStack.mBounds);
1970 }
1971 }
1972
Chong Zhang0fa656b2015-08-31 15:17:21 -07001973 /**
1974 * Returns the correct stack to use based on task type and currently set bounds,
1975 * regardless of the focused stack and current stack association of the task.
1976 * The task will be moved (and stack focus changed) later if necessary.
1977 */
1978 int getLaunchStackId() {
Matthew Ngae1ff4f2016-11-10 15:49:14 -08001979 if (isRecentsTask()) {
1980 return RECENTS_STACK_ID;
1981 }
1982 if (isHomeTask()) {
Wale Ogunwale706ed792015-08-02 10:29:44 -07001983 return HOME_STACK_ID;
1984 }
Chong Zhang0fa656b2015-08-31 15:17:21 -07001985 if (mBounds != null) {
Wale Ogunwale706ed792015-08-02 10:29:44 -07001986 return FREEFORM_WORKSPACE_STACK_ID;
1987 }
1988 return FULLSCREEN_WORKSPACE_STACK_ID;
1989 }
1990
1991 /** Returns the bounds that should be used to launch this task. */
1992 Rect getLaunchBounds() {
Chong Zhang75b37202015-12-04 14:16:36 -08001993 // If we're over lockscreen, forget about stack bounds and use fullscreen.
Jorim Jaggife762342016-10-13 14:33:27 +02001994 if (mService.mStackSupervisor.mKeyguardController.isKeyguardShowing()) {
Chong Zhang75b37202015-12-04 14:16:36 -08001995 return null;
1996 }
1997
Andrii Kulian02b7a832016-10-06 23:11:56 -07001998 if (mStack == null) {
Chong Zhang7d5f5102016-01-13 10:29:24 -08001999 return null;
2000 }
2001
Andrii Kulian02b7a832016-10-06 23:11:56 -07002002 final int stackId = mStack.mStackId;
Chong Zhang7d5f5102016-01-13 10:29:24 -08002003 if (stackId == HOME_STACK_ID
Matthew Ngae1ff4f2016-11-10 15:49:14 -08002004 || stackId == RECENTS_STACK_ID
Chong Zhang7d5f5102016-01-13 10:29:24 -08002005 || stackId == FULLSCREEN_WORKSPACE_STACK_ID
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002006 || (stackId == DOCKED_STACK_ID && !isResizeable())) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07002007 return isResizeable() ? mStack.mBounds : null;
Wale Ogunwale3797c222015-10-27 14:21:58 -07002008 } else if (!StackId.persistTaskBounds(stackId)) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07002009 return mStack.mBounds;
Wale Ogunwale706ed792015-08-02 10:29:44 -07002010 }
2011 return mLastNonFullscreenBounds;
2012 }
2013
Wale Ogunwale39381972015-12-17 17:15:29 -08002014 boolean canMatchRootAffinity() {
2015 // We don't allow root affinity matching on the pinned stack as no other task should
2016 // be launching in it based on affinity.
Andrii Kulian02b7a832016-10-06 23:11:56 -07002017 return rootAffinity != null && getStackId() != PINNED_STACK_ID;
Wale Ogunwale39381972015-12-17 17:15:29 -08002018 }
2019
Jorim Jaggi8b702ed2017-01-20 16:59:03 +01002020 void addStartingWindowsForVisibleActivities(boolean taskSwitch) {
2021 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
2022 final ActivityRecord r = mActivities.get(activityNdx);
2023 if (r.visible) {
2024 r.showStartingWindow(null /* prev */, false /* newTask */, taskSwitch);
2025 }
2026 }
2027 }
2028
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002029 void dump(PrintWriter pw, String prefix) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002030 pw.print(prefix); pw.print("userId="); pw.print(userId);
Dianne Hackborn885fbe52014-08-23 15:23:58 -07002031 pw.print(" effectiveUid="); UserHandle.formatUid(pw, effectiveUid);
2032 pw.print(" mCallingUid="); UserHandle.formatUid(pw, mCallingUid);
Suprabh Shukla7745c142016-03-07 18:21:10 -08002033 pw.print(" mUserSetupComplete="); pw.print(mUserSetupComplete);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002034 pw.print(" mCallingPackage="); pw.println(mCallingPackage);
Dianne Hackborn79228822014-09-16 11:11:23 -07002035 if (affinity != null || rootAffinity != null) {
2036 pw.print(prefix); pw.print("affinity="); pw.print(affinity);
2037 if (affinity == null || !affinity.equals(rootAffinity)) {
2038 pw.print(" root="); pw.println(rootAffinity);
2039 } else {
2040 pw.println();
2041 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002042 }
Dianne Hackborn91097de2014-04-04 18:02:06 -07002043 if (voiceSession != null || voiceInteractor != null) {
2044 pw.print(prefix); pw.print("VOICE: session=0x");
2045 pw.print(Integer.toHexString(System.identityHashCode(voiceSession)));
2046 pw.print(" interactor=0x");
2047 pw.println(Integer.toHexString(System.identityHashCode(voiceInteractor)));
2048 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002049 if (intent != null) {
2050 StringBuilder sb = new StringBuilder(128);
2051 sb.append(prefix); sb.append("intent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08002052 intent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002053 sb.append('}');
2054 pw.println(sb.toString());
2055 }
2056 if (affinityIntent != null) {
2057 StringBuilder sb = new StringBuilder(128);
2058 sb.append(prefix); sb.append("affinityIntent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08002059 affinityIntent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002060 sb.append('}');
2061 pw.println(sb.toString());
2062 }
2063 if (origActivity != null) {
2064 pw.print(prefix); pw.print("origActivity=");
2065 pw.println(origActivity.flattenToShortString());
2066 }
2067 if (realActivity != null) {
2068 pw.print(prefix); pw.print("realActivity=");
2069 pw.println(realActivity.flattenToShortString());
2070 }
Dianne Hackborn852975d2014-08-22 17:42:43 -07002071 if (autoRemoveRecents || isPersistable || taskType != 0 || mTaskToReturnTo != 0
2072 || numFullscreen != 0) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002073 pw.print(prefix); pw.print("autoRemoveRecents="); pw.print(autoRemoveRecents);
Dianne Hackborn852975d2014-08-22 17:42:43 -07002074 pw.print(" isPersistable="); pw.print(isPersistable);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002075 pw.print(" numFullscreen="); pw.print(numFullscreen);
2076 pw.print(" taskType="); pw.print(taskType);
2077 pw.print(" mTaskToReturnTo="); pw.println(mTaskToReturnTo);
2078 }
Craig Mautner432f64e2015-05-20 14:59:57 -07002079 if (rootWasReset || mNeverRelinquishIdentity || mReuseTask
2080 || mLockTaskAuth != LOCK_TASK_AUTH_PINNABLE) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002081 pw.print(prefix); pw.print("rootWasReset="); pw.print(rootWasReset);
2082 pw.print(" mNeverRelinquishIdentity="); pw.print(mNeverRelinquishIdentity);
Craig Mautner432f64e2015-05-20 14:59:57 -07002083 pw.print(" mReuseTask="); pw.print(mReuseTask);
2084 pw.print(" mLockTaskAuth="); pw.println(lockTaskAuthToString());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07002085 }
Wale Ogunwale18795a22014-12-03 11:38:33 -08002086 if (mAffiliatedTaskId != taskId || mPrevAffiliateTaskId != INVALID_TASK_ID
2087 || mPrevAffiliate != null || mNextAffiliateTaskId != INVALID_TASK_ID
2088 || mNextAffiliate != null) {
Dianne Hackborn852975d2014-08-22 17:42:43 -07002089 pw.print(prefix); pw.print("affiliation="); pw.print(mAffiliatedTaskId);
2090 pw.print(" prevAffiliation="); pw.print(mPrevAffiliateTaskId);
2091 pw.print(" (");
2092 if (mPrevAffiliate == null) {
2093 pw.print("null");
2094 } else {
2095 pw.print(Integer.toHexString(System.identityHashCode(mPrevAffiliate)));
2096 }
2097 pw.print(") nextAffiliation="); pw.print(mNextAffiliateTaskId);
2098 pw.print(" (");
2099 if (mNextAffiliate == null) {
2100 pw.print("null");
2101 } else {
2102 pw.print(Integer.toHexString(System.identityHashCode(mNextAffiliate)));
2103 }
2104 pw.println(")");
2105 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002106 pw.print(prefix); pw.print("Activities="); pw.println(mActivities);
Dianne Hackborn852975d2014-08-22 17:42:43 -07002107 if (!askedCompatMode || !inRecents || !isAvailable) {
2108 pw.print(prefix); pw.print("askedCompatMode="); pw.print(askedCompatMode);
2109 pw.print(" inRecents="); pw.print(inRecents);
2110 pw.print(" isAvailable="); pw.println(isAvailable);
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002111 }
Craig Mautnerc0ffce52014-07-01 12:38:52 -07002112 pw.print(prefix); pw.print("lastThumbnail="); pw.print(mLastThumbnail);
Dianne Hackborn852975d2014-08-22 17:42:43 -07002113 pw.print(" lastThumbnailFile="); pw.println(mLastThumbnailFile);
2114 if (lastDescription != null) {
2115 pw.print(prefix); pw.print("lastDescription="); pw.println(lastDescription);
2116 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07002117 pw.print(prefix); pw.print("stackId="); pw.println(getStackId());
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002118 pw.print(prefix + "hasBeenVisible=" + hasBeenVisible);
2119 pw.print(" mResizeMode=" + ActivityInfo.resizeModeToString(mResizeMode));
Winson Chungd3395382016-12-13 11:49:09 -08002120 pw.print(" mSupportsPictureInPicture=" + mSupportsPictureInPicture);
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002121 pw.print(" isResizeable=" + isResizeable());
Winson Chung36f3f032016-09-08 23:29:43 +00002122 pw.print(" firstActiveTime=" + lastActiveTime);
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002123 pw.print(" lastActiveTime=" + lastActiveTime);
2124 pw.println(" (inactive for " + (getInactiveDuration() / 1000) + "s)");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002125 }
2126
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002127 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002128 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002129 StringBuilder sb = new StringBuilder(128);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002130 if (stringName != null) {
2131 sb.append(stringName);
2132 sb.append(" U=");
2133 sb.append(userId);
Wale Ogunwale6c5eb1c2015-11-10 07:52:22 -08002134 sb.append(" StackId=");
Andrii Kulian02b7a832016-10-06 23:11:56 -07002135 sb.append(getStackId());
Craig Mautnerde4ef022013-04-07 19:01:33 -07002136 sb.append(" sz=");
2137 sb.append(mActivities.size());
2138 sb.append('}');
2139 return sb.toString();
2140 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002141 sb.append("TaskRecord{");
2142 sb.append(Integer.toHexString(System.identityHashCode(this)));
2143 sb.append(" #");
2144 sb.append(taskId);
2145 if (affinity != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002146 sb.append(" A=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002147 sb.append(affinity);
2148 } else if (intent != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002149 sb.append(" I=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002150 sb.append(intent.getComponent().flattenToShortString());
2151 } else if (affinityIntent != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08002152 sb.append(" aI=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002153 sb.append(affinityIntent.getComponent().flattenToShortString());
2154 } else {
2155 sb.append(" ??");
2156 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07002157 stringName = sb.toString();
2158 return toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002159 }
2160}