blob: 8ed798c766d20e05271890925648d1f964863689 [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 Ogunwale7d7973a2018-04-05 10:25:59 -070032import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070033import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
34import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Wale Ogunwale0568aed2017-09-08 13:29:37 -070035import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080036import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
37import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
Wale Ogunwale2a25a622016-01-30 11:27:21 -080038import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080039import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
Wale Ogunwale01d66562015-12-29 08:19:19 -080040import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080041import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
Wale Ogunwale01d66562015-12-29 08:19:19 -080042import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION;
43import static android.content.Intent.FLAG_ACTIVITY_NO_USER_ACTION;
Wale Ogunwale01d66562015-12-29 08:19:19 -080044import static android.content.Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP;
45import static android.content.Intent.FLAG_ACTIVITY_REORDER_TO_FRONT;
46import static android.content.Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED;
47import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
48import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP;
Louis Changb45ee7e2019-01-17 10:36:56 +080049import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
Wale Ogunwale01d66562015-12-29 08:19:19 -080050import static android.content.pm.ActivityInfo.DOCUMENT_LAUNCH_ALWAYS;
Wale Ogunwale2322bed2019-10-10 17:24:19 +020051import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
Wale Ogunwale01d66562015-12-29 08:19:19 -080052import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
53import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
54import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
Michal Karpinski7b97a022018-12-14 15:17:29 +000055import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Andrii Kulian79d67982019-08-19 11:56:16 -070056import static android.os.Process.INVALID_UID;
David Stevensc6b91c62017-02-08 14:23:58 -080057import static android.view.Display.DEFAULT_DISPLAY;
Andrii Kulian16802aa2016-11-02 12:21:33 -070058import static android.view.Display.INVALID_DISPLAY;
Riddle Hsub70b36d2018-09-11 21:20:02 +080059
Wale Ogunwale59507092018-10-29 09:00:30 -070060import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
61import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME;
62import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
63import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
64import static com.android.server.wm.ActivityStackSupervisor.TAG_TASKS;
65import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
Wale Ogunwale59507092018-10-29 09:00:30 -070066import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
67import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS;
Wale Ogunwale59507092018-10-29 09:00:30 -070068import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
69import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_USER_LEAVING;
70import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
71import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS;
72import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RESULTS;
73import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_USER_LEAVING;
74import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
75import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
76import static com.android.server.wm.ActivityTaskManagerService.ANIMATE;
Louis Chang6fb1e842018-12-03 16:07:50 +080077import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_BOUNDS;
78import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_DISPLAY;
Louis Changcdec0802019-11-11 11:45:07 +080079import static com.android.server.wm.Task.REPARENT_MOVE_STACK_TO_FRONT;
Winson Chung74666102017-02-22 17:49:24 -080080
Todd Kennedye9910222017-02-21 16:00:11 -080081import android.annotation.NonNull;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +010082import android.annotation.Nullable;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080083import android.app.ActivityManager;
84import android.app.ActivityOptions;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080085import android.app.IApplicationThread;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080086import android.app.PendingIntent;
87import android.app.ProfilerInfo;
Sudheer Shankafc46e9b2016-10-21 17:55:27 -070088import android.app.WaitResult;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080089import android.content.IIntentSender;
90import android.content.Intent;
91import android.content.IntentSender;
92import android.content.pm.ActivityInfo;
93import android.content.pm.ApplicationInfo;
Todd Kennedye9910222017-02-21 16:00:11 -080094import android.content.pm.AuxiliaryResolveInfo;
Kenny Guyb1b30262016-02-09 16:02:35 +000095import android.content.pm.PackageManager;
Winson81fef842019-08-28 12:19:08 -070096import android.content.pm.PackageManagerInternal;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080097import android.content.pm.ResolveInfo;
Kenny Guyb1b30262016-02-09 16:02:35 +000098import android.content.pm.UserInfo;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080099import android.content.res.Configuration;
100import android.graphics.Rect;
101import android.os.Binder;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800102import android.os.Bundle;
103import android.os.IBinder;
Michal Karpinski8596ded2018-11-14 14:43:48 +0000104import android.os.Process;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800105import android.os.RemoteException;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100106import android.os.Trace;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800107import android.os.UserHandle;
Kenny Guyb1b30262016-02-09 16:02:35 +0000108import android.os.UserManager;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800109import android.service.voice.IVoiceInteractionSession;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700110import android.text.TextUtils;
Michal Karpinskib7daac22019-03-25 10:12:41 +0000111import android.util.ArraySet;
Bryce Leedaa91e42017-12-06 14:13:01 -0800112import android.util.Pools.SynchronizedPool;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800113import android.util.Slog;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800114
Bryce Leed3624e12017-11-30 08:51:45 -0800115import com.android.internal.annotations.VisibleForTesting;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800116import com.android.internal.app.HeavyWeightSwitcherActivity;
117import com.android.internal.app.IVoiceInteractor;
Wale Ogunwale59507092018-10-29 09:00:30 -0700118import com.android.server.am.PendingIntentRecord;
Louis Changdd3592a2018-11-05 11:04:14 +0800119import com.android.server.pm.InstantAppResolver;
Riddle Hsufd66d4d2019-11-14 10:35:55 +0800120import com.android.server.wm.ActivityMetricsLogger.LaunchingState;
Wale Ogunwale59507092018-10-29 09:00:30 -0700121import com.android.server.wm.ActivityStackSupervisor.PendingActivityLaunch;
122import com.android.server.wm.LaunchParamsController.LaunchParams;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800123
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700124import java.io.PrintWriter;
125import java.text.DateFormat;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700126import java.util.Date;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800127
128/**
Bryce Leed3624e12017-11-30 08:51:45 -0800129 * Controller for interpreting how and then launching an activity.
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800130 *
131 * This class collects all the logic for determining how an intent and flags should be turned into
132 * an activity and associated task and stack.
133 */
Wale Ogunwale01d66562015-12-29 08:19:19 -0800134class ActivityStarter {
Wale Ogunwale98875612018-10-12 07:53:02 -0700135 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStarter" : TAG_ATM;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800136 private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS;
137 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
138 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
139 private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING;
Bryce Lee7daee392017-10-12 13:46:18 -0700140 private static final int INVALID_LAUNCH_MODE = -1;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800141
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700142 private final ActivityTaskManagerService mService;
Louis Chang149d5c82019-12-30 09:47:39 +0800143 private final RootWindowContainer mRootWindowContainer;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800144 private final ActivityStackSupervisor mSupervisor;
Benjamin Franz563707b2017-06-29 15:06:13 +0100145 private final ActivityStartInterceptor mInterceptor;
Bryce Leed3624e12017-11-30 08:51:45 -0800146 private final ActivityStartController mController;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800147
Wale Ogunwale01d66562015-12-29 08:19:19 -0800148 // Share state variable among methods when starting an activity.
Louis Chang07b13002019-11-27 22:08:37 +0800149 @VisibleForTesting
150 ActivityRecord mStartActivity;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800151 private Intent mIntent;
152 private int mCallingUid;
153 private ActivityOptions mOptions;
154
Ricky Waib147fa12019-04-25 16:08:30 +0100155 // If it is true, background activity can only be started in an existing task that contains
Alan Stokes07389b62019-05-20 15:22:54 +0100156 // an activity with same uid, or if activity starts are enabled in developer options.
Ricky Waib147fa12019-04-25 16:08:30 +0100157 private boolean mRestrictedBgActivity;
158
Bryce Lee7daee392017-10-12 13:46:18 -0700159 private int mLaunchMode;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800160 private boolean mLaunchTaskBehind;
161 private int mLaunchFlags;
162
Bryce Leeec55eb02017-12-05 20:51:27 -0800163 private LaunchParams mLaunchParams = new LaunchParams();
Wale Ogunwale01d66562015-12-29 08:19:19 -0800164
165 private ActivityRecord mNotTop;
166 private boolean mDoResume;
167 private int mStartFlags;
168 private ActivityRecord mSourceRecord;
Bryce Lee7daee392017-10-12 13:46:18 -0700169
David Stevense5a7b642017-05-22 13:18:23 -0700170 // The display to launch the activity onto, barring any strong reason to do otherwise.
171 private int mPreferredDisplayId;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800172
Louis Changcdec0802019-11-11 11:45:07 +0800173 private Task mInTask;
Louis Chang07b13002019-11-27 22:08:37 +0800174 @VisibleForTesting
175 boolean mAddingToTask;
Louis Changcdec0802019-11-11 11:45:07 +0800176 private Task mReuseTask;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800177
178 private ActivityInfo mNewTaskInfo;
179 private Intent mNewTaskIntent;
180 private ActivityStack mSourceStack;
181 private ActivityStack mTargetStack;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800182 private boolean mMovedToFront;
183 private boolean mNoAnimation;
184 private boolean mKeepCurTransition;
Jorim Jaggic875ae72016-04-26 22:41:06 -0700185 private boolean mAvoidMoveToFront;
Winson Chunge219ae12019-07-18 13:43:23 -0700186 private boolean mFrozeTaskList;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800187
Bryce Lee325e09682017-10-05 17:20:25 -0700188 // We must track when we deliver the new intent since multiple code paths invoke
189 // {@link #deliverNewIntent}. This is due to early returns in the code path. This flag is used
190 // inside {@link #deliverNewIntent} to suppress duplicate requests and ensure the intent is
191 // delivered at most once.
192 private boolean mIntentDelivered;
193
Wale Ogunwale01d66562015-12-29 08:19:19 -0800194 private IVoiceInteractionSession mVoiceSession;
195 private IVoiceInteractor mVoiceInteractor;
196
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700197 // Last activity record we attempted to start
Louis Chang54fbb052019-10-16 17:10:17 +0800198 private ActivityRecord mLastStartActivityRecord;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700199 // The result of the last activity we attempted to start.
200 private int mLastStartActivityResult;
201 // Time in milli seconds we attempted to start the last activity.
202 private long mLastStartActivityTimeMs;
203 // The reason we were trying to start the last activity
204 private String mLastStartReason;
Wale Ogunwale59bcba62017-06-16 12:42:51 -0700205
Bryce Lee4c9a5972017-12-01 22:14:24 -0800206 /*
207 * Request details provided through setter methods. Should be reset after {@link #execute()}
208 * to avoid unnecessarily retaining parameters. Note that the request is ignored when
209 * {@link #startResolvedActivity} is invoked directly.
210 */
Louis Chang54fbb052019-10-16 17:10:17 +0800211 @VisibleForTesting
212 Request mRequest = new Request();
Bryce Lee4c9a5972017-12-01 22:14:24 -0800213
Bryce Leed3624e12017-11-30 08:51:45 -0800214 /**
215 * An interface that to provide {@link ActivityStarter} instances to the controller. This is
216 * used by tests to inject their own starter implementations for verification purposes.
217 */
218 @VisibleForTesting
219 interface Factory {
220 /**
Bryce Lee4c9a5972017-12-01 22:14:24 -0800221 * Sets the {@link ActivityStartController} to be passed to {@link ActivityStarter}.
222 */
223 void setController(ActivityStartController controller);
224
225 /**
Bryce Leed3624e12017-11-30 08:51:45 -0800226 * Generates an {@link ActivityStarter} that is ready to handle a new start request.
227 * @param controller The {@link ActivityStartController} which the starter who will own
228 * this instance.
229 * @return an {@link ActivityStarter}
230 */
Bryce Leedaa91e42017-12-06 14:13:01 -0800231 ActivityStarter obtain();
232
233 /**
234 * Recycles a starter for reuse.
235 */
236 void recycle(ActivityStarter starter);
Wale Ogunwale01d66562015-12-29 08:19:19 -0800237 }
238
Bryce Leed3624e12017-11-30 08:51:45 -0800239 /**
240 * Default implementation of {@link StarterFactory}.
241 */
242 static class DefaultFactory implements Factory {
Bryce Leedaa91e42017-12-06 14:13:01 -0800243 /**
244 * The maximum count of starters that should be active at one time:
245 * 1. last ran starter (for logging and post activity processing)
246 * 2. current running starter
247 * 3. starter from re-entry in (2)
248 */
249 private final int MAX_STARTER_COUNT = 3;
250
Bryce Lee4c9a5972017-12-01 22:14:24 -0800251 private ActivityStartController mController;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700252 private ActivityTaskManagerService mService;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800253 private ActivityStackSupervisor mSupervisor;
254 private ActivityStartInterceptor mInterceptor;
255
Bryce Leedaa91e42017-12-06 14:13:01 -0800256 private SynchronizedPool<ActivityStarter> mStarterPool =
257 new SynchronizedPool<>(MAX_STARTER_COUNT);
258
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700259 DefaultFactory(ActivityTaskManagerService service,
Bryce Lee4c9a5972017-12-01 22:14:24 -0800260 ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
261 mService = service;
262 mSupervisor = supervisor;
263 mInterceptor = interceptor;
Bryce Leed3624e12017-11-30 08:51:45 -0800264 }
Bryce Lee4c9a5972017-12-01 22:14:24 -0800265
266 @Override
267 public void setController(ActivityStartController controller) {
268 mController = controller;
269 }
270
271 @Override
Bryce Leedaa91e42017-12-06 14:13:01 -0800272 public ActivityStarter obtain() {
273 ActivityStarter starter = mStarterPool.acquire();
274
275 if (starter == null) {
276 starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
277 }
278
279 return starter;
280 }
281
282 @Override
283 public void recycle(ActivityStarter starter) {
284 starter.reset(true /* clearRequest*/);
285 mStarterPool.release(starter);
Bryce Lee4c9a5972017-12-01 22:14:24 -0800286 }
287 }
288
289 /**
290 * Container for capturing initial start request details. This information is NOT reset until
291 * the {@link ActivityStarter} is recycled, allowing for multiple invocations with the same
292 * parameters.
293 *
294 * TODO(b/64750076): Investigate consolidating member variables of {@link ActivityStarter} with
295 * the request object. Note that some member variables are referenced in
296 * {@link #dump(PrintWriter, String)} and therefore cannot be cleared immediately after
297 * execution.
298 */
Louis Chang54fbb052019-10-16 17:10:17 +0800299 @VisibleForTesting
300 static class Request {
Bryce Lee4c9a5972017-12-01 22:14:24 -0800301 private static final int DEFAULT_CALLING_UID = -1;
302 private static final int DEFAULT_CALLING_PID = 0;
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000303 static final int DEFAULT_REAL_CALLING_UID = -1;
304 static final int DEFAULT_REAL_CALLING_PID = 0;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800305
306 IApplicationThread caller;
307 Intent intent;
Louis Chang54fbb052019-10-16 17:10:17 +0800308 // A copy of the original requested intent, in case for ephemeral app launch.
Bryce Lee4c9a5972017-12-01 22:14:24 -0800309 Intent ephemeralIntent;
310 String resolvedType;
311 ActivityInfo activityInfo;
312 ResolveInfo resolveInfo;
313 IVoiceInteractionSession voiceSession;
314 IVoiceInteractor voiceInteractor;
315 IBinder resultTo;
316 String resultWho;
317 int requestCode;
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000318 int callingPid = DEFAULT_CALLING_PID;
319 int callingUid = DEFAULT_CALLING_UID;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800320 String callingPackage;
Philip P. Moltmann9c5226f2020-01-10 08:53:43 -0800321 @Nullable String callingFeatureId;
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000322 int realCallingPid = DEFAULT_REAL_CALLING_PID;
323 int realCallingUid = DEFAULT_REAL_CALLING_UID;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800324 int startFlags;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100325 SafeActivityOptions activityOptions;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800326 boolean ignoreTargetSecurity;
327 boolean componentSpecified;
Winson Chunge2d72172018-01-25 17:46:20 +0000328 boolean avoidMoveToFront;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800329 ActivityRecord[] outActivity;
Louis Changcdec0802019-11-11 11:45:07 +0800330 Task inTask;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800331 String reason;
332 ProfilerInfo profilerInfo;
333 Configuration globalConfig;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800334 int userId;
335 WaitResult waitResult;
Patrick Baumann31426b22018-05-21 13:46:40 -0700336 int filterCallingUid;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100337 PendingIntentRecord originatingPendingIntent;
Michal Karpinskiac116df2018-12-10 17:51:42 +0000338 boolean allowBackgroundActivityStart;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800339
340 /**
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200341 * If set to {@code true}, allows this activity start to look into
342 * {@link PendingRemoteAnimationRegistry}
343 */
344 boolean allowPendingRemoteAnimationRegistryLookup;
345
346 /**
Bryce Leea3cd8e02018-01-09 15:44:24 -0800347 * Ensure constructed request matches reset instance.
348 */
349 Request() {
350 reset();
351 }
352
353 /**
Bryce Leedaa91e42017-12-06 14:13:01 -0800354 * Sets values back to the initial state, clearing any held references.
355 */
356 void reset() {
357 caller = null;
358 intent = null;
359 ephemeralIntent = null;
360 resolvedType = null;
361 activityInfo = null;
362 resolveInfo = null;
363 voiceSession = null;
364 voiceInteractor = null;
365 resultTo = null;
366 resultWho = null;
367 requestCode = 0;
Bryce Leea3cd8e02018-01-09 15:44:24 -0800368 callingPid = DEFAULT_CALLING_PID;
369 callingUid = DEFAULT_CALLING_UID;
Bryce Leedaa91e42017-12-06 14:13:01 -0800370 callingPackage = null;
Philip P. Moltmann9c5226f2020-01-10 08:53:43 -0800371 callingFeatureId = null;
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000372 realCallingPid = DEFAULT_REAL_CALLING_PID;
373 realCallingUid = DEFAULT_REAL_CALLING_UID;
Bryce Leedaa91e42017-12-06 14:13:01 -0800374 startFlags = 0;
375 activityOptions = null;
376 ignoreTargetSecurity = false;
377 componentSpecified = false;
378 outActivity = null;
379 inTask = null;
380 reason = null;
381 profilerInfo = null;
382 globalConfig = null;
Bryce Leedaa91e42017-12-06 14:13:01 -0800383 userId = 0;
384 waitResult = null;
Winson Chunge2d72172018-01-25 17:46:20 +0000385 avoidMoveToFront = false;
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200386 allowPendingRemoteAnimationRegistryLookup = true;
Patrick Baumann31426b22018-05-21 13:46:40 -0700387 filterCallingUid = UserHandle.USER_NULL;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100388 originatingPendingIntent = null;
Michal Karpinskiac116df2018-12-10 17:51:42 +0000389 allowBackgroundActivityStart = false;
Bryce Leedaa91e42017-12-06 14:13:01 -0800390 }
391
392 /**
393 * Adopts all values from passed in request.
394 */
395 void set(Request request) {
396 caller = request.caller;
397 intent = request.intent;
398 ephemeralIntent = request.ephemeralIntent;
399 resolvedType = request.resolvedType;
400 activityInfo = request.activityInfo;
401 resolveInfo = request.resolveInfo;
402 voiceSession = request.voiceSession;
403 voiceInteractor = request.voiceInteractor;
404 resultTo = request.resultTo;
405 resultWho = request.resultWho;
406 requestCode = request.requestCode;
407 callingPid = request.callingPid;
408 callingUid = request.callingUid;
409 callingPackage = request.callingPackage;
Philip P. Moltmann9c5226f2020-01-10 08:53:43 -0800410 callingFeatureId = request.callingFeatureId;
Bryce Leedaa91e42017-12-06 14:13:01 -0800411 realCallingPid = request.realCallingPid;
412 realCallingUid = request.realCallingUid;
413 startFlags = request.startFlags;
414 activityOptions = request.activityOptions;
415 ignoreTargetSecurity = request.ignoreTargetSecurity;
416 componentSpecified = request.componentSpecified;
417 outActivity = request.outActivity;
418 inTask = request.inTask;
419 reason = request.reason;
420 profilerInfo = request.profilerInfo;
421 globalConfig = request.globalConfig;
Bryce Leedaa91e42017-12-06 14:13:01 -0800422 userId = request.userId;
423 waitResult = request.waitResult;
Winson Chunge2d72172018-01-25 17:46:20 +0000424 avoidMoveToFront = request.avoidMoveToFront;
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200425 allowPendingRemoteAnimationRegistryLookup
426 = request.allowPendingRemoteAnimationRegistryLookup;
Patrick Baumann31426b22018-05-21 13:46:40 -0700427 filterCallingUid = request.filterCallingUid;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100428 originatingPendingIntent = request.originatingPendingIntent;
Michal Karpinskiac116df2018-12-10 17:51:42 +0000429 allowBackgroundActivityStart = request.allowBackgroundActivityStart;
Bryce Leedaa91e42017-12-06 14:13:01 -0800430 }
Louis Chang54fbb052019-10-16 17:10:17 +0800431
432 /**
433 * Resolve activity from the given intent for this launch.
434 */
435 void resolveActivity(ActivityStackSupervisor supervisor) {
436 if (realCallingPid == Request.DEFAULT_REAL_CALLING_PID) {
437 realCallingPid = Binder.getCallingPid();
438 }
439 if (realCallingUid == Request.DEFAULT_REAL_CALLING_UID) {
440 realCallingUid = Binder.getCallingUid();
441 }
442
443 if (callingUid >= 0) {
444 callingPid = -1;
445 } else if (caller == null) {
446 callingPid = realCallingPid;
447 callingUid = realCallingUid;
448 } else {
449 callingPid = callingUid = -1;
450 }
451
452 // Save a copy in case ephemeral needs it
453 ephemeralIntent = new Intent(intent);
454 // Don't modify the client's object!
455 intent = new Intent(intent);
456 if (intent.getComponent() != null
457 && !(Intent.ACTION_VIEW.equals(intent.getAction()) && intent.getData() == null)
458 && !Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE.equals(intent.getAction())
459 && !Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE.equals(intent.getAction())
460 && supervisor.mService.getPackageManagerInternalLocked()
461 .isInstantAppInstallerComponent(intent.getComponent())) {
462 // Intercept intents targeted directly to the ephemeral installer the ephemeral
463 // installer should never be started with a raw Intent; instead adjust the intent
464 // so it looks like a "normal" instant app launch.
465 intent.setComponent(null /* component */);
466 }
467
468 resolveInfo = supervisor.resolveIntent(intent, resolvedType, userId,
469 0 /* matchFlags */,
470 computeResolveFilterUid(callingUid, realCallingUid, filterCallingUid));
471 if (resolveInfo == null) {
472 final UserInfo userInfo = supervisor.getUserInfo(userId);
473 if (userInfo != null && userInfo.isManagedProfile()) {
474 // Special case for managed profiles, if attempting to launch non-cryto aware
475 // app in a locked managed profile from an unlocked parent allow it to resolve
476 // as user will be sent via confirm credentials to unlock the profile.
477 final UserManager userManager = UserManager.get(supervisor.mService.mContext);
478 boolean profileLockedAndParentUnlockingOrUnlocked = false;
479 final long token = Binder.clearCallingIdentity();
480 try {
481 final UserInfo parent = userManager.getProfileParent(userId);
482 profileLockedAndParentUnlockingOrUnlocked = (parent != null)
483 && userManager.isUserUnlockingOrUnlocked(parent.id)
484 && !userManager.isUserUnlockingOrUnlocked(userId);
485 } finally {
486 Binder.restoreCallingIdentity(token);
487 }
488 if (profileLockedAndParentUnlockingOrUnlocked) {
489 resolveInfo = supervisor.resolveIntent(intent, resolvedType, userId,
490 PackageManager.MATCH_DIRECT_BOOT_AWARE
491 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
492 computeResolveFilterUid(callingUid, realCallingUid,
493 filterCallingUid));
494 }
495 }
496 }
497
498 // Collect information about the target of the Intent.
499 activityInfo = supervisor.resolveActivity(intent, resolveInfo, startFlags,
500 profilerInfo);
501 }
Bryce Leed3624e12017-11-30 08:51:45 -0800502 }
503
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700504 ActivityStarter(ActivityStartController controller, ActivityTaskManagerService service,
Bryce Leed3624e12017-11-30 08:51:45 -0800505 ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
506 mController = controller;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800507 mService = service;
Louis Chang149d5c82019-12-30 09:47:39 +0800508 mRootWindowContainer = service.mRootWindowContainer;
Bryce Leed3624e12017-11-30 08:51:45 -0800509 mSupervisor = supervisor;
510 mInterceptor = interceptor;
Bryce Leedaa91e42017-12-06 14:13:01 -0800511 reset(true);
512 }
513
514 /**
515 * Effectively duplicates the starter passed in. All state and request values will be
516 * mirrored.
517 * @param starter
518 */
519 void set(ActivityStarter starter) {
520 mStartActivity = starter.mStartActivity;
521 mIntent = starter.mIntent;
522 mCallingUid = starter.mCallingUid;
523 mOptions = starter.mOptions;
Ricky Waib147fa12019-04-25 16:08:30 +0100524 mRestrictedBgActivity = starter.mRestrictedBgActivity;
Bryce Leedaa91e42017-12-06 14:13:01 -0800525
526 mLaunchTaskBehind = starter.mLaunchTaskBehind;
527 mLaunchFlags = starter.mLaunchFlags;
528 mLaunchMode = starter.mLaunchMode;
529
Bryce Leeec55eb02017-12-05 20:51:27 -0800530 mLaunchParams.set(starter.mLaunchParams);
Bryce Leedaa91e42017-12-06 14:13:01 -0800531
532 mNotTop = starter.mNotTop;
533 mDoResume = starter.mDoResume;
534 mStartFlags = starter.mStartFlags;
535 mSourceRecord = starter.mSourceRecord;
536 mPreferredDisplayId = starter.mPreferredDisplayId;
537
538 mInTask = starter.mInTask;
539 mAddingToTask = starter.mAddingToTask;
540 mReuseTask = starter.mReuseTask;
541
542 mNewTaskInfo = starter.mNewTaskInfo;
543 mNewTaskIntent = starter.mNewTaskIntent;
544 mSourceStack = starter.mSourceStack;
545
546 mTargetStack = starter.mTargetStack;
547 mMovedToFront = starter.mMovedToFront;
548 mNoAnimation = starter.mNoAnimation;
549 mKeepCurTransition = starter.mKeepCurTransition;
550 mAvoidMoveToFront = starter.mAvoidMoveToFront;
Winson Chunge219ae12019-07-18 13:43:23 -0700551 mFrozeTaskList = starter.mFrozeTaskList;
Bryce Leedaa91e42017-12-06 14:13:01 -0800552
553 mVoiceSession = starter.mVoiceSession;
554 mVoiceInteractor = starter.mVoiceInteractor;
555
556 mIntentDelivered = starter.mIntentDelivered;
557
558 mRequest.set(starter.mRequest);
Bryce Leed3624e12017-11-30 08:51:45 -0800559 }
560
Bryce Lee4c9a5972017-12-01 22:14:24 -0800561 boolean relatedToPackage(String packageName) {
Louis Chang54fbb052019-10-16 17:10:17 +0800562 return (mLastStartActivityRecord != null
563 && packageName.equals(mLastStartActivityRecord.packageName))
Bryce Lee4c9a5972017-12-01 22:14:24 -0800564 || (mStartActivity != null && packageName.equals(mStartActivity.packageName));
565 }
566
567 /**
Louis Chang54fbb052019-10-16 17:10:17 +0800568 * Starts an activity based on the provided {@link ActivityRecord} and environment parameters.
569 * Note that this method is called internally as well as part of {@link #executeRequest}.
570 */
571 void startResolvedActivity(final ActivityRecord r, ActivityRecord sourceRecord,
572 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
Louis Changcdec0802019-11-11 11:45:07 +0800573 int startFlags, boolean doResume, ActivityOptions options, Task inTask) {
Louis Chang54fbb052019-10-16 17:10:17 +0800574 try {
Riddle Hsufd66d4d2019-11-14 10:35:55 +0800575 final LaunchingState launchingState = mSupervisor.getActivityMetricsLogger()
576 .notifyActivityLaunching(r.intent, r.resultTo);
Louis Chang54fbb052019-10-16 17:10:17 +0800577 mLastStartReason = "startResolvedActivity";
578 mLastStartActivityTimeMs = System.currentTimeMillis();
579 mLastStartActivityRecord = r;
580 mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
581 voiceInteractor, startFlags, doResume, options, inTask,
582 false /* restrictedBgActivity */);
Riddle Hsufd66d4d2019-11-14 10:35:55 +0800583 mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState,
584 mLastStartActivityResult, mLastStartActivityRecord);
Louis Chang54fbb052019-10-16 17:10:17 +0800585 } finally {
586 onExecutionComplete();
587 }
588 }
589
590 /**
591 * Resolve necessary information according the request parameters provided earlier, and execute
592 * the request which begin the journey of starting an activity.
Bryce Lee4c9a5972017-12-01 22:14:24 -0800593 * @return The starter result.
594 */
595 int execute() {
Bryce Leedaa91e42017-12-06 14:13:01 -0800596 try {
Louis Chang54fbb052019-10-16 17:10:17 +0800597 // Refuse possible leaked file descriptors
598 if (mRequest.intent != null && mRequest.intent.hasFileDescriptors()) {
599 throw new IllegalArgumentException("File descriptors passed in Intent");
600 }
601
Riddle Hsufd66d4d2019-11-14 10:35:55 +0800602 final LaunchingState launchingState;
603 synchronized (mService.mGlobalLock) {
604 final ActivityRecord caller = ActivityRecord.forTokenLocked(mRequest.resultTo);
605 launchingState = mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(
606 mRequest.intent, caller);
607 }
Louis Chang54fbb052019-10-16 17:10:17 +0800608
Riddle Hsufd66d4d2019-11-14 10:35:55 +0800609 // Do not lock the resolving to avoid potential deadlock.
Louis Chang54fbb052019-10-16 17:10:17 +0800610 if (mRequest.activityInfo == null) {
611 mRequest.resolveActivity(mSupervisor);
612 }
613
614 int res;
615 synchronized (mService.mGlobalLock) {
Louis Chang149d5c82019-12-30 09:47:39 +0800616 final ActivityStack stack = mRootWindowContainer.getTopDisplayFocusedStack();
Louis Chang54fbb052019-10-16 17:10:17 +0800617 stack.mConfigWillChange = mRequest.globalConfig != null
618 && mService.getGlobalConfiguration().diff(mRequest.globalConfig) != 0;
619 if (DEBUG_CONFIGURATION) {
620 Slog.v(TAG_CONFIGURATION, "Starting activity when config will change = "
621 + stack.mConfigWillChange);
622 }
623
624 final long origId = Binder.clearCallingIdentity();
625
626 res = resolveToHeavyWeightSwitcherIfNeeded();
627 if (res != START_SUCCESS) {
628 return res;
629 }
630 res = executeRequest(mRequest);
631
632 Binder.restoreCallingIdentity(origId);
633
634 if (stack.mConfigWillChange) {
635 // If the caller also wants to switch to a new configuration, do so now.
636 // This allows a clean switch, as we are waiting for the current activity
637 // to pause (so we will not destroy it), and have not yet started the
638 // next activity.
639 mService.mAmInternal.enforceCallingPermission(
640 android.Manifest.permission.CHANGE_CONFIGURATION,
641 "updateConfiguration()");
642 stack.mConfigWillChange = false;
643 if (DEBUG_CONFIGURATION) {
644 Slog.v(TAG_CONFIGURATION,
645 "Updating to new configuration after starting activity.");
646 }
647 mService.updateConfigurationLocked(mRequest.globalConfig, null, false);
648 }
649
650 // Notify ActivityMetricsLogger that the activity has launched.
651 // ActivityMetricsLogger will then wait for the windows to be drawn and populate
652 // WaitResult.
Riddle Hsufd66d4d2019-11-14 10:35:55 +0800653 mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState, res,
Louis Chang54fbb052019-10-16 17:10:17 +0800654 mLastStartActivityRecord);
655 return getExternalResult(mRequest.waitResult == null ? res
656 : waitForResult(res, mLastStartActivityRecord));
Bryce Leedaa91e42017-12-06 14:13:01 -0800657 }
658 } finally {
659 onExecutionComplete();
660 }
661 }
662
663 /**
Louis Chang54fbb052019-10-16 17:10:17 +0800664 * Updates the request to heavy-weight switch if this is a heavy-weight process while there
665 * already have another, different heavy-weight process running.
Bryce Leedaa91e42017-12-06 14:13:01 -0800666 */
Louis Chang54fbb052019-10-16 17:10:17 +0800667 private int resolveToHeavyWeightSwitcherIfNeeded() {
668 if (mRequest.activityInfo == null || !mService.mHasHeavyWeightFeature
669 || (mRequest.activityInfo.applicationInfo.privateFlags
670 & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) == 0) {
671 return START_SUCCESS;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700672 }
Bryce Leef9d49542017-06-26 16:27:32 -0700673
Louis Chang54fbb052019-10-16 17:10:17 +0800674 if (!mRequest.activityInfo.processName.equals(
675 mRequest.activityInfo.applicationInfo.packageName)) {
676 return START_SUCCESS;
677 }
Bryce Lee93e7f792017-10-25 15:54:55 -0700678
Louis Chang54fbb052019-10-16 17:10:17 +0800679 final WindowProcessController heavy = mService.mHeavyWeightProcess;
680 if (heavy == null || (heavy.mInfo.uid == mRequest.activityInfo.applicationInfo.uid
681 && heavy.mName.equals(mRequest.activityInfo.processName))) {
682 return START_SUCCESS;
683 }
684
685 int appCallingUid = mRequest.callingUid;
686 if (mRequest.caller != null) {
687 WindowProcessController callerApp = mService.getProcessController(mRequest.caller);
688 if (callerApp != null) {
689 appCallingUid = callerApp.mInfo.uid;
690 } else {
691 Slog.w(TAG, "Unable to find app for caller " + mRequest.caller + " (pid="
692 + mRequest.callingPid + ") when starting: " + mRequest.intent.toString());
693 SafeActivityOptions.abort(mRequest.activityOptions);
694 return ActivityManager.START_PERMISSION_DENIED;
695 }
696 }
697
698 final IIntentSender target = mService.getIntentSenderLocked(
Philip P. Moltmann9c5226f2020-01-10 08:53:43 -0800699 ActivityManager.INTENT_SENDER_ACTIVITY, "android" /* packageName */,
700 null /* featureId */, appCallingUid, mRequest.userId, null /* token */,
701 null /* resultWho*/, 0 /* requestCode*/, new Intent[]{mRequest.intent},
702 new String[]{mRequest.resolvedType},
Louis Chang54fbb052019-10-16 17:10:17 +0800703 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;
Philip P. Moltmann9c5226f2020-01-10 08:53:43 -0800814 String callingFeatureId = request.callingFeatureId;
Louis Chang54fbb052019-10-16 17:10:17 +0800815 final int realCallingPid = request.realCallingPid;
816 final int realCallingUid = request.realCallingUid;
817 final int startFlags = request.startFlags;
818 final SafeActivityOptions options = request.activityOptions;
Louis Changcdec0802019-11-11 11:45:07 +0800819 Task inTask = request.inTask;
Louis Chang54fbb052019-10-16 17:10:17 +0800820
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800821 int err = ActivityManager.START_SUCCESS;
Chad Brubaker06068612017-04-06 09:43:47 -0700822 // Pull the optional Ephemeral Installer-only bundle out of the options early.
Louis Chang54fbb052019-10-16 17:10:17 +0800823 final Bundle verificationBundle =
824 options != null ? options.popAppVerificationBundle() : null;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800825
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700826 WindowProcessController callerApp = null;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800827 if (caller != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700828 callerApp = mService.getProcessController(caller);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800829 if (callerApp != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700830 callingPid = callerApp.getPid();
831 callingUid = callerApp.mInfo.uid;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800832 } else {
Louis Chang54fbb052019-10-16 17:10:17 +0800833 Slog.w(TAG, "Unable to find app for caller " + caller + " (pid=" + callingPid
834 + ") when starting: " + intent.toString());
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800835 err = ActivityManager.START_PERMISSION_DENIED;
836 }
837 }
838
Bryce Lee93e7f792017-10-25 15:54:55 -0700839 final int userId = aInfo != null && aInfo.applicationInfo != null
840 ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800841 if (err == ActivityManager.START_SUCCESS) {
842 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
Andrii Kulian03c403d2016-11-11 11:14:12 -0800843 + "} from uid " + callingUid);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800844 }
845
846 ActivityRecord sourceRecord = null;
847 ActivityRecord resultRecord = null;
848 if (resultTo != null) {
Louis Chang149d5c82019-12-30 09:47:39 +0800849 sourceRecord = mRootWindowContainer.isInAnyStack(resultTo);
Louis Chang54fbb052019-10-16 17:10:17 +0800850 if (DEBUG_RESULTS) {
851 Slog.v(TAG_RESULTS, "Will send result to " + resultTo + " " + sourceRecord);
852 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800853 if (sourceRecord != null) {
854 if (requestCode >= 0 && !sourceRecord.finishing) {
855 resultRecord = sourceRecord;
856 }
857 }
858 }
859
860 final int launchFlags = intent.getFlags();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800861 if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
Louis Chang54fbb052019-10-16 17:10:17 +0800862 // Transfer the result target from the source activity to the new one being started,
863 // including any failures.
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800864 if (requestCode >= 0) {
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100865 SafeActivityOptions.abort(options);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800866 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
867 }
868 resultRecord = sourceRecord.resultTo;
869 if (resultRecord != null && !resultRecord.isInStackLocked()) {
870 resultRecord = null;
871 }
872 resultWho = sourceRecord.resultWho;
873 requestCode = sourceRecord.requestCode;
874 sourceRecord.resultTo = null;
875 if (resultRecord != null) {
876 resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
877 }
878 if (sourceRecord.launchedFromUid == callingUid) {
Louis Chang54fbb052019-10-16 17:10:17 +0800879 // The new activity is being launched from the same uid as the previous activity
880 // in the flow, and asking to forward its result back to the previous. In this
881 // case the activity is serving as a trampoline between the two, so we also want
882 // to update its launchedFromPackage to be the same as the previous activity.
883 // Note that this is safe, since we know these two packages come from the same
884 // uid; the caller could just as well have supplied that same package name itself
885 // . This specifially deals with the case of an intent picker/chooser being
886 // launched in the app flow to redirect to an activity picked by the user, where
887 // we want the final activity to consider it to have been launched by the
888 // previous app activity.
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800889 callingPackage = sourceRecord.launchedFromPackage;
Philip P. Moltmann9c5226f2020-01-10 08:53:43 -0800890 callingFeatureId = sourceRecord.launchedFromFeatureId;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800891 }
892 }
893
894 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
895 // We couldn't find a class that can handle the given Intent.
896 // That's the end of that!
897 err = ActivityManager.START_INTENT_NOT_RESOLVED;
898 }
899
900 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
901 // We couldn't find the specific class specified in the Intent.
902 // Also the end of the line.
903 err = ActivityManager.START_CLASS_NOT_FOUND;
904 }
905
906 if (err == ActivityManager.START_SUCCESS && sourceRecord != null
Louis Changcdec0802019-11-11 11:45:07 +0800907 && sourceRecord.getTask().voiceSession != null) {
Louis Chang54fbb052019-10-16 17:10:17 +0800908 // If this activity is being launched as part of a voice session, we need to ensure
909 // that it is safe to do so. If the upcoming activity will also be part of the voice
910 // session, we can only launch it if it has explicitly said it supports the VOICE
911 // category, or it is a part of the calling app.
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800912 if ((launchFlags & FLAG_ACTIVITY_NEW_TASK) == 0
913 && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
914 try {
915 intent.addCategory(Intent.CATEGORY_VOICE);
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700916 if (!mService.getPackageManager().activitySupportsIntent(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800917 intent.getComponent(), intent, resolvedType)) {
Louis Chang54fbb052019-10-16 17:10:17 +0800918 Slog.w(TAG, "Activity being started in current voice task does not support "
919 + "voice: " + intent);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800920 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
921 }
922 } catch (RemoteException e) {
923 Slog.w(TAG, "Failure checking voice capabilities", e);
924 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
925 }
926 }
927 }
928
929 if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
930 // If the caller is starting a new voice session, just make sure the target
931 // is actually allowing it to run this way.
932 try {
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700933 if (!mService.getPackageManager().activitySupportsIntent(intent.getComponent(),
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800934 intent, resolvedType)) {
935 Slog.w(TAG,
Louis Chang54fbb052019-10-16 17:10:17 +0800936 "Activity being started in new voice task does not support: " + intent);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800937 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
938 }
939 } catch (RemoteException e) {
940 Slog.w(TAG, "Failure checking voice capabilities", e);
941 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
942 }
943 }
944
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800945 final ActivityStack resultStack = resultRecord == null
Wale Ogunwale1ebcd8e2020-01-21 11:27:03 -0800946 ? null : resultRecord.getRootTask();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800947
Wale Ogunwale01d66562015-12-29 08:19:19 -0800948 if (err != START_SUCCESS) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800949 if (resultRecord != null) {
Andrii Kulian79d67982019-08-19 11:56:16 -0700950 resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED,
951 null /* data */);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800952 }
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100953 SafeActivityOptions.abort(options);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800954 return err;
955 }
956
957 boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
Philip P. Moltmann9c5226f2020-01-10 08:53:43 -0800958 requestCode, callingPid, callingUid, callingPackage, callingFeatureId,
959 request.ignoreTargetSecurity, inTask != null, callerApp, resultRecord, resultStack);
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700960 abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800961 callingPid, resolvedType, aInfo.applicationInfo);
Hai Zhangf4da9be2019-05-01 13:46:06 +0800962 abort |= !mService.getPermissionPolicyInternal().checkStartActivity(intent, callingUid,
963 callingPackage);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800964
Ricky Waib147fa12019-04-25 16:08:30 +0100965 boolean restrictedBgActivity = false;
Michal Karpinski8596ded2018-11-14 14:43:48 +0000966 if (!abort) {
Michal Karpinski4fd5b842019-01-28 15:13:32 +0000967 try {
Riddle Hsu2ca561b2019-10-08 21:58:58 +0800968 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER,
Michal Karpinski4fd5b842019-01-28 15:13:32 +0000969 "shouldAbortBackgroundActivityStart");
Ricky Waib147fa12019-04-25 16:08:30 +0100970 restrictedBgActivity = shouldAbortBackgroundActivityStart(callingUid,
Ricky Waiaca8a772019-04-04 16:01:06 +0100971 callingPid, callingPackage, realCallingUid, realCallingPid, callerApp,
Louis Chang54fbb052019-10-16 17:10:17 +0800972 request.originatingPendingIntent, request.allowBackgroundActivityStart,
973 intent);
Michal Karpinski4fd5b842019-01-28 15:13:32 +0000974 } finally {
Riddle Hsu2ca561b2019-10-08 21:58:58 +0800975 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
Michal Karpinski4fd5b842019-01-28 15:13:32 +0000976 }
Michal Karpinski8596ded2018-11-14 14:43:48 +0000977 }
978
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100979 // Merge the two options bundles, while realCallerOptions takes precedence.
980 ActivityOptions checkedOptions = options != null
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700981 ? options.getOptions(intent, aInfo, callerApp, mSupervisor) : null;
Louis Chang54fbb052019-10-16 17:10:17 +0800982 if (request.allowPendingRemoteAnimationRegistryLookup) {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700983 checkedOptions = mService.getActivityStartController()
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200984 .getPendingRemoteAnimationRegistry()
985 .overrideOptionsIfNeeded(callingPackage, checkedOptions);
986 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700987 if (mService.mController != null) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800988 try {
Louis Chang54fbb052019-10-16 17:10:17 +0800989 // The Intent we give to the watcher has the extra data stripped off, since it
990 // can contain private information.
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800991 Intent watchIntent = intent.cloneFilter();
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700992 abort |= !mService.mController.activityStarting(watchIntent,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800993 aInfo.applicationInfo.packageName);
994 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700995 mService.mController = null;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800996 }
997 }
998
Philip P. Moltmann9c5226f2020-01-10 08:53:43 -0800999 mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage,
1000 callingFeatureId);
Benjamin Franz563707b2017-06-29 15:06:13 +01001001 if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001002 callingUid, checkedOptions)) {
Benjamin Franz563707b2017-06-29 15:06:13 +01001003 // activity start was intercepted, e.g. because the target user is currently in quiet
1004 // mode (turn off work) or the target application is suspended
1005 intent = mInterceptor.mIntent;
1006 rInfo = mInterceptor.mRInfo;
1007 aInfo = mInterceptor.mAInfo;
1008 resolvedType = mInterceptor.mResolvedType;
1009 inTask = mInterceptor.mInTask;
1010 callingPid = mInterceptor.mCallingPid;
1011 callingUid = mInterceptor.mCallingUid;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001012 checkedOptions = mInterceptor.mActivityOptions;
Benjamin Franz563707b2017-06-29 15:06:13 +01001013 }
1014
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001015 if (abort) {
1016 if (resultRecord != null) {
Andrii Kulian79d67982019-08-19 11:56:16 -07001017 resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED,
1018 null /* data */);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001019 }
Louis Chang54fbb052019-10-16 17:10:17 +08001020 // We pretend to the caller that it was really started, but they will just get a
1021 // cancel result.
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001022 ActivityOptions.abort(checkedOptions);
Bryce Leef9d49542017-06-26 16:27:32 -07001023 return START_ABORTED;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001024 }
1025
1026 // If permissions need a review before any of the app components can run, we
1027 // launch the review activity and pass a pending intent to start the activity
1028 // we are to launching now after the review is completed.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07001029 if (aInfo != null) {
Wale Ogunwale906f9c62018-07-23 11:23:44 -07001030 if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001031 aInfo.packageName, userId)) {
Louis Chang54fbb052019-10-16 17:10:17 +08001032 final IIntentSender target = mService.getIntentSenderLocked(
Philip P. Moltmann9c5226f2020-01-10 08:53:43 -08001033 ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage, callingFeatureId,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001034 callingUid, userId, null, null, 0, new Intent[]{intent},
1035 new String[]{resolvedType}, PendingIntent.FLAG_CANCEL_CURRENT
1036 | PendingIntent.FLAG_ONE_SHOT, null);
1037
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001038 Intent newIntent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
Philip P. Moltmannc3e66d02019-01-31 15:56:18 -08001039
1040 int flags = intent.getFlags();
1041 flags |= Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
1042
1043 /*
1044 * Prevent reuse of review activity: Each app needs their own review activity. By
1045 * default activities launched with NEW_TASK or NEW_DOCUMENT try to reuse activities
1046 * with the same launch parameters (extras are ignored). Hence to avoid possible
1047 * reuse force a new activity via the MULTIPLE_TASK flag.
1048 *
1049 * Activities that are not launched with NEW_TASK or NEW_DOCUMENT are not re-used,
1050 * hence no need to add the flag in this case.
1051 */
1052 if ((flags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_NEW_DOCUMENT)) != 0) {
1053 flags |= Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
1054 }
1055 newIntent.setFlags(flags);
1056
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001057 newIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, aInfo.packageName);
1058 newIntent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target));
1059 if (resultRecord != null) {
1060 newIntent.putExtra(Intent.EXTRA_RESULT_NEEDED, true);
1061 }
1062 intent = newIntent;
1063
1064 resolvedType = null;
1065 callingUid = realCallingUid;
1066 callingPid = realCallingPid;
1067
Svet Ganovcbcbf662018-05-10 17:25:29 -07001068 rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0,
Patrick Baumann31426b22018-05-21 13:46:40 -07001069 computeResolveFilterUid(
Louis Chang54fbb052019-10-16 17:10:17 +08001070 callingUid, realCallingUid, request.filterCallingUid));
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001071 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
1072 null /*profilerInfo*/);
1073
1074 if (DEBUG_PERMISSIONS_REVIEW) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001075 final ActivityStack focusedStack =
Louis Chang149d5c82019-12-30 09:47:39 +08001076 mRootWindowContainer.getTopDisplayFocusedStack();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001077 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true,
1078 true, false) + "} from uid " + callingUid + " on display "
Wale Ogunwale0b3d2922019-12-30 08:55:07 -08001079 + (focusedStack == null ? DEFAULT_DISPLAY
1080 : focusedStack.getDisplayId()));
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001081 }
1082 }
1083 }
1084
1085 // If we have an ephemeral app, abort the process of launching the resolved intent.
1086 // Instead, launch the ephemeral installer. Once the installer is finished, it
1087 // starts either the intent we resolved here [on install error] or the ephemeral
1088 // app [on install success].
Patrick Baumanna89a1722018-02-07 15:26:52 -08001089 if (rInfo != null && rInfo.auxiliaryInfo != null) {
Louis Chang54fbb052019-10-16 17:10:17 +08001090 intent = createLaunchIntent(rInfo.auxiliaryInfo, request.ephemeralIntent,
Philip P. Moltmann9c5226f2020-01-10 08:53:43 -08001091 callingPackage, callingFeatureId, verificationBundle, resolvedType, userId);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001092 resolvedType = null;
1093 callingUid = realCallingUid;
1094 callingPid = realCallingPid;
1095
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001096 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
1097 }
1098
Louis Chang54fbb052019-10-16 17:10:17 +08001099 final ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
Philip P. Moltmann9c5226f2020-01-10 08:53:43 -08001100 callingPackage, callingFeatureId, intent, resolvedType, aInfo,
1101 mService.getGlobalConfiguration(), resultRecord, resultWho, requestCode,
1102 request.componentSpecified, voiceSession != null, mSupervisor, checkedOptions,
1103 sourceRecord);
Louis Chang54fbb052019-10-16 17:10:17 +08001104 mLastStartActivityRecord = r;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001105
1106 if (r.appTimeTracker == null && sourceRecord != null) {
1107 // If the caller didn't specify an explicit time tracker, we want to continue
1108 // tracking under any it has.
1109 r.appTimeTracker = sourceRecord.appTimeTracker;
1110 }
1111
Louis Chang149d5c82019-12-30 09:47:39 +08001112 final ActivityStack stack = mRootWindowContainer.getTopDisplayFocusedStack();
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001113
1114 // If we are starting an activity that is not from the same uid as the currently resumed
1115 // one, check whether app switches are allowed.
Bryce Leec4ab62a2018-03-05 14:19:26 -08001116 if (voiceSession == null && (stack.getResumedActivity() == null
1117 || stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001118 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001119 realCallingPid, realCallingUid, "Activity start")) {
Alan Stokes07389b62019-05-20 15:22:54 +01001120 if (!(restrictedBgActivity && handleBackgroundActivityAbort(r))) {
Ricky Waib147fa12019-04-25 16:08:30 +01001121 mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00001122 sourceRecord, startFlags, stack, callerApp));
Ricky Waib147fa12019-04-25 16:08:30 +01001123 }
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001124 ActivityOptions.abort(checkedOptions);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001125 return ActivityManager.START_SWITCHES_CANCELED;
1126 }
1127 }
1128
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001129 mService.onStartActivitySetDidAppSwitch();
Bryce Leed3624e12017-11-30 08:51:45 -08001130 mController.doPendingActivityLaunches(false);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001131
Louis Chang54fbb052019-10-16 17:10:17 +08001132 mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
1133 request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
1134 restrictedBgActivity);
1135
1136 if (request.outActivity != null) {
1137 request.outActivity[0] = mLastStartActivityRecord;
1138 }
1139
Riddle Hsu7f8643a2019-12-05 14:37:30 +08001140 return mLastStartActivityResult;
Louis Chang54fbb052019-10-16 17:10:17 +08001141 }
1142
1143 /**
1144 * Return true if background activity is really aborted.
1145 *
1146 * TODO(b/131748165): Refactor the logic so we don't need to call this method everywhere.
1147 */
1148 private boolean handleBackgroundActivityAbort(ActivityRecord r) {
1149 // TODO(b/131747138): Remove toast and refactor related code in R release.
1150 final boolean abort = !mService.isBackgroundActivityStartsEnabled();
1151 if (!abort) {
1152 return false;
1153 }
1154 final ActivityRecord resultRecord = r.resultTo;
1155 final String resultWho = r.resultWho;
1156 int requestCode = r.requestCode;
1157 if (resultRecord != null) {
1158 resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED,
1159 null /* data */);
1160 }
1161 // We pretend to the caller that it was really started to make it backward compatible, but
1162 // they will just get a cancel result.
1163 ActivityOptions.abort(r.pendingOptions);
1164 return true;
1165 }
1166
1167 static int getExternalResult(int result) {
1168 // Aborted results are treated as successes externally, but we must track them internally.
1169 return result != START_ABORTED ? result : START_SUCCESS;
1170 }
1171
1172 /**
1173 * Called when execution is complete. Sets state indicating completion and proceeds with
1174 * recycling if appropriate.
1175 */
1176 private void onExecutionComplete() {
1177 mController.onExecutionComplete(this);
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -08001178 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001179
Ricky Waiaca8a772019-04-04 16:01:06 +01001180 boolean shouldAbortBackgroundActivityStart(int callingUid, int callingPid,
Michal Karpinski9cbb20b2019-02-05 17:31:50 +00001181 final String callingPackage, int realCallingUid, int realCallingPid,
1182 WindowProcessController callerApp, PendingIntentRecord originatingPendingIntent,
1183 boolean allowBackgroundActivityStart, Intent intent) {
Michal Karpinski8596ded2018-11-14 14:43:48 +00001184 // don't abort for the most important UIDs
Alan Stokes2f4a4ed2019-05-08 16:56:45 +01001185 final int callingAppId = UserHandle.getAppId(callingUid);
1186 if (callingUid == Process.ROOT_UID || callingAppId == Process.SYSTEM_UID
1187 || callingAppId == Process.NFC_UID) {
Michal Karpinski8596ded2018-11-14 14:43:48 +00001188 return false;
1189 }
Alan Stokeseea8d3e2019-04-10 17:37:25 +01001190 // don't abort if the callingUid has a visible window or is a persistent system process
Riddle Hsua0536432019-02-16 00:38:59 +08001191 final int callingUidProcState = mService.getUidState(callingUid);
Michal Karpinski4fd5b842019-01-28 15:13:32 +00001192 final boolean callingUidHasAnyVisibleWindow =
1193 mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(callingUid);
1194 final boolean isCallingUidForeground = callingUidHasAnyVisibleWindow
Amith Yamasanif235d0b2019-03-20 22:49:43 -07001195 || callingUidProcState == ActivityManager.PROCESS_STATE_TOP
1196 || callingUidProcState == ActivityManager.PROCESS_STATE_BOUND_TOP;
Alan Stokes2f4a4ed2019-05-08 16:56:45 +01001197 final boolean isCallingUidPersistentSystemProcess =
1198 callingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
Alan Stokeseea8d3e2019-04-10 17:37:25 +01001199 if (callingUidHasAnyVisibleWindow || isCallingUidPersistentSystemProcess) {
Michal Karpinski8596ded2018-11-14 14:43:48 +00001200 return false;
1201 }
Michal Karpinskiac116df2018-12-10 17:51:42 +00001202 // take realCallingUid into consideration
Michal Karpinski4fd5b842019-01-28 15:13:32 +00001203 final int realCallingUidProcState = (callingUid == realCallingUid)
1204 ? callingUidProcState
Riddle Hsua0536432019-02-16 00:38:59 +08001205 : mService.getUidState(realCallingUid);
Michal Karpinski4fd5b842019-01-28 15:13:32 +00001206 final boolean realCallingUidHasAnyVisibleWindow = (callingUid == realCallingUid)
1207 ? callingUidHasAnyVisibleWindow
1208 : mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(realCallingUid);
1209 final boolean isRealCallingUidForeground = (callingUid == realCallingUid)
1210 ? isCallingUidForeground
1211 : realCallingUidHasAnyVisibleWindow
1212 || realCallingUidProcState == ActivityManager.PROCESS_STATE_TOP;
Alan Stokes2f4a4ed2019-05-08 16:56:45 +01001213 final int realCallingAppId = UserHandle.getAppId(realCallingUid);
Michal Karpinski4fd5b842019-01-28 15:13:32 +00001214 final boolean isRealCallingUidPersistentSystemProcess = (callingUid == realCallingUid)
1215 ? isCallingUidPersistentSystemProcess
Alan Stokes2f4a4ed2019-05-08 16:56:45 +01001216 : (realCallingAppId == Process.SYSTEM_UID)
Michal Karpinski4fd5b842019-01-28 15:13:32 +00001217 || realCallingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
Michal Karpinskiac116df2018-12-10 17:51:42 +00001218 if (realCallingUid != callingUid) {
Alan Stokes6ac9efd2019-05-09 12:50:37 +00001219 // don't abort if the realCallingUid has a visible window
1220 if (realCallingUidHasAnyVisibleWindow) {
Michal Karpinskiac116df2018-12-10 17:51:42 +00001221 return false;
1222 }
1223 // if the realCallingUid is a persistent system process, abort if the IntentSender
1224 // wasn't whitelisted to start an activity
Michal Karpinskid0162852019-01-15 16:05:25 +00001225 if (isRealCallingUidPersistentSystemProcess && allowBackgroundActivityStart) {
Michal Karpinskiac116df2018-12-10 17:51:42 +00001226 return false;
1227 }
Michal Karpinskida34cd42019-04-02 19:46:52 +01001228 // don't abort if the realCallingUid is an associated companion app
1229 if (mService.isAssociatedCompanionApp(UserHandle.getUserId(realCallingUid),
1230 realCallingUid)) {
1231 return false;
1232 }
Michal Karpinskiac116df2018-12-10 17:51:42 +00001233 }
Michal Karpinski7b97a022018-12-14 15:17:29 +00001234 // don't abort if the callingUid has START_ACTIVITIES_FROM_BACKGROUND permission
1235 if (mService.checkPermission(START_ACTIVITIES_FROM_BACKGROUND, callingPid, callingUid)
1236 == PERMISSION_GRANTED) {
1237 return false;
1238 }
Michal Karpinski82bb5902018-11-28 15:52:52 +00001239 // don't abort if the caller has the same uid as the recents component
1240 if (mSupervisor.mRecentTasks.isCallerRecents(callingUid)) {
1241 return false;
1242 }
Ricky Wai96f5c352019-04-10 18:40:17 +01001243 // don't abort if the callingUid is the device owner
1244 if (mService.isDeviceOwner(callingUid)) {
Michal Karpinski302dcec2019-02-01 11:48:25 +00001245 return false;
1246 }
Ricky Wai96f5c352019-04-10 18:40:17 +01001247 // don't abort if the callingUid has companion device
Ricky Wai2452e2d2019-03-18 19:19:08 +00001248 final int callingUserId = UserHandle.getUserId(callingUid);
Michal Karpinskida34cd42019-04-02 19:46:52 +01001249 if (mService.isAssociatedCompanionApp(callingUserId, callingUid)) {
Ricky Wai2452e2d2019-03-18 19:19:08 +00001250 return false;
1251 }
Michal Karpinski2e0aad22019-04-12 16:22:55 +01001252 // If we don't have callerApp at this point, no caller was provided to startActivity().
1253 // That's the case for PendingIntent-based starts, since the creator's process might not be
1254 // up and alive. If that's the case, we retrieve the WindowProcessController for the send()
1255 // caller, so that we can make the decision based on its foreground/whitelisted state.
1256 int callerAppUid = callingUid;
1257 if (callerApp == null) {
1258 callerApp = mService.getProcessController(realCallingPid, realCallingUid);
1259 callerAppUid = realCallingUid;
1260 }
1261 // don't abort if the callerApp or other processes of that uid are whitelisted in any way
1262 if (callerApp != null) {
1263 // first check the original calling process
1264 if (callerApp.areBackgroundActivityStartsAllowed()) {
1265 return false;
1266 }
1267 // only if that one wasn't whitelisted, check the other ones
1268 final ArraySet<WindowProcessController> uidProcesses =
1269 mService.mProcessMap.getProcesses(callerAppUid);
1270 if (uidProcesses != null) {
1271 for (int i = uidProcesses.size() - 1; i >= 0; i--) {
1272 final WindowProcessController proc = uidProcesses.valueAt(i);
1273 if (proc != callerApp && proc.areBackgroundActivityStartsAllowed()) {
1274 return false;
1275 }
1276 }
1277 }
1278 }
Michal Karpinski15486842019-04-25 17:33:42 +01001279 // don't abort if the callingUid has SYSTEM_ALERT_WINDOW permission
1280 if (mService.hasSystemAlertWindowPermission(callingUid, callingPid, callingPackage)) {
1281 Slog.w(TAG, "Background activity start for " + callingPackage
1282 + " allowed because SYSTEM_ALERT_WINDOW permission is granted.");
1283 return false;
1284 }
Michal Karpinskic02364c2019-01-22 13:00:04 +00001285 // anything that has fallen through would currently be aborted
1286 Slog.w(TAG, "Background activity start [callingPackage: " + callingPackage
Michal Karpinskid0162852019-01-15 16:05:25 +00001287 + "; callingUid: " + callingUid
1288 + "; isCallingUidForeground: " + isCallingUidForeground
1289 + "; isCallingUidPersistentSystemProcess: " + isCallingUidPersistentSystemProcess
1290 + "; realCallingUid: " + realCallingUid
1291 + "; isRealCallingUidForeground: " + isRealCallingUidForeground
1292 + "; isRealCallingUidPersistentSystemProcess: "
Ricky Waiaca8a772019-04-04 16:01:06 +01001293 + isRealCallingUidPersistentSystemProcess
Michal Karpinskid0162852019-01-15 16:05:25 +00001294 + "; originatingPendingIntent: " + originatingPendingIntent
1295 + "; isBgStartWhitelisted: " + allowBackgroundActivityStart
1296 + "; intent: " + intent
Michal Karpinski9cbb20b2019-02-05 17:31:50 +00001297 + "; callerApp: " + callerApp
Michal Karpinskid0162852019-01-15 16:05:25 +00001298 + "]");
Michal Karpinski4fd5b842019-01-28 15:13:32 +00001299 // log aborted activity start to TRON
1300 if (mService.isActivityStartsLoggingEnabled()) {
1301 mSupervisor.getActivityMetricsLogger().logAbortedBgActivityStart(intent, callerApp,
1302 callingUid, callingPackage, callingUidProcState, callingUidHasAnyVisibleWindow,
1303 realCallingUid, realCallingUidProcState, realCallingUidHasAnyVisibleWindow,
Michal Karpinski201bc0c2018-07-20 15:32:00 +01001304 (originatingPendingIntent != null));
Michal Karpinski201bc0c2018-07-20 15:32:00 +01001305 }
Michal Karpinski4fd5b842019-01-28 15:13:32 +00001306 return true;
Michal Karpinski201bc0c2018-07-20 15:32:00 +01001307 }
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001308
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001309 /**
1310 * Creates a launch intent for the given auxiliary resolution data.
1311 */
Patrick Baumann577d4022018-01-31 16:55:10 +00001312 private @NonNull Intent createLaunchIntent(@Nullable AuxiliaryResolveInfo auxiliaryResponse,
Philip P. Moltmann9c5226f2020-01-10 08:53:43 -08001313 Intent originalIntent, String callingPackage, @Nullable String callingFeatureId,
1314 Bundle verificationBundle, String resolvedType, int userId) {
Patrick Baumann577d4022018-01-31 16:55:10 +00001315 if (auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo) {
Todd Kennedye9910222017-02-21 16:00:11 -08001316 // request phase two resolution
Winson81fef842019-08-28 12:19:08 -07001317 PackageManagerInternal packageManager = mService.getPackageManagerInternalLocked();
1318 boolean isRequesterInstantApp = packageManager.isInstantApp(callingPackage, userId);
1319 packageManager.requestInstantAppResolutionPhaseTwo(
Chad Brubaker06068612017-04-06 09:43:47 -07001320 auxiliaryResponse, originalIntent, resolvedType, callingPackage,
Philip P. Moltmann9c5226f2020-01-10 08:53:43 -08001321 callingFeatureId, isRequesterInstantApp, verificationBundle, userId);
Todd Kennedye9910222017-02-21 16:00:11 -08001322 }
Todd Kennedydfc27c62017-05-17 15:32:10 -07001323 return InstantAppResolver.buildEphemeralInstallerIntent(
Patrick Baumann577d4022018-01-31 16:55:10 +00001324 originalIntent,
1325 InstantAppResolver.sanitizeIntent(originalIntent),
1326 auxiliaryResponse == null ? null : auxiliaryResponse.failureIntent,
1327 callingPackage,
Philip P. Moltmann9c5226f2020-01-10 08:53:43 -08001328 callingFeatureId,
Patrick Baumann577d4022018-01-31 16:55:10 +00001329 verificationBundle,
1330 resolvedType,
1331 userId,
1332 auxiliaryResponse == null ? null : auxiliaryResponse.installFailureActivity,
1333 auxiliaryResponse == null ? null : auxiliaryResponse.token,
1334 auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo,
1335 auxiliaryResponse == null ? null : auxiliaryResponse.filters);
Todd Kennedye9910222017-02-21 16:00:11 -08001336 }
1337
Riddle Hsu16567132018-08-16 21:37:47 +08001338 void postStartActivityProcessing(ActivityRecord r, int result,
1339 ActivityStack startedActivityStack) {
Winson Chunge219ae12019-07-18 13:43:23 -07001340 if (!ActivityManager.isStartResultSuccessful(result)) {
1341 if (mFrozeTaskList) {
1342 // If we specifically froze the task list as part of starting an activity, then
1343 // reset the frozen list state if it failed to start. This is normally otherwise
1344 // called when the freeze-timeout has elapsed.
1345 mSupervisor.mRecentTasks.resetFreezeTaskListReorderingOnTimeout();
1346 }
1347 }
Bryce Lee7f936862017-05-09 15:33:18 -07001348 if (ActivityManager.isStartResultFatalError(result)) {
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -08001349 return;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001350 }
Filip Gruszczynski303210b2016-01-08 16:28:08 -08001351
Chong Zhang5022da32016-06-21 16:31:37 -07001352 // We're waiting for an activity launch to finish, but that activity simply
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001353 // brought another activity to front. We must also handle the case where the task is already
1354 // 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 +08001355 // considered focused as the trampoline will be finished). Let them know about this, so
1356 // it waits for the new activity to become visible instead, {@link #waitResultIfNeeded}.
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001357 mSupervisor.reportWaitingActivityLaunchedIfNeeded(r, result);
Chong Zhang5022da32016-06-21 16:31:37 -07001358
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001359 if (startedActivityStack == null) {
1360 return;
1361 }
1362
Wale Ogunwaleac36e4d2017-11-29 13:30:26 -08001363 final int clearTaskFlags = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK;
1364 boolean clearedTask = (mLaunchFlags & clearTaskFlags) == clearTaskFlags
1365 && mReuseTask != null;
Wale Ogunwale7d7973a2018-04-05 10:25:59 -07001366 if (result == START_TASK_TO_FRONT || result == START_DELIVERED_TO_TOP || clearedTask) {
1367 // The activity was already running so it wasn't started, but either brought to the
1368 // front or the new intent was delivered to it since it was already in front. Notify
1369 // anyone interested in this piece of information.
1370 switch (startedActivityStack.getWindowingMode()) {
1371 case WINDOWING_MODE_PINNED:
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001372 mService.getTaskChangeNotificationController().notifyPinnedActivityRestartAttempt(
Wale Ogunwale7d7973a2018-04-05 10:25:59 -07001373 clearedTask);
1374 break;
1375 case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
Louis Changbd48dca2018-08-29 17:44:34 +08001376 final ActivityStack homeStack =
Wale Ogunwale734b8962020-01-21 12:17:42 -08001377 startedActivityStack.getDisplay().getRootHomeTask();
Wale Ogunwale7d7973a2018-04-05 10:25:59 -07001378 if (homeStack != null && homeStack.shouldBeVisible(null /* starting */)) {
1379 mService.mWindowManager.showRecentApps();
1380 }
1381 break;
1382 }
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -08001383 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001384 }
1385
Svet Ganovcbcbf662018-05-10 17:25:29 -07001386 /**
1387 * Compute the logical UID based on which the package manager would filter
1388 * app components i.e. based on which the instant app policy would be applied
1389 * because it is the logical calling UID.
1390 *
1391 * @param customCallingUid The UID on whose behalf to make the call.
1392 * @param actualCallingUid The UID actually making the call.
Patrick Baumann31426b22018-05-21 13:46:40 -07001393 * @param filterCallingUid The UID to be used to filter for instant apps.
Svet Ganovcbcbf662018-05-10 17:25:29 -07001394 * @return The logical UID making the call.
1395 */
Patrick Baumann31426b22018-05-21 13:46:40 -07001396 static int computeResolveFilterUid(int customCallingUid, int actualCallingUid,
1397 int filterCallingUid) {
1398 return filterCallingUid != UserHandle.USER_NULL
1399 ? filterCallingUid
1400 : (customCallingUid >= 0 ? customCallingUid : actualCallingUid);
Svet Ganovcbcbf662018-05-10 17:25:29 -07001401 }
1402
Louis Chang54fbb052019-10-16 17:10:17 +08001403 /**
1404 * Start an activity while most of preliminary checks has been done and caller has been
1405 * confirmed that holds necessary permissions to do so.
1406 * Here also ensures that the starting activity is removed if the start wasn't successful.
1407 */
1408 private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
Bryce Leedaa91e42017-12-06 14:13:01 -08001409 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
Louis Changcdec0802019-11-11 11:45:07 +08001410 int startFlags, boolean doResume, ActivityOptions options, Task inTask,
Louis Chang54fbb052019-10-16 17:10:17 +08001411 boolean restrictedBgActivity) {
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001412 int result = START_CANCELED;
Riddle Hsu16567132018-08-16 21:37:47 +08001413 final ActivityStack startedActivityStack;
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001414 try {
Riddle Hsua0022cd2019-09-09 21:12:41 +08001415 mService.deferWindowLayout();
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001416 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
1417 result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
Louis Chang54fbb052019-10-16 17:10:17 +08001418 startFlags, doResume, options, inTask, restrictedBgActivity);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001419 } finally {
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001420 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
1421 startedActivityStack = handleStartResult(r, result);
Riddle Hsua0022cd2019-09-09 21:12:41 +08001422 mService.continueWindowLayout();
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001423 }
1424
Riddle Hsu16567132018-08-16 21:37:47 +08001425 postStartActivityProcessing(r, result, startedActivityStack);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001426
1427 return result;
1428 }
1429
Ricky Waib147fa12019-04-25 16:08:30 +01001430 /**
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001431 * If the start result is success, ensure that the configuration of the started activity matches
1432 * the current display. Otherwise clean up unassociated containers to avoid leakage.
1433 *
1434 * @return the stack where the successful started activity resides.
1435 */
1436 private @Nullable ActivityStack handleStartResult(@NonNull ActivityRecord started, int result) {
Wale Ogunwale1ebcd8e2020-01-21 11:27:03 -08001437 final ActivityStack currentStack = started.getRootTask();
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001438 ActivityStack startedActivityStack = currentStack != null ? currentStack : mTargetStack;
1439
1440 if (ActivityManager.isStartResultSuccessful(result)) {
1441 if (startedActivityStack != null) {
1442 // If there is no state change (e.g. a resumed activity is reparented to top of
1443 // another display) to trigger a visibility/configuration checking, we have to
1444 // update the configuration for changing to different display.
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09001445 final ActivityRecord currentTop = startedActivityStack.topRunningActivity();
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001446 if (currentTop != null && currentTop.shouldUpdateConfigForDisplayChanged()) {
Louis Chang149d5c82019-12-30 09:47:39 +08001447 mRootWindowContainer.ensureVisibilityAndConfig(
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001448 currentTop, currentTop.getDisplayId(),
1449 true /* markFrozenIfConfigChanged */, false /* deferResume */);
1450 }
1451 }
1452 return startedActivityStack;
1453 }
1454
1455 // If we are not able to proceed, disassociate the activity from the task. Leaving an
1456 // activity in an incomplete state can lead to issues, such as performing operations
1457 // without a window container.
Wale Ogunwale1ebcd8e2020-01-21 11:27:03 -08001458 final ActivityStack stack = mStartActivity.getRootTask();
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001459 if (stack != null) {
1460 mStartActivity.finishIfPossible("startActivity", true /* oomAdj */);
1461 }
1462
1463 // Stack should also be detached from display and be removed if it's empty.
1464 if (startedActivityStack != null && startedActivityStack.isAttached()
Wale Ogunwalea38654f2019-11-17 20:37:15 -08001465 && !startedActivityStack.hasActivity()
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001466 && !startedActivityStack.isActivityTypeHome()) {
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -07001467 startedActivityStack.removeIfPossible();
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001468 startedActivityStack = null;
1469 }
1470 return startedActivityStack;
1471 }
1472
1473 /**
Louis Chang54fbb052019-10-16 17:10:17 +08001474 * Start an activity and determine if the activity should be adding to the top of an existing
1475 * task or delivered new intent to an existing activity. Also manipulating the activity task
1476 * onto requested or valid stack/display.
Ricky Waib147fa12019-04-25 16:08:30 +01001477 *
Louis Chang54fbb052019-10-16 17:10:17 +08001478 * Note: This method should only be called from {@link #startActivityUnchecked}.
Ricky Waib147fa12019-04-25 16:08:30 +01001479 */
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001480 private int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
Wale Ogunwale01d66562015-12-29 08:19:19 -08001481 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
Louis Changcdec0802019-11-11 11:45:07 +08001482 int startFlags, boolean doResume, ActivityOptions options, Task inTask,
Louis Chang54fbb052019-10-16 17:10:17 +08001483 boolean restrictedBgActivity) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001484 setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
Ricky Waib147fa12019-04-25 16:08:30 +01001485 voiceInteractor, restrictedBgActivity);
1486
Louis Chang39ba54b2018-10-18 11:28:57 +08001487 final int preferredWindowingMode = mLaunchParams.mWindowingMode;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001488
Louis Chang6fb1e842018-12-03 16:07:50 +08001489 computeLaunchingTaskFlags();
1490
1491 computeSourceStack();
1492
1493 mIntent.setFlags(mLaunchFlags);
1494
Louis Changcdec0802019-11-11 11:45:07 +08001495 final Task reusedTask = getReusableTask();
Louis Chang6fb1e842018-12-03 16:07:50 +08001496
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
Louis Chang38430df2020-01-02 17:14:59 +08001509 computeLaunchParams(r, sourceRecord, targetTask);
1510
Louis Changbde91e92019-08-16 17:19:47 +08001511 // Check if starting activity on given task or on a new task is allowed.
1512 int startResult = isAllowedToStart(r, newTask, targetTask);
1513 if (startResult != START_SUCCESS) {
1514 return startResult;
Louis Changbd48dca2018-08-29 17:44:34 +08001515 }
1516
Wale Ogunwale21e06482019-11-18 05:14:15 -08001517 final ActivityRecord targetTaskTop = newTask
1518 ? null : targetTask.getTopNonFinishingActivity();
Louis Changbde91e92019-08-16 17:19:47 +08001519 if (targetTaskTop != null) {
1520 // Recycle the target task for this launch.
Louis Changf7dd7f22019-11-05 11:59:56 +08001521 startResult = recycleTask(targetTask, targetTaskTop, reusedTask);
Louis Changbde91e92019-08-16 17:19:47 +08001522 if (startResult != START_SUCCESS) {
1523 return startResult;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001524 }
Louis Changf7dd7f22019-11-05 11:59:56 +08001525 } else {
1526 mAddingToTask = true;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001527 }
1528
1529 // If the activity being launched is the same as the one currently at the top, then
1530 // we need to check if it should only be launched once.
Louis Chang149d5c82019-12-30 09:47:39 +08001531 final ActivityStack topStack = mRootWindowContainer.getTopDisplayFocusedStack();
Louis Changbde91e92019-08-16 17:19:47 +08001532 startResult = deliverToCurrentTopIfNeeded(topStack);
1533 if (startResult != START_SUCCESS) {
1534 return startResult;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001535 }
1536
Louis Changbde91e92019-08-16 17:19:47 +08001537 if (mTargetStack == null) {
Louis Chang38430df2020-01-02 17:14:59 +08001538 mTargetStack = getLaunchStack(mStartActivity, mLaunchFlags, targetTask, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001539 }
Louis Changbde91e92019-08-16 17:19:47 +08001540 if (newTask) {
Louis Changcdec0802019-11-11 11:45:07 +08001541 final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
1542 ? mSourceRecord.getTask() : null;
Louis Changbde91e92019-08-16 17:19:47 +08001543 setNewTask(taskToAffiliate);
Louis Changa3e6b892019-09-16 10:39:00 +08001544 if (mService.getLockTaskController().isLockTaskModeViolation(
Louis Changcdec0802019-11-11 11:45:07 +08001545 mStartActivity.getTask())) {
Louis Changa3e6b892019-09-16 10:39:00 +08001546 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
1547 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
1548 }
Louis Changbde91e92019-08-16 17:19:47 +08001549 } else if (mAddingToTask) {
1550 addOrReparentStartingActivity(targetTask, "adding to task");
1551 }
1552
1553 if (!mAvoidMoveToFront && mDoResume) {
1554 mTargetStack.moveToFront("reuseOrNewTask");
Chong Zhang6cda19c2016-06-14 19:07:56 -07001555 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001556
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00001557 mService.mUgmInternal.grantUriPermissionFromIntent(mCallingUid, mStartActivity.packageName,
1558 mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.mUserId);
Patrick Baumannde37e432019-08-28 09:51:29 -07001559 mService.getPackageManagerInternalLocked().grantImplicitAccess(
Andrii Kulianeceebbf2019-06-26 17:36:51 -07001560 mStartActivity.mUserId, mIntent,
Patrick Baumannb6e72972019-09-20 07:54:47 -07001561 mCallingUid,
Patrick Baumannde37e432019-08-28 09:51:29 -07001562 UserHandle.getAppId(mStartActivity.info.applicationInfo.uid)
1563 );
Wale Ogunwale01d66562015-12-29 08:19:19 -08001564 if (newTask) {
Jeff Changd136e772019-11-05 20:33:52 +08001565 EventLogTags.writeWmCreateTask(mStartActivity.mUserId,
Louis Changcdec0802019-11-11 11:45:07 +08001566 mStartActivity.getTask().mTaskId);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001567 }
Andrii Kulian79d67982019-08-19 11:56:16 -07001568 mStartActivity.logStartActivity(
Jeff Changd136e772019-11-05 20:33:52 +08001569 EventLogTags.WM_CREATE_ACTIVITY, mStartActivity.getTask());
1570
Wale Ogunwale01d66562015-12-29 08:19:19 -08001571 mTargetStack.mLastPausedActivity = null;
Wei Wang98f03f92016-05-18 11:32:52 -07001572
Louis Chang149d5c82019-12-30 09:47:39 +08001573 mRootWindowContainer.sendPowerHintForLaunchStartIfNeeded(
Wale Ogunwaled32da472018-11-16 07:19:28 -08001574 false /* forceSend */, mStartActivity);
Wei Wang98f03f92016-05-18 11:32:52 -07001575
Wale Ogunwale21e06482019-11-18 05:14:15 -08001576 mTargetStack.startActivityLocked(mStartActivity, topStack.getTopNonFinishingActivity(),
1577 newTask, mKeepCurTransition, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001578 if (mDoResume) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001579 final ActivityRecord topTaskActivity =
Louis Changcdec0802019-11-11 11:45:07 +08001580 mStartActivity.getTask().topRunningActivityLocked();
Evan Rosky226de132020-01-03 18:00:29 -08001581 if (!mTargetStack.isTopActivityFocusable()
Wale Ogunwale0b3d2922019-12-30 08:55:07 -08001582 || (topTaskActivity != null && topTaskActivity.isTaskOverlay()
Wale Ogunwale68741142016-05-17 09:40:02 -07001583 && mStartActivity != topTaskActivity)) {
Filip Gruszczynski3d7fdc12016-01-31 17:33:29 -08001584 // If the activity is not focusable, we can't resume it, but still would like to
1585 // make sure it becomes visible as it starts (this will also trigger entry
1586 // animation). An example of this are PIP activities.
Wale Ogunwale3b232392016-05-13 15:37:13 -07001587 // Also, we don't want to resume activities in a task that currently has an overlay
1588 // as the starting activity just needs to be in the visible paused state until the
1589 // over is removed.
Wale Ogunwale076c3b12019-11-20 12:17:22 -08001590 mTargetStack.ensureActivitiesVisible(mStartActivity, 0, !PRESERVE_WINDOWS);
Wale Ogunwaleae846f42016-02-22 14:00:56 -08001591 // Go ahead and tell window manager to execute app transition for this activity
1592 // since the app transition will not be triggered through the resume channel.
Wale Ogunwale3a256e62018-12-06 14:41:18 -08001593 mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
Wale Ogunwale3b232392016-05-13 15:37:13 -07001594 } else {
Winson Chung32066032016-11-04 11:55:21 -07001595 // If the target stack was not previously focusable (previous top running activity
1596 // on that stack was not visible) then any prior calls to move the stack to the
1597 // will not update the focused stack. If starting the new activity now allows the
1598 // task stack to be focusable, then ensure that we now update the focused stack
1599 // accordingly.
Evan Rosky226de132020-01-03 18:00:29 -08001600 if (mTargetStack.isTopActivityFocusable()
Louis Chang149d5c82019-12-30 09:47:39 +08001601 && !mRootWindowContainer.isTopDisplayFocusedStack(mTargetStack)) {
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001602 mTargetStack.moveToFront("startActivityInner");
Winson Chung32066032016-11-04 11:55:21 -07001603 }
Louis Chang149d5c82019-12-30 09:47:39 +08001604 mRootWindowContainer.resumeFocusedStacksTopActivities(
Wale Ogunwaled32da472018-11-16 07:19:28 -08001605 mTargetStack, mStartActivity, mOptions);
Filip Gruszczynski3d7fdc12016-01-31 17:33:29 -08001606 }
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
Winson Chungf45dd9f2019-10-11 15:07:47 -07001610 // Update the recent tasks list immediately when the activity starts
1611 mSupervisor.mRecentTasks.add(mStartActivity.getTask());
Louis Changcdec0802019-11-11 11:45:07 +08001612 mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(),
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001613 preferredWindowingMode, mPreferredDisplayId, mTargetStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001614
1615 return START_SUCCESS;
1616 }
1617
Louis Changcdec0802019-11-11 11:45:07 +08001618 private Task computeTargetTask() {
Louis Changf7dd7f22019-11-05 11:59:56 +08001619 if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
Louis Changbde91e92019-08-16 17:19:47 +08001620 && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1621 // A new task should be created instead of using existing one.
1622 return null;
1623 } else if (mSourceRecord != null) {
Louis Changcdec0802019-11-11 11:45:07 +08001624 return mSourceRecord.getTask();
Louis Changbde91e92019-08-16 17:19:47 +08001625 } else if (mInTask != null) {
1626 return mInTask;
1627 } else {
Louis Chang38430df2020-01-02 17:14:59 +08001628 final ActivityStack stack = getLaunchStack(mStartActivity, mLaunchFlags,
1629 null /* task */, mOptions);
1630 final ActivityRecord top = stack.getTopNonFinishingActivity();
Louis Changbde91e92019-08-16 17:19:47 +08001631 if (top != null) {
Louis Changcdec0802019-11-11 11:45:07 +08001632 return top.getTask();
Louis Chang38430df2020-01-02 17:14:59 +08001633 } else {
1634 // Remove the stack if no activity in the stack.
1635 stack.removeIfPossible();
Louis Changbde91e92019-08-16 17:19:47 +08001636 }
1637 }
1638 return null;
1639 }
1640
Louis Chang38430df2020-01-02 17:14:59 +08001641 private void computeLaunchParams(ActivityRecord r, ActivityRecord sourceRecord,
1642 Task targetTask) {
1643 final ActivityStack sourceStack = mSourceStack != null ? mSourceStack
1644 : mRootWindowContainer.getTopDisplayFocusedStack();
1645 if (sourceStack != null && sourceStack.inSplitScreenWindowingMode()
1646 && (mOptions == null
1647 || mOptions.getLaunchWindowingMode() == WINDOWING_MODE_UNDEFINED)) {
1648 int windowingMode =
1649 targetTask != null ? targetTask.getWindowingMode() : WINDOWING_MODE_UNDEFINED;
1650 if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
1651 if (sourceStack.inSplitScreenPrimaryWindowingMode()) {
1652 windowingMode = WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
1653 } else if (sourceStack.inSplitScreenSecondaryWindowingMode()) {
1654 windowingMode = WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
1655 }
1656 }
1657
1658 if (mOptions == null) {
1659 mOptions = ActivityOptions.makeBasic();
1660 }
1661 mOptions.setLaunchWindowingMode(windowingMode);
1662 }
1663
1664 mSupervisor.getLaunchParamsController().calculate(targetTask, r.info.windowLayout, r,
1665 sourceRecord, mOptions, PHASE_BOUNDS, mLaunchParams);
1666 mPreferredDisplayId =
1667 mLaunchParams.hasPreferredDisplay() ? mLaunchParams.mPreferredDisplayId
1668 : DEFAULT_DISPLAY;
1669 }
1670
Louis Changcdec0802019-11-11 11:45:07 +08001671 private int isAllowedToStart(ActivityRecord r, boolean newTask, Task targetTask) {
Louis Changbde91e92019-08-16 17:19:47 +08001672 if (mStartActivity.packageName == null) {
1673 if (mStartActivity.resultTo != null) {
1674 mStartActivity.resultTo.sendResult(INVALID_UID, mStartActivity.resultWho,
1675 mStartActivity.requestCode, RESULT_CANCELED, null /* data */);
1676 }
1677 ActivityOptions.abort(mOptions);
1678 return START_CLASS_NOT_FOUND;
1679 }
1680
1681 // Do not start home activity if it cannot be launched on preferred display. We are not
1682 // doing this in ActivityStackSupervisor#canPlaceEntityOnDisplay because it might
1683 // fallback to launch on other displays.
Louis Chang149d5c82019-12-30 09:47:39 +08001684 if (r.isActivityTypeHome() && !mRootWindowContainer.canStartHomeOnDisplay(r.info,
Louis Changbde91e92019-08-16 17:19:47 +08001685 mPreferredDisplayId, true /* allowInstrumenting */)) {
1686 Slog.w(TAG, "Cannot launch home on display " + mPreferredDisplayId);
1687 return START_CANCELED;
1688 }
1689
Wale Ogunwalea38654f2019-11-17 20:37:15 -08001690 if (mRestrictedBgActivity && (newTask || !targetTask.isUidPresent(mCallingUid))
Louis Changbde91e92019-08-16 17:19:47 +08001691 && handleBackgroundActivityAbort(mStartActivity)) {
1692 Slog.e(TAG, "Abort background activity starts from " + mCallingUid);
1693 return START_ABORTED;
1694 }
1695
1696 // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but still
1697 // needs to be a lock task mode violation since the task gets cleared out and the device
1698 // would otherwise leave the locked task.
1699 final boolean isNewClearTask =
1700 (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1701 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
Louis Changa3e6b892019-09-16 10:39:00 +08001702 if (!newTask && mService.getLockTaskController().isLockTaskModeViolation(targetTask,
1703 isNewClearTask)) {
Louis Changbde91e92019-08-16 17:19:47 +08001704 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
1705 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
1706 }
1707
1708 return START_SUCCESS;
1709 }
1710
1711 /**
1712 * Prepare the target task to be reused for this launch, which including:
1713 * - Position the target task on valid stack on preferred display.
1714 * - Comply to the specified activity launch flags
1715 * - Determine whether need to add a new activity on top or just brought the task to front.
1716 */
Louis Chang07b13002019-11-27 22:08:37 +08001717 @VisibleForTesting
1718 int recycleTask(Task targetTask, ActivityRecord targetTaskTop, Task reusedTask) {
1719 // Should not recycle task which is from a different user, just adding the starting
1720 // activity to the task.
1721 if (targetTask.mUserId != mStartActivity.mUserId) {
1722 mTargetStack = targetTask.getStack();
1723 mAddingToTask = true;
1724 return START_SUCCESS;
1725 }
1726
Wale Ogunwaleda8b8272018-11-29 19:37:37 -08001727 boolean clearTaskForReuse = false;
Louis Changf7dd7f22019-11-05 11:59:56 +08001728 if (reusedTask != null) {
Louis Chang2787a9a2019-12-17 15:15:11 +08001729 if (mStartActivity.getTask() == null) {
Louis Changf7dd7f22019-11-05 11:59:56 +08001730 mStartActivity.setTaskForReuse(reusedTask);
Wale Ogunwaleda8b8272018-11-29 19:37:37 -08001731 clearTaskForReuse = true;
1732 }
1733
Louis Changbde91e92019-08-16 17:19:47 +08001734 if (targetTask.intent == null) {
1735 // This task was started because of movement of the activity based on
1736 // affinity...
1737 // Now that we are actually launching it, we can assign the base intent.
1738 targetTask.setIntent(mStartActivity);
1739 } else {
1740 final boolean taskOnHome =
1741 (mStartActivity.intent.getFlags() & FLAG_ACTIVITY_TASK_ON_HOME) != 0;
1742 if (taskOnHome) {
1743 targetTask.intent.addFlags(FLAG_ACTIVITY_TASK_ON_HOME);
1744 } else {
1745 targetTask.intent.removeFlags(FLAG_ACTIVITY_TASK_ON_HOME);
1746 }
1747 }
1748 }
1749
Louis Chang149d5c82019-12-30 09:47:39 +08001750 mRootWindowContainer.sendPowerHintForLaunchStartIfNeeded(false /* forceSend */,
Louis Changbde91e92019-08-16 17:19:47 +08001751 targetTaskTop);
1752
1753 setTargetStackIfNeeded(targetTaskTop);
1754
Louis Changbde91e92019-08-16 17:19:47 +08001755 // When there is a reused activity and the current result is a trampoline activity,
1756 // set the reused activity as the result.
Louis Chang54fbb052019-10-16 17:10:17 +08001757 if (mLastStartActivityRecord != null
1758 && (mLastStartActivityRecord.finishing || mLastStartActivityRecord.noDisplay)) {
1759 mLastStartActivityRecord = targetTaskTop;
Louis Changbde91e92019-08-16 17:19:47 +08001760 }
1761
1762 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1763 // We don't need to start a new activity, and the client said not to do anything
1764 // if that is the case, so this is it! And for paranoia, make sure we have
1765 // correctly resumed the top activity.
1766 if (!mMovedToFront && mDoResume) {
1767 if (DEBUG_TASKS) {
1768 Slog.d(TAG_TASKS, "Bring to front target: " + mTargetStack
1769 + " from " + targetTaskTop);
1770 }
1771 mTargetStack.moveToFront("intentActivityFound");
1772 }
1773 resumeTargetStackIfNeeded();
1774 return START_RETURN_INTENT_TO_CALLER;
1775 }
1776
Wale Ogunwale21e06482019-11-18 05:14:15 -08001777 complyActivityFlags(targetTask,
1778 reusedTask != null ? reusedTask.getTopNonFinishingActivity() : null);
Louis Changbde91e92019-08-16 17:19:47 +08001779
Wale Ogunwaleda8b8272018-11-29 19:37:37 -08001780 if (clearTaskForReuse) {
1781 // Clear task for re-use so later code to methods
1782 // {@link #setTaskFromReuseOrCreateNewTask}, {@link #setTaskFromSourceRecord}, or
1783 // {@link #setTaskFromInTask} can parent it to the task.
1784 mStartActivity.setTaskForReuse(null);
1785 }
1786
Louis Changbde91e92019-08-16 17:19:47 +08001787 if (mAddingToTask) {
1788 return START_SUCCESS;
1789 }
1790
Louis Chang3ee5fc02019-09-23 11:32:10 +08001791 if (mMovedToFront) {
1792 // We moved the task to front, use starting window to hide initial drawn delay.
1793 targetTaskTop.showStartingWindow(null /* prev */, false /* newTask */,
1794 true /* taskSwitch */);
1795 } else if (mDoResume) {
1796 // Make sure the stack and its belonging display are moved to topmost.
Louis Changbde91e92019-08-16 17:19:47 +08001797 mTargetStack.moveToFront("intentActivityFound");
1798 }
1799 // We didn't do anything... but it was needed (a.k.a., client don't use that intent!)
1800 // And for paranoia, make sure we have correctly resumed the top activity.
1801 resumeTargetStackIfNeeded();
Louis Chang54fbb052019-10-16 17:10:17 +08001802 // The reusedActivity could be finishing, for example of starting an activity with
1803 // FLAG_ACTIVITY_CLEAR_TOP flag. In that case, return the top running activity in the
1804 // task instead.
1805 mLastStartActivityRecord =
Wale Ogunwale21e06482019-11-18 05:14:15 -08001806 targetTaskTop.finishing ? targetTask.getTopNonFinishingActivity() : targetTaskTop;
Louis Changbde91e92019-08-16 17:19:47 +08001807 return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP;
1808 }
1809
1810 /**
1811 * Check if the activity being launched is the same as the one currently at the top and it
1812 * should only be launched once.
1813 */
1814 private int deliverToCurrentTopIfNeeded(ActivityStack topStack) {
1815 final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
1816 final boolean dontStart = top != null && mStartActivity.resultTo == null
1817 && top.mActivityComponent.equals(mStartActivity.mActivityComponent)
1818 && top.mUserId == mStartActivity.mUserId
1819 && top.attachedToProcess()
1820 && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
1821 || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK))
1822 // This allows home activity to automatically launch on secondary display when
1823 // display added, if home was the top activity on default display, instead of
1824 // sending new intent to the home activity on default display.
1825 && (!top.isActivityTypeHome() || top.getDisplayId() == mPreferredDisplayId);
1826 if (!dontStart) {
1827 return START_SUCCESS;
1828 }
1829
1830 // For paranoia, make sure we have correctly resumed the top activity.
1831 topStack.mLastPausedActivity = null;
1832 if (mDoResume) {
Louis Chang149d5c82019-12-30 09:47:39 +08001833 mRootWindowContainer.resumeFocusedStacksTopActivities();
Louis Changbde91e92019-08-16 17:19:47 +08001834 }
1835 ActivityOptions.abort(mOptions);
1836 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1837 // We don't need to start a new activity, and the client said not to do anything if
1838 // that is the case, so this is it!
1839 return START_RETURN_INTENT_TO_CALLER;
1840 }
1841
1842 deliverNewIntent(top);
1843
1844 // Don't use mStartActivity.task to show the toast. We're not starting a new activity but
1845 // reusing 'top'. Fields in mStartActivity may not be fully initialized.
Louis Changcdec0802019-11-11 11:45:07 +08001846 mSupervisor.handleNonResizableTaskIfNeeded(top.getTask(),
Louis Changbde91e92019-08-16 17:19:47 +08001847 mLaunchParams.mWindowingMode, mPreferredDisplayId, topStack);
1848
1849 return START_DELIVERED_TO_TOP;
1850 }
1851
1852 /**
1853 * Applying the launching flags to the task, which might clear few or all the activities in the
1854 * task.
1855 */
Louis Changcdec0802019-11-11 11:45:07 +08001856 private void complyActivityFlags(Task targetTask, ActivityRecord reusedActivity) {
Wale Ogunwale21e06482019-11-18 05:14:15 -08001857 ActivityRecord targetTaskTop = targetTask.getTopNonFinishingActivity();
Louis Chang2dcb1272019-09-27 15:01:19 +08001858 final boolean resetTask =
1859 reusedActivity != null && (mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0;
1860 if (resetTask) {
Wale Ogunwaledfbeed72019-11-20 08:57:39 -08001861 targetTaskTop = mTargetStack.resetTaskIfNeeded(targetTaskTop, mStartActivity);
Louis Changbde91e92019-08-16 17:19:47 +08001862 }
1863
1864 if ((mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1865 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {
1866 // The caller has requested to completely replace any existing task with its new
1867 // activity. Well that should not be too hard...
Louis Changcdec0802019-11-11 11:45:07 +08001868 // Note: we must persist the {@link Task} first as intentActivity could be
Louis Changbde91e92019-08-16 17:19:47 +08001869 // removed from calling performClearTaskLocked (For example, if it is being brought out
1870 // of history or if it is finished immediately), thus disassociating the task. Also note
Louis Changcdec0802019-11-11 11:45:07 +08001871 // that mReuseTask is reset as a result of {@link Task#performClearTaskLocked}
Louis Changbde91e92019-08-16 17:19:47 +08001872 // launching another activity.
1873 // TODO(b/36119896): We shouldn't trigger activity launches in this path since we are
1874 // already launching one.
1875 targetTask.performClearTaskLocked();
1876 targetTask.setIntent(mStartActivity);
1877 mAddingToTask = true;
1878 } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
1879 || isDocumentLaunchesIntoExisting(mLaunchFlags)
1880 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
1881 // In this situation we want to remove all activities from the task up to the one
1882 // being started. In most cases this means we are resetting the task to its initial
1883 // state.
1884 final ActivityRecord top = targetTask.performClearTaskForReuseLocked(mStartActivity,
1885 mLaunchFlags);
1886
1887 // The above code can remove {@code reusedActivity} from the task, leading to the
Louis Changcdec0802019-11-11 11:45:07 +08001888 // {@code ActivityRecord} removing its reference to the {@code Task}. The task
Wale Ogunwalec17418e2019-10-13 23:00:40 +02001889 // reference is needed in the call below to {@link setTargetStackAndMoveToFrontIfNeeded}
Louis Changcdec0802019-11-11 11:45:07 +08001890 if (targetTaskTop.getTask() == null) {
Wale Ogunwale2322bed2019-10-10 17:24:19 +02001891 targetTask.addChild(targetTaskTop);
Louis Changbde91e92019-08-16 17:19:47 +08001892 }
1893
1894 if (top != null) {
1895 if (top.isRootOfTask()) {
1896 // Activity aliases may mean we use different intents for the top activity,
1897 // so make sure the task now has the identity of the new intent.
Louis Changcdec0802019-11-11 11:45:07 +08001898 top.getTask().setIntent(mStartActivity);
Louis Changbde91e92019-08-16 17:19:47 +08001899 }
1900 deliverNewIntent(top);
1901 } else {
1902 // A special case: we need to start the activity because it is not currently
1903 // running, and the caller has asked to clear the current task to have this
1904 // activity at the top.
1905 mAddingToTask = true;
1906 if (targetTask.getStack() == null) {
1907 // Target stack got cleared when we all activities were removed above.
1908 // Go ahead and reset it.
Louis Chang38430df2020-01-02 17:14:59 +08001909 mTargetStack =
1910 getLaunchStack(mStartActivity, mLaunchFlags, null /* task */, mOptions);
Wale Ogunwale2322bed2019-10-10 17:24:19 +02001911 mTargetStack.addChild(targetTask, !mLaunchTaskBehind /* toTop */,
1912 (mStartActivity.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0);
Louis Changbde91e92019-08-16 17:19:47 +08001913 }
1914 }
1915 } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) == 0 && !mAddingToTask
1916 && (mLaunchFlags & FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1917 // In this case, we are launching an activity in our own task that may
1918 // already be running somewhere in the history, and we want to shuffle it to
1919 // the front of the stack if so.
Wale Ogunwalea38654f2019-11-17 20:37:15 -08001920 final ActivityRecord act =
1921 targetTask.findActivityInHistory(mStartActivity.mActivityComponent);
Louis Changbde91e92019-08-16 17:19:47 +08001922 if (act != null) {
Louis Changcdec0802019-11-11 11:45:07 +08001923 final Task task = act.getTask();
Louis Changbde91e92019-08-16 17:19:47 +08001924 task.moveActivityToFrontLocked(act);
1925 act.updateOptionsLocked(mOptions);
1926 deliverNewIntent(act);
1927 mTargetStack.mLastPausedActivity = null;
1928 } else {
1929 mAddingToTask = true;
1930 }
1931 } else if (mStartActivity.mActivityComponent.equals(targetTask.realActivity)) {
Louis Chang382419b2019-10-03 21:43:38 +08001932 if (targetTask == mInTask) {
1933 // In this case we are bringing up an existing activity from a recent task. We
1934 // don't need to add a new activity instance on top.
1935 } else if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
1936 || LAUNCH_SINGLE_TOP == mLaunchMode)
1937 && targetTaskTop.mActivityComponent.equals(mStartActivity.mActivityComponent)
1938 && mStartActivity.resultTo == null) {
1939 // In this case the top activity on the task is the same as the one being launched,
1940 // so we take that as a request to bring the task to the foreground. If the top
1941 // activity in the task is the root activity, deliver this new intent to it if it
1942 // desires.
Louis Changbde91e92019-08-16 17:19:47 +08001943 if (targetTaskTop.isRootOfTask()) {
Louis Changcdec0802019-11-11 11:45:07 +08001944 targetTaskTop.getTask().setIntent(mStartActivity);
Louis Changbde91e92019-08-16 17:19:47 +08001945 }
1946 deliverNewIntent(targetTaskTop);
1947 } else if (!targetTask.isSameIntentFilter(mStartActivity)) {
1948 // In this case we are launching the root activity of the task, but with a
1949 // different intent. We should start a new instance on top.
1950 mAddingToTask = true;
1951 } else if (reusedActivity == null) {
1952 mAddingToTask = true;
1953 }
Louis Chang2dcb1272019-09-27 15:01:19 +08001954 } else if (!resetTask) {
Louis Changbde91e92019-08-16 17:19:47 +08001955 // In this case an activity is being launched in to an existing task, without
1956 // resetting that task. This is typically the situation of launching an activity
1957 // from a notification or shortcut. We want to place the new activity on top of the
1958 // current task.
1959 mAddingToTask = true;
1960 } else if (!targetTask.rootWasReset) {
1961 // In this case we are launching into an existing task that has not yet been started
1962 // from its front door. The current task has been brought to the front. Ideally,
1963 // we'd probably like to place this new task at the bottom of its stack, but that's
1964 // a little hard to do with the current organization of the code so for now we'll
1965 // just drop it.
1966 targetTask.setIntent(mStartActivity);
1967 }
1968 }
1969
Bryce Leedaa91e42017-12-06 14:13:01 -08001970 /**
1971 * Resets the {@link ActivityStarter} state.
1972 * @param clearRequest whether the request should be reset to default values.
1973 */
1974 void reset(boolean clearRequest) {
1975 mStartActivity = null;
1976 mIntent = null;
1977 mCallingUid = -1;
1978 mOptions = null;
Ricky Waib147fa12019-04-25 16:08:30 +01001979 mRestrictedBgActivity = false;
Bryce Leedaa91e42017-12-06 14:13:01 -08001980
1981 mLaunchTaskBehind = false;
1982 mLaunchFlags = 0;
1983 mLaunchMode = INVALID_LAUNCH_MODE;
1984
Bryce Leeec55eb02017-12-05 20:51:27 -08001985 mLaunchParams.reset();
Bryce Leedaa91e42017-12-06 14:13:01 -08001986
1987 mNotTop = null;
1988 mDoResume = false;
1989 mStartFlags = 0;
1990 mSourceRecord = null;
1991 mPreferredDisplayId = INVALID_DISPLAY;
1992
1993 mInTask = null;
1994 mAddingToTask = false;
1995 mReuseTask = null;
1996
1997 mNewTaskInfo = null;
1998 mNewTaskIntent = null;
1999 mSourceStack = null;
2000
2001 mTargetStack = null;
2002 mMovedToFront = false;
2003 mNoAnimation = false;
2004 mKeepCurTransition = false;
2005 mAvoidMoveToFront = false;
Winson Chunge219ae12019-07-18 13:43:23 -07002006 mFrozeTaskList = false;
Bryce Leedaa91e42017-12-06 14:13:01 -08002007
2008 mVoiceSession = null;
2009 mVoiceInteractor = null;
2010
2011 mIntentDelivered = false;
2012
2013 if (clearRequest) {
2014 mRequest.reset();
2015 }
2016 }
2017
Louis Changcdec0802019-11-11 11:45:07 +08002018 private void setInitialState(ActivityRecord r, ActivityOptions options, Task inTask,
Wale Ogunwale01d66562015-12-29 08:19:19 -08002019 boolean doResume, int startFlags, ActivityRecord sourceRecord,
Ricky Waib147fa12019-04-25 16:08:30 +01002020 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
2021 boolean restrictedBgActivity) {
Bryce Leedaa91e42017-12-06 14:13:01 -08002022 reset(false /* clearRequest */);
2023
Wale Ogunwale01d66562015-12-29 08:19:19 -08002024 mStartActivity = r;
2025 mIntent = r.intent;
2026 mOptions = options;
2027 mCallingUid = r.launchedFromUid;
2028 mSourceRecord = sourceRecord;
2029 mVoiceSession = voiceSession;
2030 mVoiceInteractor = voiceInteractor;
Ricky Waib147fa12019-04-25 16:08:30 +01002031 mRestrictedBgActivity = restrictedBgActivity;
Wale Ogunwale01d66562015-12-29 08:19:19 -08002032
Bryce Leeec55eb02017-12-05 20:51:27 -08002033 mLaunchParams.reset();
Bryce Leedacefc42017-10-10 12:56:02 -07002034
Louis Chang6fb1e842018-12-03 16:07:50 +08002035 // Preferred display id is the only state we need for now and it could be updated again
2036 // after we located a reusable task (which might be resided in another display).
Garfield Tan706dbcb2018-10-15 11:33:02 -07002037 mSupervisor.getLaunchParamsController().calculate(inTask, r.info.windowLayout, r,
Louis Chang6fb1e842018-12-03 16:07:50 +08002038 sourceRecord, options, PHASE_DISPLAY, mLaunchParams);
2039 mPreferredDisplayId =
2040 mLaunchParams.hasPreferredDisplay() ? mLaunchParams.mPreferredDisplayId
2041 : DEFAULT_DISPLAY;
Garfield Tanb5cc09f2018-09-28 10:06:52 -07002042
Bryce Lee7daee392017-10-12 13:46:18 -07002043 mLaunchMode = r.launchMode;
2044
Wale Ogunwale01d66562015-12-29 08:19:19 -08002045 mLaunchFlags = adjustLaunchFlagsToDocumentMode(
Bryce Lee7daee392017-10-12 13:46:18 -07002046 r, LAUNCH_SINGLE_INSTANCE == mLaunchMode,
2047 LAUNCH_SINGLE_TASK == mLaunchMode, mIntent.getFlags());
Wale Ogunwale01d66562015-12-29 08:19:19 -08002048 mLaunchTaskBehind = r.mLaunchTaskBehind
Bryce Lee7daee392017-10-12 13:46:18 -07002049 && !isLaunchModeOneOf(LAUNCH_SINGLE_TASK, LAUNCH_SINGLE_INSTANCE)
Wale Ogunwale01d66562015-12-29 08:19:19 -08002050 && (mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0;
2051
2052 sendNewTaskResultRequestIfNeeded();
2053
2054 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
2055 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2056 }
2057
2058 // If we are actually going to launch in to a new task, there are some cases where
2059 // we further want to do multiple task.
2060 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
2061 if (mLaunchTaskBehind
2062 || r.info.documentLaunchMode == DOCUMENT_LAUNCH_ALWAYS) {
2063 mLaunchFlags |= FLAG_ACTIVITY_MULTIPLE_TASK;
2064 }
2065 }
2066
2067 // We'll invoke onUserLeaving before onPause only if the launching
2068 // activity did not explicitly state that this is an automated launch.
2069 mSupervisor.mUserLeaving = (mLaunchFlags & FLAG_ACTIVITY_NO_USER_ACTION) == 0;
2070 if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
2071 "startActivity() => mUserLeaving=" + mSupervisor.mUserLeaving);
2072
2073 // If the caller has asked not to resume at this point, we make note
2074 // of this in the record so that we can skip it when trying to find
2075 // the top running activity.
2076 mDoResume = doResume;
Louis Chang37317152019-05-09 09:53:58 +08002077 if (!doResume || !r.okToShowLocked() || mLaunchTaskBehind) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002078 r.delayedResume = true;
2079 mDoResume = false;
2080 }
2081
Winson Chunge2d72172018-01-25 17:46:20 +00002082 if (mOptions != null) {
2083 if (mOptions.getLaunchTaskId() != -1 && mOptions.getTaskOverlay()) {
Wale Ogunwale0b3d2922019-12-30 08:55:07 -08002084 r.setTaskOverlay(true);
Winson Chunge2d72172018-01-25 17:46:20 +00002085 if (!mOptions.canTaskOverlayResume()) {
Louis Chang149d5c82019-12-30 09:47:39 +08002086 final Task task = mRootWindowContainer.anyTaskForId(
Winson Chunge2d72172018-01-25 17:46:20 +00002087 mOptions.getLaunchTaskId());
Wale Ogunwale21e06482019-11-18 05:14:15 -08002088 final ActivityRecord top = task != null
2089 ? task.getTopNonFinishingActivity() : null;
Bryce Lee7ace3952018-02-16 14:34:32 -08002090 if (top != null && !top.isState(RESUMED)) {
Jorim Jaggic875ae72016-04-26 22:41:06 -07002091
Winson Chunge2d72172018-01-25 17:46:20 +00002092 // The caller specifies that we'd like to be avoided to be moved to the
2093 // front, so be it!
2094 mDoResume = false;
2095 mAvoidMoveToFront = true;
2096 }
Winson Chungcbcadc92017-01-12 15:54:12 -08002097 }
Winson Chunge2d72172018-01-25 17:46:20 +00002098 } else if (mOptions.getAvoidMoveToFront()) {
Winson Chungba40d3a2018-05-16 09:40:16 -07002099 mDoResume = false;
Winson Chunge2d72172018-01-25 17:46:20 +00002100 mAvoidMoveToFront = true;
Jorim Jaggic875ae72016-04-26 22:41:06 -07002101 }
2102 }
2103
Louis Chang2f4e9b462019-03-05 16:43:15 +08002104 mNotTop = (mLaunchFlags & FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? sourceRecord : null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08002105
2106 mInTask = inTask;
2107 // In some flows in to this function, we retrieve the task record and hold on to it
2108 // without a lock before calling back in to here... so the task at this point may
2109 // not actually be in recents. Check for that, and if it isn't in recents just
2110 // consider it invalid.
2111 if (inTask != null && !inTask.inRecents) {
2112 Slog.w(TAG, "Starting activity in task not in recents: " + inTask);
2113 mInTask = null;
2114 }
2115
2116 mStartFlags = startFlags;
2117 // If the onlyIfNeeded flag is set, then we can do this if the activity being launched
2118 // is the same as the one making the call... or, as a special case, if we do not know
2119 // the caller then we count the current top activity as the caller.
2120 if ((startFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
2121 ActivityRecord checkedCaller = sourceRecord;
2122 if (checkedCaller == null) {
Louis Chang149d5c82019-12-30 09:47:39 +08002123 checkedCaller = mRootWindowContainer.getTopDisplayFocusedStack()
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002124 .topRunningNonDelayedActivityLocked(mNotTop);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002125 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002126 if (!checkedCaller.mActivityComponent.equals(r.mActivityComponent)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002127 // Caller is not the same as launcher, so always needed.
2128 mStartFlags &= ~START_FLAG_ONLY_IF_NEEDED;
2129 }
2130 }
2131
2132 mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0;
Ricky Waib147fa12019-04-25 16:08:30 +01002133
Alan Stokes07389b62019-05-20 15:22:54 +01002134 if (mRestrictedBgActivity && !mService.isBackgroundActivityStartsEnabled()) {
Ricky Waib147fa12019-04-25 16:08:30 +01002135 mAvoidMoveToFront = true;
2136 mDoResume = false;
2137 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002138 }
2139
2140 private void sendNewTaskResultRequestIfNeeded() {
Andrii Kulian79d67982019-08-19 11:56:16 -07002141 if (mStartActivity.resultTo != null && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002142 // For whatever reason this activity is being launched into a new task...
2143 // yet the caller has requested a result back. Well, that is pretty messed up,
2144 // so instead immediately send back a cancel and let the new task continue launched
2145 // as normal without a dependency on its originator.
2146 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
Andrii Kulian79d67982019-08-19 11:56:16 -07002147 mStartActivity.resultTo.sendResult(INVALID_UID, mStartActivity.resultWho,
2148 mStartActivity.requestCode, RESULT_CANCELED, null /* data */);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002149 mStartActivity.resultTo = null;
2150 }
2151 }
2152
2153 private void computeLaunchingTaskFlags() {
2154 // If the caller is not coming from another activity, but has given us an explicit task into
2155 // which they would like us to launch the new activity, then let's see about doing that.
Andrii Kulian02b7a832016-10-06 23:11:56 -07002156 if (mSourceRecord == null && mInTask != null && mInTask.getStack() != null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002157 final Intent baseIntent = mInTask.getBaseIntent();
2158 final ActivityRecord root = mInTask.getRootActivity();
2159 if (baseIntent == null) {
2160 ActivityOptions.abort(mOptions);
2161 throw new IllegalArgumentException("Launching into task without base intent: "
2162 + mInTask);
2163 }
2164
2165 // If this task is empty, then we are adding the first activity -- it
2166 // determines the root, and must be launching as a NEW_TASK.
Bryce Lee7daee392017-10-12 13:46:18 -07002167 if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002168 if (!baseIntent.getComponent().equals(mStartActivity.intent.getComponent())) {
2169 ActivityOptions.abort(mOptions);
2170 throw new IllegalArgumentException("Trying to launch singleInstance/Task "
2171 + mStartActivity + " into different task " + mInTask);
2172 }
2173 if (root != null) {
2174 ActivityOptions.abort(mOptions);
2175 throw new IllegalArgumentException("Caller with mInTask " + mInTask
2176 + " has root " + root + " but target is singleInstance/Task");
2177 }
2178 }
2179
2180 // If task is empty, then adopt the interesting intent launch flags in to the
2181 // activity being started.
2182 if (root == null) {
2183 final int flagsOfInterest = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK
2184 | FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS;
2185 mLaunchFlags = (mLaunchFlags & ~flagsOfInterest)
2186 | (baseIntent.getFlags() & flagsOfInterest);
2187 mIntent.setFlags(mLaunchFlags);
2188 mInTask.setIntent(mStartActivity);
2189 mAddingToTask = true;
2190
2191 // If the task is not empty and the caller is asking to start it as the root of
2192 // a new task, then we don't actually want to start this on the task. We will
2193 // bring the task to the front, and possibly give it a new intent.
2194 } else if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
2195 mAddingToTask = false;
2196
2197 } else {
2198 mAddingToTask = true;
2199 }
2200
2201 mReuseTask = mInTask;
2202 } else {
2203 mInTask = null;
2204 // Launch ResolverActivity in the source task, so that it stays in the task bounds
2205 // when in freeform workspace.
2206 // Also put noDisplay activities in the source task. These by itself can be placed
2207 // in any task/stack, however it could launch other activities like ResolverActivity,
2208 // and we want those to stay in the original task.
Louis Chang6a9be162019-07-15 10:41:32 +08002209 if ((mStartActivity.isResolverOrDelegateActivity() || mStartActivity.noDisplay)
2210 && mSourceRecord != null && mSourceRecord.inFreeformWindowingMode()) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002211 mAddingToTask = true;
2212 }
2213 }
2214
2215 if (mInTask == null) {
2216 if (mSourceRecord == null) {
2217 // This activity is not being started from another... in this
2218 // case we -always- start a new task.
2219 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) {
2220 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
2221 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
2222 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2223 }
2224 } else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) {
2225 // The original activity who is starting us is running as a single
2226 // instance... this new activity it is starting must go on its
2227 // own task.
2228 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
Bryce Lee7daee392017-10-12 13:46:18 -07002229 } else if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002230 // The activity being started is a single instance... it always
2231 // gets launched into its own task.
2232 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2233 }
2234 }
2235 }
2236
2237 private void computeSourceStack() {
2238 if (mSourceRecord == null) {
2239 mSourceStack = null;
2240 return;
2241 }
2242 if (!mSourceRecord.finishing) {
Wale Ogunwale1ebcd8e2020-01-21 11:27:03 -08002243 mSourceStack = mSourceRecord.getRootTask();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002244 return;
2245 }
2246
2247 // If the source is finishing, we can't further count it as our source. This is because the
2248 // task it is associated with may now be empty and on its way out, so we don't want to
2249 // blindly throw it in to that task. Instead we will take the NEW_TASK flow and try to find
2250 // a task for it. But save the task information so it can be used when creating the new task.
2251 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0) {
2252 Slog.w(TAG, "startActivity called from finishing " + mSourceRecord
2253 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
2254 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2255 mNewTaskInfo = mSourceRecord.info;
Bryce Leed9ed45d2017-05-22 15:57:24 -07002256
2257 // It is not guaranteed that the source record will have a task associated with it. For,
2258 // example, if this method is being called for processing a pending activity launch, it
2259 // is possible that the activity has been removed from the task after the launch was
2260 // enqueued.
Louis Changcdec0802019-11-11 11:45:07 +08002261 final Task sourceTask = mSourceRecord.getTask();
Bryce Leed9ed45d2017-05-22 15:57:24 -07002262 mNewTaskIntent = sourceTask != null ? sourceTask.intent : null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08002263 }
2264 mSourceRecord = null;
2265 mSourceStack = null;
2266 }
2267
2268 /**
2269 * Decide whether the new activity should be inserted into an existing task. Returns null
2270 * if not or an ActivityRecord with the task into which the new activity should be added.
2271 */
Louis Changcdec0802019-11-11 11:45:07 +08002272 private Task getReusableTask() {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002273 // We may want to try to place the new activity in to an existing task. We always
2274 // do this if the target activity is singleTask or singleInstance; we will also do
2275 // this if NEW_TASK has been requested, and there is not an additional qualifier telling
2276 // us to still place it in a new task: multi task, always doc mode, or being asked to
2277 // launch this as a new task behind the current one.
2278 boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 &&
2279 (mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
Bryce Lee7daee392017-10-12 13:46:18 -07002280 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002281 // If bring to front is requested, and no result is requested and we have not been given
2282 // an explicit task to launch in to, and we can find a task that was started with this
2283 // same component, then instead of launching bring that one to the front.
2284 putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null;
2285 ActivityRecord intentActivity = null;
Jorim Jaggi2adba072016-03-03 13:43:39 +01002286 if (mOptions != null && mOptions.getLaunchTaskId() != -1) {
Louis Chang149d5c82019-12-30 09:47:39 +08002287 Task launchTask = mRootWindowContainer.anyTaskForId(mOptions.getLaunchTaskId());
Louis Changf7dd7f22019-11-05 11:59:56 +08002288 if (launchTask != null) {
2289 return launchTask;
2290 }
Jorim Jaggi2adba072016-03-03 13:43:39 +01002291 } else if (putIntoExistingTask) {
Bryce Lee7daee392017-10-12 13:46:18 -07002292 if (LAUNCH_SINGLE_INSTANCE == mLaunchMode) {
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07002293 // There can be one and only one instance of single instance activity in the
2294 // history, and it is always in its own unique task, so we do a special search.
Louis Chang149d5c82019-12-30 09:47:39 +08002295 intentActivity = mRootWindowContainer.findActivity(mIntent, mStartActivity.info,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07002296 mStartActivity.isActivityTypeHome());
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07002297 } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
2298 // For the launch adjacent case we only want to put the activity in an existing
2299 // task if the activity already exists in the history.
Louis Chang149d5c82019-12-30 09:47:39 +08002300 intentActivity = mRootWindowContainer.findActivity(mIntent, mStartActivity.info,
Bryce Lee7daee392017-10-12 13:46:18 -07002301 !(LAUNCH_SINGLE_TASK == mLaunchMode));
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07002302 } else {
2303 // Otherwise find the best task to put the activity in.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002304 intentActivity =
Louis Chang149d5c82019-12-30 09:47:39 +08002305 mRootWindowContainer.findTask(mStartActivity, mPreferredDisplayId);
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07002306 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002307 }
Louis Changbd48dca2018-08-29 17:44:34 +08002308
Louis Chang54506cb2018-11-23 11:03:41 +08002309 if (intentActivity != null
2310 && (mStartActivity.isActivityTypeHome() || intentActivity.isActivityTypeHome())
Louis Changbd48dca2018-08-29 17:44:34 +08002311 && intentActivity.getDisplayId() != mPreferredDisplayId) {
2312 // Do not reuse home activity on other displays.
2313 intentActivity = null;
2314 }
2315
Louis Changcdec0802019-11-11 11:45:07 +08002316 return intentActivity != null ? intentActivity.getTask() : null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08002317 }
2318
Andrii Kulianfab9cd82017-03-21 19:37:09 -07002319 /**
2320 * Figure out which task and activity to bring to front when we have found an existing matching
2321 * activity record in history. May also clear the task if needed.
2322 * @param intentActivity Existing matching activity.
2323 * @return {@link ActivityRecord} brought to front.
2324 */
Louis Changbde91e92019-08-16 17:19:47 +08002325 private void setTargetStackIfNeeded(ActivityRecord intentActivity) {
Wale Ogunwale1ebcd8e2020-01-21 11:27:03 -08002326 mTargetStack = intentActivity.getRootTask();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002327 mTargetStack.mLastPausedActivity = null;
2328 // If the target task is not in the front, then we need to bring it to the front...
2329 // except... well, with SINGLE_TASK_LAUNCH it's not entirely clear. We'd like to have
2330 // the same behavior as if a new instance was being started, which means not bringing it
2331 // to the front if the caller is not itself in the front.
Riddle Hsub70b36d2018-09-11 21:20:02 +08002332 final boolean differentTopTask;
Wale Ogunwale0b3d2922019-12-30 08:55:07 -08002333 if (mPreferredDisplayId == mTargetStack.getDisplayId()) {
Riddle Hsub70b36d2018-09-11 21:20:02 +08002334 final ActivityStack focusStack = mTargetStack.getDisplay().getFocusedStack();
2335 final ActivityRecord curTop = (focusStack == null)
2336 ? null : focusStack.topRunningNonDelayedActivityLocked(mNotTop);
Louis Changcdec0802019-11-11 11:45:07 +08002337 final Task topTask = curTop != null ? curTop.getTask() : null;
2338 differentTopTask = topTask != intentActivity.getTask()
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09002339 || (focusStack != null && topTask != focusStack.getTopMostTask());
Riddle Hsub70b36d2018-09-11 21:20:02 +08002340 } else {
2341 // The existing task should always be different from those in other displays.
2342 differentTopTask = true;
2343 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002344
Riddle Hsub70b36d2018-09-11 21:20:02 +08002345 if (differentTopTask && !mAvoidMoveToFront) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002346 mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Wale Ogunwale21e06482019-11-18 05:14:15 -08002347 if (mSourceRecord == null || (mSourceStack.getTopNonFinishingActivity() != null &&
2348 mSourceStack.getTopNonFinishingActivity().getTask()
Louis Changcdec0802019-11-11 11:45:07 +08002349 == mSourceRecord.getTask())) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002350 // We really do want to push this one into the user's face, right now.
2351 if (mLaunchTaskBehind && mSourceRecord != null) {
Louis Changcdec0802019-11-11 11:45:07 +08002352 intentActivity.setTaskToAffiliateWith(mSourceRecord.getTask());
Wale Ogunwale01d66562015-12-29 08:19:19 -08002353 }
Chong Zhangdea4bd92016-03-15 12:50:03 -07002354
Louis Changcdec0802019-11-11 11:45:07 +08002355 final Task intentTask = intentActivity.getTask();
Louis Changf3070c52019-10-09 15:57:30 +08002356 final ActivityStack launchStack =
2357 getLaunchStack(mStartActivity, mLaunchFlags, intentTask, mOptions);
Louis Changbde91e92019-08-16 17:19:47 +08002358 if (launchStack == null || launchStack == mTargetStack) {
Louis Chang38430df2020-01-02 17:14:59 +08002359 // Do not set mMovedToFront to true below for split-screen-top stack, or
2360 // START_TASK_TO_FRONT will be returned and trigger unexpected animations when a
2361 // new intent has delivered.
2362 final boolean isSplitScreenTopStack = mTargetStack.isTopSplitScreenStack();
2363
Louis Changbde91e92019-08-16 17:19:47 +08002364 // We only want to move to the front, if we aren't going to launch on a
2365 // different stack. If we launch on a different stack, we will put the
2366 // task on top there.
Louis Chang38430df2020-01-02 17:14:59 +08002367 // Defer resuming the top activity while moving task to top, since the
2368 // current task-top activity may not be the activity that should be resumed.
Louis Changbde91e92019-08-16 17:19:47 +08002369 mTargetStack.moveTaskToFrontLocked(intentTask, mNoAnimation, mOptions,
Louis Chang38430df2020-01-02 17:14:59 +08002370 mStartActivity.appTimeTracker, DEFER_RESUME,
2371 "bringingFoundTaskToFront");
2372 mMovedToFront = !isSplitScreenTopStack;
2373 } else {
2374 intentTask.reparent(launchStack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, ANIMATE,
2375 DEFER_RESUME, "reparentToTargetStack");
Louis Changbde91e92019-08-16 17:19:47 +08002376 mMovedToFront = true;
Louis Changf3070c52019-10-09 15:57:30 +08002377 }
Louis Changbde91e92019-08-16 17:19:47 +08002378 mOptions = null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08002379 }
2380 }
Andrii Kulianb850ea52017-12-12 23:49:10 -08002381 // Need to update mTargetStack because if task was moved out of it, the original stack may
2382 // be destroyed.
Wale Ogunwale1ebcd8e2020-01-21 11:27:03 -08002383 mTargetStack = intentActivity.getRootTask();
Louis Changcdec0802019-11-11 11:45:07 +08002384 mSupervisor.handleNonResizableTaskIfNeeded(intentActivity.getTask(),
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07002385 WINDOWING_MODE_UNDEFINED, DEFAULT_DISPLAY, mTargetStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002386 }
2387
2388 private void resumeTargetStackIfNeeded() {
2389 if (mDoResume) {
Louis Chang149d5c82019-12-30 09:47:39 +08002390 mRootWindowContainer.resumeFocusedStacksTopActivities(mTargetStack, null, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002391 } else {
2392 ActivityOptions.abort(mOptions);
2393 }
Louis Chang149d5c82019-12-30 09:47:39 +08002394 mRootWindowContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002395 }
2396
Louis Changcdec0802019-11-11 11:45:07 +08002397 private void setNewTask(Task taskToAffiliate) {
Louis Changbde91e92019-08-16 17:19:47 +08002398 final boolean toTop = !mLaunchTaskBehind && !mAvoidMoveToFront;
Louis Changcdec0802019-11-11 11:45:07 +08002399 final Task task = mTargetStack.createTask(
Wale Ogunwale0b3d2922019-12-30 08:55:07 -08002400 mSupervisor.getNextTaskIdForUser(mStartActivity.mUserId),
Louis Changbde91e92019-08-16 17:19:47 +08002401 mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
2402 mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
2403 mVoiceInteractor, toTop, mStartActivity, mSourceRecord, mOptions);
2404 addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
Louis Changcdec0802019-11-11 11:45:07 +08002405 updateBounds(mStartActivity.getTask(), mLaunchParams.mBounds);
Louis Change8902452019-06-10 10:49:28 +08002406
Louis Changbde91e92019-08-16 17:19:47 +08002407 if (DEBUG_TASKS) {
2408 Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Louis Changcdec0802019-11-11 11:45:07 +08002409 + " in new task " + mStartActivity.getTask());
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002410 }
2411
2412 if (taskToAffiliate != null) {
2413 mStartActivity.setTaskToAffiliateWith(taskToAffiliate);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002414 }
2415 }
2416
Bryce Lee325e09682017-10-05 17:20:25 -07002417 private void deliverNewIntent(ActivityRecord activity) {
2418 if (mIntentDelivered) {
2419 return;
2420 }
2421
Jeff Changd136e772019-11-05 20:33:52 +08002422 activity.logStartActivity(EventLogTags.WM_NEW_INTENT, activity.getTask());
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00002423 activity.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
Bryce Lee325e09682017-10-05 17:20:25 -07002424 mStartActivity.launchedFromPackage);
2425 mIntentDelivered = true;
2426 }
2427
Bryce Leed3624e12017-11-30 08:51:45 -08002428 @VisibleForTesting
Louis Changcdec0802019-11-11 11:45:07 +08002429 void updateBounds(Task task, Rect bounds) {
Bryce Leedacefc42017-10-10 12:56:02 -07002430 if (bounds.isEmpty()) {
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002431 return;
2432 }
2433
Wale Ogunwale1ebcd8e2020-01-21 11:27:03 -08002434 final Task rootTask = task.getRootTask();
2435 if (rootTask != null && rootTask.inPinnedWindowingMode()) {
2436 mService.animateResizePinnedStack(rootTask.mTaskId, bounds, -1);
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002437 } else {
Wale Ogunwale1ebcd8e2020-01-21 11:27:03 -08002438 // TODO: I don't believe it is possible to reach this else condition anymore...
Evan Roskya4cc3a92019-06-28 13:25:01 -07002439 task.setBounds(bounds);
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002440 }
2441 }
2442
Louis Changcdec0802019-11-11 11:45:07 +08002443 private void addOrReparentStartingActivity(Task parent, String reason) {
2444 if (mStartActivity.getTask() == null || mStartActivity.getTask() == parent) {
Wale Ogunwalec17418e2019-10-13 23:00:40 +02002445 parent.addChild(mStartActivity);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002446 } else {
Wale Ogunwale1a06f152019-10-11 11:26:30 +02002447 mStartActivity.reparent(parent, parent.getChildCount() /* top */, reason);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002448 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002449 }
2450
2451 private int adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance,
2452 boolean launchSingleTask, int launchFlags) {
2453 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2454 (launchSingleInstance || launchSingleTask)) {
2455 // We have a conflict between the Intent and the Activity manifest, manifest wins.
2456 Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " +
2457 "\"singleInstance\" or \"singleTask\"");
2458 launchFlags &=
2459 ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK);
2460 } else {
2461 switch (r.info.documentLaunchMode) {
2462 case ActivityInfo.DOCUMENT_LAUNCH_NONE:
2463 break;
2464 case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
2465 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2466 break;
2467 case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
2468 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2469 break;
2470 case ActivityInfo.DOCUMENT_LAUNCH_NEVER:
2471 launchFlags &= ~FLAG_ACTIVITY_MULTIPLE_TASK;
2472 break;
2473 }
2474 }
2475 return launchFlags;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002476 }
2477
Louis Changcdec0802019-11-11 11:45:07 +08002478 private ActivityStack getLaunchStack(ActivityRecord r, int launchFlags, Task task,
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002479 ActivityOptions aOptions) {
Bryce Leea19b5ad2017-06-07 16:54:11 -07002480 // We are reusing a task, keep the stack!
2481 if (mReuseTask != null) {
2482 return mReuseTask.getStack();
2483 }
Jorim Jaggib8c58762016-04-20 17:58:29 -07002484
Louis Chang38430df2020-01-02 17:14:59 +08002485 final boolean onTop =
2486 (aOptions == null || !aOptions.getAvoidMoveToFront()) && !mLaunchTaskBehind;
2487 return mRootWindowContainer.getLaunchStack(r, aOptions, task, onTop, mLaunchParams,
2488 mRequest.realCallingPid, mRequest.realCallingUid);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002489 }
2490
Bryce Lee7daee392017-10-12 13:46:18 -07002491 private boolean isLaunchModeOneOf(int mode1, int mode2) {
2492 return mode1 == mLaunchMode || mode2 == mLaunchMode;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002493 }
2494
Daichi Hirono15a02992016-04-27 18:47:01 +09002495 static boolean isDocumentLaunchesIntoExisting(int flags) {
2496 return (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2497 (flags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0;
2498 }
liulvpingcfa825f2016-09-26 20:00:15 +08002499
Bryce Lee4c9a5972017-12-01 22:14:24 -08002500 ActivityStarter setIntent(Intent intent) {
2501 mRequest.intent = intent;
2502 return this;
2503 }
2504
Bryce Lee32e09ef2018-03-19 15:29:49 -07002505 Intent getIntent() {
2506 return mRequest.intent;
2507 }
2508
Bryce Lee4c9a5972017-12-01 22:14:24 -08002509 ActivityStarter setReason(String reason) {
2510 mRequest.reason = reason;
2511 return this;
2512 }
2513
2514 ActivityStarter setCaller(IApplicationThread caller) {
2515 mRequest.caller = caller;
2516 return this;
2517 }
2518
Bryce Lee4c9a5972017-12-01 22:14:24 -08002519 ActivityStarter setResolvedType(String type) {
2520 mRequest.resolvedType = type;
2521 return this;
2522 }
2523
2524 ActivityStarter setActivityInfo(ActivityInfo info) {
2525 mRequest.activityInfo = info;
2526 return this;
2527 }
2528
2529 ActivityStarter setResolveInfo(ResolveInfo info) {
2530 mRequest.resolveInfo = info;
2531 return this;
2532 }
2533
2534 ActivityStarter setVoiceSession(IVoiceInteractionSession voiceSession) {
2535 mRequest.voiceSession = voiceSession;
2536 return this;
2537 }
2538
2539 ActivityStarter setVoiceInteractor(IVoiceInteractor voiceInteractor) {
2540 mRequest.voiceInteractor = voiceInteractor;
2541 return this;
2542 }
2543
2544 ActivityStarter setResultTo(IBinder resultTo) {
2545 mRequest.resultTo = resultTo;
2546 return this;
2547 }
2548
2549 ActivityStarter setResultWho(String resultWho) {
2550 mRequest.resultWho = resultWho;
2551 return this;
2552 }
2553
2554 ActivityStarter setRequestCode(int requestCode) {
2555 mRequest.requestCode = requestCode;
2556 return this;
2557 }
2558
lumarkf65e02d2019-09-14 19:25:21 +08002559 /**
2560 * Sets the pid of the caller who originally started the activity.
2561 *
2562 * Normally, the pid/uid would be the calling pid from the binder call.
2563 * However, in case of a {@link PendingIntent}, the pid/uid pair of the caller is considered
2564 * the original entity that created the pending intent, in contrast to setRealCallingPid/Uid,
2565 * which represents the entity who invoked pending intent via {@link PendingIntent#send}.
2566 */
Bryce Lee4c9a5972017-12-01 22:14:24 -08002567 ActivityStarter setCallingPid(int pid) {
2568 mRequest.callingPid = pid;
2569 return this;
2570 }
2571
lumarkf65e02d2019-09-14 19:25:21 +08002572 /**
2573 * Sets the uid of the caller who originally started the activity.
2574 *
2575 * @see #setCallingPid
2576 */
Bryce Lee4c9a5972017-12-01 22:14:24 -08002577 ActivityStarter setCallingUid(int uid) {
2578 mRequest.callingUid = uid;
2579 return this;
2580 }
2581
2582 ActivityStarter setCallingPackage(String callingPackage) {
2583 mRequest.callingPackage = callingPackage;
2584 return this;
2585 }
2586
Philip P. Moltmann9c5226f2020-01-10 08:53:43 -08002587 ActivityStarter setCallingFeatureId(String callingFeatureId) {
2588 mRequest.callingFeatureId = callingFeatureId;
2589 return this;
2590 }
2591
lumarkf65e02d2019-09-14 19:25:21 +08002592 /**
2593 * Sets the pid of the caller who requested to launch the activity.
2594 *
2595 * The pid/uid represents the caller who launches the activity in this request.
2596 * It will almost same as setCallingPid/Uid except when processing {@link PendingIntent}:
2597 * the pid/uid will be the caller who called {@link PendingIntent#send()}.
2598 *
2599 * @see #setCallingPid
2600 */
Bryce Lee4c9a5972017-12-01 22:14:24 -08002601 ActivityStarter setRealCallingPid(int pid) {
2602 mRequest.realCallingPid = pid;
2603 return this;
2604 }
2605
lumarkf65e02d2019-09-14 19:25:21 +08002606 /**
2607 * Sets the uid of the caller who requested to launch the activity.
2608 *
2609 * @see #setRealCallingPid
2610 */
Bryce Lee4c9a5972017-12-01 22:14:24 -08002611 ActivityStarter setRealCallingUid(int uid) {
2612 mRequest.realCallingUid = uid;
2613 return this;
2614 }
2615
2616 ActivityStarter setStartFlags(int startFlags) {
2617 mRequest.startFlags = startFlags;
2618 return this;
2619 }
2620
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002621 ActivityStarter setActivityOptions(SafeActivityOptions options) {
Bryce Lee4c9a5972017-12-01 22:14:24 -08002622 mRequest.activityOptions = options;
2623 return this;
2624 }
2625
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002626 ActivityStarter setActivityOptions(Bundle bOptions) {
2627 return setActivityOptions(SafeActivityOptions.fromBundle(bOptions));
2628 }
2629
Bryce Lee4c9a5972017-12-01 22:14:24 -08002630 ActivityStarter setIgnoreTargetSecurity(boolean ignoreTargetSecurity) {
2631 mRequest.ignoreTargetSecurity = ignoreTargetSecurity;
2632 return this;
2633 }
2634
Patrick Baumann31426b22018-05-21 13:46:40 -07002635 ActivityStarter setFilterCallingUid(int filterCallingUid) {
2636 mRequest.filterCallingUid = filterCallingUid;
2637 return this;
2638 }
2639
Bryce Lee4c9a5972017-12-01 22:14:24 -08002640 ActivityStarter setComponentSpecified(boolean componentSpecified) {
2641 mRequest.componentSpecified = componentSpecified;
2642 return this;
2643 }
2644
2645 ActivityStarter setOutActivity(ActivityRecord[] outActivity) {
2646 mRequest.outActivity = outActivity;
2647 return this;
2648 }
2649
Louis Changcdec0802019-11-11 11:45:07 +08002650 ActivityStarter setInTask(Task inTask) {
Bryce Lee4c9a5972017-12-01 22:14:24 -08002651 mRequest.inTask = inTask;
2652 return this;
2653 }
2654
2655 ActivityStarter setWaitResult(WaitResult result) {
2656 mRequest.waitResult = result;
2657 return this;
2658 }
2659
2660 ActivityStarter setProfilerInfo(ProfilerInfo info) {
2661 mRequest.profilerInfo = info;
2662 return this;
2663 }
2664
2665 ActivityStarter setGlobalConfiguration(Configuration config) {
2666 mRequest.globalConfig = config;
2667 return this;
2668 }
2669
Bryce Lee4c9a5972017-12-01 22:14:24 -08002670 ActivityStarter setUserId(int userId) {
2671 mRequest.userId = userId;
2672 return this;
2673 }
2674
Jorim Jaggi6fa41c32018-04-23 18:35:00 +02002675 ActivityStarter setAllowPendingRemoteAnimationRegistryLookup(boolean allowLookup) {
2676 mRequest.allowPendingRemoteAnimationRegistryLookup = allowLookup;
2677 return this;
2678 }
2679
Michal Karpinski201bc0c2018-07-20 15:32:00 +01002680 ActivityStarter setOriginatingPendingIntent(PendingIntentRecord originatingPendingIntent) {
2681 mRequest.originatingPendingIntent = originatingPendingIntent;
2682 return this;
2683 }
2684
Michal Karpinskiac116df2018-12-10 17:51:42 +00002685 ActivityStarter setAllowBackgroundActivityStart(boolean allowBackgroundActivityStart) {
2686 mRequest.allowBackgroundActivityStart = allowBackgroundActivityStart;
2687 return this;
2688 }
2689
Bryce Leed3624e12017-11-30 08:51:45 -08002690 void dump(PrintWriter pw, String prefix) {
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002691 prefix = prefix + " ";
Dianne Hackborne676ec72017-07-25 10:55:08 -07002692 pw.print(prefix);
2693 pw.print("mCurrentUser=");
Louis Chang149d5c82019-12-30 09:47:39 +08002694 pw.println(mRootWindowContainer.mCurrentUser);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002695 pw.print(prefix);
2696 pw.print("mLastStartReason=");
2697 pw.println(mLastStartReason);
2698 pw.print(prefix);
2699 pw.print("mLastStartActivityTimeMs=");
2700 pw.println(DateFormat.getDateTimeInstance().format(new Date(mLastStartActivityTimeMs)));
2701 pw.print(prefix);
2702 pw.print("mLastStartActivityResult=");
2703 pw.println(mLastStartActivityResult);
Louis Chang54fbb052019-10-16 17:10:17 +08002704 if (mLastStartActivityRecord != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002705 pw.print(prefix);
2706 pw.println("mLastStartActivityRecord:");
Louis Chang54fbb052019-10-16 17:10:17 +08002707 mLastStartActivityRecord.dump(pw, prefix + " ", true /* dumpAll */);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002708 }
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002709 if (mStartActivity != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002710 pw.print(prefix);
2711 pw.println("mStartActivity:");
Garfield Tane8d84ab2019-10-11 09:49:40 -07002712 mStartActivity.dump(pw, prefix + " ", true /* dumpAll */);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002713 }
2714 if (mIntent != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002715 pw.print(prefix);
2716 pw.print("mIntent=");
2717 pw.println(mIntent);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002718 }
2719 if (mOptions != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002720 pw.print(prefix);
2721 pw.print("mOptions=");
2722 pw.println(mOptions);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002723 }
Dianne Hackborne676ec72017-07-25 10:55:08 -07002724 pw.print(prefix);
2725 pw.print("mLaunchSingleTop=");
Bryce Lee7daee392017-10-12 13:46:18 -07002726 pw.print(LAUNCH_SINGLE_TOP == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002727 pw.print(" mLaunchSingleInstance=");
Bryce Lee7daee392017-10-12 13:46:18 -07002728 pw.print(LAUNCH_SINGLE_INSTANCE == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002729 pw.print(" mLaunchSingleTask=");
Bryce Lee7daee392017-10-12 13:46:18 -07002730 pw.println(LAUNCH_SINGLE_TASK == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002731 pw.print(prefix);
2732 pw.print("mLaunchFlags=0x");
2733 pw.print(Integer.toHexString(mLaunchFlags));
2734 pw.print(" mDoResume=");
2735 pw.print(mDoResume);
2736 pw.print(" mAddingToTask=");
2737 pw.println(mAddingToTask);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002738 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002739}