blob: 2b1e0cab2df6c5b57cb6cd74158dc48896d91a89 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
Wale Ogunwale3797c222015-10-27 14:21:58 -070019import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
20import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
21import static android.app.ActivityManager.StackId.HOME_STACK_ID;
Wale Ogunwale6c5eb1c2015-11-10 07:52:22 -080022import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
Wale Ogunwale5f986092015-12-04 15:35:38 -080023import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
Wale Ogunwale843bfb92015-03-27 11:06:48 -070024import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
25import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
Wale Ogunwale6cae7652015-12-26 07:36:26 -080026import static android.content.pm.ActivityInfo.FLAG_RESIZEABLE;
Craig Mautner15df08a2015-04-01 12:17:18 -070027import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
28import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
29import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
30import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER;
Wale Ogunwalea7afaa22015-05-01 20:39:18 -070031import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
Suprabh Shukla23593142015-11-03 17:31:15 -080032import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ADD_REMOVE;
33import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
34import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
35import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
36import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_ADD_REMOVE;
37import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
38import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
39import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS;
40import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
41import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
Chong Zhang75b37202015-12-04 14:16:36 -080042import static com.android.server.am.ActivityManagerService.LOCK_SCREEN_SHOWN;
Craig Mautner84984fa2014-06-19 11:19:20 -070043import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
Suprabh Shukla23593142015-11-03 17:31:15 -080044import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
Craig Mautner84984fa2014-06-19 11:19:20 -070045import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
Craig Mautnerde4ef022013-04-07 19:01:33 -070046
Craig Mautnerb0f7dc72013-04-01 16:34:45 -070047import android.app.Activity;
Craig Mautner9db9a0b2013-04-29 17:05:56 -070048import android.app.ActivityManager;
Wale Ogunwale3797c222015-10-27 14:21:58 -070049import android.app.ActivityManager.StackId;
Craig Mautner648f69b2014-09-18 14:16:26 -070050import android.app.ActivityManager.TaskDescription;
Wale Ogunwaleff3c66c2015-11-18 19:22:49 -080051import android.app.ActivityManager.TaskThumbnail;
Winsonc809cbb2015-11-02 12:06:15 -080052import android.app.ActivityManager.TaskThumbnailInfo;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -070053import android.app.ActivityOptions;
Dianne Hackborn885fbe52014-08-23 15:23:58 -070054import android.app.AppGlobals;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055import android.content.ComponentName;
56import android.content.Intent;
57import android.content.pm.ActivityInfo;
Dianne Hackborn885fbe52014-08-23 15:23:58 -070058import android.content.pm.ApplicationInfo;
59import android.content.pm.IPackageManager;
60import android.content.pm.PackageManager;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -070061import android.content.res.Configuration;
Craig Mautner9db9a0b2013-04-29 17:05:56 -070062import android.graphics.Bitmap;
Winsonc809cbb2015-11-02 12:06:15 -080063import android.graphics.Point;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -070064import android.graphics.Rect;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -070065import android.os.Debug;
Craig Mautnerc0ffce52014-07-01 12:38:52 -070066import android.os.ParcelFileDescriptor;
Dianne Hackborn885fbe52014-08-23 15:23:58 -070067import android.os.RemoteException;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070068import android.os.UserHandle;
Dianne Hackborn91097de2014-04-04 18:02:06 -070069import android.service.voice.IVoiceInteractionSession;
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -070070import android.util.DisplayMetrics;
Dianne Hackborn7f96b792012-05-29 18:46:45 -070071import android.util.Slog;
Suprabh Shukla23593142015-11-03 17:31:15 -080072
Dianne Hackborn91097de2014-04-04 18:02:06 -070073import com.android.internal.app.IVoiceInteractor;
Craig Mautner21d24a22014-04-23 11:45:37 -070074import com.android.internal.util.XmlUtils;
Suprabh Shukla23593142015-11-03 17:31:15 -080075
Craig Mautner21d24a22014-04-23 11:45:37 -070076import org.xmlpull.v1.XmlPullParser;
77import org.xmlpull.v1.XmlPullParserException;
78import org.xmlpull.v1.XmlSerializer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079
Craig Mautnerc0ffce52014-07-01 12:38:52 -070080import java.io.File;
Craig Mautner21d24a22014-04-23 11:45:37 -070081import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082import java.io.PrintWriter;
Craig Mautner5d9c7be2013-02-15 14:02:56 -080083import java.util.ArrayList;
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -070084import java.util.Objects;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085
Craig Mautnerc0ffce52014-07-01 12:38:52 -070086final class TaskRecord {
Wale Ogunwalee23149f2015-03-06 15:39:44 -080087 private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskRecord" : TAG_AM;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -070088 private static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE;
Wale Ogunwaleee006da2015-03-30 14:49:25 -070089 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
Craig Mautnere0570202015-05-13 13:06:11 -070090 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwaleee006da2015-03-30 14:49:25 -070091 private static final String TAG_TASKS = TAG + POSTFIX_TASKS;
Wale Ogunwalee23149f2015-03-06 15:39:44 -080092
Wale Ogunwale18795a22014-12-03 11:38:33 -080093 static final String ATTR_TASKID = "task_id";
Craig Mautner21d24a22014-04-23 11:45:37 -070094 private static final String TAG_INTENT = "intent";
95 private static final String TAG_AFFINITYINTENT = "affinity_intent";
Wale Ogunwale18795a22014-12-03 11:38:33 -080096 static final String ATTR_REALACTIVITY = "real_activity";
Craig Mautner21d24a22014-04-23 11:45:37 -070097 private static final String ATTR_ORIGACTIVITY = "orig_activity";
Stefan Kuhnee88d1e52015-05-18 10:33:45 -070098 private static final String TAG_ACTIVITY = "activity";
Craig Mautner21d24a22014-04-23 11:45:37 -070099 private static final String ATTR_AFFINITY = "affinity";
Dianne Hackborn79228822014-09-16 11:11:23 -0700100 private static final String ATTR_ROOT_AFFINITY = "root_affinity";
Craig Mautner21d24a22014-04-23 11:45:37 -0700101 private static final String ATTR_ROOTHASRESET = "root_has_reset";
Dianne Hackborn13420f22014-07-18 15:43:56 -0700102 private static final String ATTR_AUTOREMOVERECENTS = "auto_remove_recents";
Craig Mautner21d24a22014-04-23 11:45:37 -0700103 private static final String ATTR_ASKEDCOMPATMODE = "asked_compat_mode";
104 private static final String ATTR_USERID = "user_id";
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700105 private static final String ATTR_EFFECTIVE_UID = "effective_uid";
Craig Mautner21d24a22014-04-23 11:45:37 -0700106 private static final String ATTR_TASKTYPE = "task_type";
Winson Chungffa2ec62014-07-03 15:54:42 -0700107 private static final String ATTR_FIRSTACTIVETIME = "first_active_time";
Winson Chungf1fbd772014-06-24 18:06:58 -0700108 private static final String ATTR_LASTACTIVETIME = "last_active_time";
Craig Mautner21d24a22014-04-23 11:45:37 -0700109 private static final String ATTR_LASTDESCRIPTION = "last_description";
110 private static final String ATTR_LASTTIMEMOVED = "last_time_moved";
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700111 private static final String ATTR_NEVERRELINQUISH = "never_relinquish_identity";
Wale Ogunwale18795a22014-12-03 11:38:33 -0800112 static final String ATTR_TASK_AFFILIATION = "task_affiliation";
Craig Mautnera228ae92014-07-09 05:44:55 -0700113 private static final String ATTR_PREV_AFFILIATION = "prev_affiliation";
114 private static final String ATTR_NEXT_AFFILIATION = "next_affiliation";
Winson Chungec396d62014-08-06 17:08:00 -0700115 private static final String ATTR_TASK_AFFILIATION_COLOR = "task_affiliation_color";
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700116 private static final String ATTR_CALLING_UID = "calling_uid";
117 private static final String ATTR_CALLING_PACKAGE = "calling_package";
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800118 private static final String ATTR_RESIZEABLE = "resizeable";
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700119 private static final String ATTR_PRIVILEGED = "privileged";
Wale Ogunwale706ed792015-08-02 10:29:44 -0700120 private static final String ATTR_NON_FULLSCREEN_BOUNDS = "non_fullscreen_bounds";
Craig Mautner21d24a22014-04-23 11:45:37 -0700121
122 private static final String TASK_THUMBNAIL_SUFFIX = "_task_thumbnail";
123
Craig Mautner0b633fc2014-07-23 10:42:18 -0700124 static final boolean IGNORE_RETURN_TO_RECENTS = true;
125
Wale Ogunwale18795a22014-12-03 11:38:33 -0800126 static final int INVALID_TASK_ID = -1;
127
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128 final int taskId; // Unique identifier for this task.
Dianne Hackborn79228822014-09-16 11:11:23 -0700129 String affinity; // The affinity name for this task, or null; may change identity.
130 String rootAffinity; // Initial base affinity, or null; does not change from initial root.
Dianne Hackborn91097de2014-04-04 18:02:06 -0700131 final IVoiceInteractionSession voiceSession; // Voice interaction session driving task
132 final IVoiceInteractor voiceInteractor; // Associated interactor to provide to app
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800133 Intent intent; // The original intent that started the task.
134 Intent affinityIntent; // Intent of affinity-moved activity that started this task.
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700135 int effectiveUid; // The current effective uid of the identity of this task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136 ComponentName origActivity; // The non-alias activity component of the intent.
137 ComponentName realActivity; // The actual activity component that started the task.
Winson Chungffa2ec62014-07-03 15:54:42 -0700138 long firstActiveTime; // First time this task was active.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800139 long lastActiveTime; // Last time this task was active, including sleep.
Dianne Hackborn852975d2014-08-22 17:42:43 -0700140 boolean inRecents; // Actually in the recents list?
141 boolean isAvailable; // Is the activity available to be launched?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800142 boolean rootWasReset; // True if the intent at the root of the task had
143 // the FLAG_ACTIVITY_RESET_TASK_IF_NEEDED flag.
Dianne Hackborn13420f22014-07-18 15:43:56 -0700144 boolean autoRemoveRecents; // If true, we should automatically remove the task from
145 // recents when activity finishes
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700146 boolean askedCompatMode;// Have asked the user about compat mode for this task.
Dianne Hackbornd38aed82014-06-10 21:36:35 -0700147 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 -0800148
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700149 String stringName; // caching of toString() result.
Dianne Hackborn9da2d402012-03-15 13:43:08 -0700150 int userId; // user for which this task was created
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800151
152 int numFullscreen; // Number of fullscreen activities.
153
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800154 boolean mResizeable; // Activities in the task resizeable. Based on the resizable setting of
155 // the root activity.
Craig Mautner15df08a2015-04-01 12:17:18 -0700156 int mLockTaskMode; // Which tasklock mode to launch this task in. One of
157 // ActivityManager.LOCK_TASK_LAUNCH_MODE_*
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700158 private boolean mPrivileged; // The root activity application of this task holds
159 // privileged permissions.
160
Craig Mautner15df08a2015-04-01 12:17:18 -0700161 /** Can't be put in lockTask mode. */
162 final static int LOCK_TASK_AUTH_DONT_LOCK = 0;
Benjamin Franz469dd582015-06-09 14:24:36 +0100163 /** Can enter app pinning with user approval. Can never start over existing lockTask task. */
Craig Mautner15df08a2015-04-01 12:17:18 -0700164 final static int LOCK_TASK_AUTH_PINNABLE = 1;
165 /** Starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing lockTask task. */
166 final static int LOCK_TASK_AUTH_LAUNCHABLE = 2;
Benjamin Franz469dd582015-06-09 14:24:36 +0100167 /** Can enter lockTask without user approval. Can start over existing lockTask task. */
Craig Mautner15df08a2015-04-01 12:17:18 -0700168 final static int LOCK_TASK_AUTH_WHITELISTED = 3;
Benjamin Franz469dd582015-06-09 14:24:36 +0100169 /** Priv-app that starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing
170 * lockTask task. */
171 final static int LOCK_TASK_AUTH_LAUNCHABLE_PRIV = 4;
Craig Mautner15df08a2015-04-01 12:17:18 -0700172 int mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE;
173
174 int mLockTaskUid = -1; // The uid of the application that called startLockTask().
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800175
Winson Chung03a9bae2014-05-02 09:56:12 -0700176 // This represents the last resolved activity values for this task
177 // NOTE: This value needs to be persisted with each task
Craig Mautner648f69b2014-09-18 14:16:26 -0700178 TaskDescription lastTaskDescription = new TaskDescription();
Winson Chung03a9bae2014-05-02 09:56:12 -0700179
Craig Mautnerd2328952013-03-05 12:46:26 -0800180 /** List of all activities in the task arranged in history order */
Craig Mautner21d24a22014-04-23 11:45:37 -0700181 final ArrayList<ActivityRecord> mActivities;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800182
Craig Mautnerd2328952013-03-05 12:46:26 -0800183 /** Current stack */
184 ActivityStack stack;
185
Craig Mautner2c1faed2013-07-23 12:56:02 -0700186 /** Takes on same set of values as ActivityRecord.mActivityType */
Craig Mautner21d24a22014-04-23 11:45:37 -0700187 int taskType;
Craig Mautner1602ec22013-05-12 10:24:27 -0700188
Craig Mautner21d24a22014-04-23 11:45:37 -0700189 /** Takes on same value as first root activity */
190 boolean isPersistable = false;
Craig Mautnerffcfcaa2014-06-05 09:54:38 -0700191 int maxRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700192
193 /** Only used for persistable tasks, otherwise 0. The last time this task was moved. Used for
194 * determining the order when restoring. Sign indicates whether last task movement was to front
195 * (positive) or back (negative). Absolute value indicates time. */
196 long mLastTimeMoved = System.currentTimeMillis();
197
Craig Mautner84984fa2014-06-19 11:19:20 -0700198 /** Indication of what to run next when task exits. Use ActivityRecord types.
199 * ActivityRecord.APPLICATION_ACTIVITY_TYPE indicates to resume the task below this one in the
200 * task stack. */
201 private int mTaskToReturnTo = APPLICATION_ACTIVITY_TYPE;
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700202
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700203 /** If original intent did not allow relinquishing task identity, save that information */
204 boolean mNeverRelinquishIdentity = true;
205
Craig Mautner362449a2014-06-20 14:04:39 -0700206 // Used in the unique case where we are clearing the task in order to reuse it. In that case we
207 // do not want to delete the stack when the task goes empty.
208 boolean mReuseTask = false;
209
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700210 private Bitmap mLastThumbnail; // Last thumbnail captured for this item.
Wale Ogunwalebe23ff42014-10-21 16:29:51 -0700211 private final File mLastThumbnailFile; // File containing last thumbnail.
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700212 private final String mFilename;
Winsonc809cbb2015-11-02 12:06:15 -0800213 private TaskThumbnailInfo mLastThumbnailInfo;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700214 CharSequence lastDescription; // Last description captured for this item.
215
Craig Mautnera228ae92014-07-09 05:44:55 -0700216 int mAffiliatedTaskId; // taskId of parent affiliation or self if no parent.
Winson Chungec396d62014-08-06 17:08:00 -0700217 int mAffiliatedTaskColor; // color of the parent task affiliation.
Craig Mautnera228ae92014-07-09 05:44:55 -0700218 TaskRecord mPrevAffiliate; // previous task in affiliated chain.
Wale Ogunwale18795a22014-12-03 11:38:33 -0800219 int mPrevAffiliateTaskId = INVALID_TASK_ID; // previous id for persistence.
Craig Mautnera228ae92014-07-09 05:44:55 -0700220 TaskRecord mNextAffiliate; // next task in affiliated chain.
Wale Ogunwale18795a22014-12-03 11:38:33 -0800221 int mNextAffiliateTaskId = INVALID_TASK_ID; // next id for persistence.
Craig Mautnera228ae92014-07-09 05:44:55 -0700222
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700223 // For relaunching the task from recents as though it was launched by the original launcher.
224 int mCallingUid;
225 String mCallingPackage;
226
Craig Mautner21d24a22014-04-23 11:45:37 -0700227 final ActivityManagerService mService;
228
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700229 // Whether or not this task covers the entire screen; by default tasks are fullscreen.
230 boolean mFullscreen = true;
231
232 // Bounds of the Task. null for fullscreen tasks.
233 Rect mBounds = null;
Wale Ogunwale706ed792015-08-02 10:29:44 -0700234 // Last non-fullscreen bounds the task was launched in or resized to.
235 // The information is persisted and used to determine the appropriate stack to launch the
236 // task into on restore.
237 Rect mLastNonFullscreenBounds = null;
Filip Gruszczynskid2f1d942015-10-14 15:10:12 -0700238 // Minimal size for width/height of this task when it's resizeable. -1 means it should use the
239 // default minimal size.
240 final int mMinimalSize;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700241
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700242 // Ranking (from top) of this task among all visible tasks. (-1 means it's not visible)
243 // This number will be assigned when we evaluate OOM scores for all visible tasks.
244 int mLayerRank = -1;
245
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700246 Configuration mOverrideConfig = Configuration.EMPTY;
247
Craig Mautner21d24a22014-04-23 11:45:37 -0700248 TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Dianne Hackborn91097de2014-04-04 18:02:06 -0700249 IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700250 mService = service;
Craig Mautnera228ae92014-07-09 05:44:55 -0700251 mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
252 TaskPersister.IMAGE_EXTENSION;
Suprabh Shukla23593142015-11-03 17:31:15 -0800253 userId = UserHandle.getUserId(info.applicationInfo.uid);
254 mLastThumbnailFile = new File(TaskPersister.getUserImagesDir(userId), mFilename);
Winsonc809cbb2015-11-02 12:06:15 -0800255 mLastThumbnailInfo = new TaskThumbnailInfo();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800256 taskId = _taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700257 mAffiliatedTaskId = _taskId;
Dianne Hackborn91097de2014-04-04 18:02:06 -0700258 voiceSession = _voiceSession;
259 voiceInteractor = _voiceInteractor;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700260 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800261 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700262 mCallingUid = info.applicationInfo.uid;
263 mCallingPackage = info.packageName;
Martijn Coenend4a69702014-06-30 11:12:17 -0700264 setIntent(_intent, info);
Filip Gruszczynskid2f1d942015-10-14 15:10:12 -0700265 mMinimalSize = info != null && info.layout != null ? info.layout.minimalSize : -1;
Craig Mautner21d24a22014-04-23 11:45:37 -0700266 }
267
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700268 TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Winsonc809cbb2015-11-02 12:06:15 -0800269 TaskDescription _taskDescription, TaskThumbnailInfo thumbnailInfo) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700270 mService = service;
271 mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
272 TaskPersister.IMAGE_EXTENSION;
Suprabh Shukla23593142015-11-03 17:31:15 -0800273 userId = UserHandle.getUserId(info.applicationInfo.uid);
274 mLastThumbnailFile = new File(TaskPersister.getUserImagesDir(userId), mFilename);
Winsonc809cbb2015-11-02 12:06:15 -0800275 mLastThumbnailInfo = thumbnailInfo;
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700276 taskId = _taskId;
277 mAffiliatedTaskId = _taskId;
278 voiceSession = null;
279 voiceInteractor = null;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700280 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800281 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700282 mCallingUid = info.applicationInfo.uid;
283 mCallingPackage = info.packageName;
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700284 setIntent(_intent, info);
285
286 taskType = ActivityRecord.APPLICATION_ACTIVITY_TYPE;
287 isPersistable = true;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700288 // Clamp to [1, max].
289 maxRecents = Math.min(Math.max(info.maxRecents, 1),
290 ActivityManager.getMaxAppRecentsLimitStatic());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700291
292 taskType = APPLICATION_ACTIVITY_TYPE;
293 mTaskToReturnTo = HOME_ACTIVITY_TYPE;
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700294 lastTaskDescription = _taskDescription;
Filip Gruszczynskid2f1d942015-10-14 15:10:12 -0700295 mMinimalSize = info != null && info.layout != null ? info.layout.minimalSize : -1;
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700296 }
297
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800298 private TaskRecord(ActivityManagerService service, int _taskId, Intent _intent,
299 Intent _affinityIntent, String _affinity, String _rootAffinity,
300 ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset,
301 boolean _autoRemoveRecents, boolean _askedCompatMode, int _taskType, int _userId,
302 int _effectiveUid, String _lastDescription, ArrayList<ActivityRecord> activities,
303 long _firstActiveTime, long _lastActiveTime, long lastTimeMoved,
304 boolean neverRelinquishIdentity, TaskDescription _lastTaskDescription,
Winsonc809cbb2015-11-02 12:06:15 -0800305 TaskThumbnailInfo lastThumbnailInfo, int taskAffiliation, int prevTaskId,
306 int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage,
307 boolean resizeable, boolean privileged) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700308 mService = service;
Craig Mautnera228ae92014-07-09 05:44:55 -0700309 mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
310 TaskPersister.IMAGE_EXTENSION;
Suprabh Shukla23593142015-11-03 17:31:15 -0800311 mLastThumbnailFile = new File(TaskPersister.getUserImagesDir(_userId), mFilename);
Winsonc809cbb2015-11-02 12:06:15 -0800312 mLastThumbnailInfo = lastThumbnailInfo;
Craig Mautner21d24a22014-04-23 11:45:37 -0700313 taskId = _taskId;
314 intent = _intent;
315 affinityIntent = _affinityIntent;
316 affinity = _affinity;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800317 rootAffinity = _rootAffinity;
Craig Mautner21d24a22014-04-23 11:45:37 -0700318 voiceSession = null;
319 voiceInteractor = null;
320 realActivity = _realActivity;
321 origActivity = _origActivity;
322 rootWasReset = _rootWasReset;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700323 isAvailable = true;
Dianne Hackborn13420f22014-07-18 15:43:56 -0700324 autoRemoveRecents = _autoRemoveRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700325 askedCompatMode = _askedCompatMode;
326 taskType = _taskType;
Craig Mautner84984fa2014-06-19 11:19:20 -0700327 mTaskToReturnTo = HOME_ACTIVITY_TYPE;
Craig Mautner21d24a22014-04-23 11:45:37 -0700328 userId = _userId;
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700329 effectiveUid = _effectiveUid;
Winson Chungffa2ec62014-07-03 15:54:42 -0700330 firstActiveTime = _firstActiveTime;
Winson Chungf1fbd772014-06-24 18:06:58 -0700331 lastActiveTime = _lastActiveTime;
Craig Mautner21d24a22014-04-23 11:45:37 -0700332 lastDescription = _lastDescription;
333 mActivities = activities;
334 mLastTimeMoved = lastTimeMoved;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700335 mNeverRelinquishIdentity = neverRelinquishIdentity;
Winson Chung2cb86c72014-06-25 12:03:30 -0700336 lastTaskDescription = _lastTaskDescription;
Craig Mautnera228ae92014-07-09 05:44:55 -0700337 mAffiliatedTaskId = taskAffiliation;
Winson Chungec396d62014-08-06 17:08:00 -0700338 mAffiliatedTaskColor = taskAffiliationColor;
Craig Mautnera228ae92014-07-09 05:44:55 -0700339 mPrevAffiliateTaskId = prevTaskId;
340 mNextAffiliateTaskId = nextTaskId;
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700341 mCallingUid = callingUid;
342 mCallingPackage = callingPackage;
Wale Ogunwale7a8fa602015-11-18 15:56:57 -0800343 mResizeable = resizeable || mService.mForceResizableActivities;
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700344 mPrivileged = privileged;
Suprabh Shukla74f9f162015-11-06 15:39:42 -0800345 ActivityInfo info = (mActivities.size() > 0) ? mActivities.get(0).info : null;
Filip Gruszczynskid2f1d942015-10-14 15:10:12 -0700346 mMinimalSize = info != null && info.layout != null ? info.layout.minimalSize : -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800347 }
348
349 void touchActiveTime() {
Craig Mautner494f6bdd2014-07-21 11:17:46 -0700350 lastActiveTime = System.currentTimeMillis();
Winson Chungffa2ec62014-07-03 15:54:42 -0700351 if (firstActiveTime == 0) {
352 firstActiveTime = lastActiveTime;
353 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800354 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700355
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800356 long getInactiveDuration() {
Craig Mautner494f6bdd2014-07-21 11:17:46 -0700357 return System.currentTimeMillis() - lastActiveTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800358 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700359
Winson Chungfee26772014-08-05 12:21:52 -0700360 /** Sets the original intent, and the calling uid and package. */
361 void setIntent(ActivityRecord r) {
Winson Chungfee26772014-08-05 12:21:52 -0700362 mCallingUid = r.launchedFromUid;
363 mCallingPackage = r.launchedFromPackage;
Craig Mautner15df08a2015-04-01 12:17:18 -0700364 setIntent(r.intent, r.info);
Winson Chungfee26772014-08-05 12:21:52 -0700365 }
366
367 /** Sets the original intent, _without_ updating the calling uid or package. */
368 private void setIntent(Intent _intent, ActivityInfo info) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700369 if (intent == null) {
370 mNeverRelinquishIdentity =
371 (info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) == 0;
372 } else if (mNeverRelinquishIdentity) {
373 return;
374 }
375
376 affinity = info.taskAffinity;
Dianne Hackborn79228822014-09-16 11:11:23 -0700377 if (intent == null) {
378 // If this task already has an intent associated with it, don't set the root
379 // affinity -- we don't want it changing after initially set, but the initially
380 // set value may be null.
381 rootAffinity = affinity;
382 }
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700383 effectiveUid = info.applicationInfo.uid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700384 stringName = null;
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800385
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800386 if (info.targetActivity == null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800387 if (_intent != null) {
388 // If this Intent has a selector, we want to clear it for the
389 // recent task since it is not relevant if the user later wants
390 // to re-launch the app.
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700391 if (_intent.getSelector() != null || _intent.getSourceBounds() != null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800392 _intent = new Intent(_intent);
393 _intent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700394 _intent.setSourceBounds(null);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800395 }
396 }
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700397 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Setting Intent of " + this + " to " + _intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800398 intent = _intent;
399 realActivity = _intent != null ? _intent.getComponent() : null;
400 origActivity = null;
401 } else {
402 ComponentName targetComponent = new ComponentName(
403 info.packageName, info.targetActivity);
404 if (_intent != null) {
405 Intent targetIntent = new Intent(_intent);
406 targetIntent.setComponent(targetComponent);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800407 targetIntent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700408 targetIntent.setSourceBounds(null);
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700409 if (DEBUG_TASKS) Slog.v(TAG_TASKS,
Dianne Hackborn7f96b792012-05-29 18:46:45 -0700410 "Setting Intent of " + this + " to target " + targetIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800411 intent = targetIntent;
412 realActivity = targetComponent;
413 origActivity = _intent.getComponent();
414 } else {
415 intent = null;
416 realActivity = targetComponent;
417 origActivity = new ComponentName(info.packageName, info.name);
418 }
419 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700420
Craig Mautner47b20ba2014-09-17 17:23:44 -0700421 final int intentFlags = intent == null ? 0 : intent.getFlags();
422 if ((intentFlags & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800423 // Once we are set to an Intent with this flag, we count this
424 // task as having a true root activity.
425 rootWasReset = true;
426 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700427
Dianne Hackborn09233282014-04-30 11:33:59 -0700428 userId = UserHandle.getUserId(info.applicationInfo.uid);
Craig Mautner41db4a72014-05-07 17:20:56 -0700429 if ((info.flags & ActivityInfo.FLAG_AUTO_REMOVE_FROM_RECENTS) != 0) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700430 // If the activity itself has requested auto-remove, then just always do it.
431 autoRemoveRecents = true;
Wale Ogunwale843bfb92015-03-27 11:06:48 -0700432 } else if ((intentFlags & (FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS))
433 == FLAG_ACTIVITY_NEW_DOCUMENT) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700434 // If the caller has not asked for the document to be retained, then we may
435 // want to turn on auto-remove, depending on whether the target has set its
436 // own document launch mode.
437 if (info.documentLaunchMode != ActivityInfo.DOCUMENT_LAUNCH_NONE) {
438 autoRemoveRecents = false;
439 } else {
440 autoRemoveRecents = true;
441 }
442 } else {
443 autoRemoveRecents = false;
Craig Mautner41db4a72014-05-07 17:20:56 -0700444 }
Wale Ogunwale6cae7652015-12-26 07:36:26 -0800445 mResizeable = (info.flags & FLAG_RESIZEABLE) != 0 || mService.mForceResizableActivities;
Craig Mautner15df08a2015-04-01 12:17:18 -0700446 mLockTaskMode = info.lockTaskLaunchMode;
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700447 mPrivileged = (info.applicationInfo.privateFlags & PRIVATE_FLAG_PRIVILEGED) != 0;
Craig Mautner15df08a2015-04-01 12:17:18 -0700448 setLockTaskAuth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800449 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800450
Craig Mautner84984fa2014-06-19 11:19:20 -0700451 void setTaskToReturnTo(int taskToReturnTo) {
Wale Ogunwale2d0f39b2015-04-17 15:35:39 -0700452 mTaskToReturnTo = (IGNORE_RETURN_TO_RECENTS && taskToReturnTo == RECENTS_ACTIVITY_TYPE)
453 ? HOME_ACTIVITY_TYPE : taskToReturnTo;
Craig Mautner84984fa2014-06-19 11:19:20 -0700454 }
455
456 int getTaskToReturnTo() {
457 return mTaskToReturnTo;
458 }
459
Craig Mautnera228ae92014-07-09 05:44:55 -0700460 void setPrevAffiliate(TaskRecord prevAffiliate) {
461 mPrevAffiliate = prevAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800462 mPrevAffiliateTaskId = prevAffiliate == null ? INVALID_TASK_ID : prevAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700463 }
464
465 void setNextAffiliate(TaskRecord nextAffiliate) {
466 mNextAffiliate = nextAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800467 mNextAffiliateTaskId = nextAffiliate == null ? INVALID_TASK_ID : nextAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700468 }
469
470 // Close up recents linked list.
471 void closeRecentsChain() {
472 if (mPrevAffiliate != null) {
473 mPrevAffiliate.setNextAffiliate(mNextAffiliate);
474 }
475 if (mNextAffiliate != null) {
476 mNextAffiliate.setPrevAffiliate(mPrevAffiliate);
477 }
478 setPrevAffiliate(null);
479 setNextAffiliate(null);
480 }
481
Winson Chung740c3ac2014-11-12 16:14:38 -0800482 void removedFromRecents() {
Dianne Hackborn852975d2014-08-22 17:42:43 -0700483 disposeThumbnail();
484 closeRecentsChain();
485 if (inRecents) {
486 inRecents = false;
Winson Chung740c3ac2014-11-12 16:14:38 -0800487 mService.notifyTaskPersisterLocked(this, false);
Dianne Hackborn852975d2014-08-22 17:42:43 -0700488 }
489 }
490
Craig Mautnera228ae92014-07-09 05:44:55 -0700491 void setTaskToAffiliateWith(TaskRecord taskToAffiliateWith) {
492 closeRecentsChain();
493 mAffiliatedTaskId = taskToAffiliateWith.mAffiliatedTaskId;
Winson Chungec396d62014-08-06 17:08:00 -0700494 mAffiliatedTaskColor = taskToAffiliateWith.mAffiliatedTaskColor;
Craig Mautnera228ae92014-07-09 05:44:55 -0700495 // Find the end
496 while (taskToAffiliateWith.mNextAffiliate != null) {
497 final TaskRecord nextRecents = taskToAffiliateWith.mNextAffiliate;
498 if (nextRecents.mAffiliatedTaskId != mAffiliatedTaskId) {
499 Slog.e(TAG, "setTaskToAffiliateWith: nextRecents=" + nextRecents + " affilTaskId="
500 + nextRecents.mAffiliatedTaskId + " should be " + mAffiliatedTaskId);
501 if (nextRecents.mPrevAffiliate == taskToAffiliateWith) {
502 nextRecents.setPrevAffiliate(null);
503 }
504 taskToAffiliateWith.setNextAffiliate(null);
505 break;
506 }
507 taskToAffiliateWith = nextRecents;
508 }
509 taskToAffiliateWith.setNextAffiliate(this);
510 setPrevAffiliate(taskToAffiliateWith);
511 setNextAffiliate(null);
512 }
513
Winson Chung096f36b2014-08-20 15:39:01 -0700514 /**
Winsonc809cbb2015-11-02 12:06:15 -0800515 * Sets the last thumbnail with the current task bounds and the system orientation.
Winson Chung096f36b2014-08-20 15:39:01 -0700516 * @return whether the thumbnail was set
517 */
Winsonc809cbb2015-11-02 12:06:15 -0800518 boolean setLastThumbnailLocked(Bitmap thumbnail) {
519 final Configuration serviceConfig = mService.mConfiguration;
520 int taskWidth = 0;
521 int taskHeight = 0;
522 if (mBounds != null) {
523 // Non-fullscreen tasks
524 taskWidth = mBounds.width();
525 taskHeight = mBounds.height();
526 } else if (stack != null) {
527 // Fullscreen tasks
528 final Point displaySize = new Point();
529 stack.getDisplaySize(displaySize);
530 taskWidth = displaySize.x;
531 taskHeight = displaySize.y;
532 } else {
533 Slog.e(TAG, "setLastThumbnailLocked() called on Task without stack");
534 }
535 return setLastThumbnailLocked(thumbnail, taskWidth, taskHeight, serviceConfig.orientation);
536 }
537
538 /**
539 * Sets the last thumbnail with the current task bounds.
540 * @return whether the thumbnail was set
541 */
542 private boolean setLastThumbnailLocked(Bitmap thumbnail, int taskWidth, int taskHeight,
543 int screenOrientation) {
Winson Chung096f36b2014-08-20 15:39:01 -0700544 if (mLastThumbnail != thumbnail) {
545 mLastThumbnail = thumbnail;
Winsonc809cbb2015-11-02 12:06:15 -0800546 mLastThumbnailInfo.taskWidth = taskWidth;
547 mLastThumbnailInfo.taskHeight = taskHeight;
548 mLastThumbnailInfo.screenOrientation = screenOrientation;
Winson Chung096f36b2014-08-20 15:39:01 -0700549 if (thumbnail == null) {
550 if (mLastThumbnailFile != null) {
551 mLastThumbnailFile.delete();
552 }
553 } else {
Suprabh Shukla23593142015-11-03 17:31:15 -0800554 mService.mTaskPersister.saveImage(thumbnail, mLastThumbnailFile.getAbsolutePath());
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700555 }
Winson Chung096f36b2014-08-20 15:39:01 -0700556 return true;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700557 }
Winson Chung096f36b2014-08-20 15:39:01 -0700558 return false;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700559 }
560
561 void getLastThumbnail(TaskThumbnail thumbs) {
562 thumbs.mainThumbnail = mLastThumbnail;
Winsonc809cbb2015-11-02 12:06:15 -0800563 thumbs.thumbnailInfo = mLastThumbnailInfo;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700564 thumbs.thumbnailFileDescriptor = null;
Craig Mautnerf4f8bb72014-07-29 10:41:40 -0700565 if (mLastThumbnail == null) {
Suprabh Shukla23593142015-11-03 17:31:15 -0800566 thumbs.mainThumbnail = mService.mTaskPersister.getImageFromWriteQueue(
567 mLastThumbnailFile.getAbsolutePath());
Craig Mautnerf4f8bb72014-07-29 10:41:40 -0700568 }
Winson Chung096f36b2014-08-20 15:39:01 -0700569 // Only load the thumbnail file if we don't have a thumbnail
570 if (thumbs.mainThumbnail == null && mLastThumbnailFile.exists()) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700571 try {
572 thumbs.thumbnailFileDescriptor = ParcelFileDescriptor.open(mLastThumbnailFile,
573 ParcelFileDescriptor.MODE_READ_ONLY);
574 } catch (IOException e) {
Dianne Hackborn9844d292013-10-04 16:44:22 -0700575 }
576 }
577 }
578
Winsonc809cbb2015-11-02 12:06:15 -0800579 /**
580 * Removes in-memory thumbnail data when the max number of in-memory task thumbnails is reached.
581 */
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700582 void freeLastThumbnail() {
583 mLastThumbnail = null;
584 }
585
Winsonc809cbb2015-11-02 12:06:15 -0800586 /**
587 * Removes all associated thumbnail data when a task is removed or pruned from recents.
588 */
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700589 void disposeThumbnail() {
Winsonc6a2da02015-11-11 18:11:59 -0800590 mLastThumbnailInfo.reset();
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700591 mLastThumbnail = null;
592 lastDescription = null;
593 }
594
Winson Chung1147c402014-05-14 11:05:00 -0700595 /** Returns the intent for the root activity for this task */
596 Intent getBaseIntent() {
597 return intent != null ? intent : affinityIntent;
598 }
599
Winson Chung3b3f4642014-04-22 10:08:18 -0700600 /** Returns the first non-finishing activity from the root. */
601 ActivityRecord getRootActivity() {
602 for (int i = 0; i < mActivities.size(); i++) {
603 final ActivityRecord r = mActivities.get(i);
604 if (r.finishing) {
605 continue;
606 }
607 return r;
608 }
609 return null;
610 }
611
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800612 ActivityRecord getTopActivity() {
613 for (int i = mActivities.size() - 1; i >= 0; --i) {
614 final ActivityRecord r = mActivities.get(i);
615 if (r.finishing) {
616 continue;
617 }
618 return r;
619 }
620 return null;
621 }
622
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -0700623 ActivityRecord topRunningActivityLocked() {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700624 if (stack != null) {
625 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
626 ActivityRecord r = mActivities.get(activityNdx);
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -0700627 if (!r.finishing && stack.okToShowLocked(r)) {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700628 return r;
629 }
Craig Mautner6b74cb52013-09-27 17:02:21 -0700630 }
631 }
632 return null;
633 }
634
Wale Ogunwale6d42df62015-11-05 09:50:55 -0800635 void setFrontOfTask() {
636 setFrontOfTask(null);
637 }
638
Craig Mautner3b475fe2013-12-16 15:58:31 -0800639 /** Call after activity movement or finish to make sure that frontOfTask is set correctly */
Wale Ogunwale6d42df62015-11-05 09:50:55 -0800640 void setFrontOfTask(ActivityRecord newTop) {
641 // If a top candidate is suggested by the caller, go ahead and use it and mark all others
642 // as not front. This is needed in situations where the current front activity in the
643 // task isn't finished yet and we want to set the front to the activity moved to the front
644 // of the task.
645 boolean foundFront = newTop != null ? true : false;
646
Craig Mautner3b475fe2013-12-16 15:58:31 -0800647 final int numActivities = mActivities.size();
Craig Mautner704e40b2013-12-18 16:43:51 -0800648 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
Craig Mautner3b475fe2013-12-16 15:58:31 -0800649 final ActivityRecord r = mActivities.get(activityNdx);
650 if (foundFront || r.finishing) {
651 r.frontOfTask = false;
652 } else {
653 r.frontOfTask = true;
654 // Set frontOfTask false for every following activity.
655 foundFront = true;
656 }
657 }
Craig Mautner9587ee02014-06-23 15:00:10 +0000658 if (!foundFront && numActivities > 0) {
659 // All activities of this task are finishing. As we ought to have a frontOfTask
660 // activity, make the bottom activity front.
661 mActivities.get(0).frontOfTask = true;
662 }
Wale Ogunwale6d42df62015-11-05 09:50:55 -0800663 if (newTop != null) {
664 newTop.frontOfTask = true;
665 }
Craig Mautner3b475fe2013-12-16 15:58:31 -0800666 }
667
Craig Mautnerde4ef022013-04-07 19:01:33 -0700668 /**
Craig Mautner3b475fe2013-12-16 15:58:31 -0800669 * Reorder the history stack so that the passed activity is brought to the front.
Craig Mautnerde4ef022013-04-07 19:01:33 -0700670 */
671 final void moveActivityToFrontLocked(ActivityRecord newTop) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -0700672 if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE,
673 "Removing and adding activity " + newTop
674 + " to stack at top callers=" + Debug.getCallers(4));
Craig Mautnerde4ef022013-04-07 19:01:33 -0700675
Craig Mautnerde4ef022013-04-07 19:01:33 -0700676 mActivities.remove(newTop);
677 mActivities.add(newTop);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700678 updateEffectiveIntent();
Craig Mautner3b475fe2013-12-16 15:58:31 -0800679
Wale Ogunwale6d42df62015-11-05 09:50:55 -0800680 setFrontOfTask(newTop);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700681 }
682
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800683 void addActivityAtBottom(ActivityRecord r) {
Craig Mautner77878772013-03-04 19:46:24 -0800684 addActivityAtIndex(0, r);
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800685 }
686
687 void addActivityToTop(ActivityRecord r) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700688 addActivityAtIndex(mActivities.size(), r);
689 }
690
691 void addActivityAtIndex(int index, ActivityRecord r) {
Craig Mautner6170f732013-04-02 13:05:23 -0700692 // 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 -0800693 if (!mActivities.remove(r) && r.fullscreen) {
694 // Was not previously in list.
695 numFullscreen++;
696 }
Craig Mautner2c1faed2013-07-23 12:56:02 -0700697 // Only set this based on the first activity
698 if (mActivities.isEmpty()) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700699 taskType = r.mActivityType;
Wale Ogunwale7a8fa602015-11-18 15:56:57 -0800700 if (taskType == HOME_ACTIVITY_TYPE && mService.mForceResizableActivities) {
Wale Ogunwale6cae7652015-12-26 07:36:26 -0800701 mResizeable = r.isResizeable();
Jorim Jaggi8ccdf3a2015-10-22 12:50:31 +0200702 }
Craig Mautner21d24a22014-04-23 11:45:37 -0700703 isPersistable = r.isPersistable();
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700704 mCallingUid = r.launchedFromUid;
705 mCallingPackage = r.launchedFromPackage;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700706 // Clamp to [1, max].
707 maxRecents = Math.min(Math.max(r.info.maxRecents, 1),
708 ActivityManager.getMaxAppRecentsLimitStatic());
Craig Mautner2c1faed2013-07-23 12:56:02 -0700709 } else {
710 // Otherwise make all added activities match this one.
Craig Mautner21d24a22014-04-23 11:45:37 -0700711 r.mActivityType = taskType;
Craig Mautner78733002013-06-10 13:54:49 -0700712 }
Craig Mautner77878772013-03-04 19:46:24 -0800713 mActivities.add(index, r);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700714 updateEffectiveIntent();
Craig Mautner21d24a22014-04-23 11:45:37 -0700715 if (r.isPersistable()) {
716 mService.notifyTaskPersisterLocked(this, false);
717 }
Craig Mautner77878772013-03-04 19:46:24 -0800718 }
719
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800720 /** @return true if this was the last activity in the task */
721 boolean removeActivity(ActivityRecord r) {
722 if (mActivities.remove(r) && r.fullscreen) {
723 // Was previously in list.
724 numFullscreen--;
725 }
Craig Mautner21d24a22014-04-23 11:45:37 -0700726 if (r.isPersistable()) {
727 mService.notifyTaskPersisterLocked(this, false);
728 }
Craig Mautner41326202014-06-20 14:38:21 -0700729 if (mActivities.isEmpty()) {
Craig Mautner5afcd4d2014-06-21 18:11:33 -0700730 return !mReuseTask;
Craig Mautner41326202014-06-20 14:38:21 -0700731 }
732 updateEffectiveIntent();
733 return false;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800734 }
735
Craig Mautner41db4a72014-05-07 17:20:56 -0700736 boolean autoRemoveFromRecents() {
Dianne Hackbornd38aed82014-06-10 21:36:35 -0700737 // We will automatically remove the task either if it has explicitly asked for
738 // this, or it is empty and has never contained an activity that got shown to
739 // the user.
Dianne Hackborn13420f22014-07-18 15:43:56 -0700740 return autoRemoveRecents || (mActivities.isEmpty() && !hasBeenVisible);
Craig Mautner41db4a72014-05-07 17:20:56 -0700741 }
742
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700743 /**
744 * Completely remove all activities associated with an existing
745 * task starting at a specified index.
746 */
747 final void performClearTaskAtIndexLocked(int activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700748 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700749 for ( ; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700750 final ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700751 if (r.finishing) {
752 continue;
753 }
Craig Mautner21d24a22014-04-23 11:45:37 -0700754 if (stack == null) {
755 // Task was restored from persistent storage.
756 r.takeFromHistory();
757 mActivities.remove(activityNdx);
758 --activityNdx;
759 --numActivities;
Todd Kennedy539db512014-12-15 09:57:55 -0800760 } else if (stack.finishActivityLocked(
761 r, Activity.RESULT_CANCELED, null, "clear-task-index", false)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700762 --activityNdx;
763 --numActivities;
764 }
765 }
766 }
767
768 /**
769 * Completely remove all activities associated with an existing task.
770 */
771 final void performClearTaskLocked() {
Craig Mautner362449a2014-06-20 14:04:39 -0700772 mReuseTask = true;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700773 performClearTaskAtIndexLocked(0);
Craig Mautner362449a2014-06-20 14:04:39 -0700774 mReuseTask = false;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700775 }
776
777 /**
778 * Perform clear operation as requested by
779 * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the
780 * stack to the given task, then look for
781 * an instance of that activity in the stack and, if found, finish all
782 * activities on top of it and return the instance.
783 *
784 * @param newR Description of the new activity being started.
785 * @return Returns the old activity that should be continued to be used,
786 * or null if none was found.
787 */
788 final ActivityRecord performClearTaskLocked(ActivityRecord newR, int launchFlags) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700789 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700790 for (int activityNdx = numActivities - 1; activityNdx >= 0; --activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700791 ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700792 if (r.finishing) {
793 continue;
794 }
795 if (r.realActivity.equals(newR.realActivity)) {
796 // Here it is! Now finish everything in front...
Craig Mautner1602ec22013-05-12 10:24:27 -0700797 final ActivityRecord ret = r;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700798
799 for (++activityNdx; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700800 r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700801 if (r.finishing) {
802 continue;
803 }
804 ActivityOptions opts = r.takeOptionsLocked();
805 if (opts != null) {
806 ret.updateOptionsLocked(opts);
807 }
Wale Ogunwale7d701172015-03-11 15:36:30 -0700808 if (stack != null && stack.finishActivityLocked(
Todd Kennedy539db512014-12-15 09:57:55 -0800809 r, Activity.RESULT_CANCELED, null, "clear-task-stack", false)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700810 --activityNdx;
811 --numActivities;
812 }
813 }
814
815 // Finally, if this is a normal launch mode (that is, not
816 // expecting onNewIntent()), then we will finish the current
817 // instance of the activity so a new fresh one can be started.
818 if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE
819 && (launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0) {
820 if (!ret.finishing) {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700821 if (stack != null) {
822 stack.finishActivityLocked(
823 ret, Activity.RESULT_CANCELED, null, "clear-task-top", false);
824 }
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700825 return null;
826 }
827 }
828
829 return ret;
830 }
831 }
832
833 return null;
834 }
835
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700836 public TaskThumbnail getTaskThumbnailLocked() {
Craig Mautner21d24a22014-04-23 11:45:37 -0700837 if (stack != null) {
838 final ActivityRecord resumedActivity = stack.mResumedActivity;
839 if (resumedActivity != null && resumedActivity.task == this) {
Winson8b1871d2015-11-20 09:56:20 -0800840 final Bitmap thumbnail = stack.screenshotActivitiesLocked(resumedActivity);
Winsonc809cbb2015-11-02 12:06:15 -0800841 setLastThumbnailLocked(thumbnail);
Craig Mautner21d24a22014-04-23 11:45:37 -0700842 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700843 }
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700844 final TaskThumbnail taskThumbnail = new TaskThumbnail();
845 getLastThumbnail(taskThumbnail);
846 return taskThumbnail;
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700847 }
848
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700849 public void removeTaskActivitiesLocked() {
850 // Just remove the entire task.
851 performClearTaskAtIndexLocked(0);
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700852 }
853
Craig Mautner432f64e2015-05-20 14:59:57 -0700854 String lockTaskAuthToString() {
855 switch (mLockTaskAuth) {
856 case LOCK_TASK_AUTH_DONT_LOCK: return "LOCK_TASK_AUTH_DONT_LOCK";
857 case LOCK_TASK_AUTH_PINNABLE: return "LOCK_TASK_AUTH_PINNABLE";
858 case LOCK_TASK_AUTH_LAUNCHABLE: return "LOCK_TASK_AUTH_LAUNCHABLE";
859 case LOCK_TASK_AUTH_WHITELISTED: return "LOCK_TASK_AUTH_WHITELISTED";
Benjamin Franz469dd582015-06-09 14:24:36 +0100860 case LOCK_TASK_AUTH_LAUNCHABLE_PRIV: return "LOCK_TASK_AUTH_LAUNCHABLE_PRIV";
Craig Mautner432f64e2015-05-20 14:59:57 -0700861 default: return "unknown=" + mLockTaskAuth;
862 }
863 }
864
Craig Mautner15df08a2015-04-01 12:17:18 -0700865 void setLockTaskAuth() {
Benjamin Franz469dd582015-06-09 14:24:36 +0100866 if (!mPrivileged &&
867 (mLockTaskMode == LOCK_TASK_LAUNCH_MODE_ALWAYS ||
868 mLockTaskMode == LOCK_TASK_LAUNCH_MODE_NEVER)) {
869 // Non-priv apps are not allowed to use always or never, fall back to default
870 mLockTaskMode = LOCK_TASK_LAUNCH_MODE_DEFAULT;
871 }
Craig Mautner15df08a2015-04-01 12:17:18 -0700872 switch (mLockTaskMode) {
873 case LOCK_TASK_LAUNCH_MODE_DEFAULT:
874 mLockTaskAuth = isLockTaskWhitelistedLocked() ?
875 LOCK_TASK_AUTH_WHITELISTED : LOCK_TASK_AUTH_PINNABLE;
876 break;
877
878 case LOCK_TASK_LAUNCH_MODE_NEVER:
Benjamin Franz469dd582015-06-09 14:24:36 +0100879 mLockTaskAuth = LOCK_TASK_AUTH_DONT_LOCK;
Craig Mautner15df08a2015-04-01 12:17:18 -0700880 break;
881
882 case LOCK_TASK_LAUNCH_MODE_ALWAYS:
Benjamin Franz469dd582015-06-09 14:24:36 +0100883 mLockTaskAuth = LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
Craig Mautner15df08a2015-04-01 12:17:18 -0700884 break;
885
886 case LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED:
887 mLockTaskAuth = isLockTaskWhitelistedLocked() ?
888 LOCK_TASK_AUTH_LAUNCHABLE : LOCK_TASK_AUTH_PINNABLE;
889 break;
890 }
Craig Mautner432f64e2015-05-20 14:59:57 -0700891 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
892 " mLockTaskAuth=" + lockTaskAuthToString());
Craig Mautner15df08a2015-04-01 12:17:18 -0700893 }
894
895 boolean isLockTaskWhitelistedLocked() {
Benjamin Franz6fd84cc2015-08-06 18:09:03 +0100896 String pkg = (realActivity != null) ? realActivity.getPackageName() : null;
897 if (pkg == null) {
Craig Mautner15df08a2015-04-01 12:17:18 -0700898 return false;
899 }
900 String[] packages = mService.mLockTaskPackages.get(userId);
901 if (packages == null) {
902 return false;
903 }
904 for (int i = packages.length - 1; i >= 0; --i) {
Benjamin Franz6fd84cc2015-08-06 18:09:03 +0100905 if (pkg.equals(packages[i])) {
Craig Mautner15df08a2015-04-01 12:17:18 -0700906 return true;
907 }
908 }
909 return false;
910 }
Craig Mautnera82aa092013-09-13 15:34:08 -0700911 boolean isHomeTask() {
Craig Mautner84984fa2014-06-19 11:19:20 -0700912 return taskType == HOME_ACTIVITY_TYPE;
Craig Mautnera82aa092013-09-13 15:34:08 -0700913 }
914
Craig Mautner86d67a42013-05-14 10:34:38 -0700915 boolean isApplicationTask() {
Craig Mautner84984fa2014-06-19 11:19:20 -0700916 return taskType == APPLICATION_ACTIVITY_TYPE;
917 }
918
919 boolean isOverHomeStack() {
920 return mTaskToReturnTo == HOME_ACTIVITY_TYPE || mTaskToReturnTo == RECENTS_ACTIVITY_TYPE;
Craig Mautner1602ec22013-05-12 10:24:27 -0700921 }
922
Craig Mautner525f3d92013-05-07 14:01:50 -0700923 /**
924 * Find the activity in the history stack within the given task. Returns
925 * the index within the history at which it's found, or < 0 if not found.
926 */
927 final ActivityRecord findActivityInHistoryLocked(ActivityRecord r) {
928 final ComponentName realActivity = r.realActivity;
929 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
930 ActivityRecord candidate = mActivities.get(activityNdx);
931 if (candidate.finishing) {
932 continue;
933 }
934 if (candidate.realActivity.equals(realActivity)) {
935 return candidate;
936 }
937 }
938 return null;
939 }
940
Winson Chunga449dc02014-05-16 11:15:04 -0700941 /** Updates the last task description values. */
942 void updateTaskDescription() {
943 // Traverse upwards looking for any break between main task activities and
944 // utility activities.
945 int activityNdx;
946 final int numActivities = mActivities.size();
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700947 final boolean relinquish = numActivities == 0 ? false :
948 (mActivities.get(0).info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) != 0;
Winson Chunga449dc02014-05-16 11:15:04 -0700949 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
Craig Mautner21d24a22014-04-23 11:45:37 -0700950 ++activityNdx) {
Winson Chunga449dc02014-05-16 11:15:04 -0700951 final ActivityRecord r = mActivities.get(activityNdx);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700952 if (relinquish && (r.info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
953 // This will be the top activity for determining taskDescription. Pre-inc to
954 // overcome initial decrement below.
955 ++activityNdx;
956 break;
957 }
Winson Chunga449dc02014-05-16 11:15:04 -0700958 if (r.intent != null &&
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700959 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
Winson Chunga449dc02014-05-16 11:15:04 -0700960 break;
961 }
962 }
963 if (activityNdx > 0) {
964 // Traverse downwards starting below break looking for set label, icon.
965 // Note that if there are activities in the task but none of them set the
966 // recent activity values, then we do not fall back to the last set
967 // values in the TaskRecord.
968 String label = null;
Craig Mautner648f69b2014-09-18 14:16:26 -0700969 String iconFilename = null;
Winson Chunga449dc02014-05-16 11:15:04 -0700970 int colorPrimary = 0;
971 for (--activityNdx; activityNdx >= 0; --activityNdx) {
972 final ActivityRecord r = mActivities.get(activityNdx);
973 if (r.taskDescription != null) {
974 if (label == null) {
975 label = r.taskDescription.getLabel();
976 }
Craig Mautner648f69b2014-09-18 14:16:26 -0700977 if (iconFilename == null) {
978 iconFilename = r.taskDescription.getIconFilename();
Winson Chunga449dc02014-05-16 11:15:04 -0700979 }
980 if (colorPrimary == 0) {
981 colorPrimary = r.taskDescription.getPrimaryColor();
Winson Chunga449dc02014-05-16 11:15:04 -0700982 }
983 }
984 }
Craig Mautner648f69b2014-09-18 14:16:26 -0700985 lastTaskDescription = new TaskDescription(label, colorPrimary, iconFilename);
Winson Chungec396d62014-08-06 17:08:00 -0700986 // Update the task affiliation color if we are the parent of the group
987 if (taskId == mAffiliatedTaskId) {
988 mAffiliatedTaskColor = lastTaskDescription.getPrimaryColor();
989 }
Winson Chunga449dc02014-05-16 11:15:04 -0700990 }
991 }
992
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700993 int findEffectiveRootIndex() {
Craig Mautner4767f4b2014-09-18 15:38:33 -0700994 int effectiveNdx = 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700995 final int topActivityNdx = mActivities.size() - 1;
Dianne Hackborn39569af2014-09-23 10:56:58 -0700996 for (int activityNdx = 0; activityNdx <= topActivityNdx; ++activityNdx) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700997 final ActivityRecord r = mActivities.get(activityNdx);
998 if (r.finishing) {
999 continue;
1000 }
Craig Mautner4767f4b2014-09-18 15:38:33 -07001001 effectiveNdx = activityNdx;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001002 if ((r.info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
1003 break;
1004 }
1005 }
Craig Mautner4767f4b2014-09-18 15:38:33 -07001006 return effectiveNdx;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001007 }
1008
1009 void updateEffectiveIntent() {
1010 final int effectiveRootIndex = findEffectiveRootIndex();
1011 final ActivityRecord r = mActivities.get(effectiveRootIndex);
Winson Chungfee26772014-08-05 12:21:52 -07001012 setIntent(r);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001013 }
1014
Craig Mautner21d24a22014-04-23 11:45:37 -07001015 void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001016 if (DEBUG_RECENTS) Slog.i(TAG_RECENTS, "Saving task=" + this);
Craig Mautner21d24a22014-04-23 11:45:37 -07001017
1018 out.attribute(null, ATTR_TASKID, String.valueOf(taskId));
1019 if (realActivity != null) {
1020 out.attribute(null, ATTR_REALACTIVITY, realActivity.flattenToShortString());
1021 }
1022 if (origActivity != null) {
1023 out.attribute(null, ATTR_ORIGACTIVITY, origActivity.flattenToShortString());
1024 }
Dianne Hackborn79228822014-09-16 11:11:23 -07001025 // Write affinity, and root affinity if it is different from affinity.
1026 // We use the special string "@" for a null root affinity, so we can identify
1027 // later whether we were given a root affinity or should just make it the
1028 // same as the affinity.
Craig Mautner21d24a22014-04-23 11:45:37 -07001029 if (affinity != null) {
1030 out.attribute(null, ATTR_AFFINITY, affinity);
Dianne Hackborn79228822014-09-16 11:11:23 -07001031 if (!affinity.equals(rootAffinity)) {
1032 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
1033 }
1034 } else if (rootAffinity != null) {
1035 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
Craig Mautner21d24a22014-04-23 11:45:37 -07001036 }
1037 out.attribute(null, ATTR_ROOTHASRESET, String.valueOf(rootWasReset));
Dianne Hackborn13420f22014-07-18 15:43:56 -07001038 out.attribute(null, ATTR_AUTOREMOVERECENTS, String.valueOf(autoRemoveRecents));
Craig Mautner21d24a22014-04-23 11:45:37 -07001039 out.attribute(null, ATTR_ASKEDCOMPATMODE, String.valueOf(askedCompatMode));
1040 out.attribute(null, ATTR_USERID, String.valueOf(userId));
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001041 out.attribute(null, ATTR_EFFECTIVE_UID, String.valueOf(effectiveUid));
Craig Mautner21d24a22014-04-23 11:45:37 -07001042 out.attribute(null, ATTR_TASKTYPE, String.valueOf(taskType));
Winson Chungffa2ec62014-07-03 15:54:42 -07001043 out.attribute(null, ATTR_FIRSTACTIVETIME, String.valueOf(firstActiveTime));
Winson Chungf1fbd772014-06-24 18:06:58 -07001044 out.attribute(null, ATTR_LASTACTIVETIME, String.valueOf(lastActiveTime));
Craig Mautner21d24a22014-04-23 11:45:37 -07001045 out.attribute(null, ATTR_LASTTIMEMOVED, String.valueOf(mLastTimeMoved));
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001046 out.attribute(null, ATTR_NEVERRELINQUISH, String.valueOf(mNeverRelinquishIdentity));
Craig Mautner21d24a22014-04-23 11:45:37 -07001047 if (lastDescription != null) {
1048 out.attribute(null, ATTR_LASTDESCRIPTION, lastDescription.toString());
1049 }
Winson Chung2cb86c72014-06-25 12:03:30 -07001050 if (lastTaskDescription != null) {
Craig Mautner648f69b2014-09-18 14:16:26 -07001051 lastTaskDescription.saveToXml(out);
Winson Chung2cb86c72014-06-25 12:03:30 -07001052 }
Winsonc809cbb2015-11-02 12:06:15 -08001053 mLastThumbnailInfo.saveToXml(out);
Winson Chungec396d62014-08-06 17:08:00 -07001054 out.attribute(null, ATTR_TASK_AFFILIATION_COLOR, String.valueOf(mAffiliatedTaskColor));
Craig Mautnera228ae92014-07-09 05:44:55 -07001055 out.attribute(null, ATTR_TASK_AFFILIATION, String.valueOf(mAffiliatedTaskId));
1056 out.attribute(null, ATTR_PREV_AFFILIATION, String.valueOf(mPrevAffiliateTaskId));
1057 out.attribute(null, ATTR_NEXT_AFFILIATION, String.valueOf(mNextAffiliateTaskId));
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001058 out.attribute(null, ATTR_CALLING_UID, String.valueOf(mCallingUid));
1059 out.attribute(null, ATTR_CALLING_PACKAGE, mCallingPackage == null ? "" : mCallingPackage);
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -08001060 out.attribute(null, ATTR_RESIZEABLE, String.valueOf(mResizeable));
Wale Ogunwalea7afaa22015-05-01 20:39:18 -07001061 out.attribute(null, ATTR_PRIVILEGED, String.valueOf(mPrivileged));
Wale Ogunwale706ed792015-08-02 10:29:44 -07001062 if (mLastNonFullscreenBounds != null) {
1063 out.attribute(
1064 null, ATTR_NON_FULLSCREEN_BOUNDS, mLastNonFullscreenBounds.flattenToString());
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001065 }
Winson Chung2cb86c72014-06-25 12:03:30 -07001066
Craig Mautner21d24a22014-04-23 11:45:37 -07001067 if (affinityIntent != null) {
1068 out.startTag(null, TAG_AFFINITYINTENT);
1069 affinityIntent.saveToXml(out);
1070 out.endTag(null, TAG_AFFINITYINTENT);
1071 }
1072
1073 out.startTag(null, TAG_INTENT);
1074 intent.saveToXml(out);
1075 out.endTag(null, TAG_INTENT);
1076
1077 final ArrayList<ActivityRecord> activities = mActivities;
1078 final int numActivities = activities.size();
1079 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
1080 final ActivityRecord r = activities.get(activityNdx);
Craig Mautner43e52ed2014-06-16 17:18:52 -07001081 if (r.info.persistableMode == ActivityInfo.PERSIST_ROOT_ONLY || !r.isPersistable() ||
Wale Ogunwale843bfb92015-03-27 11:06:48 -07001082 ((r.intent.getFlags() & FLAG_ACTIVITY_NEW_DOCUMENT
1083 | FLAG_ACTIVITY_RETAIN_IN_RECENTS) == FLAG_ACTIVITY_NEW_DOCUMENT) &&
Craig Mautner43e52ed2014-06-16 17:18:52 -07001084 activityNdx > 0) {
Craig Mautnerf357c0c2014-06-09 09:23:27 -07001085 // Stop at first non-persistable or first break in task (CLEAR_WHEN_TASK_RESET).
Craig Mautner21d24a22014-04-23 11:45:37 -07001086 break;
1087 }
1088 out.startTag(null, TAG_ACTIVITY);
1089 r.saveToXml(out);
1090 out.endTag(null, TAG_ACTIVITY);
1091 }
Craig Mautner21d24a22014-04-23 11:45:37 -07001092 }
1093
1094 static TaskRecord restoreFromXml(XmlPullParser in, ActivityStackSupervisor stackSupervisor)
1095 throws IOException, XmlPullParserException {
1096 Intent intent = null;
1097 Intent affinityIntent = null;
Winsonc809cbb2015-11-02 12:06:15 -08001098 ArrayList<ActivityRecord> activities = new ArrayList<>();
Craig Mautner21d24a22014-04-23 11:45:37 -07001099 ComponentName realActivity = null;
1100 ComponentName origActivity = null;
1101 String affinity = null;
Dianne Hackborn79228822014-09-16 11:11:23 -07001102 String rootAffinity = null;
1103 boolean hasRootAffinity = false;
Craig Mautner21d24a22014-04-23 11:45:37 -07001104 boolean rootHasReset = false;
Dianne Hackborn13420f22014-07-18 15:43:56 -07001105 boolean autoRemoveRecents = false;
Craig Mautner21d24a22014-04-23 11:45:37 -07001106 boolean askedCompatMode = false;
1107 int taskType = ActivityRecord.APPLICATION_ACTIVITY_TYPE;
Craig Mautner21d24a22014-04-23 11:45:37 -07001108 int userId = 0;
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001109 int effectiveUid = -1;
Craig Mautner21d24a22014-04-23 11:45:37 -07001110 String lastDescription = null;
Winson Chungffa2ec62014-07-03 15:54:42 -07001111 long firstActiveTime = -1;
Winson Chung2cb86c72014-06-25 12:03:30 -07001112 long lastActiveTime = -1;
Craig Mautner21d24a22014-04-23 11:45:37 -07001113 long lastTimeOnTop = 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001114 boolean neverRelinquishIdentity = true;
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001115 int taskId = INVALID_TASK_ID;
Craig Mautner21d24a22014-04-23 11:45:37 -07001116 final int outerDepth = in.getDepth();
Craig Mautner648f69b2014-09-18 14:16:26 -07001117 TaskDescription taskDescription = new TaskDescription();
Winsonc809cbb2015-11-02 12:06:15 -08001118 TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
Wale Ogunwale18795a22014-12-03 11:38:33 -08001119 int taskAffiliation = INVALID_TASK_ID;
Winson Chungec396d62014-08-06 17:08:00 -07001120 int taskAffiliationColor = 0;
Wale Ogunwale18795a22014-12-03 11:38:33 -08001121 int prevTaskId = INVALID_TASK_ID;
1122 int nextTaskId = INVALID_TASK_ID;
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001123 int callingUid = -1;
1124 String callingPackage = "";
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -08001125 boolean resizeable = false;
Wale Ogunwalea7afaa22015-05-01 20:39:18 -07001126 boolean privileged = false;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001127 Rect bounds = null;
Craig Mautner21d24a22014-04-23 11:45:37 -07001128
1129 for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
1130 final String attrName = in.getAttributeName(attrNdx);
1131 final String attrValue = in.getAttributeValue(attrNdx);
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001132 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: attribute name=" +
1133 attrName + " value=" + attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001134 if (ATTR_TASKID.equals(attrName)) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08001135 if (taskId == INVALID_TASK_ID) taskId = Integer.valueOf(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001136 } else if (ATTR_REALACTIVITY.equals(attrName)) {
1137 realActivity = ComponentName.unflattenFromString(attrValue);
1138 } else if (ATTR_ORIGACTIVITY.equals(attrName)) {
1139 origActivity = ComponentName.unflattenFromString(attrValue);
1140 } else if (ATTR_AFFINITY.equals(attrName)) {
1141 affinity = attrValue;
Dianne Hackborn79228822014-09-16 11:11:23 -07001142 } else if (ATTR_ROOT_AFFINITY.equals(attrName)) {
1143 rootAffinity = attrValue;
1144 hasRootAffinity = true;
Craig Mautner21d24a22014-04-23 11:45:37 -07001145 } else if (ATTR_ROOTHASRESET.equals(attrName)) {
1146 rootHasReset = Boolean.valueOf(attrValue);
Dianne Hackborn13420f22014-07-18 15:43:56 -07001147 } else if (ATTR_AUTOREMOVERECENTS.equals(attrName)) {
1148 autoRemoveRecents = Boolean.valueOf(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001149 } else if (ATTR_ASKEDCOMPATMODE.equals(attrName)) {
1150 askedCompatMode = Boolean.valueOf(attrValue);
1151 } else if (ATTR_USERID.equals(attrName)) {
1152 userId = Integer.valueOf(attrValue);
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001153 } else if (ATTR_EFFECTIVE_UID.equals(attrName)) {
1154 effectiveUid = Integer.valueOf(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001155 } else if (ATTR_TASKTYPE.equals(attrName)) {
1156 taskType = Integer.valueOf(attrValue);
Winson Chungffa2ec62014-07-03 15:54:42 -07001157 } else if (ATTR_FIRSTACTIVETIME.equals(attrName)) {
1158 firstActiveTime = Long.valueOf(attrValue);
Winson Chungf1fbd772014-06-24 18:06:58 -07001159 } else if (ATTR_LASTACTIVETIME.equals(attrName)) {
1160 lastActiveTime = Long.valueOf(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001161 } else if (ATTR_LASTDESCRIPTION.equals(attrName)) {
1162 lastDescription = attrValue;
1163 } else if (ATTR_LASTTIMEMOVED.equals(attrName)) {
1164 lastTimeOnTop = Long.valueOf(attrValue);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001165 } else if (ATTR_NEVERRELINQUISH.equals(attrName)) {
1166 neverRelinquishIdentity = Boolean.valueOf(attrValue);
Winsonc809cbb2015-11-02 12:06:15 -08001167 } else if (attrName.startsWith(TaskThumbnailInfo.ATTR_TASK_THUMBNAILINFO_PREFIX)) {
1168 thumbnailInfo.restoreFromXml(attrName, attrValue);
Craig Mautner648f69b2014-09-18 14:16:26 -07001169 } else if (attrName.startsWith(TaskDescription.ATTR_TASKDESCRIPTION_PREFIX)) {
1170 taskDescription.restoreFromXml(attrName, attrValue);
Craig Mautnera228ae92014-07-09 05:44:55 -07001171 } else if (ATTR_TASK_AFFILIATION.equals(attrName)) {
1172 taskAffiliation = Integer.valueOf(attrValue);
1173 } else if (ATTR_PREV_AFFILIATION.equals(attrName)) {
1174 prevTaskId = Integer.valueOf(attrValue);
1175 } else if (ATTR_NEXT_AFFILIATION.equals(attrName)) {
1176 nextTaskId = Integer.valueOf(attrValue);
Winson Chungec396d62014-08-06 17:08:00 -07001177 } else if (ATTR_TASK_AFFILIATION_COLOR.equals(attrName)) {
1178 taskAffiliationColor = Integer.valueOf(attrValue);
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001179 } else if (ATTR_CALLING_UID.equals(attrName)) {
1180 callingUid = Integer.valueOf(attrValue);
1181 } else if (ATTR_CALLING_PACKAGE.equals(attrName)) {
1182 callingPackage = attrValue;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -08001183 } else if (ATTR_RESIZEABLE.equals(attrName)) {
1184 resizeable = Boolean.valueOf(attrValue);
Wale Ogunwalea7afaa22015-05-01 20:39:18 -07001185 } else if (ATTR_PRIVILEGED.equals(attrName)) {
1186 privileged = Boolean.valueOf(attrValue);
Wale Ogunwale706ed792015-08-02 10:29:44 -07001187 } else if (ATTR_NON_FULLSCREEN_BOUNDS.equals(attrName)) {
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001188 bounds = Rect.unflattenFromString(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001189 } else {
1190 Slog.w(TAG, "TaskRecord: Unknown attribute=" + attrName);
1191 }
1192 }
1193
1194 int event;
1195 while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
Ben Kwa8814cf42015-07-08 10:54:56 -07001196 (event != XmlPullParser.END_TAG || in.getDepth() >= outerDepth)) {
Craig Mautner21d24a22014-04-23 11:45:37 -07001197 if (event == XmlPullParser.START_TAG) {
1198 final String name = in.getName();
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001199 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: START_TAG name=" +
1200 name);
Craig Mautner21d24a22014-04-23 11:45:37 -07001201 if (TAG_AFFINITYINTENT.equals(name)) {
1202 affinityIntent = Intent.restoreFromXml(in);
1203 } else if (TAG_INTENT.equals(name)) {
1204 intent = Intent.restoreFromXml(in);
1205 } else if (TAG_ACTIVITY.equals(name)) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08001206 ActivityRecord activity = ActivityRecord.restoreFromXml(in, stackSupervisor);
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001207 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: activity=" +
1208 activity);
Craig Mautner21d24a22014-04-23 11:45:37 -07001209 if (activity != null) {
1210 activities.add(activity);
1211 }
1212 } else {
1213 Slog.e(TAG, "restoreTask: Unexpected name=" + name);
1214 XmlUtils.skipCurrentTag(in);
1215 }
1216 }
1217 }
Dianne Hackborn79228822014-09-16 11:11:23 -07001218 if (!hasRootAffinity) {
1219 rootAffinity = affinity;
1220 } else if ("@".equals(rootAffinity)) {
1221 rootAffinity = null;
1222 }
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001223 if (effectiveUid <= 0) {
1224 Intent checkIntent = intent != null ? intent : affinityIntent;
1225 effectiveUid = 0;
1226 if (checkIntent != null) {
1227 IPackageManager pm = AppGlobals.getPackageManager();
1228 try {
1229 ApplicationInfo ai = pm.getApplicationInfo(
1230 checkIntent.getComponent().getPackageName(),
1231 PackageManager.GET_UNINSTALLED_PACKAGES
1232 | PackageManager.GET_DISABLED_COMPONENTS, userId);
1233 if (ai != null) {
1234 effectiveUid = ai.uid;
1235 }
1236 } catch (RemoteException e) {
1237 }
1238 }
1239 Slog.w(TAG, "Updating task #" + taskId + " for " + checkIntent
1240 + ": effectiveUid=" + effectiveUid);
1241 }
1242
Craig Mautner21d24a22014-04-23 11:45:37 -07001243 final TaskRecord task = new TaskRecord(stackSupervisor.mService, taskId, intent,
Dianne Hackborn79228822014-09-16 11:11:23 -07001244 affinityIntent, affinity, rootAffinity, realActivity, origActivity, rootHasReset,
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001245 autoRemoveRecents, askedCompatMode, taskType, userId, effectiveUid, lastDescription,
1246 activities, firstActiveTime, lastActiveTime, lastTimeOnTop, neverRelinquishIdentity,
Winsonc809cbb2015-11-02 12:06:15 -08001247 taskDescription, thumbnailInfo, taskAffiliation, prevTaskId, nextTaskId,
1248 taskAffiliationColor, callingUid, callingPackage, resizeable, privileged);
Filip Gruszczynskiaff7f132015-09-02 17:21:21 -07001249 task.updateOverrideConfiguration(bounds);
Craig Mautner21d24a22014-04-23 11:45:37 -07001250
1251 for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001252 activities.get(activityNdx).task = task;
Craig Mautner21d24a22014-04-23 11:45:37 -07001253 }
1254
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001255 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Restored task=" + task);
Craig Mautner21d24a22014-04-23 11:45:37 -07001256 return task;
1257 }
1258
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001259 /**
1260 * Update task's override configuration based on the bounds.
1261 * @return Update configuration or null if there is no change.
1262 */
Filip Gruszczynskiaff7f132015-09-02 17:21:21 -07001263 Configuration updateOverrideConfiguration(Rect bounds) {
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001264 if (Objects.equals(mBounds, bounds)) {
1265 return null;
1266 }
Wale Ogunwale5f986092015-12-04 15:35:38 -08001267 final Configuration oldConfig = mOverrideConfig;
1268 final boolean oldFullscreen = mFullscreen;
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001269
1270 mFullscreen = bounds == null;
Wale Ogunwale706ed792015-08-02 10:29:44 -07001271 if (mFullscreen) {
Wale Ogunwale3797c222015-10-27 14:21:58 -07001272 if (mBounds != null && StackId.persistTaskBounds(stack.mStackId)) {
Wale Ogunwale706ed792015-08-02 10:29:44 -07001273 mLastNonFullscreenBounds = mBounds;
1274 }
1275 mBounds = null;
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001276 mOverrideConfig = Configuration.EMPTY;
Wale Ogunwale706ed792015-08-02 10:29:44 -07001277 } else {
Chong Zhangb15758a2015-11-17 12:12:03 -08001278 if (mBounds == null) {
1279 mBounds = new Rect(bounds);
1280 } else {
1281 mBounds.set(bounds);
1282 }
Wale Ogunwale3797c222015-10-27 14:21:58 -07001283 if (stack == null || StackId.persistTaskBounds(stack.mStackId)) {
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -07001284 mLastNonFullscreenBounds = mBounds;
1285 }
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001286
1287 final Configuration serviceConfig = mService.mConfiguration;
Wale Ogunwale3856bf72015-11-20 09:36:46 -08001288 mOverrideConfig = new Configuration(Configuration.EMPTY);
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001289 // TODO(multidisplay): Update Dp to that of display stack is on.
1290 final float density = serviceConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
1291 mOverrideConfig.screenWidthDp =
1292 Math.min((int)(mBounds.width() / density), serviceConfig.screenWidthDp);
1293 mOverrideConfig.screenHeightDp =
1294 Math.min((int)(mBounds.height() / density), serviceConfig.screenHeightDp);
1295 mOverrideConfig.smallestScreenWidthDp =
1296 Math.min(mOverrideConfig.screenWidthDp, mOverrideConfig.screenHeightDp);
1297 mOverrideConfig.orientation =
1298 (mOverrideConfig.screenWidthDp <= mOverrideConfig.screenHeightDp)
1299 ? Configuration.ORIENTATION_PORTRAIT
1300 : Configuration.ORIENTATION_LANDSCAPE;
Filip Gruszczynski3c2db1d12016-01-06 17:39:14 -08001301 final int sl = Configuration.resetScreenLayout(serviceConfig.screenLayout);
1302 mOverrideConfig.screenLayout = Configuration.reduceScreenLayout(
1303 sl, mOverrideConfig.screenWidthDp, mOverrideConfig.screenHeightDp);
Wale Ogunwale706ed792015-08-02 10:29:44 -07001304 }
Wale Ogunwale5f986092015-12-04 15:35:38 -08001305
1306 if (mFullscreen != oldFullscreen) {
1307 reportMultiWindowModeChange();
1308 }
1309
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001310 return !mOverrideConfig.equals(oldConfig) ? mOverrideConfig : null;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001311 }
1312
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08001313 Rect updateOverrideConfigurationFromLaunchBounds() {
1314 final Rect bounds = validateBounds(getLaunchBounds());
1315 updateOverrideConfiguration(bounds);
1316 return bounds;
1317 }
1318
1319 static Rect validateBounds(Rect bounds) {
1320 if (bounds != null && bounds.isEmpty()) {
1321 Slog.wtf(TAG, "Received strange task bounds: " + bounds, new Throwable());
1322 return null;
1323 }
1324 return bounds;
1325 }
1326
Wale Ogunwale5f986092015-12-04 15:35:38 -08001327 private void reportMultiWindowModeChange() {
1328 for (int i = mActivities.size() - 1; i >= 0; i--) {
1329 final ActivityRecord r = mActivities.get(i);
1330 if (r.app != null && r.app.thread != null) {
1331 try {
1332 // An activity is consider to be in multi-window mode if its task isn't
1333 // fullscreen.
1334 r.app.thread.scheduleMultiWindowModeChanged(r.appToken, !mFullscreen);
1335 } catch (Exception e) {
1336 Slog.e(TAG, "TaskRecord.reportMultiWindowModeChange: ", e);
1337 }
1338 }
1339 }
1340 }
1341
Wale Ogunwaled046a012015-12-24 13:05:59 -08001342 void reportPictureInPictureModeChangeIfNeeded(ActivityStack prevStack) {
1343 if (prevStack == null || prevStack == stack
1344 || (prevStack.mStackId != PINNED_STACK_ID && stack.mStackId != PINNED_STACK_ID)) {
1345 return;
1346 }
1347
Wale Ogunwale5f986092015-12-04 15:35:38 -08001348 for (int i = mActivities.size() - 1; i >= 0; i--) {
1349 final ActivityRecord r = mActivities.get(i);
1350 if (r.app != null && r.app.thread != null) {
1351 try {
1352 r.app.thread.schedulePictureInPictureModeChanged(
1353 r.appToken, stack.mStackId == PINNED_STACK_ID);
1354 } catch (Exception e) {
1355 Slog.e(TAG, "TaskRecord.reportMultiWindowModeChange: ", e);
1356 }
1357 }
1358 }
1359 }
1360
Wale Ogunwale935e5022015-11-10 12:36:10 -08001361 /** Updates the task's bounds and override configuration to match what is expected for the
1362 * input stack. */
1363 void updateOverrideConfigurationForStack(ActivityStack inStack) {
1364 if (stack != null && stack == inStack) {
1365 return;
1366 }
1367
1368 if (inStack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
1369 if (!mResizeable) {
1370 throw new IllegalArgumentException("Can not position non-resizeable task="
1371 + this + " in stack=" + inStack);
1372 }
1373 if (mBounds != null) {
1374 return;
1375 }
1376 if (mLastNonFullscreenBounds != null) {
1377 updateOverrideConfiguration(mLastNonFullscreenBounds);
1378 } else {
1379 inStack.layoutTaskInStack(this, null);
1380 }
1381 } else {
1382 updateOverrideConfiguration(inStack.mBounds);
1383 }
1384 }
1385
Chong Zhang0fa656b2015-08-31 15:17:21 -07001386 /**
1387 * Returns the correct stack to use based on task type and currently set bounds,
1388 * regardless of the focused stack and current stack association of the task.
1389 * The task will be moved (and stack focus changed) later if necessary.
1390 */
1391 int getLaunchStackId() {
1392 if (!isApplicationTask()) {
Wale Ogunwale706ed792015-08-02 10:29:44 -07001393 return HOME_STACK_ID;
1394 }
Chong Zhang0fa656b2015-08-31 15:17:21 -07001395 if (mBounds != null) {
Wale Ogunwale706ed792015-08-02 10:29:44 -07001396 return FREEFORM_WORKSPACE_STACK_ID;
1397 }
1398 return FULLSCREEN_WORKSPACE_STACK_ID;
1399 }
1400
1401 /** Returns the bounds that should be used to launch this task. */
1402 Rect getLaunchBounds() {
Wale Ogunwale99db1862015-10-23 20:08:22 -07001403 final int stackId = stack.mStackId;
Chong Zhang75b37202015-12-04 14:16:36 -08001404
1405 // If we're over lockscreen, forget about stack bounds and use fullscreen.
1406 if (mService.mLockScreenShown == LOCK_SCREEN_SHOWN) {
1407 return null;
1408 }
1409
Wale Ogunwale706ed792015-08-02 10:29:44 -07001410 if (stack == null
Wale Ogunwale99db1862015-10-23 20:08:22 -07001411 || stackId == HOME_STACK_ID
1412 || stackId == FULLSCREEN_WORKSPACE_STACK_ID) {
Wale Ogunwalea6e902e2015-09-21 18:37:15 -07001413 return (mResizeable && stack != null) ? stack.mBounds : null;
Wale Ogunwale3797c222015-10-27 14:21:58 -07001414 } else if (!StackId.persistTaskBounds(stackId)) {
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -07001415 return stack.mBounds;
Wale Ogunwale706ed792015-08-02 10:29:44 -07001416 }
1417 return mLastNonFullscreenBounds;
1418 }
1419
Wale Ogunwale39381972015-12-17 17:15:29 -08001420 boolean canMatchRootAffinity() {
1421 // We don't allow root affinity matching on the pinned stack as no other task should
1422 // be launching in it based on affinity.
1423 return rootAffinity != null && (stack == null || stack.mStackId != PINNED_STACK_ID);
1424 }
1425
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001426 void dump(PrintWriter pw, String prefix) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001427 pw.print(prefix); pw.print("userId="); pw.print(userId);
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001428 pw.print(" effectiveUid="); UserHandle.formatUid(pw, effectiveUid);
1429 pw.print(" mCallingUid="); UserHandle.formatUid(pw, mCallingUid);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001430 pw.print(" mCallingPackage="); pw.println(mCallingPackage);
Dianne Hackborn79228822014-09-16 11:11:23 -07001431 if (affinity != null || rootAffinity != null) {
1432 pw.print(prefix); pw.print("affinity="); pw.print(affinity);
1433 if (affinity == null || !affinity.equals(rootAffinity)) {
1434 pw.print(" root="); pw.println(rootAffinity);
1435 } else {
1436 pw.println();
1437 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001438 }
Dianne Hackborn91097de2014-04-04 18:02:06 -07001439 if (voiceSession != null || voiceInteractor != null) {
1440 pw.print(prefix); pw.print("VOICE: session=0x");
1441 pw.print(Integer.toHexString(System.identityHashCode(voiceSession)));
1442 pw.print(" interactor=0x");
1443 pw.println(Integer.toHexString(System.identityHashCode(voiceInteractor)));
1444 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001445 if (intent != null) {
1446 StringBuilder sb = new StringBuilder(128);
1447 sb.append(prefix); sb.append("intent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08001448 intent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001449 sb.append('}');
1450 pw.println(sb.toString());
1451 }
1452 if (affinityIntent != null) {
1453 StringBuilder sb = new StringBuilder(128);
1454 sb.append(prefix); sb.append("affinityIntent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08001455 affinityIntent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001456 sb.append('}');
1457 pw.println(sb.toString());
1458 }
1459 if (origActivity != null) {
1460 pw.print(prefix); pw.print("origActivity=");
1461 pw.println(origActivity.flattenToShortString());
1462 }
1463 if (realActivity != null) {
1464 pw.print(prefix); pw.print("realActivity=");
1465 pw.println(realActivity.flattenToShortString());
1466 }
Dianne Hackborn852975d2014-08-22 17:42:43 -07001467 if (autoRemoveRecents || isPersistable || taskType != 0 || mTaskToReturnTo != 0
1468 || numFullscreen != 0) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001469 pw.print(prefix); pw.print("autoRemoveRecents="); pw.print(autoRemoveRecents);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001470 pw.print(" isPersistable="); pw.print(isPersistable);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001471 pw.print(" numFullscreen="); pw.print(numFullscreen);
1472 pw.print(" taskType="); pw.print(taskType);
1473 pw.print(" mTaskToReturnTo="); pw.println(mTaskToReturnTo);
1474 }
Craig Mautner432f64e2015-05-20 14:59:57 -07001475 if (rootWasReset || mNeverRelinquishIdentity || mReuseTask
1476 || mLockTaskAuth != LOCK_TASK_AUTH_PINNABLE) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001477 pw.print(prefix); pw.print("rootWasReset="); pw.print(rootWasReset);
1478 pw.print(" mNeverRelinquishIdentity="); pw.print(mNeverRelinquishIdentity);
Craig Mautner432f64e2015-05-20 14:59:57 -07001479 pw.print(" mReuseTask="); pw.print(mReuseTask);
1480 pw.print(" mLockTaskAuth="); pw.println(lockTaskAuthToString());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001481 }
Wale Ogunwale18795a22014-12-03 11:38:33 -08001482 if (mAffiliatedTaskId != taskId || mPrevAffiliateTaskId != INVALID_TASK_ID
1483 || mPrevAffiliate != null || mNextAffiliateTaskId != INVALID_TASK_ID
1484 || mNextAffiliate != null) {
Dianne Hackborn852975d2014-08-22 17:42:43 -07001485 pw.print(prefix); pw.print("affiliation="); pw.print(mAffiliatedTaskId);
1486 pw.print(" prevAffiliation="); pw.print(mPrevAffiliateTaskId);
1487 pw.print(" (");
1488 if (mPrevAffiliate == null) {
1489 pw.print("null");
1490 } else {
1491 pw.print(Integer.toHexString(System.identityHashCode(mPrevAffiliate)));
1492 }
1493 pw.print(") nextAffiliation="); pw.print(mNextAffiliateTaskId);
1494 pw.print(" (");
1495 if (mNextAffiliate == null) {
1496 pw.print("null");
1497 } else {
1498 pw.print(Integer.toHexString(System.identityHashCode(mNextAffiliate)));
1499 }
1500 pw.println(")");
1501 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001502 pw.print(prefix); pw.print("Activities="); pw.println(mActivities);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001503 if (!askedCompatMode || !inRecents || !isAvailable) {
1504 pw.print(prefix); pw.print("askedCompatMode="); pw.print(askedCompatMode);
1505 pw.print(" inRecents="); pw.print(inRecents);
1506 pw.print(" isAvailable="); pw.println(isAvailable);
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001507 }
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001508 pw.print(prefix); pw.print("lastThumbnail="); pw.print(mLastThumbnail);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001509 pw.print(" lastThumbnailFile="); pw.println(mLastThumbnailFile);
1510 if (lastDescription != null) {
1511 pw.print(prefix); pw.print("lastDescription="); pw.println(lastDescription);
1512 }
Wale Ogunwale069fbe42015-07-29 11:38:01 -07001513 if (stack != null) {
1514 pw.print(prefix); pw.print("stackId="); pw.println(stack.mStackId);
1515 }
Dianne Hackbornd38aed82014-06-10 21:36:35 -07001516 pw.print(prefix); pw.print("hasBeenVisible="); pw.print(hasBeenVisible);
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -08001517 pw.print(" mResizeable="); pw.print(mResizeable);
Winson Chungffa2ec62014-07-03 15:54:42 -07001518 pw.print(" firstActiveTime="); pw.print(lastActiveTime);
Dianne Hackbornd38aed82014-06-10 21:36:35 -07001519 pw.print(" lastActiveTime="); pw.print(lastActiveTime);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001520 pw.print(" (inactive for ");
1521 pw.print((getInactiveDuration()/1000)); pw.println("s)");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001522 }
1523
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001524 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001525 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001526 StringBuilder sb = new StringBuilder(128);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001527 if (stringName != null) {
1528 sb.append(stringName);
1529 sb.append(" U=");
1530 sb.append(userId);
Wale Ogunwale6c5eb1c2015-11-10 07:52:22 -08001531 sb.append(" StackId=");
1532 sb.append(stack != null ? stack.mStackId : INVALID_STACK_ID);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001533 sb.append(" sz=");
1534 sb.append(mActivities.size());
1535 sb.append('}');
1536 return sb.toString();
1537 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001538 sb.append("TaskRecord{");
1539 sb.append(Integer.toHexString(System.identityHashCode(this)));
1540 sb.append(" #");
1541 sb.append(taskId);
1542 if (affinity != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001543 sb.append(" A=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001544 sb.append(affinity);
1545 } else if (intent != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001546 sb.append(" I=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001547 sb.append(intent.getComponent().flattenToShortString());
1548 } else if (affinityIntent != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001549 sb.append(" aI=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001550 sb.append(affinityIntent.getComponent().flattenToShortString());
1551 } else {
1552 sb.append(" ??");
1553 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07001554 stringName = sb.toString();
1555 return toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001556 }
1557}