blob: 25842f58579d54114695fcd631caadfb5f5cf882 [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;
Winson Chung8a168902020-03-12 22:39:22 -070030import static android.app.ActivityTaskManager.INVALID_TASK_ID;
Louis Chang0513a942019-03-06 12:38:13 +080031import static android.app.WaitResult.LAUNCH_STATE_COLD;
32import static android.app.WaitResult.LAUNCH_STATE_HOT;
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;
Riddle Hsub70b36d2018-09-11 21:20:02 +080058
Wale Ogunwale59507092018-10-29 09:00:30 -070059import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
60import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME;
61import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
62import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
63import static com.android.server.wm.ActivityStackSupervisor.TAG_TASKS;
Bernardo Rufino1e088f12020-04-28 16:40:25 +010064import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ACTIVITY_STARTS;
Wale Ogunwale59507092018-10-29 09:00:30 -070065import 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;
Louis Changa009c762020-02-26 11:21:31 +080080import static com.android.server.wm.WindowContainer.POSITION_TOP;
Winson Chung74666102017-02-22 17:49:24 -080081
Todd Kennedye9910222017-02-21 16:00:11 -080082import android.annotation.NonNull;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +010083import android.annotation.Nullable;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080084import android.app.ActivityManager;
85import android.app.ActivityOptions;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080086import android.app.IApplicationThread;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080087import android.app.PendingIntent;
88import android.app.ProfilerInfo;
Sudheer Shankafc46e9b2016-10-21 17:55:27 -070089import android.app.WaitResult;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080090import android.content.IIntentSender;
91import android.content.Intent;
92import android.content.IntentSender;
93import android.content.pm.ActivityInfo;
94import android.content.pm.ApplicationInfo;
Todd Kennedye9910222017-02-21 16:00:11 -080095import android.content.pm.AuxiliaryResolveInfo;
Kenny Guyb1b30262016-02-09 16:02:35 +000096import android.content.pm.PackageManager;
Winson81fef842019-08-28 12:19:08 -070097import android.content.pm.PackageManagerInternal;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080098import android.content.pm.ResolveInfo;
Kenny Guyb1b30262016-02-09 16:02:35 +000099import android.content.pm.UserInfo;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800100import android.content.res.Configuration;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800101import 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;
Bernardo Rufino1e088f12020-04-28 16:40:25 +0100112import android.util.DebugUtils;
Bryce Leedaa91e42017-12-06 14:13:01 -0800113import android.util.Pools.SynchronizedPool;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800114import android.util.Slog;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800115
Bryce Leed3624e12017-11-30 08:51:45 -0800116import com.android.internal.annotations.VisibleForTesting;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800117import com.android.internal.app.HeavyWeightSwitcherActivity;
118import com.android.internal.app.IVoiceInteractor;
Wale Ogunwale59507092018-10-29 09:00:30 -0700119import com.android.server.am.PendingIntentRecord;
Louis Changdd3592a2018-11-05 11:04:14 +0800120import com.android.server.pm.InstantAppResolver;
Jeff Sharkey938089f2020-04-12 16:00:04 -0600121import com.android.server.uri.NeededUriGrants;
Riddle Hsufd66d4d2019-11-14 10:35:55 +0800122import com.android.server.wm.ActivityMetricsLogger.LaunchingState;
Wale Ogunwale59507092018-10-29 09:00:30 -0700123import com.android.server.wm.ActivityStackSupervisor.PendingActivityLaunch;
124import com.android.server.wm.LaunchParamsController.LaunchParams;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800125
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700126import java.io.PrintWriter;
127import java.text.DateFormat;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700128import java.util.Date;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800129
130/**
Bryce Leed3624e12017-11-30 08:51:45 -0800131 * Controller for interpreting how and then launching an activity.
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800132 *
133 * This class collects all the logic for determining how an intent and flags should be turned into
134 * an activity and associated task and stack.
135 */
Wale Ogunwale01d66562015-12-29 08:19:19 -0800136class ActivityStarter {
Wale Ogunwale98875612018-10-12 07:53:02 -0700137 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStarter" : TAG_ATM;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800138 private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS;
139 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
140 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
141 private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING;
Bryce Lee7daee392017-10-12 13:46:18 -0700142 private static final int INVALID_LAUNCH_MODE = -1;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800143
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700144 private final ActivityTaskManagerService mService;
Louis Chang149d5c82019-12-30 09:47:39 +0800145 private final RootWindowContainer mRootWindowContainer;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800146 private final ActivityStackSupervisor mSupervisor;
Benjamin Franz563707b2017-06-29 15:06:13 +0100147 private final ActivityStartInterceptor mInterceptor;
Bryce Leed3624e12017-11-30 08:51:45 -0800148 private final ActivityStartController mController;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800149
Wale Ogunwale01d66562015-12-29 08:19:19 -0800150 // Share state variable among methods when starting an activity.
Louis Chang07b13002019-11-27 22:08:37 +0800151 @VisibleForTesting
152 ActivityRecord mStartActivity;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800153 private Intent mIntent;
154 private int mCallingUid;
155 private ActivityOptions mOptions;
156
Ricky Waib147fa12019-04-25 16:08:30 +0100157 // If it is true, background activity can only be started in an existing task that contains
Alan Stokes07389b62019-05-20 15:22:54 +0100158 // an activity with same uid, or if activity starts are enabled in developer options.
Ricky Waib147fa12019-04-25 16:08:30 +0100159 private boolean mRestrictedBgActivity;
160
Bryce Lee7daee392017-10-12 13:46:18 -0700161 private int mLaunchMode;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800162 private boolean mLaunchTaskBehind;
163 private int mLaunchFlags;
164
Bryce Leeec55eb02017-12-05 20:51:27 -0800165 private LaunchParams mLaunchParams = new LaunchParams();
Wale Ogunwale01d66562015-12-29 08:19:19 -0800166
167 private ActivityRecord mNotTop;
168 private boolean mDoResume;
169 private int mStartFlags;
170 private ActivityRecord mSourceRecord;
Bryce Lee7daee392017-10-12 13:46:18 -0700171
Andrii Kulian1cfcae82020-04-10 12:44:38 -0700172 // The task display area to launch the activity onto, barring any strong reason to do otherwise.
173 private TaskDisplayArea mPreferredTaskDisplayArea;
Winson Chung8a168902020-03-12 22:39:22 -0700174 private int mPreferredWindowingMode;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800175
Louis Changcdec0802019-11-11 11:45:07 +0800176 private Task mInTask;
Louis Chang07b13002019-11-27 22:08:37 +0800177 @VisibleForTesting
178 boolean mAddingToTask;
Louis Changcdec0802019-11-11 11:45:07 +0800179 private Task mReuseTask;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800180
181 private ActivityInfo mNewTaskInfo;
182 private Intent mNewTaskIntent;
183 private ActivityStack mSourceStack;
184 private ActivityStack mTargetStack;
Winson Chunge789ff62020-02-24 14:40:23 -0800185 // The task that the last activity was started into. We currently reset the actual start
186 // activity's task and as a result may not have a reference to the task in all cases
187 private Task mTargetTask;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800188 private boolean mMovedToFront;
189 private boolean mNoAnimation;
190 private boolean mKeepCurTransition;
Jorim Jaggic875ae72016-04-26 22:41:06 -0700191 private boolean mAvoidMoveToFront;
Winson Chunge219ae12019-07-18 13:43:23 -0700192 private boolean mFrozeTaskList;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800193
Bryce Lee325e09682017-10-05 17:20:25 -0700194 // We must track when we deliver the new intent since multiple code paths invoke
195 // {@link #deliverNewIntent}. This is due to early returns in the code path. This flag is used
196 // inside {@link #deliverNewIntent} to suppress duplicate requests and ensure the intent is
197 // delivered at most once.
198 private boolean mIntentDelivered;
199
Wale Ogunwale01d66562015-12-29 08:19:19 -0800200 private IVoiceInteractionSession mVoiceSession;
201 private IVoiceInteractor mVoiceInteractor;
202
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700203 // Last activity record we attempted to start
Louis Chang54fbb052019-10-16 17:10:17 +0800204 private ActivityRecord mLastStartActivityRecord;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700205 // The result of the last activity we attempted to start.
206 private int mLastStartActivityResult;
207 // Time in milli seconds we attempted to start the last activity.
208 private long mLastStartActivityTimeMs;
209 // The reason we were trying to start the last activity
210 private String mLastStartReason;
Wale Ogunwale59bcba62017-06-16 12:42:51 -0700211
Bryce Lee4c9a5972017-12-01 22:14:24 -0800212 /*
213 * Request details provided through setter methods. Should be reset after {@link #execute()}
214 * to avoid unnecessarily retaining parameters. Note that the request is ignored when
215 * {@link #startResolvedActivity} is invoked directly.
216 */
Louis Chang54fbb052019-10-16 17:10:17 +0800217 @VisibleForTesting
218 Request mRequest = new Request();
Bryce Lee4c9a5972017-12-01 22:14:24 -0800219
Bryce Leed3624e12017-11-30 08:51:45 -0800220 /**
221 * An interface that to provide {@link ActivityStarter} instances to the controller. This is
222 * used by tests to inject their own starter implementations for verification purposes.
223 */
224 @VisibleForTesting
225 interface Factory {
226 /**
Bryce Lee4c9a5972017-12-01 22:14:24 -0800227 * Sets the {@link ActivityStartController} to be passed to {@link ActivityStarter}.
228 */
229 void setController(ActivityStartController controller);
230
231 /**
Bryce Leed3624e12017-11-30 08:51:45 -0800232 * Generates an {@link ActivityStarter} that is ready to handle a new start request.
233 * @param controller The {@link ActivityStartController} which the starter who will own
234 * this instance.
235 * @return an {@link ActivityStarter}
236 */
Bryce Leedaa91e42017-12-06 14:13:01 -0800237 ActivityStarter obtain();
238
239 /**
240 * Recycles a starter for reuse.
241 */
242 void recycle(ActivityStarter starter);
Wale Ogunwale01d66562015-12-29 08:19:19 -0800243 }
244
Bryce Leed3624e12017-11-30 08:51:45 -0800245 /**
246 * Default implementation of {@link StarterFactory}.
247 */
248 static class DefaultFactory implements Factory {
Bryce Leedaa91e42017-12-06 14:13:01 -0800249 /**
250 * The maximum count of starters that should be active at one time:
251 * 1. last ran starter (for logging and post activity processing)
252 * 2. current running starter
253 * 3. starter from re-entry in (2)
254 */
255 private final int MAX_STARTER_COUNT = 3;
256
Bryce Lee4c9a5972017-12-01 22:14:24 -0800257 private ActivityStartController mController;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700258 private ActivityTaskManagerService mService;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800259 private ActivityStackSupervisor mSupervisor;
260 private ActivityStartInterceptor mInterceptor;
261
Bryce Leedaa91e42017-12-06 14:13:01 -0800262 private SynchronizedPool<ActivityStarter> mStarterPool =
263 new SynchronizedPool<>(MAX_STARTER_COUNT);
264
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700265 DefaultFactory(ActivityTaskManagerService service,
Bryce Lee4c9a5972017-12-01 22:14:24 -0800266 ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
267 mService = service;
268 mSupervisor = supervisor;
269 mInterceptor = interceptor;
Bryce Leed3624e12017-11-30 08:51:45 -0800270 }
Bryce Lee4c9a5972017-12-01 22:14:24 -0800271
272 @Override
273 public void setController(ActivityStartController controller) {
274 mController = controller;
275 }
276
277 @Override
Bryce Leedaa91e42017-12-06 14:13:01 -0800278 public ActivityStarter obtain() {
279 ActivityStarter starter = mStarterPool.acquire();
280
281 if (starter == null) {
282 starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
283 }
284
285 return starter;
286 }
287
288 @Override
289 public void recycle(ActivityStarter starter) {
290 starter.reset(true /* clearRequest*/);
291 mStarterPool.release(starter);
Bryce Lee4c9a5972017-12-01 22:14:24 -0800292 }
293 }
294
295 /**
296 * Container for capturing initial start request details. This information is NOT reset until
297 * the {@link ActivityStarter} is recycled, allowing for multiple invocations with the same
298 * parameters.
299 *
300 * TODO(b/64750076): Investigate consolidating member variables of {@link ActivityStarter} with
301 * the request object. Note that some member variables are referenced in
302 * {@link #dump(PrintWriter, String)} and therefore cannot be cleared immediately after
303 * execution.
304 */
Louis Chang54fbb052019-10-16 17:10:17 +0800305 @VisibleForTesting
306 static class Request {
Bryce Lee4c9a5972017-12-01 22:14:24 -0800307 private static final int DEFAULT_CALLING_UID = -1;
308 private static final int DEFAULT_CALLING_PID = 0;
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000309 static final int DEFAULT_REAL_CALLING_UID = -1;
310 static final int DEFAULT_REAL_CALLING_PID = 0;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800311
312 IApplicationThread caller;
313 Intent intent;
Jeff Sharkey307ea7a2020-04-13 10:24:49 -0600314 NeededUriGrants intentGrants;
Louis Chang54fbb052019-10-16 17:10:17 +0800315 // A copy of the original requested intent, in case for ephemeral app launch.
Bryce Lee4c9a5972017-12-01 22:14:24 -0800316 Intent ephemeralIntent;
317 String resolvedType;
318 ActivityInfo activityInfo;
319 ResolveInfo resolveInfo;
320 IVoiceInteractionSession voiceSession;
321 IVoiceInteractor voiceInteractor;
322 IBinder resultTo;
323 String resultWho;
324 int requestCode;
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000325 int callingPid = DEFAULT_CALLING_PID;
326 int callingUid = DEFAULT_CALLING_UID;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800327 String callingPackage;
Philip P. Moltmannee295092020-02-10 08:46:26 -0800328 @Nullable String callingFeatureId;
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000329 int realCallingPid = DEFAULT_REAL_CALLING_PID;
330 int realCallingUid = DEFAULT_REAL_CALLING_UID;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800331 int startFlags;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100332 SafeActivityOptions activityOptions;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800333 boolean ignoreTargetSecurity;
334 boolean componentSpecified;
Winson Chunge2d72172018-01-25 17:46:20 +0000335 boolean avoidMoveToFront;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800336 ActivityRecord[] outActivity;
Louis Changcdec0802019-11-11 11:45:07 +0800337 Task inTask;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800338 String reason;
339 ProfilerInfo profilerInfo;
340 Configuration globalConfig;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800341 int userId;
342 WaitResult waitResult;
Patrick Baumann31426b22018-05-21 13:46:40 -0700343 int filterCallingUid;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100344 PendingIntentRecord originatingPendingIntent;
Michal Karpinskiac116df2018-12-10 17:51:42 +0000345 boolean allowBackgroundActivityStart;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800346
347 /**
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200348 * If set to {@code true}, allows this activity start to look into
349 * {@link PendingRemoteAnimationRegistry}
350 */
351 boolean allowPendingRemoteAnimationRegistryLookup;
352
353 /**
Bryce Leea3cd8e02018-01-09 15:44:24 -0800354 * Ensure constructed request matches reset instance.
355 */
356 Request() {
357 reset();
358 }
359
360 /**
Bryce Leedaa91e42017-12-06 14:13:01 -0800361 * Sets values back to the initial state, clearing any held references.
362 */
363 void reset() {
364 caller = null;
365 intent = null;
Jeff Sharkey307ea7a2020-04-13 10:24:49 -0600366 intentGrants = null;
Bryce Leedaa91e42017-12-06 14:13:01 -0800367 ephemeralIntent = null;
368 resolvedType = null;
369 activityInfo = null;
370 resolveInfo = null;
371 voiceSession = null;
372 voiceInteractor = null;
373 resultTo = null;
374 resultWho = null;
375 requestCode = 0;
Bryce Leea3cd8e02018-01-09 15:44:24 -0800376 callingPid = DEFAULT_CALLING_PID;
377 callingUid = DEFAULT_CALLING_UID;
Bryce Leedaa91e42017-12-06 14:13:01 -0800378 callingPackage = null;
Philip P. Moltmannee295092020-02-10 08:46:26 -0800379 callingFeatureId = null;
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000380 realCallingPid = DEFAULT_REAL_CALLING_PID;
381 realCallingUid = DEFAULT_REAL_CALLING_UID;
Bryce Leedaa91e42017-12-06 14:13:01 -0800382 startFlags = 0;
383 activityOptions = null;
384 ignoreTargetSecurity = false;
385 componentSpecified = false;
386 outActivity = null;
387 inTask = null;
388 reason = null;
389 profilerInfo = null;
390 globalConfig = null;
Bryce Leedaa91e42017-12-06 14:13:01 -0800391 userId = 0;
392 waitResult = null;
Winson Chunge2d72172018-01-25 17:46:20 +0000393 avoidMoveToFront = false;
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200394 allowPendingRemoteAnimationRegistryLookup = true;
Patrick Baumann31426b22018-05-21 13:46:40 -0700395 filterCallingUid = UserHandle.USER_NULL;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100396 originatingPendingIntent = null;
Michal Karpinskiac116df2018-12-10 17:51:42 +0000397 allowBackgroundActivityStart = false;
Bryce Leedaa91e42017-12-06 14:13:01 -0800398 }
399
400 /**
401 * Adopts all values from passed in request.
402 */
403 void set(Request request) {
404 caller = request.caller;
405 intent = request.intent;
Jeff Sharkey307ea7a2020-04-13 10:24:49 -0600406 intentGrants = request.intentGrants;
Bryce Leedaa91e42017-12-06 14:13:01 -0800407 ephemeralIntent = request.ephemeralIntent;
408 resolvedType = request.resolvedType;
409 activityInfo = request.activityInfo;
410 resolveInfo = request.resolveInfo;
411 voiceSession = request.voiceSession;
412 voiceInteractor = request.voiceInteractor;
413 resultTo = request.resultTo;
414 resultWho = request.resultWho;
415 requestCode = request.requestCode;
416 callingPid = request.callingPid;
417 callingUid = request.callingUid;
418 callingPackage = request.callingPackage;
Philip P. Moltmannee295092020-02-10 08:46:26 -0800419 callingFeatureId = request.callingFeatureId;
Bryce Leedaa91e42017-12-06 14:13:01 -0800420 realCallingPid = request.realCallingPid;
421 realCallingUid = request.realCallingUid;
422 startFlags = request.startFlags;
423 activityOptions = request.activityOptions;
424 ignoreTargetSecurity = request.ignoreTargetSecurity;
425 componentSpecified = request.componentSpecified;
426 outActivity = request.outActivity;
427 inTask = request.inTask;
428 reason = request.reason;
429 profilerInfo = request.profilerInfo;
430 globalConfig = request.globalConfig;
Bryce Leedaa91e42017-12-06 14:13:01 -0800431 userId = request.userId;
432 waitResult = request.waitResult;
Winson Chunge2d72172018-01-25 17:46:20 +0000433 avoidMoveToFront = request.avoidMoveToFront;
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200434 allowPendingRemoteAnimationRegistryLookup
435 = request.allowPendingRemoteAnimationRegistryLookup;
Patrick Baumann31426b22018-05-21 13:46:40 -0700436 filterCallingUid = request.filterCallingUid;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100437 originatingPendingIntent = request.originatingPendingIntent;
Michal Karpinskiac116df2018-12-10 17:51:42 +0000438 allowBackgroundActivityStart = request.allowBackgroundActivityStart;
Bryce Leedaa91e42017-12-06 14:13:01 -0800439 }
Louis Chang54fbb052019-10-16 17:10:17 +0800440
441 /**
442 * Resolve activity from the given intent for this launch.
443 */
444 void resolveActivity(ActivityStackSupervisor supervisor) {
445 if (realCallingPid == Request.DEFAULT_REAL_CALLING_PID) {
446 realCallingPid = Binder.getCallingPid();
447 }
448 if (realCallingUid == Request.DEFAULT_REAL_CALLING_UID) {
449 realCallingUid = Binder.getCallingUid();
450 }
451
452 if (callingUid >= 0) {
453 callingPid = -1;
454 } else if (caller == null) {
455 callingPid = realCallingPid;
456 callingUid = realCallingUid;
457 } else {
458 callingPid = callingUid = -1;
459 }
460
Jeff Sharkey307ea7a2020-04-13 10:24:49 -0600461 // To determine the set of needed Uri permission grants, we need the
462 // "resolved" calling UID, where we try our best to identify the
463 // actual caller that is starting this activity
464 int resolvedCallingUid = callingUid;
465 if (caller != null) {
466 synchronized (supervisor.mService.mGlobalLock) {
467 final WindowProcessController callerApp = supervisor.mService
468 .getProcessController(caller);
469 if (callerApp != null) {
470 resolvedCallingUid = callerApp.mInfo.uid;
471 }
472 }
473 }
474
Louis Chang54fbb052019-10-16 17:10:17 +0800475 // Save a copy in case ephemeral needs it
476 ephemeralIntent = new Intent(intent);
477 // Don't modify the client's object!
478 intent = new Intent(intent);
479 if (intent.getComponent() != null
480 && !(Intent.ACTION_VIEW.equals(intent.getAction()) && intent.getData() == null)
481 && !Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE.equals(intent.getAction())
482 && !Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE.equals(intent.getAction())
483 && supervisor.mService.getPackageManagerInternalLocked()
484 .isInstantAppInstallerComponent(intent.getComponent())) {
485 // Intercept intents targeted directly to the ephemeral installer the ephemeral
486 // installer should never be started with a raw Intent; instead adjust the intent
487 // so it looks like a "normal" instant app launch.
488 intent.setComponent(null /* component */);
489 }
490
491 resolveInfo = supervisor.resolveIntent(intent, resolvedType, userId,
492 0 /* matchFlags */,
493 computeResolveFilterUid(callingUid, realCallingUid, filterCallingUid));
494 if (resolveInfo == null) {
495 final UserInfo userInfo = supervisor.getUserInfo(userId);
496 if (userInfo != null && userInfo.isManagedProfile()) {
497 // Special case for managed profiles, if attempting to launch non-cryto aware
498 // app in a locked managed profile from an unlocked parent allow it to resolve
499 // as user will be sent via confirm credentials to unlock the profile.
500 final UserManager userManager = UserManager.get(supervisor.mService.mContext);
501 boolean profileLockedAndParentUnlockingOrUnlocked = false;
502 final long token = Binder.clearCallingIdentity();
503 try {
504 final UserInfo parent = userManager.getProfileParent(userId);
505 profileLockedAndParentUnlockingOrUnlocked = (parent != null)
506 && userManager.isUserUnlockingOrUnlocked(parent.id)
507 && !userManager.isUserUnlockingOrUnlocked(userId);
508 } finally {
509 Binder.restoreCallingIdentity(token);
510 }
511 if (profileLockedAndParentUnlockingOrUnlocked) {
512 resolveInfo = supervisor.resolveIntent(intent, resolvedType, userId,
513 PackageManager.MATCH_DIRECT_BOOT_AWARE
514 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
515 computeResolveFilterUid(callingUid, realCallingUid,
516 filterCallingUid));
517 }
518 }
519 }
520
521 // Collect information about the target of the Intent.
522 activityInfo = supervisor.resolveActivity(intent, resolveInfo, startFlags,
523 profilerInfo);
Jeff Sharkey307ea7a2020-04-13 10:24:49 -0600524
525 // Carefully collect grants without holding lock
526 if (activityInfo != null) {
527 intentGrants = supervisor.mService.mUgmInternal.checkGrantUriPermissionFromIntent(
528 intent, resolvedCallingUid, activityInfo.applicationInfo.packageName,
529 UserHandle.getUserId(activityInfo.applicationInfo.uid));
530 }
Louis Chang54fbb052019-10-16 17:10:17 +0800531 }
Bryce Leed3624e12017-11-30 08:51:45 -0800532 }
533
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700534 ActivityStarter(ActivityStartController controller, ActivityTaskManagerService service,
Bryce Leed3624e12017-11-30 08:51:45 -0800535 ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
536 mController = controller;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800537 mService = service;
Louis Chang149d5c82019-12-30 09:47:39 +0800538 mRootWindowContainer = service.mRootWindowContainer;
Bryce Leed3624e12017-11-30 08:51:45 -0800539 mSupervisor = supervisor;
540 mInterceptor = interceptor;
Bryce Leedaa91e42017-12-06 14:13:01 -0800541 reset(true);
542 }
543
544 /**
545 * Effectively duplicates the starter passed in. All state and request values will be
546 * mirrored.
547 * @param starter
548 */
549 void set(ActivityStarter starter) {
550 mStartActivity = starter.mStartActivity;
551 mIntent = starter.mIntent;
552 mCallingUid = starter.mCallingUid;
553 mOptions = starter.mOptions;
Ricky Waib147fa12019-04-25 16:08:30 +0100554 mRestrictedBgActivity = starter.mRestrictedBgActivity;
Bryce Leedaa91e42017-12-06 14:13:01 -0800555
556 mLaunchTaskBehind = starter.mLaunchTaskBehind;
557 mLaunchFlags = starter.mLaunchFlags;
558 mLaunchMode = starter.mLaunchMode;
559
Bryce Leeec55eb02017-12-05 20:51:27 -0800560 mLaunchParams.set(starter.mLaunchParams);
Bryce Leedaa91e42017-12-06 14:13:01 -0800561
562 mNotTop = starter.mNotTop;
563 mDoResume = starter.mDoResume;
564 mStartFlags = starter.mStartFlags;
565 mSourceRecord = starter.mSourceRecord;
Andrii Kulian1cfcae82020-04-10 12:44:38 -0700566 mPreferredTaskDisplayArea = starter.mPreferredTaskDisplayArea;
Winson Chung8a168902020-03-12 22:39:22 -0700567 mPreferredWindowingMode = starter.mPreferredWindowingMode;
Bryce Leedaa91e42017-12-06 14:13:01 -0800568
569 mInTask = starter.mInTask;
570 mAddingToTask = starter.mAddingToTask;
571 mReuseTask = starter.mReuseTask;
572
573 mNewTaskInfo = starter.mNewTaskInfo;
574 mNewTaskIntent = starter.mNewTaskIntent;
575 mSourceStack = starter.mSourceStack;
576
Winson Chunge789ff62020-02-24 14:40:23 -0800577 mTargetTask = starter.mTargetTask;
Bryce Leedaa91e42017-12-06 14:13:01 -0800578 mTargetStack = starter.mTargetStack;
579 mMovedToFront = starter.mMovedToFront;
580 mNoAnimation = starter.mNoAnimation;
581 mKeepCurTransition = starter.mKeepCurTransition;
582 mAvoidMoveToFront = starter.mAvoidMoveToFront;
Winson Chunge219ae12019-07-18 13:43:23 -0700583 mFrozeTaskList = starter.mFrozeTaskList;
Bryce Leedaa91e42017-12-06 14:13:01 -0800584
585 mVoiceSession = starter.mVoiceSession;
586 mVoiceInteractor = starter.mVoiceInteractor;
587
588 mIntentDelivered = starter.mIntentDelivered;
589
590 mRequest.set(starter.mRequest);
Bryce Leed3624e12017-11-30 08:51:45 -0800591 }
592
Bryce Lee4c9a5972017-12-01 22:14:24 -0800593 boolean relatedToPackage(String packageName) {
Louis Chang54fbb052019-10-16 17:10:17 +0800594 return (mLastStartActivityRecord != null
595 && packageName.equals(mLastStartActivityRecord.packageName))
Bryce Lee4c9a5972017-12-01 22:14:24 -0800596 || (mStartActivity != null && packageName.equals(mStartActivity.packageName));
597 }
598
599 /**
Louis Chang54fbb052019-10-16 17:10:17 +0800600 * Starts an activity based on the provided {@link ActivityRecord} and environment parameters.
601 * Note that this method is called internally as well as part of {@link #executeRequest}.
602 */
603 void startResolvedActivity(final ActivityRecord r, ActivityRecord sourceRecord,
604 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
Jeff Sharkey307ea7a2020-04-13 10:24:49 -0600605 int startFlags, boolean doResume, ActivityOptions options, Task inTask,
606 NeededUriGrants intentGrants) {
Louis Chang54fbb052019-10-16 17:10:17 +0800607 try {
Riddle Hsufd66d4d2019-11-14 10:35:55 +0800608 final LaunchingState launchingState = mSupervisor.getActivityMetricsLogger()
609 .notifyActivityLaunching(r.intent, r.resultTo);
Louis Chang54fbb052019-10-16 17:10:17 +0800610 mLastStartReason = "startResolvedActivity";
611 mLastStartActivityTimeMs = System.currentTimeMillis();
612 mLastStartActivityRecord = r;
613 mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
614 voiceInteractor, startFlags, doResume, options, inTask,
Jeff Sharkey307ea7a2020-04-13 10:24:49 -0600615 false /* restrictedBgActivity */, intentGrants);
Riddle Hsufd66d4d2019-11-14 10:35:55 +0800616 mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState,
617 mLastStartActivityResult, mLastStartActivityRecord);
Louis Chang54fbb052019-10-16 17:10:17 +0800618 } finally {
619 onExecutionComplete();
620 }
621 }
622
623 /**
624 * Resolve necessary information according the request parameters provided earlier, and execute
625 * the request which begin the journey of starting an activity.
Bryce Lee4c9a5972017-12-01 22:14:24 -0800626 * @return The starter result.
627 */
628 int execute() {
Bryce Leedaa91e42017-12-06 14:13:01 -0800629 try {
Louis Chang54fbb052019-10-16 17:10:17 +0800630 // Refuse possible leaked file descriptors
631 if (mRequest.intent != null && mRequest.intent.hasFileDescriptors()) {
632 throw new IllegalArgumentException("File descriptors passed in Intent");
633 }
634
Riddle Hsufd66d4d2019-11-14 10:35:55 +0800635 final LaunchingState launchingState;
636 synchronized (mService.mGlobalLock) {
637 final ActivityRecord caller = ActivityRecord.forTokenLocked(mRequest.resultTo);
638 launchingState = mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(
639 mRequest.intent, caller);
640 }
Louis Chang54fbb052019-10-16 17:10:17 +0800641
Jeff Sharkey1d1e7532020-06-03 13:05:01 -0600642 // If the caller hasn't already resolved the activity, we're willing
643 // to do so here, but because that may require acquiring the AM lock
644 // as part of calculating the NeededUriGrants, we must never hold
645 // the WM lock here to avoid deadlocking.
Louis Chang54fbb052019-10-16 17:10:17 +0800646 if (mRequest.activityInfo == null) {
Jeff Sharkey1d1e7532020-06-03 13:05:01 -0600647 if (Thread.holdsLock(mService.mGlobalLock)) {
648 Slog.wtf(TAG, new IllegalStateException("Caller must not hold WM lock"));
649 }
Louis Chang54fbb052019-10-16 17:10:17 +0800650 mRequest.resolveActivity(mSupervisor);
651 }
652
653 int res;
654 synchronized (mService.mGlobalLock) {
Darryl L Johnson1e3885c2020-02-27 17:38:13 -0800655 final boolean globalConfigWillChange = mRequest.globalConfig != null
Louis Chang54fbb052019-10-16 17:10:17 +0800656 && mService.getGlobalConfiguration().diff(mRequest.globalConfig) != 0;
Darryl L Johnson1e3885c2020-02-27 17:38:13 -0800657 final ActivityStack stack = mRootWindowContainer.getTopDisplayFocusedStack();
658 if (stack != null) {
659 stack.mConfigWillChange = globalConfigWillChange;
660 }
Louis Chang54fbb052019-10-16 17:10:17 +0800661 if (DEBUG_CONFIGURATION) {
662 Slog.v(TAG_CONFIGURATION, "Starting activity when config will change = "
Darryl L Johnson1e3885c2020-02-27 17:38:13 -0800663 + globalConfigWillChange);
Louis Chang54fbb052019-10-16 17:10:17 +0800664 }
665
666 final long origId = Binder.clearCallingIdentity();
667
668 res = resolveToHeavyWeightSwitcherIfNeeded();
669 if (res != START_SUCCESS) {
670 return res;
671 }
672 res = executeRequest(mRequest);
673
674 Binder.restoreCallingIdentity(origId);
675
Darryl L Johnson1e3885c2020-02-27 17:38:13 -0800676 if (globalConfigWillChange) {
Louis Chang54fbb052019-10-16 17:10:17 +0800677 // If the caller also wants to switch to a new configuration, do so now.
678 // This allows a clean switch, as we are waiting for the current activity
679 // to pause (so we will not destroy it), and have not yet started the
680 // next activity.
681 mService.mAmInternal.enforceCallingPermission(
682 android.Manifest.permission.CHANGE_CONFIGURATION,
683 "updateConfiguration()");
Darryl L Johnson1e3885c2020-02-27 17:38:13 -0800684 if (stack != null) {
685 stack.mConfigWillChange = false;
686 }
Louis Chang54fbb052019-10-16 17:10:17 +0800687 if (DEBUG_CONFIGURATION) {
688 Slog.v(TAG_CONFIGURATION,
689 "Updating to new configuration after starting activity.");
690 }
691 mService.updateConfigurationLocked(mRequest.globalConfig, null, false);
692 }
693
694 // Notify ActivityMetricsLogger that the activity has launched.
695 // ActivityMetricsLogger will then wait for the windows to be drawn and populate
696 // WaitResult.
Riddle Hsufd66d4d2019-11-14 10:35:55 +0800697 mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState, res,
Louis Chang54fbb052019-10-16 17:10:17 +0800698 mLastStartActivityRecord);
699 return getExternalResult(mRequest.waitResult == null ? res
700 : waitForResult(res, mLastStartActivityRecord));
Bryce Leedaa91e42017-12-06 14:13:01 -0800701 }
702 } finally {
703 onExecutionComplete();
704 }
705 }
706
707 /**
Louis Chang54fbb052019-10-16 17:10:17 +0800708 * Updates the request to heavy-weight switch if this is a heavy-weight process while there
709 * already have another, different heavy-weight process running.
Bryce Leedaa91e42017-12-06 14:13:01 -0800710 */
Louis Chang54fbb052019-10-16 17:10:17 +0800711 private int resolveToHeavyWeightSwitcherIfNeeded() {
712 if (mRequest.activityInfo == null || !mService.mHasHeavyWeightFeature
713 || (mRequest.activityInfo.applicationInfo.privateFlags
714 & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) == 0) {
715 return START_SUCCESS;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700716 }
Bryce Leef9d49542017-06-26 16:27:32 -0700717
Louis Chang54fbb052019-10-16 17:10:17 +0800718 if (!mRequest.activityInfo.processName.equals(
719 mRequest.activityInfo.applicationInfo.packageName)) {
720 return START_SUCCESS;
721 }
Bryce Lee93e7f792017-10-25 15:54:55 -0700722
Louis Chang54fbb052019-10-16 17:10:17 +0800723 final WindowProcessController heavy = mService.mHeavyWeightProcess;
724 if (heavy == null || (heavy.mInfo.uid == mRequest.activityInfo.applicationInfo.uid
725 && heavy.mName.equals(mRequest.activityInfo.processName))) {
726 return START_SUCCESS;
727 }
728
729 int appCallingUid = mRequest.callingUid;
730 if (mRequest.caller != null) {
731 WindowProcessController callerApp = mService.getProcessController(mRequest.caller);
732 if (callerApp != null) {
733 appCallingUid = callerApp.mInfo.uid;
734 } else {
735 Slog.w(TAG, "Unable to find app for caller " + mRequest.caller + " (pid="
736 + mRequest.callingPid + ") when starting: " + mRequest.intent.toString());
737 SafeActivityOptions.abort(mRequest.activityOptions);
738 return ActivityManager.START_PERMISSION_DENIED;
739 }
740 }
741
742 final IIntentSender target = mService.getIntentSenderLocked(
Philip P. Moltmannee295092020-02-10 08:46:26 -0800743 ActivityManager.INTENT_SENDER_ACTIVITY, "android" /* packageName */,
744 null /* featureId */, appCallingUid, mRequest.userId, null /* token */,
745 null /* resultWho*/, 0 /* requestCode*/, new Intent[]{mRequest.intent},
746 new String[]{mRequest.resolvedType},
Louis Chang54fbb052019-10-16 17:10:17 +0800747 PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT,
748 null /* bOptions */);
749
750 final Intent newIntent = new Intent();
751 if (mRequest.requestCode >= 0) {
752 // Caller is requesting a result.
753 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
754 }
755 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT, new IntentSender(target));
756 heavy.updateIntentForHeavyWeightActivity(newIntent);
757 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
758 mRequest.activityInfo.packageName);
759 newIntent.setFlags(mRequest.intent.getFlags());
760 newIntent.setClassName("android" /* packageName */,
761 HeavyWeightSwitcherActivity.class.getName());
762 mRequest.intent = newIntent;
763 mRequest.resolvedType = null;
764 mRequest.caller = null;
765 mRequest.callingUid = Binder.getCallingUid();
766 mRequest.callingPid = Binder.getCallingPid();
767 mRequest.componentSpecified = true;
768 mRequest.resolveInfo = mSupervisor.resolveIntent(mRequest.intent, null /* resolvedType */,
769 mRequest.userId, 0 /* matchFlags */,
770 computeResolveFilterUid(mRequest.callingUid, mRequest.realCallingUid,
771 mRequest.filterCallingUid));
772 mRequest.activityInfo =
773 mRequest.resolveInfo != null ? mRequest.resolveInfo.activityInfo : null;
774 if (mRequest.activityInfo != null) {
775 mRequest.activityInfo = mService.mAmInternal.getActivityInfoForUser(
776 mRequest.activityInfo, mRequest.userId);
777 }
778
779 return START_SUCCESS;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700780 }
781
Bryce Leedaa91e42017-12-06 14:13:01 -0800782 /**
Louis Chang54fbb052019-10-16 17:10:17 +0800783 * Wait for activity launch completes.
Bryce Leedaa91e42017-12-06 14:13:01 -0800784 */
Louis Chang54fbb052019-10-16 17:10:17 +0800785 private int waitForResult(int res, ActivityRecord r) {
786 mRequest.waitResult.result = res;
787 switch(res) {
788 case START_SUCCESS: {
789 mSupervisor.mWaitingActivityLaunched.add(mRequest.waitResult);
790 do {
791 try {
792 mService.mGlobalLock.wait();
793 } catch (InterruptedException e) {
794 }
795 } while (mRequest.waitResult.result != START_TASK_TO_FRONT
796 && !mRequest.waitResult.timeout && mRequest.waitResult.who == null);
797 if (mRequest.waitResult.result == START_TASK_TO_FRONT) {
798 res = START_TASK_TO_FRONT;
799 }
800 break;
801 }
802 case START_DELIVERED_TO_TOP: {
803 mRequest.waitResult.timeout = false;
804 mRequest.waitResult.who = r.mActivityComponent;
805 mRequest.waitResult.totalTime = 0;
806 break;
807 }
808 case START_TASK_TO_FRONT: {
809 mRequest.waitResult.launchState =
810 r.attachedToProcess() ? LAUNCH_STATE_HOT : LAUNCH_STATE_COLD;
811 // ActivityRecord may represent a different activity, but it should not be
812 // in the resumed state.
813 if (r.nowVisible && r.isState(RESUMED)) {
814 mRequest.waitResult.timeout = false;
815 mRequest.waitResult.who = r.mActivityComponent;
816 mRequest.waitResult.totalTime = 0;
817 } else {
Riddle Hsuc48c8912019-10-31 13:34:27 +0800818 mSupervisor.waitActivityVisible(r.mActivityComponent, mRequest.waitResult);
Louis Chang54fbb052019-10-16 17:10:17 +0800819 // Note: the timeout variable is not currently not ever set.
820 do {
821 try {
822 mService.mGlobalLock.wait();
823 } catch (InterruptedException e) {
824 }
825 } while (!mRequest.waitResult.timeout && mRequest.waitResult.who == null);
826 }
827 break;
828 }
829 }
830 return res;
Bryce Leedaa91e42017-12-06 14:13:01 -0800831 }
832
Louis Chang54fbb052019-10-16 17:10:17 +0800833 /**
834 * Executing activity start request and starts the journey of starting an activity. Here
835 * begins with performing several preliminary checks. The normally activity launch flow will
836 * go through {@link #startActivityUnchecked} to {@link #startActivityInner}.
837 */
838 private int executeRequest(Request request) {
839 if (TextUtils.isEmpty(request.reason)) {
840 throw new IllegalArgumentException("Need to specify a reason.");
841 }
842 mLastStartReason = request.reason;
843 mLastStartActivityTimeMs = System.currentTimeMillis();
844 mLastStartActivityRecord = null;
845
846 final IApplicationThread caller = request.caller;
847 Intent intent = request.intent;
Jeff Sharkey307ea7a2020-04-13 10:24:49 -0600848 NeededUriGrants intentGrants = request.intentGrants;
Louis Chang54fbb052019-10-16 17:10:17 +0800849 String resolvedType = request.resolvedType;
850 ActivityInfo aInfo = request.activityInfo;
851 ResolveInfo rInfo = request.resolveInfo;
852 final IVoiceInteractionSession voiceSession = request.voiceSession;
853 final IBinder resultTo = request.resultTo;
854 String resultWho = request.resultWho;
855 int requestCode = request.requestCode;
856 int callingPid = request.callingPid;
857 int callingUid = request.callingUid;
858 String callingPackage = request.callingPackage;
Philip P. Moltmannee295092020-02-10 08:46:26 -0800859 String callingFeatureId = request.callingFeatureId;
Louis Chang54fbb052019-10-16 17:10:17 +0800860 final int realCallingPid = request.realCallingPid;
861 final int realCallingUid = request.realCallingUid;
862 final int startFlags = request.startFlags;
863 final SafeActivityOptions options = request.activityOptions;
Louis Changcdec0802019-11-11 11:45:07 +0800864 Task inTask = request.inTask;
Louis Chang54fbb052019-10-16 17:10:17 +0800865
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800866 int err = ActivityManager.START_SUCCESS;
Chad Brubaker06068612017-04-06 09:43:47 -0700867 // Pull the optional Ephemeral Installer-only bundle out of the options early.
Louis Chang54fbb052019-10-16 17:10:17 +0800868 final Bundle verificationBundle =
869 options != null ? options.popAppVerificationBundle() : null;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800870
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700871 WindowProcessController callerApp = null;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800872 if (caller != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700873 callerApp = mService.getProcessController(caller);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800874 if (callerApp != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700875 callingPid = callerApp.getPid();
876 callingUid = callerApp.mInfo.uid;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800877 } else {
Louis Chang54fbb052019-10-16 17:10:17 +0800878 Slog.w(TAG, "Unable to find app for caller " + caller + " (pid=" + callingPid
879 + ") when starting: " + intent.toString());
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800880 err = ActivityManager.START_PERMISSION_DENIED;
881 }
882 }
883
Bryce Lee93e7f792017-10-25 15:54:55 -0700884 final int userId = aInfo != null && aInfo.applicationInfo != null
885 ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800886 if (err == ActivityManager.START_SUCCESS) {
887 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
Andrii Kulian03c403d2016-11-11 11:14:12 -0800888 + "} from uid " + callingUid);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800889 }
890
891 ActivityRecord sourceRecord = null;
892 ActivityRecord resultRecord = null;
893 if (resultTo != null) {
Louis Chang149d5c82019-12-30 09:47:39 +0800894 sourceRecord = mRootWindowContainer.isInAnyStack(resultTo);
Louis Chang54fbb052019-10-16 17:10:17 +0800895 if (DEBUG_RESULTS) {
896 Slog.v(TAG_RESULTS, "Will send result to " + resultTo + " " + sourceRecord);
897 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800898 if (sourceRecord != null) {
899 if (requestCode >= 0 && !sourceRecord.finishing) {
900 resultRecord = sourceRecord;
901 }
902 }
903 }
904
905 final int launchFlags = intent.getFlags();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800906 if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
Louis Chang54fbb052019-10-16 17:10:17 +0800907 // Transfer the result target from the source activity to the new one being started,
908 // including any failures.
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800909 if (requestCode >= 0) {
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100910 SafeActivityOptions.abort(options);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800911 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
912 }
913 resultRecord = sourceRecord.resultTo;
914 if (resultRecord != null && !resultRecord.isInStackLocked()) {
915 resultRecord = null;
916 }
917 resultWho = sourceRecord.resultWho;
918 requestCode = sourceRecord.requestCode;
919 sourceRecord.resultTo = null;
920 if (resultRecord != null) {
921 resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
922 }
923 if (sourceRecord.launchedFromUid == callingUid) {
Louis Chang54fbb052019-10-16 17:10:17 +0800924 // The new activity is being launched from the same uid as the previous activity
925 // in the flow, and asking to forward its result back to the previous. In this
926 // case the activity is serving as a trampoline between the two, so we also want
927 // to update its launchedFromPackage to be the same as the previous activity.
928 // Note that this is safe, since we know these two packages come from the same
929 // uid; the caller could just as well have supplied that same package name itself
930 // . This specifially deals with the case of an intent picker/chooser being
931 // launched in the app flow to redirect to an activity picked by the user, where
932 // we want the final activity to consider it to have been launched by the
933 // previous app activity.
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800934 callingPackage = sourceRecord.launchedFromPackage;
Philip P. Moltmannee295092020-02-10 08:46:26 -0800935 callingFeatureId = sourceRecord.launchedFromFeatureId;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800936 }
937 }
938
939 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
940 // We couldn't find a class that can handle the given Intent.
941 // That's the end of that!
942 err = ActivityManager.START_INTENT_NOT_RESOLVED;
943 }
944
945 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
946 // We couldn't find the specific class specified in the Intent.
947 // Also the end of the line.
948 err = ActivityManager.START_CLASS_NOT_FOUND;
949 }
950
951 if (err == ActivityManager.START_SUCCESS && sourceRecord != null
Louis Changcdec0802019-11-11 11:45:07 +0800952 && sourceRecord.getTask().voiceSession != null) {
Louis Chang54fbb052019-10-16 17:10:17 +0800953 // If this activity is being launched as part of a voice session, we need to ensure
954 // that it is safe to do so. If the upcoming activity will also be part of the voice
955 // session, we can only launch it if it has explicitly said it supports the VOICE
956 // category, or it is a part of the calling app.
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800957 if ((launchFlags & FLAG_ACTIVITY_NEW_TASK) == 0
958 && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
959 try {
960 intent.addCategory(Intent.CATEGORY_VOICE);
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700961 if (!mService.getPackageManager().activitySupportsIntent(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800962 intent.getComponent(), intent, resolvedType)) {
Louis Chang54fbb052019-10-16 17:10:17 +0800963 Slog.w(TAG, "Activity being started in current voice task does not support "
964 + "voice: " + intent);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800965 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
966 }
967 } catch (RemoteException e) {
968 Slog.w(TAG, "Failure checking voice capabilities", e);
969 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
970 }
971 }
972 }
973
974 if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
975 // If the caller is starting a new voice session, just make sure the target
976 // is actually allowing it to run this way.
977 try {
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700978 if (!mService.getPackageManager().activitySupportsIntent(intent.getComponent(),
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800979 intent, resolvedType)) {
980 Slog.w(TAG,
Louis Chang54fbb052019-10-16 17:10:17 +0800981 "Activity being started in new voice task does not support: " + intent);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800982 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
983 }
984 } catch (RemoteException e) {
985 Slog.w(TAG, "Failure checking voice capabilities", e);
986 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
987 }
988 }
989
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800990 final ActivityStack resultStack = resultRecord == null
Wale Ogunwale1ebcd8e2020-01-21 11:27:03 -0800991 ? null : resultRecord.getRootTask();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800992
Wale Ogunwale01d66562015-12-29 08:19:19 -0800993 if (err != START_SUCCESS) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800994 if (resultRecord != null) {
Andrii Kulian79d67982019-08-19 11:56:16 -0700995 resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED,
Jeff Sharkey307ea7a2020-04-13 10:24:49 -0600996 null /* data */, null /* dataGrants */);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800997 }
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100998 SafeActivityOptions.abort(options);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800999 return err;
1000 }
1001
1002 boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
Philip P. Moltmannee295092020-02-10 08:46:26 -08001003 requestCode, callingPid, callingUid, callingPackage, callingFeatureId,
1004 request.ignoreTargetSecurity, inTask != null, callerApp, resultRecord, resultStack);
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001005 abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001006 callingPid, resolvedType, aInfo.applicationInfo);
Hai Zhangf4da9be2019-05-01 13:46:06 +08001007 abort |= !mService.getPermissionPolicyInternal().checkStartActivity(intent, callingUid,
1008 callingPackage);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001009
Ricky Waib147fa12019-04-25 16:08:30 +01001010 boolean restrictedBgActivity = false;
Michal Karpinski8596ded2018-11-14 14:43:48 +00001011 if (!abort) {
Michal Karpinski4fd5b842019-01-28 15:13:32 +00001012 try {
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001013 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER,
Michal Karpinski4fd5b842019-01-28 15:13:32 +00001014 "shouldAbortBackgroundActivityStart");
Ricky Waib147fa12019-04-25 16:08:30 +01001015 restrictedBgActivity = shouldAbortBackgroundActivityStart(callingUid,
Ricky Waiaca8a772019-04-04 16:01:06 +01001016 callingPid, callingPackage, realCallingUid, realCallingPid, callerApp,
Louis Chang54fbb052019-10-16 17:10:17 +08001017 request.originatingPendingIntent, request.allowBackgroundActivityStart,
Galia Peychevaed401cc2020-03-19 20:28:09 +01001018 intent);
Michal Karpinski4fd5b842019-01-28 15:13:32 +00001019 } finally {
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001020 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
Michal Karpinski4fd5b842019-01-28 15:13:32 +00001021 }
Michal Karpinski8596ded2018-11-14 14:43:48 +00001022 }
1023
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001024 // Merge the two options bundles, while realCallerOptions takes precedence.
1025 ActivityOptions checkedOptions = options != null
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001026 ? options.getOptions(intent, aInfo, callerApp, mSupervisor) : null;
Louis Chang54fbb052019-10-16 17:10:17 +08001027 if (request.allowPendingRemoteAnimationRegistryLookup) {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001028 checkedOptions = mService.getActivityStartController()
Jorim Jaggi6fa41c32018-04-23 18:35:00 +02001029 .getPendingRemoteAnimationRegistry()
1030 .overrideOptionsIfNeeded(callingPackage, checkedOptions);
1031 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001032 if (mService.mController != null) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001033 try {
Louis Chang54fbb052019-10-16 17:10:17 +08001034 // The Intent we give to the watcher has the extra data stripped off, since it
1035 // can contain private information.
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001036 Intent watchIntent = intent.cloneFilter();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001037 abort |= !mService.mController.activityStarting(watchIntent,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001038 aInfo.applicationInfo.packageName);
1039 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001040 mService.mController = null;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001041 }
1042 }
1043
Philip P. Moltmannee295092020-02-10 08:46:26 -08001044 mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage,
1045 callingFeatureId);
Benjamin Franz563707b2017-06-29 15:06:13 +01001046 if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001047 callingUid, checkedOptions)) {
Benjamin Franz563707b2017-06-29 15:06:13 +01001048 // activity start was intercepted, e.g. because the target user is currently in quiet
1049 // mode (turn off work) or the target application is suspended
1050 intent = mInterceptor.mIntent;
1051 rInfo = mInterceptor.mRInfo;
1052 aInfo = mInterceptor.mAInfo;
1053 resolvedType = mInterceptor.mResolvedType;
1054 inTask = mInterceptor.mInTask;
1055 callingPid = mInterceptor.mCallingPid;
1056 callingUid = mInterceptor.mCallingUid;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001057 checkedOptions = mInterceptor.mActivityOptions;
Jeff Sharkey307ea7a2020-04-13 10:24:49 -06001058
1059 // The interception target shouldn't get any permission grants
1060 // intended for the original destination
1061 intentGrants = null;
Benjamin Franz563707b2017-06-29 15:06:13 +01001062 }
1063
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001064 if (abort) {
1065 if (resultRecord != null) {
Andrii Kulian79d67982019-08-19 11:56:16 -07001066 resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED,
Jeff Sharkey307ea7a2020-04-13 10:24:49 -06001067 null /* data */, null /* dataGrants */);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001068 }
Louis Chang54fbb052019-10-16 17:10:17 +08001069 // We pretend to the caller that it was really started, but they will just get a
1070 // cancel result.
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001071 ActivityOptions.abort(checkedOptions);
Bryce Leef9d49542017-06-26 16:27:32 -07001072 return START_ABORTED;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001073 }
1074
1075 // If permissions need a review before any of the app components can run, we
1076 // launch the review activity and pass a pending intent to start the activity
1077 // we are to launching now after the review is completed.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07001078 if (aInfo != null) {
Wale Ogunwale906f9c62018-07-23 11:23:44 -07001079 if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001080 aInfo.packageName, userId)) {
Louis Chang54fbb052019-10-16 17:10:17 +08001081 final IIntentSender target = mService.getIntentSenderLocked(
Philip P. Moltmannee295092020-02-10 08:46:26 -08001082 ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage, callingFeatureId,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001083 callingUid, userId, null, null, 0, new Intent[]{intent},
1084 new String[]{resolvedType}, PendingIntent.FLAG_CANCEL_CURRENT
1085 | PendingIntent.FLAG_ONE_SHOT, null);
1086
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001087 Intent newIntent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
Philip P. Moltmannc3e66d02019-01-31 15:56:18 -08001088
1089 int flags = intent.getFlags();
1090 flags |= Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
1091
1092 /*
1093 * Prevent reuse of review activity: Each app needs their own review activity. By
1094 * default activities launched with NEW_TASK or NEW_DOCUMENT try to reuse activities
1095 * with the same launch parameters (extras are ignored). Hence to avoid possible
1096 * reuse force a new activity via the MULTIPLE_TASK flag.
1097 *
1098 * Activities that are not launched with NEW_TASK or NEW_DOCUMENT are not re-used,
1099 * hence no need to add the flag in this case.
1100 */
1101 if ((flags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_NEW_DOCUMENT)) != 0) {
1102 flags |= Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
1103 }
1104 newIntent.setFlags(flags);
1105
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001106 newIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, aInfo.packageName);
1107 newIntent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target));
1108 if (resultRecord != null) {
1109 newIntent.putExtra(Intent.EXTRA_RESULT_NEEDED, true);
1110 }
1111 intent = newIntent;
1112
Jeff Sharkey307ea7a2020-04-13 10:24:49 -06001113 // The permissions review target shouldn't get any permission
1114 // grants intended for the original destination
1115 intentGrants = null;
1116
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001117 resolvedType = null;
1118 callingUid = realCallingUid;
1119 callingPid = realCallingPid;
1120
Svet Ganovcbcbf662018-05-10 17:25:29 -07001121 rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0,
Patrick Baumann31426b22018-05-21 13:46:40 -07001122 computeResolveFilterUid(
Louis Chang54fbb052019-10-16 17:10:17 +08001123 callingUid, realCallingUid, request.filterCallingUid));
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001124 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
1125 null /*profilerInfo*/);
1126
1127 if (DEBUG_PERMISSIONS_REVIEW) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001128 final ActivityStack focusedStack =
Louis Chang149d5c82019-12-30 09:47:39 +08001129 mRootWindowContainer.getTopDisplayFocusedStack();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001130 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true,
1131 true, false) + "} from uid " + callingUid + " on display "
Wale Ogunwale0b3d2922019-12-30 08:55:07 -08001132 + (focusedStack == null ? DEFAULT_DISPLAY
1133 : focusedStack.getDisplayId()));
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001134 }
1135 }
1136 }
1137
1138 // If we have an ephemeral app, abort the process of launching the resolved intent.
1139 // Instead, launch the ephemeral installer. Once the installer is finished, it
1140 // starts either the intent we resolved here [on install error] or the ephemeral
1141 // app [on install success].
Patrick Baumanna89a1722018-02-07 15:26:52 -08001142 if (rInfo != null && rInfo.auxiliaryInfo != null) {
Louis Chang54fbb052019-10-16 17:10:17 +08001143 intent = createLaunchIntent(rInfo.auxiliaryInfo, request.ephemeralIntent,
Philip P. Moltmannee295092020-02-10 08:46:26 -08001144 callingPackage, callingFeatureId, verificationBundle, resolvedType, userId);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001145 resolvedType = null;
1146 callingUid = realCallingUid;
1147 callingPid = realCallingPid;
1148
Jeff Sharkey307ea7a2020-04-13 10:24:49 -06001149 // The ephemeral installer shouldn't get any permission grants
1150 // intended for the original destination
1151 intentGrants = null;
1152
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001153 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
1154 }
1155
Louis Chang54fbb052019-10-16 17:10:17 +08001156 final ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
Philip P. Moltmannee295092020-02-10 08:46:26 -08001157 callingPackage, callingFeatureId, intent, resolvedType, aInfo,
1158 mService.getGlobalConfiguration(), resultRecord, resultWho, requestCode,
1159 request.componentSpecified, voiceSession != null, mSupervisor, checkedOptions,
1160 sourceRecord);
Louis Chang54fbb052019-10-16 17:10:17 +08001161 mLastStartActivityRecord = r;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001162
1163 if (r.appTimeTracker == null && sourceRecord != null) {
1164 // If the caller didn't specify an explicit time tracker, we want to continue
1165 // tracking under any it has.
1166 r.appTimeTracker = sourceRecord.appTimeTracker;
1167 }
1168
Louis Chang149d5c82019-12-30 09:47:39 +08001169 final ActivityStack stack = mRootWindowContainer.getTopDisplayFocusedStack();
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001170
1171 // If we are starting an activity that is not from the same uid as the currently resumed
1172 // one, check whether app switches are allowed.
Jeff Chang51de04a2020-04-29 16:14:31 +08001173 if (voiceSession == null && stack != null && (stack.getResumedActivity() == null
Bryce Leec4ab62a2018-03-05 14:19:26 -08001174 || stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001175 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001176 realCallingPid, realCallingUid, "Activity start")) {
Alan Stokes07389b62019-05-20 15:22:54 +01001177 if (!(restrictedBgActivity && handleBackgroundActivityAbort(r))) {
Ricky Waib147fa12019-04-25 16:08:30 +01001178 mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
Jeff Sharkey307ea7a2020-04-13 10:24:49 -06001179 sourceRecord, startFlags, stack, callerApp, intentGrants));
Ricky Waib147fa12019-04-25 16:08:30 +01001180 }
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001181 ActivityOptions.abort(checkedOptions);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001182 return ActivityManager.START_SWITCHES_CANCELED;
1183 }
1184 }
1185
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001186 mService.onStartActivitySetDidAppSwitch();
Bryce Leed3624e12017-11-30 08:51:45 -08001187 mController.doPendingActivityLaunches(false);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001188
Louis Chang54fbb052019-10-16 17:10:17 +08001189 mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
1190 request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
Jeff Sharkey307ea7a2020-04-13 10:24:49 -06001191 restrictedBgActivity, intentGrants);
Louis Chang54fbb052019-10-16 17:10:17 +08001192
1193 if (request.outActivity != null) {
1194 request.outActivity[0] = mLastStartActivityRecord;
1195 }
1196
Riddle Hsu7f8643a2019-12-05 14:37:30 +08001197 return mLastStartActivityResult;
Louis Chang54fbb052019-10-16 17:10:17 +08001198 }
1199
1200 /**
1201 * Return true if background activity is really aborted.
1202 *
1203 * TODO(b/131748165): Refactor the logic so we don't need to call this method everywhere.
1204 */
1205 private boolean handleBackgroundActivityAbort(ActivityRecord r) {
1206 // TODO(b/131747138): Remove toast and refactor related code in R release.
1207 final boolean abort = !mService.isBackgroundActivityStartsEnabled();
1208 if (!abort) {
1209 return false;
1210 }
1211 final ActivityRecord resultRecord = r.resultTo;
1212 final String resultWho = r.resultWho;
1213 int requestCode = r.requestCode;
1214 if (resultRecord != null) {
1215 resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED,
Jeff Sharkey307ea7a2020-04-13 10:24:49 -06001216 null /* data */, null /* dataGrants */);
Louis Chang54fbb052019-10-16 17:10:17 +08001217 }
1218 // We pretend to the caller that it was really started to make it backward compatible, but
1219 // they will just get a cancel result.
1220 ActivityOptions.abort(r.pendingOptions);
1221 return true;
1222 }
1223
1224 static int getExternalResult(int result) {
1225 // Aborted results are treated as successes externally, but we must track them internally.
1226 return result != START_ABORTED ? result : START_SUCCESS;
1227 }
1228
1229 /**
1230 * Called when execution is complete. Sets state indicating completion and proceeds with
1231 * recycling if appropriate.
1232 */
1233 private void onExecutionComplete() {
1234 mController.onExecutionComplete(this);
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -08001235 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001236
Ricky Waiaca8a772019-04-04 16:01:06 +01001237 boolean shouldAbortBackgroundActivityStart(int callingUid, int callingPid,
Michal Karpinski9cbb20b2019-02-05 17:31:50 +00001238 final String callingPackage, int realCallingUid, int realCallingPid,
1239 WindowProcessController callerApp, PendingIntentRecord originatingPendingIntent,
Galia Peychevaed401cc2020-03-19 20:28:09 +01001240 boolean allowBackgroundActivityStart, Intent intent) {
Michal Karpinski8596ded2018-11-14 14:43:48 +00001241 // don't abort for the most important UIDs
Alan Stokes2f4a4ed2019-05-08 16:56:45 +01001242 final int callingAppId = UserHandle.getAppId(callingUid);
1243 if (callingUid == Process.ROOT_UID || callingAppId == Process.SYSTEM_UID
1244 || callingAppId == Process.NFC_UID) {
Bernardo Rufino1e088f12020-04-28 16:40:25 +01001245 if (DEBUG_ACTIVITY_STARTS) {
1246 Slog.d(TAG, "Activity start allowed for important callingUid (" + callingUid + ")");
1247 }
Michal Karpinski8596ded2018-11-14 14:43:48 +00001248 return false;
1249 }
Galia Peycheva6861e912019-08-21 10:20:23 +02001250
Alan Stokeseea8d3e2019-04-10 17:37:25 +01001251 // don't abort if the callingUid has a visible window or is a persistent system process
Riddle Hsua0536432019-02-16 00:38:59 +08001252 final int callingUidProcState = mService.getUidState(callingUid);
Michal Karpinski4fd5b842019-01-28 15:13:32 +00001253 final boolean callingUidHasAnyVisibleWindow =
1254 mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(callingUid);
1255 final boolean isCallingUidForeground = callingUidHasAnyVisibleWindow
Amith Yamasanif235d0b2019-03-20 22:49:43 -07001256 || callingUidProcState == ActivityManager.PROCESS_STATE_TOP
1257 || callingUidProcState == ActivityManager.PROCESS_STATE_BOUND_TOP;
Alan Stokes2f4a4ed2019-05-08 16:56:45 +01001258 final boolean isCallingUidPersistentSystemProcess =
1259 callingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
Alan Stokeseea8d3e2019-04-10 17:37:25 +01001260 if (callingUidHasAnyVisibleWindow || isCallingUidPersistentSystemProcess) {
Bernardo Rufino1e088f12020-04-28 16:40:25 +01001261 if (DEBUG_ACTIVITY_STARTS) {
1262 Slog.d(TAG, "Activity start allowed: callingUidHasAnyVisibleWindow = " + callingUid
1263 + ", isCallingUidPersistentSystemProcess = "
1264 + isCallingUidPersistentSystemProcess);
1265 }
Michal Karpinski8596ded2018-11-14 14:43:48 +00001266 return false;
1267 }
Michal Karpinskiac116df2018-12-10 17:51:42 +00001268 // take realCallingUid into consideration
Michal Karpinski4fd5b842019-01-28 15:13:32 +00001269 final int realCallingUidProcState = (callingUid == realCallingUid)
1270 ? callingUidProcState
Riddle Hsua0536432019-02-16 00:38:59 +08001271 : mService.getUidState(realCallingUid);
Michal Karpinski4fd5b842019-01-28 15:13:32 +00001272 final boolean realCallingUidHasAnyVisibleWindow = (callingUid == realCallingUid)
1273 ? callingUidHasAnyVisibleWindow
1274 : mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(realCallingUid);
1275 final boolean isRealCallingUidForeground = (callingUid == realCallingUid)
1276 ? isCallingUidForeground
1277 : realCallingUidHasAnyVisibleWindow
1278 || realCallingUidProcState == ActivityManager.PROCESS_STATE_TOP;
Alan Stokes2f4a4ed2019-05-08 16:56:45 +01001279 final int realCallingAppId = UserHandle.getAppId(realCallingUid);
Michal Karpinski4fd5b842019-01-28 15:13:32 +00001280 final boolean isRealCallingUidPersistentSystemProcess = (callingUid == realCallingUid)
1281 ? isCallingUidPersistentSystemProcess
Alan Stokes2f4a4ed2019-05-08 16:56:45 +01001282 : (realCallingAppId == Process.SYSTEM_UID)
Michal Karpinski4fd5b842019-01-28 15:13:32 +00001283 || realCallingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
Michal Karpinskiac116df2018-12-10 17:51:42 +00001284 if (realCallingUid != callingUid) {
Alan Stokes6ac9efd2019-05-09 12:50:37 +00001285 // don't abort if the realCallingUid has a visible window
1286 if (realCallingUidHasAnyVisibleWindow) {
Bernardo Rufino1e088f12020-04-28 16:40:25 +01001287 if (DEBUG_ACTIVITY_STARTS) {
1288 Slog.d(TAG, "Activity start allowed: realCallingUid (" + realCallingUid
1289 + ") has visible (non-toast) window");
1290 }
Michal Karpinskiac116df2018-12-10 17:51:42 +00001291 return false;
1292 }
1293 // if the realCallingUid is a persistent system process, abort if the IntentSender
1294 // wasn't whitelisted to start an activity
Michal Karpinskid0162852019-01-15 16:05:25 +00001295 if (isRealCallingUidPersistentSystemProcess && allowBackgroundActivityStart) {
Bernardo Rufino1e088f12020-04-28 16:40:25 +01001296 if (DEBUG_ACTIVITY_STARTS) {
1297 Slog.d(TAG, "Activity start allowed: realCallingUid (" + realCallingUid
1298 + ") is persistent system process AND intent sender whitelisted "
1299 + "(allowBackgroundActivityStart = true)");
1300 }
Michal Karpinskiac116df2018-12-10 17:51:42 +00001301 return false;
1302 }
Michal Karpinskida34cd42019-04-02 19:46:52 +01001303 // don't abort if the realCallingUid is an associated companion app
1304 if (mService.isAssociatedCompanionApp(UserHandle.getUserId(realCallingUid),
1305 realCallingUid)) {
Bernardo Rufino1e088f12020-04-28 16:40:25 +01001306 if (DEBUG_ACTIVITY_STARTS) {
1307 Slog.d(TAG, "Activity start allowed: realCallingUid (" + realCallingUid
1308 + ") is companion app");
1309 }
Michal Karpinskida34cd42019-04-02 19:46:52 +01001310 return false;
1311 }
Michal Karpinskiac116df2018-12-10 17:51:42 +00001312 }
Michal Karpinski7b97a022018-12-14 15:17:29 +00001313 // don't abort if the callingUid has START_ACTIVITIES_FROM_BACKGROUND permission
1314 if (mService.checkPermission(START_ACTIVITIES_FROM_BACKGROUND, callingPid, callingUid)
1315 == PERMISSION_GRANTED) {
Bernardo Rufino1e088f12020-04-28 16:40:25 +01001316 if (DEBUG_ACTIVITY_STARTS) {
1317 Slog.d(TAG,
1318 "Background activity start allowed: START_ACTIVITIES_FROM_BACKGROUND "
1319 + "permission granted for uid "
1320 + callingUid);
1321 }
Michal Karpinski7b97a022018-12-14 15:17:29 +00001322 return false;
1323 }
Michal Karpinski82bb5902018-11-28 15:52:52 +00001324 // don't abort if the caller has the same uid as the recents component
1325 if (mSupervisor.mRecentTasks.isCallerRecents(callingUid)) {
Bernardo Rufino1e088f12020-04-28 16:40:25 +01001326 if (DEBUG_ACTIVITY_STARTS) {
1327 Slog.d(TAG, "Background activity start allowed: callingUid (" + callingUid
1328 + ") is recents");
1329 }
Michal Karpinski82bb5902018-11-28 15:52:52 +00001330 return false;
1331 }
Ricky Wai96f5c352019-04-10 18:40:17 +01001332 // don't abort if the callingUid is the device owner
1333 if (mService.isDeviceOwner(callingUid)) {
Bernardo Rufino1e088f12020-04-28 16:40:25 +01001334 if (DEBUG_ACTIVITY_STARTS) {
1335 Slog.d(TAG, "Background activity start allowed: callingUid (" + callingUid
1336 + ") is device owner");
1337 }
Michal Karpinski302dcec2019-02-01 11:48:25 +00001338 return false;
1339 }
Ricky Wai96f5c352019-04-10 18:40:17 +01001340 // don't abort if the callingUid has companion device
Ricky Wai2452e2d2019-03-18 19:19:08 +00001341 final int callingUserId = UserHandle.getUserId(callingUid);
Michal Karpinskida34cd42019-04-02 19:46:52 +01001342 if (mService.isAssociatedCompanionApp(callingUserId, callingUid)) {
Bernardo Rufino1e088f12020-04-28 16:40:25 +01001343 if (DEBUG_ACTIVITY_STARTS) {
1344 Slog.d(TAG, "Background activity start allowed: callingUid (" + callingUid
1345 + ") is companion app");
1346 }
Ricky Wai2452e2d2019-03-18 19:19:08 +00001347 return false;
1348 }
Michal Karpinski2e0aad22019-04-12 16:22:55 +01001349 // If we don't have callerApp at this point, no caller was provided to startActivity().
1350 // That's the case for PendingIntent-based starts, since the creator's process might not be
1351 // up and alive. If that's the case, we retrieve the WindowProcessController for the send()
1352 // caller, so that we can make the decision based on its foreground/whitelisted state.
1353 int callerAppUid = callingUid;
1354 if (callerApp == null) {
1355 callerApp = mService.getProcessController(realCallingPid, realCallingUid);
1356 callerAppUid = realCallingUid;
1357 }
1358 // don't abort if the callerApp or other processes of that uid are whitelisted in any way
1359 if (callerApp != null) {
1360 // first check the original calling process
1361 if (callerApp.areBackgroundActivityStartsAllowed()) {
Bernardo Rufino1e088f12020-04-28 16:40:25 +01001362 if (DEBUG_ACTIVITY_STARTS) {
1363 Slog.d(TAG, "Background activity start allowed: callerApp process (pid = "
1364 + callerApp.getPid() + ", uid = " + callerAppUid + ") is whitelisted");
1365 }
Michal Karpinski2e0aad22019-04-12 16:22:55 +01001366 return false;
1367 }
1368 // only if that one wasn't whitelisted, check the other ones
1369 final ArraySet<WindowProcessController> uidProcesses =
1370 mService.mProcessMap.getProcesses(callerAppUid);
1371 if (uidProcesses != null) {
1372 for (int i = uidProcesses.size() - 1; i >= 0; i--) {
1373 final WindowProcessController proc = uidProcesses.valueAt(i);
1374 if (proc != callerApp && proc.areBackgroundActivityStartsAllowed()) {
Bernardo Rufino1e088f12020-04-28 16:40:25 +01001375 if (DEBUG_ACTIVITY_STARTS) {
1376 Slog.d(TAG,
1377 "Background activity start allowed: process " + proc.getPid()
1378 + " from uid " + callerAppUid + " is whitelisted");
1379 }
Michal Karpinski2e0aad22019-04-12 16:22:55 +01001380 return false;
1381 }
1382 }
1383 }
1384 }
Michal Karpinski15486842019-04-25 17:33:42 +01001385 // don't abort if the callingUid has SYSTEM_ALERT_WINDOW permission
1386 if (mService.hasSystemAlertWindowPermission(callingUid, callingPid, callingPackage)) {
1387 Slog.w(TAG, "Background activity start for " + callingPackage
1388 + " allowed because SYSTEM_ALERT_WINDOW permission is granted.");
1389 return false;
1390 }
Michal Karpinskic02364c2019-01-22 13:00:04 +00001391 // anything that has fallen through would currently be aborted
1392 Slog.w(TAG, "Background activity start [callingPackage: " + callingPackage
Michal Karpinskid0162852019-01-15 16:05:25 +00001393 + "; callingUid: " + callingUid
1394 + "; isCallingUidForeground: " + isCallingUidForeground
Bernardo Rufino1e088f12020-04-28 16:40:25 +01001395 + "; callingUidHasAnyVisibleWindow: " + callingUidHasAnyVisibleWindow
1396 + "; callingUidProcState: " + DebugUtils.valueToString(ActivityManager.class,
1397 "PROCESS_STATE_", callingUidProcState)
Michal Karpinskid0162852019-01-15 16:05:25 +00001398 + "; isCallingUidPersistentSystemProcess: " + isCallingUidPersistentSystemProcess
1399 + "; realCallingUid: " + realCallingUid
1400 + "; isRealCallingUidForeground: " + isRealCallingUidForeground
Bernardo Rufino1e088f12020-04-28 16:40:25 +01001401 + "; realCallingUidHasAnyVisibleWindow: " + realCallingUidHasAnyVisibleWindow
1402 + "; realCallingUidProcState: " + DebugUtils.valueToString(ActivityManager.class,
1403 "PROCESS_STATE_", realCallingUidProcState)
Michal Karpinskid0162852019-01-15 16:05:25 +00001404 + "; isRealCallingUidPersistentSystemProcess: "
Ricky Waiaca8a772019-04-04 16:01:06 +01001405 + isRealCallingUidPersistentSystemProcess
Michal Karpinskid0162852019-01-15 16:05:25 +00001406 + "; originatingPendingIntent: " + originatingPendingIntent
1407 + "; isBgStartWhitelisted: " + allowBackgroundActivityStart
1408 + "; intent: " + intent
Michal Karpinski9cbb20b2019-02-05 17:31:50 +00001409 + "; callerApp: " + callerApp
Michal Karpinskid0162852019-01-15 16:05:25 +00001410 + "]");
Michal Karpinski4fd5b842019-01-28 15:13:32 +00001411 // log aborted activity start to TRON
1412 if (mService.isActivityStartsLoggingEnabled()) {
1413 mSupervisor.getActivityMetricsLogger().logAbortedBgActivityStart(intent, callerApp,
1414 callingUid, callingPackage, callingUidProcState, callingUidHasAnyVisibleWindow,
1415 realCallingUid, realCallingUidProcState, realCallingUidHasAnyVisibleWindow,
Michal Karpinski201bc0c2018-07-20 15:32:00 +01001416 (originatingPendingIntent != null));
Michal Karpinski201bc0c2018-07-20 15:32:00 +01001417 }
Michal Karpinski4fd5b842019-01-28 15:13:32 +00001418 return true;
Michal Karpinski201bc0c2018-07-20 15:32:00 +01001419 }
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001420
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001421 /**
1422 * Creates a launch intent for the given auxiliary resolution data.
1423 */
Patrick Baumann577d4022018-01-31 16:55:10 +00001424 private @NonNull Intent createLaunchIntent(@Nullable AuxiliaryResolveInfo auxiliaryResponse,
Philip P. Moltmannee295092020-02-10 08:46:26 -08001425 Intent originalIntent, String callingPackage, @Nullable String callingFeatureId,
1426 Bundle verificationBundle, String resolvedType, int userId) {
Patrick Baumann577d4022018-01-31 16:55:10 +00001427 if (auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo) {
Todd Kennedye9910222017-02-21 16:00:11 -08001428 // request phase two resolution
Winson81fef842019-08-28 12:19:08 -07001429 PackageManagerInternal packageManager = mService.getPackageManagerInternalLocked();
1430 boolean isRequesterInstantApp = packageManager.isInstantApp(callingPackage, userId);
1431 packageManager.requestInstantAppResolutionPhaseTwo(
Chad Brubaker06068612017-04-06 09:43:47 -07001432 auxiliaryResponse, originalIntent, resolvedType, callingPackage,
Philip P. Moltmannee295092020-02-10 08:46:26 -08001433 callingFeatureId, isRequesterInstantApp, verificationBundle, userId);
Todd Kennedye9910222017-02-21 16:00:11 -08001434 }
Todd Kennedydfc27c62017-05-17 15:32:10 -07001435 return InstantAppResolver.buildEphemeralInstallerIntent(
Patrick Baumann577d4022018-01-31 16:55:10 +00001436 originalIntent,
1437 InstantAppResolver.sanitizeIntent(originalIntent),
1438 auxiliaryResponse == null ? null : auxiliaryResponse.failureIntent,
1439 callingPackage,
Philip P. Moltmannee295092020-02-10 08:46:26 -08001440 callingFeatureId,
Patrick Baumann577d4022018-01-31 16:55:10 +00001441 verificationBundle,
1442 resolvedType,
1443 userId,
1444 auxiliaryResponse == null ? null : auxiliaryResponse.installFailureActivity,
1445 auxiliaryResponse == null ? null : auxiliaryResponse.token,
1446 auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo,
1447 auxiliaryResponse == null ? null : auxiliaryResponse.filters);
Todd Kennedye9910222017-02-21 16:00:11 -08001448 }
1449
Riddle Hsu16567132018-08-16 21:37:47 +08001450 void postStartActivityProcessing(ActivityRecord r, int result,
1451 ActivityStack startedActivityStack) {
Winson Chunge219ae12019-07-18 13:43:23 -07001452 if (!ActivityManager.isStartResultSuccessful(result)) {
1453 if (mFrozeTaskList) {
1454 // If we specifically froze the task list as part of starting an activity, then
1455 // reset the frozen list state if it failed to start. This is normally otherwise
1456 // called when the freeze-timeout has elapsed.
1457 mSupervisor.mRecentTasks.resetFreezeTaskListReorderingOnTimeout();
1458 }
1459 }
Bryce Lee7f936862017-05-09 15:33:18 -07001460 if (ActivityManager.isStartResultFatalError(result)) {
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -08001461 return;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001462 }
Filip Gruszczynski303210b2016-01-08 16:28:08 -08001463
Chong Zhang5022da32016-06-21 16:31:37 -07001464 // We're waiting for an activity launch to finish, but that activity simply
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001465 // brought another activity to front. We must also handle the case where the task is already
1466 // 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 +08001467 // considered focused as the trampoline will be finished). Let them know about this, so
1468 // it waits for the new activity to become visible instead, {@link #waitResultIfNeeded}.
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001469 mSupervisor.reportWaitingActivityLaunchedIfNeeded(r, result);
Chong Zhang5022da32016-06-21 16:31:37 -07001470
Winson Chunge789ff62020-02-24 14:40:23 -08001471 final Task targetTask = r.getTask() != null
1472 ? r.getTask()
1473 : mTargetTask;
1474 if (startedActivityStack == null || targetTask == null) {
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001475 return;
1476 }
1477
Wale Ogunwaleac36e4d2017-11-29 13:30:26 -08001478 final int clearTaskFlags = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK;
1479 boolean clearedTask = (mLaunchFlags & clearTaskFlags) == clearTaskFlags
1480 && mReuseTask != null;
Wale Ogunwale7d7973a2018-04-05 10:25:59 -07001481 if (result == START_TASK_TO_FRONT || result == START_DELIVERED_TO_TOP || clearedTask) {
1482 // The activity was already running so it wasn't started, but either brought to the
1483 // front or the new intent was delivered to it since it was already in front. Notify
1484 // anyone interested in this piece of information.
Andrii Kulian86d676c2020-03-27 19:34:54 -07001485 final ActivityStack homeStack = targetTask.getDisplayArea().getRootHomeTask();
Winson Chunge789ff62020-02-24 14:40:23 -08001486 final boolean homeTaskVisible = homeStack != null && homeStack.shouldBeVisible(null);
1487 mService.getTaskChangeNotificationController().notifyActivityRestartAttempt(
Evan Rosky8d1c24e2020-04-23 09:21:16 -07001488 targetTask.getTaskInfo(), homeTaskVisible, clearedTask,
1489 targetTask.getTopNonFinishingActivity().isVisible());
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -08001490 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001491 }
1492
Svet Ganovcbcbf662018-05-10 17:25:29 -07001493 /**
1494 * Compute the logical UID based on which the package manager would filter
1495 * app components i.e. based on which the instant app policy would be applied
1496 * because it is the logical calling UID.
1497 *
1498 * @param customCallingUid The UID on whose behalf to make the call.
1499 * @param actualCallingUid The UID actually making the call.
Patrick Baumann31426b22018-05-21 13:46:40 -07001500 * @param filterCallingUid The UID to be used to filter for instant apps.
Svet Ganovcbcbf662018-05-10 17:25:29 -07001501 * @return The logical UID making the call.
1502 */
Patrick Baumann31426b22018-05-21 13:46:40 -07001503 static int computeResolveFilterUid(int customCallingUid, int actualCallingUid,
1504 int filterCallingUid) {
1505 return filterCallingUid != UserHandle.USER_NULL
1506 ? filterCallingUid
1507 : (customCallingUid >= 0 ? customCallingUid : actualCallingUid);
Svet Ganovcbcbf662018-05-10 17:25:29 -07001508 }
1509
Louis Chang54fbb052019-10-16 17:10:17 +08001510 /**
1511 * Start an activity while most of preliminary checks has been done and caller has been
1512 * confirmed that holds necessary permissions to do so.
1513 * Here also ensures that the starting activity is removed if the start wasn't successful.
1514 */
1515 private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
Bryce Leedaa91e42017-12-06 14:13:01 -08001516 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
Louis Changcdec0802019-11-11 11:45:07 +08001517 int startFlags, boolean doResume, ActivityOptions options, Task inTask,
Jeff Sharkey307ea7a2020-04-13 10:24:49 -06001518 boolean restrictedBgActivity, NeededUriGrants intentGrants) {
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001519 int result = START_CANCELED;
Riddle Hsu16567132018-08-16 21:37:47 +08001520 final ActivityStack startedActivityStack;
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001521 try {
Riddle Hsua0022cd2019-09-09 21:12:41 +08001522 mService.deferWindowLayout();
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001523 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
1524 result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
Jeff Sharkey307ea7a2020-04-13 10:24:49 -06001525 startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001526 } finally {
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001527 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
1528 startedActivityStack = handleStartResult(r, result);
Riddle Hsua0022cd2019-09-09 21:12:41 +08001529 mService.continueWindowLayout();
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001530 }
1531
Riddle Hsu16567132018-08-16 21:37:47 +08001532 postStartActivityProcessing(r, result, startedActivityStack);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001533
1534 return result;
1535 }
1536
Ricky Waib147fa12019-04-25 16:08:30 +01001537 /**
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001538 * If the start result is success, ensure that the configuration of the started activity matches
1539 * the current display. Otherwise clean up unassociated containers to avoid leakage.
1540 *
1541 * @return the stack where the successful started activity resides.
1542 */
1543 private @Nullable ActivityStack handleStartResult(@NonNull ActivityRecord started, int result) {
Wale Ogunwale1ebcd8e2020-01-21 11:27:03 -08001544 final ActivityStack currentStack = started.getRootTask();
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001545 ActivityStack startedActivityStack = currentStack != null ? currentStack : mTargetStack;
1546
1547 if (ActivityManager.isStartResultSuccessful(result)) {
1548 if (startedActivityStack != null) {
1549 // If there is no state change (e.g. a resumed activity is reparented to top of
1550 // another display) to trigger a visibility/configuration checking, we have to
1551 // update the configuration for changing to different display.
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09001552 final ActivityRecord currentTop = startedActivityStack.topRunningActivity();
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001553 if (currentTop != null && currentTop.shouldUpdateConfigForDisplayChanged()) {
Louis Chang149d5c82019-12-30 09:47:39 +08001554 mRootWindowContainer.ensureVisibilityAndConfig(
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001555 currentTop, currentTop.getDisplayId(),
1556 true /* markFrozenIfConfigChanged */, false /* deferResume */);
1557 }
1558 }
1559 return startedActivityStack;
1560 }
1561
1562 // If we are not able to proceed, disassociate the activity from the task. Leaving an
1563 // activity in an incomplete state can lead to issues, such as performing operations
1564 // without a window container.
Wale Ogunwale1ebcd8e2020-01-21 11:27:03 -08001565 final ActivityStack stack = mStartActivity.getRootTask();
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001566 if (stack != null) {
1567 mStartActivity.finishIfPossible("startActivity", true /* oomAdj */);
1568 }
1569
1570 // Stack should also be detached from display and be removed if it's empty.
1571 if (startedActivityStack != null && startedActivityStack.isAttached()
Wale Ogunwalea38654f2019-11-17 20:37:15 -08001572 && !startedActivityStack.hasActivity()
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001573 && !startedActivityStack.isActivityTypeHome()) {
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -07001574 startedActivityStack.removeIfPossible();
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001575 startedActivityStack = null;
1576 }
1577 return startedActivityStack;
1578 }
1579
1580 /**
Louis Chang54fbb052019-10-16 17:10:17 +08001581 * Start an activity and determine if the activity should be adding to the top of an existing
1582 * task or delivered new intent to an existing activity. Also manipulating the activity task
1583 * onto requested or valid stack/display.
Ricky Waib147fa12019-04-25 16:08:30 +01001584 *
Louis Chang54fbb052019-10-16 17:10:17 +08001585 * Note: This method should only be called from {@link #startActivityUnchecked}.
Ricky Waib147fa12019-04-25 16:08:30 +01001586 */
Diego Vela5d84efb2020-05-14 15:54:21 +00001587
1588 // TODO(b/152429287): Make it easier to exercise code paths through startActivityInner
1589 @VisibleForTesting
1590 int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
Wale Ogunwale01d66562015-12-29 08:19:19 -08001591 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
Louis Changcdec0802019-11-11 11:45:07 +08001592 int startFlags, boolean doResume, ActivityOptions options, Task inTask,
Jeff Sharkey307ea7a2020-04-13 10:24:49 -06001593 boolean restrictedBgActivity, NeededUriGrants intentGrants) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001594 setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
Ricky Waib147fa12019-04-25 16:08:30 +01001595 voiceInteractor, restrictedBgActivity);
1596
Louis Chang6fb1e842018-12-03 16:07:50 +08001597 computeLaunchingTaskFlags();
1598
1599 computeSourceStack();
1600
1601 mIntent.setFlags(mLaunchFlags);
1602
Louis Changcdec0802019-11-11 11:45:07 +08001603 final Task reusedTask = getReusableTask();
Louis Chang6fb1e842018-12-03 16:07:50 +08001604
Winson Chunge219ae12019-07-18 13:43:23 -07001605 // If requested, freeze the task list
1606 if (mOptions != null && mOptions.freezeRecentTasksReordering()
1607 && mSupervisor.mRecentTasks.isCallerRecents(r.launchedFromUid)
1608 && !mSupervisor.mRecentTasks.isFreezeTaskListReorderingSet()) {
1609 mFrozeTaskList = true;
1610 mSupervisor.mRecentTasks.setFreezeTaskListReordering();
1611 }
1612
Louis Changbde91e92019-08-16 17:19:47 +08001613 // Compute if there is an existing task that should be used for.
Louis Changcdec0802019-11-11 11:45:07 +08001614 final Task targetTask = reusedTask != null ? reusedTask : computeTargetTask();
Louis Changbde91e92019-08-16 17:19:47 +08001615 final boolean newTask = targetTask == null;
Winson Chunge789ff62020-02-24 14:40:23 -08001616 mTargetTask = targetTask;
Louis Changbde91e92019-08-16 17:19:47 +08001617
Louis Chang38430df2020-01-02 17:14:59 +08001618 computeLaunchParams(r, sourceRecord, targetTask);
1619
Louis Changbde91e92019-08-16 17:19:47 +08001620 // Check if starting activity on given task or on a new task is allowed.
1621 int startResult = isAllowedToStart(r, newTask, targetTask);
1622 if (startResult != START_SUCCESS) {
1623 return startResult;
Louis Changbd48dca2018-08-29 17:44:34 +08001624 }
1625
Wale Ogunwale21e06482019-11-18 05:14:15 -08001626 final ActivityRecord targetTaskTop = newTask
1627 ? null : targetTask.getTopNonFinishingActivity();
Louis Changbde91e92019-08-16 17:19:47 +08001628 if (targetTaskTop != null) {
1629 // Recycle the target task for this launch.
Jeff Sharkey307ea7a2020-04-13 10:24:49 -06001630 startResult = recycleTask(targetTask, targetTaskTop, reusedTask, intentGrants);
Louis Changbde91e92019-08-16 17:19:47 +08001631 if (startResult != START_SUCCESS) {
1632 return startResult;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001633 }
Louis Changf7dd7f22019-11-05 11:59:56 +08001634 } else {
1635 mAddingToTask = true;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001636 }
1637
1638 // If the activity being launched is the same as the one currently at the top, then
1639 // we need to check if it should only be launched once.
Louis Chang149d5c82019-12-30 09:47:39 +08001640 final ActivityStack topStack = mRootWindowContainer.getTopDisplayFocusedStack();
Darryl L Johnson1e3885c2020-02-27 17:38:13 -08001641 if (topStack != null) {
Jeff Sharkey307ea7a2020-04-13 10:24:49 -06001642 startResult = deliverToCurrentTopIfNeeded(topStack, intentGrants);
Darryl L Johnson1e3885c2020-02-27 17:38:13 -08001643 if (startResult != START_SUCCESS) {
1644 return startResult;
1645 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001646 }
1647
Louis Changbde91e92019-08-16 17:19:47 +08001648 if (mTargetStack == null) {
Louis Chang38430df2020-01-02 17:14:59 +08001649 mTargetStack = getLaunchStack(mStartActivity, mLaunchFlags, targetTask, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001650 }
Louis Changbde91e92019-08-16 17:19:47 +08001651 if (newTask) {
Louis Changcdec0802019-11-11 11:45:07 +08001652 final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
1653 ? mSourceRecord.getTask() : null;
Louis Changbde91e92019-08-16 17:19:47 +08001654 setNewTask(taskToAffiliate);
Louis Changa3e6b892019-09-16 10:39:00 +08001655 if (mService.getLockTaskController().isLockTaskModeViolation(
Louis Changcdec0802019-11-11 11:45:07 +08001656 mStartActivity.getTask())) {
Louis Changa3e6b892019-09-16 10:39:00 +08001657 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
1658 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
1659 }
Louis Changbde91e92019-08-16 17:19:47 +08001660 } else if (mAddingToTask) {
1661 addOrReparentStartingActivity(targetTask, "adding to task");
1662 }
1663
1664 if (!mAvoidMoveToFront && mDoResume) {
Louis Changa009c762020-02-26 11:21:31 +08001665 mTargetStack.getStack().moveToFront("reuseOrNewTask", targetTask);
Winson Chung8a168902020-03-12 22:39:22 -07001666 if (mOptions != null) {
Winson Chung8a168902020-03-12 22:39:22 -07001667 if (mOptions.getTaskAlwaysOnTop()) {
1668 mTargetStack.setAlwaysOnTop(true);
1669 }
1670 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07001671 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001672
Jeff Sharkey307ea7a2020-04-13 10:24:49 -06001673 mService.mUgmInternal.grantUriPermissionUncheckedFromIntent(intentGrants,
Jeff Sharkey938089f2020-04-12 16:00:04 -06001674 mStartActivity.getUriPermissionsLocked());
Patrick Baumann58bcea62020-02-25 17:30:36 -08001675 if (mStartActivity.resultTo != null && mStartActivity.resultTo.info != null) {
1676 // we need to resolve resultTo to a uid as grantImplicitAccess deals explicitly in UIDs
1677 final PackageManagerInternal pmInternal =
1678 mService.getPackageManagerInternalLocked();
1679 final int resultToUid = pmInternal.getPackageUidInternal(
1680 mStartActivity.resultTo.info.packageName, 0, mStartActivity.mUserId);
1681 pmInternal.grantImplicitAccess(mStartActivity.mUserId, mIntent,
1682 UserHandle.getAppId(mStartActivity.info.applicationInfo.uid) /*recipient*/,
1683 resultToUid /*visible*/, true /*direct*/);
1684 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001685 if (newTask) {
Jeff Changd136e772019-11-05 20:33:52 +08001686 EventLogTags.writeWmCreateTask(mStartActivity.mUserId,
Louis Changcdec0802019-11-11 11:45:07 +08001687 mStartActivity.getTask().mTaskId);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001688 }
Andrii Kulian79d67982019-08-19 11:56:16 -07001689 mStartActivity.logStartActivity(
Jeff Changd136e772019-11-05 20:33:52 +08001690 EventLogTags.WM_CREATE_ACTIVITY, mStartActivity.getTask());
1691
Wale Ogunwale01d66562015-12-29 08:19:19 -08001692 mTargetStack.mLastPausedActivity = null;
Wei Wang98f03f92016-05-18 11:32:52 -07001693
Louis Chang149d5c82019-12-30 09:47:39 +08001694 mRootWindowContainer.sendPowerHintForLaunchStartIfNeeded(
Wale Ogunwaled32da472018-11-16 07:19:28 -08001695 false /* forceSend */, mStartActivity);
Wei Wang98f03f92016-05-18 11:32:52 -07001696
Wale Ogunwale21e06482019-11-18 05:14:15 -08001697 mTargetStack.startActivityLocked(mStartActivity, topStack.getTopNonFinishingActivity(),
1698 newTask, mKeepCurTransition, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001699 if (mDoResume) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001700 final ActivityRecord topTaskActivity =
Louis Changcdec0802019-11-11 11:45:07 +08001701 mStartActivity.getTask().topRunningActivityLocked();
Evan Rosky226de132020-01-03 18:00:29 -08001702 if (!mTargetStack.isTopActivityFocusable()
Wale Ogunwale0b3d2922019-12-30 08:55:07 -08001703 || (topTaskActivity != null && topTaskActivity.isTaskOverlay()
Wale Ogunwale68741142016-05-17 09:40:02 -07001704 && mStartActivity != topTaskActivity)) {
Filip Gruszczynski3d7fdc12016-01-31 17:33:29 -08001705 // If the activity is not focusable, we can't resume it, but still would like to
1706 // make sure it becomes visible as it starts (this will also trigger entry
1707 // animation). An example of this are PIP activities.
Wale Ogunwale3b232392016-05-13 15:37:13 -07001708 // Also, we don't want to resume activities in a task that currently has an overlay
1709 // as the starting activity just needs to be in the visible paused state until the
1710 // over is removed.
Diego Vela5d84efb2020-05-14 15:54:21 +00001711 // Passing {@code null} as the start parameter ensures all activities are made
1712 // visible.
1713 mTargetStack.ensureActivitiesVisible(null /* starting */,
1714 0 /* configChanges */, !PRESERVE_WINDOWS);
Wale Ogunwaleae846f42016-02-22 14:00:56 -08001715 // Go ahead and tell window manager to execute app transition for this activity
1716 // since the app transition will not be triggered through the resume channel.
Wale Ogunwale3a256e62018-12-06 14:41:18 -08001717 mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
Wale Ogunwale3b232392016-05-13 15:37:13 -07001718 } else {
Winson Chung32066032016-11-04 11:55:21 -07001719 // If the target stack was not previously focusable (previous top running activity
1720 // on that stack was not visible) then any prior calls to move the stack to the
1721 // will not update the focused stack. If starting the new activity now allows the
1722 // task stack to be focusable, then ensure that we now update the focused stack
1723 // accordingly.
Evan Rosky226de132020-01-03 18:00:29 -08001724 if (mTargetStack.isTopActivityFocusable()
Louis Chang149d5c82019-12-30 09:47:39 +08001725 && !mRootWindowContainer.isTopDisplayFocusedStack(mTargetStack)) {
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001726 mTargetStack.moveToFront("startActivityInner");
Winson Chung32066032016-11-04 11:55:21 -07001727 }
Louis Chang149d5c82019-12-30 09:47:39 +08001728 mRootWindowContainer.resumeFocusedStacksTopActivities(
Wale Ogunwaled32da472018-11-16 07:19:28 -08001729 mTargetStack, mStartActivity, mOptions);
Filip Gruszczynski3d7fdc12016-01-31 17:33:29 -08001730 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001731 }
Louis Chang149d5c82019-12-30 09:47:39 +08001732 mRootWindowContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001733
Winson Chungf45dd9f2019-10-11 15:07:47 -07001734 // Update the recent tasks list immediately when the activity starts
1735 mSupervisor.mRecentTasks.add(mStartActivity.getTask());
Louis Changcdec0802019-11-11 11:45:07 +08001736 mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(),
Andrii Kulian1cfcae82020-04-10 12:44:38 -07001737 mPreferredWindowingMode, mPreferredTaskDisplayArea, mTargetStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001738
1739 return START_SUCCESS;
1740 }
1741
Louis Changcdec0802019-11-11 11:45:07 +08001742 private Task computeTargetTask() {
Louis Changf7dd7f22019-11-05 11:59:56 +08001743 if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
Louis Changbde91e92019-08-16 17:19:47 +08001744 && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1745 // A new task should be created instead of using existing one.
1746 return null;
1747 } else if (mSourceRecord != null) {
Louis Changcdec0802019-11-11 11:45:07 +08001748 return mSourceRecord.getTask();
Louis Changbde91e92019-08-16 17:19:47 +08001749 } else if (mInTask != null) {
1750 return mInTask;
1751 } else {
Louis Chang38430df2020-01-02 17:14:59 +08001752 final ActivityStack stack = getLaunchStack(mStartActivity, mLaunchFlags,
1753 null /* task */, mOptions);
1754 final ActivityRecord top = stack.getTopNonFinishingActivity();
Louis Changbde91e92019-08-16 17:19:47 +08001755 if (top != null) {
Louis Changcdec0802019-11-11 11:45:07 +08001756 return top.getTask();
Louis Chang38430df2020-01-02 17:14:59 +08001757 } else {
1758 // Remove the stack if no activity in the stack.
1759 stack.removeIfPossible();
Louis Changbde91e92019-08-16 17:19:47 +08001760 }
1761 }
1762 return null;
1763 }
1764
Louis Chang38430df2020-01-02 17:14:59 +08001765 private void computeLaunchParams(ActivityRecord r, ActivityRecord sourceRecord,
1766 Task targetTask) {
1767 final ActivityStack sourceStack = mSourceStack != null ? mSourceStack
1768 : mRootWindowContainer.getTopDisplayFocusedStack();
1769 if (sourceStack != null && sourceStack.inSplitScreenWindowingMode()
1770 && (mOptions == null
1771 || mOptions.getLaunchWindowingMode() == WINDOWING_MODE_UNDEFINED)) {
1772 int windowingMode =
1773 targetTask != null ? targetTask.getWindowingMode() : WINDOWING_MODE_UNDEFINED;
1774 if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
1775 if (sourceStack.inSplitScreenPrimaryWindowingMode()) {
1776 windowingMode = WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
1777 } else if (sourceStack.inSplitScreenSecondaryWindowingMode()) {
1778 windowingMode = WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
1779 }
1780 }
1781
1782 if (mOptions == null) {
1783 mOptions = ActivityOptions.makeBasic();
1784 }
1785 mOptions.setLaunchWindowingMode(windowingMode);
1786 }
1787
1788 mSupervisor.getLaunchParamsController().calculate(targetTask, r.info.windowLayout, r,
1789 sourceRecord, mOptions, PHASE_BOUNDS, mLaunchParams);
Andrii Kulian1cfcae82020-04-10 12:44:38 -07001790 mPreferredTaskDisplayArea = mLaunchParams.hasPreferredTaskDisplayArea()
1791 ? mLaunchParams.mPreferredTaskDisplayArea
1792 : mRootWindowContainer.getDefaultTaskDisplayArea();
Winson Chung8a168902020-03-12 22:39:22 -07001793 mPreferredWindowingMode = mLaunchParams.mWindowingMode;
Louis Chang38430df2020-01-02 17:14:59 +08001794 }
1795
Louis Changcdec0802019-11-11 11:45:07 +08001796 private int isAllowedToStart(ActivityRecord r, boolean newTask, Task targetTask) {
Louis Changbde91e92019-08-16 17:19:47 +08001797 if (mStartActivity.packageName == null) {
1798 if (mStartActivity.resultTo != null) {
1799 mStartActivity.resultTo.sendResult(INVALID_UID, mStartActivity.resultWho,
Jeff Sharkey307ea7a2020-04-13 10:24:49 -06001800 mStartActivity.requestCode, RESULT_CANCELED,
1801 null /* data */, null /* dataGrants */);
Louis Changbde91e92019-08-16 17:19:47 +08001802 }
1803 ActivityOptions.abort(mOptions);
1804 return START_CLASS_NOT_FOUND;
1805 }
1806
1807 // Do not start home activity if it cannot be launched on preferred display. We are not
1808 // doing this in ActivityStackSupervisor#canPlaceEntityOnDisplay because it might
1809 // fallback to launch on other displays.
Andrii Kulian1cfcae82020-04-10 12:44:38 -07001810 if (r.isActivityTypeHome()) {
1811 if (!mRootWindowContainer.canStartHomeOnDisplayArea(r.info, mPreferredTaskDisplayArea,
1812 true /* allowInstrumenting */)) {
1813 Slog.w(TAG, "Cannot launch home on display area " + mPreferredTaskDisplayArea);
1814 return START_CANCELED;
1815 }
Louis Changbde91e92019-08-16 17:19:47 +08001816 }
1817
Wale Ogunwalea38654f2019-11-17 20:37:15 -08001818 if (mRestrictedBgActivity && (newTask || !targetTask.isUidPresent(mCallingUid))
Louis Changbde91e92019-08-16 17:19:47 +08001819 && handleBackgroundActivityAbort(mStartActivity)) {
1820 Slog.e(TAG, "Abort background activity starts from " + mCallingUid);
1821 return START_ABORTED;
1822 }
1823
1824 // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but still
1825 // needs to be a lock task mode violation since the task gets cleared out and the device
1826 // would otherwise leave the locked task.
1827 final boolean isNewClearTask =
1828 (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1829 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
Louis Changa3e6b892019-09-16 10:39:00 +08001830 if (!newTask && mService.getLockTaskController().isLockTaskModeViolation(targetTask,
1831 isNewClearTask)) {
Louis Changbde91e92019-08-16 17:19:47 +08001832 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
1833 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
1834 }
1835
1836 return START_SUCCESS;
1837 }
1838
1839 /**
1840 * Prepare the target task to be reused for this launch, which including:
1841 * - Position the target task on valid stack on preferred display.
1842 * - Comply to the specified activity launch flags
1843 * - Determine whether need to add a new activity on top or just brought the task to front.
1844 */
Louis Chang07b13002019-11-27 22:08:37 +08001845 @VisibleForTesting
Jeff Sharkey307ea7a2020-04-13 10:24:49 -06001846 int recycleTask(Task targetTask, ActivityRecord targetTaskTop, Task reusedTask,
1847 NeededUriGrants intentGrants) {
Louis Chang07b13002019-11-27 22:08:37 +08001848 // Should not recycle task which is from a different user, just adding the starting
1849 // activity to the task.
1850 if (targetTask.mUserId != mStartActivity.mUserId) {
1851 mTargetStack = targetTask.getStack();
1852 mAddingToTask = true;
1853 return START_SUCCESS;
1854 }
1855
Wale Ogunwaleda8b8272018-11-29 19:37:37 -08001856 boolean clearTaskForReuse = false;
Louis Changf7dd7f22019-11-05 11:59:56 +08001857 if (reusedTask != null) {
Louis Chang2787a9a2019-12-17 15:15:11 +08001858 if (mStartActivity.getTask() == null) {
Louis Changf7dd7f22019-11-05 11:59:56 +08001859 mStartActivity.setTaskForReuse(reusedTask);
Wale Ogunwaleda8b8272018-11-29 19:37:37 -08001860 clearTaskForReuse = true;
1861 }
1862
Louis Changbde91e92019-08-16 17:19:47 +08001863 if (targetTask.intent == null) {
1864 // This task was started because of movement of the activity based on
1865 // affinity...
1866 // Now that we are actually launching it, we can assign the base intent.
1867 targetTask.setIntent(mStartActivity);
1868 } else {
1869 final boolean taskOnHome =
1870 (mStartActivity.intent.getFlags() & FLAG_ACTIVITY_TASK_ON_HOME) != 0;
1871 if (taskOnHome) {
1872 targetTask.intent.addFlags(FLAG_ACTIVITY_TASK_ON_HOME);
1873 } else {
1874 targetTask.intent.removeFlags(FLAG_ACTIVITY_TASK_ON_HOME);
1875 }
1876 }
1877 }
1878
Louis Chang149d5c82019-12-30 09:47:39 +08001879 mRootWindowContainer.sendPowerHintForLaunchStartIfNeeded(false /* forceSend */,
Louis Changbde91e92019-08-16 17:19:47 +08001880 targetTaskTop);
1881
1882 setTargetStackIfNeeded(targetTaskTop);
1883
Louis Changbde91e92019-08-16 17:19:47 +08001884 // When there is a reused activity and the current result is a trampoline activity,
1885 // set the reused activity as the result.
Louis Chang54fbb052019-10-16 17:10:17 +08001886 if (mLastStartActivityRecord != null
1887 && (mLastStartActivityRecord.finishing || mLastStartActivityRecord.noDisplay)) {
1888 mLastStartActivityRecord = targetTaskTop;
Louis Changbde91e92019-08-16 17:19:47 +08001889 }
1890
1891 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1892 // We don't need to start a new activity, and the client said not to do anything
1893 // if that is the case, so this is it! And for paranoia, make sure we have
1894 // correctly resumed the top activity.
1895 if (!mMovedToFront && mDoResume) {
1896 if (DEBUG_TASKS) {
1897 Slog.d(TAG_TASKS, "Bring to front target: " + mTargetStack
1898 + " from " + targetTaskTop);
1899 }
1900 mTargetStack.moveToFront("intentActivityFound");
1901 }
1902 resumeTargetStackIfNeeded();
1903 return START_RETURN_INTENT_TO_CALLER;
1904 }
1905
Wale Ogunwale21e06482019-11-18 05:14:15 -08001906 complyActivityFlags(targetTask,
Jeff Sharkey307ea7a2020-04-13 10:24:49 -06001907 reusedTask != null ? reusedTask.getTopNonFinishingActivity() : null, intentGrants);
Louis Changbde91e92019-08-16 17:19:47 +08001908
Wale Ogunwaleda8b8272018-11-29 19:37:37 -08001909 if (clearTaskForReuse) {
1910 // Clear task for re-use so later code to methods
1911 // {@link #setTaskFromReuseOrCreateNewTask}, {@link #setTaskFromSourceRecord}, or
1912 // {@link #setTaskFromInTask} can parent it to the task.
1913 mStartActivity.setTaskForReuse(null);
1914 }
1915
Louis Changbde91e92019-08-16 17:19:47 +08001916 if (mAddingToTask) {
1917 return START_SUCCESS;
1918 }
1919
Louis Chang3ee5fc02019-09-23 11:32:10 +08001920 if (mMovedToFront) {
1921 // We moved the task to front, use starting window to hide initial drawn delay.
1922 targetTaskTop.showStartingWindow(null /* prev */, false /* newTask */,
1923 true /* taskSwitch */);
1924 } else if (mDoResume) {
1925 // Make sure the stack and its belonging display are moved to topmost.
Louis Changbde91e92019-08-16 17:19:47 +08001926 mTargetStack.moveToFront("intentActivityFound");
1927 }
1928 // We didn't do anything... but it was needed (a.k.a., client don't use that intent!)
1929 // And for paranoia, make sure we have correctly resumed the top activity.
1930 resumeTargetStackIfNeeded();
Louis Chang54fbb052019-10-16 17:10:17 +08001931 // The reusedActivity could be finishing, for example of starting an activity with
1932 // FLAG_ACTIVITY_CLEAR_TOP flag. In that case, return the top running activity in the
1933 // task instead.
1934 mLastStartActivityRecord =
Wale Ogunwale21e06482019-11-18 05:14:15 -08001935 targetTaskTop.finishing ? targetTask.getTopNonFinishingActivity() : targetTaskTop;
Louis Changbde91e92019-08-16 17:19:47 +08001936 return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP;
1937 }
1938
1939 /**
1940 * Check if the activity being launched is the same as the one currently at the top and it
1941 * should only be launched once.
1942 */
Jeff Sharkey307ea7a2020-04-13 10:24:49 -06001943 private int deliverToCurrentTopIfNeeded(ActivityStack topStack, NeededUriGrants intentGrants) {
Louis Changbde91e92019-08-16 17:19:47 +08001944 final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
Daniel Chapinde8fade2020-02-22 00:12:50 +00001945 final boolean dontStart = top != null && mStartActivity.resultTo == null
Louis Changbde91e92019-08-16 17:19:47 +08001946 && top.mActivityComponent.equals(mStartActivity.mActivityComponent)
1947 && top.mUserId == mStartActivity.mUserId
1948 && top.attachedToProcess()
1949 && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
Daniel Chapinde8fade2020-02-22 00:12:50 +00001950 || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK))
Andrii Kulian1cfcae82020-04-10 12:44:38 -07001951 // This allows home activity to automatically launch on secondary task display area
1952 // when it was added, if home was the top activity on default task display area,
1953 // instead of sending new intent to the home activity on default display area.
1954 && (!top.isActivityTypeHome() || top.getDisplayArea() == mPreferredTaskDisplayArea);
Louis Changbde91e92019-08-16 17:19:47 +08001955 if (!dontStart) {
1956 return START_SUCCESS;
1957 }
1958
1959 // For paranoia, make sure we have correctly resumed the top activity.
1960 topStack.mLastPausedActivity = null;
1961 if (mDoResume) {
Louis Chang149d5c82019-12-30 09:47:39 +08001962 mRootWindowContainer.resumeFocusedStacksTopActivities();
Louis Changbde91e92019-08-16 17:19:47 +08001963 }
1964 ActivityOptions.abort(mOptions);
1965 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1966 // We don't need to start a new activity, and the client said not to do anything if
1967 // that is the case, so this is it!
1968 return START_RETURN_INTENT_TO_CALLER;
1969 }
1970
Jeff Sharkey307ea7a2020-04-13 10:24:49 -06001971 deliverNewIntent(top, intentGrants);
Louis Changbde91e92019-08-16 17:19:47 +08001972
1973 // Don't use mStartActivity.task to show the toast. We're not starting a new activity but
1974 // reusing 'top'. Fields in mStartActivity may not be fully initialized.
Louis Changcdec0802019-11-11 11:45:07 +08001975 mSupervisor.handleNonResizableTaskIfNeeded(top.getTask(),
Andrii Kulian1cfcae82020-04-10 12:44:38 -07001976 mLaunchParams.mWindowingMode, mPreferredTaskDisplayArea, topStack);
Louis Changbde91e92019-08-16 17:19:47 +08001977
1978 return START_DELIVERED_TO_TOP;
1979 }
1980
1981 /**
1982 * Applying the launching flags to the task, which might clear few or all the activities in the
1983 * task.
1984 */
Jeff Sharkey307ea7a2020-04-13 10:24:49 -06001985 private void complyActivityFlags(Task targetTask, ActivityRecord reusedActivity,
1986 NeededUriGrants intentGrants) {
Wale Ogunwale21e06482019-11-18 05:14:15 -08001987 ActivityRecord targetTaskTop = targetTask.getTopNonFinishingActivity();
Louis Chang2dcb1272019-09-27 15:01:19 +08001988 final boolean resetTask =
1989 reusedActivity != null && (mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0;
1990 if (resetTask) {
Wale Ogunwaledfbeed72019-11-20 08:57:39 -08001991 targetTaskTop = mTargetStack.resetTaskIfNeeded(targetTaskTop, mStartActivity);
Louis Changbde91e92019-08-16 17:19:47 +08001992 }
1993
1994 if ((mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1995 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {
1996 // The caller has requested to completely replace any existing task with its new
1997 // activity. Well that should not be too hard...
Louis Changcdec0802019-11-11 11:45:07 +08001998 // Note: we must persist the {@link Task} first as intentActivity could be
Louis Changbde91e92019-08-16 17:19:47 +08001999 // removed from calling performClearTaskLocked (For example, if it is being brought out
2000 // of history or if it is finished immediately), thus disassociating the task. Also note
Louis Changcdec0802019-11-11 11:45:07 +08002001 // that mReuseTask is reset as a result of {@link Task#performClearTaskLocked}
Louis Changbde91e92019-08-16 17:19:47 +08002002 // launching another activity.
2003 // TODO(b/36119896): We shouldn't trigger activity launches in this path since we are
2004 // already launching one.
2005 targetTask.performClearTaskLocked();
2006 targetTask.setIntent(mStartActivity);
2007 mAddingToTask = true;
2008 } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
2009 || isDocumentLaunchesIntoExisting(mLaunchFlags)
2010 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
2011 // In this situation we want to remove all activities from the task up to the one
2012 // being started. In most cases this means we are resetting the task to its initial
2013 // state.
2014 final ActivityRecord top = targetTask.performClearTaskForReuseLocked(mStartActivity,
2015 mLaunchFlags);
2016
2017 // The above code can remove {@code reusedActivity} from the task, leading to the
Louis Changcdec0802019-11-11 11:45:07 +08002018 // {@code ActivityRecord} removing its reference to the {@code Task}. The task
Wale Ogunwalec17418e2019-10-13 23:00:40 +02002019 // reference is needed in the call below to {@link setTargetStackAndMoveToFrontIfNeeded}
Louis Changcdec0802019-11-11 11:45:07 +08002020 if (targetTaskTop.getTask() == null) {
Wale Ogunwale2322bed2019-10-10 17:24:19 +02002021 targetTask.addChild(targetTaskTop);
Louis Changbde91e92019-08-16 17:19:47 +08002022 }
2023
2024 if (top != null) {
2025 if (top.isRootOfTask()) {
2026 // Activity aliases may mean we use different intents for the top activity,
2027 // so make sure the task now has the identity of the new intent.
Louis Changcdec0802019-11-11 11:45:07 +08002028 top.getTask().setIntent(mStartActivity);
Louis Changbde91e92019-08-16 17:19:47 +08002029 }
Jeff Sharkey307ea7a2020-04-13 10:24:49 -06002030 deliverNewIntent(top, intentGrants);
Louis Changbde91e92019-08-16 17:19:47 +08002031 } else {
2032 // A special case: we need to start the activity because it is not currently
2033 // running, and the caller has asked to clear the current task to have this
2034 // activity at the top.
2035 mAddingToTask = true;
2036 if (targetTask.getStack() == null) {
2037 // Target stack got cleared when we all activities were removed above.
2038 // Go ahead and reset it.
Louis Chang38430df2020-01-02 17:14:59 +08002039 mTargetStack =
2040 getLaunchStack(mStartActivity, mLaunchFlags, null /* task */, mOptions);
Wale Ogunwale2322bed2019-10-10 17:24:19 +02002041 mTargetStack.addChild(targetTask, !mLaunchTaskBehind /* toTop */,
2042 (mStartActivity.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0);
Louis Changbde91e92019-08-16 17:19:47 +08002043 }
2044 }
2045 } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) == 0 && !mAddingToTask
2046 && (mLaunchFlags & FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
2047 // In this case, we are launching an activity in our own task that may
2048 // already be running somewhere in the history, and we want to shuffle it to
2049 // the front of the stack if so.
Wale Ogunwalea38654f2019-11-17 20:37:15 -08002050 final ActivityRecord act =
2051 targetTask.findActivityInHistory(mStartActivity.mActivityComponent);
Louis Changbde91e92019-08-16 17:19:47 +08002052 if (act != null) {
Louis Changcdec0802019-11-11 11:45:07 +08002053 final Task task = act.getTask();
Louis Changbde91e92019-08-16 17:19:47 +08002054 task.moveActivityToFrontLocked(act);
2055 act.updateOptionsLocked(mOptions);
Jeff Sharkey307ea7a2020-04-13 10:24:49 -06002056 deliverNewIntent(act, intentGrants);
Louis Changbde91e92019-08-16 17:19:47 +08002057 mTargetStack.mLastPausedActivity = null;
2058 } else {
2059 mAddingToTask = true;
2060 }
2061 } else if (mStartActivity.mActivityComponent.equals(targetTask.realActivity)) {
Louis Chang382419b2019-10-03 21:43:38 +08002062 if (targetTask == mInTask) {
2063 // In this case we are bringing up an existing activity from a recent task. We
2064 // don't need to add a new activity instance on top.
2065 } else if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
2066 || LAUNCH_SINGLE_TOP == mLaunchMode)
2067 && targetTaskTop.mActivityComponent.equals(mStartActivity.mActivityComponent)
2068 && mStartActivity.resultTo == null) {
2069 // In this case the top activity on the task is the same as the one being launched,
2070 // so we take that as a request to bring the task to the foreground. If the top
2071 // activity in the task is the root activity, deliver this new intent to it if it
2072 // desires.
Louis Changbde91e92019-08-16 17:19:47 +08002073 if (targetTaskTop.isRootOfTask()) {
Louis Changcdec0802019-11-11 11:45:07 +08002074 targetTaskTop.getTask().setIntent(mStartActivity);
Louis Changbde91e92019-08-16 17:19:47 +08002075 }
Jeff Sharkey307ea7a2020-04-13 10:24:49 -06002076 deliverNewIntent(targetTaskTop, intentGrants);
Louis Changbde91e92019-08-16 17:19:47 +08002077 } else if (!targetTask.isSameIntentFilter(mStartActivity)) {
2078 // In this case we are launching the root activity of the task, but with a
2079 // different intent. We should start a new instance on top.
2080 mAddingToTask = true;
2081 } else if (reusedActivity == null) {
2082 mAddingToTask = true;
2083 }
Louis Chang2dcb1272019-09-27 15:01:19 +08002084 } else if (!resetTask) {
Louis Changbde91e92019-08-16 17:19:47 +08002085 // In this case an activity is being launched in to an existing task, without
2086 // resetting that task. This is typically the situation of launching an activity
2087 // from a notification or shortcut. We want to place the new activity on top of the
2088 // current task.
2089 mAddingToTask = true;
2090 } else if (!targetTask.rootWasReset) {
2091 // In this case we are launching into an existing task that has not yet been started
2092 // from its front door. The current task has been brought to the front. Ideally,
2093 // we'd probably like to place this new task at the bottom of its stack, but that's
2094 // a little hard to do with the current organization of the code so for now we'll
2095 // just drop it.
2096 targetTask.setIntent(mStartActivity);
2097 }
2098 }
2099
Bryce Leedaa91e42017-12-06 14:13:01 -08002100 /**
2101 * Resets the {@link ActivityStarter} state.
2102 * @param clearRequest whether the request should be reset to default values.
2103 */
2104 void reset(boolean clearRequest) {
2105 mStartActivity = null;
2106 mIntent = null;
2107 mCallingUid = -1;
2108 mOptions = null;
Ricky Waib147fa12019-04-25 16:08:30 +01002109 mRestrictedBgActivity = false;
Bryce Leedaa91e42017-12-06 14:13:01 -08002110
2111 mLaunchTaskBehind = false;
2112 mLaunchFlags = 0;
2113 mLaunchMode = INVALID_LAUNCH_MODE;
2114
Bryce Leeec55eb02017-12-05 20:51:27 -08002115 mLaunchParams.reset();
Bryce Leedaa91e42017-12-06 14:13:01 -08002116
2117 mNotTop = null;
2118 mDoResume = false;
2119 mStartFlags = 0;
2120 mSourceRecord = null;
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002121 mPreferredTaskDisplayArea = null;
Winson Chung8a168902020-03-12 22:39:22 -07002122 mPreferredWindowingMode = WINDOWING_MODE_UNDEFINED;
Bryce Leedaa91e42017-12-06 14:13:01 -08002123
2124 mInTask = null;
2125 mAddingToTask = false;
2126 mReuseTask = null;
2127
2128 mNewTaskInfo = null;
2129 mNewTaskIntent = null;
2130 mSourceStack = null;
2131
2132 mTargetStack = null;
Winson Chunge789ff62020-02-24 14:40:23 -08002133 mTargetTask = null;
Bryce Leedaa91e42017-12-06 14:13:01 -08002134 mMovedToFront = false;
2135 mNoAnimation = false;
2136 mKeepCurTransition = false;
2137 mAvoidMoveToFront = false;
Winson Chunge219ae12019-07-18 13:43:23 -07002138 mFrozeTaskList = false;
Bryce Leedaa91e42017-12-06 14:13:01 -08002139
2140 mVoiceSession = null;
2141 mVoiceInteractor = null;
2142
2143 mIntentDelivered = false;
2144
2145 if (clearRequest) {
2146 mRequest.reset();
2147 }
2148 }
2149
Louis Changcdec0802019-11-11 11:45:07 +08002150 private void setInitialState(ActivityRecord r, ActivityOptions options, Task inTask,
Wale Ogunwale01d66562015-12-29 08:19:19 -08002151 boolean doResume, int startFlags, ActivityRecord sourceRecord,
Ricky Waib147fa12019-04-25 16:08:30 +01002152 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
2153 boolean restrictedBgActivity) {
Bryce Leedaa91e42017-12-06 14:13:01 -08002154 reset(false /* clearRequest */);
2155
Wale Ogunwale01d66562015-12-29 08:19:19 -08002156 mStartActivity = r;
2157 mIntent = r.intent;
2158 mOptions = options;
2159 mCallingUid = r.launchedFromUid;
2160 mSourceRecord = sourceRecord;
2161 mVoiceSession = voiceSession;
2162 mVoiceInteractor = voiceInteractor;
Ricky Waib147fa12019-04-25 16:08:30 +01002163 mRestrictedBgActivity = restrictedBgActivity;
Wale Ogunwale01d66562015-12-29 08:19:19 -08002164
Bryce Leeec55eb02017-12-05 20:51:27 -08002165 mLaunchParams.reset();
Bryce Leedacefc42017-10-10 12:56:02 -07002166
Louis Chang6fb1e842018-12-03 16:07:50 +08002167 // Preferred display id is the only state we need for now and it could be updated again
2168 // after we located a reusable task (which might be resided in another display).
Garfield Tan706dbcb2018-10-15 11:33:02 -07002169 mSupervisor.getLaunchParamsController().calculate(inTask, r.info.windowLayout, r,
Louis Chang6fb1e842018-12-03 16:07:50 +08002170 sourceRecord, options, PHASE_DISPLAY, mLaunchParams);
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002171 mPreferredTaskDisplayArea = mLaunchParams.hasPreferredTaskDisplayArea()
2172 ? mLaunchParams.mPreferredTaskDisplayArea
2173 : mRootWindowContainer.getDefaultTaskDisplayArea();
Winson Chung8a168902020-03-12 22:39:22 -07002174 mPreferredWindowingMode = mLaunchParams.mWindowingMode;
Garfield Tanb5cc09f2018-09-28 10:06:52 -07002175
Bryce Lee7daee392017-10-12 13:46:18 -07002176 mLaunchMode = r.launchMode;
2177
Wale Ogunwale01d66562015-12-29 08:19:19 -08002178 mLaunchFlags = adjustLaunchFlagsToDocumentMode(
Bryce Lee7daee392017-10-12 13:46:18 -07002179 r, LAUNCH_SINGLE_INSTANCE == mLaunchMode,
2180 LAUNCH_SINGLE_TASK == mLaunchMode, mIntent.getFlags());
Wale Ogunwale01d66562015-12-29 08:19:19 -08002181 mLaunchTaskBehind = r.mLaunchTaskBehind
Bryce Lee7daee392017-10-12 13:46:18 -07002182 && !isLaunchModeOneOf(LAUNCH_SINGLE_TASK, LAUNCH_SINGLE_INSTANCE)
Wale Ogunwale01d66562015-12-29 08:19:19 -08002183 && (mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0;
2184
Daniel Chapinde8fade2020-02-22 00:12:50 +00002185 sendNewTaskResultRequestIfNeeded();
2186
Wale Ogunwale01d66562015-12-29 08:19:19 -08002187 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
2188 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2189 }
2190
2191 // If we are actually going to launch in to a new task, there are some cases where
2192 // we further want to do multiple task.
2193 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
2194 if (mLaunchTaskBehind
2195 || r.info.documentLaunchMode == DOCUMENT_LAUNCH_ALWAYS) {
2196 mLaunchFlags |= FLAG_ACTIVITY_MULTIPLE_TASK;
2197 }
2198 }
2199
2200 // We'll invoke onUserLeaving before onPause only if the launching
2201 // activity did not explicitly state that this is an automated launch.
2202 mSupervisor.mUserLeaving = (mLaunchFlags & FLAG_ACTIVITY_NO_USER_ACTION) == 0;
2203 if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
2204 "startActivity() => mUserLeaving=" + mSupervisor.mUserLeaving);
2205
2206 // If the caller has asked not to resume at this point, we make note
2207 // of this in the record so that we can skip it when trying to find
2208 // the top running activity.
2209 mDoResume = doResume;
Louis Chang37317152019-05-09 09:53:58 +08002210 if (!doResume || !r.okToShowLocked() || mLaunchTaskBehind) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002211 r.delayedResume = true;
2212 mDoResume = false;
2213 }
2214
Winson Chunge2d72172018-01-25 17:46:20 +00002215 if (mOptions != null) {
Winson Chung8a168902020-03-12 22:39:22 -07002216 if (mOptions.getLaunchTaskId() != INVALID_TASK_ID && mOptions.getTaskOverlay()) {
Wale Ogunwale0b3d2922019-12-30 08:55:07 -08002217 r.setTaskOverlay(true);
Winson Chunge2d72172018-01-25 17:46:20 +00002218 if (!mOptions.canTaskOverlayResume()) {
Louis Chang149d5c82019-12-30 09:47:39 +08002219 final Task task = mRootWindowContainer.anyTaskForId(
Winson Chunge2d72172018-01-25 17:46:20 +00002220 mOptions.getLaunchTaskId());
Wale Ogunwale21e06482019-11-18 05:14:15 -08002221 final ActivityRecord top = task != null
2222 ? task.getTopNonFinishingActivity() : null;
Bryce Lee7ace3952018-02-16 14:34:32 -08002223 if (top != null && !top.isState(RESUMED)) {
Jorim Jaggic875ae72016-04-26 22:41:06 -07002224
Winson Chunge2d72172018-01-25 17:46:20 +00002225 // The caller specifies that we'd like to be avoided to be moved to the
2226 // front, so be it!
2227 mDoResume = false;
2228 mAvoidMoveToFront = true;
2229 }
Winson Chungcbcadc92017-01-12 15:54:12 -08002230 }
Winson Chunge2d72172018-01-25 17:46:20 +00002231 } else if (mOptions.getAvoidMoveToFront()) {
Winson Chungba40d3a2018-05-16 09:40:16 -07002232 mDoResume = false;
Winson Chunge2d72172018-01-25 17:46:20 +00002233 mAvoidMoveToFront = true;
Jorim Jaggic875ae72016-04-26 22:41:06 -07002234 }
2235 }
2236
Louis Chang2f4e9b462019-03-05 16:43:15 +08002237 mNotTop = (mLaunchFlags & FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? sourceRecord : null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08002238
2239 mInTask = inTask;
2240 // In some flows in to this function, we retrieve the task record and hold on to it
2241 // without a lock before calling back in to here... so the task at this point may
2242 // not actually be in recents. Check for that, and if it isn't in recents just
2243 // consider it invalid.
2244 if (inTask != null && !inTask.inRecents) {
2245 Slog.w(TAG, "Starting activity in task not in recents: " + inTask);
2246 mInTask = null;
2247 }
2248
2249 mStartFlags = startFlags;
2250 // If the onlyIfNeeded flag is set, then we can do this if the activity being launched
2251 // is the same as the one making the call... or, as a special case, if we do not know
2252 // the caller then we count the current top activity as the caller.
2253 if ((startFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
2254 ActivityRecord checkedCaller = sourceRecord;
2255 if (checkedCaller == null) {
Darryl L Johnson1e3885c2020-02-27 17:38:13 -08002256 ActivityStack topFocusedStack = mRootWindowContainer.getTopDisplayFocusedStack();
2257 if (topFocusedStack != null) {
2258 checkedCaller = topFocusedStack.topRunningNonDelayedActivityLocked(mNotTop);
2259 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002260 }
Darryl L Johnson1e3885c2020-02-27 17:38:13 -08002261 if (checkedCaller == null
2262 || !checkedCaller.mActivityComponent.equals(r.mActivityComponent)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002263 // Caller is not the same as launcher, so always needed.
2264 mStartFlags &= ~START_FLAG_ONLY_IF_NEEDED;
2265 }
2266 }
2267
2268 mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0;
Ricky Waib147fa12019-04-25 16:08:30 +01002269
Alan Stokes07389b62019-05-20 15:22:54 +01002270 if (mRestrictedBgActivity && !mService.isBackgroundActivityStartsEnabled()) {
Ricky Waib147fa12019-04-25 16:08:30 +01002271 mAvoidMoveToFront = true;
2272 mDoResume = false;
2273 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002274 }
2275
2276 private void sendNewTaskResultRequestIfNeeded() {
Andrii Kulian79d67982019-08-19 11:56:16 -07002277 if (mStartActivity.resultTo != null && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002278 // For whatever reason this activity is being launched into a new task...
2279 // yet the caller has requested a result back. Well, that is pretty messed up,
2280 // so instead immediately send back a cancel and let the new task continue launched
2281 // as normal without a dependency on its originator.
2282 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
Andrii Kulian79d67982019-08-19 11:56:16 -07002283 mStartActivity.resultTo.sendResult(INVALID_UID, mStartActivity.resultWho,
Jeff Sharkey307ea7a2020-04-13 10:24:49 -06002284 mStartActivity.requestCode, RESULT_CANCELED,
2285 null /* data */, null /* dataGrants */);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002286 mStartActivity.resultTo = null;
2287 }
2288 }
2289
2290 private void computeLaunchingTaskFlags() {
2291 // If the caller is not coming from another activity, but has given us an explicit task into
2292 // which they would like us to launch the new activity, then let's see about doing that.
Andrii Kulian02b7a832016-10-06 23:11:56 -07002293 if (mSourceRecord == null && mInTask != null && mInTask.getStack() != null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002294 final Intent baseIntent = mInTask.getBaseIntent();
2295 final ActivityRecord root = mInTask.getRootActivity();
2296 if (baseIntent == null) {
2297 ActivityOptions.abort(mOptions);
2298 throw new IllegalArgumentException("Launching into task without base intent: "
2299 + mInTask);
2300 }
2301
2302 // If this task is empty, then we are adding the first activity -- it
2303 // determines the root, and must be launching as a NEW_TASK.
Bryce Lee7daee392017-10-12 13:46:18 -07002304 if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002305 if (!baseIntent.getComponent().equals(mStartActivity.intent.getComponent())) {
2306 ActivityOptions.abort(mOptions);
2307 throw new IllegalArgumentException("Trying to launch singleInstance/Task "
2308 + mStartActivity + " into different task " + mInTask);
2309 }
2310 if (root != null) {
2311 ActivityOptions.abort(mOptions);
2312 throw new IllegalArgumentException("Caller with mInTask " + mInTask
2313 + " has root " + root + " but target is singleInstance/Task");
2314 }
2315 }
2316
2317 // If task is empty, then adopt the interesting intent launch flags in to the
2318 // activity being started.
2319 if (root == null) {
2320 final int flagsOfInterest = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK
2321 | FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS;
2322 mLaunchFlags = (mLaunchFlags & ~flagsOfInterest)
2323 | (baseIntent.getFlags() & flagsOfInterest);
2324 mIntent.setFlags(mLaunchFlags);
2325 mInTask.setIntent(mStartActivity);
2326 mAddingToTask = true;
2327
2328 // If the task is not empty and the caller is asking to start it as the root of
2329 // a new task, then we don't actually want to start this on the task. We will
2330 // bring the task to the front, and possibly give it a new intent.
2331 } else if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
2332 mAddingToTask = false;
2333
2334 } else {
2335 mAddingToTask = true;
2336 }
2337
2338 mReuseTask = mInTask;
2339 } else {
2340 mInTask = null;
2341 // Launch ResolverActivity in the source task, so that it stays in the task bounds
2342 // when in freeform workspace.
2343 // Also put noDisplay activities in the source task. These by itself can be placed
2344 // in any task/stack, however it could launch other activities like ResolverActivity,
2345 // and we want those to stay in the original task.
Louis Chang6a9be162019-07-15 10:41:32 +08002346 if ((mStartActivity.isResolverOrDelegateActivity() || mStartActivity.noDisplay)
2347 && mSourceRecord != null && mSourceRecord.inFreeformWindowingMode()) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002348 mAddingToTask = true;
2349 }
2350 }
2351
2352 if (mInTask == null) {
2353 if (mSourceRecord == null) {
2354 // This activity is not being started from another... in this
2355 // case we -always- start a new task.
2356 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) {
2357 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
2358 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
2359 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2360 }
2361 } else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) {
2362 // The original activity who is starting us is running as a single
2363 // instance... this new activity it is starting must go on its
2364 // own task.
2365 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
Bryce Lee7daee392017-10-12 13:46:18 -07002366 } else if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002367 // The activity being started is a single instance... it always
2368 // gets launched into its own task.
2369 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2370 }
2371 }
2372 }
2373
2374 private void computeSourceStack() {
2375 if (mSourceRecord == null) {
2376 mSourceStack = null;
2377 return;
2378 }
2379 if (!mSourceRecord.finishing) {
Wale Ogunwale1ebcd8e2020-01-21 11:27:03 -08002380 mSourceStack = mSourceRecord.getRootTask();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002381 return;
2382 }
2383
2384 // If the source is finishing, we can't further count it as our source. This is because the
2385 // task it is associated with may now be empty and on its way out, so we don't want to
2386 // blindly throw it in to that task. Instead we will take the NEW_TASK flow and try to find
2387 // a task for it. But save the task information so it can be used when creating the new task.
2388 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0) {
2389 Slog.w(TAG, "startActivity called from finishing " + mSourceRecord
2390 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
2391 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2392 mNewTaskInfo = mSourceRecord.info;
Bryce Leed9ed45d2017-05-22 15:57:24 -07002393
2394 // It is not guaranteed that the source record will have a task associated with it. For,
2395 // example, if this method is being called for processing a pending activity launch, it
2396 // is possible that the activity has been removed from the task after the launch was
2397 // enqueued.
Louis Changcdec0802019-11-11 11:45:07 +08002398 final Task sourceTask = mSourceRecord.getTask();
Bryce Leed9ed45d2017-05-22 15:57:24 -07002399 mNewTaskIntent = sourceTask != null ? sourceTask.intent : null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08002400 }
2401 mSourceRecord = null;
2402 mSourceStack = null;
2403 }
2404
2405 /**
2406 * Decide whether the new activity should be inserted into an existing task. Returns null
2407 * if not or an ActivityRecord with the task into which the new activity should be added.
2408 */
Louis Changcdec0802019-11-11 11:45:07 +08002409 private Task getReusableTask() {
Winson Chung8a168902020-03-12 22:39:22 -07002410 // If a target task is specified, try to reuse that one
2411 if (mOptions != null && mOptions.getLaunchTaskId() != INVALID_TASK_ID) {
2412 Task launchTask = mRootWindowContainer.anyTaskForId(mOptions.getLaunchTaskId());
2413 if (launchTask != null) {
2414 return launchTask;
2415 }
2416 return null;
2417 }
2418
Wale Ogunwale01d66562015-12-29 08:19:19 -08002419 // We may want to try to place the new activity in to an existing task. We always
2420 // do this if the target activity is singleTask or singleInstance; we will also do
2421 // this if NEW_TASK has been requested, and there is not an additional qualifier telling
2422 // us to still place it in a new task: multi task, always doc mode, or being asked to
2423 // launch this as a new task behind the current one.
2424 boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 &&
2425 (mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
Bryce Lee7daee392017-10-12 13:46:18 -07002426 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002427 // If bring to front is requested, and no result is requested and we have not been given
2428 // an explicit task to launch in to, and we can find a task that was started with this
2429 // same component, then instead of launching bring that one to the front.
2430 putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null;
2431 ActivityRecord intentActivity = null;
Winson Chung8a168902020-03-12 22:39:22 -07002432 if (putIntoExistingTask) {
Bryce Lee7daee392017-10-12 13:46:18 -07002433 if (LAUNCH_SINGLE_INSTANCE == mLaunchMode) {
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07002434 // There can be one and only one instance of single instance activity in the
2435 // history, and it is always in its own unique task, so we do a special search.
Louis Chang149d5c82019-12-30 09:47:39 +08002436 intentActivity = mRootWindowContainer.findActivity(mIntent, mStartActivity.info,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07002437 mStartActivity.isActivityTypeHome());
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07002438 } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
2439 // For the launch adjacent case we only want to put the activity in an existing
2440 // task if the activity already exists in the history.
Louis Chang149d5c82019-12-30 09:47:39 +08002441 intentActivity = mRootWindowContainer.findActivity(mIntent, mStartActivity.info,
Bryce Lee7daee392017-10-12 13:46:18 -07002442 !(LAUNCH_SINGLE_TASK == mLaunchMode));
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07002443 } else {
2444 // Otherwise find the best task to put the activity in.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002445 intentActivity =
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002446 mRootWindowContainer.findTask(mStartActivity, mPreferredTaskDisplayArea);
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07002447 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002448 }
Louis Changbd48dca2018-08-29 17:44:34 +08002449
Louis Chang54506cb2018-11-23 11:03:41 +08002450 if (intentActivity != null
2451 && (mStartActivity.isActivityTypeHome() || intentActivity.isActivityTypeHome())
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002452 && intentActivity.getDisplayArea() != mPreferredTaskDisplayArea) {
2453 // Do not reuse home activity on other display areas.
Louis Changbd48dca2018-08-29 17:44:34 +08002454 intentActivity = null;
2455 }
2456
Louis Changcdec0802019-11-11 11:45:07 +08002457 return intentActivity != null ? intentActivity.getTask() : null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08002458 }
2459
Andrii Kulianfab9cd82017-03-21 19:37:09 -07002460 /**
2461 * Figure out which task and activity to bring to front when we have found an existing matching
2462 * activity record in history. May also clear the task if needed.
2463 * @param intentActivity Existing matching activity.
2464 * @return {@link ActivityRecord} brought to front.
2465 */
Louis Changbde91e92019-08-16 17:19:47 +08002466 private void setTargetStackIfNeeded(ActivityRecord intentActivity) {
Wale Ogunwale1ebcd8e2020-01-21 11:27:03 -08002467 mTargetStack = intentActivity.getRootTask();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002468 mTargetStack.mLastPausedActivity = null;
Louis Changa009c762020-02-26 11:21:31 +08002469 Task intentTask = intentActivity.getTask();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002470 // If the target task is not in the front, then we need to bring it to the front...
2471 // except... well, with SINGLE_TASK_LAUNCH it's not entirely clear. We'd like to have
2472 // the same behavior as if a new instance was being started, which means not bringing it
2473 // to the front if the caller is not itself in the front.
Riddle Hsub70b36d2018-09-11 21:20:02 +08002474 final boolean differentTopTask;
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002475 if (mTargetStack.getDisplayArea() == mPreferredTaskDisplayArea) {
Riddle Hsub70b36d2018-09-11 21:20:02 +08002476 final ActivityStack focusStack = mTargetStack.getDisplay().getFocusedStack();
2477 final ActivityRecord curTop = (focusStack == null)
2478 ? null : focusStack.topRunningNonDelayedActivityLocked(mNotTop);
Louis Changcdec0802019-11-11 11:45:07 +08002479 final Task topTask = curTop != null ? curTop.getTask() : null;
Louis Changa009c762020-02-26 11:21:31 +08002480 differentTopTask = topTask != intentTask
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09002481 || (focusStack != null && topTask != focusStack.getTopMostTask());
Riddle Hsub70b36d2018-09-11 21:20:02 +08002482 } else {
2483 // The existing task should always be different from those in other displays.
2484 differentTopTask = true;
2485 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002486
Riddle Hsub70b36d2018-09-11 21:20:02 +08002487 if (differentTopTask && !mAvoidMoveToFront) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002488 mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Wale Ogunwale21e06482019-11-18 05:14:15 -08002489 if (mSourceRecord == null || (mSourceStack.getTopNonFinishingActivity() != null &&
2490 mSourceStack.getTopNonFinishingActivity().getTask()
Louis Changcdec0802019-11-11 11:45:07 +08002491 == mSourceRecord.getTask())) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002492 // We really do want to push this one into the user's face, right now.
2493 if (mLaunchTaskBehind && mSourceRecord != null) {
Louis Changcdec0802019-11-11 11:45:07 +08002494 intentActivity.setTaskToAffiliateWith(mSourceRecord.getTask());
Wale Ogunwale01d66562015-12-29 08:19:19 -08002495 }
Chong Zhangdea4bd92016-03-15 12:50:03 -07002496
Louis Changf3070c52019-10-09 15:57:30 +08002497 final ActivityStack launchStack =
2498 getLaunchStack(mStartActivity, mLaunchFlags, intentTask, mOptions);
Louis Changbde91e92019-08-16 17:19:47 +08002499 if (launchStack == null || launchStack == mTargetStack) {
Louis Chang38430df2020-01-02 17:14:59 +08002500 // Do not set mMovedToFront to true below for split-screen-top stack, or
2501 // START_TASK_TO_FRONT will be returned and trigger unexpected animations when a
2502 // new intent has delivered.
2503 final boolean isSplitScreenTopStack = mTargetStack.isTopSplitScreenStack();
2504
Louis Changa009c762020-02-26 11:21:31 +08002505 // TODO(b/151572268): Figure out a better way to move tasks in above 2-levels
2506 // tasks hierarchies.
2507 if (mTargetStack != intentTask
2508 && mTargetStack != intentTask.getParent().asTask()) {
2509 intentTask.getParent().positionChildAt(POSITION_TOP, intentTask,
2510 false /* includingParents */);
2511 intentTask = intentTask.getParent().asTask();
2512 }
Louis Changbde91e92019-08-16 17:19:47 +08002513 // We only want to move to the front, if we aren't going to launch on a
2514 // different stack. If we launch on a different stack, we will put the
2515 // task on top there.
Louis Chang38430df2020-01-02 17:14:59 +08002516 // Defer resuming the top activity while moving task to top, since the
2517 // current task-top activity may not be the activity that should be resumed.
Wale Ogunwale0d465192020-01-23 19:14:44 -08002518 mTargetStack.moveTaskToFront(intentTask, mNoAnimation, mOptions,
Louis Chang38430df2020-01-02 17:14:59 +08002519 mStartActivity.appTimeTracker, DEFER_RESUME,
2520 "bringingFoundTaskToFront");
2521 mMovedToFront = !isSplitScreenTopStack;
2522 } else {
2523 intentTask.reparent(launchStack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, ANIMATE,
2524 DEFER_RESUME, "reparentToTargetStack");
Louis Changbde91e92019-08-16 17:19:47 +08002525 mMovedToFront = true;
Louis Changf3070c52019-10-09 15:57:30 +08002526 }
Louis Changbde91e92019-08-16 17:19:47 +08002527 mOptions = null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08002528 }
2529 }
Andrii Kulianb850ea52017-12-12 23:49:10 -08002530 // Need to update mTargetStack because if task was moved out of it, the original stack may
2531 // be destroyed.
Wale Ogunwale1ebcd8e2020-01-21 11:27:03 -08002532 mTargetStack = intentActivity.getRootTask();
Louis Changa009c762020-02-26 11:21:31 +08002533 mSupervisor.handleNonResizableTaskIfNeeded(intentTask, WINDOWING_MODE_UNDEFINED,
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07002534 mRootWindowContainer.getDefaultTaskDisplayArea(), mTargetStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002535 }
2536
2537 private void resumeTargetStackIfNeeded() {
2538 if (mDoResume) {
Louis Chang149d5c82019-12-30 09:47:39 +08002539 mRootWindowContainer.resumeFocusedStacksTopActivities(mTargetStack, null, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002540 } else {
2541 ActivityOptions.abort(mOptions);
2542 }
Louis Chang149d5c82019-12-30 09:47:39 +08002543 mRootWindowContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002544 }
2545
Louis Changcdec0802019-11-11 11:45:07 +08002546 private void setNewTask(Task taskToAffiliate) {
Louis Changbde91e92019-08-16 17:19:47 +08002547 final boolean toTop = !mLaunchTaskBehind && !mAvoidMoveToFront;
Wale Ogunwale0d465192020-01-23 19:14:44 -08002548 final Task task = mTargetStack.reuseOrCreateTask(
Louis Changbde91e92019-08-16 17:19:47 +08002549 mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
2550 mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
2551 mVoiceInteractor, toTop, mStartActivity, mSourceRecord, mOptions);
2552 addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
Louis Change8902452019-06-10 10:49:28 +08002553
Louis Changbde91e92019-08-16 17:19:47 +08002554 if (DEBUG_TASKS) {
2555 Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Louis Changcdec0802019-11-11 11:45:07 +08002556 + " in new task " + mStartActivity.getTask());
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002557 }
2558
2559 if (taskToAffiliate != null) {
2560 mStartActivity.setTaskToAffiliateWith(taskToAffiliate);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002561 }
2562 }
2563
Jeff Sharkey307ea7a2020-04-13 10:24:49 -06002564 private void deliverNewIntent(ActivityRecord activity, NeededUriGrants intentGrants) {
Bryce Lee325e09682017-10-05 17:20:25 -07002565 if (mIntentDelivered) {
2566 return;
2567 }
2568
Jeff Changd136e772019-11-05 20:33:52 +08002569 activity.logStartActivity(EventLogTags.WM_NEW_INTENT, activity.getTask());
Jeff Sharkey307ea7a2020-04-13 10:24:49 -06002570 activity.deliverNewIntentLocked(mCallingUid, mStartActivity.intent, intentGrants,
Bryce Lee325e09682017-10-05 17:20:25 -07002571 mStartActivity.launchedFromPackage);
2572 mIntentDelivered = true;
2573 }
2574
Louis Changcdec0802019-11-11 11:45:07 +08002575 private void addOrReparentStartingActivity(Task parent, String reason) {
2576 if (mStartActivity.getTask() == null || mStartActivity.getTask() == parent) {
Wale Ogunwalec17418e2019-10-13 23:00:40 +02002577 parent.addChild(mStartActivity);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002578 } else {
Wale Ogunwale1a06f152019-10-11 11:26:30 +02002579 mStartActivity.reparent(parent, parent.getChildCount() /* top */, reason);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002580 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002581 }
2582
2583 private int adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance,
2584 boolean launchSingleTask, int launchFlags) {
2585 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2586 (launchSingleInstance || launchSingleTask)) {
2587 // We have a conflict between the Intent and the Activity manifest, manifest wins.
2588 Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " +
2589 "\"singleInstance\" or \"singleTask\"");
2590 launchFlags &=
2591 ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK);
2592 } else {
2593 switch (r.info.documentLaunchMode) {
2594 case ActivityInfo.DOCUMENT_LAUNCH_NONE:
2595 break;
2596 case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
2597 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2598 break;
2599 case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
2600 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2601 break;
2602 case ActivityInfo.DOCUMENT_LAUNCH_NEVER:
2603 launchFlags &= ~FLAG_ACTIVITY_MULTIPLE_TASK;
2604 break;
2605 }
2606 }
2607 return launchFlags;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002608 }
2609
Louis Changcdec0802019-11-11 11:45:07 +08002610 private ActivityStack getLaunchStack(ActivityRecord r, int launchFlags, Task task,
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002611 ActivityOptions aOptions) {
Bryce Leea19b5ad2017-06-07 16:54:11 -07002612 // We are reusing a task, keep the stack!
2613 if (mReuseTask != null) {
2614 return mReuseTask.getStack();
2615 }
Jorim Jaggib8c58762016-04-20 17:58:29 -07002616
Louis Chang38430df2020-01-02 17:14:59 +08002617 final boolean onTop =
2618 (aOptions == null || !aOptions.getAvoidMoveToFront()) && !mLaunchTaskBehind;
2619 return mRootWindowContainer.getLaunchStack(r, aOptions, task, onTop, mLaunchParams,
2620 mRequest.realCallingPid, mRequest.realCallingUid);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002621 }
2622
Bryce Lee7daee392017-10-12 13:46:18 -07002623 private boolean isLaunchModeOneOf(int mode1, int mode2) {
2624 return mode1 == mLaunchMode || mode2 == mLaunchMode;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002625 }
2626
Daichi Hirono15a02992016-04-27 18:47:01 +09002627 static boolean isDocumentLaunchesIntoExisting(int flags) {
2628 return (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2629 (flags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0;
2630 }
liulvpingcfa825f2016-09-26 20:00:15 +08002631
Bryce Lee4c9a5972017-12-01 22:14:24 -08002632 ActivityStarter setIntent(Intent intent) {
2633 mRequest.intent = intent;
2634 return this;
2635 }
2636
Bryce Lee32e09ef2018-03-19 15:29:49 -07002637 Intent getIntent() {
2638 return mRequest.intent;
2639 }
2640
Jeff Sharkey8b896f22020-06-19 14:01:02 -06002641 ActivityStarter setIntentGrants(NeededUriGrants intentGrants) {
2642 mRequest.intentGrants = intentGrants;
2643 return this;
2644 }
2645
Bryce Lee4c9a5972017-12-01 22:14:24 -08002646 ActivityStarter setReason(String reason) {
2647 mRequest.reason = reason;
2648 return this;
2649 }
2650
2651 ActivityStarter setCaller(IApplicationThread caller) {
2652 mRequest.caller = caller;
2653 return this;
2654 }
2655
Bryce Lee4c9a5972017-12-01 22:14:24 -08002656 ActivityStarter setResolvedType(String type) {
2657 mRequest.resolvedType = type;
2658 return this;
2659 }
2660
2661 ActivityStarter setActivityInfo(ActivityInfo info) {
2662 mRequest.activityInfo = info;
2663 return this;
2664 }
2665
2666 ActivityStarter setResolveInfo(ResolveInfo info) {
2667 mRequest.resolveInfo = info;
2668 return this;
2669 }
2670
2671 ActivityStarter setVoiceSession(IVoiceInteractionSession voiceSession) {
2672 mRequest.voiceSession = voiceSession;
2673 return this;
2674 }
2675
2676 ActivityStarter setVoiceInteractor(IVoiceInteractor voiceInteractor) {
2677 mRequest.voiceInteractor = voiceInteractor;
2678 return this;
2679 }
2680
2681 ActivityStarter setResultTo(IBinder resultTo) {
2682 mRequest.resultTo = resultTo;
2683 return this;
2684 }
2685
2686 ActivityStarter setResultWho(String resultWho) {
2687 mRequest.resultWho = resultWho;
2688 return this;
2689 }
2690
2691 ActivityStarter setRequestCode(int requestCode) {
2692 mRequest.requestCode = requestCode;
2693 return this;
2694 }
2695
lumarkf65e02d2019-09-14 19:25:21 +08002696 /**
2697 * Sets the pid of the caller who originally started the activity.
2698 *
2699 * Normally, the pid/uid would be the calling pid from the binder call.
2700 * However, in case of a {@link PendingIntent}, the pid/uid pair of the caller is considered
2701 * the original entity that created the pending intent, in contrast to setRealCallingPid/Uid,
2702 * which represents the entity who invoked pending intent via {@link PendingIntent#send}.
2703 */
Bryce Lee4c9a5972017-12-01 22:14:24 -08002704 ActivityStarter setCallingPid(int pid) {
2705 mRequest.callingPid = pid;
2706 return this;
2707 }
2708
lumarkf65e02d2019-09-14 19:25:21 +08002709 /**
2710 * Sets the uid of the caller who originally started the activity.
2711 *
2712 * @see #setCallingPid
2713 */
Bryce Lee4c9a5972017-12-01 22:14:24 -08002714 ActivityStarter setCallingUid(int uid) {
2715 mRequest.callingUid = uid;
2716 return this;
2717 }
2718
2719 ActivityStarter setCallingPackage(String callingPackage) {
2720 mRequest.callingPackage = callingPackage;
2721 return this;
2722 }
2723
Philip P. Moltmannee295092020-02-10 08:46:26 -08002724 ActivityStarter setCallingFeatureId(String callingFeatureId) {
2725 mRequest.callingFeatureId = callingFeatureId;
2726 return this;
2727 }
2728
lumarkf65e02d2019-09-14 19:25:21 +08002729 /**
2730 * Sets the pid of the caller who requested to launch the activity.
2731 *
2732 * The pid/uid represents the caller who launches the activity in this request.
2733 * It will almost same as setCallingPid/Uid except when processing {@link PendingIntent}:
2734 * the pid/uid will be the caller who called {@link PendingIntent#send()}.
2735 *
2736 * @see #setCallingPid
2737 */
Bryce Lee4c9a5972017-12-01 22:14:24 -08002738 ActivityStarter setRealCallingPid(int pid) {
2739 mRequest.realCallingPid = pid;
2740 return this;
2741 }
2742
lumarkf65e02d2019-09-14 19:25:21 +08002743 /**
2744 * Sets the uid of the caller who requested to launch the activity.
2745 *
2746 * @see #setRealCallingPid
2747 */
Bryce Lee4c9a5972017-12-01 22:14:24 -08002748 ActivityStarter setRealCallingUid(int uid) {
2749 mRequest.realCallingUid = uid;
2750 return this;
2751 }
2752
2753 ActivityStarter setStartFlags(int startFlags) {
2754 mRequest.startFlags = startFlags;
2755 return this;
2756 }
2757
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002758 ActivityStarter setActivityOptions(SafeActivityOptions options) {
Bryce Lee4c9a5972017-12-01 22:14:24 -08002759 mRequest.activityOptions = options;
2760 return this;
2761 }
2762
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002763 ActivityStarter setActivityOptions(Bundle bOptions) {
2764 return setActivityOptions(SafeActivityOptions.fromBundle(bOptions));
2765 }
2766
Bryce Lee4c9a5972017-12-01 22:14:24 -08002767 ActivityStarter setIgnoreTargetSecurity(boolean ignoreTargetSecurity) {
2768 mRequest.ignoreTargetSecurity = ignoreTargetSecurity;
2769 return this;
2770 }
2771
Patrick Baumann31426b22018-05-21 13:46:40 -07002772 ActivityStarter setFilterCallingUid(int filterCallingUid) {
2773 mRequest.filterCallingUid = filterCallingUid;
2774 return this;
2775 }
2776
Bryce Lee4c9a5972017-12-01 22:14:24 -08002777 ActivityStarter setComponentSpecified(boolean componentSpecified) {
2778 mRequest.componentSpecified = componentSpecified;
2779 return this;
2780 }
2781
2782 ActivityStarter setOutActivity(ActivityRecord[] outActivity) {
2783 mRequest.outActivity = outActivity;
2784 return this;
2785 }
2786
Louis Changcdec0802019-11-11 11:45:07 +08002787 ActivityStarter setInTask(Task inTask) {
Bryce Lee4c9a5972017-12-01 22:14:24 -08002788 mRequest.inTask = inTask;
2789 return this;
2790 }
2791
2792 ActivityStarter setWaitResult(WaitResult result) {
2793 mRequest.waitResult = result;
2794 return this;
2795 }
2796
2797 ActivityStarter setProfilerInfo(ProfilerInfo info) {
2798 mRequest.profilerInfo = info;
2799 return this;
2800 }
2801
2802 ActivityStarter setGlobalConfiguration(Configuration config) {
2803 mRequest.globalConfig = config;
2804 return this;
2805 }
2806
Bryce Lee4c9a5972017-12-01 22:14:24 -08002807 ActivityStarter setUserId(int userId) {
2808 mRequest.userId = userId;
2809 return this;
2810 }
2811
Jorim Jaggi6fa41c32018-04-23 18:35:00 +02002812 ActivityStarter setAllowPendingRemoteAnimationRegistryLookup(boolean allowLookup) {
2813 mRequest.allowPendingRemoteAnimationRegistryLookup = allowLookup;
2814 return this;
2815 }
2816
Michal Karpinski201bc0c2018-07-20 15:32:00 +01002817 ActivityStarter setOriginatingPendingIntent(PendingIntentRecord originatingPendingIntent) {
2818 mRequest.originatingPendingIntent = originatingPendingIntent;
2819 return this;
2820 }
2821
Michal Karpinskiac116df2018-12-10 17:51:42 +00002822 ActivityStarter setAllowBackgroundActivityStart(boolean allowBackgroundActivityStart) {
2823 mRequest.allowBackgroundActivityStart = allowBackgroundActivityStart;
2824 return this;
2825 }
2826
Bryce Leed3624e12017-11-30 08:51:45 -08002827 void dump(PrintWriter pw, String prefix) {
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002828 prefix = prefix + " ";
Dianne Hackborne676ec72017-07-25 10:55:08 -07002829 pw.print(prefix);
2830 pw.print("mCurrentUser=");
Louis Chang149d5c82019-12-30 09:47:39 +08002831 pw.println(mRootWindowContainer.mCurrentUser);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002832 pw.print(prefix);
2833 pw.print("mLastStartReason=");
2834 pw.println(mLastStartReason);
2835 pw.print(prefix);
2836 pw.print("mLastStartActivityTimeMs=");
2837 pw.println(DateFormat.getDateTimeInstance().format(new Date(mLastStartActivityTimeMs)));
2838 pw.print(prefix);
2839 pw.print("mLastStartActivityResult=");
2840 pw.println(mLastStartActivityResult);
Louis Chang54fbb052019-10-16 17:10:17 +08002841 if (mLastStartActivityRecord != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002842 pw.print(prefix);
2843 pw.println("mLastStartActivityRecord:");
Louis Chang54fbb052019-10-16 17:10:17 +08002844 mLastStartActivityRecord.dump(pw, prefix + " ", true /* dumpAll */);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002845 }
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002846 if (mStartActivity != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002847 pw.print(prefix);
2848 pw.println("mStartActivity:");
Garfield Tane8d84ab2019-10-11 09:49:40 -07002849 mStartActivity.dump(pw, prefix + " ", true /* dumpAll */);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002850 }
2851 if (mIntent != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002852 pw.print(prefix);
2853 pw.print("mIntent=");
2854 pw.println(mIntent);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002855 }
2856 if (mOptions != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002857 pw.print(prefix);
2858 pw.print("mOptions=");
2859 pw.println(mOptions);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002860 }
Dianne Hackborne676ec72017-07-25 10:55:08 -07002861 pw.print(prefix);
2862 pw.print("mLaunchSingleTop=");
Bryce Lee7daee392017-10-12 13:46:18 -07002863 pw.print(LAUNCH_SINGLE_TOP == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002864 pw.print(" mLaunchSingleInstance=");
Bryce Lee7daee392017-10-12 13:46:18 -07002865 pw.print(LAUNCH_SINGLE_INSTANCE == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002866 pw.print(" mLaunchSingleTask=");
Bryce Lee7daee392017-10-12 13:46:18 -07002867 pw.println(LAUNCH_SINGLE_TASK == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002868 pw.print(prefix);
2869 pw.print("mLaunchFlags=0x");
2870 pw.print(Integer.toHexString(mLaunchFlags));
2871 pw.print(" mDoResume=");
2872 pw.print(mDoResume);
2873 pw.print(" mAddingToTask=");
2874 pw.println(mAddingToTask);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002875 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002876}