blob: c68861227a7bdb3c0250efe1101180ce4569507c [file] [log] [blame]
Kenny Guyb1b30262016-02-09 16:02:35 +00001/*
2 * Copyright (C) 2016 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
Wale Ogunwale59507092018-10-29 09:00:30 -070017package com.android.server.wm;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080018
Michal Karpinski7b97a022018-12-14 15:17:29 +000019import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND;
Wale Ogunwale01d66562015-12-29 08:19:19 -080020import static android.app.Activity.RESULT_CANCELED;
Bryce Leef9d49542017-06-26 16:27:32 -070021import static android.app.ActivityManager.START_ABORTED;
Bryce Leeaa5e8c32017-03-01 16:01:06 -080022import static android.app.ActivityManager.START_CANCELED;
Wale Ogunwale01d66562015-12-29 08:19:19 -080023import static android.app.ActivityManager.START_CLASS_NOT_FOUND;
24import static android.app.ActivityManager.START_DELIVERED_TO_TOP;
25import static android.app.ActivityManager.START_FLAG_ONLY_IF_NEEDED;
26import static android.app.ActivityManager.START_RETURN_INTENT_TO_CALLER;
27import static android.app.ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
28import static android.app.ActivityManager.START_SUCCESS;
29import static android.app.ActivityManager.START_TASK_TO_FRONT;
Louis Chang0513a942019-03-06 12:38:13 +080030import static android.app.WaitResult.LAUNCH_STATE_COLD;
31import static android.app.WaitResult.LAUNCH_STATE_HOT;
Wale Ogunwale68278562017-09-23 17:13:55 -070032import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
33import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
Wale Ogunwale7d7973a2018-04-05 10:25:59 -070034import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070035import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
36import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Wale Ogunwale0568aed2017-09-08 13:29:37 -070037import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080038import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
39import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
Wale Ogunwale2a25a622016-01-30 11:27:21 -080040import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080041import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
Wale Ogunwale01d66562015-12-29 08:19:19 -080042import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080043import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
Wale Ogunwale01d66562015-12-29 08:19:19 -080044import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION;
45import static android.content.Intent.FLAG_ACTIVITY_NO_USER_ACTION;
Wale Ogunwale01d66562015-12-29 08:19:19 -080046import static android.content.Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP;
47import static android.content.Intent.FLAG_ACTIVITY_REORDER_TO_FRONT;
48import static android.content.Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED;
49import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
50import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP;
Louis Changb45ee7e2019-01-17 10:36:56 +080051import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
Wale Ogunwale01d66562015-12-29 08:19:19 -080052import static android.content.pm.ActivityInfo.DOCUMENT_LAUNCH_ALWAYS;
Wale Ogunwale2322bed2019-10-10 17:24:19 +020053import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
Wale Ogunwale01d66562015-12-29 08:19:19 -080054import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
55import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
56import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
Michal Karpinski7b97a022018-12-14 15:17:29 +000057import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Andrii Kulian79d67982019-08-19 11:56:16 -070058import static android.os.Process.INVALID_UID;
David Stevensc6b91c62017-02-08 14:23:58 -080059import static android.view.Display.DEFAULT_DISPLAY;
Andrii Kulian16802aa2016-11-02 12:21:33 -070060import static android.view.Display.INVALID_DISPLAY;
Riddle Hsub70b36d2018-09-11 21:20:02 +080061
Wale Ogunwale59507092018-10-29 09:00:30 -070062import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
63import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME;
64import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
65import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
66import static com.android.server.wm.ActivityStackSupervisor.TAG_TASKS;
67import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
68import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_FOCUS;
69import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
70import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS;
71import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STACK;
72import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
73import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_USER_LEAVING;
74import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
75import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS;
76import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RESULTS;
77import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_USER_LEAVING;
78import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
79import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
80import static com.android.server.wm.ActivityTaskManagerService.ANIMATE;
Louis Chang6fb1e842018-12-03 16:07:50 +080081import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_BOUNDS;
82import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_DISPLAY;
Louis Changcdec0802019-11-11 11:45:07 +080083import static com.android.server.wm.Task.REPARENT_MOVE_STACK_TO_FRONT;
Winson Chung74666102017-02-22 17:49:24 -080084
Todd Kennedye9910222017-02-21 16:00:11 -080085import android.annotation.NonNull;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +010086import android.annotation.Nullable;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080087import android.app.ActivityManager;
88import android.app.ActivityOptions;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080089import android.app.IApplicationThread;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080090import android.app.PendingIntent;
91import android.app.ProfilerInfo;
Sudheer Shankafc46e9b2016-10-21 17:55:27 -070092import android.app.WaitResult;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080093import android.content.IIntentSender;
94import android.content.Intent;
95import android.content.IntentSender;
96import android.content.pm.ActivityInfo;
97import android.content.pm.ApplicationInfo;
Todd Kennedye9910222017-02-21 16:00:11 -080098import android.content.pm.AuxiliaryResolveInfo;
Kenny Guyb1b30262016-02-09 16:02:35 +000099import android.content.pm.PackageManager;
Winson81fef842019-08-28 12:19:08 -0700100import android.content.pm.PackageManagerInternal;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800101import android.content.pm.ResolveInfo;
Kenny Guyb1b30262016-02-09 16:02:35 +0000102import android.content.pm.UserInfo;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800103import android.content.res.Configuration;
104import android.graphics.Rect;
105import android.os.Binder;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800106import android.os.Bundle;
107import android.os.IBinder;
Michal Karpinski8596ded2018-11-14 14:43:48 +0000108import android.os.Process;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800109import android.os.RemoteException;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100110import android.os.Trace;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800111import android.os.UserHandle;
Kenny Guyb1b30262016-02-09 16:02:35 +0000112import android.os.UserManager;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800113import android.service.voice.IVoiceInteractionSession;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700114import android.text.TextUtils;
Michal Karpinskib7daac22019-03-25 10:12:41 +0000115import android.util.ArraySet;
Bryce Leedaa91e42017-12-06 14:13:01 -0800116import android.util.Pools.SynchronizedPool;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800117import android.util.Slog;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800118
Bryce Leed3624e12017-11-30 08:51:45 -0800119import com.android.internal.annotations.VisibleForTesting;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800120import com.android.internal.app.HeavyWeightSwitcherActivity;
121import com.android.internal.app.IVoiceInteractor;
Wale Ogunwale59507092018-10-29 09:00:30 -0700122import com.android.server.am.PendingIntentRecord;
Louis Changdd3592a2018-11-05 11:04:14 +0800123import com.android.server.pm.InstantAppResolver;
Riddle Hsufd66d4d2019-11-14 10:35:55 +0800124import com.android.server.wm.ActivityMetricsLogger.LaunchingState;
Wale Ogunwale59507092018-10-29 09:00:30 -0700125import com.android.server.wm.ActivityStackSupervisor.PendingActivityLaunch;
126import com.android.server.wm.LaunchParamsController.LaunchParams;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800127
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700128import java.io.PrintWriter;
129import java.text.DateFormat;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700130import java.util.Date;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800131
132/**
Bryce Leed3624e12017-11-30 08:51:45 -0800133 * Controller for interpreting how and then launching an activity.
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800134 *
135 * This class collects all the logic for determining how an intent and flags should be turned into
136 * an activity and associated task and stack.
137 */
Wale Ogunwale01d66562015-12-29 08:19:19 -0800138class ActivityStarter {
Wale Ogunwale98875612018-10-12 07:53:02 -0700139 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStarter" : TAG_ATM;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800140 private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS;
141 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
142 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
143 private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING;
Bryce Lee7daee392017-10-12 13:46:18 -0700144 private static final int INVALID_LAUNCH_MODE = -1;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800145
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700146 private final ActivityTaskManagerService mService;
Louis Chang149d5c82019-12-30 09:47:39 +0800147 private final RootWindowContainer mRootWindowContainer;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800148 private final ActivityStackSupervisor mSupervisor;
Benjamin Franz563707b2017-06-29 15:06:13 +0100149 private final ActivityStartInterceptor mInterceptor;
Bryce Leed3624e12017-11-30 08:51:45 -0800150 private final ActivityStartController mController;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800151
Wale Ogunwale01d66562015-12-29 08:19:19 -0800152 // Share state variable among methods when starting an activity.
Louis Chang07b13002019-11-27 22:08:37 +0800153 @VisibleForTesting
154 ActivityRecord mStartActivity;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800155 private Intent mIntent;
156 private int mCallingUid;
157 private ActivityOptions mOptions;
158
Ricky Waib147fa12019-04-25 16:08:30 +0100159 // If it is true, background activity can only be started in an existing task that contains
Alan Stokes07389b62019-05-20 15:22:54 +0100160 // an activity with same uid, or if activity starts are enabled in developer options.
Ricky Waib147fa12019-04-25 16:08:30 +0100161 private boolean mRestrictedBgActivity;
162
Bryce Lee7daee392017-10-12 13:46:18 -0700163 private int mLaunchMode;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800164 private boolean mLaunchTaskBehind;
165 private int mLaunchFlags;
166
Bryce Leeec55eb02017-12-05 20:51:27 -0800167 private LaunchParams mLaunchParams = new LaunchParams();
Wale Ogunwale01d66562015-12-29 08:19:19 -0800168
169 private ActivityRecord mNotTop;
170 private boolean mDoResume;
171 private int mStartFlags;
172 private ActivityRecord mSourceRecord;
Bryce Lee7daee392017-10-12 13:46:18 -0700173
David Stevense5a7b642017-05-22 13:18:23 -0700174 // The display to launch the activity onto, barring any strong reason to do otherwise.
175 private int mPreferredDisplayId;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800176
Louis Changcdec0802019-11-11 11:45:07 +0800177 private Task mInTask;
Louis Chang07b13002019-11-27 22:08:37 +0800178 @VisibleForTesting
179 boolean mAddingToTask;
Louis Changcdec0802019-11-11 11:45:07 +0800180 private Task mReuseTask;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800181
182 private ActivityInfo mNewTaskInfo;
183 private Intent mNewTaskIntent;
184 private ActivityStack mSourceStack;
185 private ActivityStack mTargetStack;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800186 private boolean mMovedToFront;
187 private boolean mNoAnimation;
188 private boolean mKeepCurTransition;
Jorim Jaggic875ae72016-04-26 22:41:06 -0700189 private boolean mAvoidMoveToFront;
Winson Chunge219ae12019-07-18 13:43:23 -0700190 private boolean mFrozeTaskList;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800191
Bryce Lee325e09682017-10-05 17:20:25 -0700192 // We must track when we deliver the new intent since multiple code paths invoke
193 // {@link #deliverNewIntent}. This is due to early returns in the code path. This flag is used
194 // inside {@link #deliverNewIntent} to suppress duplicate requests and ensure the intent is
195 // delivered at most once.
196 private boolean mIntentDelivered;
197
Wale Ogunwale01d66562015-12-29 08:19:19 -0800198 private IVoiceInteractionSession mVoiceSession;
199 private IVoiceInteractor mVoiceInteractor;
200
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700201 // Last activity record we attempted to start
Louis Chang54fbb052019-10-16 17:10:17 +0800202 private ActivityRecord mLastStartActivityRecord;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700203 // The result of the last activity we attempted to start.
204 private int mLastStartActivityResult;
205 // Time in milli seconds we attempted to start the last activity.
206 private long mLastStartActivityTimeMs;
207 // The reason we were trying to start the last activity
208 private String mLastStartReason;
Wale Ogunwale59bcba62017-06-16 12:42:51 -0700209
Bryce Lee4c9a5972017-12-01 22:14:24 -0800210 /*
211 * Request details provided through setter methods. Should be reset after {@link #execute()}
212 * to avoid unnecessarily retaining parameters. Note that the request is ignored when
213 * {@link #startResolvedActivity} is invoked directly.
214 */
Louis Chang54fbb052019-10-16 17:10:17 +0800215 @VisibleForTesting
216 Request mRequest = new Request();
Bryce Lee4c9a5972017-12-01 22:14:24 -0800217
Bryce Leed3624e12017-11-30 08:51:45 -0800218 /**
219 * An interface that to provide {@link ActivityStarter} instances to the controller. This is
220 * used by tests to inject their own starter implementations for verification purposes.
221 */
222 @VisibleForTesting
223 interface Factory {
224 /**
Bryce Lee4c9a5972017-12-01 22:14:24 -0800225 * Sets the {@link ActivityStartController} to be passed to {@link ActivityStarter}.
226 */
227 void setController(ActivityStartController controller);
228
229 /**
Bryce Leed3624e12017-11-30 08:51:45 -0800230 * Generates an {@link ActivityStarter} that is ready to handle a new start request.
231 * @param controller The {@link ActivityStartController} which the starter who will own
232 * this instance.
233 * @return an {@link ActivityStarter}
234 */
Bryce Leedaa91e42017-12-06 14:13:01 -0800235 ActivityStarter obtain();
236
237 /**
238 * Recycles a starter for reuse.
239 */
240 void recycle(ActivityStarter starter);
Wale Ogunwale01d66562015-12-29 08:19:19 -0800241 }
242
Bryce Leed3624e12017-11-30 08:51:45 -0800243 /**
244 * Default implementation of {@link StarterFactory}.
245 */
246 static class DefaultFactory implements Factory {
Bryce Leedaa91e42017-12-06 14:13:01 -0800247 /**
248 * The maximum count of starters that should be active at one time:
249 * 1. last ran starter (for logging and post activity processing)
250 * 2. current running starter
251 * 3. starter from re-entry in (2)
252 */
253 private final int MAX_STARTER_COUNT = 3;
254
Bryce Lee4c9a5972017-12-01 22:14:24 -0800255 private ActivityStartController mController;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700256 private ActivityTaskManagerService mService;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800257 private ActivityStackSupervisor mSupervisor;
258 private ActivityStartInterceptor mInterceptor;
259
Bryce Leedaa91e42017-12-06 14:13:01 -0800260 private SynchronizedPool<ActivityStarter> mStarterPool =
261 new SynchronizedPool<>(MAX_STARTER_COUNT);
262
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700263 DefaultFactory(ActivityTaskManagerService service,
Bryce Lee4c9a5972017-12-01 22:14:24 -0800264 ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
265 mService = service;
266 mSupervisor = supervisor;
267 mInterceptor = interceptor;
Bryce Leed3624e12017-11-30 08:51:45 -0800268 }
Bryce Lee4c9a5972017-12-01 22:14:24 -0800269
270 @Override
271 public void setController(ActivityStartController controller) {
272 mController = controller;
273 }
274
275 @Override
Bryce Leedaa91e42017-12-06 14:13:01 -0800276 public ActivityStarter obtain() {
277 ActivityStarter starter = mStarterPool.acquire();
278
279 if (starter == null) {
280 starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
281 }
282
283 return starter;
284 }
285
286 @Override
287 public void recycle(ActivityStarter starter) {
288 starter.reset(true /* clearRequest*/);
289 mStarterPool.release(starter);
Bryce Lee4c9a5972017-12-01 22:14:24 -0800290 }
291 }
292
293 /**
294 * Container for capturing initial start request details. This information is NOT reset until
295 * the {@link ActivityStarter} is recycled, allowing for multiple invocations with the same
296 * parameters.
297 *
298 * TODO(b/64750076): Investigate consolidating member variables of {@link ActivityStarter} with
299 * the request object. Note that some member variables are referenced in
300 * {@link #dump(PrintWriter, String)} and therefore cannot be cleared immediately after
301 * execution.
302 */
Louis Chang54fbb052019-10-16 17:10:17 +0800303 @VisibleForTesting
304 static class Request {
Bryce Lee4c9a5972017-12-01 22:14:24 -0800305 private static final int DEFAULT_CALLING_UID = -1;
306 private static final int DEFAULT_CALLING_PID = 0;
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000307 static final int DEFAULT_REAL_CALLING_UID = -1;
308 static final int DEFAULT_REAL_CALLING_PID = 0;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800309
310 IApplicationThread caller;
311 Intent intent;
Louis Chang54fbb052019-10-16 17:10:17 +0800312 // A copy of the original requested intent, in case for ephemeral app launch.
Bryce Lee4c9a5972017-12-01 22:14:24 -0800313 Intent ephemeralIntent;
314 String resolvedType;
315 ActivityInfo activityInfo;
316 ResolveInfo resolveInfo;
317 IVoiceInteractionSession voiceSession;
318 IVoiceInteractor voiceInteractor;
319 IBinder resultTo;
320 String resultWho;
321 int requestCode;
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000322 int callingPid = DEFAULT_CALLING_PID;
323 int callingUid = DEFAULT_CALLING_UID;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800324 String callingPackage;
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000325 int realCallingPid = DEFAULT_REAL_CALLING_PID;
326 int realCallingUid = DEFAULT_REAL_CALLING_UID;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800327 int startFlags;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100328 SafeActivityOptions activityOptions;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800329 boolean ignoreTargetSecurity;
330 boolean componentSpecified;
Winson Chunge2d72172018-01-25 17:46:20 +0000331 boolean avoidMoveToFront;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800332 ActivityRecord[] outActivity;
Louis Changcdec0802019-11-11 11:45:07 +0800333 Task inTask;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800334 String reason;
335 ProfilerInfo profilerInfo;
336 Configuration globalConfig;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800337 int userId;
338 WaitResult waitResult;
Patrick Baumann31426b22018-05-21 13:46:40 -0700339 int filterCallingUid;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100340 PendingIntentRecord originatingPendingIntent;
Michal Karpinskiac116df2018-12-10 17:51:42 +0000341 boolean allowBackgroundActivityStart;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800342
343 /**
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200344 * If set to {@code true}, allows this activity start to look into
345 * {@link PendingRemoteAnimationRegistry}
346 */
347 boolean allowPendingRemoteAnimationRegistryLookup;
348
349 /**
Bryce Leea3cd8e02018-01-09 15:44:24 -0800350 * Ensure constructed request matches reset instance.
351 */
352 Request() {
353 reset();
354 }
355
356 /**
Bryce Leedaa91e42017-12-06 14:13:01 -0800357 * Sets values back to the initial state, clearing any held references.
358 */
359 void reset() {
360 caller = null;
361 intent = null;
362 ephemeralIntent = null;
363 resolvedType = null;
364 activityInfo = null;
365 resolveInfo = null;
366 voiceSession = null;
367 voiceInteractor = null;
368 resultTo = null;
369 resultWho = null;
370 requestCode = 0;
Bryce Leea3cd8e02018-01-09 15:44:24 -0800371 callingPid = DEFAULT_CALLING_PID;
372 callingUid = DEFAULT_CALLING_UID;
Bryce Leedaa91e42017-12-06 14:13:01 -0800373 callingPackage = null;
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000374 realCallingPid = DEFAULT_REAL_CALLING_PID;
375 realCallingUid = DEFAULT_REAL_CALLING_UID;
Bryce Leedaa91e42017-12-06 14:13:01 -0800376 startFlags = 0;
377 activityOptions = null;
378 ignoreTargetSecurity = false;
379 componentSpecified = false;
380 outActivity = null;
381 inTask = null;
382 reason = null;
383 profilerInfo = null;
384 globalConfig = null;
Bryce Leedaa91e42017-12-06 14:13:01 -0800385 userId = 0;
386 waitResult = null;
Winson Chunge2d72172018-01-25 17:46:20 +0000387 avoidMoveToFront = false;
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200388 allowPendingRemoteAnimationRegistryLookup = true;
Patrick Baumann31426b22018-05-21 13:46:40 -0700389 filterCallingUid = UserHandle.USER_NULL;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100390 originatingPendingIntent = null;
Michal Karpinskiac116df2018-12-10 17:51:42 +0000391 allowBackgroundActivityStart = false;
Bryce Leedaa91e42017-12-06 14:13:01 -0800392 }
393
394 /**
395 * Adopts all values from passed in request.
396 */
397 void set(Request request) {
398 caller = request.caller;
399 intent = request.intent;
400 ephemeralIntent = request.ephemeralIntent;
401 resolvedType = request.resolvedType;
402 activityInfo = request.activityInfo;
403 resolveInfo = request.resolveInfo;
404 voiceSession = request.voiceSession;
405 voiceInteractor = request.voiceInteractor;
406 resultTo = request.resultTo;
407 resultWho = request.resultWho;
408 requestCode = request.requestCode;
409 callingPid = request.callingPid;
410 callingUid = request.callingUid;
411 callingPackage = request.callingPackage;
412 realCallingPid = request.realCallingPid;
413 realCallingUid = request.realCallingUid;
414 startFlags = request.startFlags;
415 activityOptions = request.activityOptions;
416 ignoreTargetSecurity = request.ignoreTargetSecurity;
417 componentSpecified = request.componentSpecified;
418 outActivity = request.outActivity;
419 inTask = request.inTask;
420 reason = request.reason;
421 profilerInfo = request.profilerInfo;
422 globalConfig = request.globalConfig;
Bryce Leedaa91e42017-12-06 14:13:01 -0800423 userId = request.userId;
424 waitResult = request.waitResult;
Winson Chunge2d72172018-01-25 17:46:20 +0000425 avoidMoveToFront = request.avoidMoveToFront;
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200426 allowPendingRemoteAnimationRegistryLookup
427 = request.allowPendingRemoteAnimationRegistryLookup;
Patrick Baumann31426b22018-05-21 13:46:40 -0700428 filterCallingUid = request.filterCallingUid;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100429 originatingPendingIntent = request.originatingPendingIntent;
Michal Karpinskiac116df2018-12-10 17:51:42 +0000430 allowBackgroundActivityStart = request.allowBackgroundActivityStart;
Bryce Leedaa91e42017-12-06 14:13:01 -0800431 }
Louis Chang54fbb052019-10-16 17:10:17 +0800432
433 /**
434 * Resolve activity from the given intent for this launch.
435 */
436 void resolveActivity(ActivityStackSupervisor supervisor) {
437 if (realCallingPid == Request.DEFAULT_REAL_CALLING_PID) {
438 realCallingPid = Binder.getCallingPid();
439 }
440 if (realCallingUid == Request.DEFAULT_REAL_CALLING_UID) {
441 realCallingUid = Binder.getCallingUid();
442 }
443
444 if (callingUid >= 0) {
445 callingPid = -1;
446 } else if (caller == null) {
447 callingPid = realCallingPid;
448 callingUid = realCallingUid;
449 } else {
450 callingPid = callingUid = -1;
451 }
452
453 // Save a copy in case ephemeral needs it
454 ephemeralIntent = new Intent(intent);
455 // Don't modify the client's object!
456 intent = new Intent(intent);
457 if (intent.getComponent() != null
458 && !(Intent.ACTION_VIEW.equals(intent.getAction()) && intent.getData() == null)
459 && !Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE.equals(intent.getAction())
460 && !Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE.equals(intent.getAction())
461 && supervisor.mService.getPackageManagerInternalLocked()
462 .isInstantAppInstallerComponent(intent.getComponent())) {
463 // Intercept intents targeted directly to the ephemeral installer the ephemeral
464 // installer should never be started with a raw Intent; instead adjust the intent
465 // so it looks like a "normal" instant app launch.
466 intent.setComponent(null /* component */);
467 }
468
469 resolveInfo = supervisor.resolveIntent(intent, resolvedType, userId,
470 0 /* matchFlags */,
471 computeResolveFilterUid(callingUid, realCallingUid, filterCallingUid));
472 if (resolveInfo == null) {
473 final UserInfo userInfo = supervisor.getUserInfo(userId);
474 if (userInfo != null && userInfo.isManagedProfile()) {
475 // Special case for managed profiles, if attempting to launch non-cryto aware
476 // app in a locked managed profile from an unlocked parent allow it to resolve
477 // as user will be sent via confirm credentials to unlock the profile.
478 final UserManager userManager = UserManager.get(supervisor.mService.mContext);
479 boolean profileLockedAndParentUnlockingOrUnlocked = false;
480 final long token = Binder.clearCallingIdentity();
481 try {
482 final UserInfo parent = userManager.getProfileParent(userId);
483 profileLockedAndParentUnlockingOrUnlocked = (parent != null)
484 && userManager.isUserUnlockingOrUnlocked(parent.id)
485 && !userManager.isUserUnlockingOrUnlocked(userId);
486 } finally {
487 Binder.restoreCallingIdentity(token);
488 }
489 if (profileLockedAndParentUnlockingOrUnlocked) {
490 resolveInfo = supervisor.resolveIntent(intent, resolvedType, userId,
491 PackageManager.MATCH_DIRECT_BOOT_AWARE
492 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
493 computeResolveFilterUid(callingUid, realCallingUid,
494 filterCallingUid));
495 }
496 }
497 }
498
499 // Collect information about the target of the Intent.
500 activityInfo = supervisor.resolveActivity(intent, resolveInfo, startFlags,
501 profilerInfo);
502 }
Bryce Leed3624e12017-11-30 08:51:45 -0800503 }
504
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700505 ActivityStarter(ActivityStartController controller, ActivityTaskManagerService service,
Bryce Leed3624e12017-11-30 08:51:45 -0800506 ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
507 mController = controller;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800508 mService = service;
Louis Chang149d5c82019-12-30 09:47:39 +0800509 mRootWindowContainer = service.mRootWindowContainer;
Bryce Leed3624e12017-11-30 08:51:45 -0800510 mSupervisor = supervisor;
511 mInterceptor = interceptor;
Bryce Leedaa91e42017-12-06 14:13:01 -0800512 reset(true);
513 }
514
515 /**
516 * Effectively duplicates the starter passed in. All state and request values will be
517 * mirrored.
518 * @param starter
519 */
520 void set(ActivityStarter starter) {
521 mStartActivity = starter.mStartActivity;
522 mIntent = starter.mIntent;
523 mCallingUid = starter.mCallingUid;
524 mOptions = starter.mOptions;
Ricky Waib147fa12019-04-25 16:08:30 +0100525 mRestrictedBgActivity = starter.mRestrictedBgActivity;
Bryce Leedaa91e42017-12-06 14:13:01 -0800526
527 mLaunchTaskBehind = starter.mLaunchTaskBehind;
528 mLaunchFlags = starter.mLaunchFlags;
529 mLaunchMode = starter.mLaunchMode;
530
Bryce Leeec55eb02017-12-05 20:51:27 -0800531 mLaunchParams.set(starter.mLaunchParams);
Bryce Leedaa91e42017-12-06 14:13:01 -0800532
533 mNotTop = starter.mNotTop;
534 mDoResume = starter.mDoResume;
535 mStartFlags = starter.mStartFlags;
536 mSourceRecord = starter.mSourceRecord;
537 mPreferredDisplayId = starter.mPreferredDisplayId;
538
539 mInTask = starter.mInTask;
540 mAddingToTask = starter.mAddingToTask;
541 mReuseTask = starter.mReuseTask;
542
543 mNewTaskInfo = starter.mNewTaskInfo;
544 mNewTaskIntent = starter.mNewTaskIntent;
545 mSourceStack = starter.mSourceStack;
546
547 mTargetStack = starter.mTargetStack;
548 mMovedToFront = starter.mMovedToFront;
549 mNoAnimation = starter.mNoAnimation;
550 mKeepCurTransition = starter.mKeepCurTransition;
551 mAvoidMoveToFront = starter.mAvoidMoveToFront;
Winson Chunge219ae12019-07-18 13:43:23 -0700552 mFrozeTaskList = starter.mFrozeTaskList;
Bryce Leedaa91e42017-12-06 14:13:01 -0800553
554 mVoiceSession = starter.mVoiceSession;
555 mVoiceInteractor = starter.mVoiceInteractor;
556
557 mIntentDelivered = starter.mIntentDelivered;
558
559 mRequest.set(starter.mRequest);
Bryce Leed3624e12017-11-30 08:51:45 -0800560 }
561
Bryce Lee4c9a5972017-12-01 22:14:24 -0800562 boolean relatedToPackage(String packageName) {
Louis Chang54fbb052019-10-16 17:10:17 +0800563 return (mLastStartActivityRecord != null
564 && packageName.equals(mLastStartActivityRecord.packageName))
Bryce Lee4c9a5972017-12-01 22:14:24 -0800565 || (mStartActivity != null && packageName.equals(mStartActivity.packageName));
566 }
567
568 /**
Louis Chang54fbb052019-10-16 17:10:17 +0800569 * Starts an activity based on the provided {@link ActivityRecord} and environment parameters.
570 * Note that this method is called internally as well as part of {@link #executeRequest}.
571 */
572 void startResolvedActivity(final ActivityRecord r, ActivityRecord sourceRecord,
573 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
Louis Changcdec0802019-11-11 11:45:07 +0800574 int startFlags, boolean doResume, ActivityOptions options, Task inTask) {
Louis Chang54fbb052019-10-16 17:10:17 +0800575 try {
Riddle Hsufd66d4d2019-11-14 10:35:55 +0800576 final LaunchingState launchingState = mSupervisor.getActivityMetricsLogger()
577 .notifyActivityLaunching(r.intent, r.resultTo);
Louis Chang54fbb052019-10-16 17:10:17 +0800578 mLastStartReason = "startResolvedActivity";
579 mLastStartActivityTimeMs = System.currentTimeMillis();
580 mLastStartActivityRecord = r;
581 mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
582 voiceInteractor, startFlags, doResume, options, inTask,
583 false /* restrictedBgActivity */);
Riddle Hsufd66d4d2019-11-14 10:35:55 +0800584 mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState,
585 mLastStartActivityResult, mLastStartActivityRecord);
Louis Chang54fbb052019-10-16 17:10:17 +0800586 } finally {
587 onExecutionComplete();
588 }
589 }
590
591 /**
592 * Resolve necessary information according the request parameters provided earlier, and execute
593 * the request which begin the journey of starting an activity.
Bryce Lee4c9a5972017-12-01 22:14:24 -0800594 * @return The starter result.
595 */
596 int execute() {
Bryce Leedaa91e42017-12-06 14:13:01 -0800597 try {
Louis Chang54fbb052019-10-16 17:10:17 +0800598 // Refuse possible leaked file descriptors
599 if (mRequest.intent != null && mRequest.intent.hasFileDescriptors()) {
600 throw new IllegalArgumentException("File descriptors passed in Intent");
601 }
602
Riddle Hsufd66d4d2019-11-14 10:35:55 +0800603 final LaunchingState launchingState;
604 synchronized (mService.mGlobalLock) {
605 final ActivityRecord caller = ActivityRecord.forTokenLocked(mRequest.resultTo);
606 launchingState = mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(
607 mRequest.intent, caller);
608 }
Louis Chang54fbb052019-10-16 17:10:17 +0800609
Riddle Hsufd66d4d2019-11-14 10:35:55 +0800610 // Do not lock the resolving to avoid potential deadlock.
Louis Chang54fbb052019-10-16 17:10:17 +0800611 if (mRequest.activityInfo == null) {
612 mRequest.resolveActivity(mSupervisor);
613 }
614
615 int res;
616 synchronized (mService.mGlobalLock) {
Louis Chang149d5c82019-12-30 09:47:39 +0800617 final ActivityStack stack = mRootWindowContainer.getTopDisplayFocusedStack();
Louis Chang54fbb052019-10-16 17:10:17 +0800618 stack.mConfigWillChange = mRequest.globalConfig != null
619 && mService.getGlobalConfiguration().diff(mRequest.globalConfig) != 0;
620 if (DEBUG_CONFIGURATION) {
621 Slog.v(TAG_CONFIGURATION, "Starting activity when config will change = "
622 + stack.mConfigWillChange);
623 }
624
625 final long origId = Binder.clearCallingIdentity();
626
627 res = resolveToHeavyWeightSwitcherIfNeeded();
628 if (res != START_SUCCESS) {
629 return res;
630 }
631 res = executeRequest(mRequest);
632
633 Binder.restoreCallingIdentity(origId);
634
635 if (stack.mConfigWillChange) {
636 // If the caller also wants to switch to a new configuration, do so now.
637 // This allows a clean switch, as we are waiting for the current activity
638 // to pause (so we will not destroy it), and have not yet started the
639 // next activity.
640 mService.mAmInternal.enforceCallingPermission(
641 android.Manifest.permission.CHANGE_CONFIGURATION,
642 "updateConfiguration()");
643 stack.mConfigWillChange = false;
644 if (DEBUG_CONFIGURATION) {
645 Slog.v(TAG_CONFIGURATION,
646 "Updating to new configuration after starting activity.");
647 }
648 mService.updateConfigurationLocked(mRequest.globalConfig, null, false);
649 }
650
651 // Notify ActivityMetricsLogger that the activity has launched.
652 // ActivityMetricsLogger will then wait for the windows to be drawn and populate
653 // WaitResult.
Riddle Hsufd66d4d2019-11-14 10:35:55 +0800654 mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState, res,
Louis Chang54fbb052019-10-16 17:10:17 +0800655 mLastStartActivityRecord);
656 return getExternalResult(mRequest.waitResult == null ? res
657 : waitForResult(res, mLastStartActivityRecord));
Bryce Leedaa91e42017-12-06 14:13:01 -0800658 }
659 } finally {
660 onExecutionComplete();
661 }
662 }
663
664 /**
Louis Chang54fbb052019-10-16 17:10:17 +0800665 * Updates the request to heavy-weight switch if this is a heavy-weight process while there
666 * already have another, different heavy-weight process running.
Bryce Leedaa91e42017-12-06 14:13:01 -0800667 */
Louis Chang54fbb052019-10-16 17:10:17 +0800668 private int resolveToHeavyWeightSwitcherIfNeeded() {
669 if (mRequest.activityInfo == null || !mService.mHasHeavyWeightFeature
670 || (mRequest.activityInfo.applicationInfo.privateFlags
671 & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) == 0) {
672 return START_SUCCESS;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700673 }
Bryce Leef9d49542017-06-26 16:27:32 -0700674
Louis Chang54fbb052019-10-16 17:10:17 +0800675 if (!mRequest.activityInfo.processName.equals(
676 mRequest.activityInfo.applicationInfo.packageName)) {
677 return START_SUCCESS;
678 }
Bryce Lee93e7f792017-10-25 15:54:55 -0700679
Louis Chang54fbb052019-10-16 17:10:17 +0800680 final WindowProcessController heavy = mService.mHeavyWeightProcess;
681 if (heavy == null || (heavy.mInfo.uid == mRequest.activityInfo.applicationInfo.uid
682 && heavy.mName.equals(mRequest.activityInfo.processName))) {
683 return START_SUCCESS;
684 }
685
686 int appCallingUid = mRequest.callingUid;
687 if (mRequest.caller != null) {
688 WindowProcessController callerApp = mService.getProcessController(mRequest.caller);
689 if (callerApp != null) {
690 appCallingUid = callerApp.mInfo.uid;
691 } else {
692 Slog.w(TAG, "Unable to find app for caller " + mRequest.caller + " (pid="
693 + mRequest.callingPid + ") when starting: " + mRequest.intent.toString());
694 SafeActivityOptions.abort(mRequest.activityOptions);
695 return ActivityManager.START_PERMISSION_DENIED;
696 }
697 }
698
699 final IIntentSender target = mService.getIntentSenderLocked(
700 ActivityManager.INTENT_SENDER_ACTIVITY, "android" /* packageName */, appCallingUid,
701 mRequest.userId, null /* token */, null /* resultWho*/, 0 /* requestCode*/,
702 new Intent[] { mRequest.intent }, new String[] { mRequest.resolvedType },
703 PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT,
704 null /* bOptions */);
705
706 final Intent newIntent = new Intent();
707 if (mRequest.requestCode >= 0) {
708 // Caller is requesting a result.
709 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
710 }
711 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT, new IntentSender(target));
712 heavy.updateIntentForHeavyWeightActivity(newIntent);
713 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
714 mRequest.activityInfo.packageName);
715 newIntent.setFlags(mRequest.intent.getFlags());
716 newIntent.setClassName("android" /* packageName */,
717 HeavyWeightSwitcherActivity.class.getName());
718 mRequest.intent = newIntent;
719 mRequest.resolvedType = null;
720 mRequest.caller = null;
721 mRequest.callingUid = Binder.getCallingUid();
722 mRequest.callingPid = Binder.getCallingPid();
723 mRequest.componentSpecified = true;
724 mRequest.resolveInfo = mSupervisor.resolveIntent(mRequest.intent, null /* resolvedType */,
725 mRequest.userId, 0 /* matchFlags */,
726 computeResolveFilterUid(mRequest.callingUid, mRequest.realCallingUid,
727 mRequest.filterCallingUid));
728 mRequest.activityInfo =
729 mRequest.resolveInfo != null ? mRequest.resolveInfo.activityInfo : null;
730 if (mRequest.activityInfo != null) {
731 mRequest.activityInfo = mService.mAmInternal.getActivityInfoForUser(
732 mRequest.activityInfo, mRequest.userId);
733 }
734
735 return START_SUCCESS;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700736 }
737
Bryce Leedaa91e42017-12-06 14:13:01 -0800738 /**
Louis Chang54fbb052019-10-16 17:10:17 +0800739 * Wait for activity launch completes.
Bryce Leedaa91e42017-12-06 14:13:01 -0800740 */
Louis Chang54fbb052019-10-16 17:10:17 +0800741 private int waitForResult(int res, ActivityRecord r) {
742 mRequest.waitResult.result = res;
743 switch(res) {
744 case START_SUCCESS: {
745 mSupervisor.mWaitingActivityLaunched.add(mRequest.waitResult);
746 do {
747 try {
748 mService.mGlobalLock.wait();
749 } catch (InterruptedException e) {
750 }
751 } while (mRequest.waitResult.result != START_TASK_TO_FRONT
752 && !mRequest.waitResult.timeout && mRequest.waitResult.who == null);
753 if (mRequest.waitResult.result == START_TASK_TO_FRONT) {
754 res = START_TASK_TO_FRONT;
755 }
756 break;
757 }
758 case START_DELIVERED_TO_TOP: {
759 mRequest.waitResult.timeout = false;
760 mRequest.waitResult.who = r.mActivityComponent;
761 mRequest.waitResult.totalTime = 0;
762 break;
763 }
764 case START_TASK_TO_FRONT: {
765 mRequest.waitResult.launchState =
766 r.attachedToProcess() ? LAUNCH_STATE_HOT : LAUNCH_STATE_COLD;
767 // ActivityRecord may represent a different activity, but it should not be
768 // in the resumed state.
769 if (r.nowVisible && r.isState(RESUMED)) {
770 mRequest.waitResult.timeout = false;
771 mRequest.waitResult.who = r.mActivityComponent;
772 mRequest.waitResult.totalTime = 0;
773 } else {
Riddle Hsuc48c8912019-10-31 13:34:27 +0800774 mSupervisor.waitActivityVisible(r.mActivityComponent, mRequest.waitResult);
Louis Chang54fbb052019-10-16 17:10:17 +0800775 // Note: the timeout variable is not currently not ever set.
776 do {
777 try {
778 mService.mGlobalLock.wait();
779 } catch (InterruptedException e) {
780 }
781 } while (!mRequest.waitResult.timeout && mRequest.waitResult.who == null);
782 }
783 break;
784 }
785 }
786 return res;
Bryce Leedaa91e42017-12-06 14:13:01 -0800787 }
788
Louis Chang54fbb052019-10-16 17:10:17 +0800789 /**
790 * Executing activity start request and starts the journey of starting an activity. Here
791 * begins with performing several preliminary checks. The normally activity launch flow will
792 * go through {@link #startActivityUnchecked} to {@link #startActivityInner}.
793 */
794 private int executeRequest(Request request) {
795 if (TextUtils.isEmpty(request.reason)) {
796 throw new IllegalArgumentException("Need to specify a reason.");
797 }
798 mLastStartReason = request.reason;
799 mLastStartActivityTimeMs = System.currentTimeMillis();
800 mLastStartActivityRecord = null;
801
802 final IApplicationThread caller = request.caller;
803 Intent intent = request.intent;
804 String resolvedType = request.resolvedType;
805 ActivityInfo aInfo = request.activityInfo;
806 ResolveInfo rInfo = request.resolveInfo;
807 final IVoiceInteractionSession voiceSession = request.voiceSession;
808 final IBinder resultTo = request.resultTo;
809 String resultWho = request.resultWho;
810 int requestCode = request.requestCode;
811 int callingPid = request.callingPid;
812 int callingUid = request.callingUid;
813 String callingPackage = request.callingPackage;
814 final int realCallingPid = request.realCallingPid;
815 final int realCallingUid = request.realCallingUid;
816 final int startFlags = request.startFlags;
817 final SafeActivityOptions options = request.activityOptions;
Louis Changcdec0802019-11-11 11:45:07 +0800818 Task inTask = request.inTask;
Louis Chang54fbb052019-10-16 17:10:17 +0800819
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800820 int err = ActivityManager.START_SUCCESS;
Chad Brubaker06068612017-04-06 09:43:47 -0700821 // Pull the optional Ephemeral Installer-only bundle out of the options early.
Louis Chang54fbb052019-10-16 17:10:17 +0800822 final Bundle verificationBundle =
823 options != null ? options.popAppVerificationBundle() : null;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800824
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700825 WindowProcessController callerApp = null;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800826 if (caller != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700827 callerApp = mService.getProcessController(caller);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800828 if (callerApp != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700829 callingPid = callerApp.getPid();
830 callingUid = callerApp.mInfo.uid;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800831 } else {
Louis Chang54fbb052019-10-16 17:10:17 +0800832 Slog.w(TAG, "Unable to find app for caller " + caller + " (pid=" + callingPid
833 + ") when starting: " + intent.toString());
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800834 err = ActivityManager.START_PERMISSION_DENIED;
835 }
836 }
837
Bryce Lee93e7f792017-10-25 15:54:55 -0700838 final int userId = aInfo != null && aInfo.applicationInfo != null
839 ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800840 if (err == ActivityManager.START_SUCCESS) {
841 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
Andrii Kulian03c403d2016-11-11 11:14:12 -0800842 + "} from uid " + callingUid);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800843 }
844
845 ActivityRecord sourceRecord = null;
846 ActivityRecord resultRecord = null;
847 if (resultTo != null) {
Louis Chang149d5c82019-12-30 09:47:39 +0800848 sourceRecord = mRootWindowContainer.isInAnyStack(resultTo);
Louis Chang54fbb052019-10-16 17:10:17 +0800849 if (DEBUG_RESULTS) {
850 Slog.v(TAG_RESULTS, "Will send result to " + resultTo + " " + sourceRecord);
851 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800852 if (sourceRecord != null) {
853 if (requestCode >= 0 && !sourceRecord.finishing) {
854 resultRecord = sourceRecord;
855 }
856 }
857 }
858
859 final int launchFlags = intent.getFlags();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800860 if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
Louis Chang54fbb052019-10-16 17:10:17 +0800861 // Transfer the result target from the source activity to the new one being started,
862 // including any failures.
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800863 if (requestCode >= 0) {
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100864 SafeActivityOptions.abort(options);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800865 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
866 }
867 resultRecord = sourceRecord.resultTo;
868 if (resultRecord != null && !resultRecord.isInStackLocked()) {
869 resultRecord = null;
870 }
871 resultWho = sourceRecord.resultWho;
872 requestCode = sourceRecord.requestCode;
873 sourceRecord.resultTo = null;
874 if (resultRecord != null) {
875 resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
876 }
877 if (sourceRecord.launchedFromUid == callingUid) {
Louis Chang54fbb052019-10-16 17:10:17 +0800878 // The new activity is being launched from the same uid as the previous activity
879 // in the flow, and asking to forward its result back to the previous. In this
880 // case the activity is serving as a trampoline between the two, so we also want
881 // to update its launchedFromPackage to be the same as the previous activity.
882 // Note that this is safe, since we know these two packages come from the same
883 // uid; the caller could just as well have supplied that same package name itself
884 // . This specifially deals with the case of an intent picker/chooser being
885 // launched in the app flow to redirect to an activity picked by the user, where
886 // we want the final activity to consider it to have been launched by the
887 // previous app activity.
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800888 callingPackage = sourceRecord.launchedFromPackage;
889 }
890 }
891
892 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
893 // We couldn't find a class that can handle the given Intent.
894 // That's the end of that!
895 err = ActivityManager.START_INTENT_NOT_RESOLVED;
896 }
897
898 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
899 // We couldn't find the specific class specified in the Intent.
900 // Also the end of the line.
901 err = ActivityManager.START_CLASS_NOT_FOUND;
902 }
903
904 if (err == ActivityManager.START_SUCCESS && sourceRecord != null
Louis Changcdec0802019-11-11 11:45:07 +0800905 && sourceRecord.getTask().voiceSession != null) {
Louis Chang54fbb052019-10-16 17:10:17 +0800906 // If this activity is being launched as part of a voice session, we need to ensure
907 // that it is safe to do so. If the upcoming activity will also be part of the voice
908 // session, we can only launch it if it has explicitly said it supports the VOICE
909 // category, or it is a part of the calling app.
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800910 if ((launchFlags & FLAG_ACTIVITY_NEW_TASK) == 0
911 && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
912 try {
913 intent.addCategory(Intent.CATEGORY_VOICE);
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700914 if (!mService.getPackageManager().activitySupportsIntent(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800915 intent.getComponent(), intent, resolvedType)) {
Louis Chang54fbb052019-10-16 17:10:17 +0800916 Slog.w(TAG, "Activity being started in current voice task does not support "
917 + "voice: " + intent);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800918 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
919 }
920 } catch (RemoteException e) {
921 Slog.w(TAG, "Failure checking voice capabilities", e);
922 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
923 }
924 }
925 }
926
927 if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
928 // If the caller is starting a new voice session, just make sure the target
929 // is actually allowing it to run this way.
930 try {
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700931 if (!mService.getPackageManager().activitySupportsIntent(intent.getComponent(),
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800932 intent, resolvedType)) {
933 Slog.w(TAG,
Louis Chang54fbb052019-10-16 17:10:17 +0800934 "Activity being started in new voice task does not support: " + intent);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800935 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
936 }
937 } catch (RemoteException e) {
938 Slog.w(TAG, "Failure checking voice capabilities", e);
939 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
940 }
941 }
942
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800943 final ActivityStack resultStack = resultRecord == null
944 ? null : resultRecord.getActivityStack();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800945
Wale Ogunwale01d66562015-12-29 08:19:19 -0800946 if (err != START_SUCCESS) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800947 if (resultRecord != null) {
Andrii Kulian79d67982019-08-19 11:56:16 -0700948 resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED,
949 null /* data */);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800950 }
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100951 SafeActivityOptions.abort(options);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800952 return err;
953 }
954
955 boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
Louis Chang54fbb052019-10-16 17:10:17 +0800956 requestCode, callingPid, callingUid, callingPackage, request.ignoreTargetSecurity,
Winson Chungc9804e72018-05-15 11:01:44 -0700957 inTask != null, callerApp, resultRecord, resultStack);
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700958 abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800959 callingPid, resolvedType, aInfo.applicationInfo);
Hai Zhangf4da9be2019-05-01 13:46:06 +0800960 abort |= !mService.getPermissionPolicyInternal().checkStartActivity(intent, callingUid,
961 callingPackage);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800962
Ricky Waib147fa12019-04-25 16:08:30 +0100963 boolean restrictedBgActivity = false;
Michal Karpinski8596ded2018-11-14 14:43:48 +0000964 if (!abort) {
Michal Karpinski4fd5b842019-01-28 15:13:32 +0000965 try {
Riddle Hsu2ca561b2019-10-08 21:58:58 +0800966 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER,
Michal Karpinski4fd5b842019-01-28 15:13:32 +0000967 "shouldAbortBackgroundActivityStart");
Ricky Waib147fa12019-04-25 16:08:30 +0100968 restrictedBgActivity = shouldAbortBackgroundActivityStart(callingUid,
Ricky Waiaca8a772019-04-04 16:01:06 +0100969 callingPid, callingPackage, realCallingUid, realCallingPid, callerApp,
Louis Chang54fbb052019-10-16 17:10:17 +0800970 request.originatingPendingIntent, request.allowBackgroundActivityStart,
971 intent);
Michal Karpinski4fd5b842019-01-28 15:13:32 +0000972 } finally {
Riddle Hsu2ca561b2019-10-08 21:58:58 +0800973 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
Michal Karpinski4fd5b842019-01-28 15:13:32 +0000974 }
Michal Karpinski8596ded2018-11-14 14:43:48 +0000975 }
976
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100977 // Merge the two options bundles, while realCallerOptions takes precedence.
978 ActivityOptions checkedOptions = options != null
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700979 ? options.getOptions(intent, aInfo, callerApp, mSupervisor) : null;
Louis Chang54fbb052019-10-16 17:10:17 +0800980 if (request.allowPendingRemoteAnimationRegistryLookup) {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700981 checkedOptions = mService.getActivityStartController()
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200982 .getPendingRemoteAnimationRegistry()
983 .overrideOptionsIfNeeded(callingPackage, checkedOptions);
984 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700985 if (mService.mController != null) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800986 try {
Louis Chang54fbb052019-10-16 17:10:17 +0800987 // The Intent we give to the watcher has the extra data stripped off, since it
988 // can contain private information.
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800989 Intent watchIntent = intent.cloneFilter();
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700990 abort |= !mService.mController.activityStarting(watchIntent,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800991 aInfo.applicationInfo.packageName);
992 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700993 mService.mController = null;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800994 }
995 }
996
Rubin Xu58d25992016-01-21 17:47:13 +0000997 mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage);
Benjamin Franz563707b2017-06-29 15:06:13 +0100998 if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100999 callingUid, checkedOptions)) {
Benjamin Franz563707b2017-06-29 15:06:13 +01001000 // activity start was intercepted, e.g. because the target user is currently in quiet
1001 // mode (turn off work) or the target application is suspended
1002 intent = mInterceptor.mIntent;
1003 rInfo = mInterceptor.mRInfo;
1004 aInfo = mInterceptor.mAInfo;
1005 resolvedType = mInterceptor.mResolvedType;
1006 inTask = mInterceptor.mInTask;
1007 callingPid = mInterceptor.mCallingPid;
1008 callingUid = mInterceptor.mCallingUid;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001009 checkedOptions = mInterceptor.mActivityOptions;
Benjamin Franz563707b2017-06-29 15:06:13 +01001010 }
1011
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001012 if (abort) {
1013 if (resultRecord != null) {
Andrii Kulian79d67982019-08-19 11:56:16 -07001014 resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED,
1015 null /* data */);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001016 }
Louis Chang54fbb052019-10-16 17:10:17 +08001017 // We pretend to the caller that it was really started, but they will just get a
1018 // cancel result.
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001019 ActivityOptions.abort(checkedOptions);
Bryce Leef9d49542017-06-26 16:27:32 -07001020 return START_ABORTED;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001021 }
1022
1023 // If permissions need a review before any of the app components can run, we
1024 // launch the review activity and pass a pending intent to start the activity
1025 // we are to launching now after the review is completed.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07001026 if (aInfo != null) {
Wale Ogunwale906f9c62018-07-23 11:23:44 -07001027 if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001028 aInfo.packageName, userId)) {
Louis Chang54fbb052019-10-16 17:10:17 +08001029 final IIntentSender target = mService.getIntentSenderLocked(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001030 ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
1031 callingUid, userId, null, null, 0, new Intent[]{intent},
1032 new String[]{resolvedType}, PendingIntent.FLAG_CANCEL_CURRENT
1033 | PendingIntent.FLAG_ONE_SHOT, null);
1034
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001035 Intent newIntent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
Philip P. Moltmannc3e66d02019-01-31 15:56:18 -08001036
1037 int flags = intent.getFlags();
1038 flags |= Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
1039
1040 /*
1041 * Prevent reuse of review activity: Each app needs their own review activity. By
1042 * default activities launched with NEW_TASK or NEW_DOCUMENT try to reuse activities
1043 * with the same launch parameters (extras are ignored). Hence to avoid possible
1044 * reuse force a new activity via the MULTIPLE_TASK flag.
1045 *
1046 * Activities that are not launched with NEW_TASK or NEW_DOCUMENT are not re-used,
1047 * hence no need to add the flag in this case.
1048 */
1049 if ((flags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_NEW_DOCUMENT)) != 0) {
1050 flags |= Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
1051 }
1052 newIntent.setFlags(flags);
1053
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001054 newIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, aInfo.packageName);
1055 newIntent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target));
1056 if (resultRecord != null) {
1057 newIntent.putExtra(Intent.EXTRA_RESULT_NEEDED, true);
1058 }
1059 intent = newIntent;
1060
1061 resolvedType = null;
1062 callingUid = realCallingUid;
1063 callingPid = realCallingPid;
1064
Svet Ganovcbcbf662018-05-10 17:25:29 -07001065 rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0,
Patrick Baumann31426b22018-05-21 13:46:40 -07001066 computeResolveFilterUid(
Louis Chang54fbb052019-10-16 17:10:17 +08001067 callingUid, realCallingUid, request.filterCallingUid));
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001068 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
1069 null /*profilerInfo*/);
1070
1071 if (DEBUG_PERMISSIONS_REVIEW) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001072 final ActivityStack focusedStack =
Louis Chang149d5c82019-12-30 09:47:39 +08001073 mRootWindowContainer.getTopDisplayFocusedStack();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001074 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true,
1075 true, false) + "} from uid " + callingUid + " on display "
Wale Ogunwale0b3d2922019-12-30 08:55:07 -08001076 + (focusedStack == null ? DEFAULT_DISPLAY
1077 : focusedStack.getDisplayId()));
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001078 }
1079 }
1080 }
1081
1082 // If we have an ephemeral app, abort the process of launching the resolved intent.
1083 // Instead, launch the ephemeral installer. Once the installer is finished, it
1084 // starts either the intent we resolved here [on install error] or the ephemeral
1085 // app [on install success].
Patrick Baumanna89a1722018-02-07 15:26:52 -08001086 if (rInfo != null && rInfo.auxiliaryInfo != null) {
Louis Chang54fbb052019-10-16 17:10:17 +08001087 intent = createLaunchIntent(rInfo.auxiliaryInfo, request.ephemeralIntent,
Chad Brubaker06068612017-04-06 09:43:47 -07001088 callingPackage, verificationBundle, resolvedType, userId);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001089 resolvedType = null;
1090 callingUid = realCallingUid;
1091 callingPid = realCallingPid;
1092
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001093 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
1094 }
1095
Louis Chang54fbb052019-10-16 17:10:17 +08001096 final ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
Wale Ogunwalef6733932018-06-27 05:14:34 -07001097 callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
Louis Chang54fbb052019-10-16 17:10:17 +08001098 resultRecord, resultWho, requestCode, request.componentSpecified,
1099 voiceSession != null, mSupervisor, checkedOptions, sourceRecord);
1100 mLastStartActivityRecord = r;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001101
1102 if (r.appTimeTracker == null && sourceRecord != null) {
1103 // If the caller didn't specify an explicit time tracker, we want to continue
1104 // tracking under any it has.
1105 r.appTimeTracker = sourceRecord.appTimeTracker;
1106 }
1107
Louis Chang149d5c82019-12-30 09:47:39 +08001108 final ActivityStack stack = mRootWindowContainer.getTopDisplayFocusedStack();
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001109
1110 // If we are starting an activity that is not from the same uid as the currently resumed
1111 // one, check whether app switches are allowed.
Bryce Leec4ab62a2018-03-05 14:19:26 -08001112 if (voiceSession == null && (stack.getResumedActivity() == null
1113 || stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001114 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001115 realCallingPid, realCallingUid, "Activity start")) {
Alan Stokes07389b62019-05-20 15:22:54 +01001116 if (!(restrictedBgActivity && handleBackgroundActivityAbort(r))) {
Ricky Waib147fa12019-04-25 16:08:30 +01001117 mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00001118 sourceRecord, startFlags, stack, callerApp));
Ricky Waib147fa12019-04-25 16:08:30 +01001119 }
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001120 ActivityOptions.abort(checkedOptions);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001121 return ActivityManager.START_SWITCHES_CANCELED;
1122 }
1123 }
1124
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001125 mService.onStartActivitySetDidAppSwitch();
Bryce Leed3624e12017-11-30 08:51:45 -08001126 mController.doPendingActivityLaunches(false);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001127
Louis Chang54fbb052019-10-16 17:10:17 +08001128 mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
1129 request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
1130 restrictedBgActivity);
1131
1132 if (request.outActivity != null) {
1133 request.outActivity[0] = mLastStartActivityRecord;
1134 }
1135
Riddle Hsu7f8643a2019-12-05 14:37:30 +08001136 return mLastStartActivityResult;
Louis Chang54fbb052019-10-16 17:10:17 +08001137 }
1138
1139 /**
1140 * Return true if background activity is really aborted.
1141 *
1142 * TODO(b/131748165): Refactor the logic so we don't need to call this method everywhere.
1143 */
1144 private boolean handleBackgroundActivityAbort(ActivityRecord r) {
1145 // TODO(b/131747138): Remove toast and refactor related code in R release.
1146 final boolean abort = !mService.isBackgroundActivityStartsEnabled();
1147 if (!abort) {
1148 return false;
1149 }
1150 final ActivityRecord resultRecord = r.resultTo;
1151 final String resultWho = r.resultWho;
1152 int requestCode = r.requestCode;
1153 if (resultRecord != null) {
1154 resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED,
1155 null /* data */);
1156 }
1157 // We pretend to the caller that it was really started to make it backward compatible, but
1158 // they will just get a cancel result.
1159 ActivityOptions.abort(r.pendingOptions);
1160 return true;
1161 }
1162
1163 static int getExternalResult(int result) {
1164 // Aborted results are treated as successes externally, but we must track them internally.
1165 return result != START_ABORTED ? result : START_SUCCESS;
1166 }
1167
1168 /**
1169 * Called when execution is complete. Sets state indicating completion and proceeds with
1170 * recycling if appropriate.
1171 */
1172 private void onExecutionComplete() {
1173 mController.onExecutionComplete(this);
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -08001174 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001175
Ricky Waiaca8a772019-04-04 16:01:06 +01001176 boolean shouldAbortBackgroundActivityStart(int callingUid, int callingPid,
Michal Karpinski9cbb20b2019-02-05 17:31:50 +00001177 final String callingPackage, int realCallingUid, int realCallingPid,
1178 WindowProcessController callerApp, PendingIntentRecord originatingPendingIntent,
1179 boolean allowBackgroundActivityStart, Intent intent) {
Michal Karpinski8596ded2018-11-14 14:43:48 +00001180 // don't abort for the most important UIDs
Alan Stokes2f4a4ed2019-05-08 16:56:45 +01001181 final int callingAppId = UserHandle.getAppId(callingUid);
1182 if (callingUid == Process.ROOT_UID || callingAppId == Process.SYSTEM_UID
1183 || callingAppId == Process.NFC_UID) {
Michal Karpinski8596ded2018-11-14 14:43:48 +00001184 return false;
1185 }
Alan Stokeseea8d3e2019-04-10 17:37:25 +01001186 // don't abort if the callingUid has a visible window or is a persistent system process
Riddle Hsua0536432019-02-16 00:38:59 +08001187 final int callingUidProcState = mService.getUidState(callingUid);
Michal Karpinski4fd5b842019-01-28 15:13:32 +00001188 final boolean callingUidHasAnyVisibleWindow =
1189 mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(callingUid);
1190 final boolean isCallingUidForeground = callingUidHasAnyVisibleWindow
Amith Yamasanif235d0b2019-03-20 22:49:43 -07001191 || callingUidProcState == ActivityManager.PROCESS_STATE_TOP
1192 || callingUidProcState == ActivityManager.PROCESS_STATE_BOUND_TOP;
Alan Stokes2f4a4ed2019-05-08 16:56:45 +01001193 final boolean isCallingUidPersistentSystemProcess =
1194 callingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
Alan Stokeseea8d3e2019-04-10 17:37:25 +01001195 if (callingUidHasAnyVisibleWindow || isCallingUidPersistentSystemProcess) {
Michal Karpinski8596ded2018-11-14 14:43:48 +00001196 return false;
1197 }
Michal Karpinskiac116df2018-12-10 17:51:42 +00001198 // take realCallingUid into consideration
Michal Karpinski4fd5b842019-01-28 15:13:32 +00001199 final int realCallingUidProcState = (callingUid == realCallingUid)
1200 ? callingUidProcState
Riddle Hsua0536432019-02-16 00:38:59 +08001201 : mService.getUidState(realCallingUid);
Michal Karpinski4fd5b842019-01-28 15:13:32 +00001202 final boolean realCallingUidHasAnyVisibleWindow = (callingUid == realCallingUid)
1203 ? callingUidHasAnyVisibleWindow
1204 : mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(realCallingUid);
1205 final boolean isRealCallingUidForeground = (callingUid == realCallingUid)
1206 ? isCallingUidForeground
1207 : realCallingUidHasAnyVisibleWindow
1208 || realCallingUidProcState == ActivityManager.PROCESS_STATE_TOP;
Alan Stokes2f4a4ed2019-05-08 16:56:45 +01001209 final int realCallingAppId = UserHandle.getAppId(realCallingUid);
Michal Karpinski4fd5b842019-01-28 15:13:32 +00001210 final boolean isRealCallingUidPersistentSystemProcess = (callingUid == realCallingUid)
1211 ? isCallingUidPersistentSystemProcess
Alan Stokes2f4a4ed2019-05-08 16:56:45 +01001212 : (realCallingAppId == Process.SYSTEM_UID)
Michal Karpinski4fd5b842019-01-28 15:13:32 +00001213 || realCallingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
Michal Karpinskiac116df2018-12-10 17:51:42 +00001214 if (realCallingUid != callingUid) {
Alan Stokes6ac9efd2019-05-09 12:50:37 +00001215 // don't abort if the realCallingUid has a visible window
1216 if (realCallingUidHasAnyVisibleWindow) {
Michal Karpinskiac116df2018-12-10 17:51:42 +00001217 return false;
1218 }
1219 // if the realCallingUid is a persistent system process, abort if the IntentSender
1220 // wasn't whitelisted to start an activity
Michal Karpinskid0162852019-01-15 16:05:25 +00001221 if (isRealCallingUidPersistentSystemProcess && allowBackgroundActivityStart) {
Michal Karpinskiac116df2018-12-10 17:51:42 +00001222 return false;
1223 }
Michal Karpinskida34cd42019-04-02 19:46:52 +01001224 // don't abort if the realCallingUid is an associated companion app
1225 if (mService.isAssociatedCompanionApp(UserHandle.getUserId(realCallingUid),
1226 realCallingUid)) {
1227 return false;
1228 }
Michal Karpinskiac116df2018-12-10 17:51:42 +00001229 }
Michal Karpinski7b97a022018-12-14 15:17:29 +00001230 // don't abort if the callingUid has START_ACTIVITIES_FROM_BACKGROUND permission
1231 if (mService.checkPermission(START_ACTIVITIES_FROM_BACKGROUND, callingPid, callingUid)
1232 == PERMISSION_GRANTED) {
1233 return false;
1234 }
Michal Karpinski82bb5902018-11-28 15:52:52 +00001235 // don't abort if the caller has the same uid as the recents component
1236 if (mSupervisor.mRecentTasks.isCallerRecents(callingUid)) {
1237 return false;
1238 }
Ricky Wai96f5c352019-04-10 18:40:17 +01001239 // don't abort if the callingUid is the device owner
1240 if (mService.isDeviceOwner(callingUid)) {
Michal Karpinski302dcec2019-02-01 11:48:25 +00001241 return false;
1242 }
Ricky Wai96f5c352019-04-10 18:40:17 +01001243 // don't abort if the callingUid has companion device
Ricky Wai2452e2d2019-03-18 19:19:08 +00001244 final int callingUserId = UserHandle.getUserId(callingUid);
Michal Karpinskida34cd42019-04-02 19:46:52 +01001245 if (mService.isAssociatedCompanionApp(callingUserId, callingUid)) {
Ricky Wai2452e2d2019-03-18 19:19:08 +00001246 return false;
1247 }
Michal Karpinski2e0aad22019-04-12 16:22:55 +01001248 // If we don't have callerApp at this point, no caller was provided to startActivity().
1249 // That's the case for PendingIntent-based starts, since the creator's process might not be
1250 // up and alive. If that's the case, we retrieve the WindowProcessController for the send()
1251 // caller, so that we can make the decision based on its foreground/whitelisted state.
1252 int callerAppUid = callingUid;
1253 if (callerApp == null) {
1254 callerApp = mService.getProcessController(realCallingPid, realCallingUid);
1255 callerAppUid = realCallingUid;
1256 }
1257 // don't abort if the callerApp or other processes of that uid are whitelisted in any way
1258 if (callerApp != null) {
1259 // first check the original calling process
1260 if (callerApp.areBackgroundActivityStartsAllowed()) {
1261 return false;
1262 }
1263 // only if that one wasn't whitelisted, check the other ones
1264 final ArraySet<WindowProcessController> uidProcesses =
1265 mService.mProcessMap.getProcesses(callerAppUid);
1266 if (uidProcesses != null) {
1267 for (int i = uidProcesses.size() - 1; i >= 0; i--) {
1268 final WindowProcessController proc = uidProcesses.valueAt(i);
1269 if (proc != callerApp && proc.areBackgroundActivityStartsAllowed()) {
1270 return false;
1271 }
1272 }
1273 }
1274 }
Michal Karpinski15486842019-04-25 17:33:42 +01001275 // don't abort if the callingUid has SYSTEM_ALERT_WINDOW permission
1276 if (mService.hasSystemAlertWindowPermission(callingUid, callingPid, callingPackage)) {
1277 Slog.w(TAG, "Background activity start for " + callingPackage
1278 + " allowed because SYSTEM_ALERT_WINDOW permission is granted.");
1279 return false;
1280 }
Michal Karpinskic02364c2019-01-22 13:00:04 +00001281 // anything that has fallen through would currently be aborted
1282 Slog.w(TAG, "Background activity start [callingPackage: " + callingPackage
Michal Karpinskid0162852019-01-15 16:05:25 +00001283 + "; callingUid: " + callingUid
1284 + "; isCallingUidForeground: " + isCallingUidForeground
1285 + "; isCallingUidPersistentSystemProcess: " + isCallingUidPersistentSystemProcess
1286 + "; realCallingUid: " + realCallingUid
1287 + "; isRealCallingUidForeground: " + isRealCallingUidForeground
1288 + "; isRealCallingUidPersistentSystemProcess: "
Ricky Waiaca8a772019-04-04 16:01:06 +01001289 + isRealCallingUidPersistentSystemProcess
Michal Karpinskid0162852019-01-15 16:05:25 +00001290 + "; originatingPendingIntent: " + originatingPendingIntent
1291 + "; isBgStartWhitelisted: " + allowBackgroundActivityStart
1292 + "; intent: " + intent
Michal Karpinski9cbb20b2019-02-05 17:31:50 +00001293 + "; callerApp: " + callerApp
Michal Karpinskid0162852019-01-15 16:05:25 +00001294 + "]");
Michal Karpinski4fd5b842019-01-28 15:13:32 +00001295 // log aborted activity start to TRON
1296 if (mService.isActivityStartsLoggingEnabled()) {
1297 mSupervisor.getActivityMetricsLogger().logAbortedBgActivityStart(intent, callerApp,
1298 callingUid, callingPackage, callingUidProcState, callingUidHasAnyVisibleWindow,
1299 realCallingUid, realCallingUidProcState, realCallingUidHasAnyVisibleWindow,
Michal Karpinski201bc0c2018-07-20 15:32:00 +01001300 (originatingPendingIntent != null));
Michal Karpinski201bc0c2018-07-20 15:32:00 +01001301 }
Michal Karpinski4fd5b842019-01-28 15:13:32 +00001302 return true;
Michal Karpinski201bc0c2018-07-20 15:32:00 +01001303 }
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001304
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001305 /**
1306 * Creates a launch intent for the given auxiliary resolution data.
1307 */
Patrick Baumann577d4022018-01-31 16:55:10 +00001308 private @NonNull Intent createLaunchIntent(@Nullable AuxiliaryResolveInfo auxiliaryResponse,
Chad Brubaker06068612017-04-06 09:43:47 -07001309 Intent originalIntent, String callingPackage, Bundle verificationBundle,
1310 String resolvedType, int userId) {
Patrick Baumann577d4022018-01-31 16:55:10 +00001311 if (auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo) {
Todd Kennedye9910222017-02-21 16:00:11 -08001312 // request phase two resolution
Winson81fef842019-08-28 12:19:08 -07001313 PackageManagerInternal packageManager = mService.getPackageManagerInternalLocked();
1314 boolean isRequesterInstantApp = packageManager.isInstantApp(callingPackage, userId);
1315 packageManager.requestInstantAppResolutionPhaseTwo(
Chad Brubaker06068612017-04-06 09:43:47 -07001316 auxiliaryResponse, originalIntent, resolvedType, callingPackage,
Winson81fef842019-08-28 12:19:08 -07001317 isRequesterInstantApp, verificationBundle, userId);
Todd Kennedye9910222017-02-21 16:00:11 -08001318 }
Todd Kennedydfc27c62017-05-17 15:32:10 -07001319 return InstantAppResolver.buildEphemeralInstallerIntent(
Patrick Baumann577d4022018-01-31 16:55:10 +00001320 originalIntent,
1321 InstantAppResolver.sanitizeIntent(originalIntent),
1322 auxiliaryResponse == null ? null : auxiliaryResponse.failureIntent,
1323 callingPackage,
1324 verificationBundle,
1325 resolvedType,
1326 userId,
1327 auxiliaryResponse == null ? null : auxiliaryResponse.installFailureActivity,
1328 auxiliaryResponse == null ? null : auxiliaryResponse.token,
1329 auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo,
1330 auxiliaryResponse == null ? null : auxiliaryResponse.filters);
Todd Kennedye9910222017-02-21 16:00:11 -08001331 }
1332
Riddle Hsu16567132018-08-16 21:37:47 +08001333 void postStartActivityProcessing(ActivityRecord r, int result,
1334 ActivityStack startedActivityStack) {
Winson Chunge219ae12019-07-18 13:43:23 -07001335 if (!ActivityManager.isStartResultSuccessful(result)) {
1336 if (mFrozeTaskList) {
1337 // If we specifically froze the task list as part of starting an activity, then
1338 // reset the frozen list state if it failed to start. This is normally otherwise
1339 // called when the freeze-timeout has elapsed.
1340 mSupervisor.mRecentTasks.resetFreezeTaskListReorderingOnTimeout();
1341 }
1342 }
Bryce Lee7f936862017-05-09 15:33:18 -07001343 if (ActivityManager.isStartResultFatalError(result)) {
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -08001344 return;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001345 }
Filip Gruszczynski303210b2016-01-08 16:28:08 -08001346
Chong Zhang5022da32016-06-21 16:31:37 -07001347 // We're waiting for an activity launch to finish, but that activity simply
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001348 // brought another activity to front. We must also handle the case where the task is already
1349 // in the front as a result of the trampoline activity being in the same task (it will be
Louis Chang54fbb052019-10-16 17:10:17 +08001350 // considered focused as the trampoline will be finished). Let them know about this, so
1351 // it waits for the new activity to become visible instead, {@link #waitResultIfNeeded}.
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001352 mSupervisor.reportWaitingActivityLaunchedIfNeeded(r, result);
Chong Zhang5022da32016-06-21 16:31:37 -07001353
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001354 if (startedActivityStack == null) {
1355 return;
1356 }
1357
Wale Ogunwaleac36e4d2017-11-29 13:30:26 -08001358 final int clearTaskFlags = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK;
1359 boolean clearedTask = (mLaunchFlags & clearTaskFlags) == clearTaskFlags
1360 && mReuseTask != null;
Wale Ogunwale7d7973a2018-04-05 10:25:59 -07001361 if (result == START_TASK_TO_FRONT || result == START_DELIVERED_TO_TOP || clearedTask) {
1362 // The activity was already running so it wasn't started, but either brought to the
1363 // front or the new intent was delivered to it since it was already in front. Notify
1364 // anyone interested in this piece of information.
1365 switch (startedActivityStack.getWindowingMode()) {
1366 case WINDOWING_MODE_PINNED:
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001367 mService.getTaskChangeNotificationController().notifyPinnedActivityRestartAttempt(
Wale Ogunwale7d7973a2018-04-05 10:25:59 -07001368 clearedTask);
1369 break;
1370 case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
Louis Changbd48dca2018-08-29 17:44:34 +08001371 final ActivityStack homeStack =
1372 startedActivityStack.getDisplay().getHomeStack();
Wale Ogunwale7d7973a2018-04-05 10:25:59 -07001373 if (homeStack != null && homeStack.shouldBeVisible(null /* starting */)) {
1374 mService.mWindowManager.showRecentApps();
1375 }
1376 break;
1377 }
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -08001378 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001379 }
1380
Svet Ganovcbcbf662018-05-10 17:25:29 -07001381 /**
1382 * Compute the logical UID based on which the package manager would filter
1383 * app components i.e. based on which the instant app policy would be applied
1384 * because it is the logical calling UID.
1385 *
1386 * @param customCallingUid The UID on whose behalf to make the call.
1387 * @param actualCallingUid The UID actually making the call.
Patrick Baumann31426b22018-05-21 13:46:40 -07001388 * @param filterCallingUid The UID to be used to filter for instant apps.
Svet Ganovcbcbf662018-05-10 17:25:29 -07001389 * @return The logical UID making the call.
1390 */
Patrick Baumann31426b22018-05-21 13:46:40 -07001391 static int computeResolveFilterUid(int customCallingUid, int actualCallingUid,
1392 int filterCallingUid) {
1393 return filterCallingUid != UserHandle.USER_NULL
1394 ? filterCallingUid
1395 : (customCallingUid >= 0 ? customCallingUid : actualCallingUid);
Svet Ganovcbcbf662018-05-10 17:25:29 -07001396 }
1397
Louis Chang54fbb052019-10-16 17:10:17 +08001398 /**
1399 * Start an activity while most of preliminary checks has been done and caller has been
1400 * confirmed that holds necessary permissions to do so.
1401 * Here also ensures that the starting activity is removed if the start wasn't successful.
1402 */
1403 private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
Bryce Leedaa91e42017-12-06 14:13:01 -08001404 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
Louis Changcdec0802019-11-11 11:45:07 +08001405 int startFlags, boolean doResume, ActivityOptions options, Task inTask,
Louis Chang54fbb052019-10-16 17:10:17 +08001406 boolean restrictedBgActivity) {
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001407 int result = START_CANCELED;
Riddle Hsu16567132018-08-16 21:37:47 +08001408 final ActivityStack startedActivityStack;
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001409 try {
Riddle Hsua0022cd2019-09-09 21:12:41 +08001410 mService.deferWindowLayout();
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001411 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
1412 result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
Louis Chang54fbb052019-10-16 17:10:17 +08001413 startFlags, doResume, options, inTask, restrictedBgActivity);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001414 } finally {
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001415 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
1416 startedActivityStack = handleStartResult(r, result);
Riddle Hsua0022cd2019-09-09 21:12:41 +08001417 mService.continueWindowLayout();
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001418 }
1419
Riddle Hsu16567132018-08-16 21:37:47 +08001420 postStartActivityProcessing(r, result, startedActivityStack);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001421
1422 return result;
1423 }
1424
Ricky Waib147fa12019-04-25 16:08:30 +01001425 /**
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001426 * If the start result is success, ensure that the configuration of the started activity matches
1427 * the current display. Otherwise clean up unassociated containers to avoid leakage.
1428 *
1429 * @return the stack where the successful started activity resides.
1430 */
1431 private @Nullable ActivityStack handleStartResult(@NonNull ActivityRecord started, int result) {
1432 final ActivityStack currentStack = started.getActivityStack();
1433 ActivityStack startedActivityStack = currentStack != null ? currentStack : mTargetStack;
1434
1435 if (ActivityManager.isStartResultSuccessful(result)) {
1436 if (startedActivityStack != null) {
1437 // If there is no state change (e.g. a resumed activity is reparented to top of
1438 // another display) to trigger a visibility/configuration checking, we have to
1439 // update the configuration for changing to different display.
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09001440 final ActivityRecord currentTop = startedActivityStack.topRunningActivity();
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001441 if (currentTop != null && currentTop.shouldUpdateConfigForDisplayChanged()) {
Louis Chang149d5c82019-12-30 09:47:39 +08001442 mRootWindowContainer.ensureVisibilityAndConfig(
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001443 currentTop, currentTop.getDisplayId(),
1444 true /* markFrozenIfConfigChanged */, false /* deferResume */);
1445 }
1446 }
1447 return startedActivityStack;
1448 }
1449
1450 // If we are not able to proceed, disassociate the activity from the task. Leaving an
1451 // activity in an incomplete state can lead to issues, such as performing operations
1452 // without a window container.
1453 final ActivityStack stack = mStartActivity.getActivityStack();
1454 if (stack != null) {
1455 mStartActivity.finishIfPossible("startActivity", true /* oomAdj */);
1456 }
1457
1458 // Stack should also be detached from display and be removed if it's empty.
1459 if (startedActivityStack != null && startedActivityStack.isAttached()
Wale Ogunwalea38654f2019-11-17 20:37:15 -08001460 && !startedActivityStack.hasActivity()
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001461 && !startedActivityStack.isActivityTypeHome()) {
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -07001462 startedActivityStack.removeIfPossible();
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001463 startedActivityStack = null;
1464 }
1465 return startedActivityStack;
1466 }
1467
1468 /**
Louis Chang54fbb052019-10-16 17:10:17 +08001469 * Start an activity and determine if the activity should be adding to the top of an existing
1470 * task or delivered new intent to an existing activity. Also manipulating the activity task
1471 * onto requested or valid stack/display.
Ricky Waib147fa12019-04-25 16:08:30 +01001472 *
Louis Chang54fbb052019-10-16 17:10:17 +08001473 * Note: This method should only be called from {@link #startActivityUnchecked}.
Ricky Waib147fa12019-04-25 16:08:30 +01001474 */
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001475 private int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
Wale Ogunwale01d66562015-12-29 08:19:19 -08001476 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
Louis Changcdec0802019-11-11 11:45:07 +08001477 int startFlags, boolean doResume, ActivityOptions options, Task inTask,
Louis Chang54fbb052019-10-16 17:10:17 +08001478 boolean restrictedBgActivity) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001479 setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
Ricky Waib147fa12019-04-25 16:08:30 +01001480 voiceInteractor, restrictedBgActivity);
1481
Louis Chang39ba54b2018-10-18 11:28:57 +08001482 final int preferredWindowingMode = mLaunchParams.mWindowingMode;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001483
Louis Chang6fb1e842018-12-03 16:07:50 +08001484 computeLaunchingTaskFlags();
1485
1486 computeSourceStack();
1487
1488 mIntent.setFlags(mLaunchFlags);
1489
Louis Changcdec0802019-11-11 11:45:07 +08001490 final Task reusedTask = getReusableTask();
Louis Changf7dd7f22019-11-05 11:59:56 +08001491 mSupervisor.getLaunchParamsController().calculate(reusedTask != null ? reusedTask : mInTask,
Louis Chang6fb1e842018-12-03 16:07:50 +08001492 r.info.windowLayout, r, sourceRecord, options, PHASE_BOUNDS, mLaunchParams);
1493 mPreferredDisplayId =
1494 mLaunchParams.hasPreferredDisplay() ? mLaunchParams.mPreferredDisplayId
1495 : DEFAULT_DISPLAY;
1496
Winson Chunge219ae12019-07-18 13:43:23 -07001497 // If requested, freeze the task list
1498 if (mOptions != null && mOptions.freezeRecentTasksReordering()
1499 && mSupervisor.mRecentTasks.isCallerRecents(r.launchedFromUid)
1500 && !mSupervisor.mRecentTasks.isFreezeTaskListReorderingSet()) {
1501 mFrozeTaskList = true;
1502 mSupervisor.mRecentTasks.setFreezeTaskListReordering();
1503 }
1504
Louis Changbde91e92019-08-16 17:19:47 +08001505 // Compute if there is an existing task that should be used for.
Louis Changcdec0802019-11-11 11:45:07 +08001506 final Task targetTask = reusedTask != null ? reusedTask : computeTargetTask();
Louis Changbde91e92019-08-16 17:19:47 +08001507 final boolean newTask = targetTask == null;
1508
1509 // Check if starting activity on given task or on a new task is allowed.
1510 int startResult = isAllowedToStart(r, newTask, targetTask);
1511 if (startResult != START_SUCCESS) {
1512 return startResult;
Louis Changbd48dca2018-08-29 17:44:34 +08001513 }
1514
Wale Ogunwale21e06482019-11-18 05:14:15 -08001515 final ActivityRecord targetTaskTop = newTask
1516 ? null : targetTask.getTopNonFinishingActivity();
Louis Changbde91e92019-08-16 17:19:47 +08001517 if (targetTaskTop != null) {
1518 // Recycle the target task for this launch.
Louis Changf7dd7f22019-11-05 11:59:56 +08001519 startResult = recycleTask(targetTask, targetTaskTop, reusedTask);
Louis Changbde91e92019-08-16 17:19:47 +08001520 if (startResult != START_SUCCESS) {
1521 return startResult;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001522 }
Louis Changf7dd7f22019-11-05 11:59:56 +08001523 } else {
1524 mAddingToTask = true;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001525 }
1526
1527 // If the activity being launched is the same as the one currently at the top, then
1528 // we need to check if it should only be launched once.
Louis Chang149d5c82019-12-30 09:47:39 +08001529 final ActivityStack topStack = mRootWindowContainer.getTopDisplayFocusedStack();
Louis Changbde91e92019-08-16 17:19:47 +08001530 startResult = deliverToCurrentTopIfNeeded(topStack);
1531 if (startResult != START_SUCCESS) {
1532 return startResult;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001533 }
1534
Louis Changbde91e92019-08-16 17:19:47 +08001535 if (mTargetStack == null) {
1536 mTargetStack = computeStackFocus(mStartActivity, true, mLaunchFlags, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001537 }
Louis Changbde91e92019-08-16 17:19:47 +08001538 if (newTask) {
Louis Changcdec0802019-11-11 11:45:07 +08001539 final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
1540 ? mSourceRecord.getTask() : null;
Louis Changbde91e92019-08-16 17:19:47 +08001541 setNewTask(taskToAffiliate);
Louis Changa3e6b892019-09-16 10:39:00 +08001542 if (mService.getLockTaskController().isLockTaskModeViolation(
Louis Changcdec0802019-11-11 11:45:07 +08001543 mStartActivity.getTask())) {
Louis Changa3e6b892019-09-16 10:39:00 +08001544 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
1545 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
1546 }
Louis Changbde91e92019-08-16 17:19:47 +08001547 } else if (mAddingToTask) {
1548 addOrReparentStartingActivity(targetTask, "adding to task");
1549 }
1550
1551 if (!mAvoidMoveToFront && mDoResume) {
1552 mTargetStack.moveToFront("reuseOrNewTask");
Chong Zhang6cda19c2016-06-14 19:07:56 -07001553 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001554
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00001555 mService.mUgmInternal.grantUriPermissionFromIntent(mCallingUid, mStartActivity.packageName,
1556 mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.mUserId);
Patrick Baumannde37e432019-08-28 09:51:29 -07001557 mService.getPackageManagerInternalLocked().grantImplicitAccess(
Andrii Kulianeceebbf2019-06-26 17:36:51 -07001558 mStartActivity.mUserId, mIntent,
Patrick Baumannb6e72972019-09-20 07:54:47 -07001559 mCallingUid,
Patrick Baumannde37e432019-08-28 09:51:29 -07001560 UserHandle.getAppId(mStartActivity.info.applicationInfo.uid)
1561 );
Wale Ogunwale01d66562015-12-29 08:19:19 -08001562 if (newTask) {
Jeff Changd136e772019-11-05 20:33:52 +08001563 EventLogTags.writeWmCreateTask(mStartActivity.mUserId,
Louis Changcdec0802019-11-11 11:45:07 +08001564 mStartActivity.getTask().mTaskId);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001565 }
Andrii Kulian79d67982019-08-19 11:56:16 -07001566 mStartActivity.logStartActivity(
Jeff Changd136e772019-11-05 20:33:52 +08001567 EventLogTags.WM_CREATE_ACTIVITY, mStartActivity.getTask());
1568
Wale Ogunwale01d66562015-12-29 08:19:19 -08001569 mTargetStack.mLastPausedActivity = null;
Wei Wang98f03f92016-05-18 11:32:52 -07001570
Louis Chang149d5c82019-12-30 09:47:39 +08001571 mRootWindowContainer.sendPowerHintForLaunchStartIfNeeded(
Wale Ogunwaled32da472018-11-16 07:19:28 -08001572 false /* forceSend */, mStartActivity);
Wei Wang98f03f92016-05-18 11:32:52 -07001573
Wale Ogunwale21e06482019-11-18 05:14:15 -08001574 mTargetStack.startActivityLocked(mStartActivity, topStack.getTopNonFinishingActivity(),
1575 newTask, mKeepCurTransition, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001576 if (mDoResume) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001577 final ActivityRecord topTaskActivity =
Louis Changcdec0802019-11-11 11:45:07 +08001578 mStartActivity.getTask().topRunningActivityLocked();
Wale Ogunwale3b232392016-05-13 15:37:13 -07001579 if (!mTargetStack.isFocusable()
Wale Ogunwale0b3d2922019-12-30 08:55:07 -08001580 || (topTaskActivity != null && topTaskActivity.isTaskOverlay()
Wale Ogunwale68741142016-05-17 09:40:02 -07001581 && mStartActivity != topTaskActivity)) {
Filip Gruszczynski3d7fdc12016-01-31 17:33:29 -08001582 // If the activity is not focusable, we can't resume it, but still would like to
1583 // make sure it becomes visible as it starts (this will also trigger entry
1584 // animation). An example of this are PIP activities.
Wale Ogunwale3b232392016-05-13 15:37:13 -07001585 // Also, we don't want to resume activities in a task that currently has an overlay
1586 // as the starting activity just needs to be in the visible paused state until the
1587 // over is removed.
Wale Ogunwale076c3b12019-11-20 12:17:22 -08001588 mTargetStack.ensureActivitiesVisible(mStartActivity, 0, !PRESERVE_WINDOWS);
Wale Ogunwaleae846f42016-02-22 14:00:56 -08001589 // Go ahead and tell window manager to execute app transition for this activity
1590 // since the app transition will not be triggered through the resume channel.
Wale Ogunwale3a256e62018-12-06 14:41:18 -08001591 mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
Wale Ogunwale3b232392016-05-13 15:37:13 -07001592 } else {
Winson Chung32066032016-11-04 11:55:21 -07001593 // If the target stack was not previously focusable (previous top running activity
1594 // on that stack was not visible) then any prior calls to move the stack to the
1595 // will not update the focused stack. If starting the new activity now allows the
1596 // task stack to be focusable, then ensure that we now update the focused stack
1597 // accordingly.
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001598 if (mTargetStack.isFocusable()
Louis Chang149d5c82019-12-30 09:47:39 +08001599 && !mRootWindowContainer.isTopDisplayFocusedStack(mTargetStack)) {
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001600 mTargetStack.moveToFront("startActivityInner");
Winson Chung32066032016-11-04 11:55:21 -07001601 }
Louis Chang149d5c82019-12-30 09:47:39 +08001602 mRootWindowContainer.resumeFocusedStacksTopActivities(
Wale Ogunwaled32da472018-11-16 07:19:28 -08001603 mTargetStack, mStartActivity, mOptions);
Filip Gruszczynski3d7fdc12016-01-31 17:33:29 -08001604 }
Winson Chung1dbc8112017-09-28 18:05:31 -07001605 } else if (mStartActivity != null) {
Louis Changcdec0802019-11-11 11:45:07 +08001606 mSupervisor.mRecentTasks.add(mStartActivity.getTask());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001607 }
Louis Chang149d5c82019-12-30 09:47:39 +08001608 mRootWindowContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001609
Louis Changcdec0802019-11-11 11:45:07 +08001610 mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(),
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001611 preferredWindowingMode, mPreferredDisplayId, mTargetStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001612
1613 return START_SUCCESS;
1614 }
1615
Louis Changcdec0802019-11-11 11:45:07 +08001616 private Task computeTargetTask() {
Louis Changf7dd7f22019-11-05 11:59:56 +08001617 if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
Louis Changbde91e92019-08-16 17:19:47 +08001618 && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1619 // A new task should be created instead of using existing one.
1620 return null;
1621 } else if (mSourceRecord != null) {
Louis Changcdec0802019-11-11 11:45:07 +08001622 return mSourceRecord.getTask();
Louis Changbde91e92019-08-16 17:19:47 +08001623 } else if (mInTask != null) {
1624 return mInTask;
1625 } else {
1626 final ActivityRecord top = computeStackFocus(mStartActivity, false /* newTask */,
Wale Ogunwale21e06482019-11-18 05:14:15 -08001627 mLaunchFlags, mOptions).getTopNonFinishingActivity();
Louis Changbde91e92019-08-16 17:19:47 +08001628 if (top != null) {
Louis Changcdec0802019-11-11 11:45:07 +08001629 return top.getTask();
Louis Changbde91e92019-08-16 17:19:47 +08001630 }
1631 }
1632 return null;
1633 }
1634
Louis Changcdec0802019-11-11 11:45:07 +08001635 private int isAllowedToStart(ActivityRecord r, boolean newTask, Task targetTask) {
Louis Changbde91e92019-08-16 17:19:47 +08001636 if (mStartActivity.packageName == null) {
1637 if (mStartActivity.resultTo != null) {
1638 mStartActivity.resultTo.sendResult(INVALID_UID, mStartActivity.resultWho,
1639 mStartActivity.requestCode, RESULT_CANCELED, null /* data */);
1640 }
1641 ActivityOptions.abort(mOptions);
1642 return START_CLASS_NOT_FOUND;
1643 }
1644
1645 // Do not start home activity if it cannot be launched on preferred display. We are not
1646 // doing this in ActivityStackSupervisor#canPlaceEntityOnDisplay because it might
1647 // fallback to launch on other displays.
Louis Chang149d5c82019-12-30 09:47:39 +08001648 if (r.isActivityTypeHome() && !mRootWindowContainer.canStartHomeOnDisplay(r.info,
Louis Changbde91e92019-08-16 17:19:47 +08001649 mPreferredDisplayId, true /* allowInstrumenting */)) {
1650 Slog.w(TAG, "Cannot launch home on display " + mPreferredDisplayId);
1651 return START_CANCELED;
1652 }
1653
Wale Ogunwalea38654f2019-11-17 20:37:15 -08001654 if (mRestrictedBgActivity && (newTask || !targetTask.isUidPresent(mCallingUid))
Louis Changbde91e92019-08-16 17:19:47 +08001655 && handleBackgroundActivityAbort(mStartActivity)) {
1656 Slog.e(TAG, "Abort background activity starts from " + mCallingUid);
1657 return START_ABORTED;
1658 }
1659
1660 // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but still
1661 // needs to be a lock task mode violation since the task gets cleared out and the device
1662 // would otherwise leave the locked task.
1663 final boolean isNewClearTask =
1664 (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1665 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
Louis Changa3e6b892019-09-16 10:39:00 +08001666 if (!newTask && mService.getLockTaskController().isLockTaskModeViolation(targetTask,
1667 isNewClearTask)) {
Louis Changbde91e92019-08-16 17:19:47 +08001668 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
1669 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
1670 }
1671
1672 return START_SUCCESS;
1673 }
1674
1675 /**
1676 * Prepare the target task to be reused for this launch, which including:
1677 * - Position the target task on valid stack on preferred display.
1678 * - Comply to the specified activity launch flags
1679 * - Determine whether need to add a new activity on top or just brought the task to front.
1680 */
Louis Chang07b13002019-11-27 22:08:37 +08001681 @VisibleForTesting
1682 int recycleTask(Task targetTask, ActivityRecord targetTaskTop, Task reusedTask) {
1683 // Should not recycle task which is from a different user, just adding the starting
1684 // activity to the task.
1685 if (targetTask.mUserId != mStartActivity.mUserId) {
1686 mTargetStack = targetTask.getStack();
1687 mAddingToTask = true;
1688 return START_SUCCESS;
1689 }
1690
Wale Ogunwaleda8b8272018-11-29 19:37:37 -08001691 boolean clearTaskForReuse = false;
Louis Changf7dd7f22019-11-05 11:59:56 +08001692 if (reusedTask != null) {
Louis Chang2787a9a2019-12-17 15:15:11 +08001693 if (mStartActivity.getTask() == null) {
Louis Changf7dd7f22019-11-05 11:59:56 +08001694 mStartActivity.setTaskForReuse(reusedTask);
Wale Ogunwaleda8b8272018-11-29 19:37:37 -08001695 clearTaskForReuse = true;
1696 }
1697
Louis Changbde91e92019-08-16 17:19:47 +08001698 if (targetTask.intent == null) {
1699 // This task was started because of movement of the activity based on
1700 // affinity...
1701 // Now that we are actually launching it, we can assign the base intent.
1702 targetTask.setIntent(mStartActivity);
1703 } else {
1704 final boolean taskOnHome =
1705 (mStartActivity.intent.getFlags() & FLAG_ACTIVITY_TASK_ON_HOME) != 0;
1706 if (taskOnHome) {
1707 targetTask.intent.addFlags(FLAG_ACTIVITY_TASK_ON_HOME);
1708 } else {
1709 targetTask.intent.removeFlags(FLAG_ACTIVITY_TASK_ON_HOME);
1710 }
1711 }
1712 }
1713
Louis Chang149d5c82019-12-30 09:47:39 +08001714 mRootWindowContainer.sendPowerHintForLaunchStartIfNeeded(false /* forceSend */,
Louis Changbde91e92019-08-16 17:19:47 +08001715 targetTaskTop);
1716
1717 setTargetStackIfNeeded(targetTaskTop);
1718
Louis Changbde91e92019-08-16 17:19:47 +08001719 // When there is a reused activity and the current result is a trampoline activity,
1720 // set the reused activity as the result.
Louis Chang54fbb052019-10-16 17:10:17 +08001721 if (mLastStartActivityRecord != null
1722 && (mLastStartActivityRecord.finishing || mLastStartActivityRecord.noDisplay)) {
1723 mLastStartActivityRecord = targetTaskTop;
Louis Changbde91e92019-08-16 17:19:47 +08001724 }
1725
1726 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1727 // We don't need to start a new activity, and the client said not to do anything
1728 // if that is the case, so this is it! And for paranoia, make sure we have
1729 // correctly resumed the top activity.
1730 if (!mMovedToFront && mDoResume) {
1731 if (DEBUG_TASKS) {
1732 Slog.d(TAG_TASKS, "Bring to front target: " + mTargetStack
1733 + " from " + targetTaskTop);
1734 }
1735 mTargetStack.moveToFront("intentActivityFound");
1736 }
1737 resumeTargetStackIfNeeded();
1738 return START_RETURN_INTENT_TO_CALLER;
1739 }
1740
Wale Ogunwale21e06482019-11-18 05:14:15 -08001741 complyActivityFlags(targetTask,
1742 reusedTask != null ? reusedTask.getTopNonFinishingActivity() : null);
Louis Changbde91e92019-08-16 17:19:47 +08001743
Wale Ogunwaleda8b8272018-11-29 19:37:37 -08001744 if (clearTaskForReuse) {
1745 // Clear task for re-use so later code to methods
1746 // {@link #setTaskFromReuseOrCreateNewTask}, {@link #setTaskFromSourceRecord}, or
1747 // {@link #setTaskFromInTask} can parent it to the task.
1748 mStartActivity.setTaskForReuse(null);
1749 }
1750
Louis Changbde91e92019-08-16 17:19:47 +08001751 if (mAddingToTask) {
1752 return START_SUCCESS;
1753 }
1754
Louis Chang3ee5fc02019-09-23 11:32:10 +08001755 if (mMovedToFront) {
1756 // We moved the task to front, use starting window to hide initial drawn delay.
1757 targetTaskTop.showStartingWindow(null /* prev */, false /* newTask */,
1758 true /* taskSwitch */);
1759 } else if (mDoResume) {
1760 // Make sure the stack and its belonging display are moved to topmost.
Louis Changbde91e92019-08-16 17:19:47 +08001761 mTargetStack.moveToFront("intentActivityFound");
1762 }
1763 // We didn't do anything... but it was needed (a.k.a., client don't use that intent!)
1764 // And for paranoia, make sure we have correctly resumed the top activity.
1765 resumeTargetStackIfNeeded();
Louis Chang54fbb052019-10-16 17:10:17 +08001766 // The reusedActivity could be finishing, for example of starting an activity with
1767 // FLAG_ACTIVITY_CLEAR_TOP flag. In that case, return the top running activity in the
1768 // task instead.
1769 mLastStartActivityRecord =
Wale Ogunwale21e06482019-11-18 05:14:15 -08001770 targetTaskTop.finishing ? targetTask.getTopNonFinishingActivity() : targetTaskTop;
Louis Changbde91e92019-08-16 17:19:47 +08001771 return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP;
1772 }
1773
1774 /**
1775 * Check if the activity being launched is the same as the one currently at the top and it
1776 * should only be launched once.
1777 */
1778 private int deliverToCurrentTopIfNeeded(ActivityStack topStack) {
1779 final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
1780 final boolean dontStart = top != null && mStartActivity.resultTo == null
1781 && top.mActivityComponent.equals(mStartActivity.mActivityComponent)
1782 && top.mUserId == mStartActivity.mUserId
1783 && top.attachedToProcess()
1784 && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
1785 || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK))
1786 // This allows home activity to automatically launch on secondary display when
1787 // display added, if home was the top activity on default display, instead of
1788 // sending new intent to the home activity on default display.
1789 && (!top.isActivityTypeHome() || top.getDisplayId() == mPreferredDisplayId);
1790 if (!dontStart) {
1791 return START_SUCCESS;
1792 }
1793
1794 // For paranoia, make sure we have correctly resumed the top activity.
1795 topStack.mLastPausedActivity = null;
1796 if (mDoResume) {
Louis Chang149d5c82019-12-30 09:47:39 +08001797 mRootWindowContainer.resumeFocusedStacksTopActivities();
Louis Changbde91e92019-08-16 17:19:47 +08001798 }
1799 ActivityOptions.abort(mOptions);
1800 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1801 // We don't need to start a new activity, and the client said not to do anything if
1802 // that is the case, so this is it!
1803 return START_RETURN_INTENT_TO_CALLER;
1804 }
1805
1806 deliverNewIntent(top);
1807
1808 // Don't use mStartActivity.task to show the toast. We're not starting a new activity but
1809 // reusing 'top'. Fields in mStartActivity may not be fully initialized.
Louis Changcdec0802019-11-11 11:45:07 +08001810 mSupervisor.handleNonResizableTaskIfNeeded(top.getTask(),
Louis Changbde91e92019-08-16 17:19:47 +08001811 mLaunchParams.mWindowingMode, mPreferredDisplayId, topStack);
1812
1813 return START_DELIVERED_TO_TOP;
1814 }
1815
1816 /**
1817 * Applying the launching flags to the task, which might clear few or all the activities in the
1818 * task.
1819 */
Louis Changcdec0802019-11-11 11:45:07 +08001820 private void complyActivityFlags(Task targetTask, ActivityRecord reusedActivity) {
Wale Ogunwale21e06482019-11-18 05:14:15 -08001821 ActivityRecord targetTaskTop = targetTask.getTopNonFinishingActivity();
Louis Chang2dcb1272019-09-27 15:01:19 +08001822 final boolean resetTask =
1823 reusedActivity != null && (mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0;
1824 if (resetTask) {
Wale Ogunwaledfbeed72019-11-20 08:57:39 -08001825 targetTaskTop = mTargetStack.resetTaskIfNeeded(targetTaskTop, mStartActivity);
Louis Changbde91e92019-08-16 17:19:47 +08001826 }
1827
1828 if ((mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1829 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {
1830 // The caller has requested to completely replace any existing task with its new
1831 // activity. Well that should not be too hard...
Louis Changcdec0802019-11-11 11:45:07 +08001832 // Note: we must persist the {@link Task} first as intentActivity could be
Louis Changbde91e92019-08-16 17:19:47 +08001833 // removed from calling performClearTaskLocked (For example, if it is being brought out
1834 // of history or if it is finished immediately), thus disassociating the task. Also note
Louis Changcdec0802019-11-11 11:45:07 +08001835 // that mReuseTask is reset as a result of {@link Task#performClearTaskLocked}
Louis Changbde91e92019-08-16 17:19:47 +08001836 // launching another activity.
1837 // TODO(b/36119896): We shouldn't trigger activity launches in this path since we are
1838 // already launching one.
1839 targetTask.performClearTaskLocked();
1840 targetTask.setIntent(mStartActivity);
1841 mAddingToTask = true;
1842 } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
1843 || isDocumentLaunchesIntoExisting(mLaunchFlags)
1844 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
1845 // In this situation we want to remove all activities from the task up to the one
1846 // being started. In most cases this means we are resetting the task to its initial
1847 // state.
1848 final ActivityRecord top = targetTask.performClearTaskForReuseLocked(mStartActivity,
1849 mLaunchFlags);
1850
1851 // The above code can remove {@code reusedActivity} from the task, leading to the
Louis Changcdec0802019-11-11 11:45:07 +08001852 // {@code ActivityRecord} removing its reference to the {@code Task}. The task
Wale Ogunwalec17418e2019-10-13 23:00:40 +02001853 // reference is needed in the call below to {@link setTargetStackAndMoveToFrontIfNeeded}
Louis Changcdec0802019-11-11 11:45:07 +08001854 if (targetTaskTop.getTask() == null) {
Wale Ogunwale2322bed2019-10-10 17:24:19 +02001855 targetTask.addChild(targetTaskTop);
Louis Changbde91e92019-08-16 17:19:47 +08001856 }
1857
1858 if (top != null) {
1859 if (top.isRootOfTask()) {
1860 // Activity aliases may mean we use different intents for the top activity,
1861 // so make sure the task now has the identity of the new intent.
Louis Changcdec0802019-11-11 11:45:07 +08001862 top.getTask().setIntent(mStartActivity);
Louis Changbde91e92019-08-16 17:19:47 +08001863 }
1864 deliverNewIntent(top);
1865 } else {
1866 // A special case: we need to start the activity because it is not currently
1867 // running, and the caller has asked to clear the current task to have this
1868 // activity at the top.
1869 mAddingToTask = true;
1870 if (targetTask.getStack() == null) {
1871 // Target stack got cleared when we all activities were removed above.
1872 // Go ahead and reset it.
1873 mTargetStack = computeStackFocus(mSourceRecord, false /* newTask */,
1874 mLaunchFlags, mOptions);
Wale Ogunwale2322bed2019-10-10 17:24:19 +02001875 mTargetStack.addChild(targetTask, !mLaunchTaskBehind /* toTop */,
1876 (mStartActivity.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0);
Louis Changbde91e92019-08-16 17:19:47 +08001877 }
1878 }
1879 } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) == 0 && !mAddingToTask
1880 && (mLaunchFlags & FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1881 // In this case, we are launching an activity in our own task that may
1882 // already be running somewhere in the history, and we want to shuffle it to
1883 // the front of the stack if so.
Wale Ogunwalea38654f2019-11-17 20:37:15 -08001884 final ActivityRecord act =
1885 targetTask.findActivityInHistory(mStartActivity.mActivityComponent);
Louis Changbde91e92019-08-16 17:19:47 +08001886 if (act != null) {
Louis Changcdec0802019-11-11 11:45:07 +08001887 final Task task = act.getTask();
Louis Changbde91e92019-08-16 17:19:47 +08001888 task.moveActivityToFrontLocked(act);
1889 act.updateOptionsLocked(mOptions);
1890 deliverNewIntent(act);
1891 mTargetStack.mLastPausedActivity = null;
1892 } else {
1893 mAddingToTask = true;
1894 }
1895 } else if (mStartActivity.mActivityComponent.equals(targetTask.realActivity)) {
Louis Chang382419b2019-10-03 21:43:38 +08001896 if (targetTask == mInTask) {
1897 // In this case we are bringing up an existing activity from a recent task. We
1898 // don't need to add a new activity instance on top.
1899 } else if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
1900 || LAUNCH_SINGLE_TOP == mLaunchMode)
1901 && targetTaskTop.mActivityComponent.equals(mStartActivity.mActivityComponent)
1902 && mStartActivity.resultTo == null) {
1903 // In this case the top activity on the task is the same as the one being launched,
1904 // so we take that as a request to bring the task to the foreground. If the top
1905 // activity in the task is the root activity, deliver this new intent to it if it
1906 // desires.
Louis Changbde91e92019-08-16 17:19:47 +08001907 if (targetTaskTop.isRootOfTask()) {
Louis Changcdec0802019-11-11 11:45:07 +08001908 targetTaskTop.getTask().setIntent(mStartActivity);
Louis Changbde91e92019-08-16 17:19:47 +08001909 }
1910 deliverNewIntent(targetTaskTop);
1911 } else if (!targetTask.isSameIntentFilter(mStartActivity)) {
1912 // In this case we are launching the root activity of the task, but with a
1913 // different intent. We should start a new instance on top.
1914 mAddingToTask = true;
1915 } else if (reusedActivity == null) {
1916 mAddingToTask = true;
1917 }
Louis Chang2dcb1272019-09-27 15:01:19 +08001918 } else if (!resetTask) {
Louis Changbde91e92019-08-16 17:19:47 +08001919 // In this case an activity is being launched in to an existing task, without
1920 // resetting that task. This is typically the situation of launching an activity
1921 // from a notification or shortcut. We want to place the new activity on top of the
1922 // current task.
1923 mAddingToTask = true;
1924 } else if (!targetTask.rootWasReset) {
1925 // In this case we are launching into an existing task that has not yet been started
1926 // from its front door. The current task has been brought to the front. Ideally,
1927 // we'd probably like to place this new task at the bottom of its stack, but that's
1928 // a little hard to do with the current organization of the code so for now we'll
1929 // just drop it.
1930 targetTask.setIntent(mStartActivity);
1931 }
1932 }
1933
Bryce Leedaa91e42017-12-06 14:13:01 -08001934 /**
1935 * Resets the {@link ActivityStarter} state.
1936 * @param clearRequest whether the request should be reset to default values.
1937 */
1938 void reset(boolean clearRequest) {
1939 mStartActivity = null;
1940 mIntent = null;
1941 mCallingUid = -1;
1942 mOptions = null;
Ricky Waib147fa12019-04-25 16:08:30 +01001943 mRestrictedBgActivity = false;
Bryce Leedaa91e42017-12-06 14:13:01 -08001944
1945 mLaunchTaskBehind = false;
1946 mLaunchFlags = 0;
1947 mLaunchMode = INVALID_LAUNCH_MODE;
1948
Bryce Leeec55eb02017-12-05 20:51:27 -08001949 mLaunchParams.reset();
Bryce Leedaa91e42017-12-06 14:13:01 -08001950
1951 mNotTop = null;
1952 mDoResume = false;
1953 mStartFlags = 0;
1954 mSourceRecord = null;
1955 mPreferredDisplayId = INVALID_DISPLAY;
1956
1957 mInTask = null;
1958 mAddingToTask = false;
1959 mReuseTask = null;
1960
1961 mNewTaskInfo = null;
1962 mNewTaskIntent = null;
1963 mSourceStack = null;
1964
1965 mTargetStack = null;
1966 mMovedToFront = false;
1967 mNoAnimation = false;
1968 mKeepCurTransition = false;
1969 mAvoidMoveToFront = false;
Winson Chunge219ae12019-07-18 13:43:23 -07001970 mFrozeTaskList = false;
Bryce Leedaa91e42017-12-06 14:13:01 -08001971
1972 mVoiceSession = null;
1973 mVoiceInteractor = null;
1974
1975 mIntentDelivered = false;
1976
1977 if (clearRequest) {
1978 mRequest.reset();
1979 }
1980 }
1981
Louis Changcdec0802019-11-11 11:45:07 +08001982 private void setInitialState(ActivityRecord r, ActivityOptions options, Task inTask,
Wale Ogunwale01d66562015-12-29 08:19:19 -08001983 boolean doResume, int startFlags, ActivityRecord sourceRecord,
Ricky Waib147fa12019-04-25 16:08:30 +01001984 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1985 boolean restrictedBgActivity) {
Bryce Leedaa91e42017-12-06 14:13:01 -08001986 reset(false /* clearRequest */);
1987
Wale Ogunwale01d66562015-12-29 08:19:19 -08001988 mStartActivity = r;
1989 mIntent = r.intent;
1990 mOptions = options;
1991 mCallingUid = r.launchedFromUid;
1992 mSourceRecord = sourceRecord;
1993 mVoiceSession = voiceSession;
1994 mVoiceInteractor = voiceInteractor;
Ricky Waib147fa12019-04-25 16:08:30 +01001995 mRestrictedBgActivity = restrictedBgActivity;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001996
Bryce Leeec55eb02017-12-05 20:51:27 -08001997 mLaunchParams.reset();
Bryce Leedacefc42017-10-10 12:56:02 -07001998
Louis Chang6fb1e842018-12-03 16:07:50 +08001999 // Preferred display id is the only state we need for now and it could be updated again
2000 // after we located a reusable task (which might be resided in another display).
Garfield Tan706dbcb2018-10-15 11:33:02 -07002001 mSupervisor.getLaunchParamsController().calculate(inTask, r.info.windowLayout, r,
Louis Chang6fb1e842018-12-03 16:07:50 +08002002 sourceRecord, options, PHASE_DISPLAY, mLaunchParams);
2003 mPreferredDisplayId =
2004 mLaunchParams.hasPreferredDisplay() ? mLaunchParams.mPreferredDisplayId
2005 : DEFAULT_DISPLAY;
Garfield Tanb5cc09f2018-09-28 10:06:52 -07002006
Bryce Lee7daee392017-10-12 13:46:18 -07002007 mLaunchMode = r.launchMode;
2008
Wale Ogunwale01d66562015-12-29 08:19:19 -08002009 mLaunchFlags = adjustLaunchFlagsToDocumentMode(
Bryce Lee7daee392017-10-12 13:46:18 -07002010 r, LAUNCH_SINGLE_INSTANCE == mLaunchMode,
2011 LAUNCH_SINGLE_TASK == mLaunchMode, mIntent.getFlags());
Wale Ogunwale01d66562015-12-29 08:19:19 -08002012 mLaunchTaskBehind = r.mLaunchTaskBehind
Bryce Lee7daee392017-10-12 13:46:18 -07002013 && !isLaunchModeOneOf(LAUNCH_SINGLE_TASK, LAUNCH_SINGLE_INSTANCE)
Wale Ogunwale01d66562015-12-29 08:19:19 -08002014 && (mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0;
2015
2016 sendNewTaskResultRequestIfNeeded();
2017
2018 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
2019 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2020 }
2021
2022 // If we are actually going to launch in to a new task, there are some cases where
2023 // we further want to do multiple task.
2024 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
2025 if (mLaunchTaskBehind
2026 || r.info.documentLaunchMode == DOCUMENT_LAUNCH_ALWAYS) {
2027 mLaunchFlags |= FLAG_ACTIVITY_MULTIPLE_TASK;
2028 }
2029 }
2030
2031 // We'll invoke onUserLeaving before onPause only if the launching
2032 // activity did not explicitly state that this is an automated launch.
2033 mSupervisor.mUserLeaving = (mLaunchFlags & FLAG_ACTIVITY_NO_USER_ACTION) == 0;
2034 if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
2035 "startActivity() => mUserLeaving=" + mSupervisor.mUserLeaving);
2036
2037 // If the caller has asked not to resume at this point, we make note
2038 // of this in the record so that we can skip it when trying to find
2039 // the top running activity.
2040 mDoResume = doResume;
Louis Chang37317152019-05-09 09:53:58 +08002041 if (!doResume || !r.okToShowLocked() || mLaunchTaskBehind) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002042 r.delayedResume = true;
2043 mDoResume = false;
2044 }
2045
Winson Chunge2d72172018-01-25 17:46:20 +00002046 if (mOptions != null) {
2047 if (mOptions.getLaunchTaskId() != -1 && mOptions.getTaskOverlay()) {
Wale Ogunwale0b3d2922019-12-30 08:55:07 -08002048 r.setTaskOverlay(true);
Winson Chunge2d72172018-01-25 17:46:20 +00002049 if (!mOptions.canTaskOverlayResume()) {
Louis Chang149d5c82019-12-30 09:47:39 +08002050 final Task task = mRootWindowContainer.anyTaskForId(
Winson Chunge2d72172018-01-25 17:46:20 +00002051 mOptions.getLaunchTaskId());
Wale Ogunwale21e06482019-11-18 05:14:15 -08002052 final ActivityRecord top = task != null
2053 ? task.getTopNonFinishingActivity() : null;
Bryce Lee7ace3952018-02-16 14:34:32 -08002054 if (top != null && !top.isState(RESUMED)) {
Jorim Jaggic875ae72016-04-26 22:41:06 -07002055
Winson Chunge2d72172018-01-25 17:46:20 +00002056 // The caller specifies that we'd like to be avoided to be moved to the
2057 // front, so be it!
2058 mDoResume = false;
2059 mAvoidMoveToFront = true;
2060 }
Winson Chungcbcadc92017-01-12 15:54:12 -08002061 }
Winson Chunge2d72172018-01-25 17:46:20 +00002062 } else if (mOptions.getAvoidMoveToFront()) {
Winson Chungba40d3a2018-05-16 09:40:16 -07002063 mDoResume = false;
Winson Chunge2d72172018-01-25 17:46:20 +00002064 mAvoidMoveToFront = true;
Jorim Jaggic875ae72016-04-26 22:41:06 -07002065 }
2066 }
2067
Louis Chang2f4e9b462019-03-05 16:43:15 +08002068 mNotTop = (mLaunchFlags & FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? sourceRecord : null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08002069
2070 mInTask = inTask;
2071 // In some flows in to this function, we retrieve the task record and hold on to it
2072 // without a lock before calling back in to here... so the task at this point may
2073 // not actually be in recents. Check for that, and if it isn't in recents just
2074 // consider it invalid.
2075 if (inTask != null && !inTask.inRecents) {
2076 Slog.w(TAG, "Starting activity in task not in recents: " + inTask);
2077 mInTask = null;
2078 }
2079
2080 mStartFlags = startFlags;
2081 // If the onlyIfNeeded flag is set, then we can do this if the activity being launched
2082 // is the same as the one making the call... or, as a special case, if we do not know
2083 // the caller then we count the current top activity as the caller.
2084 if ((startFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
2085 ActivityRecord checkedCaller = sourceRecord;
2086 if (checkedCaller == null) {
Louis Chang149d5c82019-12-30 09:47:39 +08002087 checkedCaller = mRootWindowContainer.getTopDisplayFocusedStack()
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002088 .topRunningNonDelayedActivityLocked(mNotTop);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002089 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002090 if (!checkedCaller.mActivityComponent.equals(r.mActivityComponent)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002091 // Caller is not the same as launcher, so always needed.
2092 mStartFlags &= ~START_FLAG_ONLY_IF_NEEDED;
2093 }
2094 }
2095
2096 mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0;
Ricky Waib147fa12019-04-25 16:08:30 +01002097
Alan Stokes07389b62019-05-20 15:22:54 +01002098 if (mRestrictedBgActivity && !mService.isBackgroundActivityStartsEnabled()) {
Ricky Waib147fa12019-04-25 16:08:30 +01002099 mAvoidMoveToFront = true;
2100 mDoResume = false;
2101 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002102 }
2103
2104 private void sendNewTaskResultRequestIfNeeded() {
Andrii Kulian79d67982019-08-19 11:56:16 -07002105 if (mStartActivity.resultTo != null && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002106 // For whatever reason this activity is being launched into a new task...
2107 // yet the caller has requested a result back. Well, that is pretty messed up,
2108 // so instead immediately send back a cancel and let the new task continue launched
2109 // as normal without a dependency on its originator.
2110 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
Andrii Kulian79d67982019-08-19 11:56:16 -07002111 mStartActivity.resultTo.sendResult(INVALID_UID, mStartActivity.resultWho,
2112 mStartActivity.requestCode, RESULT_CANCELED, null /* data */);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002113 mStartActivity.resultTo = null;
2114 }
2115 }
2116
2117 private void computeLaunchingTaskFlags() {
2118 // If the caller is not coming from another activity, but has given us an explicit task into
2119 // which they would like us to launch the new activity, then let's see about doing that.
Andrii Kulian02b7a832016-10-06 23:11:56 -07002120 if (mSourceRecord == null && mInTask != null && mInTask.getStack() != null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002121 final Intent baseIntent = mInTask.getBaseIntent();
2122 final ActivityRecord root = mInTask.getRootActivity();
2123 if (baseIntent == null) {
2124 ActivityOptions.abort(mOptions);
2125 throw new IllegalArgumentException("Launching into task without base intent: "
2126 + mInTask);
2127 }
2128
2129 // If this task is empty, then we are adding the first activity -- it
2130 // determines the root, and must be launching as a NEW_TASK.
Bryce Lee7daee392017-10-12 13:46:18 -07002131 if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002132 if (!baseIntent.getComponent().equals(mStartActivity.intent.getComponent())) {
2133 ActivityOptions.abort(mOptions);
2134 throw new IllegalArgumentException("Trying to launch singleInstance/Task "
2135 + mStartActivity + " into different task " + mInTask);
2136 }
2137 if (root != null) {
2138 ActivityOptions.abort(mOptions);
2139 throw new IllegalArgumentException("Caller with mInTask " + mInTask
2140 + " has root " + root + " but target is singleInstance/Task");
2141 }
2142 }
2143
2144 // If task is empty, then adopt the interesting intent launch flags in to the
2145 // activity being started.
2146 if (root == null) {
2147 final int flagsOfInterest = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK
2148 | FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS;
2149 mLaunchFlags = (mLaunchFlags & ~flagsOfInterest)
2150 | (baseIntent.getFlags() & flagsOfInterest);
2151 mIntent.setFlags(mLaunchFlags);
2152 mInTask.setIntent(mStartActivity);
2153 mAddingToTask = true;
2154
2155 // If the task is not empty and the caller is asking to start it as the root of
2156 // a new task, then we don't actually want to start this on the task. We will
2157 // bring the task to the front, and possibly give it a new intent.
2158 } else if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
2159 mAddingToTask = false;
2160
2161 } else {
2162 mAddingToTask = true;
2163 }
2164
2165 mReuseTask = mInTask;
2166 } else {
2167 mInTask = null;
2168 // Launch ResolverActivity in the source task, so that it stays in the task bounds
2169 // when in freeform workspace.
2170 // Also put noDisplay activities in the source task. These by itself can be placed
2171 // in any task/stack, however it could launch other activities like ResolverActivity,
2172 // and we want those to stay in the original task.
Louis Chang6a9be162019-07-15 10:41:32 +08002173 if ((mStartActivity.isResolverOrDelegateActivity() || mStartActivity.noDisplay)
2174 && mSourceRecord != null && mSourceRecord.inFreeformWindowingMode()) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002175 mAddingToTask = true;
2176 }
2177 }
2178
2179 if (mInTask == null) {
2180 if (mSourceRecord == null) {
2181 // This activity is not being started from another... in this
2182 // case we -always- start a new task.
2183 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) {
2184 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
2185 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
2186 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2187 }
2188 } else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) {
2189 // The original activity who is starting us is running as a single
2190 // instance... this new activity it is starting must go on its
2191 // own task.
2192 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
Bryce Lee7daee392017-10-12 13:46:18 -07002193 } else if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002194 // The activity being started is a single instance... it always
2195 // gets launched into its own task.
2196 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2197 }
2198 }
2199 }
2200
2201 private void computeSourceStack() {
2202 if (mSourceRecord == null) {
2203 mSourceStack = null;
2204 return;
2205 }
2206 if (!mSourceRecord.finishing) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002207 mSourceStack = mSourceRecord.getActivityStack();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002208 return;
2209 }
2210
2211 // If the source is finishing, we can't further count it as our source. This is because the
2212 // task it is associated with may now be empty and on its way out, so we don't want to
2213 // blindly throw it in to that task. Instead we will take the NEW_TASK flow and try to find
2214 // a task for it. But save the task information so it can be used when creating the new task.
2215 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0) {
2216 Slog.w(TAG, "startActivity called from finishing " + mSourceRecord
2217 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
2218 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2219 mNewTaskInfo = mSourceRecord.info;
Bryce Leed9ed45d2017-05-22 15:57:24 -07002220
2221 // It is not guaranteed that the source record will have a task associated with it. For,
2222 // example, if this method is being called for processing a pending activity launch, it
2223 // is possible that the activity has been removed from the task after the launch was
2224 // enqueued.
Louis Changcdec0802019-11-11 11:45:07 +08002225 final Task sourceTask = mSourceRecord.getTask();
Bryce Leed9ed45d2017-05-22 15:57:24 -07002226 mNewTaskIntent = sourceTask != null ? sourceTask.intent : null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08002227 }
2228 mSourceRecord = null;
2229 mSourceStack = null;
2230 }
2231
2232 /**
2233 * Decide whether the new activity should be inserted into an existing task. Returns null
2234 * if not or an ActivityRecord with the task into which the new activity should be added.
2235 */
Louis Changcdec0802019-11-11 11:45:07 +08002236 private Task getReusableTask() {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002237 // We may want to try to place the new activity in to an existing task. We always
2238 // do this if the target activity is singleTask or singleInstance; we will also do
2239 // this if NEW_TASK has been requested, and there is not an additional qualifier telling
2240 // us to still place it in a new task: multi task, always doc mode, or being asked to
2241 // launch this as a new task behind the current one.
2242 boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 &&
2243 (mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
Bryce Lee7daee392017-10-12 13:46:18 -07002244 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002245 // If bring to front is requested, and no result is requested and we have not been given
2246 // an explicit task to launch in to, and we can find a task that was started with this
2247 // same component, then instead of launching bring that one to the front.
2248 putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null;
2249 ActivityRecord intentActivity = null;
Jorim Jaggi2adba072016-03-03 13:43:39 +01002250 if (mOptions != null && mOptions.getLaunchTaskId() != -1) {
Louis Chang149d5c82019-12-30 09:47:39 +08002251 Task launchTask = mRootWindowContainer.anyTaskForId(mOptions.getLaunchTaskId());
Louis Changf7dd7f22019-11-05 11:59:56 +08002252 if (launchTask != null) {
2253 return launchTask;
2254 }
Jorim Jaggi2adba072016-03-03 13:43:39 +01002255 } else if (putIntoExistingTask) {
Bryce Lee7daee392017-10-12 13:46:18 -07002256 if (LAUNCH_SINGLE_INSTANCE == mLaunchMode) {
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07002257 // There can be one and only one instance of single instance activity in the
2258 // history, and it is always in its own unique task, so we do a special search.
Louis Chang149d5c82019-12-30 09:47:39 +08002259 intentActivity = mRootWindowContainer.findActivity(mIntent, mStartActivity.info,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07002260 mStartActivity.isActivityTypeHome());
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07002261 } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
2262 // For the launch adjacent case we only want to put the activity in an existing
2263 // task if the activity already exists in the history.
Louis Chang149d5c82019-12-30 09:47:39 +08002264 intentActivity = mRootWindowContainer.findActivity(mIntent, mStartActivity.info,
Bryce Lee7daee392017-10-12 13:46:18 -07002265 !(LAUNCH_SINGLE_TASK == mLaunchMode));
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07002266 } else {
2267 // Otherwise find the best task to put the activity in.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002268 intentActivity =
Louis Chang149d5c82019-12-30 09:47:39 +08002269 mRootWindowContainer.findTask(mStartActivity, mPreferredDisplayId);
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07002270 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002271 }
Louis Changbd48dca2018-08-29 17:44:34 +08002272
Louis Chang54506cb2018-11-23 11:03:41 +08002273 if (intentActivity != null
2274 && (mStartActivity.isActivityTypeHome() || intentActivity.isActivityTypeHome())
Louis Changbd48dca2018-08-29 17:44:34 +08002275 && intentActivity.getDisplayId() != mPreferredDisplayId) {
2276 // Do not reuse home activity on other displays.
2277 intentActivity = null;
2278 }
2279
Louis Changcdec0802019-11-11 11:45:07 +08002280 return intentActivity != null ? intentActivity.getTask() : null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08002281 }
2282
Andrii Kulianfab9cd82017-03-21 19:37:09 -07002283 /**
2284 * Figure out which task and activity to bring to front when we have found an existing matching
2285 * activity record in history. May also clear the task if needed.
2286 * @param intentActivity Existing matching activity.
2287 * @return {@link ActivityRecord} brought to front.
2288 */
Louis Changbde91e92019-08-16 17:19:47 +08002289 private void setTargetStackIfNeeded(ActivityRecord intentActivity) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002290 mTargetStack = intentActivity.getActivityStack();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002291 mTargetStack.mLastPausedActivity = null;
2292 // If the target task is not in the front, then we need to bring it to the front...
2293 // except... well, with SINGLE_TASK_LAUNCH it's not entirely clear. We'd like to have
2294 // the same behavior as if a new instance was being started, which means not bringing it
2295 // to the front if the caller is not itself in the front.
Riddle Hsub70b36d2018-09-11 21:20:02 +08002296 final boolean differentTopTask;
Wale Ogunwale0b3d2922019-12-30 08:55:07 -08002297 if (mPreferredDisplayId == mTargetStack.getDisplayId()) {
Riddle Hsub70b36d2018-09-11 21:20:02 +08002298 final ActivityStack focusStack = mTargetStack.getDisplay().getFocusedStack();
2299 final ActivityRecord curTop = (focusStack == null)
2300 ? null : focusStack.topRunningNonDelayedActivityLocked(mNotTop);
Louis Changcdec0802019-11-11 11:45:07 +08002301 final Task topTask = curTop != null ? curTop.getTask() : null;
2302 differentTopTask = topTask != intentActivity.getTask()
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09002303 || (focusStack != null && topTask != focusStack.getTopMostTask());
Riddle Hsub70b36d2018-09-11 21:20:02 +08002304 } else {
2305 // The existing task should always be different from those in other displays.
2306 differentTopTask = true;
2307 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002308
Riddle Hsub70b36d2018-09-11 21:20:02 +08002309 if (differentTopTask && !mAvoidMoveToFront) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002310 mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Wale Ogunwale21e06482019-11-18 05:14:15 -08002311 if (mSourceRecord == null || (mSourceStack.getTopNonFinishingActivity() != null &&
2312 mSourceStack.getTopNonFinishingActivity().getTask()
Louis Changcdec0802019-11-11 11:45:07 +08002313 == mSourceRecord.getTask())) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002314 // We really do want to push this one into the user's face, right now.
2315 if (mLaunchTaskBehind && mSourceRecord != null) {
Louis Changcdec0802019-11-11 11:45:07 +08002316 intentActivity.setTaskToAffiliateWith(mSourceRecord.getTask());
Wale Ogunwale01d66562015-12-29 08:19:19 -08002317 }
Chong Zhangdea4bd92016-03-15 12:50:03 -07002318
Louis Changcdec0802019-11-11 11:45:07 +08002319 final Task intentTask = intentActivity.getTask();
Louis Changf3070c52019-10-09 15:57:30 +08002320 final ActivityStack launchStack =
2321 getLaunchStack(mStartActivity, mLaunchFlags, intentTask, mOptions);
Louis Changbde91e92019-08-16 17:19:47 +08002322 if (launchStack == null || launchStack == mTargetStack) {
2323 // We only want to move to the front, if we aren't going to launch on a
2324 // different stack. If we launch on a different stack, we will put the
2325 // task on top there.
2326 mTargetStack.moveTaskToFrontLocked(intentTask, mNoAnimation, mOptions,
2327 mStartActivity.appTimeTracker, "bringingFoundTaskToFront");
2328 mMovedToFront = true;
2329 } else if (launchStack.inSplitScreenWindowingMode()) {
2330 if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
2331 // If we want to launch adjacent and mTargetStack is not the computed
2332 // launch stack - move task to top of computed stack.
2333 intentTask.reparent(launchStack, ON_TOP,
Andrii Kulianfab9cd82017-03-21 19:37:09 -07002334 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
Louis Changbde91e92019-08-16 17:19:47 +08002335 "launchToSide");
2336 } else {
2337 // TODO: This should be reevaluated in MW v2.
2338 // We choose to move task to front instead of launching it adjacent
2339 // when specific stack was requested explicitly and it appeared to be
2340 // adjacent stack, but FLAG_ACTIVITY_LAUNCH_ADJACENT was not set.
2341 mTargetStack.moveTaskToFrontLocked(intentTask,
2342 mNoAnimation, mOptions, mStartActivity.appTimeTracker,
2343 "bringToFrontInsteadOfAdjacentLaunch");
Chong Zhangdea4bd92016-03-15 12:50:03 -07002344 }
Louis Changbde91e92019-08-16 17:19:47 +08002345 mMovedToFront = launchStack != launchStack.getDisplay()
2346 .getTopStackInWindowingMode(launchStack.getWindowingMode());
Wale Ogunwale0b3d2922019-12-30 08:55:07 -08002347 } else if (launchStack.getDisplayId() != mTargetStack.getDisplayId()) {
Louis Changbde91e92019-08-16 17:19:47 +08002348 // Target and computed stacks are on different displays and we've
2349 // found a matching task - move the existing instance to that display and
2350 // move it to front.
Louis Changcdec0802019-11-11 11:45:07 +08002351 intentActivity.getTask().reparent(launchStack, ON_TOP,
Louis Changbde91e92019-08-16 17:19:47 +08002352 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
2353 "reparentToDisplay");
2354 mMovedToFront = true;
2355 } else if (launchStack.isActivityTypeHome()
2356 && !mTargetStack.isActivityTypeHome()) {
2357 // It is possible for the home activity to be in another stack initially.
2358 // For example, the activity may have been initially started with an intent
2359 // which placed it in the fullscreen stack. To ensure the proper handling of
2360 // the activity based on home stack assumptions, we must move it over.
Louis Changcdec0802019-11-11 11:45:07 +08002361 intentActivity.getTask().reparent(launchStack, ON_TOP,
Louis Changbde91e92019-08-16 17:19:47 +08002362 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
2363 "reparentingHome");
2364 mMovedToFront = true;
Louis Changf3070c52019-10-09 15:57:30 +08002365 }
2366
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09002367 if (launchStack != null && launchStack.getTopMostTask() == null) {
Louis Changfe0dfcb2019-09-02 15:59:38 +08002368 // The task does not need to be reparented to the launch stack. Remove the
2369 // launch stack if there is no activity in it.
Louis Changf3070c52019-10-09 15:57:30 +08002370 Slog.w(TAG, "Removing an empty stack: " + launchStack);
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -07002371 launchStack.removeIfPossible();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002372 }
Louis Changfe0dfcb2019-09-02 15:59:38 +08002373
Louis Changbde91e92019-08-16 17:19:47 +08002374 mOptions = null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08002375 }
2376 }
Andrii Kulianb850ea52017-12-12 23:49:10 -08002377 // Need to update mTargetStack because if task was moved out of it, the original stack may
2378 // be destroyed.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002379 mTargetStack = intentActivity.getActivityStack();
Louis Changcdec0802019-11-11 11:45:07 +08002380 mSupervisor.handleNonResizableTaskIfNeeded(intentActivity.getTask(),
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07002381 WINDOWING_MODE_UNDEFINED, DEFAULT_DISPLAY, mTargetStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002382 }
2383
2384 private void resumeTargetStackIfNeeded() {
2385 if (mDoResume) {
Louis Chang149d5c82019-12-30 09:47:39 +08002386 mRootWindowContainer.resumeFocusedStacksTopActivities(mTargetStack, null, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002387 } else {
2388 ActivityOptions.abort(mOptions);
2389 }
Louis Chang149d5c82019-12-30 09:47:39 +08002390 mRootWindowContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002391 }
2392
Louis Changcdec0802019-11-11 11:45:07 +08002393 private void setNewTask(Task taskToAffiliate) {
Louis Changbde91e92019-08-16 17:19:47 +08002394 final boolean toTop = !mLaunchTaskBehind && !mAvoidMoveToFront;
Louis Changcdec0802019-11-11 11:45:07 +08002395 final Task task = mTargetStack.createTask(
Wale Ogunwale0b3d2922019-12-30 08:55:07 -08002396 mSupervisor.getNextTaskIdForUser(mStartActivity.mUserId),
Louis Changbde91e92019-08-16 17:19:47 +08002397 mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
2398 mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
2399 mVoiceInteractor, toTop, mStartActivity, mSourceRecord, mOptions);
2400 addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
Louis Changcdec0802019-11-11 11:45:07 +08002401 updateBounds(mStartActivity.getTask(), mLaunchParams.mBounds);
Louis Change8902452019-06-10 10:49:28 +08002402
Louis Changbde91e92019-08-16 17:19:47 +08002403 if (DEBUG_TASKS) {
2404 Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Louis Changcdec0802019-11-11 11:45:07 +08002405 + " in new task " + mStartActivity.getTask());
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002406 }
2407
2408 if (taskToAffiliate != null) {
2409 mStartActivity.setTaskToAffiliateWith(taskToAffiliate);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002410 }
2411 }
2412
Bryce Lee325e09682017-10-05 17:20:25 -07002413 private void deliverNewIntent(ActivityRecord activity) {
2414 if (mIntentDelivered) {
2415 return;
2416 }
2417
Jeff Changd136e772019-11-05 20:33:52 +08002418 activity.logStartActivity(EventLogTags.WM_NEW_INTENT, activity.getTask());
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00002419 activity.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
Bryce Lee325e09682017-10-05 17:20:25 -07002420 mStartActivity.launchedFromPackage);
2421 mIntentDelivered = true;
2422 }
2423
Bryce Leed3624e12017-11-30 08:51:45 -08002424 @VisibleForTesting
Louis Changcdec0802019-11-11 11:45:07 +08002425 void updateBounds(Task task, Rect bounds) {
Bryce Leedacefc42017-10-10 12:56:02 -07002426 if (bounds.isEmpty()) {
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002427 return;
2428 }
2429
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002430 final ActivityStack stack = task.getStack();
Evan Roskydbe2ce52019-07-18 11:13:17 -07002431 if (stack != null && stack.inPinnedWindowingMode()) {
2432 mService.animateResizePinnedStack(stack.mStackId, bounds, -1);
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002433 } else {
Evan Roskya4cc3a92019-06-28 13:25:01 -07002434 task.setBounds(bounds);
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002435 }
2436 }
2437
Louis Changcdec0802019-11-11 11:45:07 +08002438 private void addOrReparentStartingActivity(Task parent, String reason) {
2439 if (mStartActivity.getTask() == null || mStartActivity.getTask() == parent) {
Wale Ogunwalec17418e2019-10-13 23:00:40 +02002440 parent.addChild(mStartActivity);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002441 } else {
Wale Ogunwale1a06f152019-10-11 11:26:30 +02002442 mStartActivity.reparent(parent, parent.getChildCount() /* top */, reason);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002443 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002444 }
2445
2446 private int adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance,
2447 boolean launchSingleTask, int launchFlags) {
2448 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2449 (launchSingleInstance || launchSingleTask)) {
2450 // We have a conflict between the Intent and the Activity manifest, manifest wins.
2451 Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " +
2452 "\"singleInstance\" or \"singleTask\"");
2453 launchFlags &=
2454 ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK);
2455 } else {
2456 switch (r.info.documentLaunchMode) {
2457 case ActivityInfo.DOCUMENT_LAUNCH_NONE:
2458 break;
2459 case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
2460 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2461 break;
2462 case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
2463 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2464 break;
2465 case ActivityInfo.DOCUMENT_LAUNCH_NEVER:
2466 launchFlags &= ~FLAG_ACTIVITY_MULTIPLE_TASK;
2467 break;
2468 }
2469 }
2470 return launchFlags;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002471 }
2472
Bryce Leedacefc42017-10-10 12:56:02 -07002473 private ActivityStack computeStackFocus(ActivityRecord r, boolean newTask, int launchFlags,
2474 ActivityOptions aOptions) {
Louis Changcdec0802019-11-11 11:45:07 +08002475 final Task task = r.getTask();
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002476 ActivityStack stack = getLaunchStack(r, launchFlags, task, aOptions);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002477 if (stack != null) {
2478 return stack;
2479 }
2480
Andrii Kulian02b7a832016-10-06 23:11:56 -07002481 final ActivityStack currentStack = task != null ? task.getStack() : null;
Louis Chang149d5c82019-12-30 09:47:39 +08002482 final ActivityStack focusedStack = mRootWindowContainer.getTopDisplayFocusedStack();
Andrii Kulian02b7a832016-10-06 23:11:56 -07002483 if (currentStack != null) {
Andrii Kulian52d255c2018-07-13 11:32:19 -07002484 if (focusedStack != currentStack) {
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002485 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
2486 "computeStackFocus: Setting " + "focused stack to r=" + r
2487 + " task=" + task);
2488 } else {
2489 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
Andrii Kulian52d255c2018-07-13 11:32:19 -07002490 "computeStackFocus: Focused stack already=" + focusedStack);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002491 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07002492 return currentStack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002493 }
2494
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002495 if (canLaunchIntoFocusedStack(r, newTask)) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002496 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
Andrii Kulian52d255c2018-07-13 11:32:19 -07002497 "computeStackFocus: Have a focused stack=" + focusedStack);
2498 return focusedStack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002499 }
2500
David Stevense5a7b642017-05-22 13:18:23 -07002501 if (mPreferredDisplayId != DEFAULT_DISPLAY) {
Andrii Kuliana8fe3df2017-06-16 15:29:26 -07002502 // Try to put the activity in a stack on a secondary display.
Louis Chang149d5c82019-12-30 09:47:39 +08002503 stack = mRootWindowContainer.getValidLaunchStackOnDisplay(
Wale Ogunwaled32da472018-11-16 07:19:28 -08002504 mPreferredDisplayId, r, aOptions, mLaunchParams);
Andrii Kuliana8fe3df2017-06-16 15:29:26 -07002505 if (stack == null) {
2506 // If source display is not suitable - look for topmost valid stack in the system.
2507 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
David Stevense5a7b642017-05-22 13:18:23 -07002508 "computeStackFocus: Can't launch on mPreferredDisplayId="
2509 + mPreferredDisplayId + ", looking on all displays.");
Louis Chang149d5c82019-12-30 09:47:39 +08002510 stack = mRootWindowContainer.getNextValidLaunchStack(r, mPreferredDisplayId);
Andrii Kuliana8fe3df2017-06-16 15:29:26 -07002511 }
2512 }
2513 if (stack == null) {
Louis Chang149d5c82019-12-30 09:47:39 +08002514 stack = mRootWindowContainer.getLaunchStack(r, aOptions, task, ON_TOP);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002515 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002516 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, "computeStackFocus: New stack r="
2517 + r + " stackId=" + stack.mStackId);
2518 return stack;
2519 }
2520
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002521 /** Check if provided activity record can launch in currently focused stack. */
Wale Ogunwale68278562017-09-23 17:13:55 -07002522 // TODO: This method can probably be consolidated into getLaunchStack() below.
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002523 private boolean canLaunchIntoFocusedStack(ActivityRecord r, boolean newTask) {
Louis Chang149d5c82019-12-30 09:47:39 +08002524 final ActivityStack focusedStack = mRootWindowContainer.getTopDisplayFocusedStack();
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002525 final boolean canUseFocusedStack;
Wale Ogunwale68278562017-09-23 17:13:55 -07002526 if (focusedStack.isActivityTypeAssistant()) {
2527 canUseFocusedStack = r.isActivityTypeAssistant();
2528 } else {
2529 switch (focusedStack.getWindowingMode()) {
2530 case WINDOWING_MODE_FULLSCREEN:
2531 // The fullscreen stack can contain any task regardless of if the task is
2532 // resizeable or not. So, we let the task go in the fullscreen task if it is the
2533 // focus stack.
2534 canUseFocusedStack = true;
2535 break;
2536 case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
2537 case WINDOWING_MODE_SPLIT_SCREEN_SECONDARY:
2538 // Any activity which supports split screen can go in the docked stack.
2539 canUseFocusedStack = r.supportsSplitScreenWindowingMode();
2540 break;
2541 case WINDOWING_MODE_FREEFORM:
2542 // Any activity which supports freeform can go in the freeform stack.
2543 canUseFocusedStack = r.supportsFreeform();
2544 break;
2545 default:
2546 // Dynamic stacks behave similarly to the fullscreen stack and can contain any
2547 // resizeable task.
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002548 canUseFocusedStack = !focusedStack.isOnHomeDisplay()
Wale Ogunwale0b3d2922019-12-30 08:55:07 -08002549 && r.canBeLaunchedOnDisplay(focusedStack.getDisplayId());
Wale Ogunwale68278562017-09-23 17:13:55 -07002550 }
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002551 }
Andrii Kulian94e82d9b02017-07-13 15:33:06 -07002552 return canUseFocusedStack && !newTask
Wale Ogunwale68278562017-09-23 17:13:55 -07002553 // Using the focus stack isn't important enough to override the preferred display.
Wale Ogunwale0b3d2922019-12-30 08:55:07 -08002554 && (mPreferredDisplayId == focusedStack.getDisplayId());
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002555 }
2556
Louis Changcdec0802019-11-11 11:45:07 +08002557 private ActivityStack getLaunchStack(ActivityRecord r, int launchFlags, Task task,
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002558 ActivityOptions aOptions) {
Bryce Leea19b5ad2017-06-07 16:54:11 -07002559 // We are reusing a task, keep the stack!
2560 if (mReuseTask != null) {
2561 return mReuseTask.getStack();
2562 }
Jorim Jaggib8c58762016-04-20 17:58:29 -07002563
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -08002564 if (((launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) == 0)
David Stevense5a7b642017-05-22 13:18:23 -07002565 || mPreferredDisplayId != DEFAULT_DISPLAY) {
Louis Chang37317152019-05-09 09:53:58 +08002566 final boolean onTop =
2567 (aOptions == null || !aOptions.getAvoidMoveToFront()) && !mLaunchTaskBehind;
Wale Ogunwaled32da472018-11-16 07:19:28 -08002568 final ActivityStack stack =
Louis Chang149d5c82019-12-30 09:47:39 +08002569 mRootWindowContainer.getLaunchStack(r, aOptions, task, onTop, mLaunchParams,
lumarkf65e02d2019-09-14 19:25:21 +08002570 mRequest.realCallingPid, mRequest.realCallingUid);
Garfield Tan20d9e2f2018-11-16 15:42:29 -08002571 return stack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002572 }
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002573 // Otherwise handle adjacent launch.
Wale Ogunwale854809c2015-12-27 16:18:19 -08002574
Louis Chang149d5c82019-12-30 09:47:39 +08002575 final ActivityStack focusedStack = mRootWindowContainer.getTopDisplayFocusedStack();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002576 // The parent activity doesn't want to launch the activity on top of itself, but
2577 // instead tries to put it onto other side in side-by-side mode.
Andrii Kulian52d255c2018-07-13 11:32:19 -07002578 final ActivityStack parentStack = task != null ? task.getStack(): focusedStack;
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002579
Andrii Kulian52d255c2018-07-13 11:32:19 -07002580 if (parentStack != focusedStack) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002581 // If task's parent stack is not focused - use it during adjacent launch.
2582 return parentStack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002583 } else {
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09002584 if (focusedStack != null && task == focusedStack.getTopMostTask()) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002585 // If task is already on top of focused stack - use it. We don't want to move the
2586 // existing focused task to adjacent stack, just deliver new intent in this case.
Andrii Kulian52d255c2018-07-13 11:32:19 -07002587 return focusedStack;
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002588 }
2589
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002590 if (parentStack != null && parentStack.inSplitScreenPrimaryWindowingMode()) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002591 // If parent was in docked stack, the natural place to launch another activity
2592 // will be fullscreen, so it can appear alongside the docked window.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002593 final int activityType =
Louis Chang149d5c82019-12-30 09:47:39 +08002594 mRootWindowContainer.resolveActivityType(r, mOptions, task);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002595 return parentStack.getDisplay().getOrCreateStack(
2596 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, activityType, ON_TOP);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002597 } else {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002598 // If the parent is not in the docked stack, we check if there is docked window
2599 // and if yes, we will launch into that stack. If not, we just put the new
2600 // activity into parent's stack, because we can't find a better place.
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07002601 final ActivityStack dockedStack =
Louis Chang149d5c82019-12-30 09:47:39 +08002602 mRootWindowContainer.getDefaultDisplay().getSplitScreenPrimaryStack();
Wale Ogunwale9dcf9462017-09-19 15:13:01 -07002603 if (dockedStack != null && !dockedStack.shouldBeVisible(r)) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002604 // There is a docked stack, but it isn't visible, so we can't launch into that.
Louis Chang149d5c82019-12-30 09:47:39 +08002605 return mRootWindowContainer.getLaunchStack(r, aOptions, task, ON_TOP);
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002606 } else {
2607 return dockedStack;
2608 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002609 }
2610 }
2611 }
2612
Bryce Lee7daee392017-10-12 13:46:18 -07002613 private boolean isLaunchModeOneOf(int mode1, int mode2) {
2614 return mode1 == mLaunchMode || mode2 == mLaunchMode;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002615 }
2616
Daichi Hirono15a02992016-04-27 18:47:01 +09002617 static boolean isDocumentLaunchesIntoExisting(int flags) {
2618 return (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2619 (flags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0;
2620 }
liulvpingcfa825f2016-09-26 20:00:15 +08002621
Bryce Lee4c9a5972017-12-01 22:14:24 -08002622 ActivityStarter setIntent(Intent intent) {
2623 mRequest.intent = intent;
2624 return this;
2625 }
2626
Bryce Lee32e09ef2018-03-19 15:29:49 -07002627 @VisibleForTesting
2628 Intent getIntent() {
2629 return mRequest.intent;
2630 }
2631
Bryce Lee4c9a5972017-12-01 22:14:24 -08002632 ActivityStarter setReason(String reason) {
2633 mRequest.reason = reason;
2634 return this;
2635 }
2636
2637 ActivityStarter setCaller(IApplicationThread caller) {
2638 mRequest.caller = caller;
2639 return this;
2640 }
2641
Bryce Lee4c9a5972017-12-01 22:14:24 -08002642 ActivityStarter setResolvedType(String type) {
2643 mRequest.resolvedType = type;
2644 return this;
2645 }
2646
2647 ActivityStarter setActivityInfo(ActivityInfo info) {
2648 mRequest.activityInfo = info;
2649 return this;
2650 }
2651
2652 ActivityStarter setResolveInfo(ResolveInfo info) {
2653 mRequest.resolveInfo = info;
2654 return this;
2655 }
2656
2657 ActivityStarter setVoiceSession(IVoiceInteractionSession voiceSession) {
2658 mRequest.voiceSession = voiceSession;
2659 return this;
2660 }
2661
2662 ActivityStarter setVoiceInteractor(IVoiceInteractor voiceInteractor) {
2663 mRequest.voiceInteractor = voiceInteractor;
2664 return this;
2665 }
2666
2667 ActivityStarter setResultTo(IBinder resultTo) {
2668 mRequest.resultTo = resultTo;
2669 return this;
2670 }
2671
2672 ActivityStarter setResultWho(String resultWho) {
2673 mRequest.resultWho = resultWho;
2674 return this;
2675 }
2676
2677 ActivityStarter setRequestCode(int requestCode) {
2678 mRequest.requestCode = requestCode;
2679 return this;
2680 }
2681
lumarkf65e02d2019-09-14 19:25:21 +08002682 /**
2683 * Sets the pid of the caller who originally started the activity.
2684 *
2685 * Normally, the pid/uid would be the calling pid from the binder call.
2686 * However, in case of a {@link PendingIntent}, the pid/uid pair of the caller is considered
2687 * the original entity that created the pending intent, in contrast to setRealCallingPid/Uid,
2688 * which represents the entity who invoked pending intent via {@link PendingIntent#send}.
2689 */
Bryce Lee4c9a5972017-12-01 22:14:24 -08002690 ActivityStarter setCallingPid(int pid) {
2691 mRequest.callingPid = pid;
2692 return this;
2693 }
2694
lumarkf65e02d2019-09-14 19:25:21 +08002695 /**
2696 * Sets the uid of the caller who originally started the activity.
2697 *
2698 * @see #setCallingPid
2699 */
Bryce Lee4c9a5972017-12-01 22:14:24 -08002700 ActivityStarter setCallingUid(int uid) {
2701 mRequest.callingUid = uid;
2702 return this;
2703 }
2704
2705 ActivityStarter setCallingPackage(String callingPackage) {
2706 mRequest.callingPackage = callingPackage;
2707 return this;
2708 }
2709
lumarkf65e02d2019-09-14 19:25:21 +08002710 /**
2711 * Sets the pid of the caller who requested to launch the activity.
2712 *
2713 * The pid/uid represents the caller who launches the activity in this request.
2714 * It will almost same as setCallingPid/Uid except when processing {@link PendingIntent}:
2715 * the pid/uid will be the caller who called {@link PendingIntent#send()}.
2716 *
2717 * @see #setCallingPid
2718 */
Bryce Lee4c9a5972017-12-01 22:14:24 -08002719 ActivityStarter setRealCallingPid(int pid) {
2720 mRequest.realCallingPid = pid;
2721 return this;
2722 }
2723
lumarkf65e02d2019-09-14 19:25:21 +08002724 /**
2725 * Sets the uid of the caller who requested to launch the activity.
2726 *
2727 * @see #setRealCallingPid
2728 */
Bryce Lee4c9a5972017-12-01 22:14:24 -08002729 ActivityStarter setRealCallingUid(int uid) {
2730 mRequest.realCallingUid = uid;
2731 return this;
2732 }
2733
2734 ActivityStarter setStartFlags(int startFlags) {
2735 mRequest.startFlags = startFlags;
2736 return this;
2737 }
2738
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002739 ActivityStarter setActivityOptions(SafeActivityOptions options) {
Bryce Lee4c9a5972017-12-01 22:14:24 -08002740 mRequest.activityOptions = options;
2741 return this;
2742 }
2743
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002744 ActivityStarter setActivityOptions(Bundle bOptions) {
2745 return setActivityOptions(SafeActivityOptions.fromBundle(bOptions));
2746 }
2747
Bryce Lee4c9a5972017-12-01 22:14:24 -08002748 ActivityStarter setIgnoreTargetSecurity(boolean ignoreTargetSecurity) {
2749 mRequest.ignoreTargetSecurity = ignoreTargetSecurity;
2750 return this;
2751 }
2752
Patrick Baumann31426b22018-05-21 13:46:40 -07002753 ActivityStarter setFilterCallingUid(int filterCallingUid) {
2754 mRequest.filterCallingUid = filterCallingUid;
2755 return this;
2756 }
2757
Bryce Lee4c9a5972017-12-01 22:14:24 -08002758 ActivityStarter setComponentSpecified(boolean componentSpecified) {
2759 mRequest.componentSpecified = componentSpecified;
2760 return this;
2761 }
2762
2763 ActivityStarter setOutActivity(ActivityRecord[] outActivity) {
2764 mRequest.outActivity = outActivity;
2765 return this;
2766 }
2767
Louis Changcdec0802019-11-11 11:45:07 +08002768 ActivityStarter setInTask(Task inTask) {
Bryce Lee4c9a5972017-12-01 22:14:24 -08002769 mRequest.inTask = inTask;
2770 return this;
2771 }
2772
2773 ActivityStarter setWaitResult(WaitResult result) {
2774 mRequest.waitResult = result;
2775 return this;
2776 }
2777
2778 ActivityStarter setProfilerInfo(ProfilerInfo info) {
2779 mRequest.profilerInfo = info;
2780 return this;
2781 }
2782
2783 ActivityStarter setGlobalConfiguration(Configuration config) {
2784 mRequest.globalConfig = config;
2785 return this;
2786 }
2787
Bryce Lee4c9a5972017-12-01 22:14:24 -08002788 ActivityStarter setUserId(int userId) {
2789 mRequest.userId = userId;
2790 return this;
2791 }
2792
Jorim Jaggi6fa41c32018-04-23 18:35:00 +02002793 ActivityStarter setAllowPendingRemoteAnimationRegistryLookup(boolean allowLookup) {
2794 mRequest.allowPendingRemoteAnimationRegistryLookup = allowLookup;
2795 return this;
2796 }
2797
Michal Karpinski201bc0c2018-07-20 15:32:00 +01002798 ActivityStarter setOriginatingPendingIntent(PendingIntentRecord originatingPendingIntent) {
2799 mRequest.originatingPendingIntent = originatingPendingIntent;
2800 return this;
2801 }
2802
Michal Karpinskiac116df2018-12-10 17:51:42 +00002803 ActivityStarter setAllowBackgroundActivityStart(boolean allowBackgroundActivityStart) {
2804 mRequest.allowBackgroundActivityStart = allowBackgroundActivityStart;
2805 return this;
2806 }
2807
Bryce Leed3624e12017-11-30 08:51:45 -08002808 void dump(PrintWriter pw, String prefix) {
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002809 prefix = prefix + " ";
Dianne Hackborne676ec72017-07-25 10:55:08 -07002810 pw.print(prefix);
2811 pw.print("mCurrentUser=");
Louis Chang149d5c82019-12-30 09:47:39 +08002812 pw.println(mRootWindowContainer.mCurrentUser);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002813 pw.print(prefix);
2814 pw.print("mLastStartReason=");
2815 pw.println(mLastStartReason);
2816 pw.print(prefix);
2817 pw.print("mLastStartActivityTimeMs=");
2818 pw.println(DateFormat.getDateTimeInstance().format(new Date(mLastStartActivityTimeMs)));
2819 pw.print(prefix);
2820 pw.print("mLastStartActivityResult=");
2821 pw.println(mLastStartActivityResult);
Louis Chang54fbb052019-10-16 17:10:17 +08002822 if (mLastStartActivityRecord != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002823 pw.print(prefix);
2824 pw.println("mLastStartActivityRecord:");
Louis Chang54fbb052019-10-16 17:10:17 +08002825 mLastStartActivityRecord.dump(pw, prefix + " ", true /* dumpAll */);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002826 }
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002827 if (mStartActivity != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002828 pw.print(prefix);
2829 pw.println("mStartActivity:");
Garfield Tane8d84ab2019-10-11 09:49:40 -07002830 mStartActivity.dump(pw, prefix + " ", true /* dumpAll */);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002831 }
2832 if (mIntent != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002833 pw.print(prefix);
2834 pw.print("mIntent=");
2835 pw.println(mIntent);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002836 }
2837 if (mOptions != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002838 pw.print(prefix);
2839 pw.print("mOptions=");
2840 pw.println(mOptions);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002841 }
Dianne Hackborne676ec72017-07-25 10:55:08 -07002842 pw.print(prefix);
2843 pw.print("mLaunchSingleTop=");
Bryce Lee7daee392017-10-12 13:46:18 -07002844 pw.print(LAUNCH_SINGLE_TOP == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002845 pw.print(" mLaunchSingleInstance=");
Bryce Lee7daee392017-10-12 13:46:18 -07002846 pw.print(LAUNCH_SINGLE_INSTANCE == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002847 pw.print(" mLaunchSingleTask=");
Bryce Lee7daee392017-10-12 13:46:18 -07002848 pw.println(LAUNCH_SINGLE_TASK == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002849 pw.print(prefix);
2850 pw.print("mLaunchFlags=0x");
2851 pw.print(Integer.toHexString(mLaunchFlags));
2852 pw.print(" mDoResume=");
2853 pw.print(mDoResume);
2854 pw.print(" mAddingToTask=");
2855 pw.println(mAddingToTask);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002856 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002857}