blob: 9f04166ea4c025432421114961cdd7b7b3c2dae2 [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;
Wale Ogunwale68278562017-09-23 17:13:55 -070030import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
31import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
Wale Ogunwale7d7973a2018-04-05 10:25:59 -070032import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070033import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
34import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Wale Ogunwale0568aed2017-09-08 13:29:37 -070035import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080036import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
37import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
Wale Ogunwale2a25a622016-01-30 11:27:21 -080038import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080039import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
Wale Ogunwale01d66562015-12-29 08:19:19 -080040import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080041import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
Wale Ogunwale01d66562015-12-29 08:19:19 -080042import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION;
43import static android.content.Intent.FLAG_ACTIVITY_NO_USER_ACTION;
Wale Ogunwale01d66562015-12-29 08:19:19 -080044import static android.content.Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP;
45import static android.content.Intent.FLAG_ACTIVITY_REORDER_TO_FRONT;
46import static android.content.Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED;
47import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
48import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP;
Louis Changb45ee7e2019-01-17 10:36:56 +080049import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
Wale Ogunwale01d66562015-12-29 08:19:19 -080050import static android.content.pm.ActivityInfo.DOCUMENT_LAUNCH_ALWAYS;
Bryce Leef65ee7e2018-03-26 16:03:47 -070051import static android.content.pm.ActivityInfo.LAUNCH_MULTIPLE;
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;
David Stevensc6b91c62017-02-08 14:23:58 -080056import static android.view.Display.DEFAULT_DISPLAY;
Andrii Kulian16802aa2016-11-02 12:21:33 -070057import static android.view.Display.INVALID_DISPLAY;
Riddle Hsub70b36d2018-09-11 21:20:02 +080058
Louis Changdd3592a2018-11-05 11:04:14 +080059import static com.android.server.am.EventLogTags.AM_NEW_INTENT;
Wale Ogunwale59507092018-10-29 09:00:30 -070060import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
61import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME;
62import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
63import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
64import static com.android.server.wm.ActivityStackSupervisor.TAG_TASKS;
65import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
66import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_FOCUS;
67import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
68import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS;
69import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STACK;
70import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
71import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_USER_LEAVING;
72import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
73import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS;
74import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RESULTS;
75import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_USER_LEAVING;
76import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
77import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
78import static com.android.server.wm.ActivityTaskManagerService.ANIMATE;
Louis Chang6fb1e842018-12-03 16:07:50 +080079import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_BOUNDS;
80import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_DISPLAY;
Wale Ogunwale59507092018-10-29 09:00:30 -070081import static com.android.server.wm.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
82import static com.android.server.wm.TaskRecord.REPARENT_MOVE_STACK_TO_FRONT;
Winson Chung74666102017-02-22 17:49:24 -080083
Todd Kennedye9910222017-02-21 16:00:11 -080084import android.annotation.NonNull;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +010085import android.annotation.Nullable;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080086import android.app.ActivityManager;
87import android.app.ActivityOptions;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080088import android.app.IApplicationThread;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080089import android.app.PendingIntent;
90import android.app.ProfilerInfo;
Sudheer Shankafc46e9b2016-10-21 17:55:27 -070091import android.app.WaitResult;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080092import android.content.IIntentSender;
93import android.content.Intent;
94import android.content.IntentSender;
95import android.content.pm.ActivityInfo;
96import android.content.pm.ApplicationInfo;
Todd Kennedye9910222017-02-21 16:00:11 -080097import android.content.pm.AuxiliaryResolveInfo;
Kenny Guyb1b30262016-02-09 16:02:35 +000098import android.content.pm.PackageManager;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080099import android.content.pm.ResolveInfo;
Kenny Guyb1b30262016-02-09 16:02:35 +0000100import android.content.pm.UserInfo;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800101import android.content.res.Configuration;
Michal Karpinskiac213c62019-02-19 12:38:14 +0000102import android.content.res.Resources;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800103import android.graphics.Rect;
104import android.os.Binder;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800105import android.os.Bundle;
106import android.os.IBinder;
Michal Karpinski8596ded2018-11-14 14:43:48 +0000107import android.os.Process;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800108import android.os.RemoteException;
109import android.os.SystemClock;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100110import android.os.Trace;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800111import android.os.UserHandle;
Kenny Guyb1b30262016-02-09 16:02:35 +0000112import android.os.UserManager;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800113import android.service.voice.IVoiceInteractionSession;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700114import android.text.TextUtils;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800115import android.util.EventLog;
Bryce Leedaa91e42017-12-06 14:13:01 -0800116import android.util.Pools.SynchronizedPool;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800117import android.util.Slog;
Michal Karpinski8596ded2018-11-14 14:43:48 +0000118import android.widget.Toast;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800119
Michal Karpinskiac213c62019-02-19 12:38:14 +0000120import com.android.internal.R;
Bryce Leed3624e12017-11-30 08:51:45 -0800121import com.android.internal.annotations.VisibleForTesting;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800122import com.android.internal.app.HeavyWeightSwitcherActivity;
123import com.android.internal.app.IVoiceInteractor;
Wale Ogunwale59507092018-10-29 09:00:30 -0700124import com.android.server.am.EventLogTags;
125import com.android.server.am.PendingIntentRecord;
Louis Changdd3592a2018-11-05 11:04:14 +0800126import com.android.server.pm.InstantAppResolver;
Wale Ogunwale59507092018-10-29 09:00:30 -0700127import com.android.server.wm.ActivityStackSupervisor.PendingActivityLaunch;
128import com.android.server.wm.LaunchParamsController.LaunchParams;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800129
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700130import java.io.PrintWriter;
131import java.text.DateFormat;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700132import java.util.Date;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800133
134/**
Bryce Leed3624e12017-11-30 08:51:45 -0800135 * Controller for interpreting how and then launching an activity.
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800136 *
137 * This class collects all the logic for determining how an intent and flags should be turned into
138 * an activity and associated task and stack.
139 */
Wale Ogunwale01d66562015-12-29 08:19:19 -0800140class ActivityStarter {
Wale Ogunwale98875612018-10-12 07:53:02 -0700141 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStarter" : TAG_ATM;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800142 private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS;
143 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
144 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
145 private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING;
Bryce Lee7daee392017-10-12 13:46:18 -0700146 private static final int INVALID_LAUNCH_MODE = -1;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800147
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700148 private final ActivityTaskManagerService mService;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800149 private final RootActivityContainer mRootActivityContainer;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800150 private final ActivityStackSupervisor mSupervisor;
Benjamin Franz563707b2017-06-29 15:06:13 +0100151 private final ActivityStartInterceptor mInterceptor;
Bryce Leed3624e12017-11-30 08:51:45 -0800152 private final ActivityStartController mController;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800153
Wale Ogunwale01d66562015-12-29 08:19:19 -0800154 // Share state variable among methods when starting an activity.
155 private ActivityRecord mStartActivity;
156 private Intent mIntent;
157 private int mCallingUid;
158 private ActivityOptions mOptions;
159
Bryce Lee7daee392017-10-12 13:46:18 -0700160 private int mLaunchMode;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800161 private boolean mLaunchTaskBehind;
162 private int mLaunchFlags;
163
Bryce Leeec55eb02017-12-05 20:51:27 -0800164 private LaunchParams mLaunchParams = new LaunchParams();
Wale Ogunwale01d66562015-12-29 08:19:19 -0800165
166 private ActivityRecord mNotTop;
167 private boolean mDoResume;
168 private int mStartFlags;
169 private ActivityRecord mSourceRecord;
Bryce Lee7daee392017-10-12 13:46:18 -0700170
David Stevense5a7b642017-05-22 13:18:23 -0700171 // The display to launch the activity onto, barring any strong reason to do otherwise.
172 private int mPreferredDisplayId;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800173
174 private TaskRecord mInTask;
175 private boolean mAddingToTask;
176 private TaskRecord mReuseTask;
177
178 private ActivityInfo mNewTaskInfo;
179 private Intent mNewTaskIntent;
180 private ActivityStack mSourceStack;
181 private ActivityStack mTargetStack;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800182 private boolean mMovedToFront;
183 private boolean mNoAnimation;
184 private boolean mKeepCurTransition;
Jorim Jaggic875ae72016-04-26 22:41:06 -0700185 private boolean mAvoidMoveToFront;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800186
Bryce Lee325e09682017-10-05 17:20:25 -0700187 // We must track when we deliver the new intent since multiple code paths invoke
188 // {@link #deliverNewIntent}. This is due to early returns in the code path. This flag is used
189 // inside {@link #deliverNewIntent} to suppress duplicate requests and ensure the intent is
190 // delivered at most once.
191 private boolean mIntentDelivered;
192
Wale Ogunwale01d66562015-12-29 08:19:19 -0800193 private IVoiceInteractionSession mVoiceSession;
194 private IVoiceInteractor mVoiceInteractor;
195
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700196 // Last activity record we attempted to start
197 private final ActivityRecord[] mLastStartActivityRecord = new ActivityRecord[1];
198 // The result of the last activity we attempted to start.
199 private int mLastStartActivityResult;
200 // Time in milli seconds we attempted to start the last activity.
201 private long mLastStartActivityTimeMs;
202 // The reason we were trying to start the last activity
203 private String mLastStartReason;
Wale Ogunwale59bcba62017-06-16 12:42:51 -0700204
Bryce Lee4c9a5972017-12-01 22:14:24 -0800205 /*
206 * Request details provided through setter methods. Should be reset after {@link #execute()}
207 * to avoid unnecessarily retaining parameters. Note that the request is ignored when
208 * {@link #startResolvedActivity} is invoked directly.
209 */
210 private Request mRequest = new Request();
211
Bryce Leed3624e12017-11-30 08:51:45 -0800212 /**
213 * An interface that to provide {@link ActivityStarter} instances to the controller. This is
214 * used by tests to inject their own starter implementations for verification purposes.
215 */
216 @VisibleForTesting
217 interface Factory {
218 /**
Bryce Lee4c9a5972017-12-01 22:14:24 -0800219 * Sets the {@link ActivityStartController} to be passed to {@link ActivityStarter}.
220 */
221 void setController(ActivityStartController controller);
222
223 /**
Bryce Leed3624e12017-11-30 08:51:45 -0800224 * Generates an {@link ActivityStarter} that is ready to handle a new start request.
225 * @param controller The {@link ActivityStartController} which the starter who will own
226 * this instance.
227 * @return an {@link ActivityStarter}
228 */
Bryce Leedaa91e42017-12-06 14:13:01 -0800229 ActivityStarter obtain();
230
231 /**
232 * Recycles a starter for reuse.
233 */
234 void recycle(ActivityStarter starter);
Wale Ogunwale01d66562015-12-29 08:19:19 -0800235 }
236
Bryce Leed3624e12017-11-30 08:51:45 -0800237 /**
238 * Default implementation of {@link StarterFactory}.
239 */
240 static class DefaultFactory implements Factory {
Bryce Leedaa91e42017-12-06 14:13:01 -0800241 /**
242 * The maximum count of starters that should be active at one time:
243 * 1. last ran starter (for logging and post activity processing)
244 * 2. current running starter
245 * 3. starter from re-entry in (2)
246 */
247 private final int MAX_STARTER_COUNT = 3;
248
Bryce Lee4c9a5972017-12-01 22:14:24 -0800249 private ActivityStartController mController;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700250 private ActivityTaskManagerService mService;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800251 private ActivityStackSupervisor mSupervisor;
252 private ActivityStartInterceptor mInterceptor;
253
Bryce Leedaa91e42017-12-06 14:13:01 -0800254 private SynchronizedPool<ActivityStarter> mStarterPool =
255 new SynchronizedPool<>(MAX_STARTER_COUNT);
256
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700257 DefaultFactory(ActivityTaskManagerService service,
Bryce Lee4c9a5972017-12-01 22:14:24 -0800258 ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
259 mService = service;
260 mSupervisor = supervisor;
261 mInterceptor = interceptor;
Bryce Leed3624e12017-11-30 08:51:45 -0800262 }
Bryce Lee4c9a5972017-12-01 22:14:24 -0800263
264 @Override
265 public void setController(ActivityStartController controller) {
266 mController = controller;
267 }
268
269 @Override
Bryce Leedaa91e42017-12-06 14:13:01 -0800270 public ActivityStarter obtain() {
271 ActivityStarter starter = mStarterPool.acquire();
272
273 if (starter == null) {
274 starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
275 }
276
277 return starter;
278 }
279
280 @Override
281 public void recycle(ActivityStarter starter) {
282 starter.reset(true /* clearRequest*/);
283 mStarterPool.release(starter);
Bryce Lee4c9a5972017-12-01 22:14:24 -0800284 }
285 }
286
287 /**
288 * Container for capturing initial start request details. This information is NOT reset until
289 * the {@link ActivityStarter} is recycled, allowing for multiple invocations with the same
290 * parameters.
291 *
292 * TODO(b/64750076): Investigate consolidating member variables of {@link ActivityStarter} with
293 * the request object. Note that some member variables are referenced in
294 * {@link #dump(PrintWriter, String)} and therefore cannot be cleared immediately after
295 * execution.
296 */
297 private static class Request {
298 private static final int DEFAULT_CALLING_UID = -1;
299 private static final int DEFAULT_CALLING_PID = 0;
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000300 static final int DEFAULT_REAL_CALLING_UID = -1;
301 static final int DEFAULT_REAL_CALLING_PID = 0;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800302
303 IApplicationThread caller;
304 Intent intent;
305 Intent ephemeralIntent;
306 String resolvedType;
307 ActivityInfo activityInfo;
308 ResolveInfo resolveInfo;
309 IVoiceInteractionSession voiceSession;
310 IVoiceInteractor voiceInteractor;
311 IBinder resultTo;
312 String resultWho;
313 int requestCode;
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000314 int callingPid = DEFAULT_CALLING_PID;
315 int callingUid = DEFAULT_CALLING_UID;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800316 String callingPackage;
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000317 int realCallingPid = DEFAULT_REAL_CALLING_PID;
318 int realCallingUid = DEFAULT_REAL_CALLING_UID;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800319 int startFlags;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100320 SafeActivityOptions activityOptions;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800321 boolean ignoreTargetSecurity;
322 boolean componentSpecified;
Winson Chunge2d72172018-01-25 17:46:20 +0000323 boolean avoidMoveToFront;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800324 ActivityRecord[] outActivity;
325 TaskRecord inTask;
326 String reason;
327 ProfilerInfo profilerInfo;
328 Configuration globalConfig;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800329 int userId;
330 WaitResult waitResult;
Patrick Baumann31426b22018-05-21 13:46:40 -0700331 int filterCallingUid;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100332 PendingIntentRecord originatingPendingIntent;
Michal Karpinskiac116df2018-12-10 17:51:42 +0000333 boolean allowBackgroundActivityStart;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800334
335 /**
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200336 * If set to {@code true}, allows this activity start to look into
337 * {@link PendingRemoteAnimationRegistry}
338 */
339 boolean allowPendingRemoteAnimationRegistryLookup;
340
341 /**
Bryce Lee4c9a5972017-12-01 22:14:24 -0800342 * Indicates that we should wait for the result of the start request. This flag is set when
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100343 * {@link ActivityStarter#setMayWait(int)} is called.
Bryce Lee4c9a5972017-12-01 22:14:24 -0800344 * {@see ActivityStarter#startActivityMayWait}.
345 */
346 boolean mayWait;
Bryce Leedaa91e42017-12-06 14:13:01 -0800347
348 /**
Bryce Leea3cd8e02018-01-09 15:44:24 -0800349 * Ensure constructed request matches reset instance.
350 */
351 Request() {
352 reset();
353 }
354
355 /**
Bryce Leedaa91e42017-12-06 14:13:01 -0800356 * Sets values back to the initial state, clearing any held references.
357 */
358 void reset() {
359 caller = null;
360 intent = null;
361 ephemeralIntent = null;
362 resolvedType = null;
363 activityInfo = null;
364 resolveInfo = null;
365 voiceSession = null;
366 voiceInteractor = null;
367 resultTo = null;
368 resultWho = null;
369 requestCode = 0;
Bryce Leea3cd8e02018-01-09 15:44:24 -0800370 callingPid = DEFAULT_CALLING_PID;
371 callingUid = DEFAULT_CALLING_UID;
Bryce Leedaa91e42017-12-06 14:13:01 -0800372 callingPackage = null;
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000373 realCallingPid = DEFAULT_REAL_CALLING_PID;
374 realCallingUid = DEFAULT_REAL_CALLING_UID;
Bryce Leedaa91e42017-12-06 14:13:01 -0800375 startFlags = 0;
376 activityOptions = null;
377 ignoreTargetSecurity = false;
378 componentSpecified = false;
379 outActivity = null;
380 inTask = null;
381 reason = null;
382 profilerInfo = null;
383 globalConfig = null;
Bryce Leedaa91e42017-12-06 14:13:01 -0800384 userId = 0;
385 waitResult = null;
386 mayWait = false;
Winson Chunge2d72172018-01-25 17:46:20 +0000387 avoidMoveToFront = false;
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200388 allowPendingRemoteAnimationRegistryLookup = true;
Patrick Baumann31426b22018-05-21 13:46:40 -0700389 filterCallingUid = UserHandle.USER_NULL;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100390 originatingPendingIntent = null;
Michal Karpinskiac116df2018-12-10 17:51:42 +0000391 allowBackgroundActivityStart = false;
Bryce Leedaa91e42017-12-06 14:13:01 -0800392 }
393
394 /**
395 * Adopts all values from passed in request.
396 */
397 void set(Request request) {
398 caller = request.caller;
399 intent = request.intent;
400 ephemeralIntent = request.ephemeralIntent;
401 resolvedType = request.resolvedType;
402 activityInfo = request.activityInfo;
403 resolveInfo = request.resolveInfo;
404 voiceSession = request.voiceSession;
405 voiceInteractor = request.voiceInteractor;
406 resultTo = request.resultTo;
407 resultWho = request.resultWho;
408 requestCode = request.requestCode;
409 callingPid = request.callingPid;
410 callingUid = request.callingUid;
411 callingPackage = request.callingPackage;
412 realCallingPid = request.realCallingPid;
413 realCallingUid = request.realCallingUid;
414 startFlags = request.startFlags;
415 activityOptions = request.activityOptions;
416 ignoreTargetSecurity = request.ignoreTargetSecurity;
417 componentSpecified = request.componentSpecified;
418 outActivity = request.outActivity;
419 inTask = request.inTask;
420 reason = request.reason;
421 profilerInfo = request.profilerInfo;
422 globalConfig = request.globalConfig;
Bryce Leedaa91e42017-12-06 14:13:01 -0800423 userId = request.userId;
424 waitResult = request.waitResult;
425 mayWait = request.mayWait;
Winson Chunge2d72172018-01-25 17:46:20 +0000426 avoidMoveToFront = request.avoidMoveToFront;
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200427 allowPendingRemoteAnimationRegistryLookup
428 = request.allowPendingRemoteAnimationRegistryLookup;
Patrick Baumann31426b22018-05-21 13:46:40 -0700429 filterCallingUid = request.filterCallingUid;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100430 originatingPendingIntent = request.originatingPendingIntent;
Michal Karpinskiac116df2018-12-10 17:51:42 +0000431 allowBackgroundActivityStart = request.allowBackgroundActivityStart;
Bryce Leedaa91e42017-12-06 14:13:01 -0800432 }
Bryce Leed3624e12017-11-30 08:51:45 -0800433 }
434
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700435 ActivityStarter(ActivityStartController controller, ActivityTaskManagerService service,
Bryce Leed3624e12017-11-30 08:51:45 -0800436 ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
437 mController = controller;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800438 mService = service;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800439 mRootActivityContainer = service.mRootActivityContainer;
Bryce Leed3624e12017-11-30 08:51:45 -0800440 mSupervisor = supervisor;
441 mInterceptor = interceptor;
Bryce Leedaa91e42017-12-06 14:13:01 -0800442 reset(true);
443 }
444
445 /**
446 * Effectively duplicates the starter passed in. All state and request values will be
447 * mirrored.
448 * @param starter
449 */
450 void set(ActivityStarter starter) {
451 mStartActivity = starter.mStartActivity;
452 mIntent = starter.mIntent;
453 mCallingUid = starter.mCallingUid;
454 mOptions = starter.mOptions;
455
456 mLaunchTaskBehind = starter.mLaunchTaskBehind;
457 mLaunchFlags = starter.mLaunchFlags;
458 mLaunchMode = starter.mLaunchMode;
459
Bryce Leeec55eb02017-12-05 20:51:27 -0800460 mLaunchParams.set(starter.mLaunchParams);
Bryce Leedaa91e42017-12-06 14:13:01 -0800461
462 mNotTop = starter.mNotTop;
463 mDoResume = starter.mDoResume;
464 mStartFlags = starter.mStartFlags;
465 mSourceRecord = starter.mSourceRecord;
466 mPreferredDisplayId = starter.mPreferredDisplayId;
467
468 mInTask = starter.mInTask;
469 mAddingToTask = starter.mAddingToTask;
470 mReuseTask = starter.mReuseTask;
471
472 mNewTaskInfo = starter.mNewTaskInfo;
473 mNewTaskIntent = starter.mNewTaskIntent;
474 mSourceStack = starter.mSourceStack;
475
476 mTargetStack = starter.mTargetStack;
477 mMovedToFront = starter.mMovedToFront;
478 mNoAnimation = starter.mNoAnimation;
479 mKeepCurTransition = starter.mKeepCurTransition;
480 mAvoidMoveToFront = starter.mAvoidMoveToFront;
481
482 mVoiceSession = starter.mVoiceSession;
483 mVoiceInteractor = starter.mVoiceInteractor;
484
485 mIntentDelivered = starter.mIntentDelivered;
486
487 mRequest.set(starter.mRequest);
Bryce Leed3624e12017-11-30 08:51:45 -0800488 }
489
Bryce Lee4c9a5972017-12-01 22:14:24 -0800490 ActivityRecord getStartActivity() {
491 return mStartActivity;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800492 }
493
Bryce Lee4c9a5972017-12-01 22:14:24 -0800494 boolean relatedToPackage(String packageName) {
495 return (mLastStartActivityRecord[0] != null
496 && packageName.equals(mLastStartActivityRecord[0].packageName))
497 || (mStartActivity != null && packageName.equals(mStartActivity.packageName));
498 }
499
500 /**
501 * Starts an activity based on the request parameters provided earlier.
502 * @return The starter result.
503 */
504 int execute() {
Bryce Leedaa91e42017-12-06 14:13:01 -0800505 try {
506 // TODO(b/64750076): Look into passing request directly to these methods to allow
507 // for transactional diffs and preprocessing.
508 if (mRequest.mayWait) {
509 return startActivityMayWait(mRequest.caller, mRequest.callingUid,
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000510 mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid,
511 mRequest.intent, mRequest.resolvedType,
Bryce Leedaa91e42017-12-06 14:13:01 -0800512 mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
513 mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
514 mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100515 mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200516 mRequest.inTask, mRequest.reason,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100517 mRequest.allowPendingRemoteAnimationRegistryLookup,
Michal Karpinskiac116df2018-12-10 17:51:42 +0000518 mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
Bryce Leedaa91e42017-12-06 14:13:01 -0800519 } else {
520 return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
521 mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
522 mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
523 mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
524 mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
525 mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
526 mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200527 mRequest.outActivity, mRequest.inTask, mRequest.reason,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100528 mRequest.allowPendingRemoteAnimationRegistryLookup,
Michal Karpinskiac116df2018-12-10 17:51:42 +0000529 mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
Bryce Leedaa91e42017-12-06 14:13:01 -0800530 }
531 } finally {
532 onExecutionComplete();
533 }
534 }
535
536 /**
537 * Starts an activity based on the provided {@link ActivityRecord} and environment parameters.
538 * Note that this method is called internally as well as part of {@link #startActivity}.
539 *
540 * @return The start result.
541 */
542 int startResolvedActivity(final ActivityRecord r, ActivityRecord sourceRecord,
543 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
544 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
545 ActivityRecord[] outActivity) {
546 try {
547 return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
548 doResume, options, inTask, outActivity);
549 } finally {
550 onExecutionComplete();
Bryce Lee4c9a5972017-12-01 22:14:24 -0800551 }
552 }
553
554 private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700555 String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
556 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
557 IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
558 String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100559 SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200560 ActivityRecord[] outActivity, TaskRecord inTask, String reason,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100561 boolean allowPendingRemoteAnimationRegistryLookup,
Michal Karpinskiac116df2018-12-10 17:51:42 +0000562 PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700563
564 if (TextUtils.isEmpty(reason)) {
565 throw new IllegalArgumentException("Need to specify a reason.");
566 }
567 mLastStartReason = reason;
568 mLastStartActivityTimeMs = System.currentTimeMillis();
569 mLastStartActivityRecord[0] = null;
570
571 mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
572 aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
573 callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
574 options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
Michal Karpinskiac116df2018-12-10 17:51:42 +0000575 inTask, allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent,
576 allowBackgroundActivityStart);
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700577
578 if (outActivity != null) {
579 // mLastStartActivityRecord[0] is set in the call to startActivity above.
580 outActivity[0] = mLastStartActivityRecord[0];
581 }
Bryce Leef9d49542017-06-26 16:27:32 -0700582
Bryce Lee93e7f792017-10-25 15:54:55 -0700583 return getExternalResult(mLastStartActivityResult);
584 }
585
Bryce Leed3624e12017-11-30 08:51:45 -0800586 static int getExternalResult(int result) {
Bryce Leef9d49542017-06-26 16:27:32 -0700587 // Aborted results are treated as successes externally, but we must track them internally.
Bryce Lee93e7f792017-10-25 15:54:55 -0700588 return result != START_ABORTED ? result : START_SUCCESS;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700589 }
590
Bryce Leedaa91e42017-12-06 14:13:01 -0800591 /**
592 * Called when execution is complete. Sets state indicating completion and proceeds with
593 * recycling if appropriate.
594 */
595 private void onExecutionComplete() {
596 mController.onExecutionComplete(this);
597 }
598
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700599 private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800600 String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
601 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
602 IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
603 String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100604 SafeActivityOptions options,
605 boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100606 TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup,
Michal Karpinskiac116df2018-12-10 17:51:42 +0000607 PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800608 int err = ActivityManager.START_SUCCESS;
Chad Brubaker06068612017-04-06 09:43:47 -0700609 // Pull the optional Ephemeral Installer-only bundle out of the options early.
610 final Bundle verificationBundle
611 = options != null ? options.popAppVerificationBundle() : null;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800612
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700613 WindowProcessController callerApp = null;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800614 if (caller != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700615 callerApp = mService.getProcessController(caller);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800616 if (callerApp != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700617 callingPid = callerApp.getPid();
618 callingUid = callerApp.mInfo.uid;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800619 } else {
620 Slog.w(TAG, "Unable to find app for caller " + caller
621 + " (pid=" + callingPid + ") when starting: "
622 + intent.toString());
623 err = ActivityManager.START_PERMISSION_DENIED;
624 }
625 }
626
Bryce Lee93e7f792017-10-25 15:54:55 -0700627 final int userId = aInfo != null && aInfo.applicationInfo != null
628 ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800629
630 if (err == ActivityManager.START_SUCCESS) {
631 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
Andrii Kulian03c403d2016-11-11 11:14:12 -0800632 + "} from uid " + callingUid);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800633 }
634
635 ActivityRecord sourceRecord = null;
636 ActivityRecord resultRecord = null;
637 if (resultTo != null) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800638 sourceRecord = mRootActivityContainer.isInAnyStack(resultTo);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800639 if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
640 "Will send result to " + resultTo + " " + sourceRecord);
641 if (sourceRecord != null) {
642 if (requestCode >= 0 && !sourceRecord.finishing) {
643 resultRecord = sourceRecord;
644 }
645 }
646 }
647
648 final int launchFlags = intent.getFlags();
649
650 if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
651 // Transfer the result target from the source activity to the new
652 // one being started, including any failures.
653 if (requestCode >= 0) {
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100654 SafeActivityOptions.abort(options);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800655 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
656 }
657 resultRecord = sourceRecord.resultTo;
658 if (resultRecord != null && !resultRecord.isInStackLocked()) {
659 resultRecord = null;
660 }
661 resultWho = sourceRecord.resultWho;
662 requestCode = sourceRecord.requestCode;
663 sourceRecord.resultTo = null;
664 if (resultRecord != null) {
665 resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
666 }
667 if (sourceRecord.launchedFromUid == callingUid) {
668 // The new activity is being launched from the same uid as the previous
669 // activity in the flow, and asking to forward its result back to the
670 // previous. In this case the activity is serving as a trampoline between
671 // the two, so we also want to update its launchedFromPackage to be the
672 // same as the previous activity. Note that this is safe, since we know
673 // these two packages come from the same uid; the caller could just as
674 // well have supplied that same package name itself. This specifially
675 // deals with the case of an intent picker/chooser being launched in the app
676 // flow to redirect to an activity picked by the user, where we want the final
677 // activity to consider it to have been launched by the previous app activity.
678 callingPackage = sourceRecord.launchedFromPackage;
679 }
680 }
681
682 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
683 // We couldn't find a class that can handle the given Intent.
684 // That's the end of that!
685 err = ActivityManager.START_INTENT_NOT_RESOLVED;
686 }
687
688 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
689 // We couldn't find the specific class specified in the Intent.
690 // Also the end of the line.
691 err = ActivityManager.START_CLASS_NOT_FOUND;
692 }
693
694 if (err == ActivityManager.START_SUCCESS && sourceRecord != null
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800695 && sourceRecord.getTaskRecord().voiceSession != null) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800696 // If this activity is being launched as part of a voice session, we need
697 // to ensure that it is safe to do so. If the upcoming activity will also
698 // be part of the voice session, we can only launch it if it has explicitly
699 // said it supports the VOICE category, or it is a part of the calling app.
700 if ((launchFlags & FLAG_ACTIVITY_NEW_TASK) == 0
701 && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
702 try {
703 intent.addCategory(Intent.CATEGORY_VOICE);
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700704 if (!mService.getPackageManager().activitySupportsIntent(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800705 intent.getComponent(), intent, resolvedType)) {
706 Slog.w(TAG,
707 "Activity being started in current voice task does not support voice: "
708 + intent);
709 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
710 }
711 } catch (RemoteException e) {
712 Slog.w(TAG, "Failure checking voice capabilities", e);
713 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
714 }
715 }
716 }
717
718 if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
719 // If the caller is starting a new voice session, just make sure the target
720 // is actually allowing it to run this way.
721 try {
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700722 if (!mService.getPackageManager().activitySupportsIntent(intent.getComponent(),
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800723 intent, resolvedType)) {
724 Slog.w(TAG,
725 "Activity being started in new voice task does not support: "
726 + intent);
727 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
728 }
729 } catch (RemoteException e) {
730 Slog.w(TAG, "Failure checking voice capabilities", e);
731 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
732 }
733 }
734
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800735 final ActivityStack resultStack = resultRecord == null
736 ? null : resultRecord.getActivityStack();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800737
Wale Ogunwale01d66562015-12-29 08:19:19 -0800738 if (err != START_SUCCESS) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800739 if (resultRecord != null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -0800740 resultStack.sendActivityResultLocked(
741 -1, resultRecord, resultWho, requestCode, RESULT_CANCELED, null);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800742 }
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100743 SafeActivityOptions.abort(options);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800744 return err;
745 }
746
747 boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100748 requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity,
Winson Chungc9804e72018-05-15 11:01:44 -0700749 inTask != null, callerApp, resultRecord, resultStack);
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700750 abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800751 callingPid, resolvedType, aInfo.applicationInfo);
752
Michal Karpinskic02364c2019-01-22 13:00:04 +0000753 boolean abortBackgroundStart = false;
Michal Karpinski8596ded2018-11-14 14:43:48 +0000754 if (!abort) {
Michal Karpinski4fd5b842019-01-28 15:13:32 +0000755 try {
756 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
757 "shouldAbortBackgroundActivityStart");
758 abortBackgroundStart = shouldAbortBackgroundActivityStart(callingUid, callingPid,
Michal Karpinski9cbb20b2019-02-05 17:31:50 +0000759 callingPackage, realCallingUid, realCallingPid, callerApp,
760 originatingPendingIntent, allowBackgroundActivityStart, intent);
Michal Karpinski4fd5b842019-01-28 15:13:32 +0000761 } finally {
762 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
763 }
Michal Karpinskic02364c2019-01-22 13:00:04 +0000764 abort |= (abortBackgroundStart && !mService.isBackgroundActivityStartsEnabled());
765 // TODO: remove this toast after feature development is done
766 if (abortBackgroundStart) {
Michal Karpinskiac213c62019-02-19 12:38:14 +0000767 final Resources res = mService.mContext.getResources();
768 final String toastMsg = res.getString(abort
769 ? R.string.activity_starter_block_bg_activity_starts_enforcing
770 : R.string.activity_starter_block_bg_activity_starts_permissive,
771 callingPackage);
Michal Karpinskic02364c2019-01-22 13:00:04 +0000772 mService.mUiHandler.post(() -> {
773 Toast.makeText(mService.mContext, toastMsg, Toast.LENGTH_LONG).show();
774 });
775 }
Michal Karpinski8596ded2018-11-14 14:43:48 +0000776 }
777
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100778 // Merge the two options bundles, while realCallerOptions takes precedence.
779 ActivityOptions checkedOptions = options != null
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700780 ? options.getOptions(intent, aInfo, callerApp, mSupervisor) : null;
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200781 if (allowPendingRemoteAnimationRegistryLookup) {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700782 checkedOptions = mService.getActivityStartController()
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200783 .getPendingRemoteAnimationRegistry()
784 .overrideOptionsIfNeeded(callingPackage, checkedOptions);
785 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700786 if (mService.mController != null) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800787 try {
788 // The Intent we give to the watcher has the extra data
789 // stripped off, since it can contain private information.
790 Intent watchIntent = intent.cloneFilter();
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700791 abort |= !mService.mController.activityStarting(watchIntent,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800792 aInfo.applicationInfo.packageName);
793 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700794 mService.mController = null;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800795 }
796 }
797
Rubin Xu58d25992016-01-21 17:47:13 +0000798 mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage);
Benjamin Franz563707b2017-06-29 15:06:13 +0100799 if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100800 callingUid, checkedOptions)) {
Benjamin Franz563707b2017-06-29 15:06:13 +0100801 // activity start was intercepted, e.g. because the target user is currently in quiet
802 // mode (turn off work) or the target application is suspended
803 intent = mInterceptor.mIntent;
804 rInfo = mInterceptor.mRInfo;
805 aInfo = mInterceptor.mAInfo;
806 resolvedType = mInterceptor.mResolvedType;
807 inTask = mInterceptor.mInTask;
808 callingPid = mInterceptor.mCallingPid;
809 callingUid = mInterceptor.mCallingUid;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100810 checkedOptions = mInterceptor.mActivityOptions;
Benjamin Franz563707b2017-06-29 15:06:13 +0100811 }
812
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800813 if (abort) {
814 if (resultRecord != null) {
815 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Wale Ogunwale01d66562015-12-29 08:19:19 -0800816 RESULT_CANCELED, null);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800817 }
818 // We pretend to the caller that it was really started, but
819 // they will just get a cancel result.
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100820 ActivityOptions.abort(checkedOptions);
Bryce Leef9d49542017-06-26 16:27:32 -0700821 return START_ABORTED;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800822 }
823
824 // If permissions need a review before any of the app components can run, we
825 // launch the review activity and pass a pending intent to start the activity
826 // we are to launching now after the review is completed.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700827 if (aInfo != null) {
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700828 if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800829 aInfo.packageName, userId)) {
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700830 IIntentSender target = mService.getIntentSenderLocked(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800831 ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
832 callingUid, userId, null, null, 0, new Intent[]{intent},
833 new String[]{resolvedType}, PendingIntent.FLAG_CANCEL_CURRENT
834 | PendingIntent.FLAG_ONE_SHOT, null);
835
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800836 Intent newIntent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
Philip P. Moltmannc3e66d02019-01-31 15:56:18 -0800837
838 int flags = intent.getFlags();
839 flags |= Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
840
841 /*
842 * Prevent reuse of review activity: Each app needs their own review activity. By
843 * default activities launched with NEW_TASK or NEW_DOCUMENT try to reuse activities
844 * with the same launch parameters (extras are ignored). Hence to avoid possible
845 * reuse force a new activity via the MULTIPLE_TASK flag.
846 *
847 * Activities that are not launched with NEW_TASK or NEW_DOCUMENT are not re-used,
848 * hence no need to add the flag in this case.
849 */
850 if ((flags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_NEW_DOCUMENT)) != 0) {
851 flags |= Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
852 }
853 newIntent.setFlags(flags);
854
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800855 newIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, aInfo.packageName);
856 newIntent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target));
857 if (resultRecord != null) {
858 newIntent.putExtra(Intent.EXTRA_RESULT_NEEDED, true);
859 }
860 intent = newIntent;
861
862 resolvedType = null;
863 callingUid = realCallingUid;
864 callingPid = realCallingPid;
865
Svet Ganovcbcbf662018-05-10 17:25:29 -0700866 rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0,
Patrick Baumann31426b22018-05-21 13:46:40 -0700867 computeResolveFilterUid(
868 callingUid, realCallingUid, mRequest.filterCallingUid));
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800869 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
870 null /*profilerInfo*/);
871
872 if (DEBUG_PERMISSIONS_REVIEW) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800873 final ActivityStack focusedStack =
874 mRootActivityContainer.getTopDisplayFocusedStack();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800875 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true,
876 true, false) + "} from uid " + callingUid + " on display "
Andrii Kulian52d255c2018-07-13 11:32:19 -0700877 + (focusedStack == null ? DEFAULT_DISPLAY : focusedStack.mDisplayId));
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800878 }
879 }
880 }
881
882 // If we have an ephemeral app, abort the process of launching the resolved intent.
883 // Instead, launch the ephemeral installer. Once the installer is finished, it
884 // starts either the intent we resolved here [on install error] or the ephemeral
885 // app [on install success].
Patrick Baumanna89a1722018-02-07 15:26:52 -0800886 if (rInfo != null && rInfo.auxiliaryInfo != null) {
Todd Kennedye9910222017-02-21 16:00:11 -0800887 intent = createLaunchIntent(rInfo.auxiliaryInfo, ephemeralIntent,
Chad Brubaker06068612017-04-06 09:43:47 -0700888 callingPackage, verificationBundle, resolvedType, userId);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800889 resolvedType = null;
890 callingUid = realCallingUid;
891 callingPid = realCallingPid;
892
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800893 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
894 }
895
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700896 ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
Wale Ogunwalef6733932018-06-27 05:14:34 -0700897 callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800898 resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100899 mSupervisor, checkedOptions, sourceRecord);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800900 if (outActivity != null) {
901 outActivity[0] = r;
902 }
903
904 if (r.appTimeTracker == null && sourceRecord != null) {
905 // If the caller didn't specify an explicit time tracker, we want to continue
906 // tracking under any it has.
907 r.appTimeTracker = sourceRecord.appTimeTracker;
908 }
909
Wale Ogunwaled32da472018-11-16 07:19:28 -0800910 final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100911
912 // If we are starting an activity that is not from the same uid as the currently resumed
913 // one, check whether app switches are allowed.
Bryce Leec4ab62a2018-03-05 14:19:26 -0800914 if (voiceSession == null && (stack.getResumedActivity() == null
915 || stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700916 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800917 realCallingPid, realCallingUid, "Activity start")) {
Bryce Leed3624e12017-11-30 08:51:45 -0800918 mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700919 sourceRecord, startFlags, stack, callerApp));
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100920 ActivityOptions.abort(checkedOptions);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800921 return ActivityManager.START_SWITCHES_CANCELED;
922 }
923 }
924
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700925 mService.onStartActivitySetDidAppSwitch();
Bryce Leed3624e12017-11-30 08:51:45 -0800926 mController.doPendingActivityLaunches(false);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800927
Bryce Leedaa91e42017-12-06 14:13:01 -0800928 return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100929 true /* doResume */, checkedOptions, inTask, outActivity);
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -0800930 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800931
Michal Karpinski7b97a022018-12-14 15:17:29 +0000932 private boolean shouldAbortBackgroundActivityStart(int callingUid, int callingPid,
Michal Karpinski9cbb20b2019-02-05 17:31:50 +0000933 final String callingPackage, int realCallingUid, int realCallingPid,
934 WindowProcessController callerApp, PendingIntentRecord originatingPendingIntent,
935 boolean allowBackgroundActivityStart, Intent intent) {
Michal Karpinski8596ded2018-11-14 14:43:48 +0000936 // don't abort for the most important UIDs
Michal Karpinskib416f472019-01-24 14:34:28 +0000937 if (callingUid == Process.ROOT_UID || callingUid == Process.SYSTEM_UID
938 || callingUid == Process.NFC_UID) {
Michal Karpinski8596ded2018-11-14 14:43:48 +0000939 return false;
940 }
Michal Karpinskiac116df2018-12-10 17:51:42 +0000941 // don't abort if the callingUid is in the foreground or is a persistent system process
Riddle Hsua0536432019-02-16 00:38:59 +0800942 final int callingUidProcState = mService.getUidState(callingUid);
Michal Karpinski4fd5b842019-01-28 15:13:32 +0000943 final boolean callingUidHasAnyVisibleWindow =
944 mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(callingUid);
945 final boolean isCallingUidForeground = callingUidHasAnyVisibleWindow
946 || callingUidProcState == ActivityManager.PROCESS_STATE_TOP;
947 final boolean isCallingUidPersistentSystemProcess = (callingUid == Process.SYSTEM_UID)
948 || callingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
Michal Karpinskid0162852019-01-15 16:05:25 +0000949 if (isCallingUidForeground || isCallingUidPersistentSystemProcess) {
Michal Karpinski8596ded2018-11-14 14:43:48 +0000950 return false;
951 }
Michal Karpinskiac116df2018-12-10 17:51:42 +0000952 // take realCallingUid into consideration
Michal Karpinski4fd5b842019-01-28 15:13:32 +0000953 final int realCallingUidProcState = (callingUid == realCallingUid)
954 ? callingUidProcState
Riddle Hsua0536432019-02-16 00:38:59 +0800955 : mService.getUidState(realCallingUid);
Michal Karpinski4fd5b842019-01-28 15:13:32 +0000956 final boolean realCallingUidHasAnyVisibleWindow = (callingUid == realCallingUid)
957 ? callingUidHasAnyVisibleWindow
958 : mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(realCallingUid);
959 final boolean isRealCallingUidForeground = (callingUid == realCallingUid)
960 ? isCallingUidForeground
961 : realCallingUidHasAnyVisibleWindow
962 || realCallingUidProcState == ActivityManager.PROCESS_STATE_TOP;
963 final boolean isRealCallingUidPersistentSystemProcess = (callingUid == realCallingUid)
964 ? isCallingUidPersistentSystemProcess
965 : (realCallingUid == Process.SYSTEM_UID)
966 || realCallingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
Michal Karpinskiac116df2018-12-10 17:51:42 +0000967 if (realCallingUid != callingUid) {
968 // don't abort if the realCallingUid is in the foreground and callingUid isn't
Michal Karpinskid0162852019-01-15 16:05:25 +0000969 if (isRealCallingUidForeground) {
Michal Karpinskiac116df2018-12-10 17:51:42 +0000970 return false;
971 }
972 // if the realCallingUid is a persistent system process, abort if the IntentSender
973 // wasn't whitelisted to start an activity
Michal Karpinskid0162852019-01-15 16:05:25 +0000974 if (isRealCallingUidPersistentSystemProcess && allowBackgroundActivityStart) {
Michal Karpinskiac116df2018-12-10 17:51:42 +0000975 return false;
976 }
977 }
Michal Karpinski9cbb20b2019-02-05 17:31:50 +0000978 // If we don't have callerApp at this point, no caller was provided to startActivity().
979 // That's the case for PendingIntent-based starts, since the creator's process might not be
980 // up and alive. If that's the case, we retrieve the WindowProcessController for the send()
981 // caller, so that we can make the decision based on its foreground/whitelisted state.
982 if (callerApp == null) {
983 callerApp = mService.getProcessController(realCallingPid, realCallingUid);
984 }
985 if (callerApp != null) {
986 // don't abort if the callerApp has any visible activity
987 if (callerApp.hasForegroundActivities()) {
988 return false;
989 }
990 // don't abort if the callerApp is instrumenting with background activity starts privs
991 if (callerApp.isInstrumentingWithBackgroundActivityStartPrivileges()) {
992 return false;
993 }
994 // don't abort if the caller is currently temporarily whitelisted
995 if (callerApp.areBackgroundActivityStartsAllowed()) {
996 return false;
997 }
Michal Karpinski8596ded2018-11-14 14:43:48 +0000998 }
Michal Karpinski7b97a022018-12-14 15:17:29 +0000999 // don't abort if the callingUid has START_ACTIVITIES_FROM_BACKGROUND permission
1000 if (mService.checkPermission(START_ACTIVITIES_FROM_BACKGROUND, callingPid, callingUid)
1001 == PERMISSION_GRANTED) {
1002 return false;
1003 }
Michal Karpinski82bb5902018-11-28 15:52:52 +00001004 // don't abort if the caller has the same uid as the recents component
1005 if (mSupervisor.mRecentTasks.isCallerRecents(callingUid)) {
1006 return false;
1007 }
Michal Karpinski4026cae2019-02-12 11:51:47 +00001008 // don't abort if the callingPackage is the device owner
1009 if (mService.isDeviceOwner(callingPackage)) {
Michal Karpinski302dcec2019-02-01 11:48:25 +00001010 return false;
1011 }
Michal Karpinskic02364c2019-01-22 13:00:04 +00001012 // anything that has fallen through would currently be aborted
1013 Slog.w(TAG, "Background activity start [callingPackage: " + callingPackage
Michal Karpinskid0162852019-01-15 16:05:25 +00001014 + "; callingUid: " + callingUid
1015 + "; isCallingUidForeground: " + isCallingUidForeground
1016 + "; isCallingUidPersistentSystemProcess: " + isCallingUidPersistentSystemProcess
1017 + "; realCallingUid: " + realCallingUid
1018 + "; isRealCallingUidForeground: " + isRealCallingUidForeground
1019 + "; isRealCallingUidPersistentSystemProcess: "
1020 + isRealCallingUidPersistentSystemProcess
1021 + "; originatingPendingIntent: " + originatingPendingIntent
1022 + "; isBgStartWhitelisted: " + allowBackgroundActivityStart
1023 + "; intent: " + intent
Michal Karpinski9cbb20b2019-02-05 17:31:50 +00001024 + "; callerApp: " + callerApp
Michal Karpinskid0162852019-01-15 16:05:25 +00001025 + "]");
Michal Karpinski4fd5b842019-01-28 15:13:32 +00001026 // log aborted activity start to TRON
1027 if (mService.isActivityStartsLoggingEnabled()) {
1028 mSupervisor.getActivityMetricsLogger().logAbortedBgActivityStart(intent, callerApp,
1029 callingUid, callingPackage, callingUidProcState, callingUidHasAnyVisibleWindow,
1030 realCallingUid, realCallingUidProcState, realCallingUidHasAnyVisibleWindow,
Michal Karpinski201bc0c2018-07-20 15:32:00 +01001031 (originatingPendingIntent != null));
Michal Karpinski201bc0c2018-07-20 15:32:00 +01001032 }
Michal Karpinski4fd5b842019-01-28 15:13:32 +00001033 return true;
Michal Karpinski201bc0c2018-07-20 15:32:00 +01001034 }
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001035
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001036 /**
1037 * Creates a launch intent for the given auxiliary resolution data.
1038 */
Patrick Baumann577d4022018-01-31 16:55:10 +00001039 private @NonNull Intent createLaunchIntent(@Nullable AuxiliaryResolveInfo auxiliaryResponse,
Chad Brubaker06068612017-04-06 09:43:47 -07001040 Intent originalIntent, String callingPackage, Bundle verificationBundle,
1041 String resolvedType, int userId) {
Patrick Baumann577d4022018-01-31 16:55:10 +00001042 if (auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo) {
Todd Kennedye9910222017-02-21 16:00:11 -08001043 // request phase two resolution
Wale Ogunwale906f9c62018-07-23 11:23:44 -07001044 mService.getPackageManagerInternalLocked().requestInstantAppResolutionPhaseTwo(
Chad Brubaker06068612017-04-06 09:43:47 -07001045 auxiliaryResponse, originalIntent, resolvedType, callingPackage,
1046 verificationBundle, userId);
Todd Kennedye9910222017-02-21 16:00:11 -08001047 }
Todd Kennedydfc27c62017-05-17 15:32:10 -07001048 return InstantAppResolver.buildEphemeralInstallerIntent(
Patrick Baumann577d4022018-01-31 16:55:10 +00001049 originalIntent,
1050 InstantAppResolver.sanitizeIntent(originalIntent),
1051 auxiliaryResponse == null ? null : auxiliaryResponse.failureIntent,
1052 callingPackage,
1053 verificationBundle,
1054 resolvedType,
1055 userId,
1056 auxiliaryResponse == null ? null : auxiliaryResponse.installFailureActivity,
1057 auxiliaryResponse == null ? null : auxiliaryResponse.token,
1058 auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo,
1059 auxiliaryResponse == null ? null : auxiliaryResponse.filters);
Todd Kennedye9910222017-02-21 16:00:11 -08001060 }
1061
Riddle Hsu16567132018-08-16 21:37:47 +08001062 void postStartActivityProcessing(ActivityRecord r, int result,
1063 ActivityStack startedActivityStack) {
Bryce Lee7f936862017-05-09 15:33:18 -07001064 if (ActivityManager.isStartResultFatalError(result)) {
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -08001065 return;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001066 }
Filip Gruszczynski303210b2016-01-08 16:28:08 -08001067
Chong Zhang5022da32016-06-21 16:31:37 -07001068 // We're waiting for an activity launch to finish, but that activity simply
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001069 // brought another activity to front. We must also handle the case where the task is already
1070 // in the front as a result of the trampoline activity being in the same task (it will be
1071 // considered focused as the trampoline will be finished). Let startActivityMayWait() know
1072 // about this, so it waits for the new activity to become visible instead.
1073 mSupervisor.reportWaitingActivityLaunchedIfNeeded(r, result);
Chong Zhang5022da32016-06-21 16:31:37 -07001074
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001075 if (startedActivityStack == null) {
1076 return;
1077 }
1078
Wale Ogunwaleac36e4d2017-11-29 13:30:26 -08001079 final int clearTaskFlags = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK;
1080 boolean clearedTask = (mLaunchFlags & clearTaskFlags) == clearTaskFlags
1081 && mReuseTask != null;
Wale Ogunwale7d7973a2018-04-05 10:25:59 -07001082 if (result == START_TASK_TO_FRONT || result == START_DELIVERED_TO_TOP || clearedTask) {
1083 // The activity was already running so it wasn't started, but either brought to the
1084 // front or the new intent was delivered to it since it was already in front. Notify
1085 // anyone interested in this piece of information.
1086 switch (startedActivityStack.getWindowingMode()) {
1087 case WINDOWING_MODE_PINNED:
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001088 mService.getTaskChangeNotificationController().notifyPinnedActivityRestartAttempt(
Wale Ogunwale7d7973a2018-04-05 10:25:59 -07001089 clearedTask);
1090 break;
1091 case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
Louis Changbd48dca2018-08-29 17:44:34 +08001092 final ActivityStack homeStack =
1093 startedActivityStack.getDisplay().getHomeStack();
Wale Ogunwale7d7973a2018-04-05 10:25:59 -07001094 if (homeStack != null && homeStack.shouldBeVisible(null /* starting */)) {
1095 mService.mWindowManager.showRecentApps();
1096 }
1097 break;
1098 }
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -08001099 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001100 }
1101
Bryce Lee4c9a5972017-12-01 22:14:24 -08001102 private int startActivityMayWait(IApplicationThread caller, int callingUid,
Michal Karpinski84d9ebd2019-01-17 18:28:59 +00001103 String callingPackage, int requestRealCallingPid, int requestRealCallingUid,
1104 Intent intent, String resolvedType, IVoiceInteractionSession voiceSession,
1105 IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode,
1106 int startFlags, ProfilerInfo profilerInfo, WaitResult outResult,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001107 Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +02001108 int userId, TaskRecord inTask, String reason,
Michal Karpinski201bc0c2018-07-20 15:32:00 +01001109 boolean allowPendingRemoteAnimationRegistryLookup,
Michal Karpinskiac116df2018-12-10 17:51:42 +00001110 PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001111 // Refuse possible leaked file descriptors
1112 if (intent != null && intent.hasFileDescriptors()) {
1113 throw new IllegalArgumentException("File descriptors passed in Intent");
1114 }
Igor Murashkin212d06c2018-10-22 16:34:39 -07001115 mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001116 boolean componentSpecified = intent.getComponent() != null;
1117
Michal Karpinski84d9ebd2019-01-17 18:28:59 +00001118 final int realCallingPid = requestRealCallingPid != Request.DEFAULT_REAL_CALLING_PID
1119 ? requestRealCallingPid
1120 : Binder.getCallingPid();
1121 final int realCallingUid = requestRealCallingUid != Request.DEFAULT_REAL_CALLING_UID
1122 ? requestRealCallingUid
1123 : Binder.getCallingUid();
Makoto Onuki1a342742018-04-26 14:56:59 -07001124
Svet Ganovcbcbf662018-05-10 17:25:29 -07001125 int callingPid;
1126 if (callingUid >= 0) {
1127 callingPid = -1;
1128 } else if (caller == null) {
1129 callingPid = realCallingPid;
1130 callingUid = realCallingUid;
1131 } else {
1132 callingPid = callingUid = -1;
1133 }
1134
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001135 // Save a copy in case ephemeral needs it
1136 final Intent ephemeralIntent = new Intent(intent);
1137 // Don't modify the client's object!
1138 intent = new Intent(intent);
Todd Kennedyb21be122017-03-24 14:10:01 -07001139 if (componentSpecified
Patrick Baumann531db462018-02-13 13:01:47 -08001140 && !(Intent.ACTION_VIEW.equals(intent.getAction()) && intent.getData() == null)
Patrick Baumann577d4022018-01-31 16:55:10 +00001141 && !Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE.equals(intent.getAction())
1142 && !Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE.equals(intent.getAction())
Wale Ogunwale906f9c62018-07-23 11:23:44 -07001143 && mService.getPackageManagerInternalLocked()
Todd Kennedyb21be122017-03-24 14:10:01 -07001144 .isInstantAppInstallerComponent(intent.getComponent())) {
1145 // intercept intents targeted directly to the ephemeral installer the
Patrick Baumann577d4022018-01-31 16:55:10 +00001146 // ephemeral installer should never be started with a raw Intent; instead
Todd Kennedyb21be122017-03-24 14:10:01 -07001147 // adjust the intent so it looks like a "normal" instant app launch
1148 intent.setComponent(null /*component*/);
1149 componentSpecified = false;
1150 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001151
Makoto Onuki1a342742018-04-26 14:56:59 -07001152 ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
Patrick Baumann31426b22018-05-21 13:46:40 -07001153 0 /* matchFlags */,
1154 computeResolveFilterUid(
1155 callingUid, realCallingUid, mRequest.filterCallingUid));
Kenny Guyb1b30262016-02-09 16:02:35 +00001156 if (rInfo == null) {
1157 UserInfo userInfo = mSupervisor.getUserInfo(userId);
1158 if (userInfo != null && userInfo.isManagedProfile()) {
1159 // Special case for managed profiles, if attempting to launch non-cryto aware
1160 // app in a locked managed profile from an unlocked parent allow it to resolve
1161 // as user will be sent via confirm credentials to unlock the profile.
1162 UserManager userManager = UserManager.get(mService.mContext);
Fyodor Kupolovce4db0a2016-05-11 14:21:18 -07001163 boolean profileLockedAndParentUnlockingOrUnlocked = false;
Tony Mak13436452016-02-24 11:08:38 +00001164 long token = Binder.clearCallingIdentity();
1165 try {
Fyodor Kupolovce4db0a2016-05-11 14:21:18 -07001166 UserInfo parent = userManager.getProfileParent(userId);
1167 profileLockedAndParentUnlockingOrUnlocked = (parent != null)
1168 && userManager.isUserUnlockingOrUnlocked(parent.id)
1169 && !userManager.isUserUnlockingOrUnlocked(userId);
Tony Mak13436452016-02-24 11:08:38 +00001170 } finally {
1171 Binder.restoreCallingIdentity(token);
1172 }
Fyodor Kupolovce4db0a2016-05-11 14:21:18 -07001173 if (profileLockedAndParentUnlockingOrUnlocked) {
Kenny Guyb1b30262016-02-09 16:02:35 +00001174 rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
Jeff Sharkey8a372a02016-03-16 16:25:45 -06001175 PackageManager.MATCH_DIRECT_BOOT_AWARE
Patrick Baumann78380272018-04-04 10:41:01 -07001176 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
Patrick Baumann31426b22018-05-21 13:46:40 -07001177 computeResolveFilterUid(
1178 callingUid, realCallingUid, mRequest.filterCallingUid));
Kenny Guyb1b30262016-02-09 16:02:35 +00001179 }
1180 }
1181 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001182 // Collect information about the target of the Intent.
1183 ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
1184
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001185 synchronized (mService.mGlobalLock) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001186 final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
Andrii Kulian8072d112016-09-16 11:11:01 -07001187 stack.mConfigWillChange = globalConfig != null
Wale Ogunwalef6733932018-06-27 05:14:34 -07001188 && mService.getGlobalConfiguration().diff(globalConfig) != 0;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001189 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
1190 "Starting activity when config will change = " + stack.mConfigWillChange);
1191
1192 final long origId = Binder.clearCallingIdentity();
1193
1194 if (aInfo != null &&
1195 (aInfo.applicationInfo.privateFlags
Dianne Hackbornc8e4fad2018-05-04 11:31:09 -07001196 & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0 &&
Wale Ogunwale214f3482018-10-04 11:00:47 -07001197 mService.mHasHeavyWeightFeature) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001198 // This may be a heavy-weight process! Check to see if we already
1199 // have another, different heavy-weight process running.
1200 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
Wale Ogunwale53783742018-09-16 10:21:51 -07001201 final WindowProcessController heavy = mService.mHeavyWeightProcess;
1202 if (heavy != null && (heavy.mInfo.uid != aInfo.applicationInfo.uid
1203 || !heavy.mName.equals(aInfo.processName))) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001204 int appCallingUid = callingUid;
1205 if (caller != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001206 WindowProcessController callerApp =
1207 mService.getProcessController(caller);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001208 if (callerApp != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001209 appCallingUid = callerApp.mInfo.uid;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001210 } else {
1211 Slog.w(TAG, "Unable to find app for caller " + caller
1212 + " (pid=" + callingPid + ") when starting: "
1213 + intent.toString());
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001214 SafeActivityOptions.abort(options);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001215 return ActivityManager.START_PERMISSION_DENIED;
1216 }
1217 }
1218
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07001219 IIntentSender target = mService.getIntentSenderLocked(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001220 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
1221 appCallingUid, userId, null, null, 0, new Intent[] { intent },
1222 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
1223 | PendingIntent.FLAG_ONE_SHOT, null);
1224
1225 Intent newIntent = new Intent();
1226 if (requestCode >= 0) {
1227 // Caller is requesting a result.
1228 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
1229 }
1230 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
1231 new IntentSender(target));
Wale Ogunwale53783742018-09-16 10:21:51 -07001232 heavy.updateIntentForHeavyWeightActivity(newIntent);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001233 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
1234 aInfo.packageName);
1235 newIntent.setFlags(intent.getFlags());
1236 newIntent.setClassName("android",
1237 HeavyWeightSwitcherActivity.class.getName());
1238 intent = newIntent;
1239 resolvedType = null;
1240 caller = null;
1241 callingUid = Binder.getCallingUid();
1242 callingPid = Binder.getCallingPid();
1243 componentSpecified = true;
Makoto Onuki1a342742018-04-26 14:56:59 -07001244 rInfo = mSupervisor.resolveIntent(intent, null /*resolvedType*/, userId,
Patrick Baumann31426b22018-05-21 13:46:40 -07001245 0 /* matchFlags */, computeResolveFilterUid(
1246 callingUid, realCallingUid, mRequest.filterCallingUid));
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001247 aInfo = rInfo != null ? rInfo.activityInfo : null;
1248 if (aInfo != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001249 aInfo = mService.mAmInternal.getActivityInfoForUser(aInfo, userId);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001250 }
1251 }
1252 }
1253 }
1254
Jorim Jaggi275561a2016-02-23 10:11:02 -05001255 final ActivityRecord[] outRecord = new ActivityRecord[1];
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001256 int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
1257 voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
1258 callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +02001259 ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
Michal Karpinskiac116df2018-12-10 17:51:42 +00001260 allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent,
1261 allowBackgroundActivityStart);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001262
1263 Binder.restoreCallingIdentity(origId);
1264
1265 if (stack.mConfigWillChange) {
1266 // If the caller also wants to switch to a new configuration,
1267 // do so now. This allows a clean switch, as we are waiting
1268 // for the current activity to pause (so we will not destroy
1269 // it), and have not yet started the next activity.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001270 mService.mAmInternal.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001271 "updateConfiguration()");
1272 stack.mConfigWillChange = false;
1273 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
1274 "Updating to new configuration after starting activity.");
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001275 mService.updateConfigurationLocked(globalConfig, null, false);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001276 }
1277
Vishnu Nair132ee832018-09-28 15:00:05 -07001278 // Notify ActivityMetricsLogger that the activity has launched. ActivityMetricsLogger
1279 // will then wait for the windows to be drawn and populate WaitResult.
1280 mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outRecord[0]);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001281 if (outResult != null) {
1282 outResult.result = res;
Bryce Lee4a194382017-04-04 14:32:48 -07001283
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001284 final ActivityRecord r = outRecord[0];
1285
1286 switch(res) {
1287 case START_SUCCESS: {
1288 mSupervisor.mWaitingActivityLaunched.add(outResult);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001289 do {
1290 try {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001291 mService.mGlobalLock.wait();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001292 } catch (InterruptedException e) {
1293 }
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001294 } while (outResult.result != START_TASK_TO_FRONT
1295 && !outResult.timeout && outResult.who == null);
1296 if (outResult.result == START_TASK_TO_FRONT) {
1297 res = START_TASK_TO_FRONT;
1298 }
1299 break;
1300 }
1301 case START_DELIVERED_TO_TOP: {
1302 outResult.timeout = false;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001303 outResult.who = r.mActivityComponent;
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001304 outResult.totalTime = 0;
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001305 break;
1306 }
1307 case START_TASK_TO_FRONT: {
1308 // ActivityRecord may represent a different activity, but it should not be
1309 // in the resumed state.
Bryce Lee7ace3952018-02-16 14:34:32 -08001310 if (r.nowVisible && r.isState(RESUMED)) {
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001311 outResult.timeout = false;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001312 outResult.who = r.mActivityComponent;
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001313 outResult.totalTime = 0;
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001314 } else {
Vishnu Nair132ee832018-09-28 15:00:05 -07001315 final long startTimeMs = SystemClock.uptimeMillis();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001316 mSupervisor.waitActivityVisible(
1317 r.mActivityComponent, outResult, startTimeMs);
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001318 // Note: the timeout variable is not currently not ever set.
1319 do {
1320 try {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001321 mService.mGlobalLock.wait();
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001322 } catch (InterruptedException e) {
1323 }
1324 } while (!outResult.timeout && outResult.who == null);
1325 }
1326 break;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001327 }
1328 }
1329 }
1330
1331 return res;
1332 }
1333 }
1334
Svet Ganovcbcbf662018-05-10 17:25:29 -07001335 /**
1336 * Compute the logical UID based on which the package manager would filter
1337 * app components i.e. based on which the instant app policy would be applied
1338 * because it is the logical calling UID.
1339 *
1340 * @param customCallingUid The UID on whose behalf to make the call.
1341 * @param actualCallingUid The UID actually making the call.
Patrick Baumann31426b22018-05-21 13:46:40 -07001342 * @param filterCallingUid The UID to be used to filter for instant apps.
Svet Ganovcbcbf662018-05-10 17:25:29 -07001343 * @return The logical UID making the call.
1344 */
Patrick Baumann31426b22018-05-21 13:46:40 -07001345 static int computeResolveFilterUid(int customCallingUid, int actualCallingUid,
1346 int filterCallingUid) {
1347 return filterCallingUid != UserHandle.USER_NULL
1348 ? filterCallingUid
1349 : (customCallingUid >= 0 ? customCallingUid : actualCallingUid);
Svet Ganovcbcbf662018-05-10 17:25:29 -07001350 }
1351
Bryce Leedaa91e42017-12-06 14:13:01 -08001352 private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
1353 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1354 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
1355 ActivityRecord[] outActivity) {
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001356 int result = START_CANCELED;
Riddle Hsu16567132018-08-16 21:37:47 +08001357 final ActivityStack startedActivityStack;
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001358 try {
1359 mService.mWindowManager.deferSurfaceLayout();
1360 result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
Bryce Lee4a194382017-04-04 14:32:48 -07001361 startFlags, doResume, options, inTask, outActivity);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001362 } finally {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001363 final ActivityStack currentStack = r.getActivityStack();
Riddle Hsu16567132018-08-16 21:37:47 +08001364 startedActivityStack = currentStack != null ? currentStack : mTargetStack;
1365
1366 if (ActivityManager.isStartResultSuccessful(result)) {
1367 if (startedActivityStack != null) {
1368 // If there is no state change (e.g. a resumed activity is reparented to
1369 // top of another display) to trigger a visibility/configuration checking,
1370 // we have to update the configuration for changing to different display.
1371 final ActivityRecord currentTop =
1372 startedActivityStack.topRunningActivityLocked();
1373 if (currentTop != null && currentTop.shouldUpdateConfigForDisplayChanged()) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001374 mRootActivityContainer.ensureVisibilityAndConfig(
1375 currentTop, currentTop.getDisplayId(),
Riddle Hsu16567132018-08-16 21:37:47 +08001376 true /* markFrozenIfConfigChanged */, false /* deferResume */);
1377 }
1378 }
1379 } else {
1380 // If we are not able to proceed, disassociate the activity from the task.
1381 // Leaving an activity in an incomplete state can lead to issues, such as
1382 // performing operations without a window container.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001383 final ActivityStack stack = mStartActivity.getActivityStack();
Riddle Hsu16567132018-08-16 21:37:47 +08001384 if (stack != null) {
1385 stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,
1386 null /* intentResultData */, "startActivity", true /* oomAdj */);
1387 }
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001388 }
1389 mService.mWindowManager.continueSurfaceLayout();
1390 }
1391
Riddle Hsu16567132018-08-16 21:37:47 +08001392 postStartActivityProcessing(r, result, startedActivityStack);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001393
1394 return result;
1395 }
1396
1397 // Note: This method should only be called from {@link startActivity}.
Wale Ogunwale01d66562015-12-29 08:19:19 -08001398 private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
1399 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
Bryce Lee4a194382017-04-04 14:32:48 -07001400 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
1401 ActivityRecord[] outActivity) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001402
1403 setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
1404 voiceInteractor);
Louis Chang39ba54b2018-10-18 11:28:57 +08001405 final int preferredWindowingMode = mLaunchParams.mWindowingMode;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001406
Louis Chang6fb1e842018-12-03 16:07:50 +08001407 computeLaunchingTaskFlags();
1408
1409 computeSourceStack();
1410
1411 mIntent.setFlags(mLaunchFlags);
1412
1413 ActivityRecord reusedActivity = getReusableIntentActivity();
1414
1415 mSupervisor.getLaunchParamsController().calculate(
1416 reusedActivity != null ? reusedActivity.getTaskRecord() : mInTask,
1417 r.info.windowLayout, r, sourceRecord, options, PHASE_BOUNDS, mLaunchParams);
1418 mPreferredDisplayId =
1419 mLaunchParams.hasPreferredDisplay() ? mLaunchParams.mPreferredDisplayId
1420 : DEFAULT_DISPLAY;
1421
Louis Changbd48dca2018-08-29 17:44:34 +08001422 // Do not start home activity if it cannot be launched on preferred display. We are not
1423 // doing this in ActivityStackSupervisor#canPlaceEntityOnDisplay because it might
1424 // fallback to launch on other displays.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001425 if (r.isActivityTypeHome() && !mRootActivityContainer.canStartHomeOnDisplay(r.info,
Louis Changdd3592a2018-11-05 11:04:14 +08001426 mPreferredDisplayId, true /* allowInstrumenting */)) {
Louis Changbd48dca2018-08-29 17:44:34 +08001427 Slog.w(TAG, "Cannot launch home on display " + mPreferredDisplayId);
1428 return START_CANCELED;
1429 }
1430
Bryce Lee4a194382017-04-04 14:32:48 -07001431 if (reusedActivity != null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001432 // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but
1433 // still needs to be a lock task mode violation since the task gets cleared out and
1434 // the device would otherwise leave the locked task.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001435 if (mService.getLockTaskController().isLockTaskModeViolation(
1436 reusedActivity.getTaskRecord(),
Wale Ogunwale01d66562015-12-29 08:19:19 -08001437 (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1438 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001439 Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
1440 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
1441 }
1442
Bryce Leef65ee7e2018-03-26 16:03:47 -07001443 // True if we are clearing top and resetting of a standard (default) launch mode
1444 // ({@code LAUNCH_MULTIPLE}) activity. The existing activity will be finished.
1445 final boolean clearTopAndResetStandardLaunchMode =
1446 (mLaunchFlags & (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED))
1447 == (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
1448 && mLaunchMode == LAUNCH_MULTIPLE;
1449
1450 // If mStartActivity does not have a task associated with it, associate it with the
1451 // reused activity's task. Do not do so if we're clearing top and resetting for a
1452 // standard launchMode activity.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001453 if (mStartActivity.getTaskRecord() == null && !clearTopAndResetStandardLaunchMode) {
1454 mStartActivity.setTask(reusedActivity.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001455 }
Bryce Leef65ee7e2018-03-26 16:03:47 -07001456
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001457 if (reusedActivity.getTaskRecord().intent == null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001458 // This task was started because of movement of the activity based on affinity...
1459 // Now that we are actually launching it, we can assign the base intent.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001460 reusedActivity.getTaskRecord().setIntent(mStartActivity);
Louis Changb45ee7e2019-01-17 10:36:56 +08001461 } else {
1462 final boolean taskOnHome =
1463 (mStartActivity.intent.getFlags() & FLAG_ACTIVITY_TASK_ON_HOME) != 0;
1464 if (taskOnHome) {
1465 reusedActivity.getTaskRecord().intent.addFlags(FLAG_ACTIVITY_TASK_ON_HOME);
1466 } else {
1467 reusedActivity.getTaskRecord().intent.removeFlags(FLAG_ACTIVITY_TASK_ON_HOME);
1468 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001469 }
1470
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001471 // This code path leads to delivering a new intent, we want to make sure we schedule it
1472 // as the first operation, in case the activity will be resumed as a result of later
1473 // operations.
1474 if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
Daichi Hirono15a02992016-04-27 18:47:01 +09001475 || isDocumentLaunchesIntoExisting(mLaunchFlags)
Bryce Lee7daee392017-10-12 13:46:18 -07001476 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001477 final TaskRecord task = reusedActivity.getTaskRecord();
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001478
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001479 // In this situation we want to remove all activities from the task up to the one
1480 // being started. In most cases this means we are resetting the task to its initial
1481 // state.
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001482 final ActivityRecord top = task.performClearTaskForReuseLocked(mStartActivity,
1483 mLaunchFlags);
1484
Bryce Lee4a194382017-04-04 14:32:48 -07001485 // The above code can remove {@code reusedActivity} from the task, leading to the
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001486 // the {@code ActivityRecord} removing its reference to the {@code TaskRecord}. The
1487 // task reference is needed in the call below to
1488 // {@link setTargetStackAndMoveToFrontIfNeeded}.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001489 if (reusedActivity.getTaskRecord() == null) {
Bryce Lee4a194382017-04-04 14:32:48 -07001490 reusedActivity.setTask(task);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001491 }
1492
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001493 if (top != null) {
1494 if (top.frontOfTask) {
1495 // Activity aliases may mean we use different intents for the top activity,
1496 // so make sure the task now has the identity of the new intent.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001497 top.getTaskRecord().setIntent(mStartActivity);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001498 }
Bryce Lee325e09682017-10-05 17:20:25 -07001499 deliverNewIntent(top);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001500 }
1501 }
1502
Wale Ogunwaled32da472018-11-16 07:19:28 -08001503 mRootActivityContainer.sendPowerHintForLaunchStartIfNeeded
1504 (false /* forceSend */, reusedActivity);
Wei Wang98f03f92016-05-18 11:32:52 -07001505
Bryce Lee4a194382017-04-04 14:32:48 -07001506 reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001507
Bryce Lee89cd19a2017-05-17 15:18:35 -07001508 final ActivityRecord outResult =
1509 outActivity != null && outActivity.length > 0 ? outActivity[0] : null;
1510
1511 // When there is a reused activity and the current result is a trampoline activity,
1512 // set the reused activity as the result.
1513 if (outResult != null && (outResult.finishing || outResult.noDisplay)) {
1514 outActivity[0] = reusedActivity;
1515 }
1516
Wale Ogunwale01d66562015-12-29 08:19:19 -08001517 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1518 // We don't need to start a new activity, and the client said not to do anything
1519 // if that is the case, so this is it! And for paranoia, make sure we have
1520 // correctly resumed the top activity.
1521 resumeTargetStackIfNeeded();
1522 return START_RETURN_INTENT_TO_CALLER;
1523 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001524
Bryce Leef65ee7e2018-03-26 16:03:47 -07001525 if (reusedActivity != null) {
1526 setTaskFromIntentActivity(reusedActivity);
1527
1528 if (!mAddingToTask && mReuseTask == null) {
1529 // We didn't do anything... but it was needed (a.k.a., client don't use that
1530 // intent!) And for paranoia, make sure we have correctly resumed the top activity.
1531
1532 resumeTargetStackIfNeeded();
1533 if (outActivity != null && outActivity.length > 0) {
1534 outActivity[0] = reusedActivity;
1535 }
1536
1537 return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP;
Jorim Jaggicdfc04e2017-04-28 19:06:24 +02001538 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001539 }
1540 }
1541
1542 if (mStartActivity.packageName == null) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001543 final ActivityStack sourceStack = mStartActivity.resultTo != null
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001544 ? mStartActivity.resultTo.getActivityStack() : null;
Andrii Kulian02b7a832016-10-06 23:11:56 -07001545 if (sourceStack != null) {
1546 sourceStack.sendActivityResultLocked(-1 /* callingUid */, mStartActivity.resultTo,
1547 mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,
1548 null /* data */);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001549 }
1550 ActivityOptions.abort(mOptions);
1551 return START_CLASS_NOT_FOUND;
1552 }
1553
1554 // If the activity being launched is the same as the one currently at the top, then
1555 // we need to check if it should only be launched once.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001556 final ActivityStack topStack = mRootActivityContainer.getTopDisplayFocusedStack();
Wale Ogunwale30e441d2017-11-09 08:28:45 -08001557 final ActivityRecord topFocused = topStack.getTopActivity();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001558 final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
1559 final boolean dontStart = top != null && mStartActivity.resultTo == null
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001560 && top.mActivityComponent.equals(mStartActivity.mActivityComponent)
1561 && top.mUserId == mStartActivity.mUserId
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001562 && top.attachedToProcess()
Wale Ogunwale01d66562015-12-29 08:19:19 -08001563 && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
Louis Changbd48dca2018-08-29 17:44:34 +08001564 || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK))
1565 // This allows home activity to automatically launch on secondary display when
1566 // display added, if home was the top activity on default display, instead of
1567 // sending new intent to the home activity on default display.
1568 && (!top.isActivityTypeHome() || top.getDisplayId() == mPreferredDisplayId);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001569 if (dontStart) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001570 // For paranoia, make sure we have correctly resumed the top activity.
1571 topStack.mLastPausedActivity = null;
1572 if (mDoResume) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001573 mRootActivityContainer.resumeFocusedStacksTopActivities();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001574 }
1575 ActivityOptions.abort(mOptions);
1576 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1577 // We don't need to start a new activity, and the client said not to do
1578 // anything if that is the case, so this is it!
1579 return START_RETURN_INTENT_TO_CALLER;
1580 }
Bryce Lee325e09682017-10-05 17:20:25 -07001581
1582 deliverNewIntent(top);
Chong Zhangd44063c2016-04-08 11:52:30 -07001583
1584 // Don't use mStartActivity.task to show the toast. We're not starting a new activity
1585 // but reusing 'top'. Fields in mStartActivity may not be fully initialized.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001586 mSupervisor.handleNonResizableTaskIfNeeded(top.getTaskRecord(), preferredWindowingMode,
Louis Chang39ba54b2018-10-18 11:28:57 +08001587 mPreferredDisplayId, topStack);
Chong Zhangd44063c2016-04-08 11:52:30 -07001588
Wale Ogunwale01d66562015-12-29 08:19:19 -08001589 return START_DELIVERED_TO_TOP;
1590 }
1591
1592 boolean newTask = false;
1593 final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001594 ? mSourceRecord.getTaskRecord() : null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001595
1596 // Should this be considered a new task?
Chong Zhang6cda19c2016-06-14 19:07:56 -07001597 int result = START_SUCCESS;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001598 if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
1599 && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1600 newTask = true;
Louis Changceeb5062018-09-17 18:13:52 +08001601 result = setTaskFromReuseOrCreateNewTask(taskToAffiliate);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001602 } else if (mSourceRecord != null) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07001603 result = setTaskFromSourceRecord();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001604 } else if (mInTask != null) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07001605 result = setTaskFromInTask();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001606 } else {
1607 // This not being started from an existing activity, and not part of a new task...
1608 // just put it in the top task, though these days this case should never happen.
1609 setTaskToCurrentTopOrCreateNewTask();
1610 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07001611 if (result != START_SUCCESS) {
1612 return result;
1613 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001614
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07001615 mService.mUgmInternal.grantUriPermissionFromIntent(mCallingUid, mStartActivity.packageName,
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001616 mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.mUserId);
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001617 mService.getPackageManagerInternalLocked().grantEphemeralAccess(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001618 mStartActivity.mUserId, mIntent, UserHandle.getAppId(mStartActivity.appInfo.uid),
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001619 UserHandle.getAppId(mCallingUid));
Wale Ogunwale01d66562015-12-29 08:19:19 -08001620 if (newTask) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001621 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, mStartActivity.mUserId,
1622 mStartActivity.getTaskRecord().taskId);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001623 }
1624 ActivityStack.logStartActivity(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001625 EventLogTags.AM_CREATE_ACTIVITY, mStartActivity, mStartActivity.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001626 mTargetStack.mLastPausedActivity = null;
Wei Wang98f03f92016-05-18 11:32:52 -07001627
Wale Ogunwaled32da472018-11-16 07:19:28 -08001628 mRootActivityContainer.sendPowerHintForLaunchStartIfNeeded(
1629 false /* forceSend */, mStartActivity);
Wei Wang98f03f92016-05-18 11:32:52 -07001630
Winson Chungb5c41b72016-12-07 15:00:47 -08001631 mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
1632 mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001633 if (mDoResume) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001634 final ActivityRecord topTaskActivity =
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001635 mStartActivity.getTaskRecord().topRunningActivityLocked();
Wale Ogunwale3b232392016-05-13 15:37:13 -07001636 if (!mTargetStack.isFocusable()
Wale Ogunwale68741142016-05-17 09:40:02 -07001637 || (topTaskActivity != null && topTaskActivity.mTaskOverlay
1638 && mStartActivity != topTaskActivity)) {
Filip Gruszczynski3d7fdc12016-01-31 17:33:29 -08001639 // If the activity is not focusable, we can't resume it, but still would like to
1640 // make sure it becomes visible as it starts (this will also trigger entry
1641 // animation). An example of this are PIP activities.
Wale Ogunwale3b232392016-05-13 15:37:13 -07001642 // Also, we don't want to resume activities in a task that currently has an overlay
1643 // as the starting activity just needs to be in the visible paused state until the
1644 // over is removed.
Andrii Kulian6b321512019-01-23 06:37:00 +00001645 mTargetStack.ensureActivitiesVisibleLocked(mStartActivity, 0, !PRESERVE_WINDOWS);
Wale Ogunwaleae846f42016-02-22 14:00:56 -08001646 // Go ahead and tell window manager to execute app transition for this activity
1647 // since the app transition will not be triggered through the resume channel.
Wale Ogunwale3a256e62018-12-06 14:41:18 -08001648 mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
Wale Ogunwale3b232392016-05-13 15:37:13 -07001649 } else {
Winson Chung32066032016-11-04 11:55:21 -07001650 // If the target stack was not previously focusable (previous top running activity
1651 // on that stack was not visible) then any prior calls to move the stack to the
1652 // will not update the focused stack. If starting the new activity now allows the
1653 // task stack to be focusable, then ensure that we now update the focused stack
1654 // accordingly.
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001655 if (mTargetStack.isFocusable()
Wale Ogunwaled32da472018-11-16 07:19:28 -08001656 && !mRootActivityContainer.isTopDisplayFocusedStack(mTargetStack)) {
Winson Chung32066032016-11-04 11:55:21 -07001657 mTargetStack.moveToFront("startActivityUnchecked");
1658 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08001659 mRootActivityContainer.resumeFocusedStacksTopActivities(
1660 mTargetStack, mStartActivity, mOptions);
Filip Gruszczynski3d7fdc12016-01-31 17:33:29 -08001661 }
Winson Chung1dbc8112017-09-28 18:05:31 -07001662 } else if (mStartActivity != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001663 mSupervisor.mRecentTasks.add(mStartActivity.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001664 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001665 mRootActivityContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001666
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001667 mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTaskRecord(),
1668 preferredWindowingMode, mPreferredDisplayId, mTargetStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001669
1670 return START_SUCCESS;
1671 }
1672
Bryce Leedaa91e42017-12-06 14:13:01 -08001673 /**
1674 * Resets the {@link ActivityStarter} state.
1675 * @param clearRequest whether the request should be reset to default values.
1676 */
1677 void reset(boolean clearRequest) {
1678 mStartActivity = null;
1679 mIntent = null;
1680 mCallingUid = -1;
1681 mOptions = null;
1682
1683 mLaunchTaskBehind = false;
1684 mLaunchFlags = 0;
1685 mLaunchMode = INVALID_LAUNCH_MODE;
1686
Bryce Leeec55eb02017-12-05 20:51:27 -08001687 mLaunchParams.reset();
Bryce Leedaa91e42017-12-06 14:13:01 -08001688
1689 mNotTop = null;
1690 mDoResume = false;
1691 mStartFlags = 0;
1692 mSourceRecord = null;
1693 mPreferredDisplayId = INVALID_DISPLAY;
1694
1695 mInTask = null;
1696 mAddingToTask = false;
1697 mReuseTask = null;
1698
1699 mNewTaskInfo = null;
1700 mNewTaskIntent = null;
1701 mSourceStack = null;
1702
1703 mTargetStack = null;
1704 mMovedToFront = false;
1705 mNoAnimation = false;
1706 mKeepCurTransition = false;
1707 mAvoidMoveToFront = false;
1708
1709 mVoiceSession = null;
1710 mVoiceInteractor = null;
1711
1712 mIntentDelivered = false;
1713
1714 if (clearRequest) {
1715 mRequest.reset();
1716 }
1717 }
1718
Wale Ogunwale01d66562015-12-29 08:19:19 -08001719 private void setInitialState(ActivityRecord r, ActivityOptions options, TaskRecord inTask,
1720 boolean doResume, int startFlags, ActivityRecord sourceRecord,
1721 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
Bryce Leedaa91e42017-12-06 14:13:01 -08001722 reset(false /* clearRequest */);
1723
Wale Ogunwale01d66562015-12-29 08:19:19 -08001724 mStartActivity = r;
1725 mIntent = r.intent;
1726 mOptions = options;
1727 mCallingUid = r.launchedFromUid;
1728 mSourceRecord = sourceRecord;
1729 mVoiceSession = voiceSession;
1730 mVoiceInteractor = voiceInteractor;
1731
Bryce Leeec55eb02017-12-05 20:51:27 -08001732 mLaunchParams.reset();
Bryce Leedacefc42017-10-10 12:56:02 -07001733
Louis Chang6fb1e842018-12-03 16:07:50 +08001734 // Preferred display id is the only state we need for now and it could be updated again
1735 // after we located a reusable task (which might be resided in another display).
Garfield Tan706dbcb2018-10-15 11:33:02 -07001736 mSupervisor.getLaunchParamsController().calculate(inTask, r.info.windowLayout, r,
Louis Chang6fb1e842018-12-03 16:07:50 +08001737 sourceRecord, options, PHASE_DISPLAY, mLaunchParams);
1738 mPreferredDisplayId =
1739 mLaunchParams.hasPreferredDisplay() ? mLaunchParams.mPreferredDisplayId
1740 : DEFAULT_DISPLAY;
Garfield Tanb5cc09f2018-09-28 10:06:52 -07001741
Bryce Lee7daee392017-10-12 13:46:18 -07001742 mLaunchMode = r.launchMode;
1743
Wale Ogunwale01d66562015-12-29 08:19:19 -08001744 mLaunchFlags = adjustLaunchFlagsToDocumentMode(
Bryce Lee7daee392017-10-12 13:46:18 -07001745 r, LAUNCH_SINGLE_INSTANCE == mLaunchMode,
1746 LAUNCH_SINGLE_TASK == mLaunchMode, mIntent.getFlags());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001747 mLaunchTaskBehind = r.mLaunchTaskBehind
Bryce Lee7daee392017-10-12 13:46:18 -07001748 && !isLaunchModeOneOf(LAUNCH_SINGLE_TASK, LAUNCH_SINGLE_INSTANCE)
Wale Ogunwale01d66562015-12-29 08:19:19 -08001749 && (mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0;
1750
1751 sendNewTaskResultRequestIfNeeded();
1752
1753 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
1754 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1755 }
1756
1757 // If we are actually going to launch in to a new task, there are some cases where
1758 // we further want to do multiple task.
1759 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1760 if (mLaunchTaskBehind
1761 || r.info.documentLaunchMode == DOCUMENT_LAUNCH_ALWAYS) {
1762 mLaunchFlags |= FLAG_ACTIVITY_MULTIPLE_TASK;
1763 }
1764 }
1765
1766 // We'll invoke onUserLeaving before onPause only if the launching
1767 // activity did not explicitly state that this is an automated launch.
1768 mSupervisor.mUserLeaving = (mLaunchFlags & FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1769 if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
1770 "startActivity() => mUserLeaving=" + mSupervisor.mUserLeaving);
1771
1772 // If the caller has asked not to resume at this point, we make note
1773 // of this in the record so that we can skip it when trying to find
1774 // the top running activity.
1775 mDoResume = doResume;
Chong Zhang87761972016-08-22 13:53:24 -07001776 if (!doResume || !r.okToShowLocked()) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001777 r.delayedResume = true;
1778 mDoResume = false;
1779 }
1780
Winson Chunge2d72172018-01-25 17:46:20 +00001781 if (mOptions != null) {
1782 if (mOptions.getLaunchTaskId() != -1 && mOptions.getTaskOverlay()) {
1783 r.mTaskOverlay = true;
1784 if (!mOptions.canTaskOverlayResume()) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001785 final TaskRecord task = mRootActivityContainer.anyTaskForId(
Winson Chunge2d72172018-01-25 17:46:20 +00001786 mOptions.getLaunchTaskId());
1787 final ActivityRecord top = task != null ? task.getTopActivity() : null;
Bryce Lee7ace3952018-02-16 14:34:32 -08001788 if (top != null && !top.isState(RESUMED)) {
Jorim Jaggic875ae72016-04-26 22:41:06 -07001789
Winson Chunge2d72172018-01-25 17:46:20 +00001790 // The caller specifies that we'd like to be avoided to be moved to the
1791 // front, so be it!
1792 mDoResume = false;
1793 mAvoidMoveToFront = true;
1794 }
Winson Chungcbcadc92017-01-12 15:54:12 -08001795 }
Winson Chunge2d72172018-01-25 17:46:20 +00001796 } else if (mOptions.getAvoidMoveToFront()) {
Winson Chungba40d3a2018-05-16 09:40:16 -07001797 mDoResume = false;
Winson Chunge2d72172018-01-25 17:46:20 +00001798 mAvoidMoveToFront = true;
Jorim Jaggic875ae72016-04-26 22:41:06 -07001799 }
1800 }
1801
Wale Ogunwale01d66562015-12-29 08:19:19 -08001802 mNotTop = (mLaunchFlags & FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1803
1804 mInTask = inTask;
1805 // In some flows in to this function, we retrieve the task record and hold on to it
1806 // without a lock before calling back in to here... so the task at this point may
1807 // not actually be in recents. Check for that, and if it isn't in recents just
1808 // consider it invalid.
1809 if (inTask != null && !inTask.inRecents) {
1810 Slog.w(TAG, "Starting activity in task not in recents: " + inTask);
1811 mInTask = null;
1812 }
1813
1814 mStartFlags = startFlags;
1815 // If the onlyIfNeeded flag is set, then we can do this if the activity being launched
1816 // is the same as the one making the call... or, as a special case, if we do not know
1817 // the caller then we count the current top activity as the caller.
1818 if ((startFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1819 ActivityRecord checkedCaller = sourceRecord;
1820 if (checkedCaller == null) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001821 checkedCaller = mRootActivityContainer.getTopDisplayFocusedStack()
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001822 .topRunningNonDelayedActivityLocked(mNotTop);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001823 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001824 if (!checkedCaller.mActivityComponent.equals(r.mActivityComponent)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001825 // Caller is not the same as launcher, so always needed.
1826 mStartFlags &= ~START_FLAG_ONLY_IF_NEEDED;
1827 }
1828 }
1829
1830 mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0;
1831 }
1832
1833 private void sendNewTaskResultRequestIfNeeded() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001834 final ActivityStack sourceStack = mStartActivity.resultTo != null
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001835 ? mStartActivity.resultTo.getActivityStack() : null;
Andrii Kulian02b7a832016-10-06 23:11:56 -07001836 if (sourceStack != null && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001837 // For whatever reason this activity is being launched into a new task...
1838 // yet the caller has requested a result back. Well, that is pretty messed up,
1839 // so instead immediately send back a cancel and let the new task continue launched
1840 // as normal without a dependency on its originator.
1841 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
Andrii Kulian02b7a832016-10-06 23:11:56 -07001842 sourceStack.sendActivityResultLocked(-1 /* callingUid */, mStartActivity.resultTo,
1843 mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,
1844 null /* data */);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001845 mStartActivity.resultTo = null;
1846 }
1847 }
1848
1849 private void computeLaunchingTaskFlags() {
1850 // If the caller is not coming from another activity, but has given us an explicit task into
1851 // which they would like us to launch the new activity, then let's see about doing that.
Andrii Kulian02b7a832016-10-06 23:11:56 -07001852 if (mSourceRecord == null && mInTask != null && mInTask.getStack() != null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001853 final Intent baseIntent = mInTask.getBaseIntent();
1854 final ActivityRecord root = mInTask.getRootActivity();
1855 if (baseIntent == null) {
1856 ActivityOptions.abort(mOptions);
1857 throw new IllegalArgumentException("Launching into task without base intent: "
1858 + mInTask);
1859 }
1860
1861 // If this task is empty, then we are adding the first activity -- it
1862 // determines the root, and must be launching as a NEW_TASK.
Bryce Lee7daee392017-10-12 13:46:18 -07001863 if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001864 if (!baseIntent.getComponent().equals(mStartActivity.intent.getComponent())) {
1865 ActivityOptions.abort(mOptions);
1866 throw new IllegalArgumentException("Trying to launch singleInstance/Task "
1867 + mStartActivity + " into different task " + mInTask);
1868 }
1869 if (root != null) {
1870 ActivityOptions.abort(mOptions);
1871 throw new IllegalArgumentException("Caller with mInTask " + mInTask
1872 + " has root " + root + " but target is singleInstance/Task");
1873 }
1874 }
1875
1876 // If task is empty, then adopt the interesting intent launch flags in to the
1877 // activity being started.
1878 if (root == null) {
1879 final int flagsOfInterest = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK
1880 | FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS;
1881 mLaunchFlags = (mLaunchFlags & ~flagsOfInterest)
1882 | (baseIntent.getFlags() & flagsOfInterest);
1883 mIntent.setFlags(mLaunchFlags);
1884 mInTask.setIntent(mStartActivity);
1885 mAddingToTask = true;
1886
1887 // If the task is not empty and the caller is asking to start it as the root of
1888 // a new task, then we don't actually want to start this on the task. We will
1889 // bring the task to the front, and possibly give it a new intent.
1890 } else if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1891 mAddingToTask = false;
1892
1893 } else {
1894 mAddingToTask = true;
1895 }
1896
1897 mReuseTask = mInTask;
1898 } else {
1899 mInTask = null;
1900 // Launch ResolverActivity in the source task, so that it stays in the task bounds
1901 // when in freeform workspace.
1902 // Also put noDisplay activities in the source task. These by itself can be placed
1903 // in any task/stack, however it could launch other activities like ResolverActivity,
1904 // and we want those to stay in the original task.
1905 if ((mStartActivity.isResolverActivity() || mStartActivity.noDisplay) && mSourceRecord != null
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001906 && mSourceRecord.inFreeformWindowingMode()) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001907 mAddingToTask = true;
1908 }
1909 }
1910
1911 if (mInTask == null) {
1912 if (mSourceRecord == null) {
1913 // This activity is not being started from another... in this
1914 // case we -always- start a new task.
1915 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) {
1916 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1917 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
1918 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1919 }
1920 } else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) {
1921 // The original activity who is starting us is running as a single
1922 // instance... this new activity it is starting must go on its
1923 // own task.
1924 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
Bryce Lee7daee392017-10-12 13:46:18 -07001925 } else if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001926 // The activity being started is a single instance... it always
1927 // gets launched into its own task.
1928 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1929 }
1930 }
1931 }
1932
1933 private void computeSourceStack() {
1934 if (mSourceRecord == null) {
1935 mSourceStack = null;
1936 return;
1937 }
1938 if (!mSourceRecord.finishing) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001939 mSourceStack = mSourceRecord.getActivityStack();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001940 return;
1941 }
1942
1943 // If the source is finishing, we can't further count it as our source. This is because the
1944 // task it is associated with may now be empty and on its way out, so we don't want to
1945 // blindly throw it in to that task. Instead we will take the NEW_TASK flow and try to find
1946 // a task for it. But save the task information so it can be used when creating the new task.
1947 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0) {
1948 Slog.w(TAG, "startActivity called from finishing " + mSourceRecord
1949 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
1950 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1951 mNewTaskInfo = mSourceRecord.info;
Bryce Leed9ed45d2017-05-22 15:57:24 -07001952
1953 // It is not guaranteed that the source record will have a task associated with it. For,
1954 // example, if this method is being called for processing a pending activity launch, it
1955 // is possible that the activity has been removed from the task after the launch was
1956 // enqueued.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001957 final TaskRecord sourceTask = mSourceRecord.getTaskRecord();
Bryce Leed9ed45d2017-05-22 15:57:24 -07001958 mNewTaskIntent = sourceTask != null ? sourceTask.intent : null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001959 }
1960 mSourceRecord = null;
1961 mSourceStack = null;
1962 }
1963
1964 /**
1965 * Decide whether the new activity should be inserted into an existing task. Returns null
1966 * if not or an ActivityRecord with the task into which the new activity should be added.
1967 */
1968 private ActivityRecord getReusableIntentActivity() {
1969 // We may want to try to place the new activity in to an existing task. We always
1970 // do this if the target activity is singleTask or singleInstance; we will also do
1971 // this if NEW_TASK has been requested, and there is not an additional qualifier telling
1972 // us to still place it in a new task: multi task, always doc mode, or being asked to
1973 // launch this as a new task behind the current one.
1974 boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 &&
1975 (mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
Bryce Lee7daee392017-10-12 13:46:18 -07001976 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001977 // If bring to front is requested, and no result is requested and we have not been given
1978 // an explicit task to launch in to, and we can find a task that was started with this
1979 // same component, then instead of launching bring that one to the front.
1980 putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null;
1981 ActivityRecord intentActivity = null;
Jorim Jaggi2adba072016-03-03 13:43:39 +01001982 if (mOptions != null && mOptions.getLaunchTaskId() != -1) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001983 final TaskRecord task = mRootActivityContainer.anyTaskForId(mOptions.getLaunchTaskId());
Jorim Jaggi2adba072016-03-03 13:43:39 +01001984 intentActivity = task != null ? task.getTopActivity() : null;
1985 } else if (putIntoExistingTask) {
Bryce Lee7daee392017-10-12 13:46:18 -07001986 if (LAUNCH_SINGLE_INSTANCE == mLaunchMode) {
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07001987 // There can be one and only one instance of single instance activity in the
1988 // history, and it is always in its own unique task, so we do a special search.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001989 intentActivity = mRootActivityContainer.findActivity(mIntent, mStartActivity.info,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001990 mStartActivity.isActivityTypeHome());
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07001991 } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
1992 // For the launch adjacent case we only want to put the activity in an existing
1993 // task if the activity already exists in the history.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001994 intentActivity = mRootActivityContainer.findActivity(mIntent, mStartActivity.info,
Bryce Lee7daee392017-10-12 13:46:18 -07001995 !(LAUNCH_SINGLE_TASK == mLaunchMode));
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07001996 } else {
1997 // Otherwise find the best task to put the activity in.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001998 intentActivity =
1999 mRootActivityContainer.findTask(mStartActivity, mPreferredDisplayId);
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07002000 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002001 }
Louis Changbd48dca2018-08-29 17:44:34 +08002002
Louis Chang54506cb2018-11-23 11:03:41 +08002003 if (intentActivity != null
2004 && (mStartActivity.isActivityTypeHome() || intentActivity.isActivityTypeHome())
Louis Changbd48dca2018-08-29 17:44:34 +08002005 && intentActivity.getDisplayId() != mPreferredDisplayId) {
2006 // Do not reuse home activity on other displays.
2007 intentActivity = null;
2008 }
2009
Wale Ogunwale01d66562015-12-29 08:19:19 -08002010 return intentActivity;
2011 }
2012
Andrii Kulianfab9cd82017-03-21 19:37:09 -07002013 /**
2014 * Figure out which task and activity to bring to front when we have found an existing matching
2015 * activity record in history. May also clear the task if needed.
2016 * @param intentActivity Existing matching activity.
2017 * @return {@link ActivityRecord} brought to front.
2018 */
Wale Ogunwale01d66562015-12-29 08:19:19 -08002019 private ActivityRecord setTargetStackAndMoveToFrontIfNeeded(ActivityRecord intentActivity) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002020 mTargetStack = intentActivity.getActivityStack();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002021 mTargetStack.mLastPausedActivity = null;
2022 // If the target task is not in the front, then we need to bring it to the front...
2023 // except... well, with SINGLE_TASK_LAUNCH it's not entirely clear. We'd like to have
2024 // the same behavior as if a new instance was being started, which means not bringing it
2025 // to the front if the caller is not itself in the front.
Riddle Hsub70b36d2018-09-11 21:20:02 +08002026 final boolean differentTopTask;
2027 if (mPreferredDisplayId == mTargetStack.mDisplayId) {
2028 final ActivityStack focusStack = mTargetStack.getDisplay().getFocusedStack();
2029 final ActivityRecord curTop = (focusStack == null)
2030 ? null : focusStack.topRunningNonDelayedActivityLocked(mNotTop);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002031 final TaskRecord topTask = curTop != null ? curTop.getTaskRecord() : null;
Riddle Hsub70b36d2018-09-11 21:20:02 +08002032 differentTopTask = topTask != null
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002033 && (topTask != intentActivity.getTaskRecord() || topTask != focusStack.topTask());
Riddle Hsub70b36d2018-09-11 21:20:02 +08002034 } else {
2035 // The existing task should always be different from those in other displays.
2036 differentTopTask = true;
2037 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002038
Riddle Hsub70b36d2018-09-11 21:20:02 +08002039 if (differentTopTask && !mAvoidMoveToFront) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002040 mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Wale Ogunwale30e441d2017-11-09 08:28:45 -08002041 if (mSourceRecord == null || (mSourceStack.getTopActivity() != null &&
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002042 mSourceStack.getTopActivity().getTaskRecord()
2043 == mSourceRecord.getTaskRecord())) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002044 // We really do want to push this one into the user's face, right now.
2045 if (mLaunchTaskBehind && mSourceRecord != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002046 intentActivity.setTaskToAffiliateWith(mSourceRecord.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08002047 }
Chong Zhangdea4bd92016-03-15 12:50:03 -07002048
2049 // If the launch flags carry both NEW_TASK and CLEAR_TASK, the task's activities
2050 // will be cleared soon by ActivityStarter in setTaskFromIntentActivity().
2051 // So no point resuming any of the activities here, it just wastes one extra
2052 // resuming, plus enter AND exit transitions.
2053 // Here we only want to bring the target stack forward. Transition will be applied
2054 // to the new activity that's started after the old ones are gone.
2055 final boolean willClearTask =
2056 (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
2057 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
2058 if (!willClearTask) {
2059 final ActivityStack launchStack = getLaunchStack(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002060 mStartActivity, mLaunchFlags, mStartActivity.getTaskRecord(), mOptions);
2061 final TaskRecord intentTask = intentActivity.getTaskRecord();
Chong Zhangdea4bd92016-03-15 12:50:03 -07002062 if (launchStack == null || launchStack == mTargetStack) {
2063 // We only want to move to the front, if we aren't going to launch on a
2064 // different stack. If we launch on a different stack, we will put the
2065 // task on top there.
chaviw0d562bf2018-03-15 14:24:14 -07002066 mTargetStack.moveTaskToFrontLocked(intentTask, mNoAnimation, mOptions,
2067 mStartActivity.appTimeTracker, "bringingFoundTaskToFront");
Chong Zhangdea4bd92016-03-15 12:50:03 -07002068 mMovedToFront = true;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002069 } else if (launchStack.inSplitScreenWindowingMode()) {
Andrii Kulianad6f2e52016-06-15 15:27:01 -07002070 if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
2071 // If we want to launch adjacent and mTargetStack is not the computed
2072 // launch stack - move task to top of computed stack.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002073 intentTask.reparent(launchStack, ON_TOP,
Winson Chung74666102017-02-22 17:49:24 -08002074 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
2075 "launchToSide");
Andrii Kulianad6f2e52016-06-15 15:27:01 -07002076 } else {
2077 // TODO: This should be reevaluated in MW v2.
2078 // We choose to move task to front instead of launching it adjacent
2079 // when specific stack was requested explicitly and it appeared to be
2080 // adjacent stack, but FLAG_ACTIVITY_LAUNCH_ADJACENT was not set.
chaviw0d562bf2018-03-15 14:24:14 -07002081 mTargetStack.moveTaskToFrontLocked(intentTask,
Bryce Leeaf691c02017-03-20 14:20:22 -07002082 mNoAnimation, mOptions, mStartActivity.appTimeTracker,
Andrii Kulianad6f2e52016-06-15 15:27:01 -07002083 "bringToFrontInsteadOfAdjacentLaunch");
2084 }
Bryce Lee32e09ef2018-03-19 15:29:49 -07002085 mMovedToFront = launchStack != launchStack.getDisplay()
2086 .getTopStackInWindowingMode(launchStack.getWindowingMode());
Andrii Kulianfab9cd82017-03-21 19:37:09 -07002087 } else if (launchStack.mDisplayId != mTargetStack.mDisplayId) {
2088 // Target and computed stacks are on different displays and we've
2089 // found a matching task - move the existing instance to that display and
2090 // move it to front.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002091 intentActivity.getTaskRecord().reparent(launchStack, ON_TOP,
Andrii Kulianfab9cd82017-03-21 19:37:09 -07002092 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
2093 "reparentToDisplay");
2094 mMovedToFront = true;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002095 } else if (launchStack.isActivityTypeHome()
2096 && !mTargetStack.isActivityTypeHome()) {
Bryce Lee4ff7da92017-07-17 10:39:24 -07002097 // It is possible for the home activity to be in another stack initially.
2098 // For example, the activity may have been initially started with an intent
2099 // which placed it in the fullscreen stack. To ensure the proper handling of
2100 // the activity based on home stack assumptions, we must move it over.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002101 intentActivity.getTaskRecord().reparent(launchStack, ON_TOP,
Bryce Lee4ff7da92017-07-17 10:39:24 -07002102 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
2103 "reparentingHome");
2104 mMovedToFront = true;
Chong Zhangdea4bd92016-03-15 12:50:03 -07002105 }
2106 mOptions = null;
Jorim Jaggi02886a82016-12-06 09:10:06 -08002107
2108 // We are moving a task to the front, use starting window to hide initial drawn
2109 // delay.
2110 intentActivity.showStartingWindow(null /* prev */, false /* newTask */,
2111 true /* taskSwitch */);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002112 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002113 }
2114 }
Andrii Kulianb850ea52017-12-12 23:49:10 -08002115 // Need to update mTargetStack because if task was moved out of it, the original stack may
2116 // be destroyed.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002117 mTargetStack = intentActivity.getActivityStack();
Winson Chungba40d3a2018-05-16 09:40:16 -07002118 if (!mMovedToFront && mDoResume) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002119 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Bring to front target: " + mTargetStack
2120 + " from " + intentActivity);
2121 mTargetStack.moveToFront("intentActivityFound");
2122 }
2123
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002124 mSupervisor.handleNonResizableTaskIfNeeded(intentActivity.getTaskRecord(),
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07002125 WINDOWING_MODE_UNDEFINED, DEFAULT_DISPLAY, mTargetStack);
Jorim Jaggid53f0922016-04-06 22:16:23 -07002126
Wale Ogunwale01d66562015-12-29 08:19:19 -08002127 // If the caller has requested that the target task be reset, then do so.
2128 if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
2129 return mTargetStack.resetTaskIfNeededLocked(intentActivity, mStartActivity);
2130 }
2131 return intentActivity;
2132 }
2133
2134 private void setTaskFromIntentActivity(ActivityRecord intentActivity) {
2135 if ((mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
2136 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {
2137 // The caller has requested to completely replace any existing task with its new
2138 // activity. Well that should not be too hard...
Bryce Lee41801b42017-03-02 13:23:12 -08002139 // Note: we must persist the {@link TaskRecord} first as intentActivity could be
2140 // removed from calling performClearTaskLocked (For example, if it is being brought out
Bryce Lee59dad4e2017-03-09 11:54:08 -08002141 // of history or if it is finished immediately), thus disassociating the task. Also note
2142 // that mReuseTask is reset as a result of {@link TaskRecord#performClearTaskLocked}
2143 // launching another activity.
2144 // TODO(b/36119896): We shouldn't trigger activity launches in this path since we are
2145 // already launching one.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002146 final TaskRecord task = intentActivity.getTaskRecord();
Bryce Lee59dad4e2017-03-09 11:54:08 -08002147 task.performClearTaskLocked();
2148 mReuseTask = task;
Bryce Lee41801b42017-03-02 13:23:12 -08002149 mReuseTask.setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002150 } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
Bryce Lee7daee392017-10-12 13:46:18 -07002151 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002152 final ActivityRecord top = intentActivity.getTaskRecord().performClearTaskLocked(
2153 mStartActivity, mLaunchFlags);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08002154 if (top == null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002155 // A special case: we need to start the activity because it is not currently
2156 // running, and the caller has asked to clear the current task to have this
2157 // activity at the top.
2158 mAddingToTask = true;
Bryce Lee353112c2017-02-23 09:46:45 -08002159
2160 // We are no longer placing the activity in the task we previously thought we were.
Bryce Leeaf691c02017-03-20 14:20:22 -07002161 mStartActivity.setTask(null);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002162 // Now pretend like this activity is being started by the top of its task, so it
2163 // is put in the right place.
2164 mSourceRecord = intentActivity;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002165 final TaskRecord task = mSourceRecord.getTaskRecord();
Andrii Kulian02b7a832016-10-06 23:11:56 -07002166 if (task != null && task.getStack() == null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002167 // Target stack got cleared when we all activities were removed above.
2168 // Go ahead and reset it.
2169 mTargetStack = computeStackFocus(mSourceRecord, false /* newTask */,
Bryce Leedacefc42017-10-10 12:56:02 -07002170 mLaunchFlags, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002171 mTargetStack.addTask(task,
2172 !mLaunchTaskBehind /* toTop */, "startActivityUnchecked");
2173 }
2174 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002175 } else if (mStartActivity.mActivityComponent.equals(
2176 intentActivity.getTaskRecord().realActivity)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002177 // In this case the top activity on the task is the same as the one being launched,
2178 // so we take that as a request to bring the task to the foreground. If the top
2179 // activity in the task is the root activity, deliver this new intent to it if it
2180 // desires.
Bryce Lee7daee392017-10-12 13:46:18 -07002181 if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
2182 || LAUNCH_SINGLE_TOP == mLaunchMode)
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002183 && intentActivity.mActivityComponent.equals(
2184 mStartActivity.mActivityComponent)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002185 if (intentActivity.frontOfTask) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002186 intentActivity.getTaskRecord().setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002187 }
Bryce Lee325e09682017-10-05 17:20:25 -07002188 deliverNewIntent(intentActivity);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002189 } else if (!intentActivity.getTaskRecord().isSameIntentFilter(mStartActivity)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002190 // In this case we are launching the root activity of the task, but with a
2191 // different intent. We should start a new instance on top.
2192 mAddingToTask = true;
2193 mSourceRecord = intentActivity;
2194 }
2195 } else if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
2196 // In this case an activity is being launched in to an existing task, without
2197 // resetting that task. This is typically the situation of launching an activity
2198 // from a notification or shortcut. We want to place the new activity on top of the
2199 // current task.
2200 mAddingToTask = true;
2201 mSourceRecord = intentActivity;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002202 } else if (!intentActivity.getTaskRecord().rootWasReset) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002203 // In this case we are launching into an existing task that has not yet been started
2204 // from its front door. The current task has been brought to the front. Ideally,
2205 // we'd probably like to place this new task at the bottom of its stack, but that's
2206 // a little hard to do with the current organization of the code so for now we'll
2207 // just drop it.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002208 intentActivity.getTaskRecord().setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002209 }
2210 }
2211
2212 private void resumeTargetStackIfNeeded() {
2213 if (mDoResume) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002214 mRootActivityContainer.resumeFocusedStacksTopActivities(mTargetStack, null, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002215 } else {
2216 ActivityOptions.abort(mOptions);
2217 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002218 mRootActivityContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002219 }
2220
Louis Changceeb5062018-09-17 18:13:52 +08002221 private int setTaskFromReuseOrCreateNewTask(TaskRecord taskToAffiliate) {
Bryce Leedacefc42017-10-10 12:56:02 -07002222 mTargetStack = computeStackFocus(mStartActivity, true, mLaunchFlags, mOptions);
Chong Zhang6cda19c2016-06-14 19:07:56 -07002223
2224 // Do no move the target stack to front yet, as we might bail if
2225 // isLockTaskModeViolation fails below.
Wale Ogunwale01d66562015-12-29 08:19:19 -08002226
2227 if (mReuseTask == null) {
Suprabh Shukla09a88f52015-12-02 14:36:31 -08002228 final TaskRecord task = mTargetStack.createTaskRecord(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002229 mSupervisor.getNextTaskIdForUserLocked(mStartActivity.mUserId),
Wale Ogunwale01d66562015-12-29 08:19:19 -08002230 mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
Wale Ogunwale72919d22016-12-08 18:58:50 -08002231 mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
Bryce Leeb802ea12017-11-15 21:25:03 -08002232 mVoiceInteractor, !mLaunchTaskBehind /* toTop */, mStartActivity, mSourceRecord,
2233 mOptions);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002234 addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002235 updateBounds(mStartActivity.getTaskRecord(), mLaunchParams.mBounds);
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002236
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002237 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002238 + " in new task " + mStartActivity.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08002239 } else {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002240 addOrReparentStartingActivity(mReuseTask, "setTaskFromReuseOrCreateNewTask");
2241 }
2242
2243 if (taskToAffiliate != null) {
2244 mStartActivity.setTaskToAffiliateWith(taskToAffiliate);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002245 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07002246
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002247 if (mService.getLockTaskController().isLockTaskModeViolation(
2248 mStartActivity.getTaskRecord())) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002249 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
2250 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
2251 }
2252
Chong Zhang6cda19c2016-06-14 19:07:56 -07002253 if (mDoResume) {
2254 mTargetStack.moveToFront("reuseOrNewTask");
2255 }
2256 return START_SUCCESS;
Wale Ogunwale01d66562015-12-29 08:19:19 -08002257 }
2258
Bryce Lee325e09682017-10-05 17:20:25 -07002259 private void deliverNewIntent(ActivityRecord activity) {
2260 if (mIntentDelivered) {
2261 return;
2262 }
2263
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002264 ActivityStack.logStartActivity(AM_NEW_INTENT, activity, activity.getTaskRecord());
Bryce Lee325e09682017-10-05 17:20:25 -07002265 activity.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
2266 mStartActivity.launchedFromPackage);
2267 mIntentDelivered = true;
2268 }
2269
Wale Ogunwale01d66562015-12-29 08:19:19 -08002270 private int setTaskFromSourceRecord() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002271 if (mService.getLockTaskController().isLockTaskModeViolation(
2272 mSourceRecord.getTaskRecord())) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002273 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
2274 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
2275 }
2276
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002277 final TaskRecord sourceTask = mSourceRecord.getTaskRecord();
2278 final ActivityStack sourceStack = mSourceRecord.getActivityStack();
Andrii Kulian02689a72017-07-06 14:28:59 -07002279 // We only want to allow changing stack in two cases:
2280 // 1. If the target task is not the top one. Otherwise we would move the launching task to
2281 // the other side, rather than show two side by side.
2282 // 2. If activity is not allowed on target display.
2283 final int targetDisplayId = mTargetStack != null ? mTargetStack.mDisplayId
2284 : sourceStack.mDisplayId;
2285 final boolean moveStackAllowed = sourceStack.topTask() != sourceTask
2286 || !mStartActivity.canBeLaunchedOnDisplay(targetDisplayId);
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002287 if (moveStackAllowed) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002288 mTargetStack = getLaunchStack(mStartActivity, mLaunchFlags,
2289 mStartActivity.getTaskRecord(), mOptions);
Andrii Kulian02689a72017-07-06 14:28:59 -07002290 // If target stack is not found now - we can't just rely on the source stack, as it may
2291 // be not suitable. Let's check other displays.
2292 if (mTargetStack == null && targetDisplayId != sourceStack.mDisplayId) {
2293 // Can't use target display, lets find a stack on the source display.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002294 mTargetStack = mRootActivityContainer.getValidLaunchStackOnDisplay(
Garfield Tan20d9e2f2018-11-16 15:42:29 -08002295 sourceStack.mDisplayId, mStartActivity, mOptions, mLaunchParams);
Andrii Kulian02689a72017-07-06 14:28:59 -07002296 }
2297 if (mTargetStack == null) {
2298 // There are no suitable stacks on the target and source display(s). Look on all
2299 // displays.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002300 mTargetStack = mRootActivityContainer.getNextValidLaunchStack(
Andrii Kulian02689a72017-07-06 14:28:59 -07002301 mStartActivity, -1 /* currentFocus */);
2302 }
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002303 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002304
2305 if (mTargetStack == null) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07002306 mTargetStack = sourceStack;
2307 } else if (mTargetStack != sourceStack) {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002308 sourceTask.reparent(mTargetStack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE,
2309 DEFER_RESUME, "launchToSide");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002310 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07002311
Wale Ogunwale01d66562015-12-29 08:19:19 -08002312 final TaskRecord topTask = mTargetStack.topTask();
Jorim Jaggic875ae72016-04-26 22:41:06 -07002313 if (topTask != sourceTask && !mAvoidMoveToFront) {
chaviw0d562bf2018-03-15 14:24:14 -07002314 mTargetStack.moveTaskToFrontLocked(sourceTask, mNoAnimation, mOptions,
Wale Ogunwale01d66562015-12-29 08:19:19 -08002315 mStartActivity.appTimeTracker, "sourceTaskToFront");
Chong Zhang6cda19c2016-06-14 19:07:56 -07002316 } else if (mDoResume) {
2317 mTargetStack.moveToFront("sourceStackToFront");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002318 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07002319
Wale Ogunwale01d66562015-12-29 08:19:19 -08002320 if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0) {
2321 // In this case, we are adding the activity to an existing task, but the caller has
2322 // asked to clear that task if the activity is already running.
2323 ActivityRecord top = sourceTask.performClearTaskLocked(mStartActivity, mLaunchFlags);
2324 mKeepCurTransition = true;
2325 if (top != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002326 ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, top.getTaskRecord());
Bryce Lee325e09682017-10-05 17:20:25 -07002327 deliverNewIntent(top);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002328 // For paranoia, make sure we have correctly resumed the top activity.
2329 mTargetStack.mLastPausedActivity = null;
2330 if (mDoResume) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002331 mRootActivityContainer.resumeFocusedStacksTopActivities();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002332 }
2333 ActivityOptions.abort(mOptions);
2334 return START_DELIVERED_TO_TOP;
2335 }
2336 } else if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
2337 // In this case, we are launching an activity in our own task that may already be
2338 // running somewhere in the history, and we want to shuffle it to the front of the
2339 // stack if so.
2340 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(mStartActivity);
2341 if (top != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002342 final TaskRecord task = top.getTaskRecord();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002343 task.moveActivityToFrontLocked(top);
2344 top.updateOptionsLocked(mOptions);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08002345 ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, task);
Bryce Lee325e09682017-10-05 17:20:25 -07002346 deliverNewIntent(top);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002347 mTargetStack.mLastPausedActivity = null;
2348 if (mDoResume) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002349 mRootActivityContainer.resumeFocusedStacksTopActivities();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002350 }
2351 return START_DELIVERED_TO_TOP;
2352 }
2353 }
2354
2355 // An existing activity is starting this new activity, so we want to keep the new one in
2356 // the same task as the one that is starting it.
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002357 addOrReparentStartingActivity(sourceTask, "setTaskFromSourceRecord");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002358 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002359 + " in existing task " + mStartActivity.getTaskRecord()
2360 + " from source " + mSourceRecord);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002361 return START_SUCCESS;
2362 }
2363
2364 private int setTaskFromInTask() {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002365 // The caller is asking that the new activity be started in an explicit
2366 // task it has provided to us.
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07002367 if (mService.getLockTaskController().isLockTaskModeViolation(mInTask)) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002368 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
2369 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
2370 }
2371
Andrii Kulian02b7a832016-10-06 23:11:56 -07002372 mTargetStack = mInTask.getStack();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002373
2374 // Check whether we should actually launch the new activity in to the task,
2375 // or just reuse the current activity on top.
2376 ActivityRecord top = mInTask.getTopActivity();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002377 if (top != null && top.mActivityComponent.equals(mStartActivity.mActivityComponent)
2378 && top.mUserId == mStartActivity.mUserId) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002379 if ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
Bryce Lee7daee392017-10-12 13:46:18 -07002380 || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK)) {
chaviw0d562bf2018-03-15 14:24:14 -07002381 mTargetStack.moveTaskToFrontLocked(mInTask, mNoAnimation, mOptions,
Yorke Lee64512522017-03-24 13:09:35 -07002382 mStartActivity.appTimeTracker, "inTaskToFront");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002383 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
2384 // We don't need to start a new activity, and the client said not to do
2385 // anything if that is the case, so this is it!
2386 return START_RETURN_INTENT_TO_CALLER;
2387 }
Bryce Lee325e09682017-10-05 17:20:25 -07002388 deliverNewIntent(top);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002389 return START_DELIVERED_TO_TOP;
2390 }
2391 }
2392
2393 if (!mAddingToTask) {
chaviw0d562bf2018-03-15 14:24:14 -07002394 mTargetStack.moveTaskToFrontLocked(mInTask, mNoAnimation, mOptions,
Yorke Lee64512522017-03-24 13:09:35 -07002395 mStartActivity.appTimeTracker, "inTaskToFront");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002396 // We don't actually want to have this activity added to the task, so just
2397 // stop here but still tell the caller that we consumed the intent.
2398 ActivityOptions.abort(mOptions);
2399 return START_TASK_TO_FRONT;
2400 }
2401
Bryce Leeec55eb02017-12-05 20:51:27 -08002402 if (!mLaunchParams.mBounds.isEmpty()) {
Wale Ogunwale0568aed2017-09-08 13:29:37 -07002403 // TODO: Shouldn't we already know what stack to use by the time we get here?
Wale Ogunwaled32da472018-11-16 07:19:28 -08002404 ActivityStack stack = mRootActivityContainer.getLaunchStack(
2405 null, null, mInTask, ON_TOP);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002406 if (stack != mInTask.getStack()) {
2407 mInTask.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, !ANIMATE,
Yorke Lee64512522017-03-24 13:09:35 -07002408 DEFER_RESUME, "inTaskToFront");
Yorke Lee64512522017-03-24 13:09:35 -07002409 mTargetStack = mInTask.getStack();
2410 }
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002411
Bryce Leeec55eb02017-12-05 20:51:27 -08002412 updateBounds(mInTask, mLaunchParams.mBounds);
Yorke Lee64512522017-03-24 13:09:35 -07002413 }
2414
chaviw0d562bf2018-03-15 14:24:14 -07002415 mTargetStack.moveTaskToFrontLocked(
2416 mInTask, mNoAnimation, mOptions, mStartActivity.appTimeTracker, "inTaskToFront");
Yorke Lee64512522017-03-24 13:09:35 -07002417
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002418 addOrReparentStartingActivity(mInTask, "setTaskFromInTask");
2419 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002420 + " in explicit task " + mStartActivity.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08002421
2422 return START_SUCCESS;
2423 }
2424
Bryce Leed3624e12017-11-30 08:51:45 -08002425 @VisibleForTesting
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002426 void updateBounds(TaskRecord task, Rect bounds) {
Bryce Leedacefc42017-10-10 12:56:02 -07002427 if (bounds.isEmpty()) {
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002428 return;
2429 }
2430
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002431 final ActivityStack stack = task.getStack();
2432 if (stack != null && stack.resizeStackWithLaunchBounds()) {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07002433 mService.resizeStack(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002434 stack.mStackId, bounds, true, !PRESERVE_WINDOWS, ANIMATE, -1);
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002435 } else {
2436 task.updateOverrideConfiguration(bounds);
2437 }
2438 }
2439
Wale Ogunwale01d66562015-12-29 08:19:19 -08002440 private void setTaskToCurrentTopOrCreateNewTask() {
Bryce Leedacefc42017-10-10 12:56:02 -07002441 mTargetStack = computeStackFocus(mStartActivity, false, mLaunchFlags, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002442 if (mDoResume) {
2443 mTargetStack.moveToFront("addingToTopTask");
2444 }
Wale Ogunwale30e441d2017-11-09 08:28:45 -08002445 final ActivityRecord prev = mTargetStack.getTopActivity();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002446 final TaskRecord task = (prev != null)
2447 ? prev.getTaskRecord() : mTargetStack.createTaskRecord(
2448 mSupervisor.getNextTaskIdForUserLocked(mStartActivity.mUserId), mStartActivity.info,
Bryce Leeb802ea12017-11-15 21:25:03 -08002449 mIntent, null, null, true, mStartActivity, mSourceRecord, mOptions);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002450 addOrReparentStartingActivity(task, "setTaskToCurrentTopOrCreateNewTask");
2451 mTargetStack.positionChildWindowContainerAtTop(task);
2452 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002453 + " in new guessed " + mStartActivity.getTaskRecord());
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002454 }
2455
2456 private void addOrReparentStartingActivity(TaskRecord parent, String reason) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002457 if (mStartActivity.getTaskRecord() == null || mStartActivity.getTaskRecord() == parent) {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002458 parent.addActivityToTop(mStartActivity);
2459 } else {
2460 mStartActivity.reparent(parent, parent.mActivities.size() /* top */, reason);
2461 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002462 }
2463
2464 private int adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance,
2465 boolean launchSingleTask, int launchFlags) {
2466 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2467 (launchSingleInstance || launchSingleTask)) {
2468 // We have a conflict between the Intent and the Activity manifest, manifest wins.
2469 Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " +
2470 "\"singleInstance\" or \"singleTask\"");
2471 launchFlags &=
2472 ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK);
2473 } else {
2474 switch (r.info.documentLaunchMode) {
2475 case ActivityInfo.DOCUMENT_LAUNCH_NONE:
2476 break;
2477 case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
2478 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2479 break;
2480 case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
2481 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2482 break;
2483 case ActivityInfo.DOCUMENT_LAUNCH_NEVER:
2484 launchFlags &= ~FLAG_ACTIVITY_MULTIPLE_TASK;
2485 break;
2486 }
2487 }
2488 return launchFlags;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002489 }
2490
Bryce Leedacefc42017-10-10 12:56:02 -07002491 private ActivityStack computeStackFocus(ActivityRecord r, boolean newTask, int launchFlags,
2492 ActivityOptions aOptions) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002493 final TaskRecord task = r.getTaskRecord();
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002494 ActivityStack stack = getLaunchStack(r, launchFlags, task, aOptions);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002495 if (stack != null) {
2496 return stack;
2497 }
2498
Andrii Kulian02b7a832016-10-06 23:11:56 -07002499 final ActivityStack currentStack = task != null ? task.getStack() : null;
Wale Ogunwaled32da472018-11-16 07:19:28 -08002500 final ActivityStack focusedStack = mRootActivityContainer.getTopDisplayFocusedStack();
Andrii Kulian02b7a832016-10-06 23:11:56 -07002501 if (currentStack != null) {
Andrii Kulian52d255c2018-07-13 11:32:19 -07002502 if (focusedStack != currentStack) {
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002503 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
2504 "computeStackFocus: Setting " + "focused stack to r=" + r
2505 + " task=" + task);
2506 } else {
2507 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
Andrii Kulian52d255c2018-07-13 11:32:19 -07002508 "computeStackFocus: Focused stack already=" + focusedStack);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002509 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07002510 return currentStack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002511 }
2512
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002513 if (canLaunchIntoFocusedStack(r, newTask)) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002514 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
Andrii Kulian52d255c2018-07-13 11:32:19 -07002515 "computeStackFocus: Have a focused stack=" + focusedStack);
2516 return focusedStack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002517 }
2518
David Stevense5a7b642017-05-22 13:18:23 -07002519 if (mPreferredDisplayId != DEFAULT_DISPLAY) {
Andrii Kuliana8fe3df2017-06-16 15:29:26 -07002520 // Try to put the activity in a stack on a secondary display.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002521 stack = mRootActivityContainer.getValidLaunchStackOnDisplay(
2522 mPreferredDisplayId, r, aOptions, mLaunchParams);
Andrii Kuliana8fe3df2017-06-16 15:29:26 -07002523 if (stack == null) {
2524 // If source display is not suitable - look for topmost valid stack in the system.
2525 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
David Stevense5a7b642017-05-22 13:18:23 -07002526 "computeStackFocus: Can't launch on mPreferredDisplayId="
2527 + mPreferredDisplayId + ", looking on all displays.");
Wale Ogunwaled32da472018-11-16 07:19:28 -08002528 stack = mRootActivityContainer.getNextValidLaunchStack(r, mPreferredDisplayId);
Andrii Kuliana8fe3df2017-06-16 15:29:26 -07002529 }
2530 }
2531 if (stack == null) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002532 stack = mRootActivityContainer.getLaunchStack(r, aOptions, task, ON_TOP);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002533 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002534 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, "computeStackFocus: New stack r="
2535 + r + " stackId=" + stack.mStackId);
2536 return stack;
2537 }
2538
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002539 /** Check if provided activity record can launch in currently focused stack. */
Wale Ogunwale68278562017-09-23 17:13:55 -07002540 // TODO: This method can probably be consolidated into getLaunchStack() below.
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002541 private boolean canLaunchIntoFocusedStack(ActivityRecord r, boolean newTask) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002542 final ActivityStack focusedStack = mRootActivityContainer.getTopDisplayFocusedStack();
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002543 final boolean canUseFocusedStack;
Wale Ogunwale68278562017-09-23 17:13:55 -07002544 if (focusedStack.isActivityTypeAssistant()) {
2545 canUseFocusedStack = r.isActivityTypeAssistant();
2546 } else {
2547 switch (focusedStack.getWindowingMode()) {
2548 case WINDOWING_MODE_FULLSCREEN:
2549 // The fullscreen stack can contain any task regardless of if the task is
2550 // resizeable or not. So, we let the task go in the fullscreen task if it is the
2551 // focus stack.
2552 canUseFocusedStack = true;
2553 break;
2554 case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
2555 case WINDOWING_MODE_SPLIT_SCREEN_SECONDARY:
2556 // Any activity which supports split screen can go in the docked stack.
2557 canUseFocusedStack = r.supportsSplitScreenWindowingMode();
2558 break;
2559 case WINDOWING_MODE_FREEFORM:
2560 // Any activity which supports freeform can go in the freeform stack.
2561 canUseFocusedStack = r.supportsFreeform();
2562 break;
2563 default:
2564 // Dynamic stacks behave similarly to the fullscreen stack and can contain any
2565 // resizeable task.
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002566 canUseFocusedStack = !focusedStack.isOnHomeDisplay()
Wale Ogunwale68278562017-09-23 17:13:55 -07002567 && r.canBeLaunchedOnDisplay(focusedStack.mDisplayId);
2568 }
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002569 }
Andrii Kulian94e82d9b02017-07-13 15:33:06 -07002570 return canUseFocusedStack && !newTask
Wale Ogunwale68278562017-09-23 17:13:55 -07002571 // Using the focus stack isn't important enough to override the preferred display.
David Stevense5a7b642017-05-22 13:18:23 -07002572 && (mPreferredDisplayId == focusedStack.mDisplayId);
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002573 }
2574
Wale Ogunwale854809c2015-12-27 16:18:19 -08002575 private ActivityStack getLaunchStack(ActivityRecord r, int launchFlags, TaskRecord task,
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002576 ActivityOptions aOptions) {
Bryce Leea19b5ad2017-06-07 16:54:11 -07002577 // We are reusing a task, keep the stack!
2578 if (mReuseTask != null) {
2579 return mReuseTask.getStack();
2580 }
Jorim Jaggib8c58762016-04-20 17:58:29 -07002581
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -08002582 if (((launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) == 0)
David Stevense5a7b642017-05-22 13:18:23 -07002583 || mPreferredDisplayId != DEFAULT_DISPLAY) {
Winson Chung93442032018-12-04 13:24:29 -08002584 final boolean onTop = aOptions == null || !aOptions.getAvoidMoveToFront();
Wale Ogunwaled32da472018-11-16 07:19:28 -08002585 final ActivityStack stack =
Winson Chung93442032018-12-04 13:24:29 -08002586 mRootActivityContainer.getLaunchStack(r, aOptions, task, onTop, mLaunchParams);
Garfield Tan20d9e2f2018-11-16 15:42:29 -08002587 return stack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002588 }
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002589 // Otherwise handle adjacent launch.
Wale Ogunwale854809c2015-12-27 16:18:19 -08002590
Wale Ogunwaled32da472018-11-16 07:19:28 -08002591 final ActivityStack focusedStack = mRootActivityContainer.getTopDisplayFocusedStack();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002592 // The parent activity doesn't want to launch the activity on top of itself, but
2593 // instead tries to put it onto other side in side-by-side mode.
Andrii Kulian52d255c2018-07-13 11:32:19 -07002594 final ActivityStack parentStack = task != null ? task.getStack(): focusedStack;
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002595
Andrii Kulian52d255c2018-07-13 11:32:19 -07002596 if (parentStack != focusedStack) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002597 // If task's parent stack is not focused - use it during adjacent launch.
2598 return parentStack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002599 } else {
Andrii Kulian52d255c2018-07-13 11:32:19 -07002600 if (focusedStack != null && task == focusedStack.topTask()) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002601 // If task is already on top of focused stack - use it. We don't want to move the
2602 // existing focused task to adjacent stack, just deliver new intent in this case.
Andrii Kulian52d255c2018-07-13 11:32:19 -07002603 return focusedStack;
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002604 }
2605
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002606 if (parentStack != null && parentStack.inSplitScreenPrimaryWindowingMode()) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002607 // If parent was in docked stack, the natural place to launch another activity
2608 // will be fullscreen, so it can appear alongside the docked window.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002609 final int activityType =
2610 mRootActivityContainer.resolveActivityType(r, mOptions, task);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002611 return parentStack.getDisplay().getOrCreateStack(
2612 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, activityType, ON_TOP);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002613 } else {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002614 // If the parent is not in the docked stack, we check if there is docked window
2615 // and if yes, we will launch into that stack. If not, we just put the new
2616 // activity into parent's stack, because we can't find a better place.
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07002617 final ActivityStack dockedStack =
Wale Ogunwaled32da472018-11-16 07:19:28 -08002618 mRootActivityContainer.getDefaultDisplay().getSplitScreenPrimaryStack();
Wale Ogunwale9dcf9462017-09-19 15:13:01 -07002619 if (dockedStack != null && !dockedStack.shouldBeVisible(r)) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002620 // There is a docked stack, but it isn't visible, so we can't launch into that.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002621 return mRootActivityContainer.getLaunchStack(r, aOptions, task, ON_TOP);
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002622 } else {
2623 return dockedStack;
2624 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002625 }
2626 }
2627 }
2628
Bryce Lee7daee392017-10-12 13:46:18 -07002629 private boolean isLaunchModeOneOf(int mode1, int mode2) {
2630 return mode1 == mLaunchMode || mode2 == mLaunchMode;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002631 }
2632
Daichi Hirono15a02992016-04-27 18:47:01 +09002633 static boolean isDocumentLaunchesIntoExisting(int flags) {
2634 return (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2635 (flags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0;
2636 }
liulvpingcfa825f2016-09-26 20:00:15 +08002637
Bryce Lee4c9a5972017-12-01 22:14:24 -08002638 ActivityStarter setIntent(Intent intent) {
2639 mRequest.intent = intent;
2640 return this;
2641 }
2642
Bryce Lee32e09ef2018-03-19 15:29:49 -07002643 @VisibleForTesting
2644 Intent getIntent() {
2645 return mRequest.intent;
2646 }
2647
Bryce Lee4c9a5972017-12-01 22:14:24 -08002648 ActivityStarter setReason(String reason) {
2649 mRequest.reason = reason;
2650 return this;
2651 }
2652
2653 ActivityStarter setCaller(IApplicationThread caller) {
2654 mRequest.caller = caller;
2655 return this;
2656 }
2657
2658 ActivityStarter setEphemeralIntent(Intent intent) {
2659 mRequest.ephemeralIntent = intent;
2660 return this;
2661 }
2662
2663
2664 ActivityStarter setResolvedType(String type) {
2665 mRequest.resolvedType = type;
2666 return this;
2667 }
2668
2669 ActivityStarter setActivityInfo(ActivityInfo info) {
2670 mRequest.activityInfo = info;
2671 return this;
2672 }
2673
2674 ActivityStarter setResolveInfo(ResolveInfo info) {
2675 mRequest.resolveInfo = info;
2676 return this;
2677 }
2678
2679 ActivityStarter setVoiceSession(IVoiceInteractionSession voiceSession) {
2680 mRequest.voiceSession = voiceSession;
2681 return this;
2682 }
2683
2684 ActivityStarter setVoiceInteractor(IVoiceInteractor voiceInteractor) {
2685 mRequest.voiceInteractor = voiceInteractor;
2686 return this;
2687 }
2688
2689 ActivityStarter setResultTo(IBinder resultTo) {
2690 mRequest.resultTo = resultTo;
2691 return this;
2692 }
2693
2694 ActivityStarter setResultWho(String resultWho) {
2695 mRequest.resultWho = resultWho;
2696 return this;
2697 }
2698
2699 ActivityStarter setRequestCode(int requestCode) {
2700 mRequest.requestCode = requestCode;
2701 return this;
2702 }
2703
2704 ActivityStarter setCallingPid(int pid) {
2705 mRequest.callingPid = pid;
2706 return this;
2707 }
2708
2709 ActivityStarter setCallingUid(int uid) {
2710 mRequest.callingUid = uid;
2711 return this;
2712 }
2713
2714 ActivityStarter setCallingPackage(String callingPackage) {
2715 mRequest.callingPackage = callingPackage;
2716 return this;
2717 }
2718
2719 ActivityStarter setRealCallingPid(int pid) {
2720 mRequest.realCallingPid = pid;
2721 return this;
2722 }
2723
2724 ActivityStarter setRealCallingUid(int uid) {
2725 mRequest.realCallingUid = uid;
2726 return this;
2727 }
2728
2729 ActivityStarter setStartFlags(int startFlags) {
2730 mRequest.startFlags = startFlags;
2731 return this;
2732 }
2733
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002734 ActivityStarter setActivityOptions(SafeActivityOptions options) {
Bryce Lee4c9a5972017-12-01 22:14:24 -08002735 mRequest.activityOptions = options;
2736 return this;
2737 }
2738
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002739 ActivityStarter setActivityOptions(Bundle bOptions) {
2740 return setActivityOptions(SafeActivityOptions.fromBundle(bOptions));
2741 }
2742
Bryce Lee4c9a5972017-12-01 22:14:24 -08002743 ActivityStarter setIgnoreTargetSecurity(boolean ignoreTargetSecurity) {
2744 mRequest.ignoreTargetSecurity = ignoreTargetSecurity;
2745 return this;
2746 }
2747
Patrick Baumann31426b22018-05-21 13:46:40 -07002748 ActivityStarter setFilterCallingUid(int filterCallingUid) {
2749 mRequest.filterCallingUid = filterCallingUid;
2750 return this;
2751 }
2752
Bryce Lee4c9a5972017-12-01 22:14:24 -08002753 ActivityStarter setComponentSpecified(boolean componentSpecified) {
2754 mRequest.componentSpecified = componentSpecified;
2755 return this;
2756 }
2757
2758 ActivityStarter setOutActivity(ActivityRecord[] outActivity) {
2759 mRequest.outActivity = outActivity;
2760 return this;
2761 }
2762
2763 ActivityStarter setInTask(TaskRecord inTask) {
2764 mRequest.inTask = inTask;
2765 return this;
2766 }
2767
2768 ActivityStarter setWaitResult(WaitResult result) {
2769 mRequest.waitResult = result;
2770 return this;
2771 }
2772
2773 ActivityStarter setProfilerInfo(ProfilerInfo info) {
2774 mRequest.profilerInfo = info;
2775 return this;
2776 }
2777
2778 ActivityStarter setGlobalConfiguration(Configuration config) {
2779 mRequest.globalConfig = config;
2780 return this;
2781 }
2782
Bryce Lee4c9a5972017-12-01 22:14:24 -08002783 ActivityStarter setUserId(int userId) {
2784 mRequest.userId = userId;
2785 return this;
2786 }
2787
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002788 ActivityStarter setMayWait(int userId) {
Bryce Lee4c9a5972017-12-01 22:14:24 -08002789 mRequest.mayWait = true;
Bryce Lee4c9a5972017-12-01 22:14:24 -08002790 mRequest.userId = userId;
2791
2792 return this;
2793 }
2794
Jorim Jaggi6fa41c32018-04-23 18:35:00 +02002795 ActivityStarter setAllowPendingRemoteAnimationRegistryLookup(boolean allowLookup) {
2796 mRequest.allowPendingRemoteAnimationRegistryLookup = allowLookup;
2797 return this;
2798 }
2799
Michal Karpinski201bc0c2018-07-20 15:32:00 +01002800 ActivityStarter setOriginatingPendingIntent(PendingIntentRecord originatingPendingIntent) {
2801 mRequest.originatingPendingIntent = originatingPendingIntent;
2802 return this;
2803 }
2804
Michal Karpinskiac116df2018-12-10 17:51:42 +00002805 ActivityStarter setAllowBackgroundActivityStart(boolean allowBackgroundActivityStart) {
2806 mRequest.allowBackgroundActivityStart = allowBackgroundActivityStart;
2807 return this;
2808 }
2809
Bryce Leed3624e12017-11-30 08:51:45 -08002810 void dump(PrintWriter pw, String prefix) {
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002811 prefix = prefix + " ";
Dianne Hackborne676ec72017-07-25 10:55:08 -07002812 pw.print(prefix);
2813 pw.print("mCurrentUser=");
Wale Ogunwaled32da472018-11-16 07:19:28 -08002814 pw.println(mRootActivityContainer.mCurrentUser);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002815 pw.print(prefix);
2816 pw.print("mLastStartReason=");
2817 pw.println(mLastStartReason);
2818 pw.print(prefix);
2819 pw.print("mLastStartActivityTimeMs=");
2820 pw.println(DateFormat.getDateTimeInstance().format(new Date(mLastStartActivityTimeMs)));
2821 pw.print(prefix);
2822 pw.print("mLastStartActivityResult=");
2823 pw.println(mLastStartActivityResult);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002824 ActivityRecord r = mLastStartActivityRecord[0];
2825 if (r != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002826 pw.print(prefix);
2827 pw.println("mLastStartActivityRecord:");
2828 r.dump(pw, prefix + " ");
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002829 }
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002830 if (mStartActivity != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002831 pw.print(prefix);
2832 pw.println("mStartActivity:");
2833 mStartActivity.dump(pw, prefix + " ");
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002834 }
2835 if (mIntent != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002836 pw.print(prefix);
2837 pw.print("mIntent=");
2838 pw.println(mIntent);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002839 }
2840 if (mOptions != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002841 pw.print(prefix);
2842 pw.print("mOptions=");
2843 pw.println(mOptions);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002844 }
Dianne Hackborne676ec72017-07-25 10:55:08 -07002845 pw.print(prefix);
2846 pw.print("mLaunchSingleTop=");
Bryce Lee7daee392017-10-12 13:46:18 -07002847 pw.print(LAUNCH_SINGLE_TOP == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002848 pw.print(" mLaunchSingleInstance=");
Bryce Lee7daee392017-10-12 13:46:18 -07002849 pw.print(LAUNCH_SINGLE_INSTANCE == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002850 pw.print(" mLaunchSingleTask=");
Bryce Lee7daee392017-10-12 13:46:18 -07002851 pw.println(LAUNCH_SINGLE_TASK == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002852 pw.print(prefix);
2853 pw.print("mLaunchFlags=0x");
2854 pw.print(Integer.toHexString(mLaunchFlags));
2855 pw.print(" mDoResume=");
2856 pw.print(mDoResume);
2857 pw.print(" mAddingToTask=");
2858 pw.println(mAddingToTask);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002859 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002860}