blob: 20117c3053afbdd6bf2e2c9c2304f7bb7c1284d1 [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 Ogunwale706ed792015-08-02 10:29:44 -070019import static android.app.ActivityManager.FREEFORM_WORKSPACE_STACK_ID;
20import static android.app.ActivityManager.FULLSCREEN_WORKSPACE_STACK_ID;
21import static android.app.ActivityManager.HOME_STACK_ID;
Wale Ogunwale843bfb92015-03-27 11:06:48 -070022import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
23import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
Craig Mautner15df08a2015-04-01 12:17:18 -070024import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
25import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
26import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
27import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER;
Wale Ogunwalea7afaa22015-05-01 20:39:18 -070028import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
Wale Ogunwaleee006da2015-03-30 14:49:25 -070029import static com.android.server.am.ActivityManagerDebugConfig.*;
Craig Mautner84984fa2014-06-19 11:19:20 -070030import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
31import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
32import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
Craig Mautnerde4ef022013-04-07 19:01:33 -070033
Craig Mautnerb0f7dc72013-04-01 16:34:45 -070034import android.app.Activity;
Craig Mautner9db9a0b2013-04-29 17:05:56 -070035import android.app.ActivityManager;
Craig Mautnerc0ffce52014-07-01 12:38:52 -070036import android.app.ActivityManager.TaskThumbnail;
Craig Mautner648f69b2014-09-18 14:16:26 -070037import android.app.ActivityManager.TaskDescription;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -070038import android.app.ActivityOptions;
Dianne Hackborn885fbe52014-08-23 15:23:58 -070039import android.app.AppGlobals;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040import android.content.ComponentName;
41import android.content.Intent;
42import android.content.pm.ActivityInfo;
Dianne Hackborn885fbe52014-08-23 15:23:58 -070043import android.content.pm.ApplicationInfo;
44import android.content.pm.IPackageManager;
45import android.content.pm.PackageManager;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -070046import android.content.res.Configuration;
Craig Mautner9db9a0b2013-04-29 17:05:56 -070047import android.graphics.Bitmap;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -070048import android.graphics.Rect;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -070049import android.os.Debug;
Craig Mautnerc0ffce52014-07-01 12:38:52 -070050import android.os.ParcelFileDescriptor;
Dianne Hackborn885fbe52014-08-23 15:23:58 -070051import android.os.RemoteException;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070052import android.os.UserHandle;
Dianne Hackborn91097de2014-04-04 18:02:06 -070053import android.service.voice.IVoiceInteractionSession;
Dianne Hackborn7f96b792012-05-29 18:46:45 -070054import android.util.Slog;
Dianne Hackborn91097de2014-04-04 18:02:06 -070055import com.android.internal.app.IVoiceInteractor;
Craig Mautner21d24a22014-04-23 11:45:37 -070056import com.android.internal.util.XmlUtils;
57import org.xmlpull.v1.XmlPullParser;
58import org.xmlpull.v1.XmlPullParserException;
59import org.xmlpull.v1.XmlSerializer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060
Craig Mautnerc0ffce52014-07-01 12:38:52 -070061import java.io.File;
Craig Mautner21d24a22014-04-23 11:45:37 -070062import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063import java.io.PrintWriter;
Craig Mautner5d9c7be2013-02-15 14:02:56 -080064import java.util.ArrayList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065
Craig Mautnerc0ffce52014-07-01 12:38:52 -070066final class TaskRecord {
Wale Ogunwalee23149f2015-03-06 15:39:44 -080067 private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskRecord" : TAG_AM;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -070068 private static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE;
Wale Ogunwaleee006da2015-03-30 14:49:25 -070069 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
Craig Mautnere0570202015-05-13 13:06:11 -070070 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwaleee006da2015-03-30 14:49:25 -070071 private static final String TAG_TASKS = TAG + POSTFIX_TASKS;
Wale Ogunwalee23149f2015-03-06 15:39:44 -080072
Wale Ogunwale18795a22014-12-03 11:38:33 -080073 static final String ATTR_TASKID = "task_id";
Craig Mautner21d24a22014-04-23 11:45:37 -070074 private static final String TAG_INTENT = "intent";
75 private static final String TAG_AFFINITYINTENT = "affinity_intent";
Wale Ogunwale18795a22014-12-03 11:38:33 -080076 static final String ATTR_REALACTIVITY = "real_activity";
Craig Mautner21d24a22014-04-23 11:45:37 -070077 private static final String ATTR_ORIGACTIVITY = "orig_activity";
Stefan Kuhnee88d1e52015-05-18 10:33:45 -070078 private static final String TAG_ACTIVITY = "activity";
Craig Mautner21d24a22014-04-23 11:45:37 -070079 private static final String ATTR_AFFINITY = "affinity";
Dianne Hackborn79228822014-09-16 11:11:23 -070080 private static final String ATTR_ROOT_AFFINITY = "root_affinity";
Craig Mautner21d24a22014-04-23 11:45:37 -070081 private static final String ATTR_ROOTHASRESET = "root_has_reset";
Dianne Hackborn13420f22014-07-18 15:43:56 -070082 private static final String ATTR_AUTOREMOVERECENTS = "auto_remove_recents";
Craig Mautner21d24a22014-04-23 11:45:37 -070083 private static final String ATTR_ASKEDCOMPATMODE = "asked_compat_mode";
84 private static final String ATTR_USERID = "user_id";
Dianne Hackborn885fbe52014-08-23 15:23:58 -070085 private static final String ATTR_EFFECTIVE_UID = "effective_uid";
Craig Mautner21d24a22014-04-23 11:45:37 -070086 private static final String ATTR_TASKTYPE = "task_type";
Winson Chungffa2ec62014-07-03 15:54:42 -070087 private static final String ATTR_FIRSTACTIVETIME = "first_active_time";
Winson Chungf1fbd772014-06-24 18:06:58 -070088 private static final String ATTR_LASTACTIVETIME = "last_active_time";
Craig Mautner21d24a22014-04-23 11:45:37 -070089 private static final String ATTR_LASTDESCRIPTION = "last_description";
90 private static final String ATTR_LASTTIMEMOVED = "last_time_moved";
Craig Mautner9d4e9bc2014-06-18 18:34:56 -070091 private static final String ATTR_NEVERRELINQUISH = "never_relinquish_identity";
Wale Ogunwale18795a22014-12-03 11:38:33 -080092 static final String ATTR_TASK_AFFILIATION = "task_affiliation";
Craig Mautnera228ae92014-07-09 05:44:55 -070093 private static final String ATTR_PREV_AFFILIATION = "prev_affiliation";
94 private static final String ATTR_NEXT_AFFILIATION = "next_affiliation";
Winson Chungec396d62014-08-06 17:08:00 -070095 private static final String ATTR_TASK_AFFILIATION_COLOR = "task_affiliation_color";
Craig Mautnerdc00cbe2014-07-20 17:48:47 -070096 private static final String ATTR_CALLING_UID = "calling_uid";
97 private static final String ATTR_CALLING_PACKAGE = "calling_package";
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -080098 private static final String ATTR_RESIZEABLE = "resizeable";
Wale Ogunwalea7afaa22015-05-01 20:39:18 -070099 private static final String ATTR_PRIVILEGED = "privileged";
Wale Ogunwale706ed792015-08-02 10:29:44 -0700100 private static final String ATTR_NON_FULLSCREEN_BOUNDS = "non_fullscreen_bounds";
Craig Mautner21d24a22014-04-23 11:45:37 -0700101
102 private static final String TASK_THUMBNAIL_SUFFIX = "_task_thumbnail";
103
Craig Mautner0b633fc2014-07-23 10:42:18 -0700104 static final boolean IGNORE_RETURN_TO_RECENTS = true;
105
Wale Ogunwale18795a22014-12-03 11:38:33 -0800106 static final int INVALID_TASK_ID = -1;
107
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108 final int taskId; // Unique identifier for this task.
Dianne Hackborn79228822014-09-16 11:11:23 -0700109 String affinity; // The affinity name for this task, or null; may change identity.
110 String rootAffinity; // Initial base affinity, or null; does not change from initial root.
Dianne Hackborn91097de2014-04-04 18:02:06 -0700111 final IVoiceInteractionSession voiceSession; // Voice interaction session driving task
112 final IVoiceInteractor voiceInteractor; // Associated interactor to provide to app
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113 Intent intent; // The original intent that started the task.
114 Intent affinityIntent; // Intent of affinity-moved activity that started this task.
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700115 int effectiveUid; // The current effective uid of the identity of this task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116 ComponentName origActivity; // The non-alias activity component of the intent.
117 ComponentName realActivity; // The actual activity component that started the task.
Winson Chungffa2ec62014-07-03 15:54:42 -0700118 long firstActiveTime; // First time this task was active.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119 long lastActiveTime; // Last time this task was active, including sleep.
Dianne Hackborn852975d2014-08-22 17:42:43 -0700120 boolean inRecents; // Actually in the recents list?
121 boolean isAvailable; // Is the activity available to be launched?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800122 boolean rootWasReset; // True if the intent at the root of the task had
123 // the FLAG_ACTIVITY_RESET_TASK_IF_NEEDED flag.
Dianne Hackborn13420f22014-07-18 15:43:56 -0700124 boolean autoRemoveRecents; // If true, we should automatically remove the task from
125 // recents when activity finishes
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700126 boolean askedCompatMode;// Have asked the user about compat mode for this task.
Dianne Hackbornd38aed82014-06-10 21:36:35 -0700127 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 -0800128
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700129 String stringName; // caching of toString() result.
Dianne Hackborn9da2d402012-03-15 13:43:08 -0700130 int userId; // user for which this task was created
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800131
132 int numFullscreen; // Number of fullscreen activities.
133
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800134 boolean mResizeable; // Activities in the task resizeable. Based on the resizable setting of
135 // the root activity.
Craig Mautner15df08a2015-04-01 12:17:18 -0700136 int mLockTaskMode; // Which tasklock mode to launch this task in. One of
137 // ActivityManager.LOCK_TASK_LAUNCH_MODE_*
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700138 private boolean mPrivileged; // The root activity application of this task holds
139 // privileged permissions.
140
Craig Mautner15df08a2015-04-01 12:17:18 -0700141 /** Can't be put in lockTask mode. */
142 final static int LOCK_TASK_AUTH_DONT_LOCK = 0;
Benjamin Franz469dd582015-06-09 14:24:36 +0100143 /** Can enter app pinning with user approval. Can never start over existing lockTask task. */
Craig Mautner15df08a2015-04-01 12:17:18 -0700144 final static int LOCK_TASK_AUTH_PINNABLE = 1;
145 /** Starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing lockTask task. */
146 final static int LOCK_TASK_AUTH_LAUNCHABLE = 2;
Benjamin Franz469dd582015-06-09 14:24:36 +0100147 /** Can enter lockTask without user approval. Can start over existing lockTask task. */
Craig Mautner15df08a2015-04-01 12:17:18 -0700148 final static int LOCK_TASK_AUTH_WHITELISTED = 3;
Benjamin Franz469dd582015-06-09 14:24:36 +0100149 /** Priv-app that starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing
150 * lockTask task. */
151 final static int LOCK_TASK_AUTH_LAUNCHABLE_PRIV = 4;
Craig Mautner15df08a2015-04-01 12:17:18 -0700152 int mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE;
153
154 int mLockTaskUid = -1; // The uid of the application that called startLockTask().
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800155
Winson Chung03a9bae2014-05-02 09:56:12 -0700156 // This represents the last resolved activity values for this task
157 // NOTE: This value needs to be persisted with each task
Craig Mautner648f69b2014-09-18 14:16:26 -0700158 TaskDescription lastTaskDescription = new TaskDescription();
Winson Chung03a9bae2014-05-02 09:56:12 -0700159
Craig Mautnerd2328952013-03-05 12:46:26 -0800160 /** List of all activities in the task arranged in history order */
Craig Mautner21d24a22014-04-23 11:45:37 -0700161 final ArrayList<ActivityRecord> mActivities;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800162
Craig Mautnerd2328952013-03-05 12:46:26 -0800163 /** Current stack */
164 ActivityStack stack;
165
Craig Mautner2c1faed2013-07-23 12:56:02 -0700166 /** Takes on same set of values as ActivityRecord.mActivityType */
Craig Mautner21d24a22014-04-23 11:45:37 -0700167 int taskType;
Craig Mautner1602ec22013-05-12 10:24:27 -0700168
Craig Mautner21d24a22014-04-23 11:45:37 -0700169 /** Takes on same value as first root activity */
170 boolean isPersistable = false;
Craig Mautnerffcfcaa2014-06-05 09:54:38 -0700171 int maxRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700172
173 /** Only used for persistable tasks, otherwise 0. The last time this task was moved. Used for
174 * determining the order when restoring. Sign indicates whether last task movement was to front
175 * (positive) or back (negative). Absolute value indicates time. */
176 long mLastTimeMoved = System.currentTimeMillis();
177
Craig Mautner84984fa2014-06-19 11:19:20 -0700178 /** Indication of what to run next when task exits. Use ActivityRecord types.
179 * ActivityRecord.APPLICATION_ACTIVITY_TYPE indicates to resume the task below this one in the
180 * task stack. */
181 private int mTaskToReturnTo = APPLICATION_ACTIVITY_TYPE;
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700182
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700183 /** If original intent did not allow relinquishing task identity, save that information */
184 boolean mNeverRelinquishIdentity = true;
185
Craig Mautner362449a2014-06-20 14:04:39 -0700186 // Used in the unique case where we are clearing the task in order to reuse it. In that case we
187 // do not want to delete the stack when the task goes empty.
188 boolean mReuseTask = false;
189
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700190 private Bitmap mLastThumbnail; // Last thumbnail captured for this item.
Wale Ogunwalebe23ff42014-10-21 16:29:51 -0700191 private final File mLastThumbnailFile; // File containing last thumbnail.
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700192 private final String mFilename;
193 CharSequence lastDescription; // Last description captured for this item.
194
Craig Mautnera228ae92014-07-09 05:44:55 -0700195 int mAffiliatedTaskId; // taskId of parent affiliation or self if no parent.
Winson Chungec396d62014-08-06 17:08:00 -0700196 int mAffiliatedTaskColor; // color of the parent task affiliation.
Craig Mautnera228ae92014-07-09 05:44:55 -0700197 TaskRecord mPrevAffiliate; // previous task in affiliated chain.
Wale Ogunwale18795a22014-12-03 11:38:33 -0800198 int mPrevAffiliateTaskId = INVALID_TASK_ID; // previous id for persistence.
Craig Mautnera228ae92014-07-09 05:44:55 -0700199 TaskRecord mNextAffiliate; // next task in affiliated chain.
Wale Ogunwale18795a22014-12-03 11:38:33 -0800200 int mNextAffiliateTaskId = INVALID_TASK_ID; // next id for persistence.
Craig Mautnera228ae92014-07-09 05:44:55 -0700201
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700202 // For relaunching the task from recents as though it was launched by the original launcher.
203 int mCallingUid;
204 String mCallingPackage;
205
Craig Mautner21d24a22014-04-23 11:45:37 -0700206 final ActivityManagerService mService;
207
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700208 // Whether or not this task covers the entire screen; by default tasks are fullscreen.
209 boolean mFullscreen = true;
210
211 // Bounds of the Task. null for fullscreen tasks.
212 Rect mBounds = null;
Wale Ogunwale706ed792015-08-02 10:29:44 -0700213 // Last non-fullscreen bounds the task was launched in or resized to.
214 // The information is persisted and used to determine the appropriate stack to launch the
215 // task into on restore.
216 Rect mLastNonFullscreenBounds = null;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700217
218 Configuration mOverrideConfig = Configuration.EMPTY;
219
Craig Mautner21d24a22014-04-23 11:45:37 -0700220 TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Dianne Hackborn91097de2014-04-04 18:02:06 -0700221 IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700222 mService = service;
Craig Mautnera228ae92014-07-09 05:44:55 -0700223 mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
224 TaskPersister.IMAGE_EXTENSION;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700225 mLastThumbnailFile = new File(TaskPersister.sImagesDir, mFilename);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800226 taskId = _taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700227 mAffiliatedTaskId = _taskId;
Dianne Hackborn91097de2014-04-04 18:02:06 -0700228 voiceSession = _voiceSession;
229 voiceInteractor = _voiceInteractor;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700230 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800231 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700232 mCallingUid = info.applicationInfo.uid;
233 mCallingPackage = info.packageName;
Martijn Coenend4a69702014-06-30 11:12:17 -0700234 setIntent(_intent, info);
Craig Mautner21d24a22014-04-23 11:45:37 -0700235 }
236
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700237 TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Craig Mautner648f69b2014-09-18 14:16:26 -0700238 TaskDescription _taskDescription) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700239 mService = service;
240 mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
241 TaskPersister.IMAGE_EXTENSION;
242 mLastThumbnailFile = new File(TaskPersister.sImagesDir, mFilename);
243 taskId = _taskId;
244 mAffiliatedTaskId = _taskId;
245 voiceSession = null;
246 voiceInteractor = null;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700247 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800248 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700249 mCallingUid = info.applicationInfo.uid;
250 mCallingPackage = info.packageName;
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700251 setIntent(_intent, info);
252
253 taskType = ActivityRecord.APPLICATION_ACTIVITY_TYPE;
254 isPersistable = true;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700255 // Clamp to [1, max].
256 maxRecents = Math.min(Math.max(info.maxRecents, 1),
257 ActivityManager.getMaxAppRecentsLimitStatic());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700258
259 taskType = APPLICATION_ACTIVITY_TYPE;
260 mTaskToReturnTo = HOME_ACTIVITY_TYPE;
261 userId = UserHandle.getUserId(info.applicationInfo.uid);
262 lastTaskDescription = _taskDescription;
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700263 }
264
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800265 private TaskRecord(ActivityManagerService service, int _taskId, Intent _intent,
266 Intent _affinityIntent, String _affinity, String _rootAffinity,
267 ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset,
268 boolean _autoRemoveRecents, boolean _askedCompatMode, int _taskType, int _userId,
269 int _effectiveUid, String _lastDescription, ArrayList<ActivityRecord> activities,
270 long _firstActiveTime, long _lastActiveTime, long lastTimeMoved,
271 boolean neverRelinquishIdentity, TaskDescription _lastTaskDescription,
272 int taskAffiliation, int prevTaskId, int nextTaskId, int taskAffiliationColor,
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700273 int callingUid, String callingPackage, boolean resizeable, boolean privileged,
274 Rect bounds) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700275 mService = service;
Craig Mautnera228ae92014-07-09 05:44:55 -0700276 mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
277 TaskPersister.IMAGE_EXTENSION;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700278 mLastThumbnailFile = new File(TaskPersister.sImagesDir, mFilename);
Craig Mautner21d24a22014-04-23 11:45:37 -0700279 taskId = _taskId;
280 intent = _intent;
281 affinityIntent = _affinityIntent;
282 affinity = _affinity;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800283 rootAffinity = _rootAffinity;
Craig Mautner21d24a22014-04-23 11:45:37 -0700284 voiceSession = null;
285 voiceInteractor = null;
286 realActivity = _realActivity;
287 origActivity = _origActivity;
288 rootWasReset = _rootWasReset;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700289 isAvailable = true;
Dianne Hackborn13420f22014-07-18 15:43:56 -0700290 autoRemoveRecents = _autoRemoveRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700291 askedCompatMode = _askedCompatMode;
292 taskType = _taskType;
Craig Mautner84984fa2014-06-19 11:19:20 -0700293 mTaskToReturnTo = HOME_ACTIVITY_TYPE;
Craig Mautner21d24a22014-04-23 11:45:37 -0700294 userId = _userId;
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700295 effectiveUid = _effectiveUid;
Winson Chungffa2ec62014-07-03 15:54:42 -0700296 firstActiveTime = _firstActiveTime;
Winson Chungf1fbd772014-06-24 18:06:58 -0700297 lastActiveTime = _lastActiveTime;
Craig Mautner21d24a22014-04-23 11:45:37 -0700298 lastDescription = _lastDescription;
299 mActivities = activities;
300 mLastTimeMoved = lastTimeMoved;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700301 mNeverRelinquishIdentity = neverRelinquishIdentity;
Winson Chung2cb86c72014-06-25 12:03:30 -0700302 lastTaskDescription = _lastTaskDescription;
Craig Mautnera228ae92014-07-09 05:44:55 -0700303 mAffiliatedTaskId = taskAffiliation;
Winson Chungec396d62014-08-06 17:08:00 -0700304 mAffiliatedTaskColor = taskAffiliationColor;
Craig Mautnera228ae92014-07-09 05:44:55 -0700305 mPrevAffiliateTaskId = prevTaskId;
306 mNextAffiliateTaskId = nextTaskId;
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700307 mCallingUid = callingUid;
308 mCallingPackage = callingPackage;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800309 mResizeable = resizeable;
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700310 mPrivileged = privileged;
Wale Ogunwale706ed792015-08-02 10:29:44 -0700311 mBounds = mLastNonFullscreenBounds = bounds;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800312 }
313
314 void touchActiveTime() {
Craig Mautner494f6bdd2014-07-21 11:17:46 -0700315 lastActiveTime = System.currentTimeMillis();
Winson Chungffa2ec62014-07-03 15:54:42 -0700316 if (firstActiveTime == 0) {
317 firstActiveTime = lastActiveTime;
318 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800319 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700320
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800321 long getInactiveDuration() {
Craig Mautner494f6bdd2014-07-21 11:17:46 -0700322 return System.currentTimeMillis() - lastActiveTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800323 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700324
Winson Chungfee26772014-08-05 12:21:52 -0700325 /** Sets the original intent, and the calling uid and package. */
326 void setIntent(ActivityRecord r) {
Winson Chungfee26772014-08-05 12:21:52 -0700327 mCallingUid = r.launchedFromUid;
328 mCallingPackage = r.launchedFromPackage;
Craig Mautner15df08a2015-04-01 12:17:18 -0700329 setIntent(r.intent, r.info);
Winson Chungfee26772014-08-05 12:21:52 -0700330 }
331
332 /** Sets the original intent, _without_ updating the calling uid or package. */
333 private void setIntent(Intent _intent, ActivityInfo info) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700334 if (intent == null) {
335 mNeverRelinquishIdentity =
336 (info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) == 0;
337 } else if (mNeverRelinquishIdentity) {
338 return;
339 }
340
341 affinity = info.taskAffinity;
Dianne Hackborn79228822014-09-16 11:11:23 -0700342 if (intent == null) {
343 // If this task already has an intent associated with it, don't set the root
344 // affinity -- we don't want it changing after initially set, but the initially
345 // set value may be null.
346 rootAffinity = affinity;
347 }
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700348 effectiveUid = info.applicationInfo.uid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700349 stringName = null;
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800350
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800351 if (info.targetActivity == null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800352 if (_intent != null) {
353 // If this Intent has a selector, we want to clear it for the
354 // recent task since it is not relevant if the user later wants
355 // to re-launch the app.
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700356 if (_intent.getSelector() != null || _intent.getSourceBounds() != null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800357 _intent = new Intent(_intent);
358 _intent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700359 _intent.setSourceBounds(null);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800360 }
361 }
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700362 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Setting Intent of " + this + " to " + _intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800363 intent = _intent;
364 realActivity = _intent != null ? _intent.getComponent() : null;
365 origActivity = null;
366 } else {
367 ComponentName targetComponent = new ComponentName(
368 info.packageName, info.targetActivity);
369 if (_intent != null) {
370 Intent targetIntent = new Intent(_intent);
371 targetIntent.setComponent(targetComponent);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800372 targetIntent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700373 targetIntent.setSourceBounds(null);
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700374 if (DEBUG_TASKS) Slog.v(TAG_TASKS,
Dianne Hackborn7f96b792012-05-29 18:46:45 -0700375 "Setting Intent of " + this + " to target " + targetIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800376 intent = targetIntent;
377 realActivity = targetComponent;
378 origActivity = _intent.getComponent();
379 } else {
380 intent = null;
381 realActivity = targetComponent;
382 origActivity = new ComponentName(info.packageName, info.name);
383 }
384 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700385
Craig Mautner47b20ba2014-09-17 17:23:44 -0700386 final int intentFlags = intent == null ? 0 : intent.getFlags();
387 if ((intentFlags & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800388 // Once we are set to an Intent with this flag, we count this
389 // task as having a true root activity.
390 rootWasReset = true;
391 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700392
Dianne Hackborn09233282014-04-30 11:33:59 -0700393 userId = UserHandle.getUserId(info.applicationInfo.uid);
Craig Mautner41db4a72014-05-07 17:20:56 -0700394 if ((info.flags & ActivityInfo.FLAG_AUTO_REMOVE_FROM_RECENTS) != 0) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700395 // If the activity itself has requested auto-remove, then just always do it.
396 autoRemoveRecents = true;
Wale Ogunwale843bfb92015-03-27 11:06:48 -0700397 } else if ((intentFlags & (FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS))
398 == FLAG_ACTIVITY_NEW_DOCUMENT) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700399 // If the caller has not asked for the document to be retained, then we may
400 // want to turn on auto-remove, depending on whether the target has set its
401 // own document launch mode.
402 if (info.documentLaunchMode != ActivityInfo.DOCUMENT_LAUNCH_NONE) {
403 autoRemoveRecents = false;
404 } else {
405 autoRemoveRecents = true;
406 }
407 } else {
408 autoRemoveRecents = false;
Craig Mautner41db4a72014-05-07 17:20:56 -0700409 }
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800410 mResizeable = info.resizeable;
Craig Mautner15df08a2015-04-01 12:17:18 -0700411 mLockTaskMode = info.lockTaskLaunchMode;
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700412 mPrivileged = (info.applicationInfo.privateFlags & PRIVATE_FLAG_PRIVILEGED) != 0;
Craig Mautner15df08a2015-04-01 12:17:18 -0700413 setLockTaskAuth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800414 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800415
Craig Mautner84984fa2014-06-19 11:19:20 -0700416 void setTaskToReturnTo(int taskToReturnTo) {
Wale Ogunwale2d0f39b2015-04-17 15:35:39 -0700417 mTaskToReturnTo = (IGNORE_RETURN_TO_RECENTS && taskToReturnTo == RECENTS_ACTIVITY_TYPE)
418 ? HOME_ACTIVITY_TYPE : taskToReturnTo;
Craig Mautner84984fa2014-06-19 11:19:20 -0700419 }
420
421 int getTaskToReturnTo() {
422 return mTaskToReturnTo;
423 }
424
Craig Mautnera228ae92014-07-09 05:44:55 -0700425 void setPrevAffiliate(TaskRecord prevAffiliate) {
426 mPrevAffiliate = prevAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800427 mPrevAffiliateTaskId = prevAffiliate == null ? INVALID_TASK_ID : prevAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700428 }
429
430 void setNextAffiliate(TaskRecord nextAffiliate) {
431 mNextAffiliate = nextAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800432 mNextAffiliateTaskId = nextAffiliate == null ? INVALID_TASK_ID : nextAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700433 }
434
435 // Close up recents linked list.
436 void closeRecentsChain() {
437 if (mPrevAffiliate != null) {
438 mPrevAffiliate.setNextAffiliate(mNextAffiliate);
439 }
440 if (mNextAffiliate != null) {
441 mNextAffiliate.setPrevAffiliate(mPrevAffiliate);
442 }
443 setPrevAffiliate(null);
444 setNextAffiliate(null);
445 }
446
Winson Chung740c3ac2014-11-12 16:14:38 -0800447 void removedFromRecents() {
Dianne Hackborn852975d2014-08-22 17:42:43 -0700448 disposeThumbnail();
449 closeRecentsChain();
450 if (inRecents) {
451 inRecents = false;
Winson Chung740c3ac2014-11-12 16:14:38 -0800452 mService.notifyTaskPersisterLocked(this, false);
Dianne Hackborn852975d2014-08-22 17:42:43 -0700453 }
454 }
455
Craig Mautnera228ae92014-07-09 05:44:55 -0700456 void setTaskToAffiliateWith(TaskRecord taskToAffiliateWith) {
457 closeRecentsChain();
458 mAffiliatedTaskId = taskToAffiliateWith.mAffiliatedTaskId;
Winson Chungec396d62014-08-06 17:08:00 -0700459 mAffiliatedTaskColor = taskToAffiliateWith.mAffiliatedTaskColor;
Craig Mautnera228ae92014-07-09 05:44:55 -0700460 // Find the end
461 while (taskToAffiliateWith.mNextAffiliate != null) {
462 final TaskRecord nextRecents = taskToAffiliateWith.mNextAffiliate;
463 if (nextRecents.mAffiliatedTaskId != mAffiliatedTaskId) {
464 Slog.e(TAG, "setTaskToAffiliateWith: nextRecents=" + nextRecents + " affilTaskId="
465 + nextRecents.mAffiliatedTaskId + " should be " + mAffiliatedTaskId);
466 if (nextRecents.mPrevAffiliate == taskToAffiliateWith) {
467 nextRecents.setPrevAffiliate(null);
468 }
469 taskToAffiliateWith.setNextAffiliate(null);
470 break;
471 }
472 taskToAffiliateWith = nextRecents;
473 }
474 taskToAffiliateWith.setNextAffiliate(this);
475 setPrevAffiliate(taskToAffiliateWith);
476 setNextAffiliate(null);
477 }
478
Winson Chung096f36b2014-08-20 15:39:01 -0700479 /**
480 * Sets the last thumbnail.
481 * @return whether the thumbnail was set
482 */
483 boolean setLastThumbnail(Bitmap thumbnail) {
484 if (mLastThumbnail != thumbnail) {
485 mLastThumbnail = thumbnail;
486 if (thumbnail == null) {
487 if (mLastThumbnailFile != null) {
488 mLastThumbnailFile.delete();
489 }
490 } else {
491 mService.mTaskPersister.saveImage(thumbnail, mFilename);
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700492 }
Winson Chung096f36b2014-08-20 15:39:01 -0700493 return true;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700494 }
Winson Chung096f36b2014-08-20 15:39:01 -0700495 return false;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700496 }
497
498 void getLastThumbnail(TaskThumbnail thumbs) {
499 thumbs.mainThumbnail = mLastThumbnail;
500 thumbs.thumbnailFileDescriptor = null;
Craig Mautnerf4f8bb72014-07-29 10:41:40 -0700501 if (mLastThumbnail == null) {
Craig Mautner648f69b2014-09-18 14:16:26 -0700502 thumbs.mainThumbnail = mService.mTaskPersister.getImageFromWriteQueue(mFilename);
Craig Mautnerf4f8bb72014-07-29 10:41:40 -0700503 }
Winson Chung096f36b2014-08-20 15:39:01 -0700504 // Only load the thumbnail file if we don't have a thumbnail
505 if (thumbs.mainThumbnail == null && mLastThumbnailFile.exists()) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700506 try {
507 thumbs.thumbnailFileDescriptor = ParcelFileDescriptor.open(mLastThumbnailFile,
508 ParcelFileDescriptor.MODE_READ_ONLY);
509 } catch (IOException e) {
Dianne Hackborn9844d292013-10-04 16:44:22 -0700510 }
511 }
512 }
513
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700514 void freeLastThumbnail() {
515 mLastThumbnail = null;
516 }
517
518 void disposeThumbnail() {
519 mLastThumbnail = null;
520 lastDescription = null;
521 }
522
Winson Chung1147c402014-05-14 11:05:00 -0700523 /** Returns the intent for the root activity for this task */
524 Intent getBaseIntent() {
525 return intent != null ? intent : affinityIntent;
526 }
527
Winson Chung3b3f4642014-04-22 10:08:18 -0700528 /** Returns the first non-finishing activity from the root. */
529 ActivityRecord getRootActivity() {
530 for (int i = 0; i < mActivities.size(); i++) {
531 final ActivityRecord r = mActivities.get(i);
532 if (r.finishing) {
533 continue;
534 }
535 return r;
536 }
537 return null;
538 }
539
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800540 ActivityRecord getTopActivity() {
541 for (int i = mActivities.size() - 1; i >= 0; --i) {
542 final ActivityRecord r = mActivities.get(i);
543 if (r.finishing) {
544 continue;
545 }
546 return r;
547 }
548 return null;
549 }
550
Craig Mautner6b74cb52013-09-27 17:02:21 -0700551 ActivityRecord topRunningActivityLocked(ActivityRecord notTop) {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700552 if (stack != null) {
553 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
554 ActivityRecord r = mActivities.get(activityNdx);
555 if (!r.finishing && r != notTop && stack.okToShowLocked(r)) {
556 return r;
557 }
Craig Mautner6b74cb52013-09-27 17:02:21 -0700558 }
559 }
560 return null;
561 }
562
Craig Mautner3b475fe2013-12-16 15:58:31 -0800563 /** Call after activity movement or finish to make sure that frontOfTask is set correctly */
564 final void setFrontOfTask() {
565 boolean foundFront = false;
566 final int numActivities = mActivities.size();
Craig Mautner704e40b2013-12-18 16:43:51 -0800567 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
Craig Mautner3b475fe2013-12-16 15:58:31 -0800568 final ActivityRecord r = mActivities.get(activityNdx);
569 if (foundFront || r.finishing) {
570 r.frontOfTask = false;
571 } else {
572 r.frontOfTask = true;
573 // Set frontOfTask false for every following activity.
574 foundFront = true;
575 }
576 }
Craig Mautner9587ee02014-06-23 15:00:10 +0000577 if (!foundFront && numActivities > 0) {
578 // All activities of this task are finishing. As we ought to have a frontOfTask
579 // activity, make the bottom activity front.
580 mActivities.get(0).frontOfTask = true;
581 }
Craig Mautner3b475fe2013-12-16 15:58:31 -0800582 }
583
Craig Mautnerde4ef022013-04-07 19:01:33 -0700584 /**
Craig Mautner3b475fe2013-12-16 15:58:31 -0800585 * Reorder the history stack so that the passed activity is brought to the front.
Craig Mautnerde4ef022013-04-07 19:01:33 -0700586 */
587 final void moveActivityToFrontLocked(ActivityRecord newTop) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -0700588 if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE,
589 "Removing and adding activity " + newTop
590 + " to stack at top callers=" + Debug.getCallers(4));
Craig Mautnerde4ef022013-04-07 19:01:33 -0700591
Craig Mautnerde4ef022013-04-07 19:01:33 -0700592 mActivities.remove(newTop);
593 mActivities.add(newTop);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700594 updateEffectiveIntent();
Craig Mautner3b475fe2013-12-16 15:58:31 -0800595
596 setFrontOfTask();
Craig Mautnerde4ef022013-04-07 19:01:33 -0700597 }
598
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800599 void addActivityAtBottom(ActivityRecord r) {
Craig Mautner77878772013-03-04 19:46:24 -0800600 addActivityAtIndex(0, r);
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800601 }
602
603 void addActivityToTop(ActivityRecord r) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700604 addActivityAtIndex(mActivities.size(), r);
605 }
606
607 void addActivityAtIndex(int index, ActivityRecord r) {
Craig Mautner6170f732013-04-02 13:05:23 -0700608 // 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 -0800609 if (!mActivities.remove(r) && r.fullscreen) {
610 // Was not previously in list.
611 numFullscreen++;
612 }
Craig Mautner2c1faed2013-07-23 12:56:02 -0700613 // Only set this based on the first activity
614 if (mActivities.isEmpty()) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700615 taskType = r.mActivityType;
616 isPersistable = r.isPersistable();
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700617 mCallingUid = r.launchedFromUid;
618 mCallingPackage = r.launchedFromPackage;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700619 // Clamp to [1, max].
620 maxRecents = Math.min(Math.max(r.info.maxRecents, 1),
621 ActivityManager.getMaxAppRecentsLimitStatic());
Craig Mautner2c1faed2013-07-23 12:56:02 -0700622 } else {
623 // Otherwise make all added activities match this one.
Craig Mautner21d24a22014-04-23 11:45:37 -0700624 r.mActivityType = taskType;
Craig Mautner78733002013-06-10 13:54:49 -0700625 }
Craig Mautner77878772013-03-04 19:46:24 -0800626 mActivities.add(index, r);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700627 updateEffectiveIntent();
Craig Mautner21d24a22014-04-23 11:45:37 -0700628 if (r.isPersistable()) {
629 mService.notifyTaskPersisterLocked(this, false);
630 }
Craig Mautner77878772013-03-04 19:46:24 -0800631 }
632
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800633 /** @return true if this was the last activity in the task */
634 boolean removeActivity(ActivityRecord r) {
635 if (mActivities.remove(r) && r.fullscreen) {
636 // Was previously in list.
637 numFullscreen--;
638 }
Craig Mautner21d24a22014-04-23 11:45:37 -0700639 if (r.isPersistable()) {
640 mService.notifyTaskPersisterLocked(this, false);
641 }
Craig Mautner41326202014-06-20 14:38:21 -0700642 if (mActivities.isEmpty()) {
Craig Mautner5afcd4d2014-06-21 18:11:33 -0700643 return !mReuseTask;
Craig Mautner41326202014-06-20 14:38:21 -0700644 }
645 updateEffectiveIntent();
646 return false;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800647 }
648
Craig Mautner41db4a72014-05-07 17:20:56 -0700649 boolean autoRemoveFromRecents() {
Dianne Hackbornd38aed82014-06-10 21:36:35 -0700650 // We will automatically remove the task either if it has explicitly asked for
651 // this, or it is empty and has never contained an activity that got shown to
652 // the user.
Dianne Hackborn13420f22014-07-18 15:43:56 -0700653 return autoRemoveRecents || (mActivities.isEmpty() && !hasBeenVisible);
Craig Mautner41db4a72014-05-07 17:20:56 -0700654 }
655
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700656 /**
657 * Completely remove all activities associated with an existing
658 * task starting at a specified index.
659 */
660 final void performClearTaskAtIndexLocked(int activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700661 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700662 for ( ; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700663 final ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700664 if (r.finishing) {
665 continue;
666 }
Craig Mautner21d24a22014-04-23 11:45:37 -0700667 if (stack == null) {
668 // Task was restored from persistent storage.
669 r.takeFromHistory();
670 mActivities.remove(activityNdx);
671 --activityNdx;
672 --numActivities;
Todd Kennedy539db512014-12-15 09:57:55 -0800673 } else if (stack.finishActivityLocked(
674 r, Activity.RESULT_CANCELED, null, "clear-task-index", false)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700675 --activityNdx;
676 --numActivities;
677 }
678 }
679 }
680
681 /**
682 * Completely remove all activities associated with an existing task.
683 */
684 final void performClearTaskLocked() {
Craig Mautner362449a2014-06-20 14:04:39 -0700685 mReuseTask = true;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700686 performClearTaskAtIndexLocked(0);
Craig Mautner362449a2014-06-20 14:04:39 -0700687 mReuseTask = false;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700688 }
689
690 /**
691 * Perform clear operation as requested by
692 * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the
693 * stack to the given task, then look for
694 * an instance of that activity in the stack and, if found, finish all
695 * activities on top of it and return the instance.
696 *
697 * @param newR Description of the new activity being started.
698 * @return Returns the old activity that should be continued to be used,
699 * or null if none was found.
700 */
701 final ActivityRecord performClearTaskLocked(ActivityRecord newR, int launchFlags) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700702 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700703 for (int activityNdx = numActivities - 1; activityNdx >= 0; --activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700704 ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700705 if (r.finishing) {
706 continue;
707 }
708 if (r.realActivity.equals(newR.realActivity)) {
709 // Here it is! Now finish everything in front...
Craig Mautner1602ec22013-05-12 10:24:27 -0700710 final ActivityRecord ret = r;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700711
712 for (++activityNdx; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700713 r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700714 if (r.finishing) {
715 continue;
716 }
717 ActivityOptions opts = r.takeOptionsLocked();
718 if (opts != null) {
719 ret.updateOptionsLocked(opts);
720 }
Wale Ogunwale7d701172015-03-11 15:36:30 -0700721 if (stack != null && stack.finishActivityLocked(
Todd Kennedy539db512014-12-15 09:57:55 -0800722 r, Activity.RESULT_CANCELED, null, "clear-task-stack", false)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700723 --activityNdx;
724 --numActivities;
725 }
726 }
727
728 // Finally, if this is a normal launch mode (that is, not
729 // expecting onNewIntent()), then we will finish the current
730 // instance of the activity so a new fresh one can be started.
731 if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE
732 && (launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0) {
733 if (!ret.finishing) {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700734 if (stack != null) {
735 stack.finishActivityLocked(
736 ret, Activity.RESULT_CANCELED, null, "clear-task-top", false);
737 }
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700738 return null;
739 }
740 }
741
742 return ret;
743 }
744 }
745
746 return null;
747 }
748
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700749 public TaskThumbnail getTaskThumbnailLocked() {
Craig Mautner21d24a22014-04-23 11:45:37 -0700750 if (stack != null) {
751 final ActivityRecord resumedActivity = stack.mResumedActivity;
752 if (resumedActivity != null && resumedActivity.task == this) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700753 final Bitmap thumbnail = stack.screenshotActivities(resumedActivity);
754 setLastThumbnail(thumbnail);
Craig Mautner21d24a22014-04-23 11:45:37 -0700755 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700756 }
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700757 final TaskThumbnail taskThumbnail = new TaskThumbnail();
758 getLastThumbnail(taskThumbnail);
759 return taskThumbnail;
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700760 }
761
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700762 public void removeTaskActivitiesLocked() {
763 // Just remove the entire task.
764 performClearTaskAtIndexLocked(0);
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700765 }
766
Craig Mautner432f64e2015-05-20 14:59:57 -0700767 String lockTaskAuthToString() {
768 switch (mLockTaskAuth) {
769 case LOCK_TASK_AUTH_DONT_LOCK: return "LOCK_TASK_AUTH_DONT_LOCK";
770 case LOCK_TASK_AUTH_PINNABLE: return "LOCK_TASK_AUTH_PINNABLE";
771 case LOCK_TASK_AUTH_LAUNCHABLE: return "LOCK_TASK_AUTH_LAUNCHABLE";
772 case LOCK_TASK_AUTH_WHITELISTED: return "LOCK_TASK_AUTH_WHITELISTED";
Benjamin Franz469dd582015-06-09 14:24:36 +0100773 case LOCK_TASK_AUTH_LAUNCHABLE_PRIV: return "LOCK_TASK_AUTH_LAUNCHABLE_PRIV";
Craig Mautner432f64e2015-05-20 14:59:57 -0700774 default: return "unknown=" + mLockTaskAuth;
775 }
776 }
777
Craig Mautner15df08a2015-04-01 12:17:18 -0700778 void setLockTaskAuth() {
Benjamin Franz469dd582015-06-09 14:24:36 +0100779 if (!mPrivileged &&
780 (mLockTaskMode == LOCK_TASK_LAUNCH_MODE_ALWAYS ||
781 mLockTaskMode == LOCK_TASK_LAUNCH_MODE_NEVER)) {
782 // Non-priv apps are not allowed to use always or never, fall back to default
783 mLockTaskMode = LOCK_TASK_LAUNCH_MODE_DEFAULT;
784 }
Craig Mautner15df08a2015-04-01 12:17:18 -0700785 switch (mLockTaskMode) {
786 case LOCK_TASK_LAUNCH_MODE_DEFAULT:
787 mLockTaskAuth = isLockTaskWhitelistedLocked() ?
788 LOCK_TASK_AUTH_WHITELISTED : LOCK_TASK_AUTH_PINNABLE;
789 break;
790
791 case LOCK_TASK_LAUNCH_MODE_NEVER:
Benjamin Franz469dd582015-06-09 14:24:36 +0100792 mLockTaskAuth = LOCK_TASK_AUTH_DONT_LOCK;
Craig Mautner15df08a2015-04-01 12:17:18 -0700793 break;
794
795 case LOCK_TASK_LAUNCH_MODE_ALWAYS:
Benjamin Franz469dd582015-06-09 14:24:36 +0100796 mLockTaskAuth = LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
Craig Mautner15df08a2015-04-01 12:17:18 -0700797 break;
798
799 case LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED:
800 mLockTaskAuth = isLockTaskWhitelistedLocked() ?
801 LOCK_TASK_AUTH_LAUNCHABLE : LOCK_TASK_AUTH_PINNABLE;
802 break;
803 }
Craig Mautner432f64e2015-05-20 14:59:57 -0700804 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
805 " mLockTaskAuth=" + lockTaskAuthToString());
Craig Mautner15df08a2015-04-01 12:17:18 -0700806 }
807
808 boolean isLockTaskWhitelistedLocked() {
809 if (mCallingPackage == null) {
810 return false;
811 }
812 String[] packages = mService.mLockTaskPackages.get(userId);
813 if (packages == null) {
814 return false;
815 }
816 for (int i = packages.length - 1; i >= 0; --i) {
817 if (mCallingPackage.equals(packages[i])) {
818 return true;
819 }
820 }
821 return false;
822 }
Craig Mautnera82aa092013-09-13 15:34:08 -0700823 boolean isHomeTask() {
Craig Mautner84984fa2014-06-19 11:19:20 -0700824 return taskType == HOME_ACTIVITY_TYPE;
Craig Mautnera82aa092013-09-13 15:34:08 -0700825 }
826
Craig Mautner86d67a42013-05-14 10:34:38 -0700827 boolean isApplicationTask() {
Craig Mautner84984fa2014-06-19 11:19:20 -0700828 return taskType == APPLICATION_ACTIVITY_TYPE;
829 }
830
831 boolean isOverHomeStack() {
832 return mTaskToReturnTo == HOME_ACTIVITY_TYPE || mTaskToReturnTo == RECENTS_ACTIVITY_TYPE;
Craig Mautner1602ec22013-05-12 10:24:27 -0700833 }
834
Craig Mautner525f3d92013-05-07 14:01:50 -0700835 /**
836 * Find the activity in the history stack within the given task. Returns
837 * the index within the history at which it's found, or < 0 if not found.
838 */
839 final ActivityRecord findActivityInHistoryLocked(ActivityRecord r) {
840 final ComponentName realActivity = r.realActivity;
841 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
842 ActivityRecord candidate = mActivities.get(activityNdx);
843 if (candidate.finishing) {
844 continue;
845 }
846 if (candidate.realActivity.equals(realActivity)) {
847 return candidate;
848 }
849 }
850 return null;
851 }
852
Winson Chunga449dc02014-05-16 11:15:04 -0700853 /** Updates the last task description values. */
854 void updateTaskDescription() {
855 // Traverse upwards looking for any break between main task activities and
856 // utility activities.
857 int activityNdx;
858 final int numActivities = mActivities.size();
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700859 final boolean relinquish = numActivities == 0 ? false :
860 (mActivities.get(0).info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) != 0;
Winson Chunga449dc02014-05-16 11:15:04 -0700861 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
Craig Mautner21d24a22014-04-23 11:45:37 -0700862 ++activityNdx) {
Winson Chunga449dc02014-05-16 11:15:04 -0700863 final ActivityRecord r = mActivities.get(activityNdx);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700864 if (relinquish && (r.info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
865 // This will be the top activity for determining taskDescription. Pre-inc to
866 // overcome initial decrement below.
867 ++activityNdx;
868 break;
869 }
Winson Chunga449dc02014-05-16 11:15:04 -0700870 if (r.intent != null &&
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700871 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
Winson Chunga449dc02014-05-16 11:15:04 -0700872 break;
873 }
874 }
875 if (activityNdx > 0) {
876 // Traverse downwards starting below break looking for set label, icon.
877 // Note that if there are activities in the task but none of them set the
878 // recent activity values, then we do not fall back to the last set
879 // values in the TaskRecord.
880 String label = null;
Craig Mautner648f69b2014-09-18 14:16:26 -0700881 String iconFilename = null;
Winson Chunga449dc02014-05-16 11:15:04 -0700882 int colorPrimary = 0;
883 for (--activityNdx; activityNdx >= 0; --activityNdx) {
884 final ActivityRecord r = mActivities.get(activityNdx);
885 if (r.taskDescription != null) {
886 if (label == null) {
887 label = r.taskDescription.getLabel();
888 }
Craig Mautner648f69b2014-09-18 14:16:26 -0700889 if (iconFilename == null) {
890 iconFilename = r.taskDescription.getIconFilename();
Winson Chunga449dc02014-05-16 11:15:04 -0700891 }
892 if (colorPrimary == 0) {
893 colorPrimary = r.taskDescription.getPrimaryColor();
Winson Chunga449dc02014-05-16 11:15:04 -0700894 }
895 }
896 }
Craig Mautner648f69b2014-09-18 14:16:26 -0700897 lastTaskDescription = new TaskDescription(label, colorPrimary, iconFilename);
Winson Chungec396d62014-08-06 17:08:00 -0700898 // Update the task affiliation color if we are the parent of the group
899 if (taskId == mAffiliatedTaskId) {
900 mAffiliatedTaskColor = lastTaskDescription.getPrimaryColor();
901 }
Winson Chunga449dc02014-05-16 11:15:04 -0700902 }
903 }
904
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700905 int findEffectiveRootIndex() {
Craig Mautner4767f4b2014-09-18 15:38:33 -0700906 int effectiveNdx = 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700907 final int topActivityNdx = mActivities.size() - 1;
Dianne Hackborn39569af2014-09-23 10:56:58 -0700908 for (int activityNdx = 0; activityNdx <= topActivityNdx; ++activityNdx) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700909 final ActivityRecord r = mActivities.get(activityNdx);
910 if (r.finishing) {
911 continue;
912 }
Craig Mautner4767f4b2014-09-18 15:38:33 -0700913 effectiveNdx = activityNdx;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700914 if ((r.info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
915 break;
916 }
917 }
Craig Mautner4767f4b2014-09-18 15:38:33 -0700918 return effectiveNdx;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700919 }
920
921 void updateEffectiveIntent() {
922 final int effectiveRootIndex = findEffectiveRootIndex();
923 final ActivityRecord r = mActivities.get(effectiveRootIndex);
Winson Chungfee26772014-08-05 12:21:52 -0700924 setIntent(r);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700925 }
926
Craig Mautner21d24a22014-04-23 11:45:37 -0700927 void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700928 if (DEBUG_RECENTS) Slog.i(TAG_RECENTS, "Saving task=" + this);
Craig Mautner21d24a22014-04-23 11:45:37 -0700929
930 out.attribute(null, ATTR_TASKID, String.valueOf(taskId));
931 if (realActivity != null) {
932 out.attribute(null, ATTR_REALACTIVITY, realActivity.flattenToShortString());
933 }
934 if (origActivity != null) {
935 out.attribute(null, ATTR_ORIGACTIVITY, origActivity.flattenToShortString());
936 }
Dianne Hackborn79228822014-09-16 11:11:23 -0700937 // Write affinity, and root affinity if it is different from affinity.
938 // We use the special string "@" for a null root affinity, so we can identify
939 // later whether we were given a root affinity or should just make it the
940 // same as the affinity.
Craig Mautner21d24a22014-04-23 11:45:37 -0700941 if (affinity != null) {
942 out.attribute(null, ATTR_AFFINITY, affinity);
Dianne Hackborn79228822014-09-16 11:11:23 -0700943 if (!affinity.equals(rootAffinity)) {
944 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
945 }
946 } else if (rootAffinity != null) {
947 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
Craig Mautner21d24a22014-04-23 11:45:37 -0700948 }
949 out.attribute(null, ATTR_ROOTHASRESET, String.valueOf(rootWasReset));
Dianne Hackborn13420f22014-07-18 15:43:56 -0700950 out.attribute(null, ATTR_AUTOREMOVERECENTS, String.valueOf(autoRemoveRecents));
Craig Mautner21d24a22014-04-23 11:45:37 -0700951 out.attribute(null, ATTR_ASKEDCOMPATMODE, String.valueOf(askedCompatMode));
952 out.attribute(null, ATTR_USERID, String.valueOf(userId));
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700953 out.attribute(null, ATTR_EFFECTIVE_UID, String.valueOf(effectiveUid));
Craig Mautner21d24a22014-04-23 11:45:37 -0700954 out.attribute(null, ATTR_TASKTYPE, String.valueOf(taskType));
Winson Chungffa2ec62014-07-03 15:54:42 -0700955 out.attribute(null, ATTR_FIRSTACTIVETIME, String.valueOf(firstActiveTime));
Winson Chungf1fbd772014-06-24 18:06:58 -0700956 out.attribute(null, ATTR_LASTACTIVETIME, String.valueOf(lastActiveTime));
Craig Mautner21d24a22014-04-23 11:45:37 -0700957 out.attribute(null, ATTR_LASTTIMEMOVED, String.valueOf(mLastTimeMoved));
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700958 out.attribute(null, ATTR_NEVERRELINQUISH, String.valueOf(mNeverRelinquishIdentity));
Craig Mautner21d24a22014-04-23 11:45:37 -0700959 if (lastDescription != null) {
960 out.attribute(null, ATTR_LASTDESCRIPTION, lastDescription.toString());
961 }
Winson Chung2cb86c72014-06-25 12:03:30 -0700962 if (lastTaskDescription != null) {
Craig Mautner648f69b2014-09-18 14:16:26 -0700963 lastTaskDescription.saveToXml(out);
Winson Chung2cb86c72014-06-25 12:03:30 -0700964 }
Winson Chungec396d62014-08-06 17:08:00 -0700965 out.attribute(null, ATTR_TASK_AFFILIATION_COLOR, String.valueOf(mAffiliatedTaskColor));
Craig Mautnera228ae92014-07-09 05:44:55 -0700966 out.attribute(null, ATTR_TASK_AFFILIATION, String.valueOf(mAffiliatedTaskId));
967 out.attribute(null, ATTR_PREV_AFFILIATION, String.valueOf(mPrevAffiliateTaskId));
968 out.attribute(null, ATTR_NEXT_AFFILIATION, String.valueOf(mNextAffiliateTaskId));
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700969 out.attribute(null, ATTR_CALLING_UID, String.valueOf(mCallingUid));
970 out.attribute(null, ATTR_CALLING_PACKAGE, mCallingPackage == null ? "" : mCallingPackage);
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800971 out.attribute(null, ATTR_RESIZEABLE, String.valueOf(mResizeable));
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700972 out.attribute(null, ATTR_PRIVILEGED, String.valueOf(mPrivileged));
Wale Ogunwale706ed792015-08-02 10:29:44 -0700973 if (mLastNonFullscreenBounds != null) {
974 out.attribute(
975 null, ATTR_NON_FULLSCREEN_BOUNDS, mLastNonFullscreenBounds.flattenToString());
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700976 }
Winson Chung2cb86c72014-06-25 12:03:30 -0700977
Craig Mautner21d24a22014-04-23 11:45:37 -0700978 if (affinityIntent != null) {
979 out.startTag(null, TAG_AFFINITYINTENT);
980 affinityIntent.saveToXml(out);
981 out.endTag(null, TAG_AFFINITYINTENT);
982 }
983
984 out.startTag(null, TAG_INTENT);
985 intent.saveToXml(out);
986 out.endTag(null, TAG_INTENT);
987
988 final ArrayList<ActivityRecord> activities = mActivities;
989 final int numActivities = activities.size();
990 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
991 final ActivityRecord r = activities.get(activityNdx);
Craig Mautner43e52ed2014-06-16 17:18:52 -0700992 if (r.info.persistableMode == ActivityInfo.PERSIST_ROOT_ONLY || !r.isPersistable() ||
Wale Ogunwale843bfb92015-03-27 11:06:48 -0700993 ((r.intent.getFlags() & FLAG_ACTIVITY_NEW_DOCUMENT
994 | FLAG_ACTIVITY_RETAIN_IN_RECENTS) == FLAG_ACTIVITY_NEW_DOCUMENT) &&
Craig Mautner43e52ed2014-06-16 17:18:52 -0700995 activityNdx > 0) {
Craig Mautnerf357c0c2014-06-09 09:23:27 -0700996 // Stop at first non-persistable or first break in task (CLEAR_WHEN_TASK_RESET).
Craig Mautner21d24a22014-04-23 11:45:37 -0700997 break;
998 }
999 out.startTag(null, TAG_ACTIVITY);
1000 r.saveToXml(out);
1001 out.endTag(null, TAG_ACTIVITY);
1002 }
Craig Mautner21d24a22014-04-23 11:45:37 -07001003 }
1004
1005 static TaskRecord restoreFromXml(XmlPullParser in, ActivityStackSupervisor stackSupervisor)
1006 throws IOException, XmlPullParserException {
1007 Intent intent = null;
1008 Intent affinityIntent = null;
1009 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
1010 ComponentName realActivity = null;
1011 ComponentName origActivity = null;
1012 String affinity = null;
Dianne Hackborn79228822014-09-16 11:11:23 -07001013 String rootAffinity = null;
1014 boolean hasRootAffinity = false;
Craig Mautner21d24a22014-04-23 11:45:37 -07001015 boolean rootHasReset = false;
Dianne Hackborn13420f22014-07-18 15:43:56 -07001016 boolean autoRemoveRecents = false;
Craig Mautner21d24a22014-04-23 11:45:37 -07001017 boolean askedCompatMode = false;
1018 int taskType = ActivityRecord.APPLICATION_ACTIVITY_TYPE;
Craig Mautner21d24a22014-04-23 11:45:37 -07001019 int userId = 0;
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001020 int effectiveUid = -1;
Craig Mautner21d24a22014-04-23 11:45:37 -07001021 String lastDescription = null;
Winson Chungffa2ec62014-07-03 15:54:42 -07001022 long firstActiveTime = -1;
Winson Chung2cb86c72014-06-25 12:03:30 -07001023 long lastActiveTime = -1;
Craig Mautner21d24a22014-04-23 11:45:37 -07001024 long lastTimeOnTop = 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001025 boolean neverRelinquishIdentity = true;
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001026 int taskId = INVALID_TASK_ID;
Craig Mautner21d24a22014-04-23 11:45:37 -07001027 final int outerDepth = in.getDepth();
Craig Mautner648f69b2014-09-18 14:16:26 -07001028 TaskDescription taskDescription = new TaskDescription();
Wale Ogunwale18795a22014-12-03 11:38:33 -08001029 int taskAffiliation = INVALID_TASK_ID;
Winson Chungec396d62014-08-06 17:08:00 -07001030 int taskAffiliationColor = 0;
Wale Ogunwale18795a22014-12-03 11:38:33 -08001031 int prevTaskId = INVALID_TASK_ID;
1032 int nextTaskId = INVALID_TASK_ID;
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001033 int callingUid = -1;
1034 String callingPackage = "";
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -08001035 boolean resizeable = false;
Wale Ogunwalea7afaa22015-05-01 20:39:18 -07001036 boolean privileged = false;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001037 Rect bounds = null;
Craig Mautner21d24a22014-04-23 11:45:37 -07001038
1039 for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
1040 final String attrName = in.getAttributeName(attrNdx);
1041 final String attrValue = in.getAttributeValue(attrNdx);
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001042 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: attribute name=" +
1043 attrName + " value=" + attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001044 if (ATTR_TASKID.equals(attrName)) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08001045 if (taskId == INVALID_TASK_ID) taskId = Integer.valueOf(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001046 } else if (ATTR_REALACTIVITY.equals(attrName)) {
1047 realActivity = ComponentName.unflattenFromString(attrValue);
1048 } else if (ATTR_ORIGACTIVITY.equals(attrName)) {
1049 origActivity = ComponentName.unflattenFromString(attrValue);
1050 } else if (ATTR_AFFINITY.equals(attrName)) {
1051 affinity = attrValue;
Dianne Hackborn79228822014-09-16 11:11:23 -07001052 } else if (ATTR_ROOT_AFFINITY.equals(attrName)) {
1053 rootAffinity = attrValue;
1054 hasRootAffinity = true;
Craig Mautner21d24a22014-04-23 11:45:37 -07001055 } else if (ATTR_ROOTHASRESET.equals(attrName)) {
1056 rootHasReset = Boolean.valueOf(attrValue);
Dianne Hackborn13420f22014-07-18 15:43:56 -07001057 } else if (ATTR_AUTOREMOVERECENTS.equals(attrName)) {
1058 autoRemoveRecents = Boolean.valueOf(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001059 } else if (ATTR_ASKEDCOMPATMODE.equals(attrName)) {
1060 askedCompatMode = Boolean.valueOf(attrValue);
1061 } else if (ATTR_USERID.equals(attrName)) {
1062 userId = Integer.valueOf(attrValue);
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001063 } else if (ATTR_EFFECTIVE_UID.equals(attrName)) {
1064 effectiveUid = Integer.valueOf(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001065 } else if (ATTR_TASKTYPE.equals(attrName)) {
1066 taskType = Integer.valueOf(attrValue);
Winson Chungffa2ec62014-07-03 15:54:42 -07001067 } else if (ATTR_FIRSTACTIVETIME.equals(attrName)) {
1068 firstActiveTime = Long.valueOf(attrValue);
Winson Chungf1fbd772014-06-24 18:06:58 -07001069 } else if (ATTR_LASTACTIVETIME.equals(attrName)) {
1070 lastActiveTime = Long.valueOf(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001071 } else if (ATTR_LASTDESCRIPTION.equals(attrName)) {
1072 lastDescription = attrValue;
1073 } else if (ATTR_LASTTIMEMOVED.equals(attrName)) {
1074 lastTimeOnTop = Long.valueOf(attrValue);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001075 } else if (ATTR_NEVERRELINQUISH.equals(attrName)) {
1076 neverRelinquishIdentity = Boolean.valueOf(attrValue);
Craig Mautner648f69b2014-09-18 14:16:26 -07001077 } else if (attrName.startsWith(TaskDescription.ATTR_TASKDESCRIPTION_PREFIX)) {
1078 taskDescription.restoreFromXml(attrName, attrValue);
Craig Mautnera228ae92014-07-09 05:44:55 -07001079 } else if (ATTR_TASK_AFFILIATION.equals(attrName)) {
1080 taskAffiliation = Integer.valueOf(attrValue);
1081 } else if (ATTR_PREV_AFFILIATION.equals(attrName)) {
1082 prevTaskId = Integer.valueOf(attrValue);
1083 } else if (ATTR_NEXT_AFFILIATION.equals(attrName)) {
1084 nextTaskId = Integer.valueOf(attrValue);
Winson Chungec396d62014-08-06 17:08:00 -07001085 } else if (ATTR_TASK_AFFILIATION_COLOR.equals(attrName)) {
1086 taskAffiliationColor = Integer.valueOf(attrValue);
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001087 } else if (ATTR_CALLING_UID.equals(attrName)) {
1088 callingUid = Integer.valueOf(attrValue);
1089 } else if (ATTR_CALLING_PACKAGE.equals(attrName)) {
1090 callingPackage = attrValue;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -08001091 } else if (ATTR_RESIZEABLE.equals(attrName)) {
1092 resizeable = Boolean.valueOf(attrValue);
Wale Ogunwalea7afaa22015-05-01 20:39:18 -07001093 } else if (ATTR_PRIVILEGED.equals(attrName)) {
1094 privileged = Boolean.valueOf(attrValue);
Wale Ogunwale706ed792015-08-02 10:29:44 -07001095 } else if (ATTR_NON_FULLSCREEN_BOUNDS.equals(attrName)) {
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001096 bounds = Rect.unflattenFromString(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001097 } else {
1098 Slog.w(TAG, "TaskRecord: Unknown attribute=" + attrName);
1099 }
1100 }
1101
1102 int event;
1103 while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
1104 (event != XmlPullParser.END_TAG || in.getDepth() < outerDepth)) {
1105 if (event == XmlPullParser.START_TAG) {
1106 final String name = in.getName();
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001107 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: START_TAG name=" +
1108 name);
Craig Mautner21d24a22014-04-23 11:45:37 -07001109 if (TAG_AFFINITYINTENT.equals(name)) {
1110 affinityIntent = Intent.restoreFromXml(in);
1111 } else if (TAG_INTENT.equals(name)) {
1112 intent = Intent.restoreFromXml(in);
1113 } else if (TAG_ACTIVITY.equals(name)) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08001114 ActivityRecord activity = ActivityRecord.restoreFromXml(in, stackSupervisor);
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001115 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: activity=" +
1116 activity);
Craig Mautner21d24a22014-04-23 11:45:37 -07001117 if (activity != null) {
1118 activities.add(activity);
1119 }
1120 } else {
1121 Slog.e(TAG, "restoreTask: Unexpected name=" + name);
1122 XmlUtils.skipCurrentTag(in);
1123 }
1124 }
1125 }
Dianne Hackborn79228822014-09-16 11:11:23 -07001126 if (!hasRootAffinity) {
1127 rootAffinity = affinity;
1128 } else if ("@".equals(rootAffinity)) {
1129 rootAffinity = null;
1130 }
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001131 if (effectiveUid <= 0) {
1132 Intent checkIntent = intent != null ? intent : affinityIntent;
1133 effectiveUid = 0;
1134 if (checkIntent != null) {
1135 IPackageManager pm = AppGlobals.getPackageManager();
1136 try {
1137 ApplicationInfo ai = pm.getApplicationInfo(
1138 checkIntent.getComponent().getPackageName(),
1139 PackageManager.GET_UNINSTALLED_PACKAGES
1140 | PackageManager.GET_DISABLED_COMPONENTS, userId);
1141 if (ai != null) {
1142 effectiveUid = ai.uid;
1143 }
1144 } catch (RemoteException e) {
1145 }
1146 }
1147 Slog.w(TAG, "Updating task #" + taskId + " for " + checkIntent
1148 + ": effectiveUid=" + effectiveUid);
1149 }
1150
Craig Mautner21d24a22014-04-23 11:45:37 -07001151 final TaskRecord task = new TaskRecord(stackSupervisor.mService, taskId, intent,
Dianne Hackborn79228822014-09-16 11:11:23 -07001152 affinityIntent, affinity, rootAffinity, realActivity, origActivity, rootHasReset,
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001153 autoRemoveRecents, askedCompatMode, taskType, userId, effectiveUid, lastDescription,
1154 activities, firstActiveTime, lastActiveTime, lastTimeOnTop, neverRelinquishIdentity,
Winson Chungec396d62014-08-06 17:08:00 -07001155 taskDescription, taskAffiliation, prevTaskId, nextTaskId, taskAffiliationColor,
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001156 callingUid, callingPackage, resizeable, privileged, bounds);
Craig Mautner21d24a22014-04-23 11:45:37 -07001157
1158 for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001159 activities.get(activityNdx).task = task;
Craig Mautner21d24a22014-04-23 11:45:37 -07001160 }
1161
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001162 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Restored task=" + task);
Craig Mautner21d24a22014-04-23 11:45:37 -07001163 return task;
1164 }
1165
Wale Ogunwale706ed792015-08-02 10:29:44 -07001166 boolean updateOverrideConfiguration(Configuration newConfig, Rect bounds) {
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001167 Configuration oldConfig = mOverrideConfig;
1168 mOverrideConfig = (newConfig == null) ? Configuration.EMPTY : newConfig;
1169 // We override the configuration only when the task's dimensions are different from the
1170 // display. In this manner, we know that if the override configuration is empty, the task
1171 // is necessarily fullscreen.
1172 mFullscreen = Configuration.EMPTY.equals(mOverrideConfig);
Wale Ogunwale706ed792015-08-02 10:29:44 -07001173 if (mFullscreen) {
1174 if (mBounds != null) {
1175 mLastNonFullscreenBounds = mBounds;
1176 }
1177 mBounds = null;
1178 } else {
1179 mBounds = mLastNonFullscreenBounds = new Rect(bounds);
1180 }
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001181 return !mOverrideConfig.equals(oldConfig);
1182 }
1183
Wale Ogunwale706ed792015-08-02 10:29:44 -07001184 /** Returns the stack that should be used to launch this task. */
1185 int getLaunchStackId(ActivityStack focusStack) {
1186 if (stack != null) {
1187 // We are already in a stack silly...
1188 return stack.mStackId;
1189 }
1190 if (isHomeTask()) {
1191 return HOME_STACK_ID;
1192 }
1193 if (focusStack != null && focusStack.mStackId != HOME_STACK_ID) {
1194 // Like it or not you are going in the focused stack!
1195 return focusStack.mStackId;
1196 }
1197 if (mBounds != null || mLastNonFullscreenBounds != null) {
1198 return FREEFORM_WORKSPACE_STACK_ID;
1199 }
1200 return FULLSCREEN_WORKSPACE_STACK_ID;
1201 }
1202
1203 /** Returns the bounds that should be used to launch this task. */
1204 Rect getLaunchBounds() {
1205 if (stack == null
1206 || stack.mStackId == HOME_STACK_ID
1207 || stack.mStackId == FULLSCREEN_WORKSPACE_STACK_ID) {
1208 return null;
1209 }
1210 return mLastNonFullscreenBounds;
1211 }
1212
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001213 void dump(PrintWriter pw, String prefix) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001214 pw.print(prefix); pw.print("userId="); pw.print(userId);
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001215 pw.print(" effectiveUid="); UserHandle.formatUid(pw, effectiveUid);
1216 pw.print(" mCallingUid="); UserHandle.formatUid(pw, mCallingUid);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001217 pw.print(" mCallingPackage="); pw.println(mCallingPackage);
Dianne Hackborn79228822014-09-16 11:11:23 -07001218 if (affinity != null || rootAffinity != null) {
1219 pw.print(prefix); pw.print("affinity="); pw.print(affinity);
1220 if (affinity == null || !affinity.equals(rootAffinity)) {
1221 pw.print(" root="); pw.println(rootAffinity);
1222 } else {
1223 pw.println();
1224 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001225 }
Dianne Hackborn91097de2014-04-04 18:02:06 -07001226 if (voiceSession != null || voiceInteractor != null) {
1227 pw.print(prefix); pw.print("VOICE: session=0x");
1228 pw.print(Integer.toHexString(System.identityHashCode(voiceSession)));
1229 pw.print(" interactor=0x");
1230 pw.println(Integer.toHexString(System.identityHashCode(voiceInteractor)));
1231 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001232 if (intent != null) {
1233 StringBuilder sb = new StringBuilder(128);
1234 sb.append(prefix); sb.append("intent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08001235 intent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001236 sb.append('}');
1237 pw.println(sb.toString());
1238 }
1239 if (affinityIntent != null) {
1240 StringBuilder sb = new StringBuilder(128);
1241 sb.append(prefix); sb.append("affinityIntent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08001242 affinityIntent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001243 sb.append('}');
1244 pw.println(sb.toString());
1245 }
1246 if (origActivity != null) {
1247 pw.print(prefix); pw.print("origActivity=");
1248 pw.println(origActivity.flattenToShortString());
1249 }
1250 if (realActivity != null) {
1251 pw.print(prefix); pw.print("realActivity=");
1252 pw.println(realActivity.flattenToShortString());
1253 }
Dianne Hackborn852975d2014-08-22 17:42:43 -07001254 if (autoRemoveRecents || isPersistable || taskType != 0 || mTaskToReturnTo != 0
1255 || numFullscreen != 0) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001256 pw.print(prefix); pw.print("autoRemoveRecents="); pw.print(autoRemoveRecents);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001257 pw.print(" isPersistable="); pw.print(isPersistable);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001258 pw.print(" numFullscreen="); pw.print(numFullscreen);
1259 pw.print(" taskType="); pw.print(taskType);
1260 pw.print(" mTaskToReturnTo="); pw.println(mTaskToReturnTo);
1261 }
Craig Mautner432f64e2015-05-20 14:59:57 -07001262 if (rootWasReset || mNeverRelinquishIdentity || mReuseTask
1263 || mLockTaskAuth != LOCK_TASK_AUTH_PINNABLE) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001264 pw.print(prefix); pw.print("rootWasReset="); pw.print(rootWasReset);
1265 pw.print(" mNeverRelinquishIdentity="); pw.print(mNeverRelinquishIdentity);
Craig Mautner432f64e2015-05-20 14:59:57 -07001266 pw.print(" mReuseTask="); pw.print(mReuseTask);
1267 pw.print(" mLockTaskAuth="); pw.println(lockTaskAuthToString());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001268 }
Wale Ogunwale18795a22014-12-03 11:38:33 -08001269 if (mAffiliatedTaskId != taskId || mPrevAffiliateTaskId != INVALID_TASK_ID
1270 || mPrevAffiliate != null || mNextAffiliateTaskId != INVALID_TASK_ID
1271 || mNextAffiliate != null) {
Dianne Hackborn852975d2014-08-22 17:42:43 -07001272 pw.print(prefix); pw.print("affiliation="); pw.print(mAffiliatedTaskId);
1273 pw.print(" prevAffiliation="); pw.print(mPrevAffiliateTaskId);
1274 pw.print(" (");
1275 if (mPrevAffiliate == null) {
1276 pw.print("null");
1277 } else {
1278 pw.print(Integer.toHexString(System.identityHashCode(mPrevAffiliate)));
1279 }
1280 pw.print(") nextAffiliation="); pw.print(mNextAffiliateTaskId);
1281 pw.print(" (");
1282 if (mNextAffiliate == null) {
1283 pw.print("null");
1284 } else {
1285 pw.print(Integer.toHexString(System.identityHashCode(mNextAffiliate)));
1286 }
1287 pw.println(")");
1288 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001289 pw.print(prefix); pw.print("Activities="); pw.println(mActivities);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001290 if (!askedCompatMode || !inRecents || !isAvailable) {
1291 pw.print(prefix); pw.print("askedCompatMode="); pw.print(askedCompatMode);
1292 pw.print(" inRecents="); pw.print(inRecents);
1293 pw.print(" isAvailable="); pw.println(isAvailable);
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001294 }
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001295 pw.print(prefix); pw.print("lastThumbnail="); pw.print(mLastThumbnail);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001296 pw.print(" lastThumbnailFile="); pw.println(mLastThumbnailFile);
1297 if (lastDescription != null) {
1298 pw.print(prefix); pw.print("lastDescription="); pw.println(lastDescription);
1299 }
Wale Ogunwale069fbe42015-07-29 11:38:01 -07001300 if (stack != null) {
1301 pw.print(prefix); pw.print("stackId="); pw.println(stack.mStackId);
1302 }
Dianne Hackbornd38aed82014-06-10 21:36:35 -07001303 pw.print(prefix); pw.print("hasBeenVisible="); pw.print(hasBeenVisible);
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -08001304 pw.print(" mResizeable="); pw.print(mResizeable);
Winson Chungffa2ec62014-07-03 15:54:42 -07001305 pw.print(" firstActiveTime="); pw.print(lastActiveTime);
Dianne Hackbornd38aed82014-06-10 21:36:35 -07001306 pw.print(" lastActiveTime="); pw.print(lastActiveTime);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001307 pw.print(" (inactive for ");
1308 pw.print((getInactiveDuration()/1000)); pw.println("s)");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001309 }
1310
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001311 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001312 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001313 StringBuilder sb = new StringBuilder(128);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001314 if (stringName != null) {
1315 sb.append(stringName);
1316 sb.append(" U=");
1317 sb.append(userId);
1318 sb.append(" sz=");
1319 sb.append(mActivities.size());
1320 sb.append('}');
1321 return sb.toString();
1322 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001323 sb.append("TaskRecord{");
1324 sb.append(Integer.toHexString(System.identityHashCode(this)));
1325 sb.append(" #");
1326 sb.append(taskId);
1327 if (affinity != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001328 sb.append(" A=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001329 sb.append(affinity);
1330 } else if (intent != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001331 sb.append(" I=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001332 sb.append(intent.getComponent().flattenToShortString());
1333 } else if (affinityIntent != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001334 sb.append(" aI=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001335 sb.append(affinityIntent.getComponent().flattenToShortString());
1336 } else {
1337 sb.append(" ??");
1338 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07001339 stringName = sb.toString();
1340 return toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001341 }
1342}