blob: 4b726933a37b585977fb0847e8f7d9e5d67a9d6d [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
Wale Ogunwale3797c222015-10-27 14:21:58 -070019import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
20import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
21import static android.app.ActivityManager.StackId.HOME_STACK_ID;
Wale Ogunwale6c5eb1c2015-11-10 07:52:22 -080022import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
Wale Ogunwale843bfb92015-03-27 11:06:48 -070023import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
24import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
Craig Mautner15df08a2015-04-01 12:17:18 -070025import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
26import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
27import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
28import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER;
Wale Ogunwalea7afaa22015-05-01 20:39:18 -070029import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
Wale Ogunwaleee006da2015-03-30 14:49:25 -070030import static com.android.server.am.ActivityManagerDebugConfig.*;
Craig Mautner84984fa2014-06-19 11:19:20 -070031import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
32import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
33import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
Craig Mautnerde4ef022013-04-07 19:01:33 -070034
Craig Mautnerb0f7dc72013-04-01 16:34:45 -070035import android.app.Activity;
Craig Mautner9db9a0b2013-04-29 17:05:56 -070036import android.app.ActivityManager;
Wale Ogunwale3797c222015-10-27 14:21:58 -070037import android.app.ActivityManager.StackId;
Craig Mautnerc0ffce52014-07-01 12:38:52 -070038import android.app.ActivityManager.TaskThumbnail;
Craig Mautner648f69b2014-09-18 14:16:26 -070039import android.app.ActivityManager.TaskDescription;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -070040import android.app.ActivityOptions;
Dianne Hackborn885fbe52014-08-23 15:23:58 -070041import android.app.AppGlobals;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042import android.content.ComponentName;
43import android.content.Intent;
44import android.content.pm.ActivityInfo;
Dianne Hackborn885fbe52014-08-23 15:23:58 -070045import android.content.pm.ApplicationInfo;
46import android.content.pm.IPackageManager;
47import android.content.pm.PackageManager;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -070048import android.content.res.Configuration;
Craig Mautner9db9a0b2013-04-29 17:05:56 -070049import android.graphics.Bitmap;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -070050import android.graphics.Rect;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -070051import android.os.Debug;
Craig Mautnerc0ffce52014-07-01 12:38:52 -070052import android.os.ParcelFileDescriptor;
Dianne Hackborn885fbe52014-08-23 15:23:58 -070053import android.os.RemoteException;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070054import android.os.UserHandle;
Dianne Hackborn91097de2014-04-04 18:02:06 -070055import android.service.voice.IVoiceInteractionSession;
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -070056import android.util.DisplayMetrics;
Dianne Hackborn7f96b792012-05-29 18:46:45 -070057import android.util.Slog;
Dianne Hackborn91097de2014-04-04 18:02:06 -070058import com.android.internal.app.IVoiceInteractor;
Craig Mautner21d24a22014-04-23 11:45:37 -070059import com.android.internal.util.XmlUtils;
60import org.xmlpull.v1.XmlPullParser;
61import org.xmlpull.v1.XmlPullParserException;
62import org.xmlpull.v1.XmlSerializer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063
Craig Mautnerc0ffce52014-07-01 12:38:52 -070064import java.io.File;
Craig Mautner21d24a22014-04-23 11:45:37 -070065import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066import java.io.PrintWriter;
Craig Mautner5d9c7be2013-02-15 14:02:56 -080067import java.util.ArrayList;
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -070068import java.util.Objects;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069
Craig Mautnerc0ffce52014-07-01 12:38:52 -070070final class TaskRecord {
Wale Ogunwalee23149f2015-03-06 15:39:44 -080071 private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskRecord" : TAG_AM;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -070072 private static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE;
Wale Ogunwaleee006da2015-03-30 14:49:25 -070073 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
Craig Mautnere0570202015-05-13 13:06:11 -070074 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwaleee006da2015-03-30 14:49:25 -070075 private static final String TAG_TASKS = TAG + POSTFIX_TASKS;
Wale Ogunwalee23149f2015-03-06 15:39:44 -080076
Wale Ogunwale18795a22014-12-03 11:38:33 -080077 static final String ATTR_TASKID = "task_id";
Craig Mautner21d24a22014-04-23 11:45:37 -070078 private static final String TAG_INTENT = "intent";
79 private static final String TAG_AFFINITYINTENT = "affinity_intent";
Wale Ogunwale18795a22014-12-03 11:38:33 -080080 static final String ATTR_REALACTIVITY = "real_activity";
Craig Mautner21d24a22014-04-23 11:45:37 -070081 private static final String ATTR_ORIGACTIVITY = "orig_activity";
Stefan Kuhnee88d1e52015-05-18 10:33:45 -070082 private static final String TAG_ACTIVITY = "activity";
Craig Mautner21d24a22014-04-23 11:45:37 -070083 private static final String ATTR_AFFINITY = "affinity";
Dianne Hackborn79228822014-09-16 11:11:23 -070084 private static final String ATTR_ROOT_AFFINITY = "root_affinity";
Craig Mautner21d24a22014-04-23 11:45:37 -070085 private static final String ATTR_ROOTHASRESET = "root_has_reset";
Dianne Hackborn13420f22014-07-18 15:43:56 -070086 private static final String ATTR_AUTOREMOVERECENTS = "auto_remove_recents";
Craig Mautner21d24a22014-04-23 11:45:37 -070087 private static final String ATTR_ASKEDCOMPATMODE = "asked_compat_mode";
88 private static final String ATTR_USERID = "user_id";
Dianne Hackborn885fbe52014-08-23 15:23:58 -070089 private static final String ATTR_EFFECTIVE_UID = "effective_uid";
Craig Mautner21d24a22014-04-23 11:45:37 -070090 private static final String ATTR_TASKTYPE = "task_type";
Winson Chungffa2ec62014-07-03 15:54:42 -070091 private static final String ATTR_FIRSTACTIVETIME = "first_active_time";
Winson Chungf1fbd772014-06-24 18:06:58 -070092 private static final String ATTR_LASTACTIVETIME = "last_active_time";
Craig Mautner21d24a22014-04-23 11:45:37 -070093 private static final String ATTR_LASTDESCRIPTION = "last_description";
94 private static final String ATTR_LASTTIMEMOVED = "last_time_moved";
Craig Mautner9d4e9bc2014-06-18 18:34:56 -070095 private static final String ATTR_NEVERRELINQUISH = "never_relinquish_identity";
Wale Ogunwale18795a22014-12-03 11:38:33 -080096 static final String ATTR_TASK_AFFILIATION = "task_affiliation";
Craig Mautnera228ae92014-07-09 05:44:55 -070097 private static final String ATTR_PREV_AFFILIATION = "prev_affiliation";
98 private static final String ATTR_NEXT_AFFILIATION = "next_affiliation";
Winson Chungec396d62014-08-06 17:08:00 -070099 private static final String ATTR_TASK_AFFILIATION_COLOR = "task_affiliation_color";
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700100 private static final String ATTR_CALLING_UID = "calling_uid";
101 private static final String ATTR_CALLING_PACKAGE = "calling_package";
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800102 private static final String ATTR_RESIZEABLE = "resizeable";
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700103 private static final String ATTR_PRIVILEGED = "privileged";
Wale Ogunwale706ed792015-08-02 10:29:44 -0700104 private static final String ATTR_NON_FULLSCREEN_BOUNDS = "non_fullscreen_bounds";
Craig Mautner21d24a22014-04-23 11:45:37 -0700105
106 private static final String TASK_THUMBNAIL_SUFFIX = "_task_thumbnail";
107
Craig Mautner0b633fc2014-07-23 10:42:18 -0700108 static final boolean IGNORE_RETURN_TO_RECENTS = true;
109
Wale Ogunwale18795a22014-12-03 11:38:33 -0800110 static final int INVALID_TASK_ID = -1;
111
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112 final int taskId; // Unique identifier for this task.
Dianne Hackborn79228822014-09-16 11:11:23 -0700113 String affinity; // The affinity name for this task, or null; may change identity.
114 String rootAffinity; // Initial base affinity, or null; does not change from initial root.
Dianne Hackborn91097de2014-04-04 18:02:06 -0700115 final IVoiceInteractionSession voiceSession; // Voice interaction session driving task
116 final IVoiceInteractor voiceInteractor; // Associated interactor to provide to app
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117 Intent intent; // The original intent that started the task.
118 Intent affinityIntent; // Intent of affinity-moved activity that started this task.
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700119 int effectiveUid; // The current effective uid of the identity of this task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800120 ComponentName origActivity; // The non-alias activity component of the intent.
121 ComponentName realActivity; // The actual activity component that started the task.
Winson Chungffa2ec62014-07-03 15:54:42 -0700122 long firstActiveTime; // First time this task was active.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800123 long lastActiveTime; // Last time this task was active, including sleep.
Dianne Hackborn852975d2014-08-22 17:42:43 -0700124 boolean inRecents; // Actually in the recents list?
125 boolean isAvailable; // Is the activity available to be launched?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126 boolean rootWasReset; // True if the intent at the root of the task had
127 // the FLAG_ACTIVITY_RESET_TASK_IF_NEEDED flag.
Dianne Hackborn13420f22014-07-18 15:43:56 -0700128 boolean autoRemoveRecents; // If true, we should automatically remove the task from
129 // recents when activity finishes
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700130 boolean askedCompatMode;// Have asked the user about compat mode for this task.
Dianne Hackbornd38aed82014-06-10 21:36:35 -0700131 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 -0800132
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700133 String stringName; // caching of toString() result.
Dianne Hackborn9da2d402012-03-15 13:43:08 -0700134 int userId; // user for which this task was created
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800135
136 int numFullscreen; // Number of fullscreen activities.
137
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800138 boolean mResizeable; // Activities in the task resizeable. Based on the resizable setting of
139 // the root activity.
Craig Mautner15df08a2015-04-01 12:17:18 -0700140 int mLockTaskMode; // Which tasklock mode to launch this task in. One of
141 // ActivityManager.LOCK_TASK_LAUNCH_MODE_*
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700142 private boolean mPrivileged; // The root activity application of this task holds
143 // privileged permissions.
144
Craig Mautner15df08a2015-04-01 12:17:18 -0700145 /** Can't be put in lockTask mode. */
146 final static int LOCK_TASK_AUTH_DONT_LOCK = 0;
Benjamin Franz469dd582015-06-09 14:24:36 +0100147 /** Can enter app pinning with user approval. Can never start over existing lockTask task. */
Craig Mautner15df08a2015-04-01 12:17:18 -0700148 final static int LOCK_TASK_AUTH_PINNABLE = 1;
149 /** Starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing lockTask task. */
150 final static int LOCK_TASK_AUTH_LAUNCHABLE = 2;
Benjamin Franz469dd582015-06-09 14:24:36 +0100151 /** Can enter lockTask without user approval. Can start over existing lockTask task. */
Craig Mautner15df08a2015-04-01 12:17:18 -0700152 final static int LOCK_TASK_AUTH_WHITELISTED = 3;
Benjamin Franz469dd582015-06-09 14:24:36 +0100153 /** Priv-app that starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing
154 * lockTask task. */
155 final static int LOCK_TASK_AUTH_LAUNCHABLE_PRIV = 4;
Craig Mautner15df08a2015-04-01 12:17:18 -0700156 int mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE;
157
158 int mLockTaskUid = -1; // The uid of the application that called startLockTask().
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800159
Winson Chung03a9bae2014-05-02 09:56:12 -0700160 // This represents the last resolved activity values for this task
161 // NOTE: This value needs to be persisted with each task
Craig Mautner648f69b2014-09-18 14:16:26 -0700162 TaskDescription lastTaskDescription = new TaskDescription();
Winson Chung03a9bae2014-05-02 09:56:12 -0700163
Craig Mautnerd2328952013-03-05 12:46:26 -0800164 /** List of all activities in the task arranged in history order */
Craig Mautner21d24a22014-04-23 11:45:37 -0700165 final ArrayList<ActivityRecord> mActivities;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800166
Craig Mautnerd2328952013-03-05 12:46:26 -0800167 /** Current stack */
168 ActivityStack stack;
169
Craig Mautner2c1faed2013-07-23 12:56:02 -0700170 /** Takes on same set of values as ActivityRecord.mActivityType */
Craig Mautner21d24a22014-04-23 11:45:37 -0700171 int taskType;
Craig Mautner1602ec22013-05-12 10:24:27 -0700172
Craig Mautner21d24a22014-04-23 11:45:37 -0700173 /** Takes on same value as first root activity */
174 boolean isPersistable = false;
Craig Mautnerffcfcaa2014-06-05 09:54:38 -0700175 int maxRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700176
177 /** Only used for persistable tasks, otherwise 0. The last time this task was moved. Used for
178 * determining the order when restoring. Sign indicates whether last task movement was to front
179 * (positive) or back (negative). Absolute value indicates time. */
180 long mLastTimeMoved = System.currentTimeMillis();
181
Craig Mautner84984fa2014-06-19 11:19:20 -0700182 /** Indication of what to run next when task exits. Use ActivityRecord types.
183 * ActivityRecord.APPLICATION_ACTIVITY_TYPE indicates to resume the task below this one in the
184 * task stack. */
185 private int mTaskToReturnTo = APPLICATION_ACTIVITY_TYPE;
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700186
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700187 /** If original intent did not allow relinquishing task identity, save that information */
188 boolean mNeverRelinquishIdentity = true;
189
Craig Mautner362449a2014-06-20 14:04:39 -0700190 // Used in the unique case where we are clearing the task in order to reuse it. In that case we
191 // do not want to delete the stack when the task goes empty.
192 boolean mReuseTask = false;
193
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700194 private Bitmap mLastThumbnail; // Last thumbnail captured for this item.
Wale Ogunwalebe23ff42014-10-21 16:29:51 -0700195 private final File mLastThumbnailFile; // File containing last thumbnail.
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700196 private final String mFilename;
197 CharSequence lastDescription; // Last description captured for this item.
198
Craig Mautnera228ae92014-07-09 05:44:55 -0700199 int mAffiliatedTaskId; // taskId of parent affiliation or self if no parent.
Winson Chungec396d62014-08-06 17:08:00 -0700200 int mAffiliatedTaskColor; // color of the parent task affiliation.
Craig Mautnera228ae92014-07-09 05:44:55 -0700201 TaskRecord mPrevAffiliate; // previous task in affiliated chain.
Wale Ogunwale18795a22014-12-03 11:38:33 -0800202 int mPrevAffiliateTaskId = INVALID_TASK_ID; // previous id for persistence.
Craig Mautnera228ae92014-07-09 05:44:55 -0700203 TaskRecord mNextAffiliate; // next task in affiliated chain.
Wale Ogunwale18795a22014-12-03 11:38:33 -0800204 int mNextAffiliateTaskId = INVALID_TASK_ID; // next id for persistence.
Craig Mautnera228ae92014-07-09 05:44:55 -0700205
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700206 // For relaunching the task from recents as though it was launched by the original launcher.
207 int mCallingUid;
208 String mCallingPackage;
209
Craig Mautner21d24a22014-04-23 11:45:37 -0700210 final ActivityManagerService mService;
211
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700212 // Whether or not this task covers the entire screen; by default tasks are fullscreen.
213 boolean mFullscreen = true;
214
215 // Bounds of the Task. null for fullscreen tasks.
216 Rect mBounds = null;
Wale Ogunwale706ed792015-08-02 10:29:44 -0700217 // Last non-fullscreen bounds the task was launched in or resized to.
218 // The information is persisted and used to determine the appropriate stack to launch the
219 // task into on restore.
220 Rect mLastNonFullscreenBounds = null;
Filip Gruszczynskid2f1d942015-10-14 15:10:12 -0700221 // Minimal size for width/height of this task when it's resizeable. -1 means it should use the
222 // default minimal size.
223 final int mMinimalSize;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700224
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700225 // Ranking (from top) of this task among all visible tasks. (-1 means it's not visible)
226 // This number will be assigned when we evaluate OOM scores for all visible tasks.
227 int mLayerRank = -1;
228
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700229 Configuration mOverrideConfig = Configuration.EMPTY;
230
Craig Mautner21d24a22014-04-23 11:45:37 -0700231 TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Dianne Hackborn91097de2014-04-04 18:02:06 -0700232 IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700233 mService = service;
Craig Mautnera228ae92014-07-09 05:44:55 -0700234 mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
235 TaskPersister.IMAGE_EXTENSION;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700236 mLastThumbnailFile = new File(TaskPersister.sImagesDir, mFilename);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800237 taskId = _taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700238 mAffiliatedTaskId = _taskId;
Dianne Hackborn91097de2014-04-04 18:02:06 -0700239 voiceSession = _voiceSession;
240 voiceInteractor = _voiceInteractor;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700241 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800242 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700243 mCallingUid = info.applicationInfo.uid;
244 mCallingPackage = info.packageName;
Martijn Coenend4a69702014-06-30 11:12:17 -0700245 setIntent(_intent, info);
Filip Gruszczynskid2f1d942015-10-14 15:10:12 -0700246 mMinimalSize = info != null && info.layout != null ? info.layout.minimalSize : -1;
Craig Mautner21d24a22014-04-23 11:45:37 -0700247 }
248
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700249 TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Craig Mautner648f69b2014-09-18 14:16:26 -0700250 TaskDescription _taskDescription) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700251 mService = service;
252 mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
253 TaskPersister.IMAGE_EXTENSION;
254 mLastThumbnailFile = new File(TaskPersister.sImagesDir, mFilename);
255 taskId = _taskId;
256 mAffiliatedTaskId = _taskId;
257 voiceSession = null;
258 voiceInteractor = null;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700259 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800260 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700261 mCallingUid = info.applicationInfo.uid;
262 mCallingPackage = info.packageName;
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700263 setIntent(_intent, info);
264
265 taskType = ActivityRecord.APPLICATION_ACTIVITY_TYPE;
266 isPersistable = true;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700267 // Clamp to [1, max].
268 maxRecents = Math.min(Math.max(info.maxRecents, 1),
269 ActivityManager.getMaxAppRecentsLimitStatic());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700270
271 taskType = APPLICATION_ACTIVITY_TYPE;
272 mTaskToReturnTo = HOME_ACTIVITY_TYPE;
273 userId = UserHandle.getUserId(info.applicationInfo.uid);
274 lastTaskDescription = _taskDescription;
Filip Gruszczynskid2f1d942015-10-14 15:10:12 -0700275 mMinimalSize = info != null && info.layout != null ? info.layout.minimalSize : -1;
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700276 }
277
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800278 private TaskRecord(ActivityManagerService service, int _taskId, Intent _intent,
279 Intent _affinityIntent, String _affinity, String _rootAffinity,
280 ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset,
281 boolean _autoRemoveRecents, boolean _askedCompatMode, int _taskType, int _userId,
282 int _effectiveUid, String _lastDescription, ArrayList<ActivityRecord> activities,
283 long _firstActiveTime, long _lastActiveTime, long lastTimeMoved,
284 boolean neverRelinquishIdentity, TaskDescription _lastTaskDescription,
285 int taskAffiliation, int prevTaskId, int nextTaskId, int taskAffiliationColor,
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -0700286 int callingUid, String callingPackage, boolean resizeable, boolean privileged) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700287 mService = service;
Craig Mautnera228ae92014-07-09 05:44:55 -0700288 mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
289 TaskPersister.IMAGE_EXTENSION;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700290 mLastThumbnailFile = new File(TaskPersister.sImagesDir, mFilename);
Craig Mautner21d24a22014-04-23 11:45:37 -0700291 taskId = _taskId;
292 intent = _intent;
293 affinityIntent = _affinityIntent;
294 affinity = _affinity;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800295 rootAffinity = _rootAffinity;
Craig Mautner21d24a22014-04-23 11:45:37 -0700296 voiceSession = null;
297 voiceInteractor = null;
298 realActivity = _realActivity;
299 origActivity = _origActivity;
300 rootWasReset = _rootWasReset;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700301 isAvailable = true;
Dianne Hackborn13420f22014-07-18 15:43:56 -0700302 autoRemoveRecents = _autoRemoveRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700303 askedCompatMode = _askedCompatMode;
304 taskType = _taskType;
Craig Mautner84984fa2014-06-19 11:19:20 -0700305 mTaskToReturnTo = HOME_ACTIVITY_TYPE;
Craig Mautner21d24a22014-04-23 11:45:37 -0700306 userId = _userId;
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700307 effectiveUid = _effectiveUid;
Winson Chungffa2ec62014-07-03 15:54:42 -0700308 firstActiveTime = _firstActiveTime;
Winson Chungf1fbd772014-06-24 18:06:58 -0700309 lastActiveTime = _lastActiveTime;
Craig Mautner21d24a22014-04-23 11:45:37 -0700310 lastDescription = _lastDescription;
311 mActivities = activities;
312 mLastTimeMoved = lastTimeMoved;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700313 mNeverRelinquishIdentity = neverRelinquishIdentity;
Winson Chung2cb86c72014-06-25 12:03:30 -0700314 lastTaskDescription = _lastTaskDescription;
Craig Mautnera228ae92014-07-09 05:44:55 -0700315 mAffiliatedTaskId = taskAffiliation;
Winson Chungec396d62014-08-06 17:08:00 -0700316 mAffiliatedTaskColor = taskAffiliationColor;
Craig Mautnera228ae92014-07-09 05:44:55 -0700317 mPrevAffiliateTaskId = prevTaskId;
318 mNextAffiliateTaskId = nextTaskId;
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700319 mCallingUid = callingUid;
320 mCallingPackage = callingPackage;
Jorim Jaggi8ccdf3a2015-10-22 12:50:31 +0200321 mResizeable = resizeable || mService.mForceResizableActivites;
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700322 mPrivileged = privileged;
Suprabh Shukla74f9f162015-11-06 15:39:42 -0800323 ActivityInfo info = (mActivities.size() > 0) ? mActivities.get(0).info : null;
Filip Gruszczynskid2f1d942015-10-14 15:10:12 -0700324 mMinimalSize = info != null && info.layout != null ? info.layout.minimalSize : -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800325 }
326
327 void touchActiveTime() {
Craig Mautner494f6bdd2014-07-21 11:17:46 -0700328 lastActiveTime = System.currentTimeMillis();
Winson Chungffa2ec62014-07-03 15:54:42 -0700329 if (firstActiveTime == 0) {
330 firstActiveTime = lastActiveTime;
331 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800332 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700333
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800334 long getInactiveDuration() {
Craig Mautner494f6bdd2014-07-21 11:17:46 -0700335 return System.currentTimeMillis() - lastActiveTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800336 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700337
Winson Chungfee26772014-08-05 12:21:52 -0700338 /** Sets the original intent, and the calling uid and package. */
339 void setIntent(ActivityRecord r) {
Winson Chungfee26772014-08-05 12:21:52 -0700340 mCallingUid = r.launchedFromUid;
341 mCallingPackage = r.launchedFromPackage;
Craig Mautner15df08a2015-04-01 12:17:18 -0700342 setIntent(r.intent, r.info);
Winson Chungfee26772014-08-05 12:21:52 -0700343 }
344
345 /** Sets the original intent, _without_ updating the calling uid or package. */
346 private void setIntent(Intent _intent, ActivityInfo info) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700347 if (intent == null) {
348 mNeverRelinquishIdentity =
349 (info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) == 0;
350 } else if (mNeverRelinquishIdentity) {
351 return;
352 }
353
354 affinity = info.taskAffinity;
Dianne Hackborn79228822014-09-16 11:11:23 -0700355 if (intent == null) {
356 // If this task already has an intent associated with it, don't set the root
357 // affinity -- we don't want it changing after initially set, but the initially
358 // set value may be null.
359 rootAffinity = affinity;
360 }
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700361 effectiveUid = info.applicationInfo.uid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700362 stringName = null;
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800363
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800364 if (info.targetActivity == null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800365 if (_intent != null) {
366 // If this Intent has a selector, we want to clear it for the
367 // recent task since it is not relevant if the user later wants
368 // to re-launch the app.
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700369 if (_intent.getSelector() != null || _intent.getSourceBounds() != null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800370 _intent = new Intent(_intent);
371 _intent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700372 _intent.setSourceBounds(null);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800373 }
374 }
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700375 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Setting Intent of " + this + " to " + _intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800376 intent = _intent;
377 realActivity = _intent != null ? _intent.getComponent() : null;
378 origActivity = null;
379 } else {
380 ComponentName targetComponent = new ComponentName(
381 info.packageName, info.targetActivity);
382 if (_intent != null) {
383 Intent targetIntent = new Intent(_intent);
384 targetIntent.setComponent(targetComponent);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800385 targetIntent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700386 targetIntent.setSourceBounds(null);
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700387 if (DEBUG_TASKS) Slog.v(TAG_TASKS,
Dianne Hackborn7f96b792012-05-29 18:46:45 -0700388 "Setting Intent of " + this + " to target " + targetIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800389 intent = targetIntent;
390 realActivity = targetComponent;
391 origActivity = _intent.getComponent();
392 } else {
393 intent = null;
394 realActivity = targetComponent;
395 origActivity = new ComponentName(info.packageName, info.name);
396 }
397 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700398
Craig Mautner47b20ba2014-09-17 17:23:44 -0700399 final int intentFlags = intent == null ? 0 : intent.getFlags();
400 if ((intentFlags & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800401 // Once we are set to an Intent with this flag, we count this
402 // task as having a true root activity.
403 rootWasReset = true;
404 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700405
Dianne Hackborn09233282014-04-30 11:33:59 -0700406 userId = UserHandle.getUserId(info.applicationInfo.uid);
Craig Mautner41db4a72014-05-07 17:20:56 -0700407 if ((info.flags & ActivityInfo.FLAG_AUTO_REMOVE_FROM_RECENTS) != 0) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700408 // If the activity itself has requested auto-remove, then just always do it.
409 autoRemoveRecents = true;
Wale Ogunwale843bfb92015-03-27 11:06:48 -0700410 } else if ((intentFlags & (FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS))
411 == FLAG_ACTIVITY_NEW_DOCUMENT) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700412 // If the caller has not asked for the document to be retained, then we may
413 // want to turn on auto-remove, depending on whether the target has set its
414 // own document launch mode.
415 if (info.documentLaunchMode != ActivityInfo.DOCUMENT_LAUNCH_NONE) {
416 autoRemoveRecents = false;
417 } else {
418 autoRemoveRecents = true;
419 }
420 } else {
421 autoRemoveRecents = false;
Craig Mautner41db4a72014-05-07 17:20:56 -0700422 }
Jorim Jaggi8ccdf3a2015-10-22 12:50:31 +0200423 mResizeable = info.resizeable || mService.mForceResizableActivites;
Craig Mautner15df08a2015-04-01 12:17:18 -0700424 mLockTaskMode = info.lockTaskLaunchMode;
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700425 mPrivileged = (info.applicationInfo.privateFlags & PRIVATE_FLAG_PRIVILEGED) != 0;
Craig Mautner15df08a2015-04-01 12:17:18 -0700426 setLockTaskAuth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800427 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800428
Craig Mautner84984fa2014-06-19 11:19:20 -0700429 void setTaskToReturnTo(int taskToReturnTo) {
Wale Ogunwale2d0f39b2015-04-17 15:35:39 -0700430 mTaskToReturnTo = (IGNORE_RETURN_TO_RECENTS && taskToReturnTo == RECENTS_ACTIVITY_TYPE)
431 ? HOME_ACTIVITY_TYPE : taskToReturnTo;
Craig Mautner84984fa2014-06-19 11:19:20 -0700432 }
433
434 int getTaskToReturnTo() {
435 return mTaskToReturnTo;
436 }
437
Craig Mautnera228ae92014-07-09 05:44:55 -0700438 void setPrevAffiliate(TaskRecord prevAffiliate) {
439 mPrevAffiliate = prevAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800440 mPrevAffiliateTaskId = prevAffiliate == null ? INVALID_TASK_ID : prevAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700441 }
442
443 void setNextAffiliate(TaskRecord nextAffiliate) {
444 mNextAffiliate = nextAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800445 mNextAffiliateTaskId = nextAffiliate == null ? INVALID_TASK_ID : nextAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700446 }
447
448 // Close up recents linked list.
449 void closeRecentsChain() {
450 if (mPrevAffiliate != null) {
451 mPrevAffiliate.setNextAffiliate(mNextAffiliate);
452 }
453 if (mNextAffiliate != null) {
454 mNextAffiliate.setPrevAffiliate(mPrevAffiliate);
455 }
456 setPrevAffiliate(null);
457 setNextAffiliate(null);
458 }
459
Winson Chung740c3ac2014-11-12 16:14:38 -0800460 void removedFromRecents() {
Dianne Hackborn852975d2014-08-22 17:42:43 -0700461 disposeThumbnail();
462 closeRecentsChain();
463 if (inRecents) {
464 inRecents = false;
Winson Chung740c3ac2014-11-12 16:14:38 -0800465 mService.notifyTaskPersisterLocked(this, false);
Dianne Hackborn852975d2014-08-22 17:42:43 -0700466 }
467 }
468
Craig Mautnera228ae92014-07-09 05:44:55 -0700469 void setTaskToAffiliateWith(TaskRecord taskToAffiliateWith) {
470 closeRecentsChain();
471 mAffiliatedTaskId = taskToAffiliateWith.mAffiliatedTaskId;
Winson Chungec396d62014-08-06 17:08:00 -0700472 mAffiliatedTaskColor = taskToAffiliateWith.mAffiliatedTaskColor;
Craig Mautnera228ae92014-07-09 05:44:55 -0700473 // Find the end
474 while (taskToAffiliateWith.mNextAffiliate != null) {
475 final TaskRecord nextRecents = taskToAffiliateWith.mNextAffiliate;
476 if (nextRecents.mAffiliatedTaskId != mAffiliatedTaskId) {
477 Slog.e(TAG, "setTaskToAffiliateWith: nextRecents=" + nextRecents + " affilTaskId="
478 + nextRecents.mAffiliatedTaskId + " should be " + mAffiliatedTaskId);
479 if (nextRecents.mPrevAffiliate == taskToAffiliateWith) {
480 nextRecents.setPrevAffiliate(null);
481 }
482 taskToAffiliateWith.setNextAffiliate(null);
483 break;
484 }
485 taskToAffiliateWith = nextRecents;
486 }
487 taskToAffiliateWith.setNextAffiliate(this);
488 setPrevAffiliate(taskToAffiliateWith);
489 setNextAffiliate(null);
490 }
491
Winson Chung096f36b2014-08-20 15:39:01 -0700492 /**
493 * Sets the last thumbnail.
494 * @return whether the thumbnail was set
495 */
496 boolean setLastThumbnail(Bitmap thumbnail) {
497 if (mLastThumbnail != thumbnail) {
498 mLastThumbnail = thumbnail;
499 if (thumbnail == null) {
500 if (mLastThumbnailFile != null) {
501 mLastThumbnailFile.delete();
502 }
503 } else {
504 mService.mTaskPersister.saveImage(thumbnail, mFilename);
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700505 }
Winson Chung096f36b2014-08-20 15:39:01 -0700506 return true;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700507 }
Winson Chung096f36b2014-08-20 15:39:01 -0700508 return false;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700509 }
510
511 void getLastThumbnail(TaskThumbnail thumbs) {
512 thumbs.mainThumbnail = mLastThumbnail;
513 thumbs.thumbnailFileDescriptor = null;
Craig Mautnerf4f8bb72014-07-29 10:41:40 -0700514 if (mLastThumbnail == null) {
Craig Mautner648f69b2014-09-18 14:16:26 -0700515 thumbs.mainThumbnail = mService.mTaskPersister.getImageFromWriteQueue(mFilename);
Craig Mautnerf4f8bb72014-07-29 10:41:40 -0700516 }
Winson Chung096f36b2014-08-20 15:39:01 -0700517 // Only load the thumbnail file if we don't have a thumbnail
518 if (thumbs.mainThumbnail == null && mLastThumbnailFile.exists()) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700519 try {
520 thumbs.thumbnailFileDescriptor = ParcelFileDescriptor.open(mLastThumbnailFile,
521 ParcelFileDescriptor.MODE_READ_ONLY);
522 } catch (IOException e) {
Dianne Hackborn9844d292013-10-04 16:44:22 -0700523 }
524 }
525 }
526
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700527 void freeLastThumbnail() {
528 mLastThumbnail = null;
529 }
530
531 void disposeThumbnail() {
532 mLastThumbnail = null;
533 lastDescription = null;
534 }
535
Winson Chung1147c402014-05-14 11:05:00 -0700536 /** Returns the intent for the root activity for this task */
537 Intent getBaseIntent() {
538 return intent != null ? intent : affinityIntent;
539 }
540
Winson Chung3b3f4642014-04-22 10:08:18 -0700541 /** Returns the first non-finishing activity from the root. */
542 ActivityRecord getRootActivity() {
543 for (int i = 0; i < mActivities.size(); i++) {
544 final ActivityRecord r = mActivities.get(i);
545 if (r.finishing) {
546 continue;
547 }
548 return r;
549 }
550 return null;
551 }
552
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800553 ActivityRecord getTopActivity() {
554 for (int i = mActivities.size() - 1; i >= 0; --i) {
555 final ActivityRecord r = mActivities.get(i);
556 if (r.finishing) {
557 continue;
558 }
559 return r;
560 }
561 return null;
562 }
563
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -0700564 ActivityRecord topRunningActivityLocked() {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700565 if (stack != null) {
566 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
567 ActivityRecord r = mActivities.get(activityNdx);
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -0700568 if (!r.finishing && stack.okToShowLocked(r)) {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700569 return r;
570 }
Craig Mautner6b74cb52013-09-27 17:02:21 -0700571 }
572 }
573 return null;
574 }
575
Wale Ogunwale6d42df62015-11-05 09:50:55 -0800576 void setFrontOfTask() {
577 setFrontOfTask(null);
578 }
579
Craig Mautner3b475fe2013-12-16 15:58:31 -0800580 /** Call after activity movement or finish to make sure that frontOfTask is set correctly */
Wale Ogunwale6d42df62015-11-05 09:50:55 -0800581 void setFrontOfTask(ActivityRecord newTop) {
582 // If a top candidate is suggested by the caller, go ahead and use it and mark all others
583 // as not front. This is needed in situations where the current front activity in the
584 // task isn't finished yet and we want to set the front to the activity moved to the front
585 // of the task.
586 boolean foundFront = newTop != null ? true : false;
587
Craig Mautner3b475fe2013-12-16 15:58:31 -0800588 final int numActivities = mActivities.size();
Craig Mautner704e40b2013-12-18 16:43:51 -0800589 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
Craig Mautner3b475fe2013-12-16 15:58:31 -0800590 final ActivityRecord r = mActivities.get(activityNdx);
591 if (foundFront || r.finishing) {
592 r.frontOfTask = false;
593 } else {
594 r.frontOfTask = true;
595 // Set frontOfTask false for every following activity.
596 foundFront = true;
597 }
598 }
Craig Mautner9587ee02014-06-23 15:00:10 +0000599 if (!foundFront && numActivities > 0) {
600 // All activities of this task are finishing. As we ought to have a frontOfTask
601 // activity, make the bottom activity front.
602 mActivities.get(0).frontOfTask = true;
603 }
Wale Ogunwale6d42df62015-11-05 09:50:55 -0800604 if (newTop != null) {
605 newTop.frontOfTask = true;
606 }
Craig Mautner3b475fe2013-12-16 15:58:31 -0800607 }
608
Craig Mautnerde4ef022013-04-07 19:01:33 -0700609 /**
Craig Mautner3b475fe2013-12-16 15:58:31 -0800610 * Reorder the history stack so that the passed activity is brought to the front.
Craig Mautnerde4ef022013-04-07 19:01:33 -0700611 */
612 final void moveActivityToFrontLocked(ActivityRecord newTop) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -0700613 if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE,
614 "Removing and adding activity " + newTop
615 + " to stack at top callers=" + Debug.getCallers(4));
Craig Mautnerde4ef022013-04-07 19:01:33 -0700616
Craig Mautnerde4ef022013-04-07 19:01:33 -0700617 mActivities.remove(newTop);
618 mActivities.add(newTop);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700619 updateEffectiveIntent();
Craig Mautner3b475fe2013-12-16 15:58:31 -0800620
Wale Ogunwale6d42df62015-11-05 09:50:55 -0800621 setFrontOfTask(newTop);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700622 }
623
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800624 void addActivityAtBottom(ActivityRecord r) {
Craig Mautner77878772013-03-04 19:46:24 -0800625 addActivityAtIndex(0, r);
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800626 }
627
628 void addActivityToTop(ActivityRecord r) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700629 addActivityAtIndex(mActivities.size(), r);
630 }
631
632 void addActivityAtIndex(int index, ActivityRecord r) {
Craig Mautner6170f732013-04-02 13:05:23 -0700633 // 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 -0800634 if (!mActivities.remove(r) && r.fullscreen) {
635 // Was not previously in list.
636 numFullscreen++;
637 }
Craig Mautner2c1faed2013-07-23 12:56:02 -0700638 // Only set this based on the first activity
639 if (mActivities.isEmpty()) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700640 taskType = r.mActivityType;
Jorim Jaggi8ccdf3a2015-10-22 12:50:31 +0200641 if (taskType == HOME_ACTIVITY_TYPE && mService.mForceResizableActivites) {
642 mResizeable = r.info.resizeable;
643 }
Craig Mautner21d24a22014-04-23 11:45:37 -0700644 isPersistable = r.isPersistable();
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700645 mCallingUid = r.launchedFromUid;
646 mCallingPackage = r.launchedFromPackage;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700647 // Clamp to [1, max].
648 maxRecents = Math.min(Math.max(r.info.maxRecents, 1),
649 ActivityManager.getMaxAppRecentsLimitStatic());
Craig Mautner2c1faed2013-07-23 12:56:02 -0700650 } else {
651 // Otherwise make all added activities match this one.
Craig Mautner21d24a22014-04-23 11:45:37 -0700652 r.mActivityType = taskType;
Craig Mautner78733002013-06-10 13:54:49 -0700653 }
Craig Mautner77878772013-03-04 19:46:24 -0800654 mActivities.add(index, r);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700655 updateEffectiveIntent();
Craig Mautner21d24a22014-04-23 11:45:37 -0700656 if (r.isPersistable()) {
657 mService.notifyTaskPersisterLocked(this, false);
658 }
Craig Mautner77878772013-03-04 19:46:24 -0800659 }
660
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800661 /** @return true if this was the last activity in the task */
662 boolean removeActivity(ActivityRecord r) {
663 if (mActivities.remove(r) && r.fullscreen) {
664 // Was previously in list.
665 numFullscreen--;
666 }
Craig Mautner21d24a22014-04-23 11:45:37 -0700667 if (r.isPersistable()) {
668 mService.notifyTaskPersisterLocked(this, false);
669 }
Craig Mautner41326202014-06-20 14:38:21 -0700670 if (mActivities.isEmpty()) {
Craig Mautner5afcd4d2014-06-21 18:11:33 -0700671 return !mReuseTask;
Craig Mautner41326202014-06-20 14:38:21 -0700672 }
673 updateEffectiveIntent();
674 return false;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800675 }
676
Craig Mautner41db4a72014-05-07 17:20:56 -0700677 boolean autoRemoveFromRecents() {
Dianne Hackbornd38aed82014-06-10 21:36:35 -0700678 // We will automatically remove the task either if it has explicitly asked for
679 // this, or it is empty and has never contained an activity that got shown to
680 // the user.
Dianne Hackborn13420f22014-07-18 15:43:56 -0700681 return autoRemoveRecents || (mActivities.isEmpty() && !hasBeenVisible);
Craig Mautner41db4a72014-05-07 17:20:56 -0700682 }
683
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700684 /**
685 * Completely remove all activities associated with an existing
686 * task starting at a specified index.
687 */
688 final void performClearTaskAtIndexLocked(int activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700689 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700690 for ( ; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700691 final ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700692 if (r.finishing) {
693 continue;
694 }
Craig Mautner21d24a22014-04-23 11:45:37 -0700695 if (stack == null) {
696 // Task was restored from persistent storage.
697 r.takeFromHistory();
698 mActivities.remove(activityNdx);
699 --activityNdx;
700 --numActivities;
Todd Kennedy539db512014-12-15 09:57:55 -0800701 } else if (stack.finishActivityLocked(
702 r, Activity.RESULT_CANCELED, null, "clear-task-index", false)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700703 --activityNdx;
704 --numActivities;
705 }
706 }
707 }
708
709 /**
710 * Completely remove all activities associated with an existing task.
711 */
712 final void performClearTaskLocked() {
Craig Mautner362449a2014-06-20 14:04:39 -0700713 mReuseTask = true;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700714 performClearTaskAtIndexLocked(0);
Craig Mautner362449a2014-06-20 14:04:39 -0700715 mReuseTask = false;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700716 }
717
718 /**
719 * Perform clear operation as requested by
720 * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the
721 * stack to the given task, then look for
722 * an instance of that activity in the stack and, if found, finish all
723 * activities on top of it and return the instance.
724 *
725 * @param newR Description of the new activity being started.
726 * @return Returns the old activity that should be continued to be used,
727 * or null if none was found.
728 */
729 final ActivityRecord performClearTaskLocked(ActivityRecord newR, int launchFlags) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700730 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700731 for (int activityNdx = numActivities - 1; activityNdx >= 0; --activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700732 ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700733 if (r.finishing) {
734 continue;
735 }
736 if (r.realActivity.equals(newR.realActivity)) {
737 // Here it is! Now finish everything in front...
Craig Mautner1602ec22013-05-12 10:24:27 -0700738 final ActivityRecord ret = r;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700739
740 for (++activityNdx; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700741 r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700742 if (r.finishing) {
743 continue;
744 }
745 ActivityOptions opts = r.takeOptionsLocked();
746 if (opts != null) {
747 ret.updateOptionsLocked(opts);
748 }
Wale Ogunwale7d701172015-03-11 15:36:30 -0700749 if (stack != null && stack.finishActivityLocked(
Todd Kennedy539db512014-12-15 09:57:55 -0800750 r, Activity.RESULT_CANCELED, null, "clear-task-stack", false)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700751 --activityNdx;
752 --numActivities;
753 }
754 }
755
756 // Finally, if this is a normal launch mode (that is, not
757 // expecting onNewIntent()), then we will finish the current
758 // instance of the activity so a new fresh one can be started.
759 if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE
760 && (launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0) {
761 if (!ret.finishing) {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700762 if (stack != null) {
763 stack.finishActivityLocked(
764 ret, Activity.RESULT_CANCELED, null, "clear-task-top", false);
765 }
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700766 return null;
767 }
768 }
769
770 return ret;
771 }
772 }
773
774 return null;
775 }
776
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700777 public TaskThumbnail getTaskThumbnailLocked() {
Craig Mautner21d24a22014-04-23 11:45:37 -0700778 if (stack != null) {
779 final ActivityRecord resumedActivity = stack.mResumedActivity;
780 if (resumedActivity != null && resumedActivity.task == this) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700781 final Bitmap thumbnail = stack.screenshotActivities(resumedActivity);
782 setLastThumbnail(thumbnail);
Craig Mautner21d24a22014-04-23 11:45:37 -0700783 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700784 }
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700785 final TaskThumbnail taskThumbnail = new TaskThumbnail();
786 getLastThumbnail(taskThumbnail);
787 return taskThumbnail;
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700788 }
789
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700790 public void removeTaskActivitiesLocked() {
791 // Just remove the entire task.
792 performClearTaskAtIndexLocked(0);
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700793 }
794
Craig Mautner432f64e2015-05-20 14:59:57 -0700795 String lockTaskAuthToString() {
796 switch (mLockTaskAuth) {
797 case LOCK_TASK_AUTH_DONT_LOCK: return "LOCK_TASK_AUTH_DONT_LOCK";
798 case LOCK_TASK_AUTH_PINNABLE: return "LOCK_TASK_AUTH_PINNABLE";
799 case LOCK_TASK_AUTH_LAUNCHABLE: return "LOCK_TASK_AUTH_LAUNCHABLE";
800 case LOCK_TASK_AUTH_WHITELISTED: return "LOCK_TASK_AUTH_WHITELISTED";
Benjamin Franz469dd582015-06-09 14:24:36 +0100801 case LOCK_TASK_AUTH_LAUNCHABLE_PRIV: return "LOCK_TASK_AUTH_LAUNCHABLE_PRIV";
Craig Mautner432f64e2015-05-20 14:59:57 -0700802 default: return "unknown=" + mLockTaskAuth;
803 }
804 }
805
Craig Mautner15df08a2015-04-01 12:17:18 -0700806 void setLockTaskAuth() {
Benjamin Franz469dd582015-06-09 14:24:36 +0100807 if (!mPrivileged &&
808 (mLockTaskMode == LOCK_TASK_LAUNCH_MODE_ALWAYS ||
809 mLockTaskMode == LOCK_TASK_LAUNCH_MODE_NEVER)) {
810 // Non-priv apps are not allowed to use always or never, fall back to default
811 mLockTaskMode = LOCK_TASK_LAUNCH_MODE_DEFAULT;
812 }
Craig Mautner15df08a2015-04-01 12:17:18 -0700813 switch (mLockTaskMode) {
814 case LOCK_TASK_LAUNCH_MODE_DEFAULT:
815 mLockTaskAuth = isLockTaskWhitelistedLocked() ?
816 LOCK_TASK_AUTH_WHITELISTED : LOCK_TASK_AUTH_PINNABLE;
817 break;
818
819 case LOCK_TASK_LAUNCH_MODE_NEVER:
Benjamin Franz469dd582015-06-09 14:24:36 +0100820 mLockTaskAuth = LOCK_TASK_AUTH_DONT_LOCK;
Craig Mautner15df08a2015-04-01 12:17:18 -0700821 break;
822
823 case LOCK_TASK_LAUNCH_MODE_ALWAYS:
Benjamin Franz469dd582015-06-09 14:24:36 +0100824 mLockTaskAuth = LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
Craig Mautner15df08a2015-04-01 12:17:18 -0700825 break;
826
827 case LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED:
828 mLockTaskAuth = isLockTaskWhitelistedLocked() ?
829 LOCK_TASK_AUTH_LAUNCHABLE : LOCK_TASK_AUTH_PINNABLE;
830 break;
831 }
Craig Mautner432f64e2015-05-20 14:59:57 -0700832 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
833 " mLockTaskAuth=" + lockTaskAuthToString());
Craig Mautner15df08a2015-04-01 12:17:18 -0700834 }
835
836 boolean isLockTaskWhitelistedLocked() {
Benjamin Franz6fd84cc2015-08-06 18:09:03 +0100837 String pkg = (realActivity != null) ? realActivity.getPackageName() : null;
838 if (pkg == null) {
Craig Mautner15df08a2015-04-01 12:17:18 -0700839 return false;
840 }
841 String[] packages = mService.mLockTaskPackages.get(userId);
842 if (packages == null) {
843 return false;
844 }
845 for (int i = packages.length - 1; i >= 0; --i) {
Benjamin Franz6fd84cc2015-08-06 18:09:03 +0100846 if (pkg.equals(packages[i])) {
Craig Mautner15df08a2015-04-01 12:17:18 -0700847 return true;
848 }
849 }
850 return false;
851 }
Craig Mautnera82aa092013-09-13 15:34:08 -0700852 boolean isHomeTask() {
Craig Mautner84984fa2014-06-19 11:19:20 -0700853 return taskType == HOME_ACTIVITY_TYPE;
Craig Mautnera82aa092013-09-13 15:34:08 -0700854 }
855
Craig Mautner86d67a42013-05-14 10:34:38 -0700856 boolean isApplicationTask() {
Craig Mautner84984fa2014-06-19 11:19:20 -0700857 return taskType == APPLICATION_ACTIVITY_TYPE;
858 }
859
860 boolean isOverHomeStack() {
861 return mTaskToReturnTo == HOME_ACTIVITY_TYPE || mTaskToReturnTo == RECENTS_ACTIVITY_TYPE;
Craig Mautner1602ec22013-05-12 10:24:27 -0700862 }
863
Craig Mautner525f3d92013-05-07 14:01:50 -0700864 /**
865 * Find the activity in the history stack within the given task. Returns
866 * the index within the history at which it's found, or < 0 if not found.
867 */
868 final ActivityRecord findActivityInHistoryLocked(ActivityRecord r) {
869 final ComponentName realActivity = r.realActivity;
870 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
871 ActivityRecord candidate = mActivities.get(activityNdx);
872 if (candidate.finishing) {
873 continue;
874 }
875 if (candidate.realActivity.equals(realActivity)) {
876 return candidate;
877 }
878 }
879 return null;
880 }
881
Winson Chunga449dc02014-05-16 11:15:04 -0700882 /** Updates the last task description values. */
883 void updateTaskDescription() {
884 // Traverse upwards looking for any break between main task activities and
885 // utility activities.
886 int activityNdx;
887 final int numActivities = mActivities.size();
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700888 final boolean relinquish = numActivities == 0 ? false :
889 (mActivities.get(0).info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) != 0;
Winson Chunga449dc02014-05-16 11:15:04 -0700890 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
Craig Mautner21d24a22014-04-23 11:45:37 -0700891 ++activityNdx) {
Winson Chunga449dc02014-05-16 11:15:04 -0700892 final ActivityRecord r = mActivities.get(activityNdx);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700893 if (relinquish && (r.info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
894 // This will be the top activity for determining taskDescription. Pre-inc to
895 // overcome initial decrement below.
896 ++activityNdx;
897 break;
898 }
Winson Chunga449dc02014-05-16 11:15:04 -0700899 if (r.intent != null &&
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700900 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
Winson Chunga449dc02014-05-16 11:15:04 -0700901 break;
902 }
903 }
904 if (activityNdx > 0) {
905 // Traverse downwards starting below break looking for set label, icon.
906 // Note that if there are activities in the task but none of them set the
907 // recent activity values, then we do not fall back to the last set
908 // values in the TaskRecord.
909 String label = null;
Craig Mautner648f69b2014-09-18 14:16:26 -0700910 String iconFilename = null;
Winson Chunga449dc02014-05-16 11:15:04 -0700911 int colorPrimary = 0;
912 for (--activityNdx; activityNdx >= 0; --activityNdx) {
913 final ActivityRecord r = mActivities.get(activityNdx);
914 if (r.taskDescription != null) {
915 if (label == null) {
916 label = r.taskDescription.getLabel();
917 }
Craig Mautner648f69b2014-09-18 14:16:26 -0700918 if (iconFilename == null) {
919 iconFilename = r.taskDescription.getIconFilename();
Winson Chunga449dc02014-05-16 11:15:04 -0700920 }
921 if (colorPrimary == 0) {
922 colorPrimary = r.taskDescription.getPrimaryColor();
Winson Chunga449dc02014-05-16 11:15:04 -0700923 }
924 }
925 }
Craig Mautner648f69b2014-09-18 14:16:26 -0700926 lastTaskDescription = new TaskDescription(label, colorPrimary, iconFilename);
Winson Chungec396d62014-08-06 17:08:00 -0700927 // Update the task affiliation color if we are the parent of the group
928 if (taskId == mAffiliatedTaskId) {
929 mAffiliatedTaskColor = lastTaskDescription.getPrimaryColor();
930 }
Winson Chunga449dc02014-05-16 11:15:04 -0700931 }
932 }
933
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700934 int findEffectiveRootIndex() {
Craig Mautner4767f4b2014-09-18 15:38:33 -0700935 int effectiveNdx = 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700936 final int topActivityNdx = mActivities.size() - 1;
Dianne Hackborn39569af2014-09-23 10:56:58 -0700937 for (int activityNdx = 0; activityNdx <= topActivityNdx; ++activityNdx) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700938 final ActivityRecord r = mActivities.get(activityNdx);
939 if (r.finishing) {
940 continue;
941 }
Craig Mautner4767f4b2014-09-18 15:38:33 -0700942 effectiveNdx = activityNdx;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700943 if ((r.info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
944 break;
945 }
946 }
Craig Mautner4767f4b2014-09-18 15:38:33 -0700947 return effectiveNdx;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700948 }
949
950 void updateEffectiveIntent() {
951 final int effectiveRootIndex = findEffectiveRootIndex();
952 final ActivityRecord r = mActivities.get(effectiveRootIndex);
Winson Chungfee26772014-08-05 12:21:52 -0700953 setIntent(r);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700954 }
955
Craig Mautner21d24a22014-04-23 11:45:37 -0700956 void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700957 if (DEBUG_RECENTS) Slog.i(TAG_RECENTS, "Saving task=" + this);
Craig Mautner21d24a22014-04-23 11:45:37 -0700958
959 out.attribute(null, ATTR_TASKID, String.valueOf(taskId));
960 if (realActivity != null) {
961 out.attribute(null, ATTR_REALACTIVITY, realActivity.flattenToShortString());
962 }
963 if (origActivity != null) {
964 out.attribute(null, ATTR_ORIGACTIVITY, origActivity.flattenToShortString());
965 }
Dianne Hackborn79228822014-09-16 11:11:23 -0700966 // Write affinity, and root affinity if it is different from affinity.
967 // We use the special string "@" for a null root affinity, so we can identify
968 // later whether we were given a root affinity or should just make it the
969 // same as the affinity.
Craig Mautner21d24a22014-04-23 11:45:37 -0700970 if (affinity != null) {
971 out.attribute(null, ATTR_AFFINITY, affinity);
Dianne Hackborn79228822014-09-16 11:11:23 -0700972 if (!affinity.equals(rootAffinity)) {
973 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
974 }
975 } else if (rootAffinity != null) {
976 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
Craig Mautner21d24a22014-04-23 11:45:37 -0700977 }
978 out.attribute(null, ATTR_ROOTHASRESET, String.valueOf(rootWasReset));
Dianne Hackborn13420f22014-07-18 15:43:56 -0700979 out.attribute(null, ATTR_AUTOREMOVERECENTS, String.valueOf(autoRemoveRecents));
Craig Mautner21d24a22014-04-23 11:45:37 -0700980 out.attribute(null, ATTR_ASKEDCOMPATMODE, String.valueOf(askedCompatMode));
981 out.attribute(null, ATTR_USERID, String.valueOf(userId));
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700982 out.attribute(null, ATTR_EFFECTIVE_UID, String.valueOf(effectiveUid));
Craig Mautner21d24a22014-04-23 11:45:37 -0700983 out.attribute(null, ATTR_TASKTYPE, String.valueOf(taskType));
Winson Chungffa2ec62014-07-03 15:54:42 -0700984 out.attribute(null, ATTR_FIRSTACTIVETIME, String.valueOf(firstActiveTime));
Winson Chungf1fbd772014-06-24 18:06:58 -0700985 out.attribute(null, ATTR_LASTACTIVETIME, String.valueOf(lastActiveTime));
Craig Mautner21d24a22014-04-23 11:45:37 -0700986 out.attribute(null, ATTR_LASTTIMEMOVED, String.valueOf(mLastTimeMoved));
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700987 out.attribute(null, ATTR_NEVERRELINQUISH, String.valueOf(mNeverRelinquishIdentity));
Craig Mautner21d24a22014-04-23 11:45:37 -0700988 if (lastDescription != null) {
989 out.attribute(null, ATTR_LASTDESCRIPTION, lastDescription.toString());
990 }
Winson Chung2cb86c72014-06-25 12:03:30 -0700991 if (lastTaskDescription != null) {
Craig Mautner648f69b2014-09-18 14:16:26 -0700992 lastTaskDescription.saveToXml(out);
Winson Chung2cb86c72014-06-25 12:03:30 -0700993 }
Winson Chungec396d62014-08-06 17:08:00 -0700994 out.attribute(null, ATTR_TASK_AFFILIATION_COLOR, String.valueOf(mAffiliatedTaskColor));
Craig Mautnera228ae92014-07-09 05:44:55 -0700995 out.attribute(null, ATTR_TASK_AFFILIATION, String.valueOf(mAffiliatedTaskId));
996 out.attribute(null, ATTR_PREV_AFFILIATION, String.valueOf(mPrevAffiliateTaskId));
997 out.attribute(null, ATTR_NEXT_AFFILIATION, String.valueOf(mNextAffiliateTaskId));
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700998 out.attribute(null, ATTR_CALLING_UID, String.valueOf(mCallingUid));
999 out.attribute(null, ATTR_CALLING_PACKAGE, mCallingPackage == null ? "" : mCallingPackage);
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -08001000 out.attribute(null, ATTR_RESIZEABLE, String.valueOf(mResizeable));
Wale Ogunwalea7afaa22015-05-01 20:39:18 -07001001 out.attribute(null, ATTR_PRIVILEGED, String.valueOf(mPrivileged));
Wale Ogunwale706ed792015-08-02 10:29:44 -07001002 if (mLastNonFullscreenBounds != null) {
1003 out.attribute(
1004 null, ATTR_NON_FULLSCREEN_BOUNDS, mLastNonFullscreenBounds.flattenToString());
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001005 }
Winson Chung2cb86c72014-06-25 12:03:30 -07001006
Craig Mautner21d24a22014-04-23 11:45:37 -07001007 if (affinityIntent != null) {
1008 out.startTag(null, TAG_AFFINITYINTENT);
1009 affinityIntent.saveToXml(out);
1010 out.endTag(null, TAG_AFFINITYINTENT);
1011 }
1012
1013 out.startTag(null, TAG_INTENT);
1014 intent.saveToXml(out);
1015 out.endTag(null, TAG_INTENT);
1016
1017 final ArrayList<ActivityRecord> activities = mActivities;
1018 final int numActivities = activities.size();
1019 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
1020 final ActivityRecord r = activities.get(activityNdx);
Craig Mautner43e52ed2014-06-16 17:18:52 -07001021 if (r.info.persistableMode == ActivityInfo.PERSIST_ROOT_ONLY || !r.isPersistable() ||
Wale Ogunwale843bfb92015-03-27 11:06:48 -07001022 ((r.intent.getFlags() & FLAG_ACTIVITY_NEW_DOCUMENT
1023 | FLAG_ACTIVITY_RETAIN_IN_RECENTS) == FLAG_ACTIVITY_NEW_DOCUMENT) &&
Craig Mautner43e52ed2014-06-16 17:18:52 -07001024 activityNdx > 0) {
Craig Mautnerf357c0c2014-06-09 09:23:27 -07001025 // Stop at first non-persistable or first break in task (CLEAR_WHEN_TASK_RESET).
Craig Mautner21d24a22014-04-23 11:45:37 -07001026 break;
1027 }
1028 out.startTag(null, TAG_ACTIVITY);
1029 r.saveToXml(out);
1030 out.endTag(null, TAG_ACTIVITY);
1031 }
Craig Mautner21d24a22014-04-23 11:45:37 -07001032 }
1033
1034 static TaskRecord restoreFromXml(XmlPullParser in, ActivityStackSupervisor stackSupervisor)
1035 throws IOException, XmlPullParserException {
1036 Intent intent = null;
1037 Intent affinityIntent = null;
1038 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
1039 ComponentName realActivity = null;
1040 ComponentName origActivity = null;
1041 String affinity = null;
Dianne Hackborn79228822014-09-16 11:11:23 -07001042 String rootAffinity = null;
1043 boolean hasRootAffinity = false;
Craig Mautner21d24a22014-04-23 11:45:37 -07001044 boolean rootHasReset = false;
Dianne Hackborn13420f22014-07-18 15:43:56 -07001045 boolean autoRemoveRecents = false;
Craig Mautner21d24a22014-04-23 11:45:37 -07001046 boolean askedCompatMode = false;
1047 int taskType = ActivityRecord.APPLICATION_ACTIVITY_TYPE;
Craig Mautner21d24a22014-04-23 11:45:37 -07001048 int userId = 0;
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001049 int effectiveUid = -1;
Craig Mautner21d24a22014-04-23 11:45:37 -07001050 String lastDescription = null;
Winson Chungffa2ec62014-07-03 15:54:42 -07001051 long firstActiveTime = -1;
Winson Chung2cb86c72014-06-25 12:03:30 -07001052 long lastActiveTime = -1;
Craig Mautner21d24a22014-04-23 11:45:37 -07001053 long lastTimeOnTop = 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001054 boolean neverRelinquishIdentity = true;
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001055 int taskId = INVALID_TASK_ID;
Craig Mautner21d24a22014-04-23 11:45:37 -07001056 final int outerDepth = in.getDepth();
Craig Mautner648f69b2014-09-18 14:16:26 -07001057 TaskDescription taskDescription = new TaskDescription();
Wale Ogunwale18795a22014-12-03 11:38:33 -08001058 int taskAffiliation = INVALID_TASK_ID;
Winson Chungec396d62014-08-06 17:08:00 -07001059 int taskAffiliationColor = 0;
Wale Ogunwale18795a22014-12-03 11:38:33 -08001060 int prevTaskId = INVALID_TASK_ID;
1061 int nextTaskId = INVALID_TASK_ID;
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001062 int callingUid = -1;
1063 String callingPackage = "";
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -08001064 boolean resizeable = false;
Wale Ogunwalea7afaa22015-05-01 20:39:18 -07001065 boolean privileged = false;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001066 Rect bounds = null;
Craig Mautner21d24a22014-04-23 11:45:37 -07001067
1068 for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
1069 final String attrName = in.getAttributeName(attrNdx);
1070 final String attrValue = in.getAttributeValue(attrNdx);
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001071 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: attribute name=" +
1072 attrName + " value=" + attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001073 if (ATTR_TASKID.equals(attrName)) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08001074 if (taskId == INVALID_TASK_ID) taskId = Integer.valueOf(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001075 } else if (ATTR_REALACTIVITY.equals(attrName)) {
1076 realActivity = ComponentName.unflattenFromString(attrValue);
1077 } else if (ATTR_ORIGACTIVITY.equals(attrName)) {
1078 origActivity = ComponentName.unflattenFromString(attrValue);
1079 } else if (ATTR_AFFINITY.equals(attrName)) {
1080 affinity = attrValue;
Dianne Hackborn79228822014-09-16 11:11:23 -07001081 } else if (ATTR_ROOT_AFFINITY.equals(attrName)) {
1082 rootAffinity = attrValue;
1083 hasRootAffinity = true;
Craig Mautner21d24a22014-04-23 11:45:37 -07001084 } else if (ATTR_ROOTHASRESET.equals(attrName)) {
1085 rootHasReset = Boolean.valueOf(attrValue);
Dianne Hackborn13420f22014-07-18 15:43:56 -07001086 } else if (ATTR_AUTOREMOVERECENTS.equals(attrName)) {
1087 autoRemoveRecents = Boolean.valueOf(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001088 } else if (ATTR_ASKEDCOMPATMODE.equals(attrName)) {
1089 askedCompatMode = Boolean.valueOf(attrValue);
1090 } else if (ATTR_USERID.equals(attrName)) {
1091 userId = Integer.valueOf(attrValue);
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001092 } else if (ATTR_EFFECTIVE_UID.equals(attrName)) {
1093 effectiveUid = Integer.valueOf(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001094 } else if (ATTR_TASKTYPE.equals(attrName)) {
1095 taskType = Integer.valueOf(attrValue);
Winson Chungffa2ec62014-07-03 15:54:42 -07001096 } else if (ATTR_FIRSTACTIVETIME.equals(attrName)) {
1097 firstActiveTime = Long.valueOf(attrValue);
Winson Chungf1fbd772014-06-24 18:06:58 -07001098 } else if (ATTR_LASTACTIVETIME.equals(attrName)) {
1099 lastActiveTime = Long.valueOf(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001100 } else if (ATTR_LASTDESCRIPTION.equals(attrName)) {
1101 lastDescription = attrValue;
1102 } else if (ATTR_LASTTIMEMOVED.equals(attrName)) {
1103 lastTimeOnTop = Long.valueOf(attrValue);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001104 } else if (ATTR_NEVERRELINQUISH.equals(attrName)) {
1105 neverRelinquishIdentity = Boolean.valueOf(attrValue);
Craig Mautner648f69b2014-09-18 14:16:26 -07001106 } else if (attrName.startsWith(TaskDescription.ATTR_TASKDESCRIPTION_PREFIX)) {
1107 taskDescription.restoreFromXml(attrName, attrValue);
Craig Mautnera228ae92014-07-09 05:44:55 -07001108 } else if (ATTR_TASK_AFFILIATION.equals(attrName)) {
1109 taskAffiliation = Integer.valueOf(attrValue);
1110 } else if (ATTR_PREV_AFFILIATION.equals(attrName)) {
1111 prevTaskId = Integer.valueOf(attrValue);
1112 } else if (ATTR_NEXT_AFFILIATION.equals(attrName)) {
1113 nextTaskId = Integer.valueOf(attrValue);
Winson Chungec396d62014-08-06 17:08:00 -07001114 } else if (ATTR_TASK_AFFILIATION_COLOR.equals(attrName)) {
1115 taskAffiliationColor = Integer.valueOf(attrValue);
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001116 } else if (ATTR_CALLING_UID.equals(attrName)) {
1117 callingUid = Integer.valueOf(attrValue);
1118 } else if (ATTR_CALLING_PACKAGE.equals(attrName)) {
1119 callingPackage = attrValue;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -08001120 } else if (ATTR_RESIZEABLE.equals(attrName)) {
1121 resizeable = Boolean.valueOf(attrValue);
Wale Ogunwalea7afaa22015-05-01 20:39:18 -07001122 } else if (ATTR_PRIVILEGED.equals(attrName)) {
1123 privileged = Boolean.valueOf(attrValue);
Wale Ogunwale706ed792015-08-02 10:29:44 -07001124 } else if (ATTR_NON_FULLSCREEN_BOUNDS.equals(attrName)) {
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001125 bounds = Rect.unflattenFromString(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001126 } else {
1127 Slog.w(TAG, "TaskRecord: Unknown attribute=" + attrName);
1128 }
1129 }
1130
1131 int event;
1132 while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
Ben Kwa8814cf42015-07-08 10:54:56 -07001133 (event != XmlPullParser.END_TAG || in.getDepth() >= outerDepth)) {
Craig Mautner21d24a22014-04-23 11:45:37 -07001134 if (event == XmlPullParser.START_TAG) {
1135 final String name = in.getName();
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001136 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: START_TAG name=" +
1137 name);
Craig Mautner21d24a22014-04-23 11:45:37 -07001138 if (TAG_AFFINITYINTENT.equals(name)) {
1139 affinityIntent = Intent.restoreFromXml(in);
1140 } else if (TAG_INTENT.equals(name)) {
1141 intent = Intent.restoreFromXml(in);
1142 } else if (TAG_ACTIVITY.equals(name)) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08001143 ActivityRecord activity = ActivityRecord.restoreFromXml(in, stackSupervisor);
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001144 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: activity=" +
1145 activity);
Craig Mautner21d24a22014-04-23 11:45:37 -07001146 if (activity != null) {
1147 activities.add(activity);
1148 }
1149 } else {
1150 Slog.e(TAG, "restoreTask: Unexpected name=" + name);
1151 XmlUtils.skipCurrentTag(in);
1152 }
1153 }
1154 }
Dianne Hackborn79228822014-09-16 11:11:23 -07001155 if (!hasRootAffinity) {
1156 rootAffinity = affinity;
1157 } else if ("@".equals(rootAffinity)) {
1158 rootAffinity = null;
1159 }
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001160 if (effectiveUid <= 0) {
1161 Intent checkIntent = intent != null ? intent : affinityIntent;
1162 effectiveUid = 0;
1163 if (checkIntent != null) {
1164 IPackageManager pm = AppGlobals.getPackageManager();
1165 try {
1166 ApplicationInfo ai = pm.getApplicationInfo(
1167 checkIntent.getComponent().getPackageName(),
1168 PackageManager.GET_UNINSTALLED_PACKAGES
1169 | PackageManager.GET_DISABLED_COMPONENTS, userId);
1170 if (ai != null) {
1171 effectiveUid = ai.uid;
1172 }
1173 } catch (RemoteException e) {
1174 }
1175 }
1176 Slog.w(TAG, "Updating task #" + taskId + " for " + checkIntent
1177 + ": effectiveUid=" + effectiveUid);
1178 }
1179
Craig Mautner21d24a22014-04-23 11:45:37 -07001180 final TaskRecord task = new TaskRecord(stackSupervisor.mService, taskId, intent,
Dianne Hackborn79228822014-09-16 11:11:23 -07001181 affinityIntent, affinity, rootAffinity, realActivity, origActivity, rootHasReset,
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001182 autoRemoveRecents, askedCompatMode, taskType, userId, effectiveUid, lastDescription,
1183 activities, firstActiveTime, lastActiveTime, lastTimeOnTop, neverRelinquishIdentity,
Winson Chungec396d62014-08-06 17:08:00 -07001184 taskDescription, taskAffiliation, prevTaskId, nextTaskId, taskAffiliationColor,
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001185 callingUid, callingPackage, resizeable, privileged);
Filip Gruszczynskiaff7f132015-09-02 17:21:21 -07001186 task.updateOverrideConfiguration(bounds);
Craig Mautner21d24a22014-04-23 11:45:37 -07001187
1188 for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001189 activities.get(activityNdx).task = task;
Craig Mautner21d24a22014-04-23 11:45:37 -07001190 }
1191
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001192 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Restored task=" + task);
Craig Mautner21d24a22014-04-23 11:45:37 -07001193 return task;
1194 }
1195
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001196 /**
1197 * Update task's override configuration based on the bounds.
1198 * @return Update configuration or null if there is no change.
1199 */
Filip Gruszczynskiaff7f132015-09-02 17:21:21 -07001200 Configuration updateOverrideConfiguration(Rect bounds) {
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001201 if (Objects.equals(mBounds, bounds)) {
1202 return null;
1203 }
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001204 Configuration oldConfig = mOverrideConfig;
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001205
1206 mFullscreen = bounds == null;
Wale Ogunwale706ed792015-08-02 10:29:44 -07001207 if (mFullscreen) {
Wale Ogunwale3797c222015-10-27 14:21:58 -07001208 if (mBounds != null && StackId.persistTaskBounds(stack.mStackId)) {
Wale Ogunwale706ed792015-08-02 10:29:44 -07001209 mLastNonFullscreenBounds = mBounds;
1210 }
1211 mBounds = null;
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001212 mOverrideConfig = Configuration.EMPTY;
Wale Ogunwale706ed792015-08-02 10:29:44 -07001213 } else {
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -07001214 mBounds = new Rect(bounds);
Wale Ogunwale3797c222015-10-27 14:21:58 -07001215 if (stack == null || StackId.persistTaskBounds(stack.mStackId)) {
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -07001216 mLastNonFullscreenBounds = mBounds;
1217 }
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001218
1219 final Configuration serviceConfig = mService.mConfiguration;
1220 mOverrideConfig = new Configuration(serviceConfig);
1221 // TODO(multidisplay): Update Dp to that of display stack is on.
1222 final float density = serviceConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
1223 mOverrideConfig.screenWidthDp =
1224 Math.min((int)(mBounds.width() / density), serviceConfig.screenWidthDp);
1225 mOverrideConfig.screenHeightDp =
1226 Math.min((int)(mBounds.height() / density), serviceConfig.screenHeightDp);
1227 mOverrideConfig.smallestScreenWidthDp =
1228 Math.min(mOverrideConfig.screenWidthDp, mOverrideConfig.screenHeightDp);
1229 mOverrideConfig.orientation =
1230 (mOverrideConfig.screenWidthDp <= mOverrideConfig.screenHeightDp)
1231 ? Configuration.ORIENTATION_PORTRAIT
1232 : Configuration.ORIENTATION_LANDSCAPE;
Wale Ogunwale706ed792015-08-02 10:29:44 -07001233 }
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001234 return !mOverrideConfig.equals(oldConfig) ? mOverrideConfig : null;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001235 }
1236
Wale Ogunwale935e5022015-11-10 12:36:10 -08001237 /** Updates the task's bounds and override configuration to match what is expected for the
1238 * input stack. */
1239 void updateOverrideConfigurationForStack(ActivityStack inStack) {
1240 if (stack != null && stack == inStack) {
1241 return;
1242 }
1243
1244 if (inStack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
1245 if (!mResizeable) {
1246 throw new IllegalArgumentException("Can not position non-resizeable task="
1247 + this + " in stack=" + inStack);
1248 }
1249 if (mBounds != null) {
1250 return;
1251 }
1252 if (mLastNonFullscreenBounds != null) {
1253 updateOverrideConfiguration(mLastNonFullscreenBounds);
1254 } else {
1255 inStack.layoutTaskInStack(this, null);
1256 }
1257 } else {
1258 updateOverrideConfiguration(inStack.mBounds);
1259 }
1260 }
1261
Chong Zhang0fa656b2015-08-31 15:17:21 -07001262 /**
1263 * Returns the correct stack to use based on task type and currently set bounds,
1264 * regardless of the focused stack and current stack association of the task.
1265 * The task will be moved (and stack focus changed) later if necessary.
1266 */
1267 int getLaunchStackId() {
1268 if (!isApplicationTask()) {
Wale Ogunwale706ed792015-08-02 10:29:44 -07001269 return HOME_STACK_ID;
1270 }
Chong Zhang0fa656b2015-08-31 15:17:21 -07001271 if (mBounds != null) {
Wale Ogunwale706ed792015-08-02 10:29:44 -07001272 return FREEFORM_WORKSPACE_STACK_ID;
1273 }
1274 return FULLSCREEN_WORKSPACE_STACK_ID;
1275 }
1276
1277 /** Returns the bounds that should be used to launch this task. */
1278 Rect getLaunchBounds() {
Wale Ogunwale99db1862015-10-23 20:08:22 -07001279 final int stackId = stack.mStackId;
Wale Ogunwale706ed792015-08-02 10:29:44 -07001280 if (stack == null
Wale Ogunwale99db1862015-10-23 20:08:22 -07001281 || stackId == HOME_STACK_ID
1282 || stackId == FULLSCREEN_WORKSPACE_STACK_ID) {
Wale Ogunwalea6e902e2015-09-21 18:37:15 -07001283 return (mResizeable && stack != null) ? stack.mBounds : null;
Wale Ogunwale3797c222015-10-27 14:21:58 -07001284 } else if (!StackId.persistTaskBounds(stackId)) {
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -07001285 return stack.mBounds;
Wale Ogunwale706ed792015-08-02 10:29:44 -07001286 }
1287 return mLastNonFullscreenBounds;
1288 }
1289
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001290 void dump(PrintWriter pw, String prefix) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001291 pw.print(prefix); pw.print("userId="); pw.print(userId);
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001292 pw.print(" effectiveUid="); UserHandle.formatUid(pw, effectiveUid);
1293 pw.print(" mCallingUid="); UserHandle.formatUid(pw, mCallingUid);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001294 pw.print(" mCallingPackage="); pw.println(mCallingPackage);
Dianne Hackborn79228822014-09-16 11:11:23 -07001295 if (affinity != null || rootAffinity != null) {
1296 pw.print(prefix); pw.print("affinity="); pw.print(affinity);
1297 if (affinity == null || !affinity.equals(rootAffinity)) {
1298 pw.print(" root="); pw.println(rootAffinity);
1299 } else {
1300 pw.println();
1301 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001302 }
Dianne Hackborn91097de2014-04-04 18:02:06 -07001303 if (voiceSession != null || voiceInteractor != null) {
1304 pw.print(prefix); pw.print("VOICE: session=0x");
1305 pw.print(Integer.toHexString(System.identityHashCode(voiceSession)));
1306 pw.print(" interactor=0x");
1307 pw.println(Integer.toHexString(System.identityHashCode(voiceInteractor)));
1308 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001309 if (intent != null) {
1310 StringBuilder sb = new StringBuilder(128);
1311 sb.append(prefix); sb.append("intent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08001312 intent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001313 sb.append('}');
1314 pw.println(sb.toString());
1315 }
1316 if (affinityIntent != null) {
1317 StringBuilder sb = new StringBuilder(128);
1318 sb.append(prefix); sb.append("affinityIntent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08001319 affinityIntent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001320 sb.append('}');
1321 pw.println(sb.toString());
1322 }
1323 if (origActivity != null) {
1324 pw.print(prefix); pw.print("origActivity=");
1325 pw.println(origActivity.flattenToShortString());
1326 }
1327 if (realActivity != null) {
1328 pw.print(prefix); pw.print("realActivity=");
1329 pw.println(realActivity.flattenToShortString());
1330 }
Dianne Hackborn852975d2014-08-22 17:42:43 -07001331 if (autoRemoveRecents || isPersistable || taskType != 0 || mTaskToReturnTo != 0
1332 || numFullscreen != 0) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001333 pw.print(prefix); pw.print("autoRemoveRecents="); pw.print(autoRemoveRecents);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001334 pw.print(" isPersistable="); pw.print(isPersistable);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001335 pw.print(" numFullscreen="); pw.print(numFullscreen);
1336 pw.print(" taskType="); pw.print(taskType);
1337 pw.print(" mTaskToReturnTo="); pw.println(mTaskToReturnTo);
1338 }
Craig Mautner432f64e2015-05-20 14:59:57 -07001339 if (rootWasReset || mNeverRelinquishIdentity || mReuseTask
1340 || mLockTaskAuth != LOCK_TASK_AUTH_PINNABLE) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001341 pw.print(prefix); pw.print("rootWasReset="); pw.print(rootWasReset);
1342 pw.print(" mNeverRelinquishIdentity="); pw.print(mNeverRelinquishIdentity);
Craig Mautner432f64e2015-05-20 14:59:57 -07001343 pw.print(" mReuseTask="); pw.print(mReuseTask);
1344 pw.print(" mLockTaskAuth="); pw.println(lockTaskAuthToString());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001345 }
Wale Ogunwale18795a22014-12-03 11:38:33 -08001346 if (mAffiliatedTaskId != taskId || mPrevAffiliateTaskId != INVALID_TASK_ID
1347 || mPrevAffiliate != null || mNextAffiliateTaskId != INVALID_TASK_ID
1348 || mNextAffiliate != null) {
Dianne Hackborn852975d2014-08-22 17:42:43 -07001349 pw.print(prefix); pw.print("affiliation="); pw.print(mAffiliatedTaskId);
1350 pw.print(" prevAffiliation="); pw.print(mPrevAffiliateTaskId);
1351 pw.print(" (");
1352 if (mPrevAffiliate == null) {
1353 pw.print("null");
1354 } else {
1355 pw.print(Integer.toHexString(System.identityHashCode(mPrevAffiliate)));
1356 }
1357 pw.print(") nextAffiliation="); pw.print(mNextAffiliateTaskId);
1358 pw.print(" (");
1359 if (mNextAffiliate == null) {
1360 pw.print("null");
1361 } else {
1362 pw.print(Integer.toHexString(System.identityHashCode(mNextAffiliate)));
1363 }
1364 pw.println(")");
1365 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001366 pw.print(prefix); pw.print("Activities="); pw.println(mActivities);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001367 if (!askedCompatMode || !inRecents || !isAvailable) {
1368 pw.print(prefix); pw.print("askedCompatMode="); pw.print(askedCompatMode);
1369 pw.print(" inRecents="); pw.print(inRecents);
1370 pw.print(" isAvailable="); pw.println(isAvailable);
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001371 }
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001372 pw.print(prefix); pw.print("lastThumbnail="); pw.print(mLastThumbnail);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001373 pw.print(" lastThumbnailFile="); pw.println(mLastThumbnailFile);
1374 if (lastDescription != null) {
1375 pw.print(prefix); pw.print("lastDescription="); pw.println(lastDescription);
1376 }
Wale Ogunwale069fbe42015-07-29 11:38:01 -07001377 if (stack != null) {
1378 pw.print(prefix); pw.print("stackId="); pw.println(stack.mStackId);
1379 }
Dianne Hackbornd38aed82014-06-10 21:36:35 -07001380 pw.print(prefix); pw.print("hasBeenVisible="); pw.print(hasBeenVisible);
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -08001381 pw.print(" mResizeable="); pw.print(mResizeable);
Winson Chungffa2ec62014-07-03 15:54:42 -07001382 pw.print(" firstActiveTime="); pw.print(lastActiveTime);
Dianne Hackbornd38aed82014-06-10 21:36:35 -07001383 pw.print(" lastActiveTime="); pw.print(lastActiveTime);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001384 pw.print(" (inactive for ");
1385 pw.print((getInactiveDuration()/1000)); pw.println("s)");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001386 }
1387
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001388 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001389 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001390 StringBuilder sb = new StringBuilder(128);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001391 if (stringName != null) {
1392 sb.append(stringName);
1393 sb.append(" U=");
1394 sb.append(userId);
Wale Ogunwale6c5eb1c2015-11-10 07:52:22 -08001395 sb.append(" StackId=");
1396 sb.append(stack != null ? stack.mStackId : INVALID_STACK_ID);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001397 sb.append(" sz=");
1398 sb.append(mActivities.size());
1399 sb.append('}');
1400 return sb.toString();
1401 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001402 sb.append("TaskRecord{");
1403 sb.append(Integer.toHexString(System.identityHashCode(this)));
1404 sb.append(" #");
1405 sb.append(taskId);
1406 if (affinity != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001407 sb.append(" A=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001408 sb.append(affinity);
1409 } else if (intent != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001410 sb.append(" I=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001411 sb.append(intent.getComponent().flattenToShortString());
1412 } else if (affinityIntent != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001413 sb.append(" aI=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001414 sb.append(affinityIntent.getComponent().flattenToShortString());
1415 } else {
1416 sb.append(" ??");
1417 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07001418 stringName = sb.toString();
1419 return toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001420 }
1421}