blob: d59a651a7a33b65e521a898084d86fa5ba923d15 [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
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080017package com.android.server.am;
18
Wale Ogunwale01d66562015-12-29 08:19:19 -080019import static android.app.Activity.RESULT_CANCELED;
Bryce Leef9d49542017-06-26 16:27:32 -070020import static android.app.ActivityManager.START_ABORTED;
Bryce Leeaa5e8c32017-03-01 16:01:06 -080021import static android.app.ActivityManager.START_CANCELED;
Wale Ogunwale01d66562015-12-29 08:19:19 -080022import static android.app.ActivityManager.START_CLASS_NOT_FOUND;
23import static android.app.ActivityManager.START_DELIVERED_TO_TOP;
24import static android.app.ActivityManager.START_FLAG_ONLY_IF_NEEDED;
25import static android.app.ActivityManager.START_RETURN_INTENT_TO_CALLER;
26import static android.app.ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
27import static android.app.ActivityManager.START_SUCCESS;
28import static android.app.ActivityManager.START_TASK_TO_FRONT;
Wale Ogunwale68278562017-09-23 17:13:55 -070029import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
30import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
Wale Ogunwale7d7973a2018-04-05 10:25:59 -070031import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070032import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
33import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Wale Ogunwale0568aed2017-09-08 13:29:37 -070034import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080035import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
36import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
Wale Ogunwale2a25a622016-01-30 11:27:21 -080037import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080038import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
Wale Ogunwale01d66562015-12-29 08:19:19 -080039import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080040import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
Wale Ogunwale01d66562015-12-29 08:19:19 -080041import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION;
42import static android.content.Intent.FLAG_ACTIVITY_NO_USER_ACTION;
Wale Ogunwale01d66562015-12-29 08:19:19 -080043import static android.content.Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP;
44import static android.content.Intent.FLAG_ACTIVITY_REORDER_TO_FRONT;
45import static android.content.Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED;
46import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
47import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP;
48import static android.content.pm.ActivityInfo.DOCUMENT_LAUNCH_ALWAYS;
Bryce Leef65ee7e2018-03-26 16:03:47 -070049import static android.content.pm.ActivityInfo.LAUNCH_MULTIPLE;
Wale Ogunwale01d66562015-12-29 08:19:19 -080050import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
51import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
52import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
David Stevensc6b91c62017-02-08 14:23:58 -080053import static android.view.Display.DEFAULT_DISPLAY;
Andrii Kulian16802aa2016-11-02 12:21:33 -070054import static android.view.Display.INVALID_DISPLAY;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080055import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
56import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
57import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
58import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RESULTS;
59import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
60import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
61import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USER_LEAVING;
62import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
63import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
64import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RESULTS;
65import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_USER_LEAVING;
66import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
67import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
68import static com.android.server.am.ActivityManagerService.ANIMATE;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080069import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
Winson Chung74666102017-02-22 17:49:24 -080070import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080071import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
Wale Ogunwalecacfaa22016-01-15 11:26:08 -080072import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080073import static com.android.server.am.ActivityStackSupervisor.TAG_TASKS;
Filip Gruszczynskie826f322016-01-11 17:15:22 -080074import static com.android.server.am.EventLogTags.AM_NEW_INTENT;
Winson Chung74666102017-02-22 17:49:24 -080075import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
76import static com.android.server.am.TaskRecord.REPARENT_MOVE_STACK_TO_FRONT;
77
Todd Kennedye9910222017-02-21 16:00:11 -080078import android.annotation.NonNull;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +010079import android.annotation.Nullable;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080080import android.app.ActivityManager;
81import android.app.ActivityOptions;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080082import android.app.IApplicationThread;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080083import android.app.PendingIntent;
84import android.app.ProfilerInfo;
Sudheer Shankafc46e9b2016-10-21 17:55:27 -070085import android.app.WaitResult;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080086import android.content.IIntentSender;
87import android.content.Intent;
88import android.content.IntentSender;
89import android.content.pm.ActivityInfo;
90import android.content.pm.ApplicationInfo;
Todd Kennedye9910222017-02-21 16:00:11 -080091import android.content.pm.AuxiliaryResolveInfo;
Kenny Guyb1b30262016-02-09 16:02:35 +000092import android.content.pm.PackageManager;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080093import android.content.pm.ResolveInfo;
Kenny Guyb1b30262016-02-09 16:02:35 +000094import android.content.pm.UserInfo;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080095import android.content.res.Configuration;
96import android.graphics.Rect;
97import android.os.Binder;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080098import android.os.Bundle;
99import android.os.IBinder;
100import android.os.RemoteException;
101import android.os.SystemClock;
102import android.os.UserHandle;
Kenny Guyb1b30262016-02-09 16:02:35 +0000103import android.os.UserManager;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800104import android.service.voice.IVoiceInteractionSession;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700105import android.text.TextUtils;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800106import android.util.EventLog;
Bryce Leedaa91e42017-12-06 14:13:01 -0800107import android.util.Pools.SynchronizedPool;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800108import android.util.Slog;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800109
Bryce Leed3624e12017-11-30 08:51:45 -0800110import com.android.internal.annotations.VisibleForTesting;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800111import com.android.internal.app.HeavyWeightSwitcherActivity;
112import com.android.internal.app.IVoiceInteractor;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800113import com.android.server.am.ActivityStackSupervisor.PendingActivityLaunch;
Bryce Leeec55eb02017-12-05 20:51:27 -0800114import com.android.server.am.LaunchParamsController.LaunchParams;
Todd Kennedy1fb34042017-03-01 13:56:58 -0800115import com.android.server.pm.InstantAppResolver;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800116
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700117import java.io.PrintWriter;
118import java.text.DateFormat;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700119import java.util.Date;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800120
121/**
Bryce Leed3624e12017-11-30 08:51:45 -0800122 * Controller for interpreting how and then launching an activity.
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800123 *
124 * This class collects all the logic for determining how an intent and flags should be turned into
125 * an activity and associated task and stack.
126 */
Wale Ogunwale01d66562015-12-29 08:19:19 -0800127class ActivityStarter {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800128 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStarter" : TAG_AM;
129 private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS;
130 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
131 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
132 private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING;
Bryce Lee7daee392017-10-12 13:46:18 -0700133 private static final int INVALID_LAUNCH_MODE = -1;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800134
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700135 private final ActivityTaskManagerService mService;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800136 private final ActivityStackSupervisor mSupervisor;
Benjamin Franz563707b2017-06-29 15:06:13 +0100137 private final ActivityStartInterceptor mInterceptor;
Bryce Leed3624e12017-11-30 08:51:45 -0800138 private final ActivityStartController mController;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800139
Wale Ogunwale01d66562015-12-29 08:19:19 -0800140 // Share state variable among methods when starting an activity.
141 private ActivityRecord mStartActivity;
142 private Intent mIntent;
143 private int mCallingUid;
144 private ActivityOptions mOptions;
145
Bryce Lee7daee392017-10-12 13:46:18 -0700146 private int mLaunchMode;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800147 private boolean mLaunchTaskBehind;
148 private int mLaunchFlags;
149
Bryce Leeec55eb02017-12-05 20:51:27 -0800150 private LaunchParams mLaunchParams = new LaunchParams();
Wale Ogunwale01d66562015-12-29 08:19:19 -0800151
152 private ActivityRecord mNotTop;
153 private boolean mDoResume;
154 private int mStartFlags;
155 private ActivityRecord mSourceRecord;
Bryce Lee7daee392017-10-12 13:46:18 -0700156
David Stevense5a7b642017-05-22 13:18:23 -0700157 // The display to launch the activity onto, barring any strong reason to do otherwise.
158 private int mPreferredDisplayId;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800159
160 private TaskRecord mInTask;
161 private boolean mAddingToTask;
162 private TaskRecord mReuseTask;
163
164 private ActivityInfo mNewTaskInfo;
165 private Intent mNewTaskIntent;
166 private ActivityStack mSourceStack;
167 private ActivityStack mTargetStack;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800168 private boolean mMovedToFront;
169 private boolean mNoAnimation;
170 private boolean mKeepCurTransition;
Jorim Jaggic875ae72016-04-26 22:41:06 -0700171 private boolean mAvoidMoveToFront;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800172
Bryce Lee325e09682017-10-05 17:20:25 -0700173 // We must track when we deliver the new intent since multiple code paths invoke
174 // {@link #deliverNewIntent}. This is due to early returns in the code path. This flag is used
175 // inside {@link #deliverNewIntent} to suppress duplicate requests and ensure the intent is
176 // delivered at most once.
177 private boolean mIntentDelivered;
178
Wale Ogunwale01d66562015-12-29 08:19:19 -0800179 private IVoiceInteractionSession mVoiceSession;
180 private IVoiceInteractor mVoiceInteractor;
181
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700182 // Last activity record we attempted to start
183 private final ActivityRecord[] mLastStartActivityRecord = new ActivityRecord[1];
184 // The result of the last activity we attempted to start.
185 private int mLastStartActivityResult;
186 // Time in milli seconds we attempted to start the last activity.
187 private long mLastStartActivityTimeMs;
188 // The reason we were trying to start the last activity
189 private String mLastStartReason;
Wale Ogunwale59bcba62017-06-16 12:42:51 -0700190
Bryce Lee4c9a5972017-12-01 22:14:24 -0800191 /*
192 * Request details provided through setter methods. Should be reset after {@link #execute()}
193 * to avoid unnecessarily retaining parameters. Note that the request is ignored when
194 * {@link #startResolvedActivity} is invoked directly.
195 */
196 private Request mRequest = new Request();
197
Bryce Leed3624e12017-11-30 08:51:45 -0800198 /**
199 * An interface that to provide {@link ActivityStarter} instances to the controller. This is
200 * used by tests to inject their own starter implementations for verification purposes.
201 */
202 @VisibleForTesting
203 interface Factory {
204 /**
Bryce Lee4c9a5972017-12-01 22:14:24 -0800205 * Sets the {@link ActivityStartController} to be passed to {@link ActivityStarter}.
206 */
207 void setController(ActivityStartController controller);
208
209 /**
Bryce Leed3624e12017-11-30 08:51:45 -0800210 * Generates an {@link ActivityStarter} that is ready to handle a new start request.
211 * @param controller The {@link ActivityStartController} which the starter who will own
212 * this instance.
213 * @return an {@link ActivityStarter}
214 */
Bryce Leedaa91e42017-12-06 14:13:01 -0800215 ActivityStarter obtain();
216
217 /**
218 * Recycles a starter for reuse.
219 */
220 void recycle(ActivityStarter starter);
Wale Ogunwale01d66562015-12-29 08:19:19 -0800221 }
222
Bryce Leed3624e12017-11-30 08:51:45 -0800223 /**
224 * Default implementation of {@link StarterFactory}.
225 */
226 static class DefaultFactory implements Factory {
Bryce Leedaa91e42017-12-06 14:13:01 -0800227 /**
228 * The maximum count of starters that should be active at one time:
229 * 1. last ran starter (for logging and post activity processing)
230 * 2. current running starter
231 * 3. starter from re-entry in (2)
232 */
233 private final int MAX_STARTER_COUNT = 3;
234
Bryce Lee4c9a5972017-12-01 22:14:24 -0800235 private ActivityStartController mController;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700236 private ActivityTaskManagerService mService;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800237 private ActivityStackSupervisor mSupervisor;
238 private ActivityStartInterceptor mInterceptor;
239
Bryce Leedaa91e42017-12-06 14:13:01 -0800240 private SynchronizedPool<ActivityStarter> mStarterPool =
241 new SynchronizedPool<>(MAX_STARTER_COUNT);
242
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700243 DefaultFactory(ActivityTaskManagerService service,
Bryce Lee4c9a5972017-12-01 22:14:24 -0800244 ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
245 mService = service;
246 mSupervisor = supervisor;
247 mInterceptor = interceptor;
Bryce Leed3624e12017-11-30 08:51:45 -0800248 }
Bryce Lee4c9a5972017-12-01 22:14:24 -0800249
250 @Override
251 public void setController(ActivityStartController controller) {
252 mController = controller;
253 }
254
255 @Override
Bryce Leedaa91e42017-12-06 14:13:01 -0800256 public ActivityStarter obtain() {
257 ActivityStarter starter = mStarterPool.acquire();
258
259 if (starter == null) {
260 starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
261 }
262
263 return starter;
264 }
265
266 @Override
267 public void recycle(ActivityStarter starter) {
268 starter.reset(true /* clearRequest*/);
269 mStarterPool.release(starter);
Bryce Lee4c9a5972017-12-01 22:14:24 -0800270 }
271 }
272
273 /**
274 * Container for capturing initial start request details. This information is NOT reset until
275 * the {@link ActivityStarter} is recycled, allowing for multiple invocations with the same
276 * parameters.
277 *
278 * TODO(b/64750076): Investigate consolidating member variables of {@link ActivityStarter} with
279 * the request object. Note that some member variables are referenced in
280 * {@link #dump(PrintWriter, String)} and therefore cannot be cleared immediately after
281 * execution.
282 */
283 private static class Request {
284 private static final int DEFAULT_CALLING_UID = -1;
285 private static final int DEFAULT_CALLING_PID = 0;
286
287 IApplicationThread caller;
288 Intent intent;
289 Intent ephemeralIntent;
290 String resolvedType;
291 ActivityInfo activityInfo;
292 ResolveInfo resolveInfo;
293 IVoiceInteractionSession voiceSession;
294 IVoiceInteractor voiceInteractor;
295 IBinder resultTo;
296 String resultWho;
297 int requestCode;
298 int callingPid = DEFAULT_CALLING_UID;
299 int callingUid = DEFAULT_CALLING_PID;
300 String callingPackage;
301 int realCallingPid;
302 int realCallingUid;
303 int startFlags;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100304 SafeActivityOptions activityOptions;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800305 boolean ignoreTargetSecurity;
306 boolean componentSpecified;
Winson Chunge2d72172018-01-25 17:46:20 +0000307 boolean avoidMoveToFront;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800308 ActivityRecord[] outActivity;
309 TaskRecord inTask;
310 String reason;
311 ProfilerInfo profilerInfo;
312 Configuration globalConfig;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800313 int userId;
314 WaitResult waitResult;
Patrick Baumann31426b22018-05-21 13:46:40 -0700315 int filterCallingUid;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800316
317 /**
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200318 * If set to {@code true}, allows this activity start to look into
319 * {@link PendingRemoteAnimationRegistry}
320 */
321 boolean allowPendingRemoteAnimationRegistryLookup;
322
323 /**
Bryce Lee4c9a5972017-12-01 22:14:24 -0800324 * Indicates that we should wait for the result of the start request. This flag is set when
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100325 * {@link ActivityStarter#setMayWait(int)} is called.
Bryce Lee4c9a5972017-12-01 22:14:24 -0800326 * {@see ActivityStarter#startActivityMayWait}.
327 */
328 boolean mayWait;
Bryce Leedaa91e42017-12-06 14:13:01 -0800329
330 /**
Bryce Leea3cd8e02018-01-09 15:44:24 -0800331 * Ensure constructed request matches reset instance.
332 */
333 Request() {
334 reset();
335 }
336
337 /**
Bryce Leedaa91e42017-12-06 14:13:01 -0800338 * Sets values back to the initial state, clearing any held references.
339 */
340 void reset() {
341 caller = null;
342 intent = null;
343 ephemeralIntent = null;
344 resolvedType = null;
345 activityInfo = null;
346 resolveInfo = null;
347 voiceSession = null;
348 voiceInteractor = null;
349 resultTo = null;
350 resultWho = null;
351 requestCode = 0;
Bryce Leea3cd8e02018-01-09 15:44:24 -0800352 callingPid = DEFAULT_CALLING_PID;
353 callingUid = DEFAULT_CALLING_UID;
Bryce Leedaa91e42017-12-06 14:13:01 -0800354 callingPackage = null;
355 realCallingPid = 0;
356 realCallingUid = 0;
357 startFlags = 0;
358 activityOptions = null;
359 ignoreTargetSecurity = false;
360 componentSpecified = false;
361 outActivity = null;
362 inTask = null;
363 reason = null;
364 profilerInfo = null;
365 globalConfig = null;
Bryce Leedaa91e42017-12-06 14:13:01 -0800366 userId = 0;
367 waitResult = null;
368 mayWait = false;
Winson Chunge2d72172018-01-25 17:46:20 +0000369 avoidMoveToFront = false;
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200370 allowPendingRemoteAnimationRegistryLookup = true;
Patrick Baumann31426b22018-05-21 13:46:40 -0700371 filterCallingUid = UserHandle.USER_NULL;
Bryce Leedaa91e42017-12-06 14:13:01 -0800372 }
373
374 /**
375 * Adopts all values from passed in request.
376 */
377 void set(Request request) {
378 caller = request.caller;
379 intent = request.intent;
380 ephemeralIntent = request.ephemeralIntent;
381 resolvedType = request.resolvedType;
382 activityInfo = request.activityInfo;
383 resolveInfo = request.resolveInfo;
384 voiceSession = request.voiceSession;
385 voiceInteractor = request.voiceInteractor;
386 resultTo = request.resultTo;
387 resultWho = request.resultWho;
388 requestCode = request.requestCode;
389 callingPid = request.callingPid;
390 callingUid = request.callingUid;
391 callingPackage = request.callingPackage;
392 realCallingPid = request.realCallingPid;
393 realCallingUid = request.realCallingUid;
394 startFlags = request.startFlags;
395 activityOptions = request.activityOptions;
396 ignoreTargetSecurity = request.ignoreTargetSecurity;
397 componentSpecified = request.componentSpecified;
398 outActivity = request.outActivity;
399 inTask = request.inTask;
400 reason = request.reason;
401 profilerInfo = request.profilerInfo;
402 globalConfig = request.globalConfig;
Bryce Leedaa91e42017-12-06 14:13:01 -0800403 userId = request.userId;
404 waitResult = request.waitResult;
405 mayWait = request.mayWait;
Winson Chunge2d72172018-01-25 17:46:20 +0000406 avoidMoveToFront = request.avoidMoveToFront;
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200407 allowPendingRemoteAnimationRegistryLookup
408 = request.allowPendingRemoteAnimationRegistryLookup;
Patrick Baumann31426b22018-05-21 13:46:40 -0700409 filterCallingUid = request.filterCallingUid;
Bryce Leedaa91e42017-12-06 14:13:01 -0800410 }
Bryce Leed3624e12017-11-30 08:51:45 -0800411 }
412
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700413 ActivityStarter(ActivityStartController controller, ActivityTaskManagerService service,
Bryce Leed3624e12017-11-30 08:51:45 -0800414 ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
415 mController = controller;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800416 mService = service;
Bryce Leed3624e12017-11-30 08:51:45 -0800417 mSupervisor = supervisor;
418 mInterceptor = interceptor;
Bryce Leedaa91e42017-12-06 14:13:01 -0800419 reset(true);
420 }
421
422 /**
423 * Effectively duplicates the starter passed in. All state and request values will be
424 * mirrored.
425 * @param starter
426 */
427 void set(ActivityStarter starter) {
428 mStartActivity = starter.mStartActivity;
429 mIntent = starter.mIntent;
430 mCallingUid = starter.mCallingUid;
431 mOptions = starter.mOptions;
432
433 mLaunchTaskBehind = starter.mLaunchTaskBehind;
434 mLaunchFlags = starter.mLaunchFlags;
435 mLaunchMode = starter.mLaunchMode;
436
Bryce Leeec55eb02017-12-05 20:51:27 -0800437 mLaunchParams.set(starter.mLaunchParams);
Bryce Leedaa91e42017-12-06 14:13:01 -0800438
439 mNotTop = starter.mNotTop;
440 mDoResume = starter.mDoResume;
441 mStartFlags = starter.mStartFlags;
442 mSourceRecord = starter.mSourceRecord;
443 mPreferredDisplayId = starter.mPreferredDisplayId;
444
445 mInTask = starter.mInTask;
446 mAddingToTask = starter.mAddingToTask;
447 mReuseTask = starter.mReuseTask;
448
449 mNewTaskInfo = starter.mNewTaskInfo;
450 mNewTaskIntent = starter.mNewTaskIntent;
451 mSourceStack = starter.mSourceStack;
452
453 mTargetStack = starter.mTargetStack;
454 mMovedToFront = starter.mMovedToFront;
455 mNoAnimation = starter.mNoAnimation;
456 mKeepCurTransition = starter.mKeepCurTransition;
457 mAvoidMoveToFront = starter.mAvoidMoveToFront;
458
459 mVoiceSession = starter.mVoiceSession;
460 mVoiceInteractor = starter.mVoiceInteractor;
461
462 mIntentDelivered = starter.mIntentDelivered;
463
464 mRequest.set(starter.mRequest);
Bryce Leed3624e12017-11-30 08:51:45 -0800465 }
466
Bryce Lee4c9a5972017-12-01 22:14:24 -0800467 ActivityRecord getStartActivity() {
468 return mStartActivity;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800469 }
470
Bryce Lee4c9a5972017-12-01 22:14:24 -0800471 boolean relatedToPackage(String packageName) {
472 return (mLastStartActivityRecord[0] != null
473 && packageName.equals(mLastStartActivityRecord[0].packageName))
474 || (mStartActivity != null && packageName.equals(mStartActivity.packageName));
475 }
476
477 /**
478 * Starts an activity based on the request parameters provided earlier.
479 * @return The starter result.
480 */
481 int execute() {
Bryce Leedaa91e42017-12-06 14:13:01 -0800482 try {
483 // TODO(b/64750076): Look into passing request directly to these methods to allow
484 // for transactional diffs and preprocessing.
485 if (mRequest.mayWait) {
486 return startActivityMayWait(mRequest.caller, mRequest.callingUid,
487 mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
488 mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
489 mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
490 mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100491 mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200492 mRequest.inTask, mRequest.reason,
493 mRequest.allowPendingRemoteAnimationRegistryLookup);
Bryce Leedaa91e42017-12-06 14:13:01 -0800494 } else {
495 return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
496 mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
497 mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
498 mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
499 mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
500 mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
501 mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200502 mRequest.outActivity, mRequest.inTask, mRequest.reason,
503 mRequest.allowPendingRemoteAnimationRegistryLookup);
Bryce Leedaa91e42017-12-06 14:13:01 -0800504 }
505 } finally {
506 onExecutionComplete();
507 }
508 }
509
510 /**
511 * Starts an activity based on the provided {@link ActivityRecord} and environment parameters.
512 * Note that this method is called internally as well as part of {@link #startActivity}.
513 *
514 * @return The start result.
515 */
516 int startResolvedActivity(final ActivityRecord r, ActivityRecord sourceRecord,
517 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
518 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
519 ActivityRecord[] outActivity) {
520 try {
521 return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
522 doResume, options, inTask, outActivity);
523 } finally {
524 onExecutionComplete();
Bryce Lee4c9a5972017-12-01 22:14:24 -0800525 }
526 }
527
528 private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700529 String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
530 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
531 IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
532 String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100533 SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200534 ActivityRecord[] outActivity, TaskRecord inTask, String reason,
535 boolean allowPendingRemoteAnimationRegistryLookup) {
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700536
537 if (TextUtils.isEmpty(reason)) {
538 throw new IllegalArgumentException("Need to specify a reason.");
539 }
540 mLastStartReason = reason;
541 mLastStartActivityTimeMs = System.currentTimeMillis();
542 mLastStartActivityRecord[0] = null;
543
544 mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
545 aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
546 callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
547 options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200548 inTask, allowPendingRemoteAnimationRegistryLookup);
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700549
550 if (outActivity != null) {
551 // mLastStartActivityRecord[0] is set in the call to startActivity above.
552 outActivity[0] = mLastStartActivityRecord[0];
553 }
Bryce Leef9d49542017-06-26 16:27:32 -0700554
Bryce Lee93e7f792017-10-25 15:54:55 -0700555 return getExternalResult(mLastStartActivityResult);
556 }
557
Bryce Leed3624e12017-11-30 08:51:45 -0800558 static int getExternalResult(int result) {
Bryce Leef9d49542017-06-26 16:27:32 -0700559 // Aborted results are treated as successes externally, but we must track them internally.
Bryce Lee93e7f792017-10-25 15:54:55 -0700560 return result != START_ABORTED ? result : START_SUCCESS;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700561 }
562
Bryce Leedaa91e42017-12-06 14:13:01 -0800563 /**
564 * Called when execution is complete. Sets state indicating completion and proceeds with
565 * recycling if appropriate.
566 */
567 private void onExecutionComplete() {
568 mController.onExecutionComplete(this);
569 }
570
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700571 private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800572 String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
573 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
574 IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
575 String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100576 SafeActivityOptions options,
577 boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200578 TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800579 int err = ActivityManager.START_SUCCESS;
Chad Brubaker06068612017-04-06 09:43:47 -0700580 // Pull the optional Ephemeral Installer-only bundle out of the options early.
581 final Bundle verificationBundle
582 = options != null ? options.popAppVerificationBundle() : null;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800583
584 ProcessRecord callerApp = null;
585 if (caller != null) {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700586 callerApp = mService.mAm.getRecordForAppLocked(caller);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800587 if (callerApp != null) {
588 callingPid = callerApp.pid;
589 callingUid = callerApp.info.uid;
590 } else {
591 Slog.w(TAG, "Unable to find app for caller " + caller
592 + " (pid=" + callingPid + ") when starting: "
593 + intent.toString());
594 err = ActivityManager.START_PERMISSION_DENIED;
595 }
596 }
597
Bryce Lee93e7f792017-10-25 15:54:55 -0700598 final int userId = aInfo != null && aInfo.applicationInfo != null
599 ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800600
601 if (err == ActivityManager.START_SUCCESS) {
602 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
Andrii Kulian03c403d2016-11-11 11:14:12 -0800603 + "} from uid " + callingUid);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800604 }
605
606 ActivityRecord sourceRecord = null;
607 ActivityRecord resultRecord = null;
608 if (resultTo != null) {
609 sourceRecord = mSupervisor.isInAnyStackLocked(resultTo);
610 if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
611 "Will send result to " + resultTo + " " + sourceRecord);
612 if (sourceRecord != null) {
613 if (requestCode >= 0 && !sourceRecord.finishing) {
614 resultRecord = sourceRecord;
615 }
616 }
617 }
618
619 final int launchFlags = intent.getFlags();
620
621 if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
622 // Transfer the result target from the source activity to the new
623 // one being started, including any failures.
624 if (requestCode >= 0) {
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100625 SafeActivityOptions.abort(options);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800626 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
627 }
628 resultRecord = sourceRecord.resultTo;
629 if (resultRecord != null && !resultRecord.isInStackLocked()) {
630 resultRecord = null;
631 }
632 resultWho = sourceRecord.resultWho;
633 requestCode = sourceRecord.requestCode;
634 sourceRecord.resultTo = null;
635 if (resultRecord != null) {
636 resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
637 }
638 if (sourceRecord.launchedFromUid == callingUid) {
639 // The new activity is being launched from the same uid as the previous
640 // activity in the flow, and asking to forward its result back to the
641 // previous. In this case the activity is serving as a trampoline between
642 // the two, so we also want to update its launchedFromPackage to be the
643 // same as the previous activity. Note that this is safe, since we know
644 // these two packages come from the same uid; the caller could just as
645 // well have supplied that same package name itself. This specifially
646 // deals with the case of an intent picker/chooser being launched in the app
647 // flow to redirect to an activity picked by the user, where we want the final
648 // activity to consider it to have been launched by the previous app activity.
649 callingPackage = sourceRecord.launchedFromPackage;
650 }
651 }
652
653 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
654 // We couldn't find a class that can handle the given Intent.
655 // That's the end of that!
656 err = ActivityManager.START_INTENT_NOT_RESOLVED;
657 }
658
659 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
660 // We couldn't find the specific class specified in the Intent.
661 // Also the end of the line.
662 err = ActivityManager.START_CLASS_NOT_FOUND;
663 }
664
665 if (err == ActivityManager.START_SUCCESS && sourceRecord != null
Bryce Leeaf691c02017-03-20 14:20:22 -0700666 && sourceRecord.getTask().voiceSession != null) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800667 // If this activity is being launched as part of a voice session, we need
668 // to ensure that it is safe to do so. If the upcoming activity will also
669 // be part of the voice session, we can only launch it if it has explicitly
670 // said it supports the VOICE category, or it is a part of the calling app.
671 if ((launchFlags & FLAG_ACTIVITY_NEW_TASK) == 0
672 && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
673 try {
674 intent.addCategory(Intent.CATEGORY_VOICE);
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700675 if (!mService.mAm.getPackageManager().activitySupportsIntent(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800676 intent.getComponent(), intent, resolvedType)) {
677 Slog.w(TAG,
678 "Activity being started in current voice task does not support voice: "
679 + intent);
680 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
681 }
682 } catch (RemoteException e) {
683 Slog.w(TAG, "Failure checking voice capabilities", e);
684 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
685 }
686 }
687 }
688
689 if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
690 // If the caller is starting a new voice session, just make sure the target
691 // is actually allowing it to run this way.
692 try {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700693 if (!mService.mAm.getPackageManager().activitySupportsIntent(intent.getComponent(),
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800694 intent, resolvedType)) {
695 Slog.w(TAG,
696 "Activity being started in new voice task does not support: "
697 + intent);
698 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
699 }
700 } catch (RemoteException e) {
701 Slog.w(TAG, "Failure checking voice capabilities", e);
702 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
703 }
704 }
705
Andrii Kulian02b7a832016-10-06 23:11:56 -0700706 final ActivityStack resultStack = resultRecord == null ? null : resultRecord.getStack();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800707
Wale Ogunwale01d66562015-12-29 08:19:19 -0800708 if (err != START_SUCCESS) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800709 if (resultRecord != null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -0800710 resultStack.sendActivityResultLocked(
711 -1, resultRecord, resultWho, requestCode, RESULT_CANCELED, null);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800712 }
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100713 SafeActivityOptions.abort(options);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800714 return err;
715 }
716
717 boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100718 requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity,
Winson Chungc9804e72018-05-15 11:01:44 -0700719 inTask != null, callerApp, resultRecord, resultStack);
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700720 abort |= !mService.mAm.mIntentFirewall.checkStartActivity(intent, callingUid,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800721 callingPid, resolvedType, aInfo.applicationInfo);
722
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700723 final WindowProcessController callerWpc =
724 callerApp != null ? callerApp.getWindowProcessController() : null;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100725 // Merge the two options bundles, while realCallerOptions takes precedence.
726 ActivityOptions checkedOptions = options != null
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700727 ? options.getOptions(intent, aInfo, callerWpc, mSupervisor) : null;
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200728 if (allowPendingRemoteAnimationRegistryLookup) {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700729 checkedOptions = mService.getActivityStartController()
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200730 .getPendingRemoteAnimationRegistry()
731 .overrideOptionsIfNeeded(callingPackage, checkedOptions);
732 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700733 if (mService.mController != null) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800734 try {
735 // The Intent we give to the watcher has the extra data
736 // stripped off, since it can contain private information.
737 Intent watchIntent = intent.cloneFilter();
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700738 abort |= !mService.mController.activityStarting(watchIntent,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800739 aInfo.applicationInfo.packageName);
740 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700741 mService.mController = null;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800742 }
743 }
744
Rubin Xu58d25992016-01-21 17:47:13 +0000745 mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage);
Benjamin Franz563707b2017-06-29 15:06:13 +0100746 if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100747 callingUid, checkedOptions)) {
Benjamin Franz563707b2017-06-29 15:06:13 +0100748 // activity start was intercepted, e.g. because the target user is currently in quiet
749 // mode (turn off work) or the target application is suspended
750 intent = mInterceptor.mIntent;
751 rInfo = mInterceptor.mRInfo;
752 aInfo = mInterceptor.mAInfo;
753 resolvedType = mInterceptor.mResolvedType;
754 inTask = mInterceptor.mInTask;
755 callingPid = mInterceptor.mCallingPid;
756 callingUid = mInterceptor.mCallingUid;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100757 checkedOptions = mInterceptor.mActivityOptions;
Benjamin Franz563707b2017-06-29 15:06:13 +0100758 }
759
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800760 if (abort) {
761 if (resultRecord != null) {
762 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Wale Ogunwale01d66562015-12-29 08:19:19 -0800763 RESULT_CANCELED, null);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800764 }
765 // We pretend to the caller that it was really started, but
766 // they will just get a cancel result.
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100767 ActivityOptions.abort(checkedOptions);
Bryce Leef9d49542017-06-26 16:27:32 -0700768 return START_ABORTED;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800769 }
770
771 // If permissions need a review before any of the app components can run, we
772 // launch the review activity and pass a pending intent to start the activity
773 // we are to launching now after the review is completed.
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700774 if (mService.mAm.mPermissionReviewRequired && aInfo != null) {
775 if (mService.mAm.getPackageManagerInternalLocked().isPermissionsReviewRequired(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800776 aInfo.packageName, userId)) {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700777 IIntentSender target = mService.mAm.getIntentSenderLocked(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800778 ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
779 callingUid, userId, null, null, 0, new Intent[]{intent},
780 new String[]{resolvedType}, PendingIntent.FLAG_CANCEL_CURRENT
781 | PendingIntent.FLAG_ONE_SHOT, null);
782
783 final int flags = intent.getFlags();
784 Intent newIntent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
785 newIntent.setFlags(flags
786 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
787 newIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, aInfo.packageName);
788 newIntent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target));
789 if (resultRecord != null) {
790 newIntent.putExtra(Intent.EXTRA_RESULT_NEEDED, true);
791 }
792 intent = newIntent;
793
794 resolvedType = null;
795 callingUid = realCallingUid;
796 callingPid = realCallingPid;
797
Svet Ganovcbcbf662018-05-10 17:25:29 -0700798 rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0,
Patrick Baumann31426b22018-05-21 13:46:40 -0700799 computeResolveFilterUid(
800 callingUid, realCallingUid, mRequest.filterCallingUid));
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800801 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
802 null /*profilerInfo*/);
803
804 if (DEBUG_PERMISSIONS_REVIEW) {
805 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true,
806 true, false) + "} from uid " + callingUid + " on display "
Andrii Kulian94e82d9b02017-07-13 15:33:06 -0700807 + (mSupervisor.mFocusedStack == null
808 ? DEFAULT_DISPLAY : mSupervisor.mFocusedStack.mDisplayId));
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800809 }
810 }
811 }
812
813 // If we have an ephemeral app, abort the process of launching the resolved intent.
814 // Instead, launch the ephemeral installer. Once the installer is finished, it
815 // starts either the intent we resolved here [on install error] or the ephemeral
816 // app [on install success].
Patrick Baumanna89a1722018-02-07 15:26:52 -0800817 if (rInfo != null && rInfo.auxiliaryInfo != null) {
Todd Kennedye9910222017-02-21 16:00:11 -0800818 intent = createLaunchIntent(rInfo.auxiliaryInfo, ephemeralIntent,
Chad Brubaker06068612017-04-06 09:43:47 -0700819 callingPackage, verificationBundle, resolvedType, userId);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800820 resolvedType = null;
821 callingUid = realCallingUid;
822 callingPid = realCallingPid;
823
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800824 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
825 }
826
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700827 ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid,
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700828 callingUid,
Wale Ogunwalef6733932018-06-27 05:14:34 -0700829 callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800830 resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100831 mSupervisor, checkedOptions, sourceRecord);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800832 if (outActivity != null) {
833 outActivity[0] = r;
834 }
835
836 if (r.appTimeTracker == null && sourceRecord != null) {
837 // If the caller didn't specify an explicit time tracker, we want to continue
838 // tracking under any it has.
839 r.appTimeTracker = sourceRecord.appTimeTracker;
840 }
841
842 final ActivityStack stack = mSupervisor.mFocusedStack;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100843
844 // If we are starting an activity that is not from the same uid as the currently resumed
845 // one, check whether app switches are allowed.
Bryce Leec4ab62a2018-03-05 14:19:26 -0800846 if (voiceSession == null && (stack.getResumedActivity() == null
847 || stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700848 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800849 realCallingPid, realCallingUid, "Activity start")) {
Bryce Leed3624e12017-11-30 08:51:45 -0800850 mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700851 sourceRecord, startFlags, stack, callerWpc));
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100852 ActivityOptions.abort(checkedOptions);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800853 return ActivityManager.START_SWITCHES_CANCELED;
854 }
855 }
856
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700857 mService.onStartActivitySetDidAppSwitch();
Bryce Leed3624e12017-11-30 08:51:45 -0800858 mController.doPendingActivityLaunches(false);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800859
Bryce Leedaa91e42017-12-06 14:13:01 -0800860 return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100861 true /* doResume */, checkedOptions, inTask, outActivity);
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -0800862 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800863
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100864
Bryce Leeaa5e8c32017-03-01 16:01:06 -0800865 /**
866 * Creates a launch intent for the given auxiliary resolution data.
867 */
Patrick Baumann577d4022018-01-31 16:55:10 +0000868 private @NonNull Intent createLaunchIntent(@Nullable AuxiliaryResolveInfo auxiliaryResponse,
Chad Brubaker06068612017-04-06 09:43:47 -0700869 Intent originalIntent, String callingPackage, Bundle verificationBundle,
870 String resolvedType, int userId) {
Patrick Baumann577d4022018-01-31 16:55:10 +0000871 if (auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo) {
Todd Kennedye9910222017-02-21 16:00:11 -0800872 // request phase two resolution
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700873 mService.mAm.getPackageManagerInternalLocked().requestInstantAppResolutionPhaseTwo(
Chad Brubaker06068612017-04-06 09:43:47 -0700874 auxiliaryResponse, originalIntent, resolvedType, callingPackage,
875 verificationBundle, userId);
Todd Kennedye9910222017-02-21 16:00:11 -0800876 }
Todd Kennedydfc27c62017-05-17 15:32:10 -0700877 return InstantAppResolver.buildEphemeralInstallerIntent(
Patrick Baumann577d4022018-01-31 16:55:10 +0000878 originalIntent,
879 InstantAppResolver.sanitizeIntent(originalIntent),
880 auxiliaryResponse == null ? null : auxiliaryResponse.failureIntent,
881 callingPackage,
882 verificationBundle,
883 resolvedType,
884 userId,
885 auxiliaryResponse == null ? null : auxiliaryResponse.installFailureActivity,
886 auxiliaryResponse == null ? null : auxiliaryResponse.token,
887 auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo,
888 auxiliaryResponse == null ? null : auxiliaryResponse.filters);
Todd Kennedye9910222017-02-21 16:00:11 -0800889 }
890
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700891 void postStartActivityProcessing(ActivityRecord r, int result, ActivityStack targetStack) {
Bryce Lee7f936862017-05-09 15:33:18 -0700892 if (ActivityManager.isStartResultFatalError(result)) {
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -0800893 return;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800894 }
Filip Gruszczynski303210b2016-01-08 16:28:08 -0800895
Chong Zhang5022da32016-06-21 16:31:37 -0700896 // We're waiting for an activity launch to finish, but that activity simply
Bryce Lee5f0e28f2018-01-30 16:00:03 -0800897 // brought another activity to front. We must also handle the case where the task is already
898 // in the front as a result of the trampoline activity being in the same task (it will be
899 // considered focused as the trampoline will be finished). Let startActivityMayWait() know
900 // about this, so it waits for the new activity to become visible instead.
901 mSupervisor.reportWaitingActivityLaunchedIfNeeded(r, result);
Chong Zhang5022da32016-06-21 16:31:37 -0700902
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700903 ActivityStack startedActivityStack = null;
Andrii Kulian02b7a832016-10-06 23:11:56 -0700904 final ActivityStack currentStack = r.getStack();
905 if (currentStack != null) {
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700906 startedActivityStack = currentStack;
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -0800907 } else if (mTargetStack != null) {
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700908 startedActivityStack = targetStack;
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -0800909 }
910
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700911 if (startedActivityStack == null) {
912 return;
913 }
914
Wale Ogunwaleac36e4d2017-11-29 13:30:26 -0800915 final int clearTaskFlags = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK;
916 boolean clearedTask = (mLaunchFlags & clearTaskFlags) == clearTaskFlags
917 && mReuseTask != null;
Wale Ogunwale7d7973a2018-04-05 10:25:59 -0700918 if (result == START_TASK_TO_FRONT || result == START_DELIVERED_TO_TOP || clearedTask) {
919 // The activity was already running so it wasn't started, but either brought to the
920 // front or the new intent was delivered to it since it was already in front. Notify
921 // anyone interested in this piece of information.
922 switch (startedActivityStack.getWindowingMode()) {
923 case WINDOWING_MODE_PINNED:
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700924 mService.getTaskChangeNotificationController().notifyPinnedActivityRestartAttempt(
Wale Ogunwale7d7973a2018-04-05 10:25:59 -0700925 clearedTask);
926 break;
927 case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
928 final ActivityStack homeStack = mSupervisor.mHomeStack;
929 if (homeStack != null && homeStack.shouldBeVisible(null /* starting */)) {
930 mService.mWindowManager.showRecentApps();
931 }
932 break;
933 }
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -0800934 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800935 }
936
Bryce Lee4c9a5972017-12-01 22:14:24 -0800937 private int startActivityMayWait(IApplicationThread caller, int callingUid,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800938 String callingPackage, Intent intent, String resolvedType,
939 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
940 IBinder resultTo, String resultWho, int requestCode, int startFlags,
Sudheer Shankafc46e9b2016-10-21 17:55:27 -0700941 ProfilerInfo profilerInfo, WaitResult outResult,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100942 Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200943 int userId, TaskRecord inTask, String reason,
944 boolean allowPendingRemoteAnimationRegistryLookup) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800945 // Refuse possible leaked file descriptors
946 if (intent != null && intent.hasFileDescriptors()) {
947 throw new IllegalArgumentException("File descriptors passed in Intent");
948 }
Bryce Lee2a3cc462017-10-27 10:57:35 -0700949 mSupervisor.getActivityMetricsLogger().notifyActivityLaunching();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800950 boolean componentSpecified = intent.getComponent() != null;
951
Makoto Onuki1a342742018-04-26 14:56:59 -0700952 final int realCallingPid = Binder.getCallingPid();
953 final int realCallingUid = Binder.getCallingUid();
954
Svet Ganovcbcbf662018-05-10 17:25:29 -0700955 int callingPid;
956 if (callingUid >= 0) {
957 callingPid = -1;
958 } else if (caller == null) {
959 callingPid = realCallingPid;
960 callingUid = realCallingUid;
961 } else {
962 callingPid = callingUid = -1;
963 }
964
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800965 // Save a copy in case ephemeral needs it
966 final Intent ephemeralIntent = new Intent(intent);
967 // Don't modify the client's object!
968 intent = new Intent(intent);
Todd Kennedyb21be122017-03-24 14:10:01 -0700969 if (componentSpecified
Patrick Baumann531db462018-02-13 13:01:47 -0800970 && !(Intent.ACTION_VIEW.equals(intent.getAction()) && intent.getData() == null)
Patrick Baumann577d4022018-01-31 16:55:10 +0000971 && !Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE.equals(intent.getAction())
972 && !Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE.equals(intent.getAction())
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700973 && mService.mAm.getPackageManagerInternalLocked()
Todd Kennedyb21be122017-03-24 14:10:01 -0700974 .isInstantAppInstallerComponent(intent.getComponent())) {
975 // intercept intents targeted directly to the ephemeral installer the
Patrick Baumann577d4022018-01-31 16:55:10 +0000976 // ephemeral installer should never be started with a raw Intent; instead
Todd Kennedyb21be122017-03-24 14:10:01 -0700977 // adjust the intent so it looks like a "normal" instant app launch
978 intent.setComponent(null /*component*/);
979 componentSpecified = false;
980 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800981
Makoto Onuki1a342742018-04-26 14:56:59 -0700982 ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
Patrick Baumann31426b22018-05-21 13:46:40 -0700983 0 /* matchFlags */,
984 computeResolveFilterUid(
985 callingUid, realCallingUid, mRequest.filterCallingUid));
Kenny Guyb1b30262016-02-09 16:02:35 +0000986 if (rInfo == null) {
987 UserInfo userInfo = mSupervisor.getUserInfo(userId);
988 if (userInfo != null && userInfo.isManagedProfile()) {
989 // Special case for managed profiles, if attempting to launch non-cryto aware
990 // app in a locked managed profile from an unlocked parent allow it to resolve
991 // as user will be sent via confirm credentials to unlock the profile.
992 UserManager userManager = UserManager.get(mService.mContext);
Fyodor Kupolovce4db0a2016-05-11 14:21:18 -0700993 boolean profileLockedAndParentUnlockingOrUnlocked = false;
Tony Mak13436452016-02-24 11:08:38 +0000994 long token = Binder.clearCallingIdentity();
995 try {
Fyodor Kupolovce4db0a2016-05-11 14:21:18 -0700996 UserInfo parent = userManager.getProfileParent(userId);
997 profileLockedAndParentUnlockingOrUnlocked = (parent != null)
998 && userManager.isUserUnlockingOrUnlocked(parent.id)
999 && !userManager.isUserUnlockingOrUnlocked(userId);
Tony Mak13436452016-02-24 11:08:38 +00001000 } finally {
1001 Binder.restoreCallingIdentity(token);
1002 }
Fyodor Kupolovce4db0a2016-05-11 14:21:18 -07001003 if (profileLockedAndParentUnlockingOrUnlocked) {
Kenny Guyb1b30262016-02-09 16:02:35 +00001004 rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
Jeff Sharkey8a372a02016-03-16 16:25:45 -06001005 PackageManager.MATCH_DIRECT_BOOT_AWARE
Patrick Baumann78380272018-04-04 10:41:01 -07001006 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
Patrick Baumann31426b22018-05-21 13:46:40 -07001007 computeResolveFilterUid(
1008 callingUid, realCallingUid, mRequest.filterCallingUid));
Kenny Guyb1b30262016-02-09 16:02:35 +00001009 }
1010 }
1011 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001012 // Collect information about the target of the Intent.
1013 ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
1014
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001015 synchronized (mService.mGlobalLock) {
Andrii Kulian94e82d9b02017-07-13 15:33:06 -07001016 final ActivityStack stack = mSupervisor.mFocusedStack;
Andrii Kulian8072d112016-09-16 11:11:01 -07001017 stack.mConfigWillChange = globalConfig != null
Wale Ogunwalef6733932018-06-27 05:14:34 -07001018 && mService.getGlobalConfiguration().diff(globalConfig) != 0;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001019 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
1020 "Starting activity when config will change = " + stack.mConfigWillChange);
1021
1022 final long origId = Binder.clearCallingIdentity();
1023
1024 if (aInfo != null &&
1025 (aInfo.applicationInfo.privateFlags
Dianne Hackbornc8e4fad2018-05-04 11:31:09 -07001026 & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0 &&
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001027 mService.mAm.mHasHeavyWeightFeature) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001028 // This may be a heavy-weight process! Check to see if we already
1029 // have another, different heavy-weight process running.
1030 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001031 final ProcessRecord heavy = mService.mAm.mHeavyWeightProcess;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001032 if (heavy != null && (heavy.info.uid != aInfo.applicationInfo.uid
1033 || !heavy.processName.equals(aInfo.processName))) {
1034 int appCallingUid = callingUid;
1035 if (caller != null) {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001036 ProcessRecord callerApp = mService.mAm.getRecordForAppLocked(caller);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001037 if (callerApp != null) {
1038 appCallingUid = callerApp.info.uid;
1039 } else {
1040 Slog.w(TAG, "Unable to find app for caller " + caller
1041 + " (pid=" + callingPid + ") when starting: "
1042 + intent.toString());
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001043 SafeActivityOptions.abort(options);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001044 return ActivityManager.START_PERMISSION_DENIED;
1045 }
1046 }
1047
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001048 IIntentSender target = mService.mAm.getIntentSenderLocked(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001049 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
1050 appCallingUid, userId, null, null, 0, new Intent[] { intent },
1051 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
1052 | PendingIntent.FLAG_ONE_SHOT, null);
1053
1054 Intent newIntent = new Intent();
1055 if (requestCode >= 0) {
1056 // Caller is requesting a result.
1057 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
1058 }
1059 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
1060 new IntentSender(target));
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001061 heavy.getWindowProcessController().updateIntentForHeavyWeightActivity(
1062 newIntent);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001063 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
1064 aInfo.packageName);
1065 newIntent.setFlags(intent.getFlags());
1066 newIntent.setClassName("android",
1067 HeavyWeightSwitcherActivity.class.getName());
1068 intent = newIntent;
1069 resolvedType = null;
1070 caller = null;
1071 callingUid = Binder.getCallingUid();
1072 callingPid = Binder.getCallingPid();
1073 componentSpecified = true;
Makoto Onuki1a342742018-04-26 14:56:59 -07001074 rInfo = mSupervisor.resolveIntent(intent, null /*resolvedType*/, userId,
Patrick Baumann31426b22018-05-21 13:46:40 -07001075 0 /* matchFlags */, computeResolveFilterUid(
1076 callingUid, realCallingUid, mRequest.filterCallingUid));
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001077 aInfo = rInfo != null ? rInfo.activityInfo : null;
1078 if (aInfo != null) {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001079 aInfo = mService.mAm.getActivityInfoForUser(aInfo, userId);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001080 }
1081 }
1082 }
1083 }
1084
Jorim Jaggi275561a2016-02-23 10:11:02 -05001085 final ActivityRecord[] outRecord = new ActivityRecord[1];
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001086 int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
1087 voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
1088 callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +02001089 ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
1090 allowPendingRemoteAnimationRegistryLookup);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001091
1092 Binder.restoreCallingIdentity(origId);
1093
1094 if (stack.mConfigWillChange) {
1095 // If the caller also wants to switch to a new configuration,
1096 // do so now. This allows a clean switch, as we are waiting
1097 // for the current activity to pause (so we will not destroy
1098 // it), and have not yet started the next activity.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001099 mService.mAmInternal.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001100 "updateConfiguration()");
1101 stack.mConfigWillChange = false;
1102 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
1103 "Updating to new configuration after starting activity.");
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001104 mService.updateConfigurationLocked(globalConfig, null, false);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001105 }
1106
1107 if (outResult != null) {
1108 outResult.result = res;
Bryce Lee4a194382017-04-04 14:32:48 -07001109
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001110 final ActivityRecord r = outRecord[0];
1111
1112 switch(res) {
1113 case START_SUCCESS: {
1114 mSupervisor.mWaitingActivityLaunched.add(outResult);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001115 do {
1116 try {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001117 mService.mGlobalLock.wait();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001118 } catch (InterruptedException e) {
1119 }
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001120 } while (outResult.result != START_TASK_TO_FRONT
1121 && !outResult.timeout && outResult.who == null);
1122 if (outResult.result == START_TASK_TO_FRONT) {
1123 res = START_TASK_TO_FRONT;
1124 }
1125 break;
1126 }
1127 case START_DELIVERED_TO_TOP: {
1128 outResult.timeout = false;
1129 outResult.who = r.realActivity;
1130 outResult.totalTime = 0;
1131 outResult.thisTime = 0;
1132 break;
1133 }
1134 case START_TASK_TO_FRONT: {
1135 // ActivityRecord may represent a different activity, but it should not be
1136 // in the resumed state.
Bryce Lee7ace3952018-02-16 14:34:32 -08001137 if (r.nowVisible && r.isState(RESUMED)) {
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001138 outResult.timeout = false;
1139 outResult.who = r.realActivity;
1140 outResult.totalTime = 0;
1141 outResult.thisTime = 0;
1142 } else {
1143 outResult.thisTime = SystemClock.uptimeMillis();
1144 mSupervisor.waitActivityVisible(r.realActivity, outResult);
1145 // Note: the timeout variable is not currently not ever set.
1146 do {
1147 try {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001148 mService.mGlobalLock.wait();
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001149 } catch (InterruptedException e) {
1150 }
1151 } while (!outResult.timeout && outResult.who == null);
1152 }
1153 break;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001154 }
1155 }
1156 }
1157
Bryce Lee2a3cc462017-10-27 10:57:35 -07001158 mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outRecord[0]);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001159 return res;
1160 }
1161 }
1162
Svet Ganovcbcbf662018-05-10 17:25:29 -07001163 /**
1164 * Compute the logical UID based on which the package manager would filter
1165 * app components i.e. based on which the instant app policy would be applied
1166 * because it is the logical calling UID.
1167 *
1168 * @param customCallingUid The UID on whose behalf to make the call.
1169 * @param actualCallingUid The UID actually making the call.
Patrick Baumann31426b22018-05-21 13:46:40 -07001170 * @param filterCallingUid The UID to be used to filter for instant apps.
Svet Ganovcbcbf662018-05-10 17:25:29 -07001171 * @return The logical UID making the call.
1172 */
Patrick Baumann31426b22018-05-21 13:46:40 -07001173 static int computeResolveFilterUid(int customCallingUid, int actualCallingUid,
1174 int filterCallingUid) {
1175 return filterCallingUid != UserHandle.USER_NULL
1176 ? filterCallingUid
1177 : (customCallingUid >= 0 ? customCallingUid : actualCallingUid);
Svet Ganovcbcbf662018-05-10 17:25:29 -07001178 }
1179
Bryce Leedaa91e42017-12-06 14:13:01 -08001180 private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
1181 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1182 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
1183 ActivityRecord[] outActivity) {
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001184 int result = START_CANCELED;
1185 try {
1186 mService.mWindowManager.deferSurfaceLayout();
1187 result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
Bryce Lee4a194382017-04-04 14:32:48 -07001188 startFlags, doResume, options, inTask, outActivity);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001189 } finally {
1190 // If we are not able to proceed, disassociate the activity from the task. Leaving an
1191 // activity in an incomplete state can lead to issues, such as performing operations
1192 // without a window container.
Bryce Lee2b8e0372018-04-05 17:01:37 -07001193 final ActivityStack stack = mStartActivity.getStack();
1194 if (!ActivityManager.isStartResultSuccessful(result) && stack != null) {
1195 stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,
1196 null /* intentResultData */, "startActivity", true /* oomAdj */);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001197 }
1198 mService.mWindowManager.continueSurfaceLayout();
1199 }
1200
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001201 postStartActivityProcessing(r, result, mTargetStack);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001202
1203 return result;
1204 }
1205
1206 // Note: This method should only be called from {@link startActivity}.
Wale Ogunwale01d66562015-12-29 08:19:19 -08001207 private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
1208 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
Bryce Lee4a194382017-04-04 14:32:48 -07001209 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
1210 ActivityRecord[] outActivity) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001211
1212 setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
1213 voiceInteractor);
1214
1215 computeLaunchingTaskFlags();
1216
1217 computeSourceStack();
1218
1219 mIntent.setFlags(mLaunchFlags);
1220
Bryce Lee4a194382017-04-04 14:32:48 -07001221 ActivityRecord reusedActivity = getReusableIntentActivity();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001222
Wale Ogunwale0568aed2017-09-08 13:29:37 -07001223 int preferredWindowingMode = WINDOWING_MODE_UNDEFINED;
1224 int preferredLaunchDisplayId = DEFAULT_DISPLAY;
1225 if (mOptions != null) {
1226 preferredWindowingMode = mOptions.getLaunchWindowingMode();
1227 preferredLaunchDisplayId = mOptions.getLaunchDisplayId();
1228 }
Jorim Jaggi2adba072016-03-03 13:43:39 +01001229
Bryce Leeec55eb02017-12-05 20:51:27 -08001230 // windowing mode and preferred launch display values from {@link LaunchParams} take
1231 // priority over those specified in {@link ActivityOptions}.
1232 if (!mLaunchParams.isEmpty()) {
1233 if (mLaunchParams.hasPreferredDisplay()) {
1234 preferredLaunchDisplayId = mLaunchParams.mPreferredDisplayId;
1235 }
1236
1237 if (mLaunchParams.hasWindowingMode()) {
1238 preferredWindowingMode = mLaunchParams.mWindowingMode;
1239 }
1240 }
1241
Bryce Lee4a194382017-04-04 14:32:48 -07001242 if (reusedActivity != null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001243 // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but
1244 // still needs to be a lock task mode violation since the task gets cleared out and
1245 // the device would otherwise leave the locked task.
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001246 if (mService.getLockTaskController().isLockTaskModeViolation(reusedActivity.getTask(),
Wale Ogunwale01d66562015-12-29 08:19:19 -08001247 (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1248 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001249 Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
1250 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
1251 }
1252
Bryce Leef65ee7e2018-03-26 16:03:47 -07001253 // True if we are clearing top and resetting of a standard (default) launch mode
1254 // ({@code LAUNCH_MULTIPLE}) activity. The existing activity will be finished.
1255 final boolean clearTopAndResetStandardLaunchMode =
1256 (mLaunchFlags & (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED))
1257 == (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
1258 && mLaunchMode == LAUNCH_MULTIPLE;
1259
1260 // If mStartActivity does not have a task associated with it, associate it with the
1261 // reused activity's task. Do not do so if we're clearing top and resetting for a
1262 // standard launchMode activity.
1263 if (mStartActivity.getTask() == null && !clearTopAndResetStandardLaunchMode) {
Bryce Lee4a194382017-04-04 14:32:48 -07001264 mStartActivity.setTask(reusedActivity.getTask());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001265 }
Bryce Leef65ee7e2018-03-26 16:03:47 -07001266
Bryce Lee4a194382017-04-04 14:32:48 -07001267 if (reusedActivity.getTask().intent == null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001268 // This task was started because of movement of the activity based on affinity...
1269 // Now that we are actually launching it, we can assign the base intent.
Bryce Lee4a194382017-04-04 14:32:48 -07001270 reusedActivity.getTask().setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001271 }
1272
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001273 // This code path leads to delivering a new intent, we want to make sure we schedule it
1274 // as the first operation, in case the activity will be resumed as a result of later
1275 // operations.
1276 if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
Daichi Hirono15a02992016-04-27 18:47:01 +09001277 || isDocumentLaunchesIntoExisting(mLaunchFlags)
Bryce Lee7daee392017-10-12 13:46:18 -07001278 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Bryce Lee4a194382017-04-04 14:32:48 -07001279 final TaskRecord task = reusedActivity.getTask();
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001280
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001281 // In this situation we want to remove all activities from the task up to the one
1282 // being started. In most cases this means we are resetting the task to its initial
1283 // state.
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001284 final ActivityRecord top = task.performClearTaskForReuseLocked(mStartActivity,
1285 mLaunchFlags);
1286
Bryce Lee4a194382017-04-04 14:32:48 -07001287 // The above code can remove {@code reusedActivity} from the task, leading to the
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001288 // the {@code ActivityRecord} removing its reference to the {@code TaskRecord}. The
1289 // task reference is needed in the call below to
1290 // {@link setTargetStackAndMoveToFrontIfNeeded}.
Bryce Lee4a194382017-04-04 14:32:48 -07001291 if (reusedActivity.getTask() == null) {
1292 reusedActivity.setTask(task);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001293 }
1294
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001295 if (top != null) {
1296 if (top.frontOfTask) {
1297 // Activity aliases may mean we use different intents for the top activity,
1298 // so make sure the task now has the identity of the new intent.
Bryce Leeaf691c02017-03-20 14:20:22 -07001299 top.getTask().setIntent(mStartActivity);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001300 }
Bryce Lee325e09682017-10-05 17:20:25 -07001301 deliverNewIntent(top);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001302 }
1303 }
1304
Bryce Leed3624e12017-11-30 08:51:45 -08001305 mSupervisor.sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, reusedActivity);
Wei Wang98f03f92016-05-18 11:32:52 -07001306
Bryce Lee4a194382017-04-04 14:32:48 -07001307 reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001308
Bryce Lee89cd19a2017-05-17 15:18:35 -07001309 final ActivityRecord outResult =
1310 outActivity != null && outActivity.length > 0 ? outActivity[0] : null;
1311
1312 // When there is a reused activity and the current result is a trampoline activity,
1313 // set the reused activity as the result.
1314 if (outResult != null && (outResult.finishing || outResult.noDisplay)) {
1315 outActivity[0] = reusedActivity;
1316 }
1317
Wale Ogunwale01d66562015-12-29 08:19:19 -08001318 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1319 // We don't need to start a new activity, and the client said not to do anything
1320 // if that is the case, so this is it! And for paranoia, make sure we have
1321 // correctly resumed the top activity.
1322 resumeTargetStackIfNeeded();
1323 return START_RETURN_INTENT_TO_CALLER;
1324 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001325
Bryce Leef65ee7e2018-03-26 16:03:47 -07001326 if (reusedActivity != null) {
1327 setTaskFromIntentActivity(reusedActivity);
1328
1329 if (!mAddingToTask && mReuseTask == null) {
1330 // We didn't do anything... but it was needed (a.k.a., client don't use that
1331 // intent!) And for paranoia, make sure we have correctly resumed the top activity.
1332
1333 resumeTargetStackIfNeeded();
1334 if (outActivity != null && outActivity.length > 0) {
1335 outActivity[0] = reusedActivity;
1336 }
1337
1338 return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP;
Jorim Jaggicdfc04e2017-04-28 19:06:24 +02001339 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001340 }
1341 }
1342
1343 if (mStartActivity.packageName == null) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001344 final ActivityStack sourceStack = mStartActivity.resultTo != null
1345 ? mStartActivity.resultTo.getStack() : null;
1346 if (sourceStack != null) {
1347 sourceStack.sendActivityResultLocked(-1 /* callingUid */, mStartActivity.resultTo,
1348 mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,
1349 null /* data */);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001350 }
1351 ActivityOptions.abort(mOptions);
1352 return START_CLASS_NOT_FOUND;
1353 }
1354
1355 // If the activity being launched is the same as the one currently at the top, then
1356 // we need to check if it should only be launched once.
1357 final ActivityStack topStack = mSupervisor.mFocusedStack;
Wale Ogunwale30e441d2017-11-09 08:28:45 -08001358 final ActivityRecord topFocused = topStack.getTopActivity();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001359 final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
1360 final boolean dontStart = top != null && mStartActivity.resultTo == null
1361 && top.realActivity.equals(mStartActivity.realActivity)
1362 && top.userId == mStartActivity.userId
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001363 && top.attachedToProcess()
Wale Ogunwale01d66562015-12-29 08:19:19 -08001364 && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
Bryce Lee7daee392017-10-12 13:46:18 -07001365 || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK));
Wale Ogunwale01d66562015-12-29 08:19:19 -08001366 if (dontStart) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001367 // For paranoia, make sure we have correctly resumed the top activity.
1368 topStack.mLastPausedActivity = null;
1369 if (mDoResume) {
1370 mSupervisor.resumeFocusedStackTopActivityLocked();
1371 }
1372 ActivityOptions.abort(mOptions);
1373 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1374 // We don't need to start a new activity, and the client said not to do
1375 // anything if that is the case, so this is it!
1376 return START_RETURN_INTENT_TO_CALLER;
1377 }
Bryce Lee325e09682017-10-05 17:20:25 -07001378
1379 deliverNewIntent(top);
Chong Zhangd44063c2016-04-08 11:52:30 -07001380
1381 // Don't use mStartActivity.task to show the toast. We're not starting a new activity
1382 // but reusing 'top'. Fields in mStartActivity may not be fully initialized.
Wale Ogunwale0568aed2017-09-08 13:29:37 -07001383 mSupervisor.handleNonResizableTaskIfNeeded(top.getTask(), preferredWindowingMode,
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07001384 preferredLaunchDisplayId, topStack);
Chong Zhangd44063c2016-04-08 11:52:30 -07001385
Wale Ogunwale01d66562015-12-29 08:19:19 -08001386 return START_DELIVERED_TO_TOP;
1387 }
1388
1389 boolean newTask = false;
1390 final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
Bryce Leeaf691c02017-03-20 14:20:22 -07001391 ? mSourceRecord.getTask() : null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001392
1393 // Should this be considered a new task?
Chong Zhang6cda19c2016-06-14 19:07:56 -07001394 int result = START_SUCCESS;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001395 if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
1396 && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1397 newTask = true;
Wale Ogunwale0568aed2017-09-08 13:29:37 -07001398 result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, topStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001399 } else if (mSourceRecord != null) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07001400 result = setTaskFromSourceRecord();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001401 } else if (mInTask != null) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07001402 result = setTaskFromInTask();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001403 } else {
1404 // This not being started from an existing activity, and not part of a new task...
1405 // just put it in the top task, though these days this case should never happen.
1406 setTaskToCurrentTopOrCreateNewTask();
1407 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07001408 if (result != START_SUCCESS) {
1409 return result;
1410 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001411
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001412 mService.mAm.grantUriPermissionFromIntentLocked(mCallingUid, mStartActivity.packageName,
Wale Ogunwale01d66562015-12-29 08:19:19 -08001413 mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.userId);
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001414 mService.mAm.grantEphemeralAccessLocked(mStartActivity.userId, mIntent,
Todd Kennedy0e989d02017-01-13 14:15:36 -08001415 mStartActivity.appInfo.uid, UserHandle.getAppId(mCallingUid));
Wale Ogunwale01d66562015-12-29 08:19:19 -08001416 if (newTask) {
Wale Ogunwale66e16852017-10-19 13:35:52 -07001417 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, mStartActivity.userId,
Bryce Leeaf691c02017-03-20 14:20:22 -07001418 mStartActivity.getTask().taskId);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001419 }
1420 ActivityStack.logStartActivity(
Bryce Leeaf691c02017-03-20 14:20:22 -07001421 EventLogTags.AM_CREATE_ACTIVITY, mStartActivity, mStartActivity.getTask());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001422 mTargetStack.mLastPausedActivity = null;
Wei Wang98f03f92016-05-18 11:32:52 -07001423
Bryce Leed3624e12017-11-30 08:51:45 -08001424 mSupervisor.sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, mStartActivity);
Wei Wang98f03f92016-05-18 11:32:52 -07001425
Winson Chungb5c41b72016-12-07 15:00:47 -08001426 mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
1427 mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001428 if (mDoResume) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001429 final ActivityRecord topTaskActivity =
1430 mStartActivity.getTask().topRunningActivityLocked();
Wale Ogunwale3b232392016-05-13 15:37:13 -07001431 if (!mTargetStack.isFocusable()
Wale Ogunwale68741142016-05-17 09:40:02 -07001432 || (topTaskActivity != null && topTaskActivity.mTaskOverlay
1433 && mStartActivity != topTaskActivity)) {
Filip Gruszczynski3d7fdc12016-01-31 17:33:29 -08001434 // If the activity is not focusable, we can't resume it, but still would like to
1435 // make sure it becomes visible as it starts (this will also trigger entry
1436 // animation). An example of this are PIP activities.
Wale Ogunwale3b232392016-05-13 15:37:13 -07001437 // Also, we don't want to resume activities in a task that currently has an overlay
1438 // as the starting activity just needs to be in the visible paused state until the
1439 // over is removed.
Wale Ogunwale480dca02016-02-06 13:58:29 -08001440 mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Wale Ogunwaleae846f42016-02-22 14:00:56 -08001441 // Go ahead and tell window manager to execute app transition for this activity
1442 // since the app transition will not be triggered through the resume channel.
Bryce Lee7daee392017-10-12 13:46:18 -07001443 mService.mWindowManager.executeAppTransition();
Wale Ogunwale3b232392016-05-13 15:37:13 -07001444 } else {
Winson Chung32066032016-11-04 11:55:21 -07001445 // If the target stack was not previously focusable (previous top running activity
1446 // on that stack was not visible) then any prior calls to move the stack to the
1447 // will not update the focused stack. If starting the new activity now allows the
1448 // task stack to be focusable, then ensure that we now update the focused stack
1449 // accordingly.
1450 if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
1451 mTargetStack.moveToFront("startActivityUnchecked");
1452 }
Wale Ogunwale3b232392016-05-13 15:37:13 -07001453 mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
1454 mOptions);
Filip Gruszczynski3d7fdc12016-01-31 17:33:29 -08001455 }
Winson Chung1dbc8112017-09-28 18:05:31 -07001456 } else if (mStartActivity != null) {
1457 mSupervisor.mRecentTasks.add(mStartActivity.getTask());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001458 }
1459 mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);
1460
Wale Ogunwale0568aed2017-09-08 13:29:37 -07001461 mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(), preferredWindowingMode,
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07001462 preferredLaunchDisplayId, mTargetStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001463
1464 return START_SUCCESS;
1465 }
1466
Bryce Leedaa91e42017-12-06 14:13:01 -08001467 /**
1468 * Resets the {@link ActivityStarter} state.
1469 * @param clearRequest whether the request should be reset to default values.
1470 */
1471 void reset(boolean clearRequest) {
1472 mStartActivity = null;
1473 mIntent = null;
1474 mCallingUid = -1;
1475 mOptions = null;
1476
1477 mLaunchTaskBehind = false;
1478 mLaunchFlags = 0;
1479 mLaunchMode = INVALID_LAUNCH_MODE;
1480
Bryce Leeec55eb02017-12-05 20:51:27 -08001481 mLaunchParams.reset();
Bryce Leedaa91e42017-12-06 14:13:01 -08001482
1483 mNotTop = null;
1484 mDoResume = false;
1485 mStartFlags = 0;
1486 mSourceRecord = null;
1487 mPreferredDisplayId = INVALID_DISPLAY;
1488
1489 mInTask = null;
1490 mAddingToTask = false;
1491 mReuseTask = null;
1492
1493 mNewTaskInfo = null;
1494 mNewTaskIntent = null;
1495 mSourceStack = null;
1496
1497 mTargetStack = null;
1498 mMovedToFront = false;
1499 mNoAnimation = false;
1500 mKeepCurTransition = false;
1501 mAvoidMoveToFront = false;
1502
1503 mVoiceSession = null;
1504 mVoiceInteractor = null;
1505
1506 mIntentDelivered = false;
1507
1508 if (clearRequest) {
1509 mRequest.reset();
1510 }
1511 }
1512
Wale Ogunwale01d66562015-12-29 08:19:19 -08001513 private void setInitialState(ActivityRecord r, ActivityOptions options, TaskRecord inTask,
1514 boolean doResume, int startFlags, ActivityRecord sourceRecord,
1515 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
Bryce Leedaa91e42017-12-06 14:13:01 -08001516 reset(false /* clearRequest */);
1517
Wale Ogunwale01d66562015-12-29 08:19:19 -08001518 mStartActivity = r;
1519 mIntent = r.intent;
1520 mOptions = options;
1521 mCallingUid = r.launchedFromUid;
1522 mSourceRecord = sourceRecord;
1523 mVoiceSession = voiceSession;
1524 mVoiceInteractor = voiceInteractor;
1525
David Stevense5a7b642017-05-22 13:18:23 -07001526 mPreferredDisplayId = getPreferedDisplayId(mSourceRecord, mStartActivity, options);
David Stevensc6b91c62017-02-08 14:23:58 -08001527
Bryce Leeec55eb02017-12-05 20:51:27 -08001528 mLaunchParams.reset();
Bryce Leedacefc42017-10-10 12:56:02 -07001529
Bryce Leeec55eb02017-12-05 20:51:27 -08001530 mSupervisor.getLaunchParamsController().calculate(inTask, null /*layout*/, r, sourceRecord,
1531 options, mLaunchParams);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001532
Bryce Lee7daee392017-10-12 13:46:18 -07001533 mLaunchMode = r.launchMode;
1534
Wale Ogunwale01d66562015-12-29 08:19:19 -08001535 mLaunchFlags = adjustLaunchFlagsToDocumentMode(
Bryce Lee7daee392017-10-12 13:46:18 -07001536 r, LAUNCH_SINGLE_INSTANCE == mLaunchMode,
1537 LAUNCH_SINGLE_TASK == mLaunchMode, mIntent.getFlags());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001538 mLaunchTaskBehind = r.mLaunchTaskBehind
Bryce Lee7daee392017-10-12 13:46:18 -07001539 && !isLaunchModeOneOf(LAUNCH_SINGLE_TASK, LAUNCH_SINGLE_INSTANCE)
Wale Ogunwale01d66562015-12-29 08:19:19 -08001540 && (mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0;
1541
1542 sendNewTaskResultRequestIfNeeded();
1543
1544 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
1545 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1546 }
1547
1548 // If we are actually going to launch in to a new task, there are some cases where
1549 // we further want to do multiple task.
1550 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1551 if (mLaunchTaskBehind
1552 || r.info.documentLaunchMode == DOCUMENT_LAUNCH_ALWAYS) {
1553 mLaunchFlags |= FLAG_ACTIVITY_MULTIPLE_TASK;
1554 }
1555 }
1556
1557 // We'll invoke onUserLeaving before onPause only if the launching
1558 // activity did not explicitly state that this is an automated launch.
1559 mSupervisor.mUserLeaving = (mLaunchFlags & FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1560 if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
1561 "startActivity() => mUserLeaving=" + mSupervisor.mUserLeaving);
1562
1563 // If the caller has asked not to resume at this point, we make note
1564 // of this in the record so that we can skip it when trying to find
1565 // the top running activity.
1566 mDoResume = doResume;
Chong Zhang87761972016-08-22 13:53:24 -07001567 if (!doResume || !r.okToShowLocked()) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001568 r.delayedResume = true;
1569 mDoResume = false;
1570 }
1571
Winson Chunge2d72172018-01-25 17:46:20 +00001572 if (mOptions != null) {
1573 if (mOptions.getLaunchTaskId() != -1 && mOptions.getTaskOverlay()) {
1574 r.mTaskOverlay = true;
1575 if (!mOptions.canTaskOverlayResume()) {
1576 final TaskRecord task = mSupervisor.anyTaskForIdLocked(
1577 mOptions.getLaunchTaskId());
1578 final ActivityRecord top = task != null ? task.getTopActivity() : null;
Bryce Lee7ace3952018-02-16 14:34:32 -08001579 if (top != null && !top.isState(RESUMED)) {
Jorim Jaggic875ae72016-04-26 22:41:06 -07001580
Winson Chunge2d72172018-01-25 17:46:20 +00001581 // The caller specifies that we'd like to be avoided to be moved to the
1582 // front, so be it!
1583 mDoResume = false;
1584 mAvoidMoveToFront = true;
1585 }
Winson Chungcbcadc92017-01-12 15:54:12 -08001586 }
Winson Chunge2d72172018-01-25 17:46:20 +00001587 } else if (mOptions.getAvoidMoveToFront()) {
Winson Chungba40d3a2018-05-16 09:40:16 -07001588 mDoResume = false;
Winson Chunge2d72172018-01-25 17:46:20 +00001589 mAvoidMoveToFront = true;
Jorim Jaggic875ae72016-04-26 22:41:06 -07001590 }
1591 }
1592
Wale Ogunwale01d66562015-12-29 08:19:19 -08001593 mNotTop = (mLaunchFlags & FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1594
1595 mInTask = inTask;
1596 // In some flows in to this function, we retrieve the task record and hold on to it
1597 // without a lock before calling back in to here... so the task at this point may
1598 // not actually be in recents. Check for that, and if it isn't in recents just
1599 // consider it invalid.
1600 if (inTask != null && !inTask.inRecents) {
1601 Slog.w(TAG, "Starting activity in task not in recents: " + inTask);
1602 mInTask = null;
1603 }
1604
1605 mStartFlags = startFlags;
1606 // If the onlyIfNeeded flag is set, then we can do this if the activity being launched
1607 // is the same as the one making the call... or, as a special case, if we do not know
1608 // the caller then we count the current top activity as the caller.
1609 if ((startFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1610 ActivityRecord checkedCaller = sourceRecord;
1611 if (checkedCaller == null) {
1612 checkedCaller = mSupervisor.mFocusedStack.topRunningNonDelayedActivityLocked(
1613 mNotTop);
1614 }
1615 if (!checkedCaller.realActivity.equals(r.realActivity)) {
1616 // Caller is not the same as launcher, so always needed.
1617 mStartFlags &= ~START_FLAG_ONLY_IF_NEEDED;
1618 }
1619 }
1620
1621 mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0;
1622 }
1623
1624 private void sendNewTaskResultRequestIfNeeded() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001625 final ActivityStack sourceStack = mStartActivity.resultTo != null
1626 ? mStartActivity.resultTo.getStack() : null;
1627 if (sourceStack != null && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001628 // For whatever reason this activity is being launched into a new task...
1629 // yet the caller has requested a result back. Well, that is pretty messed up,
1630 // so instead immediately send back a cancel and let the new task continue launched
1631 // as normal without a dependency on its originator.
1632 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
Andrii Kulian02b7a832016-10-06 23:11:56 -07001633 sourceStack.sendActivityResultLocked(-1 /* callingUid */, mStartActivity.resultTo,
1634 mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,
1635 null /* data */);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001636 mStartActivity.resultTo = null;
1637 }
1638 }
1639
1640 private void computeLaunchingTaskFlags() {
1641 // If the caller is not coming from another activity, but has given us an explicit task into
1642 // which they would like us to launch the new activity, then let's see about doing that.
Andrii Kulian02b7a832016-10-06 23:11:56 -07001643 if (mSourceRecord == null && mInTask != null && mInTask.getStack() != null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001644 final Intent baseIntent = mInTask.getBaseIntent();
1645 final ActivityRecord root = mInTask.getRootActivity();
1646 if (baseIntent == null) {
1647 ActivityOptions.abort(mOptions);
1648 throw new IllegalArgumentException("Launching into task without base intent: "
1649 + mInTask);
1650 }
1651
1652 // If this task is empty, then we are adding the first activity -- it
1653 // determines the root, and must be launching as a NEW_TASK.
Bryce Lee7daee392017-10-12 13:46:18 -07001654 if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001655 if (!baseIntent.getComponent().equals(mStartActivity.intent.getComponent())) {
1656 ActivityOptions.abort(mOptions);
1657 throw new IllegalArgumentException("Trying to launch singleInstance/Task "
1658 + mStartActivity + " into different task " + mInTask);
1659 }
1660 if (root != null) {
1661 ActivityOptions.abort(mOptions);
1662 throw new IllegalArgumentException("Caller with mInTask " + mInTask
1663 + " has root " + root + " but target is singleInstance/Task");
1664 }
1665 }
1666
1667 // If task is empty, then adopt the interesting intent launch flags in to the
1668 // activity being started.
1669 if (root == null) {
1670 final int flagsOfInterest = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK
1671 | FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS;
1672 mLaunchFlags = (mLaunchFlags & ~flagsOfInterest)
1673 | (baseIntent.getFlags() & flagsOfInterest);
1674 mIntent.setFlags(mLaunchFlags);
1675 mInTask.setIntent(mStartActivity);
1676 mAddingToTask = true;
1677
1678 // If the task is not empty and the caller is asking to start it as the root of
1679 // a new task, then we don't actually want to start this on the task. We will
1680 // bring the task to the front, and possibly give it a new intent.
1681 } else if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1682 mAddingToTask = false;
1683
1684 } else {
1685 mAddingToTask = true;
1686 }
1687
1688 mReuseTask = mInTask;
1689 } else {
1690 mInTask = null;
1691 // Launch ResolverActivity in the source task, so that it stays in the task bounds
1692 // when in freeform workspace.
1693 // Also put noDisplay activities in the source task. These by itself can be placed
1694 // in any task/stack, however it could launch other activities like ResolverActivity,
1695 // and we want those to stay in the original task.
1696 if ((mStartActivity.isResolverActivity() || mStartActivity.noDisplay) && mSourceRecord != null
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001697 && mSourceRecord.inFreeformWindowingMode()) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001698 mAddingToTask = true;
1699 }
1700 }
1701
1702 if (mInTask == null) {
1703 if (mSourceRecord == null) {
1704 // This activity is not being started from another... in this
1705 // case we -always- start a new task.
1706 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) {
1707 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1708 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
1709 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1710 }
1711 } else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) {
1712 // The original activity who is starting us is running as a single
1713 // instance... this new activity it is starting must go on its
1714 // own task.
1715 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
Bryce Lee7daee392017-10-12 13:46:18 -07001716 } else if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001717 // The activity being started is a single instance... it always
1718 // gets launched into its own task.
1719 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1720 }
1721 }
1722 }
1723
1724 private void computeSourceStack() {
1725 if (mSourceRecord == null) {
1726 mSourceStack = null;
1727 return;
1728 }
1729 if (!mSourceRecord.finishing) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001730 mSourceStack = mSourceRecord.getStack();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001731 return;
1732 }
1733
1734 // If the source is finishing, we can't further count it as our source. This is because the
1735 // task it is associated with may now be empty and on its way out, so we don't want to
1736 // blindly throw it in to that task. Instead we will take the NEW_TASK flow and try to find
1737 // a task for it. But save the task information so it can be used when creating the new task.
1738 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0) {
1739 Slog.w(TAG, "startActivity called from finishing " + mSourceRecord
1740 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
1741 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1742 mNewTaskInfo = mSourceRecord.info;
Bryce Leed9ed45d2017-05-22 15:57:24 -07001743
1744 // It is not guaranteed that the source record will have a task associated with it. For,
1745 // example, if this method is being called for processing a pending activity launch, it
1746 // is possible that the activity has been removed from the task after the launch was
1747 // enqueued.
1748 final TaskRecord sourceTask = mSourceRecord.getTask();
1749 mNewTaskIntent = sourceTask != null ? sourceTask.intent : null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001750 }
1751 mSourceRecord = null;
1752 mSourceStack = null;
1753 }
1754
1755 /**
1756 * Decide whether the new activity should be inserted into an existing task. Returns null
1757 * if not or an ActivityRecord with the task into which the new activity should be added.
1758 */
1759 private ActivityRecord getReusableIntentActivity() {
1760 // We may want to try to place the new activity in to an existing task. We always
1761 // do this if the target activity is singleTask or singleInstance; we will also do
1762 // this if NEW_TASK has been requested, and there is not an additional qualifier telling
1763 // us to still place it in a new task: multi task, always doc mode, or being asked to
1764 // launch this as a new task behind the current one.
1765 boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 &&
1766 (mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
Bryce Lee7daee392017-10-12 13:46:18 -07001767 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001768 // If bring to front is requested, and no result is requested and we have not been given
1769 // an explicit task to launch in to, and we can find a task that was started with this
1770 // same component, then instead of launching bring that one to the front.
1771 putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null;
1772 ActivityRecord intentActivity = null;
Jorim Jaggi2adba072016-03-03 13:43:39 +01001773 if (mOptions != null && mOptions.getLaunchTaskId() != -1) {
1774 final TaskRecord task = mSupervisor.anyTaskForIdLocked(mOptions.getLaunchTaskId());
1775 intentActivity = task != null ? task.getTopActivity() : null;
1776 } else if (putIntoExistingTask) {
Bryce Lee7daee392017-10-12 13:46:18 -07001777 if (LAUNCH_SINGLE_INSTANCE == mLaunchMode) {
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07001778 // There can be one and only one instance of single instance activity in the
1779 // history, and it is always in its own unique task, so we do a special search.
Bryce Lee28d80422017-07-21 13:25:13 -07001780 intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001781 mStartActivity.isActivityTypeHome());
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07001782 } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
1783 // For the launch adjacent case we only want to put the activity in an existing
1784 // task if the activity already exists in the history.
Andrii Kulian039ba482016-06-22 17:16:45 -07001785 intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info,
Bryce Lee7daee392017-10-12 13:46:18 -07001786 !(LAUNCH_SINGLE_TASK == mLaunchMode));
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07001787 } else {
1788 // Otherwise find the best task to put the activity in.
David Stevense5a7b642017-05-22 13:18:23 -07001789 intentActivity = mSupervisor.findTaskLocked(mStartActivity, mPreferredDisplayId);
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07001790 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001791 }
1792 return intentActivity;
1793 }
1794
Andrii Kulianfab9cd82017-03-21 19:37:09 -07001795 /**
Karthik Ravi Shankarf29b4c22017-04-06 17:02:01 -07001796 * Returns the ID of the display to use for a new activity. If the device is in VR mode,
David Stevense5a7b642017-05-22 13:18:23 -07001797 * then return the Vr mode's virtual display ID. If not, if the activity was started with
1798 * a launchDisplayId, use that. Otherwise, if the source activity has a explicit display ID
1799 * set, use that to launch the activity.
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -08001800 */
David Stevense5a7b642017-05-22 13:18:23 -07001801 private int getPreferedDisplayId(
1802 ActivityRecord sourceRecord, ActivityRecord startingActivity, ActivityOptions options) {
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -08001803 // Check if the Activity is a VR activity. If so, the activity should be launched in
1804 // main display.
1805 if (startingActivity != null && startingActivity.requestedVrComponent != null) {
1806 return DEFAULT_DISPLAY;
1807 }
1808
1809 // Get the virtual display id from ActivityManagerService.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001810 int displayId = mService.mVr2dDisplayId;
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -08001811 if (displayId != INVALID_DISPLAY) {
1812 if (DEBUG_STACK) {
1813 Slog.d(TAG, "getSourceDisplayId :" + displayId);
1814 }
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -08001815 return displayId;
1816 }
Karthik Ravi Shankarf29b4c22017-04-06 17:02:01 -07001817
David Stevense5a7b642017-05-22 13:18:23 -07001818 // If the caller requested a display, prefer that display.
1819 final int launchDisplayId =
1820 (options != null) ? options.getLaunchDisplayId() : INVALID_DISPLAY;
1821 if (launchDisplayId != INVALID_DISPLAY) {
1822 return launchDisplayId;
1823 }
1824
Karthik Ravi Shankarf29b4c22017-04-06 17:02:01 -07001825 displayId = sourceRecord != null ? sourceRecord.getDisplayId() : INVALID_DISPLAY;
1826 // If the activity has a displayId set explicitly, launch it on the same displayId.
1827 if (displayId != INVALID_DISPLAY) {
1828 return displayId;
1829 }
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -08001830 return DEFAULT_DISPLAY;
1831 }
1832
1833 /**
Andrii Kulianfab9cd82017-03-21 19:37:09 -07001834 * Figure out which task and activity to bring to front when we have found an existing matching
1835 * activity record in history. May also clear the task if needed.
1836 * @param intentActivity Existing matching activity.
1837 * @return {@link ActivityRecord} brought to front.
1838 */
Wale Ogunwale01d66562015-12-29 08:19:19 -08001839 private ActivityRecord setTargetStackAndMoveToFrontIfNeeded(ActivityRecord intentActivity) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001840 mTargetStack = intentActivity.getStack();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001841 mTargetStack.mLastPausedActivity = null;
1842 // If the target task is not in the front, then we need to bring it to the front...
1843 // except... well, with SINGLE_TASK_LAUNCH it's not entirely clear. We'd like to have
1844 // the same behavior as if a new instance was being started, which means not bringing it
1845 // to the front if the caller is not itself in the front.
1846 final ActivityStack focusStack = mSupervisor.getFocusedStack();
1847 ActivityRecord curTop = (focusStack == null)
1848 ? null : focusStack.topRunningNonDelayedActivityLocked(mNotTop);
1849
Bryce Leeaf691c02017-03-20 14:20:22 -07001850 final TaskRecord topTask = curTop != null ? curTop.getTask() : null;
1851 if (topTask != null
1852 && (topTask != intentActivity.getTask() || topTask != focusStack.topTask())
Jorim Jaggic875ae72016-04-26 22:41:06 -07001853 && !mAvoidMoveToFront) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001854 mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Wale Ogunwale30e441d2017-11-09 08:28:45 -08001855 if (mSourceRecord == null || (mSourceStack.getTopActivity() != null &&
1856 mSourceStack.getTopActivity().getTask() == mSourceRecord.getTask())) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001857 // We really do want to push this one into the user's face, right now.
1858 if (mLaunchTaskBehind && mSourceRecord != null) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001859 intentActivity.setTaskToAffiliateWith(mSourceRecord.getTask());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001860 }
Chong Zhangdea4bd92016-03-15 12:50:03 -07001861
1862 // If the launch flags carry both NEW_TASK and CLEAR_TASK, the task's activities
1863 // will be cleared soon by ActivityStarter in setTaskFromIntentActivity().
1864 // So no point resuming any of the activities here, it just wastes one extra
1865 // resuming, plus enter AND exit transitions.
1866 // Here we only want to bring the target stack forward. Transition will be applied
1867 // to the new activity that's started after the old ones are gone.
1868 final boolean willClearTask =
1869 (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1870 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
1871 if (!willClearTask) {
1872 final ActivityStack launchStack = getLaunchStack(
Bryce Leeaf691c02017-03-20 14:20:22 -07001873 mStartActivity, mLaunchFlags, mStartActivity.getTask(), mOptions);
1874 final TaskRecord intentTask = intentActivity.getTask();
Chong Zhangdea4bd92016-03-15 12:50:03 -07001875 if (launchStack == null || launchStack == mTargetStack) {
1876 // We only want to move to the front, if we aren't going to launch on a
1877 // different stack. If we launch on a different stack, we will put the
1878 // task on top there.
chaviw0d562bf2018-03-15 14:24:14 -07001879 mTargetStack.moveTaskToFrontLocked(intentTask, mNoAnimation, mOptions,
1880 mStartActivity.appTimeTracker, "bringingFoundTaskToFront");
Chong Zhangdea4bd92016-03-15 12:50:03 -07001881 mMovedToFront = true;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001882 } else if (launchStack.inSplitScreenWindowingMode()) {
Andrii Kulianad6f2e52016-06-15 15:27:01 -07001883 if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
1884 // If we want to launch adjacent and mTargetStack is not the computed
1885 // launch stack - move task to top of computed stack.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001886 intentTask.reparent(launchStack, ON_TOP,
Winson Chung74666102017-02-22 17:49:24 -08001887 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
1888 "launchToSide");
Andrii Kulianad6f2e52016-06-15 15:27:01 -07001889 } else {
1890 // TODO: This should be reevaluated in MW v2.
1891 // We choose to move task to front instead of launching it adjacent
1892 // when specific stack was requested explicitly and it appeared to be
1893 // adjacent stack, but FLAG_ACTIVITY_LAUNCH_ADJACENT was not set.
chaviw0d562bf2018-03-15 14:24:14 -07001894 mTargetStack.moveTaskToFrontLocked(intentTask,
Bryce Leeaf691c02017-03-20 14:20:22 -07001895 mNoAnimation, mOptions, mStartActivity.appTimeTracker,
Andrii Kulianad6f2e52016-06-15 15:27:01 -07001896 "bringToFrontInsteadOfAdjacentLaunch");
1897 }
Bryce Lee32e09ef2018-03-19 15:29:49 -07001898 mMovedToFront = launchStack != launchStack.getDisplay()
1899 .getTopStackInWindowingMode(launchStack.getWindowingMode());
Andrii Kulianfab9cd82017-03-21 19:37:09 -07001900 } else if (launchStack.mDisplayId != mTargetStack.mDisplayId) {
1901 // Target and computed stacks are on different displays and we've
1902 // found a matching task - move the existing instance to that display and
1903 // move it to front.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001904 intentActivity.getTask().reparent(launchStack, ON_TOP,
Andrii Kulianfab9cd82017-03-21 19:37:09 -07001905 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
1906 "reparentToDisplay");
1907 mMovedToFront = true;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001908 } else if (launchStack.isActivityTypeHome()
1909 && !mTargetStack.isActivityTypeHome()) {
Bryce Lee4ff7da92017-07-17 10:39:24 -07001910 // It is possible for the home activity to be in another stack initially.
1911 // For example, the activity may have been initially started with an intent
1912 // which placed it in the fullscreen stack. To ensure the proper handling of
1913 // the activity based on home stack assumptions, we must move it over.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001914 intentActivity.getTask().reparent(launchStack, ON_TOP,
Bryce Lee4ff7da92017-07-17 10:39:24 -07001915 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
1916 "reparentingHome");
1917 mMovedToFront = true;
Chong Zhangdea4bd92016-03-15 12:50:03 -07001918 }
1919 mOptions = null;
Jorim Jaggi02886a82016-12-06 09:10:06 -08001920
1921 // We are moving a task to the front, use starting window to hide initial drawn
1922 // delay.
1923 intentActivity.showStartingWindow(null /* prev */, false /* newTask */,
1924 true /* taskSwitch */);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001925 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001926 }
1927 }
Andrii Kulianb850ea52017-12-12 23:49:10 -08001928 // Need to update mTargetStack because if task was moved out of it, the original stack may
1929 // be destroyed.
1930 mTargetStack = intentActivity.getStack();
Winson Chungba40d3a2018-05-16 09:40:16 -07001931 if (!mMovedToFront && mDoResume) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001932 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Bring to front target: " + mTargetStack
1933 + " from " + intentActivity);
1934 mTargetStack.moveToFront("intentActivityFound");
1935 }
1936
Wale Ogunwale0568aed2017-09-08 13:29:37 -07001937 mSupervisor.handleNonResizableTaskIfNeeded(intentActivity.getTask(),
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07001938 WINDOWING_MODE_UNDEFINED, DEFAULT_DISPLAY, mTargetStack);
Jorim Jaggid53f0922016-04-06 22:16:23 -07001939
Wale Ogunwale01d66562015-12-29 08:19:19 -08001940 // If the caller has requested that the target task be reset, then do so.
1941 if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1942 return mTargetStack.resetTaskIfNeededLocked(intentActivity, mStartActivity);
1943 }
1944 return intentActivity;
1945 }
1946
1947 private void setTaskFromIntentActivity(ActivityRecord intentActivity) {
1948 if ((mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1949 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {
1950 // The caller has requested to completely replace any existing task with its new
1951 // activity. Well that should not be too hard...
Bryce Lee41801b42017-03-02 13:23:12 -08001952 // Note: we must persist the {@link TaskRecord} first as intentActivity could be
1953 // removed from calling performClearTaskLocked (For example, if it is being brought out
Bryce Lee59dad4e2017-03-09 11:54:08 -08001954 // of history or if it is finished immediately), thus disassociating the task. Also note
1955 // that mReuseTask is reset as a result of {@link TaskRecord#performClearTaskLocked}
1956 // launching another activity.
1957 // TODO(b/36119896): We shouldn't trigger activity launches in this path since we are
1958 // already launching one.
Bryce Leeaf691c02017-03-20 14:20:22 -07001959 final TaskRecord task = intentActivity.getTask();
Bryce Lee59dad4e2017-03-09 11:54:08 -08001960 task.performClearTaskLocked();
1961 mReuseTask = task;
Bryce Lee41801b42017-03-02 13:23:12 -08001962 mReuseTask.setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001963 } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
Bryce Lee7daee392017-10-12 13:46:18 -07001964 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001965 ActivityRecord top = intentActivity.getTask().performClearTaskLocked(mStartActivity,
Wale Ogunwale01d66562015-12-29 08:19:19 -08001966 mLaunchFlags);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001967 if (top == null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001968 // A special case: we need to start the activity because it is not currently
1969 // running, and the caller has asked to clear the current task to have this
1970 // activity at the top.
1971 mAddingToTask = true;
Bryce Lee353112c2017-02-23 09:46:45 -08001972
1973 // We are no longer placing the activity in the task we previously thought we were.
Bryce Leeaf691c02017-03-20 14:20:22 -07001974 mStartActivity.setTask(null);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001975 // Now pretend like this activity is being started by the top of its task, so it
1976 // is put in the right place.
1977 mSourceRecord = intentActivity;
Bryce Leeaf691c02017-03-20 14:20:22 -07001978 final TaskRecord task = mSourceRecord.getTask();
Andrii Kulian02b7a832016-10-06 23:11:56 -07001979 if (task != null && task.getStack() == null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001980 // Target stack got cleared when we all activities were removed above.
1981 // Go ahead and reset it.
1982 mTargetStack = computeStackFocus(mSourceRecord, false /* newTask */,
Bryce Leedacefc42017-10-10 12:56:02 -07001983 mLaunchFlags, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001984 mTargetStack.addTask(task,
1985 !mLaunchTaskBehind /* toTop */, "startActivityUnchecked");
1986 }
1987 }
Bryce Leeaf691c02017-03-20 14:20:22 -07001988 } else if (mStartActivity.realActivity.equals(intentActivity.getTask().realActivity)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001989 // In this case the top activity on the task is the same as the one being launched,
1990 // so we take that as a request to bring the task to the foreground. If the top
1991 // activity in the task is the root activity, deliver this new intent to it if it
1992 // desires.
Bryce Lee7daee392017-10-12 13:46:18 -07001993 if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
1994 || LAUNCH_SINGLE_TOP == mLaunchMode)
Wale Ogunwale01d66562015-12-29 08:19:19 -08001995 && intentActivity.realActivity.equals(mStartActivity.realActivity)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001996 if (intentActivity.frontOfTask) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001997 intentActivity.getTask().setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001998 }
Bryce Lee325e09682017-10-05 17:20:25 -07001999 deliverNewIntent(intentActivity);
Bryce Leeaf691c02017-03-20 14:20:22 -07002000 } else if (!intentActivity.getTask().isSameIntentFilter(mStartActivity)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002001 // In this case we are launching the root activity of the task, but with a
2002 // different intent. We should start a new instance on top.
2003 mAddingToTask = true;
2004 mSourceRecord = intentActivity;
2005 }
2006 } else if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
2007 // In this case an activity is being launched in to an existing task, without
2008 // resetting that task. This is typically the situation of launching an activity
2009 // from a notification or shortcut. We want to place the new activity on top of the
2010 // current task.
2011 mAddingToTask = true;
2012 mSourceRecord = intentActivity;
Bryce Leeaf691c02017-03-20 14:20:22 -07002013 } else if (!intentActivity.getTask().rootWasReset) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002014 // In this case we are launching into an existing task that has not yet been started
2015 // from its front door. The current task has been brought to the front. Ideally,
2016 // we'd probably like to place this new task at the bottom of its stack, but that's
2017 // a little hard to do with the current organization of the code so for now we'll
2018 // just drop it.
Bryce Leeaf691c02017-03-20 14:20:22 -07002019 intentActivity.getTask().setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002020 }
2021 }
2022
2023 private void resumeTargetStackIfNeeded() {
2024 if (mDoResume) {
2025 mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, null, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002026 } else {
2027 ActivityOptions.abort(mOptions);
2028 }
2029 mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);
2030 }
2031
Chong Zhang6cda19c2016-06-14 19:07:56 -07002032 private int setTaskFromReuseOrCreateNewTask(
Wale Ogunwale0568aed2017-09-08 13:29:37 -07002033 TaskRecord taskToAffiliate, ActivityStack topStack) {
Bryce Leedacefc42017-10-10 12:56:02 -07002034 mTargetStack = computeStackFocus(mStartActivity, true, mLaunchFlags, mOptions);
Chong Zhang6cda19c2016-06-14 19:07:56 -07002035
2036 // Do no move the target stack to front yet, as we might bail if
2037 // isLockTaskModeViolation fails below.
Wale Ogunwale01d66562015-12-29 08:19:19 -08002038
2039 if (mReuseTask == null) {
Suprabh Shukla09a88f52015-12-02 14:36:31 -08002040 final TaskRecord task = mTargetStack.createTaskRecord(
2041 mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId),
Wale Ogunwale01d66562015-12-29 08:19:19 -08002042 mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
Wale Ogunwale72919d22016-12-08 18:58:50 -08002043 mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
Bryce Leeb802ea12017-11-15 21:25:03 -08002044 mVoiceInteractor, !mLaunchTaskBehind /* toTop */, mStartActivity, mSourceRecord,
2045 mOptions);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002046 addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
Bryce Leeec55eb02017-12-05 20:51:27 -08002047 updateBounds(mStartActivity.getTask(), mLaunchParams.mBounds);
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002048
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002049 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Bryce Leeaf691c02017-03-20 14:20:22 -07002050 + " in new task " + mStartActivity.getTask());
Wale Ogunwale01d66562015-12-29 08:19:19 -08002051 } else {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002052 addOrReparentStartingActivity(mReuseTask, "setTaskFromReuseOrCreateNewTask");
2053 }
2054
2055 if (taskToAffiliate != null) {
2056 mStartActivity.setTaskToAffiliateWith(taskToAffiliate);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002057 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07002058
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07002059 if (mService.getLockTaskController().isLockTaskModeViolation(mStartActivity.getTask())) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002060 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
2061 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
2062 }
2063
Chong Zhang6cda19c2016-06-14 19:07:56 -07002064 if (mDoResume) {
2065 mTargetStack.moveToFront("reuseOrNewTask");
2066 }
2067 return START_SUCCESS;
Wale Ogunwale01d66562015-12-29 08:19:19 -08002068 }
2069
Bryce Lee325e09682017-10-05 17:20:25 -07002070 private void deliverNewIntent(ActivityRecord activity) {
2071 if (mIntentDelivered) {
2072 return;
2073 }
2074
2075 ActivityStack.logStartActivity(AM_NEW_INTENT, activity, activity.getTask());
2076 activity.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
2077 mStartActivity.launchedFromPackage);
2078 mIntentDelivered = true;
2079 }
2080
Wale Ogunwale01d66562015-12-29 08:19:19 -08002081 private int setTaskFromSourceRecord() {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07002082 if (mService.getLockTaskController().isLockTaskModeViolation(mSourceRecord.getTask())) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002083 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
2084 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
2085 }
2086
Bryce Leeaf691c02017-03-20 14:20:22 -07002087 final TaskRecord sourceTask = mSourceRecord.getTask();
Andrii Kulian02b7a832016-10-06 23:11:56 -07002088 final ActivityStack sourceStack = mSourceRecord.getStack();
Andrii Kulian02689a72017-07-06 14:28:59 -07002089 // We only want to allow changing stack in two cases:
2090 // 1. If the target task is not the top one. Otherwise we would move the launching task to
2091 // the other side, rather than show two side by side.
2092 // 2. If activity is not allowed on target display.
2093 final int targetDisplayId = mTargetStack != null ? mTargetStack.mDisplayId
2094 : sourceStack.mDisplayId;
2095 final boolean moveStackAllowed = sourceStack.topTask() != sourceTask
2096 || !mStartActivity.canBeLaunchedOnDisplay(targetDisplayId);
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002097 if (moveStackAllowed) {
Bryce Leeaf691c02017-03-20 14:20:22 -07002098 mTargetStack = getLaunchStack(mStartActivity, mLaunchFlags, mStartActivity.getTask(),
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002099 mOptions);
Andrii Kulian02689a72017-07-06 14:28:59 -07002100 // If target stack is not found now - we can't just rely on the source stack, as it may
2101 // be not suitable. Let's check other displays.
2102 if (mTargetStack == null && targetDisplayId != sourceStack.mDisplayId) {
2103 // Can't use target display, lets find a stack on the source display.
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07002104 mTargetStack = mSupervisor.getValidLaunchStackOnDisplay(
Andrii Kulian02689a72017-07-06 14:28:59 -07002105 sourceStack.mDisplayId, mStartActivity);
2106 }
2107 if (mTargetStack == null) {
2108 // There are no suitable stacks on the target and source display(s). Look on all
2109 // displays.
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07002110 mTargetStack = mSupervisor.getNextValidLaunchStackLocked(
Andrii Kulian02689a72017-07-06 14:28:59 -07002111 mStartActivity, -1 /* currentFocus */);
2112 }
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002113 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002114
2115 if (mTargetStack == null) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07002116 mTargetStack = sourceStack;
2117 } else if (mTargetStack != sourceStack) {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002118 sourceTask.reparent(mTargetStack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE,
2119 DEFER_RESUME, "launchToSide");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002120 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07002121
Wale Ogunwale01d66562015-12-29 08:19:19 -08002122 final TaskRecord topTask = mTargetStack.topTask();
Jorim Jaggic875ae72016-04-26 22:41:06 -07002123 if (topTask != sourceTask && !mAvoidMoveToFront) {
chaviw0d562bf2018-03-15 14:24:14 -07002124 mTargetStack.moveTaskToFrontLocked(sourceTask, mNoAnimation, mOptions,
Wale Ogunwale01d66562015-12-29 08:19:19 -08002125 mStartActivity.appTimeTracker, "sourceTaskToFront");
Chong Zhang6cda19c2016-06-14 19:07:56 -07002126 } else if (mDoResume) {
2127 mTargetStack.moveToFront("sourceStackToFront");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002128 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07002129
Wale Ogunwale01d66562015-12-29 08:19:19 -08002130 if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0) {
2131 // In this case, we are adding the activity to an existing task, but the caller has
2132 // asked to clear that task if the activity is already running.
2133 ActivityRecord top = sourceTask.performClearTaskLocked(mStartActivity, mLaunchFlags);
2134 mKeepCurTransition = true;
2135 if (top != null) {
Bryce Leeaf691c02017-03-20 14:20:22 -07002136 ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, top.getTask());
Bryce Lee325e09682017-10-05 17:20:25 -07002137 deliverNewIntent(top);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002138 // For paranoia, make sure we have correctly resumed the top activity.
2139 mTargetStack.mLastPausedActivity = null;
2140 if (mDoResume) {
2141 mSupervisor.resumeFocusedStackTopActivityLocked();
2142 }
2143 ActivityOptions.abort(mOptions);
2144 return START_DELIVERED_TO_TOP;
2145 }
2146 } else if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
2147 // In this case, we are launching an activity in our own task that may already be
2148 // running somewhere in the history, and we want to shuffle it to the front of the
2149 // stack if so.
2150 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(mStartActivity);
2151 if (top != null) {
Bryce Leeaf691c02017-03-20 14:20:22 -07002152 final TaskRecord task = top.getTask();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002153 task.moveActivityToFrontLocked(top);
2154 top.updateOptionsLocked(mOptions);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08002155 ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, task);
Bryce Lee325e09682017-10-05 17:20:25 -07002156 deliverNewIntent(top);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002157 mTargetStack.mLastPausedActivity = null;
2158 if (mDoResume) {
2159 mSupervisor.resumeFocusedStackTopActivityLocked();
2160 }
2161 return START_DELIVERED_TO_TOP;
2162 }
2163 }
2164
2165 // An existing activity is starting this new activity, so we want to keep the new one in
2166 // the same task as the one that is starting it.
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002167 addOrReparentStartingActivity(sourceTask, "setTaskFromSourceRecord");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002168 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Bryce Leeaf691c02017-03-20 14:20:22 -07002169 + " in existing task " + mStartActivity.getTask() + " from source " + mSourceRecord);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002170 return START_SUCCESS;
2171 }
2172
2173 private int setTaskFromInTask() {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002174 // The caller is asking that the new activity be started in an explicit
2175 // task it has provided to us.
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07002176 if (mService.getLockTaskController().isLockTaskModeViolation(mInTask)) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002177 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
2178 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
2179 }
2180
Andrii Kulian02b7a832016-10-06 23:11:56 -07002181 mTargetStack = mInTask.getStack();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002182
2183 // Check whether we should actually launch the new activity in to the task,
2184 // or just reuse the current activity on top.
2185 ActivityRecord top = mInTask.getTopActivity();
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002186 if (top != null && top.realActivity.equals(mStartActivity.realActivity)
2187 && top.userId == mStartActivity.userId) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002188 if ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
Bryce Lee7daee392017-10-12 13:46:18 -07002189 || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK)) {
chaviw0d562bf2018-03-15 14:24:14 -07002190 mTargetStack.moveTaskToFrontLocked(mInTask, mNoAnimation, mOptions,
Yorke Lee64512522017-03-24 13:09:35 -07002191 mStartActivity.appTimeTracker, "inTaskToFront");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002192 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
2193 // We don't need to start a new activity, and the client said not to do
2194 // anything if that is the case, so this is it!
2195 return START_RETURN_INTENT_TO_CALLER;
2196 }
Bryce Lee325e09682017-10-05 17:20:25 -07002197 deliverNewIntent(top);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002198 return START_DELIVERED_TO_TOP;
2199 }
2200 }
2201
2202 if (!mAddingToTask) {
chaviw0d562bf2018-03-15 14:24:14 -07002203 mTargetStack.moveTaskToFrontLocked(mInTask, mNoAnimation, mOptions,
Yorke Lee64512522017-03-24 13:09:35 -07002204 mStartActivity.appTimeTracker, "inTaskToFront");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002205 // We don't actually want to have this activity added to the task, so just
2206 // stop here but still tell the caller that we consumed the intent.
2207 ActivityOptions.abort(mOptions);
2208 return START_TASK_TO_FRONT;
2209 }
2210
Bryce Leeec55eb02017-12-05 20:51:27 -08002211 if (!mLaunchParams.mBounds.isEmpty()) {
Wale Ogunwale0568aed2017-09-08 13:29:37 -07002212 // TODO: Shouldn't we already know what stack to use by the time we get here?
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002213 ActivityStack stack = mSupervisor.getLaunchStack(null, null, mInTask, ON_TOP);
2214 if (stack != mInTask.getStack()) {
2215 mInTask.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, !ANIMATE,
Yorke Lee64512522017-03-24 13:09:35 -07002216 DEFER_RESUME, "inTaskToFront");
Yorke Lee64512522017-03-24 13:09:35 -07002217 mTargetStack = mInTask.getStack();
2218 }
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002219
Bryce Leeec55eb02017-12-05 20:51:27 -08002220 updateBounds(mInTask, mLaunchParams.mBounds);
Yorke Lee64512522017-03-24 13:09:35 -07002221 }
2222
chaviw0d562bf2018-03-15 14:24:14 -07002223 mTargetStack.moveTaskToFrontLocked(
2224 mInTask, mNoAnimation, mOptions, mStartActivity.appTimeTracker, "inTaskToFront");
Yorke Lee64512522017-03-24 13:09:35 -07002225
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002226 addOrReparentStartingActivity(mInTask, "setTaskFromInTask");
2227 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Bryce Leeaf691c02017-03-20 14:20:22 -07002228 + " in explicit task " + mStartActivity.getTask());
Wale Ogunwale01d66562015-12-29 08:19:19 -08002229
2230 return START_SUCCESS;
2231 }
2232
Bryce Leed3624e12017-11-30 08:51:45 -08002233 @VisibleForTesting
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002234 void updateBounds(TaskRecord task, Rect bounds) {
Bryce Leedacefc42017-10-10 12:56:02 -07002235 if (bounds.isEmpty()) {
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002236 return;
2237 }
2238
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002239 final ActivityStack stack = task.getStack();
2240 if (stack != null && stack.resizeStackWithLaunchBounds()) {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07002241 mService.resizeStack(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002242 stack.mStackId, bounds, true, !PRESERVE_WINDOWS, ANIMATE, -1);
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002243 } else {
2244 task.updateOverrideConfiguration(bounds);
2245 }
2246 }
2247
Wale Ogunwale01d66562015-12-29 08:19:19 -08002248 private void setTaskToCurrentTopOrCreateNewTask() {
Bryce Leedacefc42017-10-10 12:56:02 -07002249 mTargetStack = computeStackFocus(mStartActivity, false, mLaunchFlags, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002250 if (mDoResume) {
2251 mTargetStack.moveToFront("addingToTopTask");
2252 }
Wale Ogunwale30e441d2017-11-09 08:28:45 -08002253 final ActivityRecord prev = mTargetStack.getTopActivity();
Bryce Leeaf691c02017-03-20 14:20:22 -07002254 final TaskRecord task = (prev != null) ? prev.getTask() : mTargetStack.createTaskRecord(
Wale Ogunwale72919d22016-12-08 18:58:50 -08002255 mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId), mStartActivity.info,
Bryce Leeb802ea12017-11-15 21:25:03 -08002256 mIntent, null, null, true, mStartActivity, mSourceRecord, mOptions);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002257 addOrReparentStartingActivity(task, "setTaskToCurrentTopOrCreateNewTask");
2258 mTargetStack.positionChildWindowContainerAtTop(task);
2259 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Bryce Leeaf691c02017-03-20 14:20:22 -07002260 + " in new guessed " + mStartActivity.getTask());
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002261 }
2262
2263 private void addOrReparentStartingActivity(TaskRecord parent, String reason) {
Bryce Leeaf691c02017-03-20 14:20:22 -07002264 if (mStartActivity.getTask() == null || mStartActivity.getTask() == parent) {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002265 parent.addActivityToTop(mStartActivity);
2266 } else {
2267 mStartActivity.reparent(parent, parent.mActivities.size() /* top */, reason);
2268 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002269 }
2270
2271 private int adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance,
2272 boolean launchSingleTask, int launchFlags) {
2273 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2274 (launchSingleInstance || launchSingleTask)) {
2275 // We have a conflict between the Intent and the Activity manifest, manifest wins.
2276 Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " +
2277 "\"singleInstance\" or \"singleTask\"");
2278 launchFlags &=
2279 ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK);
2280 } else {
2281 switch (r.info.documentLaunchMode) {
2282 case ActivityInfo.DOCUMENT_LAUNCH_NONE:
2283 break;
2284 case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
2285 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2286 break;
2287 case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
2288 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2289 break;
2290 case ActivityInfo.DOCUMENT_LAUNCH_NEVER:
2291 launchFlags &= ~FLAG_ACTIVITY_MULTIPLE_TASK;
2292 break;
2293 }
2294 }
2295 return launchFlags;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002296 }
2297
Bryce Leedacefc42017-10-10 12:56:02 -07002298 private ActivityStack computeStackFocus(ActivityRecord r, boolean newTask, int launchFlags,
2299 ActivityOptions aOptions) {
Bryce Leeaf691c02017-03-20 14:20:22 -07002300 final TaskRecord task = r.getTask();
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002301 ActivityStack stack = getLaunchStack(r, launchFlags, task, aOptions);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002302 if (stack != null) {
2303 return stack;
2304 }
2305
Andrii Kulian02b7a832016-10-06 23:11:56 -07002306 final ActivityStack currentStack = task != null ? task.getStack() : null;
2307 if (currentStack != null) {
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002308 if (mSupervisor.mFocusedStack != currentStack) {
2309 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
2310 "computeStackFocus: Setting " + "focused stack to r=" + r
2311 + " task=" + task);
2312 } else {
2313 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
2314 "computeStackFocus: Focused stack already="
2315 + mSupervisor.mFocusedStack);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002316 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07002317 return currentStack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002318 }
2319
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002320 if (canLaunchIntoFocusedStack(r, newTask)) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002321 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
2322 "computeStackFocus: Have a focused stack=" + mSupervisor.mFocusedStack);
2323 return mSupervisor.mFocusedStack;
2324 }
2325
David Stevense5a7b642017-05-22 13:18:23 -07002326 if (mPreferredDisplayId != DEFAULT_DISPLAY) {
Andrii Kuliana8fe3df2017-06-16 15:29:26 -07002327 // Try to put the activity in a stack on a secondary display.
David Stevense5a7b642017-05-22 13:18:23 -07002328 stack = mSupervisor.getValidLaunchStackOnDisplay(mPreferredDisplayId, r);
Andrii Kuliana8fe3df2017-06-16 15:29:26 -07002329 if (stack == null) {
2330 // If source display is not suitable - look for topmost valid stack in the system.
2331 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
David Stevense5a7b642017-05-22 13:18:23 -07002332 "computeStackFocus: Can't launch on mPreferredDisplayId="
2333 + mPreferredDisplayId + ", looking on all displays.");
2334 stack = mSupervisor.getNextValidLaunchStackLocked(r, mPreferredDisplayId);
Andrii Kuliana8fe3df2017-06-16 15:29:26 -07002335 }
2336 }
2337 if (stack == null) {
David Stevensc6b91c62017-02-08 14:23:58 -08002338 // We first try to put the task in the first dynamic stack on home display.
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07002339 final ActivityDisplay display = mSupervisor.getDefaultDisplay();
2340 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
2341 stack = display.getChildAt(stackNdx);
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002342 if (!stack.isOnHomeDisplay()) {
David Stevensc6b91c62017-02-08 14:23:58 -08002343 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
2344 "computeStackFocus: Setting focused stack=" + stack);
2345 return stack;
2346 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002347 }
David Stevensc6b91c62017-02-08 14:23:58 -08002348 // If there is no suitable dynamic stack then we figure out which static stack to use.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002349 stack = mSupervisor.getLaunchStack(r, aOptions, task, ON_TOP);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002350 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002351 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, "computeStackFocus: New stack r="
2352 + r + " stackId=" + stack.mStackId);
2353 return stack;
2354 }
2355
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002356 /** Check if provided activity record can launch in currently focused stack. */
Wale Ogunwale68278562017-09-23 17:13:55 -07002357 // TODO: This method can probably be consolidated into getLaunchStack() below.
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002358 private boolean canLaunchIntoFocusedStack(ActivityRecord r, boolean newTask) {
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002359 final ActivityStack focusedStack = mSupervisor.mFocusedStack;
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002360 final boolean canUseFocusedStack;
Wale Ogunwale68278562017-09-23 17:13:55 -07002361 if (focusedStack.isActivityTypeAssistant()) {
2362 canUseFocusedStack = r.isActivityTypeAssistant();
2363 } else {
2364 switch (focusedStack.getWindowingMode()) {
2365 case WINDOWING_MODE_FULLSCREEN:
2366 // The fullscreen stack can contain any task regardless of if the task is
2367 // resizeable or not. So, we let the task go in the fullscreen task if it is the
2368 // focus stack.
2369 canUseFocusedStack = true;
2370 break;
2371 case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
2372 case WINDOWING_MODE_SPLIT_SCREEN_SECONDARY:
2373 // Any activity which supports split screen can go in the docked stack.
2374 canUseFocusedStack = r.supportsSplitScreenWindowingMode();
2375 break;
2376 case WINDOWING_MODE_FREEFORM:
2377 // Any activity which supports freeform can go in the freeform stack.
2378 canUseFocusedStack = r.supportsFreeform();
2379 break;
2380 default:
2381 // Dynamic stacks behave similarly to the fullscreen stack and can contain any
2382 // resizeable task.
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002383 canUseFocusedStack = !focusedStack.isOnHomeDisplay()
Wale Ogunwale68278562017-09-23 17:13:55 -07002384 && r.canBeLaunchedOnDisplay(focusedStack.mDisplayId);
2385 }
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002386 }
Andrii Kulian94e82d9b02017-07-13 15:33:06 -07002387 return canUseFocusedStack && !newTask
Wale Ogunwale68278562017-09-23 17:13:55 -07002388 // Using the focus stack isn't important enough to override the preferred display.
David Stevense5a7b642017-05-22 13:18:23 -07002389 && (mPreferredDisplayId == focusedStack.mDisplayId);
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002390 }
2391
Wale Ogunwale854809c2015-12-27 16:18:19 -08002392 private ActivityStack getLaunchStack(ActivityRecord r, int launchFlags, TaskRecord task,
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002393 ActivityOptions aOptions) {
Bryce Leea19b5ad2017-06-07 16:54:11 -07002394 // We are reusing a task, keep the stack!
2395 if (mReuseTask != null) {
2396 return mReuseTask.getStack();
2397 }
Jorim Jaggib8c58762016-04-20 17:58:29 -07002398
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -08002399 if (((launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) == 0)
David Stevense5a7b642017-05-22 13:18:23 -07002400 || mPreferredDisplayId != DEFAULT_DISPLAY) {
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08002401 // We don't pass in the default display id into the get launch stack call so it can do a
2402 // full resolution.
2403 final int candidateDisplay =
2404 mPreferredDisplayId != DEFAULT_DISPLAY ? mPreferredDisplayId : INVALID_DISPLAY;
2405 return mSupervisor.getLaunchStack(r, aOptions, task, ON_TOP, candidateDisplay);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002406 }
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002407 // Otherwise handle adjacent launch.
Wale Ogunwale854809c2015-12-27 16:18:19 -08002408
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002409 // The parent activity doesn't want to launch the activity on top of itself, but
2410 // instead tries to put it onto other side in side-by-side mode.
Andrii Kulian94e82d9b02017-07-13 15:33:06 -07002411 final ActivityStack parentStack = task != null ? task.getStack(): mSupervisor.mFocusedStack;
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002412
2413 if (parentStack != mSupervisor.mFocusedStack) {
2414 // If task's parent stack is not focused - use it during adjacent launch.
2415 return parentStack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002416 } else {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002417 if (mSupervisor.mFocusedStack != null && task == mSupervisor.mFocusedStack.topTask()) {
2418 // If task is already on top of focused stack - use it. We don't want to move the
2419 // existing focused task to adjacent stack, just deliver new intent in this case.
2420 return mSupervisor.mFocusedStack;
2421 }
2422
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002423 if (parentStack != null && parentStack.inSplitScreenPrimaryWindowingMode()) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002424 // If parent was in docked stack, the natural place to launch another activity
2425 // will be fullscreen, so it can appear alongside the docked window.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002426 final int activityType = mSupervisor.resolveActivityType(r, mOptions, task);
2427 return parentStack.getDisplay().getOrCreateStack(
2428 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, activityType, ON_TOP);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002429 } else {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002430 // If the parent is not in the docked stack, we check if there is docked window
2431 // and if yes, we will launch into that stack. If not, we just put the new
2432 // activity into parent's stack, because we can't find a better place.
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07002433 final ActivityStack dockedStack =
2434 mSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
Wale Ogunwale9dcf9462017-09-19 15:13:01 -07002435 if (dockedStack != null && !dockedStack.shouldBeVisible(r)) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002436 // There is a docked stack, but it isn't visible, so we can't launch into that.
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08002437 return mSupervisor.getLaunchStack(r, aOptions, task, ON_TOP);
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002438 } else {
2439 return dockedStack;
2440 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002441 }
2442 }
2443 }
2444
Bryce Lee7daee392017-10-12 13:46:18 -07002445 private boolean isLaunchModeOneOf(int mode1, int mode2) {
2446 return mode1 == mLaunchMode || mode2 == mLaunchMode;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002447 }
2448
Daichi Hirono15a02992016-04-27 18:47:01 +09002449 static boolean isDocumentLaunchesIntoExisting(int flags) {
2450 return (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2451 (flags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0;
2452 }
liulvpingcfa825f2016-09-26 20:00:15 +08002453
Bryce Lee4c9a5972017-12-01 22:14:24 -08002454 ActivityStarter setIntent(Intent intent) {
2455 mRequest.intent = intent;
2456 return this;
2457 }
2458
Bryce Lee32e09ef2018-03-19 15:29:49 -07002459 @VisibleForTesting
2460 Intent getIntent() {
2461 return mRequest.intent;
2462 }
2463
Bryce Lee4c9a5972017-12-01 22:14:24 -08002464 ActivityStarter setReason(String reason) {
2465 mRequest.reason = reason;
2466 return this;
2467 }
2468
2469 ActivityStarter setCaller(IApplicationThread caller) {
2470 mRequest.caller = caller;
2471 return this;
2472 }
2473
2474 ActivityStarter setEphemeralIntent(Intent intent) {
2475 mRequest.ephemeralIntent = intent;
2476 return this;
2477 }
2478
2479
2480 ActivityStarter setResolvedType(String type) {
2481 mRequest.resolvedType = type;
2482 return this;
2483 }
2484
2485 ActivityStarter setActivityInfo(ActivityInfo info) {
2486 mRequest.activityInfo = info;
2487 return this;
2488 }
2489
2490 ActivityStarter setResolveInfo(ResolveInfo info) {
2491 mRequest.resolveInfo = info;
2492 return this;
2493 }
2494
2495 ActivityStarter setVoiceSession(IVoiceInteractionSession voiceSession) {
2496 mRequest.voiceSession = voiceSession;
2497 return this;
2498 }
2499
2500 ActivityStarter setVoiceInteractor(IVoiceInteractor voiceInteractor) {
2501 mRequest.voiceInteractor = voiceInteractor;
2502 return this;
2503 }
2504
2505 ActivityStarter setResultTo(IBinder resultTo) {
2506 mRequest.resultTo = resultTo;
2507 return this;
2508 }
2509
2510 ActivityStarter setResultWho(String resultWho) {
2511 mRequest.resultWho = resultWho;
2512 return this;
2513 }
2514
2515 ActivityStarter setRequestCode(int requestCode) {
2516 mRequest.requestCode = requestCode;
2517 return this;
2518 }
2519
2520 ActivityStarter setCallingPid(int pid) {
2521 mRequest.callingPid = pid;
2522 return this;
2523 }
2524
2525 ActivityStarter setCallingUid(int uid) {
2526 mRequest.callingUid = uid;
2527 return this;
2528 }
2529
2530 ActivityStarter setCallingPackage(String callingPackage) {
2531 mRequest.callingPackage = callingPackage;
2532 return this;
2533 }
2534
2535 ActivityStarter setRealCallingPid(int pid) {
2536 mRequest.realCallingPid = pid;
2537 return this;
2538 }
2539
2540 ActivityStarter setRealCallingUid(int uid) {
2541 mRequest.realCallingUid = uid;
2542 return this;
2543 }
2544
2545 ActivityStarter setStartFlags(int startFlags) {
2546 mRequest.startFlags = startFlags;
2547 return this;
2548 }
2549
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002550 ActivityStarter setActivityOptions(SafeActivityOptions options) {
Bryce Lee4c9a5972017-12-01 22:14:24 -08002551 mRequest.activityOptions = options;
2552 return this;
2553 }
2554
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002555 ActivityStarter setActivityOptions(Bundle bOptions) {
2556 return setActivityOptions(SafeActivityOptions.fromBundle(bOptions));
2557 }
2558
Bryce Lee4c9a5972017-12-01 22:14:24 -08002559 ActivityStarter setIgnoreTargetSecurity(boolean ignoreTargetSecurity) {
2560 mRequest.ignoreTargetSecurity = ignoreTargetSecurity;
2561 return this;
2562 }
2563
Patrick Baumann31426b22018-05-21 13:46:40 -07002564 ActivityStarter setFilterCallingUid(int filterCallingUid) {
2565 mRequest.filterCallingUid = filterCallingUid;
2566 return this;
2567 }
2568
Bryce Lee4c9a5972017-12-01 22:14:24 -08002569 ActivityStarter setComponentSpecified(boolean componentSpecified) {
2570 mRequest.componentSpecified = componentSpecified;
2571 return this;
2572 }
2573
2574 ActivityStarter setOutActivity(ActivityRecord[] outActivity) {
2575 mRequest.outActivity = outActivity;
2576 return this;
2577 }
2578
2579 ActivityStarter setInTask(TaskRecord inTask) {
2580 mRequest.inTask = inTask;
2581 return this;
2582 }
2583
2584 ActivityStarter setWaitResult(WaitResult result) {
2585 mRequest.waitResult = result;
2586 return this;
2587 }
2588
2589 ActivityStarter setProfilerInfo(ProfilerInfo info) {
2590 mRequest.profilerInfo = info;
2591 return this;
2592 }
2593
2594 ActivityStarter setGlobalConfiguration(Configuration config) {
2595 mRequest.globalConfig = config;
2596 return this;
2597 }
2598
Bryce Lee4c9a5972017-12-01 22:14:24 -08002599 ActivityStarter setUserId(int userId) {
2600 mRequest.userId = userId;
2601 return this;
2602 }
2603
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002604 ActivityStarter setMayWait(int userId) {
Bryce Lee4c9a5972017-12-01 22:14:24 -08002605 mRequest.mayWait = true;
Bryce Lee4c9a5972017-12-01 22:14:24 -08002606 mRequest.userId = userId;
2607
2608 return this;
2609 }
2610
Jorim Jaggi6fa41c32018-04-23 18:35:00 +02002611 ActivityStarter setAllowPendingRemoteAnimationRegistryLookup(boolean allowLookup) {
2612 mRequest.allowPendingRemoteAnimationRegistryLookup = allowLookup;
2613 return this;
2614 }
2615
Bryce Leed3624e12017-11-30 08:51:45 -08002616 void dump(PrintWriter pw, String prefix) {
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002617 prefix = prefix + " ";
Dianne Hackborne676ec72017-07-25 10:55:08 -07002618 pw.print(prefix);
2619 pw.print("mCurrentUser=");
2620 pw.println(mSupervisor.mCurrentUser);
2621 pw.print(prefix);
2622 pw.print("mLastStartReason=");
2623 pw.println(mLastStartReason);
2624 pw.print(prefix);
2625 pw.print("mLastStartActivityTimeMs=");
2626 pw.println(DateFormat.getDateTimeInstance().format(new Date(mLastStartActivityTimeMs)));
2627 pw.print(prefix);
2628 pw.print("mLastStartActivityResult=");
2629 pw.println(mLastStartActivityResult);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002630 ActivityRecord r = mLastStartActivityRecord[0];
2631 if (r != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002632 pw.print(prefix);
2633 pw.println("mLastStartActivityRecord:");
2634 r.dump(pw, prefix + " ");
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002635 }
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002636 if (mStartActivity != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002637 pw.print(prefix);
2638 pw.println("mStartActivity:");
2639 mStartActivity.dump(pw, prefix + " ");
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002640 }
2641 if (mIntent != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002642 pw.print(prefix);
2643 pw.print("mIntent=");
2644 pw.println(mIntent);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002645 }
2646 if (mOptions != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002647 pw.print(prefix);
2648 pw.print("mOptions=");
2649 pw.println(mOptions);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002650 }
Dianne Hackborne676ec72017-07-25 10:55:08 -07002651 pw.print(prefix);
2652 pw.print("mLaunchSingleTop=");
Bryce Lee7daee392017-10-12 13:46:18 -07002653 pw.print(LAUNCH_SINGLE_TOP == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002654 pw.print(" mLaunchSingleInstance=");
Bryce Lee7daee392017-10-12 13:46:18 -07002655 pw.print(LAUNCH_SINGLE_INSTANCE == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002656 pw.print(" mLaunchSingleTask=");
Bryce Lee7daee392017-10-12 13:46:18 -07002657 pw.println(LAUNCH_SINGLE_TASK == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002658 pw.print(prefix);
2659 pw.print("mLaunchFlags=0x");
2660 pw.print(Integer.toHexString(mLaunchFlags));
2661 pw.print(" mDoResume=");
2662 pw.print(mDoResume);
2663 pw.print(" mAddingToTask=");
2664 pw.println(mAddingToTask);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002665 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002666}