blob: 78f9f181bae03c060b2811956a6b58cf7daa1e99 [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 Ogunwale843bfb92015-03-27 11:06:48 -070019import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
20import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
Craig Mautner15df08a2015-04-01 12:17:18 -070021import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
22import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
23import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
24import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER;
Wale Ogunwalea7afaa22015-05-01 20:39:18 -070025import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
Wale Ogunwaleee006da2015-03-30 14:49:25 -070026import static com.android.server.am.ActivityManagerDebugConfig.*;
Craig Mautner84984fa2014-06-19 11:19:20 -070027import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
28import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
29import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
Craig Mautnerde4ef022013-04-07 19:01:33 -070030
Craig Mautnerb0f7dc72013-04-01 16:34:45 -070031import android.app.Activity;
Craig Mautner9db9a0b2013-04-29 17:05:56 -070032import android.app.ActivityManager;
Craig Mautnerc0ffce52014-07-01 12:38:52 -070033import android.app.ActivityManager.TaskThumbnail;
Craig Mautner648f69b2014-09-18 14:16:26 -070034import android.app.ActivityManager.TaskDescription;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -070035import android.app.ActivityOptions;
Dianne Hackborn885fbe52014-08-23 15:23:58 -070036import android.app.AppGlobals;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037import android.content.ComponentName;
38import android.content.Intent;
39import android.content.pm.ActivityInfo;
Dianne Hackborn885fbe52014-08-23 15:23:58 -070040import android.content.pm.ApplicationInfo;
41import android.content.pm.IPackageManager;
42import android.content.pm.PackageManager;
Craig Mautner9db9a0b2013-04-29 17:05:56 -070043import android.graphics.Bitmap;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -070044import android.os.Debug;
Craig Mautnerc0ffce52014-07-01 12:38:52 -070045import android.os.ParcelFileDescriptor;
Dianne Hackborn885fbe52014-08-23 15:23:58 -070046import android.os.RemoteException;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070047import android.os.UserHandle;
Dianne Hackborn91097de2014-04-04 18:02:06 -070048import android.service.voice.IVoiceInteractionSession;
Dianne Hackborn7f96b792012-05-29 18:46:45 -070049import android.util.Slog;
Dianne Hackborn91097de2014-04-04 18:02:06 -070050import com.android.internal.app.IVoiceInteractor;
Craig Mautner21d24a22014-04-23 11:45:37 -070051import com.android.internal.util.XmlUtils;
52import org.xmlpull.v1.XmlPullParser;
53import org.xmlpull.v1.XmlPullParserException;
54import org.xmlpull.v1.XmlSerializer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055
Craig Mautnerc0ffce52014-07-01 12:38:52 -070056import java.io.File;
Craig Mautner21d24a22014-04-23 11:45:37 -070057import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058import java.io.PrintWriter;
Craig Mautner5d9c7be2013-02-15 14:02:56 -080059import java.util.ArrayList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060
Craig Mautnerc0ffce52014-07-01 12:38:52 -070061final class TaskRecord {
Wale Ogunwalee23149f2015-03-06 15:39:44 -080062 private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskRecord" : TAG_AM;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -070063 private static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE;
Wale Ogunwaleee006da2015-03-30 14:49:25 -070064 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
Craig Mautnere0570202015-05-13 13:06:11 -070065 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwaleee006da2015-03-30 14:49:25 -070066 private static final String TAG_TASKS = TAG + POSTFIX_TASKS;
Wale Ogunwalee23149f2015-03-06 15:39:44 -080067
Wale Ogunwale18795a22014-12-03 11:38:33 -080068 static final String ATTR_TASKID = "task_id";
Craig Mautner21d24a22014-04-23 11:45:37 -070069 private static final String TAG_INTENT = "intent";
70 private static final String TAG_AFFINITYINTENT = "affinity_intent";
Wale Ogunwale18795a22014-12-03 11:38:33 -080071 static final String ATTR_REALACTIVITY = "real_activity";
Craig Mautner21d24a22014-04-23 11:45:37 -070072 private static final String ATTR_ORIGACTIVITY = "orig_activity";
Stefan Kuhnee88d1e52015-05-18 10:33:45 -070073 private static final String TAG_ACTIVITY = "activity";
Craig Mautner21d24a22014-04-23 11:45:37 -070074 private static final String ATTR_AFFINITY = "affinity";
Dianne Hackborn79228822014-09-16 11:11:23 -070075 private static final String ATTR_ROOT_AFFINITY = "root_affinity";
Craig Mautner21d24a22014-04-23 11:45:37 -070076 private static final String ATTR_ROOTHASRESET = "root_has_reset";
Dianne Hackborn13420f22014-07-18 15:43:56 -070077 private static final String ATTR_AUTOREMOVERECENTS = "auto_remove_recents";
Craig Mautner21d24a22014-04-23 11:45:37 -070078 private static final String ATTR_ASKEDCOMPATMODE = "asked_compat_mode";
79 private static final String ATTR_USERID = "user_id";
Dianne Hackborn885fbe52014-08-23 15:23:58 -070080 private static final String ATTR_EFFECTIVE_UID = "effective_uid";
Craig Mautner21d24a22014-04-23 11:45:37 -070081 private static final String ATTR_TASKTYPE = "task_type";
Winson Chungffa2ec62014-07-03 15:54:42 -070082 private static final String ATTR_FIRSTACTIVETIME = "first_active_time";
Winson Chungf1fbd772014-06-24 18:06:58 -070083 private static final String ATTR_LASTACTIVETIME = "last_active_time";
Craig Mautner21d24a22014-04-23 11:45:37 -070084 private static final String ATTR_LASTDESCRIPTION = "last_description";
85 private static final String ATTR_LASTTIMEMOVED = "last_time_moved";
Craig Mautner9d4e9bc2014-06-18 18:34:56 -070086 private static final String ATTR_NEVERRELINQUISH = "never_relinquish_identity";
Wale Ogunwale18795a22014-12-03 11:38:33 -080087 static final String ATTR_TASK_AFFILIATION = "task_affiliation";
Craig Mautnera228ae92014-07-09 05:44:55 -070088 private static final String ATTR_PREV_AFFILIATION = "prev_affiliation";
89 private static final String ATTR_NEXT_AFFILIATION = "next_affiliation";
Winson Chungec396d62014-08-06 17:08:00 -070090 private static final String ATTR_TASK_AFFILIATION_COLOR = "task_affiliation_color";
Craig Mautnerdc00cbe2014-07-20 17:48:47 -070091 private static final String ATTR_CALLING_UID = "calling_uid";
92 private static final String ATTR_CALLING_PACKAGE = "calling_package";
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -080093 private static final String ATTR_RESIZEABLE = "resizeable";
Wale Ogunwalea7afaa22015-05-01 20:39:18 -070094 private static final String ATTR_PRIVILEGED = "privileged";
Craig Mautner21d24a22014-04-23 11:45:37 -070095
96 private static final String TASK_THUMBNAIL_SUFFIX = "_task_thumbnail";
97
Craig Mautner0b633fc2014-07-23 10:42:18 -070098 static final boolean IGNORE_RETURN_TO_RECENTS = true;
99
Wale Ogunwale18795a22014-12-03 11:38:33 -0800100 static final int INVALID_TASK_ID = -1;
101
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102 final int taskId; // Unique identifier for this task.
Dianne Hackborn79228822014-09-16 11:11:23 -0700103 String affinity; // The affinity name for this task, or null; may change identity.
104 String rootAffinity; // Initial base affinity, or null; does not change from initial root.
Dianne Hackborn91097de2014-04-04 18:02:06 -0700105 final IVoiceInteractionSession voiceSession; // Voice interaction session driving task
106 final IVoiceInteractor voiceInteractor; // Associated interactor to provide to app
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107 Intent intent; // The original intent that started the task.
108 Intent affinityIntent; // Intent of affinity-moved activity that started this task.
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700109 int effectiveUid; // The current effective uid of the identity of this task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110 ComponentName origActivity; // The non-alias activity component of the intent.
111 ComponentName realActivity; // The actual activity component that started the task.
Winson Chungffa2ec62014-07-03 15:54:42 -0700112 long firstActiveTime; // First time this task was active.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113 long lastActiveTime; // Last time this task was active, including sleep.
Dianne Hackborn852975d2014-08-22 17:42:43 -0700114 boolean inRecents; // Actually in the recents list?
115 boolean isAvailable; // Is the activity available to be launched?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116 boolean rootWasReset; // True if the intent at the root of the task had
117 // the FLAG_ACTIVITY_RESET_TASK_IF_NEEDED flag.
Dianne Hackborn13420f22014-07-18 15:43:56 -0700118 boolean autoRemoveRecents; // If true, we should automatically remove the task from
119 // recents when activity finishes
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700120 boolean askedCompatMode;// Have asked the user about compat mode for this task.
Dianne Hackbornd38aed82014-06-10 21:36:35 -0700121 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 -0800122
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700123 String stringName; // caching of toString() result.
Dianne Hackborn9da2d402012-03-15 13:43:08 -0700124 int userId; // user for which this task was created
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800125
126 int numFullscreen; // Number of fullscreen activities.
127
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800128 boolean mResizeable; // Activities in the task resizeable. Based on the resizable setting of
129 // the root activity.
Craig Mautner15df08a2015-04-01 12:17:18 -0700130 int mLockTaskMode; // Which tasklock mode to launch this task in. One of
131 // ActivityManager.LOCK_TASK_LAUNCH_MODE_*
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700132 private boolean mPrivileged; // The root activity application of this task holds
133 // privileged permissions.
134
Craig Mautner15df08a2015-04-01 12:17:18 -0700135 /** Can't be put in lockTask mode. */
136 final static int LOCK_TASK_AUTH_DONT_LOCK = 0;
Benjamin Franz469dd582015-06-09 14:24:36 +0100137 /** Can enter app pinning with user approval. Can never start over existing lockTask task. */
Craig Mautner15df08a2015-04-01 12:17:18 -0700138 final static int LOCK_TASK_AUTH_PINNABLE = 1;
139 /** Starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing lockTask task. */
140 final static int LOCK_TASK_AUTH_LAUNCHABLE = 2;
Benjamin Franz469dd582015-06-09 14:24:36 +0100141 /** Can enter lockTask without user approval. Can start over existing lockTask task. */
Craig Mautner15df08a2015-04-01 12:17:18 -0700142 final static int LOCK_TASK_AUTH_WHITELISTED = 3;
Benjamin Franz469dd582015-06-09 14:24:36 +0100143 /** Priv-app that starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing
144 * lockTask task. */
145 final static int LOCK_TASK_AUTH_LAUNCHABLE_PRIV = 4;
Craig Mautner15df08a2015-04-01 12:17:18 -0700146 int mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE;
147
148 int mLockTaskUid = -1; // The uid of the application that called startLockTask().
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800149
Winson Chung03a9bae2014-05-02 09:56:12 -0700150 // This represents the last resolved activity values for this task
151 // NOTE: This value needs to be persisted with each task
Craig Mautner648f69b2014-09-18 14:16:26 -0700152 TaskDescription lastTaskDescription = new TaskDescription();
Winson Chung03a9bae2014-05-02 09:56:12 -0700153
Craig Mautnerd2328952013-03-05 12:46:26 -0800154 /** List of all activities in the task arranged in history order */
Craig Mautner21d24a22014-04-23 11:45:37 -0700155 final ArrayList<ActivityRecord> mActivities;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800156
Craig Mautnerd2328952013-03-05 12:46:26 -0800157 /** Current stack */
158 ActivityStack stack;
159
Craig Mautner2c1faed2013-07-23 12:56:02 -0700160 /** Takes on same set of values as ActivityRecord.mActivityType */
Craig Mautner21d24a22014-04-23 11:45:37 -0700161 int taskType;
Craig Mautner1602ec22013-05-12 10:24:27 -0700162
Craig Mautner21d24a22014-04-23 11:45:37 -0700163 /** Takes on same value as first root activity */
164 boolean isPersistable = false;
Craig Mautnerffcfcaa2014-06-05 09:54:38 -0700165 int maxRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700166
167 /** Only used for persistable tasks, otherwise 0. The last time this task was moved. Used for
168 * determining the order when restoring. Sign indicates whether last task movement was to front
169 * (positive) or back (negative). Absolute value indicates time. */
170 long mLastTimeMoved = System.currentTimeMillis();
171
Craig Mautner84984fa2014-06-19 11:19:20 -0700172 /** Indication of what to run next when task exits. Use ActivityRecord types.
173 * ActivityRecord.APPLICATION_ACTIVITY_TYPE indicates to resume the task below this one in the
174 * task stack. */
175 private int mTaskToReturnTo = APPLICATION_ACTIVITY_TYPE;
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700176
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700177 /** If original intent did not allow relinquishing task identity, save that information */
178 boolean mNeverRelinquishIdentity = true;
179
Craig Mautner362449a2014-06-20 14:04:39 -0700180 // Used in the unique case where we are clearing the task in order to reuse it. In that case we
181 // do not want to delete the stack when the task goes empty.
182 boolean mReuseTask = false;
183
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700184 private Bitmap mLastThumbnail; // Last thumbnail captured for this item.
Wale Ogunwalebe23ff42014-10-21 16:29:51 -0700185 private final File mLastThumbnailFile; // File containing last thumbnail.
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700186 private final String mFilename;
187 CharSequence lastDescription; // Last description captured for this item.
188
Craig Mautnera228ae92014-07-09 05:44:55 -0700189 int mAffiliatedTaskId; // taskId of parent affiliation or self if no parent.
Winson Chungec396d62014-08-06 17:08:00 -0700190 int mAffiliatedTaskColor; // color of the parent task affiliation.
Craig Mautnera228ae92014-07-09 05:44:55 -0700191 TaskRecord mPrevAffiliate; // previous task in affiliated chain.
Wale Ogunwale18795a22014-12-03 11:38:33 -0800192 int mPrevAffiliateTaskId = INVALID_TASK_ID; // previous id for persistence.
Craig Mautnera228ae92014-07-09 05:44:55 -0700193 TaskRecord mNextAffiliate; // next task in affiliated chain.
Wale Ogunwale18795a22014-12-03 11:38:33 -0800194 int mNextAffiliateTaskId = INVALID_TASK_ID; // next id for persistence.
Craig Mautnera228ae92014-07-09 05:44:55 -0700195
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700196 // For relaunching the task from recents as though it was launched by the original launcher.
197 int mCallingUid;
198 String mCallingPackage;
199
Craig Mautner21d24a22014-04-23 11:45:37 -0700200 final ActivityManagerService mService;
201
202 TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Dianne Hackborn91097de2014-04-04 18:02:06 -0700203 IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700204 mService = service;
Craig Mautnera228ae92014-07-09 05:44:55 -0700205 mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
206 TaskPersister.IMAGE_EXTENSION;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700207 mLastThumbnailFile = new File(TaskPersister.sImagesDir, mFilename);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800208 taskId = _taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700209 mAffiliatedTaskId = _taskId;
Dianne Hackborn91097de2014-04-04 18:02:06 -0700210 voiceSession = _voiceSession;
211 voiceInteractor = _voiceInteractor;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700212 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800213 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700214 mCallingUid = info.applicationInfo.uid;
215 mCallingPackage = info.packageName;
Martijn Coenend4a69702014-06-30 11:12:17 -0700216 setIntent(_intent, info);
Craig Mautner21d24a22014-04-23 11:45:37 -0700217 }
218
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700219 TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Craig Mautner648f69b2014-09-18 14:16:26 -0700220 TaskDescription _taskDescription) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700221 mService = service;
222 mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
223 TaskPersister.IMAGE_EXTENSION;
224 mLastThumbnailFile = new File(TaskPersister.sImagesDir, mFilename);
225 taskId = _taskId;
226 mAffiliatedTaskId = _taskId;
227 voiceSession = null;
228 voiceInteractor = null;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700229 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800230 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700231 mCallingUid = info.applicationInfo.uid;
232 mCallingPackage = info.packageName;
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700233 setIntent(_intent, info);
234
235 taskType = ActivityRecord.APPLICATION_ACTIVITY_TYPE;
236 isPersistable = true;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700237 // Clamp to [1, max].
238 maxRecents = Math.min(Math.max(info.maxRecents, 1),
239 ActivityManager.getMaxAppRecentsLimitStatic());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700240
241 taskType = APPLICATION_ACTIVITY_TYPE;
242 mTaskToReturnTo = HOME_ACTIVITY_TYPE;
243 userId = UserHandle.getUserId(info.applicationInfo.uid);
244 lastTaskDescription = _taskDescription;
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700245 }
246
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800247 private TaskRecord(ActivityManagerService service, int _taskId, Intent _intent,
248 Intent _affinityIntent, String _affinity, String _rootAffinity,
249 ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset,
250 boolean _autoRemoveRecents, boolean _askedCompatMode, int _taskType, int _userId,
251 int _effectiveUid, String _lastDescription, ArrayList<ActivityRecord> activities,
252 long _firstActiveTime, long _lastActiveTime, long lastTimeMoved,
253 boolean neverRelinquishIdentity, TaskDescription _lastTaskDescription,
254 int taskAffiliation, int prevTaskId, int nextTaskId, int taskAffiliationColor,
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700255 int callingUid, String callingPackage, boolean resizeable, boolean privileged) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700256 mService = service;
Craig Mautnera228ae92014-07-09 05:44:55 -0700257 mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
258 TaskPersister.IMAGE_EXTENSION;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700259 mLastThumbnailFile = new File(TaskPersister.sImagesDir, mFilename);
Craig Mautner21d24a22014-04-23 11:45:37 -0700260 taskId = _taskId;
261 intent = _intent;
262 affinityIntent = _affinityIntent;
263 affinity = _affinity;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800264 rootAffinity = _rootAffinity;
Craig Mautner21d24a22014-04-23 11:45:37 -0700265 voiceSession = null;
266 voiceInteractor = null;
267 realActivity = _realActivity;
268 origActivity = _origActivity;
269 rootWasReset = _rootWasReset;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700270 isAvailable = true;
Dianne Hackborn13420f22014-07-18 15:43:56 -0700271 autoRemoveRecents = _autoRemoveRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700272 askedCompatMode = _askedCompatMode;
273 taskType = _taskType;
Craig Mautner84984fa2014-06-19 11:19:20 -0700274 mTaskToReturnTo = HOME_ACTIVITY_TYPE;
Craig Mautner21d24a22014-04-23 11:45:37 -0700275 userId = _userId;
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700276 effectiveUid = _effectiveUid;
Winson Chungffa2ec62014-07-03 15:54:42 -0700277 firstActiveTime = _firstActiveTime;
Winson Chungf1fbd772014-06-24 18:06:58 -0700278 lastActiveTime = _lastActiveTime;
Craig Mautner21d24a22014-04-23 11:45:37 -0700279 lastDescription = _lastDescription;
280 mActivities = activities;
281 mLastTimeMoved = lastTimeMoved;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700282 mNeverRelinquishIdentity = neverRelinquishIdentity;
Winson Chung2cb86c72014-06-25 12:03:30 -0700283 lastTaskDescription = _lastTaskDescription;
Craig Mautnera228ae92014-07-09 05:44:55 -0700284 mAffiliatedTaskId = taskAffiliation;
Winson Chungec396d62014-08-06 17:08:00 -0700285 mAffiliatedTaskColor = taskAffiliationColor;
Craig Mautnera228ae92014-07-09 05:44:55 -0700286 mPrevAffiliateTaskId = prevTaskId;
287 mNextAffiliateTaskId = nextTaskId;
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700288 mCallingUid = callingUid;
289 mCallingPackage = callingPackage;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800290 mResizeable = resizeable;
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700291 mPrivileged = privileged;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800292 }
293
294 void touchActiveTime() {
Craig Mautner494f6bdd2014-07-21 11:17:46 -0700295 lastActiveTime = System.currentTimeMillis();
Winson Chungffa2ec62014-07-03 15:54:42 -0700296 if (firstActiveTime == 0) {
297 firstActiveTime = lastActiveTime;
298 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800299 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700300
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800301 long getInactiveDuration() {
Craig Mautner494f6bdd2014-07-21 11:17:46 -0700302 return System.currentTimeMillis() - lastActiveTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800303 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700304
Winson Chungfee26772014-08-05 12:21:52 -0700305 /** Sets the original intent, and the calling uid and package. */
306 void setIntent(ActivityRecord r) {
Winson Chungfee26772014-08-05 12:21:52 -0700307 mCallingUid = r.launchedFromUid;
308 mCallingPackage = r.launchedFromPackage;
Craig Mautner15df08a2015-04-01 12:17:18 -0700309 setIntent(r.intent, r.info);
Winson Chungfee26772014-08-05 12:21:52 -0700310 }
311
312 /** Sets the original intent, _without_ updating the calling uid or package. */
313 private void setIntent(Intent _intent, ActivityInfo info) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700314 if (intent == null) {
315 mNeverRelinquishIdentity =
316 (info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) == 0;
317 } else if (mNeverRelinquishIdentity) {
318 return;
319 }
320
321 affinity = info.taskAffinity;
Dianne Hackborn79228822014-09-16 11:11:23 -0700322 if (intent == null) {
323 // If this task already has an intent associated with it, don't set the root
324 // affinity -- we don't want it changing after initially set, but the initially
325 // set value may be null.
326 rootAffinity = affinity;
327 }
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700328 effectiveUid = info.applicationInfo.uid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700329 stringName = null;
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800330
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800331 if (info.targetActivity == null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800332 if (_intent != null) {
333 // If this Intent has a selector, we want to clear it for the
334 // recent task since it is not relevant if the user later wants
335 // to re-launch the app.
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700336 if (_intent.getSelector() != null || _intent.getSourceBounds() != null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800337 _intent = new Intent(_intent);
338 _intent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700339 _intent.setSourceBounds(null);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800340 }
341 }
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700342 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Setting Intent of " + this + " to " + _intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800343 intent = _intent;
344 realActivity = _intent != null ? _intent.getComponent() : null;
345 origActivity = null;
346 } else {
347 ComponentName targetComponent = new ComponentName(
348 info.packageName, info.targetActivity);
349 if (_intent != null) {
350 Intent targetIntent = new Intent(_intent);
351 targetIntent.setComponent(targetComponent);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800352 targetIntent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700353 targetIntent.setSourceBounds(null);
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700354 if (DEBUG_TASKS) Slog.v(TAG_TASKS,
Dianne Hackborn7f96b792012-05-29 18:46:45 -0700355 "Setting Intent of " + this + " to target " + targetIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800356 intent = targetIntent;
357 realActivity = targetComponent;
358 origActivity = _intent.getComponent();
359 } else {
360 intent = null;
361 realActivity = targetComponent;
362 origActivity = new ComponentName(info.packageName, info.name);
363 }
364 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700365
Craig Mautner47b20ba2014-09-17 17:23:44 -0700366 final int intentFlags = intent == null ? 0 : intent.getFlags();
367 if ((intentFlags & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800368 // Once we are set to an Intent with this flag, we count this
369 // task as having a true root activity.
370 rootWasReset = true;
371 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700372
Dianne Hackborn09233282014-04-30 11:33:59 -0700373 userId = UserHandle.getUserId(info.applicationInfo.uid);
Craig Mautner41db4a72014-05-07 17:20:56 -0700374 if ((info.flags & ActivityInfo.FLAG_AUTO_REMOVE_FROM_RECENTS) != 0) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700375 // If the activity itself has requested auto-remove, then just always do it.
376 autoRemoveRecents = true;
Wale Ogunwale843bfb92015-03-27 11:06:48 -0700377 } else if ((intentFlags & (FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS))
378 == FLAG_ACTIVITY_NEW_DOCUMENT) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700379 // If the caller has not asked for the document to be retained, then we may
380 // want to turn on auto-remove, depending on whether the target has set its
381 // own document launch mode.
382 if (info.documentLaunchMode != ActivityInfo.DOCUMENT_LAUNCH_NONE) {
383 autoRemoveRecents = false;
384 } else {
385 autoRemoveRecents = true;
386 }
387 } else {
388 autoRemoveRecents = false;
Craig Mautner41db4a72014-05-07 17:20:56 -0700389 }
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800390 mResizeable = info.resizeable;
Craig Mautner15df08a2015-04-01 12:17:18 -0700391 mLockTaskMode = info.lockTaskLaunchMode;
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700392 mPrivileged = (info.applicationInfo.privateFlags & PRIVATE_FLAG_PRIVILEGED) != 0;
Craig Mautner15df08a2015-04-01 12:17:18 -0700393 setLockTaskAuth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800394 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800395
Craig Mautner84984fa2014-06-19 11:19:20 -0700396 void setTaskToReturnTo(int taskToReturnTo) {
Wale Ogunwale2d0f39b2015-04-17 15:35:39 -0700397 mTaskToReturnTo = (IGNORE_RETURN_TO_RECENTS && taskToReturnTo == RECENTS_ACTIVITY_TYPE)
398 ? HOME_ACTIVITY_TYPE : taskToReturnTo;
Craig Mautner84984fa2014-06-19 11:19:20 -0700399 }
400
401 int getTaskToReturnTo() {
402 return mTaskToReturnTo;
403 }
404
Craig Mautnera228ae92014-07-09 05:44:55 -0700405 void setPrevAffiliate(TaskRecord prevAffiliate) {
406 mPrevAffiliate = prevAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800407 mPrevAffiliateTaskId = prevAffiliate == null ? INVALID_TASK_ID : prevAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700408 }
409
410 void setNextAffiliate(TaskRecord nextAffiliate) {
411 mNextAffiliate = nextAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800412 mNextAffiliateTaskId = nextAffiliate == null ? INVALID_TASK_ID : nextAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700413 }
414
415 // Close up recents linked list.
416 void closeRecentsChain() {
417 if (mPrevAffiliate != null) {
418 mPrevAffiliate.setNextAffiliate(mNextAffiliate);
419 }
420 if (mNextAffiliate != null) {
421 mNextAffiliate.setPrevAffiliate(mPrevAffiliate);
422 }
423 setPrevAffiliate(null);
424 setNextAffiliate(null);
425 }
426
Winson Chung740c3ac2014-11-12 16:14:38 -0800427 void removedFromRecents() {
Dianne Hackborn852975d2014-08-22 17:42:43 -0700428 disposeThumbnail();
429 closeRecentsChain();
430 if (inRecents) {
431 inRecents = false;
Winson Chung740c3ac2014-11-12 16:14:38 -0800432 mService.notifyTaskPersisterLocked(this, false);
Dianne Hackborn852975d2014-08-22 17:42:43 -0700433 }
434 }
435
Craig Mautnera228ae92014-07-09 05:44:55 -0700436 void setTaskToAffiliateWith(TaskRecord taskToAffiliateWith) {
437 closeRecentsChain();
438 mAffiliatedTaskId = taskToAffiliateWith.mAffiliatedTaskId;
Winson Chungec396d62014-08-06 17:08:00 -0700439 mAffiliatedTaskColor = taskToAffiliateWith.mAffiliatedTaskColor;
Craig Mautnera228ae92014-07-09 05:44:55 -0700440 // Find the end
441 while (taskToAffiliateWith.mNextAffiliate != null) {
442 final TaskRecord nextRecents = taskToAffiliateWith.mNextAffiliate;
443 if (nextRecents.mAffiliatedTaskId != mAffiliatedTaskId) {
444 Slog.e(TAG, "setTaskToAffiliateWith: nextRecents=" + nextRecents + " affilTaskId="
445 + nextRecents.mAffiliatedTaskId + " should be " + mAffiliatedTaskId);
446 if (nextRecents.mPrevAffiliate == taskToAffiliateWith) {
447 nextRecents.setPrevAffiliate(null);
448 }
449 taskToAffiliateWith.setNextAffiliate(null);
450 break;
451 }
452 taskToAffiliateWith = nextRecents;
453 }
454 taskToAffiliateWith.setNextAffiliate(this);
455 setPrevAffiliate(taskToAffiliateWith);
456 setNextAffiliate(null);
457 }
458
Winson Chung096f36b2014-08-20 15:39:01 -0700459 /**
460 * Sets the last thumbnail.
461 * @return whether the thumbnail was set
462 */
463 boolean setLastThumbnail(Bitmap thumbnail) {
464 if (mLastThumbnail != thumbnail) {
465 mLastThumbnail = thumbnail;
466 if (thumbnail == null) {
467 if (mLastThumbnailFile != null) {
468 mLastThumbnailFile.delete();
469 }
470 } else {
471 mService.mTaskPersister.saveImage(thumbnail, mFilename);
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700472 }
Winson Chung096f36b2014-08-20 15:39:01 -0700473 return true;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700474 }
Winson Chung096f36b2014-08-20 15:39:01 -0700475 return false;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700476 }
477
478 void getLastThumbnail(TaskThumbnail thumbs) {
479 thumbs.mainThumbnail = mLastThumbnail;
480 thumbs.thumbnailFileDescriptor = null;
Craig Mautnerf4f8bb72014-07-29 10:41:40 -0700481 if (mLastThumbnail == null) {
Craig Mautner648f69b2014-09-18 14:16:26 -0700482 thumbs.mainThumbnail = mService.mTaskPersister.getImageFromWriteQueue(mFilename);
Craig Mautnerf4f8bb72014-07-29 10:41:40 -0700483 }
Winson Chung096f36b2014-08-20 15:39:01 -0700484 // Only load the thumbnail file if we don't have a thumbnail
485 if (thumbs.mainThumbnail == null && mLastThumbnailFile.exists()) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700486 try {
487 thumbs.thumbnailFileDescriptor = ParcelFileDescriptor.open(mLastThumbnailFile,
488 ParcelFileDescriptor.MODE_READ_ONLY);
489 } catch (IOException e) {
Dianne Hackborn9844d292013-10-04 16:44:22 -0700490 }
491 }
492 }
493
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700494 void freeLastThumbnail() {
495 mLastThumbnail = null;
496 }
497
498 void disposeThumbnail() {
499 mLastThumbnail = null;
500 lastDescription = null;
501 }
502
Winson Chung1147c402014-05-14 11:05:00 -0700503 /** Returns the intent for the root activity for this task */
504 Intent getBaseIntent() {
505 return intent != null ? intent : affinityIntent;
506 }
507
Winson Chung3b3f4642014-04-22 10:08:18 -0700508 /** Returns the first non-finishing activity from the root. */
509 ActivityRecord getRootActivity() {
510 for (int i = 0; i < mActivities.size(); i++) {
511 final ActivityRecord r = mActivities.get(i);
512 if (r.finishing) {
513 continue;
514 }
515 return r;
516 }
517 return null;
518 }
519
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800520 ActivityRecord getTopActivity() {
521 for (int i = mActivities.size() - 1; i >= 0; --i) {
522 final ActivityRecord r = mActivities.get(i);
523 if (r.finishing) {
524 continue;
525 }
526 return r;
527 }
528 return null;
529 }
530
Craig Mautner6b74cb52013-09-27 17:02:21 -0700531 ActivityRecord topRunningActivityLocked(ActivityRecord notTop) {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700532 if (stack != null) {
533 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
534 ActivityRecord r = mActivities.get(activityNdx);
535 if (!r.finishing && r != notTop && stack.okToShowLocked(r)) {
536 return r;
537 }
Craig Mautner6b74cb52013-09-27 17:02:21 -0700538 }
539 }
540 return null;
541 }
542
Craig Mautner3b475fe2013-12-16 15:58:31 -0800543 /** Call after activity movement or finish to make sure that frontOfTask is set correctly */
544 final void setFrontOfTask() {
545 boolean foundFront = false;
546 final int numActivities = mActivities.size();
Craig Mautner704e40b2013-12-18 16:43:51 -0800547 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
Craig Mautner3b475fe2013-12-16 15:58:31 -0800548 final ActivityRecord r = mActivities.get(activityNdx);
549 if (foundFront || r.finishing) {
550 r.frontOfTask = false;
551 } else {
552 r.frontOfTask = true;
553 // Set frontOfTask false for every following activity.
554 foundFront = true;
555 }
556 }
Craig Mautner9587ee02014-06-23 15:00:10 +0000557 if (!foundFront && numActivities > 0) {
558 // All activities of this task are finishing. As we ought to have a frontOfTask
559 // activity, make the bottom activity front.
560 mActivities.get(0).frontOfTask = true;
561 }
Craig Mautner3b475fe2013-12-16 15:58:31 -0800562 }
563
Craig Mautnerde4ef022013-04-07 19:01:33 -0700564 /**
Craig Mautner3b475fe2013-12-16 15:58:31 -0800565 * Reorder the history stack so that the passed activity is brought to the front.
Craig Mautnerde4ef022013-04-07 19:01:33 -0700566 */
567 final void moveActivityToFrontLocked(ActivityRecord newTop) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -0700568 if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE,
569 "Removing and adding activity " + newTop
570 + " to stack at top callers=" + Debug.getCallers(4));
Craig Mautnerde4ef022013-04-07 19:01:33 -0700571
Craig Mautnerde4ef022013-04-07 19:01:33 -0700572 mActivities.remove(newTop);
573 mActivities.add(newTop);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700574 updateEffectiveIntent();
Craig Mautner3b475fe2013-12-16 15:58:31 -0800575
576 setFrontOfTask();
Craig Mautnerde4ef022013-04-07 19:01:33 -0700577 }
578
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800579 void addActivityAtBottom(ActivityRecord r) {
Craig Mautner77878772013-03-04 19:46:24 -0800580 addActivityAtIndex(0, r);
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800581 }
582
583 void addActivityToTop(ActivityRecord r) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700584 addActivityAtIndex(mActivities.size(), r);
585 }
586
587 void addActivityAtIndex(int index, ActivityRecord r) {
Craig Mautner6170f732013-04-02 13:05:23 -0700588 // 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 -0800589 if (!mActivities.remove(r) && r.fullscreen) {
590 // Was not previously in list.
591 numFullscreen++;
592 }
Craig Mautner2c1faed2013-07-23 12:56:02 -0700593 // Only set this based on the first activity
594 if (mActivities.isEmpty()) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700595 taskType = r.mActivityType;
596 isPersistable = r.isPersistable();
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700597 mCallingUid = r.launchedFromUid;
598 mCallingPackage = r.launchedFromPackage;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700599 // Clamp to [1, max].
600 maxRecents = Math.min(Math.max(r.info.maxRecents, 1),
601 ActivityManager.getMaxAppRecentsLimitStatic());
Craig Mautner2c1faed2013-07-23 12:56:02 -0700602 } else {
603 // Otherwise make all added activities match this one.
Craig Mautner21d24a22014-04-23 11:45:37 -0700604 r.mActivityType = taskType;
Craig Mautner78733002013-06-10 13:54:49 -0700605 }
Craig Mautner77878772013-03-04 19:46:24 -0800606 mActivities.add(index, r);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700607 updateEffectiveIntent();
Craig Mautner21d24a22014-04-23 11:45:37 -0700608 if (r.isPersistable()) {
609 mService.notifyTaskPersisterLocked(this, false);
610 }
Craig Mautner77878772013-03-04 19:46:24 -0800611 }
612
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800613 /** @return true if this was the last activity in the task */
614 boolean removeActivity(ActivityRecord r) {
615 if (mActivities.remove(r) && r.fullscreen) {
616 // Was previously in list.
617 numFullscreen--;
618 }
Craig Mautner21d24a22014-04-23 11:45:37 -0700619 if (r.isPersistable()) {
620 mService.notifyTaskPersisterLocked(this, false);
621 }
Craig Mautner41326202014-06-20 14:38:21 -0700622 if (mActivities.isEmpty()) {
Craig Mautner5afcd4d2014-06-21 18:11:33 -0700623 return !mReuseTask;
Craig Mautner41326202014-06-20 14:38:21 -0700624 }
625 updateEffectiveIntent();
626 return false;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800627 }
628
Craig Mautner41db4a72014-05-07 17:20:56 -0700629 boolean autoRemoveFromRecents() {
Dianne Hackbornd38aed82014-06-10 21:36:35 -0700630 // We will automatically remove the task either if it has explicitly asked for
631 // this, or it is empty and has never contained an activity that got shown to
632 // the user.
Dianne Hackborn13420f22014-07-18 15:43:56 -0700633 return autoRemoveRecents || (mActivities.isEmpty() && !hasBeenVisible);
Craig Mautner41db4a72014-05-07 17:20:56 -0700634 }
635
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700636 /**
637 * Completely remove all activities associated with an existing
638 * task starting at a specified index.
639 */
640 final void performClearTaskAtIndexLocked(int activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700641 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700642 for ( ; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700643 final ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700644 if (r.finishing) {
645 continue;
646 }
Craig Mautner21d24a22014-04-23 11:45:37 -0700647 if (stack == null) {
648 // Task was restored from persistent storage.
649 r.takeFromHistory();
650 mActivities.remove(activityNdx);
651 --activityNdx;
652 --numActivities;
Todd Kennedy539db512014-12-15 09:57:55 -0800653 } else if (stack.finishActivityLocked(
654 r, Activity.RESULT_CANCELED, null, "clear-task-index", false)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700655 --activityNdx;
656 --numActivities;
657 }
658 }
659 }
660
661 /**
662 * Completely remove all activities associated with an existing task.
663 */
664 final void performClearTaskLocked() {
Craig Mautner362449a2014-06-20 14:04:39 -0700665 mReuseTask = true;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700666 performClearTaskAtIndexLocked(0);
Craig Mautner362449a2014-06-20 14:04:39 -0700667 mReuseTask = false;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700668 }
669
670 /**
671 * Perform clear operation as requested by
672 * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the
673 * stack to the given task, then look for
674 * an instance of that activity in the stack and, if found, finish all
675 * activities on top of it and return the instance.
676 *
677 * @param newR Description of the new activity being started.
678 * @return Returns the old activity that should be continued to be used,
679 * or null if none was found.
680 */
681 final ActivityRecord performClearTaskLocked(ActivityRecord newR, int launchFlags) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700682 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700683 for (int activityNdx = numActivities - 1; activityNdx >= 0; --activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700684 ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700685 if (r.finishing) {
686 continue;
687 }
688 if (r.realActivity.equals(newR.realActivity)) {
689 // Here it is! Now finish everything in front...
Craig Mautner1602ec22013-05-12 10:24:27 -0700690 final ActivityRecord ret = r;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700691
692 for (++activityNdx; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700693 r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700694 if (r.finishing) {
695 continue;
696 }
697 ActivityOptions opts = r.takeOptionsLocked();
698 if (opts != null) {
699 ret.updateOptionsLocked(opts);
700 }
Wale Ogunwale7d701172015-03-11 15:36:30 -0700701 if (stack != null && stack.finishActivityLocked(
Todd Kennedy539db512014-12-15 09:57:55 -0800702 r, Activity.RESULT_CANCELED, null, "clear-task-stack", false)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700703 --activityNdx;
704 --numActivities;
705 }
706 }
707
708 // Finally, if this is a normal launch mode (that is, not
709 // expecting onNewIntent()), then we will finish the current
710 // instance of the activity so a new fresh one can be started.
711 if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE
712 && (launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0) {
713 if (!ret.finishing) {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700714 if (stack != null) {
715 stack.finishActivityLocked(
716 ret, Activity.RESULT_CANCELED, null, "clear-task-top", false);
717 }
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700718 return null;
719 }
720 }
721
722 return ret;
723 }
724 }
725
726 return null;
727 }
728
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700729 public TaskThumbnail getTaskThumbnailLocked() {
Craig Mautner21d24a22014-04-23 11:45:37 -0700730 if (stack != null) {
731 final ActivityRecord resumedActivity = stack.mResumedActivity;
732 if (resumedActivity != null && resumedActivity.task == this) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700733 final Bitmap thumbnail = stack.screenshotActivities(resumedActivity);
734 setLastThumbnail(thumbnail);
Craig Mautner21d24a22014-04-23 11:45:37 -0700735 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700736 }
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700737 final TaskThumbnail taskThumbnail = new TaskThumbnail();
738 getLastThumbnail(taskThumbnail);
739 return taskThumbnail;
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700740 }
741
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700742 public void removeTaskActivitiesLocked() {
743 // Just remove the entire task.
744 performClearTaskAtIndexLocked(0);
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700745 }
746
Craig Mautner432f64e2015-05-20 14:59:57 -0700747 String lockTaskAuthToString() {
748 switch (mLockTaskAuth) {
749 case LOCK_TASK_AUTH_DONT_LOCK: return "LOCK_TASK_AUTH_DONT_LOCK";
750 case LOCK_TASK_AUTH_PINNABLE: return "LOCK_TASK_AUTH_PINNABLE";
751 case LOCK_TASK_AUTH_LAUNCHABLE: return "LOCK_TASK_AUTH_LAUNCHABLE";
752 case LOCK_TASK_AUTH_WHITELISTED: return "LOCK_TASK_AUTH_WHITELISTED";
Benjamin Franz469dd582015-06-09 14:24:36 +0100753 case LOCK_TASK_AUTH_LAUNCHABLE_PRIV: return "LOCK_TASK_AUTH_LAUNCHABLE_PRIV";
Craig Mautner432f64e2015-05-20 14:59:57 -0700754 default: return "unknown=" + mLockTaskAuth;
755 }
756 }
757
Craig Mautner15df08a2015-04-01 12:17:18 -0700758 void setLockTaskAuth() {
Benjamin Franz469dd582015-06-09 14:24:36 +0100759 if (!mPrivileged &&
760 (mLockTaskMode == LOCK_TASK_LAUNCH_MODE_ALWAYS ||
761 mLockTaskMode == LOCK_TASK_LAUNCH_MODE_NEVER)) {
762 // Non-priv apps are not allowed to use always or never, fall back to default
763 mLockTaskMode = LOCK_TASK_LAUNCH_MODE_DEFAULT;
764 }
Craig Mautner15df08a2015-04-01 12:17:18 -0700765 switch (mLockTaskMode) {
766 case LOCK_TASK_LAUNCH_MODE_DEFAULT:
767 mLockTaskAuth = isLockTaskWhitelistedLocked() ?
768 LOCK_TASK_AUTH_WHITELISTED : LOCK_TASK_AUTH_PINNABLE;
769 break;
770
771 case LOCK_TASK_LAUNCH_MODE_NEVER:
Benjamin Franz469dd582015-06-09 14:24:36 +0100772 mLockTaskAuth = LOCK_TASK_AUTH_DONT_LOCK;
Craig Mautner15df08a2015-04-01 12:17:18 -0700773 break;
774
775 case LOCK_TASK_LAUNCH_MODE_ALWAYS:
Benjamin Franz469dd582015-06-09 14:24:36 +0100776 mLockTaskAuth = LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
Craig Mautner15df08a2015-04-01 12:17:18 -0700777 break;
778
779 case LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED:
780 mLockTaskAuth = isLockTaskWhitelistedLocked() ?
781 LOCK_TASK_AUTH_LAUNCHABLE : LOCK_TASK_AUTH_PINNABLE;
782 break;
783 }
Craig Mautner432f64e2015-05-20 14:59:57 -0700784 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
785 " mLockTaskAuth=" + lockTaskAuthToString());
Craig Mautner15df08a2015-04-01 12:17:18 -0700786 }
787
788 boolean isLockTaskWhitelistedLocked() {
789 if (mCallingPackage == null) {
790 return false;
791 }
792 String[] packages = mService.mLockTaskPackages.get(userId);
793 if (packages == null) {
794 return false;
795 }
796 for (int i = packages.length - 1; i >= 0; --i) {
797 if (mCallingPackage.equals(packages[i])) {
798 return true;
799 }
800 }
801 return false;
802 }
Craig Mautnera82aa092013-09-13 15:34:08 -0700803 boolean isHomeTask() {
Craig Mautner84984fa2014-06-19 11:19:20 -0700804 return taskType == HOME_ACTIVITY_TYPE;
Craig Mautnera82aa092013-09-13 15:34:08 -0700805 }
806
Craig Mautner86d67a42013-05-14 10:34:38 -0700807 boolean isApplicationTask() {
Craig Mautner84984fa2014-06-19 11:19:20 -0700808 return taskType == APPLICATION_ACTIVITY_TYPE;
809 }
810
811 boolean isOverHomeStack() {
812 return mTaskToReturnTo == HOME_ACTIVITY_TYPE || mTaskToReturnTo == RECENTS_ACTIVITY_TYPE;
Craig Mautner1602ec22013-05-12 10:24:27 -0700813 }
814
Craig Mautner525f3d92013-05-07 14:01:50 -0700815 /**
816 * Find the activity in the history stack within the given task. Returns
817 * the index within the history at which it's found, or < 0 if not found.
818 */
819 final ActivityRecord findActivityInHistoryLocked(ActivityRecord r) {
820 final ComponentName realActivity = r.realActivity;
821 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
822 ActivityRecord candidate = mActivities.get(activityNdx);
823 if (candidate.finishing) {
824 continue;
825 }
826 if (candidate.realActivity.equals(realActivity)) {
827 return candidate;
828 }
829 }
830 return null;
831 }
832
Winson Chunga449dc02014-05-16 11:15:04 -0700833 /** Updates the last task description values. */
834 void updateTaskDescription() {
835 // Traverse upwards looking for any break between main task activities and
836 // utility activities.
837 int activityNdx;
838 final int numActivities = mActivities.size();
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700839 final boolean relinquish = numActivities == 0 ? false :
840 (mActivities.get(0).info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) != 0;
Winson Chunga449dc02014-05-16 11:15:04 -0700841 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
Craig Mautner21d24a22014-04-23 11:45:37 -0700842 ++activityNdx) {
Winson Chunga449dc02014-05-16 11:15:04 -0700843 final ActivityRecord r = mActivities.get(activityNdx);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700844 if (relinquish && (r.info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
845 // This will be the top activity for determining taskDescription. Pre-inc to
846 // overcome initial decrement below.
847 ++activityNdx;
848 break;
849 }
Winson Chunga449dc02014-05-16 11:15:04 -0700850 if (r.intent != null &&
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700851 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
Winson Chunga449dc02014-05-16 11:15:04 -0700852 break;
853 }
854 }
855 if (activityNdx > 0) {
856 // Traverse downwards starting below break looking for set label, icon.
857 // Note that if there are activities in the task but none of them set the
858 // recent activity values, then we do not fall back to the last set
859 // values in the TaskRecord.
860 String label = null;
Craig Mautner648f69b2014-09-18 14:16:26 -0700861 String iconFilename = null;
Winson Chunga449dc02014-05-16 11:15:04 -0700862 int colorPrimary = 0;
863 for (--activityNdx; activityNdx >= 0; --activityNdx) {
864 final ActivityRecord r = mActivities.get(activityNdx);
865 if (r.taskDescription != null) {
866 if (label == null) {
867 label = r.taskDescription.getLabel();
868 }
Craig Mautner648f69b2014-09-18 14:16:26 -0700869 if (iconFilename == null) {
870 iconFilename = r.taskDescription.getIconFilename();
Winson Chunga449dc02014-05-16 11:15:04 -0700871 }
872 if (colorPrimary == 0) {
873 colorPrimary = r.taskDescription.getPrimaryColor();
Winson Chunga449dc02014-05-16 11:15:04 -0700874 }
875 }
876 }
Craig Mautner648f69b2014-09-18 14:16:26 -0700877 lastTaskDescription = new TaskDescription(label, colorPrimary, iconFilename);
Winson Chungec396d62014-08-06 17:08:00 -0700878 // Update the task affiliation color if we are the parent of the group
879 if (taskId == mAffiliatedTaskId) {
880 mAffiliatedTaskColor = lastTaskDescription.getPrimaryColor();
881 }
Winson Chunga449dc02014-05-16 11:15:04 -0700882 }
883 }
884
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700885 int findEffectiveRootIndex() {
Craig Mautner4767f4b2014-09-18 15:38:33 -0700886 int effectiveNdx = 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700887 final int topActivityNdx = mActivities.size() - 1;
Dianne Hackborn39569af2014-09-23 10:56:58 -0700888 for (int activityNdx = 0; activityNdx <= topActivityNdx; ++activityNdx) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700889 final ActivityRecord r = mActivities.get(activityNdx);
890 if (r.finishing) {
891 continue;
892 }
Craig Mautner4767f4b2014-09-18 15:38:33 -0700893 effectiveNdx = activityNdx;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700894 if ((r.info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
895 break;
896 }
897 }
Craig Mautner4767f4b2014-09-18 15:38:33 -0700898 return effectiveNdx;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700899 }
900
901 void updateEffectiveIntent() {
902 final int effectiveRootIndex = findEffectiveRootIndex();
903 final ActivityRecord r = mActivities.get(effectiveRootIndex);
Winson Chungfee26772014-08-05 12:21:52 -0700904 setIntent(r);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700905 }
906
Craig Mautner21d24a22014-04-23 11:45:37 -0700907 void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700908 if (DEBUG_RECENTS) Slog.i(TAG_RECENTS, "Saving task=" + this);
Craig Mautner21d24a22014-04-23 11:45:37 -0700909
910 out.attribute(null, ATTR_TASKID, String.valueOf(taskId));
911 if (realActivity != null) {
912 out.attribute(null, ATTR_REALACTIVITY, realActivity.flattenToShortString());
913 }
914 if (origActivity != null) {
915 out.attribute(null, ATTR_ORIGACTIVITY, origActivity.flattenToShortString());
916 }
Dianne Hackborn79228822014-09-16 11:11:23 -0700917 // Write affinity, and root affinity if it is different from affinity.
918 // We use the special string "@" for a null root affinity, so we can identify
919 // later whether we were given a root affinity or should just make it the
920 // same as the affinity.
Craig Mautner21d24a22014-04-23 11:45:37 -0700921 if (affinity != null) {
922 out.attribute(null, ATTR_AFFINITY, affinity);
Dianne Hackborn79228822014-09-16 11:11:23 -0700923 if (!affinity.equals(rootAffinity)) {
924 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
925 }
926 } else if (rootAffinity != null) {
927 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
Craig Mautner21d24a22014-04-23 11:45:37 -0700928 }
929 out.attribute(null, ATTR_ROOTHASRESET, String.valueOf(rootWasReset));
Dianne Hackborn13420f22014-07-18 15:43:56 -0700930 out.attribute(null, ATTR_AUTOREMOVERECENTS, String.valueOf(autoRemoveRecents));
Craig Mautner21d24a22014-04-23 11:45:37 -0700931 out.attribute(null, ATTR_ASKEDCOMPATMODE, String.valueOf(askedCompatMode));
932 out.attribute(null, ATTR_USERID, String.valueOf(userId));
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700933 out.attribute(null, ATTR_EFFECTIVE_UID, String.valueOf(effectiveUid));
Craig Mautner21d24a22014-04-23 11:45:37 -0700934 out.attribute(null, ATTR_TASKTYPE, String.valueOf(taskType));
Winson Chungffa2ec62014-07-03 15:54:42 -0700935 out.attribute(null, ATTR_FIRSTACTIVETIME, String.valueOf(firstActiveTime));
Winson Chungf1fbd772014-06-24 18:06:58 -0700936 out.attribute(null, ATTR_LASTACTIVETIME, String.valueOf(lastActiveTime));
Craig Mautner21d24a22014-04-23 11:45:37 -0700937 out.attribute(null, ATTR_LASTTIMEMOVED, String.valueOf(mLastTimeMoved));
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700938 out.attribute(null, ATTR_NEVERRELINQUISH, String.valueOf(mNeverRelinquishIdentity));
Craig Mautner21d24a22014-04-23 11:45:37 -0700939 if (lastDescription != null) {
940 out.attribute(null, ATTR_LASTDESCRIPTION, lastDescription.toString());
941 }
Winson Chung2cb86c72014-06-25 12:03:30 -0700942 if (lastTaskDescription != null) {
Craig Mautner648f69b2014-09-18 14:16:26 -0700943 lastTaskDescription.saveToXml(out);
Winson Chung2cb86c72014-06-25 12:03:30 -0700944 }
Winson Chungec396d62014-08-06 17:08:00 -0700945 out.attribute(null, ATTR_TASK_AFFILIATION_COLOR, String.valueOf(mAffiliatedTaskColor));
Craig Mautnera228ae92014-07-09 05:44:55 -0700946 out.attribute(null, ATTR_TASK_AFFILIATION, String.valueOf(mAffiliatedTaskId));
947 out.attribute(null, ATTR_PREV_AFFILIATION, String.valueOf(mPrevAffiliateTaskId));
948 out.attribute(null, ATTR_NEXT_AFFILIATION, String.valueOf(mNextAffiliateTaskId));
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700949 out.attribute(null, ATTR_CALLING_UID, String.valueOf(mCallingUid));
950 out.attribute(null, ATTR_CALLING_PACKAGE, mCallingPackage == null ? "" : mCallingPackage);
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800951 out.attribute(null, ATTR_RESIZEABLE, String.valueOf(mResizeable));
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700952 out.attribute(null, ATTR_PRIVILEGED, String.valueOf(mPrivileged));
Winson Chung2cb86c72014-06-25 12:03:30 -0700953
Craig Mautner21d24a22014-04-23 11:45:37 -0700954 if (affinityIntent != null) {
955 out.startTag(null, TAG_AFFINITYINTENT);
956 affinityIntent.saveToXml(out);
957 out.endTag(null, TAG_AFFINITYINTENT);
958 }
959
960 out.startTag(null, TAG_INTENT);
961 intent.saveToXml(out);
962 out.endTag(null, TAG_INTENT);
963
964 final ArrayList<ActivityRecord> activities = mActivities;
965 final int numActivities = activities.size();
966 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
967 final ActivityRecord r = activities.get(activityNdx);
Craig Mautner43e52ed2014-06-16 17:18:52 -0700968 if (r.info.persistableMode == ActivityInfo.PERSIST_ROOT_ONLY || !r.isPersistable() ||
Wale Ogunwale843bfb92015-03-27 11:06:48 -0700969 ((r.intent.getFlags() & FLAG_ACTIVITY_NEW_DOCUMENT
970 | FLAG_ACTIVITY_RETAIN_IN_RECENTS) == FLAG_ACTIVITY_NEW_DOCUMENT) &&
Craig Mautner43e52ed2014-06-16 17:18:52 -0700971 activityNdx > 0) {
Craig Mautnerf357c0c2014-06-09 09:23:27 -0700972 // Stop at first non-persistable or first break in task (CLEAR_WHEN_TASK_RESET).
Craig Mautner21d24a22014-04-23 11:45:37 -0700973 break;
974 }
975 out.startTag(null, TAG_ACTIVITY);
976 r.saveToXml(out);
977 out.endTag(null, TAG_ACTIVITY);
978 }
Craig Mautner21d24a22014-04-23 11:45:37 -0700979 }
980
981 static TaskRecord restoreFromXml(XmlPullParser in, ActivityStackSupervisor stackSupervisor)
982 throws IOException, XmlPullParserException {
983 Intent intent = null;
984 Intent affinityIntent = null;
985 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
986 ComponentName realActivity = null;
987 ComponentName origActivity = null;
988 String affinity = null;
Dianne Hackborn79228822014-09-16 11:11:23 -0700989 String rootAffinity = null;
990 boolean hasRootAffinity = false;
Craig Mautner21d24a22014-04-23 11:45:37 -0700991 boolean rootHasReset = false;
Dianne Hackborn13420f22014-07-18 15:43:56 -0700992 boolean autoRemoveRecents = false;
Craig Mautner21d24a22014-04-23 11:45:37 -0700993 boolean askedCompatMode = false;
994 int taskType = ActivityRecord.APPLICATION_ACTIVITY_TYPE;
Craig Mautner21d24a22014-04-23 11:45:37 -0700995 int userId = 0;
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700996 int effectiveUid = -1;
Craig Mautner21d24a22014-04-23 11:45:37 -0700997 String lastDescription = null;
Winson Chungffa2ec62014-07-03 15:54:42 -0700998 long firstActiveTime = -1;
Winson Chung2cb86c72014-06-25 12:03:30 -0700999 long lastActiveTime = -1;
Craig Mautner21d24a22014-04-23 11:45:37 -07001000 long lastTimeOnTop = 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001001 boolean neverRelinquishIdentity = true;
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001002 int taskId = INVALID_TASK_ID;
Craig Mautner21d24a22014-04-23 11:45:37 -07001003 final int outerDepth = in.getDepth();
Craig Mautner648f69b2014-09-18 14:16:26 -07001004 TaskDescription taskDescription = new TaskDescription();
Wale Ogunwale18795a22014-12-03 11:38:33 -08001005 int taskAffiliation = INVALID_TASK_ID;
Winson Chungec396d62014-08-06 17:08:00 -07001006 int taskAffiliationColor = 0;
Wale Ogunwale18795a22014-12-03 11:38:33 -08001007 int prevTaskId = INVALID_TASK_ID;
1008 int nextTaskId = INVALID_TASK_ID;
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001009 int callingUid = -1;
1010 String callingPackage = "";
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -08001011 boolean resizeable = false;
Wale Ogunwalea7afaa22015-05-01 20:39:18 -07001012 boolean privileged = false;
Craig Mautner21d24a22014-04-23 11:45:37 -07001013
1014 for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
1015 final String attrName = in.getAttributeName(attrNdx);
1016 final String attrValue = in.getAttributeValue(attrNdx);
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001017 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: attribute name=" +
1018 attrName + " value=" + attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001019 if (ATTR_TASKID.equals(attrName)) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08001020 if (taskId == INVALID_TASK_ID) taskId = Integer.valueOf(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001021 } else if (ATTR_REALACTIVITY.equals(attrName)) {
1022 realActivity = ComponentName.unflattenFromString(attrValue);
1023 } else if (ATTR_ORIGACTIVITY.equals(attrName)) {
1024 origActivity = ComponentName.unflattenFromString(attrValue);
1025 } else if (ATTR_AFFINITY.equals(attrName)) {
1026 affinity = attrValue;
Dianne Hackborn79228822014-09-16 11:11:23 -07001027 } else if (ATTR_ROOT_AFFINITY.equals(attrName)) {
1028 rootAffinity = attrValue;
1029 hasRootAffinity = true;
Craig Mautner21d24a22014-04-23 11:45:37 -07001030 } else if (ATTR_ROOTHASRESET.equals(attrName)) {
1031 rootHasReset = Boolean.valueOf(attrValue);
Dianne Hackborn13420f22014-07-18 15:43:56 -07001032 } else if (ATTR_AUTOREMOVERECENTS.equals(attrName)) {
1033 autoRemoveRecents = Boolean.valueOf(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001034 } else if (ATTR_ASKEDCOMPATMODE.equals(attrName)) {
1035 askedCompatMode = Boolean.valueOf(attrValue);
1036 } else if (ATTR_USERID.equals(attrName)) {
1037 userId = Integer.valueOf(attrValue);
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001038 } else if (ATTR_EFFECTIVE_UID.equals(attrName)) {
1039 effectiveUid = Integer.valueOf(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001040 } else if (ATTR_TASKTYPE.equals(attrName)) {
1041 taskType = Integer.valueOf(attrValue);
Winson Chungffa2ec62014-07-03 15:54:42 -07001042 } else if (ATTR_FIRSTACTIVETIME.equals(attrName)) {
1043 firstActiveTime = Long.valueOf(attrValue);
Winson Chungf1fbd772014-06-24 18:06:58 -07001044 } else if (ATTR_LASTACTIVETIME.equals(attrName)) {
1045 lastActiveTime = Long.valueOf(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001046 } else if (ATTR_LASTDESCRIPTION.equals(attrName)) {
1047 lastDescription = attrValue;
1048 } else if (ATTR_LASTTIMEMOVED.equals(attrName)) {
1049 lastTimeOnTop = Long.valueOf(attrValue);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001050 } else if (ATTR_NEVERRELINQUISH.equals(attrName)) {
1051 neverRelinquishIdentity = Boolean.valueOf(attrValue);
Craig Mautner648f69b2014-09-18 14:16:26 -07001052 } else if (attrName.startsWith(TaskDescription.ATTR_TASKDESCRIPTION_PREFIX)) {
1053 taskDescription.restoreFromXml(attrName, attrValue);
Craig Mautnera228ae92014-07-09 05:44:55 -07001054 } else if (ATTR_TASK_AFFILIATION.equals(attrName)) {
1055 taskAffiliation = Integer.valueOf(attrValue);
1056 } else if (ATTR_PREV_AFFILIATION.equals(attrName)) {
1057 prevTaskId = Integer.valueOf(attrValue);
1058 } else if (ATTR_NEXT_AFFILIATION.equals(attrName)) {
1059 nextTaskId = Integer.valueOf(attrValue);
Winson Chungec396d62014-08-06 17:08:00 -07001060 } else if (ATTR_TASK_AFFILIATION_COLOR.equals(attrName)) {
1061 taskAffiliationColor = Integer.valueOf(attrValue);
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001062 } else if (ATTR_CALLING_UID.equals(attrName)) {
1063 callingUid = Integer.valueOf(attrValue);
1064 } else if (ATTR_CALLING_PACKAGE.equals(attrName)) {
1065 callingPackage = attrValue;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -08001066 } else if (ATTR_RESIZEABLE.equals(attrName)) {
1067 resizeable = Boolean.valueOf(attrValue);
Wale Ogunwalea7afaa22015-05-01 20:39:18 -07001068 } else if (ATTR_PRIVILEGED.equals(attrName)) {
1069 privileged = Boolean.valueOf(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001070 } else {
1071 Slog.w(TAG, "TaskRecord: Unknown attribute=" + attrName);
1072 }
1073 }
1074
1075 int event;
1076 while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
1077 (event != XmlPullParser.END_TAG || in.getDepth() < outerDepth)) {
1078 if (event == XmlPullParser.START_TAG) {
1079 final String name = in.getName();
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001080 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: START_TAG name=" +
1081 name);
Craig Mautner21d24a22014-04-23 11:45:37 -07001082 if (TAG_AFFINITYINTENT.equals(name)) {
1083 affinityIntent = Intent.restoreFromXml(in);
1084 } else if (TAG_INTENT.equals(name)) {
1085 intent = Intent.restoreFromXml(in);
1086 } else if (TAG_ACTIVITY.equals(name)) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08001087 ActivityRecord activity = ActivityRecord.restoreFromXml(in, stackSupervisor);
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001088 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: activity=" +
1089 activity);
Craig Mautner21d24a22014-04-23 11:45:37 -07001090 if (activity != null) {
1091 activities.add(activity);
1092 }
1093 } else {
1094 Slog.e(TAG, "restoreTask: Unexpected name=" + name);
1095 XmlUtils.skipCurrentTag(in);
1096 }
1097 }
1098 }
Dianne Hackborn79228822014-09-16 11:11:23 -07001099 if (!hasRootAffinity) {
1100 rootAffinity = affinity;
1101 } else if ("@".equals(rootAffinity)) {
1102 rootAffinity = null;
1103 }
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001104 if (effectiveUid <= 0) {
1105 Intent checkIntent = intent != null ? intent : affinityIntent;
1106 effectiveUid = 0;
1107 if (checkIntent != null) {
1108 IPackageManager pm = AppGlobals.getPackageManager();
1109 try {
1110 ApplicationInfo ai = pm.getApplicationInfo(
1111 checkIntent.getComponent().getPackageName(),
1112 PackageManager.GET_UNINSTALLED_PACKAGES
1113 | PackageManager.GET_DISABLED_COMPONENTS, userId);
1114 if (ai != null) {
1115 effectiveUid = ai.uid;
1116 }
1117 } catch (RemoteException e) {
1118 }
1119 }
1120 Slog.w(TAG, "Updating task #" + taskId + " for " + checkIntent
1121 + ": effectiveUid=" + effectiveUid);
1122 }
1123
Craig Mautner21d24a22014-04-23 11:45:37 -07001124 final TaskRecord task = new TaskRecord(stackSupervisor.mService, taskId, intent,
Dianne Hackborn79228822014-09-16 11:11:23 -07001125 affinityIntent, affinity, rootAffinity, realActivity, origActivity, rootHasReset,
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001126 autoRemoveRecents, askedCompatMode, taskType, userId, effectiveUid, lastDescription,
1127 activities, firstActiveTime, lastActiveTime, lastTimeOnTop, neverRelinquishIdentity,
Winson Chungec396d62014-08-06 17:08:00 -07001128 taskDescription, taskAffiliation, prevTaskId, nextTaskId, taskAffiliationColor,
Wale Ogunwalea7afaa22015-05-01 20:39:18 -07001129 callingUid, callingPackage, resizeable, privileged);
Craig Mautner21d24a22014-04-23 11:45:37 -07001130
1131 for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001132 activities.get(activityNdx).task = task;
Craig Mautner21d24a22014-04-23 11:45:37 -07001133 }
1134
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001135 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Restored task=" + task);
Craig Mautner21d24a22014-04-23 11:45:37 -07001136 return task;
1137 }
1138
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001139 void dump(PrintWriter pw, String prefix) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001140 pw.print(prefix); pw.print("userId="); pw.print(userId);
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001141 pw.print(" effectiveUid="); UserHandle.formatUid(pw, effectiveUid);
1142 pw.print(" mCallingUid="); UserHandle.formatUid(pw, mCallingUid);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001143 pw.print(" mCallingPackage="); pw.println(mCallingPackage);
Dianne Hackborn79228822014-09-16 11:11:23 -07001144 if (affinity != null || rootAffinity != null) {
1145 pw.print(prefix); pw.print("affinity="); pw.print(affinity);
1146 if (affinity == null || !affinity.equals(rootAffinity)) {
1147 pw.print(" root="); pw.println(rootAffinity);
1148 } else {
1149 pw.println();
1150 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001151 }
Dianne Hackborn91097de2014-04-04 18:02:06 -07001152 if (voiceSession != null || voiceInteractor != null) {
1153 pw.print(prefix); pw.print("VOICE: session=0x");
1154 pw.print(Integer.toHexString(System.identityHashCode(voiceSession)));
1155 pw.print(" interactor=0x");
1156 pw.println(Integer.toHexString(System.identityHashCode(voiceInteractor)));
1157 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001158 if (intent != null) {
1159 StringBuilder sb = new StringBuilder(128);
1160 sb.append(prefix); sb.append("intent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08001161 intent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001162 sb.append('}');
1163 pw.println(sb.toString());
1164 }
1165 if (affinityIntent != null) {
1166 StringBuilder sb = new StringBuilder(128);
1167 sb.append(prefix); sb.append("affinityIntent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08001168 affinityIntent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001169 sb.append('}');
1170 pw.println(sb.toString());
1171 }
1172 if (origActivity != null) {
1173 pw.print(prefix); pw.print("origActivity=");
1174 pw.println(origActivity.flattenToShortString());
1175 }
1176 if (realActivity != null) {
1177 pw.print(prefix); pw.print("realActivity=");
1178 pw.println(realActivity.flattenToShortString());
1179 }
Dianne Hackborn852975d2014-08-22 17:42:43 -07001180 if (autoRemoveRecents || isPersistable || taskType != 0 || mTaskToReturnTo != 0
1181 || numFullscreen != 0) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001182 pw.print(prefix); pw.print("autoRemoveRecents="); pw.print(autoRemoveRecents);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001183 pw.print(" isPersistable="); pw.print(isPersistable);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001184 pw.print(" numFullscreen="); pw.print(numFullscreen);
1185 pw.print(" taskType="); pw.print(taskType);
1186 pw.print(" mTaskToReturnTo="); pw.println(mTaskToReturnTo);
1187 }
Craig Mautner432f64e2015-05-20 14:59:57 -07001188 if (rootWasReset || mNeverRelinquishIdentity || mReuseTask
1189 || mLockTaskAuth != LOCK_TASK_AUTH_PINNABLE) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001190 pw.print(prefix); pw.print("rootWasReset="); pw.print(rootWasReset);
1191 pw.print(" mNeverRelinquishIdentity="); pw.print(mNeverRelinquishIdentity);
Craig Mautner432f64e2015-05-20 14:59:57 -07001192 pw.print(" mReuseTask="); pw.print(mReuseTask);
1193 pw.print(" mLockTaskAuth="); pw.println(lockTaskAuthToString());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001194 }
Wale Ogunwale18795a22014-12-03 11:38:33 -08001195 if (mAffiliatedTaskId != taskId || mPrevAffiliateTaskId != INVALID_TASK_ID
1196 || mPrevAffiliate != null || mNextAffiliateTaskId != INVALID_TASK_ID
1197 || mNextAffiliate != null) {
Dianne Hackborn852975d2014-08-22 17:42:43 -07001198 pw.print(prefix); pw.print("affiliation="); pw.print(mAffiliatedTaskId);
1199 pw.print(" prevAffiliation="); pw.print(mPrevAffiliateTaskId);
1200 pw.print(" (");
1201 if (mPrevAffiliate == null) {
1202 pw.print("null");
1203 } else {
1204 pw.print(Integer.toHexString(System.identityHashCode(mPrevAffiliate)));
1205 }
1206 pw.print(") nextAffiliation="); pw.print(mNextAffiliateTaskId);
1207 pw.print(" (");
1208 if (mNextAffiliate == null) {
1209 pw.print("null");
1210 } else {
1211 pw.print(Integer.toHexString(System.identityHashCode(mNextAffiliate)));
1212 }
1213 pw.println(")");
1214 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001215 pw.print(prefix); pw.print("Activities="); pw.println(mActivities);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001216 if (!askedCompatMode || !inRecents || !isAvailable) {
1217 pw.print(prefix); pw.print("askedCompatMode="); pw.print(askedCompatMode);
1218 pw.print(" inRecents="); pw.print(inRecents);
1219 pw.print(" isAvailable="); pw.println(isAvailable);
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001220 }
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001221 pw.print(prefix); pw.print("lastThumbnail="); pw.print(mLastThumbnail);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001222 pw.print(" lastThumbnailFile="); pw.println(mLastThumbnailFile);
1223 if (lastDescription != null) {
1224 pw.print(prefix); pw.print("lastDescription="); pw.println(lastDescription);
1225 }
Dianne Hackbornd38aed82014-06-10 21:36:35 -07001226 pw.print(prefix); pw.print("hasBeenVisible="); pw.print(hasBeenVisible);
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -08001227 pw.print(" mResizeable="); pw.print(mResizeable);
Winson Chungffa2ec62014-07-03 15:54:42 -07001228 pw.print(" firstActiveTime="); pw.print(lastActiveTime);
Dianne Hackbornd38aed82014-06-10 21:36:35 -07001229 pw.print(" lastActiveTime="); pw.print(lastActiveTime);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001230 pw.print(" (inactive for ");
1231 pw.print((getInactiveDuration()/1000)); pw.println("s)");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001232 }
1233
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001234 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001235 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001236 StringBuilder sb = new StringBuilder(128);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001237 if (stringName != null) {
1238 sb.append(stringName);
1239 sb.append(" U=");
1240 sb.append(userId);
1241 sb.append(" sz=");
1242 sb.append(mActivities.size());
1243 sb.append('}');
1244 return sb.toString();
1245 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001246 sb.append("TaskRecord{");
1247 sb.append(Integer.toHexString(System.identityHashCode(this)));
1248 sb.append(" #");
1249 sb.append(taskId);
1250 if (affinity != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001251 sb.append(" A=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001252 sb.append(affinity);
1253 } else if (intent != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001254 sb.append(" I=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001255 sb.append(intent.getComponent().flattenToShortString());
1256 } else if (affinityIntent != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001257 sb.append(" aI=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001258 sb.append(affinityIntent.getComponent().flattenToShortString());
1259 } else {
1260 sb.append(" ??");
1261 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07001262 stringName = sb.toString();
1263 return toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001264 }
1265}