blob: 0652182dca95ab6c914782cc85d39e363e4433f1 [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;
49import static android.content.pm.ActivityInfo.DOCUMENT_LAUNCH_ALWAYS;
Bryce Leef65ee7e2018-03-26 16:03:47 -070050import static android.content.pm.ActivityInfo.LAUNCH_MULTIPLE;
Wale Ogunwale01d66562015-12-29 08:19:19 -080051import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
52import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
53import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
Michal Karpinski7b97a022018-12-14 15:17:29 +000054import static android.content.pm.PackageManager.PERMISSION_GRANTED;
David Stevensc6b91c62017-02-08 14:23:58 -080055import static android.view.Display.DEFAULT_DISPLAY;
Andrii Kulian16802aa2016-11-02 12:21:33 -070056import static android.view.Display.INVALID_DISPLAY;
Riddle Hsub70b36d2018-09-11 21:20:02 +080057
Louis Changdd3592a2018-11-05 11:04:14 +080058import static com.android.server.am.EventLogTags.AM_NEW_INTENT;
Wale Ogunwale59507092018-10-29 09:00:30 -070059import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
60import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME;
61import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
62import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
63import static com.android.server.wm.ActivityStackSupervisor.TAG_TASKS;
64import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
65import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_FOCUS;
66import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
67import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS;
68import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STACK;
69import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
70import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_USER_LEAVING;
71import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
72import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS;
73import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RESULTS;
74import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_USER_LEAVING;
75import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
76import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
77import static com.android.server.wm.ActivityTaskManagerService.ANIMATE;
Louis Chang6fb1e842018-12-03 16:07:50 +080078import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_BOUNDS;
79import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_DISPLAY;
Wale Ogunwale59507092018-10-29 09:00:30 -070080import static com.android.server.wm.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
81import static com.android.server.wm.TaskRecord.REPARENT_MOVE_STACK_TO_FRONT;
Winson Chung74666102017-02-22 17:49:24 -080082
Todd Kennedye9910222017-02-21 16:00:11 -080083import android.annotation.NonNull;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +010084import android.annotation.Nullable;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080085import android.app.ActivityManager;
86import android.app.ActivityOptions;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080087import android.app.IApplicationThread;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080088import android.app.PendingIntent;
89import android.app.ProfilerInfo;
Sudheer Shankafc46e9b2016-10-21 17:55:27 -070090import android.app.WaitResult;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080091import android.content.IIntentSender;
92import android.content.Intent;
93import android.content.IntentSender;
94import android.content.pm.ActivityInfo;
95import android.content.pm.ApplicationInfo;
Todd Kennedye9910222017-02-21 16:00:11 -080096import android.content.pm.AuxiliaryResolveInfo;
Kenny Guyb1b30262016-02-09 16:02:35 +000097import android.content.pm.PackageManager;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080098import android.content.pm.ResolveInfo;
Kenny Guyb1b30262016-02-09 16:02:35 +000099import android.content.pm.UserInfo;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800100import android.content.res.Configuration;
101import android.graphics.Rect;
102import android.os.Binder;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800103import android.os.Bundle;
104import android.os.IBinder;
Michal Karpinski8596ded2018-11-14 14:43:48 +0000105import android.os.Process;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800106import android.os.RemoteException;
107import android.os.SystemClock;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100108import android.os.Trace;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800109import android.os.UserHandle;
Kenny Guyb1b30262016-02-09 16:02:35 +0000110import android.os.UserManager;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800111import android.service.voice.IVoiceInteractionSession;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700112import android.text.TextUtils;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800113import android.util.EventLog;
Bryce Leedaa91e42017-12-06 14:13:01 -0800114import android.util.Pools.SynchronizedPool;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800115import android.util.Slog;
Michal Karpinski8596ded2018-11-14 14:43:48 +0000116import android.widget.Toast;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800117
Bryce Leed3624e12017-11-30 08:51:45 -0800118import com.android.internal.annotations.VisibleForTesting;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800119import com.android.internal.app.HeavyWeightSwitcherActivity;
120import com.android.internal.app.IVoiceInteractor;
Wale Ogunwale59507092018-10-29 09:00:30 -0700121import com.android.server.am.EventLogTags;
122import com.android.server.am.PendingIntentRecord;
Louis Changdd3592a2018-11-05 11:04:14 +0800123import com.android.server.pm.InstantAppResolver;
Wale Ogunwale59507092018-10-29 09:00:30 -0700124import com.android.server.wm.ActivityStackSupervisor.PendingActivityLaunch;
125import com.android.server.wm.LaunchParamsController.LaunchParams;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800126
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700127import java.io.PrintWriter;
128import java.text.DateFormat;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700129import java.util.Date;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800130
131/**
Bryce Leed3624e12017-11-30 08:51:45 -0800132 * Controller for interpreting how and then launching an activity.
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800133 *
134 * This class collects all the logic for determining how an intent and flags should be turned into
135 * an activity and associated task and stack.
136 */
Wale Ogunwale01d66562015-12-29 08:19:19 -0800137class ActivityStarter {
Wale Ogunwale98875612018-10-12 07:53:02 -0700138 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStarter" : TAG_ATM;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800139 private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS;
140 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
141 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
142 private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING;
Bryce Lee7daee392017-10-12 13:46:18 -0700143 private static final int INVALID_LAUNCH_MODE = -1;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800144
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700145 private final ActivityTaskManagerService mService;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800146 private final RootActivityContainer mRootActivityContainer;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800147 private final ActivityStackSupervisor mSupervisor;
Benjamin Franz563707b2017-06-29 15:06:13 +0100148 private final ActivityStartInterceptor mInterceptor;
Bryce Leed3624e12017-11-30 08:51:45 -0800149 private final ActivityStartController mController;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800150
Wale Ogunwale01d66562015-12-29 08:19:19 -0800151 // Share state variable among methods when starting an activity.
152 private ActivityRecord mStartActivity;
153 private Intent mIntent;
154 private int mCallingUid;
155 private ActivityOptions mOptions;
156
Bryce Lee7daee392017-10-12 13:46:18 -0700157 private int mLaunchMode;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800158 private boolean mLaunchTaskBehind;
159 private int mLaunchFlags;
160
Bryce Leeec55eb02017-12-05 20:51:27 -0800161 private LaunchParams mLaunchParams = new LaunchParams();
Wale Ogunwale01d66562015-12-29 08:19:19 -0800162
163 private ActivityRecord mNotTop;
164 private boolean mDoResume;
165 private int mStartFlags;
166 private ActivityRecord mSourceRecord;
Bryce Lee7daee392017-10-12 13:46:18 -0700167
David Stevense5a7b642017-05-22 13:18:23 -0700168 // The display to launch the activity onto, barring any strong reason to do otherwise.
169 private int mPreferredDisplayId;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800170
171 private TaskRecord mInTask;
172 private boolean mAddingToTask;
173 private TaskRecord mReuseTask;
174
175 private ActivityInfo mNewTaskInfo;
176 private Intent mNewTaskIntent;
177 private ActivityStack mSourceStack;
178 private ActivityStack mTargetStack;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800179 private boolean mMovedToFront;
180 private boolean mNoAnimation;
181 private boolean mKeepCurTransition;
Jorim Jaggic875ae72016-04-26 22:41:06 -0700182 private boolean mAvoidMoveToFront;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800183
Bryce Lee325e09682017-10-05 17:20:25 -0700184 // We must track when we deliver the new intent since multiple code paths invoke
185 // {@link #deliverNewIntent}. This is due to early returns in the code path. This flag is used
186 // inside {@link #deliverNewIntent} to suppress duplicate requests and ensure the intent is
187 // delivered at most once.
188 private boolean mIntentDelivered;
189
Wale Ogunwale01d66562015-12-29 08:19:19 -0800190 private IVoiceInteractionSession mVoiceSession;
191 private IVoiceInteractor mVoiceInteractor;
192
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700193 // Last activity record we attempted to start
194 private final ActivityRecord[] mLastStartActivityRecord = new ActivityRecord[1];
195 // The result of the last activity we attempted to start.
196 private int mLastStartActivityResult;
197 // Time in milli seconds we attempted to start the last activity.
198 private long mLastStartActivityTimeMs;
199 // The reason we were trying to start the last activity
200 private String mLastStartReason;
Wale Ogunwale59bcba62017-06-16 12:42:51 -0700201
Bryce Lee4c9a5972017-12-01 22:14:24 -0800202 /*
203 * Request details provided through setter methods. Should be reset after {@link #execute()}
204 * to avoid unnecessarily retaining parameters. Note that the request is ignored when
205 * {@link #startResolvedActivity} is invoked directly.
206 */
207 private Request mRequest = new Request();
208
Bryce Leed3624e12017-11-30 08:51:45 -0800209 /**
210 * An interface that to provide {@link ActivityStarter} instances to the controller. This is
211 * used by tests to inject their own starter implementations for verification purposes.
212 */
213 @VisibleForTesting
214 interface Factory {
215 /**
Bryce Lee4c9a5972017-12-01 22:14:24 -0800216 * Sets the {@link ActivityStartController} to be passed to {@link ActivityStarter}.
217 */
218 void setController(ActivityStartController controller);
219
220 /**
Bryce Leed3624e12017-11-30 08:51:45 -0800221 * Generates an {@link ActivityStarter} that is ready to handle a new start request.
222 * @param controller The {@link ActivityStartController} which the starter who will own
223 * this instance.
224 * @return an {@link ActivityStarter}
225 */
Bryce Leedaa91e42017-12-06 14:13:01 -0800226 ActivityStarter obtain();
227
228 /**
229 * Recycles a starter for reuse.
230 */
231 void recycle(ActivityStarter starter);
Wale Ogunwale01d66562015-12-29 08:19:19 -0800232 }
233
Bryce Leed3624e12017-11-30 08:51:45 -0800234 /**
235 * Default implementation of {@link StarterFactory}.
236 */
237 static class DefaultFactory implements Factory {
Bryce Leedaa91e42017-12-06 14:13:01 -0800238 /**
239 * The maximum count of starters that should be active at one time:
240 * 1. last ran starter (for logging and post activity processing)
241 * 2. current running starter
242 * 3. starter from re-entry in (2)
243 */
244 private final int MAX_STARTER_COUNT = 3;
245
Bryce Lee4c9a5972017-12-01 22:14:24 -0800246 private ActivityStartController mController;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700247 private ActivityTaskManagerService mService;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800248 private ActivityStackSupervisor mSupervisor;
249 private ActivityStartInterceptor mInterceptor;
250
Bryce Leedaa91e42017-12-06 14:13:01 -0800251 private SynchronizedPool<ActivityStarter> mStarterPool =
252 new SynchronizedPool<>(MAX_STARTER_COUNT);
253
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700254 DefaultFactory(ActivityTaskManagerService service,
Bryce Lee4c9a5972017-12-01 22:14:24 -0800255 ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
256 mService = service;
257 mSupervisor = supervisor;
258 mInterceptor = interceptor;
Bryce Leed3624e12017-11-30 08:51:45 -0800259 }
Bryce Lee4c9a5972017-12-01 22:14:24 -0800260
261 @Override
262 public void setController(ActivityStartController controller) {
263 mController = controller;
264 }
265
266 @Override
Bryce Leedaa91e42017-12-06 14:13:01 -0800267 public ActivityStarter obtain() {
268 ActivityStarter starter = mStarterPool.acquire();
269
270 if (starter == null) {
271 starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
272 }
273
274 return starter;
275 }
276
277 @Override
278 public void recycle(ActivityStarter starter) {
279 starter.reset(true /* clearRequest*/);
280 mStarterPool.release(starter);
Bryce Lee4c9a5972017-12-01 22:14:24 -0800281 }
282 }
283
284 /**
285 * Container for capturing initial start request details. This information is NOT reset until
286 * the {@link ActivityStarter} is recycled, allowing for multiple invocations with the same
287 * parameters.
288 *
289 * TODO(b/64750076): Investigate consolidating member variables of {@link ActivityStarter} with
290 * the request object. Note that some member variables are referenced in
291 * {@link #dump(PrintWriter, String)} and therefore cannot be cleared immediately after
292 * execution.
293 */
294 private static class Request {
295 private static final int DEFAULT_CALLING_UID = -1;
296 private static final int DEFAULT_CALLING_PID = 0;
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000297 static final int DEFAULT_REAL_CALLING_UID = -1;
298 static final int DEFAULT_REAL_CALLING_PID = 0;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800299
300 IApplicationThread caller;
301 Intent intent;
302 Intent ephemeralIntent;
303 String resolvedType;
304 ActivityInfo activityInfo;
305 ResolveInfo resolveInfo;
306 IVoiceInteractionSession voiceSession;
307 IVoiceInteractor voiceInteractor;
308 IBinder resultTo;
309 String resultWho;
310 int requestCode;
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000311 int callingPid = DEFAULT_CALLING_PID;
312 int callingUid = DEFAULT_CALLING_UID;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800313 String callingPackage;
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000314 int realCallingPid = DEFAULT_REAL_CALLING_PID;
315 int realCallingUid = DEFAULT_REAL_CALLING_UID;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800316 int startFlags;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100317 SafeActivityOptions activityOptions;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800318 boolean ignoreTargetSecurity;
319 boolean componentSpecified;
Winson Chunge2d72172018-01-25 17:46:20 +0000320 boolean avoidMoveToFront;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800321 ActivityRecord[] outActivity;
322 TaskRecord inTask;
323 String reason;
324 ProfilerInfo profilerInfo;
325 Configuration globalConfig;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800326 int userId;
327 WaitResult waitResult;
Patrick Baumann31426b22018-05-21 13:46:40 -0700328 int filterCallingUid;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100329 PendingIntentRecord originatingPendingIntent;
Michal Karpinskiac116df2018-12-10 17:51:42 +0000330 boolean allowBackgroundActivityStart;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800331
332 /**
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200333 * If set to {@code true}, allows this activity start to look into
334 * {@link PendingRemoteAnimationRegistry}
335 */
336 boolean allowPendingRemoteAnimationRegistryLookup;
337
338 /**
Bryce Lee4c9a5972017-12-01 22:14:24 -0800339 * Indicates that we should wait for the result of the start request. This flag is set when
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100340 * {@link ActivityStarter#setMayWait(int)} is called.
Bryce Lee4c9a5972017-12-01 22:14:24 -0800341 * {@see ActivityStarter#startActivityMayWait}.
342 */
343 boolean mayWait;
Bryce Leedaa91e42017-12-06 14:13:01 -0800344
345 /**
Bryce Leea3cd8e02018-01-09 15:44:24 -0800346 * Ensure constructed request matches reset instance.
347 */
348 Request() {
349 reset();
350 }
351
352 /**
Bryce Leedaa91e42017-12-06 14:13:01 -0800353 * Sets values back to the initial state, clearing any held references.
354 */
355 void reset() {
356 caller = null;
357 intent = null;
358 ephemeralIntent = null;
359 resolvedType = null;
360 activityInfo = null;
361 resolveInfo = null;
362 voiceSession = null;
363 voiceInteractor = null;
364 resultTo = null;
365 resultWho = null;
366 requestCode = 0;
Bryce Leea3cd8e02018-01-09 15:44:24 -0800367 callingPid = DEFAULT_CALLING_PID;
368 callingUid = DEFAULT_CALLING_UID;
Bryce Leedaa91e42017-12-06 14:13:01 -0800369 callingPackage = null;
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000370 realCallingPid = DEFAULT_REAL_CALLING_PID;
371 realCallingUid = DEFAULT_REAL_CALLING_UID;
Bryce Leedaa91e42017-12-06 14:13:01 -0800372 startFlags = 0;
373 activityOptions = null;
374 ignoreTargetSecurity = false;
375 componentSpecified = false;
376 outActivity = null;
377 inTask = null;
378 reason = null;
379 profilerInfo = null;
380 globalConfig = null;
Bryce Leedaa91e42017-12-06 14:13:01 -0800381 userId = 0;
382 waitResult = null;
383 mayWait = false;
Winson Chunge2d72172018-01-25 17:46:20 +0000384 avoidMoveToFront = false;
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200385 allowPendingRemoteAnimationRegistryLookup = true;
Patrick Baumann31426b22018-05-21 13:46:40 -0700386 filterCallingUid = UserHandle.USER_NULL;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100387 originatingPendingIntent = null;
Michal Karpinskiac116df2018-12-10 17:51:42 +0000388 allowBackgroundActivityStart = false;
Bryce Leedaa91e42017-12-06 14:13:01 -0800389 }
390
391 /**
392 * Adopts all values from passed in request.
393 */
394 void set(Request request) {
395 caller = request.caller;
396 intent = request.intent;
397 ephemeralIntent = request.ephemeralIntent;
398 resolvedType = request.resolvedType;
399 activityInfo = request.activityInfo;
400 resolveInfo = request.resolveInfo;
401 voiceSession = request.voiceSession;
402 voiceInteractor = request.voiceInteractor;
403 resultTo = request.resultTo;
404 resultWho = request.resultWho;
405 requestCode = request.requestCode;
406 callingPid = request.callingPid;
407 callingUid = request.callingUid;
408 callingPackage = request.callingPackage;
409 realCallingPid = request.realCallingPid;
410 realCallingUid = request.realCallingUid;
411 startFlags = request.startFlags;
412 activityOptions = request.activityOptions;
413 ignoreTargetSecurity = request.ignoreTargetSecurity;
414 componentSpecified = request.componentSpecified;
415 outActivity = request.outActivity;
416 inTask = request.inTask;
417 reason = request.reason;
418 profilerInfo = request.profilerInfo;
419 globalConfig = request.globalConfig;
Bryce Leedaa91e42017-12-06 14:13:01 -0800420 userId = request.userId;
421 waitResult = request.waitResult;
422 mayWait = request.mayWait;
Winson Chunge2d72172018-01-25 17:46:20 +0000423 avoidMoveToFront = request.avoidMoveToFront;
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200424 allowPendingRemoteAnimationRegistryLookup
425 = request.allowPendingRemoteAnimationRegistryLookup;
Patrick Baumann31426b22018-05-21 13:46:40 -0700426 filterCallingUid = request.filterCallingUid;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100427 originatingPendingIntent = request.originatingPendingIntent;
Michal Karpinskiac116df2018-12-10 17:51:42 +0000428 allowBackgroundActivityStart = request.allowBackgroundActivityStart;
Bryce Leedaa91e42017-12-06 14:13:01 -0800429 }
Bryce Leed3624e12017-11-30 08:51:45 -0800430 }
431
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700432 ActivityStarter(ActivityStartController controller, ActivityTaskManagerService service,
Bryce Leed3624e12017-11-30 08:51:45 -0800433 ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
434 mController = controller;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800435 mService = service;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800436 mRootActivityContainer = service.mRootActivityContainer;
Bryce Leed3624e12017-11-30 08:51:45 -0800437 mSupervisor = supervisor;
438 mInterceptor = interceptor;
Bryce Leedaa91e42017-12-06 14:13:01 -0800439 reset(true);
440 }
441
442 /**
443 * Effectively duplicates the starter passed in. All state and request values will be
444 * mirrored.
445 * @param starter
446 */
447 void set(ActivityStarter starter) {
448 mStartActivity = starter.mStartActivity;
449 mIntent = starter.mIntent;
450 mCallingUid = starter.mCallingUid;
451 mOptions = starter.mOptions;
452
453 mLaunchTaskBehind = starter.mLaunchTaskBehind;
454 mLaunchFlags = starter.mLaunchFlags;
455 mLaunchMode = starter.mLaunchMode;
456
Bryce Leeec55eb02017-12-05 20:51:27 -0800457 mLaunchParams.set(starter.mLaunchParams);
Bryce Leedaa91e42017-12-06 14:13:01 -0800458
459 mNotTop = starter.mNotTop;
460 mDoResume = starter.mDoResume;
461 mStartFlags = starter.mStartFlags;
462 mSourceRecord = starter.mSourceRecord;
463 mPreferredDisplayId = starter.mPreferredDisplayId;
464
465 mInTask = starter.mInTask;
466 mAddingToTask = starter.mAddingToTask;
467 mReuseTask = starter.mReuseTask;
468
469 mNewTaskInfo = starter.mNewTaskInfo;
470 mNewTaskIntent = starter.mNewTaskIntent;
471 mSourceStack = starter.mSourceStack;
472
473 mTargetStack = starter.mTargetStack;
474 mMovedToFront = starter.mMovedToFront;
475 mNoAnimation = starter.mNoAnimation;
476 mKeepCurTransition = starter.mKeepCurTransition;
477 mAvoidMoveToFront = starter.mAvoidMoveToFront;
478
479 mVoiceSession = starter.mVoiceSession;
480 mVoiceInteractor = starter.mVoiceInteractor;
481
482 mIntentDelivered = starter.mIntentDelivered;
483
484 mRequest.set(starter.mRequest);
Bryce Leed3624e12017-11-30 08:51:45 -0800485 }
486
Bryce Lee4c9a5972017-12-01 22:14:24 -0800487 ActivityRecord getStartActivity() {
488 return mStartActivity;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800489 }
490
Bryce Lee4c9a5972017-12-01 22:14:24 -0800491 boolean relatedToPackage(String packageName) {
492 return (mLastStartActivityRecord[0] != null
493 && packageName.equals(mLastStartActivityRecord[0].packageName))
494 || (mStartActivity != null && packageName.equals(mStartActivity.packageName));
495 }
496
497 /**
498 * Starts an activity based on the request parameters provided earlier.
499 * @return The starter result.
500 */
501 int execute() {
Bryce Leedaa91e42017-12-06 14:13:01 -0800502 try {
503 // TODO(b/64750076): Look into passing request directly to these methods to allow
504 // for transactional diffs and preprocessing.
505 if (mRequest.mayWait) {
506 return startActivityMayWait(mRequest.caller, mRequest.callingUid,
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000507 mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid,
508 mRequest.intent, mRequest.resolvedType,
Bryce Leedaa91e42017-12-06 14:13:01 -0800509 mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
510 mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
511 mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100512 mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200513 mRequest.inTask, mRequest.reason,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100514 mRequest.allowPendingRemoteAnimationRegistryLookup,
Michal Karpinskiac116df2018-12-10 17:51:42 +0000515 mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
Bryce Leedaa91e42017-12-06 14:13:01 -0800516 } else {
517 return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
518 mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
519 mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
520 mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
521 mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
522 mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
523 mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200524 mRequest.outActivity, mRequest.inTask, mRequest.reason,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100525 mRequest.allowPendingRemoteAnimationRegistryLookup,
Michal Karpinskiac116df2018-12-10 17:51:42 +0000526 mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
Bryce Leedaa91e42017-12-06 14:13:01 -0800527 }
528 } finally {
529 onExecutionComplete();
530 }
531 }
532
533 /**
534 * Starts an activity based on the provided {@link ActivityRecord} and environment parameters.
535 * Note that this method is called internally as well as part of {@link #startActivity}.
536 *
537 * @return The start result.
538 */
539 int startResolvedActivity(final ActivityRecord r, ActivityRecord sourceRecord,
540 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
541 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
542 ActivityRecord[] outActivity) {
543 try {
544 return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
545 doResume, options, inTask, outActivity);
546 } finally {
547 onExecutionComplete();
Bryce Lee4c9a5972017-12-01 22:14:24 -0800548 }
549 }
550
551 private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700552 String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
553 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
554 IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
555 String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100556 SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200557 ActivityRecord[] outActivity, TaskRecord inTask, String reason,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100558 boolean allowPendingRemoteAnimationRegistryLookup,
Michal Karpinskiac116df2018-12-10 17:51:42 +0000559 PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700560
561 if (TextUtils.isEmpty(reason)) {
562 throw new IllegalArgumentException("Need to specify a reason.");
563 }
564 mLastStartReason = reason;
565 mLastStartActivityTimeMs = System.currentTimeMillis();
566 mLastStartActivityRecord[0] = null;
567
568 mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
569 aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
570 callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
571 options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
Michal Karpinskiac116df2018-12-10 17:51:42 +0000572 inTask, allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent,
573 allowBackgroundActivityStart);
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700574
575 if (outActivity != null) {
576 // mLastStartActivityRecord[0] is set in the call to startActivity above.
577 outActivity[0] = mLastStartActivityRecord[0];
578 }
Bryce Leef9d49542017-06-26 16:27:32 -0700579
Bryce Lee93e7f792017-10-25 15:54:55 -0700580 return getExternalResult(mLastStartActivityResult);
581 }
582
Bryce Leed3624e12017-11-30 08:51:45 -0800583 static int getExternalResult(int result) {
Bryce Leef9d49542017-06-26 16:27:32 -0700584 // Aborted results are treated as successes externally, but we must track them internally.
Bryce Lee93e7f792017-10-25 15:54:55 -0700585 return result != START_ABORTED ? result : START_SUCCESS;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700586 }
587
Bryce Leedaa91e42017-12-06 14:13:01 -0800588 /**
589 * Called when execution is complete. Sets state indicating completion and proceeds with
590 * recycling if appropriate.
591 */
592 private void onExecutionComplete() {
593 mController.onExecutionComplete(this);
594 }
595
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700596 private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800597 String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
598 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
599 IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
600 String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100601 SafeActivityOptions options,
602 boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100603 TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup,
Michal Karpinskiac116df2018-12-10 17:51:42 +0000604 PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800605 int err = ActivityManager.START_SUCCESS;
Chad Brubaker06068612017-04-06 09:43:47 -0700606 // Pull the optional Ephemeral Installer-only bundle out of the options early.
607 final Bundle verificationBundle
608 = options != null ? options.popAppVerificationBundle() : null;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800609
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700610 WindowProcessController callerApp = null;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800611 if (caller != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700612 callerApp = mService.getProcessController(caller);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800613 if (callerApp != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700614 callingPid = callerApp.getPid();
615 callingUid = callerApp.mInfo.uid;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800616 } else {
617 Slog.w(TAG, "Unable to find app for caller " + caller
618 + " (pid=" + callingPid + ") when starting: "
619 + intent.toString());
620 err = ActivityManager.START_PERMISSION_DENIED;
621 }
622 }
623
Bryce Lee93e7f792017-10-25 15:54:55 -0700624 final int userId = aInfo != null && aInfo.applicationInfo != null
625 ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800626
627 if (err == ActivityManager.START_SUCCESS) {
628 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
Andrii Kulian03c403d2016-11-11 11:14:12 -0800629 + "} from uid " + callingUid);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800630 }
631
632 ActivityRecord sourceRecord = null;
633 ActivityRecord resultRecord = null;
634 if (resultTo != null) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800635 sourceRecord = mRootActivityContainer.isInAnyStack(resultTo);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800636 if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
637 "Will send result to " + resultTo + " " + sourceRecord);
638 if (sourceRecord != null) {
639 if (requestCode >= 0 && !sourceRecord.finishing) {
640 resultRecord = sourceRecord;
641 }
642 }
643 }
644
645 final int launchFlags = intent.getFlags();
646
647 if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
648 // Transfer the result target from the source activity to the new
649 // one being started, including any failures.
650 if (requestCode >= 0) {
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100651 SafeActivityOptions.abort(options);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800652 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
653 }
654 resultRecord = sourceRecord.resultTo;
655 if (resultRecord != null && !resultRecord.isInStackLocked()) {
656 resultRecord = null;
657 }
658 resultWho = sourceRecord.resultWho;
659 requestCode = sourceRecord.requestCode;
660 sourceRecord.resultTo = null;
661 if (resultRecord != null) {
662 resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
663 }
664 if (sourceRecord.launchedFromUid == callingUid) {
665 // The new activity is being launched from the same uid as the previous
666 // activity in the flow, and asking to forward its result back to the
667 // previous. In this case the activity is serving as a trampoline between
668 // the two, so we also want to update its launchedFromPackage to be the
669 // same as the previous activity. Note that this is safe, since we know
670 // these two packages come from the same uid; the caller could just as
671 // well have supplied that same package name itself. This specifially
672 // deals with the case of an intent picker/chooser being launched in the app
673 // flow to redirect to an activity picked by the user, where we want the final
674 // activity to consider it to have been launched by the previous app activity.
675 callingPackage = sourceRecord.launchedFromPackage;
676 }
677 }
678
679 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
680 // We couldn't find a class that can handle the given Intent.
681 // That's the end of that!
682 err = ActivityManager.START_INTENT_NOT_RESOLVED;
683 }
684
685 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
686 // We couldn't find the specific class specified in the Intent.
687 // Also the end of the line.
688 err = ActivityManager.START_CLASS_NOT_FOUND;
689 }
690
691 if (err == ActivityManager.START_SUCCESS && sourceRecord != null
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800692 && sourceRecord.getTaskRecord().voiceSession != null) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800693 // If this activity is being launched as part of a voice session, we need
694 // to ensure that it is safe to do so. If the upcoming activity will also
695 // be part of the voice session, we can only launch it if it has explicitly
696 // said it supports the VOICE category, or it is a part of the calling app.
697 if ((launchFlags & FLAG_ACTIVITY_NEW_TASK) == 0
698 && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
699 try {
700 intent.addCategory(Intent.CATEGORY_VOICE);
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700701 if (!mService.getPackageManager().activitySupportsIntent(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800702 intent.getComponent(), intent, resolvedType)) {
703 Slog.w(TAG,
704 "Activity being started in current voice task does not support voice: "
705 + intent);
706 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
707 }
708 } catch (RemoteException e) {
709 Slog.w(TAG, "Failure checking voice capabilities", e);
710 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
711 }
712 }
713 }
714
715 if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
716 // If the caller is starting a new voice session, just make sure the target
717 // is actually allowing it to run this way.
718 try {
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700719 if (!mService.getPackageManager().activitySupportsIntent(intent.getComponent(),
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800720 intent, resolvedType)) {
721 Slog.w(TAG,
722 "Activity being started in new voice task does not support: "
723 + intent);
724 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
725 }
726 } catch (RemoteException e) {
727 Slog.w(TAG, "Failure checking voice capabilities", e);
728 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
729 }
730 }
731
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800732 final ActivityStack resultStack = resultRecord == null
733 ? null : resultRecord.getActivityStack();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800734
Wale Ogunwale01d66562015-12-29 08:19:19 -0800735 if (err != START_SUCCESS) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800736 if (resultRecord != null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -0800737 resultStack.sendActivityResultLocked(
738 -1, resultRecord, resultWho, requestCode, RESULT_CANCELED, null);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800739 }
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100740 SafeActivityOptions.abort(options);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800741 return err;
742 }
743
744 boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100745 requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity,
Winson Chungc9804e72018-05-15 11:01:44 -0700746 inTask != null, callerApp, resultRecord, resultStack);
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700747 abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800748 callingPid, resolvedType, aInfo.applicationInfo);
749
Michal Karpinskic02364c2019-01-22 13:00:04 +0000750 boolean abortBackgroundStart = false;
Michal Karpinski8596ded2018-11-14 14:43:48 +0000751 if (!abort) {
Michal Karpinskic02364c2019-01-22 13:00:04 +0000752 abortBackgroundStart = shouldAbortBackgroundActivityStart(callingUid, callingPid,
753 callingPackage, realCallingUid, callerApp, originatingPendingIntent,
Michal Karpinskid0162852019-01-15 16:05:25 +0000754 allowBackgroundActivityStart, intent);
Michal Karpinskic02364c2019-01-22 13:00:04 +0000755 abort |= (abortBackgroundStart && !mService.isBackgroundActivityStartsEnabled());
756 // TODO: remove this toast after feature development is done
757 if (abortBackgroundStart) {
758 final String toastMsg = abort
759 ? "Background activity start from " + callingPackage
760 + " blocked. See go/q-bg-block."
761 : "This background activity start from " + callingPackage
762 + " will be blocked in future Q builds. See go/q-bg-block.";
763 mService.mUiHandler.post(() -> {
764 Toast.makeText(mService.mContext, toastMsg, Toast.LENGTH_LONG).show();
765 });
766 }
Michal Karpinski8596ded2018-11-14 14:43:48 +0000767 }
768
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100769 // Merge the two options bundles, while realCallerOptions takes precedence.
770 ActivityOptions checkedOptions = options != null
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700771 ? options.getOptions(intent, aInfo, callerApp, mSupervisor) : null;
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200772 if (allowPendingRemoteAnimationRegistryLookup) {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700773 checkedOptions = mService.getActivityStartController()
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200774 .getPendingRemoteAnimationRegistry()
775 .overrideOptionsIfNeeded(callingPackage, checkedOptions);
776 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700777 if (mService.mController != null) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800778 try {
779 // The Intent we give to the watcher has the extra data
780 // stripped off, since it can contain private information.
781 Intent watchIntent = intent.cloneFilter();
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700782 abort |= !mService.mController.activityStarting(watchIntent,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800783 aInfo.applicationInfo.packageName);
784 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700785 mService.mController = null;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800786 }
787 }
788
Rubin Xu58d25992016-01-21 17:47:13 +0000789 mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage);
Benjamin Franz563707b2017-06-29 15:06:13 +0100790 if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100791 callingUid, checkedOptions)) {
Benjamin Franz563707b2017-06-29 15:06:13 +0100792 // activity start was intercepted, e.g. because the target user is currently in quiet
793 // mode (turn off work) or the target application is suspended
794 intent = mInterceptor.mIntent;
795 rInfo = mInterceptor.mRInfo;
796 aInfo = mInterceptor.mAInfo;
797 resolvedType = mInterceptor.mResolvedType;
798 inTask = mInterceptor.mInTask;
799 callingPid = mInterceptor.mCallingPid;
800 callingUid = mInterceptor.mCallingUid;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100801 checkedOptions = mInterceptor.mActivityOptions;
Benjamin Franz563707b2017-06-29 15:06:13 +0100802 }
803
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800804 if (abort) {
805 if (resultRecord != null) {
806 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Wale Ogunwale01d66562015-12-29 08:19:19 -0800807 RESULT_CANCELED, null);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800808 }
809 // We pretend to the caller that it was really started, but
810 // they will just get a cancel result.
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100811 ActivityOptions.abort(checkedOptions);
Bryce Leef9d49542017-06-26 16:27:32 -0700812 return START_ABORTED;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800813 }
814
815 // If permissions need a review before any of the app components can run, we
816 // launch the review activity and pass a pending intent to start the activity
817 // we are to launching now after the review is completed.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700818 if (aInfo != null) {
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700819 if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800820 aInfo.packageName, userId)) {
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700821 IIntentSender target = mService.getIntentSenderLocked(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800822 ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
823 callingUid, userId, null, null, 0, new Intent[]{intent},
824 new String[]{resolvedType}, PendingIntent.FLAG_CANCEL_CURRENT
825 | PendingIntent.FLAG_ONE_SHOT, null);
826
827 final int flags = intent.getFlags();
828 Intent newIntent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
829 newIntent.setFlags(flags
830 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
831 newIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, aInfo.packageName);
832 newIntent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target));
833 if (resultRecord != null) {
834 newIntent.putExtra(Intent.EXTRA_RESULT_NEEDED, true);
835 }
836 intent = newIntent;
837
838 resolvedType = null;
839 callingUid = realCallingUid;
840 callingPid = realCallingPid;
841
Svet Ganovcbcbf662018-05-10 17:25:29 -0700842 rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0,
Patrick Baumann31426b22018-05-21 13:46:40 -0700843 computeResolveFilterUid(
844 callingUid, realCallingUid, mRequest.filterCallingUid));
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800845 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
846 null /*profilerInfo*/);
847
848 if (DEBUG_PERMISSIONS_REVIEW) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800849 final ActivityStack focusedStack =
850 mRootActivityContainer.getTopDisplayFocusedStack();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800851 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true,
852 true, false) + "} from uid " + callingUid + " on display "
Andrii Kulian52d255c2018-07-13 11:32:19 -0700853 + (focusedStack == null ? DEFAULT_DISPLAY : focusedStack.mDisplayId));
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800854 }
855 }
856 }
857
858 // If we have an ephemeral app, abort the process of launching the resolved intent.
859 // Instead, launch the ephemeral installer. Once the installer is finished, it
860 // starts either the intent we resolved here [on install error] or the ephemeral
861 // app [on install success].
Patrick Baumanna89a1722018-02-07 15:26:52 -0800862 if (rInfo != null && rInfo.auxiliaryInfo != null) {
Todd Kennedye9910222017-02-21 16:00:11 -0800863 intent = createLaunchIntent(rInfo.auxiliaryInfo, ephemeralIntent,
Chad Brubaker06068612017-04-06 09:43:47 -0700864 callingPackage, verificationBundle, resolvedType, userId);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800865 resolvedType = null;
866 callingUid = realCallingUid;
867 callingPid = realCallingPid;
868
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800869 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
870 }
871
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700872 ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
Wale Ogunwalef6733932018-06-27 05:14:34 -0700873 callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800874 resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100875 mSupervisor, checkedOptions, sourceRecord);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800876 if (outActivity != null) {
877 outActivity[0] = r;
878 }
879
880 if (r.appTimeTracker == null && sourceRecord != null) {
881 // If the caller didn't specify an explicit time tracker, we want to continue
882 // tracking under any it has.
883 r.appTimeTracker = sourceRecord.appTimeTracker;
884 }
885
Wale Ogunwaled32da472018-11-16 07:19:28 -0800886 final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100887
888 // If we are starting an activity that is not from the same uid as the currently resumed
889 // one, check whether app switches are allowed.
Bryce Leec4ab62a2018-03-05 14:19:26 -0800890 if (voiceSession == null && (stack.getResumedActivity() == null
891 || stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700892 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800893 realCallingPid, realCallingUid, "Activity start")) {
Bryce Leed3624e12017-11-30 08:51:45 -0800894 mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700895 sourceRecord, startFlags, stack, callerApp));
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100896 ActivityOptions.abort(checkedOptions);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800897 return ActivityManager.START_SWITCHES_CANCELED;
898 }
899 }
900
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700901 mService.onStartActivitySetDidAppSwitch();
Bryce Leed3624e12017-11-30 08:51:45 -0800902 mController.doPendingActivityLaunches(false);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800903
Michal Karpinskic02364c2019-01-22 13:00:04 +0000904 // maybe log to TRON, but only if we haven't already in shouldAbortBackgroundActivityStart()
905 if (!abortBackgroundStart) {
906 maybeLogActivityStart(callingUid, callingPackage, realCallingUid, intent, callerApp, r,
907 originatingPendingIntent, false /*abortedStart*/);
908 }
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100909
Bryce Leedaa91e42017-12-06 14:13:01 -0800910 return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100911 true /* doResume */, checkedOptions, inTask, outActivity);
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -0800912 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800913
Michal Karpinski7b97a022018-12-14 15:17:29 +0000914 private boolean shouldAbortBackgroundActivityStart(int callingUid, int callingPid,
915 final String callingPackage, int realCallingUid, WindowProcessController callerApp,
Michal Karpinskid0162852019-01-15 16:05:25 +0000916 PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart,
917 Intent intent) {
Michal Karpinski8596ded2018-11-14 14:43:48 +0000918 // don't abort for the most important UIDs
919 if (callingUid == Process.ROOT_UID || callingUid == Process.SYSTEM_UID) {
920 return false;
921 }
922 // don't abort if the callerApp has any visible activity
923 if (callerApp != null && callerApp.hasForegroundActivities()) {
924 return false;
925 }
Michal Karpinskiac116df2018-12-10 17:51:42 +0000926 // don't abort if the callingUid is in the foreground or is a persistent system process
Michal Karpinskicc88d7e2019-01-24 15:32:12 +0000927 final boolean isCallingUidForeground = mService.isUidForeground(callingUid);
Michal Karpinskid0162852019-01-15 16:05:25 +0000928 final boolean isCallingUidPersistentSystemProcess = isUidPersistentSystemProcess(
929 callingUid);
930 if (isCallingUidForeground || isCallingUidPersistentSystemProcess) {
Michal Karpinski8596ded2018-11-14 14:43:48 +0000931 return false;
932 }
Michal Karpinskiac116df2018-12-10 17:51:42 +0000933 // take realCallingUid into consideration
Michal Karpinskicc88d7e2019-01-24 15:32:12 +0000934 final boolean isRealCallingUidForeground = mService.isUidForeground(
935 realCallingUid);
Michal Karpinskid0162852019-01-15 16:05:25 +0000936 final boolean isRealCallingUidPersistentSystemProcess = isUidPersistentSystemProcess(
937 realCallingUid);
Michal Karpinskiac116df2018-12-10 17:51:42 +0000938 if (realCallingUid != callingUid) {
939 // don't abort if the realCallingUid is in the foreground and callingUid isn't
Michal Karpinskid0162852019-01-15 16:05:25 +0000940 if (isRealCallingUidForeground) {
Michal Karpinskiac116df2018-12-10 17:51:42 +0000941 return false;
942 }
943 // if the realCallingUid is a persistent system process, abort if the IntentSender
944 // wasn't whitelisted to start an activity
Michal Karpinskid0162852019-01-15 16:05:25 +0000945 if (isRealCallingUidPersistentSystemProcess && allowBackgroundActivityStart) {
Michal Karpinskiac116df2018-12-10 17:51:42 +0000946 return false;
947 }
948 }
949 // don't abort if the caller is currently temporarily whitelisted
950 if (callerApp != null && callerApp.areBackgroundActivityStartsAllowed()) {
Michal Karpinski8596ded2018-11-14 14:43:48 +0000951 return false;
952 }
Michal Karpinski7b97a022018-12-14 15:17:29 +0000953 // don't abort if the callingUid has START_ACTIVITIES_FROM_BACKGROUND permission
954 if (mService.checkPermission(START_ACTIVITIES_FROM_BACKGROUND, callingPid, callingUid)
955 == PERMISSION_GRANTED) {
956 return false;
957 }
Michal Karpinski82bb5902018-11-28 15:52:52 +0000958 // don't abort if the caller has the same uid as the recents component
959 if (mSupervisor.mRecentTasks.isCallerRecents(callingUid)) {
960 return false;
961 }
Michal Karpinskic02364c2019-01-22 13:00:04 +0000962 // anything that has fallen through would currently be aborted
963 Slog.w(TAG, "Background activity start [callingPackage: " + callingPackage
Michal Karpinskid0162852019-01-15 16:05:25 +0000964 + "; callingUid: " + callingUid
965 + "; isCallingUidForeground: " + isCallingUidForeground
966 + "; isCallingUidPersistentSystemProcess: " + isCallingUidPersistentSystemProcess
967 + "; realCallingUid: " + realCallingUid
968 + "; isRealCallingUidForeground: " + isRealCallingUidForeground
969 + "; isRealCallingUidPersistentSystemProcess: "
970 + isRealCallingUidPersistentSystemProcess
971 + "; originatingPendingIntent: " + originatingPendingIntent
972 + "; isBgStartWhitelisted: " + allowBackgroundActivityStart
973 + "; intent: " + intent
974 + "]");
Michal Karpinskic02364c2019-01-22 13:00:04 +0000975 maybeLogActivityStart(callingUid, callingPackage, realCallingUid, intent, callerApp,
976 null /*r*/, originatingPendingIntent, true /*abortedStart*/);
Michal Karpinski8596ded2018-11-14 14:43:48 +0000977 return true;
978 }
979
Michal Karpinskiac116df2018-12-10 17:51:42 +0000980 /** Returns true if uid is in a persistent state. */
981 private boolean isUidPersistentSystemProcess(int uid) {
982 return (mService.getUidStateLocked(uid) <= ActivityManager.PROCESS_STATE_PERSISTENT_UI);
983 }
984
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100985 private void maybeLogActivityStart(int callingUid, String callingPackage, int realCallingUid,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700986 Intent intent, WindowProcessController callerApp, ActivityRecord r,
Michal Karpinski8596ded2018-11-14 14:43:48 +0000987 PendingIntentRecord originatingPendingIntent, boolean abortedStart) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700988 boolean callerAppHasForegroundActivity =
989 callerApp != null && callerApp.hasForegroundActivities();
990 if (!mService.isActivityStartsLoggingEnabled() || callerAppHasForegroundActivity
Michal Karpinski8596ded2018-11-14 14:43:48 +0000991 || (!abortedStart && r == null)) {
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100992 // skip logging in this case
993 return;
994 }
995
996 try {
997 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "logActivityStart");
Wale Ogunwalebff2df42018-10-18 17:09:19 -0700998 final int callingUidProcState = mService.getUidStateLocked(callingUid);
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100999 final boolean callingUidHasAnyVisibleWindow =
Michal Karpinskia606a292019-01-12 17:29:52 +00001000 mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(callingUid);
Michal Karpinski201bc0c2018-07-20 15:32:00 +01001001 final int realCallingUidProcState = (callingUid == realCallingUid)
1002 ? callingUidProcState
Wale Ogunwalebff2df42018-10-18 17:09:19 -07001003 : mService.getUidStateLocked(realCallingUid);
Michal Karpinski201bc0c2018-07-20 15:32:00 +01001004 final boolean realCallingUidHasAnyVisibleWindow = (callingUid == realCallingUid)
1005 ? callingUidHasAnyVisibleWindow
Michal Karpinskia606a292019-01-12 17:29:52 +00001006 : mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(
1007 realCallingUid);
Michal Karpinski8596ded2018-11-14 14:43:48 +00001008 final String targetPackage = (r != null) ? r.packageName : null;
1009 final int targetUid = (r!= null) ? ((r.appInfo != null) ? r.appInfo.uid : -1) : -1;
Wale Ogunwalebff2df42018-10-18 17:09:19 -07001010 final int targetUidProcState = mService.getUidStateLocked(targetUid);
Michal Karpinski201bc0c2018-07-20 15:32:00 +01001011 final boolean targetUidHasAnyVisibleWindow = (targetUid != -1)
Michal Karpinskia606a292019-01-12 17:29:52 +00001012 ? mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(targetUid)
Michal Karpinski201bc0c2018-07-20 15:32:00 +01001013 : false;
1014 final String targetWhitelistTag = (targetUid != -1)
Wale Ogunwale9de19442018-10-18 19:05:03 -07001015 ? mService.getPendingTempWhitelistTagForUidLocked(targetUid)
Michal Karpinski201bc0c2018-07-20 15:32:00 +01001016 : null;
1017
1018 mSupervisor.getActivityMetricsLogger().logActivityStart(intent, callerApp, r,
1019 callingUid, callingPackage, callingUidProcState,
1020 callingUidHasAnyVisibleWindow,
1021 realCallingUid, realCallingUidProcState,
1022 realCallingUidHasAnyVisibleWindow,
1023 targetUid, targetPackage, targetUidProcState,
1024 targetUidHasAnyVisibleWindow, targetWhitelistTag,
1025 (originatingPendingIntent != null));
1026 } finally {
1027 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1028 }
1029 }
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001030
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001031 /**
1032 * Creates a launch intent for the given auxiliary resolution data.
1033 */
Patrick Baumann577d4022018-01-31 16:55:10 +00001034 private @NonNull Intent createLaunchIntent(@Nullable AuxiliaryResolveInfo auxiliaryResponse,
Chad Brubaker06068612017-04-06 09:43:47 -07001035 Intent originalIntent, String callingPackage, Bundle verificationBundle,
1036 String resolvedType, int userId) {
Patrick Baumann577d4022018-01-31 16:55:10 +00001037 if (auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo) {
Todd Kennedye9910222017-02-21 16:00:11 -08001038 // request phase two resolution
Wale Ogunwale906f9c62018-07-23 11:23:44 -07001039 mService.getPackageManagerInternalLocked().requestInstantAppResolutionPhaseTwo(
Chad Brubaker06068612017-04-06 09:43:47 -07001040 auxiliaryResponse, originalIntent, resolvedType, callingPackage,
1041 verificationBundle, userId);
Todd Kennedye9910222017-02-21 16:00:11 -08001042 }
Todd Kennedydfc27c62017-05-17 15:32:10 -07001043 return InstantAppResolver.buildEphemeralInstallerIntent(
Patrick Baumann577d4022018-01-31 16:55:10 +00001044 originalIntent,
1045 InstantAppResolver.sanitizeIntent(originalIntent),
1046 auxiliaryResponse == null ? null : auxiliaryResponse.failureIntent,
1047 callingPackage,
1048 verificationBundle,
1049 resolvedType,
1050 userId,
1051 auxiliaryResponse == null ? null : auxiliaryResponse.installFailureActivity,
1052 auxiliaryResponse == null ? null : auxiliaryResponse.token,
1053 auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo,
1054 auxiliaryResponse == null ? null : auxiliaryResponse.filters);
Todd Kennedye9910222017-02-21 16:00:11 -08001055 }
1056
Riddle Hsu16567132018-08-16 21:37:47 +08001057 void postStartActivityProcessing(ActivityRecord r, int result,
1058 ActivityStack startedActivityStack) {
Bryce Lee7f936862017-05-09 15:33:18 -07001059 if (ActivityManager.isStartResultFatalError(result)) {
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -08001060 return;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001061 }
Filip Gruszczynski303210b2016-01-08 16:28:08 -08001062
Chong Zhang5022da32016-06-21 16:31:37 -07001063 // We're waiting for an activity launch to finish, but that activity simply
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001064 // brought another activity to front. We must also handle the case where the task is already
1065 // in the front as a result of the trampoline activity being in the same task (it will be
1066 // considered focused as the trampoline will be finished). Let startActivityMayWait() know
1067 // about this, so it waits for the new activity to become visible instead.
1068 mSupervisor.reportWaitingActivityLaunchedIfNeeded(r, result);
Chong Zhang5022da32016-06-21 16:31:37 -07001069
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001070 if (startedActivityStack == null) {
1071 return;
1072 }
1073
Wale Ogunwaleac36e4d2017-11-29 13:30:26 -08001074 final int clearTaskFlags = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK;
1075 boolean clearedTask = (mLaunchFlags & clearTaskFlags) == clearTaskFlags
1076 && mReuseTask != null;
Wale Ogunwale7d7973a2018-04-05 10:25:59 -07001077 if (result == START_TASK_TO_FRONT || result == START_DELIVERED_TO_TOP || clearedTask) {
1078 // The activity was already running so it wasn't started, but either brought to the
1079 // front or the new intent was delivered to it since it was already in front. Notify
1080 // anyone interested in this piece of information.
1081 switch (startedActivityStack.getWindowingMode()) {
1082 case WINDOWING_MODE_PINNED:
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001083 mService.getTaskChangeNotificationController().notifyPinnedActivityRestartAttempt(
Wale Ogunwale7d7973a2018-04-05 10:25:59 -07001084 clearedTask);
1085 break;
1086 case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
Louis Changbd48dca2018-08-29 17:44:34 +08001087 final ActivityStack homeStack =
1088 startedActivityStack.getDisplay().getHomeStack();
Wale Ogunwale7d7973a2018-04-05 10:25:59 -07001089 if (homeStack != null && homeStack.shouldBeVisible(null /* starting */)) {
1090 mService.mWindowManager.showRecentApps();
1091 }
1092 break;
1093 }
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -08001094 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001095 }
1096
Bryce Lee4c9a5972017-12-01 22:14:24 -08001097 private int startActivityMayWait(IApplicationThread caller, int callingUid,
Michal Karpinski84d9ebd2019-01-17 18:28:59 +00001098 String callingPackage, int requestRealCallingPid, int requestRealCallingUid,
1099 Intent intent, String resolvedType, IVoiceInteractionSession voiceSession,
1100 IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode,
1101 int startFlags, ProfilerInfo profilerInfo, WaitResult outResult,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001102 Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +02001103 int userId, TaskRecord inTask, String reason,
Michal Karpinski201bc0c2018-07-20 15:32:00 +01001104 boolean allowPendingRemoteAnimationRegistryLookup,
Michal Karpinskiac116df2018-12-10 17:51:42 +00001105 PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001106 // Refuse possible leaked file descriptors
1107 if (intent != null && intent.hasFileDescriptors()) {
1108 throw new IllegalArgumentException("File descriptors passed in Intent");
1109 }
Igor Murashkin212d06c2018-10-22 16:34:39 -07001110 mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001111 boolean componentSpecified = intent.getComponent() != null;
1112
Michal Karpinski84d9ebd2019-01-17 18:28:59 +00001113 final int realCallingPid = requestRealCallingPid != Request.DEFAULT_REAL_CALLING_PID
1114 ? requestRealCallingPid
1115 : Binder.getCallingPid();
1116 final int realCallingUid = requestRealCallingUid != Request.DEFAULT_REAL_CALLING_UID
1117 ? requestRealCallingUid
1118 : Binder.getCallingUid();
Makoto Onuki1a342742018-04-26 14:56:59 -07001119
Svet Ganovcbcbf662018-05-10 17:25:29 -07001120 int callingPid;
1121 if (callingUid >= 0) {
1122 callingPid = -1;
1123 } else if (caller == null) {
1124 callingPid = realCallingPid;
1125 callingUid = realCallingUid;
1126 } else {
1127 callingPid = callingUid = -1;
1128 }
1129
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001130 // Save a copy in case ephemeral needs it
1131 final Intent ephemeralIntent = new Intent(intent);
1132 // Don't modify the client's object!
1133 intent = new Intent(intent);
Todd Kennedyb21be122017-03-24 14:10:01 -07001134 if (componentSpecified
Patrick Baumann531db462018-02-13 13:01:47 -08001135 && !(Intent.ACTION_VIEW.equals(intent.getAction()) && intent.getData() == null)
Patrick Baumann577d4022018-01-31 16:55:10 +00001136 && !Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE.equals(intent.getAction())
1137 && !Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE.equals(intent.getAction())
Wale Ogunwale906f9c62018-07-23 11:23:44 -07001138 && mService.getPackageManagerInternalLocked()
Todd Kennedyb21be122017-03-24 14:10:01 -07001139 .isInstantAppInstallerComponent(intent.getComponent())) {
1140 // intercept intents targeted directly to the ephemeral installer the
Patrick Baumann577d4022018-01-31 16:55:10 +00001141 // ephemeral installer should never be started with a raw Intent; instead
Todd Kennedyb21be122017-03-24 14:10:01 -07001142 // adjust the intent so it looks like a "normal" instant app launch
1143 intent.setComponent(null /*component*/);
1144 componentSpecified = false;
1145 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001146
Makoto Onuki1a342742018-04-26 14:56:59 -07001147 ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
Patrick Baumann31426b22018-05-21 13:46:40 -07001148 0 /* matchFlags */,
1149 computeResolveFilterUid(
1150 callingUid, realCallingUid, mRequest.filterCallingUid));
Kenny Guyb1b30262016-02-09 16:02:35 +00001151 if (rInfo == null) {
1152 UserInfo userInfo = mSupervisor.getUserInfo(userId);
1153 if (userInfo != null && userInfo.isManagedProfile()) {
1154 // Special case for managed profiles, if attempting to launch non-cryto aware
1155 // app in a locked managed profile from an unlocked parent allow it to resolve
1156 // as user will be sent via confirm credentials to unlock the profile.
1157 UserManager userManager = UserManager.get(mService.mContext);
Fyodor Kupolovce4db0a2016-05-11 14:21:18 -07001158 boolean profileLockedAndParentUnlockingOrUnlocked = false;
Tony Mak13436452016-02-24 11:08:38 +00001159 long token = Binder.clearCallingIdentity();
1160 try {
Fyodor Kupolovce4db0a2016-05-11 14:21:18 -07001161 UserInfo parent = userManager.getProfileParent(userId);
1162 profileLockedAndParentUnlockingOrUnlocked = (parent != null)
1163 && userManager.isUserUnlockingOrUnlocked(parent.id)
1164 && !userManager.isUserUnlockingOrUnlocked(userId);
Tony Mak13436452016-02-24 11:08:38 +00001165 } finally {
1166 Binder.restoreCallingIdentity(token);
1167 }
Fyodor Kupolovce4db0a2016-05-11 14:21:18 -07001168 if (profileLockedAndParentUnlockingOrUnlocked) {
Kenny Guyb1b30262016-02-09 16:02:35 +00001169 rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
Jeff Sharkey8a372a02016-03-16 16:25:45 -06001170 PackageManager.MATCH_DIRECT_BOOT_AWARE
Patrick Baumann78380272018-04-04 10:41:01 -07001171 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
Patrick Baumann31426b22018-05-21 13:46:40 -07001172 computeResolveFilterUid(
1173 callingUid, realCallingUid, mRequest.filterCallingUid));
Kenny Guyb1b30262016-02-09 16:02:35 +00001174 }
1175 }
1176 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001177 // Collect information about the target of the Intent.
1178 ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
1179
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001180 synchronized (mService.mGlobalLock) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001181 final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
Andrii Kulian8072d112016-09-16 11:11:01 -07001182 stack.mConfigWillChange = globalConfig != null
Wale Ogunwalef6733932018-06-27 05:14:34 -07001183 && mService.getGlobalConfiguration().diff(globalConfig) != 0;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001184 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
1185 "Starting activity when config will change = " + stack.mConfigWillChange);
1186
1187 final long origId = Binder.clearCallingIdentity();
1188
1189 if (aInfo != null &&
1190 (aInfo.applicationInfo.privateFlags
Dianne Hackbornc8e4fad2018-05-04 11:31:09 -07001191 & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0 &&
Wale Ogunwale214f3482018-10-04 11:00:47 -07001192 mService.mHasHeavyWeightFeature) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001193 // This may be a heavy-weight process! Check to see if we already
1194 // have another, different heavy-weight process running.
1195 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
Wale Ogunwale53783742018-09-16 10:21:51 -07001196 final WindowProcessController heavy = mService.mHeavyWeightProcess;
1197 if (heavy != null && (heavy.mInfo.uid != aInfo.applicationInfo.uid
1198 || !heavy.mName.equals(aInfo.processName))) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001199 int appCallingUid = callingUid;
1200 if (caller != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001201 WindowProcessController callerApp =
1202 mService.getProcessController(caller);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001203 if (callerApp != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001204 appCallingUid = callerApp.mInfo.uid;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001205 } else {
1206 Slog.w(TAG, "Unable to find app for caller " + caller
1207 + " (pid=" + callingPid + ") when starting: "
1208 + intent.toString());
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001209 SafeActivityOptions.abort(options);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001210 return ActivityManager.START_PERMISSION_DENIED;
1211 }
1212 }
1213
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07001214 IIntentSender target = mService.getIntentSenderLocked(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001215 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
1216 appCallingUid, userId, null, null, 0, new Intent[] { intent },
1217 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
1218 | PendingIntent.FLAG_ONE_SHOT, null);
1219
1220 Intent newIntent = new Intent();
1221 if (requestCode >= 0) {
1222 // Caller is requesting a result.
1223 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
1224 }
1225 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
1226 new IntentSender(target));
Wale Ogunwale53783742018-09-16 10:21:51 -07001227 heavy.updateIntentForHeavyWeightActivity(newIntent);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001228 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
1229 aInfo.packageName);
1230 newIntent.setFlags(intent.getFlags());
1231 newIntent.setClassName("android",
1232 HeavyWeightSwitcherActivity.class.getName());
1233 intent = newIntent;
1234 resolvedType = null;
1235 caller = null;
1236 callingUid = Binder.getCallingUid();
1237 callingPid = Binder.getCallingPid();
1238 componentSpecified = true;
Makoto Onuki1a342742018-04-26 14:56:59 -07001239 rInfo = mSupervisor.resolveIntent(intent, null /*resolvedType*/, userId,
Patrick Baumann31426b22018-05-21 13:46:40 -07001240 0 /* matchFlags */, computeResolveFilterUid(
1241 callingUid, realCallingUid, mRequest.filterCallingUid));
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001242 aInfo = rInfo != null ? rInfo.activityInfo : null;
1243 if (aInfo != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001244 aInfo = mService.mAmInternal.getActivityInfoForUser(aInfo, userId);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001245 }
1246 }
1247 }
1248 }
1249
Jorim Jaggi275561a2016-02-23 10:11:02 -05001250 final ActivityRecord[] outRecord = new ActivityRecord[1];
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001251 int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
1252 voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
1253 callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +02001254 ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
Michal Karpinskiac116df2018-12-10 17:51:42 +00001255 allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent,
1256 allowBackgroundActivityStart);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001257
1258 Binder.restoreCallingIdentity(origId);
1259
1260 if (stack.mConfigWillChange) {
1261 // If the caller also wants to switch to a new configuration,
1262 // do so now. This allows a clean switch, as we are waiting
1263 // for the current activity to pause (so we will not destroy
1264 // it), and have not yet started the next activity.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001265 mService.mAmInternal.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001266 "updateConfiguration()");
1267 stack.mConfigWillChange = false;
1268 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
1269 "Updating to new configuration after starting activity.");
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001270 mService.updateConfigurationLocked(globalConfig, null, false);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001271 }
1272
Vishnu Nair132ee832018-09-28 15:00:05 -07001273 // Notify ActivityMetricsLogger that the activity has launched. ActivityMetricsLogger
1274 // will then wait for the windows to be drawn and populate WaitResult.
1275 mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outRecord[0]);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001276 if (outResult != null) {
1277 outResult.result = res;
Bryce Lee4a194382017-04-04 14:32:48 -07001278
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001279 final ActivityRecord r = outRecord[0];
1280
1281 switch(res) {
1282 case START_SUCCESS: {
1283 mSupervisor.mWaitingActivityLaunched.add(outResult);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001284 do {
1285 try {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001286 mService.mGlobalLock.wait();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001287 } catch (InterruptedException e) {
1288 }
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001289 } while (outResult.result != START_TASK_TO_FRONT
1290 && !outResult.timeout && outResult.who == null);
1291 if (outResult.result == START_TASK_TO_FRONT) {
1292 res = START_TASK_TO_FRONT;
1293 }
1294 break;
1295 }
1296 case START_DELIVERED_TO_TOP: {
1297 outResult.timeout = false;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001298 outResult.who = r.mActivityComponent;
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001299 outResult.totalTime = 0;
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001300 break;
1301 }
1302 case START_TASK_TO_FRONT: {
1303 // ActivityRecord may represent a different activity, but it should not be
1304 // in the resumed state.
Bryce Lee7ace3952018-02-16 14:34:32 -08001305 if (r.nowVisible && r.isState(RESUMED)) {
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001306 outResult.timeout = false;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001307 outResult.who = r.mActivityComponent;
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001308 outResult.totalTime = 0;
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001309 } else {
Vishnu Nair132ee832018-09-28 15:00:05 -07001310 final long startTimeMs = SystemClock.uptimeMillis();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001311 mSupervisor.waitActivityVisible(
1312 r.mActivityComponent, outResult, startTimeMs);
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001313 // Note: the timeout variable is not currently not ever set.
1314 do {
1315 try {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001316 mService.mGlobalLock.wait();
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001317 } catch (InterruptedException e) {
1318 }
1319 } while (!outResult.timeout && outResult.who == null);
1320 }
1321 break;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001322 }
1323 }
1324 }
1325
1326 return res;
1327 }
1328 }
1329
Svet Ganovcbcbf662018-05-10 17:25:29 -07001330 /**
1331 * Compute the logical UID based on which the package manager would filter
1332 * app components i.e. based on which the instant app policy would be applied
1333 * because it is the logical calling UID.
1334 *
1335 * @param customCallingUid The UID on whose behalf to make the call.
1336 * @param actualCallingUid The UID actually making the call.
Patrick Baumann31426b22018-05-21 13:46:40 -07001337 * @param filterCallingUid The UID to be used to filter for instant apps.
Svet Ganovcbcbf662018-05-10 17:25:29 -07001338 * @return The logical UID making the call.
1339 */
Patrick Baumann31426b22018-05-21 13:46:40 -07001340 static int computeResolveFilterUid(int customCallingUid, int actualCallingUid,
1341 int filterCallingUid) {
1342 return filterCallingUid != UserHandle.USER_NULL
1343 ? filterCallingUid
1344 : (customCallingUid >= 0 ? customCallingUid : actualCallingUid);
Svet Ganovcbcbf662018-05-10 17:25:29 -07001345 }
1346
Bryce Leedaa91e42017-12-06 14:13:01 -08001347 private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
1348 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1349 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
1350 ActivityRecord[] outActivity) {
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001351 int result = START_CANCELED;
Riddle Hsu16567132018-08-16 21:37:47 +08001352 final ActivityStack startedActivityStack;
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001353 try {
1354 mService.mWindowManager.deferSurfaceLayout();
1355 result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
Bryce Lee4a194382017-04-04 14:32:48 -07001356 startFlags, doResume, options, inTask, outActivity);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001357 } finally {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001358 final ActivityStack currentStack = r.getActivityStack();
Riddle Hsu16567132018-08-16 21:37:47 +08001359 startedActivityStack = currentStack != null ? currentStack : mTargetStack;
1360
1361 if (ActivityManager.isStartResultSuccessful(result)) {
1362 if (startedActivityStack != null) {
1363 // If there is no state change (e.g. a resumed activity is reparented to
1364 // top of another display) to trigger a visibility/configuration checking,
1365 // we have to update the configuration for changing to different display.
1366 final ActivityRecord currentTop =
1367 startedActivityStack.topRunningActivityLocked();
1368 if (currentTop != null && currentTop.shouldUpdateConfigForDisplayChanged()) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001369 mRootActivityContainer.ensureVisibilityAndConfig(
1370 currentTop, currentTop.getDisplayId(),
Riddle Hsu16567132018-08-16 21:37:47 +08001371 true /* markFrozenIfConfigChanged */, false /* deferResume */);
1372 }
1373 }
1374 } else {
1375 // If we are not able to proceed, disassociate the activity from the task.
1376 // Leaving an activity in an incomplete state can lead to issues, such as
1377 // performing operations without a window container.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001378 final ActivityStack stack = mStartActivity.getActivityStack();
Riddle Hsu16567132018-08-16 21:37:47 +08001379 if (stack != null) {
1380 stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,
1381 null /* intentResultData */, "startActivity", true /* oomAdj */);
1382 }
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001383 }
1384 mService.mWindowManager.continueSurfaceLayout();
1385 }
1386
Riddle Hsu16567132018-08-16 21:37:47 +08001387 postStartActivityProcessing(r, result, startedActivityStack);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001388
1389 return result;
1390 }
1391
1392 // Note: This method should only be called from {@link startActivity}.
Wale Ogunwale01d66562015-12-29 08:19:19 -08001393 private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
1394 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
Bryce Lee4a194382017-04-04 14:32:48 -07001395 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
1396 ActivityRecord[] outActivity) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001397
1398 setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
1399 voiceInteractor);
Louis Chang39ba54b2018-10-18 11:28:57 +08001400 final int preferredWindowingMode = mLaunchParams.mWindowingMode;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001401
Louis Chang6fb1e842018-12-03 16:07:50 +08001402 computeLaunchingTaskFlags();
1403
1404 computeSourceStack();
1405
1406 mIntent.setFlags(mLaunchFlags);
1407
1408 ActivityRecord reusedActivity = getReusableIntentActivity();
1409
1410 mSupervisor.getLaunchParamsController().calculate(
1411 reusedActivity != null ? reusedActivity.getTaskRecord() : mInTask,
1412 r.info.windowLayout, r, sourceRecord, options, PHASE_BOUNDS, mLaunchParams);
1413 mPreferredDisplayId =
1414 mLaunchParams.hasPreferredDisplay() ? mLaunchParams.mPreferredDisplayId
1415 : DEFAULT_DISPLAY;
1416
Louis Changbd48dca2018-08-29 17:44:34 +08001417 // Do not start home activity if it cannot be launched on preferred display. We are not
1418 // doing this in ActivityStackSupervisor#canPlaceEntityOnDisplay because it might
1419 // fallback to launch on other displays.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001420 if (r.isActivityTypeHome() && !mRootActivityContainer.canStartHomeOnDisplay(r.info,
Louis Changdd3592a2018-11-05 11:04:14 +08001421 mPreferredDisplayId, true /* allowInstrumenting */)) {
Louis Changbd48dca2018-08-29 17:44:34 +08001422 Slog.w(TAG, "Cannot launch home on display " + mPreferredDisplayId);
1423 return START_CANCELED;
1424 }
1425
Bryce Lee4a194382017-04-04 14:32:48 -07001426 if (reusedActivity != null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001427 // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but
1428 // still needs to be a lock task mode violation since the task gets cleared out and
1429 // the device would otherwise leave the locked task.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001430 if (mService.getLockTaskController().isLockTaskModeViolation(
1431 reusedActivity.getTaskRecord(),
Wale Ogunwale01d66562015-12-29 08:19:19 -08001432 (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1433 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001434 Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
1435 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
1436 }
1437
Bryce Leef65ee7e2018-03-26 16:03:47 -07001438 // True if we are clearing top and resetting of a standard (default) launch mode
1439 // ({@code LAUNCH_MULTIPLE}) activity. The existing activity will be finished.
1440 final boolean clearTopAndResetStandardLaunchMode =
1441 (mLaunchFlags & (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED))
1442 == (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
1443 && mLaunchMode == LAUNCH_MULTIPLE;
1444
1445 // If mStartActivity does not have a task associated with it, associate it with the
1446 // reused activity's task. Do not do so if we're clearing top and resetting for a
1447 // standard launchMode activity.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001448 if (mStartActivity.getTaskRecord() == null && !clearTopAndResetStandardLaunchMode) {
1449 mStartActivity.setTask(reusedActivity.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001450 }
Bryce Leef65ee7e2018-03-26 16:03:47 -07001451
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001452 if (reusedActivity.getTaskRecord().intent == null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001453 // This task was started because of movement of the activity based on affinity...
1454 // Now that we are actually launching it, we can assign the base intent.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001455 reusedActivity.getTaskRecord().setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001456 }
1457
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001458 // This code path leads to delivering a new intent, we want to make sure we schedule it
1459 // as the first operation, in case the activity will be resumed as a result of later
1460 // operations.
1461 if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
Daichi Hirono15a02992016-04-27 18:47:01 +09001462 || isDocumentLaunchesIntoExisting(mLaunchFlags)
Bryce Lee7daee392017-10-12 13:46:18 -07001463 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001464 final TaskRecord task = reusedActivity.getTaskRecord();
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001465
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001466 // In this situation we want to remove all activities from the task up to the one
1467 // being started. In most cases this means we are resetting the task to its initial
1468 // state.
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001469 final ActivityRecord top = task.performClearTaskForReuseLocked(mStartActivity,
1470 mLaunchFlags);
1471
Bryce Lee4a194382017-04-04 14:32:48 -07001472 // The above code can remove {@code reusedActivity} from the task, leading to the
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001473 // the {@code ActivityRecord} removing its reference to the {@code TaskRecord}. The
1474 // task reference is needed in the call below to
1475 // {@link setTargetStackAndMoveToFrontIfNeeded}.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001476 if (reusedActivity.getTaskRecord() == null) {
Bryce Lee4a194382017-04-04 14:32:48 -07001477 reusedActivity.setTask(task);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001478 }
1479
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001480 if (top != null) {
1481 if (top.frontOfTask) {
1482 // Activity aliases may mean we use different intents for the top activity,
1483 // so make sure the task now has the identity of the new intent.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001484 top.getTaskRecord().setIntent(mStartActivity);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001485 }
Bryce Lee325e09682017-10-05 17:20:25 -07001486 deliverNewIntent(top);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001487 }
1488 }
1489
Wale Ogunwaled32da472018-11-16 07:19:28 -08001490 mRootActivityContainer.sendPowerHintForLaunchStartIfNeeded
1491 (false /* forceSend */, reusedActivity);
Wei Wang98f03f92016-05-18 11:32:52 -07001492
Bryce Lee4a194382017-04-04 14:32:48 -07001493 reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001494
Bryce Lee89cd19a2017-05-17 15:18:35 -07001495 final ActivityRecord outResult =
1496 outActivity != null && outActivity.length > 0 ? outActivity[0] : null;
1497
1498 // When there is a reused activity and the current result is a trampoline activity,
1499 // set the reused activity as the result.
1500 if (outResult != null && (outResult.finishing || outResult.noDisplay)) {
1501 outActivity[0] = reusedActivity;
1502 }
1503
Wale Ogunwale01d66562015-12-29 08:19:19 -08001504 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1505 // We don't need to start a new activity, and the client said not to do anything
1506 // if that is the case, so this is it! And for paranoia, make sure we have
1507 // correctly resumed the top activity.
1508 resumeTargetStackIfNeeded();
1509 return START_RETURN_INTENT_TO_CALLER;
1510 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001511
Bryce Leef65ee7e2018-03-26 16:03:47 -07001512 if (reusedActivity != null) {
1513 setTaskFromIntentActivity(reusedActivity);
1514
1515 if (!mAddingToTask && mReuseTask == null) {
1516 // We didn't do anything... but it was needed (a.k.a., client don't use that
1517 // intent!) And for paranoia, make sure we have correctly resumed the top activity.
1518
1519 resumeTargetStackIfNeeded();
1520 if (outActivity != null && outActivity.length > 0) {
1521 outActivity[0] = reusedActivity;
1522 }
1523
1524 return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP;
Jorim Jaggicdfc04e2017-04-28 19:06:24 +02001525 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001526 }
1527 }
1528
1529 if (mStartActivity.packageName == null) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001530 final ActivityStack sourceStack = mStartActivity.resultTo != null
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001531 ? mStartActivity.resultTo.getActivityStack() : null;
Andrii Kulian02b7a832016-10-06 23:11:56 -07001532 if (sourceStack != null) {
1533 sourceStack.sendActivityResultLocked(-1 /* callingUid */, mStartActivity.resultTo,
1534 mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,
1535 null /* data */);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001536 }
1537 ActivityOptions.abort(mOptions);
1538 return START_CLASS_NOT_FOUND;
1539 }
1540
1541 // If the activity being launched is the same as the one currently at the top, then
1542 // we need to check if it should only be launched once.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001543 final ActivityStack topStack = mRootActivityContainer.getTopDisplayFocusedStack();
Wale Ogunwale30e441d2017-11-09 08:28:45 -08001544 final ActivityRecord topFocused = topStack.getTopActivity();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001545 final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
1546 final boolean dontStart = top != null && mStartActivity.resultTo == null
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001547 && top.mActivityComponent.equals(mStartActivity.mActivityComponent)
1548 && top.mUserId == mStartActivity.mUserId
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001549 && top.attachedToProcess()
Wale Ogunwale01d66562015-12-29 08:19:19 -08001550 && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
Louis Changbd48dca2018-08-29 17:44:34 +08001551 || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK))
1552 // This allows home activity to automatically launch on secondary display when
1553 // display added, if home was the top activity on default display, instead of
1554 // sending new intent to the home activity on default display.
1555 && (!top.isActivityTypeHome() || top.getDisplayId() == mPreferredDisplayId);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001556 if (dontStart) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001557 // For paranoia, make sure we have correctly resumed the top activity.
1558 topStack.mLastPausedActivity = null;
1559 if (mDoResume) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001560 mRootActivityContainer.resumeFocusedStacksTopActivities();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001561 }
1562 ActivityOptions.abort(mOptions);
1563 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1564 // We don't need to start a new activity, and the client said not to do
1565 // anything if that is the case, so this is it!
1566 return START_RETURN_INTENT_TO_CALLER;
1567 }
Bryce Lee325e09682017-10-05 17:20:25 -07001568
1569 deliverNewIntent(top);
Chong Zhangd44063c2016-04-08 11:52:30 -07001570
1571 // Don't use mStartActivity.task to show the toast. We're not starting a new activity
1572 // but reusing 'top'. Fields in mStartActivity may not be fully initialized.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001573 mSupervisor.handleNonResizableTaskIfNeeded(top.getTaskRecord(), preferredWindowingMode,
Louis Chang39ba54b2018-10-18 11:28:57 +08001574 mPreferredDisplayId, topStack);
Chong Zhangd44063c2016-04-08 11:52:30 -07001575
Wale Ogunwale01d66562015-12-29 08:19:19 -08001576 return START_DELIVERED_TO_TOP;
1577 }
1578
1579 boolean newTask = false;
1580 final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001581 ? mSourceRecord.getTaskRecord() : null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001582
1583 // Should this be considered a new task?
Chong Zhang6cda19c2016-06-14 19:07:56 -07001584 int result = START_SUCCESS;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001585 if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
1586 && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1587 newTask = true;
Louis Changceeb5062018-09-17 18:13:52 +08001588 result = setTaskFromReuseOrCreateNewTask(taskToAffiliate);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001589 } else if (mSourceRecord != null) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07001590 result = setTaskFromSourceRecord();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001591 } else if (mInTask != null) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07001592 result = setTaskFromInTask();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001593 } else {
1594 // This not being started from an existing activity, and not part of a new task...
1595 // just put it in the top task, though these days this case should never happen.
1596 setTaskToCurrentTopOrCreateNewTask();
1597 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07001598 if (result != START_SUCCESS) {
1599 return result;
1600 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001601
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07001602 mService.mUgmInternal.grantUriPermissionFromIntent(mCallingUid, mStartActivity.packageName,
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001603 mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.mUserId);
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001604 mService.getPackageManagerInternalLocked().grantEphemeralAccess(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001605 mStartActivity.mUserId, mIntent, UserHandle.getAppId(mStartActivity.appInfo.uid),
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001606 UserHandle.getAppId(mCallingUid));
Wale Ogunwale01d66562015-12-29 08:19:19 -08001607 if (newTask) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001608 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, mStartActivity.mUserId,
1609 mStartActivity.getTaskRecord().taskId);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001610 }
1611 ActivityStack.logStartActivity(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001612 EventLogTags.AM_CREATE_ACTIVITY, mStartActivity, mStartActivity.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001613 mTargetStack.mLastPausedActivity = null;
Wei Wang98f03f92016-05-18 11:32:52 -07001614
Wale Ogunwaled32da472018-11-16 07:19:28 -08001615 mRootActivityContainer.sendPowerHintForLaunchStartIfNeeded(
1616 false /* forceSend */, mStartActivity);
Wei Wang98f03f92016-05-18 11:32:52 -07001617
Winson Chungb5c41b72016-12-07 15:00:47 -08001618 mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
1619 mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001620 if (mDoResume) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001621 final ActivityRecord topTaskActivity =
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001622 mStartActivity.getTaskRecord().topRunningActivityLocked();
Wale Ogunwale3b232392016-05-13 15:37:13 -07001623 if (!mTargetStack.isFocusable()
Wale Ogunwale68741142016-05-17 09:40:02 -07001624 || (topTaskActivity != null && topTaskActivity.mTaskOverlay
1625 && mStartActivity != topTaskActivity)) {
Filip Gruszczynski3d7fdc12016-01-31 17:33:29 -08001626 // If the activity is not focusable, we can't resume it, but still would like to
1627 // make sure it becomes visible as it starts (this will also trigger entry
1628 // animation). An example of this are PIP activities.
Wale Ogunwale3b232392016-05-13 15:37:13 -07001629 // Also, we don't want to resume activities in a task that currently has an overlay
1630 // as the starting activity just needs to be in the visible paused state until the
1631 // over is removed.
Andrii Kulianf2d3f742019-01-22 23:41:54 +00001632 mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Wale Ogunwaleae846f42016-02-22 14:00:56 -08001633 // Go ahead and tell window manager to execute app transition for this activity
1634 // since the app transition will not be triggered through the resume channel.
Wale Ogunwale3a256e62018-12-06 14:41:18 -08001635 mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
Wale Ogunwale3b232392016-05-13 15:37:13 -07001636 } else {
Winson Chung32066032016-11-04 11:55:21 -07001637 // If the target stack was not previously focusable (previous top running activity
1638 // on that stack was not visible) then any prior calls to move the stack to the
1639 // will not update the focused stack. If starting the new activity now allows the
1640 // task stack to be focusable, then ensure that we now update the focused stack
1641 // accordingly.
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001642 if (mTargetStack.isFocusable()
Wale Ogunwaled32da472018-11-16 07:19:28 -08001643 && !mRootActivityContainer.isTopDisplayFocusedStack(mTargetStack)) {
Winson Chung32066032016-11-04 11:55:21 -07001644 mTargetStack.moveToFront("startActivityUnchecked");
1645 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08001646 mRootActivityContainer.resumeFocusedStacksTopActivities(
1647 mTargetStack, mStartActivity, mOptions);
Filip Gruszczynski3d7fdc12016-01-31 17:33:29 -08001648 }
Winson Chung1dbc8112017-09-28 18:05:31 -07001649 } else if (mStartActivity != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001650 mSupervisor.mRecentTasks.add(mStartActivity.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001651 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001652 mRootActivityContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001653
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001654 mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTaskRecord(),
1655 preferredWindowingMode, mPreferredDisplayId, mTargetStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001656
1657 return START_SUCCESS;
1658 }
1659
Bryce Leedaa91e42017-12-06 14:13:01 -08001660 /**
1661 * Resets the {@link ActivityStarter} state.
1662 * @param clearRequest whether the request should be reset to default values.
1663 */
1664 void reset(boolean clearRequest) {
1665 mStartActivity = null;
1666 mIntent = null;
1667 mCallingUid = -1;
1668 mOptions = null;
1669
1670 mLaunchTaskBehind = false;
1671 mLaunchFlags = 0;
1672 mLaunchMode = INVALID_LAUNCH_MODE;
1673
Bryce Leeec55eb02017-12-05 20:51:27 -08001674 mLaunchParams.reset();
Bryce Leedaa91e42017-12-06 14:13:01 -08001675
1676 mNotTop = null;
1677 mDoResume = false;
1678 mStartFlags = 0;
1679 mSourceRecord = null;
1680 mPreferredDisplayId = INVALID_DISPLAY;
1681
1682 mInTask = null;
1683 mAddingToTask = false;
1684 mReuseTask = null;
1685
1686 mNewTaskInfo = null;
1687 mNewTaskIntent = null;
1688 mSourceStack = null;
1689
1690 mTargetStack = null;
1691 mMovedToFront = false;
1692 mNoAnimation = false;
1693 mKeepCurTransition = false;
1694 mAvoidMoveToFront = false;
1695
1696 mVoiceSession = null;
1697 mVoiceInteractor = null;
1698
1699 mIntentDelivered = false;
1700
1701 if (clearRequest) {
1702 mRequest.reset();
1703 }
1704 }
1705
Wale Ogunwale01d66562015-12-29 08:19:19 -08001706 private void setInitialState(ActivityRecord r, ActivityOptions options, TaskRecord inTask,
1707 boolean doResume, int startFlags, ActivityRecord sourceRecord,
1708 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
Bryce Leedaa91e42017-12-06 14:13:01 -08001709 reset(false /* clearRequest */);
1710
Wale Ogunwale01d66562015-12-29 08:19:19 -08001711 mStartActivity = r;
1712 mIntent = r.intent;
1713 mOptions = options;
1714 mCallingUid = r.launchedFromUid;
1715 mSourceRecord = sourceRecord;
1716 mVoiceSession = voiceSession;
1717 mVoiceInteractor = voiceInteractor;
1718
Bryce Leeec55eb02017-12-05 20:51:27 -08001719 mLaunchParams.reset();
Bryce Leedacefc42017-10-10 12:56:02 -07001720
Louis Chang6fb1e842018-12-03 16:07:50 +08001721 // Preferred display id is the only state we need for now and it could be updated again
1722 // after we located a reusable task (which might be resided in another display).
Garfield Tan706dbcb2018-10-15 11:33:02 -07001723 mSupervisor.getLaunchParamsController().calculate(inTask, r.info.windowLayout, r,
Louis Chang6fb1e842018-12-03 16:07:50 +08001724 sourceRecord, options, PHASE_DISPLAY, mLaunchParams);
1725 mPreferredDisplayId =
1726 mLaunchParams.hasPreferredDisplay() ? mLaunchParams.mPreferredDisplayId
1727 : DEFAULT_DISPLAY;
Garfield Tanb5cc09f2018-09-28 10:06:52 -07001728
Bryce Lee7daee392017-10-12 13:46:18 -07001729 mLaunchMode = r.launchMode;
1730
Wale Ogunwale01d66562015-12-29 08:19:19 -08001731 mLaunchFlags = adjustLaunchFlagsToDocumentMode(
Bryce Lee7daee392017-10-12 13:46:18 -07001732 r, LAUNCH_SINGLE_INSTANCE == mLaunchMode,
1733 LAUNCH_SINGLE_TASK == mLaunchMode, mIntent.getFlags());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001734 mLaunchTaskBehind = r.mLaunchTaskBehind
Bryce Lee7daee392017-10-12 13:46:18 -07001735 && !isLaunchModeOneOf(LAUNCH_SINGLE_TASK, LAUNCH_SINGLE_INSTANCE)
Wale Ogunwale01d66562015-12-29 08:19:19 -08001736 && (mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0;
1737
1738 sendNewTaskResultRequestIfNeeded();
1739
1740 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
1741 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1742 }
1743
1744 // If we are actually going to launch in to a new task, there are some cases where
1745 // we further want to do multiple task.
1746 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1747 if (mLaunchTaskBehind
1748 || r.info.documentLaunchMode == DOCUMENT_LAUNCH_ALWAYS) {
1749 mLaunchFlags |= FLAG_ACTIVITY_MULTIPLE_TASK;
1750 }
1751 }
1752
1753 // We'll invoke onUserLeaving before onPause only if the launching
1754 // activity did not explicitly state that this is an automated launch.
1755 mSupervisor.mUserLeaving = (mLaunchFlags & FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1756 if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
1757 "startActivity() => mUserLeaving=" + mSupervisor.mUserLeaving);
1758
1759 // If the caller has asked not to resume at this point, we make note
1760 // of this in the record so that we can skip it when trying to find
1761 // the top running activity.
1762 mDoResume = doResume;
Chong Zhang87761972016-08-22 13:53:24 -07001763 if (!doResume || !r.okToShowLocked()) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001764 r.delayedResume = true;
1765 mDoResume = false;
1766 }
1767
Winson Chunge2d72172018-01-25 17:46:20 +00001768 if (mOptions != null) {
1769 if (mOptions.getLaunchTaskId() != -1 && mOptions.getTaskOverlay()) {
1770 r.mTaskOverlay = true;
1771 if (!mOptions.canTaskOverlayResume()) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001772 final TaskRecord task = mRootActivityContainer.anyTaskForId(
Winson Chunge2d72172018-01-25 17:46:20 +00001773 mOptions.getLaunchTaskId());
1774 final ActivityRecord top = task != null ? task.getTopActivity() : null;
Bryce Lee7ace3952018-02-16 14:34:32 -08001775 if (top != null && !top.isState(RESUMED)) {
Jorim Jaggic875ae72016-04-26 22:41:06 -07001776
Winson Chunge2d72172018-01-25 17:46:20 +00001777 // The caller specifies that we'd like to be avoided to be moved to the
1778 // front, so be it!
1779 mDoResume = false;
1780 mAvoidMoveToFront = true;
1781 }
Winson Chungcbcadc92017-01-12 15:54:12 -08001782 }
Winson Chunge2d72172018-01-25 17:46:20 +00001783 } else if (mOptions.getAvoidMoveToFront()) {
Winson Chungba40d3a2018-05-16 09:40:16 -07001784 mDoResume = false;
Winson Chunge2d72172018-01-25 17:46:20 +00001785 mAvoidMoveToFront = true;
Jorim Jaggic875ae72016-04-26 22:41:06 -07001786 }
1787 }
1788
Wale Ogunwale01d66562015-12-29 08:19:19 -08001789 mNotTop = (mLaunchFlags & FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1790
1791 mInTask = inTask;
1792 // In some flows in to this function, we retrieve the task record and hold on to it
1793 // without a lock before calling back in to here... so the task at this point may
1794 // not actually be in recents. Check for that, and if it isn't in recents just
1795 // consider it invalid.
1796 if (inTask != null && !inTask.inRecents) {
1797 Slog.w(TAG, "Starting activity in task not in recents: " + inTask);
1798 mInTask = null;
1799 }
1800
1801 mStartFlags = startFlags;
1802 // If the onlyIfNeeded flag is set, then we can do this if the activity being launched
1803 // is the same as the one making the call... or, as a special case, if we do not know
1804 // the caller then we count the current top activity as the caller.
1805 if ((startFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1806 ActivityRecord checkedCaller = sourceRecord;
1807 if (checkedCaller == null) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001808 checkedCaller = mRootActivityContainer.getTopDisplayFocusedStack()
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001809 .topRunningNonDelayedActivityLocked(mNotTop);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001810 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001811 if (!checkedCaller.mActivityComponent.equals(r.mActivityComponent)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001812 // Caller is not the same as launcher, so always needed.
1813 mStartFlags &= ~START_FLAG_ONLY_IF_NEEDED;
1814 }
1815 }
1816
1817 mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0;
1818 }
1819
1820 private void sendNewTaskResultRequestIfNeeded() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001821 final ActivityStack sourceStack = mStartActivity.resultTo != null
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001822 ? mStartActivity.resultTo.getActivityStack() : null;
Andrii Kulian02b7a832016-10-06 23:11:56 -07001823 if (sourceStack != null && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001824 // For whatever reason this activity is being launched into a new task...
1825 // yet the caller has requested a result back. Well, that is pretty messed up,
1826 // so instead immediately send back a cancel and let the new task continue launched
1827 // as normal without a dependency on its originator.
1828 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
Andrii Kulian02b7a832016-10-06 23:11:56 -07001829 sourceStack.sendActivityResultLocked(-1 /* callingUid */, mStartActivity.resultTo,
1830 mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,
1831 null /* data */);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001832 mStartActivity.resultTo = null;
1833 }
1834 }
1835
1836 private void computeLaunchingTaskFlags() {
1837 // If the caller is not coming from another activity, but has given us an explicit task into
1838 // which they would like us to launch the new activity, then let's see about doing that.
Andrii Kulian02b7a832016-10-06 23:11:56 -07001839 if (mSourceRecord == null && mInTask != null && mInTask.getStack() != null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001840 final Intent baseIntent = mInTask.getBaseIntent();
1841 final ActivityRecord root = mInTask.getRootActivity();
1842 if (baseIntent == null) {
1843 ActivityOptions.abort(mOptions);
1844 throw new IllegalArgumentException("Launching into task without base intent: "
1845 + mInTask);
1846 }
1847
1848 // If this task is empty, then we are adding the first activity -- it
1849 // determines the root, and must be launching as a NEW_TASK.
Bryce Lee7daee392017-10-12 13:46:18 -07001850 if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001851 if (!baseIntent.getComponent().equals(mStartActivity.intent.getComponent())) {
1852 ActivityOptions.abort(mOptions);
1853 throw new IllegalArgumentException("Trying to launch singleInstance/Task "
1854 + mStartActivity + " into different task " + mInTask);
1855 }
1856 if (root != null) {
1857 ActivityOptions.abort(mOptions);
1858 throw new IllegalArgumentException("Caller with mInTask " + mInTask
1859 + " has root " + root + " but target is singleInstance/Task");
1860 }
1861 }
1862
1863 // If task is empty, then adopt the interesting intent launch flags in to the
1864 // activity being started.
1865 if (root == null) {
1866 final int flagsOfInterest = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK
1867 | FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS;
1868 mLaunchFlags = (mLaunchFlags & ~flagsOfInterest)
1869 | (baseIntent.getFlags() & flagsOfInterest);
1870 mIntent.setFlags(mLaunchFlags);
1871 mInTask.setIntent(mStartActivity);
1872 mAddingToTask = true;
1873
1874 // If the task is not empty and the caller is asking to start it as the root of
1875 // a new task, then we don't actually want to start this on the task. We will
1876 // bring the task to the front, and possibly give it a new intent.
1877 } else if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1878 mAddingToTask = false;
1879
1880 } else {
1881 mAddingToTask = true;
1882 }
1883
1884 mReuseTask = mInTask;
1885 } else {
1886 mInTask = null;
1887 // Launch ResolverActivity in the source task, so that it stays in the task bounds
1888 // when in freeform workspace.
1889 // Also put noDisplay activities in the source task. These by itself can be placed
1890 // in any task/stack, however it could launch other activities like ResolverActivity,
1891 // and we want those to stay in the original task.
1892 if ((mStartActivity.isResolverActivity() || mStartActivity.noDisplay) && mSourceRecord != null
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001893 && mSourceRecord.inFreeformWindowingMode()) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001894 mAddingToTask = true;
1895 }
1896 }
1897
1898 if (mInTask == null) {
1899 if (mSourceRecord == null) {
1900 // This activity is not being started from another... in this
1901 // case we -always- start a new task.
1902 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) {
1903 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1904 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
1905 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1906 }
1907 } else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) {
1908 // The original activity who is starting us is running as a single
1909 // instance... this new activity it is starting must go on its
1910 // own task.
1911 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
Bryce Lee7daee392017-10-12 13:46:18 -07001912 } else if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001913 // The activity being started is a single instance... it always
1914 // gets launched into its own task.
1915 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1916 }
1917 }
1918 }
1919
1920 private void computeSourceStack() {
1921 if (mSourceRecord == null) {
1922 mSourceStack = null;
1923 return;
1924 }
1925 if (!mSourceRecord.finishing) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001926 mSourceStack = mSourceRecord.getActivityStack();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001927 return;
1928 }
1929
1930 // If the source is finishing, we can't further count it as our source. This is because the
1931 // task it is associated with may now be empty and on its way out, so we don't want to
1932 // blindly throw it in to that task. Instead we will take the NEW_TASK flow and try to find
1933 // a task for it. But save the task information so it can be used when creating the new task.
1934 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0) {
1935 Slog.w(TAG, "startActivity called from finishing " + mSourceRecord
1936 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
1937 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1938 mNewTaskInfo = mSourceRecord.info;
Bryce Leed9ed45d2017-05-22 15:57:24 -07001939
1940 // It is not guaranteed that the source record will have a task associated with it. For,
1941 // example, if this method is being called for processing a pending activity launch, it
1942 // is possible that the activity has been removed from the task after the launch was
1943 // enqueued.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001944 final TaskRecord sourceTask = mSourceRecord.getTaskRecord();
Bryce Leed9ed45d2017-05-22 15:57:24 -07001945 mNewTaskIntent = sourceTask != null ? sourceTask.intent : null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001946 }
1947 mSourceRecord = null;
1948 mSourceStack = null;
1949 }
1950
1951 /**
1952 * Decide whether the new activity should be inserted into an existing task. Returns null
1953 * if not or an ActivityRecord with the task into which the new activity should be added.
1954 */
1955 private ActivityRecord getReusableIntentActivity() {
1956 // We may want to try to place the new activity in to an existing task. We always
1957 // do this if the target activity is singleTask or singleInstance; we will also do
1958 // this if NEW_TASK has been requested, and there is not an additional qualifier telling
1959 // us to still place it in a new task: multi task, always doc mode, or being asked to
1960 // launch this as a new task behind the current one.
1961 boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 &&
1962 (mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
Bryce Lee7daee392017-10-12 13:46:18 -07001963 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001964 // If bring to front is requested, and no result is requested and we have not been given
1965 // an explicit task to launch in to, and we can find a task that was started with this
1966 // same component, then instead of launching bring that one to the front.
1967 putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null;
1968 ActivityRecord intentActivity = null;
Jorim Jaggi2adba072016-03-03 13:43:39 +01001969 if (mOptions != null && mOptions.getLaunchTaskId() != -1) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001970 final TaskRecord task = mRootActivityContainer.anyTaskForId(mOptions.getLaunchTaskId());
Jorim Jaggi2adba072016-03-03 13:43:39 +01001971 intentActivity = task != null ? task.getTopActivity() : null;
1972 } else if (putIntoExistingTask) {
Bryce Lee7daee392017-10-12 13:46:18 -07001973 if (LAUNCH_SINGLE_INSTANCE == mLaunchMode) {
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07001974 // There can be one and only one instance of single instance activity in the
1975 // history, and it is always in its own unique task, so we do a special search.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001976 intentActivity = mRootActivityContainer.findActivity(mIntent, mStartActivity.info,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001977 mStartActivity.isActivityTypeHome());
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07001978 } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
1979 // For the launch adjacent case we only want to put the activity in an existing
1980 // task if the activity already exists in the history.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001981 intentActivity = mRootActivityContainer.findActivity(mIntent, mStartActivity.info,
Bryce Lee7daee392017-10-12 13:46:18 -07001982 !(LAUNCH_SINGLE_TASK == mLaunchMode));
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07001983 } else {
1984 // Otherwise find the best task to put the activity in.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001985 intentActivity =
1986 mRootActivityContainer.findTask(mStartActivity, mPreferredDisplayId);
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07001987 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001988 }
Louis Changbd48dca2018-08-29 17:44:34 +08001989
Louis Chang54506cb2018-11-23 11:03:41 +08001990 if (intentActivity != null
1991 && (mStartActivity.isActivityTypeHome() || intentActivity.isActivityTypeHome())
Louis Changbd48dca2018-08-29 17:44:34 +08001992 && intentActivity.getDisplayId() != mPreferredDisplayId) {
1993 // Do not reuse home activity on other displays.
1994 intentActivity = null;
1995 }
1996
Wale Ogunwale01d66562015-12-29 08:19:19 -08001997 return intentActivity;
1998 }
1999
Andrii Kulianfab9cd82017-03-21 19:37:09 -07002000 /**
2001 * Figure out which task and activity to bring to front when we have found an existing matching
2002 * activity record in history. May also clear the task if needed.
2003 * @param intentActivity Existing matching activity.
2004 * @return {@link ActivityRecord} brought to front.
2005 */
Wale Ogunwale01d66562015-12-29 08:19:19 -08002006 private ActivityRecord setTargetStackAndMoveToFrontIfNeeded(ActivityRecord intentActivity) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002007 mTargetStack = intentActivity.getActivityStack();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002008 mTargetStack.mLastPausedActivity = null;
2009 // If the target task is not in the front, then we need to bring it to the front...
2010 // except... well, with SINGLE_TASK_LAUNCH it's not entirely clear. We'd like to have
2011 // the same behavior as if a new instance was being started, which means not bringing it
2012 // to the front if the caller is not itself in the front.
Riddle Hsub70b36d2018-09-11 21:20:02 +08002013 final boolean differentTopTask;
2014 if (mPreferredDisplayId == mTargetStack.mDisplayId) {
2015 final ActivityStack focusStack = mTargetStack.getDisplay().getFocusedStack();
2016 final ActivityRecord curTop = (focusStack == null)
2017 ? null : focusStack.topRunningNonDelayedActivityLocked(mNotTop);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002018 final TaskRecord topTask = curTop != null ? curTop.getTaskRecord() : null;
Riddle Hsub70b36d2018-09-11 21:20:02 +08002019 differentTopTask = topTask != null
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002020 && (topTask != intentActivity.getTaskRecord() || topTask != focusStack.topTask());
Riddle Hsub70b36d2018-09-11 21:20:02 +08002021 } else {
2022 // The existing task should always be different from those in other displays.
2023 differentTopTask = true;
2024 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002025
Riddle Hsub70b36d2018-09-11 21:20:02 +08002026 if (differentTopTask && !mAvoidMoveToFront) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002027 mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Wale Ogunwale30e441d2017-11-09 08:28:45 -08002028 if (mSourceRecord == null || (mSourceStack.getTopActivity() != null &&
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002029 mSourceStack.getTopActivity().getTaskRecord()
2030 == mSourceRecord.getTaskRecord())) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002031 // We really do want to push this one into the user's face, right now.
2032 if (mLaunchTaskBehind && mSourceRecord != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002033 intentActivity.setTaskToAffiliateWith(mSourceRecord.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08002034 }
Chong Zhangdea4bd92016-03-15 12:50:03 -07002035
2036 // If the launch flags carry both NEW_TASK and CLEAR_TASK, the task's activities
2037 // will be cleared soon by ActivityStarter in setTaskFromIntentActivity().
2038 // So no point resuming any of the activities here, it just wastes one extra
2039 // resuming, plus enter AND exit transitions.
2040 // Here we only want to bring the target stack forward. Transition will be applied
2041 // to the new activity that's started after the old ones are gone.
2042 final boolean willClearTask =
2043 (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
2044 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
2045 if (!willClearTask) {
2046 final ActivityStack launchStack = getLaunchStack(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002047 mStartActivity, mLaunchFlags, mStartActivity.getTaskRecord(), mOptions);
2048 final TaskRecord intentTask = intentActivity.getTaskRecord();
Chong Zhangdea4bd92016-03-15 12:50:03 -07002049 if (launchStack == null || launchStack == mTargetStack) {
2050 // We only want to move to the front, if we aren't going to launch on a
2051 // different stack. If we launch on a different stack, we will put the
2052 // task on top there.
chaviw0d562bf2018-03-15 14:24:14 -07002053 mTargetStack.moveTaskToFrontLocked(intentTask, mNoAnimation, mOptions,
2054 mStartActivity.appTimeTracker, "bringingFoundTaskToFront");
Chong Zhangdea4bd92016-03-15 12:50:03 -07002055 mMovedToFront = true;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002056 } else if (launchStack.inSplitScreenWindowingMode()) {
Andrii Kulianad6f2e52016-06-15 15:27:01 -07002057 if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
2058 // If we want to launch adjacent and mTargetStack is not the computed
2059 // launch stack - move task to top of computed stack.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002060 intentTask.reparent(launchStack, ON_TOP,
Winson Chung74666102017-02-22 17:49:24 -08002061 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
2062 "launchToSide");
Andrii Kulianad6f2e52016-06-15 15:27:01 -07002063 } else {
2064 // TODO: This should be reevaluated in MW v2.
2065 // We choose to move task to front instead of launching it adjacent
2066 // when specific stack was requested explicitly and it appeared to be
2067 // adjacent stack, but FLAG_ACTIVITY_LAUNCH_ADJACENT was not set.
chaviw0d562bf2018-03-15 14:24:14 -07002068 mTargetStack.moveTaskToFrontLocked(intentTask,
Bryce Leeaf691c02017-03-20 14:20:22 -07002069 mNoAnimation, mOptions, mStartActivity.appTimeTracker,
Andrii Kulianad6f2e52016-06-15 15:27:01 -07002070 "bringToFrontInsteadOfAdjacentLaunch");
2071 }
Bryce Lee32e09ef2018-03-19 15:29:49 -07002072 mMovedToFront = launchStack != launchStack.getDisplay()
2073 .getTopStackInWindowingMode(launchStack.getWindowingMode());
Andrii Kulianfab9cd82017-03-21 19:37:09 -07002074 } else if (launchStack.mDisplayId != mTargetStack.mDisplayId) {
2075 // Target and computed stacks are on different displays and we've
2076 // found a matching task - move the existing instance to that display and
2077 // move it to front.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002078 intentActivity.getTaskRecord().reparent(launchStack, ON_TOP,
Andrii Kulianfab9cd82017-03-21 19:37:09 -07002079 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
2080 "reparentToDisplay");
2081 mMovedToFront = true;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002082 } else if (launchStack.isActivityTypeHome()
2083 && !mTargetStack.isActivityTypeHome()) {
Bryce Lee4ff7da92017-07-17 10:39:24 -07002084 // It is possible for the home activity to be in another stack initially.
2085 // For example, the activity may have been initially started with an intent
2086 // which placed it in the fullscreen stack. To ensure the proper handling of
2087 // the activity based on home stack assumptions, we must move it over.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002088 intentActivity.getTaskRecord().reparent(launchStack, ON_TOP,
Bryce Lee4ff7da92017-07-17 10:39:24 -07002089 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
2090 "reparentingHome");
2091 mMovedToFront = true;
Chong Zhangdea4bd92016-03-15 12:50:03 -07002092 }
2093 mOptions = null;
Jorim Jaggi02886a82016-12-06 09:10:06 -08002094
2095 // We are moving a task to the front, use starting window to hide initial drawn
2096 // delay.
2097 intentActivity.showStartingWindow(null /* prev */, false /* newTask */,
2098 true /* taskSwitch */);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002099 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002100 }
2101 }
Andrii Kulianb850ea52017-12-12 23:49:10 -08002102 // Need to update mTargetStack because if task was moved out of it, the original stack may
2103 // be destroyed.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002104 mTargetStack = intentActivity.getActivityStack();
Winson Chungba40d3a2018-05-16 09:40:16 -07002105 if (!mMovedToFront && mDoResume) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002106 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Bring to front target: " + mTargetStack
2107 + " from " + intentActivity);
2108 mTargetStack.moveToFront("intentActivityFound");
2109 }
2110
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002111 mSupervisor.handleNonResizableTaskIfNeeded(intentActivity.getTaskRecord(),
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07002112 WINDOWING_MODE_UNDEFINED, DEFAULT_DISPLAY, mTargetStack);
Jorim Jaggid53f0922016-04-06 22:16:23 -07002113
Wale Ogunwale01d66562015-12-29 08:19:19 -08002114 // If the caller has requested that the target task be reset, then do so.
2115 if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
2116 return mTargetStack.resetTaskIfNeededLocked(intentActivity, mStartActivity);
2117 }
2118 return intentActivity;
2119 }
2120
2121 private void setTaskFromIntentActivity(ActivityRecord intentActivity) {
2122 if ((mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
2123 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {
2124 // The caller has requested to completely replace any existing task with its new
2125 // activity. Well that should not be too hard...
Bryce Lee41801b42017-03-02 13:23:12 -08002126 // Note: we must persist the {@link TaskRecord} first as intentActivity could be
2127 // removed from calling performClearTaskLocked (For example, if it is being brought out
Bryce Lee59dad4e2017-03-09 11:54:08 -08002128 // of history or if it is finished immediately), thus disassociating the task. Also note
2129 // that mReuseTask is reset as a result of {@link TaskRecord#performClearTaskLocked}
2130 // launching another activity.
2131 // TODO(b/36119896): We shouldn't trigger activity launches in this path since we are
2132 // already launching one.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002133 final TaskRecord task = intentActivity.getTaskRecord();
Bryce Lee59dad4e2017-03-09 11:54:08 -08002134 task.performClearTaskLocked();
2135 mReuseTask = task;
Bryce Lee41801b42017-03-02 13:23:12 -08002136 mReuseTask.setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002137 } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
Bryce Lee7daee392017-10-12 13:46:18 -07002138 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002139 final ActivityRecord top = intentActivity.getTaskRecord().performClearTaskLocked(
2140 mStartActivity, mLaunchFlags);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08002141 if (top == null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002142 // A special case: we need to start the activity because it is not currently
2143 // running, and the caller has asked to clear the current task to have this
2144 // activity at the top.
2145 mAddingToTask = true;
Bryce Lee353112c2017-02-23 09:46:45 -08002146
2147 // We are no longer placing the activity in the task we previously thought we were.
Bryce Leeaf691c02017-03-20 14:20:22 -07002148 mStartActivity.setTask(null);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002149 // Now pretend like this activity is being started by the top of its task, so it
2150 // is put in the right place.
2151 mSourceRecord = intentActivity;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002152 final TaskRecord task = mSourceRecord.getTaskRecord();
Andrii Kulian02b7a832016-10-06 23:11:56 -07002153 if (task != null && task.getStack() == null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002154 // Target stack got cleared when we all activities were removed above.
2155 // Go ahead and reset it.
2156 mTargetStack = computeStackFocus(mSourceRecord, false /* newTask */,
Bryce Leedacefc42017-10-10 12:56:02 -07002157 mLaunchFlags, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002158 mTargetStack.addTask(task,
2159 !mLaunchTaskBehind /* toTop */, "startActivityUnchecked");
2160 }
2161 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002162 } else if (mStartActivity.mActivityComponent.equals(
2163 intentActivity.getTaskRecord().realActivity)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002164 // In this case the top activity on the task is the same as the one being launched,
2165 // so we take that as a request to bring the task to the foreground. If the top
2166 // activity in the task is the root activity, deliver this new intent to it if it
2167 // desires.
Bryce Lee7daee392017-10-12 13:46:18 -07002168 if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
2169 || LAUNCH_SINGLE_TOP == mLaunchMode)
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002170 && intentActivity.mActivityComponent.equals(
2171 mStartActivity.mActivityComponent)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002172 if (intentActivity.frontOfTask) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002173 intentActivity.getTaskRecord().setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002174 }
Bryce Lee325e09682017-10-05 17:20:25 -07002175 deliverNewIntent(intentActivity);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002176 } else if (!intentActivity.getTaskRecord().isSameIntentFilter(mStartActivity)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002177 // In this case we are launching the root activity of the task, but with a
2178 // different intent. We should start a new instance on top.
2179 mAddingToTask = true;
2180 mSourceRecord = intentActivity;
2181 }
2182 } else if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
2183 // In this case an activity is being launched in to an existing task, without
2184 // resetting that task. This is typically the situation of launching an activity
2185 // from a notification or shortcut. We want to place the new activity on top of the
2186 // current task.
2187 mAddingToTask = true;
2188 mSourceRecord = intentActivity;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002189 } else if (!intentActivity.getTaskRecord().rootWasReset) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002190 // In this case we are launching into an existing task that has not yet been started
2191 // from its front door. The current task has been brought to the front. Ideally,
2192 // we'd probably like to place this new task at the bottom of its stack, but that's
2193 // a little hard to do with the current organization of the code so for now we'll
2194 // just drop it.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002195 intentActivity.getTaskRecord().setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002196 }
2197 }
2198
2199 private void resumeTargetStackIfNeeded() {
2200 if (mDoResume) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002201 mRootActivityContainer.resumeFocusedStacksTopActivities(mTargetStack, null, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002202 } else {
2203 ActivityOptions.abort(mOptions);
2204 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002205 mRootActivityContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002206 }
2207
Louis Changceeb5062018-09-17 18:13:52 +08002208 private int setTaskFromReuseOrCreateNewTask(TaskRecord taskToAffiliate) {
Bryce Leedacefc42017-10-10 12:56:02 -07002209 mTargetStack = computeStackFocus(mStartActivity, true, mLaunchFlags, mOptions);
Chong Zhang6cda19c2016-06-14 19:07:56 -07002210
2211 // Do no move the target stack to front yet, as we might bail if
2212 // isLockTaskModeViolation fails below.
Wale Ogunwale01d66562015-12-29 08:19:19 -08002213
2214 if (mReuseTask == null) {
Suprabh Shukla09a88f52015-12-02 14:36:31 -08002215 final TaskRecord task = mTargetStack.createTaskRecord(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002216 mSupervisor.getNextTaskIdForUserLocked(mStartActivity.mUserId),
Wale Ogunwale01d66562015-12-29 08:19:19 -08002217 mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
Wale Ogunwale72919d22016-12-08 18:58:50 -08002218 mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
Bryce Leeb802ea12017-11-15 21:25:03 -08002219 mVoiceInteractor, !mLaunchTaskBehind /* toTop */, mStartActivity, mSourceRecord,
2220 mOptions);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002221 addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002222 updateBounds(mStartActivity.getTaskRecord(), mLaunchParams.mBounds);
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002223
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002224 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002225 + " in new task " + mStartActivity.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08002226 } else {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002227 addOrReparentStartingActivity(mReuseTask, "setTaskFromReuseOrCreateNewTask");
2228 }
2229
2230 if (taskToAffiliate != null) {
2231 mStartActivity.setTaskToAffiliateWith(taskToAffiliate);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002232 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07002233
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002234 if (mService.getLockTaskController().isLockTaskModeViolation(
2235 mStartActivity.getTaskRecord())) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002236 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
2237 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
2238 }
2239
Chong Zhang6cda19c2016-06-14 19:07:56 -07002240 if (mDoResume) {
2241 mTargetStack.moveToFront("reuseOrNewTask");
2242 }
2243 return START_SUCCESS;
Wale Ogunwale01d66562015-12-29 08:19:19 -08002244 }
2245
Bryce Lee325e09682017-10-05 17:20:25 -07002246 private void deliverNewIntent(ActivityRecord activity) {
2247 if (mIntentDelivered) {
2248 return;
2249 }
2250
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002251 ActivityStack.logStartActivity(AM_NEW_INTENT, activity, activity.getTaskRecord());
Bryce Lee325e09682017-10-05 17:20:25 -07002252 activity.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
2253 mStartActivity.launchedFromPackage);
2254 mIntentDelivered = true;
2255 }
2256
Wale Ogunwale01d66562015-12-29 08:19:19 -08002257 private int setTaskFromSourceRecord() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002258 if (mService.getLockTaskController().isLockTaskModeViolation(
2259 mSourceRecord.getTaskRecord())) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002260 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
2261 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
2262 }
2263
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002264 final TaskRecord sourceTask = mSourceRecord.getTaskRecord();
2265 final ActivityStack sourceStack = mSourceRecord.getActivityStack();
Andrii Kulian02689a72017-07-06 14:28:59 -07002266 // We only want to allow changing stack in two cases:
2267 // 1. If the target task is not the top one. Otherwise we would move the launching task to
2268 // the other side, rather than show two side by side.
2269 // 2. If activity is not allowed on target display.
2270 final int targetDisplayId = mTargetStack != null ? mTargetStack.mDisplayId
2271 : sourceStack.mDisplayId;
2272 final boolean moveStackAllowed = sourceStack.topTask() != sourceTask
2273 || !mStartActivity.canBeLaunchedOnDisplay(targetDisplayId);
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002274 if (moveStackAllowed) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002275 mTargetStack = getLaunchStack(mStartActivity, mLaunchFlags,
2276 mStartActivity.getTaskRecord(), mOptions);
Andrii Kulian02689a72017-07-06 14:28:59 -07002277 // If target stack is not found now - we can't just rely on the source stack, as it may
2278 // be not suitable. Let's check other displays.
2279 if (mTargetStack == null && targetDisplayId != sourceStack.mDisplayId) {
2280 // Can't use target display, lets find a stack on the source display.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002281 mTargetStack = mRootActivityContainer.getValidLaunchStackOnDisplay(
Garfield Tan20d9e2f2018-11-16 15:42:29 -08002282 sourceStack.mDisplayId, mStartActivity, mOptions, mLaunchParams);
Andrii Kulian02689a72017-07-06 14:28:59 -07002283 }
2284 if (mTargetStack == null) {
2285 // There are no suitable stacks on the target and source display(s). Look on all
2286 // displays.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002287 mTargetStack = mRootActivityContainer.getNextValidLaunchStack(
Andrii Kulian02689a72017-07-06 14:28:59 -07002288 mStartActivity, -1 /* currentFocus */);
2289 }
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002290 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002291
2292 if (mTargetStack == null) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07002293 mTargetStack = sourceStack;
2294 } else if (mTargetStack != sourceStack) {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002295 sourceTask.reparent(mTargetStack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE,
2296 DEFER_RESUME, "launchToSide");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002297 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07002298
Wale Ogunwale01d66562015-12-29 08:19:19 -08002299 final TaskRecord topTask = mTargetStack.topTask();
Jorim Jaggic875ae72016-04-26 22:41:06 -07002300 if (topTask != sourceTask && !mAvoidMoveToFront) {
chaviw0d562bf2018-03-15 14:24:14 -07002301 mTargetStack.moveTaskToFrontLocked(sourceTask, mNoAnimation, mOptions,
Wale Ogunwale01d66562015-12-29 08:19:19 -08002302 mStartActivity.appTimeTracker, "sourceTaskToFront");
Chong Zhang6cda19c2016-06-14 19:07:56 -07002303 } else if (mDoResume) {
2304 mTargetStack.moveToFront("sourceStackToFront");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002305 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07002306
Wale Ogunwale01d66562015-12-29 08:19:19 -08002307 if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0) {
2308 // In this case, we are adding the activity to an existing task, but the caller has
2309 // asked to clear that task if the activity is already running.
2310 ActivityRecord top = sourceTask.performClearTaskLocked(mStartActivity, mLaunchFlags);
2311 mKeepCurTransition = true;
2312 if (top != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002313 ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, top.getTaskRecord());
Bryce Lee325e09682017-10-05 17:20:25 -07002314 deliverNewIntent(top);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002315 // For paranoia, make sure we have correctly resumed the top activity.
2316 mTargetStack.mLastPausedActivity = null;
2317 if (mDoResume) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002318 mRootActivityContainer.resumeFocusedStacksTopActivities();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002319 }
2320 ActivityOptions.abort(mOptions);
2321 return START_DELIVERED_TO_TOP;
2322 }
2323 } else if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
2324 // In this case, we are launching an activity in our own task that may already be
2325 // running somewhere in the history, and we want to shuffle it to the front of the
2326 // stack if so.
2327 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(mStartActivity);
2328 if (top != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002329 final TaskRecord task = top.getTaskRecord();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002330 task.moveActivityToFrontLocked(top);
2331 top.updateOptionsLocked(mOptions);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08002332 ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, task);
Bryce Lee325e09682017-10-05 17:20:25 -07002333 deliverNewIntent(top);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002334 mTargetStack.mLastPausedActivity = null;
2335 if (mDoResume) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002336 mRootActivityContainer.resumeFocusedStacksTopActivities();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002337 }
2338 return START_DELIVERED_TO_TOP;
2339 }
2340 }
2341
2342 // An existing activity is starting this new activity, so we want to keep the new one in
2343 // the same task as the one that is starting it.
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002344 addOrReparentStartingActivity(sourceTask, "setTaskFromSourceRecord");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002345 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002346 + " in existing task " + mStartActivity.getTaskRecord()
2347 + " from source " + mSourceRecord);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002348 return START_SUCCESS;
2349 }
2350
2351 private int setTaskFromInTask() {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002352 // The caller is asking that the new activity be started in an explicit
2353 // task it has provided to us.
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07002354 if (mService.getLockTaskController().isLockTaskModeViolation(mInTask)) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002355 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
2356 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
2357 }
2358
Andrii Kulian02b7a832016-10-06 23:11:56 -07002359 mTargetStack = mInTask.getStack();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002360
2361 // Check whether we should actually launch the new activity in to the task,
2362 // or just reuse the current activity on top.
2363 ActivityRecord top = mInTask.getTopActivity();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002364 if (top != null && top.mActivityComponent.equals(mStartActivity.mActivityComponent)
2365 && top.mUserId == mStartActivity.mUserId) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002366 if ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
Bryce Lee7daee392017-10-12 13:46:18 -07002367 || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK)) {
chaviw0d562bf2018-03-15 14:24:14 -07002368 mTargetStack.moveTaskToFrontLocked(mInTask, mNoAnimation, mOptions,
Yorke Lee64512522017-03-24 13:09:35 -07002369 mStartActivity.appTimeTracker, "inTaskToFront");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002370 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
2371 // We don't need to start a new activity, and the client said not to do
2372 // anything if that is the case, so this is it!
2373 return START_RETURN_INTENT_TO_CALLER;
2374 }
Bryce Lee325e09682017-10-05 17:20:25 -07002375 deliverNewIntent(top);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002376 return START_DELIVERED_TO_TOP;
2377 }
2378 }
2379
2380 if (!mAddingToTask) {
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 // We don't actually want to have this activity added to the task, so just
2384 // stop here but still tell the caller that we consumed the intent.
2385 ActivityOptions.abort(mOptions);
2386 return START_TASK_TO_FRONT;
2387 }
2388
Bryce Leeec55eb02017-12-05 20:51:27 -08002389 if (!mLaunchParams.mBounds.isEmpty()) {
Wale Ogunwale0568aed2017-09-08 13:29:37 -07002390 // TODO: Shouldn't we already know what stack to use by the time we get here?
Wale Ogunwaled32da472018-11-16 07:19:28 -08002391 ActivityStack stack = mRootActivityContainer.getLaunchStack(
2392 null, null, mInTask, ON_TOP);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002393 if (stack != mInTask.getStack()) {
2394 mInTask.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, !ANIMATE,
Yorke Lee64512522017-03-24 13:09:35 -07002395 DEFER_RESUME, "inTaskToFront");
Yorke Lee64512522017-03-24 13:09:35 -07002396 mTargetStack = mInTask.getStack();
2397 }
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002398
Bryce Leeec55eb02017-12-05 20:51:27 -08002399 updateBounds(mInTask, mLaunchParams.mBounds);
Yorke Lee64512522017-03-24 13:09:35 -07002400 }
2401
chaviw0d562bf2018-03-15 14:24:14 -07002402 mTargetStack.moveTaskToFrontLocked(
2403 mInTask, mNoAnimation, mOptions, mStartActivity.appTimeTracker, "inTaskToFront");
Yorke Lee64512522017-03-24 13:09:35 -07002404
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002405 addOrReparentStartingActivity(mInTask, "setTaskFromInTask");
2406 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002407 + " in explicit task " + mStartActivity.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08002408
2409 return START_SUCCESS;
2410 }
2411
Bryce Leed3624e12017-11-30 08:51:45 -08002412 @VisibleForTesting
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002413 void updateBounds(TaskRecord task, Rect bounds) {
Bryce Leedacefc42017-10-10 12:56:02 -07002414 if (bounds.isEmpty()) {
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002415 return;
2416 }
2417
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002418 final ActivityStack stack = task.getStack();
2419 if (stack != null && stack.resizeStackWithLaunchBounds()) {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07002420 mService.resizeStack(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002421 stack.mStackId, bounds, true, !PRESERVE_WINDOWS, ANIMATE, -1);
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002422 } else {
2423 task.updateOverrideConfiguration(bounds);
2424 }
2425 }
2426
Wale Ogunwale01d66562015-12-29 08:19:19 -08002427 private void setTaskToCurrentTopOrCreateNewTask() {
Bryce Leedacefc42017-10-10 12:56:02 -07002428 mTargetStack = computeStackFocus(mStartActivity, false, mLaunchFlags, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002429 if (mDoResume) {
2430 mTargetStack.moveToFront("addingToTopTask");
2431 }
Wale Ogunwale30e441d2017-11-09 08:28:45 -08002432 final ActivityRecord prev = mTargetStack.getTopActivity();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002433 final TaskRecord task = (prev != null)
2434 ? prev.getTaskRecord() : mTargetStack.createTaskRecord(
2435 mSupervisor.getNextTaskIdForUserLocked(mStartActivity.mUserId), mStartActivity.info,
Bryce Leeb802ea12017-11-15 21:25:03 -08002436 mIntent, null, null, true, mStartActivity, mSourceRecord, mOptions);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002437 addOrReparentStartingActivity(task, "setTaskToCurrentTopOrCreateNewTask");
2438 mTargetStack.positionChildWindowContainerAtTop(task);
2439 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002440 + " in new guessed " + mStartActivity.getTaskRecord());
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002441 }
2442
2443 private void addOrReparentStartingActivity(TaskRecord parent, String reason) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002444 if (mStartActivity.getTaskRecord() == null || mStartActivity.getTaskRecord() == parent) {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002445 parent.addActivityToTop(mStartActivity);
2446 } else {
2447 mStartActivity.reparent(parent, parent.mActivities.size() /* top */, reason);
2448 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002449 }
2450
2451 private int adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance,
2452 boolean launchSingleTask, int launchFlags) {
2453 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2454 (launchSingleInstance || launchSingleTask)) {
2455 // We have a conflict between the Intent and the Activity manifest, manifest wins.
2456 Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " +
2457 "\"singleInstance\" or \"singleTask\"");
2458 launchFlags &=
2459 ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK);
2460 } else {
2461 switch (r.info.documentLaunchMode) {
2462 case ActivityInfo.DOCUMENT_LAUNCH_NONE:
2463 break;
2464 case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
2465 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2466 break;
2467 case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
2468 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2469 break;
2470 case ActivityInfo.DOCUMENT_LAUNCH_NEVER:
2471 launchFlags &= ~FLAG_ACTIVITY_MULTIPLE_TASK;
2472 break;
2473 }
2474 }
2475 return launchFlags;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002476 }
2477
Bryce Leedacefc42017-10-10 12:56:02 -07002478 private ActivityStack computeStackFocus(ActivityRecord r, boolean newTask, int launchFlags,
2479 ActivityOptions aOptions) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002480 final TaskRecord task = r.getTaskRecord();
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002481 ActivityStack stack = getLaunchStack(r, launchFlags, task, aOptions);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002482 if (stack != null) {
2483 return stack;
2484 }
2485
Andrii Kulian02b7a832016-10-06 23:11:56 -07002486 final ActivityStack currentStack = task != null ? task.getStack() : null;
Wale Ogunwaled32da472018-11-16 07:19:28 -08002487 final ActivityStack focusedStack = mRootActivityContainer.getTopDisplayFocusedStack();
Andrii Kulian02b7a832016-10-06 23:11:56 -07002488 if (currentStack != null) {
Andrii Kulian52d255c2018-07-13 11:32:19 -07002489 if (focusedStack != currentStack) {
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002490 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
2491 "computeStackFocus: Setting " + "focused stack to r=" + r
2492 + " task=" + task);
2493 } else {
2494 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
Andrii Kulian52d255c2018-07-13 11:32:19 -07002495 "computeStackFocus: Focused stack already=" + focusedStack);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002496 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07002497 return currentStack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002498 }
2499
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002500 if (canLaunchIntoFocusedStack(r, newTask)) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002501 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
Andrii Kulian52d255c2018-07-13 11:32:19 -07002502 "computeStackFocus: Have a focused stack=" + focusedStack);
2503 return focusedStack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002504 }
2505
David Stevense5a7b642017-05-22 13:18:23 -07002506 if (mPreferredDisplayId != DEFAULT_DISPLAY) {
Andrii Kuliana8fe3df2017-06-16 15:29:26 -07002507 // Try to put the activity in a stack on a secondary display.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002508 stack = mRootActivityContainer.getValidLaunchStackOnDisplay(
2509 mPreferredDisplayId, r, aOptions, mLaunchParams);
Andrii Kuliana8fe3df2017-06-16 15:29:26 -07002510 if (stack == null) {
2511 // If source display is not suitable - look for topmost valid stack in the system.
2512 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
David Stevense5a7b642017-05-22 13:18:23 -07002513 "computeStackFocus: Can't launch on mPreferredDisplayId="
2514 + mPreferredDisplayId + ", looking on all displays.");
Wale Ogunwaled32da472018-11-16 07:19:28 -08002515 stack = mRootActivityContainer.getNextValidLaunchStack(r, mPreferredDisplayId);
Andrii Kuliana8fe3df2017-06-16 15:29:26 -07002516 }
2517 }
2518 if (stack == null) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002519 stack = mRootActivityContainer.getLaunchStack(r, aOptions, task, ON_TOP);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002520 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002521 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, "computeStackFocus: New stack r="
2522 + r + " stackId=" + stack.mStackId);
2523 return stack;
2524 }
2525
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002526 /** Check if provided activity record can launch in currently focused stack. */
Wale Ogunwale68278562017-09-23 17:13:55 -07002527 // TODO: This method can probably be consolidated into getLaunchStack() below.
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002528 private boolean canLaunchIntoFocusedStack(ActivityRecord r, boolean newTask) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002529 final ActivityStack focusedStack = mRootActivityContainer.getTopDisplayFocusedStack();
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002530 final boolean canUseFocusedStack;
Wale Ogunwale68278562017-09-23 17:13:55 -07002531 if (focusedStack.isActivityTypeAssistant()) {
2532 canUseFocusedStack = r.isActivityTypeAssistant();
2533 } else {
2534 switch (focusedStack.getWindowingMode()) {
2535 case WINDOWING_MODE_FULLSCREEN:
2536 // The fullscreen stack can contain any task regardless of if the task is
2537 // resizeable or not. So, we let the task go in the fullscreen task if it is the
2538 // focus stack.
2539 canUseFocusedStack = true;
2540 break;
2541 case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
2542 case WINDOWING_MODE_SPLIT_SCREEN_SECONDARY:
2543 // Any activity which supports split screen can go in the docked stack.
2544 canUseFocusedStack = r.supportsSplitScreenWindowingMode();
2545 break;
2546 case WINDOWING_MODE_FREEFORM:
2547 // Any activity which supports freeform can go in the freeform stack.
2548 canUseFocusedStack = r.supportsFreeform();
2549 break;
2550 default:
2551 // Dynamic stacks behave similarly to the fullscreen stack and can contain any
2552 // resizeable task.
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002553 canUseFocusedStack = !focusedStack.isOnHomeDisplay()
Wale Ogunwale68278562017-09-23 17:13:55 -07002554 && r.canBeLaunchedOnDisplay(focusedStack.mDisplayId);
2555 }
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002556 }
Andrii Kulian94e82d9b02017-07-13 15:33:06 -07002557 return canUseFocusedStack && !newTask
Wale Ogunwale68278562017-09-23 17:13:55 -07002558 // Using the focus stack isn't important enough to override the preferred display.
David Stevense5a7b642017-05-22 13:18:23 -07002559 && (mPreferredDisplayId == focusedStack.mDisplayId);
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002560 }
2561
Wale Ogunwale854809c2015-12-27 16:18:19 -08002562 private ActivityStack getLaunchStack(ActivityRecord r, int launchFlags, TaskRecord task,
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002563 ActivityOptions aOptions) {
Bryce Leea19b5ad2017-06-07 16:54:11 -07002564 // We are reusing a task, keep the stack!
2565 if (mReuseTask != null) {
2566 return mReuseTask.getStack();
2567 }
Jorim Jaggib8c58762016-04-20 17:58:29 -07002568
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -08002569 if (((launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) == 0)
David Stevense5a7b642017-05-22 13:18:23 -07002570 || mPreferredDisplayId != DEFAULT_DISPLAY) {
Winson Chung93442032018-12-04 13:24:29 -08002571 final boolean onTop = aOptions == null || !aOptions.getAvoidMoveToFront();
Wale Ogunwaled32da472018-11-16 07:19:28 -08002572 final ActivityStack stack =
Winson Chung93442032018-12-04 13:24:29 -08002573 mRootActivityContainer.getLaunchStack(r, aOptions, task, onTop, mLaunchParams);
Garfield Tan20d9e2f2018-11-16 15:42:29 -08002574 return stack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002575 }
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002576 // Otherwise handle adjacent launch.
Wale Ogunwale854809c2015-12-27 16:18:19 -08002577
Wale Ogunwaled32da472018-11-16 07:19:28 -08002578 final ActivityStack focusedStack = mRootActivityContainer.getTopDisplayFocusedStack();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002579 // The parent activity doesn't want to launch the activity on top of itself, but
2580 // instead tries to put it onto other side in side-by-side mode.
Andrii Kulian52d255c2018-07-13 11:32:19 -07002581 final ActivityStack parentStack = task != null ? task.getStack(): focusedStack;
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002582
Andrii Kulian52d255c2018-07-13 11:32:19 -07002583 if (parentStack != focusedStack) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002584 // If task's parent stack is not focused - use it during adjacent launch.
2585 return parentStack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002586 } else {
Andrii Kulian52d255c2018-07-13 11:32:19 -07002587 if (focusedStack != null && task == focusedStack.topTask()) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002588 // If task is already on top of focused stack - use it. We don't want to move the
2589 // existing focused task to adjacent stack, just deliver new intent in this case.
Andrii Kulian52d255c2018-07-13 11:32:19 -07002590 return focusedStack;
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002591 }
2592
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002593 if (parentStack != null && parentStack.inSplitScreenPrimaryWindowingMode()) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002594 // If parent was in docked stack, the natural place to launch another activity
2595 // will be fullscreen, so it can appear alongside the docked window.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002596 final int activityType =
2597 mRootActivityContainer.resolveActivityType(r, mOptions, task);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002598 return parentStack.getDisplay().getOrCreateStack(
2599 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, activityType, ON_TOP);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002600 } else {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002601 // If the parent is not in the docked stack, we check if there is docked window
2602 // and if yes, we will launch into that stack. If not, we just put the new
2603 // activity into parent's stack, because we can't find a better place.
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07002604 final ActivityStack dockedStack =
Wale Ogunwaled32da472018-11-16 07:19:28 -08002605 mRootActivityContainer.getDefaultDisplay().getSplitScreenPrimaryStack();
Wale Ogunwale9dcf9462017-09-19 15:13:01 -07002606 if (dockedStack != null && !dockedStack.shouldBeVisible(r)) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002607 // There is a docked stack, but it isn't visible, so we can't launch into that.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002608 return mRootActivityContainer.getLaunchStack(r, aOptions, task, ON_TOP);
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002609 } else {
2610 return dockedStack;
2611 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002612 }
2613 }
2614 }
2615
Bryce Lee7daee392017-10-12 13:46:18 -07002616 private boolean isLaunchModeOneOf(int mode1, int mode2) {
2617 return mode1 == mLaunchMode || mode2 == mLaunchMode;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002618 }
2619
Daichi Hirono15a02992016-04-27 18:47:01 +09002620 static boolean isDocumentLaunchesIntoExisting(int flags) {
2621 return (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2622 (flags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0;
2623 }
liulvpingcfa825f2016-09-26 20:00:15 +08002624
Bryce Lee4c9a5972017-12-01 22:14:24 -08002625 ActivityStarter setIntent(Intent intent) {
2626 mRequest.intent = intent;
2627 return this;
2628 }
2629
Bryce Lee32e09ef2018-03-19 15:29:49 -07002630 @VisibleForTesting
2631 Intent getIntent() {
2632 return mRequest.intent;
2633 }
2634
Bryce Lee4c9a5972017-12-01 22:14:24 -08002635 ActivityStarter setReason(String reason) {
2636 mRequest.reason = reason;
2637 return this;
2638 }
2639
2640 ActivityStarter setCaller(IApplicationThread caller) {
2641 mRequest.caller = caller;
2642 return this;
2643 }
2644
2645 ActivityStarter setEphemeralIntent(Intent intent) {
2646 mRequest.ephemeralIntent = intent;
2647 return this;
2648 }
2649
2650
2651 ActivityStarter setResolvedType(String type) {
2652 mRequest.resolvedType = type;
2653 return this;
2654 }
2655
2656 ActivityStarter setActivityInfo(ActivityInfo info) {
2657 mRequest.activityInfo = info;
2658 return this;
2659 }
2660
2661 ActivityStarter setResolveInfo(ResolveInfo info) {
2662 mRequest.resolveInfo = info;
2663 return this;
2664 }
2665
2666 ActivityStarter setVoiceSession(IVoiceInteractionSession voiceSession) {
2667 mRequest.voiceSession = voiceSession;
2668 return this;
2669 }
2670
2671 ActivityStarter setVoiceInteractor(IVoiceInteractor voiceInteractor) {
2672 mRequest.voiceInteractor = voiceInteractor;
2673 return this;
2674 }
2675
2676 ActivityStarter setResultTo(IBinder resultTo) {
2677 mRequest.resultTo = resultTo;
2678 return this;
2679 }
2680
2681 ActivityStarter setResultWho(String resultWho) {
2682 mRequest.resultWho = resultWho;
2683 return this;
2684 }
2685
2686 ActivityStarter setRequestCode(int requestCode) {
2687 mRequest.requestCode = requestCode;
2688 return this;
2689 }
2690
2691 ActivityStarter setCallingPid(int pid) {
2692 mRequest.callingPid = pid;
2693 return this;
2694 }
2695
2696 ActivityStarter setCallingUid(int uid) {
2697 mRequest.callingUid = uid;
2698 return this;
2699 }
2700
2701 ActivityStarter setCallingPackage(String callingPackage) {
2702 mRequest.callingPackage = callingPackage;
2703 return this;
2704 }
2705
2706 ActivityStarter setRealCallingPid(int pid) {
2707 mRequest.realCallingPid = pid;
2708 return this;
2709 }
2710
2711 ActivityStarter setRealCallingUid(int uid) {
2712 mRequest.realCallingUid = uid;
2713 return this;
2714 }
2715
2716 ActivityStarter setStartFlags(int startFlags) {
2717 mRequest.startFlags = startFlags;
2718 return this;
2719 }
2720
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002721 ActivityStarter setActivityOptions(SafeActivityOptions options) {
Bryce Lee4c9a5972017-12-01 22:14:24 -08002722 mRequest.activityOptions = options;
2723 return this;
2724 }
2725
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002726 ActivityStarter setActivityOptions(Bundle bOptions) {
2727 return setActivityOptions(SafeActivityOptions.fromBundle(bOptions));
2728 }
2729
Bryce Lee4c9a5972017-12-01 22:14:24 -08002730 ActivityStarter setIgnoreTargetSecurity(boolean ignoreTargetSecurity) {
2731 mRequest.ignoreTargetSecurity = ignoreTargetSecurity;
2732 return this;
2733 }
2734
Patrick Baumann31426b22018-05-21 13:46:40 -07002735 ActivityStarter setFilterCallingUid(int filterCallingUid) {
2736 mRequest.filterCallingUid = filterCallingUid;
2737 return this;
2738 }
2739
Bryce Lee4c9a5972017-12-01 22:14:24 -08002740 ActivityStarter setComponentSpecified(boolean componentSpecified) {
2741 mRequest.componentSpecified = componentSpecified;
2742 return this;
2743 }
2744
2745 ActivityStarter setOutActivity(ActivityRecord[] outActivity) {
2746 mRequest.outActivity = outActivity;
2747 return this;
2748 }
2749
2750 ActivityStarter setInTask(TaskRecord inTask) {
2751 mRequest.inTask = inTask;
2752 return this;
2753 }
2754
2755 ActivityStarter setWaitResult(WaitResult result) {
2756 mRequest.waitResult = result;
2757 return this;
2758 }
2759
2760 ActivityStarter setProfilerInfo(ProfilerInfo info) {
2761 mRequest.profilerInfo = info;
2762 return this;
2763 }
2764
2765 ActivityStarter setGlobalConfiguration(Configuration config) {
2766 mRequest.globalConfig = config;
2767 return this;
2768 }
2769
Bryce Lee4c9a5972017-12-01 22:14:24 -08002770 ActivityStarter setUserId(int userId) {
2771 mRequest.userId = userId;
2772 return this;
2773 }
2774
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002775 ActivityStarter setMayWait(int userId) {
Bryce Lee4c9a5972017-12-01 22:14:24 -08002776 mRequest.mayWait = true;
Bryce Lee4c9a5972017-12-01 22:14:24 -08002777 mRequest.userId = userId;
2778
2779 return this;
2780 }
2781
Jorim Jaggi6fa41c32018-04-23 18:35:00 +02002782 ActivityStarter setAllowPendingRemoteAnimationRegistryLookup(boolean allowLookup) {
2783 mRequest.allowPendingRemoteAnimationRegistryLookup = allowLookup;
2784 return this;
2785 }
2786
Michal Karpinski201bc0c2018-07-20 15:32:00 +01002787 ActivityStarter setOriginatingPendingIntent(PendingIntentRecord originatingPendingIntent) {
2788 mRequest.originatingPendingIntent = originatingPendingIntent;
2789 return this;
2790 }
2791
Michal Karpinskiac116df2018-12-10 17:51:42 +00002792 ActivityStarter setAllowBackgroundActivityStart(boolean allowBackgroundActivityStart) {
2793 mRequest.allowBackgroundActivityStart = allowBackgroundActivityStart;
2794 return this;
2795 }
2796
Bryce Leed3624e12017-11-30 08:51:45 -08002797 void dump(PrintWriter pw, String prefix) {
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002798 prefix = prefix + " ";
Dianne Hackborne676ec72017-07-25 10:55:08 -07002799 pw.print(prefix);
2800 pw.print("mCurrentUser=");
Wale Ogunwaled32da472018-11-16 07:19:28 -08002801 pw.println(mRootActivityContainer.mCurrentUser);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002802 pw.print(prefix);
2803 pw.print("mLastStartReason=");
2804 pw.println(mLastStartReason);
2805 pw.print(prefix);
2806 pw.print("mLastStartActivityTimeMs=");
2807 pw.println(DateFormat.getDateTimeInstance().format(new Date(mLastStartActivityTimeMs)));
2808 pw.print(prefix);
2809 pw.print("mLastStartActivityResult=");
2810 pw.println(mLastStartActivityResult);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002811 ActivityRecord r = mLastStartActivityRecord[0];
2812 if (r != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002813 pw.print(prefix);
2814 pw.println("mLastStartActivityRecord:");
2815 r.dump(pw, prefix + " ");
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002816 }
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002817 if (mStartActivity != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002818 pw.print(prefix);
2819 pw.println("mStartActivity:");
2820 mStartActivity.dump(pw, prefix + " ");
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002821 }
2822 if (mIntent != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002823 pw.print(prefix);
2824 pw.print("mIntent=");
2825 pw.println(mIntent);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002826 }
2827 if (mOptions != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002828 pw.print(prefix);
2829 pw.print("mOptions=");
2830 pw.println(mOptions);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002831 }
Dianne Hackborne676ec72017-07-25 10:55:08 -07002832 pw.print(prefix);
2833 pw.print("mLaunchSingleTop=");
Bryce Lee7daee392017-10-12 13:46:18 -07002834 pw.print(LAUNCH_SINGLE_TOP == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002835 pw.print(" mLaunchSingleInstance=");
Bryce Lee7daee392017-10-12 13:46:18 -07002836 pw.print(LAUNCH_SINGLE_INSTANCE == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002837 pw.print(" mLaunchSingleTask=");
Bryce Lee7daee392017-10-12 13:46:18 -07002838 pw.println(LAUNCH_SINGLE_TASK == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002839 pw.print(prefix);
2840 pw.print("mLaunchFlags=0x");
2841 pw.print(Integer.toHexString(mLaunchFlags));
2842 pw.print(" mDoResume=");
2843 pw.print(mDoResume);
2844 pw.print(" mAddingToTask=");
2845 pw.println(mAddingToTask);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002846 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002847}