blob: 0745a85f098d727c9090722c7d38235ea2814e11 [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
Jorim Jaggi0a932142016-02-01 17:42:25 -080019import android.annotation.Nullable;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -070020import android.app.Activity;
Craig Mautner9db9a0b2013-04-29 17:05:56 -070021import android.app.ActivityManager;
Wale Ogunwale3797c222015-10-27 14:21:58 -070022import android.app.ActivityManager.StackId;
Craig Mautner648f69b2014-09-18 14:16:26 -070023import android.app.ActivityManager.TaskDescription;
Wale Ogunwaleff3c66c2015-11-18 19:22:49 -080024import android.app.ActivityManager.TaskThumbnail;
Winsonc809cbb2015-11-02 12:06:15 -080025import android.app.ActivityManager.TaskThumbnailInfo;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -070026import android.app.ActivityOptions;
Dianne Hackborn885fbe52014-08-23 15:23:58 -070027import android.app.AppGlobals;
Jorim Jaggi0a932142016-02-01 17:42:25 -080028import android.app.IActivityManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029import android.content.ComponentName;
30import android.content.Intent;
31import android.content.pm.ActivityInfo;
Dianne Hackborn885fbe52014-08-23 15:23:58 -070032import android.content.pm.ApplicationInfo;
33import android.content.pm.IPackageManager;
34import android.content.pm.PackageManager;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -070035import android.content.res.Configuration;
Craig Mautner9db9a0b2013-04-29 17:05:56 -070036import android.graphics.Bitmap;
Winsonc809cbb2015-11-02 12:06:15 -080037import android.graphics.Point;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -070038import android.graphics.Rect;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -070039import android.os.Debug;
Craig Mautnerc0ffce52014-07-01 12:38:52 -070040import android.os.ParcelFileDescriptor;
Dianne Hackborn885fbe52014-08-23 15:23:58 -070041import android.os.RemoteException;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070042import android.os.UserHandle;
Suprabh Shukla7745c142016-03-07 18:21:10 -080043import android.provider.Settings;
Dianne Hackborn91097de2014-04-04 18:02:06 -070044import android.service.voice.IVoiceInteractionSession;
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -070045import android.util.DisplayMetrics;
Dianne Hackborn7f96b792012-05-29 18:46:45 -070046import android.util.Slog;
Suprabh Shukla23593142015-11-03 17:31:15 -080047
Dianne Hackborn91097de2014-04-04 18:02:06 -070048import com.android.internal.app.IVoiceInteractor;
Craig Mautner21d24a22014-04-23 11:45:37 -070049import com.android.internal.util.XmlUtils;
Suprabh Shukla23593142015-11-03 17:31:15 -080050
Craig Mautner21d24a22014-04-23 11:45:37 -070051import org.xmlpull.v1.XmlPullParser;
52import org.xmlpull.v1.XmlPullParserException;
53import org.xmlpull.v1.XmlSerializer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054
Craig Mautnerc0ffce52014-07-01 12:38:52 -070055import java.io.File;
Craig Mautner21d24a22014-04-23 11:45:37 -070056import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057import java.io.PrintWriter;
Craig Mautner5d9c7be2013-02-15 14:02:56 -080058import java.util.ArrayList;
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -070059import java.util.Objects;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060
Jorim Jaggi0a932142016-02-01 17:42:25 -080061import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
62import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
63import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
64import static android.app.ActivityManager.StackId.HOME_STACK_ID;
65import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
66import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
67import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
68import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
Jiaquan Hedd1e66f2016-06-15 15:15:12 -070069import static android.content.pm.ActivityInfo.FLAG_ON_TOP_LAUNCHER;
Jorim Jaggi0a932142016-02-01 17:42:25 -080070import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
71import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
72import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
73import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER;
74import static android.content.pm.ActivityInfo.RESIZE_MODE_CROP_WINDOWS;
Wale Ogunwaled829d362016-02-10 19:24:49 -080075import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
Jorim Jaggi0a932142016-02-01 17:42:25 -080076import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
Andrii Kulianf12fce12016-05-27 17:30:16 -070077import static android.content.res.Configuration.SCREENLAYOUT_LONG_MASK;
78import static android.content.res.Configuration.SCREENLAYOUT_SIZE_MASK;
Suprabh Shukla7745c142016-03-07 18:21:10 -080079import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
Jorim Jaggi0a932142016-02-01 17:42:25 -080080import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ADD_REMOVE;
81import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
82import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
83import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
84import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_ADD_REMOVE;
85import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
86import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
87import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS;
88import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
89import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
90import static com.android.server.am.ActivityManagerService.LOCK_SCREEN_SHOWN;
91import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
92import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
93import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
Wale Ogunwale3b232392016-05-13 15:37:13 -070094import static com.android.server.am.ActivityRecord.STARTING_WINDOW_SHOWN;
Jorim Jaggi0a932142016-02-01 17:42:25 -080095
Craig Mautnerc0ffce52014-07-01 12:38:52 -070096final class TaskRecord {
Wale Ogunwalee23149f2015-03-06 15:39:44 -080097 private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskRecord" : TAG_AM;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -070098 private static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE;
Wale Ogunwaleee006da2015-03-30 14:49:25 -070099 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
Craig Mautnere0570202015-05-13 13:06:11 -0700100 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700101 private static final String TAG_TASKS = TAG + POSTFIX_TASKS;
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800102
Wale Ogunwale18795a22014-12-03 11:38:33 -0800103 static final String ATTR_TASKID = "task_id";
Craig Mautner21d24a22014-04-23 11:45:37 -0700104 private static final String TAG_INTENT = "intent";
105 private static final String TAG_AFFINITYINTENT = "affinity_intent";
Wale Ogunwale18795a22014-12-03 11:38:33 -0800106 static final String ATTR_REALACTIVITY = "real_activity";
Andrei Stingaceanu4ccec532016-01-13 12:10:21 +0000107 static final String ATTR_REALACTIVITY_SUSPENDED = "real_activity_suspended";
Craig Mautner21d24a22014-04-23 11:45:37 -0700108 private static final String ATTR_ORIGACTIVITY = "orig_activity";
Stefan Kuhnee88d1e52015-05-18 10:33:45 -0700109 private static final String TAG_ACTIVITY = "activity";
Craig Mautner21d24a22014-04-23 11:45:37 -0700110 private static final String ATTR_AFFINITY = "affinity";
Dianne Hackborn79228822014-09-16 11:11:23 -0700111 private static final String ATTR_ROOT_AFFINITY = "root_affinity";
Craig Mautner21d24a22014-04-23 11:45:37 -0700112 private static final String ATTR_ROOTHASRESET = "root_has_reset";
Dianne Hackborn13420f22014-07-18 15:43:56 -0700113 private static final String ATTR_AUTOREMOVERECENTS = "auto_remove_recents";
Craig Mautner21d24a22014-04-23 11:45:37 -0700114 private static final String ATTR_ASKEDCOMPATMODE = "asked_compat_mode";
115 private static final String ATTR_USERID = "user_id";
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800116 private static final String ATTR_USER_SETUP_COMPLETE = "user_setup_complete";
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700117 private static final String ATTR_EFFECTIVE_UID = "effective_uid";
Craig Mautner21d24a22014-04-23 11:45:37 -0700118 private static final String ATTR_TASKTYPE = "task_type";
Winson Chungffa2ec62014-07-03 15:54:42 -0700119 private static final String ATTR_FIRSTACTIVETIME = "first_active_time";
Winson Chungf1fbd772014-06-24 18:06:58 -0700120 private static final String ATTR_LASTACTIVETIME = "last_active_time";
Craig Mautner21d24a22014-04-23 11:45:37 -0700121 private static final String ATTR_LASTDESCRIPTION = "last_description";
122 private static final String ATTR_LASTTIMEMOVED = "last_time_moved";
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700123 private static final String ATTR_NEVERRELINQUISH = "never_relinquish_identity";
Wale Ogunwale18795a22014-12-03 11:38:33 -0800124 static final String ATTR_TASK_AFFILIATION = "task_affiliation";
Craig Mautnera228ae92014-07-09 05:44:55 -0700125 private static final String ATTR_PREV_AFFILIATION = "prev_affiliation";
126 private static final String ATTR_NEXT_AFFILIATION = "next_affiliation";
Winson Chungec396d62014-08-06 17:08:00 -0700127 private static final String ATTR_TASK_AFFILIATION_COLOR = "task_affiliation_color";
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700128 private static final String ATTR_CALLING_UID = "calling_uid";
129 private static final String ATTR_CALLING_PACKAGE = "calling_package";
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800130 private static final String ATTR_RESIZE_MODE = "resize_mode";
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700131 private static final String ATTR_PRIVILEGED = "privileged";
Wale Ogunwale706ed792015-08-02 10:29:44 -0700132 private static final String ATTR_NON_FULLSCREEN_BOUNDS = "non_fullscreen_bounds";
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700133 private static final String ATTR_MIN_WIDTH = "min_width";
134 private static final String ATTR_MIN_HEIGHT = "min_height";
Andrii Kulian18d75122016-03-27 20:20:28 -0700135
Craig Mautner21d24a22014-04-23 11:45:37 -0700136
137 private static final String TASK_THUMBNAIL_SUFFIX = "_task_thumbnail";
138
Wale Ogunwale18795a22014-12-03 11:38:33 -0800139 static final int INVALID_TASK_ID = -1;
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700140 static final int INVALID_MIN_SIZE = -1;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800141
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800142 final int taskId; // Unique identifier for this task.
Dianne Hackborn79228822014-09-16 11:11:23 -0700143 String affinity; // The affinity name for this task, or null; may change identity.
144 String rootAffinity; // Initial base affinity, or null; does not change from initial root.
Dianne Hackborn91097de2014-04-04 18:02:06 -0700145 final IVoiceInteractionSession voiceSession; // Voice interaction session driving task
146 final IVoiceInteractor voiceInteractor; // Associated interactor to provide to app
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147 Intent intent; // The original intent that started the task.
148 Intent affinityIntent; // Intent of affinity-moved activity that started this task.
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700149 int effectiveUid; // The current effective uid of the identity of this task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150 ComponentName origActivity; // The non-alias activity component of the intent.
151 ComponentName realActivity; // The actual activity component that started the task.
Andrei Stingaceanu4ccec532016-01-13 12:10:21 +0000152 boolean realActivitySuspended; // True if the actual activity component that started the
153 // task is suspended.
Winson Chungffa2ec62014-07-03 15:54:42 -0700154 long firstActiveTime; // First time this task was active.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800155 long lastActiveTime; // Last time this task was active, including sleep.
Dianne Hackborn852975d2014-08-22 17:42:43 -0700156 boolean inRecents; // Actually in the recents list?
157 boolean isAvailable; // Is the activity available to be launched?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800158 boolean rootWasReset; // True if the intent at the root of the task had
159 // the FLAG_ACTIVITY_RESET_TASK_IF_NEEDED flag.
Dianne Hackborn13420f22014-07-18 15:43:56 -0700160 boolean autoRemoveRecents; // If true, we should automatically remove the task from
161 // recents when activity finishes
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700162 boolean askedCompatMode;// Have asked the user about compat mode for this task.
Dianne Hackbornd38aed82014-06-10 21:36:35 -0700163 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 -0800164
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700165 String stringName; // caching of toString() result.
Dianne Hackborn9da2d402012-03-15 13:43:08 -0700166 int userId; // user for which this task was created
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800167 boolean mUserSetupComplete; // The user set-up is complete as of the last time the task activity
168 // was changed.
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800169
170 int numFullscreen; // Number of fullscreen activities.
171
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800172 int mResizeMode; // The resize mode of this task and its activities.
173 // Based on the {@link ActivityInfo#resizeMode} of the root activity.
Jorim Jaggi8202b2a2016-02-03 19:24:31 -0800174 boolean mTemporarilyUnresizable; // Separate flag from mResizeMode used to suppress resize
175 // changes on a temporary basis.
Craig Mautner15df08a2015-04-01 12:17:18 -0700176 int mLockTaskMode; // Which tasklock mode to launch this task in. One of
177 // ActivityManager.LOCK_TASK_LAUNCH_MODE_*
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700178 private boolean mPrivileged; // The root activity application of this task holds
179 // privileged permissions.
Jiaquan Hedd1e66f2016-06-15 15:15:12 -0700180 private boolean mIsOnTopLauncher; // Whether this task is an on-top launcher. See
181 // android.R.attr#onTopLauncher.
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700182
Craig Mautner15df08a2015-04-01 12:17:18 -0700183 /** Can't be put in lockTask mode. */
184 final static int LOCK_TASK_AUTH_DONT_LOCK = 0;
Benjamin Franz469dd582015-06-09 14:24:36 +0100185 /** Can enter app pinning with user approval. Can never start over existing lockTask task. */
Craig Mautner15df08a2015-04-01 12:17:18 -0700186 final static int LOCK_TASK_AUTH_PINNABLE = 1;
187 /** Starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing lockTask task. */
188 final static int LOCK_TASK_AUTH_LAUNCHABLE = 2;
Benjamin Franz469dd582015-06-09 14:24:36 +0100189 /** Can enter lockTask without user approval. Can start over existing lockTask task. */
Craig Mautner15df08a2015-04-01 12:17:18 -0700190 final static int LOCK_TASK_AUTH_WHITELISTED = 3;
Benjamin Franz469dd582015-06-09 14:24:36 +0100191 /** Priv-app that starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing
192 * lockTask task. */
193 final static int LOCK_TASK_AUTH_LAUNCHABLE_PRIV = 4;
Craig Mautner15df08a2015-04-01 12:17:18 -0700194 int mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE;
195
196 int mLockTaskUid = -1; // The uid of the application that called startLockTask().
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800197
Winson Chung03a9bae2014-05-02 09:56:12 -0700198 // This represents the last resolved activity values for this task
199 // NOTE: This value needs to be persisted with each task
Craig Mautner648f69b2014-09-18 14:16:26 -0700200 TaskDescription lastTaskDescription = new TaskDescription();
Winson Chung03a9bae2014-05-02 09:56:12 -0700201
Craig Mautnerd2328952013-03-05 12:46:26 -0800202 /** List of all activities in the task arranged in history order */
Craig Mautner21d24a22014-04-23 11:45:37 -0700203 final ArrayList<ActivityRecord> mActivities;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800204
Craig Mautnerd2328952013-03-05 12:46:26 -0800205 /** Current stack */
206 ActivityStack stack;
207
Craig Mautner2c1faed2013-07-23 12:56:02 -0700208 /** Takes on same set of values as ActivityRecord.mActivityType */
Craig Mautner21d24a22014-04-23 11:45:37 -0700209 int taskType;
Craig Mautner1602ec22013-05-12 10:24:27 -0700210
Craig Mautner21d24a22014-04-23 11:45:37 -0700211 /** Takes on same value as first root activity */
212 boolean isPersistable = false;
Craig Mautnerffcfcaa2014-06-05 09:54:38 -0700213 int maxRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700214
215 /** Only used for persistable tasks, otherwise 0. The last time this task was moved. Used for
216 * determining the order when restoring. Sign indicates whether last task movement was to front
217 * (positive) or back (negative). Absolute value indicates time. */
218 long mLastTimeMoved = System.currentTimeMillis();
219
Craig Mautner84984fa2014-06-19 11:19:20 -0700220 /** Indication of what to run next when task exits. Use ActivityRecord types.
221 * ActivityRecord.APPLICATION_ACTIVITY_TYPE indicates to resume the task below this one in the
222 * task stack. */
223 private int mTaskToReturnTo = APPLICATION_ACTIVITY_TYPE;
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700224
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700225 /** If original intent did not allow relinquishing task identity, save that information */
226 boolean mNeverRelinquishIdentity = true;
227
Craig Mautner362449a2014-06-20 14:04:39 -0700228 // Used in the unique case where we are clearing the task in order to reuse it. In that case we
229 // do not want to delete the stack when the task goes empty.
Filip Gruszczynskibe9dabd2016-01-19 12:23:10 -0800230 private boolean mReuseTask = false;
Craig Mautner362449a2014-06-20 14:04:39 -0700231
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700232 private Bitmap mLastThumbnail; // Last thumbnail captured for this item.
Wale Ogunwalebe23ff42014-10-21 16:29:51 -0700233 private final File mLastThumbnailFile; // File containing last thumbnail.
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700234 private final String mFilename;
Winsonc809cbb2015-11-02 12:06:15 -0800235 private TaskThumbnailInfo mLastThumbnailInfo;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700236 CharSequence lastDescription; // Last description captured for this item.
237
Craig Mautnera228ae92014-07-09 05:44:55 -0700238 int mAffiliatedTaskId; // taskId of parent affiliation or self if no parent.
Winson Chungec396d62014-08-06 17:08:00 -0700239 int mAffiliatedTaskColor; // color of the parent task affiliation.
Craig Mautnera228ae92014-07-09 05:44:55 -0700240 TaskRecord mPrevAffiliate; // previous task in affiliated chain.
Wale Ogunwale18795a22014-12-03 11:38:33 -0800241 int mPrevAffiliateTaskId = INVALID_TASK_ID; // previous id for persistence.
Craig Mautnera228ae92014-07-09 05:44:55 -0700242 TaskRecord mNextAffiliate; // next task in affiliated chain.
Wale Ogunwale18795a22014-12-03 11:38:33 -0800243 int mNextAffiliateTaskId = INVALID_TASK_ID; // next id for persistence.
Craig Mautnera228ae92014-07-09 05:44:55 -0700244
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700245 // For relaunching the task from recents as though it was launched by the original launcher.
246 int mCallingUid;
247 String mCallingPackage;
248
Craig Mautner21d24a22014-04-23 11:45:37 -0700249 final ActivityManagerService mService;
250
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700251 // Whether or not this task covers the entire screen; by default tasks are fullscreen.
252 boolean mFullscreen = true;
253
254 // Bounds of the Task. null for fullscreen tasks.
255 Rect mBounds = null;
Jorim Jaggi82c9dc92016-02-05 15:10:33 -0800256 private final Rect mTmpStableBounds = new Rect();
257 private final Rect mTmpNonDecorBounds = new Rect();
Wale Ogunwale9a08f822016-02-17 19:03:58 -0800258 private final Rect mTmpRect = new Rect();
Jorim Jaggi0a932142016-02-01 17:42:25 -0800259 private final Rect mTmpRect2 = new Rect();
260
Wale Ogunwale706ed792015-08-02 10:29:44 -0700261 // Last non-fullscreen bounds the task was launched in or resized to.
262 // The information is persisted and used to determine the appropriate stack to launch the
263 // task into on restore.
264 Rect mLastNonFullscreenBounds = null;
Andrii Kulian2e751b82016-03-16 16:59:32 -0700265 // Minimal width and height of this task when it's resizeable. -1 means it should use the
266 // default minimal width/height.
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700267 int mMinWidth;
268 int mMinHeight;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700269
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700270 // Ranking (from top) of this task among all visible tasks. (-1 means it's not visible)
271 // This number will be assigned when we evaluate OOM scores for all visible tasks.
272 int mLayerRank = -1;
273
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700274 Configuration mOverrideConfig = Configuration.EMPTY;
275
Craig Mautner21d24a22014-04-23 11:45:37 -0700276 TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Dianne Hackborn91097de2014-04-04 18:02:06 -0700277 IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700278 mService = service;
Craig Mautnera228ae92014-07-09 05:44:55 -0700279 mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
280 TaskPersister.IMAGE_EXTENSION;
Suprabh Shukla23593142015-11-03 17:31:15 -0800281 userId = UserHandle.getUserId(info.applicationInfo.uid);
282 mLastThumbnailFile = new File(TaskPersister.getUserImagesDir(userId), mFilename);
Winsonc809cbb2015-11-02 12:06:15 -0800283 mLastThumbnailInfo = new TaskThumbnailInfo();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800284 taskId = _taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700285 mAffiliatedTaskId = _taskId;
Dianne Hackborn91097de2014-04-04 18:02:06 -0700286 voiceSession = _voiceSession;
287 voiceInteractor = _voiceInteractor;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700288 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800289 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700290 mCallingUid = info.applicationInfo.uid;
291 mCallingPackage = info.packageName;
Martijn Coenend4a69702014-06-30 11:12:17 -0700292 setIntent(_intent, info);
Andrii Kulian2e751b82016-03-16 16:59:32 -0700293 setMinDimensions(info);
Winson730bf062016-03-31 18:04:56 -0700294 touchActiveTime();
Craig Mautner21d24a22014-04-23 11:45:37 -0700295 }
296
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700297 TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
Winsonc809cbb2015-11-02 12:06:15 -0800298 TaskDescription _taskDescription, TaskThumbnailInfo thumbnailInfo) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700299 mService = service;
300 mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
301 TaskPersister.IMAGE_EXTENSION;
Suprabh Shukla23593142015-11-03 17:31:15 -0800302 userId = UserHandle.getUserId(info.applicationInfo.uid);
303 mLastThumbnailFile = new File(TaskPersister.getUserImagesDir(userId), mFilename);
Winsonc809cbb2015-11-02 12:06:15 -0800304 mLastThumbnailInfo = thumbnailInfo;
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700305 taskId = _taskId;
306 mAffiliatedTaskId = _taskId;
307 voiceSession = null;
308 voiceInteractor = null;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700309 isAvailable = true;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800310 mActivities = new ArrayList<>();
Craig Mautner15df08a2015-04-01 12:17:18 -0700311 mCallingUid = info.applicationInfo.uid;
312 mCallingPackage = info.packageName;
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700313 setIntent(_intent, info);
Andrii Kulian2e751b82016-03-16 16:59:32 -0700314 setMinDimensions(info);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700315
316 taskType = ActivityRecord.APPLICATION_ACTIVITY_TYPE;
317 isPersistable = true;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700318 // Clamp to [1, max].
319 maxRecents = Math.min(Math.max(info.maxRecents, 1),
320 ActivityManager.getMaxAppRecentsLimitStatic());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700321
322 taskType = APPLICATION_ACTIVITY_TYPE;
323 mTaskToReturnTo = HOME_ACTIVITY_TYPE;
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700324 lastTaskDescription = _taskDescription;
Winson730bf062016-03-31 18:04:56 -0700325 touchActiveTime();
Dianne Hackbornaec68bb2014-08-20 15:25:13 -0700326 }
327
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800328 private TaskRecord(ActivityManagerService service, int _taskId, Intent _intent,
329 Intent _affinityIntent, String _affinity, String _rootAffinity,
330 ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset,
331 boolean _autoRemoveRecents, boolean _askedCompatMode, int _taskType, int _userId,
332 int _effectiveUid, String _lastDescription, ArrayList<ActivityRecord> activities,
333 long _firstActiveTime, long _lastActiveTime, long lastTimeMoved,
334 boolean neverRelinquishIdentity, TaskDescription _lastTaskDescription,
Winsonc809cbb2015-11-02 12:06:15 -0800335 TaskThumbnailInfo lastThumbnailInfo, int taskAffiliation, int prevTaskId,
336 int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage,
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800337 int resizeMode, boolean privileged, boolean _realActivitySuspended,
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700338 boolean userSetupComplete, int minWidth, int minHeight) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700339 mService = service;
Craig Mautnera228ae92014-07-09 05:44:55 -0700340 mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
341 TaskPersister.IMAGE_EXTENSION;
Suprabh Shukla23593142015-11-03 17:31:15 -0800342 mLastThumbnailFile = new File(TaskPersister.getUserImagesDir(_userId), mFilename);
Winsonc809cbb2015-11-02 12:06:15 -0800343 mLastThumbnailInfo = lastThumbnailInfo;
Craig Mautner21d24a22014-04-23 11:45:37 -0700344 taskId = _taskId;
345 intent = _intent;
346 affinityIntent = _affinityIntent;
347 affinity = _affinity;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800348 rootAffinity = _rootAffinity;
Craig Mautner21d24a22014-04-23 11:45:37 -0700349 voiceSession = null;
350 voiceInteractor = null;
351 realActivity = _realActivity;
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800352 realActivitySuspended = _realActivitySuspended;
Craig Mautner21d24a22014-04-23 11:45:37 -0700353 origActivity = _origActivity;
354 rootWasReset = _rootWasReset;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700355 isAvailable = true;
Dianne Hackborn13420f22014-07-18 15:43:56 -0700356 autoRemoveRecents = _autoRemoveRecents;
Craig Mautner21d24a22014-04-23 11:45:37 -0700357 askedCompatMode = _askedCompatMode;
358 taskType = _taskType;
Craig Mautner84984fa2014-06-19 11:19:20 -0700359 mTaskToReturnTo = HOME_ACTIVITY_TYPE;
Craig Mautner21d24a22014-04-23 11:45:37 -0700360 userId = _userId;
Wale Ogunwalef80170f2016-02-04 15:12:29 -0800361 mUserSetupComplete = userSetupComplete;
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700362 effectiveUid = _effectiveUid;
Winson Chungffa2ec62014-07-03 15:54:42 -0700363 firstActiveTime = _firstActiveTime;
Winson Chungf1fbd772014-06-24 18:06:58 -0700364 lastActiveTime = _lastActiveTime;
Craig Mautner21d24a22014-04-23 11:45:37 -0700365 lastDescription = _lastDescription;
366 mActivities = activities;
367 mLastTimeMoved = lastTimeMoved;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700368 mNeverRelinquishIdentity = neverRelinquishIdentity;
Winson Chung2cb86c72014-06-25 12:03:30 -0700369 lastTaskDescription = _lastTaskDescription;
Craig Mautnera228ae92014-07-09 05:44:55 -0700370 mAffiliatedTaskId = taskAffiliation;
Winson Chungec396d62014-08-06 17:08:00 -0700371 mAffiliatedTaskColor = taskAffiliationColor;
Craig Mautnera228ae92014-07-09 05:44:55 -0700372 mPrevAffiliateTaskId = prevTaskId;
373 mNextAffiliateTaskId = nextTaskId;
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700374 mCallingUid = callingUid;
375 mCallingPackage = callingPackage;
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800376 mResizeMode = resizeMode;
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700377 mPrivileged = privileged;
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700378 mMinWidth = minWidth;
379 mMinHeight = minHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800380 }
381
382 void touchActiveTime() {
Craig Mautner494f6bdd2014-07-21 11:17:46 -0700383 lastActiveTime = System.currentTimeMillis();
Winson Chungffa2ec62014-07-03 15:54:42 -0700384 if (firstActiveTime == 0) {
385 firstActiveTime = lastActiveTime;
386 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800387 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700388
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800389 long getInactiveDuration() {
Craig Mautner494f6bdd2014-07-21 11:17:46 -0700390 return System.currentTimeMillis() - lastActiveTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800391 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700392
Winson Chungfee26772014-08-05 12:21:52 -0700393 /** Sets the original intent, and the calling uid and package. */
394 void setIntent(ActivityRecord r) {
Winson Chungfee26772014-08-05 12:21:52 -0700395 mCallingUid = r.launchedFromUid;
396 mCallingPackage = r.launchedFromPackage;
Craig Mautner15df08a2015-04-01 12:17:18 -0700397 setIntent(r.intent, r.info);
Winson Chungfee26772014-08-05 12:21:52 -0700398 }
399
400 /** Sets the original intent, _without_ updating the calling uid or package. */
401 private void setIntent(Intent _intent, ActivityInfo info) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700402 if (intent == null) {
403 mNeverRelinquishIdentity =
404 (info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) == 0;
405 } else if (mNeverRelinquishIdentity) {
406 return;
407 }
408
409 affinity = info.taskAffinity;
Dianne Hackborn79228822014-09-16 11:11:23 -0700410 if (intent == null) {
411 // If this task already has an intent associated with it, don't set the root
412 // affinity -- we don't want it changing after initially set, but the initially
413 // set value may be null.
414 rootAffinity = affinity;
415 }
Dianne Hackborn885fbe52014-08-23 15:23:58 -0700416 effectiveUid = info.applicationInfo.uid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700417 stringName = null;
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800418
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800419 if (info.targetActivity == null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800420 if (_intent != null) {
421 // If this Intent has a selector, we want to clear it for the
422 // recent task since it is not relevant if the user later wants
423 // to re-launch the app.
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700424 if (_intent.getSelector() != null || _intent.getSourceBounds() != null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800425 _intent = new Intent(_intent);
426 _intent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700427 _intent.setSourceBounds(null);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800428 }
429 }
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700430 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Setting Intent of " + this + " to " + _intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800431 intent = _intent;
432 realActivity = _intent != null ? _intent.getComponent() : null;
433 origActivity = null;
434 } else {
435 ComponentName targetComponent = new ComponentName(
436 info.packageName, info.targetActivity);
437 if (_intent != null) {
438 Intent targetIntent = new Intent(_intent);
439 targetIntent.setComponent(targetComponent);
Dianne Hackbornf5b86712011-12-05 17:42:41 -0800440 targetIntent.setSelector(null);
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700441 targetIntent.setSourceBounds(null);
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700442 if (DEBUG_TASKS) Slog.v(TAG_TASKS,
Dianne Hackborn7f96b792012-05-29 18:46:45 -0700443 "Setting Intent of " + this + " to target " + targetIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800444 intent = targetIntent;
445 realActivity = targetComponent;
446 origActivity = _intent.getComponent();
447 } else {
448 intent = null;
449 realActivity = targetComponent;
450 origActivity = new ComponentName(info.packageName, info.name);
451 }
452 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700453
Craig Mautner47b20ba2014-09-17 17:23:44 -0700454 final int intentFlags = intent == null ? 0 : intent.getFlags();
455 if ((intentFlags & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800456 // Once we are set to an Intent with this flag, we count this
457 // task as having a true root activity.
458 rootWasReset = true;
459 }
Dianne Hackborn09233282014-04-30 11:33:59 -0700460 userId = UserHandle.getUserId(info.applicationInfo.uid);
Suprabh Shukla7745c142016-03-07 18:21:10 -0800461 mUserSetupComplete = Settings.Secure.getIntForUser(mService.mContext.getContentResolver(),
462 USER_SETUP_COMPLETE, 0, userId) != 0;
Craig Mautner41db4a72014-05-07 17:20:56 -0700463 if ((info.flags & ActivityInfo.FLAG_AUTO_REMOVE_FROM_RECENTS) != 0) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700464 // If the activity itself has requested auto-remove, then just always do it.
465 autoRemoveRecents = true;
Wale Ogunwale843bfb92015-03-27 11:06:48 -0700466 } else if ((intentFlags & (FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS))
467 == FLAG_ACTIVITY_NEW_DOCUMENT) {
Dianne Hackborn13420f22014-07-18 15:43:56 -0700468 // If the caller has not asked for the document to be retained, then we may
469 // want to turn on auto-remove, depending on whether the target has set its
470 // own document launch mode.
471 if (info.documentLaunchMode != ActivityInfo.DOCUMENT_LAUNCH_NONE) {
472 autoRemoveRecents = false;
473 } else {
474 autoRemoveRecents = true;
475 }
476 } else {
477 autoRemoveRecents = false;
Craig Mautner41db4a72014-05-07 17:20:56 -0700478 }
Wale Ogunwaleb1faf602016-01-27 09:12:31 -0800479 mResizeMode = info.resizeMode;
Jiaquan Hedd1e66f2016-06-15 15:15:12 -0700480 mIsOnTopLauncher = (info.flags & FLAG_ON_TOP_LAUNCHER) != 0;
Craig Mautner15df08a2015-04-01 12:17:18 -0700481 mLockTaskMode = info.lockTaskLaunchMode;
Wale Ogunwalea7afaa22015-05-01 20:39:18 -0700482 mPrivileged = (info.applicationInfo.privateFlags & PRIVATE_FLAG_PRIVILEGED) != 0;
Craig Mautner15df08a2015-04-01 12:17:18 -0700483 setLockTaskAuth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800484 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800485
Andrii Kulian2e751b82016-03-16 16:59:32 -0700486 /** Sets the original minimal width and height. */
487 private void setMinDimensions(ActivityInfo info) {
488 if (info != null && info.windowLayout != null) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700489 mMinWidth = info.windowLayout.minWidth;
490 mMinHeight = info.windowLayout.minHeight;
Andrii Kulian2e751b82016-03-16 16:59:32 -0700491 } else {
Andrii Kulianf66a83d2016-05-17 12:17:44 -0700492 mMinWidth = INVALID_MIN_SIZE;
493 mMinHeight = INVALID_MIN_SIZE;
Andrii Kulian2e751b82016-03-16 16:59:32 -0700494 }
495 }
496
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800497 /**
Andrii Kulian206b9fa2016-06-02 13:18:01 -0700498 * Return true if the input activity has the same intent filter as the intent this task
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800499 * record is based on (normally the root activity intent).
500 */
Andrii Kulian206b9fa2016-06-02 13:18:01 -0700501 boolean isSameIntentFilter(ActivityRecord r) {
Wale Ogunwale715a1dc2016-02-29 14:27:32 -0800502 final Intent intent = new Intent(r.intent);
503 // Correct the activity intent for aliasing. The task record intent will always be based on
504 // the real activity that will be launched not the alias, so we need to use an intent with
505 // the component name pointing to the real activity not the alias in the activity record.
506 intent.setComponent(r.realActivity);
507 return this.intent.filterEquals(intent);
508 }
509
Craig Mautner84984fa2014-06-19 11:19:20 -0700510 void setTaskToReturnTo(int taskToReturnTo) {
Wale Ogunwale673cbd22016-01-30 18:30:55 -0800511 mTaskToReturnTo = (taskToReturnTo == RECENTS_ACTIVITY_TYPE)
512 ? HOME_ACTIVITY_TYPE : taskToReturnTo;
Craig Mautner84984fa2014-06-19 11:19:20 -0700513 }
514
515 int getTaskToReturnTo() {
516 return mTaskToReturnTo;
517 }
518
Craig Mautnera228ae92014-07-09 05:44:55 -0700519 void setPrevAffiliate(TaskRecord prevAffiliate) {
520 mPrevAffiliate = prevAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800521 mPrevAffiliateTaskId = prevAffiliate == null ? INVALID_TASK_ID : prevAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700522 }
523
524 void setNextAffiliate(TaskRecord nextAffiliate) {
525 mNextAffiliate = nextAffiliate;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800526 mNextAffiliateTaskId = nextAffiliate == null ? INVALID_TASK_ID : nextAffiliate.taskId;
Craig Mautnera228ae92014-07-09 05:44:55 -0700527 }
528
529 // Close up recents linked list.
530 void closeRecentsChain() {
531 if (mPrevAffiliate != null) {
532 mPrevAffiliate.setNextAffiliate(mNextAffiliate);
533 }
534 if (mNextAffiliate != null) {
535 mNextAffiliate.setPrevAffiliate(mPrevAffiliate);
536 }
537 setPrevAffiliate(null);
538 setNextAffiliate(null);
539 }
540
Winson Chung740c3ac2014-11-12 16:14:38 -0800541 void removedFromRecents() {
Dianne Hackborn852975d2014-08-22 17:42:43 -0700542 disposeThumbnail();
543 closeRecentsChain();
544 if (inRecents) {
545 inRecents = false;
Winson Chung740c3ac2014-11-12 16:14:38 -0800546 mService.notifyTaskPersisterLocked(this, false);
Dianne Hackborn852975d2014-08-22 17:42:43 -0700547 }
548 }
549
Craig Mautnera228ae92014-07-09 05:44:55 -0700550 void setTaskToAffiliateWith(TaskRecord taskToAffiliateWith) {
551 closeRecentsChain();
552 mAffiliatedTaskId = taskToAffiliateWith.mAffiliatedTaskId;
Winson Chungec396d62014-08-06 17:08:00 -0700553 mAffiliatedTaskColor = taskToAffiliateWith.mAffiliatedTaskColor;
Craig Mautnera228ae92014-07-09 05:44:55 -0700554 // Find the end
555 while (taskToAffiliateWith.mNextAffiliate != null) {
556 final TaskRecord nextRecents = taskToAffiliateWith.mNextAffiliate;
557 if (nextRecents.mAffiliatedTaskId != mAffiliatedTaskId) {
558 Slog.e(TAG, "setTaskToAffiliateWith: nextRecents=" + nextRecents + " affilTaskId="
559 + nextRecents.mAffiliatedTaskId + " should be " + mAffiliatedTaskId);
560 if (nextRecents.mPrevAffiliate == taskToAffiliateWith) {
561 nextRecents.setPrevAffiliate(null);
562 }
563 taskToAffiliateWith.setNextAffiliate(null);
564 break;
565 }
566 taskToAffiliateWith = nextRecents;
567 }
568 taskToAffiliateWith.setNextAffiliate(this);
569 setPrevAffiliate(taskToAffiliateWith);
570 setNextAffiliate(null);
571 }
572
Winson Chung096f36b2014-08-20 15:39:01 -0700573 /**
Winsonc809cbb2015-11-02 12:06:15 -0800574 * Sets the last thumbnail with the current task bounds and the system orientation.
Winson Chung096f36b2014-08-20 15:39:01 -0700575 * @return whether the thumbnail was set
576 */
Winsonc809cbb2015-11-02 12:06:15 -0800577 boolean setLastThumbnailLocked(Bitmap thumbnail) {
578 final Configuration serviceConfig = mService.mConfiguration;
579 int taskWidth = 0;
580 int taskHeight = 0;
581 if (mBounds != null) {
582 // Non-fullscreen tasks
583 taskWidth = mBounds.width();
584 taskHeight = mBounds.height();
585 } else if (stack != null) {
586 // Fullscreen tasks
587 final Point displaySize = new Point();
588 stack.getDisplaySize(displaySize);
589 taskWidth = displaySize.x;
590 taskHeight = displaySize.y;
591 } else {
592 Slog.e(TAG, "setLastThumbnailLocked() called on Task without stack");
593 }
594 return setLastThumbnailLocked(thumbnail, taskWidth, taskHeight, serviceConfig.orientation);
595 }
596
597 /**
598 * Sets the last thumbnail with the current task bounds.
599 * @return whether the thumbnail was set
600 */
601 private boolean setLastThumbnailLocked(Bitmap thumbnail, int taskWidth, int taskHeight,
602 int screenOrientation) {
Winson Chung096f36b2014-08-20 15:39:01 -0700603 if (mLastThumbnail != thumbnail) {
604 mLastThumbnail = thumbnail;
Winsonc809cbb2015-11-02 12:06:15 -0800605 mLastThumbnailInfo.taskWidth = taskWidth;
606 mLastThumbnailInfo.taskHeight = taskHeight;
607 mLastThumbnailInfo.screenOrientation = screenOrientation;
Winson Chung096f36b2014-08-20 15:39:01 -0700608 if (thumbnail == null) {
609 if (mLastThumbnailFile != null) {
610 mLastThumbnailFile.delete();
611 }
612 } else {
Suprabh Shukla09a88f52015-12-02 14:36:31 -0800613 mService.mRecentTasks.saveImage(thumbnail, mLastThumbnailFile.getAbsolutePath());
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700614 }
Winson Chung096f36b2014-08-20 15:39:01 -0700615 return true;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700616 }
Winson Chung096f36b2014-08-20 15:39:01 -0700617 return false;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700618 }
619
620 void getLastThumbnail(TaskThumbnail thumbs) {
621 thumbs.mainThumbnail = mLastThumbnail;
Winsonc809cbb2015-11-02 12:06:15 -0800622 thumbs.thumbnailInfo = mLastThumbnailInfo;
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700623 thumbs.thumbnailFileDescriptor = null;
Craig Mautnerf4f8bb72014-07-29 10:41:40 -0700624 if (mLastThumbnail == null) {
Suprabh Shukla09a88f52015-12-02 14:36:31 -0800625 thumbs.mainThumbnail = mService.mRecentTasks.getImageFromWriteQueue(
Suprabh Shukla23593142015-11-03 17:31:15 -0800626 mLastThumbnailFile.getAbsolutePath());
Craig Mautnerf4f8bb72014-07-29 10:41:40 -0700627 }
Winson Chung096f36b2014-08-20 15:39:01 -0700628 // Only load the thumbnail file if we don't have a thumbnail
629 if (thumbs.mainThumbnail == null && mLastThumbnailFile.exists()) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700630 try {
631 thumbs.thumbnailFileDescriptor = ParcelFileDescriptor.open(mLastThumbnailFile,
632 ParcelFileDescriptor.MODE_READ_ONLY);
633 } catch (IOException e) {
Dianne Hackborn9844d292013-10-04 16:44:22 -0700634 }
635 }
636 }
637
Winsonc809cbb2015-11-02 12:06:15 -0800638 /**
639 * Removes in-memory thumbnail data when the max number of in-memory task thumbnails is reached.
640 */
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700641 void freeLastThumbnail() {
642 mLastThumbnail = null;
643 }
644
Winsonc809cbb2015-11-02 12:06:15 -0800645 /**
646 * Removes all associated thumbnail data when a task is removed or pruned from recents.
647 */
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700648 void disposeThumbnail() {
Winsonc6a2da02015-11-11 18:11:59 -0800649 mLastThumbnailInfo.reset();
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700650 mLastThumbnail = null;
651 lastDescription = null;
652 }
653
Winson Chung1147c402014-05-14 11:05:00 -0700654 /** Returns the intent for the root activity for this task */
655 Intent getBaseIntent() {
656 return intent != null ? intent : affinityIntent;
657 }
658
Winson Chung3b3f4642014-04-22 10:08:18 -0700659 /** Returns the first non-finishing activity from the root. */
660 ActivityRecord getRootActivity() {
661 for (int i = 0; i < mActivities.size(); i++) {
662 final ActivityRecord r = mActivities.get(i);
663 if (r.finishing) {
664 continue;
665 }
666 return r;
667 }
668 return null;
669 }
670
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800671 ActivityRecord getTopActivity() {
672 for (int i = mActivities.size() - 1; i >= 0; --i) {
673 final ActivityRecord r = mActivities.get(i);
674 if (r.finishing) {
675 continue;
676 }
677 return r;
678 }
679 return null;
680 }
681
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -0700682 ActivityRecord topRunningActivityLocked() {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700683 if (stack != null) {
684 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
685 ActivityRecord r = mActivities.get(activityNdx);
Chong Zhang87761972016-08-22 13:53:24 -0700686 if (!r.finishing && r.okToShowLocked()) {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700687 return r;
688 }
Craig Mautner6b74cb52013-09-27 17:02:21 -0700689 }
690 }
691 return null;
692 }
693
Wale Ogunwale3b232392016-05-13 15:37:13 -0700694 ActivityRecord topRunningActivityWithStartingWindowLocked() {
695 if (stack != null) {
696 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
697 ActivityRecord r = mActivities.get(activityNdx);
698 if (r.mStartingWindowState != STARTING_WINDOW_SHOWN
Chong Zhang87761972016-08-22 13:53:24 -0700699 || r.finishing || !r.okToShowLocked()) {
Wale Ogunwale3b232392016-05-13 15:37:13 -0700700 continue;
701 }
702 return r;
703 }
704 }
705 return null;
706 }
707
Chong Zhang87761972016-08-22 13:53:24 -0700708 boolean okToShowLocked() {
709 // NOTE: If {@link TaskRecord#topRunningActivityLocked} return is not null then it is
710 // okay to show the activity when locked.
711 return mService.mStackSupervisor.isCurrentProfileLocked(userId)
712 || topRunningActivityLocked() != null;
713 }
714
Wale Ogunwale6d42df62015-11-05 09:50:55 -0800715 void setFrontOfTask() {
716 setFrontOfTask(null);
717 }
718
Craig Mautner3b475fe2013-12-16 15:58:31 -0800719 /** Call after activity movement or finish to make sure that frontOfTask is set correctly */
Wale Ogunwale6d42df62015-11-05 09:50:55 -0800720 void setFrontOfTask(ActivityRecord newTop) {
721 // If a top candidate is suggested by the caller, go ahead and use it and mark all others
722 // as not front. This is needed in situations where the current front activity in the
723 // task isn't finished yet and we want to set the front to the activity moved to the front
724 // of the task.
725 boolean foundFront = newTop != null ? true : false;
726
Craig Mautner3b475fe2013-12-16 15:58:31 -0800727 final int numActivities = mActivities.size();
Craig Mautner704e40b2013-12-18 16:43:51 -0800728 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
Craig Mautner3b475fe2013-12-16 15:58:31 -0800729 final ActivityRecord r = mActivities.get(activityNdx);
730 if (foundFront || r.finishing) {
731 r.frontOfTask = false;
732 } else {
733 r.frontOfTask = true;
734 // Set frontOfTask false for every following activity.
735 foundFront = true;
736 }
737 }
Craig Mautner9587ee02014-06-23 15:00:10 +0000738 if (!foundFront && numActivities > 0) {
739 // All activities of this task are finishing. As we ought to have a frontOfTask
740 // activity, make the bottom activity front.
741 mActivities.get(0).frontOfTask = true;
742 }
Wale Ogunwale6d42df62015-11-05 09:50:55 -0800743 if (newTop != null) {
744 newTop.frontOfTask = true;
745 }
Craig Mautner3b475fe2013-12-16 15:58:31 -0800746 }
747
Craig Mautnerde4ef022013-04-07 19:01:33 -0700748 /**
Craig Mautner3b475fe2013-12-16 15:58:31 -0800749 * Reorder the history stack so that the passed activity is brought to the front.
Craig Mautnerde4ef022013-04-07 19:01:33 -0700750 */
751 final void moveActivityToFrontLocked(ActivityRecord newTop) {
Wale Ogunwale0fc365c2015-05-25 19:35:42 -0700752 if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE,
753 "Removing and adding activity " + newTop
754 + " to stack at top callers=" + Debug.getCallers(4));
Craig Mautnerde4ef022013-04-07 19:01:33 -0700755
Craig Mautnerde4ef022013-04-07 19:01:33 -0700756 mActivities.remove(newTop);
757 mActivities.add(newTop);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700758 updateEffectiveIntent();
Craig Mautner3b475fe2013-12-16 15:58:31 -0800759
Wale Ogunwale6d42df62015-11-05 09:50:55 -0800760 setFrontOfTask(newTop);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700761 }
762
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800763 void addActivityAtBottom(ActivityRecord r) {
Craig Mautner77878772013-03-04 19:46:24 -0800764 addActivityAtIndex(0, r);
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800765 }
766
767 void addActivityToTop(ActivityRecord r) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700768 addActivityAtIndex(mActivities.size(), r);
769 }
770
771 void addActivityAtIndex(int index, ActivityRecord r) {
Craig Mautner6170f732013-04-02 13:05:23 -0700772 // 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 -0800773 if (!mActivities.remove(r) && r.fullscreen) {
774 // Was not previously in list.
775 numFullscreen++;
776 }
Craig Mautner2c1faed2013-07-23 12:56:02 -0700777 // Only set this based on the first activity
778 if (mActivities.isEmpty()) {
Craig Mautner21d24a22014-04-23 11:45:37 -0700779 taskType = r.mActivityType;
780 isPersistable = r.isPersistable();
Craig Mautnerdc00cbe2014-07-20 17:48:47 -0700781 mCallingUid = r.launchedFromUid;
782 mCallingPackage = r.launchedFromPackage;
Dianne Hackborn852975d2014-08-22 17:42:43 -0700783 // Clamp to [1, max].
784 maxRecents = Math.min(Math.max(r.info.maxRecents, 1),
785 ActivityManager.getMaxAppRecentsLimitStatic());
Craig Mautner2c1faed2013-07-23 12:56:02 -0700786 } else {
787 // Otherwise make all added activities match this one.
Craig Mautner21d24a22014-04-23 11:45:37 -0700788 r.mActivityType = taskType;
Craig Mautner78733002013-06-10 13:54:49 -0700789 }
Wale Ogunwale3b232392016-05-13 15:37:13 -0700790
791 final int size = mActivities.size();
792
793 if (index == size && size > 0) {
794 final ActivityRecord top = mActivities.get(size - 1);
795 if (top.mTaskOverlay) {
796 // Place below the task overlay activity since the overlay activity should always
797 // be on top.
798 index--;
799 }
800 }
801
Craig Mautner77878772013-03-04 19:46:24 -0800802 mActivities.add(index, r);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -0700803 updateEffectiveIntent();
Craig Mautner21d24a22014-04-23 11:45:37 -0700804 if (r.isPersistable()) {
805 mService.notifyTaskPersisterLocked(this, false);
806 }
Craig Mautner77878772013-03-04 19:46:24 -0800807 }
808
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800809 /** @return true if this was the last activity in the task */
810 boolean removeActivity(ActivityRecord r) {
811 if (mActivities.remove(r) && r.fullscreen) {
812 // Was previously in list.
813 numFullscreen--;
814 }
Craig Mautner21d24a22014-04-23 11:45:37 -0700815 if (r.isPersistable()) {
816 mService.notifyTaskPersisterLocked(this, false);
817 }
Wale Ogunwale89182d52016-03-11 10:38:36 -0800818
819 if (stack != null && stack.mStackId == PINNED_STACK_ID) {
820 // We normally notify listeners of task stack changes on pause, however pinned stack
821 // activities are normally in the paused state so no notification will be sent there
822 // before the activity is removed. We send it here so instead.
823 mService.notifyTaskStackChangedLocked();
824 }
825
Craig Mautner41326202014-06-20 14:38:21 -0700826 if (mActivities.isEmpty()) {
Craig Mautner5afcd4d2014-06-21 18:11:33 -0700827 return !mReuseTask;
Craig Mautner41326202014-06-20 14:38:21 -0700828 }
829 updateEffectiveIntent();
830 return false;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800831 }
832
Craig Mautner41db4a72014-05-07 17:20:56 -0700833 boolean autoRemoveFromRecents() {
Dianne Hackbornd38aed82014-06-10 21:36:35 -0700834 // We will automatically remove the task either if it has explicitly asked for
835 // this, or it is empty and has never contained an activity that got shown to
836 // the user.
Dianne Hackborn13420f22014-07-18 15:43:56 -0700837 return autoRemoveRecents || (mActivities.isEmpty() && !hasBeenVisible);
Craig Mautner41db4a72014-05-07 17:20:56 -0700838 }
839
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700840 /**
841 * Completely remove all activities associated with an existing
842 * task starting at a specified index.
843 */
844 final void performClearTaskAtIndexLocked(int activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700845 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700846 for ( ; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700847 final ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700848 if (r.finishing) {
849 continue;
850 }
Craig Mautner21d24a22014-04-23 11:45:37 -0700851 if (stack == null) {
852 // Task was restored from persistent storage.
853 r.takeFromHistory();
854 mActivities.remove(activityNdx);
855 --activityNdx;
856 --numActivities;
Todd Kennedy539db512014-12-15 09:57:55 -0800857 } else if (stack.finishActivityLocked(
858 r, Activity.RESULT_CANCELED, null, "clear-task-index", false)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700859 --activityNdx;
860 --numActivities;
861 }
862 }
863 }
864
865 /**
866 * Completely remove all activities associated with an existing task.
867 */
868 final void performClearTaskLocked() {
Craig Mautner362449a2014-06-20 14:04:39 -0700869 mReuseTask = true;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700870 performClearTaskAtIndexLocked(0);
Craig Mautner362449a2014-06-20 14:04:39 -0700871 mReuseTask = false;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700872 }
873
Filip Gruszczynskibe9dabd2016-01-19 12:23:10 -0800874 ActivityRecord performClearTaskForReuseLocked(ActivityRecord newR, int launchFlags) {
875 mReuseTask = true;
876 final ActivityRecord result = performClearTaskLocked(newR, launchFlags);
877 mReuseTask = false;
878 return result;
879 }
880
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700881 /**
882 * Perform clear operation as requested by
883 * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the
884 * stack to the given task, then look for
885 * an instance of that activity in the stack and, if found, finish all
886 * activities on top of it and return the instance.
887 *
888 * @param newR Description of the new activity being started.
889 * @return Returns the old activity that should be continued to be used,
890 * or null if none was found.
891 */
892 final ActivityRecord performClearTaskLocked(ActivityRecord newR, int launchFlags) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700893 int numActivities = mActivities.size();
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700894 for (int activityNdx = numActivities - 1; activityNdx >= 0; --activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700895 ActivityRecord r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700896 if (r.finishing) {
897 continue;
898 }
899 if (r.realActivity.equals(newR.realActivity)) {
900 // Here it is! Now finish everything in front...
Craig Mautner1602ec22013-05-12 10:24:27 -0700901 final ActivityRecord ret = r;
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700902
903 for (++activityNdx; activityNdx < numActivities; ++activityNdx) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700904 r = mActivities.get(activityNdx);
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700905 if (r.finishing) {
906 continue;
907 }
908 ActivityOptions opts = r.takeOptionsLocked();
909 if (opts != null) {
910 ret.updateOptionsLocked(opts);
911 }
Wale Ogunwale7d701172015-03-11 15:36:30 -0700912 if (stack != null && stack.finishActivityLocked(
Todd Kennedy539db512014-12-15 09:57:55 -0800913 r, Activity.RESULT_CANCELED, null, "clear-task-stack", false)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700914 --activityNdx;
915 --numActivities;
916 }
917 }
918
919 // Finally, if this is a normal launch mode (that is, not
920 // expecting onNewIntent()), then we will finish the current
921 // instance of the activity so a new fresh one can be started.
922 if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE
Daichi Hirono15a02992016-04-27 18:47:01 +0900923 && (launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0
924 && !ActivityStarter.isDocumentLaunchesIntoExisting(launchFlags)) {
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700925 if (!ret.finishing) {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700926 if (stack != null) {
927 stack.finishActivityLocked(
928 ret, Activity.RESULT_CANCELED, null, "clear-task-top", false);
929 }
Craig Mautnerb0f7dc72013-04-01 16:34:45 -0700930 return null;
931 }
932 }
933
934 return ret;
935 }
936 }
937
938 return null;
939 }
940
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700941 public TaskThumbnail getTaskThumbnailLocked() {
Craig Mautner21d24a22014-04-23 11:45:37 -0700942 if (stack != null) {
943 final ActivityRecord resumedActivity = stack.mResumedActivity;
944 if (resumedActivity != null && resumedActivity.task == this) {
Winson8b1871d2015-11-20 09:56:20 -0800945 final Bitmap thumbnail = stack.screenshotActivitiesLocked(resumedActivity);
Winsonc809cbb2015-11-02 12:06:15 -0800946 setLastThumbnailLocked(thumbnail);
Craig Mautner21d24a22014-04-23 11:45:37 -0700947 }
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700948 }
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700949 final TaskThumbnail taskThumbnail = new TaskThumbnail();
950 getLastThumbnail(taskThumbnail);
951 return taskThumbnail;
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700952 }
953
Craig Mautnerc0ffce52014-07-01 12:38:52 -0700954 public void removeTaskActivitiesLocked() {
955 // Just remove the entire task.
956 performClearTaskAtIndexLocked(0);
Craig Mautner9db9a0b2013-04-29 17:05:56 -0700957 }
958
Craig Mautner432f64e2015-05-20 14:59:57 -0700959 String lockTaskAuthToString() {
960 switch (mLockTaskAuth) {
961 case LOCK_TASK_AUTH_DONT_LOCK: return "LOCK_TASK_AUTH_DONT_LOCK";
962 case LOCK_TASK_AUTH_PINNABLE: return "LOCK_TASK_AUTH_PINNABLE";
963 case LOCK_TASK_AUTH_LAUNCHABLE: return "LOCK_TASK_AUTH_LAUNCHABLE";
964 case LOCK_TASK_AUTH_WHITELISTED: return "LOCK_TASK_AUTH_WHITELISTED";
Benjamin Franz469dd582015-06-09 14:24:36 +0100965 case LOCK_TASK_AUTH_LAUNCHABLE_PRIV: return "LOCK_TASK_AUTH_LAUNCHABLE_PRIV";
Craig Mautner432f64e2015-05-20 14:59:57 -0700966 default: return "unknown=" + mLockTaskAuth;
967 }
968 }
969
Craig Mautner15df08a2015-04-01 12:17:18 -0700970 void setLockTaskAuth() {
Benjamin Franz469dd582015-06-09 14:24:36 +0100971 if (!mPrivileged &&
972 (mLockTaskMode == LOCK_TASK_LAUNCH_MODE_ALWAYS ||
973 mLockTaskMode == LOCK_TASK_LAUNCH_MODE_NEVER)) {
974 // Non-priv apps are not allowed to use always or never, fall back to default
975 mLockTaskMode = LOCK_TASK_LAUNCH_MODE_DEFAULT;
976 }
Craig Mautner15df08a2015-04-01 12:17:18 -0700977 switch (mLockTaskMode) {
978 case LOCK_TASK_LAUNCH_MODE_DEFAULT:
979 mLockTaskAuth = isLockTaskWhitelistedLocked() ?
980 LOCK_TASK_AUTH_WHITELISTED : LOCK_TASK_AUTH_PINNABLE;
981 break;
982
983 case LOCK_TASK_LAUNCH_MODE_NEVER:
Benjamin Franz469dd582015-06-09 14:24:36 +0100984 mLockTaskAuth = LOCK_TASK_AUTH_DONT_LOCK;
Craig Mautner15df08a2015-04-01 12:17:18 -0700985 break;
986
987 case LOCK_TASK_LAUNCH_MODE_ALWAYS:
Benjamin Franz469dd582015-06-09 14:24:36 +0100988 mLockTaskAuth = LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
Craig Mautner15df08a2015-04-01 12:17:18 -0700989 break;
990
991 case LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED:
992 mLockTaskAuth = isLockTaskWhitelistedLocked() ?
993 LOCK_TASK_AUTH_LAUNCHABLE : LOCK_TASK_AUTH_PINNABLE;
994 break;
995 }
Craig Mautner432f64e2015-05-20 14:59:57 -0700996 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
997 " mLockTaskAuth=" + lockTaskAuthToString());
Craig Mautner15df08a2015-04-01 12:17:18 -0700998 }
999
1000 boolean isLockTaskWhitelistedLocked() {
Benjamin Franz6fd84cc2015-08-06 18:09:03 +01001001 String pkg = (realActivity != null) ? realActivity.getPackageName() : null;
1002 if (pkg == null) {
Craig Mautner15df08a2015-04-01 12:17:18 -07001003 return false;
1004 }
1005 String[] packages = mService.mLockTaskPackages.get(userId);
1006 if (packages == null) {
1007 return false;
1008 }
1009 for (int i = packages.length - 1; i >= 0; --i) {
Benjamin Franz6fd84cc2015-08-06 18:09:03 +01001010 if (pkg.equals(packages[i])) {
Craig Mautner15df08a2015-04-01 12:17:18 -07001011 return true;
1012 }
1013 }
1014 return false;
1015 }
Wale Ogunwale74e26592016-02-05 11:48:37 -08001016
Craig Mautnera82aa092013-09-13 15:34:08 -07001017 boolean isHomeTask() {
Craig Mautner84984fa2014-06-19 11:19:20 -07001018 return taskType == HOME_ACTIVITY_TYPE;
Craig Mautnera82aa092013-09-13 15:34:08 -07001019 }
1020
Wale Ogunwale74e26592016-02-05 11:48:37 -08001021 boolean isRecentsTask() {
1022 return taskType == RECENTS_ACTIVITY_TYPE;
1023 }
1024
Craig Mautner86d67a42013-05-14 10:34:38 -07001025 boolean isApplicationTask() {
Craig Mautner84984fa2014-06-19 11:19:20 -07001026 return taskType == APPLICATION_ACTIVITY_TYPE;
1027 }
1028
1029 boolean isOverHomeStack() {
1030 return mTaskToReturnTo == HOME_ACTIVITY_TYPE || mTaskToReturnTo == RECENTS_ACTIVITY_TYPE;
Craig Mautner1602ec22013-05-12 10:24:27 -07001031 }
1032
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001033 boolean isResizeable() {
1034 return !isHomeTask() && (mService.mForceResizableActivities
Jorim Jaggi8202b2a2016-02-03 19:24:31 -08001035 || ActivityInfo.isResizeableMode(mResizeMode)) && !mTemporarilyUnresizable;
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001036 }
1037
Jiaquan Hedd1e66f2016-06-15 15:15:12 -07001038 boolean isOnTopLauncher() {
1039 return isHomeTask() && mIsOnTopLauncher;
1040 }
1041
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001042 boolean inCropWindowsResizeMode() {
1043 return !isResizeable() && mResizeMode == RESIZE_MODE_CROP_WINDOWS;
1044 }
1045
Wale Ogunwale513346d2016-01-27 10:55:01 -08001046 boolean canGoInDockedStack() {
1047 return isResizeable() || inCropWindowsResizeMode();
1048 }
1049
Craig Mautner525f3d92013-05-07 14:01:50 -07001050 /**
1051 * Find the activity in the history stack within the given task. Returns
1052 * the index within the history at which it's found, or < 0 if not found.
1053 */
1054 final ActivityRecord findActivityInHistoryLocked(ActivityRecord r) {
1055 final ComponentName realActivity = r.realActivity;
1056 for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
1057 ActivityRecord candidate = mActivities.get(activityNdx);
1058 if (candidate.finishing) {
1059 continue;
1060 }
1061 if (candidate.realActivity.equals(realActivity)) {
1062 return candidate;
1063 }
1064 }
1065 return null;
1066 }
1067
Winson Chunga449dc02014-05-16 11:15:04 -07001068 /** Updates the last task description values. */
1069 void updateTaskDescription() {
1070 // Traverse upwards looking for any break between main task activities and
1071 // utility activities.
1072 int activityNdx;
1073 final int numActivities = mActivities.size();
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001074 final boolean relinquish = numActivities == 0 ? false :
1075 (mActivities.get(0).info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) != 0;
Winson Chunga449dc02014-05-16 11:15:04 -07001076 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
Craig Mautner21d24a22014-04-23 11:45:37 -07001077 ++activityNdx) {
Winson Chunga449dc02014-05-16 11:15:04 -07001078 final ActivityRecord r = mActivities.get(activityNdx);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001079 if (relinquish && (r.info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
1080 // This will be the top activity for determining taskDescription. Pre-inc to
1081 // overcome initial decrement below.
1082 ++activityNdx;
1083 break;
1084 }
Winson Chunga449dc02014-05-16 11:15:04 -07001085 if (r.intent != null &&
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001086 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
Winson Chunga449dc02014-05-16 11:15:04 -07001087 break;
1088 }
1089 }
1090 if (activityNdx > 0) {
1091 // Traverse downwards starting below break looking for set label, icon.
1092 // Note that if there are activities in the task but none of them set the
1093 // recent activity values, then we do not fall back to the last set
1094 // values in the TaskRecord.
1095 String label = null;
Craig Mautner648f69b2014-09-18 14:16:26 -07001096 String iconFilename = null;
Winson Chunga449dc02014-05-16 11:15:04 -07001097 int colorPrimary = 0;
Winson Chung1af8eda2016-02-05 17:55:56 +00001098 int colorBackground = 0;
Winson Chunga449dc02014-05-16 11:15:04 -07001099 for (--activityNdx; activityNdx >= 0; --activityNdx) {
1100 final ActivityRecord r = mActivities.get(activityNdx);
1101 if (r.taskDescription != null) {
1102 if (label == null) {
1103 label = r.taskDescription.getLabel();
1104 }
Craig Mautner648f69b2014-09-18 14:16:26 -07001105 if (iconFilename == null) {
1106 iconFilename = r.taskDescription.getIconFilename();
Winson Chunga449dc02014-05-16 11:15:04 -07001107 }
1108 if (colorPrimary == 0) {
1109 colorPrimary = r.taskDescription.getPrimaryColor();
Winson Chunga449dc02014-05-16 11:15:04 -07001110 }
Winson Chung1af8eda2016-02-05 17:55:56 +00001111 if (colorBackground == 0) {
1112 colorBackground = r.taskDescription.getBackgroundColor();
1113 }
Winson Chunga449dc02014-05-16 11:15:04 -07001114 }
1115 }
Winson Chung1af8eda2016-02-05 17:55:56 +00001116 lastTaskDescription = new TaskDescription(label, null, iconFilename, colorPrimary,
1117 colorBackground);
Winson Chungec396d62014-08-06 17:08:00 -07001118 // Update the task affiliation color if we are the parent of the group
1119 if (taskId == mAffiliatedTaskId) {
1120 mAffiliatedTaskColor = lastTaskDescription.getPrimaryColor();
1121 }
Winson Chunga449dc02014-05-16 11:15:04 -07001122 }
1123 }
1124
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001125 int findEffectiveRootIndex() {
Craig Mautner4767f4b2014-09-18 15:38:33 -07001126 int effectiveNdx = 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001127 final int topActivityNdx = mActivities.size() - 1;
Dianne Hackborn39569af2014-09-23 10:56:58 -07001128 for (int activityNdx = 0; activityNdx <= topActivityNdx; ++activityNdx) {
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001129 final ActivityRecord r = mActivities.get(activityNdx);
1130 if (r.finishing) {
1131 continue;
1132 }
Craig Mautner4767f4b2014-09-18 15:38:33 -07001133 effectiveNdx = activityNdx;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001134 if ((r.info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
1135 break;
1136 }
1137 }
Craig Mautner4767f4b2014-09-18 15:38:33 -07001138 return effectiveNdx;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001139 }
1140
1141 void updateEffectiveIntent() {
1142 final int effectiveRootIndex = findEffectiveRootIndex();
1143 final ActivityRecord r = mActivities.get(effectiveRootIndex);
Winson Chungfee26772014-08-05 12:21:52 -07001144 setIntent(r);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001145 }
1146
Craig Mautner21d24a22014-04-23 11:45:37 -07001147 void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001148 if (DEBUG_RECENTS) Slog.i(TAG_RECENTS, "Saving task=" + this);
Craig Mautner21d24a22014-04-23 11:45:37 -07001149
1150 out.attribute(null, ATTR_TASKID, String.valueOf(taskId));
1151 if (realActivity != null) {
1152 out.attribute(null, ATTR_REALACTIVITY, realActivity.flattenToShortString());
1153 }
Andrei Stingaceanu4ccec532016-01-13 12:10:21 +00001154 out.attribute(null, ATTR_REALACTIVITY_SUSPENDED, String.valueOf(realActivitySuspended));
Craig Mautner21d24a22014-04-23 11:45:37 -07001155 if (origActivity != null) {
1156 out.attribute(null, ATTR_ORIGACTIVITY, origActivity.flattenToShortString());
1157 }
Dianne Hackborn79228822014-09-16 11:11:23 -07001158 // Write affinity, and root affinity if it is different from affinity.
1159 // We use the special string "@" for a null root affinity, so we can identify
1160 // later whether we were given a root affinity or should just make it the
1161 // same as the affinity.
Craig Mautner21d24a22014-04-23 11:45:37 -07001162 if (affinity != null) {
1163 out.attribute(null, ATTR_AFFINITY, affinity);
Dianne Hackborn79228822014-09-16 11:11:23 -07001164 if (!affinity.equals(rootAffinity)) {
1165 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
1166 }
1167 } else if (rootAffinity != null) {
1168 out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
Craig Mautner21d24a22014-04-23 11:45:37 -07001169 }
1170 out.attribute(null, ATTR_ROOTHASRESET, String.valueOf(rootWasReset));
Dianne Hackborn13420f22014-07-18 15:43:56 -07001171 out.attribute(null, ATTR_AUTOREMOVERECENTS, String.valueOf(autoRemoveRecents));
Craig Mautner21d24a22014-04-23 11:45:37 -07001172 out.attribute(null, ATTR_ASKEDCOMPATMODE, String.valueOf(askedCompatMode));
1173 out.attribute(null, ATTR_USERID, String.valueOf(userId));
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001174 out.attribute(null, ATTR_USER_SETUP_COMPLETE, String.valueOf(mUserSetupComplete));
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001175 out.attribute(null, ATTR_EFFECTIVE_UID, String.valueOf(effectiveUid));
Craig Mautner21d24a22014-04-23 11:45:37 -07001176 out.attribute(null, ATTR_TASKTYPE, String.valueOf(taskType));
Winson Chungffa2ec62014-07-03 15:54:42 -07001177 out.attribute(null, ATTR_FIRSTACTIVETIME, String.valueOf(firstActiveTime));
Winson Chungf1fbd772014-06-24 18:06:58 -07001178 out.attribute(null, ATTR_LASTACTIVETIME, String.valueOf(lastActiveTime));
Craig Mautner21d24a22014-04-23 11:45:37 -07001179 out.attribute(null, ATTR_LASTTIMEMOVED, String.valueOf(mLastTimeMoved));
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001180 out.attribute(null, ATTR_NEVERRELINQUISH, String.valueOf(mNeverRelinquishIdentity));
Craig Mautner21d24a22014-04-23 11:45:37 -07001181 if (lastDescription != null) {
1182 out.attribute(null, ATTR_LASTDESCRIPTION, lastDescription.toString());
1183 }
Winson Chung2cb86c72014-06-25 12:03:30 -07001184 if (lastTaskDescription != null) {
Craig Mautner648f69b2014-09-18 14:16:26 -07001185 lastTaskDescription.saveToXml(out);
Winson Chung2cb86c72014-06-25 12:03:30 -07001186 }
Winsonc809cbb2015-11-02 12:06:15 -08001187 mLastThumbnailInfo.saveToXml(out);
Winson Chungec396d62014-08-06 17:08:00 -07001188 out.attribute(null, ATTR_TASK_AFFILIATION_COLOR, String.valueOf(mAffiliatedTaskColor));
Craig Mautnera228ae92014-07-09 05:44:55 -07001189 out.attribute(null, ATTR_TASK_AFFILIATION, String.valueOf(mAffiliatedTaskId));
1190 out.attribute(null, ATTR_PREV_AFFILIATION, String.valueOf(mPrevAffiliateTaskId));
1191 out.attribute(null, ATTR_NEXT_AFFILIATION, String.valueOf(mNextAffiliateTaskId));
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001192 out.attribute(null, ATTR_CALLING_UID, String.valueOf(mCallingUid));
1193 out.attribute(null, ATTR_CALLING_PACKAGE, mCallingPackage == null ? "" : mCallingPackage);
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001194 out.attribute(null, ATTR_RESIZE_MODE, String.valueOf(mResizeMode));
Wale Ogunwalea7afaa22015-05-01 20:39:18 -07001195 out.attribute(null, ATTR_PRIVILEGED, String.valueOf(mPrivileged));
Wale Ogunwale706ed792015-08-02 10:29:44 -07001196 if (mLastNonFullscreenBounds != null) {
1197 out.attribute(
1198 null, ATTR_NON_FULLSCREEN_BOUNDS, mLastNonFullscreenBounds.flattenToString());
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001199 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001200 out.attribute(null, ATTR_MIN_WIDTH, String.valueOf(mMinWidth));
1201 out.attribute(null, ATTR_MIN_HEIGHT, String.valueOf(mMinHeight));
Winson Chung2cb86c72014-06-25 12:03:30 -07001202
Craig Mautner21d24a22014-04-23 11:45:37 -07001203 if (affinityIntent != null) {
1204 out.startTag(null, TAG_AFFINITYINTENT);
1205 affinityIntent.saveToXml(out);
1206 out.endTag(null, TAG_AFFINITYINTENT);
1207 }
1208
1209 out.startTag(null, TAG_INTENT);
1210 intent.saveToXml(out);
1211 out.endTag(null, TAG_INTENT);
1212
1213 final ArrayList<ActivityRecord> activities = mActivities;
1214 final int numActivities = activities.size();
1215 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
1216 final ActivityRecord r = activities.get(activityNdx);
Craig Mautner43e52ed2014-06-16 17:18:52 -07001217 if (r.info.persistableMode == ActivityInfo.PERSIST_ROOT_ONLY || !r.isPersistable() ||
Wale Ogunwale843bfb92015-03-27 11:06:48 -07001218 ((r.intent.getFlags() & FLAG_ACTIVITY_NEW_DOCUMENT
1219 | FLAG_ACTIVITY_RETAIN_IN_RECENTS) == FLAG_ACTIVITY_NEW_DOCUMENT) &&
Craig Mautner43e52ed2014-06-16 17:18:52 -07001220 activityNdx > 0) {
Craig Mautnerf357c0c2014-06-09 09:23:27 -07001221 // Stop at first non-persistable or first break in task (CLEAR_WHEN_TASK_RESET).
Craig Mautner21d24a22014-04-23 11:45:37 -07001222 break;
1223 }
1224 out.startTag(null, TAG_ACTIVITY);
1225 r.saveToXml(out);
1226 out.endTag(null, TAG_ACTIVITY);
1227 }
Craig Mautner21d24a22014-04-23 11:45:37 -07001228 }
1229
1230 static TaskRecord restoreFromXml(XmlPullParser in, ActivityStackSupervisor stackSupervisor)
1231 throws IOException, XmlPullParserException {
1232 Intent intent = null;
1233 Intent affinityIntent = null;
Winsonc809cbb2015-11-02 12:06:15 -08001234 ArrayList<ActivityRecord> activities = new ArrayList<>();
Craig Mautner21d24a22014-04-23 11:45:37 -07001235 ComponentName realActivity = null;
Andrei Stingaceanu4ccec532016-01-13 12:10:21 +00001236 boolean realActivitySuspended = false;
Craig Mautner21d24a22014-04-23 11:45:37 -07001237 ComponentName origActivity = null;
1238 String affinity = null;
Dianne Hackborn79228822014-09-16 11:11:23 -07001239 String rootAffinity = null;
1240 boolean hasRootAffinity = false;
Craig Mautner21d24a22014-04-23 11:45:37 -07001241 boolean rootHasReset = false;
Dianne Hackborn13420f22014-07-18 15:43:56 -07001242 boolean autoRemoveRecents = false;
Craig Mautner21d24a22014-04-23 11:45:37 -07001243 boolean askedCompatMode = false;
1244 int taskType = ActivityRecord.APPLICATION_ACTIVITY_TYPE;
Craig Mautner21d24a22014-04-23 11:45:37 -07001245 int userId = 0;
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001246 boolean userSetupComplete = true;
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001247 int effectiveUid = -1;
Craig Mautner21d24a22014-04-23 11:45:37 -07001248 String lastDescription = null;
Winson Chungffa2ec62014-07-03 15:54:42 -07001249 long firstActiveTime = -1;
Winson Chung2cb86c72014-06-25 12:03:30 -07001250 long lastActiveTime = -1;
Craig Mautner21d24a22014-04-23 11:45:37 -07001251 long lastTimeOnTop = 0;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001252 boolean neverRelinquishIdentity = true;
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001253 int taskId = INVALID_TASK_ID;
Craig Mautner21d24a22014-04-23 11:45:37 -07001254 final int outerDepth = in.getDepth();
Craig Mautner648f69b2014-09-18 14:16:26 -07001255 TaskDescription taskDescription = new TaskDescription();
Winsonc809cbb2015-11-02 12:06:15 -08001256 TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
Wale Ogunwale18795a22014-12-03 11:38:33 -08001257 int taskAffiliation = INVALID_TASK_ID;
Winson Chungec396d62014-08-06 17:08:00 -07001258 int taskAffiliationColor = 0;
Wale Ogunwale18795a22014-12-03 11:38:33 -08001259 int prevTaskId = INVALID_TASK_ID;
1260 int nextTaskId = INVALID_TASK_ID;
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001261 int callingUid = -1;
1262 String callingPackage = "";
Wale Ogunwaled829d362016-02-10 19:24:49 -08001263 int resizeMode = RESIZE_MODE_FORCE_RESIZEABLE;
Wale Ogunwalea7afaa22015-05-01 20:39:18 -07001264 boolean privileged = false;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001265 Rect bounds = null;
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001266 int minWidth = INVALID_MIN_SIZE;
1267 int minHeight = INVALID_MIN_SIZE;
Craig Mautner21d24a22014-04-23 11:45:37 -07001268
1269 for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
1270 final String attrName = in.getAttributeName(attrNdx);
1271 final String attrValue = in.getAttributeValue(attrNdx);
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001272 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: attribute name=" +
1273 attrName + " value=" + attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001274 if (ATTR_TASKID.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001275 if (taskId == INVALID_TASK_ID) taskId = Integer.parseInt(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001276 } else if (ATTR_REALACTIVITY.equals(attrName)) {
1277 realActivity = ComponentName.unflattenFromString(attrValue);
Andrei Stingaceanu4ccec532016-01-13 12:10:21 +00001278 } else if (ATTR_REALACTIVITY_SUSPENDED.equals(attrName)) {
1279 realActivitySuspended = Boolean.valueOf(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001280 } else if (ATTR_ORIGACTIVITY.equals(attrName)) {
1281 origActivity = ComponentName.unflattenFromString(attrValue);
1282 } else if (ATTR_AFFINITY.equals(attrName)) {
1283 affinity = attrValue;
Dianne Hackborn79228822014-09-16 11:11:23 -07001284 } else if (ATTR_ROOT_AFFINITY.equals(attrName)) {
1285 rootAffinity = attrValue;
1286 hasRootAffinity = true;
Craig Mautner21d24a22014-04-23 11:45:37 -07001287 } else if (ATTR_ROOTHASRESET.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01001288 rootHasReset = Boolean.parseBoolean(attrValue);
Dianne Hackborn13420f22014-07-18 15:43:56 -07001289 } else if (ATTR_AUTOREMOVERECENTS.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01001290 autoRemoveRecents = Boolean.parseBoolean(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001291 } else if (ATTR_ASKEDCOMPATMODE.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01001292 askedCompatMode = Boolean.parseBoolean(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001293 } else if (ATTR_USERID.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001294 userId = Integer.parseInt(attrValue);
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001295 } else if (ATTR_USER_SETUP_COMPLETE.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01001296 userSetupComplete = Boolean.parseBoolean(attrValue);
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001297 } else if (ATTR_EFFECTIVE_UID.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001298 effectiveUid = Integer.parseInt(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001299 } else if (ATTR_TASKTYPE.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001300 taskType = Integer.parseInt(attrValue);
Winson Chungffa2ec62014-07-03 15:54:42 -07001301 } else if (ATTR_FIRSTACTIVETIME.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01001302 firstActiveTime = Long.parseLong(attrValue);
Winson Chungf1fbd772014-06-24 18:06:58 -07001303 } else if (ATTR_LASTACTIVETIME.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01001304 lastActiveTime = Long.parseLong(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001305 } else if (ATTR_LASTDESCRIPTION.equals(attrName)) {
1306 lastDescription = attrValue;
1307 } else if (ATTR_LASTTIMEMOVED.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01001308 lastTimeOnTop = Long.parseLong(attrValue);
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07001309 } else if (ATTR_NEVERRELINQUISH.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01001310 neverRelinquishIdentity = Boolean.parseBoolean(attrValue);
Winsonc809cbb2015-11-02 12:06:15 -08001311 } else if (attrName.startsWith(TaskThumbnailInfo.ATTR_TASK_THUMBNAILINFO_PREFIX)) {
1312 thumbnailInfo.restoreFromXml(attrName, attrValue);
Craig Mautner648f69b2014-09-18 14:16:26 -07001313 } else if (attrName.startsWith(TaskDescription.ATTR_TASKDESCRIPTION_PREFIX)) {
1314 taskDescription.restoreFromXml(attrName, attrValue);
Craig Mautnera228ae92014-07-09 05:44:55 -07001315 } else if (ATTR_TASK_AFFILIATION.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001316 taskAffiliation = Integer.parseInt(attrValue);
Craig Mautnera228ae92014-07-09 05:44:55 -07001317 } else if (ATTR_PREV_AFFILIATION.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001318 prevTaskId = Integer.parseInt(attrValue);
Craig Mautnera228ae92014-07-09 05:44:55 -07001319 } else if (ATTR_NEXT_AFFILIATION.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001320 nextTaskId = Integer.parseInt(attrValue);
Winson Chungec396d62014-08-06 17:08:00 -07001321 } else if (ATTR_TASK_AFFILIATION_COLOR.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001322 taskAffiliationColor = Integer.parseInt(attrValue);
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001323 } else if (ATTR_CALLING_UID.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001324 callingUid = Integer.parseInt(attrValue);
Craig Mautnerdc00cbe2014-07-20 17:48:47 -07001325 } else if (ATTR_CALLING_PACKAGE.equals(attrName)) {
1326 callingPackage = attrValue;
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001327 } else if (ATTR_RESIZE_MODE.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01001328 resizeMode = Integer.parseInt(attrValue);
Wale Ogunwaled829d362016-02-10 19:24:49 -08001329 resizeMode = (resizeMode == RESIZE_MODE_CROP_WINDOWS)
1330 ? RESIZE_MODE_FORCE_RESIZEABLE : resizeMode;
Wale Ogunwalea7afaa22015-05-01 20:39:18 -07001331 } else if (ATTR_PRIVILEGED.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01001332 privileged = Boolean.parseBoolean(attrValue);
Wale Ogunwale706ed792015-08-02 10:29:44 -07001333 } else if (ATTR_NON_FULLSCREEN_BOUNDS.equals(attrName)) {
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001334 bounds = Rect.unflattenFromString(attrValue);
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001335 } else if (ATTR_MIN_WIDTH.equals(attrName)) {
1336 minWidth = Integer.parseInt(attrValue);
1337 } else if (ATTR_MIN_HEIGHT.equals(attrName)) {
1338 minHeight = Integer.parseInt(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07001339 } else {
1340 Slog.w(TAG, "TaskRecord: Unknown attribute=" + attrName);
1341 }
1342 }
1343
1344 int event;
1345 while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
Ben Kwa8814cf42015-07-08 10:54:56 -07001346 (event != XmlPullParser.END_TAG || in.getDepth() >= outerDepth)) {
Craig Mautner21d24a22014-04-23 11:45:37 -07001347 if (event == XmlPullParser.START_TAG) {
1348 final String name = in.getName();
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001349 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: START_TAG name=" +
1350 name);
Craig Mautner21d24a22014-04-23 11:45:37 -07001351 if (TAG_AFFINITYINTENT.equals(name)) {
1352 affinityIntent = Intent.restoreFromXml(in);
1353 } else if (TAG_INTENT.equals(name)) {
1354 intent = Intent.restoreFromXml(in);
1355 } else if (TAG_ACTIVITY.equals(name)) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08001356 ActivityRecord activity = ActivityRecord.restoreFromXml(in, stackSupervisor);
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07001357 if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: activity=" +
1358 activity);
Craig Mautner21d24a22014-04-23 11:45:37 -07001359 if (activity != null) {
1360 activities.add(activity);
1361 }
1362 } else {
1363 Slog.e(TAG, "restoreTask: Unexpected name=" + name);
1364 XmlUtils.skipCurrentTag(in);
1365 }
1366 }
1367 }
Dianne Hackborn79228822014-09-16 11:11:23 -07001368 if (!hasRootAffinity) {
1369 rootAffinity = affinity;
1370 } else if ("@".equals(rootAffinity)) {
1371 rootAffinity = null;
1372 }
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001373 if (effectiveUid <= 0) {
1374 Intent checkIntent = intent != null ? intent : affinityIntent;
1375 effectiveUid = 0;
1376 if (checkIntent != null) {
1377 IPackageManager pm = AppGlobals.getPackageManager();
1378 try {
1379 ApplicationInfo ai = pm.getApplicationInfo(
1380 checkIntent.getComponent().getPackageName(),
1381 PackageManager.GET_UNINSTALLED_PACKAGES
1382 | PackageManager.GET_DISABLED_COMPONENTS, userId);
1383 if (ai != null) {
1384 effectiveUid = ai.uid;
1385 }
1386 } catch (RemoteException e) {
1387 }
1388 }
1389 Slog.w(TAG, "Updating task #" + taskId + " for " + checkIntent
1390 + ": effectiveUid=" + effectiveUid);
1391 }
1392
Craig Mautner21d24a22014-04-23 11:45:37 -07001393 final TaskRecord task = new TaskRecord(stackSupervisor.mService, taskId, intent,
Dianne Hackborn79228822014-09-16 11:11:23 -07001394 affinityIntent, affinity, rootAffinity, realActivity, origActivity, rootHasReset,
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001395 autoRemoveRecents, askedCompatMode, taskType, userId, effectiveUid, lastDescription,
1396 activities, firstActiveTime, lastActiveTime, lastTimeOnTop, neverRelinquishIdentity,
Winsonc809cbb2015-11-02 12:06:15 -08001397 taskDescription, thumbnailInfo, taskAffiliation, prevTaskId, nextTaskId,
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001398 taskAffiliationColor, callingUid, callingPackage, resizeMode, privileged,
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001399 realActivitySuspended, userSetupComplete, minWidth, minHeight);
Filip Gruszczynskiaff7f132015-09-02 17:21:21 -07001400 task.updateOverrideConfiguration(bounds);
Craig Mautner21d24a22014-04-23 11:45:37 -07001401
1402 for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001403 activities.get(activityNdx).task = task;
Craig Mautner21d24a22014-04-23 11:45:37 -07001404 }
1405
Wale Ogunwaleee006da2015-03-30 14:49:25 -07001406 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Restored task=" + task);
Craig Mautner21d24a22014-04-23 11:45:37 -07001407 return task;
1408 }
1409
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001410 private void adjustForMinimalTaskDimensions(Rect bounds) {
1411 if (bounds == null) {
1412 return;
1413 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001414 int minWidth = mMinWidth;
1415 int minHeight = mMinHeight;
Robert Carr9c5867d2016-03-10 15:52:46 -08001416 // If the task has no requested minimal size, we'd like to enforce a minimal size
1417 // so that the user can not render the task too small to manipulate. We don't need
1418 // to do this for the pinned stack as the bounds are controlled by the system.
Andrii Kulian2e751b82016-03-16 16:59:32 -07001419 if (stack.mStackId != PINNED_STACK_ID) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001420 if (minWidth == INVALID_MIN_SIZE) {
1421 minWidth = mService.mStackSupervisor.mDefaultMinSizeOfResizeableTask;
Andrii Kulian2e751b82016-03-16 16:59:32 -07001422 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001423 if (minHeight == INVALID_MIN_SIZE) {
1424 minHeight = mService.mStackSupervisor.mDefaultMinSizeOfResizeableTask;
Andrii Kulian2e751b82016-03-16 16:59:32 -07001425 }
Robert Carr9c5867d2016-03-10 15:52:46 -08001426 }
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001427 final boolean adjustWidth = minWidth > bounds.width();
1428 final boolean adjustHeight = minHeight > bounds.height();
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001429 if (!(adjustWidth || adjustHeight)) {
1430 return;
1431 }
1432
1433 if (adjustWidth) {
1434 if (mBounds != null && bounds.right == mBounds.right) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001435 bounds.left = bounds.right - minWidth;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001436 } else {
1437 // Either left bounds match, or neither match, or the previous bounds were
1438 // fullscreen and we default to keeping left.
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001439 bounds.right = bounds.left + minWidth;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001440 }
1441 }
1442 if (adjustHeight) {
1443 if (mBounds != null && bounds.bottom == mBounds.bottom) {
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001444 bounds.top = bounds.bottom - minHeight;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001445 } else {
1446 // Either top bounds match, or neither match, or the previous bounds were
1447 // fullscreen and we default to keeping top.
Andrii Kulianf66a83d2016-05-17 12:17:44 -07001448 bounds.bottom = bounds.top + minHeight;
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001449 }
1450 }
1451 }
1452
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001453 /**
1454 * Update task's override configuration based on the bounds.
Jorim Jaggi0a932142016-02-01 17:42:25 -08001455 * @param bounds The bounds of the task.
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001456 * @return Update configuration or null if there is no change.
1457 */
Filip Gruszczynskiaff7f132015-09-02 17:21:21 -07001458 Configuration updateOverrideConfiguration(Rect bounds) {
Jorim Jaggi0a932142016-02-01 17:42:25 -08001459 return updateOverrideConfiguration(bounds, null /* insetBounds */);
1460 }
1461
1462 /**
1463 * Update task's override configuration based on the bounds.
1464 * @param bounds The bounds of the task.
1465 * @param insetBounds The bounds used to calculate the system insets, which is used here to
1466 * subtract the navigation bar/status bar size from the screen size reported
1467 * to the application. See {@link IActivityManager#resizeDockedStack}.
1468 * @return Update configuration or null if there is no change.
1469 */
1470 Configuration updateOverrideConfiguration(Rect bounds, @Nullable Rect insetBounds) {
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001471 if (Objects.equals(mBounds, bounds)) {
1472 return null;
1473 }
Wale Ogunwale5f986092015-12-04 15:35:38 -08001474 final Configuration oldConfig = mOverrideConfig;
1475 final boolean oldFullscreen = mFullscreen;
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001476
1477 mFullscreen = bounds == null;
Wale Ogunwale706ed792015-08-02 10:29:44 -07001478 if (mFullscreen) {
Wale Ogunwale3797c222015-10-27 14:21:58 -07001479 if (mBounds != null && StackId.persistTaskBounds(stack.mStackId)) {
Wale Ogunwale706ed792015-08-02 10:29:44 -07001480 mLastNonFullscreenBounds = mBounds;
1481 }
1482 mBounds = null;
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001483 mOverrideConfig = Configuration.EMPTY;
Wale Ogunwale706ed792015-08-02 10:29:44 -07001484 } else {
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001485 mTmpRect.set(bounds);
1486 adjustForMinimalTaskDimensions(mTmpRect);
Chong Zhangb15758a2015-11-17 12:12:03 -08001487 if (mBounds == null) {
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001488 mBounds = new Rect(mTmpRect);
Chong Zhangb15758a2015-11-17 12:12:03 -08001489 } else {
Wale Ogunwale9a08f822016-02-17 19:03:58 -08001490 mBounds.set(mTmpRect);
Chong Zhangb15758a2015-11-17 12:12:03 -08001491 }
Wale Ogunwale3797c222015-10-27 14:21:58 -07001492 if (stack == null || StackId.persistTaskBounds(stack.mStackId)) {
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -07001493 mLastNonFullscreenBounds = mBounds;
1494 }
Andrii Kuliandaea3572016-04-08 13:20:51 -07001495 mOverrideConfig = calculateOverrideConfig(mTmpRect, insetBounds,
1496 mTmpRect.right != bounds.right, mTmpRect.bottom != bounds.bottom);
Wale Ogunwale706ed792015-08-02 10:29:44 -07001497 }
Wale Ogunwale5f986092015-12-04 15:35:38 -08001498
1499 if (mFullscreen != oldFullscreen) {
Andrii Kulian933076d2016-03-29 17:04:42 -07001500 mService.mStackSupervisor.scheduleReportMultiWindowModeChanged(this);
Wale Ogunwale5f986092015-12-04 15:35:38 -08001501 }
1502
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -07001503 return !mOverrideConfig.equals(oldConfig) ? mOverrideConfig : null;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001504 }
1505
Andrii Kuliandaea3572016-04-08 13:20:51 -07001506 private void subtractNonDecorInsets(Rect inOutBounds, Rect inInsetBounds,
1507 boolean overrideWidth, boolean overrideHeight) {
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001508 mTmpRect2.set(inInsetBounds);
1509 mService.mWindowManager.subtractNonDecorInsets(mTmpRect2);
1510 int leftInset = mTmpRect2.left - inInsetBounds.left;
1511 int topInset = mTmpRect2.top - inInsetBounds.top;
Andrii Kuliandaea3572016-04-08 13:20:51 -07001512 int rightInset = overrideWidth ? 0 : inInsetBounds.right - mTmpRect2.right;
1513 int bottomInset = overrideHeight ? 0 : inInsetBounds.bottom - mTmpRect2.bottom;
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001514 inOutBounds.inset(leftInset, topInset, rightInset, bottomInset);
1515 }
1516
Andrii Kuliandaea3572016-04-08 13:20:51 -07001517 private void subtractStableInsets(Rect inOutBounds, Rect inInsetBounds,
1518 boolean overrideWidth, boolean overrideHeight) {
Jorim Jaggi0a932142016-02-01 17:42:25 -08001519 mTmpRect2.set(inInsetBounds);
1520 mService.mWindowManager.subtractStableInsets(mTmpRect2);
1521 int leftInset = mTmpRect2.left - inInsetBounds.left;
1522 int topInset = mTmpRect2.top - inInsetBounds.top;
Andrii Kuliandaea3572016-04-08 13:20:51 -07001523 int rightInset = overrideWidth ? 0 : inInsetBounds.right - mTmpRect2.right;
1524 int bottomInset = overrideHeight ? 0 : inInsetBounds.bottom - mTmpRect2.bottom;
Jorim Jaggi0a932142016-02-01 17:42:25 -08001525 inOutBounds.inset(leftInset, topInset, rightInset, bottomInset);
1526 }
1527
Andrii Kuliandaea3572016-04-08 13:20:51 -07001528 private Configuration calculateOverrideConfig(Rect bounds, Rect insetBounds,
1529 boolean overrideWidth, boolean overrideHeight) {
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001530 mTmpNonDecorBounds.set(bounds);
1531 mTmpStableBounds.set(bounds);
1532 subtractNonDecorInsets(
Andrii Kuliandaea3572016-04-08 13:20:51 -07001533 mTmpNonDecorBounds, insetBounds != null ? insetBounds : bounds,
1534 overrideWidth, overrideHeight);
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001535 subtractStableInsets(
Andrii Kuliandaea3572016-04-08 13:20:51 -07001536 mTmpStableBounds, insetBounds != null ? insetBounds : bounds,
1537 overrideWidth, overrideHeight);
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001538
1539 // For calculating screenWidthDp, screenWidthDp, we use the stable inset screen area,
1540 // i.e. the screen area without the system bars.
Jorim Jaggia95ca8d2016-01-15 22:54:46 -08001541 final Configuration serviceConfig = mService.mConfiguration;
1542 final Configuration config = new Configuration(Configuration.EMPTY);
1543 // TODO(multidisplay): Update Dp to that of display stack is on.
1544 final float density = serviceConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
1545 config.screenWidthDp =
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001546 Math.min((int)(mTmpStableBounds.width() / density), serviceConfig.screenWidthDp);
Jorim Jaggia95ca8d2016-01-15 22:54:46 -08001547 config.screenHeightDp =
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001548 Math.min((int)(mTmpStableBounds.height() / density), serviceConfig.screenHeightDp);
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001549
1550 // TODO: Orientation?
Jorim Jaggia95ca8d2016-01-15 22:54:46 -08001551 config.orientation = (config.screenWidthDp <= config.screenHeightDp)
1552 ? Configuration.ORIENTATION_PORTRAIT
1553 : Configuration.ORIENTATION_LANDSCAPE;
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001554
Jorim Jaggi85639432016-05-06 17:27:55 -07001555 // For calculating screen layout, we need to use the non-decor inset screen area for the
1556 // calculation for compatibility reasons, i.e. screen area without system bars that could
1557 // never go away in Honeycomb.
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001558 final int compatScreenWidthDp = (int)(mTmpNonDecorBounds.width() / density);
1559 final int compatScreenHeightDp = (int)(mTmpNonDecorBounds.height() / density);
Jorim Jaggia95ca8d2016-01-15 22:54:46 -08001560 final int sl = Configuration.resetScreenLayout(serviceConfig.screenLayout);
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08001561 final int longSize = Math.max(compatScreenHeightDp, compatScreenWidthDp);
Jorim Jaggi85639432016-05-06 17:27:55 -07001562 final int shortSize = Math.min(compatScreenHeightDp, compatScreenWidthDp);;
1563 config.screenLayout = Configuration.reduceScreenLayout(sl, longSize, shortSize);
1564
1565 config.smallestScreenWidthDp = mService.mWindowManager.getSmallestWidthForTaskBounds(
1566 insetBounds != null ? insetBounds : bounds);
Jorim Jaggia95ca8d2016-01-15 22:54:46 -08001567 return config;
1568 }
1569
1570 /**
1571 * Using the existing configuration {@param config}, creates a new task override config such
1572 * that all the fields that are usually set in an override config are set to the ones in
1573 * {@param config}.
1574 */
1575 Configuration extractOverrideConfig(Configuration config) {
1576 final Configuration extracted = new Configuration(Configuration.EMPTY);
1577 extracted.screenWidthDp = config.screenWidthDp;
1578 extracted.screenHeightDp = config.screenHeightDp;
1579 extracted.smallestScreenWidthDp = config.smallestScreenWidthDp;
1580 extracted.orientation = config.orientation;
1581 extracted.screenLayout = config.screenLayout;
Chong Zhang92ab1032016-06-03 17:43:10 -07001582 extracted.fontScale = config.fontScale;
Jorim Jaggia95ca8d2016-01-15 22:54:46 -08001583 return extracted;
1584 }
1585
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08001586 Rect updateOverrideConfigurationFromLaunchBounds() {
1587 final Rect bounds = validateBounds(getLaunchBounds());
1588 updateOverrideConfiguration(bounds);
Andrii Kulian73336d812016-03-24 12:56:08 -07001589 if (bounds != null) {
1590 bounds.set(mBounds);
1591 }
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08001592 return bounds;
1593 }
1594
Andrii Kulianf12fce12016-05-27 17:30:16 -07001595 /**
1596 * Update fields that are not overridden for task from global configuration.
1597 *
1598 * @param globalConfig global configuration to update from.
1599 */
1600 void sanitizeOverrideConfiguration(Configuration globalConfig) {
Chong Zhanga8cc3782016-06-01 12:20:10 -07001601 // If it's fullscreen, the override config should be empty and we should leave it alone.
1602 if (mFullscreen) {
1603 return;
1604 }
1605
Andrii Kulianf12fce12016-05-27 17:30:16 -07001606 // screenLayout field is set in #calculateOverrideConfig but only part of it is really
1607 // overridden - aspect ratio and size. Other flags (like layout direction) can be updated
1608 // separately in global config and they also must be updated in override config.
1609 int overrideScreenLayout = mOverrideConfig.screenLayout;
1610 int newScreenLayout = globalConfig.screenLayout;
1611 newScreenLayout = (newScreenLayout & ~SCREENLAYOUT_LONG_MASK)
1612 | (overrideScreenLayout & SCREENLAYOUT_LONG_MASK);
1613 newScreenLayout = (newScreenLayout & ~SCREENLAYOUT_SIZE_MASK)
1614 | (overrideScreenLayout & SCREENLAYOUT_SIZE_MASK);
1615 mOverrideConfig.screenLayout = newScreenLayout;
1616 }
1617
Filip Gruszczynskidce2d162016-01-12 15:40:13 -08001618 static Rect validateBounds(Rect bounds) {
1619 if (bounds != null && bounds.isEmpty()) {
1620 Slog.wtf(TAG, "Received strange task bounds: " + bounds, new Throwable());
1621 return null;
1622 }
1623 return bounds;
1624 }
1625
Wale Ogunwale935e5022015-11-10 12:36:10 -08001626 /** Updates the task's bounds and override configuration to match what is expected for the
1627 * input stack. */
1628 void updateOverrideConfigurationForStack(ActivityStack inStack) {
1629 if (stack != null && stack == inStack) {
1630 return;
1631 }
1632
1633 if (inStack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001634 if (!isResizeable()) {
Wale Ogunwale935e5022015-11-10 12:36:10 -08001635 throw new IllegalArgumentException("Can not position non-resizeable task="
1636 + this + " in stack=" + inStack);
1637 }
1638 if (mBounds != null) {
1639 return;
1640 }
1641 if (mLastNonFullscreenBounds != null) {
1642 updateOverrideConfiguration(mLastNonFullscreenBounds);
1643 } else {
1644 inStack.layoutTaskInStack(this, null);
1645 }
1646 } else {
1647 updateOverrideConfiguration(inStack.mBounds);
1648 }
1649 }
1650
Chong Zhang0fa656b2015-08-31 15:17:21 -07001651 /**
1652 * Returns the correct stack to use based on task type and currently set bounds,
1653 * regardless of the focused stack and current stack association of the task.
1654 * The task will be moved (and stack focus changed) later if necessary.
1655 */
1656 int getLaunchStackId() {
1657 if (!isApplicationTask()) {
Wale Ogunwale706ed792015-08-02 10:29:44 -07001658 return HOME_STACK_ID;
1659 }
Chong Zhang0fa656b2015-08-31 15:17:21 -07001660 if (mBounds != null) {
Wale Ogunwale706ed792015-08-02 10:29:44 -07001661 return FREEFORM_WORKSPACE_STACK_ID;
1662 }
1663 return FULLSCREEN_WORKSPACE_STACK_ID;
1664 }
1665
1666 /** Returns the bounds that should be used to launch this task. */
1667 Rect getLaunchBounds() {
Chong Zhang75b37202015-12-04 14:16:36 -08001668 // If we're over lockscreen, forget about stack bounds and use fullscreen.
1669 if (mService.mLockScreenShown == LOCK_SCREEN_SHOWN) {
1670 return null;
1671 }
1672
Chong Zhang7d5f5102016-01-13 10:29:24 -08001673 if (stack == null) {
1674 return null;
1675 }
1676
1677 final int stackId = stack.mStackId;
1678 if (stackId == HOME_STACK_ID
1679 || stackId == FULLSCREEN_WORKSPACE_STACK_ID
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001680 || (stackId == DOCKED_STACK_ID && !isResizeable())) {
1681 return isResizeable() ? stack.mBounds : null;
Wale Ogunwale3797c222015-10-27 14:21:58 -07001682 } else if (!StackId.persistTaskBounds(stackId)) {
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -07001683 return stack.mBounds;
Wale Ogunwale706ed792015-08-02 10:29:44 -07001684 }
1685 return mLastNonFullscreenBounds;
1686 }
1687
Wale Ogunwale39381972015-12-17 17:15:29 -08001688 boolean canMatchRootAffinity() {
1689 // We don't allow root affinity matching on the pinned stack as no other task should
1690 // be launching in it based on affinity.
1691 return rootAffinity != null && (stack == null || stack.mStackId != PINNED_STACK_ID);
1692 }
1693
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001694 void dump(PrintWriter pw, String prefix) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001695 pw.print(prefix); pw.print("userId="); pw.print(userId);
Dianne Hackborn885fbe52014-08-23 15:23:58 -07001696 pw.print(" effectiveUid="); UserHandle.formatUid(pw, effectiveUid);
1697 pw.print(" mCallingUid="); UserHandle.formatUid(pw, mCallingUid);
Suprabh Shukla7745c142016-03-07 18:21:10 -08001698 pw.print(" mUserSetupComplete="); pw.print(mUserSetupComplete);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001699 pw.print(" mCallingPackage="); pw.println(mCallingPackage);
Dianne Hackborn79228822014-09-16 11:11:23 -07001700 if (affinity != null || rootAffinity != null) {
1701 pw.print(prefix); pw.print("affinity="); pw.print(affinity);
1702 if (affinity == null || !affinity.equals(rootAffinity)) {
1703 pw.print(" root="); pw.println(rootAffinity);
1704 } else {
1705 pw.println();
1706 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001707 }
Dianne Hackborn91097de2014-04-04 18:02:06 -07001708 if (voiceSession != null || voiceInteractor != null) {
1709 pw.print(prefix); pw.print("VOICE: session=0x");
1710 pw.print(Integer.toHexString(System.identityHashCode(voiceSession)));
1711 pw.print(" interactor=0x");
1712 pw.println(Integer.toHexString(System.identityHashCode(voiceInteractor)));
1713 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001714 if (intent != null) {
1715 StringBuilder sb = new StringBuilder(128);
1716 sb.append(prefix); sb.append("intent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08001717 intent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001718 sb.append('}');
1719 pw.println(sb.toString());
1720 }
1721 if (affinityIntent != null) {
1722 StringBuilder sb = new StringBuilder(128);
1723 sb.append(prefix); sb.append("affinityIntent={");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08001724 affinityIntent.toShortString(sb, false, true, false, true);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001725 sb.append('}');
1726 pw.println(sb.toString());
1727 }
1728 if (origActivity != null) {
1729 pw.print(prefix); pw.print("origActivity=");
1730 pw.println(origActivity.flattenToShortString());
1731 }
1732 if (realActivity != null) {
1733 pw.print(prefix); pw.print("realActivity=");
1734 pw.println(realActivity.flattenToShortString());
1735 }
Dianne Hackborn852975d2014-08-22 17:42:43 -07001736 if (autoRemoveRecents || isPersistable || taskType != 0 || mTaskToReturnTo != 0
1737 || numFullscreen != 0) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001738 pw.print(prefix); pw.print("autoRemoveRecents="); pw.print(autoRemoveRecents);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001739 pw.print(" isPersistable="); pw.print(isPersistable);
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001740 pw.print(" numFullscreen="); pw.print(numFullscreen);
1741 pw.print(" taskType="); pw.print(taskType);
1742 pw.print(" mTaskToReturnTo="); pw.println(mTaskToReturnTo);
1743 }
Craig Mautner432f64e2015-05-20 14:59:57 -07001744 if (rootWasReset || mNeverRelinquishIdentity || mReuseTask
1745 || mLockTaskAuth != LOCK_TASK_AUTH_PINNABLE) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001746 pw.print(prefix); pw.print("rootWasReset="); pw.print(rootWasReset);
1747 pw.print(" mNeverRelinquishIdentity="); pw.print(mNeverRelinquishIdentity);
Craig Mautner432f64e2015-05-20 14:59:57 -07001748 pw.print(" mReuseTask="); pw.print(mReuseTask);
1749 pw.print(" mLockTaskAuth="); pw.println(lockTaskAuthToString());
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001750 }
Wale Ogunwale18795a22014-12-03 11:38:33 -08001751 if (mAffiliatedTaskId != taskId || mPrevAffiliateTaskId != INVALID_TASK_ID
1752 || mPrevAffiliate != null || mNextAffiliateTaskId != INVALID_TASK_ID
1753 || mNextAffiliate != null) {
Dianne Hackborn852975d2014-08-22 17:42:43 -07001754 pw.print(prefix); pw.print("affiliation="); pw.print(mAffiliatedTaskId);
1755 pw.print(" prevAffiliation="); pw.print(mPrevAffiliateTaskId);
1756 pw.print(" (");
1757 if (mPrevAffiliate == null) {
1758 pw.print("null");
1759 } else {
1760 pw.print(Integer.toHexString(System.identityHashCode(mPrevAffiliate)));
1761 }
1762 pw.print(") nextAffiliation="); pw.print(mNextAffiliateTaskId);
1763 pw.print(" (");
1764 if (mNextAffiliate == null) {
1765 pw.print("null");
1766 } else {
1767 pw.print(Integer.toHexString(System.identityHashCode(mNextAffiliate)));
1768 }
1769 pw.println(")");
1770 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001771 pw.print(prefix); pw.print("Activities="); pw.println(mActivities);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001772 if (!askedCompatMode || !inRecents || !isAvailable) {
1773 pw.print(prefix); pw.print("askedCompatMode="); pw.print(askedCompatMode);
1774 pw.print(" inRecents="); pw.print(inRecents);
1775 pw.print(" isAvailable="); pw.println(isAvailable);
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001776 }
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001777 pw.print(prefix); pw.print("lastThumbnail="); pw.print(mLastThumbnail);
Dianne Hackborn852975d2014-08-22 17:42:43 -07001778 pw.print(" lastThumbnailFile="); pw.println(mLastThumbnailFile);
1779 if (lastDescription != null) {
1780 pw.print(prefix); pw.print("lastDescription="); pw.println(lastDescription);
1781 }
Wale Ogunwale069fbe42015-07-29 11:38:01 -07001782 if (stack != null) {
1783 pw.print(prefix); pw.print("stackId="); pw.println(stack.mStackId);
1784 }
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001785 pw.print(prefix + "hasBeenVisible=" + hasBeenVisible);
1786 pw.print(" mResizeMode=" + ActivityInfo.resizeModeToString(mResizeMode));
1787 pw.print(" isResizeable=" + isResizeable());
1788 pw.print(" firstActiveTime=" + lastActiveTime);
1789 pw.print(" lastActiveTime=" + lastActiveTime);
1790 pw.println(" (inactive for " + (getInactiveDuration() / 1000) + "s)");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001791 }
1792
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001793 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001794 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001795 StringBuilder sb = new StringBuilder(128);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001796 if (stringName != null) {
1797 sb.append(stringName);
1798 sb.append(" U=");
1799 sb.append(userId);
Wale Ogunwale6c5eb1c2015-11-10 07:52:22 -08001800 sb.append(" StackId=");
1801 sb.append(stack != null ? stack.mStackId : INVALID_STACK_ID);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001802 sb.append(" sz=");
1803 sb.append(mActivities.size());
1804 sb.append('}');
1805 return sb.toString();
1806 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001807 sb.append("TaskRecord{");
1808 sb.append(Integer.toHexString(System.identityHashCode(this)));
1809 sb.append(" #");
1810 sb.append(taskId);
1811 if (affinity != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001812 sb.append(" A=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001813 sb.append(affinity);
1814 } else if (intent != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001815 sb.append(" I=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001816 sb.append(intent.getComponent().flattenToShortString());
1817 } else if (affinityIntent != null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001818 sb.append(" aI=");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001819 sb.append(affinityIntent.getComponent().flattenToShortString());
1820 } else {
1821 sb.append(" ??");
1822 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07001823 stringName = sb.toString();
1824 return toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001825 }
1826}