blob: 4dfd23b74bb8da9a34e719f0cae6f990cda8cd59 [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 Mautner648f69b2014-09-18 14:16:26 -070028import android.app.ActivityManager.TaskDescription;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -070029import android.app.ActivityOptions;
Dianne Hackborn885fbe52014-08-23 15:23:58 -070030import android.app.AppGlobals;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import android.content.ComponentName;
32import android.content.Intent;
33import android.content.pm.ActivityInfo;
Dianne Hackborn885fbe52014-08-23 15:23:58 -070034import android.content.pm.ApplicationInfo;
35import android.content.pm.IPackageManager;
36import android.content.pm.PackageManager;
Craig Mautner9db9a0b2013-04-29 17:05:56 -070037import android.graphics.Bitmap;
Craig Mautnerc0ffce52014-07-01 12:38:52 -070038import android.os.ParcelFileDescriptor;
Dianne Hackborn885fbe52014-08-23 15:23:58 -070039import android.os.RemoteException;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070040import android.os.UserHandle;
Dianne Hackborn91097de2014-04-04 18:02:06 -070041import android.service.voice.IVoiceInteractionSession;
Dianne Hackborn7f96b792012-05-29 18:46:45 -070042import android.util.Slog;
Dianne Hackborn91097de2014-04-04 18:02:06 -070043import com.android.internal.app.IVoiceInteractor;
Craig Mautner21d24a22014-04-23 11:45:37 -070044import com.android.internal.util.XmlUtils;
45import org.xmlpull.v1.XmlPullParser;
46import org.xmlpull.v1.XmlPullParserException;
47import org.xmlpull.v1.XmlSerializer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048
Craig Mautnerc0ffce52014-07-01 12:38:52 -070049import java.io.File;
Craig Mautner21d24a22014-04-23 11:45:37 -070050import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051import java.io.PrintWriter;
Craig Mautner5d9c7be2013-02-15 14:02:56 -080052import java.util.ArrayList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053
Craig Mautnerc0ffce52014-07-01 12:38:52 -070054final class TaskRecord {
Craig Mautner21d24a22014-04-23 11:45:37 -070055 private static final String ATTR_TASKID = "task_id";
56 private static final String TAG_INTENT = "intent";
57 private static final String TAG_AFFINITYINTENT = "affinity_intent";
58 private static final String ATTR_REALACTIVITY = "real_activity";
59 private static final String ATTR_ORIGACTIVITY = "orig_activity";
60 private static final String TAG_ACTIVITY = "activity";
61 private static final String ATTR_AFFINITY = "affinity";
Dianne Hackborn79228822014-09-16 11:11:23 -070062 private static final String ATTR_ROOT_AFFINITY = "root_affinity";
Craig Mautner21d24a22014-04-23 11:45:37 -070063 private static final String ATTR_ROOTHASRESET = "root_has_reset";
Dianne Hackborn13420f22014-07-18 15:43:56 -070064 private static final String ATTR_AUTOREMOVERECENTS = "auto_remove_recents";
Craig Mautner21d24a22014-04-23 11:45:37 -070065 private static final String ATTR_ASKEDCOMPATMODE = "asked_compat_mode";
66 private static final String ATTR_USERID = "user_id";
Dianne Hackborn885fbe52014-08-23 15:23:58 -070067 private static final String ATTR_EFFECTIVE_UID = "effective_uid";
Craig Mautner21d24a22014-04-23 11:45:37 -070068 private static final String ATTR_TASKTYPE = "task_type";
Winson Chungffa2ec62014-07-03 15:54:42 -070069 private static final String ATTR_FIRSTACTIVETIME = "first_active_time";
Winson Chungf1fbd772014-06-24 18:06:58 -070070 private static final String ATTR_LASTACTIVETIME = "last_active_time";
Craig Mautner21d24a22014-04-23 11:45:37 -070071 private static final String ATTR_LASTDESCRIPTION = "last_description";
72 private static final String ATTR_LASTTIMEMOVED = "last_time_moved";
Craig Mautner9d4e9bc2014-06-18 18:34:56 -070073 private static final String ATTR_NEVERRELINQUISH = "never_relinquish_identity";
Craig Mautnera228ae92014-07-09 05:44:55 -070074 private static final String ATTR_TASK_AFFILIATION = "task_affiliation";
75 private static final String ATTR_PREV_AFFILIATION = "prev_affiliation";
76 private static final String ATTR_NEXT_AFFILIATION = "next_affiliation";
Winson Chungec396d62014-08-06 17:08:00 -070077 private static final String ATTR_TASK_AFFILIATION_COLOR = "task_affiliation_color";
Craig Mautnerdc00cbe2014-07-20 17:48:47 -070078 private static final String ATTR_CALLING_UID = "calling_uid";
79 private static final String ATTR_CALLING_PACKAGE = "calling_package";
Craig Mautner21d24a22014-04-23 11:45:37 -070080
81 private static final String TASK_THUMBNAIL_SUFFIX = "_task_thumbnail";
82
Craig Mautner0b633fc2014-07-23 10:42:18 -070083 static final boolean IGNORE_RETURN_TO_RECENTS = true;
84
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085 final int taskId; // Unique identifier for this task.
Dianne Hackborn79228822014-09-16 11:11:23 -070086 String affinity; // The affinity name for this task, or null; may change identity.
87 String rootAffinity; // Initial base affinity, or null; does not change from initial root.
Dianne Hackborn91097de2014-04-04 18:02:06 -070088 final IVoiceInteractionSession voiceSession; // Voice interaction session driving task
89 final IVoiceInteractor voiceInteractor; // Associated interactor to provide to app
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090 Intent intent; // The original intent that started the task.
91 Intent affinityIntent; // Intent of affinity-moved activity that started this task.
Dianne Hackborn885fbe52014-08-23 15:23:58 -070092 int effectiveUid; // The current effective uid of the identity of this task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093 ComponentName origActivity; // The non-alias activity component of the intent.
94 ComponentName realActivity; // The actual activity component that started the task.
Winson Chungffa2ec62014-07-03 15:54:42 -070095 long firstActiveTime; // First time this task was active.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096 long lastActiveTime; // Last time this task was active, including sleep.
Dianne Hackborn852975d2014-08-22 17:42:43 -070097 boolean inRecents; // Actually in the recents list?
98 boolean isAvailable; // Is the activity available to be launched?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099 boolean rootWasReset; // True if the intent at the root of the task had
100 // the FLAG_ACTIVITY_RESET_TASK_IF_NEEDED flag.
Dianne Hackborn13420f22014-07-18 15:43:56 -0700101 boolean autoRemoveRecents; // If true, we should automatically remove the task from
102 // recents when activity finishes
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700103 boolean askedCompatMode;// Have asked the user about compat mode for this task.
Dianne Hackbornd38aed82014-06-10 21:36:35 -0700104 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 -0800105
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700106 String stringName; // caching of toString() result.
Dianne Hackborn9da2d402012-03-15 13:43:08 -0700107 int userId; // user for which this task was created
Dianne Hackborn09233282014-04-30 11:33:59 -0700108 int creatorUid; // The app uid that originally created the task
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800109
110 int numFullscreen; // Number of fullscreen activities.
111
Winson Chung03a9bae2014-05-02 09:56:12 -0700112 // This represents the last resolved activity values for this task
113 // NOTE: This value needs to be persisted with each task
Craig Mautner648f69b2014-09-18 14:16:26 -0700114 TaskDescription lastTaskDescription = new TaskDescription();
Winson Chung03a9bae2014-05-02 09:56:12 -0700115
Craig Mautnerd2328952013-03-05 12:46:26 -0800116 /** List of all activities in the task arranged in history order */
Craig Mautner21d24a22014-04-23 11:45:37 -0700117 final ArrayList<ActivityRecord> mActivities;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800118
Craig Mautnerd2328952013-03-05 12:46:26 -0800119 /** Current stack */
120 ActivityStack stack;
121
Craig Mautner2c1faed2013-07-23 12:56:02 -0700122 /** Takes on same set of values as ActivityRecord.mActivityType */
Craig Mautner21d24a22014-04-23 11:45:37 -0700123 int taskType;
Craig Mautner1602ec22013-05-12 10:24:27 -0700124
Craig Mautner21d24a22014-04-23 11:45:37 -0700125 /** Takes on same value as first root activity */
126 boolean isPersistable = false;
Craig Mautnerffcfcaa2014-06-05 09:54:38 -0700127 int maxRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700128
129 /** Only used for persistable tasks, otherwise 0. The last time this task was moved. Used for
130 * determining the order when restoring. Sign indicates whether last task movement was to front
131 * (positive) or back (negative). Absolute value indicates time. */
132 long mLastTimeMoved = System.currentTimeMillis();
133
Craig Mautner84984fa2014-06-19 11:19:20 -0700134 /** Indication of what to run next when task exits. Use ActivityRecord types.
135 * ActivityRecord.APPLICATION_ACTIVITY_TYPE indicates to resume the task below this one in the
136 * task stack. */
137 private int mTaskToReturnTo = APPLICATION_ACTIVITY_TYPE;
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700138
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700139 /** If original intent did not allow relinquishing task identity, save that information */
140 boolean mNeverRelinquishIdentity = true;
141
Craig Mautner362449a2014-06-20 14:04:39 -0700142 // Used in the unique case where we are clearing the task in order to reuse it. In that case we
143 // do not want to delete the stack when the task goes empty.
144 boolean mReuseTask = false;
145
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700146 private Bitmap mLastThumbnail; // Last thumbnail captured for this item.
147 private final File mLastThumbnailFile; // File containing last thubmnail.
148 private final String mFilename;
149 CharSequence lastDescription; // Last description captured for this item.
150
Craig Mautnera228ae92014-07-09 05:44:55 -0700151 int mAffiliatedTaskId; // taskId of parent affiliation or self if no parent.
Winson Chungec396d62014-08-06 17:08:00 -0700152 int mAffiliatedTaskColor; // color of the parent task affiliation.
Craig Mautnera228ae92014-07-09 05:44:55 -0700153 TaskRecord mPrevAffiliate; // previous task in affiliated chain.
154 int mPrevAffiliateTaskId = -1; // previous id for persistence.
155 TaskRecord mNextAffiliate; // next task in affiliated chain.
156 int mNextAffiliateTaskId = -1; // next id for persistence.
157
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700158 // For relaunching the task from recents as though it was launched by the original launcher.
159 int mCallingUid;
160 String mCallingPackage;
161
Craig Mautner21d24a22014-04-23 11:45:37 -0700162 final ActivityManagerService mService;
163
164 TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Dianne Hackborn91097de2014-04-04 18:02:06 -0700165 IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700166 mService = service;
Craig Mautnera228ae92014-07-09 05:44:55 -0700167 mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
168 TaskPersister.IMAGE_EXTENSION;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700169 mLastThumbnailFile = new File(TaskPersister.sImagesDir, mFilename);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170 taskId = _taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700171 mAffiliatedTaskId = _taskId;
Dianne Hackborn91097de2014-04-04 18:02:06 -0700172 voiceSession = _voiceSession;
173 voiceInteractor = _voiceInteractor;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700174 isAvailable = true;
Craig Mautner21d24a22014-04-23 11:45:37 -0700175 mActivities = new ArrayList<ActivityRecord>();
Martijn Coenend4a69702014-06-30 11:12:17 -0700176 setIntent(_intent, info);
Craig Mautner21d24a22014-04-23 11:45:37 -0700177 }
178
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700179 TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Craig Mautner648f69b2014-09-18 14:16:26 -0700180 TaskDescription _taskDescription) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700181 mService = service;
182 mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
183 TaskPersister.IMAGE_EXTENSION;
184 mLastThumbnailFile = new File(TaskPersister.sImagesDir, mFilename);
185 taskId = _taskId;
186 mAffiliatedTaskId = _taskId;
187 voiceSession = null;
188 voiceInteractor = null;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700189 isAvailable = true;
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700190 mActivities = new ArrayList<ActivityRecord>();
191 setIntent(_intent, info);
192
193 taskType = ActivityRecord.APPLICATION_ACTIVITY_TYPE;
194 isPersistable = true;
195 mCallingUid = info.applicationInfo.uid;
196 mCallingPackage = info.packageName;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700197 // Clamp to [1, max].
198 maxRecents = Math.min(Math.max(info.maxRecents, 1),
199 ActivityManager.getMaxAppRecentsLimitStatic());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700200
201 taskType = APPLICATION_ACTIVITY_TYPE;
202 mTaskToReturnTo = HOME_ACTIVITY_TYPE;
203 userId = UserHandle.getUserId(info.applicationInfo.uid);
204 lastTaskDescription = _taskDescription;
205 mCallingUid = info.applicationInfo.uid;
206 mCallingPackage = info.packageName;
207 }
208
Craig Mautner21d24a22014-04-23 11:45:37 -0700209 TaskRecord(ActivityManagerService service, int _taskId, Intent _intent, Intent _affinityIntent,
Dianne Hackborn79228822014-09-16 11:11:23 -0700210 String _affinity, String _rootAffinity, ComponentName _realActivity,
211 ComponentName _origActivity, boolean _rootWasReset, boolean _autoRemoveRecents,
212 boolean _askedCompatMode, int _taskType, int _userId, int _effectiveUid,
Winson Chungffa2ec62014-07-03 15:54:42 -0700213 String _lastDescription, ArrayList<ActivityRecord> activities, long _firstActiveTime,
214 long _lastActiveTime, long lastTimeMoved, boolean neverRelinquishIdentity,
Craig Mautner648f69b2014-09-18 14:16:26 -0700215 TaskDescription _lastTaskDescription, int taskAffiliation,
Winson Chungec396d62014-08-06 17:08:00 -0700216 int prevTaskId, int nextTaskId, int taskAffiliationColor, int callingUid,
217 String callingPackage) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700218 mService = service;
Craig Mautnera228ae92014-07-09 05:44:55 -0700219 mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
220 TaskPersister.IMAGE_EXTENSION;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700221 mLastThumbnailFile = new File(TaskPersister.sImagesDir, mFilename);
Craig Mautner21d24a22014-04-23 11:45:37 -0700222 taskId = _taskId;
223 intent = _intent;
224 affinityIntent = _affinityIntent;
225 affinity = _affinity;
Dianne Hackborn79228822014-09-16 11:11:23 -0700226 rootAffinity = _affinity;
Craig Mautner21d24a22014-04-23 11:45:37 -0700227 voiceSession = null;
228 voiceInteractor = null;
229 realActivity = _realActivity;
230 origActivity = _origActivity;
231 rootWasReset = _rootWasReset;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700232 isAvailable = true;
Dianne Hackborn13420f22014-07-18 15:43:56 -0700233 autoRemoveRecents = _autoRemoveRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700234 askedCompatMode = _askedCompatMode;
235 taskType = _taskType;
Craig Mautner84984fa2014-06-19 11:19:20 -0700236 mTaskToReturnTo = HOME_ACTIVITY_TYPE;
Craig Mautner21d24a22014-04-23 11:45:37 -0700237 userId = _userId;
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700238 effectiveUid = _effectiveUid;
Winson Chungffa2ec62014-07-03 15:54:42 -0700239 firstActiveTime = _firstActiveTime;
Winson Chungf1fbd772014-06-24 18:06:58 -0700240 lastActiveTime = _lastActiveTime;
Craig Mautner21d24a22014-04-23 11:45:37 -0700241 lastDescription = _lastDescription;
242 mActivities = activities;
243 mLastTimeMoved = lastTimeMoved;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700244 mNeverRelinquishIdentity = neverRelinquishIdentity;
Winson Chung2cb86c72014-06-25 12:03:30 -0700245 lastTaskDescription = _lastTaskDescription;
Craig Mautnera228ae92014-07-09 05:44:55 -0700246 mAffiliatedTaskId = taskAffiliation;
Winson Chungec396d62014-08-06 17:08:00 -0700247 mAffiliatedTaskColor = taskAffiliationColor;
Craig Mautnera228ae92014-07-09 05:44:55 -0700248 mPrevAffiliateTaskId = prevTaskId;
249 mNextAffiliateTaskId = nextTaskId;
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700250 mCallingUid = callingUid;
251 mCallingPackage = callingPackage;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800252 }
253
254 void touchActiveTime() {
Craig Mautner494f6bdd2014-07-21 11:17:46 -0700255 lastActiveTime = System.currentTimeMillis();
Winson Chungffa2ec62014-07-03 15:54:42 -0700256 if (firstActiveTime == 0) {
257 firstActiveTime = lastActiveTime;
258 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800259 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700260
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800261 long getInactiveDuration() {
Craig Mautner494f6bdd2014-07-21 11:17:46 -0700262 return System.currentTimeMillis() - lastActiveTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800263 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700264
Winson Chungfee26772014-08-05 12:21:52 -0700265 /** Sets the original intent, and the calling uid and package. */
266 void setIntent(ActivityRecord r) {
267 setIntent(r.intent, r.info);
268 mCallingUid = r.launchedFromUid;
269 mCallingPackage = r.launchedFromPackage;
270 }
271
272 /** Sets the original intent, _without_ updating the calling uid or package. */
273 private void setIntent(Intent _intent, ActivityInfo info) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700274 if (intent == null) {
275 mNeverRelinquishIdentity =
276 (info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) == 0;
277 } else if (mNeverRelinquishIdentity) {
278 return;
279 }
280
281 affinity = info.taskAffinity;
Dianne Hackborn79228822014-09-16 11:11:23 -0700282 if (intent == null) {
283 // If this task already has an intent associated with it, don't set the root
284 // affinity -- we don't want it changing after initially set, but the initially
285 // set value may be null.
286 rootAffinity = affinity;
287 }
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700288 effectiveUid = info.applicationInfo.uid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700289 stringName = null;
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800290
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800291 if (info.targetActivity == null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800292 if (_intent != null) {
293 // If this Intent has a selector, we want to clear it for the
294 // recent task since it is not relevant if the user later wants
295 // to re-launch the app.
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700296 if (_intent.getSelector() != null || _intent.getSourceBounds() != null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800297 _intent = new Intent(_intent);
298 _intent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700299 _intent.setSourceBounds(null);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800300 }
301 }
Dianne Hackborn7f96b792012-05-29 18:46:45 -0700302 if (ActivityManagerService.DEBUG_TASKS) Slog.v(ActivityManagerService.TAG,
303 "Setting Intent of " + this + " to " + _intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800304 intent = _intent;
305 realActivity = _intent != null ? _intent.getComponent() : null;
306 origActivity = null;
307 } else {
308 ComponentName targetComponent = new ComponentName(
309 info.packageName, info.targetActivity);
310 if (_intent != null) {
311 Intent targetIntent = new Intent(_intent);
312 targetIntent.setComponent(targetComponent);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800313 targetIntent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700314 targetIntent.setSourceBounds(null);
Dianne Hackborn7f96b792012-05-29 18:46:45 -0700315 if (ActivityManagerService.DEBUG_TASKS) Slog.v(ActivityManagerService.TAG,
316 "Setting Intent of " + this + " to target " + targetIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800317 intent = targetIntent;
318 realActivity = targetComponent;
319 origActivity = _intent.getComponent();
320 } else {
321 intent = null;
322 realActivity = targetComponent;
323 origActivity = new ComponentName(info.packageName, info.name);
324 }
325 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700326
Craig Mautner47b20ba2014-09-17 17:23:44 -0700327 final int intentFlags = intent == null ? 0 : intent.getFlags();
328 if ((intentFlags & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800329 // Once we are set to an Intent with this flag, we count this
330 // task as having a true root activity.
331 rootWasReset = true;
332 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700333
Dianne Hackborn09233282014-04-30 11:33:59 -0700334 userId = UserHandle.getUserId(info.applicationInfo.uid);
Craig Mautner41db4a72014-05-07 17:20:56 -0700335 if ((info.flags & ActivityInfo.FLAG_AUTO_REMOVE_FROM_RECENTS) != 0) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700336 // If the activity itself has requested auto-remove, then just always do it.
337 autoRemoveRecents = true;
Craig Mautner47b20ba2014-09-17 17:23:44 -0700338 } else if ((intentFlags & (Intent.FLAG_ACTIVITY_NEW_DOCUMENT
339 | Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS)) == Intent.FLAG_ACTIVITY_NEW_DOCUMENT) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700340 // If the caller has not asked for the document to be retained, then we may
341 // want to turn on auto-remove, depending on whether the target has set its
342 // own document launch mode.
343 if (info.documentLaunchMode != ActivityInfo.DOCUMENT_LAUNCH_NONE) {
344 autoRemoveRecents = false;
345 } else {
346 autoRemoveRecents = true;
347 }
348 } else {
349 autoRemoveRecents = false;
Craig Mautner41db4a72014-05-07 17:20:56 -0700350 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800351 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800352
Craig Mautner84984fa2014-06-19 11:19:20 -0700353 void setTaskToReturnTo(int taskToReturnTo) {
Craig Mautner0b633fc2014-07-23 10:42:18 -0700354 if (IGNORE_RETURN_TO_RECENTS && taskToReturnTo == RECENTS_ACTIVITY_TYPE) {
355 taskToReturnTo = HOME_ACTIVITY_TYPE;
356 }
Craig Mautner84984fa2014-06-19 11:19:20 -0700357 mTaskToReturnTo = taskToReturnTo;
358 }
359
360 int getTaskToReturnTo() {
361 return mTaskToReturnTo;
362 }
363
Craig Mautnera228ae92014-07-09 05:44:55 -0700364 void setPrevAffiliate(TaskRecord prevAffiliate) {
365 mPrevAffiliate = prevAffiliate;
366 mPrevAffiliateTaskId = prevAffiliate == null ? -1 : prevAffiliate.taskId;
367 }
368
369 void setNextAffiliate(TaskRecord nextAffiliate) {
370 mNextAffiliate = nextAffiliate;
371 mNextAffiliateTaskId = nextAffiliate == null ? -1 : nextAffiliate.taskId;
372 }
373
374 // Close up recents linked list.
375 void closeRecentsChain() {
376 if (mPrevAffiliate != null) {
377 mPrevAffiliate.setNextAffiliate(mNextAffiliate);
378 }
379 if (mNextAffiliate != null) {
380 mNextAffiliate.setPrevAffiliate(mPrevAffiliate);
381 }
382 setPrevAffiliate(null);
383 setNextAffiliate(null);
384 }
385
Dianne Hackborn852975d2014-08-22 17:42:43 -0700386 void removedFromRecents(TaskPersister persister) {
387 disposeThumbnail();
388 closeRecentsChain();
389 if (inRecents) {
390 inRecents = false;
391 persister.wakeup(this, false);
392 }
393 }
394
Craig Mautnera228ae92014-07-09 05:44:55 -0700395 void setTaskToAffiliateWith(TaskRecord taskToAffiliateWith) {
396 closeRecentsChain();
397 mAffiliatedTaskId = taskToAffiliateWith.mAffiliatedTaskId;
Winson Chungec396d62014-08-06 17:08:00 -0700398 mAffiliatedTaskColor = taskToAffiliateWith.mAffiliatedTaskColor;
Craig Mautnera228ae92014-07-09 05:44:55 -0700399 // Find the end
400 while (taskToAffiliateWith.mNextAffiliate != null) {
401 final TaskRecord nextRecents = taskToAffiliateWith.mNextAffiliate;
402 if (nextRecents.mAffiliatedTaskId != mAffiliatedTaskId) {
403 Slog.e(TAG, "setTaskToAffiliateWith: nextRecents=" + nextRecents + " affilTaskId="
404 + nextRecents.mAffiliatedTaskId + " should be " + mAffiliatedTaskId);
405 if (nextRecents.mPrevAffiliate == taskToAffiliateWith) {
406 nextRecents.setPrevAffiliate(null);
407 }
408 taskToAffiliateWith.setNextAffiliate(null);
409 break;
410 }
411 taskToAffiliateWith = nextRecents;
412 }
413 taskToAffiliateWith.setNextAffiliate(this);
414 setPrevAffiliate(taskToAffiliateWith);
415 setNextAffiliate(null);
416 }
417
Winson Chung096f36b2014-08-20 15:39:01 -0700418 /**
419 * Sets the last thumbnail.
420 * @return whether the thumbnail was set
421 */
422 boolean setLastThumbnail(Bitmap thumbnail) {
423 if (mLastThumbnail != thumbnail) {
424 mLastThumbnail = thumbnail;
425 if (thumbnail == null) {
426 if (mLastThumbnailFile != null) {
427 mLastThumbnailFile.delete();
428 }
429 } else {
430 mService.mTaskPersister.saveImage(thumbnail, mFilename);
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700431 }
Winson Chung096f36b2014-08-20 15:39:01 -0700432 return true;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700433 }
Winson Chung096f36b2014-08-20 15:39:01 -0700434 return false;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700435 }
436
437 void getLastThumbnail(TaskThumbnail thumbs) {
438 thumbs.mainThumbnail = mLastThumbnail;
439 thumbs.thumbnailFileDescriptor = null;
Craig Mautnerf4f8bb72014-07-29 10:41:40 -0700440 if (mLastThumbnail == null) {
Craig Mautner648f69b2014-09-18 14:16:26 -0700441 thumbs.mainThumbnail = mService.mTaskPersister.getImageFromWriteQueue(mFilename);
Craig Mautnerf4f8bb72014-07-29 10:41:40 -0700442 }
Winson Chung096f36b2014-08-20 15:39:01 -0700443 // Only load the thumbnail file if we don't have a thumbnail
444 if (thumbs.mainThumbnail == null && mLastThumbnailFile.exists()) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700445 try {
446 thumbs.thumbnailFileDescriptor = ParcelFileDescriptor.open(mLastThumbnailFile,
447 ParcelFileDescriptor.MODE_READ_ONLY);
448 } catch (IOException e) {
Dianne Hackborn9844d292013-10-04 16:44:22 -0700449 }
450 }
451 }
452
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700453 void freeLastThumbnail() {
454 mLastThumbnail = null;
455 }
456
457 void disposeThumbnail() {
458 mLastThumbnail = null;
459 lastDescription = null;
460 }
461
Winson Chung1147c402014-05-14 11:05:00 -0700462 /** Returns the intent for the root activity for this task */
463 Intent getBaseIntent() {
464 return intent != null ? intent : affinityIntent;
465 }
466
Winson Chung3b3f4642014-04-22 10:08:18 -0700467 /** Returns the first non-finishing activity from the root. */
468 ActivityRecord getRootActivity() {
469 for (int i = 0; i < mActivities.size(); i++) {
470 final ActivityRecord r = mActivities.get(i);
471 if (r.finishing) {
472 continue;
473 }
474 return r;
475 }
476 return null;
477 }
478
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800479 ActivityRecord getTopActivity() {
480 for (int i = mActivities.size() - 1; i >= 0; --i) {
481 final ActivityRecord r = mActivities.get(i);
482 if (r.finishing) {
483 continue;
484 }
485 return r;
486 }
487 return null;
488 }
489
Craig Mautner6b74cb52013-09-27 17:02:21 -0700490 ActivityRecord topRunningActivityLocked(ActivityRecord notTop) {
491 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
492 ActivityRecord r = mActivities.get(activityNdx);
Amith Yamasani734983f2014-03-04 16:48:05 -0800493 if (!r.finishing && r != notTop && stack.okToShowLocked(r)) {
Craig Mautner6b74cb52013-09-27 17:02:21 -0700494 return r;
495 }
496 }
497 return null;
498 }
499
Craig Mautner3b475fe2013-12-16 15:58:31 -0800500 /** Call after activity movement or finish to make sure that frontOfTask is set correctly */
501 final void setFrontOfTask() {
502 boolean foundFront = false;
503 final int numActivities = mActivities.size();
Craig Mautner704e40b2013-12-18 16:43:51 -0800504 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
Craig Mautner3b475fe2013-12-16 15:58:31 -0800505 final ActivityRecord r = mActivities.get(activityNdx);
506 if (foundFront || r.finishing) {
507 r.frontOfTask = false;
508 } else {
509 r.frontOfTask = true;
510 // Set frontOfTask false for every following activity.
511 foundFront = true;
512 }
513 }
Craig Mautner9587ee02014-06-23 15:00:10 +0000514 if (!foundFront && numActivities > 0) {
515 // All activities of this task are finishing. As we ought to have a frontOfTask
516 // activity, make the bottom activity front.
517 mActivities.get(0).frontOfTask = true;
518 }
Craig Mautner3b475fe2013-12-16 15:58:31 -0800519 }
520
Craig Mautnerde4ef022013-04-07 19:01:33 -0700521 /**
Craig Mautner3b475fe2013-12-16 15:58:31 -0800522 * Reorder the history stack so that the passed activity is brought to the front.
Craig Mautnerde4ef022013-04-07 19:01:33 -0700523 */
524 final void moveActivityToFrontLocked(ActivityRecord newTop) {
525 if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Removing and adding activity " + newTop
526 + " to stack at top", new RuntimeException("here").fillInStackTrace());
527
Craig Mautnerde4ef022013-04-07 19:01:33 -0700528 mActivities.remove(newTop);
529 mActivities.add(newTop);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700530 updateEffectiveIntent();
Craig Mautner3b475fe2013-12-16 15:58:31 -0800531
532 setFrontOfTask();
Craig Mautnerde4ef022013-04-07 19:01:33 -0700533 }
534
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800535 void addActivityAtBottom(ActivityRecord r) {
Craig Mautner77878772013-03-04 19:46:24 -0800536 addActivityAtIndex(0, r);
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800537 }
538
539 void addActivityToTop(ActivityRecord r) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700540 addActivityAtIndex(mActivities.size(), r);
541 }
542
543 void addActivityAtIndex(int index, ActivityRecord r) {
Craig Mautner6170f732013-04-02 13:05:23 -0700544 // 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 -0800545 if (!mActivities.remove(r) && r.fullscreen) {
546 // Was not previously in list.
547 numFullscreen++;
548 }
Craig Mautner2c1faed2013-07-23 12:56:02 -0700549 // Only set this based on the first activity
550 if (mActivities.isEmpty()) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700551 taskType = r.mActivityType;
552 isPersistable = r.isPersistable();
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700553 mCallingUid = r.launchedFromUid;
554 mCallingPackage = r.launchedFromPackage;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700555 // Clamp to [1, max].
556 maxRecents = Math.min(Math.max(r.info.maxRecents, 1),
557 ActivityManager.getMaxAppRecentsLimitStatic());
Craig Mautner2c1faed2013-07-23 12:56:02 -0700558 } else {
559 // Otherwise make all added activities match this one.
Craig Mautner21d24a22014-04-23 11:45:37 -0700560 r.mActivityType = taskType;
Craig Mautner78733002013-06-10 13:54:49 -0700561 }
Craig Mautner77878772013-03-04 19:46:24 -0800562 mActivities.add(index, r);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700563 updateEffectiveIntent();
Craig Mautner21d24a22014-04-23 11:45:37 -0700564 if (r.isPersistable()) {
565 mService.notifyTaskPersisterLocked(this, false);
566 }
Craig Mautner77878772013-03-04 19:46:24 -0800567 }
568
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800569 /** @return true if this was the last activity in the task */
570 boolean removeActivity(ActivityRecord r) {
571 if (mActivities.remove(r) && r.fullscreen) {
572 // Was previously in list.
573 numFullscreen--;
574 }
Craig Mautner21d24a22014-04-23 11:45:37 -0700575 if (r.isPersistable()) {
576 mService.notifyTaskPersisterLocked(this, false);
577 }
Craig Mautner41326202014-06-20 14:38:21 -0700578 if (mActivities.isEmpty()) {
Craig Mautner5afcd4d2014-06-21 18:11:33 -0700579 return !mReuseTask;
Craig Mautner41326202014-06-20 14:38:21 -0700580 }
581 updateEffectiveIntent();
582 return false;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800583 }
584
Craig Mautner41db4a72014-05-07 17:20:56 -0700585 boolean autoRemoveFromRecents() {
Dianne Hackbornd38aed82014-06-10 21:36:35 -0700586 // We will automatically remove the task either if it has explicitly asked for
587 // this, or it is empty and has never contained an activity that got shown to
588 // the user.
Dianne Hackborn13420f22014-07-18 15:43:56 -0700589 return autoRemoveRecents || (mActivities.isEmpty() && !hasBeenVisible);
Craig Mautner41db4a72014-05-07 17:20:56 -0700590 }
591
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700592 /**
593 * Completely remove all activities associated with an existing
594 * task starting at a specified index.
595 */
596 final void performClearTaskAtIndexLocked(int activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700597 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700598 for ( ; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700599 final ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700600 if (r.finishing) {
601 continue;
602 }
Craig Mautner21d24a22014-04-23 11:45:37 -0700603 if (stack == null) {
604 // Task was restored from persistent storage.
605 r.takeFromHistory();
606 mActivities.remove(activityNdx);
607 --activityNdx;
608 --numActivities;
609 } else if (stack.finishActivityLocked(r, Activity.RESULT_CANCELED, null, "clear",
610 false)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700611 --activityNdx;
612 --numActivities;
613 }
614 }
615 }
616
617 /**
618 * Completely remove all activities associated with an existing task.
619 */
620 final void performClearTaskLocked() {
Craig Mautner362449a2014-06-20 14:04:39 -0700621 mReuseTask = true;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700622 performClearTaskAtIndexLocked(0);
Craig Mautner362449a2014-06-20 14:04:39 -0700623 mReuseTask = false;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700624 }
625
626 /**
627 * Perform clear operation as requested by
628 * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the
629 * stack to the given task, then look for
630 * an instance of that activity in the stack and, if found, finish all
631 * activities on top of it and return the instance.
632 *
633 * @param newR Description of the new activity being started.
634 * @return Returns the old activity that should be continued to be used,
635 * or null if none was found.
636 */
637 final ActivityRecord performClearTaskLocked(ActivityRecord newR, int launchFlags) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700638 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700639 for (int activityNdx = numActivities - 1; activityNdx >= 0; --activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700640 ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700641 if (r.finishing) {
642 continue;
643 }
644 if (r.realActivity.equals(newR.realActivity)) {
645 // Here it is! Now finish everything in front...
Craig Mautner1602ec22013-05-12 10:24:27 -0700646 final ActivityRecord ret = r;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700647
648 for (++activityNdx; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700649 r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700650 if (r.finishing) {
651 continue;
652 }
653 ActivityOptions opts = r.takeOptionsLocked();
654 if (opts != null) {
655 ret.updateOptionsLocked(opts);
656 }
657 if (stack.finishActivityLocked(r, Activity.RESULT_CANCELED, null, "clear",
658 false)) {
659 --activityNdx;
660 --numActivities;
661 }
662 }
663
664 // Finally, if this is a normal launch mode (that is, not
665 // expecting onNewIntent()), then we will finish the current
666 // instance of the activity so a new fresh one can be started.
667 if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE
668 && (launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0) {
669 if (!ret.finishing) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700670 stack.finishActivityLocked(ret, Activity.RESULT_CANCELED, null,
671 "clear", false);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700672 return null;
673 }
674 }
675
676 return ret;
677 }
678 }
679
680 return null;
681 }
682
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700683 public TaskThumbnail getTaskThumbnailLocked() {
Craig Mautner21d24a22014-04-23 11:45:37 -0700684 if (stack != null) {
685 final ActivityRecord resumedActivity = stack.mResumedActivity;
686 if (resumedActivity != null && resumedActivity.task == this) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700687 final Bitmap thumbnail = stack.screenshotActivities(resumedActivity);
688 setLastThumbnail(thumbnail);
Craig Mautner21d24a22014-04-23 11:45:37 -0700689 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700690 }
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700691 final TaskThumbnail taskThumbnail = new TaskThumbnail();
692 getLastThumbnail(taskThumbnail);
693 return taskThumbnail;
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700694 }
695
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700696 public void removeTaskActivitiesLocked() {
697 // Just remove the entire task.
698 performClearTaskAtIndexLocked(0);
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700699 }
700
Craig Mautnera82aa092013-09-13 15:34:08 -0700701 boolean isHomeTask() {
Craig Mautner84984fa2014-06-19 11:19:20 -0700702 return taskType == HOME_ACTIVITY_TYPE;
Craig Mautnera82aa092013-09-13 15:34:08 -0700703 }
704
Craig Mautner86d67a42013-05-14 10:34:38 -0700705 boolean isApplicationTask() {
Craig Mautner84984fa2014-06-19 11:19:20 -0700706 return taskType == APPLICATION_ACTIVITY_TYPE;
707 }
708
709 boolean isOverHomeStack() {
710 return mTaskToReturnTo == HOME_ACTIVITY_TYPE || mTaskToReturnTo == RECENTS_ACTIVITY_TYPE;
Craig Mautner1602ec22013-05-12 10:24:27 -0700711 }
712
Craig Mautner525f3d92013-05-07 14:01:50 -0700713 /**
714 * Find the activity in the history stack within the given task. Returns
715 * the index within the history at which it's found, or < 0 if not found.
716 */
717 final ActivityRecord findActivityInHistoryLocked(ActivityRecord r) {
718 final ComponentName realActivity = r.realActivity;
719 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
720 ActivityRecord candidate = mActivities.get(activityNdx);
721 if (candidate.finishing) {
722 continue;
723 }
724 if (candidate.realActivity.equals(realActivity)) {
725 return candidate;
726 }
727 }
728 return null;
729 }
730
Winson Chunga449dc02014-05-16 11:15:04 -0700731 /** Updates the last task description values. */
732 void updateTaskDescription() {
733 // Traverse upwards looking for any break between main task activities and
734 // utility activities.
735 int activityNdx;
736 final int numActivities = mActivities.size();
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700737 final boolean relinquish = numActivities == 0 ? false :
738 (mActivities.get(0).info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) != 0;
Winson Chunga449dc02014-05-16 11:15:04 -0700739 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
Craig Mautner21d24a22014-04-23 11:45:37 -0700740 ++activityNdx) {
Winson Chunga449dc02014-05-16 11:15:04 -0700741 final ActivityRecord r = mActivities.get(activityNdx);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700742 if (relinquish && (r.info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
743 // This will be the top activity for determining taskDescription. Pre-inc to
744 // overcome initial decrement below.
745 ++activityNdx;
746 break;
747 }
Winson Chunga449dc02014-05-16 11:15:04 -0700748 if (r.intent != null &&
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700749 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
Winson Chunga449dc02014-05-16 11:15:04 -0700750 break;
751 }
752 }
753 if (activityNdx > 0) {
754 // Traverse downwards starting below break looking for set label, icon.
755 // Note that if there are activities in the task but none of them set the
756 // recent activity values, then we do not fall back to the last set
757 // values in the TaskRecord.
758 String label = null;
Craig Mautner648f69b2014-09-18 14:16:26 -0700759 String iconFilename = null;
Winson Chunga449dc02014-05-16 11:15:04 -0700760 int colorPrimary = 0;
761 for (--activityNdx; activityNdx >= 0; --activityNdx) {
762 final ActivityRecord r = mActivities.get(activityNdx);
763 if (r.taskDescription != null) {
764 if (label == null) {
765 label = r.taskDescription.getLabel();
766 }
Craig Mautner648f69b2014-09-18 14:16:26 -0700767 if (iconFilename == null) {
768 iconFilename = r.taskDescription.getIconFilename();
Winson Chunga449dc02014-05-16 11:15:04 -0700769 }
770 if (colorPrimary == 0) {
771 colorPrimary = r.taskDescription.getPrimaryColor();
Winson Chunga449dc02014-05-16 11:15:04 -0700772 }
773 }
774 }
Craig Mautner648f69b2014-09-18 14:16:26 -0700775 lastTaskDescription = new TaskDescription(label, colorPrimary, iconFilename);
Winson Chungec396d62014-08-06 17:08:00 -0700776 // Update the task affiliation color if we are the parent of the group
777 if (taskId == mAffiliatedTaskId) {
778 mAffiliatedTaskColor = lastTaskDescription.getPrimaryColor();
779 }
Winson Chunga449dc02014-05-16 11:15:04 -0700780 }
781 }
782
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700783 int findEffectiveRootIndex() {
Craig Mautner4767f4b2014-09-18 15:38:33 -0700784 int effectiveNdx = 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700785 final int topActivityNdx = mActivities.size() - 1;
Dianne Hackborn39569af2014-09-23 10:56:58 -0700786 for (int activityNdx = 0; activityNdx <= topActivityNdx; ++activityNdx) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700787 final ActivityRecord r = mActivities.get(activityNdx);
788 if (r.finishing) {
789 continue;
790 }
Craig Mautner4767f4b2014-09-18 15:38:33 -0700791 effectiveNdx = activityNdx;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700792 if ((r.info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
793 break;
794 }
795 }
Craig Mautner4767f4b2014-09-18 15:38:33 -0700796 return effectiveNdx;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700797 }
798
799 void updateEffectiveIntent() {
800 final int effectiveRootIndex = findEffectiveRootIndex();
801 final ActivityRecord r = mActivities.get(effectiveRootIndex);
Winson Chungfee26772014-08-05 12:21:52 -0700802 setIntent(r);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700803 }
804
Craig Mautner21d24a22014-04-23 11:45:37 -0700805 void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700806 if (ActivityManagerService.DEBUG_RECENTS) Slog.i(TAG, "Saving task=" + this);
Craig Mautner21d24a22014-04-23 11:45:37 -0700807
808 out.attribute(null, ATTR_TASKID, String.valueOf(taskId));
809 if (realActivity != null) {
810 out.attribute(null, ATTR_REALACTIVITY, realActivity.flattenToShortString());
811 }
812 if (origActivity != null) {
813 out.attribute(null, ATTR_ORIGACTIVITY, origActivity.flattenToShortString());
814 }
Dianne Hackborn79228822014-09-16 11:11:23 -0700815 // Write affinity, and root affinity if it is different from affinity.
816 // We use the special string "@" for a null root affinity, so we can identify
817 // later whether we were given a root affinity or should just make it the
818 // same as the affinity.
Craig Mautner21d24a22014-04-23 11:45:37 -0700819 if (affinity != null) {
820 out.attribute(null, ATTR_AFFINITY, affinity);
Dianne Hackborn79228822014-09-16 11:11:23 -0700821 if (!affinity.equals(rootAffinity)) {
822 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
823 }
824 } else if (rootAffinity != null) {
825 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
Craig Mautner21d24a22014-04-23 11:45:37 -0700826 }
827 out.attribute(null, ATTR_ROOTHASRESET, String.valueOf(rootWasReset));
Dianne Hackborn13420f22014-07-18 15:43:56 -0700828 out.attribute(null, ATTR_AUTOREMOVERECENTS, String.valueOf(autoRemoveRecents));
Craig Mautner21d24a22014-04-23 11:45:37 -0700829 out.attribute(null, ATTR_ASKEDCOMPATMODE, String.valueOf(askedCompatMode));
830 out.attribute(null, ATTR_USERID, String.valueOf(userId));
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700831 out.attribute(null, ATTR_EFFECTIVE_UID, String.valueOf(effectiveUid));
Craig Mautner21d24a22014-04-23 11:45:37 -0700832 out.attribute(null, ATTR_TASKTYPE, String.valueOf(taskType));
Winson Chungffa2ec62014-07-03 15:54:42 -0700833 out.attribute(null, ATTR_FIRSTACTIVETIME, String.valueOf(firstActiveTime));
Winson Chungf1fbd772014-06-24 18:06:58 -0700834 out.attribute(null, ATTR_LASTACTIVETIME, String.valueOf(lastActiveTime));
Craig Mautner21d24a22014-04-23 11:45:37 -0700835 out.attribute(null, ATTR_LASTTIMEMOVED, String.valueOf(mLastTimeMoved));
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700836 out.attribute(null, ATTR_NEVERRELINQUISH, String.valueOf(mNeverRelinquishIdentity));
Craig Mautner21d24a22014-04-23 11:45:37 -0700837 if (lastDescription != null) {
838 out.attribute(null, ATTR_LASTDESCRIPTION, lastDescription.toString());
839 }
Winson Chung2cb86c72014-06-25 12:03:30 -0700840 if (lastTaskDescription != null) {
Craig Mautner648f69b2014-09-18 14:16:26 -0700841 lastTaskDescription.saveToXml(out);
Winson Chung2cb86c72014-06-25 12:03:30 -0700842 }
Winson Chungec396d62014-08-06 17:08:00 -0700843 out.attribute(null, ATTR_TASK_AFFILIATION_COLOR, String.valueOf(mAffiliatedTaskColor));
Craig Mautnera228ae92014-07-09 05:44:55 -0700844 out.attribute(null, ATTR_TASK_AFFILIATION, String.valueOf(mAffiliatedTaskId));
845 out.attribute(null, ATTR_PREV_AFFILIATION, String.valueOf(mPrevAffiliateTaskId));
846 out.attribute(null, ATTR_NEXT_AFFILIATION, String.valueOf(mNextAffiliateTaskId));
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700847 out.attribute(null, ATTR_CALLING_UID, String.valueOf(mCallingUid));
848 out.attribute(null, ATTR_CALLING_PACKAGE, mCallingPackage == null ? "" : mCallingPackage);
Winson Chung2cb86c72014-06-25 12:03:30 -0700849
Craig Mautner21d24a22014-04-23 11:45:37 -0700850 if (affinityIntent != null) {
851 out.startTag(null, TAG_AFFINITYINTENT);
852 affinityIntent.saveToXml(out);
853 out.endTag(null, TAG_AFFINITYINTENT);
854 }
855
856 out.startTag(null, TAG_INTENT);
857 intent.saveToXml(out);
858 out.endTag(null, TAG_INTENT);
859
860 final ArrayList<ActivityRecord> activities = mActivities;
861 final int numActivities = activities.size();
862 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
863 final ActivityRecord r = activities.get(activityNdx);
Craig Mautner43e52ed2014-06-16 17:18:52 -0700864 if (r.info.persistableMode == ActivityInfo.PERSIST_ROOT_ONLY || !r.isPersistable() ||
865 ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) &&
866 activityNdx > 0) {
Craig Mautnerf357c0c2014-06-09 09:23:27 -0700867 // Stop at first non-persistable or first break in task (CLEAR_WHEN_TASK_RESET).
Craig Mautner21d24a22014-04-23 11:45:37 -0700868 break;
869 }
870 out.startTag(null, TAG_ACTIVITY);
871 r.saveToXml(out);
872 out.endTag(null, TAG_ACTIVITY);
873 }
Craig Mautner21d24a22014-04-23 11:45:37 -0700874 }
875
876 static TaskRecord restoreFromXml(XmlPullParser in, ActivityStackSupervisor stackSupervisor)
877 throws IOException, XmlPullParserException {
878 Intent intent = null;
879 Intent affinityIntent = null;
880 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
881 ComponentName realActivity = null;
882 ComponentName origActivity = null;
883 String affinity = null;
Dianne Hackborn79228822014-09-16 11:11:23 -0700884 String rootAffinity = null;
885 boolean hasRootAffinity = false;
Craig Mautner21d24a22014-04-23 11:45:37 -0700886 boolean rootHasReset = false;
Dianne Hackborn13420f22014-07-18 15:43:56 -0700887 boolean autoRemoveRecents = false;
Craig Mautner21d24a22014-04-23 11:45:37 -0700888 boolean askedCompatMode = false;
889 int taskType = ActivityRecord.APPLICATION_ACTIVITY_TYPE;
Craig Mautner21d24a22014-04-23 11:45:37 -0700890 int userId = 0;
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700891 int effectiveUid = -1;
Craig Mautner21d24a22014-04-23 11:45:37 -0700892 String lastDescription = null;
Winson Chungffa2ec62014-07-03 15:54:42 -0700893 long firstActiveTime = -1;
Winson Chung2cb86c72014-06-25 12:03:30 -0700894 long lastActiveTime = -1;
Craig Mautner21d24a22014-04-23 11:45:37 -0700895 long lastTimeOnTop = 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700896 boolean neverRelinquishIdentity = true;
Craig Mautner21d24a22014-04-23 11:45:37 -0700897 int taskId = -1;
898 final int outerDepth = in.getDepth();
Craig Mautner648f69b2014-09-18 14:16:26 -0700899 TaskDescription taskDescription = new TaskDescription();
Craig Mautnera228ae92014-07-09 05:44:55 -0700900 int taskAffiliation = -1;
Winson Chungec396d62014-08-06 17:08:00 -0700901 int taskAffiliationColor = 0;
Craig Mautnera228ae92014-07-09 05:44:55 -0700902 int prevTaskId = -1;
903 int nextTaskId = -1;
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700904 int callingUid = -1;
905 String callingPackage = "";
Craig Mautner21d24a22014-04-23 11:45:37 -0700906
907 for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
908 final String attrName = in.getAttributeName(attrNdx);
909 final String attrValue = in.getAttributeValue(attrNdx);
910 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: attribute name=" +
911 attrName + " value=" + attrValue);
912 if (ATTR_TASKID.equals(attrName)) {
913 taskId = Integer.valueOf(attrValue);
914 } else if (ATTR_REALACTIVITY.equals(attrName)) {
915 realActivity = ComponentName.unflattenFromString(attrValue);
916 } else if (ATTR_ORIGACTIVITY.equals(attrName)) {
917 origActivity = ComponentName.unflattenFromString(attrValue);
918 } else if (ATTR_AFFINITY.equals(attrName)) {
919 affinity = attrValue;
Dianne Hackborn79228822014-09-16 11:11:23 -0700920 } else if (ATTR_ROOT_AFFINITY.equals(attrName)) {
921 rootAffinity = attrValue;
922 hasRootAffinity = true;
Craig Mautner21d24a22014-04-23 11:45:37 -0700923 } else if (ATTR_ROOTHASRESET.equals(attrName)) {
924 rootHasReset = Boolean.valueOf(attrValue);
Dianne Hackborn13420f22014-07-18 15:43:56 -0700925 } else if (ATTR_AUTOREMOVERECENTS.equals(attrName)) {
926 autoRemoveRecents = Boolean.valueOf(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -0700927 } else if (ATTR_ASKEDCOMPATMODE.equals(attrName)) {
928 askedCompatMode = Boolean.valueOf(attrValue);
929 } else if (ATTR_USERID.equals(attrName)) {
930 userId = Integer.valueOf(attrValue);
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700931 } else if (ATTR_EFFECTIVE_UID.equals(attrName)) {
932 effectiveUid = Integer.valueOf(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -0700933 } else if (ATTR_TASKTYPE.equals(attrName)) {
934 taskType = Integer.valueOf(attrValue);
Winson Chungffa2ec62014-07-03 15:54:42 -0700935 } else if (ATTR_FIRSTACTIVETIME.equals(attrName)) {
936 firstActiveTime = Long.valueOf(attrValue);
Winson Chungf1fbd772014-06-24 18:06:58 -0700937 } else if (ATTR_LASTACTIVETIME.equals(attrName)) {
938 lastActiveTime = Long.valueOf(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -0700939 } else if (ATTR_LASTDESCRIPTION.equals(attrName)) {
940 lastDescription = attrValue;
941 } else if (ATTR_LASTTIMEMOVED.equals(attrName)) {
942 lastTimeOnTop = Long.valueOf(attrValue);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700943 } else if (ATTR_NEVERRELINQUISH.equals(attrName)) {
944 neverRelinquishIdentity = Boolean.valueOf(attrValue);
Craig Mautner648f69b2014-09-18 14:16:26 -0700945 } else if (attrName.startsWith(TaskDescription.ATTR_TASKDESCRIPTION_PREFIX)) {
946 taskDescription.restoreFromXml(attrName, attrValue);
Craig Mautnera228ae92014-07-09 05:44:55 -0700947 } else if (ATTR_TASK_AFFILIATION.equals(attrName)) {
948 taskAffiliation = Integer.valueOf(attrValue);
949 } else if (ATTR_PREV_AFFILIATION.equals(attrName)) {
950 prevTaskId = Integer.valueOf(attrValue);
951 } else if (ATTR_NEXT_AFFILIATION.equals(attrName)) {
952 nextTaskId = Integer.valueOf(attrValue);
Winson Chungec396d62014-08-06 17:08:00 -0700953 } else if (ATTR_TASK_AFFILIATION_COLOR.equals(attrName)) {
954 taskAffiliationColor = Integer.valueOf(attrValue);
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700955 } else if (ATTR_CALLING_UID.equals(attrName)) {
956 callingUid = Integer.valueOf(attrValue);
957 } else if (ATTR_CALLING_PACKAGE.equals(attrName)) {
958 callingPackage = attrValue;
Craig Mautner21d24a22014-04-23 11:45:37 -0700959 } else {
960 Slog.w(TAG, "TaskRecord: Unknown attribute=" + attrName);
961 }
962 }
963
964 int event;
965 while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
966 (event != XmlPullParser.END_TAG || in.getDepth() < outerDepth)) {
967 if (event == XmlPullParser.START_TAG) {
968 final String name = in.getName();
969 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: START_TAG name=" +
970 name);
971 if (TAG_AFFINITYINTENT.equals(name)) {
972 affinityIntent = Intent.restoreFromXml(in);
973 } else if (TAG_INTENT.equals(name)) {
974 intent = Intent.restoreFromXml(in);
975 } else if (TAG_ACTIVITY.equals(name)) {
976 ActivityRecord activity =
977 ActivityRecord.restoreFromXml(in, taskId, stackSupervisor);
978 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: activity=" +
979 activity);
980 if (activity != null) {
981 activities.add(activity);
982 }
983 } else {
984 Slog.e(TAG, "restoreTask: Unexpected name=" + name);
985 XmlUtils.skipCurrentTag(in);
986 }
987 }
988 }
989
Dianne Hackborn79228822014-09-16 11:11:23 -0700990 if (!hasRootAffinity) {
991 rootAffinity = affinity;
992 } else if ("@".equals(rootAffinity)) {
993 rootAffinity = null;
994 }
995
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700996 if (effectiveUid <= 0) {
997 Intent checkIntent = intent != null ? intent : affinityIntent;
998 effectiveUid = 0;
999 if (checkIntent != null) {
1000 IPackageManager pm = AppGlobals.getPackageManager();
1001 try {
1002 ApplicationInfo ai = pm.getApplicationInfo(
1003 checkIntent.getComponent().getPackageName(),
1004 PackageManager.GET_UNINSTALLED_PACKAGES
1005 | PackageManager.GET_DISABLED_COMPONENTS, userId);
1006 if (ai != null) {
1007 effectiveUid = ai.uid;
1008 }
1009 } catch (RemoteException e) {
1010 }
1011 }
1012 Slog.w(TAG, "Updating task #" + taskId + " for " + checkIntent
1013 + ": effectiveUid=" + effectiveUid);
1014 }
1015
Craig Mautner21d24a22014-04-23 11:45:37 -07001016 final TaskRecord task = new TaskRecord(stackSupervisor.mService, taskId, intent,
Dianne Hackborn79228822014-09-16 11:11:23 -07001017 affinityIntent, affinity, rootAffinity, realActivity, origActivity, rootHasReset,
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001018 autoRemoveRecents, askedCompatMode, taskType, userId, effectiveUid, lastDescription,
1019 activities, firstActiveTime, lastActiveTime, lastTimeOnTop, neverRelinquishIdentity,
Winson Chungec396d62014-08-06 17:08:00 -07001020 taskDescription, taskAffiliation, prevTaskId, nextTaskId, taskAffiliationColor,
1021 callingUid, callingPackage);
Craig Mautner21d24a22014-04-23 11:45:37 -07001022
1023 for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001024 activities.get(activityNdx).task = task;
Craig Mautner21d24a22014-04-23 11:45:37 -07001025 }
1026
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001027 if (ActivityManagerService.DEBUG_RECENTS) Slog.d(TAG, "Restored task=" + task);
Craig Mautner21d24a22014-04-23 11:45:37 -07001028 return task;
1029 }
1030
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001031 void dump(PrintWriter pw, String prefix) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001032 pw.print(prefix); pw.print("userId="); pw.print(userId);
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001033 pw.print(" effectiveUid="); UserHandle.formatUid(pw, effectiveUid);
1034 pw.print(" mCallingUid="); UserHandle.formatUid(pw, mCallingUid);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001035 pw.print(" mCallingPackage="); pw.println(mCallingPackage);
Dianne Hackborn79228822014-09-16 11:11:23 -07001036 if (affinity != null || rootAffinity != null) {
1037 pw.print(prefix); pw.print("affinity="); pw.print(affinity);
1038 if (affinity == null || !affinity.equals(rootAffinity)) {
1039 pw.print(" root="); pw.println(rootAffinity);
1040 } else {
1041 pw.println();
1042 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001043 }
Dianne Hackborn91097de2014-04-04 18:02:06 -07001044 if (voiceSession != null || voiceInteractor != null) {
1045 pw.print(prefix); pw.print("VOICE: session=0x");
1046 pw.print(Integer.toHexString(System.identityHashCode(voiceSession)));
1047 pw.print(" interactor=0x");
1048 pw.println(Integer.toHexString(System.identityHashCode(voiceInteractor)));
1049 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001050 if (intent != null) {
1051 StringBuilder sb = new StringBuilder(128);
1052 sb.append(prefix); sb.append("intent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08001053 intent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001054 sb.append('}');
1055 pw.println(sb.toString());
1056 }
1057 if (affinityIntent != null) {
1058 StringBuilder sb = new StringBuilder(128);
1059 sb.append(prefix); sb.append("affinityIntent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08001060 affinityIntent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001061 sb.append('}');
1062 pw.println(sb.toString());
1063 }
1064 if (origActivity != null) {
1065 pw.print(prefix); pw.print("origActivity=");
1066 pw.println(origActivity.flattenToShortString());
1067 }
1068 if (realActivity != null) {
1069 pw.print(prefix); pw.print("realActivity=");
1070 pw.println(realActivity.flattenToShortString());
1071 }
Dianne Hackborn852975d2014-08-22 17:42:43 -07001072 if (autoRemoveRecents || isPersistable || taskType != 0 || mTaskToReturnTo != 0
1073 || numFullscreen != 0) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001074 pw.print(prefix); pw.print("autoRemoveRecents="); pw.print(autoRemoveRecents);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001075 pw.print(" isPersistable="); pw.print(isPersistable);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001076 pw.print(" numFullscreen="); pw.print(numFullscreen);
1077 pw.print(" taskType="); pw.print(taskType);
1078 pw.print(" mTaskToReturnTo="); pw.println(mTaskToReturnTo);
1079 }
1080 if (rootWasReset || mNeverRelinquishIdentity || mReuseTask) {
1081 pw.print(prefix); pw.print("rootWasReset="); pw.print(rootWasReset);
1082 pw.print(" mNeverRelinquishIdentity="); pw.print(mNeverRelinquishIdentity);
1083 pw.print(" mReuseTask="); pw.println(mReuseTask);
1084 }
Dianne Hackborn852975d2014-08-22 17:42:43 -07001085 if (mAffiliatedTaskId != taskId || mPrevAffiliateTaskId != -1 || mPrevAffiliate != null
1086 || mNextAffiliateTaskId != -1 || mNextAffiliate != null) {
1087 pw.print(prefix); pw.print("affiliation="); pw.print(mAffiliatedTaskId);
1088 pw.print(" prevAffiliation="); pw.print(mPrevAffiliateTaskId);
1089 pw.print(" (");
1090 if (mPrevAffiliate == null) {
1091 pw.print("null");
1092 } else {
1093 pw.print(Integer.toHexString(System.identityHashCode(mPrevAffiliate)));
1094 }
1095 pw.print(") nextAffiliation="); pw.print(mNextAffiliateTaskId);
1096 pw.print(" (");
1097 if (mNextAffiliate == null) {
1098 pw.print("null");
1099 } else {
1100 pw.print(Integer.toHexString(System.identityHashCode(mNextAffiliate)));
1101 }
1102 pw.println(")");
1103 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001104 pw.print(prefix); pw.print("Activities="); pw.println(mActivities);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001105 if (!askedCompatMode || !inRecents || !isAvailable) {
1106 pw.print(prefix); pw.print("askedCompatMode="); pw.print(askedCompatMode);
1107 pw.print(" inRecents="); pw.print(inRecents);
1108 pw.print(" isAvailable="); pw.println(isAvailable);
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001109 }
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001110 pw.print(prefix); pw.print("lastThumbnail="); pw.print(mLastThumbnail);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001111 pw.print(" lastThumbnailFile="); pw.println(mLastThumbnailFile);
1112 if (lastDescription != null) {
1113 pw.print(prefix); pw.print("lastDescription="); pw.println(lastDescription);
1114 }
Dianne Hackbornd38aed82014-06-10 21:36:35 -07001115 pw.print(prefix); pw.print("hasBeenVisible="); pw.print(hasBeenVisible);
Winson Chungffa2ec62014-07-03 15:54:42 -07001116 pw.print(" firstActiveTime="); pw.print(lastActiveTime);
Dianne Hackbornd38aed82014-06-10 21:36:35 -07001117 pw.print(" lastActiveTime="); pw.print(lastActiveTime);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001118 pw.print(" (inactive for ");
1119 pw.print((getInactiveDuration()/1000)); pw.println("s)");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001120 }
1121
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001122 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001123 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001124 StringBuilder sb = new StringBuilder(128);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001125 if (stringName != null) {
1126 sb.append(stringName);
1127 sb.append(" U=");
1128 sb.append(userId);
1129 sb.append(" sz=");
1130 sb.append(mActivities.size());
1131 sb.append('}');
1132 return sb.toString();
1133 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001134 sb.append("TaskRecord{");
1135 sb.append(Integer.toHexString(System.identityHashCode(this)));
1136 sb.append(" #");
1137 sb.append(taskId);
1138 if (affinity != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001139 sb.append(" A=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001140 sb.append(affinity);
1141 } else if (intent != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001142 sb.append(" I=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001143 sb.append(intent.getComponent().flattenToShortString());
1144 } else if (affinityIntent != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001145 sb.append(" aI=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001146 sb.append(affinityIntent.getComponent().flattenToShortString());
1147 } else {
1148 sb.append(" ??");
1149 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07001150 stringName = sb.toString();
1151 return toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001152 }
1153}