blob: e8476dd6e0ed7f849968b4b2f6253c4442c973b1 [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
Chong Zhang7d5f5102016-01-13 10:29:24 -080019import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
Wale Ogunwale3797c222015-10-27 14:21:58 -070020import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
21import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
22import static android.app.ActivityManager.StackId.HOME_STACK_ID;
Wale Ogunwale6c5eb1c2015-11-10 07:52:22 -080023import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
Wale Ogunwale5f986092015-12-04 15:35:38 -080024import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
Wale Ogunwale843bfb92015-03-27 11:06:48 -070025import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
26import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
Wale Ogunwaleb1faf602016-01-27 09:12:31 -080027import static android.content.pm.ActivityInfo.RESIZE_MODE_CROP_WINDOWS;
Wale Ogunwaled26176f2016-01-25 20:04:04 -080028import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
Wale Ogunwaleb1faf602016-01-27 09:12:31 -080029import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
Craig Mautner15df08a2015-04-01 12:17:18 -070030import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
31import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
32import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
33import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER;
Wale Ogunwalea7afaa22015-05-01 20:39:18 -070034import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
Suprabh Shukla23593142015-11-03 17:31:15 -080035import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ADD_REMOVE;
36import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
37import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
38import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
39import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_ADD_REMOVE;
40import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
41import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
42import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS;
43import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
44import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
Chong Zhang75b37202015-12-04 14:16:36 -080045import static com.android.server.am.ActivityManagerService.LOCK_SCREEN_SHOWN;
Craig Mautner84984fa2014-06-19 11:19:20 -070046import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
Suprabh Shukla23593142015-11-03 17:31:15 -080047import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
Craig Mautner84984fa2014-06-19 11:19:20 -070048import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
Craig Mautnerde4ef022013-04-07 19:01:33 -070049
Craig Mautnerb0f7dc72013-04-01 16:34:45 -070050import android.app.Activity;
Craig Mautner9db9a0b2013-04-29 17:05:56 -070051import android.app.ActivityManager;
Wale Ogunwale3797c222015-10-27 14:21:58 -070052import android.app.ActivityManager.StackId;
Craig Mautner648f69b2014-09-18 14:16:26 -070053import android.app.ActivityManager.TaskDescription;
Wale Ogunwaleff3c66c2015-11-18 19:22:49 -080054import android.app.ActivityManager.TaskThumbnail;
Winsonc809cbb2015-11-02 12:06:15 -080055import android.app.ActivityManager.TaskThumbnailInfo;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -070056import android.app.ActivityOptions;
Dianne Hackborn885fbe52014-08-23 15:23:58 -070057import android.app.AppGlobals;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058import android.content.ComponentName;
59import android.content.Intent;
60import android.content.pm.ActivityInfo;
Dianne Hackborn885fbe52014-08-23 15:23:58 -070061import android.content.pm.ApplicationInfo;
62import android.content.pm.IPackageManager;
63import android.content.pm.PackageManager;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -070064import android.content.res.Configuration;
Craig Mautner9db9a0b2013-04-29 17:05:56 -070065import android.graphics.Bitmap;
Winsonc809cbb2015-11-02 12:06:15 -080066import android.graphics.Point;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -070067import android.graphics.Rect;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -070068import android.os.Debug;
Craig Mautnerc0ffce52014-07-01 12:38:52 -070069import android.os.ParcelFileDescriptor;
Dianne Hackborn885fbe52014-08-23 15:23:58 -070070import android.os.RemoteException;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070071import android.os.UserHandle;
Dianne Hackborn91097de2014-04-04 18:02:06 -070072import android.service.voice.IVoiceInteractionSession;
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -070073import android.util.DisplayMetrics;
Dianne Hackborn7f96b792012-05-29 18:46:45 -070074import android.util.Slog;
Suprabh Shukla23593142015-11-03 17:31:15 -080075
Dianne Hackborn91097de2014-04-04 18:02:06 -070076import com.android.internal.app.IVoiceInteractor;
Craig Mautner21d24a22014-04-23 11:45:37 -070077import com.android.internal.util.XmlUtils;
Suprabh Shukla23593142015-11-03 17:31:15 -080078
Craig Mautner21d24a22014-04-23 11:45:37 -070079import org.xmlpull.v1.XmlPullParser;
80import org.xmlpull.v1.XmlPullParserException;
81import org.xmlpull.v1.XmlSerializer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082
Craig Mautnerc0ffce52014-07-01 12:38:52 -070083import java.io.File;
Craig Mautner21d24a22014-04-23 11:45:37 -070084import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085import java.io.PrintWriter;
Craig Mautner5d9c7be2013-02-15 14:02:56 -080086import java.util.ArrayList;
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -070087import java.util.Objects;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088
Craig Mautnerc0ffce52014-07-01 12:38:52 -070089final class TaskRecord {
Wale Ogunwalee23149f2015-03-06 15:39:44 -080090 private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskRecord" : TAG_AM;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -070091 private static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE;
Wale Ogunwaleee006da2015-03-30 14:49:25 -070092 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
Craig Mautnere0570202015-05-13 13:06:11 -070093 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwaleee006da2015-03-30 14:49:25 -070094 private static final String TAG_TASKS = TAG + POSTFIX_TASKS;
Wale Ogunwalee23149f2015-03-06 15:39:44 -080095
Wale Ogunwale18795a22014-12-03 11:38:33 -080096 static final String ATTR_TASKID = "task_id";
Craig Mautner21d24a22014-04-23 11:45:37 -070097 private static final String TAG_INTENT = "intent";
98 private static final String TAG_AFFINITYINTENT = "affinity_intent";
Wale Ogunwale18795a22014-12-03 11:38:33 -080099 static final String ATTR_REALACTIVITY = "real_activity";
Andrei Stingaceanu4ccec532016-01-13 12:10:21 +0000100 static final String ATTR_REALACTIVITY_SUSPENDED = "real_activity_suspended";
Craig Mautner21d24a22014-04-23 11:45:37 -0700101 private static final String ATTR_ORIGACTIVITY = "orig_activity";
Stefan Kuhnee88d1e52015-05-18 10:33:45 -0700102 private static final String TAG_ACTIVITY = "activity";
Craig Mautner21d24a22014-04-23 11:45:37 -0700103 private static final String ATTR_AFFINITY = "affinity";
Dianne Hackborn79228822014-09-16 11:11:23 -0700104 private static final String ATTR_ROOT_AFFINITY = "root_affinity";
Craig Mautner21d24a22014-04-23 11:45:37 -0700105 private static final String ATTR_ROOTHASRESET = "root_has_reset";
Dianne Hackborn13420f22014-07-18 15:43:56 -0700106 private static final String ATTR_AUTOREMOVERECENTS = "auto_remove_recents";
Craig Mautner21d24a22014-04-23 11:45:37 -0700107 private static final String ATTR_ASKEDCOMPATMODE = "asked_compat_mode";
108 private static final String ATTR_USERID = "user_id";
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800109 private static final String ATTR_USER_SETUP_COMPLETE = "user_setup_complete";
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700110 private static final String ATTR_EFFECTIVE_UID = "effective_uid";
Craig Mautner21d24a22014-04-23 11:45:37 -0700111 private static final String ATTR_TASKTYPE = "task_type";
Winson Chungffa2ec62014-07-03 15:54:42 -0700112 private static final String ATTR_FIRSTACTIVETIME = "first_active_time";
Winson Chungf1fbd772014-06-24 18:06:58 -0700113 private static final String ATTR_LASTACTIVETIME = "last_active_time";
Craig Mautner21d24a22014-04-23 11:45:37 -0700114 private static final String ATTR_LASTDESCRIPTION = "last_description";
115 private static final String ATTR_LASTTIMEMOVED = "last_time_moved";
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700116 private static final String ATTR_NEVERRELINQUISH = "never_relinquish_identity";
Wale Ogunwale18795a22014-12-03 11:38:33 -0800117 static final String ATTR_TASK_AFFILIATION = "task_affiliation";
Craig Mautnera228ae92014-07-09 05:44:55 -0700118 private static final String ATTR_PREV_AFFILIATION = "prev_affiliation";
119 private static final String ATTR_NEXT_AFFILIATION = "next_affiliation";
Winson Chungec396d62014-08-06 17:08:00 -0700120 private static final String ATTR_TASK_AFFILIATION_COLOR = "task_affiliation_color";
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700121 private static final String ATTR_CALLING_UID = "calling_uid";
122 private static final String ATTR_CALLING_PACKAGE = "calling_package";
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800123 // TODO(b/26847884): Currently needed while migrating to resize_mode.
124 // Can be removed at some later point.
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800125 private static final String ATTR_RESIZEABLE = "resizeable";
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800126 private static final String ATTR_RESIZE_MODE = "resize_mode";
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700127 private static final String ATTR_PRIVILEGED = "privileged";
Wale Ogunwale706ed792015-08-02 10:29:44 -0700128 private static final String ATTR_NON_FULLSCREEN_BOUNDS = "non_fullscreen_bounds";
Craig Mautner21d24a22014-04-23 11:45:37 -0700129
130 private static final String TASK_THUMBNAIL_SUFFIX = "_task_thumbnail";
131
Wale Ogunwale18795a22014-12-03 11:38:33 -0800132 static final int INVALID_TASK_ID = -1;
133
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134 final int taskId; // Unique identifier for this task.
Dianne Hackborn79228822014-09-16 11:11:23 -0700135 String affinity; // The affinity name for this task, or null; may change identity.
136 String rootAffinity; // Initial base affinity, or null; does not change from initial root.
Dianne Hackborn91097de2014-04-04 18:02:06 -0700137 final IVoiceInteractionSession voiceSession; // Voice interaction session driving task
138 final IVoiceInteractor voiceInteractor; // Associated interactor to provide to app
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800139 Intent intent; // The original intent that started the task.
140 Intent affinityIntent; // Intent of affinity-moved activity that started this task.
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700141 int effectiveUid; // The current effective uid of the identity of this task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800142 ComponentName origActivity; // The non-alias activity component of the intent.
143 ComponentName realActivity; // The actual activity component that started the task.
Andrei Stingaceanu4ccec532016-01-13 12:10:21 +0000144 boolean realActivitySuspended; // True if the actual activity component that started the
145 // task is suspended.
Winson Chungffa2ec62014-07-03 15:54:42 -0700146 long firstActiveTime; // First time this task was active.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147 long lastActiveTime; // Last time this task was active, including sleep.
Dianne Hackborn852975d2014-08-22 17:42:43 -0700148 boolean inRecents; // Actually in the recents list?
149 boolean isAvailable; // Is the activity available to be launched?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150 boolean rootWasReset; // True if the intent at the root of the task had
151 // the FLAG_ACTIVITY_RESET_TASK_IF_NEEDED flag.
Dianne Hackborn13420f22014-07-18 15:43:56 -0700152 boolean autoRemoveRecents; // If true, we should automatically remove the task from
153 // recents when activity finishes
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700154 boolean askedCompatMode;// Have asked the user about compat mode for this task.
Dianne Hackbornd38aed82014-06-10 21:36:35 -0700155 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 -0800156
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700157 String stringName; // caching of toString() result.
Dianne Hackborn9da2d402012-03-15 13:43:08 -0700158 int userId; // user for which this task was created
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800159 boolean mUserSetupComplete; // The user set-up is complete as of the last time the task activity
160 // was changed.
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800161
162 int numFullscreen; // Number of fullscreen activities.
163
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800164 int mResizeMode; // The resize mode of this task and its activities.
165 // Based on the {@link ActivityInfo#resizeMode} of the root activity.
Craig Mautner15df08a2015-04-01 12:17:18 -0700166 int mLockTaskMode; // Which tasklock mode to launch this task in. One of
167 // ActivityManager.LOCK_TASK_LAUNCH_MODE_*
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700168 private boolean mPrivileged; // The root activity application of this task holds
169 // privileged permissions.
170
Craig Mautner15df08a2015-04-01 12:17:18 -0700171 /** Can't be put in lockTask mode. */
172 final static int LOCK_TASK_AUTH_DONT_LOCK = 0;
Benjamin Franz469dd582015-06-09 14:24:36 +0100173 /** Can enter app pinning with user approval. Can never start over existing lockTask task. */
Craig Mautner15df08a2015-04-01 12:17:18 -0700174 final static int LOCK_TASK_AUTH_PINNABLE = 1;
175 /** Starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing lockTask task. */
176 final static int LOCK_TASK_AUTH_LAUNCHABLE = 2;
Benjamin Franz469dd582015-06-09 14:24:36 +0100177 /** Can enter lockTask without user approval. Can start over existing lockTask task. */
Craig Mautner15df08a2015-04-01 12:17:18 -0700178 final static int LOCK_TASK_AUTH_WHITELISTED = 3;
Benjamin Franz469dd582015-06-09 14:24:36 +0100179 /** Priv-app that starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing
180 * lockTask task. */
181 final static int LOCK_TASK_AUTH_LAUNCHABLE_PRIV = 4;
Craig Mautner15df08a2015-04-01 12:17:18 -0700182 int mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE;
183
184 int mLockTaskUid = -1; // The uid of the application that called startLockTask().
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800185
Winson Chung03a9bae2014-05-02 09:56:12 -0700186 // This represents the last resolved activity values for this task
187 // NOTE: This value needs to be persisted with each task
Craig Mautner648f69b2014-09-18 14:16:26 -0700188 TaskDescription lastTaskDescription = new TaskDescription();
Winson Chung03a9bae2014-05-02 09:56:12 -0700189
Craig Mautnerd2328952013-03-05 12:46:26 -0800190 /** List of all activities in the task arranged in history order */
Craig Mautner21d24a22014-04-23 11:45:37 -0700191 final ArrayList<ActivityRecord> mActivities;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800192
Craig Mautnerd2328952013-03-05 12:46:26 -0800193 /** Current stack */
194 ActivityStack stack;
195
Craig Mautner2c1faed2013-07-23 12:56:02 -0700196 /** Takes on same set of values as ActivityRecord.mActivityType */
Craig Mautner21d24a22014-04-23 11:45:37 -0700197 int taskType;
Craig Mautner1602ec22013-05-12 10:24:27 -0700198
Craig Mautner21d24a22014-04-23 11:45:37 -0700199 /** Takes on same value as first root activity */
200 boolean isPersistable = false;
Craig Mautnerffcfcaa2014-06-05 09:54:38 -0700201 int maxRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700202
203 /** Only used for persistable tasks, otherwise 0. The last time this task was moved. Used for
204 * determining the order when restoring. Sign indicates whether last task movement was to front
205 * (positive) or back (negative). Absolute value indicates time. */
206 long mLastTimeMoved = System.currentTimeMillis();
207
Craig Mautner84984fa2014-06-19 11:19:20 -0700208 /** Indication of what to run next when task exits. Use ActivityRecord types.
209 * ActivityRecord.APPLICATION_ACTIVITY_TYPE indicates to resume the task below this one in the
210 * task stack. */
211 private int mTaskToReturnTo = APPLICATION_ACTIVITY_TYPE;
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700212
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700213 /** If original intent did not allow relinquishing task identity, save that information */
214 boolean mNeverRelinquishIdentity = true;
215
Craig Mautner362449a2014-06-20 14:04:39 -0700216 // Used in the unique case where we are clearing the task in order to reuse it. In that case we
217 // do not want to delete the stack when the task goes empty.
Filip Gruszczynskibe9dabd2016-01-19 12:23:10 -0800218 private boolean mReuseTask = false;
Craig Mautner362449a2014-06-20 14:04:39 -0700219
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700220 private Bitmap mLastThumbnail; // Last thumbnail captured for this item.
Wale Ogunwalebe23ff42014-10-21 16:29:51 -0700221 private final File mLastThumbnailFile; // File containing last thumbnail.
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700222 private final String mFilename;
Winsonc809cbb2015-11-02 12:06:15 -0800223 private TaskThumbnailInfo mLastThumbnailInfo;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700224 CharSequence lastDescription; // Last description captured for this item.
225
Craig Mautnera228ae92014-07-09 05:44:55 -0700226 int mAffiliatedTaskId; // taskId of parent affiliation or self if no parent.
Winson Chungec396d62014-08-06 17:08:00 -0700227 int mAffiliatedTaskColor; // color of the parent task affiliation.
Craig Mautnera228ae92014-07-09 05:44:55 -0700228 TaskRecord mPrevAffiliate; // previous task in affiliated chain.
Wale Ogunwale18795a22014-12-03 11:38:33 -0800229 int mPrevAffiliateTaskId = INVALID_TASK_ID; // previous id for persistence.
Craig Mautnera228ae92014-07-09 05:44:55 -0700230 TaskRecord mNextAffiliate; // next task in affiliated chain.
Wale Ogunwale18795a22014-12-03 11:38:33 -0800231 int mNextAffiliateTaskId = INVALID_TASK_ID; // next id for persistence.
Craig Mautnera228ae92014-07-09 05:44:55 -0700232
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700233 // For relaunching the task from recents as though it was launched by the original launcher.
234 int mCallingUid;
235 String mCallingPackage;
236
Craig Mautner21d24a22014-04-23 11:45:37 -0700237 final ActivityManagerService mService;
238
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700239 // Whether or not this task covers the entire screen; by default tasks are fullscreen.
240 boolean mFullscreen = true;
241
242 // Bounds of the Task. null for fullscreen tasks.
243 Rect mBounds = null;
Wale Ogunwale706ed792015-08-02 10:29:44 -0700244 // Last non-fullscreen bounds the task was launched in or resized to.
245 // The information is persisted and used to determine the appropriate stack to launch the
246 // task into on restore.
247 Rect mLastNonFullscreenBounds = null;
Filip Gruszczynskid2f1d942015-10-14 15:10:12 -0700248 // Minimal size for width/height of this task when it's resizeable. -1 means it should use the
249 // default minimal size.
250 final int mMinimalSize;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700251
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700252 // Ranking (from top) of this task among all visible tasks. (-1 means it's not visible)
253 // This number will be assigned when we evaluate OOM scores for all visible tasks.
254 int mLayerRank = -1;
255
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700256 Configuration mOverrideConfig = Configuration.EMPTY;
257
Craig Mautner21d24a22014-04-23 11:45:37 -0700258 TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Dianne Hackborn91097de2014-04-04 18:02:06 -0700259 IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700260 mService = service;
Craig Mautnera228ae92014-07-09 05:44:55 -0700261 mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
262 TaskPersister.IMAGE_EXTENSION;
Suprabh Shukla23593142015-11-03 17:31:15 -0800263 userId = UserHandle.getUserId(info.applicationInfo.uid);
264 mLastThumbnailFile = new File(TaskPersister.getUserImagesDir(userId), mFilename);
Winsonc809cbb2015-11-02 12:06:15 -0800265 mLastThumbnailInfo = new TaskThumbnailInfo();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800266 taskId = _taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700267 mAffiliatedTaskId = _taskId;
Dianne Hackborn91097de2014-04-04 18:02:06 -0700268 voiceSession = _voiceSession;
269 voiceInteractor = _voiceInteractor;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700270 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800271 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700272 mCallingUid = info.applicationInfo.uid;
273 mCallingPackage = info.packageName;
Martijn Coenend4a69702014-06-30 11:12:17 -0700274 setIntent(_intent, info);
Filip Gruszczynskid2f1d942015-10-14 15:10:12 -0700275 mMinimalSize = info != null && info.layout != null ? info.layout.minimalSize : -1;
Craig Mautner21d24a22014-04-23 11:45:37 -0700276 }
277
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700278 TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Winsonc809cbb2015-11-02 12:06:15 -0800279 TaskDescription _taskDescription, TaskThumbnailInfo thumbnailInfo) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700280 mService = service;
281 mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
282 TaskPersister.IMAGE_EXTENSION;
Suprabh Shukla23593142015-11-03 17:31:15 -0800283 userId = UserHandle.getUserId(info.applicationInfo.uid);
284 mLastThumbnailFile = new File(TaskPersister.getUserImagesDir(userId), mFilename);
Winsonc809cbb2015-11-02 12:06:15 -0800285 mLastThumbnailInfo = thumbnailInfo;
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700286 taskId = _taskId;
287 mAffiliatedTaskId = _taskId;
288 voiceSession = null;
289 voiceInteractor = null;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700290 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800291 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700292 mCallingUid = info.applicationInfo.uid;
293 mCallingPackage = info.packageName;
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700294 setIntent(_intent, info);
295
296 taskType = ActivityRecord.APPLICATION_ACTIVITY_TYPE;
297 isPersistable = true;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700298 // Clamp to [1, max].
299 maxRecents = Math.min(Math.max(info.maxRecents, 1),
300 ActivityManager.getMaxAppRecentsLimitStatic());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700301
302 taskType = APPLICATION_ACTIVITY_TYPE;
303 mTaskToReturnTo = HOME_ACTIVITY_TYPE;
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700304 lastTaskDescription = _taskDescription;
Filip Gruszczynskid2f1d942015-10-14 15:10:12 -0700305 mMinimalSize = info != null && info.layout != null ? info.layout.minimalSize : -1;
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700306 }
307
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800308 private TaskRecord(ActivityManagerService service, int _taskId, Intent _intent,
309 Intent _affinityIntent, String _affinity, String _rootAffinity,
310 ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset,
311 boolean _autoRemoveRecents, boolean _askedCompatMode, int _taskType, int _userId,
312 int _effectiveUid, String _lastDescription, ArrayList<ActivityRecord> activities,
313 long _firstActiveTime, long _lastActiveTime, long lastTimeMoved,
314 boolean neverRelinquishIdentity, TaskDescription _lastTaskDescription,
Winsonc809cbb2015-11-02 12:06:15 -0800315 TaskThumbnailInfo lastThumbnailInfo, int taskAffiliation, int prevTaskId,
316 int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage,
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800317 int resizeMode, boolean privileged, boolean _realActivitySuspended,
318 boolean userSetupComplete) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700319 mService = service;
Craig Mautnera228ae92014-07-09 05:44:55 -0700320 mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
321 TaskPersister.IMAGE_EXTENSION;
Suprabh Shukla23593142015-11-03 17:31:15 -0800322 mLastThumbnailFile = new File(TaskPersister.getUserImagesDir(_userId), mFilename);
Winsonc809cbb2015-11-02 12:06:15 -0800323 mLastThumbnailInfo = lastThumbnailInfo;
Craig Mautner21d24a22014-04-23 11:45:37 -0700324 taskId = _taskId;
325 intent = _intent;
326 affinityIntent = _affinityIntent;
327 affinity = _affinity;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800328 rootAffinity = _rootAffinity;
Craig Mautner21d24a22014-04-23 11:45:37 -0700329 voiceSession = null;
330 voiceInteractor = null;
331 realActivity = _realActivity;
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800332 realActivitySuspended = _realActivitySuspended;
Craig Mautner21d24a22014-04-23 11:45:37 -0700333 origActivity = _origActivity;
334 rootWasReset = _rootWasReset;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700335 isAvailable = true;
Dianne Hackborn13420f22014-07-18 15:43:56 -0700336 autoRemoveRecents = _autoRemoveRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700337 askedCompatMode = _askedCompatMode;
338 taskType = _taskType;
Craig Mautner84984fa2014-06-19 11:19:20 -0700339 mTaskToReturnTo = HOME_ACTIVITY_TYPE;
Craig Mautner21d24a22014-04-23 11:45:37 -0700340 userId = _userId;
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800341 mUserSetupComplete = userSetupComplete;
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700342 effectiveUid = _effectiveUid;
Winson Chungffa2ec62014-07-03 15:54:42 -0700343 firstActiveTime = _firstActiveTime;
Winson Chungf1fbd772014-06-24 18:06:58 -0700344 lastActiveTime = _lastActiveTime;
Craig Mautner21d24a22014-04-23 11:45:37 -0700345 lastDescription = _lastDescription;
346 mActivities = activities;
347 mLastTimeMoved = lastTimeMoved;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700348 mNeverRelinquishIdentity = neverRelinquishIdentity;
Winson Chung2cb86c72014-06-25 12:03:30 -0700349 lastTaskDescription = _lastTaskDescription;
Craig Mautnera228ae92014-07-09 05:44:55 -0700350 mAffiliatedTaskId = taskAffiliation;
Winson Chungec396d62014-08-06 17:08:00 -0700351 mAffiliatedTaskColor = taskAffiliationColor;
Craig Mautnera228ae92014-07-09 05:44:55 -0700352 mPrevAffiliateTaskId = prevTaskId;
353 mNextAffiliateTaskId = nextTaskId;
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700354 mCallingUid = callingUid;
355 mCallingPackage = callingPackage;
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800356 mResizeMode = resizeMode;
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700357 mPrivileged = privileged;
Suprabh Shukla74f9f162015-11-06 15:39:42 -0800358 ActivityInfo info = (mActivities.size() > 0) ? mActivities.get(0).info : null;
Filip Gruszczynskid2f1d942015-10-14 15:10:12 -0700359 mMinimalSize = info != null && info.layout != null ? info.layout.minimalSize : -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800360 }
361
362 void touchActiveTime() {
Craig Mautner494f6bdd2014-07-21 11:17:46 -0700363 lastActiveTime = System.currentTimeMillis();
Winson Chungffa2ec62014-07-03 15:54:42 -0700364 if (firstActiveTime == 0) {
365 firstActiveTime = lastActiveTime;
366 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800367 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700368
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800369 long getInactiveDuration() {
Craig Mautner494f6bdd2014-07-21 11:17:46 -0700370 return System.currentTimeMillis() - lastActiveTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800371 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700372
Winson Chungfee26772014-08-05 12:21:52 -0700373 /** Sets the original intent, and the calling uid and package. */
374 void setIntent(ActivityRecord r) {
Winson Chungfee26772014-08-05 12:21:52 -0700375 mCallingUid = r.launchedFromUid;
376 mCallingPackage = r.launchedFromPackage;
Craig Mautner15df08a2015-04-01 12:17:18 -0700377 setIntent(r.intent, r.info);
Winson Chungfee26772014-08-05 12:21:52 -0700378 }
379
380 /** Sets the original intent, _without_ updating the calling uid or package. */
381 private void setIntent(Intent _intent, ActivityInfo info) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700382 if (intent == null) {
383 mNeverRelinquishIdentity =
384 (info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) == 0;
385 } else if (mNeverRelinquishIdentity) {
386 return;
387 }
388
389 affinity = info.taskAffinity;
Dianne Hackborn79228822014-09-16 11:11:23 -0700390 if (intent == null) {
391 // If this task already has an intent associated with it, don't set the root
392 // affinity -- we don't want it changing after initially set, but the initially
393 // set value may be null.
394 rootAffinity = affinity;
395 }
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700396 effectiveUid = info.applicationInfo.uid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700397 stringName = null;
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800398
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800399 if (info.targetActivity == null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800400 if (_intent != null) {
401 // If this Intent has a selector, we want to clear it for the
402 // recent task since it is not relevant if the user later wants
403 // to re-launch the app.
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700404 if (_intent.getSelector() != null || _intent.getSourceBounds() != null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800405 _intent = new Intent(_intent);
406 _intent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700407 _intent.setSourceBounds(null);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800408 }
409 }
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700410 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Setting Intent of " + this + " to " + _intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800411 intent = _intent;
412 realActivity = _intent != null ? _intent.getComponent() : null;
413 origActivity = null;
414 } else {
415 ComponentName targetComponent = new ComponentName(
416 info.packageName, info.targetActivity);
417 if (_intent != null) {
418 Intent targetIntent = new Intent(_intent);
419 targetIntent.setComponent(targetComponent);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800420 targetIntent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700421 targetIntent.setSourceBounds(null);
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700422 if (DEBUG_TASKS) Slog.v(TAG_TASKS,
Dianne Hackborn7f96b792012-05-29 18:46:45 -0700423 "Setting Intent of " + this + " to target " + targetIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800424 intent = targetIntent;
425 realActivity = targetComponent;
426 origActivity = _intent.getComponent();
427 } else {
428 intent = null;
429 realActivity = targetComponent;
430 origActivity = new ComponentName(info.packageName, info.name);
431 }
432 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700433
Craig Mautner47b20ba2014-09-17 17:23:44 -0700434 final int intentFlags = intent == null ? 0 : intent.getFlags();
435 if ((intentFlags & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800436 // Once we are set to an Intent with this flag, we count this
437 // task as having a true root activity.
438 rootWasReset = true;
439 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700440
Dianne Hackborn09233282014-04-30 11:33:59 -0700441 userId = UserHandle.getUserId(info.applicationInfo.uid);
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800442 mUserSetupComplete = mService.mUserController.isUserSetupCompleteLocked(userId);
Craig Mautner41db4a72014-05-07 17:20:56 -0700443 if ((info.flags & ActivityInfo.FLAG_AUTO_REMOVE_FROM_RECENTS) != 0) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700444 // If the activity itself has requested auto-remove, then just always do it.
445 autoRemoveRecents = true;
Wale Ogunwale843bfb92015-03-27 11:06:48 -0700446 } else if ((intentFlags & (FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS))
447 == FLAG_ACTIVITY_NEW_DOCUMENT) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700448 // If the caller has not asked for the document to be retained, then we may
449 // want to turn on auto-remove, depending on whether the target has set its
450 // own document launch mode.
451 if (info.documentLaunchMode != ActivityInfo.DOCUMENT_LAUNCH_NONE) {
452 autoRemoveRecents = false;
453 } else {
454 autoRemoveRecents = true;
455 }
456 } else {
457 autoRemoveRecents = false;
Craig Mautner41db4a72014-05-07 17:20:56 -0700458 }
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800459 mResizeMode = info.resizeMode;
Craig Mautner15df08a2015-04-01 12:17:18 -0700460 mLockTaskMode = info.lockTaskLaunchMode;
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700461 mPrivileged = (info.applicationInfo.privateFlags & PRIVATE_FLAG_PRIVILEGED) != 0;
Craig Mautner15df08a2015-04-01 12:17:18 -0700462 setLockTaskAuth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800463 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800464
Craig Mautner84984fa2014-06-19 11:19:20 -0700465 void setTaskToReturnTo(int taskToReturnTo) {
Wale Ogunwale673cbd22016-01-30 18:30:55 -0800466 mTaskToReturnTo = (taskToReturnTo == RECENTS_ACTIVITY_TYPE)
467 ? HOME_ACTIVITY_TYPE : taskToReturnTo;
Craig Mautner84984fa2014-06-19 11:19:20 -0700468 }
469
470 int getTaskToReturnTo() {
471 return mTaskToReturnTo;
472 }
473
Craig Mautnera228ae92014-07-09 05:44:55 -0700474 void setPrevAffiliate(TaskRecord prevAffiliate) {
475 mPrevAffiliate = prevAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800476 mPrevAffiliateTaskId = prevAffiliate == null ? INVALID_TASK_ID : prevAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700477 }
478
479 void setNextAffiliate(TaskRecord nextAffiliate) {
480 mNextAffiliate = nextAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800481 mNextAffiliateTaskId = nextAffiliate == null ? INVALID_TASK_ID : nextAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700482 }
483
484 // Close up recents linked list.
485 void closeRecentsChain() {
486 if (mPrevAffiliate != null) {
487 mPrevAffiliate.setNextAffiliate(mNextAffiliate);
488 }
489 if (mNextAffiliate != null) {
490 mNextAffiliate.setPrevAffiliate(mPrevAffiliate);
491 }
492 setPrevAffiliate(null);
493 setNextAffiliate(null);
494 }
495
Winson Chung740c3ac2014-11-12 16:14:38 -0800496 void removedFromRecents() {
Dianne Hackborn852975d2014-08-22 17:42:43 -0700497 disposeThumbnail();
498 closeRecentsChain();
499 if (inRecents) {
500 inRecents = false;
Winson Chung740c3ac2014-11-12 16:14:38 -0800501 mService.notifyTaskPersisterLocked(this, false);
Dianne Hackborn852975d2014-08-22 17:42:43 -0700502 }
503 }
504
Craig Mautnera228ae92014-07-09 05:44:55 -0700505 void setTaskToAffiliateWith(TaskRecord taskToAffiliateWith) {
506 closeRecentsChain();
507 mAffiliatedTaskId = taskToAffiliateWith.mAffiliatedTaskId;
Winson Chungec396d62014-08-06 17:08:00 -0700508 mAffiliatedTaskColor = taskToAffiliateWith.mAffiliatedTaskColor;
Craig Mautnera228ae92014-07-09 05:44:55 -0700509 // Find the end
510 while (taskToAffiliateWith.mNextAffiliate != null) {
511 final TaskRecord nextRecents = taskToAffiliateWith.mNextAffiliate;
512 if (nextRecents.mAffiliatedTaskId != mAffiliatedTaskId) {
513 Slog.e(TAG, "setTaskToAffiliateWith: nextRecents=" + nextRecents + " affilTaskId="
514 + nextRecents.mAffiliatedTaskId + " should be " + mAffiliatedTaskId);
515 if (nextRecents.mPrevAffiliate == taskToAffiliateWith) {
516 nextRecents.setPrevAffiliate(null);
517 }
518 taskToAffiliateWith.setNextAffiliate(null);
519 break;
520 }
521 taskToAffiliateWith = nextRecents;
522 }
523 taskToAffiliateWith.setNextAffiliate(this);
524 setPrevAffiliate(taskToAffiliateWith);
525 setNextAffiliate(null);
526 }
527
Winson Chung096f36b2014-08-20 15:39:01 -0700528 /**
Winsonc809cbb2015-11-02 12:06:15 -0800529 * Sets the last thumbnail with the current task bounds and the system orientation.
Winson Chung096f36b2014-08-20 15:39:01 -0700530 * @return whether the thumbnail was set
531 */
Winsonc809cbb2015-11-02 12:06:15 -0800532 boolean setLastThumbnailLocked(Bitmap thumbnail) {
533 final Configuration serviceConfig = mService.mConfiguration;
534 int taskWidth = 0;
535 int taskHeight = 0;
536 if (mBounds != null) {
537 // Non-fullscreen tasks
538 taskWidth = mBounds.width();
539 taskHeight = mBounds.height();
540 } else if (stack != null) {
541 // Fullscreen tasks
542 final Point displaySize = new Point();
543 stack.getDisplaySize(displaySize);
544 taskWidth = displaySize.x;
545 taskHeight = displaySize.y;
546 } else {
547 Slog.e(TAG, "setLastThumbnailLocked() called on Task without stack");
548 }
549 return setLastThumbnailLocked(thumbnail, taskWidth, taskHeight, serviceConfig.orientation);
550 }
551
552 /**
553 * Sets the last thumbnail with the current task bounds.
554 * @return whether the thumbnail was set
555 */
556 private boolean setLastThumbnailLocked(Bitmap thumbnail, int taskWidth, int taskHeight,
557 int screenOrientation) {
Winson Chung096f36b2014-08-20 15:39:01 -0700558 if (mLastThumbnail != thumbnail) {
559 mLastThumbnail = thumbnail;
Winsonc809cbb2015-11-02 12:06:15 -0800560 mLastThumbnailInfo.taskWidth = taskWidth;
561 mLastThumbnailInfo.taskHeight = taskHeight;
562 mLastThumbnailInfo.screenOrientation = screenOrientation;
Winson Chung096f36b2014-08-20 15:39:01 -0700563 if (thumbnail == null) {
564 if (mLastThumbnailFile != null) {
565 mLastThumbnailFile.delete();
566 }
567 } else {
Suprabh Shukla09a88f52015-12-02 14:36:31 -0800568 mService.mRecentTasks.saveImage(thumbnail, mLastThumbnailFile.getAbsolutePath());
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700569 }
Winson Chung096f36b2014-08-20 15:39:01 -0700570 return true;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700571 }
Winson Chung096f36b2014-08-20 15:39:01 -0700572 return false;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700573 }
574
575 void getLastThumbnail(TaskThumbnail thumbs) {
576 thumbs.mainThumbnail = mLastThumbnail;
Winsonc809cbb2015-11-02 12:06:15 -0800577 thumbs.thumbnailInfo = mLastThumbnailInfo;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700578 thumbs.thumbnailFileDescriptor = null;
Craig Mautnerf4f8bb72014-07-29 10:41:40 -0700579 if (mLastThumbnail == null) {
Suprabh Shukla09a88f52015-12-02 14:36:31 -0800580 thumbs.mainThumbnail = mService.mRecentTasks.getImageFromWriteQueue(
Suprabh Shukla23593142015-11-03 17:31:15 -0800581 mLastThumbnailFile.getAbsolutePath());
Craig Mautnerf4f8bb72014-07-29 10:41:40 -0700582 }
Winson Chung096f36b2014-08-20 15:39:01 -0700583 // Only load the thumbnail file if we don't have a thumbnail
584 if (thumbs.mainThumbnail == null && mLastThumbnailFile.exists()) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700585 try {
586 thumbs.thumbnailFileDescriptor = ParcelFileDescriptor.open(mLastThumbnailFile,
587 ParcelFileDescriptor.MODE_READ_ONLY);
588 } catch (IOException e) {
Dianne Hackborn9844d292013-10-04 16:44:22 -0700589 }
590 }
591 }
592
Winsonc809cbb2015-11-02 12:06:15 -0800593 /**
594 * Removes in-memory thumbnail data when the max number of in-memory task thumbnails is reached.
595 */
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700596 void freeLastThumbnail() {
597 mLastThumbnail = null;
598 }
599
Winsonc809cbb2015-11-02 12:06:15 -0800600 /**
601 * Removes all associated thumbnail data when a task is removed or pruned from recents.
602 */
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700603 void disposeThumbnail() {
Winsonc6a2da02015-11-11 18:11:59 -0800604 mLastThumbnailInfo.reset();
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700605 mLastThumbnail = null;
606 lastDescription = null;
607 }
608
Winson Chung1147c402014-05-14 11:05:00 -0700609 /** Returns the intent for the root activity for this task */
610 Intent getBaseIntent() {
611 return intent != null ? intent : affinityIntent;
612 }
613
Winson Chung3b3f4642014-04-22 10:08:18 -0700614 /** Returns the first non-finishing activity from the root. */
615 ActivityRecord getRootActivity() {
616 for (int i = 0; i < mActivities.size(); i++) {
617 final ActivityRecord r = mActivities.get(i);
618 if (r.finishing) {
619 continue;
620 }
621 return r;
622 }
623 return null;
624 }
625
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800626 ActivityRecord getTopActivity() {
627 for (int i = mActivities.size() - 1; i >= 0; --i) {
628 final ActivityRecord r = mActivities.get(i);
629 if (r.finishing) {
630 continue;
631 }
632 return r;
633 }
634 return null;
635 }
636
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -0700637 ActivityRecord topRunningActivityLocked() {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700638 if (stack != null) {
639 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
640 ActivityRecord r = mActivities.get(activityNdx);
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -0700641 if (!r.finishing && stack.okToShowLocked(r)) {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700642 return r;
643 }
Craig Mautner6b74cb52013-09-27 17:02:21 -0700644 }
645 }
646 return null;
647 }
648
Wale Ogunwale6d42df62015-11-05 09:50:55 -0800649 void setFrontOfTask() {
650 setFrontOfTask(null);
651 }
652
Craig Mautner3b475fe2013-12-16 15:58:31 -0800653 /** Call after activity movement or finish to make sure that frontOfTask is set correctly */
Wale Ogunwale6d42df62015-11-05 09:50:55 -0800654 void setFrontOfTask(ActivityRecord newTop) {
655 // If a top candidate is suggested by the caller, go ahead and use it and mark all others
656 // as not front. This is needed in situations where the current front activity in the
657 // task isn't finished yet and we want to set the front to the activity moved to the front
658 // of the task.
659 boolean foundFront = newTop != null ? true : false;
660
Craig Mautner3b475fe2013-12-16 15:58:31 -0800661 final int numActivities = mActivities.size();
Craig Mautner704e40b2013-12-18 16:43:51 -0800662 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
Craig Mautner3b475fe2013-12-16 15:58:31 -0800663 final ActivityRecord r = mActivities.get(activityNdx);
664 if (foundFront || r.finishing) {
665 r.frontOfTask = false;
666 } else {
667 r.frontOfTask = true;
668 // Set frontOfTask false for every following activity.
669 foundFront = true;
670 }
671 }
Craig Mautner9587ee02014-06-23 15:00:10 +0000672 if (!foundFront && numActivities > 0) {
673 // All activities of this task are finishing. As we ought to have a frontOfTask
674 // activity, make the bottom activity front.
675 mActivities.get(0).frontOfTask = true;
676 }
Wale Ogunwale6d42df62015-11-05 09:50:55 -0800677 if (newTop != null) {
678 newTop.frontOfTask = true;
679 }
Craig Mautner3b475fe2013-12-16 15:58:31 -0800680 }
681
Craig Mautnerde4ef022013-04-07 19:01:33 -0700682 /**
Craig Mautner3b475fe2013-12-16 15:58:31 -0800683 * Reorder the history stack so that the passed activity is brought to the front.
Craig Mautnerde4ef022013-04-07 19:01:33 -0700684 */
685 final void moveActivityToFrontLocked(ActivityRecord newTop) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -0700686 if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE,
687 "Removing and adding activity " + newTop
688 + " to stack at top callers=" + Debug.getCallers(4));
Craig Mautnerde4ef022013-04-07 19:01:33 -0700689
Craig Mautnerde4ef022013-04-07 19:01:33 -0700690 mActivities.remove(newTop);
691 mActivities.add(newTop);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700692 updateEffectiveIntent();
Craig Mautner3b475fe2013-12-16 15:58:31 -0800693
Wale Ogunwale6d42df62015-11-05 09:50:55 -0800694 setFrontOfTask(newTop);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700695 }
696
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800697 void addActivityAtBottom(ActivityRecord r) {
Craig Mautner77878772013-03-04 19:46:24 -0800698 addActivityAtIndex(0, r);
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800699 }
700
701 void addActivityToTop(ActivityRecord r) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700702 addActivityAtIndex(mActivities.size(), r);
703 }
704
705 void addActivityAtIndex(int index, ActivityRecord r) {
Craig Mautner6170f732013-04-02 13:05:23 -0700706 // 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 -0800707 if (!mActivities.remove(r) && r.fullscreen) {
708 // Was not previously in list.
709 numFullscreen++;
710 }
Craig Mautner2c1faed2013-07-23 12:56:02 -0700711 // Only set this based on the first activity
712 if (mActivities.isEmpty()) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700713 taskType = r.mActivityType;
714 isPersistable = r.isPersistable();
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700715 mCallingUid = r.launchedFromUid;
716 mCallingPackage = r.launchedFromPackage;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700717 // Clamp to [1, max].
718 maxRecents = Math.min(Math.max(r.info.maxRecents, 1),
719 ActivityManager.getMaxAppRecentsLimitStatic());
Craig Mautner2c1faed2013-07-23 12:56:02 -0700720 } else {
721 // Otherwise make all added activities match this one.
Craig Mautner21d24a22014-04-23 11:45:37 -0700722 r.mActivityType = taskType;
Craig Mautner78733002013-06-10 13:54:49 -0700723 }
Craig Mautner77878772013-03-04 19:46:24 -0800724 mActivities.add(index, r);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700725 updateEffectiveIntent();
Craig Mautner21d24a22014-04-23 11:45:37 -0700726 if (r.isPersistable()) {
727 mService.notifyTaskPersisterLocked(this, false);
728 }
Craig Mautner77878772013-03-04 19:46:24 -0800729 }
730
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800731 /** @return true if this was the last activity in the task */
732 boolean removeActivity(ActivityRecord r) {
733 if (mActivities.remove(r) && r.fullscreen) {
734 // Was previously in list.
735 numFullscreen--;
736 }
Craig Mautner21d24a22014-04-23 11:45:37 -0700737 if (r.isPersistable()) {
738 mService.notifyTaskPersisterLocked(this, false);
739 }
Craig Mautner41326202014-06-20 14:38:21 -0700740 if (mActivities.isEmpty()) {
Craig Mautner5afcd4d2014-06-21 18:11:33 -0700741 return !mReuseTask;
Craig Mautner41326202014-06-20 14:38:21 -0700742 }
743 updateEffectiveIntent();
744 return false;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800745 }
746
Craig Mautner41db4a72014-05-07 17:20:56 -0700747 boolean autoRemoveFromRecents() {
Dianne Hackbornd38aed82014-06-10 21:36:35 -0700748 // We will automatically remove the task either if it has explicitly asked for
749 // this, or it is empty and has never contained an activity that got shown to
750 // the user.
Dianne Hackborn13420f22014-07-18 15:43:56 -0700751 return autoRemoveRecents || (mActivities.isEmpty() && !hasBeenVisible);
Craig Mautner41db4a72014-05-07 17:20:56 -0700752 }
753
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700754 /**
755 * Completely remove all activities associated with an existing
756 * task starting at a specified index.
757 */
758 final void performClearTaskAtIndexLocked(int activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700759 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700760 for ( ; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700761 final ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700762 if (r.finishing) {
763 continue;
764 }
Craig Mautner21d24a22014-04-23 11:45:37 -0700765 if (stack == null) {
766 // Task was restored from persistent storage.
767 r.takeFromHistory();
768 mActivities.remove(activityNdx);
769 --activityNdx;
770 --numActivities;
Todd Kennedy539db512014-12-15 09:57:55 -0800771 } else if (stack.finishActivityLocked(
772 r, Activity.RESULT_CANCELED, null, "clear-task-index", false)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700773 --activityNdx;
774 --numActivities;
775 }
776 }
777 }
778
779 /**
780 * Completely remove all activities associated with an existing task.
781 */
782 final void performClearTaskLocked() {
Craig Mautner362449a2014-06-20 14:04:39 -0700783 mReuseTask = true;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700784 performClearTaskAtIndexLocked(0);
Craig Mautner362449a2014-06-20 14:04:39 -0700785 mReuseTask = false;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700786 }
787
Filip Gruszczynskibe9dabd2016-01-19 12:23:10 -0800788 ActivityRecord performClearTaskForReuseLocked(ActivityRecord newR, int launchFlags) {
789 mReuseTask = true;
790 final ActivityRecord result = performClearTaskLocked(newR, launchFlags);
791 mReuseTask = false;
792 return result;
793 }
794
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700795 /**
796 * Perform clear operation as requested by
797 * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the
798 * stack to the given task, then look for
799 * an instance of that activity in the stack and, if found, finish all
800 * activities on top of it and return the instance.
801 *
802 * @param newR Description of the new activity being started.
803 * @return Returns the old activity that should be continued to be used,
804 * or null if none was found.
805 */
806 final ActivityRecord performClearTaskLocked(ActivityRecord newR, int launchFlags) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700807 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700808 for (int activityNdx = numActivities - 1; activityNdx >= 0; --activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700809 ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700810 if (r.finishing) {
811 continue;
812 }
813 if (r.realActivity.equals(newR.realActivity)) {
814 // Here it is! Now finish everything in front...
Craig Mautner1602ec22013-05-12 10:24:27 -0700815 final ActivityRecord ret = r;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700816
817 for (++activityNdx; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700818 r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700819 if (r.finishing) {
820 continue;
821 }
822 ActivityOptions opts = r.takeOptionsLocked();
823 if (opts != null) {
824 ret.updateOptionsLocked(opts);
825 }
Wale Ogunwale7d701172015-03-11 15:36:30 -0700826 if (stack != null && stack.finishActivityLocked(
Todd Kennedy539db512014-12-15 09:57:55 -0800827 r, Activity.RESULT_CANCELED, null, "clear-task-stack", false)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700828 --activityNdx;
829 --numActivities;
830 }
831 }
832
833 // Finally, if this is a normal launch mode (that is, not
834 // expecting onNewIntent()), then we will finish the current
835 // instance of the activity so a new fresh one can be started.
836 if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE
837 && (launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0) {
838 if (!ret.finishing) {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700839 if (stack != null) {
840 stack.finishActivityLocked(
841 ret, Activity.RESULT_CANCELED, null, "clear-task-top", false);
842 }
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700843 return null;
844 }
845 }
846
847 return ret;
848 }
849 }
850
851 return null;
852 }
853
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700854 public TaskThumbnail getTaskThumbnailLocked() {
Craig Mautner21d24a22014-04-23 11:45:37 -0700855 if (stack != null) {
856 final ActivityRecord resumedActivity = stack.mResumedActivity;
857 if (resumedActivity != null && resumedActivity.task == this) {
Winson8b1871d2015-11-20 09:56:20 -0800858 final Bitmap thumbnail = stack.screenshotActivitiesLocked(resumedActivity);
Winsonc809cbb2015-11-02 12:06:15 -0800859 setLastThumbnailLocked(thumbnail);
Craig Mautner21d24a22014-04-23 11:45:37 -0700860 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700861 }
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700862 final TaskThumbnail taskThumbnail = new TaskThumbnail();
863 getLastThumbnail(taskThumbnail);
864 return taskThumbnail;
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700865 }
866
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700867 public void removeTaskActivitiesLocked() {
868 // Just remove the entire task.
869 performClearTaskAtIndexLocked(0);
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700870 }
871
Craig Mautner432f64e2015-05-20 14:59:57 -0700872 String lockTaskAuthToString() {
873 switch (mLockTaskAuth) {
874 case LOCK_TASK_AUTH_DONT_LOCK: return "LOCK_TASK_AUTH_DONT_LOCK";
875 case LOCK_TASK_AUTH_PINNABLE: return "LOCK_TASK_AUTH_PINNABLE";
876 case LOCK_TASK_AUTH_LAUNCHABLE: return "LOCK_TASK_AUTH_LAUNCHABLE";
877 case LOCK_TASK_AUTH_WHITELISTED: return "LOCK_TASK_AUTH_WHITELISTED";
Benjamin Franz469dd582015-06-09 14:24:36 +0100878 case LOCK_TASK_AUTH_LAUNCHABLE_PRIV: return "LOCK_TASK_AUTH_LAUNCHABLE_PRIV";
Craig Mautner432f64e2015-05-20 14:59:57 -0700879 default: return "unknown=" + mLockTaskAuth;
880 }
881 }
882
Craig Mautner15df08a2015-04-01 12:17:18 -0700883 void setLockTaskAuth() {
Benjamin Franz469dd582015-06-09 14:24:36 +0100884 if (!mPrivileged &&
885 (mLockTaskMode == LOCK_TASK_LAUNCH_MODE_ALWAYS ||
886 mLockTaskMode == LOCK_TASK_LAUNCH_MODE_NEVER)) {
887 // Non-priv apps are not allowed to use always or never, fall back to default
888 mLockTaskMode = LOCK_TASK_LAUNCH_MODE_DEFAULT;
889 }
Craig Mautner15df08a2015-04-01 12:17:18 -0700890 switch (mLockTaskMode) {
891 case LOCK_TASK_LAUNCH_MODE_DEFAULT:
892 mLockTaskAuth = isLockTaskWhitelistedLocked() ?
893 LOCK_TASK_AUTH_WHITELISTED : LOCK_TASK_AUTH_PINNABLE;
894 break;
895
896 case LOCK_TASK_LAUNCH_MODE_NEVER:
Benjamin Franz469dd582015-06-09 14:24:36 +0100897 mLockTaskAuth = LOCK_TASK_AUTH_DONT_LOCK;
Craig Mautner15df08a2015-04-01 12:17:18 -0700898 break;
899
900 case LOCK_TASK_LAUNCH_MODE_ALWAYS:
Benjamin Franz469dd582015-06-09 14:24:36 +0100901 mLockTaskAuth = LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
Craig Mautner15df08a2015-04-01 12:17:18 -0700902 break;
903
904 case LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED:
905 mLockTaskAuth = isLockTaskWhitelistedLocked() ?
906 LOCK_TASK_AUTH_LAUNCHABLE : LOCK_TASK_AUTH_PINNABLE;
907 break;
908 }
Craig Mautner432f64e2015-05-20 14:59:57 -0700909 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
910 " mLockTaskAuth=" + lockTaskAuthToString());
Craig Mautner15df08a2015-04-01 12:17:18 -0700911 }
912
913 boolean isLockTaskWhitelistedLocked() {
Benjamin Franz6fd84cc2015-08-06 18:09:03 +0100914 String pkg = (realActivity != null) ? realActivity.getPackageName() : null;
915 if (pkg == null) {
Craig Mautner15df08a2015-04-01 12:17:18 -0700916 return false;
917 }
918 String[] packages = mService.mLockTaskPackages.get(userId);
919 if (packages == null) {
920 return false;
921 }
922 for (int i = packages.length - 1; i >= 0; --i) {
Benjamin Franz6fd84cc2015-08-06 18:09:03 +0100923 if (pkg.equals(packages[i])) {
Craig Mautner15df08a2015-04-01 12:17:18 -0700924 return true;
925 }
926 }
927 return false;
928 }
Craig Mautnera82aa092013-09-13 15:34:08 -0700929 boolean isHomeTask() {
Craig Mautner84984fa2014-06-19 11:19:20 -0700930 return taskType == HOME_ACTIVITY_TYPE;
Craig Mautnera82aa092013-09-13 15:34:08 -0700931 }
932
Craig Mautner86d67a42013-05-14 10:34:38 -0700933 boolean isApplicationTask() {
Craig Mautner84984fa2014-06-19 11:19:20 -0700934 return taskType == APPLICATION_ACTIVITY_TYPE;
935 }
936
937 boolean isOverHomeStack() {
938 return mTaskToReturnTo == HOME_ACTIVITY_TYPE || mTaskToReturnTo == RECENTS_ACTIVITY_TYPE;
Craig Mautner1602ec22013-05-12 10:24:27 -0700939 }
940
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800941 boolean isResizeable() {
942 return !isHomeTask() && (mService.mForceResizableActivities
943 || ActivityInfo.isResizeableMode(mResizeMode));
944 }
945
946 boolean inCropWindowsResizeMode() {
947 return !isResizeable() && mResizeMode == RESIZE_MODE_CROP_WINDOWS;
948 }
949
Wale Ogunwale513346d2016-01-27 10:55:01 -0800950 boolean canGoInDockedStack() {
951 return isResizeable() || inCropWindowsResizeMode();
952 }
953
Craig Mautner525f3d92013-05-07 14:01:50 -0700954 /**
955 * Find the activity in the history stack within the given task. Returns
956 * the index within the history at which it's found, or < 0 if not found.
957 */
958 final ActivityRecord findActivityInHistoryLocked(ActivityRecord r) {
959 final ComponentName realActivity = r.realActivity;
960 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
961 ActivityRecord candidate = mActivities.get(activityNdx);
962 if (candidate.finishing) {
963 continue;
964 }
965 if (candidate.realActivity.equals(realActivity)) {
966 return candidate;
967 }
968 }
969 return null;
970 }
971
Winson Chunga449dc02014-05-16 11:15:04 -0700972 /** Updates the last task description values. */
973 void updateTaskDescription() {
974 // Traverse upwards looking for any break between main task activities and
975 // utility activities.
976 int activityNdx;
977 final int numActivities = mActivities.size();
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700978 final boolean relinquish = numActivities == 0 ? false :
979 (mActivities.get(0).info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) != 0;
Winson Chunga449dc02014-05-16 11:15:04 -0700980 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
Craig Mautner21d24a22014-04-23 11:45:37 -0700981 ++activityNdx) {
Winson Chunga449dc02014-05-16 11:15:04 -0700982 final ActivityRecord r = mActivities.get(activityNdx);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700983 if (relinquish && (r.info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
984 // This will be the top activity for determining taskDescription. Pre-inc to
985 // overcome initial decrement below.
986 ++activityNdx;
987 break;
988 }
Winson Chunga449dc02014-05-16 11:15:04 -0700989 if (r.intent != null &&
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700990 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
Winson Chunga449dc02014-05-16 11:15:04 -0700991 break;
992 }
993 }
994 if (activityNdx > 0) {
995 // Traverse downwards starting below break looking for set label, icon.
996 // Note that if there are activities in the task but none of them set the
997 // recent activity values, then we do not fall back to the last set
998 // values in the TaskRecord.
999 String label = null;
Craig Mautner648f69b2014-09-18 14:16:26 -07001000 String iconFilename = null;
Winson Chunga449dc02014-05-16 11:15:04 -07001001 int colorPrimary = 0;
1002 for (--activityNdx; activityNdx >= 0; --activityNdx) {
1003 final ActivityRecord r = mActivities.get(activityNdx);
1004 if (r.taskDescription != null) {
1005 if (label == null) {
1006 label = r.taskDescription.getLabel();
1007 }
Craig Mautner648f69b2014-09-18 14:16:26 -07001008 if (iconFilename == null) {
1009 iconFilename = r.taskDescription.getIconFilename();
Winson Chunga449dc02014-05-16 11:15:04 -07001010 }
1011 if (colorPrimary == 0) {
1012 colorPrimary = r.taskDescription.getPrimaryColor();
Winson Chunga449dc02014-05-16 11:15:04 -07001013 }
1014 }
1015 }
Craig Mautner648f69b2014-09-18 14:16:26 -07001016 lastTaskDescription = new TaskDescription(label, colorPrimary, iconFilename);
Winson Chungec396d62014-08-06 17:08:00 -07001017 // Update the task affiliation color if we are the parent of the group
1018 if (taskId == mAffiliatedTaskId) {
1019 mAffiliatedTaskColor = lastTaskDescription.getPrimaryColor();
1020 }
Winson Chunga449dc02014-05-16 11:15:04 -07001021 }
1022 }
1023
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001024 int findEffectiveRootIndex() {
Craig Mautner4767f4b2014-09-18 15:38:33 -07001025 int effectiveNdx = 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001026 final int topActivityNdx = mActivities.size() - 1;
Dianne Hackborn39569af2014-09-23 10:56:58 -07001027 for (int activityNdx = 0; activityNdx <= topActivityNdx; ++activityNdx) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001028 final ActivityRecord r = mActivities.get(activityNdx);
1029 if (r.finishing) {
1030 continue;
1031 }
Craig Mautner4767f4b2014-09-18 15:38:33 -07001032 effectiveNdx = activityNdx;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001033 if ((r.info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
1034 break;
1035 }
1036 }
Craig Mautner4767f4b2014-09-18 15:38:33 -07001037 return effectiveNdx;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001038 }
1039
1040 void updateEffectiveIntent() {
1041 final int effectiveRootIndex = findEffectiveRootIndex();
1042 final ActivityRecord r = mActivities.get(effectiveRootIndex);
Winson Chungfee26772014-08-05 12:21:52 -07001043 setIntent(r);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001044 }
1045
Craig Mautner21d24a22014-04-23 11:45:37 -07001046 void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001047 if (DEBUG_RECENTS) Slog.i(TAG_RECENTS, "Saving task=" + this);
Craig Mautner21d24a22014-04-23 11:45:37 -07001048
1049 out.attribute(null, ATTR_TASKID, String.valueOf(taskId));
1050 if (realActivity != null) {
1051 out.attribute(null, ATTR_REALACTIVITY, realActivity.flattenToShortString());
1052 }
Andrei Stingaceanu4ccec532016-01-13 12:10:21 +00001053 out.attribute(null, ATTR_REALACTIVITY_SUSPENDED, String.valueOf(realActivitySuspended));
Craig Mautner21d24a22014-04-23 11:45:37 -07001054 if (origActivity != null) {
1055 out.attribute(null, ATTR_ORIGACTIVITY, origActivity.flattenToShortString());
1056 }
Dianne Hackborn79228822014-09-16 11:11:23 -07001057 // Write affinity, and root affinity if it is different from affinity.
1058 // We use the special string "@" for a null root affinity, so we can identify
1059 // later whether we were given a root affinity or should just make it the
1060 // same as the affinity.
Craig Mautner21d24a22014-04-23 11:45:37 -07001061 if (affinity != null) {
1062 out.attribute(null, ATTR_AFFINITY, affinity);
Dianne Hackborn79228822014-09-16 11:11:23 -07001063 if (!affinity.equals(rootAffinity)) {
1064 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
1065 }
1066 } else if (rootAffinity != null) {
1067 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
Craig Mautner21d24a22014-04-23 11:45:37 -07001068 }
1069 out.attribute(null, ATTR_ROOTHASRESET, String.valueOf(rootWasReset));
Dianne Hackborn13420f22014-07-18 15:43:56 -07001070 out.attribute(null, ATTR_AUTOREMOVERECENTS, String.valueOf(autoRemoveRecents));
Craig Mautner21d24a22014-04-23 11:45:37 -07001071 out.attribute(null, ATTR_ASKEDCOMPATMODE, String.valueOf(askedCompatMode));
1072 out.attribute(null, ATTR_USERID, String.valueOf(userId));
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001073 out.attribute(null, ATTR_USER_SETUP_COMPLETE, String.valueOf(mUserSetupComplete));
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001074 out.attribute(null, ATTR_EFFECTIVE_UID, String.valueOf(effectiveUid));
Craig Mautner21d24a22014-04-23 11:45:37 -07001075 out.attribute(null, ATTR_TASKTYPE, String.valueOf(taskType));
Winson Chungffa2ec62014-07-03 15:54:42 -07001076 out.attribute(null, ATTR_FIRSTACTIVETIME, String.valueOf(firstActiveTime));
Winson Chungf1fbd772014-06-24 18:06:58 -07001077 out.attribute(null, ATTR_LASTACTIVETIME, String.valueOf(lastActiveTime));
Craig Mautner21d24a22014-04-23 11:45:37 -07001078 out.attribute(null, ATTR_LASTTIMEMOVED, String.valueOf(mLastTimeMoved));
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001079 out.attribute(null, ATTR_NEVERRELINQUISH, String.valueOf(mNeverRelinquishIdentity));
Craig Mautner21d24a22014-04-23 11:45:37 -07001080 if (lastDescription != null) {
1081 out.attribute(null, ATTR_LASTDESCRIPTION, lastDescription.toString());
1082 }
Winson Chung2cb86c72014-06-25 12:03:30 -07001083 if (lastTaskDescription != null) {
Craig Mautner648f69b2014-09-18 14:16:26 -07001084 lastTaskDescription.saveToXml(out);
Winson Chung2cb86c72014-06-25 12:03:30 -07001085 }
Winsonc809cbb2015-11-02 12:06:15 -08001086 mLastThumbnailInfo.saveToXml(out);
Winson Chungec396d62014-08-06 17:08:00 -07001087 out.attribute(null, ATTR_TASK_AFFILIATION_COLOR, String.valueOf(mAffiliatedTaskColor));
Craig Mautnera228ae92014-07-09 05:44:55 -07001088 out.attribute(null, ATTR_TASK_AFFILIATION, String.valueOf(mAffiliatedTaskId));
1089 out.attribute(null, ATTR_PREV_AFFILIATION, String.valueOf(mPrevAffiliateTaskId));
1090 out.attribute(null, ATTR_NEXT_AFFILIATION, String.valueOf(mNextAffiliateTaskId));
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001091 out.attribute(null, ATTR_CALLING_UID, String.valueOf(mCallingUid));
1092 out.attribute(null, ATTR_CALLING_PACKAGE, mCallingPackage == null ? "" : mCallingPackage);
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001093 out.attribute(null, ATTR_RESIZE_MODE, String.valueOf(mResizeMode));
Wale Ogunwalea7afaa22015-05-01 20:39:18 -07001094 out.attribute(null, ATTR_PRIVILEGED, String.valueOf(mPrivileged));
Wale Ogunwale706ed792015-08-02 10:29:44 -07001095 if (mLastNonFullscreenBounds != null) {
1096 out.attribute(
1097 null, ATTR_NON_FULLSCREEN_BOUNDS, mLastNonFullscreenBounds.flattenToString());
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001098 }
Winson Chung2cb86c72014-06-25 12:03:30 -07001099
Craig Mautner21d24a22014-04-23 11:45:37 -07001100 if (affinityIntent != null) {
1101 out.startTag(null, TAG_AFFINITYINTENT);
1102 affinityIntent.saveToXml(out);
1103 out.endTag(null, TAG_AFFINITYINTENT);
1104 }
1105
1106 out.startTag(null, TAG_INTENT);
1107 intent.saveToXml(out);
1108 out.endTag(null, TAG_INTENT);
1109
1110 final ArrayList<ActivityRecord> activities = mActivities;
1111 final int numActivities = activities.size();
1112 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
1113 final ActivityRecord r = activities.get(activityNdx);
Craig Mautner43e52ed2014-06-16 17:18:52 -07001114 if (r.info.persistableMode == ActivityInfo.PERSIST_ROOT_ONLY || !r.isPersistable() ||
Wale Ogunwale843bfb92015-03-27 11:06:48 -07001115 ((r.intent.getFlags() & FLAG_ACTIVITY_NEW_DOCUMENT
1116 | FLAG_ACTIVITY_RETAIN_IN_RECENTS) == FLAG_ACTIVITY_NEW_DOCUMENT) &&
Craig Mautner43e52ed2014-06-16 17:18:52 -07001117 activityNdx > 0) {
Craig Mautnerf357c0c2014-06-09 09:23:27 -07001118 // Stop at first non-persistable or first break in task (CLEAR_WHEN_TASK_RESET).
Craig Mautner21d24a22014-04-23 11:45:37 -07001119 break;
1120 }
1121 out.startTag(null, TAG_ACTIVITY);
1122 r.saveToXml(out);
1123 out.endTag(null, TAG_ACTIVITY);
1124 }
Craig Mautner21d24a22014-04-23 11:45:37 -07001125 }
1126
1127 static TaskRecord restoreFromXml(XmlPullParser in, ActivityStackSupervisor stackSupervisor)
1128 throws IOException, XmlPullParserException {
1129 Intent intent = null;
1130 Intent affinityIntent = null;
Winsonc809cbb2015-11-02 12:06:15 -08001131 ArrayList<ActivityRecord> activities = new ArrayList<>();
Craig Mautner21d24a22014-04-23 11:45:37 -07001132 ComponentName realActivity = null;
Andrei Stingaceanu4ccec532016-01-13 12:10:21 +00001133 boolean realActivitySuspended = false;
Craig Mautner21d24a22014-04-23 11:45:37 -07001134 ComponentName origActivity = null;
1135 String affinity = null;
Dianne Hackborn79228822014-09-16 11:11:23 -07001136 String rootAffinity = null;
1137 boolean hasRootAffinity = false;
Craig Mautner21d24a22014-04-23 11:45:37 -07001138 boolean rootHasReset = false;
Dianne Hackborn13420f22014-07-18 15:43:56 -07001139 boolean autoRemoveRecents = false;
Craig Mautner21d24a22014-04-23 11:45:37 -07001140 boolean askedCompatMode = false;
1141 int taskType = ActivityRecord.APPLICATION_ACTIVITY_TYPE;
Craig Mautner21d24a22014-04-23 11:45:37 -07001142 int userId = 0;
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001143 boolean userSetupComplete = true;
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001144 int effectiveUid = -1;
Craig Mautner21d24a22014-04-23 11:45:37 -07001145 String lastDescription = null;
Winson Chungffa2ec62014-07-03 15:54:42 -07001146 long firstActiveTime = -1;
Winson Chung2cb86c72014-06-25 12:03:30 -07001147 long lastActiveTime = -1;
Craig Mautner21d24a22014-04-23 11:45:37 -07001148 long lastTimeOnTop = 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001149 boolean neverRelinquishIdentity = true;
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001150 int taskId = INVALID_TASK_ID;
Craig Mautner21d24a22014-04-23 11:45:37 -07001151 final int outerDepth = in.getDepth();
Craig Mautner648f69b2014-09-18 14:16:26 -07001152 TaskDescription taskDescription = new TaskDescription();
Winsonc809cbb2015-11-02 12:06:15 -08001153 TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
Wale Ogunwale18795a22014-12-03 11:38:33 -08001154 int taskAffiliation = INVALID_TASK_ID;
Winson Chungec396d62014-08-06 17:08:00 -07001155 int taskAffiliationColor = 0;
Wale Ogunwale18795a22014-12-03 11:38:33 -08001156 int prevTaskId = INVALID_TASK_ID;
1157 int nextTaskId = INVALID_TASK_ID;
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001158 int callingUid = -1;
1159 String callingPackage = "";
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001160 int resizeMode = RESIZE_MODE_UNRESIZEABLE;
Wale Ogunwalea7afaa22015-05-01 20:39:18 -07001161 boolean privileged = false;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001162 Rect bounds = null;
Craig Mautner21d24a22014-04-23 11:45:37 -07001163
1164 for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
1165 final String attrName = in.getAttributeName(attrNdx);
1166 final String attrValue = in.getAttributeValue(attrNdx);
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001167 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: attribute name=" +
1168 attrName + " value=" + attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001169 if (ATTR_TASKID.equals(attrName)) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08001170 if (taskId == INVALID_TASK_ID) taskId = Integer.valueOf(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001171 } else if (ATTR_REALACTIVITY.equals(attrName)) {
1172 realActivity = ComponentName.unflattenFromString(attrValue);
Andrei Stingaceanu4ccec532016-01-13 12:10:21 +00001173 } else if (ATTR_REALACTIVITY_SUSPENDED.equals(attrName)) {
1174 realActivitySuspended = Boolean.valueOf(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001175 } else if (ATTR_ORIGACTIVITY.equals(attrName)) {
1176 origActivity = ComponentName.unflattenFromString(attrValue);
1177 } else if (ATTR_AFFINITY.equals(attrName)) {
1178 affinity = attrValue;
Dianne Hackborn79228822014-09-16 11:11:23 -07001179 } else if (ATTR_ROOT_AFFINITY.equals(attrName)) {
1180 rootAffinity = attrValue;
1181 hasRootAffinity = true;
Craig Mautner21d24a22014-04-23 11:45:37 -07001182 } else if (ATTR_ROOTHASRESET.equals(attrName)) {
1183 rootHasReset = Boolean.valueOf(attrValue);
Dianne Hackborn13420f22014-07-18 15:43:56 -07001184 } else if (ATTR_AUTOREMOVERECENTS.equals(attrName)) {
1185 autoRemoveRecents = Boolean.valueOf(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001186 } else if (ATTR_ASKEDCOMPATMODE.equals(attrName)) {
1187 askedCompatMode = Boolean.valueOf(attrValue);
1188 } else if (ATTR_USERID.equals(attrName)) {
1189 userId = Integer.valueOf(attrValue);
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001190 } else if (ATTR_USER_SETUP_COMPLETE.equals(attrName)) {
1191 userSetupComplete = Boolean.valueOf(attrValue);
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001192 } else if (ATTR_EFFECTIVE_UID.equals(attrName)) {
1193 effectiveUid = Integer.valueOf(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001194 } else if (ATTR_TASKTYPE.equals(attrName)) {
1195 taskType = Integer.valueOf(attrValue);
Winson Chungffa2ec62014-07-03 15:54:42 -07001196 } else if (ATTR_FIRSTACTIVETIME.equals(attrName)) {
1197 firstActiveTime = Long.valueOf(attrValue);
Winson Chungf1fbd772014-06-24 18:06:58 -07001198 } else if (ATTR_LASTACTIVETIME.equals(attrName)) {
1199 lastActiveTime = Long.valueOf(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001200 } else if (ATTR_LASTDESCRIPTION.equals(attrName)) {
1201 lastDescription = attrValue;
1202 } else if (ATTR_LASTTIMEMOVED.equals(attrName)) {
1203 lastTimeOnTop = Long.valueOf(attrValue);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001204 } else if (ATTR_NEVERRELINQUISH.equals(attrName)) {
1205 neverRelinquishIdentity = Boolean.valueOf(attrValue);
Winsonc809cbb2015-11-02 12:06:15 -08001206 } else if (attrName.startsWith(TaskThumbnailInfo.ATTR_TASK_THUMBNAILINFO_PREFIX)) {
1207 thumbnailInfo.restoreFromXml(attrName, attrValue);
Craig Mautner648f69b2014-09-18 14:16:26 -07001208 } else if (attrName.startsWith(TaskDescription.ATTR_TASKDESCRIPTION_PREFIX)) {
1209 taskDescription.restoreFromXml(attrName, attrValue);
Craig Mautnera228ae92014-07-09 05:44:55 -07001210 } else if (ATTR_TASK_AFFILIATION.equals(attrName)) {
1211 taskAffiliation = Integer.valueOf(attrValue);
1212 } else if (ATTR_PREV_AFFILIATION.equals(attrName)) {
1213 prevTaskId = Integer.valueOf(attrValue);
1214 } else if (ATTR_NEXT_AFFILIATION.equals(attrName)) {
1215 nextTaskId = Integer.valueOf(attrValue);
Winson Chungec396d62014-08-06 17:08:00 -07001216 } else if (ATTR_TASK_AFFILIATION_COLOR.equals(attrName)) {
1217 taskAffiliationColor = Integer.valueOf(attrValue);
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001218 } else if (ATTR_CALLING_UID.equals(attrName)) {
1219 callingUid = Integer.valueOf(attrValue);
1220 } else if (ATTR_CALLING_PACKAGE.equals(attrName)) {
1221 callingPackage = attrValue;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -08001222 } else if (ATTR_RESIZEABLE.equals(attrName)) {
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001223 resizeMode = Boolean.valueOf(attrValue)
1224 ? RESIZE_MODE_RESIZEABLE : RESIZE_MODE_CROP_WINDOWS;
1225 } else if (ATTR_RESIZE_MODE.equals(attrName)) {
1226 resizeMode = Integer.valueOf(attrValue);
Wale Ogunwalea7afaa22015-05-01 20:39:18 -07001227 } else if (ATTR_PRIVILEGED.equals(attrName)) {
1228 privileged = Boolean.valueOf(attrValue);
Wale Ogunwale706ed792015-08-02 10:29:44 -07001229 } else if (ATTR_NON_FULLSCREEN_BOUNDS.equals(attrName)) {
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001230 bounds = Rect.unflattenFromString(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001231 } else {
1232 Slog.w(TAG, "TaskRecord: Unknown attribute=" + attrName);
1233 }
1234 }
1235
1236 int event;
1237 while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
Ben Kwa8814cf42015-07-08 10:54:56 -07001238 (event != XmlPullParser.END_TAG || in.getDepth() >= outerDepth)) {
Craig Mautner21d24a22014-04-23 11:45:37 -07001239 if (event == XmlPullParser.START_TAG) {
1240 final String name = in.getName();
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001241 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: START_TAG name=" +
1242 name);
Craig Mautner21d24a22014-04-23 11:45:37 -07001243 if (TAG_AFFINITYINTENT.equals(name)) {
1244 affinityIntent = Intent.restoreFromXml(in);
1245 } else if (TAG_INTENT.equals(name)) {
1246 intent = Intent.restoreFromXml(in);
1247 } else if (TAG_ACTIVITY.equals(name)) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08001248 ActivityRecord activity = ActivityRecord.restoreFromXml(in, stackSupervisor);
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001249 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: activity=" +
1250 activity);
Craig Mautner21d24a22014-04-23 11:45:37 -07001251 if (activity != null) {
1252 activities.add(activity);
1253 }
1254 } else {
1255 Slog.e(TAG, "restoreTask: Unexpected name=" + name);
1256 XmlUtils.skipCurrentTag(in);
1257 }
1258 }
1259 }
Dianne Hackborn79228822014-09-16 11:11:23 -07001260 if (!hasRootAffinity) {
1261 rootAffinity = affinity;
1262 } else if ("@".equals(rootAffinity)) {
1263 rootAffinity = null;
1264 }
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001265 if (effectiveUid <= 0) {
1266 Intent checkIntent = intent != null ? intent : affinityIntent;
1267 effectiveUid = 0;
1268 if (checkIntent != null) {
1269 IPackageManager pm = AppGlobals.getPackageManager();
1270 try {
1271 ApplicationInfo ai = pm.getApplicationInfo(
1272 checkIntent.getComponent().getPackageName(),
1273 PackageManager.GET_UNINSTALLED_PACKAGES
1274 | PackageManager.GET_DISABLED_COMPONENTS, userId);
1275 if (ai != null) {
1276 effectiveUid = ai.uid;
1277 }
1278 } catch (RemoteException e) {
1279 }
1280 }
1281 Slog.w(TAG, "Updating task #" + taskId + " for " + checkIntent
1282 + ": effectiveUid=" + effectiveUid);
1283 }
1284
Craig Mautner21d24a22014-04-23 11:45:37 -07001285 final TaskRecord task = new TaskRecord(stackSupervisor.mService, taskId, intent,
Dianne Hackborn79228822014-09-16 11:11:23 -07001286 affinityIntent, affinity, rootAffinity, realActivity, origActivity, rootHasReset,
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001287 autoRemoveRecents, askedCompatMode, taskType, userId, effectiveUid, lastDescription,
1288 activities, firstActiveTime, lastActiveTime, lastTimeOnTop, neverRelinquishIdentity,
Winsonc809cbb2015-11-02 12:06:15 -08001289 taskDescription, thumbnailInfo, taskAffiliation, prevTaskId, nextTaskId,
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001290 taskAffiliationColor, callingUid, callingPackage, resizeMode, privileged,
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001291 realActivitySuspended, userSetupComplete);
Filip Gruszczynskiaff7f132015-09-02 17:21:21 -07001292 task.updateOverrideConfiguration(bounds);
Craig Mautner21d24a22014-04-23 11:45:37 -07001293
1294 for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001295 activities.get(activityNdx).task = task;
Craig Mautner21d24a22014-04-23 11:45:37 -07001296 }
1297
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001298 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Restored task=" + task);
Craig Mautner21d24a22014-04-23 11:45:37 -07001299 return task;
1300 }
1301
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001302 /**
1303 * Update task's override configuration based on the bounds.
1304 * @return Update configuration or null if there is no change.
1305 */
Filip Gruszczynskiaff7f132015-09-02 17:21:21 -07001306 Configuration updateOverrideConfiguration(Rect bounds) {
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001307 if (Objects.equals(mBounds, bounds)) {
1308 return null;
1309 }
Wale Ogunwale5f986092015-12-04 15:35:38 -08001310 final Configuration oldConfig = mOverrideConfig;
1311 final boolean oldFullscreen = mFullscreen;
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001312
1313 mFullscreen = bounds == null;
Wale Ogunwale706ed792015-08-02 10:29:44 -07001314 if (mFullscreen) {
Wale Ogunwale3797c222015-10-27 14:21:58 -07001315 if (mBounds != null && StackId.persistTaskBounds(stack.mStackId)) {
Wale Ogunwale706ed792015-08-02 10:29:44 -07001316 mLastNonFullscreenBounds = mBounds;
1317 }
1318 mBounds = null;
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001319 mOverrideConfig = Configuration.EMPTY;
Wale Ogunwale706ed792015-08-02 10:29:44 -07001320 } else {
Chong Zhangb15758a2015-11-17 12:12:03 -08001321 if (mBounds == null) {
1322 mBounds = new Rect(bounds);
1323 } else {
1324 mBounds.set(bounds);
1325 }
Wale Ogunwale3797c222015-10-27 14:21:58 -07001326 if (stack == null || StackId.persistTaskBounds(stack.mStackId)) {
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -07001327 mLastNonFullscreenBounds = mBounds;
1328 }
Jorim Jaggia95ca8d2016-01-15 22:54:46 -08001329 mOverrideConfig = calculateOverrideConfig(mBounds);
Wale Ogunwale706ed792015-08-02 10:29:44 -07001330 }
Wale Ogunwale5f986092015-12-04 15:35:38 -08001331
1332 if (mFullscreen != oldFullscreen) {
Wale Ogunwale22e25262016-02-01 10:32:02 -08001333 mService.mStackSupervisor.scheduleReportMultiWindowChanged(this);
Wale Ogunwale5f986092015-12-04 15:35:38 -08001334 }
1335
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001336 return !mOverrideConfig.equals(oldConfig) ? mOverrideConfig : null;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001337 }
1338
Jorim Jaggia95ca8d2016-01-15 22:54:46 -08001339 Configuration calculateOverrideConfig(Rect bounds) {
1340 final Configuration serviceConfig = mService.mConfiguration;
1341 final Configuration config = new Configuration(Configuration.EMPTY);
1342 // TODO(multidisplay): Update Dp to that of display stack is on.
1343 final float density = serviceConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
1344 config.screenWidthDp =
1345 Math.min((int)(bounds.width() / density), serviceConfig.screenWidthDp);
1346 config.screenHeightDp =
1347 Math.min((int)(bounds.height() / density), serviceConfig.screenHeightDp);
1348 config.smallestScreenWidthDp =
1349 Math.min(config.screenWidthDp, config.screenHeightDp);
1350 config.orientation = (config.screenWidthDp <= config.screenHeightDp)
1351 ? Configuration.ORIENTATION_PORTRAIT
1352 : Configuration.ORIENTATION_LANDSCAPE;
1353 final int sl = Configuration.resetScreenLayout(serviceConfig.screenLayout);
1354 config.screenLayout = Configuration.reduceScreenLayout(
1355 sl, config.screenWidthDp, config.screenHeightDp);
1356 return config;
1357 }
1358
1359 /**
1360 * Using the existing configuration {@param config}, creates a new task override config such
1361 * that all the fields that are usually set in an override config are set to the ones in
1362 * {@param config}.
1363 */
1364 Configuration extractOverrideConfig(Configuration config) {
1365 final Configuration extracted = new Configuration(Configuration.EMPTY);
1366 extracted.screenWidthDp = config.screenWidthDp;
1367 extracted.screenHeightDp = config.screenHeightDp;
1368 extracted.smallestScreenWidthDp = config.smallestScreenWidthDp;
1369 extracted.orientation = config.orientation;
1370 extracted.screenLayout = config.screenLayout;
1371 return extracted;
1372 }
1373
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08001374 Rect updateOverrideConfigurationFromLaunchBounds() {
1375 final Rect bounds = validateBounds(getLaunchBounds());
1376 updateOverrideConfiguration(bounds);
1377 return bounds;
1378 }
1379
1380 static Rect validateBounds(Rect bounds) {
1381 if (bounds != null && bounds.isEmpty()) {
1382 Slog.wtf(TAG, "Received strange task bounds: " + bounds, new Throwable());
1383 return null;
1384 }
1385 return bounds;
1386 }
1387
Wale Ogunwale935e5022015-11-10 12:36:10 -08001388 /** Updates the task's bounds and override configuration to match what is expected for the
1389 * input stack. */
1390 void updateOverrideConfigurationForStack(ActivityStack inStack) {
1391 if (stack != null && stack == inStack) {
1392 return;
1393 }
1394
1395 if (inStack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001396 if (!isResizeable()) {
Wale Ogunwale935e5022015-11-10 12:36:10 -08001397 throw new IllegalArgumentException("Can not position non-resizeable task="
1398 + this + " in stack=" + inStack);
1399 }
1400 if (mBounds != null) {
1401 return;
1402 }
1403 if (mLastNonFullscreenBounds != null) {
1404 updateOverrideConfiguration(mLastNonFullscreenBounds);
1405 } else {
1406 inStack.layoutTaskInStack(this, null);
1407 }
1408 } else {
1409 updateOverrideConfiguration(inStack.mBounds);
1410 }
1411 }
1412
Chong Zhang0fa656b2015-08-31 15:17:21 -07001413 /**
1414 * Returns the correct stack to use based on task type and currently set bounds,
1415 * regardless of the focused stack and current stack association of the task.
1416 * The task will be moved (and stack focus changed) later if necessary.
1417 */
1418 int getLaunchStackId() {
1419 if (!isApplicationTask()) {
Wale Ogunwale706ed792015-08-02 10:29:44 -07001420 return HOME_STACK_ID;
1421 }
Chong Zhang0fa656b2015-08-31 15:17:21 -07001422 if (mBounds != null) {
Wale Ogunwale706ed792015-08-02 10:29:44 -07001423 return FREEFORM_WORKSPACE_STACK_ID;
1424 }
1425 return FULLSCREEN_WORKSPACE_STACK_ID;
1426 }
1427
1428 /** Returns the bounds that should be used to launch this task. */
1429 Rect getLaunchBounds() {
Chong Zhang75b37202015-12-04 14:16:36 -08001430 // If we're over lockscreen, forget about stack bounds and use fullscreen.
1431 if (mService.mLockScreenShown == LOCK_SCREEN_SHOWN) {
1432 return null;
1433 }
1434
Chong Zhang7d5f5102016-01-13 10:29:24 -08001435 if (stack == null) {
1436 return null;
1437 }
1438
1439 final int stackId = stack.mStackId;
1440 if (stackId == HOME_STACK_ID
1441 || stackId == FULLSCREEN_WORKSPACE_STACK_ID
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001442 || (stackId == DOCKED_STACK_ID && !isResizeable())) {
1443 return isResizeable() ? stack.mBounds : null;
Wale Ogunwale3797c222015-10-27 14:21:58 -07001444 } else if (!StackId.persistTaskBounds(stackId)) {
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -07001445 return stack.mBounds;
Wale Ogunwale706ed792015-08-02 10:29:44 -07001446 }
1447 return mLastNonFullscreenBounds;
1448 }
1449
Wale Ogunwale39381972015-12-17 17:15:29 -08001450 boolean canMatchRootAffinity() {
1451 // We don't allow root affinity matching on the pinned stack as no other task should
1452 // be launching in it based on affinity.
1453 return rootAffinity != null && (stack == null || stack.mStackId != PINNED_STACK_ID);
1454 }
1455
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001456 void dump(PrintWriter pw, String prefix) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001457 pw.print(prefix); pw.print("userId="); pw.print(userId);
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001458 pw.print(" effectiveUid="); UserHandle.formatUid(pw, effectiveUid);
1459 pw.print(" mCallingUid="); UserHandle.formatUid(pw, mCallingUid);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001460 pw.print(" mCallingPackage="); pw.println(mCallingPackage);
Dianne Hackborn79228822014-09-16 11:11:23 -07001461 if (affinity != null || rootAffinity != null) {
1462 pw.print(prefix); pw.print("affinity="); pw.print(affinity);
1463 if (affinity == null || !affinity.equals(rootAffinity)) {
1464 pw.print(" root="); pw.println(rootAffinity);
1465 } else {
1466 pw.println();
1467 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001468 }
Dianne Hackborn91097de2014-04-04 18:02:06 -07001469 if (voiceSession != null || voiceInteractor != null) {
1470 pw.print(prefix); pw.print("VOICE: session=0x");
1471 pw.print(Integer.toHexString(System.identityHashCode(voiceSession)));
1472 pw.print(" interactor=0x");
1473 pw.println(Integer.toHexString(System.identityHashCode(voiceInteractor)));
1474 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001475 if (intent != null) {
1476 StringBuilder sb = new StringBuilder(128);
1477 sb.append(prefix); sb.append("intent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08001478 intent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001479 sb.append('}');
1480 pw.println(sb.toString());
1481 }
1482 if (affinityIntent != null) {
1483 StringBuilder sb = new StringBuilder(128);
1484 sb.append(prefix); sb.append("affinityIntent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08001485 affinityIntent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001486 sb.append('}');
1487 pw.println(sb.toString());
1488 }
1489 if (origActivity != null) {
1490 pw.print(prefix); pw.print("origActivity=");
1491 pw.println(origActivity.flattenToShortString());
1492 }
1493 if (realActivity != null) {
1494 pw.print(prefix); pw.print("realActivity=");
1495 pw.println(realActivity.flattenToShortString());
1496 }
Dianne Hackborn852975d2014-08-22 17:42:43 -07001497 if (autoRemoveRecents || isPersistable || taskType != 0 || mTaskToReturnTo != 0
1498 || numFullscreen != 0) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001499 pw.print(prefix); pw.print("autoRemoveRecents="); pw.print(autoRemoveRecents);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001500 pw.print(" isPersistable="); pw.print(isPersistable);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001501 pw.print(" numFullscreen="); pw.print(numFullscreen);
1502 pw.print(" taskType="); pw.print(taskType);
1503 pw.print(" mTaskToReturnTo="); pw.println(mTaskToReturnTo);
1504 }
Craig Mautner432f64e2015-05-20 14:59:57 -07001505 if (rootWasReset || mNeverRelinquishIdentity || mReuseTask
1506 || mLockTaskAuth != LOCK_TASK_AUTH_PINNABLE) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001507 pw.print(prefix); pw.print("rootWasReset="); pw.print(rootWasReset);
1508 pw.print(" mNeverRelinquishIdentity="); pw.print(mNeverRelinquishIdentity);
Craig Mautner432f64e2015-05-20 14:59:57 -07001509 pw.print(" mReuseTask="); pw.print(mReuseTask);
1510 pw.print(" mLockTaskAuth="); pw.println(lockTaskAuthToString());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001511 }
Wale Ogunwale18795a22014-12-03 11:38:33 -08001512 if (mAffiliatedTaskId != taskId || mPrevAffiliateTaskId != INVALID_TASK_ID
1513 || mPrevAffiliate != null || mNextAffiliateTaskId != INVALID_TASK_ID
1514 || mNextAffiliate != null) {
Dianne Hackborn852975d2014-08-22 17:42:43 -07001515 pw.print(prefix); pw.print("affiliation="); pw.print(mAffiliatedTaskId);
1516 pw.print(" prevAffiliation="); pw.print(mPrevAffiliateTaskId);
1517 pw.print(" (");
1518 if (mPrevAffiliate == null) {
1519 pw.print("null");
1520 } else {
1521 pw.print(Integer.toHexString(System.identityHashCode(mPrevAffiliate)));
1522 }
1523 pw.print(") nextAffiliation="); pw.print(mNextAffiliateTaskId);
1524 pw.print(" (");
1525 if (mNextAffiliate == null) {
1526 pw.print("null");
1527 } else {
1528 pw.print(Integer.toHexString(System.identityHashCode(mNextAffiliate)));
1529 }
1530 pw.println(")");
1531 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001532 pw.print(prefix); pw.print("Activities="); pw.println(mActivities);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001533 if (!askedCompatMode || !inRecents || !isAvailable) {
1534 pw.print(prefix); pw.print("askedCompatMode="); pw.print(askedCompatMode);
1535 pw.print(" inRecents="); pw.print(inRecents);
1536 pw.print(" isAvailable="); pw.println(isAvailable);
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001537 }
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001538 pw.print(prefix); pw.print("lastThumbnail="); pw.print(mLastThumbnail);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001539 pw.print(" lastThumbnailFile="); pw.println(mLastThumbnailFile);
1540 if (lastDescription != null) {
1541 pw.print(prefix); pw.print("lastDescription="); pw.println(lastDescription);
1542 }
Wale Ogunwale069fbe42015-07-29 11:38:01 -07001543 if (stack != null) {
1544 pw.print(prefix); pw.print("stackId="); pw.println(stack.mStackId);
1545 }
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001546 pw.print(prefix + "hasBeenVisible=" + hasBeenVisible);
1547 pw.print(" mResizeMode=" + ActivityInfo.resizeModeToString(mResizeMode));
1548 pw.print(" isResizeable=" + isResizeable());
1549 pw.print(" firstActiveTime=" + lastActiveTime);
1550 pw.print(" lastActiveTime=" + lastActiveTime);
1551 pw.println(" (inactive for " + (getInactiveDuration() / 1000) + "s)");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001552 }
1553
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001554 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001555 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001556 StringBuilder sb = new StringBuilder(128);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001557 if (stringName != null) {
1558 sb.append(stringName);
1559 sb.append(" U=");
1560 sb.append(userId);
Wale Ogunwale6c5eb1c2015-11-10 07:52:22 -08001561 sb.append(" StackId=");
1562 sb.append(stack != null ? stack.mStackId : INVALID_STACK_ID);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001563 sb.append(" sz=");
1564 sb.append(mActivities.size());
1565 sb.append('}');
1566 return sb.toString();
1567 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001568 sb.append("TaskRecord{");
1569 sb.append(Integer.toHexString(System.identityHashCode(this)));
1570 sb.append(" #");
1571 sb.append(taskId);
1572 if (affinity != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001573 sb.append(" A=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001574 sb.append(affinity);
1575 } else if (intent != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001576 sb.append(" I=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001577 sb.append(intent.getComponent().flattenToShortString());
1578 } else if (affinityIntent != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001579 sb.append(" aI=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001580 sb.append(affinityIntent.getComponent().flattenToShortString());
1581 } else {
1582 sb.append(" ??");
1583 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07001584 stringName = sb.toString();
1585 return toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001586 }
1587}