blob: f74b795f63148729dd4f33cbef494f07a6d3997e [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
Craig Mautnerde4ef022013-04-07 19:01:33 -070019import static com.android.server.am.ActivityManagerService.TAG;
Craig Mautner84984fa2014-06-19 11:19:20 -070020import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
21import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
22import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
Craig Mautner0eea92c2013-05-16 13:35:39 -070023import static com.android.server.am.ActivityStackSupervisor.DEBUG_ADD_REMOVE;
Craig Mautnerde4ef022013-04-07 19:01:33 -070024
Craig Mautnerb0f7dc72013-04-01 16:34:45 -070025import android.app.Activity;
Craig Mautner9db9a0b2013-04-29 17:05:56 -070026import android.app.ActivityManager;
Craig Mautnerc0ffce52014-07-01 12:38:52 -070027import android.app.ActivityManager.TaskThumbnail;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -070028import android.app.ActivityOptions;
Dianne Hackborn885fbe52014-08-23 15:23:58 -070029import android.app.AppGlobals;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import android.content.ComponentName;
31import android.content.Intent;
32import android.content.pm.ActivityInfo;
Dianne Hackborn885fbe52014-08-23 15:23:58 -070033import android.content.pm.ApplicationInfo;
34import android.content.pm.IPackageManager;
35import android.content.pm.PackageManager;
Craig Mautner9db9a0b2013-04-29 17:05:56 -070036import android.graphics.Bitmap;
Craig Mautnerc0ffce52014-07-01 12:38:52 -070037import android.os.ParcelFileDescriptor;
Dianne Hackborn885fbe52014-08-23 15:23:58 -070038import android.os.RemoteException;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070039import android.os.UserHandle;
Dianne Hackborn91097de2014-04-04 18:02:06 -070040import android.service.voice.IVoiceInteractionSession;
Dianne Hackborn7f96b792012-05-29 18:46:45 -070041import android.util.Slog;
Dianne Hackborn91097de2014-04-04 18:02:06 -070042import com.android.internal.app.IVoiceInteractor;
Craig Mautner21d24a22014-04-23 11:45:37 -070043import com.android.internal.util.XmlUtils;
44import org.xmlpull.v1.XmlPullParser;
45import org.xmlpull.v1.XmlPullParserException;
46import org.xmlpull.v1.XmlSerializer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047
Craig Mautnerc0ffce52014-07-01 12:38:52 -070048import java.io.File;
Craig Mautner21d24a22014-04-23 11:45:37 -070049import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050import java.io.PrintWriter;
Craig Mautner5d9c7be2013-02-15 14:02:56 -080051import java.util.ArrayList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052
Craig Mautnerc0ffce52014-07-01 12:38:52 -070053final class TaskRecord {
Craig Mautner21d24a22014-04-23 11:45:37 -070054 private static final String ATTR_TASKID = "task_id";
55 private static final String TAG_INTENT = "intent";
56 private static final String TAG_AFFINITYINTENT = "affinity_intent";
57 private static final String ATTR_REALACTIVITY = "real_activity";
58 private static final String ATTR_ORIGACTIVITY = "orig_activity";
59 private static final String TAG_ACTIVITY = "activity";
60 private static final String ATTR_AFFINITY = "affinity";
Dianne Hackborn79228822014-09-16 11:11:23 -070061 private static final String ATTR_ROOT_AFFINITY = "root_affinity";
Craig Mautner21d24a22014-04-23 11:45:37 -070062 private static final String ATTR_ROOTHASRESET = "root_has_reset";
Dianne Hackborn13420f22014-07-18 15:43:56 -070063 private static final String ATTR_AUTOREMOVERECENTS = "auto_remove_recents";
Craig Mautner21d24a22014-04-23 11:45:37 -070064 private static final String ATTR_ASKEDCOMPATMODE = "asked_compat_mode";
65 private static final String ATTR_USERID = "user_id";
Dianne Hackborn885fbe52014-08-23 15:23:58 -070066 private static final String ATTR_EFFECTIVE_UID = "effective_uid";
Craig Mautner21d24a22014-04-23 11:45:37 -070067 private static final String ATTR_TASKTYPE = "task_type";
Winson Chungffa2ec62014-07-03 15:54:42 -070068 private static final String ATTR_FIRSTACTIVETIME = "first_active_time";
Winson Chungf1fbd772014-06-24 18:06:58 -070069 private static final String ATTR_LASTACTIVETIME = "last_active_time";
Craig Mautner21d24a22014-04-23 11:45:37 -070070 private static final String ATTR_LASTDESCRIPTION = "last_description";
71 private static final String ATTR_LASTTIMEMOVED = "last_time_moved";
Craig Mautner9d4e9bc2014-06-18 18:34:56 -070072 private static final String ATTR_NEVERRELINQUISH = "never_relinquish_identity";
Craig Mautnerc0ffce52014-07-01 12:38:52 -070073 private static final String ATTR_TASKDESCRIPTIONLABEL = "task_description_label";
74 private static final String ATTR_TASKDESCRIPTIONCOLOR = "task_description_color";
Craig Mautnera228ae92014-07-09 05:44:55 -070075 private static final String ATTR_TASK_AFFILIATION = "task_affiliation";
76 private static final String ATTR_PREV_AFFILIATION = "prev_affiliation";
77 private static final String ATTR_NEXT_AFFILIATION = "next_affiliation";
Winson Chungec396d62014-08-06 17:08:00 -070078 private static final String ATTR_TASK_AFFILIATION_COLOR = "task_affiliation_color";
Craig Mautnerdc00cbe2014-07-20 17:48:47 -070079 private static final String ATTR_CALLING_UID = "calling_uid";
80 private static final String ATTR_CALLING_PACKAGE = "calling_package";
Winson Chung2cb86c72014-06-25 12:03:30 -070081 private static final String LAST_ACTIVITY_ICON_SUFFIX = "_last_activity_icon_";
Craig Mautner21d24a22014-04-23 11:45:37 -070082
83 private static final String TASK_THUMBNAIL_SUFFIX = "_task_thumbnail";
84
Craig Mautner0b633fc2014-07-23 10:42:18 -070085 static final boolean IGNORE_RETURN_TO_RECENTS = true;
86
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087 final int taskId; // Unique identifier for this task.
Dianne Hackborn79228822014-09-16 11:11:23 -070088 String affinity; // The affinity name for this task, or null; may change identity.
89 String rootAffinity; // Initial base affinity, or null; does not change from initial root.
Dianne Hackborn91097de2014-04-04 18:02:06 -070090 final IVoiceInteractionSession voiceSession; // Voice interaction session driving task
91 final IVoiceInteractor voiceInteractor; // Associated interactor to provide to app
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092 Intent intent; // The original intent that started the task.
93 Intent affinityIntent; // Intent of affinity-moved activity that started this task.
Dianne Hackborn885fbe52014-08-23 15:23:58 -070094 int effectiveUid; // The current effective uid of the identity of this task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095 ComponentName origActivity; // The non-alias activity component of the intent.
96 ComponentName realActivity; // The actual activity component that started the task.
Winson Chungffa2ec62014-07-03 15:54:42 -070097 long firstActiveTime; // First time this task was active.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098 long lastActiveTime; // Last time this task was active, including sleep.
Dianne Hackborn852975d2014-08-22 17:42:43 -070099 boolean inRecents; // Actually in the recents list?
100 boolean isAvailable; // Is the activity available to be launched?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101 boolean rootWasReset; // True if the intent at the root of the task had
102 // the FLAG_ACTIVITY_RESET_TASK_IF_NEEDED flag.
Dianne Hackborn13420f22014-07-18 15:43:56 -0700103 boolean autoRemoveRecents; // If true, we should automatically remove the task from
104 // recents when activity finishes
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700105 boolean askedCompatMode;// Have asked the user about compat mode for this task.
Dianne Hackbornd38aed82014-06-10 21:36:35 -0700106 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 -0800107
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700108 String stringName; // caching of toString() result.
Dianne Hackborn9da2d402012-03-15 13:43:08 -0700109 int userId; // user for which this task was created
Dianne Hackborn09233282014-04-30 11:33:59 -0700110 int creatorUid; // The app uid that originally created the task
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800111
112 int numFullscreen; // Number of fullscreen activities.
113
Winson Chung03a9bae2014-05-02 09:56:12 -0700114 // This represents the last resolved activity values for this task
115 // NOTE: This value needs to be persisted with each task
Winson Chunga449dc02014-05-16 11:15:04 -0700116 ActivityManager.TaskDescription lastTaskDescription =
117 new ActivityManager.TaskDescription();
Winson Chung03a9bae2014-05-02 09:56:12 -0700118
Craig Mautnerd2328952013-03-05 12:46:26 -0800119 /** List of all activities in the task arranged in history order */
Craig Mautner21d24a22014-04-23 11:45:37 -0700120 final ArrayList<ActivityRecord> mActivities;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800121
Craig Mautnerd2328952013-03-05 12:46:26 -0800122 /** Current stack */
123 ActivityStack stack;
124
Craig Mautner2c1faed2013-07-23 12:56:02 -0700125 /** Takes on same set of values as ActivityRecord.mActivityType */
Craig Mautner21d24a22014-04-23 11:45:37 -0700126 int taskType;
Craig Mautner1602ec22013-05-12 10:24:27 -0700127
Craig Mautner21d24a22014-04-23 11:45:37 -0700128 /** Takes on same value as first root activity */
129 boolean isPersistable = false;
Craig Mautnerffcfcaa2014-06-05 09:54:38 -0700130 int maxRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700131
132 /** Only used for persistable tasks, otherwise 0. The last time this task was moved. Used for
133 * determining the order when restoring. Sign indicates whether last task movement was to front
134 * (positive) or back (negative). Absolute value indicates time. */
135 long mLastTimeMoved = System.currentTimeMillis();
136
Craig Mautner84984fa2014-06-19 11:19:20 -0700137 /** Indication of what to run next when task exits. Use ActivityRecord types.
138 * ActivityRecord.APPLICATION_ACTIVITY_TYPE indicates to resume the task below this one in the
139 * task stack. */
140 private int mTaskToReturnTo = APPLICATION_ACTIVITY_TYPE;
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700141
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700142 /** If original intent did not allow relinquishing task identity, save that information */
143 boolean mNeverRelinquishIdentity = true;
144
Craig Mautner362449a2014-06-20 14:04:39 -0700145 // Used in the unique case where we are clearing the task in order to reuse it. In that case we
146 // do not want to delete the stack when the task goes empty.
147 boolean mReuseTask = false;
148
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700149 private Bitmap mLastThumbnail; // Last thumbnail captured for this item.
150 private final File mLastThumbnailFile; // File containing last thubmnail.
151 private final String mFilename;
152 CharSequence lastDescription; // Last description captured for this item.
153
Craig Mautnera228ae92014-07-09 05:44:55 -0700154 int mAffiliatedTaskId; // taskId of parent affiliation or self if no parent.
Winson Chungec396d62014-08-06 17:08:00 -0700155 int mAffiliatedTaskColor; // color of the parent task affiliation.
Craig Mautnera228ae92014-07-09 05:44:55 -0700156 TaskRecord mPrevAffiliate; // previous task in affiliated chain.
157 int mPrevAffiliateTaskId = -1; // previous id for persistence.
158 TaskRecord mNextAffiliate; // next task in affiliated chain.
159 int mNextAffiliateTaskId = -1; // next id for persistence.
160
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700161 // For relaunching the task from recents as though it was launched by the original launcher.
162 int mCallingUid;
163 String mCallingPackage;
164
Craig Mautner21d24a22014-04-23 11:45:37 -0700165 final ActivityManagerService mService;
166
167 TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Dianne Hackborn91097de2014-04-04 18:02:06 -0700168 IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700169 mService = service;
Craig Mautnera228ae92014-07-09 05:44:55 -0700170 mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
171 TaskPersister.IMAGE_EXTENSION;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700172 mLastThumbnailFile = new File(TaskPersister.sImagesDir, mFilename);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800173 taskId = _taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700174 mAffiliatedTaskId = _taskId;
Dianne Hackborn91097de2014-04-04 18:02:06 -0700175 voiceSession = _voiceSession;
176 voiceInteractor = _voiceInteractor;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700177 isAvailable = true;
Craig Mautner21d24a22014-04-23 11:45:37 -0700178 mActivities = new ArrayList<ActivityRecord>();
Martijn Coenend4a69702014-06-30 11:12:17 -0700179 setIntent(_intent, info);
Craig Mautner21d24a22014-04-23 11:45:37 -0700180 }
181
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700182 TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
183 ActivityManager.TaskDescription _taskDescription) {
184 mService = service;
185 mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
186 TaskPersister.IMAGE_EXTENSION;
187 mLastThumbnailFile = new File(TaskPersister.sImagesDir, mFilename);
188 taskId = _taskId;
189 mAffiliatedTaskId = _taskId;
190 voiceSession = null;
191 voiceInteractor = null;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700192 isAvailable = true;
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700193 mActivities = new ArrayList<ActivityRecord>();
194 setIntent(_intent, info);
195
196 taskType = ActivityRecord.APPLICATION_ACTIVITY_TYPE;
197 isPersistable = true;
198 mCallingUid = info.applicationInfo.uid;
199 mCallingPackage = info.packageName;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700200 // Clamp to [1, max].
201 maxRecents = Math.min(Math.max(info.maxRecents, 1),
202 ActivityManager.getMaxAppRecentsLimitStatic());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700203
204 taskType = APPLICATION_ACTIVITY_TYPE;
205 mTaskToReturnTo = HOME_ACTIVITY_TYPE;
206 userId = UserHandle.getUserId(info.applicationInfo.uid);
207 lastTaskDescription = _taskDescription;
208 mCallingUid = info.applicationInfo.uid;
209 mCallingPackage = info.packageName;
210 }
211
Craig Mautner21d24a22014-04-23 11:45:37 -0700212 TaskRecord(ActivityManagerService service, int _taskId, Intent _intent, Intent _affinityIntent,
Dianne Hackborn79228822014-09-16 11:11:23 -0700213 String _affinity, String _rootAffinity, ComponentName _realActivity,
214 ComponentName _origActivity, boolean _rootWasReset, boolean _autoRemoveRecents,
215 boolean _askedCompatMode, int _taskType, int _userId, int _effectiveUid,
Winson Chungffa2ec62014-07-03 15:54:42 -0700216 String _lastDescription, ArrayList<ActivityRecord> activities, long _firstActiveTime,
217 long _lastActiveTime, long lastTimeMoved, boolean neverRelinquishIdentity,
Craig Mautnera228ae92014-07-09 05:44:55 -0700218 ActivityManager.TaskDescription _lastTaskDescription, int taskAffiliation,
Winson Chungec396d62014-08-06 17:08:00 -0700219 int prevTaskId, int nextTaskId, int taskAffiliationColor, int callingUid,
220 String callingPackage) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700221 mService = service;
Craig Mautnera228ae92014-07-09 05:44:55 -0700222 mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
223 TaskPersister.IMAGE_EXTENSION;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700224 mLastThumbnailFile = new File(TaskPersister.sImagesDir, mFilename);
Craig Mautner21d24a22014-04-23 11:45:37 -0700225 taskId = _taskId;
226 intent = _intent;
227 affinityIntent = _affinityIntent;
228 affinity = _affinity;
Dianne Hackborn79228822014-09-16 11:11:23 -0700229 rootAffinity = _affinity;
Craig Mautner21d24a22014-04-23 11:45:37 -0700230 voiceSession = null;
231 voiceInteractor = null;
232 realActivity = _realActivity;
233 origActivity = _origActivity;
234 rootWasReset = _rootWasReset;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700235 isAvailable = true;
Dianne Hackborn13420f22014-07-18 15:43:56 -0700236 autoRemoveRecents = _autoRemoveRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700237 askedCompatMode = _askedCompatMode;
238 taskType = _taskType;
Craig Mautner84984fa2014-06-19 11:19:20 -0700239 mTaskToReturnTo = HOME_ACTIVITY_TYPE;
Craig Mautner21d24a22014-04-23 11:45:37 -0700240 userId = _userId;
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700241 effectiveUid = _effectiveUid;
Winson Chungffa2ec62014-07-03 15:54:42 -0700242 firstActiveTime = _firstActiveTime;
Winson Chungf1fbd772014-06-24 18:06:58 -0700243 lastActiveTime = _lastActiveTime;
Craig Mautner21d24a22014-04-23 11:45:37 -0700244 lastDescription = _lastDescription;
245 mActivities = activities;
246 mLastTimeMoved = lastTimeMoved;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700247 mNeverRelinquishIdentity = neverRelinquishIdentity;
Winson Chung2cb86c72014-06-25 12:03:30 -0700248 lastTaskDescription = _lastTaskDescription;
Craig Mautnera228ae92014-07-09 05:44:55 -0700249 mAffiliatedTaskId = taskAffiliation;
Winson Chungec396d62014-08-06 17:08:00 -0700250 mAffiliatedTaskColor = taskAffiliationColor;
Craig Mautnera228ae92014-07-09 05:44:55 -0700251 mPrevAffiliateTaskId = prevTaskId;
252 mNextAffiliateTaskId = nextTaskId;
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700253 mCallingUid = callingUid;
254 mCallingPackage = callingPackage;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800255 }
256
257 void touchActiveTime() {
Craig Mautner494f6bdd2014-07-21 11:17:46 -0700258 lastActiveTime = System.currentTimeMillis();
Winson Chungffa2ec62014-07-03 15:54:42 -0700259 if (firstActiveTime == 0) {
260 firstActiveTime = lastActiveTime;
261 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800262 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700263
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800264 long getInactiveDuration() {
Craig Mautner494f6bdd2014-07-21 11:17:46 -0700265 return System.currentTimeMillis() - lastActiveTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800266 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700267
Winson Chungfee26772014-08-05 12:21:52 -0700268 /** Sets the original intent, and the calling uid and package. */
269 void setIntent(ActivityRecord r) {
270 setIntent(r.intent, r.info);
271 mCallingUid = r.launchedFromUid;
272 mCallingPackage = r.launchedFromPackage;
273 }
274
275 /** Sets the original intent, _without_ updating the calling uid or package. */
276 private void setIntent(Intent _intent, ActivityInfo info) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700277 if (intent == null) {
278 mNeverRelinquishIdentity =
279 (info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) == 0;
280 } else if (mNeverRelinquishIdentity) {
281 return;
282 }
283
284 affinity = info.taskAffinity;
Dianne Hackborn79228822014-09-16 11:11:23 -0700285 if (intent == null) {
286 // If this task already has an intent associated with it, don't set the root
287 // affinity -- we don't want it changing after initially set, but the initially
288 // set value may be null.
289 rootAffinity = affinity;
290 }
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700291 effectiveUid = info.applicationInfo.uid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700292 stringName = null;
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800293
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800294 if (info.targetActivity == null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800295 if (_intent != null) {
296 // If this Intent has a selector, we want to clear it for the
297 // recent task since it is not relevant if the user later wants
298 // to re-launch the app.
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700299 if (_intent.getSelector() != null || _intent.getSourceBounds() != null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800300 _intent = new Intent(_intent);
301 _intent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700302 _intent.setSourceBounds(null);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800303 }
304 }
Dianne Hackborn7f96b792012-05-29 18:46:45 -0700305 if (ActivityManagerService.DEBUG_TASKS) Slog.v(ActivityManagerService.TAG,
306 "Setting Intent of " + this + " to " + _intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800307 intent = _intent;
308 realActivity = _intent != null ? _intent.getComponent() : null;
309 origActivity = null;
310 } else {
311 ComponentName targetComponent = new ComponentName(
312 info.packageName, info.targetActivity);
313 if (_intent != null) {
314 Intent targetIntent = new Intent(_intent);
315 targetIntent.setComponent(targetComponent);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800316 targetIntent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700317 targetIntent.setSourceBounds(null);
Dianne Hackborn7f96b792012-05-29 18:46:45 -0700318 if (ActivityManagerService.DEBUG_TASKS) Slog.v(ActivityManagerService.TAG,
319 "Setting Intent of " + this + " to target " + targetIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800320 intent = targetIntent;
321 realActivity = targetComponent;
322 origActivity = _intent.getComponent();
323 } else {
324 intent = null;
325 realActivity = targetComponent;
326 origActivity = new ComponentName(info.packageName, info.name);
327 }
328 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700329
Craig Mautner47b20ba2014-09-17 17:23:44 -0700330 final int intentFlags = intent == null ? 0 : intent.getFlags();
331 if ((intentFlags & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800332 // Once we are set to an Intent with this flag, we count this
333 // task as having a true root activity.
334 rootWasReset = true;
335 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700336
Dianne Hackborn09233282014-04-30 11:33:59 -0700337 userId = UserHandle.getUserId(info.applicationInfo.uid);
Craig Mautner41db4a72014-05-07 17:20:56 -0700338 if ((info.flags & ActivityInfo.FLAG_AUTO_REMOVE_FROM_RECENTS) != 0) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700339 // If the activity itself has requested auto-remove, then just always do it.
340 autoRemoveRecents = true;
Craig Mautner47b20ba2014-09-17 17:23:44 -0700341 } else if ((intentFlags & (Intent.FLAG_ACTIVITY_NEW_DOCUMENT
342 | Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS)) == Intent.FLAG_ACTIVITY_NEW_DOCUMENT) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700343 // If the caller has not asked for the document to be retained, then we may
344 // want to turn on auto-remove, depending on whether the target has set its
345 // own document launch mode.
346 if (info.documentLaunchMode != ActivityInfo.DOCUMENT_LAUNCH_NONE) {
347 autoRemoveRecents = false;
348 } else {
349 autoRemoveRecents = true;
350 }
351 } else {
352 autoRemoveRecents = false;
Craig Mautner41db4a72014-05-07 17:20:56 -0700353 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800354 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800355
Craig Mautner84984fa2014-06-19 11:19:20 -0700356 void setTaskToReturnTo(int taskToReturnTo) {
Craig Mautner0b633fc2014-07-23 10:42:18 -0700357 if (IGNORE_RETURN_TO_RECENTS && taskToReturnTo == RECENTS_ACTIVITY_TYPE) {
358 taskToReturnTo = HOME_ACTIVITY_TYPE;
359 }
Craig Mautner84984fa2014-06-19 11:19:20 -0700360 mTaskToReturnTo = taskToReturnTo;
361 }
362
363 int getTaskToReturnTo() {
364 return mTaskToReturnTo;
365 }
366
Craig Mautnera228ae92014-07-09 05:44:55 -0700367 void setPrevAffiliate(TaskRecord prevAffiliate) {
368 mPrevAffiliate = prevAffiliate;
369 mPrevAffiliateTaskId = prevAffiliate == null ? -1 : prevAffiliate.taskId;
370 }
371
372 void setNextAffiliate(TaskRecord nextAffiliate) {
373 mNextAffiliate = nextAffiliate;
374 mNextAffiliateTaskId = nextAffiliate == null ? -1 : nextAffiliate.taskId;
375 }
376
377 // Close up recents linked list.
378 void closeRecentsChain() {
379 if (mPrevAffiliate != null) {
380 mPrevAffiliate.setNextAffiliate(mNextAffiliate);
381 }
382 if (mNextAffiliate != null) {
383 mNextAffiliate.setPrevAffiliate(mPrevAffiliate);
384 }
385 setPrevAffiliate(null);
386 setNextAffiliate(null);
387 }
388
Dianne Hackborn852975d2014-08-22 17:42:43 -0700389 void removedFromRecents(TaskPersister persister) {
390 disposeThumbnail();
391 closeRecentsChain();
392 if (inRecents) {
393 inRecents = false;
394 persister.wakeup(this, false);
395 }
396 }
397
Craig Mautnera228ae92014-07-09 05:44:55 -0700398 void setTaskToAffiliateWith(TaskRecord taskToAffiliateWith) {
399 closeRecentsChain();
400 mAffiliatedTaskId = taskToAffiliateWith.mAffiliatedTaskId;
Winson Chungec396d62014-08-06 17:08:00 -0700401 mAffiliatedTaskColor = taskToAffiliateWith.mAffiliatedTaskColor;
Craig Mautnera228ae92014-07-09 05:44:55 -0700402 // Find the end
403 while (taskToAffiliateWith.mNextAffiliate != null) {
404 final TaskRecord nextRecents = taskToAffiliateWith.mNextAffiliate;
405 if (nextRecents.mAffiliatedTaskId != mAffiliatedTaskId) {
406 Slog.e(TAG, "setTaskToAffiliateWith: nextRecents=" + nextRecents + " affilTaskId="
407 + nextRecents.mAffiliatedTaskId + " should be " + mAffiliatedTaskId);
408 if (nextRecents.mPrevAffiliate == taskToAffiliateWith) {
409 nextRecents.setPrevAffiliate(null);
410 }
411 taskToAffiliateWith.setNextAffiliate(null);
412 break;
413 }
414 taskToAffiliateWith = nextRecents;
415 }
416 taskToAffiliateWith.setNextAffiliate(this);
417 setPrevAffiliate(taskToAffiliateWith);
418 setNextAffiliate(null);
419 }
420
Winson Chung096f36b2014-08-20 15:39:01 -0700421 /**
422 * Sets the last thumbnail.
423 * @return whether the thumbnail was set
424 */
425 boolean setLastThumbnail(Bitmap thumbnail) {
426 if (mLastThumbnail != thumbnail) {
427 mLastThumbnail = thumbnail;
428 if (thumbnail == null) {
429 if (mLastThumbnailFile != null) {
430 mLastThumbnailFile.delete();
431 }
432 } else {
433 mService.mTaskPersister.saveImage(thumbnail, mFilename);
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700434 }
Winson Chung096f36b2014-08-20 15:39:01 -0700435 return true;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700436 }
Winson Chung096f36b2014-08-20 15:39:01 -0700437 return false;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700438 }
439
440 void getLastThumbnail(TaskThumbnail thumbs) {
441 thumbs.mainThumbnail = mLastThumbnail;
442 thumbs.thumbnailFileDescriptor = null;
Craig Mautnerf4f8bb72014-07-29 10:41:40 -0700443 if (mLastThumbnail == null) {
444 thumbs.mainThumbnail = mService.mTaskPersister.getThumbnail(mFilename);
445 }
Winson Chung096f36b2014-08-20 15:39:01 -0700446 // Only load the thumbnail file if we don't have a thumbnail
447 if (thumbs.mainThumbnail == null && mLastThumbnailFile.exists()) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700448 try {
449 thumbs.thumbnailFileDescriptor = ParcelFileDescriptor.open(mLastThumbnailFile,
450 ParcelFileDescriptor.MODE_READ_ONLY);
451 } catch (IOException e) {
Dianne Hackborn9844d292013-10-04 16:44:22 -0700452 }
453 }
454 }
455
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700456 void freeLastThumbnail() {
457 mLastThumbnail = null;
458 }
459
460 void disposeThumbnail() {
461 mLastThumbnail = null;
462 lastDescription = null;
463 }
464
Winson Chung1147c402014-05-14 11:05:00 -0700465 /** Returns the intent for the root activity for this task */
466 Intent getBaseIntent() {
467 return intent != null ? intent : affinityIntent;
468 }
469
Winson Chung3b3f4642014-04-22 10:08:18 -0700470 /** Returns the first non-finishing activity from the root. */
471 ActivityRecord getRootActivity() {
472 for (int i = 0; i < mActivities.size(); i++) {
473 final ActivityRecord r = mActivities.get(i);
474 if (r.finishing) {
475 continue;
476 }
477 return r;
478 }
479 return null;
480 }
481
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800482 ActivityRecord getTopActivity() {
483 for (int i = mActivities.size() - 1; i >= 0; --i) {
484 final ActivityRecord r = mActivities.get(i);
485 if (r.finishing) {
486 continue;
487 }
488 return r;
489 }
490 return null;
491 }
492
Craig Mautner6b74cb52013-09-27 17:02:21 -0700493 ActivityRecord topRunningActivityLocked(ActivityRecord notTop) {
494 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
495 ActivityRecord r = mActivities.get(activityNdx);
Amith Yamasani734983f2014-03-04 16:48:05 -0800496 if (!r.finishing && r != notTop && stack.okToShowLocked(r)) {
Craig Mautner6b74cb52013-09-27 17:02:21 -0700497 return r;
498 }
499 }
500 return null;
501 }
502
Craig Mautner3b475fe2013-12-16 15:58:31 -0800503 /** Call after activity movement or finish to make sure that frontOfTask is set correctly */
504 final void setFrontOfTask() {
505 boolean foundFront = false;
506 final int numActivities = mActivities.size();
Craig Mautner704e40b2013-12-18 16:43:51 -0800507 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
Craig Mautner3b475fe2013-12-16 15:58:31 -0800508 final ActivityRecord r = mActivities.get(activityNdx);
509 if (foundFront || r.finishing) {
510 r.frontOfTask = false;
511 } else {
512 r.frontOfTask = true;
513 // Set frontOfTask false for every following activity.
514 foundFront = true;
515 }
516 }
Craig Mautner9587ee02014-06-23 15:00:10 +0000517 if (!foundFront && numActivities > 0) {
518 // All activities of this task are finishing. As we ought to have a frontOfTask
519 // activity, make the bottom activity front.
520 mActivities.get(0).frontOfTask = true;
521 }
Craig Mautner3b475fe2013-12-16 15:58:31 -0800522 }
523
Craig Mautnerde4ef022013-04-07 19:01:33 -0700524 /**
Craig Mautner3b475fe2013-12-16 15:58:31 -0800525 * Reorder the history stack so that the passed activity is brought to the front.
Craig Mautnerde4ef022013-04-07 19:01:33 -0700526 */
527 final void moveActivityToFrontLocked(ActivityRecord newTop) {
528 if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Removing and adding activity " + newTop
529 + " to stack at top", new RuntimeException("here").fillInStackTrace());
530
Craig Mautnerde4ef022013-04-07 19:01:33 -0700531 mActivities.remove(newTop);
532 mActivities.add(newTop);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700533 updateEffectiveIntent();
Craig Mautner3b475fe2013-12-16 15:58:31 -0800534
535 setFrontOfTask();
Craig Mautnerde4ef022013-04-07 19:01:33 -0700536 }
537
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800538 void addActivityAtBottom(ActivityRecord r) {
Craig Mautner77878772013-03-04 19:46:24 -0800539 addActivityAtIndex(0, r);
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800540 }
541
542 void addActivityToTop(ActivityRecord r) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700543 addActivityAtIndex(mActivities.size(), r);
544 }
545
546 void addActivityAtIndex(int index, ActivityRecord r) {
Craig Mautner6170f732013-04-02 13:05:23 -0700547 // 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 -0800548 if (!mActivities.remove(r) && r.fullscreen) {
549 // Was not previously in list.
550 numFullscreen++;
551 }
Craig Mautner2c1faed2013-07-23 12:56:02 -0700552 // Only set this based on the first activity
553 if (mActivities.isEmpty()) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700554 taskType = r.mActivityType;
555 isPersistable = r.isPersistable();
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700556 mCallingUid = r.launchedFromUid;
557 mCallingPackage = r.launchedFromPackage;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700558 // Clamp to [1, max].
559 maxRecents = Math.min(Math.max(r.info.maxRecents, 1),
560 ActivityManager.getMaxAppRecentsLimitStatic());
Craig Mautner2c1faed2013-07-23 12:56:02 -0700561 } else {
562 // Otherwise make all added activities match this one.
Craig Mautner21d24a22014-04-23 11:45:37 -0700563 r.mActivityType = taskType;
Craig Mautner78733002013-06-10 13:54:49 -0700564 }
Craig Mautner77878772013-03-04 19:46:24 -0800565 mActivities.add(index, r);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700566 updateEffectiveIntent();
Craig Mautner21d24a22014-04-23 11:45:37 -0700567 if (r.isPersistable()) {
568 mService.notifyTaskPersisterLocked(this, false);
569 }
Craig Mautner77878772013-03-04 19:46:24 -0800570 }
571
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800572 /** @return true if this was the last activity in the task */
573 boolean removeActivity(ActivityRecord r) {
574 if (mActivities.remove(r) && r.fullscreen) {
575 // Was previously in list.
576 numFullscreen--;
577 }
Craig Mautner21d24a22014-04-23 11:45:37 -0700578 if (r.isPersistable()) {
579 mService.notifyTaskPersisterLocked(this, false);
580 }
Craig Mautner41326202014-06-20 14:38:21 -0700581 if (mActivities.isEmpty()) {
Craig Mautner5afcd4d2014-06-21 18:11:33 -0700582 return !mReuseTask;
Craig Mautner41326202014-06-20 14:38:21 -0700583 }
584 updateEffectiveIntent();
585 return false;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800586 }
587
Craig Mautner41db4a72014-05-07 17:20:56 -0700588 boolean autoRemoveFromRecents() {
Dianne Hackbornd38aed82014-06-10 21:36:35 -0700589 // We will automatically remove the task either if it has explicitly asked for
590 // this, or it is empty and has never contained an activity that got shown to
591 // the user.
Dianne Hackborn13420f22014-07-18 15:43:56 -0700592 return autoRemoveRecents || (mActivities.isEmpty() && !hasBeenVisible);
Craig Mautner41db4a72014-05-07 17:20:56 -0700593 }
594
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700595 /**
596 * Completely remove all activities associated with an existing
597 * task starting at a specified index.
598 */
599 final void performClearTaskAtIndexLocked(int activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700600 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700601 for ( ; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700602 final ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700603 if (r.finishing) {
604 continue;
605 }
Craig Mautner21d24a22014-04-23 11:45:37 -0700606 if (stack == null) {
607 // Task was restored from persistent storage.
608 r.takeFromHistory();
609 mActivities.remove(activityNdx);
610 --activityNdx;
611 --numActivities;
612 } else if (stack.finishActivityLocked(r, Activity.RESULT_CANCELED, null, "clear",
613 false)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700614 --activityNdx;
615 --numActivities;
616 }
617 }
618 }
619
620 /**
621 * Completely remove all activities associated with an existing task.
622 */
623 final void performClearTaskLocked() {
Craig Mautner362449a2014-06-20 14:04:39 -0700624 mReuseTask = true;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700625 performClearTaskAtIndexLocked(0);
Craig Mautner362449a2014-06-20 14:04:39 -0700626 mReuseTask = false;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700627 }
628
629 /**
630 * Perform clear operation as requested by
631 * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the
632 * stack to the given task, then look for
633 * an instance of that activity in the stack and, if found, finish all
634 * activities on top of it and return the instance.
635 *
636 * @param newR Description of the new activity being started.
637 * @return Returns the old activity that should be continued to be used,
638 * or null if none was found.
639 */
640 final ActivityRecord performClearTaskLocked(ActivityRecord newR, int launchFlags) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700641 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700642 for (int activityNdx = numActivities - 1; activityNdx >= 0; --activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700643 ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700644 if (r.finishing) {
645 continue;
646 }
647 if (r.realActivity.equals(newR.realActivity)) {
648 // Here it is! Now finish everything in front...
Craig Mautner1602ec22013-05-12 10:24:27 -0700649 final ActivityRecord ret = r;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700650
651 for (++activityNdx; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700652 r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700653 if (r.finishing) {
654 continue;
655 }
656 ActivityOptions opts = r.takeOptionsLocked();
657 if (opts != null) {
658 ret.updateOptionsLocked(opts);
659 }
660 if (stack.finishActivityLocked(r, Activity.RESULT_CANCELED, null, "clear",
661 false)) {
662 --activityNdx;
663 --numActivities;
664 }
665 }
666
667 // Finally, if this is a normal launch mode (that is, not
668 // expecting onNewIntent()), then we will finish the current
669 // instance of the activity so a new fresh one can be started.
670 if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE
671 && (launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0) {
672 if (!ret.finishing) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700673 stack.finishActivityLocked(ret, Activity.RESULT_CANCELED, null,
674 "clear", false);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700675 return null;
676 }
677 }
678
679 return ret;
680 }
681 }
682
683 return null;
684 }
685
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700686 public TaskThumbnail getTaskThumbnailLocked() {
Craig Mautner21d24a22014-04-23 11:45:37 -0700687 if (stack != null) {
688 final ActivityRecord resumedActivity = stack.mResumedActivity;
689 if (resumedActivity != null && resumedActivity.task == this) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700690 final Bitmap thumbnail = stack.screenshotActivities(resumedActivity);
691 setLastThumbnail(thumbnail);
Craig Mautner21d24a22014-04-23 11:45:37 -0700692 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700693 }
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700694 final TaskThumbnail taskThumbnail = new TaskThumbnail();
695 getLastThumbnail(taskThumbnail);
696 return taskThumbnail;
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700697 }
698
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700699 public void removeTaskActivitiesLocked() {
700 // Just remove the entire task.
701 performClearTaskAtIndexLocked(0);
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700702 }
703
Craig Mautnera82aa092013-09-13 15:34:08 -0700704 boolean isHomeTask() {
Craig Mautner84984fa2014-06-19 11:19:20 -0700705 return taskType == HOME_ACTIVITY_TYPE;
Craig Mautnera82aa092013-09-13 15:34:08 -0700706 }
707
Craig Mautner86d67a42013-05-14 10:34:38 -0700708 boolean isApplicationTask() {
Craig Mautner84984fa2014-06-19 11:19:20 -0700709 return taskType == APPLICATION_ACTIVITY_TYPE;
710 }
711
712 boolean isOverHomeStack() {
713 return mTaskToReturnTo == HOME_ACTIVITY_TYPE || mTaskToReturnTo == RECENTS_ACTIVITY_TYPE;
Craig Mautner1602ec22013-05-12 10:24:27 -0700714 }
715
Craig Mautner525f3d92013-05-07 14:01:50 -0700716 /**
717 * Find the activity in the history stack within the given task. Returns
718 * the index within the history at which it's found, or < 0 if not found.
719 */
720 final ActivityRecord findActivityInHistoryLocked(ActivityRecord r) {
721 final ComponentName realActivity = r.realActivity;
722 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
723 ActivityRecord candidate = mActivities.get(activityNdx);
724 if (candidate.finishing) {
725 continue;
726 }
727 if (candidate.realActivity.equals(realActivity)) {
728 return candidate;
729 }
730 }
731 return null;
732 }
733
Winson Chunga449dc02014-05-16 11:15:04 -0700734 /** Updates the last task description values. */
735 void updateTaskDescription() {
736 // Traverse upwards looking for any break between main task activities and
737 // utility activities.
738 int activityNdx;
739 final int numActivities = mActivities.size();
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700740 final boolean relinquish = numActivities == 0 ? false :
741 (mActivities.get(0).info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) != 0;
Winson Chunga449dc02014-05-16 11:15:04 -0700742 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
Craig Mautner21d24a22014-04-23 11:45:37 -0700743 ++activityNdx) {
Winson Chunga449dc02014-05-16 11:15:04 -0700744 final ActivityRecord r = mActivities.get(activityNdx);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700745 if (relinquish && (r.info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
746 // This will be the top activity for determining taskDescription. Pre-inc to
747 // overcome initial decrement below.
748 ++activityNdx;
749 break;
750 }
Winson Chunga449dc02014-05-16 11:15:04 -0700751 if (r.intent != null &&
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700752 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
Winson Chunga449dc02014-05-16 11:15:04 -0700753 break;
754 }
755 }
756 if (activityNdx > 0) {
757 // Traverse downwards starting below break looking for set label, icon.
758 // Note that if there are activities in the task but none of them set the
759 // recent activity values, then we do not fall back to the last set
760 // values in the TaskRecord.
761 String label = null;
762 Bitmap icon = null;
763 int colorPrimary = 0;
764 for (--activityNdx; activityNdx >= 0; --activityNdx) {
765 final ActivityRecord r = mActivities.get(activityNdx);
766 if (r.taskDescription != null) {
767 if (label == null) {
768 label = r.taskDescription.getLabel();
769 }
770 if (icon == null) {
771 icon = r.taskDescription.getIcon();
772 }
773 if (colorPrimary == 0) {
774 colorPrimary = r.taskDescription.getPrimaryColor();
Winson Chunga449dc02014-05-16 11:15:04 -0700775 }
776 }
777 }
778 lastTaskDescription = new ActivityManager.TaskDescription(label, icon, colorPrimary);
Winson Chungec396d62014-08-06 17:08:00 -0700779 // Update the task affiliation color if we are the parent of the group
780 if (taskId == mAffiliatedTaskId) {
781 mAffiliatedTaskColor = lastTaskDescription.getPrimaryColor();
782 }
Winson Chunga449dc02014-05-16 11:15:04 -0700783 }
784 }
785
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700786 int findEffectiveRootIndex() {
787 int activityNdx;
788 final int topActivityNdx = mActivities.size() - 1;
789 for (activityNdx = 0; activityNdx < topActivityNdx; ++activityNdx) {
790 final ActivityRecord r = mActivities.get(activityNdx);
791 if (r.finishing) {
792 continue;
793 }
794 if ((r.info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
795 break;
796 }
797 }
798 return activityNdx;
799 }
800
801 void updateEffectiveIntent() {
802 final int effectiveRootIndex = findEffectiveRootIndex();
803 final ActivityRecord r = mActivities.get(effectiveRootIndex);
Winson Chungfee26772014-08-05 12:21:52 -0700804 setIntent(r);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700805 }
806
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700807 void saveTaskDescription(ActivityManager.TaskDescription taskDescription,
808 String iconFilename, XmlSerializer out) throws IOException {
809 if (taskDescription != null) {
810 final String label = taskDescription.getLabel();
811 if (label != null) {
812 out.attribute(null, ATTR_TASKDESCRIPTIONLABEL, label);
813 }
814 final int colorPrimary = taskDescription.getPrimaryColor();
815 if (colorPrimary != 0) {
816 out.attribute(null, ATTR_TASKDESCRIPTIONCOLOR, Integer.toHexString(colorPrimary));
817 }
818 final Bitmap icon = taskDescription.getIcon();
819 if (icon != null) {
820 mService.mTaskPersister.saveImage(icon, iconFilename);
821 }
822 }
823 }
824
825 static boolean readTaskDescriptionAttribute(ActivityManager.TaskDescription taskDescription,
826 String attrName, String attrValue) {
827 if (ATTR_TASKDESCRIPTIONLABEL.equals(attrName)) {
828 taskDescription.setLabel(attrValue);
829 } else if (ATTR_TASKDESCRIPTIONCOLOR.equals(attrName)) {
830 taskDescription.setPrimaryColor((int) Long.parseLong(attrValue, 16));
831 } else {
832 return false;
833 }
834 return true;
835 }
836
Winson Chung3bad5cc02014-08-19 17:44:32 -0700837 private static String createLastTaskDescriptionIconFilename(int taskId, long lastActiveTime) {
838 return String.valueOf(taskId) + LAST_ACTIVITY_ICON_SUFFIX + lastActiveTime +
839 TaskPersister.IMAGE_EXTENSION;
840 }
841
Craig Mautner21d24a22014-04-23 11:45:37 -0700842 void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700843 if (ActivityManagerService.DEBUG_RECENTS) Slog.i(TAG, "Saving task=" + this);
Craig Mautner21d24a22014-04-23 11:45:37 -0700844
845 out.attribute(null, ATTR_TASKID, String.valueOf(taskId));
846 if (realActivity != null) {
847 out.attribute(null, ATTR_REALACTIVITY, realActivity.flattenToShortString());
848 }
849 if (origActivity != null) {
850 out.attribute(null, ATTR_ORIGACTIVITY, origActivity.flattenToShortString());
851 }
Dianne Hackborn79228822014-09-16 11:11:23 -0700852 // Write affinity, and root affinity if it is different from affinity.
853 // We use the special string "@" for a null root affinity, so we can identify
854 // later whether we were given a root affinity or should just make it the
855 // same as the affinity.
Craig Mautner21d24a22014-04-23 11:45:37 -0700856 if (affinity != null) {
857 out.attribute(null, ATTR_AFFINITY, affinity);
Dianne Hackborn79228822014-09-16 11:11:23 -0700858 if (!affinity.equals(rootAffinity)) {
859 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
860 }
861 } else if (rootAffinity != null) {
862 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
Craig Mautner21d24a22014-04-23 11:45:37 -0700863 }
864 out.attribute(null, ATTR_ROOTHASRESET, String.valueOf(rootWasReset));
Dianne Hackborn13420f22014-07-18 15:43:56 -0700865 out.attribute(null, ATTR_AUTOREMOVERECENTS, String.valueOf(autoRemoveRecents));
Craig Mautner21d24a22014-04-23 11:45:37 -0700866 out.attribute(null, ATTR_ASKEDCOMPATMODE, String.valueOf(askedCompatMode));
867 out.attribute(null, ATTR_USERID, String.valueOf(userId));
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700868 out.attribute(null, ATTR_EFFECTIVE_UID, String.valueOf(effectiveUid));
Craig Mautner21d24a22014-04-23 11:45:37 -0700869 out.attribute(null, ATTR_TASKTYPE, String.valueOf(taskType));
Winson Chungffa2ec62014-07-03 15:54:42 -0700870 out.attribute(null, ATTR_FIRSTACTIVETIME, String.valueOf(firstActiveTime));
Winson Chungf1fbd772014-06-24 18:06:58 -0700871 out.attribute(null, ATTR_LASTACTIVETIME, String.valueOf(lastActiveTime));
Craig Mautner21d24a22014-04-23 11:45:37 -0700872 out.attribute(null, ATTR_LASTTIMEMOVED, String.valueOf(mLastTimeMoved));
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700873 out.attribute(null, ATTR_NEVERRELINQUISH, String.valueOf(mNeverRelinquishIdentity));
Craig Mautner21d24a22014-04-23 11:45:37 -0700874 if (lastDescription != null) {
875 out.attribute(null, ATTR_LASTDESCRIPTION, lastDescription.toString());
876 }
Winson Chung2cb86c72014-06-25 12:03:30 -0700877 if (lastTaskDescription != null) {
Winson Chung3bad5cc02014-08-19 17:44:32 -0700878 saveTaskDescription(lastTaskDescription, createLastTaskDescriptionIconFilename(taskId,
879 lastActiveTime), out);
Winson Chung2cb86c72014-06-25 12:03:30 -0700880 }
Winson Chungec396d62014-08-06 17:08:00 -0700881 out.attribute(null, ATTR_TASK_AFFILIATION_COLOR, String.valueOf(mAffiliatedTaskColor));
Craig Mautnera228ae92014-07-09 05:44:55 -0700882 out.attribute(null, ATTR_TASK_AFFILIATION, String.valueOf(mAffiliatedTaskId));
883 out.attribute(null, ATTR_PREV_AFFILIATION, String.valueOf(mPrevAffiliateTaskId));
884 out.attribute(null, ATTR_NEXT_AFFILIATION, String.valueOf(mNextAffiliateTaskId));
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700885 out.attribute(null, ATTR_CALLING_UID, String.valueOf(mCallingUid));
886 out.attribute(null, ATTR_CALLING_PACKAGE, mCallingPackage == null ? "" : mCallingPackage);
Winson Chung2cb86c72014-06-25 12:03:30 -0700887
Craig Mautner21d24a22014-04-23 11:45:37 -0700888 if (affinityIntent != null) {
889 out.startTag(null, TAG_AFFINITYINTENT);
890 affinityIntent.saveToXml(out);
891 out.endTag(null, TAG_AFFINITYINTENT);
892 }
893
894 out.startTag(null, TAG_INTENT);
895 intent.saveToXml(out);
896 out.endTag(null, TAG_INTENT);
897
898 final ArrayList<ActivityRecord> activities = mActivities;
899 final int numActivities = activities.size();
900 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
901 final ActivityRecord r = activities.get(activityNdx);
Craig Mautner43e52ed2014-06-16 17:18:52 -0700902 if (r.info.persistableMode == ActivityInfo.PERSIST_ROOT_ONLY || !r.isPersistable() ||
903 ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) &&
904 activityNdx > 0) {
Craig Mautnerf357c0c2014-06-09 09:23:27 -0700905 // Stop at first non-persistable or first break in task (CLEAR_WHEN_TASK_RESET).
Craig Mautner21d24a22014-04-23 11:45:37 -0700906 break;
907 }
908 out.startTag(null, TAG_ACTIVITY);
909 r.saveToXml(out);
910 out.endTag(null, TAG_ACTIVITY);
911 }
Craig Mautner21d24a22014-04-23 11:45:37 -0700912 }
913
914 static TaskRecord restoreFromXml(XmlPullParser in, ActivityStackSupervisor stackSupervisor)
915 throws IOException, XmlPullParserException {
916 Intent intent = null;
917 Intent affinityIntent = null;
918 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
919 ComponentName realActivity = null;
920 ComponentName origActivity = null;
921 String affinity = null;
Dianne Hackborn79228822014-09-16 11:11:23 -0700922 String rootAffinity = null;
923 boolean hasRootAffinity = false;
Craig Mautner21d24a22014-04-23 11:45:37 -0700924 boolean rootHasReset = false;
Dianne Hackborn13420f22014-07-18 15:43:56 -0700925 boolean autoRemoveRecents = false;
Craig Mautner21d24a22014-04-23 11:45:37 -0700926 boolean askedCompatMode = false;
927 int taskType = ActivityRecord.APPLICATION_ACTIVITY_TYPE;
Craig Mautner21d24a22014-04-23 11:45:37 -0700928 int userId = 0;
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700929 int effectiveUid = -1;
Craig Mautner21d24a22014-04-23 11:45:37 -0700930 String lastDescription = null;
Winson Chungffa2ec62014-07-03 15:54:42 -0700931 long firstActiveTime = -1;
Winson Chung2cb86c72014-06-25 12:03:30 -0700932 long lastActiveTime = -1;
Craig Mautner21d24a22014-04-23 11:45:37 -0700933 long lastTimeOnTop = 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700934 boolean neverRelinquishIdentity = true;
Craig Mautner21d24a22014-04-23 11:45:37 -0700935 int taskId = -1;
936 final int outerDepth = in.getDepth();
Winson Chung2cb86c72014-06-25 12:03:30 -0700937 ActivityManager.TaskDescription taskDescription = new ActivityManager.TaskDescription();
Craig Mautnera228ae92014-07-09 05:44:55 -0700938 int taskAffiliation = -1;
Winson Chungec396d62014-08-06 17:08:00 -0700939 int taskAffiliationColor = 0;
Craig Mautnera228ae92014-07-09 05:44:55 -0700940 int prevTaskId = -1;
941 int nextTaskId = -1;
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700942 int callingUid = -1;
943 String callingPackage = "";
Craig Mautner21d24a22014-04-23 11:45:37 -0700944
945 for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
946 final String attrName = in.getAttributeName(attrNdx);
947 final String attrValue = in.getAttributeValue(attrNdx);
948 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: attribute name=" +
949 attrName + " value=" + attrValue);
950 if (ATTR_TASKID.equals(attrName)) {
951 taskId = Integer.valueOf(attrValue);
952 } else if (ATTR_REALACTIVITY.equals(attrName)) {
953 realActivity = ComponentName.unflattenFromString(attrValue);
954 } else if (ATTR_ORIGACTIVITY.equals(attrName)) {
955 origActivity = ComponentName.unflattenFromString(attrValue);
956 } else if (ATTR_AFFINITY.equals(attrName)) {
957 affinity = attrValue;
Dianne Hackborn79228822014-09-16 11:11:23 -0700958 } else if (ATTR_ROOT_AFFINITY.equals(attrName)) {
959 rootAffinity = attrValue;
960 hasRootAffinity = true;
Craig Mautner21d24a22014-04-23 11:45:37 -0700961 } else if (ATTR_ROOTHASRESET.equals(attrName)) {
962 rootHasReset = Boolean.valueOf(attrValue);
Dianne Hackborn13420f22014-07-18 15:43:56 -0700963 } else if (ATTR_AUTOREMOVERECENTS.equals(attrName)) {
964 autoRemoveRecents = Boolean.valueOf(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -0700965 } else if (ATTR_ASKEDCOMPATMODE.equals(attrName)) {
966 askedCompatMode = Boolean.valueOf(attrValue);
967 } else if (ATTR_USERID.equals(attrName)) {
968 userId = Integer.valueOf(attrValue);
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700969 } else if (ATTR_EFFECTIVE_UID.equals(attrName)) {
970 effectiveUid = Integer.valueOf(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -0700971 } else if (ATTR_TASKTYPE.equals(attrName)) {
972 taskType = Integer.valueOf(attrValue);
Winson Chungffa2ec62014-07-03 15:54:42 -0700973 } else if (ATTR_FIRSTACTIVETIME.equals(attrName)) {
974 firstActiveTime = Long.valueOf(attrValue);
Winson Chungf1fbd772014-06-24 18:06:58 -0700975 } else if (ATTR_LASTACTIVETIME.equals(attrName)) {
976 lastActiveTime = Long.valueOf(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -0700977 } else if (ATTR_LASTDESCRIPTION.equals(attrName)) {
978 lastDescription = attrValue;
979 } else if (ATTR_LASTTIMEMOVED.equals(attrName)) {
980 lastTimeOnTop = Long.valueOf(attrValue);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700981 } else if (ATTR_NEVERRELINQUISH.equals(attrName)) {
982 neverRelinquishIdentity = Boolean.valueOf(attrValue);
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700983 } else if (readTaskDescriptionAttribute(taskDescription, attrName, attrValue)) {
Winson Chung2cb86c72014-06-25 12:03:30 -0700984 // Completed in TaskPersister.readTaskDescriptionAttribute()
Craig Mautnera228ae92014-07-09 05:44:55 -0700985 } else if (ATTR_TASK_AFFILIATION.equals(attrName)) {
986 taskAffiliation = Integer.valueOf(attrValue);
987 } else if (ATTR_PREV_AFFILIATION.equals(attrName)) {
988 prevTaskId = Integer.valueOf(attrValue);
989 } else if (ATTR_NEXT_AFFILIATION.equals(attrName)) {
990 nextTaskId = Integer.valueOf(attrValue);
Winson Chungec396d62014-08-06 17:08:00 -0700991 } else if (ATTR_TASK_AFFILIATION_COLOR.equals(attrName)) {
992 taskAffiliationColor = Integer.valueOf(attrValue);
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700993 } else if (ATTR_CALLING_UID.equals(attrName)) {
994 callingUid = Integer.valueOf(attrValue);
995 } else if (ATTR_CALLING_PACKAGE.equals(attrName)) {
996 callingPackage = attrValue;
Craig Mautner21d24a22014-04-23 11:45:37 -0700997 } else {
998 Slog.w(TAG, "TaskRecord: Unknown attribute=" + attrName);
999 }
1000 }
1001
1002 int event;
1003 while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
1004 (event != XmlPullParser.END_TAG || in.getDepth() < outerDepth)) {
1005 if (event == XmlPullParser.START_TAG) {
1006 final String name = in.getName();
1007 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: START_TAG name=" +
1008 name);
1009 if (TAG_AFFINITYINTENT.equals(name)) {
1010 affinityIntent = Intent.restoreFromXml(in);
1011 } else if (TAG_INTENT.equals(name)) {
1012 intent = Intent.restoreFromXml(in);
1013 } else if (TAG_ACTIVITY.equals(name)) {
1014 ActivityRecord activity =
1015 ActivityRecord.restoreFromXml(in, taskId, stackSupervisor);
1016 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: activity=" +
1017 activity);
1018 if (activity != null) {
1019 activities.add(activity);
1020 }
1021 } else {
1022 Slog.e(TAG, "restoreTask: Unexpected name=" + name);
1023 XmlUtils.skipCurrentTag(in);
1024 }
1025 }
1026 }
1027
Winson Chung2cb86c72014-06-25 12:03:30 -07001028 if (lastActiveTime >= 0) {
Winson Chung3bad5cc02014-08-19 17:44:32 -07001029 taskDescription.setIcon(TaskPersister.restoreImage(
1030 createLastTaskDescriptionIconFilename(taskId, lastActiveTime)));
Winson Chung2cb86c72014-06-25 12:03:30 -07001031 }
1032
Dianne Hackborn79228822014-09-16 11:11:23 -07001033 if (!hasRootAffinity) {
1034 rootAffinity = affinity;
1035 } else if ("@".equals(rootAffinity)) {
1036 rootAffinity = null;
1037 }
1038
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001039 if (effectiveUid <= 0) {
1040 Intent checkIntent = intent != null ? intent : affinityIntent;
1041 effectiveUid = 0;
1042 if (checkIntent != null) {
1043 IPackageManager pm = AppGlobals.getPackageManager();
1044 try {
1045 ApplicationInfo ai = pm.getApplicationInfo(
1046 checkIntent.getComponent().getPackageName(),
1047 PackageManager.GET_UNINSTALLED_PACKAGES
1048 | PackageManager.GET_DISABLED_COMPONENTS, userId);
1049 if (ai != null) {
1050 effectiveUid = ai.uid;
1051 }
1052 } catch (RemoteException e) {
1053 }
1054 }
1055 Slog.w(TAG, "Updating task #" + taskId + " for " + checkIntent
1056 + ": effectiveUid=" + effectiveUid);
1057 }
1058
Craig Mautner21d24a22014-04-23 11:45:37 -07001059 final TaskRecord task = new TaskRecord(stackSupervisor.mService, taskId, intent,
Dianne Hackborn79228822014-09-16 11:11:23 -07001060 affinityIntent, affinity, rootAffinity, realActivity, origActivity, rootHasReset,
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001061 autoRemoveRecents, askedCompatMode, taskType, userId, effectiveUid, lastDescription,
1062 activities, firstActiveTime, lastActiveTime, lastTimeOnTop, neverRelinquishIdentity,
Winson Chungec396d62014-08-06 17:08:00 -07001063 taskDescription, taskAffiliation, prevTaskId, nextTaskId, taskAffiliationColor,
1064 callingUid, callingPackage);
Craig Mautner21d24a22014-04-23 11:45:37 -07001065
1066 for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001067 activities.get(activityNdx).task = task;
Craig Mautner21d24a22014-04-23 11:45:37 -07001068 }
1069
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001070 if (ActivityManagerService.DEBUG_RECENTS) Slog.d(TAG, "Restored task=" + task);
Craig Mautner21d24a22014-04-23 11:45:37 -07001071 return task;
1072 }
1073
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001074 void dump(PrintWriter pw, String prefix) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001075 pw.print(prefix); pw.print("userId="); pw.print(userId);
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001076 pw.print(" effectiveUid="); UserHandle.formatUid(pw, effectiveUid);
1077 pw.print(" mCallingUid="); UserHandle.formatUid(pw, mCallingUid);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001078 pw.print(" mCallingPackage="); pw.println(mCallingPackage);
Dianne Hackborn79228822014-09-16 11:11:23 -07001079 if (affinity != null || rootAffinity != null) {
1080 pw.print(prefix); pw.print("affinity="); pw.print(affinity);
1081 if (affinity == null || !affinity.equals(rootAffinity)) {
1082 pw.print(" root="); pw.println(rootAffinity);
1083 } else {
1084 pw.println();
1085 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001086 }
Dianne Hackborn91097de2014-04-04 18:02:06 -07001087 if (voiceSession != null || voiceInteractor != null) {
1088 pw.print(prefix); pw.print("VOICE: session=0x");
1089 pw.print(Integer.toHexString(System.identityHashCode(voiceSession)));
1090 pw.print(" interactor=0x");
1091 pw.println(Integer.toHexString(System.identityHashCode(voiceInteractor)));
1092 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001093 if (intent != null) {
1094 StringBuilder sb = new StringBuilder(128);
1095 sb.append(prefix); sb.append("intent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08001096 intent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001097 sb.append('}');
1098 pw.println(sb.toString());
1099 }
1100 if (affinityIntent != null) {
1101 StringBuilder sb = new StringBuilder(128);
1102 sb.append(prefix); sb.append("affinityIntent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08001103 affinityIntent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001104 sb.append('}');
1105 pw.println(sb.toString());
1106 }
1107 if (origActivity != null) {
1108 pw.print(prefix); pw.print("origActivity=");
1109 pw.println(origActivity.flattenToShortString());
1110 }
1111 if (realActivity != null) {
1112 pw.print(prefix); pw.print("realActivity=");
1113 pw.println(realActivity.flattenToShortString());
1114 }
Dianne Hackborn852975d2014-08-22 17:42:43 -07001115 if (autoRemoveRecents || isPersistable || taskType != 0 || mTaskToReturnTo != 0
1116 || numFullscreen != 0) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001117 pw.print(prefix); pw.print("autoRemoveRecents="); pw.print(autoRemoveRecents);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001118 pw.print(" isPersistable="); pw.print(isPersistable);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001119 pw.print(" numFullscreen="); pw.print(numFullscreen);
1120 pw.print(" taskType="); pw.print(taskType);
1121 pw.print(" mTaskToReturnTo="); pw.println(mTaskToReturnTo);
1122 }
1123 if (rootWasReset || mNeverRelinquishIdentity || mReuseTask) {
1124 pw.print(prefix); pw.print("rootWasReset="); pw.print(rootWasReset);
1125 pw.print(" mNeverRelinquishIdentity="); pw.print(mNeverRelinquishIdentity);
1126 pw.print(" mReuseTask="); pw.println(mReuseTask);
1127 }
Dianne Hackborn852975d2014-08-22 17:42:43 -07001128 if (mAffiliatedTaskId != taskId || mPrevAffiliateTaskId != -1 || mPrevAffiliate != null
1129 || mNextAffiliateTaskId != -1 || mNextAffiliate != null) {
1130 pw.print(prefix); pw.print("affiliation="); pw.print(mAffiliatedTaskId);
1131 pw.print(" prevAffiliation="); pw.print(mPrevAffiliateTaskId);
1132 pw.print(" (");
1133 if (mPrevAffiliate == null) {
1134 pw.print("null");
1135 } else {
1136 pw.print(Integer.toHexString(System.identityHashCode(mPrevAffiliate)));
1137 }
1138 pw.print(") nextAffiliation="); pw.print(mNextAffiliateTaskId);
1139 pw.print(" (");
1140 if (mNextAffiliate == null) {
1141 pw.print("null");
1142 } else {
1143 pw.print(Integer.toHexString(System.identityHashCode(mNextAffiliate)));
1144 }
1145 pw.println(")");
1146 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001147 pw.print(prefix); pw.print("Activities="); pw.println(mActivities);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001148 if (!askedCompatMode || !inRecents || !isAvailable) {
1149 pw.print(prefix); pw.print("askedCompatMode="); pw.print(askedCompatMode);
1150 pw.print(" inRecents="); pw.print(inRecents);
1151 pw.print(" isAvailable="); pw.println(isAvailable);
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001152 }
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001153 pw.print(prefix); pw.print("lastThumbnail="); pw.print(mLastThumbnail);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001154 pw.print(" lastThumbnailFile="); pw.println(mLastThumbnailFile);
1155 if (lastDescription != null) {
1156 pw.print(prefix); pw.print("lastDescription="); pw.println(lastDescription);
1157 }
Dianne Hackbornd38aed82014-06-10 21:36:35 -07001158 pw.print(prefix); pw.print("hasBeenVisible="); pw.print(hasBeenVisible);
Winson Chungffa2ec62014-07-03 15:54:42 -07001159 pw.print(" firstActiveTime="); pw.print(lastActiveTime);
Dianne Hackbornd38aed82014-06-10 21:36:35 -07001160 pw.print(" lastActiveTime="); pw.print(lastActiveTime);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001161 pw.print(" (inactive for ");
1162 pw.print((getInactiveDuration()/1000)); pw.println("s)");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001163 }
1164
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001165 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001166 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001167 StringBuilder sb = new StringBuilder(128);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001168 if (stringName != null) {
1169 sb.append(stringName);
1170 sb.append(" U=");
1171 sb.append(userId);
1172 sb.append(" sz=");
1173 sb.append(mActivities.size());
1174 sb.append('}');
1175 return sb.toString();
1176 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001177 sb.append("TaskRecord{");
1178 sb.append(Integer.toHexString(System.identityHashCode(this)));
1179 sb.append(" #");
1180 sb.append(taskId);
1181 if (affinity != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001182 sb.append(" A=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001183 sb.append(affinity);
1184 } else if (intent != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001185 sb.append(" I=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001186 sb.append(intent.getComponent().flattenToShortString());
1187 } else if (affinityIntent != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001188 sb.append(" aI=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001189 sb.append(affinityIntent.getComponent().flattenToShortString());
1190 } else {
1191 sb.append(" ??");
1192 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07001193 stringName = sb.toString();
1194 return toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001195 }
1196}