blob: f886b6dc57bef638abe229b9cd5404268d016d7d [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.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700774 if (aInfo != null) {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700775 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) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -0700805 final ActivityStack focusedStack = mSupervisor.getTopDisplayFocusedStack();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800806 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true,
807 true, false) + "} from uid " + callingUid + " on display "
Andrii Kulian52d255c2018-07-13 11:32:19 -0700808 + (focusedStack == null ? DEFAULT_DISPLAY : focusedStack.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
Andrii Kulian5f750bc2018-07-17 08:57:23 -0700842 final ActivityStack stack = mSupervisor.getTopDisplayFocusedStack();
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 Kulian5f750bc2018-07-17 08:57:23 -07001016 final ActivityStack stack = mSupervisor.getTopDisplayFocusedStack();
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.
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001357 final ActivityStack topStack = mSupervisor.getTopDisplayFocusedStack();
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.
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001450 if (mTargetStack.isFocusable()
1451 && !mSupervisor.isTopDisplayFocusedStack(mTargetStack)) {
Winson Chung32066032016-11-04 11:55:21 -07001452 mTargetStack.moveToFront("startActivityUnchecked");
1453 }
Wale Ogunwale3b232392016-05-13 15:37:13 -07001454 mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
1455 mOptions);
Filip Gruszczynski3d7fdc12016-01-31 17:33:29 -08001456 }
Winson Chung1dbc8112017-09-28 18:05:31 -07001457 } else if (mStartActivity != null) {
1458 mSupervisor.mRecentTasks.add(mStartActivity.getTask());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001459 }
1460 mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);
1461
Wale Ogunwale0568aed2017-09-08 13:29:37 -07001462 mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(), preferredWindowingMode,
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07001463 preferredLaunchDisplayId, mTargetStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001464
1465 return START_SUCCESS;
1466 }
1467
Bryce Leedaa91e42017-12-06 14:13:01 -08001468 /**
1469 * Resets the {@link ActivityStarter} state.
1470 * @param clearRequest whether the request should be reset to default values.
1471 */
1472 void reset(boolean clearRequest) {
1473 mStartActivity = null;
1474 mIntent = null;
1475 mCallingUid = -1;
1476 mOptions = null;
1477
1478 mLaunchTaskBehind = false;
1479 mLaunchFlags = 0;
1480 mLaunchMode = INVALID_LAUNCH_MODE;
1481
Bryce Leeec55eb02017-12-05 20:51:27 -08001482 mLaunchParams.reset();
Bryce Leedaa91e42017-12-06 14:13:01 -08001483
1484 mNotTop = null;
1485 mDoResume = false;
1486 mStartFlags = 0;
1487 mSourceRecord = null;
1488 mPreferredDisplayId = INVALID_DISPLAY;
1489
1490 mInTask = null;
1491 mAddingToTask = false;
1492 mReuseTask = null;
1493
1494 mNewTaskInfo = null;
1495 mNewTaskIntent = null;
1496 mSourceStack = null;
1497
1498 mTargetStack = null;
1499 mMovedToFront = false;
1500 mNoAnimation = false;
1501 mKeepCurTransition = false;
1502 mAvoidMoveToFront = false;
1503
1504 mVoiceSession = null;
1505 mVoiceInteractor = null;
1506
1507 mIntentDelivered = false;
1508
1509 if (clearRequest) {
1510 mRequest.reset();
1511 }
1512 }
1513
Wale Ogunwale01d66562015-12-29 08:19:19 -08001514 private void setInitialState(ActivityRecord r, ActivityOptions options, TaskRecord inTask,
1515 boolean doResume, int startFlags, ActivityRecord sourceRecord,
1516 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
Bryce Leedaa91e42017-12-06 14:13:01 -08001517 reset(false /* clearRequest */);
1518
Wale Ogunwale01d66562015-12-29 08:19:19 -08001519 mStartActivity = r;
1520 mIntent = r.intent;
1521 mOptions = options;
1522 mCallingUid = r.launchedFromUid;
1523 mSourceRecord = sourceRecord;
1524 mVoiceSession = voiceSession;
1525 mVoiceInteractor = voiceInteractor;
1526
David Stevense5a7b642017-05-22 13:18:23 -07001527 mPreferredDisplayId = getPreferedDisplayId(mSourceRecord, mStartActivity, options);
David Stevensc6b91c62017-02-08 14:23:58 -08001528
Bryce Leeec55eb02017-12-05 20:51:27 -08001529 mLaunchParams.reset();
Bryce Leedacefc42017-10-10 12:56:02 -07001530
Bryce Leeec55eb02017-12-05 20:51:27 -08001531 mSupervisor.getLaunchParamsController().calculate(inTask, null /*layout*/, r, sourceRecord,
1532 options, mLaunchParams);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001533
Bryce Lee7daee392017-10-12 13:46:18 -07001534 mLaunchMode = r.launchMode;
1535
Wale Ogunwale01d66562015-12-29 08:19:19 -08001536 mLaunchFlags = adjustLaunchFlagsToDocumentMode(
Bryce Lee7daee392017-10-12 13:46:18 -07001537 r, LAUNCH_SINGLE_INSTANCE == mLaunchMode,
1538 LAUNCH_SINGLE_TASK == mLaunchMode, mIntent.getFlags());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001539 mLaunchTaskBehind = r.mLaunchTaskBehind
Bryce Lee7daee392017-10-12 13:46:18 -07001540 && !isLaunchModeOneOf(LAUNCH_SINGLE_TASK, LAUNCH_SINGLE_INSTANCE)
Wale Ogunwale01d66562015-12-29 08:19:19 -08001541 && (mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0;
1542
1543 sendNewTaskResultRequestIfNeeded();
1544
1545 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
1546 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1547 }
1548
1549 // If we are actually going to launch in to a new task, there are some cases where
1550 // we further want to do multiple task.
1551 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1552 if (mLaunchTaskBehind
1553 || r.info.documentLaunchMode == DOCUMENT_LAUNCH_ALWAYS) {
1554 mLaunchFlags |= FLAG_ACTIVITY_MULTIPLE_TASK;
1555 }
1556 }
1557
1558 // We'll invoke onUserLeaving before onPause only if the launching
1559 // activity did not explicitly state that this is an automated launch.
1560 mSupervisor.mUserLeaving = (mLaunchFlags & FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1561 if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
1562 "startActivity() => mUserLeaving=" + mSupervisor.mUserLeaving);
1563
1564 // If the caller has asked not to resume at this point, we make note
1565 // of this in the record so that we can skip it when trying to find
1566 // the top running activity.
1567 mDoResume = doResume;
Chong Zhang87761972016-08-22 13:53:24 -07001568 if (!doResume || !r.okToShowLocked()) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001569 r.delayedResume = true;
1570 mDoResume = false;
1571 }
1572
Winson Chunge2d72172018-01-25 17:46:20 +00001573 if (mOptions != null) {
1574 if (mOptions.getLaunchTaskId() != -1 && mOptions.getTaskOverlay()) {
1575 r.mTaskOverlay = true;
1576 if (!mOptions.canTaskOverlayResume()) {
1577 final TaskRecord task = mSupervisor.anyTaskForIdLocked(
1578 mOptions.getLaunchTaskId());
1579 final ActivityRecord top = task != null ? task.getTopActivity() : null;
Bryce Lee7ace3952018-02-16 14:34:32 -08001580 if (top != null && !top.isState(RESUMED)) {
Jorim Jaggic875ae72016-04-26 22:41:06 -07001581
Winson Chunge2d72172018-01-25 17:46:20 +00001582 // The caller specifies that we'd like to be avoided to be moved to the
1583 // front, so be it!
1584 mDoResume = false;
1585 mAvoidMoveToFront = true;
1586 }
Winson Chungcbcadc92017-01-12 15:54:12 -08001587 }
Winson Chunge2d72172018-01-25 17:46:20 +00001588 } else if (mOptions.getAvoidMoveToFront()) {
Winson Chungba40d3a2018-05-16 09:40:16 -07001589 mDoResume = false;
Winson Chunge2d72172018-01-25 17:46:20 +00001590 mAvoidMoveToFront = true;
Jorim Jaggic875ae72016-04-26 22:41:06 -07001591 }
1592 }
1593
Wale Ogunwale01d66562015-12-29 08:19:19 -08001594 mNotTop = (mLaunchFlags & FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1595
1596 mInTask = inTask;
1597 // In some flows in to this function, we retrieve the task record and hold on to it
1598 // without a lock before calling back in to here... so the task at this point may
1599 // not actually be in recents. Check for that, and if it isn't in recents just
1600 // consider it invalid.
1601 if (inTask != null && !inTask.inRecents) {
1602 Slog.w(TAG, "Starting activity in task not in recents: " + inTask);
1603 mInTask = null;
1604 }
1605
1606 mStartFlags = startFlags;
1607 // If the onlyIfNeeded flag is set, then we can do this if the activity being launched
1608 // is the same as the one making the call... or, as a special case, if we do not know
1609 // the caller then we count the current top activity as the caller.
1610 if ((startFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1611 ActivityRecord checkedCaller = sourceRecord;
1612 if (checkedCaller == null) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001613 checkedCaller = mSupervisor.getTopDisplayFocusedStack()
1614 .topRunningNonDelayedActivityLocked(mNotTop);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001615 }
1616 if (!checkedCaller.realActivity.equals(r.realActivity)) {
1617 // Caller is not the same as launcher, so always needed.
1618 mStartFlags &= ~START_FLAG_ONLY_IF_NEEDED;
1619 }
1620 }
1621
1622 mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0;
1623 }
1624
1625 private void sendNewTaskResultRequestIfNeeded() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001626 final ActivityStack sourceStack = mStartActivity.resultTo != null
1627 ? mStartActivity.resultTo.getStack() : null;
1628 if (sourceStack != null && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001629 // For whatever reason this activity is being launched into a new task...
1630 // yet the caller has requested a result back. Well, that is pretty messed up,
1631 // so instead immediately send back a cancel and let the new task continue launched
1632 // as normal without a dependency on its originator.
1633 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
Andrii Kulian02b7a832016-10-06 23:11:56 -07001634 sourceStack.sendActivityResultLocked(-1 /* callingUid */, mStartActivity.resultTo,
1635 mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,
1636 null /* data */);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001637 mStartActivity.resultTo = null;
1638 }
1639 }
1640
1641 private void computeLaunchingTaskFlags() {
1642 // If the caller is not coming from another activity, but has given us an explicit task into
1643 // which they would like us to launch the new activity, then let's see about doing that.
Andrii Kulian02b7a832016-10-06 23:11:56 -07001644 if (mSourceRecord == null && mInTask != null && mInTask.getStack() != null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001645 final Intent baseIntent = mInTask.getBaseIntent();
1646 final ActivityRecord root = mInTask.getRootActivity();
1647 if (baseIntent == null) {
1648 ActivityOptions.abort(mOptions);
1649 throw new IllegalArgumentException("Launching into task without base intent: "
1650 + mInTask);
1651 }
1652
1653 // If this task is empty, then we are adding the first activity -- it
1654 // determines the root, and must be launching as a NEW_TASK.
Bryce Lee7daee392017-10-12 13:46:18 -07001655 if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001656 if (!baseIntent.getComponent().equals(mStartActivity.intent.getComponent())) {
1657 ActivityOptions.abort(mOptions);
1658 throw new IllegalArgumentException("Trying to launch singleInstance/Task "
1659 + mStartActivity + " into different task " + mInTask);
1660 }
1661 if (root != null) {
1662 ActivityOptions.abort(mOptions);
1663 throw new IllegalArgumentException("Caller with mInTask " + mInTask
1664 + " has root " + root + " but target is singleInstance/Task");
1665 }
1666 }
1667
1668 // If task is empty, then adopt the interesting intent launch flags in to the
1669 // activity being started.
1670 if (root == null) {
1671 final int flagsOfInterest = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK
1672 | FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS;
1673 mLaunchFlags = (mLaunchFlags & ~flagsOfInterest)
1674 | (baseIntent.getFlags() & flagsOfInterest);
1675 mIntent.setFlags(mLaunchFlags);
1676 mInTask.setIntent(mStartActivity);
1677 mAddingToTask = true;
1678
1679 // If the task is not empty and the caller is asking to start it as the root of
1680 // a new task, then we don't actually want to start this on the task. We will
1681 // bring the task to the front, and possibly give it a new intent.
1682 } else if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1683 mAddingToTask = false;
1684
1685 } else {
1686 mAddingToTask = true;
1687 }
1688
1689 mReuseTask = mInTask;
1690 } else {
1691 mInTask = null;
1692 // Launch ResolverActivity in the source task, so that it stays in the task bounds
1693 // when in freeform workspace.
1694 // Also put noDisplay activities in the source task. These by itself can be placed
1695 // in any task/stack, however it could launch other activities like ResolverActivity,
1696 // and we want those to stay in the original task.
1697 if ((mStartActivity.isResolverActivity() || mStartActivity.noDisplay) && mSourceRecord != null
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001698 && mSourceRecord.inFreeformWindowingMode()) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001699 mAddingToTask = true;
1700 }
1701 }
1702
1703 if (mInTask == null) {
1704 if (mSourceRecord == null) {
1705 // This activity is not being started from another... in this
1706 // case we -always- start a new task.
1707 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) {
1708 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1709 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
1710 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1711 }
1712 } else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) {
1713 // The original activity who is starting us is running as a single
1714 // instance... this new activity it is starting must go on its
1715 // own task.
1716 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
Bryce Lee7daee392017-10-12 13:46:18 -07001717 } else if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001718 // The activity being started is a single instance... it always
1719 // gets launched into its own task.
1720 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1721 }
1722 }
1723 }
1724
1725 private void computeSourceStack() {
1726 if (mSourceRecord == null) {
1727 mSourceStack = null;
1728 return;
1729 }
1730 if (!mSourceRecord.finishing) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001731 mSourceStack = mSourceRecord.getStack();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001732 return;
1733 }
1734
1735 // If the source is finishing, we can't further count it as our source. This is because the
1736 // task it is associated with may now be empty and on its way out, so we don't want to
1737 // blindly throw it in to that task. Instead we will take the NEW_TASK flow and try to find
1738 // a task for it. But save the task information so it can be used when creating the new task.
1739 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0) {
1740 Slog.w(TAG, "startActivity called from finishing " + mSourceRecord
1741 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
1742 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1743 mNewTaskInfo = mSourceRecord.info;
Bryce Leed9ed45d2017-05-22 15:57:24 -07001744
1745 // It is not guaranteed that the source record will have a task associated with it. For,
1746 // example, if this method is being called for processing a pending activity launch, it
1747 // is possible that the activity has been removed from the task after the launch was
1748 // enqueued.
1749 final TaskRecord sourceTask = mSourceRecord.getTask();
1750 mNewTaskIntent = sourceTask != null ? sourceTask.intent : null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001751 }
1752 mSourceRecord = null;
1753 mSourceStack = null;
1754 }
1755
1756 /**
1757 * Decide whether the new activity should be inserted into an existing task. Returns null
1758 * if not or an ActivityRecord with the task into which the new activity should be added.
1759 */
1760 private ActivityRecord getReusableIntentActivity() {
1761 // We may want to try to place the new activity in to an existing task. We always
1762 // do this if the target activity is singleTask or singleInstance; we will also do
1763 // this if NEW_TASK has been requested, and there is not an additional qualifier telling
1764 // us to still place it in a new task: multi task, always doc mode, or being asked to
1765 // launch this as a new task behind the current one.
1766 boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 &&
1767 (mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
Bryce Lee7daee392017-10-12 13:46:18 -07001768 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001769 // If bring to front is requested, and no result is requested and we have not been given
1770 // an explicit task to launch in to, and we can find a task that was started with this
1771 // same component, then instead of launching bring that one to the front.
1772 putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null;
1773 ActivityRecord intentActivity = null;
Jorim Jaggi2adba072016-03-03 13:43:39 +01001774 if (mOptions != null && mOptions.getLaunchTaskId() != -1) {
1775 final TaskRecord task = mSupervisor.anyTaskForIdLocked(mOptions.getLaunchTaskId());
1776 intentActivity = task != null ? task.getTopActivity() : null;
1777 } else if (putIntoExistingTask) {
Bryce Lee7daee392017-10-12 13:46:18 -07001778 if (LAUNCH_SINGLE_INSTANCE == mLaunchMode) {
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07001779 // There can be one and only one instance of single instance activity in the
1780 // history, and it is always in its own unique task, so we do a special search.
Bryce Lee28d80422017-07-21 13:25:13 -07001781 intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001782 mStartActivity.isActivityTypeHome());
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07001783 } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
1784 // For the launch adjacent case we only want to put the activity in an existing
1785 // task if the activity already exists in the history.
Andrii Kulian039ba482016-06-22 17:16:45 -07001786 intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info,
Bryce Lee7daee392017-10-12 13:46:18 -07001787 !(LAUNCH_SINGLE_TASK == mLaunchMode));
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07001788 } else {
1789 // Otherwise find the best task to put the activity in.
David Stevense5a7b642017-05-22 13:18:23 -07001790 intentActivity = mSupervisor.findTaskLocked(mStartActivity, mPreferredDisplayId);
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07001791 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001792 }
1793 return intentActivity;
1794 }
1795
Andrii Kulianfab9cd82017-03-21 19:37:09 -07001796 /**
Karthik Ravi Shankarf29b4c22017-04-06 17:02:01 -07001797 * 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 -07001798 * then return the Vr mode's virtual display ID. If not, if the activity was started with
1799 * a launchDisplayId, use that. Otherwise, if the source activity has a explicit display ID
1800 * set, use that to launch the activity.
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -08001801 */
David Stevense5a7b642017-05-22 13:18:23 -07001802 private int getPreferedDisplayId(
1803 ActivityRecord sourceRecord, ActivityRecord startingActivity, ActivityOptions options) {
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -08001804 // Check if the Activity is a VR activity. If so, the activity should be launched in
1805 // main display.
1806 if (startingActivity != null && startingActivity.requestedVrComponent != null) {
1807 return DEFAULT_DISPLAY;
1808 }
1809
1810 // Get the virtual display id from ActivityManagerService.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001811 int displayId = mService.mVr2dDisplayId;
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -08001812 if (displayId != INVALID_DISPLAY) {
1813 if (DEBUG_STACK) {
1814 Slog.d(TAG, "getSourceDisplayId :" + displayId);
1815 }
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -08001816 return displayId;
1817 }
Karthik Ravi Shankarf29b4c22017-04-06 17:02:01 -07001818
David Stevense5a7b642017-05-22 13:18:23 -07001819 // If the caller requested a display, prefer that display.
1820 final int launchDisplayId =
1821 (options != null) ? options.getLaunchDisplayId() : INVALID_DISPLAY;
1822 if (launchDisplayId != INVALID_DISPLAY) {
1823 return launchDisplayId;
1824 }
1825
Karthik Ravi Shankarf29b4c22017-04-06 17:02:01 -07001826 displayId = sourceRecord != null ? sourceRecord.getDisplayId() : INVALID_DISPLAY;
1827 // If the activity has a displayId set explicitly, launch it on the same displayId.
1828 if (displayId != INVALID_DISPLAY) {
1829 return displayId;
1830 }
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -08001831 return DEFAULT_DISPLAY;
1832 }
1833
1834 /**
Andrii Kulianfab9cd82017-03-21 19:37:09 -07001835 * Figure out which task and activity to bring to front when we have found an existing matching
1836 * activity record in history. May also clear the task if needed.
1837 * @param intentActivity Existing matching activity.
1838 * @return {@link ActivityRecord} brought to front.
1839 */
Wale Ogunwale01d66562015-12-29 08:19:19 -08001840 private ActivityRecord setTargetStackAndMoveToFrontIfNeeded(ActivityRecord intentActivity) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001841 mTargetStack = intentActivity.getStack();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001842 mTargetStack.mLastPausedActivity = null;
1843 // If the target task is not in the front, then we need to bring it to the front...
1844 // except... well, with SINGLE_TASK_LAUNCH it's not entirely clear. We'd like to have
1845 // the same behavior as if a new instance was being started, which means not bringing it
1846 // to the front if the caller is not itself in the front.
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001847 final ActivityStack focusStack = mSupervisor.getTopDisplayFocusedStack();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001848 ActivityRecord curTop = (focusStack == null)
1849 ? null : focusStack.topRunningNonDelayedActivityLocked(mNotTop);
1850
Bryce Leeaf691c02017-03-20 14:20:22 -07001851 final TaskRecord topTask = curTop != null ? curTop.getTask() : null;
1852 if (topTask != null
1853 && (topTask != intentActivity.getTask() || topTask != focusStack.topTask())
Jorim Jaggic875ae72016-04-26 22:41:06 -07001854 && !mAvoidMoveToFront) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001855 mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Wale Ogunwale30e441d2017-11-09 08:28:45 -08001856 if (mSourceRecord == null || (mSourceStack.getTopActivity() != null &&
1857 mSourceStack.getTopActivity().getTask() == mSourceRecord.getTask())) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001858 // We really do want to push this one into the user's face, right now.
1859 if (mLaunchTaskBehind && mSourceRecord != null) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001860 intentActivity.setTaskToAffiliateWith(mSourceRecord.getTask());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001861 }
Chong Zhangdea4bd92016-03-15 12:50:03 -07001862
1863 // If the launch flags carry both NEW_TASK and CLEAR_TASK, the task's activities
1864 // will be cleared soon by ActivityStarter in setTaskFromIntentActivity().
1865 // So no point resuming any of the activities here, it just wastes one extra
1866 // resuming, plus enter AND exit transitions.
1867 // Here we only want to bring the target stack forward. Transition will be applied
1868 // to the new activity that's started after the old ones are gone.
1869 final boolean willClearTask =
1870 (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1871 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
1872 if (!willClearTask) {
1873 final ActivityStack launchStack = getLaunchStack(
Bryce Leeaf691c02017-03-20 14:20:22 -07001874 mStartActivity, mLaunchFlags, mStartActivity.getTask(), mOptions);
1875 final TaskRecord intentTask = intentActivity.getTask();
Chong Zhangdea4bd92016-03-15 12:50:03 -07001876 if (launchStack == null || launchStack == mTargetStack) {
1877 // We only want to move to the front, if we aren't going to launch on a
1878 // different stack. If we launch on a different stack, we will put the
1879 // task on top there.
chaviw0d562bf2018-03-15 14:24:14 -07001880 mTargetStack.moveTaskToFrontLocked(intentTask, mNoAnimation, mOptions,
1881 mStartActivity.appTimeTracker, "bringingFoundTaskToFront");
Chong Zhangdea4bd92016-03-15 12:50:03 -07001882 mMovedToFront = true;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001883 } else if (launchStack.inSplitScreenWindowingMode()) {
Andrii Kulianad6f2e52016-06-15 15:27:01 -07001884 if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
1885 // If we want to launch adjacent and mTargetStack is not the computed
1886 // launch stack - move task to top of computed stack.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001887 intentTask.reparent(launchStack, ON_TOP,
Winson Chung74666102017-02-22 17:49:24 -08001888 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
1889 "launchToSide");
Andrii Kulianad6f2e52016-06-15 15:27:01 -07001890 } else {
1891 // TODO: This should be reevaluated in MW v2.
1892 // We choose to move task to front instead of launching it adjacent
1893 // when specific stack was requested explicitly and it appeared to be
1894 // adjacent stack, but FLAG_ACTIVITY_LAUNCH_ADJACENT was not set.
chaviw0d562bf2018-03-15 14:24:14 -07001895 mTargetStack.moveTaskToFrontLocked(intentTask,
Bryce Leeaf691c02017-03-20 14:20:22 -07001896 mNoAnimation, mOptions, mStartActivity.appTimeTracker,
Andrii Kulianad6f2e52016-06-15 15:27:01 -07001897 "bringToFrontInsteadOfAdjacentLaunch");
1898 }
Bryce Lee32e09ef2018-03-19 15:29:49 -07001899 mMovedToFront = launchStack != launchStack.getDisplay()
1900 .getTopStackInWindowingMode(launchStack.getWindowingMode());
Andrii Kulianfab9cd82017-03-21 19:37:09 -07001901 } else if (launchStack.mDisplayId != mTargetStack.mDisplayId) {
1902 // Target and computed stacks are on different displays and we've
1903 // found a matching task - move the existing instance to that display and
1904 // move it to front.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001905 intentActivity.getTask().reparent(launchStack, ON_TOP,
Andrii Kulianfab9cd82017-03-21 19:37:09 -07001906 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
1907 "reparentToDisplay");
1908 mMovedToFront = true;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001909 } else if (launchStack.isActivityTypeHome()
1910 && !mTargetStack.isActivityTypeHome()) {
Bryce Lee4ff7da92017-07-17 10:39:24 -07001911 // It is possible for the home activity to be in another stack initially.
1912 // For example, the activity may have been initially started with an intent
1913 // which placed it in the fullscreen stack. To ensure the proper handling of
1914 // the activity based on home stack assumptions, we must move it over.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001915 intentActivity.getTask().reparent(launchStack, ON_TOP,
Bryce Lee4ff7da92017-07-17 10:39:24 -07001916 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
1917 "reparentingHome");
1918 mMovedToFront = true;
Chong Zhangdea4bd92016-03-15 12:50:03 -07001919 }
1920 mOptions = null;
Jorim Jaggi02886a82016-12-06 09:10:06 -08001921
1922 // We are moving a task to the front, use starting window to hide initial drawn
1923 // delay.
1924 intentActivity.showStartingWindow(null /* prev */, false /* newTask */,
1925 true /* taskSwitch */);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001926 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001927 }
1928 }
Andrii Kulianb850ea52017-12-12 23:49:10 -08001929 // Need to update mTargetStack because if task was moved out of it, the original stack may
1930 // be destroyed.
1931 mTargetStack = intentActivity.getStack();
Winson Chungba40d3a2018-05-16 09:40:16 -07001932 if (!mMovedToFront && mDoResume) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001933 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Bring to front target: " + mTargetStack
1934 + " from " + intentActivity);
1935 mTargetStack.moveToFront("intentActivityFound");
1936 }
1937
Wale Ogunwale0568aed2017-09-08 13:29:37 -07001938 mSupervisor.handleNonResizableTaskIfNeeded(intentActivity.getTask(),
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07001939 WINDOWING_MODE_UNDEFINED, DEFAULT_DISPLAY, mTargetStack);
Jorim Jaggid53f0922016-04-06 22:16:23 -07001940
Wale Ogunwale01d66562015-12-29 08:19:19 -08001941 // If the caller has requested that the target task be reset, then do so.
1942 if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1943 return mTargetStack.resetTaskIfNeededLocked(intentActivity, mStartActivity);
1944 }
1945 return intentActivity;
1946 }
1947
1948 private void setTaskFromIntentActivity(ActivityRecord intentActivity) {
1949 if ((mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1950 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {
1951 // The caller has requested to completely replace any existing task with its new
1952 // activity. Well that should not be too hard...
Bryce Lee41801b42017-03-02 13:23:12 -08001953 // Note: we must persist the {@link TaskRecord} first as intentActivity could be
1954 // removed from calling performClearTaskLocked (For example, if it is being brought out
Bryce Lee59dad4e2017-03-09 11:54:08 -08001955 // of history or if it is finished immediately), thus disassociating the task. Also note
1956 // that mReuseTask is reset as a result of {@link TaskRecord#performClearTaskLocked}
1957 // launching another activity.
1958 // TODO(b/36119896): We shouldn't trigger activity launches in this path since we are
1959 // already launching one.
Bryce Leeaf691c02017-03-20 14:20:22 -07001960 final TaskRecord task = intentActivity.getTask();
Bryce Lee59dad4e2017-03-09 11:54:08 -08001961 task.performClearTaskLocked();
1962 mReuseTask = task;
Bryce Lee41801b42017-03-02 13:23:12 -08001963 mReuseTask.setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001964 } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
Bryce Lee7daee392017-10-12 13:46:18 -07001965 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001966 ActivityRecord top = intentActivity.getTask().performClearTaskLocked(mStartActivity,
Wale Ogunwale01d66562015-12-29 08:19:19 -08001967 mLaunchFlags);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001968 if (top == null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001969 // A special case: we need to start the activity because it is not currently
1970 // running, and the caller has asked to clear the current task to have this
1971 // activity at the top.
1972 mAddingToTask = true;
Bryce Lee353112c2017-02-23 09:46:45 -08001973
1974 // We are no longer placing the activity in the task we previously thought we were.
Bryce Leeaf691c02017-03-20 14:20:22 -07001975 mStartActivity.setTask(null);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001976 // Now pretend like this activity is being started by the top of its task, so it
1977 // is put in the right place.
1978 mSourceRecord = intentActivity;
Bryce Leeaf691c02017-03-20 14:20:22 -07001979 final TaskRecord task = mSourceRecord.getTask();
Andrii Kulian02b7a832016-10-06 23:11:56 -07001980 if (task != null && task.getStack() == null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001981 // Target stack got cleared when we all activities were removed above.
1982 // Go ahead and reset it.
1983 mTargetStack = computeStackFocus(mSourceRecord, false /* newTask */,
Bryce Leedacefc42017-10-10 12:56:02 -07001984 mLaunchFlags, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001985 mTargetStack.addTask(task,
1986 !mLaunchTaskBehind /* toTop */, "startActivityUnchecked");
1987 }
1988 }
Bryce Leeaf691c02017-03-20 14:20:22 -07001989 } else if (mStartActivity.realActivity.equals(intentActivity.getTask().realActivity)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001990 // In this case the top activity on the task is the same as the one being launched,
1991 // so we take that as a request to bring the task to the foreground. If the top
1992 // activity in the task is the root activity, deliver this new intent to it if it
1993 // desires.
Bryce Lee7daee392017-10-12 13:46:18 -07001994 if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
1995 || LAUNCH_SINGLE_TOP == mLaunchMode)
Wale Ogunwale01d66562015-12-29 08:19:19 -08001996 && intentActivity.realActivity.equals(mStartActivity.realActivity)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001997 if (intentActivity.frontOfTask) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001998 intentActivity.getTask().setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001999 }
Bryce Lee325e09682017-10-05 17:20:25 -07002000 deliverNewIntent(intentActivity);
Bryce Leeaf691c02017-03-20 14:20:22 -07002001 } else if (!intentActivity.getTask().isSameIntentFilter(mStartActivity)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002002 // In this case we are launching the root activity of the task, but with a
2003 // different intent. We should start a new instance on top.
2004 mAddingToTask = true;
2005 mSourceRecord = intentActivity;
2006 }
2007 } else if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
2008 // In this case an activity is being launched in to an existing task, without
2009 // resetting that task. This is typically the situation of launching an activity
2010 // from a notification or shortcut. We want to place the new activity on top of the
2011 // current task.
2012 mAddingToTask = true;
2013 mSourceRecord = intentActivity;
Bryce Leeaf691c02017-03-20 14:20:22 -07002014 } else if (!intentActivity.getTask().rootWasReset) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002015 // In this case we are launching into an existing task that has not yet been started
2016 // from its front door. The current task has been brought to the front. Ideally,
2017 // we'd probably like to place this new task at the bottom of its stack, but that's
2018 // a little hard to do with the current organization of the code so for now we'll
2019 // just drop it.
Bryce Leeaf691c02017-03-20 14:20:22 -07002020 intentActivity.getTask().setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002021 }
2022 }
2023
2024 private void resumeTargetStackIfNeeded() {
2025 if (mDoResume) {
2026 mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, null, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002027 } else {
2028 ActivityOptions.abort(mOptions);
2029 }
2030 mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);
2031 }
2032
Chong Zhang6cda19c2016-06-14 19:07:56 -07002033 private int setTaskFromReuseOrCreateNewTask(
Wale Ogunwale0568aed2017-09-08 13:29:37 -07002034 TaskRecord taskToAffiliate, ActivityStack topStack) {
Bryce Leedacefc42017-10-10 12:56:02 -07002035 mTargetStack = computeStackFocus(mStartActivity, true, mLaunchFlags, mOptions);
Chong Zhang6cda19c2016-06-14 19:07:56 -07002036
2037 // Do no move the target stack to front yet, as we might bail if
2038 // isLockTaskModeViolation fails below.
Wale Ogunwale01d66562015-12-29 08:19:19 -08002039
2040 if (mReuseTask == null) {
Suprabh Shukla09a88f52015-12-02 14:36:31 -08002041 final TaskRecord task = mTargetStack.createTaskRecord(
2042 mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId),
Wale Ogunwale01d66562015-12-29 08:19:19 -08002043 mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
Wale Ogunwale72919d22016-12-08 18:58:50 -08002044 mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
Bryce Leeb802ea12017-11-15 21:25:03 -08002045 mVoiceInteractor, !mLaunchTaskBehind /* toTop */, mStartActivity, mSourceRecord,
2046 mOptions);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002047 addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
Bryce Leeec55eb02017-12-05 20:51:27 -08002048 updateBounds(mStartActivity.getTask(), mLaunchParams.mBounds);
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002049
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002050 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Bryce Leeaf691c02017-03-20 14:20:22 -07002051 + " in new task " + mStartActivity.getTask());
Wale Ogunwale01d66562015-12-29 08:19:19 -08002052 } else {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002053 addOrReparentStartingActivity(mReuseTask, "setTaskFromReuseOrCreateNewTask");
2054 }
2055
2056 if (taskToAffiliate != null) {
2057 mStartActivity.setTaskToAffiliateWith(taskToAffiliate);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002058 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07002059
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07002060 if (mService.getLockTaskController().isLockTaskModeViolation(mStartActivity.getTask())) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002061 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
2062 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
2063 }
2064
Chong Zhang6cda19c2016-06-14 19:07:56 -07002065 if (mDoResume) {
2066 mTargetStack.moveToFront("reuseOrNewTask");
2067 }
2068 return START_SUCCESS;
Wale Ogunwale01d66562015-12-29 08:19:19 -08002069 }
2070
Bryce Lee325e09682017-10-05 17:20:25 -07002071 private void deliverNewIntent(ActivityRecord activity) {
2072 if (mIntentDelivered) {
2073 return;
2074 }
2075
2076 ActivityStack.logStartActivity(AM_NEW_INTENT, activity, activity.getTask());
2077 activity.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
2078 mStartActivity.launchedFromPackage);
2079 mIntentDelivered = true;
2080 }
2081
Wale Ogunwale01d66562015-12-29 08:19:19 -08002082 private int setTaskFromSourceRecord() {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07002083 if (mService.getLockTaskController().isLockTaskModeViolation(mSourceRecord.getTask())) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002084 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
2085 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
2086 }
2087
Bryce Leeaf691c02017-03-20 14:20:22 -07002088 final TaskRecord sourceTask = mSourceRecord.getTask();
Andrii Kulian02b7a832016-10-06 23:11:56 -07002089 final ActivityStack sourceStack = mSourceRecord.getStack();
Andrii Kulian02689a72017-07-06 14:28:59 -07002090 // We only want to allow changing stack in two cases:
2091 // 1. If the target task is not the top one. Otherwise we would move the launching task to
2092 // the other side, rather than show two side by side.
2093 // 2. If activity is not allowed on target display.
2094 final int targetDisplayId = mTargetStack != null ? mTargetStack.mDisplayId
2095 : sourceStack.mDisplayId;
2096 final boolean moveStackAllowed = sourceStack.topTask() != sourceTask
2097 || !mStartActivity.canBeLaunchedOnDisplay(targetDisplayId);
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002098 if (moveStackAllowed) {
Bryce Leeaf691c02017-03-20 14:20:22 -07002099 mTargetStack = getLaunchStack(mStartActivity, mLaunchFlags, mStartActivity.getTask(),
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002100 mOptions);
Andrii Kulian02689a72017-07-06 14:28:59 -07002101 // If target stack is not found now - we can't just rely on the source stack, as it may
2102 // be not suitable. Let's check other displays.
2103 if (mTargetStack == null && targetDisplayId != sourceStack.mDisplayId) {
2104 // Can't use target display, lets find a stack on the source display.
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07002105 mTargetStack = mSupervisor.getValidLaunchStackOnDisplay(
Louis Chang6322c422018-07-18 18:37:28 +08002106 sourceStack.mDisplayId, mStartActivity, mOptions);
Andrii Kulian02689a72017-07-06 14:28:59 -07002107 }
2108 if (mTargetStack == null) {
2109 // There are no suitable stacks on the target and source display(s). Look on all
2110 // displays.
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07002111 mTargetStack = mSupervisor.getNextValidLaunchStackLocked(
Andrii Kulian02689a72017-07-06 14:28:59 -07002112 mStartActivity, -1 /* currentFocus */);
2113 }
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002114 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002115
2116 if (mTargetStack == null) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07002117 mTargetStack = sourceStack;
2118 } else if (mTargetStack != sourceStack) {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002119 sourceTask.reparent(mTargetStack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE,
2120 DEFER_RESUME, "launchToSide");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002121 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07002122
Wale Ogunwale01d66562015-12-29 08:19:19 -08002123 final TaskRecord topTask = mTargetStack.topTask();
Jorim Jaggic875ae72016-04-26 22:41:06 -07002124 if (topTask != sourceTask && !mAvoidMoveToFront) {
chaviw0d562bf2018-03-15 14:24:14 -07002125 mTargetStack.moveTaskToFrontLocked(sourceTask, mNoAnimation, mOptions,
Wale Ogunwale01d66562015-12-29 08:19:19 -08002126 mStartActivity.appTimeTracker, "sourceTaskToFront");
Chong Zhang6cda19c2016-06-14 19:07:56 -07002127 } else if (mDoResume) {
2128 mTargetStack.moveToFront("sourceStackToFront");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002129 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07002130
Wale Ogunwale01d66562015-12-29 08:19:19 -08002131 if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0) {
2132 // In this case, we are adding the activity to an existing task, but the caller has
2133 // asked to clear that task if the activity is already running.
2134 ActivityRecord top = sourceTask.performClearTaskLocked(mStartActivity, mLaunchFlags);
2135 mKeepCurTransition = true;
2136 if (top != null) {
Bryce Leeaf691c02017-03-20 14:20:22 -07002137 ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, top.getTask());
Bryce Lee325e09682017-10-05 17:20:25 -07002138 deliverNewIntent(top);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002139 // For paranoia, make sure we have correctly resumed the top activity.
2140 mTargetStack.mLastPausedActivity = null;
2141 if (mDoResume) {
2142 mSupervisor.resumeFocusedStackTopActivityLocked();
2143 }
2144 ActivityOptions.abort(mOptions);
2145 return START_DELIVERED_TO_TOP;
2146 }
2147 } else if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
2148 // In this case, we are launching an activity in our own task that may already be
2149 // running somewhere in the history, and we want to shuffle it to the front of the
2150 // stack if so.
2151 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(mStartActivity);
2152 if (top != null) {
Bryce Leeaf691c02017-03-20 14:20:22 -07002153 final TaskRecord task = top.getTask();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002154 task.moveActivityToFrontLocked(top);
2155 top.updateOptionsLocked(mOptions);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08002156 ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, task);
Bryce Lee325e09682017-10-05 17:20:25 -07002157 deliverNewIntent(top);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002158 mTargetStack.mLastPausedActivity = null;
2159 if (mDoResume) {
2160 mSupervisor.resumeFocusedStackTopActivityLocked();
2161 }
2162 return START_DELIVERED_TO_TOP;
2163 }
2164 }
2165
2166 // An existing activity is starting this new activity, so we want to keep the new one in
2167 // the same task as the one that is starting it.
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002168 addOrReparentStartingActivity(sourceTask, "setTaskFromSourceRecord");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002169 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Bryce Leeaf691c02017-03-20 14:20:22 -07002170 + " in existing task " + mStartActivity.getTask() + " from source " + mSourceRecord);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002171 return START_SUCCESS;
2172 }
2173
2174 private int setTaskFromInTask() {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002175 // The caller is asking that the new activity be started in an explicit
2176 // task it has provided to us.
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07002177 if (mService.getLockTaskController().isLockTaskModeViolation(mInTask)) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002178 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
2179 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
2180 }
2181
Andrii Kulian02b7a832016-10-06 23:11:56 -07002182 mTargetStack = mInTask.getStack();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002183
2184 // Check whether we should actually launch the new activity in to the task,
2185 // or just reuse the current activity on top.
2186 ActivityRecord top = mInTask.getTopActivity();
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002187 if (top != null && top.realActivity.equals(mStartActivity.realActivity)
2188 && top.userId == mStartActivity.userId) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002189 if ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
Bryce Lee7daee392017-10-12 13:46:18 -07002190 || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK)) {
chaviw0d562bf2018-03-15 14:24:14 -07002191 mTargetStack.moveTaskToFrontLocked(mInTask, mNoAnimation, mOptions,
Yorke Lee64512522017-03-24 13:09:35 -07002192 mStartActivity.appTimeTracker, "inTaskToFront");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002193 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
2194 // We don't need to start a new activity, and the client said not to do
2195 // anything if that is the case, so this is it!
2196 return START_RETURN_INTENT_TO_CALLER;
2197 }
Bryce Lee325e09682017-10-05 17:20:25 -07002198 deliverNewIntent(top);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002199 return START_DELIVERED_TO_TOP;
2200 }
2201 }
2202
2203 if (!mAddingToTask) {
chaviw0d562bf2018-03-15 14:24:14 -07002204 mTargetStack.moveTaskToFrontLocked(mInTask, mNoAnimation, mOptions,
Yorke Lee64512522017-03-24 13:09:35 -07002205 mStartActivity.appTimeTracker, "inTaskToFront");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002206 // We don't actually want to have this activity added to the task, so just
2207 // stop here but still tell the caller that we consumed the intent.
2208 ActivityOptions.abort(mOptions);
2209 return START_TASK_TO_FRONT;
2210 }
2211
Bryce Leeec55eb02017-12-05 20:51:27 -08002212 if (!mLaunchParams.mBounds.isEmpty()) {
Wale Ogunwale0568aed2017-09-08 13:29:37 -07002213 // TODO: Shouldn't we already know what stack to use by the time we get here?
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002214 ActivityStack stack = mSupervisor.getLaunchStack(null, null, mInTask, ON_TOP);
2215 if (stack != mInTask.getStack()) {
2216 mInTask.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, !ANIMATE,
Yorke Lee64512522017-03-24 13:09:35 -07002217 DEFER_RESUME, "inTaskToFront");
Yorke Lee64512522017-03-24 13:09:35 -07002218 mTargetStack = mInTask.getStack();
2219 }
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002220
Bryce Leeec55eb02017-12-05 20:51:27 -08002221 updateBounds(mInTask, mLaunchParams.mBounds);
Yorke Lee64512522017-03-24 13:09:35 -07002222 }
2223
chaviw0d562bf2018-03-15 14:24:14 -07002224 mTargetStack.moveTaskToFrontLocked(
2225 mInTask, mNoAnimation, mOptions, mStartActivity.appTimeTracker, "inTaskToFront");
Yorke Lee64512522017-03-24 13:09:35 -07002226
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002227 addOrReparentStartingActivity(mInTask, "setTaskFromInTask");
2228 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Bryce Leeaf691c02017-03-20 14:20:22 -07002229 + " in explicit task " + mStartActivity.getTask());
Wale Ogunwale01d66562015-12-29 08:19:19 -08002230
2231 return START_SUCCESS;
2232 }
2233
Bryce Leed3624e12017-11-30 08:51:45 -08002234 @VisibleForTesting
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002235 void updateBounds(TaskRecord task, Rect bounds) {
Bryce Leedacefc42017-10-10 12:56:02 -07002236 if (bounds.isEmpty()) {
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002237 return;
2238 }
2239
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002240 final ActivityStack stack = task.getStack();
2241 if (stack != null && stack.resizeStackWithLaunchBounds()) {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07002242 mService.resizeStack(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002243 stack.mStackId, bounds, true, !PRESERVE_WINDOWS, ANIMATE, -1);
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002244 } else {
2245 task.updateOverrideConfiguration(bounds);
2246 }
2247 }
2248
Wale Ogunwale01d66562015-12-29 08:19:19 -08002249 private void setTaskToCurrentTopOrCreateNewTask() {
Bryce Leedacefc42017-10-10 12:56:02 -07002250 mTargetStack = computeStackFocus(mStartActivity, false, mLaunchFlags, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002251 if (mDoResume) {
2252 mTargetStack.moveToFront("addingToTopTask");
2253 }
Wale Ogunwale30e441d2017-11-09 08:28:45 -08002254 final ActivityRecord prev = mTargetStack.getTopActivity();
Bryce Leeaf691c02017-03-20 14:20:22 -07002255 final TaskRecord task = (prev != null) ? prev.getTask() : mTargetStack.createTaskRecord(
Wale Ogunwale72919d22016-12-08 18:58:50 -08002256 mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId), mStartActivity.info,
Bryce Leeb802ea12017-11-15 21:25:03 -08002257 mIntent, null, null, true, mStartActivity, mSourceRecord, mOptions);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002258 addOrReparentStartingActivity(task, "setTaskToCurrentTopOrCreateNewTask");
2259 mTargetStack.positionChildWindowContainerAtTop(task);
2260 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Bryce Leeaf691c02017-03-20 14:20:22 -07002261 + " in new guessed " + mStartActivity.getTask());
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002262 }
2263
2264 private void addOrReparentStartingActivity(TaskRecord parent, String reason) {
Bryce Leeaf691c02017-03-20 14:20:22 -07002265 if (mStartActivity.getTask() == null || mStartActivity.getTask() == parent) {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002266 parent.addActivityToTop(mStartActivity);
2267 } else {
2268 mStartActivity.reparent(parent, parent.mActivities.size() /* top */, reason);
2269 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002270 }
2271
2272 private int adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance,
2273 boolean launchSingleTask, int launchFlags) {
2274 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2275 (launchSingleInstance || launchSingleTask)) {
2276 // We have a conflict between the Intent and the Activity manifest, manifest wins.
2277 Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " +
2278 "\"singleInstance\" or \"singleTask\"");
2279 launchFlags &=
2280 ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK);
2281 } else {
2282 switch (r.info.documentLaunchMode) {
2283 case ActivityInfo.DOCUMENT_LAUNCH_NONE:
2284 break;
2285 case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
2286 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2287 break;
2288 case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
2289 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2290 break;
2291 case ActivityInfo.DOCUMENT_LAUNCH_NEVER:
2292 launchFlags &= ~FLAG_ACTIVITY_MULTIPLE_TASK;
2293 break;
2294 }
2295 }
2296 return launchFlags;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002297 }
2298
Bryce Leedacefc42017-10-10 12:56:02 -07002299 private ActivityStack computeStackFocus(ActivityRecord r, boolean newTask, int launchFlags,
2300 ActivityOptions aOptions) {
Bryce Leeaf691c02017-03-20 14:20:22 -07002301 final TaskRecord task = r.getTask();
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002302 ActivityStack stack = getLaunchStack(r, launchFlags, task, aOptions);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002303 if (stack != null) {
2304 return stack;
2305 }
2306
Andrii Kulian02b7a832016-10-06 23:11:56 -07002307 final ActivityStack currentStack = task != null ? task.getStack() : null;
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002308 final ActivityStack focusedStack = mSupervisor.getTopDisplayFocusedStack();
Andrii Kulian02b7a832016-10-06 23:11:56 -07002309 if (currentStack != null) {
Andrii Kulian52d255c2018-07-13 11:32:19 -07002310 if (focusedStack != currentStack) {
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002311 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
2312 "computeStackFocus: Setting " + "focused stack to r=" + r
2313 + " task=" + task);
2314 } else {
2315 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
Andrii Kulian52d255c2018-07-13 11:32:19 -07002316 "computeStackFocus: Focused stack already=" + focusedStack);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002317 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07002318 return currentStack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002319 }
2320
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002321 if (canLaunchIntoFocusedStack(r, newTask)) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002322 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
Andrii Kulian52d255c2018-07-13 11:32:19 -07002323 "computeStackFocus: Have a focused stack=" + focusedStack);
2324 return focusedStack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002325 }
2326
David Stevense5a7b642017-05-22 13:18:23 -07002327 if (mPreferredDisplayId != DEFAULT_DISPLAY) {
Andrii Kuliana8fe3df2017-06-16 15:29:26 -07002328 // Try to put the activity in a stack on a secondary display.
Louis Chang6322c422018-07-18 18:37:28 +08002329 stack = mSupervisor.getValidLaunchStackOnDisplay(mPreferredDisplayId, r, aOptions);
Andrii Kuliana8fe3df2017-06-16 15:29:26 -07002330 if (stack == null) {
2331 // If source display is not suitable - look for topmost valid stack in the system.
2332 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
David Stevense5a7b642017-05-22 13:18:23 -07002333 "computeStackFocus: Can't launch on mPreferredDisplayId="
2334 + mPreferredDisplayId + ", looking on all displays.");
2335 stack = mSupervisor.getNextValidLaunchStackLocked(r, mPreferredDisplayId);
Andrii Kuliana8fe3df2017-06-16 15:29:26 -07002336 }
2337 }
2338 if (stack == null) {
David Stevensc6b91c62017-02-08 14:23:58 -08002339 // We first try to put the task in the first dynamic stack on home display.
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07002340 final ActivityDisplay display = mSupervisor.getDefaultDisplay();
2341 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
2342 stack = display.getChildAt(stackNdx);
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002343 if (!stack.isOnHomeDisplay()) {
David Stevensc6b91c62017-02-08 14:23:58 -08002344 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
2345 "computeStackFocus: Setting focused stack=" + stack);
2346 return stack;
2347 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002348 }
David Stevensc6b91c62017-02-08 14:23:58 -08002349 // If there is no suitable dynamic stack then we figure out which static stack to use.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002350 stack = mSupervisor.getLaunchStack(r, aOptions, task, ON_TOP);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002351 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002352 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, "computeStackFocus: New stack r="
2353 + r + " stackId=" + stack.mStackId);
2354 return stack;
2355 }
2356
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002357 /** Check if provided activity record can launch in currently focused stack. */
Wale Ogunwale68278562017-09-23 17:13:55 -07002358 // TODO: This method can probably be consolidated into getLaunchStack() below.
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002359 private boolean canLaunchIntoFocusedStack(ActivityRecord r, boolean newTask) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002360 final ActivityStack focusedStack = mSupervisor.getTopDisplayFocusedStack();
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002361 final boolean canUseFocusedStack;
Wale Ogunwale68278562017-09-23 17:13:55 -07002362 if (focusedStack.isActivityTypeAssistant()) {
2363 canUseFocusedStack = r.isActivityTypeAssistant();
2364 } else {
2365 switch (focusedStack.getWindowingMode()) {
2366 case WINDOWING_MODE_FULLSCREEN:
2367 // The fullscreen stack can contain any task regardless of if the task is
2368 // resizeable or not. So, we let the task go in the fullscreen task if it is the
2369 // focus stack.
2370 canUseFocusedStack = true;
2371 break;
2372 case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
2373 case WINDOWING_MODE_SPLIT_SCREEN_SECONDARY:
2374 // Any activity which supports split screen can go in the docked stack.
2375 canUseFocusedStack = r.supportsSplitScreenWindowingMode();
2376 break;
2377 case WINDOWING_MODE_FREEFORM:
2378 // Any activity which supports freeform can go in the freeform stack.
2379 canUseFocusedStack = r.supportsFreeform();
2380 break;
2381 default:
2382 // Dynamic stacks behave similarly to the fullscreen stack and can contain any
2383 // resizeable task.
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002384 canUseFocusedStack = !focusedStack.isOnHomeDisplay()
Wale Ogunwale68278562017-09-23 17:13:55 -07002385 && r.canBeLaunchedOnDisplay(focusedStack.mDisplayId);
2386 }
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002387 }
Andrii Kulian94e82d9b02017-07-13 15:33:06 -07002388 return canUseFocusedStack && !newTask
Wale Ogunwale68278562017-09-23 17:13:55 -07002389 // Using the focus stack isn't important enough to override the preferred display.
David Stevense5a7b642017-05-22 13:18:23 -07002390 && (mPreferredDisplayId == focusedStack.mDisplayId);
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002391 }
2392
Wale Ogunwale854809c2015-12-27 16:18:19 -08002393 private ActivityStack getLaunchStack(ActivityRecord r, int launchFlags, TaskRecord task,
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002394 ActivityOptions aOptions) {
Bryce Leea19b5ad2017-06-07 16:54:11 -07002395 // We are reusing a task, keep the stack!
2396 if (mReuseTask != null) {
2397 return mReuseTask.getStack();
2398 }
Jorim Jaggib8c58762016-04-20 17:58:29 -07002399
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -08002400 if (((launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) == 0)
David Stevense5a7b642017-05-22 13:18:23 -07002401 || mPreferredDisplayId != DEFAULT_DISPLAY) {
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08002402 // We don't pass in the default display id into the get launch stack call so it can do a
2403 // full resolution.
2404 final int candidateDisplay =
2405 mPreferredDisplayId != DEFAULT_DISPLAY ? mPreferredDisplayId : INVALID_DISPLAY;
2406 return mSupervisor.getLaunchStack(r, aOptions, task, ON_TOP, candidateDisplay);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002407 }
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002408 // Otherwise handle adjacent launch.
Wale Ogunwale854809c2015-12-27 16:18:19 -08002409
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002410 final ActivityStack focusedStack = mSupervisor.getTopDisplayFocusedStack();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002411 // The parent activity doesn't want to launch the activity on top of itself, but
2412 // instead tries to put it onto other side in side-by-side mode.
Andrii Kulian52d255c2018-07-13 11:32:19 -07002413 final ActivityStack parentStack = task != null ? task.getStack(): focusedStack;
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002414
Andrii Kulian52d255c2018-07-13 11:32:19 -07002415 if (parentStack != focusedStack) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002416 // If task's parent stack is not focused - use it during adjacent launch.
2417 return parentStack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002418 } else {
Andrii Kulian52d255c2018-07-13 11:32:19 -07002419 if (focusedStack != null && task == focusedStack.topTask()) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002420 // If task is already on top of focused stack - use it. We don't want to move the
2421 // existing focused task to adjacent stack, just deliver new intent in this case.
Andrii Kulian52d255c2018-07-13 11:32:19 -07002422 return focusedStack;
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002423 }
2424
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002425 if (parentStack != null && parentStack.inSplitScreenPrimaryWindowingMode()) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002426 // If parent was in docked stack, the natural place to launch another activity
2427 // will be fullscreen, so it can appear alongside the docked window.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002428 final int activityType = mSupervisor.resolveActivityType(r, mOptions, task);
2429 return parentStack.getDisplay().getOrCreateStack(
2430 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, activityType, ON_TOP);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002431 } else {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002432 // If the parent is not in the docked stack, we check if there is docked window
2433 // and if yes, we will launch into that stack. If not, we just put the new
2434 // activity into parent's stack, because we can't find a better place.
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07002435 final ActivityStack dockedStack =
2436 mSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
Wale Ogunwale9dcf9462017-09-19 15:13:01 -07002437 if (dockedStack != null && !dockedStack.shouldBeVisible(r)) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002438 // There is a docked stack, but it isn't visible, so we can't launch into that.
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08002439 return mSupervisor.getLaunchStack(r, aOptions, task, ON_TOP);
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002440 } else {
2441 return dockedStack;
2442 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002443 }
2444 }
2445 }
2446
Bryce Lee7daee392017-10-12 13:46:18 -07002447 private boolean isLaunchModeOneOf(int mode1, int mode2) {
2448 return mode1 == mLaunchMode || mode2 == mLaunchMode;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002449 }
2450
Daichi Hirono15a02992016-04-27 18:47:01 +09002451 static boolean isDocumentLaunchesIntoExisting(int flags) {
2452 return (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2453 (flags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0;
2454 }
liulvpingcfa825f2016-09-26 20:00:15 +08002455
Bryce Lee4c9a5972017-12-01 22:14:24 -08002456 ActivityStarter setIntent(Intent intent) {
2457 mRequest.intent = intent;
2458 return this;
2459 }
2460
Bryce Lee32e09ef2018-03-19 15:29:49 -07002461 @VisibleForTesting
2462 Intent getIntent() {
2463 return mRequest.intent;
2464 }
2465
Bryce Lee4c9a5972017-12-01 22:14:24 -08002466 ActivityStarter setReason(String reason) {
2467 mRequest.reason = reason;
2468 return this;
2469 }
2470
2471 ActivityStarter setCaller(IApplicationThread caller) {
2472 mRequest.caller = caller;
2473 return this;
2474 }
2475
2476 ActivityStarter setEphemeralIntent(Intent intent) {
2477 mRequest.ephemeralIntent = intent;
2478 return this;
2479 }
2480
2481
2482 ActivityStarter setResolvedType(String type) {
2483 mRequest.resolvedType = type;
2484 return this;
2485 }
2486
2487 ActivityStarter setActivityInfo(ActivityInfo info) {
2488 mRequest.activityInfo = info;
2489 return this;
2490 }
2491
2492 ActivityStarter setResolveInfo(ResolveInfo info) {
2493 mRequest.resolveInfo = info;
2494 return this;
2495 }
2496
2497 ActivityStarter setVoiceSession(IVoiceInteractionSession voiceSession) {
2498 mRequest.voiceSession = voiceSession;
2499 return this;
2500 }
2501
2502 ActivityStarter setVoiceInteractor(IVoiceInteractor voiceInteractor) {
2503 mRequest.voiceInteractor = voiceInteractor;
2504 return this;
2505 }
2506
2507 ActivityStarter setResultTo(IBinder resultTo) {
2508 mRequest.resultTo = resultTo;
2509 return this;
2510 }
2511
2512 ActivityStarter setResultWho(String resultWho) {
2513 mRequest.resultWho = resultWho;
2514 return this;
2515 }
2516
2517 ActivityStarter setRequestCode(int requestCode) {
2518 mRequest.requestCode = requestCode;
2519 return this;
2520 }
2521
2522 ActivityStarter setCallingPid(int pid) {
2523 mRequest.callingPid = pid;
2524 return this;
2525 }
2526
2527 ActivityStarter setCallingUid(int uid) {
2528 mRequest.callingUid = uid;
2529 return this;
2530 }
2531
2532 ActivityStarter setCallingPackage(String callingPackage) {
2533 mRequest.callingPackage = callingPackage;
2534 return this;
2535 }
2536
2537 ActivityStarter setRealCallingPid(int pid) {
2538 mRequest.realCallingPid = pid;
2539 return this;
2540 }
2541
2542 ActivityStarter setRealCallingUid(int uid) {
2543 mRequest.realCallingUid = uid;
2544 return this;
2545 }
2546
2547 ActivityStarter setStartFlags(int startFlags) {
2548 mRequest.startFlags = startFlags;
2549 return this;
2550 }
2551
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002552 ActivityStarter setActivityOptions(SafeActivityOptions options) {
Bryce Lee4c9a5972017-12-01 22:14:24 -08002553 mRequest.activityOptions = options;
2554 return this;
2555 }
2556
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002557 ActivityStarter setActivityOptions(Bundle bOptions) {
2558 return setActivityOptions(SafeActivityOptions.fromBundle(bOptions));
2559 }
2560
Bryce Lee4c9a5972017-12-01 22:14:24 -08002561 ActivityStarter setIgnoreTargetSecurity(boolean ignoreTargetSecurity) {
2562 mRequest.ignoreTargetSecurity = ignoreTargetSecurity;
2563 return this;
2564 }
2565
Patrick Baumann31426b22018-05-21 13:46:40 -07002566 ActivityStarter setFilterCallingUid(int filterCallingUid) {
2567 mRequest.filterCallingUid = filterCallingUid;
2568 return this;
2569 }
2570
Bryce Lee4c9a5972017-12-01 22:14:24 -08002571 ActivityStarter setComponentSpecified(boolean componentSpecified) {
2572 mRequest.componentSpecified = componentSpecified;
2573 return this;
2574 }
2575
2576 ActivityStarter setOutActivity(ActivityRecord[] outActivity) {
2577 mRequest.outActivity = outActivity;
2578 return this;
2579 }
2580
2581 ActivityStarter setInTask(TaskRecord inTask) {
2582 mRequest.inTask = inTask;
2583 return this;
2584 }
2585
2586 ActivityStarter setWaitResult(WaitResult result) {
2587 mRequest.waitResult = result;
2588 return this;
2589 }
2590
2591 ActivityStarter setProfilerInfo(ProfilerInfo info) {
2592 mRequest.profilerInfo = info;
2593 return this;
2594 }
2595
2596 ActivityStarter setGlobalConfiguration(Configuration config) {
2597 mRequest.globalConfig = config;
2598 return this;
2599 }
2600
Bryce Lee4c9a5972017-12-01 22:14:24 -08002601 ActivityStarter setUserId(int userId) {
2602 mRequest.userId = userId;
2603 return this;
2604 }
2605
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002606 ActivityStarter setMayWait(int userId) {
Bryce Lee4c9a5972017-12-01 22:14:24 -08002607 mRequest.mayWait = true;
Bryce Lee4c9a5972017-12-01 22:14:24 -08002608 mRequest.userId = userId;
2609
2610 return this;
2611 }
2612
Jorim Jaggi6fa41c32018-04-23 18:35:00 +02002613 ActivityStarter setAllowPendingRemoteAnimationRegistryLookup(boolean allowLookup) {
2614 mRequest.allowPendingRemoteAnimationRegistryLookup = allowLookup;
2615 return this;
2616 }
2617
Bryce Leed3624e12017-11-30 08:51:45 -08002618 void dump(PrintWriter pw, String prefix) {
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002619 prefix = prefix + " ";
Dianne Hackborne676ec72017-07-25 10:55:08 -07002620 pw.print(prefix);
2621 pw.print("mCurrentUser=");
2622 pw.println(mSupervisor.mCurrentUser);
2623 pw.print(prefix);
2624 pw.print("mLastStartReason=");
2625 pw.println(mLastStartReason);
2626 pw.print(prefix);
2627 pw.print("mLastStartActivityTimeMs=");
2628 pw.println(DateFormat.getDateTimeInstance().format(new Date(mLastStartActivityTimeMs)));
2629 pw.print(prefix);
2630 pw.print("mLastStartActivityResult=");
2631 pw.println(mLastStartActivityResult);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002632 ActivityRecord r = mLastStartActivityRecord[0];
2633 if (r != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002634 pw.print(prefix);
2635 pw.println("mLastStartActivityRecord:");
2636 r.dump(pw, prefix + " ");
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002637 }
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002638 if (mStartActivity != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002639 pw.print(prefix);
2640 pw.println("mStartActivity:");
2641 mStartActivity.dump(pw, prefix + " ");
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002642 }
2643 if (mIntent != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002644 pw.print(prefix);
2645 pw.print("mIntent=");
2646 pw.println(mIntent);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002647 }
2648 if (mOptions != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002649 pw.print(prefix);
2650 pw.print("mOptions=");
2651 pw.println(mOptions);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002652 }
Dianne Hackborne676ec72017-07-25 10:55:08 -07002653 pw.print(prefix);
2654 pw.print("mLaunchSingleTop=");
Bryce Lee7daee392017-10-12 13:46:18 -07002655 pw.print(LAUNCH_SINGLE_TOP == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002656 pw.print(" mLaunchSingleInstance=");
Bryce Lee7daee392017-10-12 13:46:18 -07002657 pw.print(LAUNCH_SINGLE_INSTANCE == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002658 pw.print(" mLaunchSingleTask=");
Bryce Lee7daee392017-10-12 13:46:18 -07002659 pw.println(LAUNCH_SINGLE_TASK == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002660 pw.print(prefix);
2661 pw.print("mLaunchFlags=0x");
2662 pw.print(Integer.toHexString(mLaunchFlags));
2663 pw.print(" mDoResume=");
2664 pw.print(mDoResume);
2665 pw.print(" mAddingToTask=");
2666 pw.println(mAddingToTask);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002667 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002668}