blob: 0104980f59fe147af0ba0398004060b9727c4447 [file] [log] [blame]
Kenny Guyb1b30262016-02-09 16:02:35 +00001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080017package com.android.server.am;
18
Wale Ogunwale01d66562015-12-29 08:19:19 -080019import static android.app.Activity.RESULT_CANCELED;
Bryce Leef9d49542017-06-26 16:27:32 -070020import static android.app.ActivityManager.START_ABORTED;
Bryce Leeaa5e8c32017-03-01 16:01:06 -080021import static android.app.ActivityManager.START_CANCELED;
Wale Ogunwale01d66562015-12-29 08:19:19 -080022import static android.app.ActivityManager.START_CLASS_NOT_FOUND;
23import static android.app.ActivityManager.START_DELIVERED_TO_TOP;
24import static android.app.ActivityManager.START_FLAG_ONLY_IF_NEEDED;
25import static android.app.ActivityManager.START_RETURN_INTENT_TO_CALLER;
26import static android.app.ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
27import static android.app.ActivityManager.START_SUCCESS;
28import static android.app.ActivityManager.START_TASK_TO_FRONT;
Wale Ogunwale68278562017-09-23 17:13:55 -070029import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
30import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
Wale Ogunwale7d7973a2018-04-05 10:25:59 -070031import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070032import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
33import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Wale Ogunwale0568aed2017-09-08 13:29:37 -070034import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080035import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
36import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
Wale Ogunwale2a25a622016-01-30 11:27:21 -080037import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080038import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
Wale Ogunwale01d66562015-12-29 08:19:19 -080039import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080040import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
Wale Ogunwale01d66562015-12-29 08:19:19 -080041import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION;
42import static android.content.Intent.FLAG_ACTIVITY_NO_USER_ACTION;
Wale Ogunwale01d66562015-12-29 08:19:19 -080043import static android.content.Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP;
44import static android.content.Intent.FLAG_ACTIVITY_REORDER_TO_FRONT;
45import static android.content.Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED;
46import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
47import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP;
48import static android.content.pm.ActivityInfo.DOCUMENT_LAUNCH_ALWAYS;
Bryce Leef65ee7e2018-03-26 16:03:47 -070049import static android.content.pm.ActivityInfo.LAUNCH_MULTIPLE;
Wale Ogunwale01d66562015-12-29 08:19:19 -080050import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
51import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
52import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
David Stevensc6b91c62017-02-08 14:23:58 -080053import static android.view.Display.DEFAULT_DISPLAY;
Andrii Kulian16802aa2016-11-02 12:21:33 -070054import static android.view.Display.INVALID_DISPLAY;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080055import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
56import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
57import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
58import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RESULTS;
59import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
60import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
61import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USER_LEAVING;
62import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
63import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
64import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RESULTS;
65import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_USER_LEAVING;
66import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
67import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
68import static com.android.server.am.ActivityManagerService.ANIMATE;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080069import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
Winson Chung74666102017-02-22 17:49:24 -080070import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080071import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
Wale Ogunwalecacfaa22016-01-15 11:26:08 -080072import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080073import static com.android.server.am.ActivityStackSupervisor.TAG_TASKS;
Filip Gruszczynskie826f322016-01-11 17:15:22 -080074import static com.android.server.am.EventLogTags.AM_NEW_INTENT;
Winson Chung74666102017-02-22 17:49:24 -080075import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
76import static com.android.server.am.TaskRecord.REPARENT_MOVE_STACK_TO_FRONT;
77
Todd Kennedye9910222017-02-21 16:00:11 -080078import android.annotation.NonNull;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +010079import android.annotation.Nullable;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080080import android.app.ActivityManager;
81import android.app.ActivityOptions;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080082import android.app.IApplicationThread;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080083import android.app.PendingIntent;
84import android.app.ProfilerInfo;
Sudheer Shankafc46e9b2016-10-21 17:55:27 -070085import android.app.WaitResult;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080086import android.content.IIntentSender;
87import android.content.Intent;
88import android.content.IntentSender;
89import android.content.pm.ActivityInfo;
90import android.content.pm.ApplicationInfo;
Todd Kennedye9910222017-02-21 16:00:11 -080091import android.content.pm.AuxiliaryResolveInfo;
Kenny Guyb1b30262016-02-09 16:02:35 +000092import android.content.pm.PackageManager;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080093import android.content.pm.ResolveInfo;
Kenny Guyb1b30262016-02-09 16:02:35 +000094import android.content.pm.UserInfo;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080095import android.content.res.Configuration;
96import android.graphics.Rect;
97import android.os.Binder;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080098import android.os.Bundle;
99import android.os.IBinder;
100import android.os.RemoteException;
101import android.os.SystemClock;
102import android.os.UserHandle;
Kenny Guyb1b30262016-02-09 16:02:35 +0000103import android.os.UserManager;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800104import android.service.voice.IVoiceInteractionSession;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700105import android.text.TextUtils;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800106import android.util.EventLog;
Bryce Leedaa91e42017-12-06 14:13:01 -0800107import android.util.Pools.SynchronizedPool;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800108import android.util.Slog;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800109
Bryce Leed3624e12017-11-30 08:51:45 -0800110import com.android.internal.annotations.VisibleForTesting;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800111import com.android.internal.app.HeavyWeightSwitcherActivity;
112import com.android.internal.app.IVoiceInteractor;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800113import com.android.server.am.ActivityStackSupervisor.PendingActivityLaunch;
Bryce Leeec55eb02017-12-05 20:51:27 -0800114import com.android.server.am.LaunchParamsController.LaunchParams;
Todd Kennedy1fb34042017-03-01 13:56:58 -0800115import com.android.server.pm.InstantAppResolver;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800116
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700117import java.io.PrintWriter;
118import java.text.DateFormat;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700119import java.util.Date;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800120
121/**
Bryce Leed3624e12017-11-30 08:51:45 -0800122 * Controller for interpreting how and then launching an activity.
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800123 *
124 * This class collects all the logic for determining how an intent and flags should be turned into
125 * an activity and associated task and stack.
126 */
Wale Ogunwale01d66562015-12-29 08:19:19 -0800127class ActivityStarter {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800128 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStarter" : TAG_AM;
129 private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS;
130 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
131 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
132 private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING;
Bryce Lee7daee392017-10-12 13:46:18 -0700133 private static final int INVALID_LAUNCH_MODE = -1;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800134
135 private final ActivityManagerService mService;
136 private final ActivityStackSupervisor mSupervisor;
Benjamin Franz563707b2017-06-29 15:06:13 +0100137 private final ActivityStartInterceptor mInterceptor;
Bryce Leed3624e12017-11-30 08:51:45 -0800138 private final ActivityStartController mController;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800139
Wale Ogunwale01d66562015-12-29 08:19:19 -0800140 // Share state variable among methods when starting an activity.
141 private ActivityRecord mStartActivity;
142 private Intent mIntent;
143 private int mCallingUid;
144 private ActivityOptions mOptions;
145
Bryce Lee7daee392017-10-12 13:46:18 -0700146 private int mLaunchMode;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800147 private boolean mLaunchTaskBehind;
148 private int mLaunchFlags;
149
Bryce Leeec55eb02017-12-05 20:51:27 -0800150 private LaunchParams mLaunchParams = new LaunchParams();
Wale Ogunwale01d66562015-12-29 08:19:19 -0800151
152 private ActivityRecord mNotTop;
153 private boolean mDoResume;
154 private int mStartFlags;
155 private ActivityRecord mSourceRecord;
Bryce Lee7daee392017-10-12 13:46:18 -0700156
David Stevense5a7b642017-05-22 13:18:23 -0700157 // The display to launch the activity onto, barring any strong reason to do otherwise.
158 private int mPreferredDisplayId;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800159
160 private TaskRecord mInTask;
161 private boolean mAddingToTask;
162 private TaskRecord mReuseTask;
163
164 private ActivityInfo mNewTaskInfo;
165 private Intent mNewTaskIntent;
166 private ActivityStack mSourceStack;
167 private ActivityStack mTargetStack;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800168 private boolean mMovedToFront;
169 private boolean mNoAnimation;
170 private boolean mKeepCurTransition;
Jorim Jaggic875ae72016-04-26 22:41:06 -0700171 private boolean mAvoidMoveToFront;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800172
Bryce Lee325e09682017-10-05 17:20:25 -0700173 // We must track when we deliver the new intent since multiple code paths invoke
174 // {@link #deliverNewIntent}. This is due to early returns in the code path. This flag is used
175 // inside {@link #deliverNewIntent} to suppress duplicate requests and ensure the intent is
176 // delivered at most once.
177 private boolean mIntentDelivered;
178
Wale Ogunwale01d66562015-12-29 08:19:19 -0800179 private IVoiceInteractionSession mVoiceSession;
180 private IVoiceInteractor mVoiceInteractor;
181
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700182 // Last activity record we attempted to start
183 private final ActivityRecord[] mLastStartActivityRecord = new ActivityRecord[1];
184 // The result of the last activity we attempted to start.
185 private int mLastStartActivityResult;
186 // Time in milli seconds we attempted to start the last activity.
187 private long mLastStartActivityTimeMs;
188 // The reason we were trying to start the last activity
189 private String mLastStartReason;
Wale Ogunwale59bcba62017-06-16 12:42:51 -0700190
Bryce Lee4c9a5972017-12-01 22:14:24 -0800191 /*
192 * Request details provided through setter methods. Should be reset after {@link #execute()}
193 * to avoid unnecessarily retaining parameters. Note that the request is ignored when
194 * {@link #startResolvedActivity} is invoked directly.
195 */
196 private Request mRequest = new Request();
197
Bryce Leed3624e12017-11-30 08:51:45 -0800198 /**
199 * An interface that to provide {@link ActivityStarter} instances to the controller. This is
200 * used by tests to inject their own starter implementations for verification purposes.
201 */
202 @VisibleForTesting
203 interface Factory {
204 /**
Bryce Lee4c9a5972017-12-01 22:14:24 -0800205 * Sets the {@link ActivityStartController} to be passed to {@link ActivityStarter}.
206 */
207 void setController(ActivityStartController controller);
208
209 /**
Bryce Leed3624e12017-11-30 08:51:45 -0800210 * Generates an {@link ActivityStarter} that is ready to handle a new start request.
211 * @param controller The {@link ActivityStartController} which the starter who will own
212 * this instance.
213 * @return an {@link ActivityStarter}
214 */
Bryce Leedaa91e42017-12-06 14:13:01 -0800215 ActivityStarter obtain();
216
217 /**
218 * Recycles a starter for reuse.
219 */
220 void recycle(ActivityStarter starter);
Wale Ogunwale01d66562015-12-29 08:19:19 -0800221 }
222
Bryce Leed3624e12017-11-30 08:51:45 -0800223 /**
224 * Default implementation of {@link StarterFactory}.
225 */
226 static class DefaultFactory implements Factory {
Bryce Leedaa91e42017-12-06 14:13:01 -0800227 /**
228 * The maximum count of starters that should be active at one time:
229 * 1. last ran starter (for logging and post activity processing)
230 * 2. current running starter
231 * 3. starter from re-entry in (2)
232 */
233 private final int MAX_STARTER_COUNT = 3;
234
Bryce Lee4c9a5972017-12-01 22:14:24 -0800235 private ActivityStartController mController;
236 private ActivityManagerService mService;
237 private ActivityStackSupervisor mSupervisor;
238 private ActivityStartInterceptor mInterceptor;
239
Bryce Leedaa91e42017-12-06 14:13:01 -0800240 private SynchronizedPool<ActivityStarter> mStarterPool =
241 new SynchronizedPool<>(MAX_STARTER_COUNT);
242
Bryce Lee4c9a5972017-12-01 22:14:24 -0800243 DefaultFactory(ActivityManagerService service,
244 ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
245 mService = service;
246 mSupervisor = supervisor;
247 mInterceptor = interceptor;
Bryce Leed3624e12017-11-30 08:51:45 -0800248 }
Bryce Lee4c9a5972017-12-01 22:14:24 -0800249
250 @Override
251 public void setController(ActivityStartController controller) {
252 mController = controller;
253 }
254
255 @Override
Bryce Leedaa91e42017-12-06 14:13:01 -0800256 public ActivityStarter obtain() {
257 ActivityStarter starter = mStarterPool.acquire();
258
259 if (starter == null) {
260 starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
261 }
262
263 return starter;
264 }
265
266 @Override
267 public void recycle(ActivityStarter starter) {
268 starter.reset(true /* clearRequest*/);
269 mStarterPool.release(starter);
Bryce Lee4c9a5972017-12-01 22:14:24 -0800270 }
271 }
272
273 /**
274 * Container for capturing initial start request details. This information is NOT reset until
275 * the {@link ActivityStarter} is recycled, allowing for multiple invocations with the same
276 * parameters.
277 *
278 * TODO(b/64750076): Investigate consolidating member variables of {@link ActivityStarter} with
279 * the request object. Note that some member variables are referenced in
280 * {@link #dump(PrintWriter, String)} and therefore cannot be cleared immediately after
281 * execution.
282 */
283 private static class Request {
284 private static final int DEFAULT_CALLING_UID = -1;
285 private static final int DEFAULT_CALLING_PID = 0;
286
287 IApplicationThread caller;
288 Intent intent;
289 Intent ephemeralIntent;
290 String resolvedType;
291 ActivityInfo activityInfo;
292 ResolveInfo resolveInfo;
293 IVoiceInteractionSession voiceSession;
294 IVoiceInteractor voiceInteractor;
295 IBinder resultTo;
296 String resultWho;
297 int requestCode;
298 int callingPid = DEFAULT_CALLING_UID;
299 int callingUid = DEFAULT_CALLING_PID;
300 String callingPackage;
301 int realCallingPid;
302 int realCallingUid;
303 int startFlags;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100304 SafeActivityOptions activityOptions;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800305 boolean ignoreTargetSecurity;
306 boolean componentSpecified;
Winson Chunge2d72172018-01-25 17:46:20 +0000307 boolean avoidMoveToFront;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800308 ActivityRecord[] outActivity;
309 TaskRecord inTask;
310 String reason;
311 ProfilerInfo profilerInfo;
312 Configuration globalConfig;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800313 int userId;
314 WaitResult waitResult;
315
316 /**
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200317 * If set to {@code true}, allows this activity start to look into
318 * {@link PendingRemoteAnimationRegistry}
319 */
320 boolean allowPendingRemoteAnimationRegistryLookup;
321
322 /**
Bryce Lee4c9a5972017-12-01 22:14:24 -0800323 * Indicates that we should wait for the result of the start request. This flag is set when
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100324 * {@link ActivityStarter#setMayWait(int)} is called.
Bryce Lee4c9a5972017-12-01 22:14:24 -0800325 * {@see ActivityStarter#startActivityMayWait}.
326 */
327 boolean mayWait;
Bryce Leedaa91e42017-12-06 14:13:01 -0800328
329 /**
Bryce Leea3cd8e02018-01-09 15:44:24 -0800330 * Ensure constructed request matches reset instance.
331 */
332 Request() {
333 reset();
334 }
335
336 /**
Bryce Leedaa91e42017-12-06 14:13:01 -0800337 * Sets values back to the initial state, clearing any held references.
338 */
339 void reset() {
340 caller = null;
341 intent = null;
342 ephemeralIntent = null;
343 resolvedType = null;
344 activityInfo = null;
345 resolveInfo = null;
346 voiceSession = null;
347 voiceInteractor = null;
348 resultTo = null;
349 resultWho = null;
350 requestCode = 0;
Bryce Leea3cd8e02018-01-09 15:44:24 -0800351 callingPid = DEFAULT_CALLING_PID;
352 callingUid = DEFAULT_CALLING_UID;
Bryce Leedaa91e42017-12-06 14:13:01 -0800353 callingPackage = null;
354 realCallingPid = 0;
355 realCallingUid = 0;
356 startFlags = 0;
357 activityOptions = null;
358 ignoreTargetSecurity = false;
359 componentSpecified = false;
360 outActivity = null;
361 inTask = null;
362 reason = null;
363 profilerInfo = null;
364 globalConfig = null;
Bryce Leedaa91e42017-12-06 14:13:01 -0800365 userId = 0;
366 waitResult = null;
367 mayWait = false;
Winson Chunge2d72172018-01-25 17:46:20 +0000368 avoidMoveToFront = false;
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200369 allowPendingRemoteAnimationRegistryLookup = true;
Bryce Leedaa91e42017-12-06 14:13:01 -0800370 }
371
372 /**
373 * Adopts all values from passed in request.
374 */
375 void set(Request request) {
376 caller = request.caller;
377 intent = request.intent;
378 ephemeralIntent = request.ephemeralIntent;
379 resolvedType = request.resolvedType;
380 activityInfo = request.activityInfo;
381 resolveInfo = request.resolveInfo;
382 voiceSession = request.voiceSession;
383 voiceInteractor = request.voiceInteractor;
384 resultTo = request.resultTo;
385 resultWho = request.resultWho;
386 requestCode = request.requestCode;
387 callingPid = request.callingPid;
388 callingUid = request.callingUid;
389 callingPackage = request.callingPackage;
390 realCallingPid = request.realCallingPid;
391 realCallingUid = request.realCallingUid;
392 startFlags = request.startFlags;
393 activityOptions = request.activityOptions;
394 ignoreTargetSecurity = request.ignoreTargetSecurity;
395 componentSpecified = request.componentSpecified;
396 outActivity = request.outActivity;
397 inTask = request.inTask;
398 reason = request.reason;
399 profilerInfo = request.profilerInfo;
400 globalConfig = request.globalConfig;
Bryce Leedaa91e42017-12-06 14:13:01 -0800401 userId = request.userId;
402 waitResult = request.waitResult;
403 mayWait = request.mayWait;
Winson Chunge2d72172018-01-25 17:46:20 +0000404 avoidMoveToFront = request.avoidMoveToFront;
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200405 allowPendingRemoteAnimationRegistryLookup
406 = request.allowPendingRemoteAnimationRegistryLookup;
Bryce Leedaa91e42017-12-06 14:13:01 -0800407 }
Bryce Leed3624e12017-11-30 08:51:45 -0800408 }
409
410 ActivityStarter(ActivityStartController controller, ActivityManagerService service,
411 ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
412 mController = controller;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800413 mService = service;
Bryce Leed3624e12017-11-30 08:51:45 -0800414 mSupervisor = supervisor;
415 mInterceptor = interceptor;
Bryce Leedaa91e42017-12-06 14:13:01 -0800416 reset(true);
417 }
418
419 /**
420 * Effectively duplicates the starter passed in. All state and request values will be
421 * mirrored.
422 * @param starter
423 */
424 void set(ActivityStarter starter) {
425 mStartActivity = starter.mStartActivity;
426 mIntent = starter.mIntent;
427 mCallingUid = starter.mCallingUid;
428 mOptions = starter.mOptions;
429
430 mLaunchTaskBehind = starter.mLaunchTaskBehind;
431 mLaunchFlags = starter.mLaunchFlags;
432 mLaunchMode = starter.mLaunchMode;
433
Bryce Leeec55eb02017-12-05 20:51:27 -0800434 mLaunchParams.set(starter.mLaunchParams);
Bryce Leedaa91e42017-12-06 14:13:01 -0800435
436 mNotTop = starter.mNotTop;
437 mDoResume = starter.mDoResume;
438 mStartFlags = starter.mStartFlags;
439 mSourceRecord = starter.mSourceRecord;
440 mPreferredDisplayId = starter.mPreferredDisplayId;
441
442 mInTask = starter.mInTask;
443 mAddingToTask = starter.mAddingToTask;
444 mReuseTask = starter.mReuseTask;
445
446 mNewTaskInfo = starter.mNewTaskInfo;
447 mNewTaskIntent = starter.mNewTaskIntent;
448 mSourceStack = starter.mSourceStack;
449
450 mTargetStack = starter.mTargetStack;
451 mMovedToFront = starter.mMovedToFront;
452 mNoAnimation = starter.mNoAnimation;
453 mKeepCurTransition = starter.mKeepCurTransition;
454 mAvoidMoveToFront = starter.mAvoidMoveToFront;
455
456 mVoiceSession = starter.mVoiceSession;
457 mVoiceInteractor = starter.mVoiceInteractor;
458
459 mIntentDelivered = starter.mIntentDelivered;
460
461 mRequest.set(starter.mRequest);
Bryce Leed3624e12017-11-30 08:51:45 -0800462 }
463
Bryce Lee4c9a5972017-12-01 22:14:24 -0800464 ActivityRecord getStartActivity() {
465 return mStartActivity;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800466 }
467
Bryce Lee4c9a5972017-12-01 22:14:24 -0800468 boolean relatedToPackage(String packageName) {
469 return (mLastStartActivityRecord[0] != null
470 && packageName.equals(mLastStartActivityRecord[0].packageName))
471 || (mStartActivity != null && packageName.equals(mStartActivity.packageName));
472 }
473
474 /**
475 * Starts an activity based on the request parameters provided earlier.
476 * @return The starter result.
477 */
478 int execute() {
Bryce Leedaa91e42017-12-06 14:13:01 -0800479 try {
480 // TODO(b/64750076): Look into passing request directly to these methods to allow
481 // for transactional diffs and preprocessing.
482 if (mRequest.mayWait) {
483 return startActivityMayWait(mRequest.caller, mRequest.callingUid,
484 mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
485 mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
486 mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
487 mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100488 mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200489 mRequest.inTask, mRequest.reason,
490 mRequest.allowPendingRemoteAnimationRegistryLookup);
Bryce Leedaa91e42017-12-06 14:13:01 -0800491 } else {
492 return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
493 mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
494 mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
495 mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
496 mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
497 mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
498 mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200499 mRequest.outActivity, mRequest.inTask, mRequest.reason,
500 mRequest.allowPendingRemoteAnimationRegistryLookup);
Bryce Leedaa91e42017-12-06 14:13:01 -0800501 }
502 } finally {
503 onExecutionComplete();
504 }
505 }
506
507 /**
508 * Starts an activity based on the provided {@link ActivityRecord} and environment parameters.
509 * Note that this method is called internally as well as part of {@link #startActivity}.
510 *
511 * @return The start result.
512 */
513 int startResolvedActivity(final ActivityRecord r, ActivityRecord sourceRecord,
514 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
515 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
516 ActivityRecord[] outActivity) {
517 try {
518 return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
519 doResume, options, inTask, outActivity);
520 } finally {
521 onExecutionComplete();
Bryce Lee4c9a5972017-12-01 22:14:24 -0800522 }
523 }
524
525 private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700526 String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
527 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
528 IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
529 String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100530 SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200531 ActivityRecord[] outActivity, TaskRecord inTask, String reason,
532 boolean allowPendingRemoteAnimationRegistryLookup) {
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700533
534 if (TextUtils.isEmpty(reason)) {
535 throw new IllegalArgumentException("Need to specify a reason.");
536 }
537 mLastStartReason = reason;
538 mLastStartActivityTimeMs = System.currentTimeMillis();
539 mLastStartActivityRecord[0] = null;
540
541 mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
542 aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
543 callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
544 options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200545 inTask, allowPendingRemoteAnimationRegistryLookup);
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700546
547 if (outActivity != null) {
548 // mLastStartActivityRecord[0] is set in the call to startActivity above.
549 outActivity[0] = mLastStartActivityRecord[0];
550 }
Bryce Leef9d49542017-06-26 16:27:32 -0700551
Bryce Lee93e7f792017-10-25 15:54:55 -0700552 return getExternalResult(mLastStartActivityResult);
553 }
554
Bryce Leed3624e12017-11-30 08:51:45 -0800555 static int getExternalResult(int result) {
Bryce Leef9d49542017-06-26 16:27:32 -0700556 // Aborted results are treated as successes externally, but we must track them internally.
Bryce Lee93e7f792017-10-25 15:54:55 -0700557 return result != START_ABORTED ? result : START_SUCCESS;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700558 }
559
Bryce Leedaa91e42017-12-06 14:13:01 -0800560 /**
561 * Called when execution is complete. Sets state indicating completion and proceeds with
562 * recycling if appropriate.
563 */
564 private void onExecutionComplete() {
565 mController.onExecutionComplete(this);
566 }
567
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700568 private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800569 String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
570 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
571 IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
572 String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100573 SafeActivityOptions options,
574 boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200575 TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800576 int err = ActivityManager.START_SUCCESS;
Chad Brubaker06068612017-04-06 09:43:47 -0700577 // Pull the optional Ephemeral Installer-only bundle out of the options early.
578 final Bundle verificationBundle
579 = options != null ? options.popAppVerificationBundle() : null;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800580
581 ProcessRecord callerApp = null;
582 if (caller != null) {
583 callerApp = mService.getRecordForAppLocked(caller);
584 if (callerApp != null) {
585 callingPid = callerApp.pid;
586 callingUid = callerApp.info.uid;
587 } else {
588 Slog.w(TAG, "Unable to find app for caller " + caller
589 + " (pid=" + callingPid + ") when starting: "
590 + intent.toString());
591 err = ActivityManager.START_PERMISSION_DENIED;
592 }
593 }
594
Bryce Lee93e7f792017-10-25 15:54:55 -0700595 final int userId = aInfo != null && aInfo.applicationInfo != null
596 ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800597
598 if (err == ActivityManager.START_SUCCESS) {
599 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
Andrii Kulian03c403d2016-11-11 11:14:12 -0800600 + "} from uid " + callingUid);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800601 }
602
603 ActivityRecord sourceRecord = null;
604 ActivityRecord resultRecord = null;
605 if (resultTo != null) {
606 sourceRecord = mSupervisor.isInAnyStackLocked(resultTo);
607 if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
608 "Will send result to " + resultTo + " " + sourceRecord);
609 if (sourceRecord != null) {
610 if (requestCode >= 0 && !sourceRecord.finishing) {
611 resultRecord = sourceRecord;
612 }
613 }
614 }
615
616 final int launchFlags = intent.getFlags();
617
618 if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
619 // Transfer the result target from the source activity to the new
620 // one being started, including any failures.
621 if (requestCode >= 0) {
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100622 SafeActivityOptions.abort(options);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800623 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
624 }
625 resultRecord = sourceRecord.resultTo;
626 if (resultRecord != null && !resultRecord.isInStackLocked()) {
627 resultRecord = null;
628 }
629 resultWho = sourceRecord.resultWho;
630 requestCode = sourceRecord.requestCode;
631 sourceRecord.resultTo = null;
632 if (resultRecord != null) {
633 resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
634 }
635 if (sourceRecord.launchedFromUid == callingUid) {
636 // The new activity is being launched from the same uid as the previous
637 // activity in the flow, and asking to forward its result back to the
638 // previous. In this case the activity is serving as a trampoline between
639 // the two, so we also want to update its launchedFromPackage to be the
640 // same as the previous activity. Note that this is safe, since we know
641 // these two packages come from the same uid; the caller could just as
642 // well have supplied that same package name itself. This specifially
643 // deals with the case of an intent picker/chooser being launched in the app
644 // flow to redirect to an activity picked by the user, where we want the final
645 // activity to consider it to have been launched by the previous app activity.
646 callingPackage = sourceRecord.launchedFromPackage;
647 }
648 }
649
650 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
651 // We couldn't find a class that can handle the given Intent.
652 // That's the end of that!
653 err = ActivityManager.START_INTENT_NOT_RESOLVED;
654 }
655
656 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
657 // We couldn't find the specific class specified in the Intent.
658 // Also the end of the line.
659 err = ActivityManager.START_CLASS_NOT_FOUND;
660 }
661
662 if (err == ActivityManager.START_SUCCESS && sourceRecord != null
Bryce Leeaf691c02017-03-20 14:20:22 -0700663 && sourceRecord.getTask().voiceSession != null) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800664 // If this activity is being launched as part of a voice session, we need
665 // to ensure that it is safe to do so. If the upcoming activity will also
666 // be part of the voice session, we can only launch it if it has explicitly
667 // said it supports the VOICE category, or it is a part of the calling app.
668 if ((launchFlags & FLAG_ACTIVITY_NEW_TASK) == 0
669 && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
670 try {
671 intent.addCategory(Intent.CATEGORY_VOICE);
Bryce Leeba8f4422017-11-20 12:35:57 -0800672 if (!mService.getPackageManager().activitySupportsIntent(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800673 intent.getComponent(), intent, resolvedType)) {
674 Slog.w(TAG,
675 "Activity being started in current voice task does not support voice: "
676 + intent);
677 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
678 }
679 } catch (RemoteException e) {
680 Slog.w(TAG, "Failure checking voice capabilities", e);
681 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
682 }
683 }
684 }
685
686 if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
687 // If the caller is starting a new voice session, just make sure the target
688 // is actually allowing it to run this way.
689 try {
Bryce Leeba8f4422017-11-20 12:35:57 -0800690 if (!mService.getPackageManager().activitySupportsIntent(intent.getComponent(),
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800691 intent, resolvedType)) {
692 Slog.w(TAG,
693 "Activity being started in new voice task does not support: "
694 + intent);
695 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
696 }
697 } catch (RemoteException e) {
698 Slog.w(TAG, "Failure checking voice capabilities", e);
699 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
700 }
701 }
702
Andrii Kulian02b7a832016-10-06 23:11:56 -0700703 final ActivityStack resultStack = resultRecord == null ? null : resultRecord.getStack();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800704
Wale Ogunwale01d66562015-12-29 08:19:19 -0800705 if (err != START_SUCCESS) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800706 if (resultRecord != null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -0800707 resultStack.sendActivityResultLocked(
708 -1, resultRecord, resultWho, requestCode, RESULT_CANCELED, null);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800709 }
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100710 SafeActivityOptions.abort(options);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800711 return err;
712 }
713
714 boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100715 requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity,
Winson Chungc9804e72018-05-15 11:01:44 -0700716 inTask != null, callerApp, resultRecord, resultStack);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800717 abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
718 callingPid, resolvedType, aInfo.applicationInfo);
719
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100720 // Merge the two options bundles, while realCallerOptions takes precedence.
721 ActivityOptions checkedOptions = options != null
722 ? options.getOptions(intent, aInfo, callerApp, mSupervisor)
723 : null;
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200724 if (allowPendingRemoteAnimationRegistryLookup) {
725 checkedOptions = mService.getActivityStartController()
726 .getPendingRemoteAnimationRegistry()
727 .overrideOptionsIfNeeded(callingPackage, checkedOptions);
728 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800729 if (mService.mController != null) {
730 try {
731 // The Intent we give to the watcher has the extra data
732 // stripped off, since it can contain private information.
733 Intent watchIntent = intent.cloneFilter();
734 abort |= !mService.mController.activityStarting(watchIntent,
735 aInfo.applicationInfo.packageName);
736 } catch (RemoteException e) {
737 mService.mController = null;
738 }
739 }
740
Rubin Xu58d25992016-01-21 17:47:13 +0000741 mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage);
Benjamin Franz563707b2017-06-29 15:06:13 +0100742 if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100743 callingUid, checkedOptions)) {
Benjamin Franz563707b2017-06-29 15:06:13 +0100744 // activity start was intercepted, e.g. because the target user is currently in quiet
745 // mode (turn off work) or the target application is suspended
746 intent = mInterceptor.mIntent;
747 rInfo = mInterceptor.mRInfo;
748 aInfo = mInterceptor.mAInfo;
749 resolvedType = mInterceptor.mResolvedType;
750 inTask = mInterceptor.mInTask;
751 callingPid = mInterceptor.mCallingPid;
752 callingUid = mInterceptor.mCallingUid;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100753 checkedOptions = mInterceptor.mActivityOptions;
Benjamin Franz563707b2017-06-29 15:06:13 +0100754 }
755
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800756 if (abort) {
757 if (resultRecord != null) {
758 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Wale Ogunwale01d66562015-12-29 08:19:19 -0800759 RESULT_CANCELED, null);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800760 }
761 // We pretend to the caller that it was really started, but
762 // they will just get a cancel result.
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100763 ActivityOptions.abort(checkedOptions);
Bryce Leef9d49542017-06-26 16:27:32 -0700764 return START_ABORTED;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800765 }
766
767 // If permissions need a review before any of the app components can run, we
768 // launch the review activity and pass a pending intent to start the activity
769 // we are to launching now after the review is completed.
Svet Ganov77df6f32016-08-17 11:46:34 -0700770 if (mService.mPermissionReviewRequired && aInfo != null) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800771 if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
772 aInfo.packageName, userId)) {
773 IIntentSender target = mService.getIntentSenderLocked(
774 ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
775 callingUid, userId, null, null, 0, new Intent[]{intent},
776 new String[]{resolvedType}, PendingIntent.FLAG_CANCEL_CURRENT
777 | PendingIntent.FLAG_ONE_SHOT, null);
778
779 final int flags = intent.getFlags();
780 Intent newIntent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
781 newIntent.setFlags(flags
782 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
783 newIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, aInfo.packageName);
784 newIntent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target));
785 if (resultRecord != null) {
786 newIntent.putExtra(Intent.EXTRA_RESULT_NEEDED, true);
787 }
788 intent = newIntent;
789
790 resolvedType = null;
791 callingUid = realCallingUid;
792 callingPid = realCallingPid;
793
Svet Ganovcbcbf662018-05-10 17:25:29 -0700794 rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0,
795 computeResolveFilterUid(callingUid, realCallingUid));
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800796 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
797 null /*profilerInfo*/);
798
799 if (DEBUG_PERMISSIONS_REVIEW) {
800 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true,
801 true, false) + "} from uid " + callingUid + " on display "
Andrii Kulian94e82d9b02017-07-13 15:33:06 -0700802 + (mSupervisor.mFocusedStack == null
803 ? DEFAULT_DISPLAY : mSupervisor.mFocusedStack.mDisplayId));
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800804 }
805 }
806 }
807
808 // If we have an ephemeral app, abort the process of launching the resolved intent.
809 // Instead, launch the ephemeral installer. Once the installer is finished, it
810 // starts either the intent we resolved here [on install error] or the ephemeral
811 // app [on install success].
Patrick Baumanna89a1722018-02-07 15:26:52 -0800812 if (rInfo != null && rInfo.auxiliaryInfo != null) {
Todd Kennedye9910222017-02-21 16:00:11 -0800813 intent = createLaunchIntent(rInfo.auxiliaryInfo, ephemeralIntent,
Chad Brubaker06068612017-04-06 09:43:47 -0700814 callingPackage, verificationBundle, resolvedType, userId);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800815 resolvedType = null;
816 callingUid = realCallingUid;
817 callingPid = realCallingPid;
818
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800819 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
820 }
821
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800822 ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
823 callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
824 resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100825 mSupervisor, checkedOptions, sourceRecord);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800826 if (outActivity != null) {
827 outActivity[0] = r;
828 }
829
830 if (r.appTimeTracker == null && sourceRecord != null) {
831 // If the caller didn't specify an explicit time tracker, we want to continue
832 // tracking under any it has.
833 r.appTimeTracker = sourceRecord.appTimeTracker;
834 }
835
836 final ActivityStack stack = mSupervisor.mFocusedStack;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100837
838 // If we are starting an activity that is not from the same uid as the currently resumed
839 // one, check whether app switches are allowed.
Bryce Leec4ab62a2018-03-05 14:19:26 -0800840 if (voiceSession == null && (stack.getResumedActivity() == null
841 || stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800842 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
843 realCallingPid, realCallingUid, "Activity start")) {
Bryce Leed3624e12017-11-30 08:51:45 -0800844 mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
845 sourceRecord, startFlags, stack, callerApp));
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100846 ActivityOptions.abort(checkedOptions);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800847 return ActivityManager.START_SWITCHES_CANCELED;
848 }
849 }
850
851 if (mService.mDidAppSwitch) {
852 // This is the second allowed switch since we stopped switches,
853 // so now just generally allow switches. Use case: user presses
854 // home (switches disabled, switch to home, mDidAppSwitch now true);
855 // user taps a home icon (coming from home so allowed, we hit here
856 // and now allow anyone to switch again).
857 mService.mAppSwitchesAllowedTime = 0;
858 } else {
859 mService.mDidAppSwitch = true;
860 }
861
Bryce Leed3624e12017-11-30 08:51:45 -0800862 mController.doPendingActivityLaunches(false);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800863
Bryce Leedaa91e42017-12-06 14:13:01 -0800864 return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100865 true /* doResume */, checkedOptions, inTask, outActivity);
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -0800866 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800867
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100868
Bryce Leeaa5e8c32017-03-01 16:01:06 -0800869 /**
870 * Creates a launch intent for the given auxiliary resolution data.
871 */
Patrick Baumann577d4022018-01-31 16:55:10 +0000872 private @NonNull Intent createLaunchIntent(@Nullable AuxiliaryResolveInfo auxiliaryResponse,
Chad Brubaker06068612017-04-06 09:43:47 -0700873 Intent originalIntent, String callingPackage, Bundle verificationBundle,
874 String resolvedType, int userId) {
Patrick Baumann577d4022018-01-31 16:55:10 +0000875 if (auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo) {
Todd Kennedye9910222017-02-21 16:00:11 -0800876 // request phase two resolution
877 mService.getPackageManagerInternalLocked().requestInstantAppResolutionPhaseTwo(
Chad Brubaker06068612017-04-06 09:43:47 -0700878 auxiliaryResponse, originalIntent, resolvedType, callingPackage,
879 verificationBundle, userId);
Todd Kennedye9910222017-02-21 16:00:11 -0800880 }
Todd Kennedydfc27c62017-05-17 15:32:10 -0700881 return InstantAppResolver.buildEphemeralInstallerIntent(
Patrick Baumann577d4022018-01-31 16:55:10 +0000882 originalIntent,
883 InstantAppResolver.sanitizeIntent(originalIntent),
884 auxiliaryResponse == null ? null : auxiliaryResponse.failureIntent,
885 callingPackage,
886 verificationBundle,
887 resolvedType,
888 userId,
889 auxiliaryResponse == null ? null : auxiliaryResponse.installFailureActivity,
890 auxiliaryResponse == null ? null : auxiliaryResponse.token,
891 auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo,
892 auxiliaryResponse == null ? null : auxiliaryResponse.filters);
Todd Kennedye9910222017-02-21 16:00:11 -0800893 }
894
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700895 void postStartActivityProcessing(ActivityRecord r, int result, ActivityStack targetStack) {
Bryce Lee7f936862017-05-09 15:33:18 -0700896 if (ActivityManager.isStartResultFatalError(result)) {
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -0800897 return;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800898 }
Filip Gruszczynski303210b2016-01-08 16:28:08 -0800899
Chong Zhang5022da32016-06-21 16:31:37 -0700900 // We're waiting for an activity launch to finish, but that activity simply
Bryce Lee5f0e28f2018-01-30 16:00:03 -0800901 // brought another activity to front. We must also handle the case where the task is already
902 // in the front as a result of the trampoline activity being in the same task (it will be
903 // considered focused as the trampoline will be finished). Let startActivityMayWait() know
904 // about this, so it waits for the new activity to become visible instead.
905 mSupervisor.reportWaitingActivityLaunchedIfNeeded(r, result);
Chong Zhang5022da32016-06-21 16:31:37 -0700906
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700907 ActivityStack startedActivityStack = null;
Andrii Kulian02b7a832016-10-06 23:11:56 -0700908 final ActivityStack currentStack = r.getStack();
909 if (currentStack != null) {
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700910 startedActivityStack = currentStack;
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -0800911 } else if (mTargetStack != null) {
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700912 startedActivityStack = targetStack;
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -0800913 }
914
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700915 if (startedActivityStack == null) {
916 return;
917 }
918
Wale Ogunwaleac36e4d2017-11-29 13:30:26 -0800919 final int clearTaskFlags = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK;
920 boolean clearedTask = (mLaunchFlags & clearTaskFlags) == clearTaskFlags
921 && mReuseTask != null;
Wale Ogunwale7d7973a2018-04-05 10:25:59 -0700922 if (result == START_TASK_TO_FRONT || result == START_DELIVERED_TO_TOP || clearedTask) {
923 // The activity was already running so it wasn't started, but either brought to the
924 // front or the new intent was delivered to it since it was already in front. Notify
925 // anyone interested in this piece of information.
926 switch (startedActivityStack.getWindowingMode()) {
927 case WINDOWING_MODE_PINNED:
928 mService.mTaskChangeNotificationController.notifyPinnedActivityRestartAttempt(
929 clearedTask);
930 break;
931 case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
932 final ActivityStack homeStack = mSupervisor.mHomeStack;
933 if (homeStack != null && homeStack.shouldBeVisible(null /* starting */)) {
934 mService.mWindowManager.showRecentApps();
935 }
936 break;
937 }
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -0800938 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800939 }
940
Bryce Lee4c9a5972017-12-01 22:14:24 -0800941 private int startActivityMayWait(IApplicationThread caller, int callingUid,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800942 String callingPackage, Intent intent, String resolvedType,
943 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
944 IBinder resultTo, String resultWho, int requestCode, int startFlags,
Sudheer Shankafc46e9b2016-10-21 17:55:27 -0700945 ProfilerInfo profilerInfo, WaitResult outResult,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100946 Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200947 int userId, TaskRecord inTask, String reason,
948 boolean allowPendingRemoteAnimationRegistryLookup) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800949 // Refuse possible leaked file descriptors
950 if (intent != null && intent.hasFileDescriptors()) {
951 throw new IllegalArgumentException("File descriptors passed in Intent");
952 }
Bryce Lee2a3cc462017-10-27 10:57:35 -0700953 mSupervisor.getActivityMetricsLogger().notifyActivityLaunching();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800954 boolean componentSpecified = intent.getComponent() != null;
955
Makoto Onuki1a342742018-04-26 14:56:59 -0700956 final int realCallingPid = Binder.getCallingPid();
957 final int realCallingUid = Binder.getCallingUid();
958
Svet Ganovcbcbf662018-05-10 17:25:29 -0700959 int callingPid;
960 if (callingUid >= 0) {
961 callingPid = -1;
962 } else if (caller == null) {
963 callingPid = realCallingPid;
964 callingUid = realCallingUid;
965 } else {
966 callingPid = callingUid = -1;
967 }
968
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800969 // Save a copy in case ephemeral needs it
970 final Intent ephemeralIntent = new Intent(intent);
971 // Don't modify the client's object!
972 intent = new Intent(intent);
Todd Kennedyb21be122017-03-24 14:10:01 -0700973 if (componentSpecified
Patrick Baumann531db462018-02-13 13:01:47 -0800974 && !(Intent.ACTION_VIEW.equals(intent.getAction()) && intent.getData() == null)
Patrick Baumann577d4022018-01-31 16:55:10 +0000975 && !Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE.equals(intent.getAction())
976 && !Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE.equals(intent.getAction())
Todd Kennedyb21be122017-03-24 14:10:01 -0700977 && mService.getPackageManagerInternalLocked()
978 .isInstantAppInstallerComponent(intent.getComponent())) {
979 // intercept intents targeted directly to the ephemeral installer the
Patrick Baumann577d4022018-01-31 16:55:10 +0000980 // ephemeral installer should never be started with a raw Intent; instead
Todd Kennedyb21be122017-03-24 14:10:01 -0700981 // adjust the intent so it looks like a "normal" instant app launch
982 intent.setComponent(null /*component*/);
983 componentSpecified = false;
984 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800985
Makoto Onuki1a342742018-04-26 14:56:59 -0700986 ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
Svet Ganovcbcbf662018-05-10 17:25:29 -0700987 0 /* matchFlags */, computeResolveFilterUid(callingUid, realCallingUid));
Kenny Guyb1b30262016-02-09 16:02:35 +0000988 if (rInfo == null) {
989 UserInfo userInfo = mSupervisor.getUserInfo(userId);
990 if (userInfo != null && userInfo.isManagedProfile()) {
991 // Special case for managed profiles, if attempting to launch non-cryto aware
992 // app in a locked managed profile from an unlocked parent allow it to resolve
993 // as user will be sent via confirm credentials to unlock the profile.
994 UserManager userManager = UserManager.get(mService.mContext);
Fyodor Kupolovce4db0a2016-05-11 14:21:18 -0700995 boolean profileLockedAndParentUnlockingOrUnlocked = false;
Tony Mak13436452016-02-24 11:08:38 +0000996 long token = Binder.clearCallingIdentity();
997 try {
Fyodor Kupolovce4db0a2016-05-11 14:21:18 -0700998 UserInfo parent = userManager.getProfileParent(userId);
999 profileLockedAndParentUnlockingOrUnlocked = (parent != null)
1000 && userManager.isUserUnlockingOrUnlocked(parent.id)
1001 && !userManager.isUserUnlockingOrUnlocked(userId);
Tony Mak13436452016-02-24 11:08:38 +00001002 } finally {
1003 Binder.restoreCallingIdentity(token);
1004 }
Fyodor Kupolovce4db0a2016-05-11 14:21:18 -07001005 if (profileLockedAndParentUnlockingOrUnlocked) {
Kenny Guyb1b30262016-02-09 16:02:35 +00001006 rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
Jeff Sharkey8a372a02016-03-16 16:25:45 -06001007 PackageManager.MATCH_DIRECT_BOOT_AWARE
Patrick Baumann78380272018-04-04 10:41:01 -07001008 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
Svet Ganovcbcbf662018-05-10 17:25:29 -07001009 computeResolveFilterUid(callingUid, realCallingUid));
Kenny Guyb1b30262016-02-09 16:02:35 +00001010 }
1011 }
1012 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001013 // Collect information about the target of the Intent.
1014 ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
1015
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001016 synchronized (mService) {
Andrii Kulian94e82d9b02017-07-13 15:33:06 -07001017 final ActivityStack stack = mSupervisor.mFocusedStack;
Andrii Kulian8072d112016-09-16 11:11:01 -07001018 stack.mConfigWillChange = globalConfig != null
Andrii Kulian1779e612016-10-12 21:58:25 -07001019 && mService.getGlobalConfiguration().diff(globalConfig) != 0;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001020 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
1021 "Starting activity when config will change = " + stack.mConfigWillChange);
1022
1023 final long origId = Binder.clearCallingIdentity();
1024
1025 if (aInfo != null &&
1026 (aInfo.applicationInfo.privateFlags
Dianne Hackbornc8e4fad2018-05-04 11:31:09 -07001027 & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0 &&
1028 mService.mHasHeavyWeightFeature) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001029 // This may be a heavy-weight process! Check to see if we already
1030 // have another, different heavy-weight process running.
1031 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
1032 final ProcessRecord heavy = mService.mHeavyWeightProcess;
1033 if (heavy != null && (heavy.info.uid != aInfo.applicationInfo.uid
1034 || !heavy.processName.equals(aInfo.processName))) {
1035 int appCallingUid = callingUid;
1036 if (caller != null) {
1037 ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
1038 if (callerApp != null) {
1039 appCallingUid = callerApp.info.uid;
1040 } else {
1041 Slog.w(TAG, "Unable to find app for caller " + caller
1042 + " (pid=" + callingPid + ") when starting: "
1043 + intent.toString());
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001044 SafeActivityOptions.abort(options);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001045 return ActivityManager.START_PERMISSION_DENIED;
1046 }
1047 }
1048
1049 IIntentSender target = mService.getIntentSenderLocked(
1050 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
1051 appCallingUid, userId, null, null, 0, new Intent[] { intent },
1052 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
1053 | PendingIntent.FLAG_ONE_SHOT, null);
1054
1055 Intent newIntent = new Intent();
1056 if (requestCode >= 0) {
1057 // Caller is requesting a result.
1058 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
1059 }
1060 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
1061 new IntentSender(target));
1062 if (heavy.activities.size() > 0) {
1063 ActivityRecord hist = heavy.activities.get(0);
1064 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
1065 hist.packageName);
1066 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
Bryce Leeaf691c02017-03-20 14:20:22 -07001067 hist.getTask().taskId);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001068 }
1069 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
1070 aInfo.packageName);
1071 newIntent.setFlags(intent.getFlags());
1072 newIntent.setClassName("android",
1073 HeavyWeightSwitcherActivity.class.getName());
1074 intent = newIntent;
1075 resolvedType = null;
1076 caller = null;
1077 callingUid = Binder.getCallingUid();
1078 callingPid = Binder.getCallingPid();
1079 componentSpecified = true;
Makoto Onuki1a342742018-04-26 14:56:59 -07001080 rInfo = mSupervisor.resolveIntent(intent, null /*resolvedType*/, userId,
Svet Ganovcbcbf662018-05-10 17:25:29 -07001081 0 /* matchFlags */, computeResolveFilterUid(callingUid,
1082 realCallingUid));
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001083 aInfo = rInfo != null ? rInfo.activityInfo : null;
1084 if (aInfo != null) {
1085 aInfo = mService.getActivityInfoForUser(aInfo, userId);
1086 }
1087 }
1088 }
1089 }
1090
Jorim Jaggi275561a2016-02-23 10:11:02 -05001091 final ActivityRecord[] outRecord = new ActivityRecord[1];
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001092 int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
1093 voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
1094 callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +02001095 ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
1096 allowPendingRemoteAnimationRegistryLookup);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001097
1098 Binder.restoreCallingIdentity(origId);
1099
1100 if (stack.mConfigWillChange) {
1101 // If the caller also wants to switch to a new configuration,
1102 // do so now. This allows a clean switch, as we are waiting
1103 // for the current activity to pause (so we will not destroy
1104 // it), and have not yet started the next activity.
1105 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
1106 "updateConfiguration()");
1107 stack.mConfigWillChange = false;
1108 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
1109 "Updating to new configuration after starting activity.");
Andrii Kulian8072d112016-09-16 11:11:01 -07001110 mService.updateConfigurationLocked(globalConfig, null, false);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001111 }
1112
1113 if (outResult != null) {
1114 outResult.result = res;
Bryce Lee4a194382017-04-04 14:32:48 -07001115
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001116 final ActivityRecord r = outRecord[0];
1117
1118 switch(res) {
1119 case START_SUCCESS: {
1120 mSupervisor.mWaitingActivityLaunched.add(outResult);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001121 do {
1122 try {
1123 mService.wait();
1124 } catch (InterruptedException e) {
1125 }
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001126 } while (outResult.result != START_TASK_TO_FRONT
1127 && !outResult.timeout && outResult.who == null);
1128 if (outResult.result == START_TASK_TO_FRONT) {
1129 res = START_TASK_TO_FRONT;
1130 }
1131 break;
1132 }
1133 case START_DELIVERED_TO_TOP: {
1134 outResult.timeout = false;
1135 outResult.who = r.realActivity;
1136 outResult.totalTime = 0;
1137 outResult.thisTime = 0;
1138 break;
1139 }
1140 case START_TASK_TO_FRONT: {
1141 // ActivityRecord may represent a different activity, but it should not be
1142 // in the resumed state.
Bryce Lee7ace3952018-02-16 14:34:32 -08001143 if (r.nowVisible && r.isState(RESUMED)) {
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001144 outResult.timeout = false;
1145 outResult.who = r.realActivity;
1146 outResult.totalTime = 0;
1147 outResult.thisTime = 0;
1148 } else {
1149 outResult.thisTime = SystemClock.uptimeMillis();
1150 mSupervisor.waitActivityVisible(r.realActivity, outResult);
1151 // Note: the timeout variable is not currently not ever set.
1152 do {
1153 try {
1154 mService.wait();
1155 } catch (InterruptedException e) {
1156 }
1157 } while (!outResult.timeout && outResult.who == null);
1158 }
1159 break;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001160 }
1161 }
1162 }
1163
Bryce Lee2a3cc462017-10-27 10:57:35 -07001164 mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outRecord[0]);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001165 return res;
1166 }
1167 }
1168
Svet Ganovcbcbf662018-05-10 17:25:29 -07001169 /**
1170 * Compute the logical UID based on which the package manager would filter
1171 * app components i.e. based on which the instant app policy would be applied
1172 * because it is the logical calling UID.
1173 *
1174 * @param customCallingUid The UID on whose behalf to make the call.
1175 * @param actualCallingUid The UID actually making the call.
1176 * @return The logical UID making the call.
1177 */
1178 static int computeResolveFilterUid(int customCallingUid, int actualCallingUid) {
1179 return customCallingUid >= 0 ? customCallingUid : actualCallingUid;
1180 }
1181
Bryce Leedaa91e42017-12-06 14:13:01 -08001182 private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
1183 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1184 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
1185 ActivityRecord[] outActivity) {
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001186 int result = START_CANCELED;
1187 try {
1188 mService.mWindowManager.deferSurfaceLayout();
1189 result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
Bryce Lee4a194382017-04-04 14:32:48 -07001190 startFlags, doResume, options, inTask, outActivity);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001191 } finally {
1192 // If we are not able to proceed, disassociate the activity from the task. Leaving an
1193 // activity in an incomplete state can lead to issues, such as performing operations
1194 // without a window container.
Bryce Lee2b8e0372018-04-05 17:01:37 -07001195 final ActivityStack stack = mStartActivity.getStack();
1196 if (!ActivityManager.isStartResultSuccessful(result) && stack != null) {
1197 stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,
1198 null /* intentResultData */, "startActivity", true /* oomAdj */);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001199 }
1200 mService.mWindowManager.continueSurfaceLayout();
1201 }
1202
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001203 postStartActivityProcessing(r, result, mTargetStack);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001204
1205 return result;
1206 }
1207
1208 // Note: This method should only be called from {@link startActivity}.
Wale Ogunwale01d66562015-12-29 08:19:19 -08001209 private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
1210 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
Bryce Lee4a194382017-04-04 14:32:48 -07001211 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
1212 ActivityRecord[] outActivity) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001213
1214 setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
1215 voiceInteractor);
1216
1217 computeLaunchingTaskFlags();
1218
1219 computeSourceStack();
1220
1221 mIntent.setFlags(mLaunchFlags);
1222
Bryce Lee4a194382017-04-04 14:32:48 -07001223 ActivityRecord reusedActivity = getReusableIntentActivity();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001224
Wale Ogunwale0568aed2017-09-08 13:29:37 -07001225 int preferredWindowingMode = WINDOWING_MODE_UNDEFINED;
1226 int preferredLaunchDisplayId = DEFAULT_DISPLAY;
1227 if (mOptions != null) {
1228 preferredWindowingMode = mOptions.getLaunchWindowingMode();
1229 preferredLaunchDisplayId = mOptions.getLaunchDisplayId();
1230 }
Jorim Jaggi2adba072016-03-03 13:43:39 +01001231
Bryce Leeec55eb02017-12-05 20:51:27 -08001232 // windowing mode and preferred launch display values from {@link LaunchParams} take
1233 // priority over those specified in {@link ActivityOptions}.
1234 if (!mLaunchParams.isEmpty()) {
1235 if (mLaunchParams.hasPreferredDisplay()) {
1236 preferredLaunchDisplayId = mLaunchParams.mPreferredDisplayId;
1237 }
1238
1239 if (mLaunchParams.hasWindowingMode()) {
1240 preferredWindowingMode = mLaunchParams.mWindowingMode;
1241 }
1242 }
1243
Bryce Lee4a194382017-04-04 14:32:48 -07001244 if (reusedActivity != null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001245 // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but
1246 // still needs to be a lock task mode violation since the task gets cleared out and
1247 // the device would otherwise leave the locked task.
Bryce Lee2b8e0372018-04-05 17:01:37 -07001248 if (mService.getLockTaskController().isLockTaskModeViolation(reusedActivity.getTask(),
Wale Ogunwale01d66562015-12-29 08:19:19 -08001249 (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1250 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001251 Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
1252 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
1253 }
1254
Bryce Leef65ee7e2018-03-26 16:03:47 -07001255 // True if we are clearing top and resetting of a standard (default) launch mode
1256 // ({@code LAUNCH_MULTIPLE}) activity. The existing activity will be finished.
1257 final boolean clearTopAndResetStandardLaunchMode =
1258 (mLaunchFlags & (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED))
1259 == (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
1260 && mLaunchMode == LAUNCH_MULTIPLE;
1261
1262 // If mStartActivity does not have a task associated with it, associate it with the
1263 // reused activity's task. Do not do so if we're clearing top and resetting for a
1264 // standard launchMode activity.
1265 if (mStartActivity.getTask() == null && !clearTopAndResetStandardLaunchMode) {
Bryce Lee4a194382017-04-04 14:32:48 -07001266 mStartActivity.setTask(reusedActivity.getTask());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001267 }
Bryce Leef65ee7e2018-03-26 16:03:47 -07001268
Bryce Lee4a194382017-04-04 14:32:48 -07001269 if (reusedActivity.getTask().intent == null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001270 // This task was started because of movement of the activity based on affinity...
1271 // Now that we are actually launching it, we can assign the base intent.
Bryce Lee4a194382017-04-04 14:32:48 -07001272 reusedActivity.getTask().setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001273 }
1274
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001275 // This code path leads to delivering a new intent, we want to make sure we schedule it
1276 // as the first operation, in case the activity will be resumed as a result of later
1277 // operations.
1278 if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
Daichi Hirono15a02992016-04-27 18:47:01 +09001279 || isDocumentLaunchesIntoExisting(mLaunchFlags)
Bryce Lee7daee392017-10-12 13:46:18 -07001280 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Bryce Lee4a194382017-04-04 14:32:48 -07001281 final TaskRecord task = reusedActivity.getTask();
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001282
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001283 // In this situation we want to remove all activities from the task up to the one
1284 // being started. In most cases this means we are resetting the task to its initial
1285 // state.
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001286 final ActivityRecord top = task.performClearTaskForReuseLocked(mStartActivity,
1287 mLaunchFlags);
1288
Bryce Lee4a194382017-04-04 14:32:48 -07001289 // The above code can remove {@code reusedActivity} from the task, leading to the
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001290 // the {@code ActivityRecord} removing its reference to the {@code TaskRecord}. The
1291 // task reference is needed in the call below to
1292 // {@link setTargetStackAndMoveToFrontIfNeeded}.
Bryce Lee4a194382017-04-04 14:32:48 -07001293 if (reusedActivity.getTask() == null) {
1294 reusedActivity.setTask(task);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001295 }
1296
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001297 if (top != null) {
1298 if (top.frontOfTask) {
1299 // Activity aliases may mean we use different intents for the top activity,
1300 // so make sure the task now has the identity of the new intent.
Bryce Leeaf691c02017-03-20 14:20:22 -07001301 top.getTask().setIntent(mStartActivity);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001302 }
Bryce Lee325e09682017-10-05 17:20:25 -07001303 deliverNewIntent(top);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001304 }
1305 }
1306
Bryce Leed3624e12017-11-30 08:51:45 -08001307 mSupervisor.sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, reusedActivity);
Wei Wang98f03f92016-05-18 11:32:52 -07001308
Bryce Lee4a194382017-04-04 14:32:48 -07001309 reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001310
Bryce Lee89cd19a2017-05-17 15:18:35 -07001311 final ActivityRecord outResult =
1312 outActivity != null && outActivity.length > 0 ? outActivity[0] : null;
1313
1314 // When there is a reused activity and the current result is a trampoline activity,
1315 // set the reused activity as the result.
1316 if (outResult != null && (outResult.finishing || outResult.noDisplay)) {
1317 outActivity[0] = reusedActivity;
1318 }
1319
Wale Ogunwale01d66562015-12-29 08:19:19 -08001320 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1321 // We don't need to start a new activity, and the client said not to do anything
1322 // if that is the case, so this is it! And for paranoia, make sure we have
1323 // correctly resumed the top activity.
1324 resumeTargetStackIfNeeded();
1325 return START_RETURN_INTENT_TO_CALLER;
1326 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001327
Bryce Leef65ee7e2018-03-26 16:03:47 -07001328 if (reusedActivity != null) {
1329 setTaskFromIntentActivity(reusedActivity);
1330
1331 if (!mAddingToTask && mReuseTask == null) {
1332 // We didn't do anything... but it was needed (a.k.a., client don't use that
1333 // intent!) And for paranoia, make sure we have correctly resumed the top activity.
1334
1335 resumeTargetStackIfNeeded();
1336 if (outActivity != null && outActivity.length > 0) {
1337 outActivity[0] = reusedActivity;
1338 }
1339
1340 return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP;
Jorim Jaggicdfc04e2017-04-28 19:06:24 +02001341 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001342 }
1343 }
1344
1345 if (mStartActivity.packageName == null) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001346 final ActivityStack sourceStack = mStartActivity.resultTo != null
1347 ? mStartActivity.resultTo.getStack() : null;
1348 if (sourceStack != null) {
1349 sourceStack.sendActivityResultLocked(-1 /* callingUid */, mStartActivity.resultTo,
1350 mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,
1351 null /* data */);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001352 }
1353 ActivityOptions.abort(mOptions);
1354 return START_CLASS_NOT_FOUND;
1355 }
1356
1357 // If the activity being launched is the same as the one currently at the top, then
1358 // we need to check if it should only be launched once.
1359 final ActivityStack topStack = mSupervisor.mFocusedStack;
Wale Ogunwale30e441d2017-11-09 08:28:45 -08001360 final ActivityRecord topFocused = topStack.getTopActivity();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001361 final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
1362 final boolean dontStart = top != null && mStartActivity.resultTo == null
1363 && top.realActivity.equals(mStartActivity.realActivity)
1364 && top.userId == mStartActivity.userId
1365 && top.app != null && top.app.thread != null
1366 && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
Bryce Lee7daee392017-10-12 13:46:18 -07001367 || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK));
Wale Ogunwale01d66562015-12-29 08:19:19 -08001368 if (dontStart) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001369 // For paranoia, make sure we have correctly resumed the top activity.
1370 topStack.mLastPausedActivity = null;
1371 if (mDoResume) {
1372 mSupervisor.resumeFocusedStackTopActivityLocked();
1373 }
1374 ActivityOptions.abort(mOptions);
1375 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1376 // We don't need to start a new activity, and the client said not to do
1377 // anything if that is the case, so this is it!
1378 return START_RETURN_INTENT_TO_CALLER;
1379 }
Bryce Lee325e09682017-10-05 17:20:25 -07001380
1381 deliverNewIntent(top);
Chong Zhangd44063c2016-04-08 11:52:30 -07001382
1383 // Don't use mStartActivity.task to show the toast. We're not starting a new activity
1384 // but reusing 'top'. Fields in mStartActivity may not be fully initialized.
Wale Ogunwale0568aed2017-09-08 13:29:37 -07001385 mSupervisor.handleNonResizableTaskIfNeeded(top.getTask(), preferredWindowingMode,
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07001386 preferredLaunchDisplayId, topStack);
Chong Zhangd44063c2016-04-08 11:52:30 -07001387
Wale Ogunwale01d66562015-12-29 08:19:19 -08001388 return START_DELIVERED_TO_TOP;
1389 }
1390
1391 boolean newTask = false;
1392 final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
Bryce Leeaf691c02017-03-20 14:20:22 -07001393 ? mSourceRecord.getTask() : null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001394
1395 // Should this be considered a new task?
Chong Zhang6cda19c2016-06-14 19:07:56 -07001396 int result = START_SUCCESS;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001397 if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
1398 && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1399 newTask = true;
Wale Ogunwale0568aed2017-09-08 13:29:37 -07001400 result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, topStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001401 } else if (mSourceRecord != null) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07001402 result = setTaskFromSourceRecord();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001403 } else if (mInTask != null) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07001404 result = setTaskFromInTask();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001405 } else {
1406 // This not being started from an existing activity, and not part of a new task...
1407 // just put it in the top task, though these days this case should never happen.
1408 setTaskToCurrentTopOrCreateNewTask();
1409 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07001410 if (result != START_SUCCESS) {
1411 return result;
1412 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001413
1414 mService.grantUriPermissionFromIntentLocked(mCallingUid, mStartActivity.packageName,
1415 mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.userId);
Todd Kennedy0e989d02017-01-13 14:15:36 -08001416 mService.grantEphemeralAccessLocked(mStartActivity.userId, mIntent,
1417 mStartActivity.appInfo.uid, UserHandle.getAppId(mCallingUid));
Wale Ogunwale01d66562015-12-29 08:19:19 -08001418 if (newTask) {
Wale Ogunwale66e16852017-10-19 13:35:52 -07001419 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, mStartActivity.userId,
Bryce Leeaf691c02017-03-20 14:20:22 -07001420 mStartActivity.getTask().taskId);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001421 }
1422 ActivityStack.logStartActivity(
Bryce Leeaf691c02017-03-20 14:20:22 -07001423 EventLogTags.AM_CREATE_ACTIVITY, mStartActivity, mStartActivity.getTask());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001424 mTargetStack.mLastPausedActivity = null;
Wei Wang98f03f92016-05-18 11:32:52 -07001425
Bryce Leed3624e12017-11-30 08:51:45 -08001426 mSupervisor.sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, mStartActivity);
Wei Wang98f03f92016-05-18 11:32:52 -07001427
Winson Chungb5c41b72016-12-07 15:00:47 -08001428 mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
1429 mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001430 if (mDoResume) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001431 final ActivityRecord topTaskActivity =
1432 mStartActivity.getTask().topRunningActivityLocked();
Wale Ogunwale3b232392016-05-13 15:37:13 -07001433 if (!mTargetStack.isFocusable()
Wale Ogunwale68741142016-05-17 09:40:02 -07001434 || (topTaskActivity != null && topTaskActivity.mTaskOverlay
1435 && mStartActivity != topTaskActivity)) {
Filip Gruszczynski3d7fdc12016-01-31 17:33:29 -08001436 // If the activity is not focusable, we can't resume it, but still would like to
1437 // make sure it becomes visible as it starts (this will also trigger entry
1438 // animation). An example of this are PIP activities.
Wale Ogunwale3b232392016-05-13 15:37:13 -07001439 // Also, we don't want to resume activities in a task that currently has an overlay
1440 // as the starting activity just needs to be in the visible paused state until the
1441 // over is removed.
Wale Ogunwale480dca02016-02-06 13:58:29 -08001442 mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Wale Ogunwaleae846f42016-02-22 14:00:56 -08001443 // Go ahead and tell window manager to execute app transition for this activity
1444 // since the app transition will not be triggered through the resume channel.
Bryce Lee7daee392017-10-12 13:46:18 -07001445 mService.mWindowManager.executeAppTransition();
Wale Ogunwale3b232392016-05-13 15:37:13 -07001446 } else {
Winson Chung32066032016-11-04 11:55:21 -07001447 // If the target stack was not previously focusable (previous top running activity
1448 // on that stack was not visible) then any prior calls to move the stack to the
1449 // will not update the focused stack. If starting the new activity now allows the
1450 // task stack to be focusable, then ensure that we now update the focused stack
1451 // accordingly.
1452 if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
1453 mTargetStack.moveToFront("startActivityUnchecked");
1454 }
Wale Ogunwale3b232392016-05-13 15:37:13 -07001455 mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
1456 mOptions);
Filip Gruszczynski3d7fdc12016-01-31 17:33:29 -08001457 }
Winson Chung1dbc8112017-09-28 18:05:31 -07001458 } else if (mStartActivity != null) {
1459 mSupervisor.mRecentTasks.add(mStartActivity.getTask());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001460 }
1461 mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);
1462
Wale Ogunwale0568aed2017-09-08 13:29:37 -07001463 mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(), preferredWindowingMode,
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07001464 preferredLaunchDisplayId, mTargetStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001465
1466 return START_SUCCESS;
1467 }
1468
Bryce Leedaa91e42017-12-06 14:13:01 -08001469 /**
1470 * Resets the {@link ActivityStarter} state.
1471 * @param clearRequest whether the request should be reset to default values.
1472 */
1473 void reset(boolean clearRequest) {
1474 mStartActivity = null;
1475 mIntent = null;
1476 mCallingUid = -1;
1477 mOptions = null;
1478
1479 mLaunchTaskBehind = false;
1480 mLaunchFlags = 0;
1481 mLaunchMode = INVALID_LAUNCH_MODE;
1482
Bryce Leeec55eb02017-12-05 20:51:27 -08001483 mLaunchParams.reset();
Bryce Leedaa91e42017-12-06 14:13:01 -08001484
1485 mNotTop = null;
1486 mDoResume = false;
1487 mStartFlags = 0;
1488 mSourceRecord = null;
1489 mPreferredDisplayId = INVALID_DISPLAY;
1490
1491 mInTask = null;
1492 mAddingToTask = false;
1493 mReuseTask = null;
1494
1495 mNewTaskInfo = null;
1496 mNewTaskIntent = null;
1497 mSourceStack = null;
1498
1499 mTargetStack = null;
1500 mMovedToFront = false;
1501 mNoAnimation = false;
1502 mKeepCurTransition = false;
1503 mAvoidMoveToFront = false;
1504
1505 mVoiceSession = null;
1506 mVoiceInteractor = null;
1507
1508 mIntentDelivered = false;
1509
1510 if (clearRequest) {
1511 mRequest.reset();
1512 }
1513 }
1514
Wale Ogunwale01d66562015-12-29 08:19:19 -08001515 private void setInitialState(ActivityRecord r, ActivityOptions options, TaskRecord inTask,
1516 boolean doResume, int startFlags, ActivityRecord sourceRecord,
1517 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
Bryce Leedaa91e42017-12-06 14:13:01 -08001518 reset(false /* clearRequest */);
1519
Wale Ogunwale01d66562015-12-29 08:19:19 -08001520 mStartActivity = r;
1521 mIntent = r.intent;
1522 mOptions = options;
1523 mCallingUid = r.launchedFromUid;
1524 mSourceRecord = sourceRecord;
1525 mVoiceSession = voiceSession;
1526 mVoiceInteractor = voiceInteractor;
1527
David Stevense5a7b642017-05-22 13:18:23 -07001528 mPreferredDisplayId = getPreferedDisplayId(mSourceRecord, mStartActivity, options);
David Stevensc6b91c62017-02-08 14:23:58 -08001529
Bryce Leeec55eb02017-12-05 20:51:27 -08001530 mLaunchParams.reset();
Bryce Leedacefc42017-10-10 12:56:02 -07001531
Bryce Leeec55eb02017-12-05 20:51:27 -08001532 mSupervisor.getLaunchParamsController().calculate(inTask, null /*layout*/, r, sourceRecord,
1533 options, mLaunchParams);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001534
Bryce Lee7daee392017-10-12 13:46:18 -07001535 mLaunchMode = r.launchMode;
1536
Wale Ogunwale01d66562015-12-29 08:19:19 -08001537 mLaunchFlags = adjustLaunchFlagsToDocumentMode(
Bryce Lee7daee392017-10-12 13:46:18 -07001538 r, LAUNCH_SINGLE_INSTANCE == mLaunchMode,
1539 LAUNCH_SINGLE_TASK == mLaunchMode, mIntent.getFlags());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001540 mLaunchTaskBehind = r.mLaunchTaskBehind
Bryce Lee7daee392017-10-12 13:46:18 -07001541 && !isLaunchModeOneOf(LAUNCH_SINGLE_TASK, LAUNCH_SINGLE_INSTANCE)
Wale Ogunwale01d66562015-12-29 08:19:19 -08001542 && (mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0;
1543
1544 sendNewTaskResultRequestIfNeeded();
1545
1546 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
1547 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1548 }
1549
1550 // If we are actually going to launch in to a new task, there are some cases where
1551 // we further want to do multiple task.
1552 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1553 if (mLaunchTaskBehind
1554 || r.info.documentLaunchMode == DOCUMENT_LAUNCH_ALWAYS) {
1555 mLaunchFlags |= FLAG_ACTIVITY_MULTIPLE_TASK;
1556 }
1557 }
1558
1559 // We'll invoke onUserLeaving before onPause only if the launching
1560 // activity did not explicitly state that this is an automated launch.
1561 mSupervisor.mUserLeaving = (mLaunchFlags & FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1562 if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
1563 "startActivity() => mUserLeaving=" + mSupervisor.mUserLeaving);
1564
1565 // If the caller has asked not to resume at this point, we make note
1566 // of this in the record so that we can skip it when trying to find
1567 // the top running activity.
1568 mDoResume = doResume;
Chong Zhang87761972016-08-22 13:53:24 -07001569 if (!doResume || !r.okToShowLocked()) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001570 r.delayedResume = true;
1571 mDoResume = false;
1572 }
1573
Winson Chunge2d72172018-01-25 17:46:20 +00001574 if (mOptions != null) {
1575 if (mOptions.getLaunchTaskId() != -1 && mOptions.getTaskOverlay()) {
1576 r.mTaskOverlay = true;
1577 if (!mOptions.canTaskOverlayResume()) {
1578 final TaskRecord task = mSupervisor.anyTaskForIdLocked(
1579 mOptions.getLaunchTaskId());
1580 final ActivityRecord top = task != null ? task.getTopActivity() : null;
Bryce Lee7ace3952018-02-16 14:34:32 -08001581 if (top != null && !top.isState(RESUMED)) {
Jorim Jaggic875ae72016-04-26 22:41:06 -07001582
Winson Chunge2d72172018-01-25 17:46:20 +00001583 // The caller specifies that we'd like to be avoided to be moved to the
1584 // front, so be it!
1585 mDoResume = false;
1586 mAvoidMoveToFront = true;
1587 }
Winson Chungcbcadc92017-01-12 15:54:12 -08001588 }
Winson Chunge2d72172018-01-25 17:46:20 +00001589 } else if (mOptions.getAvoidMoveToFront()) {
1590 mAvoidMoveToFront = true;
Jorim Jaggic875ae72016-04-26 22:41:06 -07001591 }
1592 }
1593
Wale Ogunwale01d66562015-12-29 08:19:19 -08001594 mNotTop = (mLaunchFlags & FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1595
1596 mInTask = inTask;
1597 // In some flows in to this function, we retrieve the task record and hold on to it
1598 // without a lock before calling back in to here... so the task at this point may
1599 // not actually be in recents. Check for that, and if it isn't in recents just
1600 // consider it invalid.
1601 if (inTask != null && !inTask.inRecents) {
1602 Slog.w(TAG, "Starting activity in task not in recents: " + inTask);
1603 mInTask = null;
1604 }
1605
1606 mStartFlags = startFlags;
1607 // If the onlyIfNeeded flag is set, then we can do this if the activity being launched
1608 // is the same as the one making the call... or, as a special case, if we do not know
1609 // the caller then we count the current top activity as the caller.
1610 if ((startFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1611 ActivityRecord checkedCaller = sourceRecord;
1612 if (checkedCaller == null) {
1613 checkedCaller = mSupervisor.mFocusedStack.topRunningNonDelayedActivityLocked(
1614 mNotTop);
1615 }
1616 if (!checkedCaller.realActivity.equals(r.realActivity)) {
1617 // Caller is not the same as launcher, so always needed.
1618 mStartFlags &= ~START_FLAG_ONLY_IF_NEEDED;
1619 }
1620 }
1621
1622 mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0;
1623 }
1624
1625 private void sendNewTaskResultRequestIfNeeded() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001626 final ActivityStack sourceStack = mStartActivity.resultTo != null
1627 ? mStartActivity.resultTo.getStack() : null;
1628 if (sourceStack != null && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001629 // For whatever reason this activity is being launched into a new task...
1630 // yet the caller has requested a result back. Well, that is pretty messed up,
1631 // so instead immediately send back a cancel and let the new task continue launched
1632 // as normal without a dependency on its originator.
1633 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
Andrii Kulian02b7a832016-10-06 23:11:56 -07001634 sourceStack.sendActivityResultLocked(-1 /* callingUid */, mStartActivity.resultTo,
1635 mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,
1636 null /* data */);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001637 mStartActivity.resultTo = null;
1638 }
1639 }
1640
1641 private void computeLaunchingTaskFlags() {
1642 // If the caller is not coming from another activity, but has given us an explicit task into
1643 // which they would like us to launch the new activity, then let's see about doing that.
Andrii Kulian02b7a832016-10-06 23:11:56 -07001644 if (mSourceRecord == null && mInTask != null && mInTask.getStack() != null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001645 final Intent baseIntent = mInTask.getBaseIntent();
1646 final ActivityRecord root = mInTask.getRootActivity();
1647 if (baseIntent == null) {
1648 ActivityOptions.abort(mOptions);
1649 throw new IllegalArgumentException("Launching into task without base intent: "
1650 + mInTask);
1651 }
1652
1653 // If this task is empty, then we are adding the first activity -- it
1654 // determines the root, and must be launching as a NEW_TASK.
Bryce Lee7daee392017-10-12 13:46:18 -07001655 if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001656 if (!baseIntent.getComponent().equals(mStartActivity.intent.getComponent())) {
1657 ActivityOptions.abort(mOptions);
1658 throw new IllegalArgumentException("Trying to launch singleInstance/Task "
1659 + mStartActivity + " into different task " + mInTask);
1660 }
1661 if (root != null) {
1662 ActivityOptions.abort(mOptions);
1663 throw new IllegalArgumentException("Caller with mInTask " + mInTask
1664 + " has root " + root + " but target is singleInstance/Task");
1665 }
1666 }
1667
1668 // If task is empty, then adopt the interesting intent launch flags in to the
1669 // activity being started.
1670 if (root == null) {
1671 final int flagsOfInterest = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK
1672 | FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS;
1673 mLaunchFlags = (mLaunchFlags & ~flagsOfInterest)
1674 | (baseIntent.getFlags() & flagsOfInterest);
1675 mIntent.setFlags(mLaunchFlags);
1676 mInTask.setIntent(mStartActivity);
1677 mAddingToTask = true;
1678
1679 // If the task is not empty and the caller is asking to start it as the root of
1680 // a new task, then we don't actually want to start this on the task. We will
1681 // bring the task to the front, and possibly give it a new intent.
1682 } else if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1683 mAddingToTask = false;
1684
1685 } else {
1686 mAddingToTask = true;
1687 }
1688
1689 mReuseTask = mInTask;
1690 } else {
1691 mInTask = null;
1692 // Launch ResolverActivity in the source task, so that it stays in the task bounds
1693 // when in freeform workspace.
1694 // Also put noDisplay activities in the source task. These by itself can be placed
1695 // in any task/stack, however it could launch other activities like ResolverActivity,
1696 // and we want those to stay in the original task.
1697 if ((mStartActivity.isResolverActivity() || mStartActivity.noDisplay) && mSourceRecord != null
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001698 && mSourceRecord.inFreeformWindowingMode()) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001699 mAddingToTask = true;
1700 }
1701 }
1702
1703 if (mInTask == null) {
1704 if (mSourceRecord == null) {
1705 // This activity is not being started from another... in this
1706 // case we -always- start a new task.
1707 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) {
1708 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1709 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
1710 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1711 }
1712 } else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) {
1713 // The original activity who is starting us is running as a single
1714 // instance... this new activity it is starting must go on its
1715 // own task.
1716 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
Bryce Lee7daee392017-10-12 13:46:18 -07001717 } else if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001718 // The activity being started is a single instance... it always
1719 // gets launched into its own task.
1720 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1721 }
1722 }
1723 }
1724
1725 private void computeSourceStack() {
1726 if (mSourceRecord == null) {
1727 mSourceStack = null;
1728 return;
1729 }
1730 if (!mSourceRecord.finishing) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001731 mSourceStack = mSourceRecord.getStack();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001732 return;
1733 }
1734
1735 // If the source is finishing, we can't further count it as our source. This is because the
1736 // task it is associated with may now be empty and on its way out, so we don't want to
1737 // blindly throw it in to that task. Instead we will take the NEW_TASK flow and try to find
1738 // a task for it. But save the task information so it can be used when creating the new task.
1739 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0) {
1740 Slog.w(TAG, "startActivity called from finishing " + mSourceRecord
1741 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
1742 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1743 mNewTaskInfo = mSourceRecord.info;
Bryce Leed9ed45d2017-05-22 15:57:24 -07001744
1745 // It is not guaranteed that the source record will have a task associated with it. For,
1746 // example, if this method is being called for processing a pending activity launch, it
1747 // is possible that the activity has been removed from the task after the launch was
1748 // enqueued.
1749 final TaskRecord sourceTask = mSourceRecord.getTask();
1750 mNewTaskIntent = sourceTask != null ? sourceTask.intent : null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001751 }
1752 mSourceRecord = null;
1753 mSourceStack = null;
1754 }
1755
1756 /**
1757 * Decide whether the new activity should be inserted into an existing task. Returns null
1758 * if not or an ActivityRecord with the task into which the new activity should be added.
1759 */
1760 private ActivityRecord getReusableIntentActivity() {
1761 // We may want to try to place the new activity in to an existing task. We always
1762 // do this if the target activity is singleTask or singleInstance; we will also do
1763 // this if NEW_TASK has been requested, and there is not an additional qualifier telling
1764 // us to still place it in a new task: multi task, always doc mode, or being asked to
1765 // launch this as a new task behind the current one.
1766 boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 &&
1767 (mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
Bryce Lee7daee392017-10-12 13:46:18 -07001768 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001769 // If bring to front is requested, and no result is requested and we have not been given
1770 // an explicit task to launch in to, and we can find a task that was started with this
1771 // same component, then instead of launching bring that one to the front.
1772 putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null;
1773 ActivityRecord intentActivity = null;
Jorim Jaggi2adba072016-03-03 13:43:39 +01001774 if (mOptions != null && mOptions.getLaunchTaskId() != -1) {
1775 final TaskRecord task = mSupervisor.anyTaskForIdLocked(mOptions.getLaunchTaskId());
1776 intentActivity = task != null ? task.getTopActivity() : null;
1777 } else if (putIntoExistingTask) {
Bryce Lee7daee392017-10-12 13:46:18 -07001778 if (LAUNCH_SINGLE_INSTANCE == mLaunchMode) {
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07001779 // There can be one and only one instance of single instance activity in the
1780 // history, and it is always in its own unique task, so we do a special search.
Bryce Lee28d80422017-07-21 13:25:13 -07001781 intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001782 mStartActivity.isActivityTypeHome());
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07001783 } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
1784 // For the launch adjacent case we only want to put the activity in an existing
1785 // task if the activity already exists in the history.
Andrii Kulian039ba482016-06-22 17:16:45 -07001786 intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info,
Bryce Lee7daee392017-10-12 13:46:18 -07001787 !(LAUNCH_SINGLE_TASK == mLaunchMode));
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07001788 } else {
1789 // Otherwise find the best task to put the activity in.
David Stevense5a7b642017-05-22 13:18:23 -07001790 intentActivity = mSupervisor.findTaskLocked(mStartActivity, mPreferredDisplayId);
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07001791 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001792 }
1793 return intentActivity;
1794 }
1795
Andrii Kulianfab9cd82017-03-21 19:37:09 -07001796 /**
Karthik Ravi Shankarf29b4c22017-04-06 17:02:01 -07001797 * Returns the ID of the display to use for a new activity. If the device is in VR mode,
David Stevense5a7b642017-05-22 13:18:23 -07001798 * then return the Vr mode's virtual display ID. If not, if the activity was started with
1799 * a launchDisplayId, use that. Otherwise, if the source activity has a explicit display ID
1800 * set, use that to launch the activity.
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -08001801 */
David Stevense5a7b642017-05-22 13:18:23 -07001802 private int getPreferedDisplayId(
1803 ActivityRecord sourceRecord, ActivityRecord startingActivity, ActivityOptions options) {
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -08001804 // Check if the Activity is a VR activity. If so, the activity should be launched in
1805 // main display.
1806 if (startingActivity != null && startingActivity.requestedVrComponent != null) {
1807 return DEFAULT_DISPLAY;
1808 }
1809
1810 // Get the virtual display id from ActivityManagerService.
Karthik Ravi Shankar2b9aaed2017-05-01 01:34:19 -07001811 int displayId = mService.mVr2dDisplayId;
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -08001812 if (displayId != INVALID_DISPLAY) {
1813 if (DEBUG_STACK) {
1814 Slog.d(TAG, "getSourceDisplayId :" + displayId);
1815 }
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -08001816 return displayId;
1817 }
Karthik Ravi Shankarf29b4c22017-04-06 17:02:01 -07001818
David Stevense5a7b642017-05-22 13:18:23 -07001819 // If the caller requested a display, prefer that display.
1820 final int launchDisplayId =
1821 (options != null) ? options.getLaunchDisplayId() : INVALID_DISPLAY;
1822 if (launchDisplayId != INVALID_DISPLAY) {
1823 return launchDisplayId;
1824 }
1825
Karthik Ravi Shankarf29b4c22017-04-06 17:02:01 -07001826 displayId = sourceRecord != null ? sourceRecord.getDisplayId() : INVALID_DISPLAY;
1827 // If the activity has a displayId set explicitly, launch it on the same displayId.
1828 if (displayId != INVALID_DISPLAY) {
1829 return displayId;
1830 }
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -08001831 return DEFAULT_DISPLAY;
1832 }
1833
1834 /**
Andrii Kulianfab9cd82017-03-21 19:37:09 -07001835 * Figure out which task and activity to bring to front when we have found an existing matching
1836 * activity record in history. May also clear the task if needed.
1837 * @param intentActivity Existing matching activity.
1838 * @return {@link ActivityRecord} brought to front.
1839 */
Wale Ogunwale01d66562015-12-29 08:19:19 -08001840 private ActivityRecord setTargetStackAndMoveToFrontIfNeeded(ActivityRecord intentActivity) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001841 mTargetStack = intentActivity.getStack();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001842 mTargetStack.mLastPausedActivity = null;
1843 // If the target task is not in the front, then we need to bring it to the front...
1844 // except... well, with SINGLE_TASK_LAUNCH it's not entirely clear. We'd like to have
1845 // the same behavior as if a new instance was being started, which means not bringing it
1846 // to the front if the caller is not itself in the front.
1847 final ActivityStack focusStack = mSupervisor.getFocusedStack();
1848 ActivityRecord curTop = (focusStack == null)
1849 ? null : focusStack.topRunningNonDelayedActivityLocked(mNotTop);
1850
Bryce Leeaf691c02017-03-20 14:20:22 -07001851 final TaskRecord topTask = curTop != null ? curTop.getTask() : null;
1852 if (topTask != null
1853 && (topTask != intentActivity.getTask() || topTask != focusStack.topTask())
Jorim Jaggic875ae72016-04-26 22:41:06 -07001854 && !mAvoidMoveToFront) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001855 mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Wale Ogunwale30e441d2017-11-09 08:28:45 -08001856 if (mSourceRecord == null || (mSourceStack.getTopActivity() != null &&
1857 mSourceStack.getTopActivity().getTask() == mSourceRecord.getTask())) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001858 // We really do want to push this one into the user's face, right now.
1859 if (mLaunchTaskBehind && mSourceRecord != null) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001860 intentActivity.setTaskToAffiliateWith(mSourceRecord.getTask());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001861 }
Chong Zhangdea4bd92016-03-15 12:50:03 -07001862
1863 // If the launch flags carry both NEW_TASK and CLEAR_TASK, the task's activities
1864 // will be cleared soon by ActivityStarter in setTaskFromIntentActivity().
1865 // So no point resuming any of the activities here, it just wastes one extra
1866 // resuming, plus enter AND exit transitions.
1867 // Here we only want to bring the target stack forward. Transition will be applied
1868 // to the new activity that's started after the old ones are gone.
1869 final boolean willClearTask =
1870 (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1871 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
1872 if (!willClearTask) {
1873 final ActivityStack launchStack = getLaunchStack(
Bryce Leeaf691c02017-03-20 14:20:22 -07001874 mStartActivity, mLaunchFlags, mStartActivity.getTask(), mOptions);
1875 final TaskRecord intentTask = intentActivity.getTask();
Chong Zhangdea4bd92016-03-15 12:50:03 -07001876 if (launchStack == null || launchStack == mTargetStack) {
1877 // We only want to move to the front, if we aren't going to launch on a
1878 // different stack. If we launch on a different stack, we will put the
1879 // task on top there.
chaviw0d562bf2018-03-15 14:24:14 -07001880 mTargetStack.moveTaskToFrontLocked(intentTask, mNoAnimation, mOptions,
1881 mStartActivity.appTimeTracker, "bringingFoundTaskToFront");
Chong Zhangdea4bd92016-03-15 12:50:03 -07001882 mMovedToFront = true;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001883 } else if (launchStack.inSplitScreenWindowingMode()) {
Andrii Kulianad6f2e52016-06-15 15:27:01 -07001884 if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
1885 // If we want to launch adjacent and mTargetStack is not the computed
1886 // launch stack - move task to top of computed stack.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001887 intentTask.reparent(launchStack, ON_TOP,
Winson Chung74666102017-02-22 17:49:24 -08001888 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
1889 "launchToSide");
Andrii Kulianad6f2e52016-06-15 15:27:01 -07001890 } else {
1891 // TODO: This should be reevaluated in MW v2.
1892 // We choose to move task to front instead of launching it adjacent
1893 // when specific stack was requested explicitly and it appeared to be
1894 // adjacent stack, but FLAG_ACTIVITY_LAUNCH_ADJACENT was not set.
chaviw0d562bf2018-03-15 14:24:14 -07001895 mTargetStack.moveTaskToFrontLocked(intentTask,
Bryce Leeaf691c02017-03-20 14:20:22 -07001896 mNoAnimation, mOptions, mStartActivity.appTimeTracker,
Andrii Kulianad6f2e52016-06-15 15:27:01 -07001897 "bringToFrontInsteadOfAdjacentLaunch");
1898 }
Bryce Lee32e09ef2018-03-19 15:29:49 -07001899 mMovedToFront = launchStack != launchStack.getDisplay()
1900 .getTopStackInWindowingMode(launchStack.getWindowingMode());
Andrii Kulianfab9cd82017-03-21 19:37:09 -07001901 } else if (launchStack.mDisplayId != mTargetStack.mDisplayId) {
1902 // Target and computed stacks are on different displays and we've
1903 // found a matching task - move the existing instance to that display and
1904 // move it to front.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001905 intentActivity.getTask().reparent(launchStack, ON_TOP,
Andrii Kulianfab9cd82017-03-21 19:37:09 -07001906 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
1907 "reparentToDisplay");
1908 mMovedToFront = true;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001909 } else if (launchStack.isActivityTypeHome()
1910 && !mTargetStack.isActivityTypeHome()) {
Bryce Lee4ff7da92017-07-17 10:39:24 -07001911 // It is possible for the home activity to be in another stack initially.
1912 // For example, the activity may have been initially started with an intent
1913 // which placed it in the fullscreen stack. To ensure the proper handling of
1914 // the activity based on home stack assumptions, we must move it over.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001915 intentActivity.getTask().reparent(launchStack, ON_TOP,
Bryce Lee4ff7da92017-07-17 10:39:24 -07001916 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
1917 "reparentingHome");
1918 mMovedToFront = true;
Chong Zhangdea4bd92016-03-15 12:50:03 -07001919 }
1920 mOptions = null;
Jorim Jaggi02886a82016-12-06 09:10:06 -08001921
1922 // We are moving a task to the front, use starting window to hide initial drawn
1923 // delay.
1924 intentActivity.showStartingWindow(null /* prev */, false /* newTask */,
1925 true /* taskSwitch */);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001926 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001927 }
1928 }
Andrii Kulianb850ea52017-12-12 23:49:10 -08001929 // Need to update mTargetStack because if task was moved out of it, the original stack may
1930 // be destroyed.
1931 mTargetStack = intentActivity.getStack();
Winson Chunge2d72172018-01-25 17:46:20 +00001932 if (!mAvoidMoveToFront && !mMovedToFront && mDoResume) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001933 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Bring to front target: " + mTargetStack
1934 + " from " + intentActivity);
1935 mTargetStack.moveToFront("intentActivityFound");
1936 }
1937
Wale Ogunwale0568aed2017-09-08 13:29:37 -07001938 mSupervisor.handleNonResizableTaskIfNeeded(intentActivity.getTask(),
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07001939 WINDOWING_MODE_UNDEFINED, DEFAULT_DISPLAY, mTargetStack);
Jorim Jaggid53f0922016-04-06 22:16:23 -07001940
Wale Ogunwale01d66562015-12-29 08:19:19 -08001941 // If the caller has requested that the target task be reset, then do so.
1942 if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1943 return mTargetStack.resetTaskIfNeededLocked(intentActivity, mStartActivity);
1944 }
1945 return intentActivity;
1946 }
1947
1948 private void setTaskFromIntentActivity(ActivityRecord intentActivity) {
1949 if ((mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1950 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {
1951 // The caller has requested to completely replace any existing task with its new
1952 // activity. Well that should not be too hard...
Bryce Lee41801b42017-03-02 13:23:12 -08001953 // Note: we must persist the {@link TaskRecord} first as intentActivity could be
1954 // removed from calling performClearTaskLocked (For example, if it is being brought out
Bryce Lee59dad4e2017-03-09 11:54:08 -08001955 // of history or if it is finished immediately), thus disassociating the task. Also note
1956 // that mReuseTask is reset as a result of {@link TaskRecord#performClearTaskLocked}
1957 // launching another activity.
1958 // TODO(b/36119896): We shouldn't trigger activity launches in this path since we are
1959 // already launching one.
Bryce Leeaf691c02017-03-20 14:20:22 -07001960 final TaskRecord task = intentActivity.getTask();
Bryce Lee59dad4e2017-03-09 11:54:08 -08001961 task.performClearTaskLocked();
1962 mReuseTask = task;
Bryce Lee41801b42017-03-02 13:23:12 -08001963 mReuseTask.setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001964 } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
Bryce Lee7daee392017-10-12 13:46:18 -07001965 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001966 ActivityRecord top = intentActivity.getTask().performClearTaskLocked(mStartActivity,
Wale Ogunwale01d66562015-12-29 08:19:19 -08001967 mLaunchFlags);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001968 if (top == null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001969 // A special case: we need to start the activity because it is not currently
1970 // running, and the caller has asked to clear the current task to have this
1971 // activity at the top.
1972 mAddingToTask = true;
Bryce Lee353112c2017-02-23 09:46:45 -08001973
1974 // We are no longer placing the activity in the task we previously thought we were.
Bryce Leeaf691c02017-03-20 14:20:22 -07001975 mStartActivity.setTask(null);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001976 // Now pretend like this activity is being started by the top of its task, so it
1977 // is put in the right place.
1978 mSourceRecord = intentActivity;
Bryce Leeaf691c02017-03-20 14:20:22 -07001979 final TaskRecord task = mSourceRecord.getTask();
Andrii Kulian02b7a832016-10-06 23:11:56 -07001980 if (task != null && task.getStack() == null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001981 // Target stack got cleared when we all activities were removed above.
1982 // Go ahead and reset it.
1983 mTargetStack = computeStackFocus(mSourceRecord, false /* newTask */,
Bryce Leedacefc42017-10-10 12:56:02 -07001984 mLaunchFlags, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001985 mTargetStack.addTask(task,
1986 !mLaunchTaskBehind /* toTop */, "startActivityUnchecked");
1987 }
1988 }
Bryce Leeaf691c02017-03-20 14:20:22 -07001989 } else if (mStartActivity.realActivity.equals(intentActivity.getTask().realActivity)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001990 // In this case the top activity on the task is the same as the one being launched,
1991 // so we take that as a request to bring the task to the foreground. If the top
1992 // activity in the task is the root activity, deliver this new intent to it if it
1993 // desires.
Bryce Lee7daee392017-10-12 13:46:18 -07001994 if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
1995 || LAUNCH_SINGLE_TOP == mLaunchMode)
Wale Ogunwale01d66562015-12-29 08:19:19 -08001996 && intentActivity.realActivity.equals(mStartActivity.realActivity)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001997 if (intentActivity.frontOfTask) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001998 intentActivity.getTask().setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001999 }
Bryce Lee325e09682017-10-05 17:20:25 -07002000 deliverNewIntent(intentActivity);
Bryce Leeaf691c02017-03-20 14:20:22 -07002001 } else if (!intentActivity.getTask().isSameIntentFilter(mStartActivity)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002002 // In this case we are launching the root activity of the task, but with a
2003 // different intent. We should start a new instance on top.
2004 mAddingToTask = true;
2005 mSourceRecord = intentActivity;
2006 }
2007 } else if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
2008 // In this case an activity is being launched in to an existing task, without
2009 // resetting that task. This is typically the situation of launching an activity
2010 // from a notification or shortcut. We want to place the new activity on top of the
2011 // current task.
2012 mAddingToTask = true;
2013 mSourceRecord = intentActivity;
Bryce Leeaf691c02017-03-20 14:20:22 -07002014 } else if (!intentActivity.getTask().rootWasReset) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002015 // In this case we are launching into an existing task that has not yet been started
2016 // from its front door. The current task has been brought to the front. Ideally,
2017 // we'd probably like to place this new task at the bottom of its stack, but that's
2018 // a little hard to do with the current organization of the code so for now we'll
2019 // just drop it.
Bryce Leeaf691c02017-03-20 14:20:22 -07002020 intentActivity.getTask().setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002021 }
2022 }
2023
2024 private void resumeTargetStackIfNeeded() {
2025 if (mDoResume) {
2026 mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, null, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002027 } else {
2028 ActivityOptions.abort(mOptions);
2029 }
2030 mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);
2031 }
2032
Chong Zhang6cda19c2016-06-14 19:07:56 -07002033 private int setTaskFromReuseOrCreateNewTask(
Wale Ogunwale0568aed2017-09-08 13:29:37 -07002034 TaskRecord taskToAffiliate, ActivityStack topStack) {
Bryce Leedacefc42017-10-10 12:56:02 -07002035 mTargetStack = computeStackFocus(mStartActivity, true, mLaunchFlags, mOptions);
Chong Zhang6cda19c2016-06-14 19:07:56 -07002036
2037 // Do no move the target stack to front yet, as we might bail if
2038 // isLockTaskModeViolation fails below.
Wale Ogunwale01d66562015-12-29 08:19:19 -08002039
2040 if (mReuseTask == null) {
Suprabh Shukla09a88f52015-12-02 14:36:31 -08002041 final TaskRecord task = mTargetStack.createTaskRecord(
2042 mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId),
Wale Ogunwale01d66562015-12-29 08:19:19 -08002043 mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
Wale Ogunwale72919d22016-12-08 18:58:50 -08002044 mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
Bryce Leeb802ea12017-11-15 21:25:03 -08002045 mVoiceInteractor, !mLaunchTaskBehind /* toTop */, mStartActivity, mSourceRecord,
2046 mOptions);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002047 addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
Bryce Leeec55eb02017-12-05 20:51:27 -08002048 updateBounds(mStartActivity.getTask(), mLaunchParams.mBounds);
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002049
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002050 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Bryce Leeaf691c02017-03-20 14:20:22 -07002051 + " in new task " + mStartActivity.getTask());
Wale Ogunwale01d66562015-12-29 08:19:19 -08002052 } else {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002053 addOrReparentStartingActivity(mReuseTask, "setTaskFromReuseOrCreateNewTask");
2054 }
2055
2056 if (taskToAffiliate != null) {
2057 mStartActivity.setTaskToAffiliateWith(taskToAffiliate);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002058 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07002059
Bryce Lee2b8e0372018-04-05 17:01:37 -07002060 if (mService.getLockTaskController().isLockTaskModeViolation(mStartActivity.getTask())) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002061 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
2062 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
2063 }
2064
Chong Zhang6cda19c2016-06-14 19:07:56 -07002065 if (mDoResume) {
2066 mTargetStack.moveToFront("reuseOrNewTask");
2067 }
2068 return START_SUCCESS;
Wale Ogunwale01d66562015-12-29 08:19:19 -08002069 }
2070
Bryce Lee325e09682017-10-05 17:20:25 -07002071 private void deliverNewIntent(ActivityRecord activity) {
2072 if (mIntentDelivered) {
2073 return;
2074 }
2075
2076 ActivityStack.logStartActivity(AM_NEW_INTENT, activity, activity.getTask());
2077 activity.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
2078 mStartActivity.launchedFromPackage);
2079 mIntentDelivered = true;
2080 }
2081
Wale Ogunwale01d66562015-12-29 08:19:19 -08002082 private int setTaskFromSourceRecord() {
Bryce Lee2b8e0372018-04-05 17:01:37 -07002083 if (mService.getLockTaskController().isLockTaskModeViolation(mSourceRecord.getTask())) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002084 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
2085 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
2086 }
2087
Bryce Leeaf691c02017-03-20 14:20:22 -07002088 final TaskRecord sourceTask = mSourceRecord.getTask();
Andrii Kulian02b7a832016-10-06 23:11:56 -07002089 final ActivityStack sourceStack = mSourceRecord.getStack();
Andrii Kulian02689a72017-07-06 14:28:59 -07002090 // We only want to allow changing stack in two cases:
2091 // 1. If the target task is not the top one. Otherwise we would move the launching task to
2092 // the other side, rather than show two side by side.
2093 // 2. If activity is not allowed on target display.
2094 final int targetDisplayId = mTargetStack != null ? mTargetStack.mDisplayId
2095 : sourceStack.mDisplayId;
2096 final boolean moveStackAllowed = sourceStack.topTask() != sourceTask
2097 || !mStartActivity.canBeLaunchedOnDisplay(targetDisplayId);
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002098 if (moveStackAllowed) {
Bryce Leeaf691c02017-03-20 14:20:22 -07002099 mTargetStack = getLaunchStack(mStartActivity, mLaunchFlags, mStartActivity.getTask(),
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002100 mOptions);
Andrii Kulian02689a72017-07-06 14:28:59 -07002101 // If target stack is not found now - we can't just rely on the source stack, as it may
2102 // be not suitable. Let's check other displays.
2103 if (mTargetStack == null && targetDisplayId != sourceStack.mDisplayId) {
2104 // Can't use target display, lets find a stack on the source display.
2105 mTargetStack = mService.mStackSupervisor.getValidLaunchStackOnDisplay(
2106 sourceStack.mDisplayId, mStartActivity);
2107 }
2108 if (mTargetStack == null) {
2109 // There are no suitable stacks on the target and source display(s). Look on all
2110 // displays.
2111 mTargetStack = mService.mStackSupervisor.getNextValidLaunchStackLocked(
2112 mStartActivity, -1 /* currentFocus */);
2113 }
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002114 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002115
2116 if (mTargetStack == null) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07002117 mTargetStack = sourceStack;
2118 } else if (mTargetStack != sourceStack) {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002119 sourceTask.reparent(mTargetStack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE,
2120 DEFER_RESUME, "launchToSide");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002121 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07002122
Wale Ogunwale01d66562015-12-29 08:19:19 -08002123 final TaskRecord topTask = mTargetStack.topTask();
Jorim Jaggic875ae72016-04-26 22:41:06 -07002124 if (topTask != sourceTask && !mAvoidMoveToFront) {
chaviw0d562bf2018-03-15 14:24:14 -07002125 mTargetStack.moveTaskToFrontLocked(sourceTask, mNoAnimation, mOptions,
Wale Ogunwale01d66562015-12-29 08:19:19 -08002126 mStartActivity.appTimeTracker, "sourceTaskToFront");
Chong Zhang6cda19c2016-06-14 19:07:56 -07002127 } else if (mDoResume) {
2128 mTargetStack.moveToFront("sourceStackToFront");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002129 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07002130
Wale Ogunwale01d66562015-12-29 08:19:19 -08002131 if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0) {
2132 // In this case, we are adding the activity to an existing task, but the caller has
2133 // asked to clear that task if the activity is already running.
2134 ActivityRecord top = sourceTask.performClearTaskLocked(mStartActivity, mLaunchFlags);
2135 mKeepCurTransition = true;
2136 if (top != null) {
Bryce Leeaf691c02017-03-20 14:20:22 -07002137 ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, top.getTask());
Bryce Lee325e09682017-10-05 17:20:25 -07002138 deliverNewIntent(top);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002139 // For paranoia, make sure we have correctly resumed the top activity.
2140 mTargetStack.mLastPausedActivity = null;
2141 if (mDoResume) {
2142 mSupervisor.resumeFocusedStackTopActivityLocked();
2143 }
2144 ActivityOptions.abort(mOptions);
2145 return START_DELIVERED_TO_TOP;
2146 }
2147 } else if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
2148 // In this case, we are launching an activity in our own task that may already be
2149 // running somewhere in the history, and we want to shuffle it to the front of the
2150 // stack if so.
2151 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(mStartActivity);
2152 if (top != null) {
Bryce Leeaf691c02017-03-20 14:20:22 -07002153 final TaskRecord task = top.getTask();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002154 task.moveActivityToFrontLocked(top);
2155 top.updateOptionsLocked(mOptions);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08002156 ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, task);
Bryce Lee325e09682017-10-05 17:20:25 -07002157 deliverNewIntent(top);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002158 mTargetStack.mLastPausedActivity = null;
2159 if (mDoResume) {
2160 mSupervisor.resumeFocusedStackTopActivityLocked();
2161 }
2162 return START_DELIVERED_TO_TOP;
2163 }
2164 }
2165
2166 // An existing activity is starting this new activity, so we want to keep the new one in
2167 // the same task as the one that is starting it.
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002168 addOrReparentStartingActivity(sourceTask, "setTaskFromSourceRecord");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002169 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Bryce Leeaf691c02017-03-20 14:20:22 -07002170 + " in existing task " + mStartActivity.getTask() + " from source " + mSourceRecord);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002171 return START_SUCCESS;
2172 }
2173
2174 private int setTaskFromInTask() {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002175 // The caller is asking that the new activity be started in an explicit
2176 // task it has provided to us.
Bryce Lee2b8e0372018-04-05 17:01:37 -07002177 if (mService.getLockTaskController().isLockTaskModeViolation(mInTask)) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002178 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
2179 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
2180 }
2181
Andrii Kulian02b7a832016-10-06 23:11:56 -07002182 mTargetStack = mInTask.getStack();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002183
2184 // Check whether we should actually launch the new activity in to the task,
2185 // or just reuse the current activity on top.
2186 ActivityRecord top = mInTask.getTopActivity();
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002187 if (top != null && top.realActivity.equals(mStartActivity.realActivity)
2188 && top.userId == mStartActivity.userId) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002189 if ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
Bryce Lee7daee392017-10-12 13:46:18 -07002190 || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK)) {
chaviw0d562bf2018-03-15 14:24:14 -07002191 mTargetStack.moveTaskToFrontLocked(mInTask, mNoAnimation, mOptions,
Yorke Lee64512522017-03-24 13:09:35 -07002192 mStartActivity.appTimeTracker, "inTaskToFront");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002193 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
2194 // We don't need to start a new activity, and the client said not to do
2195 // anything if that is the case, so this is it!
2196 return START_RETURN_INTENT_TO_CALLER;
2197 }
Bryce Lee325e09682017-10-05 17:20:25 -07002198 deliverNewIntent(top);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002199 return START_DELIVERED_TO_TOP;
2200 }
2201 }
2202
2203 if (!mAddingToTask) {
chaviw0d562bf2018-03-15 14:24:14 -07002204 mTargetStack.moveTaskToFrontLocked(mInTask, mNoAnimation, mOptions,
Yorke Lee64512522017-03-24 13:09:35 -07002205 mStartActivity.appTimeTracker, "inTaskToFront");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002206 // We don't actually want to have this activity added to the task, so just
2207 // stop here but still tell the caller that we consumed the intent.
2208 ActivityOptions.abort(mOptions);
2209 return START_TASK_TO_FRONT;
2210 }
2211
Bryce Leeec55eb02017-12-05 20:51:27 -08002212 if (!mLaunchParams.mBounds.isEmpty()) {
Wale Ogunwale0568aed2017-09-08 13:29:37 -07002213 // TODO: Shouldn't we already know what stack to use by the time we get here?
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002214 ActivityStack stack = mSupervisor.getLaunchStack(null, null, mInTask, ON_TOP);
2215 if (stack != mInTask.getStack()) {
2216 mInTask.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, !ANIMATE,
Yorke Lee64512522017-03-24 13:09:35 -07002217 DEFER_RESUME, "inTaskToFront");
Yorke Lee64512522017-03-24 13:09:35 -07002218 mTargetStack = mInTask.getStack();
2219 }
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002220
Bryce Leeec55eb02017-12-05 20:51:27 -08002221 updateBounds(mInTask, mLaunchParams.mBounds);
Yorke Lee64512522017-03-24 13:09:35 -07002222 }
2223
chaviw0d562bf2018-03-15 14:24:14 -07002224 mTargetStack.moveTaskToFrontLocked(
2225 mInTask, mNoAnimation, mOptions, mStartActivity.appTimeTracker, "inTaskToFront");
Yorke Lee64512522017-03-24 13:09:35 -07002226
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002227 addOrReparentStartingActivity(mInTask, "setTaskFromInTask");
2228 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Bryce Leeaf691c02017-03-20 14:20:22 -07002229 + " in explicit task " + mStartActivity.getTask());
Wale Ogunwale01d66562015-12-29 08:19:19 -08002230
2231 return START_SUCCESS;
2232 }
2233
Bryce Leed3624e12017-11-30 08:51:45 -08002234 @VisibleForTesting
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002235 void updateBounds(TaskRecord task, Rect bounds) {
Bryce Leedacefc42017-10-10 12:56:02 -07002236 if (bounds.isEmpty()) {
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002237 return;
2238 }
2239
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002240 final ActivityStack stack = task.getStack();
2241 if (stack != null && stack.resizeStackWithLaunchBounds()) {
2242 mService.resizeStack(stack.mStackId, bounds, true, !PRESERVE_WINDOWS, ANIMATE, -1);
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002243 } else {
2244 task.updateOverrideConfiguration(bounds);
2245 }
2246 }
2247
Wale Ogunwale01d66562015-12-29 08:19:19 -08002248 private void setTaskToCurrentTopOrCreateNewTask() {
Bryce Leedacefc42017-10-10 12:56:02 -07002249 mTargetStack = computeStackFocus(mStartActivity, false, mLaunchFlags, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002250 if (mDoResume) {
2251 mTargetStack.moveToFront("addingToTopTask");
2252 }
Wale Ogunwale30e441d2017-11-09 08:28:45 -08002253 final ActivityRecord prev = mTargetStack.getTopActivity();
Bryce Leeaf691c02017-03-20 14:20:22 -07002254 final TaskRecord task = (prev != null) ? prev.getTask() : mTargetStack.createTaskRecord(
Wale Ogunwale72919d22016-12-08 18:58:50 -08002255 mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId), mStartActivity.info,
Bryce Leeb802ea12017-11-15 21:25:03 -08002256 mIntent, null, null, true, mStartActivity, mSourceRecord, mOptions);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002257 addOrReparentStartingActivity(task, "setTaskToCurrentTopOrCreateNewTask");
2258 mTargetStack.positionChildWindowContainerAtTop(task);
2259 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Bryce Leeaf691c02017-03-20 14:20:22 -07002260 + " in new guessed " + mStartActivity.getTask());
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002261 }
2262
2263 private void addOrReparentStartingActivity(TaskRecord parent, String reason) {
Bryce Leeaf691c02017-03-20 14:20:22 -07002264 if (mStartActivity.getTask() == null || mStartActivity.getTask() == parent) {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002265 parent.addActivityToTop(mStartActivity);
2266 } else {
2267 mStartActivity.reparent(parent, parent.mActivities.size() /* top */, reason);
2268 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002269 }
2270
2271 private int adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance,
2272 boolean launchSingleTask, int launchFlags) {
2273 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2274 (launchSingleInstance || launchSingleTask)) {
2275 // We have a conflict between the Intent and the Activity manifest, manifest wins.
2276 Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " +
2277 "\"singleInstance\" or \"singleTask\"");
2278 launchFlags &=
2279 ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK);
2280 } else {
2281 switch (r.info.documentLaunchMode) {
2282 case ActivityInfo.DOCUMENT_LAUNCH_NONE:
2283 break;
2284 case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
2285 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2286 break;
2287 case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
2288 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2289 break;
2290 case ActivityInfo.DOCUMENT_LAUNCH_NEVER:
2291 launchFlags &= ~FLAG_ACTIVITY_MULTIPLE_TASK;
2292 break;
2293 }
2294 }
2295 return launchFlags;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002296 }
2297
Bryce Leedacefc42017-10-10 12:56:02 -07002298 private ActivityStack computeStackFocus(ActivityRecord r, boolean newTask, int launchFlags,
2299 ActivityOptions aOptions) {
Bryce Leeaf691c02017-03-20 14:20:22 -07002300 final TaskRecord task = r.getTask();
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002301 ActivityStack stack = getLaunchStack(r, launchFlags, task, aOptions);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002302 if (stack != null) {
2303 return stack;
2304 }
2305
Andrii Kulian02b7a832016-10-06 23:11:56 -07002306 final ActivityStack currentStack = task != null ? task.getStack() : null;
2307 if (currentStack != null) {
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002308 if (mSupervisor.mFocusedStack != currentStack) {
2309 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
2310 "computeStackFocus: Setting " + "focused stack to r=" + r
2311 + " task=" + task);
2312 } else {
2313 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
2314 "computeStackFocus: Focused stack already="
2315 + mSupervisor.mFocusedStack);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002316 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07002317 return currentStack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002318 }
2319
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002320 if (canLaunchIntoFocusedStack(r, newTask)) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002321 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
2322 "computeStackFocus: Have a focused stack=" + mSupervisor.mFocusedStack);
2323 return mSupervisor.mFocusedStack;
2324 }
2325
David Stevense5a7b642017-05-22 13:18:23 -07002326 if (mPreferredDisplayId != DEFAULT_DISPLAY) {
Andrii Kuliana8fe3df2017-06-16 15:29:26 -07002327 // Try to put the activity in a stack on a secondary display.
David Stevense5a7b642017-05-22 13:18:23 -07002328 stack = mSupervisor.getValidLaunchStackOnDisplay(mPreferredDisplayId, r);
Andrii Kuliana8fe3df2017-06-16 15:29:26 -07002329 if (stack == null) {
2330 // If source display is not suitable - look for topmost valid stack in the system.
2331 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
David Stevense5a7b642017-05-22 13:18:23 -07002332 "computeStackFocus: Can't launch on mPreferredDisplayId="
2333 + mPreferredDisplayId + ", looking on all displays.");
2334 stack = mSupervisor.getNextValidLaunchStackLocked(r, mPreferredDisplayId);
Andrii Kuliana8fe3df2017-06-16 15:29:26 -07002335 }
2336 }
2337 if (stack == null) {
David Stevensc6b91c62017-02-08 14:23:58 -08002338 // We first try to put the task in the first dynamic stack on home display.
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07002339 final ActivityDisplay display = mSupervisor.getDefaultDisplay();
2340 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
2341 stack = display.getChildAt(stackNdx);
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002342 if (!stack.isOnHomeDisplay()) {
David Stevensc6b91c62017-02-08 14:23:58 -08002343 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
2344 "computeStackFocus: Setting focused stack=" + stack);
2345 return stack;
2346 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002347 }
David Stevensc6b91c62017-02-08 14:23:58 -08002348 // If there is no suitable dynamic stack then we figure out which static stack to use.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002349 stack = mSupervisor.getLaunchStack(r, aOptions, task, ON_TOP);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002350 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002351 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, "computeStackFocus: New stack r="
2352 + r + " stackId=" + stack.mStackId);
2353 return stack;
2354 }
2355
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002356 /** Check if provided activity record can launch in currently focused stack. */
Wale Ogunwale68278562017-09-23 17:13:55 -07002357 // TODO: This method can probably be consolidated into getLaunchStack() below.
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002358 private boolean canLaunchIntoFocusedStack(ActivityRecord r, boolean newTask) {
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002359 final ActivityStack focusedStack = mSupervisor.mFocusedStack;
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002360 final boolean canUseFocusedStack;
Wale Ogunwale68278562017-09-23 17:13:55 -07002361 if (focusedStack.isActivityTypeAssistant()) {
2362 canUseFocusedStack = r.isActivityTypeAssistant();
2363 } else {
2364 switch (focusedStack.getWindowingMode()) {
2365 case WINDOWING_MODE_FULLSCREEN:
2366 // The fullscreen stack can contain any task regardless of if the task is
2367 // resizeable or not. So, we let the task go in the fullscreen task if it is the
2368 // focus stack.
2369 canUseFocusedStack = true;
2370 break;
2371 case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
2372 case WINDOWING_MODE_SPLIT_SCREEN_SECONDARY:
2373 // Any activity which supports split screen can go in the docked stack.
2374 canUseFocusedStack = r.supportsSplitScreenWindowingMode();
2375 break;
2376 case WINDOWING_MODE_FREEFORM:
2377 // Any activity which supports freeform can go in the freeform stack.
2378 canUseFocusedStack = r.supportsFreeform();
2379 break;
2380 default:
2381 // Dynamic stacks behave similarly to the fullscreen stack and can contain any
2382 // resizeable task.
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002383 canUseFocusedStack = !focusedStack.isOnHomeDisplay()
Wale Ogunwale68278562017-09-23 17:13:55 -07002384 && r.canBeLaunchedOnDisplay(focusedStack.mDisplayId);
2385 }
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002386 }
Andrii Kulian94e82d9b02017-07-13 15:33:06 -07002387 return canUseFocusedStack && !newTask
Wale Ogunwale68278562017-09-23 17:13:55 -07002388 // Using the focus stack isn't important enough to override the preferred display.
David Stevense5a7b642017-05-22 13:18:23 -07002389 && (mPreferredDisplayId == focusedStack.mDisplayId);
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002390 }
2391
Wale Ogunwale854809c2015-12-27 16:18:19 -08002392 private ActivityStack getLaunchStack(ActivityRecord r, int launchFlags, TaskRecord task,
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002393 ActivityOptions aOptions) {
Bryce Leea19b5ad2017-06-07 16:54:11 -07002394 // We are reusing a task, keep the stack!
2395 if (mReuseTask != null) {
2396 return mReuseTask.getStack();
2397 }
Jorim Jaggib8c58762016-04-20 17:58:29 -07002398
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -08002399 if (((launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) == 0)
David Stevense5a7b642017-05-22 13:18:23 -07002400 || mPreferredDisplayId != DEFAULT_DISPLAY) {
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08002401 // We don't pass in the default display id into the get launch stack call so it can do a
2402 // full resolution.
2403 final int candidateDisplay =
2404 mPreferredDisplayId != DEFAULT_DISPLAY ? mPreferredDisplayId : INVALID_DISPLAY;
2405 return mSupervisor.getLaunchStack(r, aOptions, task, ON_TOP, candidateDisplay);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002406 }
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002407 // Otherwise handle adjacent launch.
Wale Ogunwale854809c2015-12-27 16:18:19 -08002408
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002409 // The parent activity doesn't want to launch the activity on top of itself, but
2410 // instead tries to put it onto other side in side-by-side mode.
Andrii Kulian94e82d9b02017-07-13 15:33:06 -07002411 final ActivityStack parentStack = task != null ? task.getStack(): mSupervisor.mFocusedStack;
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002412
2413 if (parentStack != mSupervisor.mFocusedStack) {
2414 // If task's parent stack is not focused - use it during adjacent launch.
2415 return parentStack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002416 } else {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002417 if (mSupervisor.mFocusedStack != null && task == mSupervisor.mFocusedStack.topTask()) {
2418 // If task is already on top of focused stack - use it. We don't want to move the
2419 // existing focused task to adjacent stack, just deliver new intent in this case.
2420 return mSupervisor.mFocusedStack;
2421 }
2422
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002423 if (parentStack != null && parentStack.inSplitScreenPrimaryWindowingMode()) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002424 // If parent was in docked stack, the natural place to launch another activity
2425 // will be fullscreen, so it can appear alongside the docked window.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002426 final int activityType = mSupervisor.resolveActivityType(r, mOptions, task);
2427 return parentStack.getDisplay().getOrCreateStack(
2428 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, activityType, ON_TOP);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002429 } else {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002430 // If the parent is not in the docked stack, we check if there is docked window
2431 // and if yes, we will launch into that stack. If not, we just put the new
2432 // activity into parent's stack, because we can't find a better place.
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07002433 final ActivityStack dockedStack =
2434 mSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
Wale Ogunwale9dcf9462017-09-19 15:13:01 -07002435 if (dockedStack != null && !dockedStack.shouldBeVisible(r)) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002436 // There is a docked stack, but it isn't visible, so we can't launch into that.
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08002437 return mSupervisor.getLaunchStack(r, aOptions, task, ON_TOP);
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002438 } else {
2439 return dockedStack;
2440 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002441 }
2442 }
2443 }
2444
Bryce Lee7daee392017-10-12 13:46:18 -07002445 private boolean isLaunchModeOneOf(int mode1, int mode2) {
2446 return mode1 == mLaunchMode || mode2 == mLaunchMode;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002447 }
2448
Daichi Hirono15a02992016-04-27 18:47:01 +09002449 static boolean isDocumentLaunchesIntoExisting(int flags) {
2450 return (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2451 (flags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0;
2452 }
liulvpingcfa825f2016-09-26 20:00:15 +08002453
Bryce Lee4c9a5972017-12-01 22:14:24 -08002454 ActivityStarter setIntent(Intent intent) {
2455 mRequest.intent = intent;
2456 return this;
2457 }
2458
Bryce Lee32e09ef2018-03-19 15:29:49 -07002459 @VisibleForTesting
2460 Intent getIntent() {
2461 return mRequest.intent;
2462 }
2463
Bryce Lee4c9a5972017-12-01 22:14:24 -08002464 ActivityStarter setReason(String reason) {
2465 mRequest.reason = reason;
2466 return this;
2467 }
2468
2469 ActivityStarter setCaller(IApplicationThread caller) {
2470 mRequest.caller = caller;
2471 return this;
2472 }
2473
2474 ActivityStarter setEphemeralIntent(Intent intent) {
2475 mRequest.ephemeralIntent = intent;
2476 return this;
2477 }
2478
2479
2480 ActivityStarter setResolvedType(String type) {
2481 mRequest.resolvedType = type;
2482 return this;
2483 }
2484
2485 ActivityStarter setActivityInfo(ActivityInfo info) {
2486 mRequest.activityInfo = info;
2487 return this;
2488 }
2489
2490 ActivityStarter setResolveInfo(ResolveInfo info) {
2491 mRequest.resolveInfo = info;
2492 return this;
2493 }
2494
2495 ActivityStarter setVoiceSession(IVoiceInteractionSession voiceSession) {
2496 mRequest.voiceSession = voiceSession;
2497 return this;
2498 }
2499
2500 ActivityStarter setVoiceInteractor(IVoiceInteractor voiceInteractor) {
2501 mRequest.voiceInteractor = voiceInteractor;
2502 return this;
2503 }
2504
2505 ActivityStarter setResultTo(IBinder resultTo) {
2506 mRequest.resultTo = resultTo;
2507 return this;
2508 }
2509
2510 ActivityStarter setResultWho(String resultWho) {
2511 mRequest.resultWho = resultWho;
2512 return this;
2513 }
2514
2515 ActivityStarter setRequestCode(int requestCode) {
2516 mRequest.requestCode = requestCode;
2517 return this;
2518 }
2519
2520 ActivityStarter setCallingPid(int pid) {
2521 mRequest.callingPid = pid;
2522 return this;
2523 }
2524
2525 ActivityStarter setCallingUid(int uid) {
2526 mRequest.callingUid = uid;
2527 return this;
2528 }
2529
2530 ActivityStarter setCallingPackage(String callingPackage) {
2531 mRequest.callingPackage = callingPackage;
2532 return this;
2533 }
2534
2535 ActivityStarter setRealCallingPid(int pid) {
2536 mRequest.realCallingPid = pid;
2537 return this;
2538 }
2539
2540 ActivityStarter setRealCallingUid(int uid) {
2541 mRequest.realCallingUid = uid;
2542 return this;
2543 }
2544
2545 ActivityStarter setStartFlags(int startFlags) {
2546 mRequest.startFlags = startFlags;
2547 return this;
2548 }
2549
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002550 ActivityStarter setActivityOptions(SafeActivityOptions options) {
Bryce Lee4c9a5972017-12-01 22:14:24 -08002551 mRequest.activityOptions = options;
2552 return this;
2553 }
2554
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002555 ActivityStarter setActivityOptions(Bundle bOptions) {
2556 return setActivityOptions(SafeActivityOptions.fromBundle(bOptions));
2557 }
2558
Bryce Lee4c9a5972017-12-01 22:14:24 -08002559 ActivityStarter setIgnoreTargetSecurity(boolean ignoreTargetSecurity) {
2560 mRequest.ignoreTargetSecurity = ignoreTargetSecurity;
2561 return this;
2562 }
2563
2564 ActivityStarter setComponentSpecified(boolean componentSpecified) {
2565 mRequest.componentSpecified = componentSpecified;
2566 return this;
2567 }
2568
2569 ActivityStarter setOutActivity(ActivityRecord[] outActivity) {
2570 mRequest.outActivity = outActivity;
2571 return this;
2572 }
2573
2574 ActivityStarter setInTask(TaskRecord inTask) {
2575 mRequest.inTask = inTask;
2576 return this;
2577 }
2578
2579 ActivityStarter setWaitResult(WaitResult result) {
2580 mRequest.waitResult = result;
2581 return this;
2582 }
2583
2584 ActivityStarter setProfilerInfo(ProfilerInfo info) {
2585 mRequest.profilerInfo = info;
2586 return this;
2587 }
2588
2589 ActivityStarter setGlobalConfiguration(Configuration config) {
2590 mRequest.globalConfig = config;
2591 return this;
2592 }
2593
Bryce Lee4c9a5972017-12-01 22:14:24 -08002594 ActivityStarter setUserId(int userId) {
2595 mRequest.userId = userId;
2596 return this;
2597 }
2598
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002599 ActivityStarter setMayWait(int userId) {
Bryce Lee4c9a5972017-12-01 22:14:24 -08002600 mRequest.mayWait = true;
Bryce Lee4c9a5972017-12-01 22:14:24 -08002601 mRequest.userId = userId;
2602
2603 return this;
2604 }
2605
Jorim Jaggi6fa41c32018-04-23 18:35:00 +02002606 ActivityStarter setAllowPendingRemoteAnimationRegistryLookup(boolean allowLookup) {
2607 mRequest.allowPendingRemoteAnimationRegistryLookup = allowLookup;
2608 return this;
2609 }
2610
Bryce Leed3624e12017-11-30 08:51:45 -08002611 void dump(PrintWriter pw, String prefix) {
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002612 prefix = prefix + " ";
Dianne Hackborne676ec72017-07-25 10:55:08 -07002613 pw.print(prefix);
2614 pw.print("mCurrentUser=");
2615 pw.println(mSupervisor.mCurrentUser);
2616 pw.print(prefix);
2617 pw.print("mLastStartReason=");
2618 pw.println(mLastStartReason);
2619 pw.print(prefix);
2620 pw.print("mLastStartActivityTimeMs=");
2621 pw.println(DateFormat.getDateTimeInstance().format(new Date(mLastStartActivityTimeMs)));
2622 pw.print(prefix);
2623 pw.print("mLastStartActivityResult=");
2624 pw.println(mLastStartActivityResult);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002625 ActivityRecord r = mLastStartActivityRecord[0];
2626 if (r != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002627 pw.print(prefix);
2628 pw.println("mLastStartActivityRecord:");
2629 r.dump(pw, prefix + " ");
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002630 }
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002631 if (mStartActivity != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002632 pw.print(prefix);
2633 pw.println("mStartActivity:");
2634 mStartActivity.dump(pw, prefix + " ");
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002635 }
2636 if (mIntent != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002637 pw.print(prefix);
2638 pw.print("mIntent=");
2639 pw.println(mIntent);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002640 }
2641 if (mOptions != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002642 pw.print(prefix);
2643 pw.print("mOptions=");
2644 pw.println(mOptions);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002645 }
Dianne Hackborne676ec72017-07-25 10:55:08 -07002646 pw.print(prefix);
2647 pw.print("mLaunchSingleTop=");
Bryce Lee7daee392017-10-12 13:46:18 -07002648 pw.print(LAUNCH_SINGLE_TOP == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002649 pw.print(" mLaunchSingleInstance=");
Bryce Lee7daee392017-10-12 13:46:18 -07002650 pw.print(LAUNCH_SINGLE_INSTANCE == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002651 pw.print(" mLaunchSingleTask=");
Bryce Lee7daee392017-10-12 13:46:18 -07002652 pw.println(LAUNCH_SINGLE_TASK == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002653 pw.print(prefix);
2654 pw.print("mLaunchFlags=0x");
2655 pw.print(Integer.toHexString(mLaunchFlags));
2656 pw.print(" mDoResume=");
2657 pw.print(mDoResume);
2658 pw.print(" mAddingToTask=");
2659 pw.println(mAddingToTask);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002660 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002661}