blob: 00ba3a61d1d6a940a45855e584a80832d3fe5792 [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;
Michal Karpinski3eab9512018-07-20 15:32:00 +0100102import android.os.Trace;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800103import android.os.UserHandle;
Kenny Guyb1b30262016-02-09 16:02:35 +0000104import android.os.UserManager;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800105import android.service.voice.IVoiceInteractionSession;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700106import android.text.TextUtils;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800107import android.util.EventLog;
Bryce Leedaa91e42017-12-06 14:13:01 -0800108import android.util.Pools.SynchronizedPool;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800109import android.util.Slog;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800110
Bryce Leed3624e12017-11-30 08:51:45 -0800111import com.android.internal.annotations.VisibleForTesting;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800112import com.android.internal.app.HeavyWeightSwitcherActivity;
113import com.android.internal.app.IVoiceInteractor;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800114import com.android.server.am.ActivityStackSupervisor.PendingActivityLaunch;
Bryce Leeec55eb02017-12-05 20:51:27 -0800115import com.android.server.am.LaunchParamsController.LaunchParams;
Todd Kennedy1fb34042017-03-01 13:56:58 -0800116import com.android.server.pm.InstantAppResolver;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800117
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700118import java.io.PrintWriter;
119import java.text.DateFormat;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700120import java.util.Date;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800121
122/**
Bryce Leed3624e12017-11-30 08:51:45 -0800123 * Controller for interpreting how and then launching an activity.
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800124 *
125 * This class collects all the logic for determining how an intent and flags should be turned into
126 * an activity and associated task and stack.
127 */
Wale Ogunwale01d66562015-12-29 08:19:19 -0800128class ActivityStarter {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800129 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStarter" : TAG_AM;
130 private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS;
131 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
132 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
133 private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING;
Bryce Lee7daee392017-10-12 13:46:18 -0700134 private static final int INVALID_LAUNCH_MODE = -1;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800135
136 private final ActivityManagerService mService;
137 private final ActivityStackSupervisor mSupervisor;
Benjamin Franz563707b2017-06-29 15:06:13 +0100138 private final ActivityStartInterceptor mInterceptor;
Bryce Leed3624e12017-11-30 08:51:45 -0800139 private final ActivityStartController mController;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800140
Wale Ogunwale01d66562015-12-29 08:19:19 -0800141 // Share state variable among methods when starting an activity.
142 private ActivityRecord mStartActivity;
143 private Intent mIntent;
144 private int mCallingUid;
145 private ActivityOptions mOptions;
146
Bryce Lee7daee392017-10-12 13:46:18 -0700147 private int mLaunchMode;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800148 private boolean mLaunchTaskBehind;
149 private int mLaunchFlags;
150
Bryce Leeec55eb02017-12-05 20:51:27 -0800151 private LaunchParams mLaunchParams = new LaunchParams();
Wale Ogunwale01d66562015-12-29 08:19:19 -0800152
153 private ActivityRecord mNotTop;
154 private boolean mDoResume;
155 private int mStartFlags;
156 private ActivityRecord mSourceRecord;
Bryce Lee7daee392017-10-12 13:46:18 -0700157
David Stevense5a7b642017-05-22 13:18:23 -0700158 // The display to launch the activity onto, barring any strong reason to do otherwise.
159 private int mPreferredDisplayId;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800160
161 private TaskRecord mInTask;
162 private boolean mAddingToTask;
163 private TaskRecord mReuseTask;
164
165 private ActivityInfo mNewTaskInfo;
166 private Intent mNewTaskIntent;
167 private ActivityStack mSourceStack;
168 private ActivityStack mTargetStack;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800169 private boolean mMovedToFront;
170 private boolean mNoAnimation;
171 private boolean mKeepCurTransition;
Jorim Jaggic875ae72016-04-26 22:41:06 -0700172 private boolean mAvoidMoveToFront;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800173
Bryce Lee325e09682017-10-05 17:20:25 -0700174 // We must track when we deliver the new intent since multiple code paths invoke
175 // {@link #deliverNewIntent}. This is due to early returns in the code path. This flag is used
176 // inside {@link #deliverNewIntent} to suppress duplicate requests and ensure the intent is
177 // delivered at most once.
178 private boolean mIntentDelivered;
179
Wale Ogunwale01d66562015-12-29 08:19:19 -0800180 private IVoiceInteractionSession mVoiceSession;
181 private IVoiceInteractor mVoiceInteractor;
182
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700183 // Last activity record we attempted to start
184 private final ActivityRecord[] mLastStartActivityRecord = new ActivityRecord[1];
185 // The result of the last activity we attempted to start.
186 private int mLastStartActivityResult;
187 // Time in milli seconds we attempted to start the last activity.
188 private long mLastStartActivityTimeMs;
189 // The reason we were trying to start the last activity
190 private String mLastStartReason;
Wale Ogunwale59bcba62017-06-16 12:42:51 -0700191
Bryce Lee4c9a5972017-12-01 22:14:24 -0800192 /*
193 * Request details provided through setter methods. Should be reset after {@link #execute()}
194 * to avoid unnecessarily retaining parameters. Note that the request is ignored when
195 * {@link #startResolvedActivity} is invoked directly.
196 */
197 private Request mRequest = new Request();
198
Bryce Leed3624e12017-11-30 08:51:45 -0800199 /**
200 * An interface that to provide {@link ActivityStarter} instances to the controller. This is
201 * used by tests to inject their own starter implementations for verification purposes.
202 */
203 @VisibleForTesting
204 interface Factory {
205 /**
Bryce Lee4c9a5972017-12-01 22:14:24 -0800206 * Sets the {@link ActivityStartController} to be passed to {@link ActivityStarter}.
207 */
208 void setController(ActivityStartController controller);
209
210 /**
Bryce Leed3624e12017-11-30 08:51:45 -0800211 * Generates an {@link ActivityStarter} that is ready to handle a new start request.
212 * @param controller The {@link ActivityStartController} which the starter who will own
213 * this instance.
214 * @return an {@link ActivityStarter}
215 */
Bryce Leedaa91e42017-12-06 14:13:01 -0800216 ActivityStarter obtain();
217
218 /**
219 * Recycles a starter for reuse.
220 */
221 void recycle(ActivityStarter starter);
Wale Ogunwale01d66562015-12-29 08:19:19 -0800222 }
223
Bryce Leed3624e12017-11-30 08:51:45 -0800224 /**
225 * Default implementation of {@link StarterFactory}.
226 */
227 static class DefaultFactory implements Factory {
Bryce Leedaa91e42017-12-06 14:13:01 -0800228 /**
229 * The maximum count of starters that should be active at one time:
230 * 1. last ran starter (for logging and post activity processing)
231 * 2. current running starter
232 * 3. starter from re-entry in (2)
233 */
234 private final int MAX_STARTER_COUNT = 3;
235
Bryce Lee4c9a5972017-12-01 22:14:24 -0800236 private ActivityStartController mController;
237 private ActivityManagerService mService;
238 private ActivityStackSupervisor mSupervisor;
239 private ActivityStartInterceptor mInterceptor;
240
Bryce Leedaa91e42017-12-06 14:13:01 -0800241 private SynchronizedPool<ActivityStarter> mStarterPool =
242 new SynchronizedPool<>(MAX_STARTER_COUNT);
243
Bryce Lee4c9a5972017-12-01 22:14:24 -0800244 DefaultFactory(ActivityManagerService service,
245 ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
246 mService = service;
247 mSupervisor = supervisor;
248 mInterceptor = interceptor;
Bryce Leed3624e12017-11-30 08:51:45 -0800249 }
Bryce Lee4c9a5972017-12-01 22:14:24 -0800250
251 @Override
252 public void setController(ActivityStartController controller) {
253 mController = controller;
254 }
255
256 @Override
Bryce Leedaa91e42017-12-06 14:13:01 -0800257 public ActivityStarter obtain() {
258 ActivityStarter starter = mStarterPool.acquire();
259
260 if (starter == null) {
261 starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
262 }
263
264 return starter;
265 }
266
267 @Override
268 public void recycle(ActivityStarter starter) {
269 starter.reset(true /* clearRequest*/);
270 mStarterPool.release(starter);
Bryce Lee4c9a5972017-12-01 22:14:24 -0800271 }
272 }
273
274 /**
275 * Container for capturing initial start request details. This information is NOT reset until
276 * the {@link ActivityStarter} is recycled, allowing for multiple invocations with the same
277 * parameters.
278 *
279 * TODO(b/64750076): Investigate consolidating member variables of {@link ActivityStarter} with
280 * the request object. Note that some member variables are referenced in
281 * {@link #dump(PrintWriter, String)} and therefore cannot be cleared immediately after
282 * execution.
283 */
284 private static class Request {
285 private static final int DEFAULT_CALLING_UID = -1;
286 private static final int DEFAULT_CALLING_PID = 0;
287
288 IApplicationThread caller;
289 Intent intent;
290 Intent ephemeralIntent;
291 String resolvedType;
292 ActivityInfo activityInfo;
293 ResolveInfo resolveInfo;
294 IVoiceInteractionSession voiceSession;
295 IVoiceInteractor voiceInteractor;
296 IBinder resultTo;
297 String resultWho;
298 int requestCode;
299 int callingPid = DEFAULT_CALLING_UID;
300 int callingUid = DEFAULT_CALLING_PID;
301 String callingPackage;
302 int realCallingPid;
303 int realCallingUid;
304 int startFlags;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100305 SafeActivityOptions activityOptions;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800306 boolean ignoreTargetSecurity;
307 boolean componentSpecified;
Winson Chunge2d72172018-01-25 17:46:20 +0000308 boolean avoidMoveToFront;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800309 ActivityRecord[] outActivity;
310 TaskRecord inTask;
311 String reason;
312 ProfilerInfo profilerInfo;
313 Configuration globalConfig;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800314 int userId;
315 WaitResult waitResult;
Patrick Baumann31426b22018-05-21 13:46:40 -0700316 int filterCallingUid;
Michal Karpinski3eab9512018-07-20 15:32:00 +0100317 PendingIntentRecord originatingPendingIntent;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800318
319 /**
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200320 * If set to {@code true}, allows this activity start to look into
321 * {@link PendingRemoteAnimationRegistry}
322 */
323 boolean allowPendingRemoteAnimationRegistryLookup;
324
325 /**
Bryce Lee4c9a5972017-12-01 22:14:24 -0800326 * Indicates that we should wait for the result of the start request. This flag is set when
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100327 * {@link ActivityStarter#setMayWait(int)} is called.
Bryce Lee4c9a5972017-12-01 22:14:24 -0800328 * {@see ActivityStarter#startActivityMayWait}.
329 */
330 boolean mayWait;
Bryce Leedaa91e42017-12-06 14:13:01 -0800331
332 /**
Bryce Leea3cd8e02018-01-09 15:44:24 -0800333 * Ensure constructed request matches reset instance.
334 */
335 Request() {
336 reset();
337 }
338
339 /**
Bryce Leedaa91e42017-12-06 14:13:01 -0800340 * Sets values back to the initial state, clearing any held references.
341 */
342 void reset() {
343 caller = null;
344 intent = null;
345 ephemeralIntent = null;
346 resolvedType = null;
347 activityInfo = null;
348 resolveInfo = null;
349 voiceSession = null;
350 voiceInteractor = null;
351 resultTo = null;
352 resultWho = null;
353 requestCode = 0;
Bryce Leea3cd8e02018-01-09 15:44:24 -0800354 callingPid = DEFAULT_CALLING_PID;
355 callingUid = DEFAULT_CALLING_UID;
Bryce Leedaa91e42017-12-06 14:13:01 -0800356 callingPackage = null;
357 realCallingPid = 0;
358 realCallingUid = 0;
359 startFlags = 0;
360 activityOptions = null;
361 ignoreTargetSecurity = false;
362 componentSpecified = false;
363 outActivity = null;
364 inTask = null;
365 reason = null;
366 profilerInfo = null;
367 globalConfig = null;
Bryce Leedaa91e42017-12-06 14:13:01 -0800368 userId = 0;
369 waitResult = null;
370 mayWait = false;
Winson Chunge2d72172018-01-25 17:46:20 +0000371 avoidMoveToFront = false;
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200372 allowPendingRemoteAnimationRegistryLookup = true;
Patrick Baumann31426b22018-05-21 13:46:40 -0700373 filterCallingUid = UserHandle.USER_NULL;
Michal Karpinski3eab9512018-07-20 15:32:00 +0100374 originatingPendingIntent = null;
Bryce Leedaa91e42017-12-06 14:13:01 -0800375 }
376
377 /**
378 * Adopts all values from passed in request.
379 */
380 void set(Request request) {
381 caller = request.caller;
382 intent = request.intent;
383 ephemeralIntent = request.ephemeralIntent;
384 resolvedType = request.resolvedType;
385 activityInfo = request.activityInfo;
386 resolveInfo = request.resolveInfo;
387 voiceSession = request.voiceSession;
388 voiceInteractor = request.voiceInteractor;
389 resultTo = request.resultTo;
390 resultWho = request.resultWho;
391 requestCode = request.requestCode;
392 callingPid = request.callingPid;
393 callingUid = request.callingUid;
394 callingPackage = request.callingPackage;
395 realCallingPid = request.realCallingPid;
396 realCallingUid = request.realCallingUid;
397 startFlags = request.startFlags;
398 activityOptions = request.activityOptions;
399 ignoreTargetSecurity = request.ignoreTargetSecurity;
400 componentSpecified = request.componentSpecified;
401 outActivity = request.outActivity;
402 inTask = request.inTask;
403 reason = request.reason;
404 profilerInfo = request.profilerInfo;
405 globalConfig = request.globalConfig;
Bryce Leedaa91e42017-12-06 14:13:01 -0800406 userId = request.userId;
407 waitResult = request.waitResult;
408 mayWait = request.mayWait;
Winson Chunge2d72172018-01-25 17:46:20 +0000409 avoidMoveToFront = request.avoidMoveToFront;
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200410 allowPendingRemoteAnimationRegistryLookup
411 = request.allowPendingRemoteAnimationRegistryLookup;
Patrick Baumann31426b22018-05-21 13:46:40 -0700412 filterCallingUid = request.filterCallingUid;
Michal Karpinski3eab9512018-07-20 15:32:00 +0100413 originatingPendingIntent = request.originatingPendingIntent;
Bryce Leedaa91e42017-12-06 14:13:01 -0800414 }
Bryce Leed3624e12017-11-30 08:51:45 -0800415 }
416
417 ActivityStarter(ActivityStartController controller, ActivityManagerService service,
418 ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
419 mController = controller;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800420 mService = service;
Bryce Leed3624e12017-11-30 08:51:45 -0800421 mSupervisor = supervisor;
422 mInterceptor = interceptor;
Bryce Leedaa91e42017-12-06 14:13:01 -0800423 reset(true);
424 }
425
426 /**
427 * Effectively duplicates the starter passed in. All state and request values will be
428 * mirrored.
429 * @param starter
430 */
431 void set(ActivityStarter starter) {
432 mStartActivity = starter.mStartActivity;
433 mIntent = starter.mIntent;
434 mCallingUid = starter.mCallingUid;
435 mOptions = starter.mOptions;
436
437 mLaunchTaskBehind = starter.mLaunchTaskBehind;
438 mLaunchFlags = starter.mLaunchFlags;
439 mLaunchMode = starter.mLaunchMode;
440
Bryce Leeec55eb02017-12-05 20:51:27 -0800441 mLaunchParams.set(starter.mLaunchParams);
Bryce Leedaa91e42017-12-06 14:13:01 -0800442
443 mNotTop = starter.mNotTop;
444 mDoResume = starter.mDoResume;
445 mStartFlags = starter.mStartFlags;
446 mSourceRecord = starter.mSourceRecord;
447 mPreferredDisplayId = starter.mPreferredDisplayId;
448
449 mInTask = starter.mInTask;
450 mAddingToTask = starter.mAddingToTask;
451 mReuseTask = starter.mReuseTask;
452
453 mNewTaskInfo = starter.mNewTaskInfo;
454 mNewTaskIntent = starter.mNewTaskIntent;
455 mSourceStack = starter.mSourceStack;
456
457 mTargetStack = starter.mTargetStack;
458 mMovedToFront = starter.mMovedToFront;
459 mNoAnimation = starter.mNoAnimation;
460 mKeepCurTransition = starter.mKeepCurTransition;
461 mAvoidMoveToFront = starter.mAvoidMoveToFront;
462
463 mVoiceSession = starter.mVoiceSession;
464 mVoiceInteractor = starter.mVoiceInteractor;
465
466 mIntentDelivered = starter.mIntentDelivered;
467
468 mRequest.set(starter.mRequest);
Bryce Leed3624e12017-11-30 08:51:45 -0800469 }
470
Bryce Lee4c9a5972017-12-01 22:14:24 -0800471 ActivityRecord getStartActivity() {
472 return mStartActivity;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800473 }
474
Bryce Lee4c9a5972017-12-01 22:14:24 -0800475 boolean relatedToPackage(String packageName) {
476 return (mLastStartActivityRecord[0] != null
477 && packageName.equals(mLastStartActivityRecord[0].packageName))
478 || (mStartActivity != null && packageName.equals(mStartActivity.packageName));
479 }
480
481 /**
482 * Starts an activity based on the request parameters provided earlier.
483 * @return The starter result.
484 */
485 int execute() {
Bryce Leedaa91e42017-12-06 14:13:01 -0800486 try {
487 // TODO(b/64750076): Look into passing request directly to these methods to allow
488 // for transactional diffs and preprocessing.
489 if (mRequest.mayWait) {
490 return startActivityMayWait(mRequest.caller, mRequest.callingUid,
491 mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
492 mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
493 mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
494 mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100495 mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200496 mRequest.inTask, mRequest.reason,
Michal Karpinski3eab9512018-07-20 15:32:00 +0100497 mRequest.allowPendingRemoteAnimationRegistryLookup,
498 mRequest.originatingPendingIntent);
Bryce Leedaa91e42017-12-06 14:13:01 -0800499 } else {
500 return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
501 mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
502 mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
503 mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
504 mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
505 mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
506 mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200507 mRequest.outActivity, mRequest.inTask, mRequest.reason,
Michal Karpinski3eab9512018-07-20 15:32:00 +0100508 mRequest.allowPendingRemoteAnimationRegistryLookup,
509 mRequest.originatingPendingIntent);
Bryce Leedaa91e42017-12-06 14:13:01 -0800510 }
511 } finally {
512 onExecutionComplete();
513 }
514 }
515
516 /**
517 * Starts an activity based on the provided {@link ActivityRecord} and environment parameters.
518 * Note that this method is called internally as well as part of {@link #startActivity}.
519 *
520 * @return The start result.
521 */
522 int startResolvedActivity(final ActivityRecord r, ActivityRecord sourceRecord,
523 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
524 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
525 ActivityRecord[] outActivity) {
526 try {
527 return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
528 doResume, options, inTask, outActivity);
529 } finally {
530 onExecutionComplete();
Bryce Lee4c9a5972017-12-01 22:14:24 -0800531 }
532 }
533
534 private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700535 String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
536 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
537 IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
538 String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100539 SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200540 ActivityRecord[] outActivity, TaskRecord inTask, String reason,
Michal Karpinski3eab9512018-07-20 15:32:00 +0100541 boolean allowPendingRemoteAnimationRegistryLookup,
542 PendingIntentRecord originatingPendingIntent) {
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700543
544 if (TextUtils.isEmpty(reason)) {
545 throw new IllegalArgumentException("Need to specify a reason.");
546 }
547 mLastStartReason = reason;
548 mLastStartActivityTimeMs = System.currentTimeMillis();
549 mLastStartActivityRecord[0] = null;
550
551 mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
552 aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
553 callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
554 options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
Michal Karpinski3eab9512018-07-20 15:32:00 +0100555 inTask, allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent);
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700556
557 if (outActivity != null) {
558 // mLastStartActivityRecord[0] is set in the call to startActivity above.
559 outActivity[0] = mLastStartActivityRecord[0];
560 }
Bryce Leef9d49542017-06-26 16:27:32 -0700561
Bryce Lee93e7f792017-10-25 15:54:55 -0700562 return getExternalResult(mLastStartActivityResult);
563 }
564
Bryce Leed3624e12017-11-30 08:51:45 -0800565 static int getExternalResult(int result) {
Bryce Leef9d49542017-06-26 16:27:32 -0700566 // Aborted results are treated as successes externally, but we must track them internally.
Bryce Lee93e7f792017-10-25 15:54:55 -0700567 return result != START_ABORTED ? result : START_SUCCESS;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700568 }
569
Bryce Leedaa91e42017-12-06 14:13:01 -0800570 /**
571 * Called when execution is complete. Sets state indicating completion and proceeds with
572 * recycling if appropriate.
573 */
574 private void onExecutionComplete() {
575 mController.onExecutionComplete(this);
576 }
577
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700578 private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800579 String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
580 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
581 IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
582 String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100583 SafeActivityOptions options,
584 boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
Michal Karpinski3eab9512018-07-20 15:32:00 +0100585 TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup,
586 PendingIntentRecord originatingPendingIntent) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800587 int err = ActivityManager.START_SUCCESS;
Chad Brubaker06068612017-04-06 09:43:47 -0700588 // Pull the optional Ephemeral Installer-only bundle out of the options early.
589 final Bundle verificationBundle
590 = options != null ? options.popAppVerificationBundle() : null;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800591
592 ProcessRecord callerApp = null;
593 if (caller != null) {
594 callerApp = mService.getRecordForAppLocked(caller);
595 if (callerApp != null) {
596 callingPid = callerApp.pid;
597 callingUid = callerApp.info.uid;
598 } else {
599 Slog.w(TAG, "Unable to find app for caller " + caller
600 + " (pid=" + callingPid + ") when starting: "
601 + intent.toString());
602 err = ActivityManager.START_PERMISSION_DENIED;
603 }
604 }
605
Bryce Lee93e7f792017-10-25 15:54:55 -0700606 final int userId = aInfo != null && aInfo.applicationInfo != null
607 ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800608
609 if (err == ActivityManager.START_SUCCESS) {
610 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
Andrii Kulian03c403d2016-11-11 11:14:12 -0800611 + "} from uid " + callingUid);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800612 }
613
614 ActivityRecord sourceRecord = null;
615 ActivityRecord resultRecord = null;
616 if (resultTo != null) {
617 sourceRecord = mSupervisor.isInAnyStackLocked(resultTo);
618 if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
619 "Will send result to " + resultTo + " " + sourceRecord);
620 if (sourceRecord != null) {
621 if (requestCode >= 0 && !sourceRecord.finishing) {
622 resultRecord = sourceRecord;
623 }
624 }
625 }
626
627 final int launchFlags = intent.getFlags();
628
629 if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
630 // Transfer the result target from the source activity to the new
631 // one being started, including any failures.
632 if (requestCode >= 0) {
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100633 SafeActivityOptions.abort(options);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800634 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
635 }
636 resultRecord = sourceRecord.resultTo;
637 if (resultRecord != null && !resultRecord.isInStackLocked()) {
638 resultRecord = null;
639 }
640 resultWho = sourceRecord.resultWho;
641 requestCode = sourceRecord.requestCode;
642 sourceRecord.resultTo = null;
643 if (resultRecord != null) {
644 resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
645 }
646 if (sourceRecord.launchedFromUid == callingUid) {
647 // The new activity is being launched from the same uid as the previous
648 // activity in the flow, and asking to forward its result back to the
649 // previous. In this case the activity is serving as a trampoline between
650 // the two, so we also want to update its launchedFromPackage to be the
651 // same as the previous activity. Note that this is safe, since we know
652 // these two packages come from the same uid; the caller could just as
653 // well have supplied that same package name itself. This specifially
654 // deals with the case of an intent picker/chooser being launched in the app
655 // flow to redirect to an activity picked by the user, where we want the final
656 // activity to consider it to have been launched by the previous app activity.
657 callingPackage = sourceRecord.launchedFromPackage;
658 }
659 }
660
661 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
662 // We couldn't find a class that can handle the given Intent.
663 // That's the end of that!
664 err = ActivityManager.START_INTENT_NOT_RESOLVED;
665 }
666
667 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
668 // We couldn't find the specific class specified in the Intent.
669 // Also the end of the line.
670 err = ActivityManager.START_CLASS_NOT_FOUND;
671 }
672
673 if (err == ActivityManager.START_SUCCESS && sourceRecord != null
Bryce Leeaf691c02017-03-20 14:20:22 -0700674 && sourceRecord.getTask().voiceSession != null) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800675 // If this activity is being launched as part of a voice session, we need
676 // to ensure that it is safe to do so. If the upcoming activity will also
677 // be part of the voice session, we can only launch it if it has explicitly
678 // said it supports the VOICE category, or it is a part of the calling app.
679 if ((launchFlags & FLAG_ACTIVITY_NEW_TASK) == 0
680 && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
681 try {
682 intent.addCategory(Intent.CATEGORY_VOICE);
Bryce Leeba8f4422017-11-20 12:35:57 -0800683 if (!mService.getPackageManager().activitySupportsIntent(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800684 intent.getComponent(), intent, resolvedType)) {
685 Slog.w(TAG,
686 "Activity being started in current voice task does not support voice: "
687 + intent);
688 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
689 }
690 } catch (RemoteException e) {
691 Slog.w(TAG, "Failure checking voice capabilities", e);
692 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
693 }
694 }
695 }
696
697 if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
698 // If the caller is starting a new voice session, just make sure the target
699 // is actually allowing it to run this way.
700 try {
Bryce Leeba8f4422017-11-20 12:35:57 -0800701 if (!mService.getPackageManager().activitySupportsIntent(intent.getComponent(),
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800702 intent, resolvedType)) {
703 Slog.w(TAG,
704 "Activity being started in new voice task does not support: "
705 + intent);
706 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
707 }
708 } catch (RemoteException e) {
709 Slog.w(TAG, "Failure checking voice capabilities", e);
710 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
711 }
712 }
713
Andrii Kulian02b7a832016-10-06 23:11:56 -0700714 final ActivityStack resultStack = resultRecord == null ? null : resultRecord.getStack();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800715
Wale Ogunwale01d66562015-12-29 08:19:19 -0800716 if (err != START_SUCCESS) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800717 if (resultRecord != null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -0800718 resultStack.sendActivityResultLocked(
719 -1, resultRecord, resultWho, requestCode, RESULT_CANCELED, null);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800720 }
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100721 SafeActivityOptions.abort(options);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800722 return err;
723 }
724
725 boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100726 requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity,
Winson Chungc9804e72018-05-15 11:01:44 -0700727 inTask != null, callerApp, resultRecord, resultStack);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800728 abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
729 callingPid, resolvedType, aInfo.applicationInfo);
730
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100731 // Merge the two options bundles, while realCallerOptions takes precedence.
732 ActivityOptions checkedOptions = options != null
733 ? options.getOptions(intent, aInfo, callerApp, mSupervisor)
734 : null;
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200735 if (allowPendingRemoteAnimationRegistryLookup) {
736 checkedOptions = mService.getActivityStartController()
737 .getPendingRemoteAnimationRegistry()
738 .overrideOptionsIfNeeded(callingPackage, checkedOptions);
739 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800740 if (mService.mController != null) {
741 try {
742 // The Intent we give to the watcher has the extra data
743 // stripped off, since it can contain private information.
744 Intent watchIntent = intent.cloneFilter();
745 abort |= !mService.mController.activityStarting(watchIntent,
746 aInfo.applicationInfo.packageName);
747 } catch (RemoteException e) {
748 mService.mController = null;
749 }
750 }
751
Rubin Xu58d25992016-01-21 17:47:13 +0000752 mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage);
Benjamin Franz563707b2017-06-29 15:06:13 +0100753 if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100754 callingUid, checkedOptions)) {
Benjamin Franz563707b2017-06-29 15:06:13 +0100755 // activity start was intercepted, e.g. because the target user is currently in quiet
756 // mode (turn off work) or the target application is suspended
757 intent = mInterceptor.mIntent;
758 rInfo = mInterceptor.mRInfo;
759 aInfo = mInterceptor.mAInfo;
760 resolvedType = mInterceptor.mResolvedType;
761 inTask = mInterceptor.mInTask;
762 callingPid = mInterceptor.mCallingPid;
763 callingUid = mInterceptor.mCallingUid;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100764 checkedOptions = mInterceptor.mActivityOptions;
Benjamin Franz563707b2017-06-29 15:06:13 +0100765 }
766
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800767 if (abort) {
768 if (resultRecord != null) {
769 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Wale Ogunwale01d66562015-12-29 08:19:19 -0800770 RESULT_CANCELED, null);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800771 }
772 // We pretend to the caller that it was really started, but
773 // they will just get a cancel result.
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100774 ActivityOptions.abort(checkedOptions);
Bryce Leef9d49542017-06-26 16:27:32 -0700775 return START_ABORTED;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800776 }
777
778 // If permissions need a review before any of the app components can run, we
779 // launch the review activity and pass a pending intent to start the activity
780 // we are to launching now after the review is completed.
Svet Ganov77df6f32016-08-17 11:46:34 -0700781 if (mService.mPermissionReviewRequired && aInfo != null) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800782 if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
783 aInfo.packageName, userId)) {
784 IIntentSender target = mService.getIntentSenderLocked(
785 ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
786 callingUid, userId, null, null, 0, new Intent[]{intent},
787 new String[]{resolvedType}, PendingIntent.FLAG_CANCEL_CURRENT
788 | PendingIntent.FLAG_ONE_SHOT, null);
789
790 final int flags = intent.getFlags();
791 Intent newIntent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
792 newIntent.setFlags(flags
793 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
794 newIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, aInfo.packageName);
795 newIntent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target));
796 if (resultRecord != null) {
797 newIntent.putExtra(Intent.EXTRA_RESULT_NEEDED, true);
798 }
799 intent = newIntent;
800
801 resolvedType = null;
802 callingUid = realCallingUid;
803 callingPid = realCallingPid;
804
Svet Ganovcbcbf662018-05-10 17:25:29 -0700805 rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0,
Patrick Baumann31426b22018-05-21 13:46:40 -0700806 computeResolveFilterUid(
807 callingUid, realCallingUid, mRequest.filterCallingUid));
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800808 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
809 null /*profilerInfo*/);
810
811 if (DEBUG_PERMISSIONS_REVIEW) {
812 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true,
813 true, false) + "} from uid " + callingUid + " on display "
Andrii Kulian94e82d9b02017-07-13 15:33:06 -0700814 + (mSupervisor.mFocusedStack == null
815 ? DEFAULT_DISPLAY : mSupervisor.mFocusedStack.mDisplayId));
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800816 }
817 }
818 }
819
820 // If we have an ephemeral app, abort the process of launching the resolved intent.
821 // Instead, launch the ephemeral installer. Once the installer is finished, it
822 // starts either the intent we resolved here [on install error] or the ephemeral
823 // app [on install success].
Patrick Baumanna89a1722018-02-07 15:26:52 -0800824 if (rInfo != null && rInfo.auxiliaryInfo != null) {
Todd Kennedye9910222017-02-21 16:00:11 -0800825 intent = createLaunchIntent(rInfo.auxiliaryInfo, ephemeralIntent,
Chad Brubaker06068612017-04-06 09:43:47 -0700826 callingPackage, verificationBundle, resolvedType, userId);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800827 resolvedType = null;
828 callingUid = realCallingUid;
829 callingPid = realCallingPid;
830
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800831 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
832 }
833
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800834 ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
835 callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
836 resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100837 mSupervisor, checkedOptions, sourceRecord);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800838 if (outActivity != null) {
839 outActivity[0] = r;
840 }
841
842 if (r.appTimeTracker == null && sourceRecord != null) {
843 // If the caller didn't specify an explicit time tracker, we want to continue
844 // tracking under any it has.
845 r.appTimeTracker = sourceRecord.appTimeTracker;
846 }
847
848 final ActivityStack stack = mSupervisor.mFocusedStack;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100849
850 // If we are starting an activity that is not from the same uid as the currently resumed
851 // one, check whether app switches are allowed.
Bryce Leec4ab62a2018-03-05 14:19:26 -0800852 if (voiceSession == null && (stack.getResumedActivity() == null
853 || stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800854 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
855 realCallingPid, realCallingUid, "Activity start")) {
Bryce Leed3624e12017-11-30 08:51:45 -0800856 mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
857 sourceRecord, startFlags, stack, callerApp));
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100858 ActivityOptions.abort(checkedOptions);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800859 return ActivityManager.START_SWITCHES_CANCELED;
860 }
861 }
862
863 if (mService.mDidAppSwitch) {
864 // This is the second allowed switch since we stopped switches,
865 // so now just generally allow switches. Use case: user presses
866 // home (switches disabled, switch to home, mDidAppSwitch now true);
867 // user taps a home icon (coming from home so allowed, we hit here
868 // and now allow anyone to switch again).
869 mService.mAppSwitchesAllowedTime = 0;
870 } else {
871 mService.mDidAppSwitch = true;
872 }
873
Bryce Leed3624e12017-11-30 08:51:45 -0800874 mController.doPendingActivityLaunches(false);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800875
Michal Karpinski3eab9512018-07-20 15:32:00 +0100876 maybeLogActivityStart(callingUid, callingPackage, realCallingUid, intent, callerApp, r,
877 originatingPendingIntent);
878
Bryce Leedaa91e42017-12-06 14:13:01 -0800879 return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100880 true /* doResume */, checkedOptions, inTask, outActivity);
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -0800881 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800882
Michal Karpinski3eab9512018-07-20 15:32:00 +0100883 private void maybeLogActivityStart(int callingUid, String callingPackage, int realCallingUid,
884 Intent intent, ProcessRecord callerApp, ActivityRecord r,
885 PendingIntentRecord originatingPendingIntent) {
886 boolean callerAppHasForegroundActivity = (callerApp != null)
887 ? callerApp.foregroundActivities
888 : false;
889 if (!mService.isActivityStartsLoggingEnabled() || callerAppHasForegroundActivity
890 || r == null) {
891 // skip logging in this case
892 return;
893 }
894
895 try {
896 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "logActivityStart");
897 final int callingUidProcState = mService.getUidStateLocked(callingUid);
898 final boolean callingUidHasAnyVisibleWindow =
899 mService.mWindowManager.isAnyWindowVisibleForUid(callingUid);
900 final int realCallingUidProcState = (callingUid == realCallingUid)
901 ? callingUidProcState
902 : mService.getUidStateLocked(realCallingUid);
903 final boolean realCallingUidHasAnyVisibleWindow = (callingUid == realCallingUid)
904 ? callingUidHasAnyVisibleWindow
905 : mService.mWindowManager.isAnyWindowVisibleForUid(realCallingUid);
906 final String targetPackage = r.packageName;
907 final int targetUid = (r.appInfo != null) ? r.appInfo.uid : -1;
908 final int targetUidProcState = mService.getUidStateLocked(targetUid);
909 final boolean targetUidHasAnyVisibleWindow = (targetUid != -1)
910 ? mService.mWindowManager.isAnyWindowVisibleForUid(targetUid)
911 : false;
912 final String targetWhitelistTag = (targetUid != -1)
913 ? mService.getPendingTempWhitelistTagForUidLocked(targetUid)
914 : null;
915
916 mSupervisor.getActivityMetricsLogger().logActivityStart(intent, callerApp, r,
917 callingUid, callingPackage, callingUidProcState,
918 callingUidHasAnyVisibleWindow,
919 realCallingUid, realCallingUidProcState,
920 realCallingUidHasAnyVisibleWindow,
921 targetUid, targetPackage, targetUidProcState,
922 targetUidHasAnyVisibleWindow, targetWhitelistTag,
923 (originatingPendingIntent != null));
924 } finally {
925 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
926 }
927 }
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100928
Bryce Leeaa5e8c32017-03-01 16:01:06 -0800929 /**
930 * Creates a launch intent for the given auxiliary resolution data.
931 */
Patrick Baumann577d4022018-01-31 16:55:10 +0000932 private @NonNull Intent createLaunchIntent(@Nullable AuxiliaryResolveInfo auxiliaryResponse,
Chad Brubaker06068612017-04-06 09:43:47 -0700933 Intent originalIntent, String callingPackage, Bundle verificationBundle,
934 String resolvedType, int userId) {
Patrick Baumann577d4022018-01-31 16:55:10 +0000935 if (auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo) {
Todd Kennedye9910222017-02-21 16:00:11 -0800936 // request phase two resolution
937 mService.getPackageManagerInternalLocked().requestInstantAppResolutionPhaseTwo(
Chad Brubaker06068612017-04-06 09:43:47 -0700938 auxiliaryResponse, originalIntent, resolvedType, callingPackage,
939 verificationBundle, userId);
Todd Kennedye9910222017-02-21 16:00:11 -0800940 }
Todd Kennedydfc27c62017-05-17 15:32:10 -0700941 return InstantAppResolver.buildEphemeralInstallerIntent(
Patrick Baumann577d4022018-01-31 16:55:10 +0000942 originalIntent,
943 InstantAppResolver.sanitizeIntent(originalIntent),
944 auxiliaryResponse == null ? null : auxiliaryResponse.failureIntent,
945 callingPackage,
946 verificationBundle,
947 resolvedType,
948 userId,
949 auxiliaryResponse == null ? null : auxiliaryResponse.installFailureActivity,
950 auxiliaryResponse == null ? null : auxiliaryResponse.token,
951 auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo,
952 auxiliaryResponse == null ? null : auxiliaryResponse.filters);
Todd Kennedye9910222017-02-21 16:00:11 -0800953 }
954
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700955 void postStartActivityProcessing(ActivityRecord r, int result, ActivityStack targetStack) {
Bryce Lee7f936862017-05-09 15:33:18 -0700956 if (ActivityManager.isStartResultFatalError(result)) {
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -0800957 return;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800958 }
Filip Gruszczynski303210b2016-01-08 16:28:08 -0800959
Chong Zhang5022da32016-06-21 16:31:37 -0700960 // We're waiting for an activity launch to finish, but that activity simply
Bryce Lee5f0e28f2018-01-30 16:00:03 -0800961 // brought another activity to front. We must also handle the case where the task is already
962 // in the front as a result of the trampoline activity being in the same task (it will be
963 // considered focused as the trampoline will be finished). Let startActivityMayWait() know
964 // about this, so it waits for the new activity to become visible instead.
965 mSupervisor.reportWaitingActivityLaunchedIfNeeded(r, result);
Chong Zhang5022da32016-06-21 16:31:37 -0700966
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700967 ActivityStack startedActivityStack = null;
Andrii Kulian02b7a832016-10-06 23:11:56 -0700968 final ActivityStack currentStack = r.getStack();
969 if (currentStack != null) {
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700970 startedActivityStack = currentStack;
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -0800971 } else if (mTargetStack != null) {
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700972 startedActivityStack = targetStack;
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -0800973 }
974
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700975 if (startedActivityStack == null) {
976 return;
977 }
978
Wale Ogunwaleac36e4d2017-11-29 13:30:26 -0800979 final int clearTaskFlags = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK;
980 boolean clearedTask = (mLaunchFlags & clearTaskFlags) == clearTaskFlags
981 && mReuseTask != null;
Wale Ogunwale7d7973a2018-04-05 10:25:59 -0700982 if (result == START_TASK_TO_FRONT || result == START_DELIVERED_TO_TOP || clearedTask) {
983 // The activity was already running so it wasn't started, but either brought to the
984 // front or the new intent was delivered to it since it was already in front. Notify
985 // anyone interested in this piece of information.
986 switch (startedActivityStack.getWindowingMode()) {
987 case WINDOWING_MODE_PINNED:
988 mService.mTaskChangeNotificationController.notifyPinnedActivityRestartAttempt(
989 clearedTask);
990 break;
991 case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
992 final ActivityStack homeStack = mSupervisor.mHomeStack;
993 if (homeStack != null && homeStack.shouldBeVisible(null /* starting */)) {
994 mService.mWindowManager.showRecentApps();
995 }
996 break;
997 }
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -0800998 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800999 }
1000
Bryce Lee4c9a5972017-12-01 22:14:24 -08001001 private int startActivityMayWait(IApplicationThread caller, int callingUid,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001002 String callingPackage, Intent intent, String resolvedType,
1003 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1004 IBinder resultTo, String resultWho, int requestCode, int startFlags,
Sudheer Shankafc46e9b2016-10-21 17:55:27 -07001005 ProfilerInfo profilerInfo, WaitResult outResult,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001006 Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +02001007 int userId, TaskRecord inTask, String reason,
Michal Karpinski3eab9512018-07-20 15:32:00 +01001008 boolean allowPendingRemoteAnimationRegistryLookup,
1009 PendingIntentRecord originatingPendingIntent) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001010 // Refuse possible leaked file descriptors
1011 if (intent != null && intent.hasFileDescriptors()) {
1012 throw new IllegalArgumentException("File descriptors passed in Intent");
1013 }
Bryce Lee2a3cc462017-10-27 10:57:35 -07001014 mSupervisor.getActivityMetricsLogger().notifyActivityLaunching();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001015 boolean componentSpecified = intent.getComponent() != null;
1016
Makoto Onuki1a342742018-04-26 14:56:59 -07001017 final int realCallingPid = Binder.getCallingPid();
1018 final int realCallingUid = Binder.getCallingUid();
1019
Svet Ganovcbcbf662018-05-10 17:25:29 -07001020 int callingPid;
1021 if (callingUid >= 0) {
1022 callingPid = -1;
1023 } else if (caller == null) {
1024 callingPid = realCallingPid;
1025 callingUid = realCallingUid;
1026 } else {
1027 callingPid = callingUid = -1;
1028 }
1029
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001030 // Save a copy in case ephemeral needs it
1031 final Intent ephemeralIntent = new Intent(intent);
1032 // Don't modify the client's object!
1033 intent = new Intent(intent);
Todd Kennedyb21be122017-03-24 14:10:01 -07001034 if (componentSpecified
Patrick Baumann531db462018-02-13 13:01:47 -08001035 && !(Intent.ACTION_VIEW.equals(intent.getAction()) && intent.getData() == null)
Patrick Baumann577d4022018-01-31 16:55:10 +00001036 && !Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE.equals(intent.getAction())
1037 && !Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE.equals(intent.getAction())
Todd Kennedyb21be122017-03-24 14:10:01 -07001038 && mService.getPackageManagerInternalLocked()
1039 .isInstantAppInstallerComponent(intent.getComponent())) {
1040 // intercept intents targeted directly to the ephemeral installer the
Patrick Baumann577d4022018-01-31 16:55:10 +00001041 // ephemeral installer should never be started with a raw Intent; instead
Todd Kennedyb21be122017-03-24 14:10:01 -07001042 // adjust the intent so it looks like a "normal" instant app launch
1043 intent.setComponent(null /*component*/);
1044 componentSpecified = false;
1045 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001046
Makoto Onuki1a342742018-04-26 14:56:59 -07001047 ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
Patrick Baumann31426b22018-05-21 13:46:40 -07001048 0 /* matchFlags */,
1049 computeResolveFilterUid(
1050 callingUid, realCallingUid, mRequest.filterCallingUid));
Kenny Guyb1b30262016-02-09 16:02:35 +00001051 if (rInfo == null) {
1052 UserInfo userInfo = mSupervisor.getUserInfo(userId);
1053 if (userInfo != null && userInfo.isManagedProfile()) {
1054 // Special case for managed profiles, if attempting to launch non-cryto aware
1055 // app in a locked managed profile from an unlocked parent allow it to resolve
1056 // as user will be sent via confirm credentials to unlock the profile.
1057 UserManager userManager = UserManager.get(mService.mContext);
Fyodor Kupolovce4db0a2016-05-11 14:21:18 -07001058 boolean profileLockedAndParentUnlockingOrUnlocked = false;
Tony Mak13436452016-02-24 11:08:38 +00001059 long token = Binder.clearCallingIdentity();
1060 try {
Fyodor Kupolovce4db0a2016-05-11 14:21:18 -07001061 UserInfo parent = userManager.getProfileParent(userId);
1062 profileLockedAndParentUnlockingOrUnlocked = (parent != null)
1063 && userManager.isUserUnlockingOrUnlocked(parent.id)
1064 && !userManager.isUserUnlockingOrUnlocked(userId);
Tony Mak13436452016-02-24 11:08:38 +00001065 } finally {
1066 Binder.restoreCallingIdentity(token);
1067 }
Fyodor Kupolovce4db0a2016-05-11 14:21:18 -07001068 if (profileLockedAndParentUnlockingOrUnlocked) {
Kenny Guyb1b30262016-02-09 16:02:35 +00001069 rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
Jeff Sharkey8a372a02016-03-16 16:25:45 -06001070 PackageManager.MATCH_DIRECT_BOOT_AWARE
Patrick Baumann78380272018-04-04 10:41:01 -07001071 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
Patrick Baumann31426b22018-05-21 13:46:40 -07001072 computeResolveFilterUid(
1073 callingUid, realCallingUid, mRequest.filterCallingUid));
Kenny Guyb1b30262016-02-09 16:02:35 +00001074 }
1075 }
1076 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001077 // Collect information about the target of the Intent.
1078 ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
1079
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001080 synchronized (mService) {
Andrii Kulian94e82d9b02017-07-13 15:33:06 -07001081 final ActivityStack stack = mSupervisor.mFocusedStack;
Andrii Kulian8072d112016-09-16 11:11:01 -07001082 stack.mConfigWillChange = globalConfig != null
Andrii Kulian1779e612016-10-12 21:58:25 -07001083 && mService.getGlobalConfiguration().diff(globalConfig) != 0;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001084 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
1085 "Starting activity when config will change = " + stack.mConfigWillChange);
1086
1087 final long origId = Binder.clearCallingIdentity();
1088
1089 if (aInfo != null &&
1090 (aInfo.applicationInfo.privateFlags
Dianne Hackbornc8e4fad2018-05-04 11:31:09 -07001091 & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0 &&
1092 mService.mHasHeavyWeightFeature) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001093 // This may be a heavy-weight process! Check to see if we already
1094 // have another, different heavy-weight process running.
1095 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
1096 final ProcessRecord heavy = mService.mHeavyWeightProcess;
1097 if (heavy != null && (heavy.info.uid != aInfo.applicationInfo.uid
1098 || !heavy.processName.equals(aInfo.processName))) {
1099 int appCallingUid = callingUid;
1100 if (caller != null) {
1101 ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
1102 if (callerApp != null) {
1103 appCallingUid = callerApp.info.uid;
1104 } else {
1105 Slog.w(TAG, "Unable to find app for caller " + caller
1106 + " (pid=" + callingPid + ") when starting: "
1107 + intent.toString());
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001108 SafeActivityOptions.abort(options);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001109 return ActivityManager.START_PERMISSION_DENIED;
1110 }
1111 }
1112
1113 IIntentSender target = mService.getIntentSenderLocked(
1114 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
1115 appCallingUid, userId, null, null, 0, new Intent[] { intent },
1116 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
1117 | PendingIntent.FLAG_ONE_SHOT, null);
1118
1119 Intent newIntent = new Intent();
1120 if (requestCode >= 0) {
1121 // Caller is requesting a result.
1122 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
1123 }
1124 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
1125 new IntentSender(target));
1126 if (heavy.activities.size() > 0) {
1127 ActivityRecord hist = heavy.activities.get(0);
1128 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
1129 hist.packageName);
1130 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
Bryce Leeaf691c02017-03-20 14:20:22 -07001131 hist.getTask().taskId);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001132 }
1133 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
1134 aInfo.packageName);
1135 newIntent.setFlags(intent.getFlags());
1136 newIntent.setClassName("android",
1137 HeavyWeightSwitcherActivity.class.getName());
1138 intent = newIntent;
1139 resolvedType = null;
1140 caller = null;
1141 callingUid = Binder.getCallingUid();
1142 callingPid = Binder.getCallingPid();
1143 componentSpecified = true;
Makoto Onuki1a342742018-04-26 14:56:59 -07001144 rInfo = mSupervisor.resolveIntent(intent, null /*resolvedType*/, userId,
Patrick Baumann31426b22018-05-21 13:46:40 -07001145 0 /* matchFlags */, computeResolveFilterUid(
1146 callingUid, realCallingUid, mRequest.filterCallingUid));
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001147 aInfo = rInfo != null ? rInfo.activityInfo : null;
1148 if (aInfo != null) {
1149 aInfo = mService.getActivityInfoForUser(aInfo, userId);
1150 }
1151 }
1152 }
1153 }
1154
Jorim Jaggi275561a2016-02-23 10:11:02 -05001155 final ActivityRecord[] outRecord = new ActivityRecord[1];
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001156 int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
1157 voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
1158 callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +02001159 ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
Michal Karpinski3eab9512018-07-20 15:32:00 +01001160 allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001161
1162 Binder.restoreCallingIdentity(origId);
1163
1164 if (stack.mConfigWillChange) {
1165 // If the caller also wants to switch to a new configuration,
1166 // do so now. This allows a clean switch, as we are waiting
1167 // for the current activity to pause (so we will not destroy
1168 // it), and have not yet started the next activity.
1169 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
1170 "updateConfiguration()");
1171 stack.mConfigWillChange = false;
1172 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
1173 "Updating to new configuration after starting activity.");
Andrii Kulian8072d112016-09-16 11:11:01 -07001174 mService.updateConfigurationLocked(globalConfig, null, false);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001175 }
1176
1177 if (outResult != null) {
1178 outResult.result = res;
Bryce Lee4a194382017-04-04 14:32:48 -07001179
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001180 final ActivityRecord r = outRecord[0];
1181
1182 switch(res) {
1183 case START_SUCCESS: {
1184 mSupervisor.mWaitingActivityLaunched.add(outResult);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001185 do {
1186 try {
1187 mService.wait();
1188 } catch (InterruptedException e) {
1189 }
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001190 } while (outResult.result != START_TASK_TO_FRONT
1191 && !outResult.timeout && outResult.who == null);
1192 if (outResult.result == START_TASK_TO_FRONT) {
1193 res = START_TASK_TO_FRONT;
1194 }
1195 break;
1196 }
1197 case START_DELIVERED_TO_TOP: {
1198 outResult.timeout = false;
1199 outResult.who = r.realActivity;
1200 outResult.totalTime = 0;
1201 outResult.thisTime = 0;
1202 break;
1203 }
1204 case START_TASK_TO_FRONT: {
1205 // ActivityRecord may represent a different activity, but it should not be
1206 // in the resumed state.
Bryce Lee7ace3952018-02-16 14:34:32 -08001207 if (r.nowVisible && r.isState(RESUMED)) {
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001208 outResult.timeout = false;
1209 outResult.who = r.realActivity;
1210 outResult.totalTime = 0;
1211 outResult.thisTime = 0;
1212 } else {
1213 outResult.thisTime = SystemClock.uptimeMillis();
1214 mSupervisor.waitActivityVisible(r.realActivity, outResult);
1215 // Note: the timeout variable is not currently not ever set.
1216 do {
1217 try {
1218 mService.wait();
1219 } catch (InterruptedException e) {
1220 }
1221 } while (!outResult.timeout && outResult.who == null);
1222 }
1223 break;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001224 }
1225 }
1226 }
1227
Bryce Lee2a3cc462017-10-27 10:57:35 -07001228 mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outRecord[0]);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001229 return res;
1230 }
1231 }
1232
Svet Ganovcbcbf662018-05-10 17:25:29 -07001233 /**
1234 * Compute the logical UID based on which the package manager would filter
1235 * app components i.e. based on which the instant app policy would be applied
1236 * because it is the logical calling UID.
1237 *
1238 * @param customCallingUid The UID on whose behalf to make the call.
1239 * @param actualCallingUid The UID actually making the call.
Patrick Baumann31426b22018-05-21 13:46:40 -07001240 * @param filterCallingUid The UID to be used to filter for instant apps.
Svet Ganovcbcbf662018-05-10 17:25:29 -07001241 * @return The logical UID making the call.
1242 */
Patrick Baumann31426b22018-05-21 13:46:40 -07001243 static int computeResolveFilterUid(int customCallingUid, int actualCallingUid,
1244 int filterCallingUid) {
1245 return filterCallingUid != UserHandle.USER_NULL
1246 ? filterCallingUid
1247 : (customCallingUid >= 0 ? customCallingUid : actualCallingUid);
Svet Ganovcbcbf662018-05-10 17:25:29 -07001248 }
1249
Bryce Leedaa91e42017-12-06 14:13:01 -08001250 private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
1251 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1252 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
1253 ActivityRecord[] outActivity) {
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001254 int result = START_CANCELED;
1255 try {
1256 mService.mWindowManager.deferSurfaceLayout();
1257 result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
Bryce Lee4a194382017-04-04 14:32:48 -07001258 startFlags, doResume, options, inTask, outActivity);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001259 } finally {
1260 // If we are not able to proceed, disassociate the activity from the task. Leaving an
1261 // activity in an incomplete state can lead to issues, such as performing operations
1262 // without a window container.
Bryce Lee2b8e0372018-04-05 17:01:37 -07001263 final ActivityStack stack = mStartActivity.getStack();
1264 if (!ActivityManager.isStartResultSuccessful(result) && stack != null) {
1265 stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,
1266 null /* intentResultData */, "startActivity", true /* oomAdj */);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001267 }
1268 mService.mWindowManager.continueSurfaceLayout();
1269 }
1270
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001271 postStartActivityProcessing(r, result, mTargetStack);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001272
1273 return result;
1274 }
1275
1276 // Note: This method should only be called from {@link startActivity}.
Wale Ogunwale01d66562015-12-29 08:19:19 -08001277 private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
1278 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
Bryce Lee4a194382017-04-04 14:32:48 -07001279 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
1280 ActivityRecord[] outActivity) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001281
1282 setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
1283 voiceInteractor);
1284
1285 computeLaunchingTaskFlags();
1286
1287 computeSourceStack();
1288
1289 mIntent.setFlags(mLaunchFlags);
1290
Bryce Lee4a194382017-04-04 14:32:48 -07001291 ActivityRecord reusedActivity = getReusableIntentActivity();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001292
Wale Ogunwale0568aed2017-09-08 13:29:37 -07001293 int preferredWindowingMode = WINDOWING_MODE_UNDEFINED;
1294 int preferredLaunchDisplayId = DEFAULT_DISPLAY;
1295 if (mOptions != null) {
1296 preferredWindowingMode = mOptions.getLaunchWindowingMode();
1297 preferredLaunchDisplayId = mOptions.getLaunchDisplayId();
1298 }
Jorim Jaggi2adba072016-03-03 13:43:39 +01001299
Bryce Leeec55eb02017-12-05 20:51:27 -08001300 // windowing mode and preferred launch display values from {@link LaunchParams} take
1301 // priority over those specified in {@link ActivityOptions}.
1302 if (!mLaunchParams.isEmpty()) {
1303 if (mLaunchParams.hasPreferredDisplay()) {
1304 preferredLaunchDisplayId = mLaunchParams.mPreferredDisplayId;
1305 }
1306
1307 if (mLaunchParams.hasWindowingMode()) {
1308 preferredWindowingMode = mLaunchParams.mWindowingMode;
1309 }
1310 }
1311
Bryce Lee4a194382017-04-04 14:32:48 -07001312 if (reusedActivity != null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001313 // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but
1314 // still needs to be a lock task mode violation since the task gets cleared out and
1315 // the device would otherwise leave the locked task.
Bryce Lee2b8e0372018-04-05 17:01:37 -07001316 if (mService.getLockTaskController().isLockTaskModeViolation(reusedActivity.getTask(),
Wale Ogunwale01d66562015-12-29 08:19:19 -08001317 (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1318 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001319 Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
1320 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
1321 }
1322
Bryce Leef65ee7e2018-03-26 16:03:47 -07001323 // True if we are clearing top and resetting of a standard (default) launch mode
1324 // ({@code LAUNCH_MULTIPLE}) activity. The existing activity will be finished.
1325 final boolean clearTopAndResetStandardLaunchMode =
1326 (mLaunchFlags & (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED))
1327 == (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
1328 && mLaunchMode == LAUNCH_MULTIPLE;
1329
1330 // If mStartActivity does not have a task associated with it, associate it with the
1331 // reused activity's task. Do not do so if we're clearing top and resetting for a
1332 // standard launchMode activity.
1333 if (mStartActivity.getTask() == null && !clearTopAndResetStandardLaunchMode) {
Bryce Lee4a194382017-04-04 14:32:48 -07001334 mStartActivity.setTask(reusedActivity.getTask());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001335 }
Bryce Leef65ee7e2018-03-26 16:03:47 -07001336
Bryce Lee4a194382017-04-04 14:32:48 -07001337 if (reusedActivity.getTask().intent == null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001338 // This task was started because of movement of the activity based on affinity...
1339 // Now that we are actually launching it, we can assign the base intent.
Bryce Lee4a194382017-04-04 14:32:48 -07001340 reusedActivity.getTask().setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001341 }
1342
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001343 // This code path leads to delivering a new intent, we want to make sure we schedule it
1344 // as the first operation, in case the activity will be resumed as a result of later
1345 // operations.
1346 if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
Daichi Hirono15a02992016-04-27 18:47:01 +09001347 || isDocumentLaunchesIntoExisting(mLaunchFlags)
Bryce Lee7daee392017-10-12 13:46:18 -07001348 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Bryce Lee4a194382017-04-04 14:32:48 -07001349 final TaskRecord task = reusedActivity.getTask();
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001350
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001351 // In this situation we want to remove all activities from the task up to the one
1352 // being started. In most cases this means we are resetting the task to its initial
1353 // state.
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001354 final ActivityRecord top = task.performClearTaskForReuseLocked(mStartActivity,
1355 mLaunchFlags);
1356
Bryce Lee4a194382017-04-04 14:32:48 -07001357 // The above code can remove {@code reusedActivity} from the task, leading to the
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001358 // the {@code ActivityRecord} removing its reference to the {@code TaskRecord}. The
1359 // task reference is needed in the call below to
1360 // {@link setTargetStackAndMoveToFrontIfNeeded}.
Bryce Lee4a194382017-04-04 14:32:48 -07001361 if (reusedActivity.getTask() == null) {
1362 reusedActivity.setTask(task);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001363 }
1364
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001365 if (top != null) {
1366 if (top.frontOfTask) {
1367 // Activity aliases may mean we use different intents for the top activity,
1368 // so make sure the task now has the identity of the new intent.
Bryce Leeaf691c02017-03-20 14:20:22 -07001369 top.getTask().setIntent(mStartActivity);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001370 }
Bryce Lee325e09682017-10-05 17:20:25 -07001371 deliverNewIntent(top);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001372 }
1373 }
1374
Bryce Leed3624e12017-11-30 08:51:45 -08001375 mSupervisor.sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, reusedActivity);
Wei Wang98f03f92016-05-18 11:32:52 -07001376
Bryce Lee4a194382017-04-04 14:32:48 -07001377 reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001378
Bryce Lee89cd19a2017-05-17 15:18:35 -07001379 final ActivityRecord outResult =
1380 outActivity != null && outActivity.length > 0 ? outActivity[0] : null;
1381
1382 // When there is a reused activity and the current result is a trampoline activity,
1383 // set the reused activity as the result.
1384 if (outResult != null && (outResult.finishing || outResult.noDisplay)) {
1385 outActivity[0] = reusedActivity;
1386 }
1387
Wale Ogunwale01d66562015-12-29 08:19:19 -08001388 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1389 // We don't need to start a new activity, and the client said not to do anything
1390 // if that is the case, so this is it! And for paranoia, make sure we have
1391 // correctly resumed the top activity.
1392 resumeTargetStackIfNeeded();
1393 return START_RETURN_INTENT_TO_CALLER;
1394 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001395
Bryce Leef65ee7e2018-03-26 16:03:47 -07001396 if (reusedActivity != null) {
1397 setTaskFromIntentActivity(reusedActivity);
1398
1399 if (!mAddingToTask && mReuseTask == null) {
1400 // We didn't do anything... but it was needed (a.k.a., client don't use that
1401 // intent!) And for paranoia, make sure we have correctly resumed the top activity.
1402
1403 resumeTargetStackIfNeeded();
1404 if (outActivity != null && outActivity.length > 0) {
1405 outActivity[0] = reusedActivity;
1406 }
1407
1408 return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP;
Jorim Jaggicdfc04e2017-04-28 19:06:24 +02001409 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001410 }
1411 }
1412
1413 if (mStartActivity.packageName == null) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001414 final ActivityStack sourceStack = mStartActivity.resultTo != null
1415 ? mStartActivity.resultTo.getStack() : null;
1416 if (sourceStack != null) {
1417 sourceStack.sendActivityResultLocked(-1 /* callingUid */, mStartActivity.resultTo,
1418 mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,
1419 null /* data */);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001420 }
1421 ActivityOptions.abort(mOptions);
1422 return START_CLASS_NOT_FOUND;
1423 }
1424
1425 // If the activity being launched is the same as the one currently at the top, then
1426 // we need to check if it should only be launched once.
1427 final ActivityStack topStack = mSupervisor.mFocusedStack;
Wale Ogunwale30e441d2017-11-09 08:28:45 -08001428 final ActivityRecord topFocused = topStack.getTopActivity();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001429 final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
1430 final boolean dontStart = top != null && mStartActivity.resultTo == null
1431 && top.realActivity.equals(mStartActivity.realActivity)
1432 && top.userId == mStartActivity.userId
1433 && top.app != null && top.app.thread != null
1434 && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
Bryce Lee7daee392017-10-12 13:46:18 -07001435 || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK));
Wale Ogunwale01d66562015-12-29 08:19:19 -08001436 if (dontStart) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001437 // For paranoia, make sure we have correctly resumed the top activity.
1438 topStack.mLastPausedActivity = null;
1439 if (mDoResume) {
1440 mSupervisor.resumeFocusedStackTopActivityLocked();
1441 }
1442 ActivityOptions.abort(mOptions);
1443 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1444 // We don't need to start a new activity, and the client said not to do
1445 // anything if that is the case, so this is it!
1446 return START_RETURN_INTENT_TO_CALLER;
1447 }
Bryce Lee325e09682017-10-05 17:20:25 -07001448
1449 deliverNewIntent(top);
Chong Zhangd44063c2016-04-08 11:52:30 -07001450
1451 // Don't use mStartActivity.task to show the toast. We're not starting a new activity
1452 // but reusing 'top'. Fields in mStartActivity may not be fully initialized.
Wale Ogunwale0568aed2017-09-08 13:29:37 -07001453 mSupervisor.handleNonResizableTaskIfNeeded(top.getTask(), preferredWindowingMode,
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07001454 preferredLaunchDisplayId, topStack);
Chong Zhangd44063c2016-04-08 11:52:30 -07001455
Wale Ogunwale01d66562015-12-29 08:19:19 -08001456 return START_DELIVERED_TO_TOP;
1457 }
1458
1459 boolean newTask = false;
1460 final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
Bryce Leeaf691c02017-03-20 14:20:22 -07001461 ? mSourceRecord.getTask() : null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001462
1463 // Should this be considered a new task?
Chong Zhang6cda19c2016-06-14 19:07:56 -07001464 int result = START_SUCCESS;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001465 if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
1466 && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1467 newTask = true;
Wale Ogunwale0568aed2017-09-08 13:29:37 -07001468 result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, topStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001469 } else if (mSourceRecord != null) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07001470 result = setTaskFromSourceRecord();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001471 } else if (mInTask != null) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07001472 result = setTaskFromInTask();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001473 } else {
1474 // This not being started from an existing activity, and not part of a new task...
1475 // just put it in the top task, though these days this case should never happen.
1476 setTaskToCurrentTopOrCreateNewTask();
1477 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07001478 if (result != START_SUCCESS) {
1479 return result;
1480 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001481
1482 mService.grantUriPermissionFromIntentLocked(mCallingUid, mStartActivity.packageName,
1483 mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.userId);
Todd Kennedy0e989d02017-01-13 14:15:36 -08001484 mService.grantEphemeralAccessLocked(mStartActivity.userId, mIntent,
1485 mStartActivity.appInfo.uid, UserHandle.getAppId(mCallingUid));
Wale Ogunwale01d66562015-12-29 08:19:19 -08001486 if (newTask) {
Wale Ogunwale66e16852017-10-19 13:35:52 -07001487 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, mStartActivity.userId,
Bryce Leeaf691c02017-03-20 14:20:22 -07001488 mStartActivity.getTask().taskId);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001489 }
1490 ActivityStack.logStartActivity(
Bryce Leeaf691c02017-03-20 14:20:22 -07001491 EventLogTags.AM_CREATE_ACTIVITY, mStartActivity, mStartActivity.getTask());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001492 mTargetStack.mLastPausedActivity = null;
Wei Wang98f03f92016-05-18 11:32:52 -07001493
Bryce Leed3624e12017-11-30 08:51:45 -08001494 mSupervisor.sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, mStartActivity);
Wei Wang98f03f92016-05-18 11:32:52 -07001495
Winson Chungb5c41b72016-12-07 15:00:47 -08001496 mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
1497 mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001498 if (mDoResume) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001499 final ActivityRecord topTaskActivity =
1500 mStartActivity.getTask().topRunningActivityLocked();
Wale Ogunwale3b232392016-05-13 15:37:13 -07001501 if (!mTargetStack.isFocusable()
Wale Ogunwale68741142016-05-17 09:40:02 -07001502 || (topTaskActivity != null && topTaskActivity.mTaskOverlay
1503 && mStartActivity != topTaskActivity)) {
Filip Gruszczynski3d7fdc12016-01-31 17:33:29 -08001504 // If the activity is not focusable, we can't resume it, but still would like to
1505 // make sure it becomes visible as it starts (this will also trigger entry
1506 // animation). An example of this are PIP activities.
Wale Ogunwale3b232392016-05-13 15:37:13 -07001507 // Also, we don't want to resume activities in a task that currently has an overlay
1508 // as the starting activity just needs to be in the visible paused state until the
1509 // over is removed.
Wale Ogunwale480dca02016-02-06 13:58:29 -08001510 mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Wale Ogunwaleae846f42016-02-22 14:00:56 -08001511 // Go ahead and tell window manager to execute app transition for this activity
1512 // since the app transition will not be triggered through the resume channel.
Bryce Lee7daee392017-10-12 13:46:18 -07001513 mService.mWindowManager.executeAppTransition();
Wale Ogunwale3b232392016-05-13 15:37:13 -07001514 } else {
Winson Chung32066032016-11-04 11:55:21 -07001515 // If the target stack was not previously focusable (previous top running activity
1516 // on that stack was not visible) then any prior calls to move the stack to the
1517 // will not update the focused stack. If starting the new activity now allows the
1518 // task stack to be focusable, then ensure that we now update the focused stack
1519 // accordingly.
1520 if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
1521 mTargetStack.moveToFront("startActivityUnchecked");
1522 }
Wale Ogunwale3b232392016-05-13 15:37:13 -07001523 mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
1524 mOptions);
Filip Gruszczynski3d7fdc12016-01-31 17:33:29 -08001525 }
Winson Chung1dbc8112017-09-28 18:05:31 -07001526 } else if (mStartActivity != null) {
1527 mSupervisor.mRecentTasks.add(mStartActivity.getTask());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001528 }
1529 mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);
1530
Wale Ogunwale0568aed2017-09-08 13:29:37 -07001531 mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(), preferredWindowingMode,
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07001532 preferredLaunchDisplayId, mTargetStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001533
1534 return START_SUCCESS;
1535 }
1536
Bryce Leedaa91e42017-12-06 14:13:01 -08001537 /**
1538 * Resets the {@link ActivityStarter} state.
1539 * @param clearRequest whether the request should be reset to default values.
1540 */
1541 void reset(boolean clearRequest) {
1542 mStartActivity = null;
1543 mIntent = null;
1544 mCallingUid = -1;
1545 mOptions = null;
1546
1547 mLaunchTaskBehind = false;
1548 mLaunchFlags = 0;
1549 mLaunchMode = INVALID_LAUNCH_MODE;
1550
Bryce Leeec55eb02017-12-05 20:51:27 -08001551 mLaunchParams.reset();
Bryce Leedaa91e42017-12-06 14:13:01 -08001552
1553 mNotTop = null;
1554 mDoResume = false;
1555 mStartFlags = 0;
1556 mSourceRecord = null;
1557 mPreferredDisplayId = INVALID_DISPLAY;
1558
1559 mInTask = null;
1560 mAddingToTask = false;
1561 mReuseTask = null;
1562
1563 mNewTaskInfo = null;
1564 mNewTaskIntent = null;
1565 mSourceStack = null;
1566
1567 mTargetStack = null;
1568 mMovedToFront = false;
1569 mNoAnimation = false;
1570 mKeepCurTransition = false;
1571 mAvoidMoveToFront = false;
1572
1573 mVoiceSession = null;
1574 mVoiceInteractor = null;
1575
1576 mIntentDelivered = false;
1577
1578 if (clearRequest) {
1579 mRequest.reset();
1580 }
1581 }
1582
Wale Ogunwale01d66562015-12-29 08:19:19 -08001583 private void setInitialState(ActivityRecord r, ActivityOptions options, TaskRecord inTask,
1584 boolean doResume, int startFlags, ActivityRecord sourceRecord,
1585 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
Bryce Leedaa91e42017-12-06 14:13:01 -08001586 reset(false /* clearRequest */);
1587
Wale Ogunwale01d66562015-12-29 08:19:19 -08001588 mStartActivity = r;
1589 mIntent = r.intent;
1590 mOptions = options;
1591 mCallingUid = r.launchedFromUid;
1592 mSourceRecord = sourceRecord;
1593 mVoiceSession = voiceSession;
1594 mVoiceInteractor = voiceInteractor;
1595
David Stevense5a7b642017-05-22 13:18:23 -07001596 mPreferredDisplayId = getPreferedDisplayId(mSourceRecord, mStartActivity, options);
David Stevensc6b91c62017-02-08 14:23:58 -08001597
Bryce Leeec55eb02017-12-05 20:51:27 -08001598 mLaunchParams.reset();
Bryce Leedacefc42017-10-10 12:56:02 -07001599
Bryce Leeec55eb02017-12-05 20:51:27 -08001600 mSupervisor.getLaunchParamsController().calculate(inTask, null /*layout*/, r, sourceRecord,
1601 options, mLaunchParams);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001602
Bryce Lee7daee392017-10-12 13:46:18 -07001603 mLaunchMode = r.launchMode;
1604
Wale Ogunwale01d66562015-12-29 08:19:19 -08001605 mLaunchFlags = adjustLaunchFlagsToDocumentMode(
Bryce Lee7daee392017-10-12 13:46:18 -07001606 r, LAUNCH_SINGLE_INSTANCE == mLaunchMode,
1607 LAUNCH_SINGLE_TASK == mLaunchMode, mIntent.getFlags());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001608 mLaunchTaskBehind = r.mLaunchTaskBehind
Bryce Lee7daee392017-10-12 13:46:18 -07001609 && !isLaunchModeOneOf(LAUNCH_SINGLE_TASK, LAUNCH_SINGLE_INSTANCE)
Wale Ogunwale01d66562015-12-29 08:19:19 -08001610 && (mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0;
1611
1612 sendNewTaskResultRequestIfNeeded();
1613
1614 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
1615 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1616 }
1617
1618 // If we are actually going to launch in to a new task, there are some cases where
1619 // we further want to do multiple task.
1620 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1621 if (mLaunchTaskBehind
1622 || r.info.documentLaunchMode == DOCUMENT_LAUNCH_ALWAYS) {
1623 mLaunchFlags |= FLAG_ACTIVITY_MULTIPLE_TASK;
1624 }
1625 }
1626
1627 // We'll invoke onUserLeaving before onPause only if the launching
1628 // activity did not explicitly state that this is an automated launch.
1629 mSupervisor.mUserLeaving = (mLaunchFlags & FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1630 if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
1631 "startActivity() => mUserLeaving=" + mSupervisor.mUserLeaving);
1632
1633 // If the caller has asked not to resume at this point, we make note
1634 // of this in the record so that we can skip it when trying to find
1635 // the top running activity.
1636 mDoResume = doResume;
Chong Zhang87761972016-08-22 13:53:24 -07001637 if (!doResume || !r.okToShowLocked()) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001638 r.delayedResume = true;
1639 mDoResume = false;
1640 }
1641
Winson Chunge2d72172018-01-25 17:46:20 +00001642 if (mOptions != null) {
1643 if (mOptions.getLaunchTaskId() != -1 && mOptions.getTaskOverlay()) {
1644 r.mTaskOverlay = true;
1645 if (!mOptions.canTaskOverlayResume()) {
1646 final TaskRecord task = mSupervisor.anyTaskForIdLocked(
1647 mOptions.getLaunchTaskId());
1648 final ActivityRecord top = task != null ? task.getTopActivity() : null;
Bryce Lee7ace3952018-02-16 14:34:32 -08001649 if (top != null && !top.isState(RESUMED)) {
Jorim Jaggic875ae72016-04-26 22:41:06 -07001650
Winson Chunge2d72172018-01-25 17:46:20 +00001651 // The caller specifies that we'd like to be avoided to be moved to the
1652 // front, so be it!
1653 mDoResume = false;
1654 mAvoidMoveToFront = true;
1655 }
Winson Chungcbcadc92017-01-12 15:54:12 -08001656 }
Winson Chunge2d72172018-01-25 17:46:20 +00001657 } else if (mOptions.getAvoidMoveToFront()) {
Winson Chungba40d3a2018-05-16 09:40:16 -07001658 mDoResume = false;
Winson Chunge2d72172018-01-25 17:46:20 +00001659 mAvoidMoveToFront = true;
Jorim Jaggic875ae72016-04-26 22:41:06 -07001660 }
1661 }
1662
Wale Ogunwale01d66562015-12-29 08:19:19 -08001663 mNotTop = (mLaunchFlags & FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1664
1665 mInTask = inTask;
1666 // In some flows in to this function, we retrieve the task record and hold on to it
1667 // without a lock before calling back in to here... so the task at this point may
1668 // not actually be in recents. Check for that, and if it isn't in recents just
1669 // consider it invalid.
1670 if (inTask != null && !inTask.inRecents) {
1671 Slog.w(TAG, "Starting activity in task not in recents: " + inTask);
1672 mInTask = null;
1673 }
1674
1675 mStartFlags = startFlags;
1676 // If the onlyIfNeeded flag is set, then we can do this if the activity being launched
1677 // is the same as the one making the call... or, as a special case, if we do not know
1678 // the caller then we count the current top activity as the caller.
1679 if ((startFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1680 ActivityRecord checkedCaller = sourceRecord;
1681 if (checkedCaller == null) {
1682 checkedCaller = mSupervisor.mFocusedStack.topRunningNonDelayedActivityLocked(
1683 mNotTop);
1684 }
1685 if (!checkedCaller.realActivity.equals(r.realActivity)) {
1686 // Caller is not the same as launcher, so always needed.
1687 mStartFlags &= ~START_FLAG_ONLY_IF_NEEDED;
1688 }
1689 }
1690
1691 mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0;
1692 }
1693
1694 private void sendNewTaskResultRequestIfNeeded() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001695 final ActivityStack sourceStack = mStartActivity.resultTo != null
1696 ? mStartActivity.resultTo.getStack() : null;
1697 if (sourceStack != null && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001698 // For whatever reason this activity is being launched into a new task...
1699 // yet the caller has requested a result back. Well, that is pretty messed up,
1700 // so instead immediately send back a cancel and let the new task continue launched
1701 // as normal without a dependency on its originator.
1702 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
Andrii Kulian02b7a832016-10-06 23:11:56 -07001703 sourceStack.sendActivityResultLocked(-1 /* callingUid */, mStartActivity.resultTo,
1704 mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,
1705 null /* data */);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001706 mStartActivity.resultTo = null;
1707 }
1708 }
1709
1710 private void computeLaunchingTaskFlags() {
1711 // If the caller is not coming from another activity, but has given us an explicit task into
1712 // which they would like us to launch the new activity, then let's see about doing that.
Andrii Kulian02b7a832016-10-06 23:11:56 -07001713 if (mSourceRecord == null && mInTask != null && mInTask.getStack() != null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001714 final Intent baseIntent = mInTask.getBaseIntent();
1715 final ActivityRecord root = mInTask.getRootActivity();
1716 if (baseIntent == null) {
1717 ActivityOptions.abort(mOptions);
1718 throw new IllegalArgumentException("Launching into task without base intent: "
1719 + mInTask);
1720 }
1721
1722 // If this task is empty, then we are adding the first activity -- it
1723 // determines the root, and must be launching as a NEW_TASK.
Bryce Lee7daee392017-10-12 13:46:18 -07001724 if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001725 if (!baseIntent.getComponent().equals(mStartActivity.intent.getComponent())) {
1726 ActivityOptions.abort(mOptions);
1727 throw new IllegalArgumentException("Trying to launch singleInstance/Task "
1728 + mStartActivity + " into different task " + mInTask);
1729 }
1730 if (root != null) {
1731 ActivityOptions.abort(mOptions);
1732 throw new IllegalArgumentException("Caller with mInTask " + mInTask
1733 + " has root " + root + " but target is singleInstance/Task");
1734 }
1735 }
1736
1737 // If task is empty, then adopt the interesting intent launch flags in to the
1738 // activity being started.
1739 if (root == null) {
1740 final int flagsOfInterest = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK
1741 | FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS;
1742 mLaunchFlags = (mLaunchFlags & ~flagsOfInterest)
1743 | (baseIntent.getFlags() & flagsOfInterest);
1744 mIntent.setFlags(mLaunchFlags);
1745 mInTask.setIntent(mStartActivity);
1746 mAddingToTask = true;
1747
1748 // If the task is not empty and the caller is asking to start it as the root of
1749 // a new task, then we don't actually want to start this on the task. We will
1750 // bring the task to the front, and possibly give it a new intent.
1751 } else if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1752 mAddingToTask = false;
1753
1754 } else {
1755 mAddingToTask = true;
1756 }
1757
1758 mReuseTask = mInTask;
1759 } else {
1760 mInTask = null;
1761 // Launch ResolverActivity in the source task, so that it stays in the task bounds
1762 // when in freeform workspace.
1763 // Also put noDisplay activities in the source task. These by itself can be placed
1764 // in any task/stack, however it could launch other activities like ResolverActivity,
1765 // and we want those to stay in the original task.
1766 if ((mStartActivity.isResolverActivity() || mStartActivity.noDisplay) && mSourceRecord != null
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001767 && mSourceRecord.inFreeformWindowingMode()) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001768 mAddingToTask = true;
1769 }
1770 }
1771
1772 if (mInTask == null) {
1773 if (mSourceRecord == null) {
1774 // This activity is not being started from another... in this
1775 // case we -always- start a new task.
1776 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) {
1777 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1778 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
1779 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1780 }
1781 } else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) {
1782 // The original activity who is starting us is running as a single
1783 // instance... this new activity it is starting must go on its
1784 // own task.
1785 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
Bryce Lee7daee392017-10-12 13:46:18 -07001786 } else if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001787 // The activity being started is a single instance... it always
1788 // gets launched into its own task.
1789 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1790 }
1791 }
1792 }
1793
1794 private void computeSourceStack() {
1795 if (mSourceRecord == null) {
1796 mSourceStack = null;
1797 return;
1798 }
1799 if (!mSourceRecord.finishing) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001800 mSourceStack = mSourceRecord.getStack();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001801 return;
1802 }
1803
1804 // If the source is finishing, we can't further count it as our source. This is because the
1805 // task it is associated with may now be empty and on its way out, so we don't want to
1806 // blindly throw it in to that task. Instead we will take the NEW_TASK flow and try to find
1807 // a task for it. But save the task information so it can be used when creating the new task.
1808 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0) {
1809 Slog.w(TAG, "startActivity called from finishing " + mSourceRecord
1810 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
1811 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1812 mNewTaskInfo = mSourceRecord.info;
Bryce Leed9ed45d2017-05-22 15:57:24 -07001813
1814 // It is not guaranteed that the source record will have a task associated with it. For,
1815 // example, if this method is being called for processing a pending activity launch, it
1816 // is possible that the activity has been removed from the task after the launch was
1817 // enqueued.
1818 final TaskRecord sourceTask = mSourceRecord.getTask();
1819 mNewTaskIntent = sourceTask != null ? sourceTask.intent : null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001820 }
1821 mSourceRecord = null;
1822 mSourceStack = null;
1823 }
1824
1825 /**
1826 * Decide whether the new activity should be inserted into an existing task. Returns null
1827 * if not or an ActivityRecord with the task into which the new activity should be added.
1828 */
1829 private ActivityRecord getReusableIntentActivity() {
1830 // We may want to try to place the new activity in to an existing task. We always
1831 // do this if the target activity is singleTask or singleInstance; we will also do
1832 // this if NEW_TASK has been requested, and there is not an additional qualifier telling
1833 // us to still place it in a new task: multi task, always doc mode, or being asked to
1834 // launch this as a new task behind the current one.
1835 boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 &&
1836 (mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
Bryce Lee7daee392017-10-12 13:46:18 -07001837 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001838 // If bring to front is requested, and no result is requested and we have not been given
1839 // an explicit task to launch in to, and we can find a task that was started with this
1840 // same component, then instead of launching bring that one to the front.
1841 putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null;
1842 ActivityRecord intentActivity = null;
Jorim Jaggi2adba072016-03-03 13:43:39 +01001843 if (mOptions != null && mOptions.getLaunchTaskId() != -1) {
1844 final TaskRecord task = mSupervisor.anyTaskForIdLocked(mOptions.getLaunchTaskId());
1845 intentActivity = task != null ? task.getTopActivity() : null;
1846 } else if (putIntoExistingTask) {
Bryce Lee7daee392017-10-12 13:46:18 -07001847 if (LAUNCH_SINGLE_INSTANCE == mLaunchMode) {
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07001848 // There can be one and only one instance of single instance activity in the
1849 // history, and it is always in its own unique task, so we do a special search.
Bryce Lee28d80422017-07-21 13:25:13 -07001850 intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001851 mStartActivity.isActivityTypeHome());
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07001852 } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
1853 // For the launch adjacent case we only want to put the activity in an existing
1854 // task if the activity already exists in the history.
Andrii Kulian039ba482016-06-22 17:16:45 -07001855 intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info,
Bryce Lee7daee392017-10-12 13:46:18 -07001856 !(LAUNCH_SINGLE_TASK == mLaunchMode));
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07001857 } else {
1858 // Otherwise find the best task to put the activity in.
David Stevense5a7b642017-05-22 13:18:23 -07001859 intentActivity = mSupervisor.findTaskLocked(mStartActivity, mPreferredDisplayId);
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07001860 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001861 }
1862 return intentActivity;
1863 }
1864
Andrii Kulianfab9cd82017-03-21 19:37:09 -07001865 /**
Karthik Ravi Shankarf29b4c22017-04-06 17:02:01 -07001866 * 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 -07001867 * then return the Vr mode's virtual display ID. If not, if the activity was started with
1868 * a launchDisplayId, use that. Otherwise, if the source activity has a explicit display ID
1869 * set, use that to launch the activity.
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -08001870 */
David Stevense5a7b642017-05-22 13:18:23 -07001871 private int getPreferedDisplayId(
1872 ActivityRecord sourceRecord, ActivityRecord startingActivity, ActivityOptions options) {
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -08001873 // Check if the Activity is a VR activity. If so, the activity should be launched in
1874 // main display.
1875 if (startingActivity != null && startingActivity.requestedVrComponent != null) {
1876 return DEFAULT_DISPLAY;
1877 }
1878
1879 // Get the virtual display id from ActivityManagerService.
Karthik Ravi Shankar2b9aaed2017-05-01 01:34:19 -07001880 int displayId = mService.mVr2dDisplayId;
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -08001881 if (displayId != INVALID_DISPLAY) {
1882 if (DEBUG_STACK) {
1883 Slog.d(TAG, "getSourceDisplayId :" + displayId);
1884 }
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -08001885 return displayId;
1886 }
Karthik Ravi Shankarf29b4c22017-04-06 17:02:01 -07001887
David Stevense5a7b642017-05-22 13:18:23 -07001888 // If the caller requested a display, prefer that display.
1889 final int launchDisplayId =
1890 (options != null) ? options.getLaunchDisplayId() : INVALID_DISPLAY;
1891 if (launchDisplayId != INVALID_DISPLAY) {
1892 return launchDisplayId;
1893 }
1894
Karthik Ravi Shankarf29b4c22017-04-06 17:02:01 -07001895 displayId = sourceRecord != null ? sourceRecord.getDisplayId() : INVALID_DISPLAY;
1896 // If the activity has a displayId set explicitly, launch it on the same displayId.
1897 if (displayId != INVALID_DISPLAY) {
1898 return displayId;
1899 }
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -08001900 return DEFAULT_DISPLAY;
1901 }
1902
1903 /**
Andrii Kulianfab9cd82017-03-21 19:37:09 -07001904 * Figure out which task and activity to bring to front when we have found an existing matching
1905 * activity record in history. May also clear the task if needed.
1906 * @param intentActivity Existing matching activity.
1907 * @return {@link ActivityRecord} brought to front.
1908 */
Wale Ogunwale01d66562015-12-29 08:19:19 -08001909 private ActivityRecord setTargetStackAndMoveToFrontIfNeeded(ActivityRecord intentActivity) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001910 mTargetStack = intentActivity.getStack();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001911 mTargetStack.mLastPausedActivity = null;
1912 // If the target task is not in the front, then we need to bring it to the front...
1913 // except... well, with SINGLE_TASK_LAUNCH it's not entirely clear. We'd like to have
1914 // the same behavior as if a new instance was being started, which means not bringing it
1915 // to the front if the caller is not itself in the front.
1916 final ActivityStack focusStack = mSupervisor.getFocusedStack();
1917 ActivityRecord curTop = (focusStack == null)
1918 ? null : focusStack.topRunningNonDelayedActivityLocked(mNotTop);
1919
Bryce Leeaf691c02017-03-20 14:20:22 -07001920 final TaskRecord topTask = curTop != null ? curTop.getTask() : null;
1921 if (topTask != null
1922 && (topTask != intentActivity.getTask() || topTask != focusStack.topTask())
Jorim Jaggic875ae72016-04-26 22:41:06 -07001923 && !mAvoidMoveToFront) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001924 mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Wale Ogunwale30e441d2017-11-09 08:28:45 -08001925 if (mSourceRecord == null || (mSourceStack.getTopActivity() != null &&
1926 mSourceStack.getTopActivity().getTask() == mSourceRecord.getTask())) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001927 // We really do want to push this one into the user's face, right now.
1928 if (mLaunchTaskBehind && mSourceRecord != null) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001929 intentActivity.setTaskToAffiliateWith(mSourceRecord.getTask());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001930 }
Chong Zhangdea4bd92016-03-15 12:50:03 -07001931
1932 // If the launch flags carry both NEW_TASK and CLEAR_TASK, the task's activities
1933 // will be cleared soon by ActivityStarter in setTaskFromIntentActivity().
1934 // So no point resuming any of the activities here, it just wastes one extra
1935 // resuming, plus enter AND exit transitions.
1936 // Here we only want to bring the target stack forward. Transition will be applied
1937 // to the new activity that's started after the old ones are gone.
1938 final boolean willClearTask =
1939 (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1940 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
1941 if (!willClearTask) {
1942 final ActivityStack launchStack = getLaunchStack(
Bryce Leeaf691c02017-03-20 14:20:22 -07001943 mStartActivity, mLaunchFlags, mStartActivity.getTask(), mOptions);
1944 final TaskRecord intentTask = intentActivity.getTask();
Chong Zhangdea4bd92016-03-15 12:50:03 -07001945 if (launchStack == null || launchStack == mTargetStack) {
1946 // We only want to move to the front, if we aren't going to launch on a
1947 // different stack. If we launch on a different stack, we will put the
1948 // task on top there.
chaviw0d562bf2018-03-15 14:24:14 -07001949 mTargetStack.moveTaskToFrontLocked(intentTask, mNoAnimation, mOptions,
1950 mStartActivity.appTimeTracker, "bringingFoundTaskToFront");
Chong Zhangdea4bd92016-03-15 12:50:03 -07001951 mMovedToFront = true;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001952 } else if (launchStack.inSplitScreenWindowingMode()) {
Andrii Kulianad6f2e52016-06-15 15:27:01 -07001953 if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
1954 // If we want to launch adjacent and mTargetStack is not the computed
1955 // launch stack - move task to top of computed stack.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001956 intentTask.reparent(launchStack, ON_TOP,
Winson Chung74666102017-02-22 17:49:24 -08001957 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
1958 "launchToSide");
Andrii Kulianad6f2e52016-06-15 15:27:01 -07001959 } else {
1960 // TODO: This should be reevaluated in MW v2.
1961 // We choose to move task to front instead of launching it adjacent
1962 // when specific stack was requested explicitly and it appeared to be
1963 // adjacent stack, but FLAG_ACTIVITY_LAUNCH_ADJACENT was not set.
chaviw0d562bf2018-03-15 14:24:14 -07001964 mTargetStack.moveTaskToFrontLocked(intentTask,
Bryce Leeaf691c02017-03-20 14:20:22 -07001965 mNoAnimation, mOptions, mStartActivity.appTimeTracker,
Andrii Kulianad6f2e52016-06-15 15:27:01 -07001966 "bringToFrontInsteadOfAdjacentLaunch");
1967 }
Bryce Lee32e09ef2018-03-19 15:29:49 -07001968 mMovedToFront = launchStack != launchStack.getDisplay()
1969 .getTopStackInWindowingMode(launchStack.getWindowingMode());
Andrii Kulianfab9cd82017-03-21 19:37:09 -07001970 } else if (launchStack.mDisplayId != mTargetStack.mDisplayId) {
1971 // Target and computed stacks are on different displays and we've
1972 // found a matching task - move the existing instance to that display and
1973 // move it to front.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001974 intentActivity.getTask().reparent(launchStack, ON_TOP,
Andrii Kulianfab9cd82017-03-21 19:37:09 -07001975 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
1976 "reparentToDisplay");
1977 mMovedToFront = true;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001978 } else if (launchStack.isActivityTypeHome()
1979 && !mTargetStack.isActivityTypeHome()) {
Bryce Lee4ff7da92017-07-17 10:39:24 -07001980 // It is possible for the home activity to be in another stack initially.
1981 // For example, the activity may have been initially started with an intent
1982 // which placed it in the fullscreen stack. To ensure the proper handling of
1983 // the activity based on home stack assumptions, we must move it over.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001984 intentActivity.getTask().reparent(launchStack, ON_TOP,
Bryce Lee4ff7da92017-07-17 10:39:24 -07001985 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
1986 "reparentingHome");
1987 mMovedToFront = true;
Chong Zhangdea4bd92016-03-15 12:50:03 -07001988 }
1989 mOptions = null;
Jorim Jaggi02886a82016-12-06 09:10:06 -08001990
1991 // We are moving a task to the front, use starting window to hide initial drawn
1992 // delay.
1993 intentActivity.showStartingWindow(null /* prev */, false /* newTask */,
1994 true /* taskSwitch */);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001995 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001996 }
1997 }
Andrii Kulianb850ea52017-12-12 23:49:10 -08001998 // Need to update mTargetStack because if task was moved out of it, the original stack may
1999 // be destroyed.
2000 mTargetStack = intentActivity.getStack();
Winson Chungba40d3a2018-05-16 09:40:16 -07002001 if (!mMovedToFront && mDoResume) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002002 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Bring to front target: " + mTargetStack
2003 + " from " + intentActivity);
2004 mTargetStack.moveToFront("intentActivityFound");
2005 }
2006
Wale Ogunwale0568aed2017-09-08 13:29:37 -07002007 mSupervisor.handleNonResizableTaskIfNeeded(intentActivity.getTask(),
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07002008 WINDOWING_MODE_UNDEFINED, DEFAULT_DISPLAY, mTargetStack);
Jorim Jaggid53f0922016-04-06 22:16:23 -07002009
Wale Ogunwale01d66562015-12-29 08:19:19 -08002010 // If the caller has requested that the target task be reset, then do so.
2011 if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
2012 return mTargetStack.resetTaskIfNeededLocked(intentActivity, mStartActivity);
2013 }
2014 return intentActivity;
2015 }
2016
2017 private void setTaskFromIntentActivity(ActivityRecord intentActivity) {
2018 if ((mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
2019 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {
2020 // The caller has requested to completely replace any existing task with its new
2021 // activity. Well that should not be too hard...
Bryce Lee41801b42017-03-02 13:23:12 -08002022 // Note: we must persist the {@link TaskRecord} first as intentActivity could be
2023 // removed from calling performClearTaskLocked (For example, if it is being brought out
Bryce Lee59dad4e2017-03-09 11:54:08 -08002024 // of history or if it is finished immediately), thus disassociating the task. Also note
2025 // that mReuseTask is reset as a result of {@link TaskRecord#performClearTaskLocked}
2026 // launching another activity.
2027 // TODO(b/36119896): We shouldn't trigger activity launches in this path since we are
2028 // already launching one.
Bryce Leeaf691c02017-03-20 14:20:22 -07002029 final TaskRecord task = intentActivity.getTask();
Bryce Lee59dad4e2017-03-09 11:54:08 -08002030 task.performClearTaskLocked();
2031 mReuseTask = task;
Bryce Lee41801b42017-03-02 13:23:12 -08002032 mReuseTask.setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002033 } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
Bryce Lee7daee392017-10-12 13:46:18 -07002034 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Bryce Leeaf691c02017-03-20 14:20:22 -07002035 ActivityRecord top = intentActivity.getTask().performClearTaskLocked(mStartActivity,
Wale Ogunwale01d66562015-12-29 08:19:19 -08002036 mLaunchFlags);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08002037 if (top == null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002038 // A special case: we need to start the activity because it is not currently
2039 // running, and the caller has asked to clear the current task to have this
2040 // activity at the top.
2041 mAddingToTask = true;
Bryce Lee353112c2017-02-23 09:46:45 -08002042
2043 // We are no longer placing the activity in the task we previously thought we were.
Bryce Leeaf691c02017-03-20 14:20:22 -07002044 mStartActivity.setTask(null);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002045 // Now pretend like this activity is being started by the top of its task, so it
2046 // is put in the right place.
2047 mSourceRecord = intentActivity;
Bryce Leeaf691c02017-03-20 14:20:22 -07002048 final TaskRecord task = mSourceRecord.getTask();
Andrii Kulian02b7a832016-10-06 23:11:56 -07002049 if (task != null && task.getStack() == null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002050 // Target stack got cleared when we all activities were removed above.
2051 // Go ahead and reset it.
2052 mTargetStack = computeStackFocus(mSourceRecord, false /* newTask */,
Bryce Leedacefc42017-10-10 12:56:02 -07002053 mLaunchFlags, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002054 mTargetStack.addTask(task,
2055 !mLaunchTaskBehind /* toTop */, "startActivityUnchecked");
2056 }
2057 }
Bryce Leeaf691c02017-03-20 14:20:22 -07002058 } else if (mStartActivity.realActivity.equals(intentActivity.getTask().realActivity)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002059 // In this case the top activity on the task is the same as the one being launched,
2060 // so we take that as a request to bring the task to the foreground. If the top
2061 // activity in the task is the root activity, deliver this new intent to it if it
2062 // desires.
Bryce Lee7daee392017-10-12 13:46:18 -07002063 if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
2064 || LAUNCH_SINGLE_TOP == mLaunchMode)
Wale Ogunwale01d66562015-12-29 08:19:19 -08002065 && intentActivity.realActivity.equals(mStartActivity.realActivity)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002066 if (intentActivity.frontOfTask) {
Bryce Leeaf691c02017-03-20 14:20:22 -07002067 intentActivity.getTask().setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002068 }
Bryce Lee325e09682017-10-05 17:20:25 -07002069 deliverNewIntent(intentActivity);
Bryce Leeaf691c02017-03-20 14:20:22 -07002070 } else if (!intentActivity.getTask().isSameIntentFilter(mStartActivity)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002071 // In this case we are launching the root activity of the task, but with a
2072 // different intent. We should start a new instance on top.
2073 mAddingToTask = true;
2074 mSourceRecord = intentActivity;
2075 }
2076 } else if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
2077 // In this case an activity is being launched in to an existing task, without
2078 // resetting that task. This is typically the situation of launching an activity
2079 // from a notification or shortcut. We want to place the new activity on top of the
2080 // current task.
2081 mAddingToTask = true;
2082 mSourceRecord = intentActivity;
Bryce Leeaf691c02017-03-20 14:20:22 -07002083 } else if (!intentActivity.getTask().rootWasReset) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002084 // In this case we are launching into an existing task that has not yet been started
2085 // from its front door. The current task has been brought to the front. Ideally,
2086 // we'd probably like to place this new task at the bottom of its stack, but that's
2087 // a little hard to do with the current organization of the code so for now we'll
2088 // just drop it.
Bryce Leeaf691c02017-03-20 14:20:22 -07002089 intentActivity.getTask().setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002090 }
2091 }
2092
2093 private void resumeTargetStackIfNeeded() {
2094 if (mDoResume) {
2095 mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, null, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002096 } else {
2097 ActivityOptions.abort(mOptions);
2098 }
2099 mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);
2100 }
2101
Chong Zhang6cda19c2016-06-14 19:07:56 -07002102 private int setTaskFromReuseOrCreateNewTask(
Wale Ogunwale0568aed2017-09-08 13:29:37 -07002103 TaskRecord taskToAffiliate, ActivityStack topStack) {
Bryce Leedacefc42017-10-10 12:56:02 -07002104 mTargetStack = computeStackFocus(mStartActivity, true, mLaunchFlags, mOptions);
Chong Zhang6cda19c2016-06-14 19:07:56 -07002105
2106 // Do no move the target stack to front yet, as we might bail if
2107 // isLockTaskModeViolation fails below.
Wale Ogunwale01d66562015-12-29 08:19:19 -08002108
2109 if (mReuseTask == null) {
Suprabh Shukla09a88f52015-12-02 14:36:31 -08002110 final TaskRecord task = mTargetStack.createTaskRecord(
2111 mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId),
Wale Ogunwale01d66562015-12-29 08:19:19 -08002112 mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
Wale Ogunwale72919d22016-12-08 18:58:50 -08002113 mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
Bryce Leeb802ea12017-11-15 21:25:03 -08002114 mVoiceInteractor, !mLaunchTaskBehind /* toTop */, mStartActivity, mSourceRecord,
2115 mOptions);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002116 addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
Bryce Leeec55eb02017-12-05 20:51:27 -08002117 updateBounds(mStartActivity.getTask(), mLaunchParams.mBounds);
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002118
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002119 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Bryce Leeaf691c02017-03-20 14:20:22 -07002120 + " in new task " + mStartActivity.getTask());
Wale Ogunwale01d66562015-12-29 08:19:19 -08002121 } else {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002122 addOrReparentStartingActivity(mReuseTask, "setTaskFromReuseOrCreateNewTask");
2123 }
2124
2125 if (taskToAffiliate != null) {
2126 mStartActivity.setTaskToAffiliateWith(taskToAffiliate);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002127 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07002128
Bryce Lee2b8e0372018-04-05 17:01:37 -07002129 if (mService.getLockTaskController().isLockTaskModeViolation(mStartActivity.getTask())) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002130 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
2131 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
2132 }
2133
Chong Zhang6cda19c2016-06-14 19:07:56 -07002134 if (mDoResume) {
2135 mTargetStack.moveToFront("reuseOrNewTask");
2136 }
2137 return START_SUCCESS;
Wale Ogunwale01d66562015-12-29 08:19:19 -08002138 }
2139
Bryce Lee325e09682017-10-05 17:20:25 -07002140 private void deliverNewIntent(ActivityRecord activity) {
2141 if (mIntentDelivered) {
2142 return;
2143 }
2144
2145 ActivityStack.logStartActivity(AM_NEW_INTENT, activity, activity.getTask());
2146 activity.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
2147 mStartActivity.launchedFromPackage);
2148 mIntentDelivered = true;
2149 }
2150
Wale Ogunwale01d66562015-12-29 08:19:19 -08002151 private int setTaskFromSourceRecord() {
Bryce Lee2b8e0372018-04-05 17:01:37 -07002152 if (mService.getLockTaskController().isLockTaskModeViolation(mSourceRecord.getTask())) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002153 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
2154 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
2155 }
2156
Bryce Leeaf691c02017-03-20 14:20:22 -07002157 final TaskRecord sourceTask = mSourceRecord.getTask();
Andrii Kulian02b7a832016-10-06 23:11:56 -07002158 final ActivityStack sourceStack = mSourceRecord.getStack();
Andrii Kulian02689a72017-07-06 14:28:59 -07002159 // We only want to allow changing stack in two cases:
2160 // 1. If the target task is not the top one. Otherwise we would move the launching task to
2161 // the other side, rather than show two side by side.
2162 // 2. If activity is not allowed on target display.
2163 final int targetDisplayId = mTargetStack != null ? mTargetStack.mDisplayId
2164 : sourceStack.mDisplayId;
2165 final boolean moveStackAllowed = sourceStack.topTask() != sourceTask
2166 || !mStartActivity.canBeLaunchedOnDisplay(targetDisplayId);
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002167 if (moveStackAllowed) {
Bryce Leeaf691c02017-03-20 14:20:22 -07002168 mTargetStack = getLaunchStack(mStartActivity, mLaunchFlags, mStartActivity.getTask(),
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002169 mOptions);
Andrii Kulian02689a72017-07-06 14:28:59 -07002170 // If target stack is not found now - we can't just rely on the source stack, as it may
2171 // be not suitable. Let's check other displays.
2172 if (mTargetStack == null && targetDisplayId != sourceStack.mDisplayId) {
2173 // Can't use target display, lets find a stack on the source display.
2174 mTargetStack = mService.mStackSupervisor.getValidLaunchStackOnDisplay(
2175 sourceStack.mDisplayId, mStartActivity);
2176 }
2177 if (mTargetStack == null) {
2178 // There are no suitable stacks on the target and source display(s). Look on all
2179 // displays.
2180 mTargetStack = mService.mStackSupervisor.getNextValidLaunchStackLocked(
2181 mStartActivity, -1 /* currentFocus */);
2182 }
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002183 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002184
2185 if (mTargetStack == null) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07002186 mTargetStack = sourceStack;
2187 } else if (mTargetStack != sourceStack) {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002188 sourceTask.reparent(mTargetStack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE,
2189 DEFER_RESUME, "launchToSide");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002190 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07002191
Wale Ogunwale01d66562015-12-29 08:19:19 -08002192 final TaskRecord topTask = mTargetStack.topTask();
Jorim Jaggic875ae72016-04-26 22:41:06 -07002193 if (topTask != sourceTask && !mAvoidMoveToFront) {
chaviw0d562bf2018-03-15 14:24:14 -07002194 mTargetStack.moveTaskToFrontLocked(sourceTask, mNoAnimation, mOptions,
Wale Ogunwale01d66562015-12-29 08:19:19 -08002195 mStartActivity.appTimeTracker, "sourceTaskToFront");
Chong Zhang6cda19c2016-06-14 19:07:56 -07002196 } else if (mDoResume) {
2197 mTargetStack.moveToFront("sourceStackToFront");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002198 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07002199
Wale Ogunwale01d66562015-12-29 08:19:19 -08002200 if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0) {
2201 // In this case, we are adding the activity to an existing task, but the caller has
2202 // asked to clear that task if the activity is already running.
2203 ActivityRecord top = sourceTask.performClearTaskLocked(mStartActivity, mLaunchFlags);
2204 mKeepCurTransition = true;
2205 if (top != null) {
Bryce Leeaf691c02017-03-20 14:20:22 -07002206 ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, top.getTask());
Bryce Lee325e09682017-10-05 17:20:25 -07002207 deliverNewIntent(top);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002208 // For paranoia, make sure we have correctly resumed the top activity.
2209 mTargetStack.mLastPausedActivity = null;
2210 if (mDoResume) {
2211 mSupervisor.resumeFocusedStackTopActivityLocked();
2212 }
2213 ActivityOptions.abort(mOptions);
2214 return START_DELIVERED_TO_TOP;
2215 }
2216 } else if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
2217 // In this case, we are launching an activity in our own task that may already be
2218 // running somewhere in the history, and we want to shuffle it to the front of the
2219 // stack if so.
2220 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(mStartActivity);
2221 if (top != null) {
Bryce Leeaf691c02017-03-20 14:20:22 -07002222 final TaskRecord task = top.getTask();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002223 task.moveActivityToFrontLocked(top);
2224 top.updateOptionsLocked(mOptions);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08002225 ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, task);
Bryce Lee325e09682017-10-05 17:20:25 -07002226 deliverNewIntent(top);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002227 mTargetStack.mLastPausedActivity = null;
2228 if (mDoResume) {
2229 mSupervisor.resumeFocusedStackTopActivityLocked();
2230 }
2231 return START_DELIVERED_TO_TOP;
2232 }
2233 }
2234
2235 // An existing activity is starting this new activity, so we want to keep the new one in
2236 // the same task as the one that is starting it.
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002237 addOrReparentStartingActivity(sourceTask, "setTaskFromSourceRecord");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002238 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Bryce Leeaf691c02017-03-20 14:20:22 -07002239 + " in existing task " + mStartActivity.getTask() + " from source " + mSourceRecord);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002240 return START_SUCCESS;
2241 }
2242
2243 private int setTaskFromInTask() {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002244 // The caller is asking that the new activity be started in an explicit
2245 // task it has provided to us.
Bryce Lee2b8e0372018-04-05 17:01:37 -07002246 if (mService.getLockTaskController().isLockTaskModeViolation(mInTask)) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002247 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
2248 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
2249 }
2250
Andrii Kulian02b7a832016-10-06 23:11:56 -07002251 mTargetStack = mInTask.getStack();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002252
2253 // Check whether we should actually launch the new activity in to the task,
2254 // or just reuse the current activity on top.
2255 ActivityRecord top = mInTask.getTopActivity();
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002256 if (top != null && top.realActivity.equals(mStartActivity.realActivity)
2257 && top.userId == mStartActivity.userId) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002258 if ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
Bryce Lee7daee392017-10-12 13:46:18 -07002259 || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK)) {
chaviw0d562bf2018-03-15 14:24:14 -07002260 mTargetStack.moveTaskToFrontLocked(mInTask, mNoAnimation, mOptions,
Yorke Lee64512522017-03-24 13:09:35 -07002261 mStartActivity.appTimeTracker, "inTaskToFront");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002262 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
2263 // We don't need to start a new activity, and the client said not to do
2264 // anything if that is the case, so this is it!
2265 return START_RETURN_INTENT_TO_CALLER;
2266 }
Bryce Lee325e09682017-10-05 17:20:25 -07002267 deliverNewIntent(top);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002268 return START_DELIVERED_TO_TOP;
2269 }
2270 }
2271
2272 if (!mAddingToTask) {
chaviw0d562bf2018-03-15 14:24:14 -07002273 mTargetStack.moveTaskToFrontLocked(mInTask, mNoAnimation, mOptions,
Yorke Lee64512522017-03-24 13:09:35 -07002274 mStartActivity.appTimeTracker, "inTaskToFront");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002275 // We don't actually want to have this activity added to the task, so just
2276 // stop here but still tell the caller that we consumed the intent.
2277 ActivityOptions.abort(mOptions);
2278 return START_TASK_TO_FRONT;
2279 }
2280
Bryce Leeec55eb02017-12-05 20:51:27 -08002281 if (!mLaunchParams.mBounds.isEmpty()) {
Wale Ogunwale0568aed2017-09-08 13:29:37 -07002282 // TODO: Shouldn't we already know what stack to use by the time we get here?
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002283 ActivityStack stack = mSupervisor.getLaunchStack(null, null, mInTask, ON_TOP);
2284 if (stack != mInTask.getStack()) {
2285 mInTask.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, !ANIMATE,
Yorke Lee64512522017-03-24 13:09:35 -07002286 DEFER_RESUME, "inTaskToFront");
Yorke Lee64512522017-03-24 13:09:35 -07002287 mTargetStack = mInTask.getStack();
2288 }
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002289
Bryce Leeec55eb02017-12-05 20:51:27 -08002290 updateBounds(mInTask, mLaunchParams.mBounds);
Yorke Lee64512522017-03-24 13:09:35 -07002291 }
2292
chaviw0d562bf2018-03-15 14:24:14 -07002293 mTargetStack.moveTaskToFrontLocked(
2294 mInTask, mNoAnimation, mOptions, mStartActivity.appTimeTracker, "inTaskToFront");
Yorke Lee64512522017-03-24 13:09:35 -07002295
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002296 addOrReparentStartingActivity(mInTask, "setTaskFromInTask");
2297 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Bryce Leeaf691c02017-03-20 14:20:22 -07002298 + " in explicit task " + mStartActivity.getTask());
Wale Ogunwale01d66562015-12-29 08:19:19 -08002299
2300 return START_SUCCESS;
2301 }
2302
Bryce Leed3624e12017-11-30 08:51:45 -08002303 @VisibleForTesting
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002304 void updateBounds(TaskRecord task, Rect bounds) {
Bryce Leedacefc42017-10-10 12:56:02 -07002305 if (bounds.isEmpty()) {
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002306 return;
2307 }
2308
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002309 final ActivityStack stack = task.getStack();
2310 if (stack != null && stack.resizeStackWithLaunchBounds()) {
2311 mService.resizeStack(stack.mStackId, bounds, true, !PRESERVE_WINDOWS, ANIMATE, -1);
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002312 } else {
2313 task.updateOverrideConfiguration(bounds);
2314 }
2315 }
2316
Wale Ogunwale01d66562015-12-29 08:19:19 -08002317 private void setTaskToCurrentTopOrCreateNewTask() {
Bryce Leedacefc42017-10-10 12:56:02 -07002318 mTargetStack = computeStackFocus(mStartActivity, false, mLaunchFlags, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002319 if (mDoResume) {
2320 mTargetStack.moveToFront("addingToTopTask");
2321 }
Wale Ogunwale30e441d2017-11-09 08:28:45 -08002322 final ActivityRecord prev = mTargetStack.getTopActivity();
Bryce Leeaf691c02017-03-20 14:20:22 -07002323 final TaskRecord task = (prev != null) ? prev.getTask() : mTargetStack.createTaskRecord(
Wale Ogunwale72919d22016-12-08 18:58:50 -08002324 mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId), mStartActivity.info,
Bryce Leeb802ea12017-11-15 21:25:03 -08002325 mIntent, null, null, true, mStartActivity, mSourceRecord, mOptions);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002326 addOrReparentStartingActivity(task, "setTaskToCurrentTopOrCreateNewTask");
2327 mTargetStack.positionChildWindowContainerAtTop(task);
2328 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Bryce Leeaf691c02017-03-20 14:20:22 -07002329 + " in new guessed " + mStartActivity.getTask());
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002330 }
2331
2332 private void addOrReparentStartingActivity(TaskRecord parent, String reason) {
Bryce Leeaf691c02017-03-20 14:20:22 -07002333 if (mStartActivity.getTask() == null || mStartActivity.getTask() == parent) {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002334 parent.addActivityToTop(mStartActivity);
2335 } else {
2336 mStartActivity.reparent(parent, parent.mActivities.size() /* top */, reason);
2337 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002338 }
2339
2340 private int adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance,
2341 boolean launchSingleTask, int launchFlags) {
2342 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2343 (launchSingleInstance || launchSingleTask)) {
2344 // We have a conflict between the Intent and the Activity manifest, manifest wins.
2345 Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " +
2346 "\"singleInstance\" or \"singleTask\"");
2347 launchFlags &=
2348 ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK);
2349 } else {
2350 switch (r.info.documentLaunchMode) {
2351 case ActivityInfo.DOCUMENT_LAUNCH_NONE:
2352 break;
2353 case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
2354 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2355 break;
2356 case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
2357 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2358 break;
2359 case ActivityInfo.DOCUMENT_LAUNCH_NEVER:
2360 launchFlags &= ~FLAG_ACTIVITY_MULTIPLE_TASK;
2361 break;
2362 }
2363 }
2364 return launchFlags;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002365 }
2366
Bryce Leedacefc42017-10-10 12:56:02 -07002367 private ActivityStack computeStackFocus(ActivityRecord r, boolean newTask, int launchFlags,
2368 ActivityOptions aOptions) {
Bryce Leeaf691c02017-03-20 14:20:22 -07002369 final TaskRecord task = r.getTask();
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002370 ActivityStack stack = getLaunchStack(r, launchFlags, task, aOptions);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002371 if (stack != null) {
2372 return stack;
2373 }
2374
Andrii Kulian02b7a832016-10-06 23:11:56 -07002375 final ActivityStack currentStack = task != null ? task.getStack() : null;
2376 if (currentStack != null) {
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002377 if (mSupervisor.mFocusedStack != currentStack) {
2378 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
2379 "computeStackFocus: Setting " + "focused stack to r=" + r
2380 + " task=" + task);
2381 } else {
2382 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
2383 "computeStackFocus: Focused stack already="
2384 + mSupervisor.mFocusedStack);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002385 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07002386 return currentStack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002387 }
2388
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002389 if (canLaunchIntoFocusedStack(r, newTask)) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002390 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
2391 "computeStackFocus: Have a focused stack=" + mSupervisor.mFocusedStack);
2392 return mSupervisor.mFocusedStack;
2393 }
2394
David Stevense5a7b642017-05-22 13:18:23 -07002395 if (mPreferredDisplayId != DEFAULT_DISPLAY) {
Andrii Kuliana8fe3df2017-06-16 15:29:26 -07002396 // Try to put the activity in a stack on a secondary display.
David Stevense5a7b642017-05-22 13:18:23 -07002397 stack = mSupervisor.getValidLaunchStackOnDisplay(mPreferredDisplayId, r);
Andrii Kuliana8fe3df2017-06-16 15:29:26 -07002398 if (stack == null) {
2399 // If source display is not suitable - look for topmost valid stack in the system.
2400 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
David Stevense5a7b642017-05-22 13:18:23 -07002401 "computeStackFocus: Can't launch on mPreferredDisplayId="
2402 + mPreferredDisplayId + ", looking on all displays.");
2403 stack = mSupervisor.getNextValidLaunchStackLocked(r, mPreferredDisplayId);
Andrii Kuliana8fe3df2017-06-16 15:29:26 -07002404 }
2405 }
2406 if (stack == null) {
David Stevensc6b91c62017-02-08 14:23:58 -08002407 // We first try to put the task in the first dynamic stack on home display.
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07002408 final ActivityDisplay display = mSupervisor.getDefaultDisplay();
2409 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
2410 stack = display.getChildAt(stackNdx);
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002411 if (!stack.isOnHomeDisplay()) {
David Stevensc6b91c62017-02-08 14:23:58 -08002412 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
2413 "computeStackFocus: Setting focused stack=" + stack);
2414 return stack;
2415 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002416 }
David Stevensc6b91c62017-02-08 14:23:58 -08002417 // If there is no suitable dynamic stack then we figure out which static stack to use.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002418 stack = mSupervisor.getLaunchStack(r, aOptions, task, ON_TOP);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002419 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002420 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, "computeStackFocus: New stack r="
2421 + r + " stackId=" + stack.mStackId);
2422 return stack;
2423 }
2424
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002425 /** Check if provided activity record can launch in currently focused stack. */
Wale Ogunwale68278562017-09-23 17:13:55 -07002426 // TODO: This method can probably be consolidated into getLaunchStack() below.
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002427 private boolean canLaunchIntoFocusedStack(ActivityRecord r, boolean newTask) {
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002428 final ActivityStack focusedStack = mSupervisor.mFocusedStack;
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002429 final boolean canUseFocusedStack;
Wale Ogunwale68278562017-09-23 17:13:55 -07002430 if (focusedStack.isActivityTypeAssistant()) {
2431 canUseFocusedStack = r.isActivityTypeAssistant();
2432 } else {
2433 switch (focusedStack.getWindowingMode()) {
2434 case WINDOWING_MODE_FULLSCREEN:
2435 // The fullscreen stack can contain any task regardless of if the task is
2436 // resizeable or not. So, we let the task go in the fullscreen task if it is the
2437 // focus stack.
2438 canUseFocusedStack = true;
2439 break;
2440 case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
2441 case WINDOWING_MODE_SPLIT_SCREEN_SECONDARY:
2442 // Any activity which supports split screen can go in the docked stack.
2443 canUseFocusedStack = r.supportsSplitScreenWindowingMode();
2444 break;
2445 case WINDOWING_MODE_FREEFORM:
2446 // Any activity which supports freeform can go in the freeform stack.
2447 canUseFocusedStack = r.supportsFreeform();
2448 break;
2449 default:
2450 // Dynamic stacks behave similarly to the fullscreen stack and can contain any
2451 // resizeable task.
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002452 canUseFocusedStack = !focusedStack.isOnHomeDisplay()
Wale Ogunwale68278562017-09-23 17:13:55 -07002453 && r.canBeLaunchedOnDisplay(focusedStack.mDisplayId);
2454 }
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002455 }
Andrii Kulian94e82d9b02017-07-13 15:33:06 -07002456 return canUseFocusedStack && !newTask
Wale Ogunwale68278562017-09-23 17:13:55 -07002457 // Using the focus stack isn't important enough to override the preferred display.
David Stevense5a7b642017-05-22 13:18:23 -07002458 && (mPreferredDisplayId == focusedStack.mDisplayId);
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002459 }
2460
Wale Ogunwale854809c2015-12-27 16:18:19 -08002461 private ActivityStack getLaunchStack(ActivityRecord r, int launchFlags, TaskRecord task,
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002462 ActivityOptions aOptions) {
Bryce Leea19b5ad2017-06-07 16:54:11 -07002463 // We are reusing a task, keep the stack!
2464 if (mReuseTask != null) {
2465 return mReuseTask.getStack();
2466 }
Jorim Jaggib8c58762016-04-20 17:58:29 -07002467
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -08002468 if (((launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) == 0)
David Stevense5a7b642017-05-22 13:18:23 -07002469 || mPreferredDisplayId != DEFAULT_DISPLAY) {
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08002470 // We don't pass in the default display id into the get launch stack call so it can do a
2471 // full resolution.
2472 final int candidateDisplay =
2473 mPreferredDisplayId != DEFAULT_DISPLAY ? mPreferredDisplayId : INVALID_DISPLAY;
2474 return mSupervisor.getLaunchStack(r, aOptions, task, ON_TOP, candidateDisplay);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002475 }
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002476 // Otherwise handle adjacent launch.
Wale Ogunwale854809c2015-12-27 16:18:19 -08002477
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002478 // The parent activity doesn't want to launch the activity on top of itself, but
2479 // instead tries to put it onto other side in side-by-side mode.
Andrii Kulian94e82d9b02017-07-13 15:33:06 -07002480 final ActivityStack parentStack = task != null ? task.getStack(): mSupervisor.mFocusedStack;
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002481
2482 if (parentStack != mSupervisor.mFocusedStack) {
2483 // If task's parent stack is not focused - use it during adjacent launch.
2484 return parentStack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002485 } else {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002486 if (mSupervisor.mFocusedStack != null && task == mSupervisor.mFocusedStack.topTask()) {
2487 // If task is already on top of focused stack - use it. We don't want to move the
2488 // existing focused task to adjacent stack, just deliver new intent in this case.
2489 return mSupervisor.mFocusedStack;
2490 }
2491
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002492 if (parentStack != null && parentStack.inSplitScreenPrimaryWindowingMode()) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002493 // If parent was in docked stack, the natural place to launch another activity
2494 // will be fullscreen, so it can appear alongside the docked window.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002495 final int activityType = mSupervisor.resolveActivityType(r, mOptions, task);
2496 return parentStack.getDisplay().getOrCreateStack(
2497 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, activityType, ON_TOP);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002498 } else {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002499 // If the parent is not in the docked stack, we check if there is docked window
2500 // and if yes, we will launch into that stack. If not, we just put the new
2501 // activity into parent's stack, because we can't find a better place.
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07002502 final ActivityStack dockedStack =
2503 mSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
Wale Ogunwale9dcf9462017-09-19 15:13:01 -07002504 if (dockedStack != null && !dockedStack.shouldBeVisible(r)) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002505 // There is a docked stack, but it isn't visible, so we can't launch into that.
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08002506 return mSupervisor.getLaunchStack(r, aOptions, task, ON_TOP);
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002507 } else {
2508 return dockedStack;
2509 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002510 }
2511 }
2512 }
2513
Bryce Lee7daee392017-10-12 13:46:18 -07002514 private boolean isLaunchModeOneOf(int mode1, int mode2) {
2515 return mode1 == mLaunchMode || mode2 == mLaunchMode;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002516 }
2517
Daichi Hirono15a02992016-04-27 18:47:01 +09002518 static boolean isDocumentLaunchesIntoExisting(int flags) {
2519 return (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2520 (flags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0;
2521 }
liulvpingcfa825f2016-09-26 20:00:15 +08002522
Bryce Lee4c9a5972017-12-01 22:14:24 -08002523 ActivityStarter setIntent(Intent intent) {
2524 mRequest.intent = intent;
2525 return this;
2526 }
2527
Bryce Lee32e09ef2018-03-19 15:29:49 -07002528 @VisibleForTesting
2529 Intent getIntent() {
2530 return mRequest.intent;
2531 }
2532
Bryce Lee4c9a5972017-12-01 22:14:24 -08002533 ActivityStarter setReason(String reason) {
2534 mRequest.reason = reason;
2535 return this;
2536 }
2537
2538 ActivityStarter setCaller(IApplicationThread caller) {
2539 mRequest.caller = caller;
2540 return this;
2541 }
2542
2543 ActivityStarter setEphemeralIntent(Intent intent) {
2544 mRequest.ephemeralIntent = intent;
2545 return this;
2546 }
2547
2548
2549 ActivityStarter setResolvedType(String type) {
2550 mRequest.resolvedType = type;
2551 return this;
2552 }
2553
2554 ActivityStarter setActivityInfo(ActivityInfo info) {
2555 mRequest.activityInfo = info;
2556 return this;
2557 }
2558
2559 ActivityStarter setResolveInfo(ResolveInfo info) {
2560 mRequest.resolveInfo = info;
2561 return this;
2562 }
2563
2564 ActivityStarter setVoiceSession(IVoiceInteractionSession voiceSession) {
2565 mRequest.voiceSession = voiceSession;
2566 return this;
2567 }
2568
2569 ActivityStarter setVoiceInteractor(IVoiceInteractor voiceInteractor) {
2570 mRequest.voiceInteractor = voiceInteractor;
2571 return this;
2572 }
2573
2574 ActivityStarter setResultTo(IBinder resultTo) {
2575 mRequest.resultTo = resultTo;
2576 return this;
2577 }
2578
2579 ActivityStarter setResultWho(String resultWho) {
2580 mRequest.resultWho = resultWho;
2581 return this;
2582 }
2583
2584 ActivityStarter setRequestCode(int requestCode) {
2585 mRequest.requestCode = requestCode;
2586 return this;
2587 }
2588
2589 ActivityStarter setCallingPid(int pid) {
2590 mRequest.callingPid = pid;
2591 return this;
2592 }
2593
2594 ActivityStarter setCallingUid(int uid) {
2595 mRequest.callingUid = uid;
2596 return this;
2597 }
2598
2599 ActivityStarter setCallingPackage(String callingPackage) {
2600 mRequest.callingPackage = callingPackage;
2601 return this;
2602 }
2603
2604 ActivityStarter setRealCallingPid(int pid) {
2605 mRequest.realCallingPid = pid;
2606 return this;
2607 }
2608
2609 ActivityStarter setRealCallingUid(int uid) {
2610 mRequest.realCallingUid = uid;
2611 return this;
2612 }
2613
2614 ActivityStarter setStartFlags(int startFlags) {
2615 mRequest.startFlags = startFlags;
2616 return this;
2617 }
2618
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002619 ActivityStarter setActivityOptions(SafeActivityOptions options) {
Bryce Lee4c9a5972017-12-01 22:14:24 -08002620 mRequest.activityOptions = options;
2621 return this;
2622 }
2623
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002624 ActivityStarter setActivityOptions(Bundle bOptions) {
2625 return setActivityOptions(SafeActivityOptions.fromBundle(bOptions));
2626 }
2627
Bryce Lee4c9a5972017-12-01 22:14:24 -08002628 ActivityStarter setIgnoreTargetSecurity(boolean ignoreTargetSecurity) {
2629 mRequest.ignoreTargetSecurity = ignoreTargetSecurity;
2630 return this;
2631 }
2632
Patrick Baumann31426b22018-05-21 13:46:40 -07002633 ActivityStarter setFilterCallingUid(int filterCallingUid) {
2634 mRequest.filterCallingUid = filterCallingUid;
2635 return this;
2636 }
2637
Bryce Lee4c9a5972017-12-01 22:14:24 -08002638 ActivityStarter setComponentSpecified(boolean componentSpecified) {
2639 mRequest.componentSpecified = componentSpecified;
2640 return this;
2641 }
2642
2643 ActivityStarter setOutActivity(ActivityRecord[] outActivity) {
2644 mRequest.outActivity = outActivity;
2645 return this;
2646 }
2647
2648 ActivityStarter setInTask(TaskRecord inTask) {
2649 mRequest.inTask = inTask;
2650 return this;
2651 }
2652
2653 ActivityStarter setWaitResult(WaitResult result) {
2654 mRequest.waitResult = result;
2655 return this;
2656 }
2657
2658 ActivityStarter setProfilerInfo(ProfilerInfo info) {
2659 mRequest.profilerInfo = info;
2660 return this;
2661 }
2662
2663 ActivityStarter setGlobalConfiguration(Configuration config) {
2664 mRequest.globalConfig = config;
2665 return this;
2666 }
2667
Bryce Lee4c9a5972017-12-01 22:14:24 -08002668 ActivityStarter setUserId(int userId) {
2669 mRequest.userId = userId;
2670 return this;
2671 }
2672
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002673 ActivityStarter setMayWait(int userId) {
Bryce Lee4c9a5972017-12-01 22:14:24 -08002674 mRequest.mayWait = true;
Bryce Lee4c9a5972017-12-01 22:14:24 -08002675 mRequest.userId = userId;
2676
2677 return this;
2678 }
2679
Jorim Jaggi6fa41c32018-04-23 18:35:00 +02002680 ActivityStarter setAllowPendingRemoteAnimationRegistryLookup(boolean allowLookup) {
2681 mRequest.allowPendingRemoteAnimationRegistryLookup = allowLookup;
2682 return this;
2683 }
2684
Michal Karpinski3eab9512018-07-20 15:32:00 +01002685 ActivityStarter setOriginatingPendingIntent(PendingIntentRecord originatingPendingIntent) {
2686 mRequest.originatingPendingIntent = originatingPendingIntent;
2687 return this;
2688 }
2689
Bryce Leed3624e12017-11-30 08:51:45 -08002690 void dump(PrintWriter pw, String prefix) {
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002691 prefix = prefix + " ";
Dianne Hackborne676ec72017-07-25 10:55:08 -07002692 pw.print(prefix);
2693 pw.print("mCurrentUser=");
2694 pw.println(mSupervisor.mCurrentUser);
2695 pw.print(prefix);
2696 pw.print("mLastStartReason=");
2697 pw.println(mLastStartReason);
2698 pw.print(prefix);
2699 pw.print("mLastStartActivityTimeMs=");
2700 pw.println(DateFormat.getDateTimeInstance().format(new Date(mLastStartActivityTimeMs)));
2701 pw.print(prefix);
2702 pw.print("mLastStartActivityResult=");
2703 pw.println(mLastStartActivityResult);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002704 ActivityRecord r = mLastStartActivityRecord[0];
2705 if (r != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002706 pw.print(prefix);
2707 pw.println("mLastStartActivityRecord:");
2708 r.dump(pw, prefix + " ");
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002709 }
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002710 if (mStartActivity != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002711 pw.print(prefix);
2712 pw.println("mStartActivity:");
2713 mStartActivity.dump(pw, prefix + " ");
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002714 }
2715 if (mIntent != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002716 pw.print(prefix);
2717 pw.print("mIntent=");
2718 pw.println(mIntent);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002719 }
2720 if (mOptions != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002721 pw.print(prefix);
2722 pw.print("mOptions=");
2723 pw.println(mOptions);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002724 }
Dianne Hackborne676ec72017-07-25 10:55:08 -07002725 pw.print(prefix);
2726 pw.print("mLaunchSingleTop=");
Bryce Lee7daee392017-10-12 13:46:18 -07002727 pw.print(LAUNCH_SINGLE_TOP == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002728 pw.print(" mLaunchSingleInstance=");
Bryce Lee7daee392017-10-12 13:46:18 -07002729 pw.print(LAUNCH_SINGLE_INSTANCE == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002730 pw.print(" mLaunchSingleTask=");
Bryce Lee7daee392017-10-12 13:46:18 -07002731 pw.println(LAUNCH_SINGLE_TASK == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002732 pw.print(prefix);
2733 pw.print("mLaunchFlags=0x");
2734 pw.print(Integer.toHexString(mLaunchFlags));
2735 pw.print(" mDoResume=");
2736 pw.print(mDoResume);
2737 pw.print(" mAddingToTask=");
2738 pw.println(mAddingToTask);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002739 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002740}