OSDN Git Service

[automerger] [RESTRICT AUTOMERGE] Make Lock task default behaviour consistent with...
[android-x86/frameworks-base.git] / services / core / java / com / android / server / am / ActivityStarter.java
1 /*
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
17 package com.android.server.am;
18
19 import static android.app.Activity.RESULT_CANCELED;
20 import static android.app.ActivityManager.START_ABORTED;
21 import static android.app.ActivityManager.START_CANCELED;
22 import static android.app.ActivityManager.START_CLASS_NOT_FOUND;
23 import static android.app.ActivityManager.START_DELIVERED_TO_TOP;
24 import static android.app.ActivityManager.START_FLAG_ONLY_IF_NEEDED;
25 import static android.app.ActivityManager.START_RETURN_INTENT_TO_CALLER;
26 import static android.app.ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
27 import static android.app.ActivityManager.START_SUCCESS;
28 import static android.app.ActivityManager.START_TASK_TO_FRONT;
29 import static android.app.ActivityManager.StackId;
30 import static android.app.ActivityManager.StackId.ASSISTANT_STACK_ID;
31 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
32 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
33 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
34 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
35 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
36 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
37 import static android.app.ActivityManager.StackId.RECENTS_STACK_ID;
38 import static android.app.ActivityManager.StackId.isDynamicStack;
39 import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
40 import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
41 import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
42 import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT;
43 import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
44 import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
45 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
46 import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION;
47 import static android.content.Intent.FLAG_ACTIVITY_NO_USER_ACTION;
48 import static android.content.Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP;
49 import static android.content.Intent.FLAG_ACTIVITY_REORDER_TO_FRONT;
50 import static android.content.Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED;
51 import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
52 import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP;
53 import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
54 import static android.content.pm.ActivityInfo.DOCUMENT_LAUNCH_ALWAYS;
55 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
56 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
57 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
58 import static android.view.Display.DEFAULT_DISPLAY;
59 import static android.view.Display.INVALID_DISPLAY;
60 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
61 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
62 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
63 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
64 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RESULTS;
65 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
66 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
67 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USER_LEAVING;
68 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
69 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
70 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RESULTS;
71 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_USER_LEAVING;
72 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
73 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
74 import static com.android.server.am.ActivityManagerService.ANIMATE;
75 import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
76 import static com.android.server.am.ActivityRecord.ASSISTANT_ACTIVITY_TYPE;
77 import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
78 import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
79 import static com.android.server.am.ActivityStack.STACK_INVISIBLE;
80 import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
81 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
82 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
83 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
84 import static com.android.server.am.ActivityStackSupervisor.TAG_TASKS;
85 import static com.android.server.am.EventLogTags.AM_NEW_INTENT;
86 import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
87 import static com.android.server.am.TaskRecord.REPARENT_MOVE_STACK_TO_FRONT;
88
89 import android.annotation.NonNull;
90 import android.app.ActivityManager;
91 import android.app.ActivityOptions;
92 import android.app.AppGlobals;
93 import android.app.IApplicationThread;
94 import android.app.PendingIntent;
95 import android.app.ProfilerInfo;
96 import android.app.WaitResult;
97 import android.content.IIntentSender;
98 import android.content.Intent;
99 import android.content.IntentSender;
100 import android.content.pm.ActivityInfo;
101 import android.content.pm.ApplicationInfo;
102 import android.content.pm.AuxiliaryResolveInfo;
103 import android.content.pm.PackageManager;
104 import android.content.pm.ResolveInfo;
105 import android.content.pm.UserInfo;
106 import android.content.res.Configuration;
107 import android.graphics.Rect;
108 import android.hardware.power.V1_0.PowerHint;
109 import android.os.Binder;
110 import android.os.Bundle;
111 import android.os.IBinder;
112 import android.os.RemoteException;
113 import android.os.SystemClock;
114 import android.os.UserHandle;
115 import android.os.UserManager;
116 import android.service.voice.IVoiceInteractionSession;
117 import android.text.TextUtils;
118 import android.util.EventLog;
119 import android.util.Slog;
120
121 import com.android.internal.app.HeavyWeightSwitcherActivity;
122 import com.android.internal.app.IVoiceInteractor;
123 import com.android.server.am.ActivityStackSupervisor.PendingActivityLaunch;
124 import com.android.server.pm.InstantAppResolver;
125 import com.android.server.wm.WindowManagerService;
126
127 import java.io.PrintWriter;
128 import java.text.DateFormat;
129 import java.util.ArrayList;
130 import java.util.Date;
131
132 /**
133  * Controller for interpreting how and then launching activities.
134  *
135  * This class collects all the logic for determining how an intent and flags should be turned into
136  * an activity and associated task and stack.
137  */
138 class ActivityStarter {
139     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStarter" : TAG_AM;
140     private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS;
141     private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
142     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
143     private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING;
144
145     private final ActivityManagerService mService;
146     private final ActivityStackSupervisor mSupervisor;
147     private ActivityStartInterceptor mInterceptor;
148     private WindowManagerService mWindowManager;
149
150     final ArrayList<PendingActivityLaunch> mPendingActivityLaunches = new ArrayList<>();
151
152     // Share state variable among methods when starting an activity.
153     private ActivityRecord mStartActivity;
154     private Intent mIntent;
155     private int mCallingUid;
156     private ActivityOptions mOptions;
157
158     private boolean mLaunchSingleTop;
159     private boolean mLaunchSingleInstance;
160     private boolean mLaunchSingleTask;
161     private boolean mLaunchTaskBehind;
162     private int mLaunchFlags;
163
164     private Rect mLaunchBounds;
165
166     private ActivityRecord mNotTop;
167     private boolean mDoResume;
168     private int mStartFlags;
169     private ActivityRecord mSourceRecord;
170     private int mSourceDisplayId;
171
172     private TaskRecord mInTask;
173     private boolean mAddingToTask;
174     private TaskRecord mReuseTask;
175
176     private ActivityInfo mNewTaskInfo;
177     private Intent mNewTaskIntent;
178     private ActivityStack mSourceStack;
179     private ActivityStack mTargetStack;
180     // Indicates that we moved other task and are going to put something on top soon, so
181     // we don't want to show it redundantly or accidentally change what's shown below.
182     private boolean mMovedOtherTask;
183     private boolean mMovedToFront;
184     private boolean mNoAnimation;
185     private boolean mKeepCurTransition;
186     private boolean mAvoidMoveToFront;
187     private boolean mPowerHintSent;
188
189     // We must track when we deliver the new intent since multiple code paths invoke
190     // {@link #deliverNewIntent}. This is due to early returns in the code path. This flag is used
191     // inside {@link #deliverNewIntent} to suppress duplicate requests and ensure the intent is
192     // delivered at most once.
193     private boolean mIntentDelivered;
194
195     private IVoiceInteractionSession mVoiceSession;
196     private IVoiceInteractor mVoiceInteractor;
197
198     private boolean mUsingVr2dDisplay;
199
200     // Last home activity record we attempted to start
201     private final ActivityRecord[] mLastHomeActivityStartRecord = new ActivityRecord[1];
202     // The result of the last home activity we attempted to start.
203     private int mLastHomeActivityStartResult;
204     // Last activity record we attempted to start
205     private final ActivityRecord[] mLastStartActivityRecord = new ActivityRecord[1];
206     // The result of the last activity we attempted to start.
207     private int mLastStartActivityResult;
208     // Time in milli seconds we attempted to start the last activity.
209     private long mLastStartActivityTimeMs;
210     // The reason we were trying to start the last activity
211     private String mLastStartReason;
212
213     private void reset() {
214         mStartActivity = null;
215         mIntent = null;
216         mCallingUid = -1;
217         mOptions = null;
218
219         mLaunchSingleTop = false;
220         mLaunchSingleInstance = false;
221         mLaunchSingleTask = false;
222         mLaunchTaskBehind = false;
223         mLaunchFlags = 0;
224
225         mLaunchBounds = null;
226
227         mNotTop = null;
228         mDoResume = false;
229         mStartFlags = 0;
230         mSourceRecord = null;
231         mSourceDisplayId = INVALID_DISPLAY;
232
233         mInTask = null;
234         mAddingToTask = false;
235         mReuseTask = null;
236
237         mNewTaskInfo = null;
238         mNewTaskIntent = null;
239         mSourceStack = null;
240
241         mTargetStack = null;
242         mMovedOtherTask = false;
243         mMovedToFront = false;
244         mNoAnimation = false;
245         mKeepCurTransition = false;
246         mAvoidMoveToFront = false;
247
248         mVoiceSession = null;
249         mVoiceInteractor = null;
250
251         mUsingVr2dDisplay = false;
252
253         mIntentDelivered = false;
254     }
255
256     ActivityStarter(ActivityManagerService service, ActivityStackSupervisor supervisor) {
257         mService = service;
258         mSupervisor = supervisor;
259         mInterceptor = new ActivityStartInterceptor(mService, mSupervisor);
260         mUsingVr2dDisplay = false;
261     }
262
263     int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
264             String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
265             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
266             IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
267             String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
268             ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
269             ActivityRecord[] outActivity, TaskRecord inTask, String reason) {
270
271         if (TextUtils.isEmpty(reason)) {
272             throw new IllegalArgumentException("Need to specify a reason.");
273         }
274         mLastStartReason = reason;
275         mLastStartActivityTimeMs = System.currentTimeMillis();
276         mLastStartActivityRecord[0] = null;
277
278         mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
279                 aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
280                 callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
281                 options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
282                 inTask);
283
284         if (outActivity != null) {
285             // mLastStartActivityRecord[0] is set in the call to startActivity above.
286             outActivity[0] = mLastStartActivityRecord[0];
287         }
288
289         // Aborted results are treated as successes externally, but we must track them internally.
290         return mLastStartActivityResult != START_ABORTED ? mLastStartActivityResult : START_SUCCESS;
291     }
292
293     /** DO NOT call this method directly. Use {@link #startActivityLocked} instead. */
294     private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
295             String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
296             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
297             IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
298             String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
299             ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
300             ActivityRecord[] outActivity, TaskRecord inTask) {
301         int err = ActivityManager.START_SUCCESS;
302         // Pull the optional Ephemeral Installer-only bundle out of the options early.
303         final Bundle verificationBundle
304                 = options != null ? options.popAppVerificationBundle() : null;
305
306         ProcessRecord callerApp = null;
307         if (caller != null) {
308             callerApp = mService.getRecordForAppLocked(caller);
309             if (callerApp != null) {
310                 callingPid = callerApp.pid;
311                 callingUid = callerApp.info.uid;
312             } else {
313                 Slog.w(TAG, "Unable to find app for caller " + caller
314                         + " (pid=" + callingPid + ") when starting: "
315                         + intent.toString());
316                 err = ActivityManager.START_PERMISSION_DENIED;
317             }
318         }
319
320         final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
321
322         if (err == ActivityManager.START_SUCCESS) {
323             Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
324                     + "} from uid " + callingUid);
325         }
326
327         ActivityRecord sourceRecord = null;
328         ActivityRecord resultRecord = null;
329         if (resultTo != null) {
330             sourceRecord = mSupervisor.isInAnyStackLocked(resultTo);
331             if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
332                     "Will send result to " + resultTo + " " + sourceRecord);
333             if (sourceRecord != null) {
334                 if (requestCode >= 0 && !sourceRecord.finishing) {
335                     resultRecord = sourceRecord;
336                 }
337             }
338         }
339
340         final int launchFlags = intent.getFlags();
341
342         if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
343             // Transfer the result target from the source activity to the new
344             // one being started, including any failures.
345             if (requestCode >= 0) {
346                 ActivityOptions.abort(options);
347                 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
348             }
349             resultRecord = sourceRecord.resultTo;
350             if (resultRecord != null && !resultRecord.isInStackLocked()) {
351                 resultRecord = null;
352             }
353             resultWho = sourceRecord.resultWho;
354             requestCode = sourceRecord.requestCode;
355             sourceRecord.resultTo = null;
356             if (resultRecord != null) {
357                 resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
358             }
359             if (sourceRecord.launchedFromUid == callingUid) {
360                 // The new activity is being launched from the same uid as the previous
361                 // activity in the flow, and asking to forward its result back to the
362                 // previous.  In this case the activity is serving as a trampoline between
363                 // the two, so we also want to update its launchedFromPackage to be the
364                 // same as the previous activity.  Note that this is safe, since we know
365                 // these two packages come from the same uid; the caller could just as
366                 // well have supplied that same package name itself.  This specifially
367                 // deals with the case of an intent picker/chooser being launched in the app
368                 // flow to redirect to an activity picked by the user, where we want the final
369                 // activity to consider it to have been launched by the previous app activity.
370                 callingPackage = sourceRecord.launchedFromPackage;
371             }
372         }
373
374         if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
375             // We couldn't find a class that can handle the given Intent.
376             // That's the end of that!
377             err = ActivityManager.START_INTENT_NOT_RESOLVED;
378         }
379
380         if (err == ActivityManager.START_SUCCESS && aInfo == null) {
381             // We couldn't find the specific class specified in the Intent.
382             // Also the end of the line.
383             err = ActivityManager.START_CLASS_NOT_FOUND;
384         }
385
386         if (err == ActivityManager.START_SUCCESS && sourceRecord != null
387                 && sourceRecord.getTask().voiceSession != null) {
388             // If this activity is being launched as part of a voice session, we need
389             // to ensure that it is safe to do so.  If the upcoming activity will also
390             // be part of the voice session, we can only launch it if it has explicitly
391             // said it supports the VOICE category, or it is a part of the calling app.
392             if ((launchFlags & FLAG_ACTIVITY_NEW_TASK) == 0
393                     && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
394                 try {
395                     intent.addCategory(Intent.CATEGORY_VOICE);
396                     if (!AppGlobals.getPackageManager().activitySupportsIntent(
397                             intent.getComponent(), intent, resolvedType)) {
398                         Slog.w(TAG,
399                                 "Activity being started in current voice task does not support voice: "
400                                         + intent);
401                         err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
402                     }
403                 } catch (RemoteException e) {
404                     Slog.w(TAG, "Failure checking voice capabilities", e);
405                     err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
406                 }
407             }
408         }
409
410         if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
411             // If the caller is starting a new voice session, just make sure the target
412             // is actually allowing it to run this way.
413             try {
414                 if (!AppGlobals.getPackageManager().activitySupportsIntent(intent.getComponent(),
415                         intent, resolvedType)) {
416                     Slog.w(TAG,
417                             "Activity being started in new voice task does not support: "
418                                     + intent);
419                     err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
420                 }
421             } catch (RemoteException e) {
422                 Slog.w(TAG, "Failure checking voice capabilities", e);
423                 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
424             }
425         }
426
427         final ActivityStack resultStack = resultRecord == null ? null : resultRecord.getStack();
428
429         if (err != START_SUCCESS) {
430             if (resultRecord != null) {
431                 resultStack.sendActivityResultLocked(
432                         -1, resultRecord, resultWho, requestCode, RESULT_CANCELED, null);
433             }
434             ActivityOptions.abort(options);
435             return err;
436         }
437
438         boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
439                 requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity, callerApp,
440                 resultRecord, resultStack, options);
441         abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
442                 callingPid, resolvedType, aInfo.applicationInfo);
443
444         if (mService.mController != null) {
445             try {
446                 // The Intent we give to the watcher has the extra data
447                 // stripped off, since it can contain private information.
448                 Intent watchIntent = intent.cloneFilter();
449                 abort |= !mService.mController.activityStarting(watchIntent,
450                         aInfo.applicationInfo.packageName);
451             } catch (RemoteException e) {
452                 mService.mController = null;
453             }
454         }
455
456         mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage);
457         mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid, callingUid,
458                 options);
459         intent = mInterceptor.mIntent;
460         rInfo = mInterceptor.mRInfo;
461         aInfo = mInterceptor.mAInfo;
462         resolvedType = mInterceptor.mResolvedType;
463         inTask = mInterceptor.mInTask;
464         callingPid = mInterceptor.mCallingPid;
465         callingUid = mInterceptor.mCallingUid;
466         options = mInterceptor.mActivityOptions;
467         if (abort) {
468             if (resultRecord != null) {
469                 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
470                         RESULT_CANCELED, null);
471             }
472             // We pretend to the caller that it was really started, but
473             // they will just get a cancel result.
474             ActivityOptions.abort(options);
475             return START_ABORTED;
476         }
477
478         // If permissions need a review before any of the app components can run, we
479         // launch the review activity and pass a pending intent to start the activity
480         // we are to launching now after the review is completed.
481         if (mService.mPermissionReviewRequired && aInfo != null) {
482             if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
483                     aInfo.packageName, userId)) {
484                 IIntentSender target = mService.getIntentSenderLocked(
485                         ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
486                         callingUid, userId, null, null, 0, new Intent[]{intent},
487                         new String[]{resolvedType}, PendingIntent.FLAG_CANCEL_CURRENT
488                                 | PendingIntent.FLAG_ONE_SHOT, null);
489
490                 final int flags = intent.getFlags();
491                 Intent newIntent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
492                 newIntent.setFlags(flags
493                         | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
494                 newIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, aInfo.packageName);
495                 newIntent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target));
496                 if (resultRecord != null) {
497                     newIntent.putExtra(Intent.EXTRA_RESULT_NEEDED, true);
498                 }
499                 intent = newIntent;
500
501                 resolvedType = null;
502                 callingUid = realCallingUid;
503                 callingPid = realCallingPid;
504
505                 rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
506                 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
507                         null /*profilerInfo*/);
508
509                 if (DEBUG_PERMISSIONS_REVIEW) {
510                     Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true,
511                             true, false) + "} from uid " + callingUid + " on display "
512                             + (mSupervisor.mFocusedStack == null
513                             ? DEFAULT_DISPLAY : mSupervisor.mFocusedStack.mDisplayId));
514                 }
515             }
516         }
517
518         // If we have an ephemeral app, abort the process of launching the resolved intent.
519         // Instead, launch the ephemeral installer. Once the installer is finished, it
520         // starts either the intent we resolved here [on install error] or the ephemeral
521         // app [on install success].
522         if (rInfo != null && rInfo.auxiliaryInfo != null) {
523             intent = createLaunchIntent(rInfo.auxiliaryInfo, ephemeralIntent,
524                     callingPackage, verificationBundle, resolvedType, userId);
525             resolvedType = null;
526             callingUid = realCallingUid;
527             callingPid = realCallingPid;
528
529             aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
530         }
531
532         ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
533                 callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
534                 resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
535                 mSupervisor, options, sourceRecord);
536         if (outActivity != null) {
537             outActivity[0] = r;
538         }
539
540         if (r.appTimeTracker == null && sourceRecord != null) {
541             // If the caller didn't specify an explicit time tracker, we want to continue
542             // tracking under any it has.
543             r.appTimeTracker = sourceRecord.appTimeTracker;
544         }
545
546         final ActivityStack stack = mSupervisor.mFocusedStack;
547         if (voiceSession == null && (stack.mResumedActivity == null
548                 || stack.mResumedActivity.info.applicationInfo.uid != callingUid)) {
549             if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
550                     realCallingPid, realCallingUid, "Activity start")) {
551                 PendingActivityLaunch pal =  new PendingActivityLaunch(r,
552                         sourceRecord, startFlags, stack, callerApp);
553                 mPendingActivityLaunches.add(pal);
554                 ActivityOptions.abort(options);
555                 return ActivityManager.START_SWITCHES_CANCELED;
556             }
557         }
558
559         if (mService.mDidAppSwitch) {
560             // This is the second allowed switch since we stopped switches,
561             // so now just generally allow switches.  Use case: user presses
562             // home (switches disabled, switch to home, mDidAppSwitch now true);
563             // user taps a home icon (coming from home so allowed, we hit here
564             // and now allow anyone to switch again).
565             mService.mAppSwitchesAllowedTime = 0;
566         } else {
567             mService.mDidAppSwitch = true;
568         }
569
570         doPendingActivityLaunchesLocked(false);
571
572         return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
573                 options, inTask, outActivity);
574     }
575
576     /**
577      * Creates a launch intent for the given auxiliary resolution data.
578      */
579     private @NonNull Intent createLaunchIntent(@NonNull AuxiliaryResolveInfo auxiliaryResponse,
580             Intent originalIntent, String callingPackage, Bundle verificationBundle,
581             String resolvedType, int userId) {
582         if (auxiliaryResponse.needsPhaseTwo) {
583             // request phase two resolution
584             mService.getPackageManagerInternalLocked().requestInstantAppResolutionPhaseTwo(
585                     auxiliaryResponse, originalIntent, resolvedType, callingPackage,
586                     verificationBundle, userId);
587         }
588         return InstantAppResolver.buildEphemeralInstallerIntent(
589                 Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE, originalIntent,
590                 auxiliaryResponse.failureIntent, callingPackage, verificationBundle,
591                 resolvedType, userId, auxiliaryResponse.packageName, auxiliaryResponse.splitName,
592                 auxiliaryResponse.installFailureActivity, auxiliaryResponse.versionCode,
593                 auxiliaryResponse.token, auxiliaryResponse.needsPhaseTwo);
594     }
595
596     void postStartActivityProcessing(
597             ActivityRecord r, int result, int prevFocusedStackId, ActivityRecord sourceRecord,
598             ActivityStack targetStack) {
599
600         if (ActivityManager.isStartResultFatalError(result)) {
601             return;
602         }
603
604         // We're waiting for an activity launch to finish, but that activity simply
605         // brought another activity to front. Let startActivityMayWait() know about
606         // this, so it waits for the new activity to become visible instead.
607         if (result == START_TASK_TO_FRONT && !mSupervisor.mWaitingActivityLaunched.isEmpty()) {
608             mSupervisor.reportTaskToFrontNoLaunch(mStartActivity);
609         }
610
611         int startedActivityStackId = INVALID_STACK_ID;
612         final ActivityStack currentStack = r.getStack();
613         if (currentStack != null) {
614             startedActivityStackId = currentStack.mStackId;
615         } else if (mTargetStack != null) {
616             startedActivityStackId = targetStack.mStackId;
617         }
618
619         if (startedActivityStackId == DOCKED_STACK_ID) {
620             final ActivityStack homeStack = mSupervisor.getStack(HOME_STACK_ID);
621             final boolean homeStackVisible = homeStack != null && homeStack.isVisible();
622             if (homeStackVisible) {
623                 // We launch an activity while being in home stack, which means either launcher or
624                 // recents into docked stack. We don't want the launched activity to be alone in a
625                 // docked stack, so we want to immediately launch recents too.
626                 if (DEBUG_RECENTS) Slog.d(TAG, "Scheduling recents launch.");
627                 mWindowManager.showRecentApps(true /* fromHome */);
628             }
629             return;
630         }
631
632         boolean clearedTask = (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
633                 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK) && (mReuseTask != null);
634         if (startedActivityStackId == PINNED_STACK_ID && (result == START_TASK_TO_FRONT
635                 || result == START_DELIVERED_TO_TOP || clearedTask)) {
636             // The activity was already running in the pinned stack so it wasn't started, but either
637             // brought to the front or the new intent was delivered to it since it was already in
638             // front. Notify anyone interested in this piece of information.
639             mService.mTaskChangeNotificationController.notifyPinnedActivityRestartAttempt(
640                     clearedTask);
641             return;
642         }
643     }
644
645     void startHomeActivityLocked(Intent intent, ActivityInfo aInfo, String reason) {
646         mSupervisor.moveHomeStackTaskToTop(reason);
647         mLastHomeActivityStartResult = startActivityLocked(null /*caller*/, intent,
648                 null /*ephemeralIntent*/, null /*resolvedType*/, aInfo, null /*rInfo*/,
649                 null /*voiceSession*/, null /*voiceInteractor*/, null /*resultTo*/,
650                 null /*resultWho*/, 0 /*requestCode*/, 0 /*callingPid*/, 0 /*callingUid*/,
651                 null /*callingPackage*/, 0 /*realCallingPid*/, 0 /*realCallingUid*/,
652                 0 /*startFlags*/, null /*options*/, false /*ignoreTargetSecurity*/,
653                 false /*componentSpecified*/, mLastHomeActivityStartRecord /*outActivity*/,
654                 null /*inTask*/, "startHomeActivity: " + reason);
655         if (mSupervisor.inResumeTopActivity) {
656             // If we are in resume section already, home activity will be initialized, but not
657             // resumed (to avoid recursive resume) and will stay that way until something pokes it
658             // again. We need to schedule another resume.
659             mSupervisor.scheduleResumeTopActivities();
660         }
661     }
662
663     void startConfirmCredentialIntent(Intent intent, Bundle optionsBundle) {
664         intent.addFlags(FLAG_ACTIVITY_NEW_TASK |
665                 FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
666                 FLAG_ACTIVITY_TASK_ON_HOME);
667         ActivityOptions options = (optionsBundle != null ? new ActivityOptions(optionsBundle)
668                         : ActivityOptions.makeBasic());
669         options.setLaunchTaskId(mSupervisor.getHomeActivity().getTask().taskId);
670         mService.mContext.startActivityAsUser(intent, options.toBundle(), UserHandle.CURRENT);
671     }
672
673     final int startActivityMayWait(IApplicationThread caller, int callingUid,
674             String callingPackage, Intent intent, String resolvedType,
675             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
676             IBinder resultTo, String resultWho, int requestCode, int startFlags,
677             ProfilerInfo profilerInfo, WaitResult outResult,
678             Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId,
679             TaskRecord inTask, String reason) {
680         // Refuse possible leaked file descriptors
681         if (intent != null && intent.hasFileDescriptors()) {
682             throw new IllegalArgumentException("File descriptors passed in Intent");
683         }
684         mSupervisor.mActivityMetricsLogger.notifyActivityLaunching();
685         boolean componentSpecified = intent.getComponent() != null;
686
687         // Save a copy in case ephemeral needs it
688         final Intent ephemeralIntent = new Intent(intent);
689         // Don't modify the client's object!
690         intent = new Intent(intent);
691         if (componentSpecified
692                 && intent.getData() != null
693                 && Intent.ACTION_VIEW.equals(intent.getAction())
694                 && mService.getPackageManagerInternalLocked()
695                         .isInstantAppInstallerComponent(intent.getComponent())) {
696             // intercept intents targeted directly to the ephemeral installer the
697             // ephemeral installer should never be started with a raw URL; instead
698             // adjust the intent so it looks like a "normal" instant app launch
699             intent.setComponent(null /*component*/);
700             componentSpecified = false;
701         }
702
703         ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
704         if (rInfo == null) {
705             UserInfo userInfo = mSupervisor.getUserInfo(userId);
706             if (userInfo != null && userInfo.isManagedProfile()) {
707                 // Special case for managed profiles, if attempting to launch non-cryto aware
708                 // app in a locked managed profile from an unlocked parent allow it to resolve
709                 // as user will be sent via confirm credentials to unlock the profile.
710                 UserManager userManager = UserManager.get(mService.mContext);
711                 boolean profileLockedAndParentUnlockingOrUnlocked = false;
712                 long token = Binder.clearCallingIdentity();
713                 try {
714                     UserInfo parent = userManager.getProfileParent(userId);
715                     profileLockedAndParentUnlockingOrUnlocked = (parent != null)
716                             && userManager.isUserUnlockingOrUnlocked(parent.id)
717                             && !userManager.isUserUnlockingOrUnlocked(userId);
718                 } finally {
719                     Binder.restoreCallingIdentity(token);
720                 }
721                 if (profileLockedAndParentUnlockingOrUnlocked) {
722                     rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
723                             PackageManager.MATCH_DIRECT_BOOT_AWARE
724                                     | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
725                 }
726             }
727         }
728         // Collect information about the target of the Intent.
729         ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
730
731         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
732         synchronized (mService) {
733             final int realCallingPid = Binder.getCallingPid();
734             final int realCallingUid = Binder.getCallingUid();
735             int callingPid;
736             if (callingUid >= 0) {
737                 callingPid = -1;
738             } else if (caller == null) {
739                 callingPid = realCallingPid;
740                 callingUid = realCallingUid;
741             } else {
742                 callingPid = callingUid = -1;
743             }
744
745             final ActivityStack stack = mSupervisor.mFocusedStack;
746             stack.mConfigWillChange = globalConfig != null
747                     && mService.getGlobalConfiguration().diff(globalConfig) != 0;
748             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
749                     "Starting activity when config will change = " + stack.mConfigWillChange);
750
751             final long origId = Binder.clearCallingIdentity();
752
753             if (aInfo != null &&
754                     (aInfo.applicationInfo.privateFlags
755                             & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
756                 // This may be a heavy-weight process!  Check to see if we already
757                 // have another, different heavy-weight process running.
758                 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
759                     final ProcessRecord heavy = mService.mHeavyWeightProcess;
760                     if (heavy != null && (heavy.info.uid != aInfo.applicationInfo.uid
761                             || !heavy.processName.equals(aInfo.processName))) {
762                         int appCallingUid = callingUid;
763                         if (caller != null) {
764                             ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
765                             if (callerApp != null) {
766                                 appCallingUid = callerApp.info.uid;
767                             } else {
768                                 Slog.w(TAG, "Unable to find app for caller " + caller
769                                         + " (pid=" + callingPid + ") when starting: "
770                                         + intent.toString());
771                                 ActivityOptions.abort(options);
772                                 return ActivityManager.START_PERMISSION_DENIED;
773                             }
774                         }
775
776                         IIntentSender target = mService.getIntentSenderLocked(
777                                 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
778                                 appCallingUid, userId, null, null, 0, new Intent[] { intent },
779                                 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
780                                         | PendingIntent.FLAG_ONE_SHOT, null);
781
782                         Intent newIntent = new Intent();
783                         if (requestCode >= 0) {
784                             // Caller is requesting a result.
785                             newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
786                         }
787                         newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
788                                 new IntentSender(target));
789                         if (heavy.activities.size() > 0) {
790                             ActivityRecord hist = heavy.activities.get(0);
791                             newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
792                                     hist.packageName);
793                             newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
794                                     hist.getTask().taskId);
795                         }
796                         newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
797                                 aInfo.packageName);
798                         newIntent.setFlags(intent.getFlags());
799                         newIntent.setClassName("android",
800                                 HeavyWeightSwitcherActivity.class.getName());
801                         intent = newIntent;
802                         resolvedType = null;
803                         caller = null;
804                         callingUid = Binder.getCallingUid();
805                         callingPid = Binder.getCallingPid();
806                         componentSpecified = true;
807                         rInfo = mSupervisor.resolveIntent(intent, null /*resolvedType*/, userId);
808                         aInfo = rInfo != null ? rInfo.activityInfo : null;
809                         if (aInfo != null) {
810                             aInfo = mService.getActivityInfoForUser(aInfo, userId);
811                         }
812                     }
813                 }
814             }
815
816             final ActivityRecord[] outRecord = new ActivityRecord[1];
817             int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
818                     aInfo, rInfo, voiceSession, voiceInteractor,
819                     resultTo, resultWho, requestCode, callingPid,
820                     callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
821                     options, ignoreTargetSecurity, componentSpecified, outRecord, inTask,
822                     reason);
823
824             Binder.restoreCallingIdentity(origId);
825
826             if (stack.mConfigWillChange) {
827                 // If the caller also wants to switch to a new configuration,
828                 // do so now.  This allows a clean switch, as we are waiting
829                 // for the current activity to pause (so we will not destroy
830                 // it), and have not yet started the next activity.
831                 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
832                         "updateConfiguration()");
833                 stack.mConfigWillChange = false;
834                 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
835                         "Updating to new configuration after starting activity.");
836                 mService.updateConfigurationLocked(globalConfig, null, false);
837             }
838
839             if (outResult != null) {
840                 outResult.result = res;
841                 if (res == ActivityManager.START_SUCCESS) {
842                     mSupervisor.mWaitingActivityLaunched.add(outResult);
843                     do {
844                         try {
845                             mService.wait();
846                         } catch (InterruptedException e) {
847                         }
848                     } while (outResult.result != START_TASK_TO_FRONT
849                             && !outResult.timeout && outResult.who == null);
850                     if (outResult.result == START_TASK_TO_FRONT) {
851                         res = START_TASK_TO_FRONT;
852                     }
853                 }
854                 if (res == START_TASK_TO_FRONT) {
855                     final ActivityRecord r = outRecord[0];
856
857                     // ActivityRecord may represent a different activity, but it should not be in
858                     // the resumed state.
859                     if (r.nowVisible && r.state == RESUMED) {
860                         outResult.timeout = false;
861                         outResult.who = r.realActivity;
862                         outResult.totalTime = 0;
863                         outResult.thisTime = 0;
864                     } else {
865                         outResult.thisTime = SystemClock.uptimeMillis();
866                         mSupervisor.waitActivityVisible(r.realActivity, outResult);
867                         // Note: the timeout variable is not currently not ever set.
868                         do {
869                             try {
870                                 mService.wait();
871                             } catch (InterruptedException e) {
872                             }
873                         } while (!outResult.timeout && outResult.who == null);
874                     }
875                 }
876             }
877
878             mSupervisor.mActivityMetricsLogger.notifyActivityLaunched(res, outRecord[0]);
879             return res;
880         }
881     }
882
883     final int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
884             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
885             Bundle bOptions, int userId, String reason) {
886         if (intents == null) {
887             throw new NullPointerException("intents is null");
888         }
889         if (resolvedTypes == null) {
890             throw new NullPointerException("resolvedTypes is null");
891         }
892         if (intents.length != resolvedTypes.length) {
893             throw new IllegalArgumentException("intents are length different than resolvedTypes");
894         }
895
896         final int realCallingPid = Binder.getCallingPid();
897         final int realCallingUid = Binder.getCallingUid();
898
899         int callingPid;
900         if (callingUid >= 0) {
901             callingPid = -1;
902         } else if (caller == null) {
903             callingPid = realCallingPid;
904             callingUid = realCallingUid;
905         } else {
906             callingPid = callingUid = -1;
907         }
908         final long origId = Binder.clearCallingIdentity();
909         try {
910             synchronized (mService) {
911                 ActivityRecord[] outActivity = new ActivityRecord[1];
912                 for (int i=0; i<intents.length; i++) {
913                     Intent intent = intents[i];
914                     if (intent == null) {
915                         continue;
916                     }
917
918                     // Refuse possible leaked file descriptors
919                     if (intent != null && intent.hasFileDescriptors()) {
920                         throw new IllegalArgumentException("File descriptors passed in Intent");
921                     }
922
923                     boolean componentSpecified = intent.getComponent() != null;
924
925                     // Don't modify the client's object!
926                     intent = new Intent(intent);
927
928                     // Collect information about the target of the Intent.
929                     ActivityInfo aInfo = mSupervisor.resolveActivity(intent, resolvedTypes[i], 0,
930                             null, userId);
931                     // TODO: New, check if this is correct
932                     aInfo = mService.getActivityInfoForUser(aInfo, userId);
933
934                     if (aInfo != null &&
935                             (aInfo.applicationInfo.privateFlags
936                                     & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE)  != 0) {
937                         throw new IllegalArgumentException(
938                                 "FLAG_CANT_SAVE_STATE not supported here");
939                     }
940
941                     ActivityOptions options = ActivityOptions.fromBundle(
942                             i == intents.length - 1 ? bOptions : null);
943                     int res = startActivityLocked(caller, intent, null /*ephemeralIntent*/,
944                             resolvedTypes[i], aInfo, null /*rInfo*/, null, null, resultTo, null, -1,
945                             callingPid, callingUid, callingPackage,
946                             realCallingPid, realCallingUid, 0,
947                             options, false, componentSpecified, outActivity, null, reason);
948                     if (res < 0) {
949                         return res;
950                     }
951
952                     resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
953                 }
954             }
955         } finally {
956             Binder.restoreCallingIdentity(origId);
957         }
958
959         return START_SUCCESS;
960     }
961
962     void sendPowerHintForLaunchStartIfNeeded(boolean forceSend, ActivityRecord targetActivity) {
963         boolean sendHint = forceSend;
964
965         if (!sendHint) {
966             // If not forced, send power hint when the activity's process is different than the
967             // current resumed activity.
968             final ActivityRecord resumedActivity = mSupervisor.getResumedActivityLocked();
969             sendHint = resumedActivity == null
970                 || resumedActivity.app == null
971                 || !resumedActivity.app.equals(targetActivity.app);
972         }
973
974         if (sendHint && mService.mLocalPowerManager != null) {
975             mService.mLocalPowerManager.powerHint(PowerHint.LAUNCH, 1);
976             mPowerHintSent = true;
977         }
978     }
979
980     void sendPowerHintForLaunchEndIfNeeded() {
981         // Trigger launch power hint if activity is launched
982         if (mPowerHintSent && mService.mLocalPowerManager != null) {
983             mService.mLocalPowerManager.powerHint(PowerHint.LAUNCH, 0);
984             mPowerHintSent = false;
985         }
986     }
987
988     private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
989             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
990             int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
991             ActivityRecord[] outActivity) {
992         int result = START_CANCELED;
993         try {
994             mService.mWindowManager.deferSurfaceLayout();
995             result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
996                     startFlags, doResume, options, inTask, outActivity);
997         } finally {
998             // If we are not able to proceed, disassociate the activity from the task. Leaving an
999             // activity in an incomplete state can lead to issues, such as performing operations
1000             // without a window container.
1001             if (!ActivityManager.isStartResultSuccessful(result)
1002                     && mStartActivity.getTask() != null) {
1003                 mStartActivity.getTask().removeActivity(mStartActivity);
1004             }
1005             mService.mWindowManager.continueSurfaceLayout();
1006         }
1007
1008         postStartActivityProcessing(r, result, mSupervisor.getLastStack().mStackId,  mSourceRecord,
1009                 mTargetStack);
1010
1011         return result;
1012     }
1013
1014     // Note: This method should only be called from {@link startActivity}.
1015     private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
1016             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1017             int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
1018             ActivityRecord[] outActivity) {
1019
1020         setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
1021                 voiceInteractor);
1022
1023         computeLaunchingTaskFlags();
1024
1025         computeSourceStack();
1026
1027         mIntent.setFlags(mLaunchFlags);
1028
1029         ActivityRecord reusedActivity = getReusableIntentActivity();
1030
1031         final int preferredLaunchStackId =
1032                 (mOptions != null) ? mOptions.getLaunchStackId() : INVALID_STACK_ID;
1033         final int preferredLaunchDisplayId =
1034                 (mOptions != null) ? mOptions.getLaunchDisplayId() : DEFAULT_DISPLAY;
1035
1036         if (reusedActivity != null) {
1037             // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but
1038             // still needs to be a lock task mode violation since the task gets cleared out and
1039             // the device would otherwise leave the locked task.
1040             if (mSupervisor.isLockTaskModeViolation(reusedActivity.getTask(),
1041                     (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1042                             == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
1043                 mSupervisor.showLockTaskToast();
1044                 Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
1045                 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
1046             }
1047
1048             if (mStartActivity.getTask() == null) {
1049                 mStartActivity.setTask(reusedActivity.getTask());
1050             }
1051             if (reusedActivity.getTask().intent == null) {
1052                 // This task was started because of movement of the activity based on affinity...
1053                 // Now that we are actually launching it, we can assign the base intent.
1054                 reusedActivity.getTask().setIntent(mStartActivity);
1055             }
1056
1057             // This code path leads to delivering a new intent, we want to make sure we schedule it
1058             // as the first operation, in case the activity will be resumed as a result of later
1059             // operations.
1060             if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
1061                     || isDocumentLaunchesIntoExisting(mLaunchFlags)
1062                     || mLaunchSingleInstance || mLaunchSingleTask) {
1063                 final TaskRecord task = reusedActivity.getTask();
1064
1065                 // In this situation we want to remove all activities from the task up to the one
1066                 // being started. In most cases this means we are resetting the task to its initial
1067                 // state.
1068                 final ActivityRecord top = task.performClearTaskForReuseLocked(mStartActivity,
1069                         mLaunchFlags);
1070
1071                 // The above code can remove {@code reusedActivity} from the task, leading to the
1072                 // the {@code ActivityRecord} removing its reference to the {@code TaskRecord}. The
1073                 // task reference is needed in the call below to
1074                 // {@link setTargetStackAndMoveToFrontIfNeeded}.
1075                 if (reusedActivity.getTask() == null) {
1076                     reusedActivity.setTask(task);
1077                 }
1078
1079                 if (top != null) {
1080                     if (top.frontOfTask) {
1081                         // Activity aliases may mean we use different intents for the top activity,
1082                         // so make sure the task now has the identity of the new intent.
1083                         top.getTask().setIntent(mStartActivity);
1084                     }
1085                     deliverNewIntent(top);
1086                 }
1087             }
1088
1089             sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, reusedActivity);
1090
1091             reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);
1092
1093             final ActivityRecord outResult =
1094                     outActivity != null && outActivity.length > 0 ? outActivity[0] : null;
1095
1096             // When there is a reused activity and the current result is a trampoline activity,
1097             // set the reused activity as the result.
1098             if (outResult != null && (outResult.finishing || outResult.noDisplay)) {
1099                 outActivity[0] = reusedActivity;
1100             }
1101
1102             if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1103                 // We don't need to start a new activity, and the client said not to do anything
1104                 // if that is the case, so this is it!  And for paranoia, make sure we have
1105                 // correctly resumed the top activity.
1106                 resumeTargetStackIfNeeded();
1107                 return START_RETURN_INTENT_TO_CALLER;
1108             }
1109             setTaskFromIntentActivity(reusedActivity);
1110
1111             if (!mAddingToTask && mReuseTask == null) {
1112                 // We didn't do anything...  but it was needed (a.k.a., client don't use that
1113                 // intent!)  And for paranoia, make sure we have correctly resumed the top activity.
1114                 resumeTargetStackIfNeeded();
1115                 if (outActivity != null && outActivity.length > 0) {
1116                     outActivity[0] = reusedActivity;
1117                 }
1118
1119                 return START_TASK_TO_FRONT;
1120             }
1121         }
1122
1123         if (mStartActivity.packageName == null) {
1124             final ActivityStack sourceStack = mStartActivity.resultTo != null
1125                     ? mStartActivity.resultTo.getStack() : null;
1126             if (sourceStack != null) {
1127                 sourceStack.sendActivityResultLocked(-1 /* callingUid */, mStartActivity.resultTo,
1128                         mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,
1129                         null /* data */);
1130             }
1131             ActivityOptions.abort(mOptions);
1132             return START_CLASS_NOT_FOUND;
1133         }
1134
1135         // If the activity being launched is the same as the one currently at the top, then
1136         // we need to check if it should only be launched once.
1137         final ActivityStack topStack = mSupervisor.mFocusedStack;
1138         final ActivityRecord topFocused = topStack.topActivity();
1139         final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
1140         final boolean dontStart = top != null && mStartActivity.resultTo == null
1141                 && top.realActivity.equals(mStartActivity.realActivity)
1142                 && top.userId == mStartActivity.userId
1143                 && top.app != null && top.app.thread != null
1144                 && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
1145                 || mLaunchSingleTop || mLaunchSingleTask);
1146         if (dontStart) {
1147             // For paranoia, make sure we have correctly resumed the top activity.
1148             topStack.mLastPausedActivity = null;
1149             if (mDoResume) {
1150                 mSupervisor.resumeFocusedStackTopActivityLocked();
1151             }
1152             ActivityOptions.abort(mOptions);
1153             if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1154                 // We don't need to start a new activity, and the client said not to do
1155                 // anything if that is the case, so this is it!
1156                 return START_RETURN_INTENT_TO_CALLER;
1157             }
1158
1159             deliverNewIntent(top);
1160
1161             // Don't use mStartActivity.task to show the toast. We're not starting a new activity
1162             // but reusing 'top'. Fields in mStartActivity may not be fully initialized.
1163             mSupervisor.handleNonResizableTaskIfNeeded(top.getTask(), preferredLaunchStackId,
1164                     preferredLaunchDisplayId, topStack.mStackId);
1165
1166             return START_DELIVERED_TO_TOP;
1167         }
1168
1169         boolean newTask = false;
1170         final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
1171                 ? mSourceRecord.getTask() : null;
1172
1173         // Should this be considered a new task?
1174         int result = START_SUCCESS;
1175         if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
1176                 && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1177             newTask = true;
1178             result = setTaskFromReuseOrCreateNewTask(
1179                     taskToAffiliate, preferredLaunchStackId, topStack);
1180         } else if (mSourceRecord != null) {
1181             result = setTaskFromSourceRecord();
1182         } else if (mInTask != null) {
1183             result = setTaskFromInTask();
1184         } else {
1185             // This not being started from an existing activity, and not part of a new task...
1186             // just put it in the top task, though these days this case should never happen.
1187             setTaskToCurrentTopOrCreateNewTask();
1188         }
1189         if (result != START_SUCCESS) {
1190             return result;
1191         }
1192
1193         mService.grantUriPermissionFromIntentLocked(mCallingUid, mStartActivity.packageName,
1194                 mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.userId);
1195         mService.grantEphemeralAccessLocked(mStartActivity.userId, mIntent,
1196                 mStartActivity.appInfo.uid, UserHandle.getAppId(mCallingUid));
1197         if (mSourceRecord != null) {
1198             mStartActivity.getTask().setTaskToReturnTo(mSourceRecord);
1199         }
1200         if (newTask) {
1201             EventLog.writeEvent(
1202                     EventLogTags.AM_CREATE_TASK, mStartActivity.userId,
1203                     mStartActivity.getTask().taskId);
1204         }
1205         ActivityStack.logStartActivity(
1206                 EventLogTags.AM_CREATE_ACTIVITY, mStartActivity, mStartActivity.getTask());
1207         mTargetStack.mLastPausedActivity = null;
1208
1209         sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, mStartActivity);
1210
1211         mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
1212                 mOptions);
1213         if (mDoResume) {
1214             final ActivityRecord topTaskActivity =
1215                     mStartActivity.getTask().topRunningActivityLocked();
1216             if (!mTargetStack.isFocusable()
1217                     || (topTaskActivity != null && topTaskActivity.mTaskOverlay
1218                     && mStartActivity != topTaskActivity)) {
1219                 // If the activity is not focusable, we can't resume it, but still would like to
1220                 // make sure it becomes visible as it starts (this will also trigger entry
1221                 // animation). An example of this are PIP activities.
1222                 // Also, we don't want to resume activities in a task that currently has an overlay
1223                 // as the starting activity just needs to be in the visible paused state until the
1224                 // over is removed.
1225                 mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
1226                 // Go ahead and tell window manager to execute app transition for this activity
1227                 // since the app transition will not be triggered through the resume channel.
1228                 mWindowManager.executeAppTransition();
1229             } else {
1230                 // If the target stack was not previously focusable (previous top running activity
1231                 // on that stack was not visible) then any prior calls to move the stack to the
1232                 // will not update the focused stack.  If starting the new activity now allows the
1233                 // task stack to be focusable, then ensure that we now update the focused stack
1234                 // accordingly.
1235                 if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
1236                     mTargetStack.moveToFront("startActivityUnchecked");
1237                 }
1238                 mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
1239                         mOptions);
1240             }
1241         } else {
1242             mTargetStack.addRecentActivityLocked(mStartActivity);
1243         }
1244         mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);
1245
1246         mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(), preferredLaunchStackId,
1247                 preferredLaunchDisplayId, mTargetStack.mStackId);
1248
1249         return START_SUCCESS;
1250     }
1251
1252     private void setInitialState(ActivityRecord r, ActivityOptions options, TaskRecord inTask,
1253             boolean doResume, int startFlags, ActivityRecord sourceRecord,
1254             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
1255         reset();
1256
1257         mStartActivity = r;
1258         mIntent = r.intent;
1259         mOptions = options;
1260         mCallingUid = r.launchedFromUid;
1261         mSourceRecord = sourceRecord;
1262         mVoiceSession = voiceSession;
1263         mVoiceInteractor = voiceInteractor;
1264
1265         mSourceDisplayId = getSourceDisplayId(mSourceRecord, mStartActivity);
1266
1267         mLaunchBounds = getOverrideBounds(r, options, inTask);
1268
1269         mLaunchSingleTop = r.launchMode == LAUNCH_SINGLE_TOP;
1270         mLaunchSingleInstance = r.launchMode == LAUNCH_SINGLE_INSTANCE;
1271         mLaunchSingleTask = r.launchMode == LAUNCH_SINGLE_TASK;
1272         mLaunchFlags = adjustLaunchFlagsToDocumentMode(
1273                 r, mLaunchSingleInstance, mLaunchSingleTask, mIntent.getFlags());
1274         mLaunchTaskBehind = r.mLaunchTaskBehind
1275                 && !mLaunchSingleTask && !mLaunchSingleInstance
1276                 && (mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0;
1277
1278         sendNewTaskResultRequestIfNeeded();
1279
1280         if ((mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
1281             mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1282         }
1283
1284         // If we are actually going to launch in to a new task, there are some cases where
1285         // we further want to do multiple task.
1286         if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1287             if (mLaunchTaskBehind
1288                     || r.info.documentLaunchMode == DOCUMENT_LAUNCH_ALWAYS) {
1289                 mLaunchFlags |= FLAG_ACTIVITY_MULTIPLE_TASK;
1290             }
1291         }
1292
1293         // We'll invoke onUserLeaving before onPause only if the launching
1294         // activity did not explicitly state that this is an automated launch.
1295         mSupervisor.mUserLeaving = (mLaunchFlags & FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1296         if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
1297                 "startActivity() => mUserLeaving=" + mSupervisor.mUserLeaving);
1298
1299         // If the caller has asked not to resume at this point, we make note
1300         // of this in the record so that we can skip it when trying to find
1301         // the top running activity.
1302         mDoResume = doResume;
1303         if (!doResume || !r.okToShowLocked()) {
1304             r.delayedResume = true;
1305             mDoResume = false;
1306         }
1307
1308         if (mOptions != null && mOptions.getLaunchTaskId() != -1
1309                 && mOptions.getTaskOverlay()) {
1310             r.mTaskOverlay = true;
1311             if (!mOptions.canTaskOverlayResume()) {
1312                 final TaskRecord task = mSupervisor.anyTaskForIdLocked(mOptions.getLaunchTaskId());
1313                 final ActivityRecord top = task != null ? task.getTopActivity() : null;
1314                 if (top != null && top.state != RESUMED) {
1315
1316                     // The caller specifies that we'd like to be avoided to be moved to the front,
1317                     // so be it!
1318                     mDoResume = false;
1319                     mAvoidMoveToFront = true;
1320                 }
1321             }
1322         }
1323
1324         mNotTop = (mLaunchFlags & FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1325
1326         mInTask = inTask;
1327         // In some flows in to this function, we retrieve the task record and hold on to it
1328         // without a lock before calling back in to here...  so the task at this point may
1329         // not actually be in recents.  Check for that, and if it isn't in recents just
1330         // consider it invalid.
1331         if (inTask != null && !inTask.inRecents) {
1332             Slog.w(TAG, "Starting activity in task not in recents: " + inTask);
1333             mInTask = null;
1334         }
1335
1336         mStartFlags = startFlags;
1337         // If the onlyIfNeeded flag is set, then we can do this if the activity being launched
1338         // is the same as the one making the call...  or, as a special case, if we do not know
1339         // the caller then we count the current top activity as the caller.
1340         if ((startFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1341             ActivityRecord checkedCaller = sourceRecord;
1342             if (checkedCaller == null) {
1343                 checkedCaller = mSupervisor.mFocusedStack.topRunningNonDelayedActivityLocked(
1344                         mNotTop);
1345             }
1346             if (!checkedCaller.realActivity.equals(r.realActivity)) {
1347                 // Caller is not the same as launcher, so always needed.
1348                 mStartFlags &= ~START_FLAG_ONLY_IF_NEEDED;
1349             }
1350         }
1351
1352         mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0;
1353     }
1354
1355     private void sendNewTaskResultRequestIfNeeded() {
1356         final ActivityStack sourceStack = mStartActivity.resultTo != null
1357                 ? mStartActivity.resultTo.getStack() : null;
1358         if (sourceStack != null && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1359             // For whatever reason this activity is being launched into a new task...
1360             // yet the caller has requested a result back.  Well, that is pretty messed up,
1361             // so instead immediately send back a cancel and let the new task continue launched
1362             // as normal without a dependency on its originator.
1363             Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1364             sourceStack.sendActivityResultLocked(-1 /* callingUid */, mStartActivity.resultTo,
1365                     mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,
1366                     null /* data */);
1367             mStartActivity.resultTo = null;
1368         }
1369     }
1370
1371     private void computeLaunchingTaskFlags() {
1372         // If the caller is not coming from another activity, but has given us an explicit task into
1373         // which they would like us to launch the new activity, then let's see about doing that.
1374         if (mSourceRecord == null && mInTask != null && mInTask.getStack() != null) {
1375             final Intent baseIntent = mInTask.getBaseIntent();
1376             final ActivityRecord root = mInTask.getRootActivity();
1377             if (baseIntent == null) {
1378                 ActivityOptions.abort(mOptions);
1379                 throw new IllegalArgumentException("Launching into task without base intent: "
1380                         + mInTask);
1381             }
1382
1383             // If this task is empty, then we are adding the first activity -- it
1384             // determines the root, and must be launching as a NEW_TASK.
1385             if (mLaunchSingleInstance || mLaunchSingleTask) {
1386                 if (!baseIntent.getComponent().equals(mStartActivity.intent.getComponent())) {
1387                     ActivityOptions.abort(mOptions);
1388                     throw new IllegalArgumentException("Trying to launch singleInstance/Task "
1389                             + mStartActivity + " into different task " + mInTask);
1390                 }
1391                 if (root != null) {
1392                     ActivityOptions.abort(mOptions);
1393                     throw new IllegalArgumentException("Caller with mInTask " + mInTask
1394                             + " has root " + root + " but target is singleInstance/Task");
1395                 }
1396             }
1397
1398             // If task is empty, then adopt the interesting intent launch flags in to the
1399             // activity being started.
1400             if (root == null) {
1401                 final int flagsOfInterest = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK
1402                         | FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS;
1403                 mLaunchFlags = (mLaunchFlags & ~flagsOfInterest)
1404                         | (baseIntent.getFlags() & flagsOfInterest);
1405                 mIntent.setFlags(mLaunchFlags);
1406                 mInTask.setIntent(mStartActivity);
1407                 mAddingToTask = true;
1408
1409                 // If the task is not empty and the caller is asking to start it as the root of
1410                 // a new task, then we don't actually want to start this on the task. We will
1411                 // bring the task to the front, and possibly give it a new intent.
1412             } else if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1413                 mAddingToTask = false;
1414
1415             } else {
1416                 mAddingToTask = true;
1417             }
1418
1419             mReuseTask = mInTask;
1420         } else {
1421             mInTask = null;
1422             // Launch ResolverActivity in the source task, so that it stays in the task bounds
1423             // when in freeform workspace.
1424             // Also put noDisplay activities in the source task. These by itself can be placed
1425             // in any task/stack, however it could launch other activities like ResolverActivity,
1426             // and we want those to stay in the original task.
1427             if ((mStartActivity.isResolverActivity() || mStartActivity.noDisplay) && mSourceRecord != null
1428                     && mSourceRecord.isFreeform())  {
1429                 mAddingToTask = true;
1430             }
1431         }
1432
1433         if (mInTask == null) {
1434             if (mSourceRecord == null) {
1435                 // This activity is not being started from another...  in this
1436                 // case we -always- start a new task.
1437                 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) {
1438                     Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1439                             "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
1440                     mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1441                 }
1442             } else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) {
1443                 // The original activity who is starting us is running as a single
1444                 // instance...  this new activity it is starting must go on its
1445                 // own task.
1446                 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1447             } else if (mLaunchSingleInstance || mLaunchSingleTask) {
1448                 // The activity being started is a single instance...  it always
1449                 // gets launched into its own task.
1450                 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1451             }
1452         }
1453     }
1454
1455     private void computeSourceStack() {
1456         if (mSourceRecord == null) {
1457             mSourceStack = null;
1458             return;
1459         }
1460         if (!mSourceRecord.finishing) {
1461             mSourceStack = mSourceRecord.getStack();
1462             return;
1463         }
1464
1465         // If the source is finishing, we can't further count it as our source. This is because the
1466         // task it is associated with may now be empty and on its way out, so we don't want to
1467         // blindly throw it in to that task.  Instead we will take the NEW_TASK flow and try to find
1468         // a task for it. But save the task information so it can be used when creating the new task.
1469         if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0) {
1470             Slog.w(TAG, "startActivity called from finishing " + mSourceRecord
1471                     + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
1472             mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1473             mNewTaskInfo = mSourceRecord.info;
1474
1475             // It is not guaranteed that the source record will have a task associated with it. For,
1476             // example, if this method is being called for processing a pending activity launch, it
1477             // is possible that the activity has been removed from the task after the launch was
1478             // enqueued.
1479             final TaskRecord sourceTask = mSourceRecord.getTask();
1480             mNewTaskIntent = sourceTask != null ? sourceTask.intent : null;
1481         }
1482         mSourceRecord = null;
1483         mSourceStack = null;
1484     }
1485
1486     /**
1487      * Decide whether the new activity should be inserted into an existing task. Returns null
1488      * if not or an ActivityRecord with the task into which the new activity should be added.
1489      */
1490     private ActivityRecord getReusableIntentActivity() {
1491         // We may want to try to place the new activity in to an existing task.  We always
1492         // do this if the target activity is singleTask or singleInstance; we will also do
1493         // this if NEW_TASK has been requested, and there is not an additional qualifier telling
1494         // us to still place it in a new task: multi task, always doc mode, or being asked to
1495         // launch this as a new task behind the current one.
1496         boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 &&
1497                 (mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1498                 || mLaunchSingleInstance || mLaunchSingleTask;
1499         // If bring to front is requested, and no result is requested and we have not been given
1500         // an explicit task to launch in to, and we can find a task that was started with this
1501         // same component, then instead of launching bring that one to the front.
1502         putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null;
1503         ActivityRecord intentActivity = null;
1504         if (mOptions != null && mOptions.getLaunchTaskId() != -1) {
1505             final TaskRecord task = mSupervisor.anyTaskForIdLocked(mOptions.getLaunchTaskId());
1506             intentActivity = task != null ? task.getTopActivity() : null;
1507         } else if (putIntoExistingTask) {
1508             if (mLaunchSingleInstance) {
1509                 // There can be one and only one instance of single instance activity in the
1510                 // history, and it is always in its own unique task, so we do a special search.
1511                intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info,
1512                        mStartActivity.isHomeActivity());
1513             } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
1514                 // For the launch adjacent case we only want to put the activity in an existing
1515                 // task if the activity already exists in the history.
1516                 intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info,
1517                         !mLaunchSingleTask);
1518             } else {
1519                 // Otherwise find the best task to put the activity in.
1520                 intentActivity = mSupervisor.findTaskLocked(mStartActivity, mSourceDisplayId);
1521             }
1522         }
1523         return intentActivity;
1524     }
1525
1526     /**
1527      * Returns the ID of the display to use for a new activity. If the device is in VR mode,
1528      * then return the Vr mode's virtual display ID. If not, if the source activity has
1529      * a explicit display ID set, use that to launch the activity.
1530      */
1531     private int getSourceDisplayId(ActivityRecord sourceRecord, ActivityRecord startingActivity) {
1532         // Check if the Activity is a VR activity. If so, the activity should be launched in
1533         // main display.
1534         if (startingActivity != null && startingActivity.requestedVrComponent != null) {
1535             return DEFAULT_DISPLAY;
1536         }
1537
1538         // Get the virtual display id from ActivityManagerService.
1539         int displayId = mService.mVr2dDisplayId;
1540         if (displayId != INVALID_DISPLAY) {
1541             if (DEBUG_STACK) {
1542                 Slog.d(TAG, "getSourceDisplayId :" + displayId);
1543             }
1544             mUsingVr2dDisplay = true;
1545             return displayId;
1546         }
1547
1548         displayId = sourceRecord != null ? sourceRecord.getDisplayId() : INVALID_DISPLAY;
1549         // If the activity has a displayId set explicitly, launch it on the same displayId.
1550         if (displayId != INVALID_DISPLAY) {
1551             return displayId;
1552         }
1553         return DEFAULT_DISPLAY;
1554     }
1555
1556     /**
1557      * Figure out which task and activity to bring to front when we have found an existing matching
1558      * activity record in history. May also clear the task if needed.
1559      * @param intentActivity Existing matching activity.
1560      * @return {@link ActivityRecord} brought to front.
1561      */
1562     private ActivityRecord setTargetStackAndMoveToFrontIfNeeded(ActivityRecord intentActivity) {
1563         mTargetStack = intentActivity.getStack();
1564         mTargetStack.mLastPausedActivity = null;
1565         // If the target task is not in the front, then we need to bring it to the front...
1566         // except...  well, with SINGLE_TASK_LAUNCH it's not entirely clear. We'd like to have
1567         // the same behavior as if a new instance was being started, which means not bringing it
1568         // to the front if the caller is not itself in the front.
1569         final ActivityStack focusStack = mSupervisor.getFocusedStack();
1570         ActivityRecord curTop = (focusStack == null)
1571                 ? null : focusStack.topRunningNonDelayedActivityLocked(mNotTop);
1572
1573         final TaskRecord topTask = curTop != null ? curTop.getTask() : null;
1574         if (topTask != null
1575                 && (topTask != intentActivity.getTask() || topTask != focusStack.topTask())
1576                 && !mAvoidMoveToFront) {
1577             mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
1578             if (mSourceRecord == null || (mSourceStack.topActivity() != null &&
1579                     mSourceStack.topActivity().getTask() == mSourceRecord.getTask())) {
1580                 // We really do want to push this one into the user's face, right now.
1581                 if (mLaunchTaskBehind && mSourceRecord != null) {
1582                     intentActivity.setTaskToAffiliateWith(mSourceRecord.getTask());
1583                 }
1584                 mMovedOtherTask = true;
1585
1586                 // If the launch flags carry both NEW_TASK and CLEAR_TASK, the task's activities
1587                 // will be cleared soon by ActivityStarter in setTaskFromIntentActivity().
1588                 // So no point resuming any of the activities here, it just wastes one extra
1589                 // resuming, plus enter AND exit transitions.
1590                 // Here we only want to bring the target stack forward. Transition will be applied
1591                 // to the new activity that's started after the old ones are gone.
1592                 final boolean willClearTask =
1593                         (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1594                             == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
1595                 if (!willClearTask) {
1596                     final ActivityStack launchStack = getLaunchStack(
1597                             mStartActivity, mLaunchFlags, mStartActivity.getTask(), mOptions);
1598                     final TaskRecord intentTask = intentActivity.getTask();
1599                     if (launchStack == null || launchStack == mTargetStack) {
1600                         // We only want to move to the front, if we aren't going to launch on a
1601                         // different stack. If we launch on a different stack, we will put the
1602                         // task on top there.
1603                         mTargetStack.moveTaskToFrontLocked(intentTask, mNoAnimation, mOptions,
1604                                 mStartActivity.appTimeTracker, "bringingFoundTaskToFront");
1605                         mMovedToFront = true;
1606                     } else if (launchStack.mStackId == DOCKED_STACK_ID
1607                             || launchStack.mStackId == FULLSCREEN_WORKSPACE_STACK_ID) {
1608                         if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
1609                             // If we want to launch adjacent and mTargetStack is not the computed
1610                             // launch stack - move task to top of computed stack.
1611                             intentTask.reparent(launchStack.mStackId, ON_TOP,
1612                                     REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
1613                                     "launchToSide");
1614                         } else {
1615                             // TODO: This should be reevaluated in MW v2.
1616                             // We choose to move task to front instead of launching it adjacent
1617                             // when specific stack was requested explicitly and it appeared to be
1618                             // adjacent stack, but FLAG_ACTIVITY_LAUNCH_ADJACENT was not set.
1619                             mTargetStack.moveTaskToFrontLocked(intentTask,
1620                                     mNoAnimation, mOptions, mStartActivity.appTimeTracker,
1621                                     "bringToFrontInsteadOfAdjacentLaunch");
1622                         }
1623                         mMovedToFront = true;
1624                     } else if (launchStack.mDisplayId != mTargetStack.mDisplayId) {
1625                         // Target and computed stacks are on different displays and we've
1626                         // found a matching task - move the existing instance to that display and
1627                         // move it to front.
1628                         intentActivity.getTask().reparent(launchStack.mStackId, ON_TOP,
1629                                 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
1630                                 "reparentToDisplay");
1631                         mMovedToFront = true;
1632                     } else if (launchStack.getStackId() == StackId.HOME_STACK_ID
1633                         && mTargetStack.getStackId() != StackId.HOME_STACK_ID) {
1634                         // It is possible for the home activity to be in another stack initially.
1635                         // For example, the activity may have been initially started with an intent
1636                         // which placed it in the fullscreen stack. To ensure the proper handling of
1637                         // the activity based on home stack assumptions, we must move it over.
1638                         intentActivity.getTask().reparent(launchStack.mStackId, ON_TOP,
1639                                 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
1640                                 "reparentingHome");
1641                         mMovedToFront = true;
1642                     }
1643                     mOptions = null;
1644
1645                     // We are moving a task to the front, use starting window to hide initial drawn
1646                     // delay.
1647                     intentActivity.showStartingWindow(null /* prev */, false /* newTask */,
1648                             true /* taskSwitch */);
1649                 }
1650                 updateTaskReturnToType(intentActivity.getTask(), mLaunchFlags, focusStack);
1651             }
1652         }
1653         if (!mMovedToFront && mDoResume) {
1654             if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Bring to front target: " + mTargetStack
1655                     + " from " + intentActivity);
1656             mTargetStack.moveToFront("intentActivityFound");
1657         }
1658
1659         mSupervisor.handleNonResizableTaskIfNeeded(intentActivity.getTask(), INVALID_STACK_ID,
1660                 DEFAULT_DISPLAY, mTargetStack.mStackId);
1661
1662         // If the caller has requested that the target task be reset, then do so.
1663         if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1664             return mTargetStack.resetTaskIfNeededLocked(intentActivity, mStartActivity);
1665         }
1666         return intentActivity;
1667     }
1668
1669     private void updateTaskReturnToType(
1670             TaskRecord task, int launchFlags, ActivityStack focusedStack) {
1671         if ((launchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1672                 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
1673             // Caller wants to appear on home activity.
1674             task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
1675             return;
1676         } else if (focusedStack == null || focusedStack.isHomeStack()) {
1677             // Task will be launched over the home stack, so return home.
1678             task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
1679             return;
1680         } else if (focusedStack != null && focusedStack != task.getStack() &&
1681                 focusedStack.isAssistantStack()) {
1682             // Task was launched over the assistant stack, so return there
1683             task.setTaskToReturnTo(ASSISTANT_ACTIVITY_TYPE);
1684             return;
1685         }
1686
1687         // Else we are coming from an application stack so return to an application.
1688         task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
1689     }
1690
1691     private void setTaskFromIntentActivity(ActivityRecord intentActivity) {
1692         if ((mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1693                 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {
1694             // The caller has requested to completely replace any existing task with its new
1695             // activity. Well that should not be too hard...
1696             // Note: we must persist the {@link TaskRecord} first as intentActivity could be
1697             // removed from calling performClearTaskLocked (For example, if it is being brought out
1698             // of history or if it is finished immediately), thus disassociating the task. Also note
1699             // that mReuseTask is reset as a result of {@link TaskRecord#performClearTaskLocked}
1700             // launching another activity.
1701             // TODO(b/36119896):  We shouldn't trigger activity launches in this path since we are
1702             // already launching one.
1703             final TaskRecord task = intentActivity.getTask();
1704             task.performClearTaskLocked();
1705             mReuseTask = task;
1706             mReuseTask.setIntent(mStartActivity);
1707
1708             // When we clear the task - focus will be adjusted, which will bring another task
1709             // to top before we launch the activity we need. This will temporary swap their
1710             // mTaskToReturnTo values and we don't want to overwrite them accidentally.
1711             mMovedOtherTask = true;
1712         } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
1713                 || mLaunchSingleInstance || mLaunchSingleTask) {
1714             ActivityRecord top = intentActivity.getTask().performClearTaskLocked(mStartActivity,
1715                     mLaunchFlags);
1716             if (top == null) {
1717                 // A special case: we need to start the activity because it is not currently
1718                 // running, and the caller has asked to clear the current task to have this
1719                 // activity at the top.
1720                 mAddingToTask = true;
1721
1722                 // We are no longer placing the activity in the task we previously thought we were.
1723                 mStartActivity.setTask(null);
1724                 // Now pretend like this activity is being started by the top of its task, so it
1725                 // is put in the right place.
1726                 mSourceRecord = intentActivity;
1727                 final TaskRecord task = mSourceRecord.getTask();
1728                 if (task != null && task.getStack() == null) {
1729                     // Target stack got cleared when we all activities were removed above.
1730                     // Go ahead and reset it.
1731                     mTargetStack = computeStackFocus(mSourceRecord, false /* newTask */,
1732                             null /* bounds */, mLaunchFlags, mOptions);
1733                     mTargetStack.addTask(task,
1734                             !mLaunchTaskBehind /* toTop */, "startActivityUnchecked");
1735                 }
1736             }
1737         } else if (mStartActivity.realActivity.equals(intentActivity.getTask().realActivity)) {
1738             // In this case the top activity on the task is the same as the one being launched,
1739             // so we take that as a request to bring the task to the foreground. If the top
1740             // activity in the task is the root activity, deliver this new intent to it if it
1741             // desires.
1742             if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0 || mLaunchSingleTop)
1743                     && intentActivity.realActivity.equals(mStartActivity.realActivity)) {
1744                 if (intentActivity.frontOfTask) {
1745                     intentActivity.getTask().setIntent(mStartActivity);
1746                 }
1747                 deliverNewIntent(intentActivity);
1748             } else if (!intentActivity.getTask().isSameIntentFilter(mStartActivity)) {
1749                 // In this case we are launching the root activity of the task, but with a
1750                 // different intent. We should start a new instance on top.
1751                 mAddingToTask = true;
1752                 mSourceRecord = intentActivity;
1753             }
1754         } else if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1755             // In this case an activity is being launched in to an existing task, without
1756             // resetting that task. This is typically the situation of launching an activity
1757             // from a notification or shortcut. We want to place the new activity on top of the
1758             // current task.
1759             mAddingToTask = true;
1760             mSourceRecord = intentActivity;
1761         } else if (!intentActivity.getTask().rootWasReset) {
1762             // In this case we are launching into an existing task that has not yet been started
1763             // from its front door. The current task has been brought to the front. Ideally,
1764             // we'd probably like to place this new task at the bottom of its stack, but that's
1765             // a little hard to do with the current organization of the code so for now we'll
1766             // just drop it.
1767             intentActivity.getTask().setIntent(mStartActivity);
1768         }
1769     }
1770
1771     private void resumeTargetStackIfNeeded() {
1772         if (mDoResume) {
1773             mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, null, mOptions);
1774         } else {
1775             ActivityOptions.abort(mOptions);
1776         }
1777         mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);
1778     }
1779
1780     private int setTaskFromReuseOrCreateNewTask(
1781             TaskRecord taskToAffiliate, int preferredLaunchStackId, ActivityStack topStack) {
1782         mTargetStack = computeStackFocus(
1783                 mStartActivity, true, mLaunchBounds, mLaunchFlags, mOptions);
1784
1785         // Do no move the target stack to front yet, as we might bail if
1786         // isLockTaskModeViolation fails below.
1787
1788         if (mReuseTask == null) {
1789             final TaskRecord task = mTargetStack.createTaskRecord(
1790                     mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId),
1791                     mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
1792                     mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
1793                     mVoiceInteractor, !mLaunchTaskBehind /* toTop */, mStartActivity.mActivityType);
1794             addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
1795             if (mLaunchBounds != null) {
1796                 final int stackId = mTargetStack.mStackId;
1797                 if (StackId.resizeStackWithLaunchBounds(stackId)) {
1798                     mService.resizeStack(
1799                             stackId, mLaunchBounds, true, !PRESERVE_WINDOWS, ANIMATE, -1);
1800                 } else {
1801                     mStartActivity.getTask().updateOverrideConfiguration(mLaunchBounds);
1802                 }
1803             }
1804             if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
1805                     + " in new task " + mStartActivity.getTask());
1806         } else {
1807             addOrReparentStartingActivity(mReuseTask, "setTaskFromReuseOrCreateNewTask");
1808         }
1809
1810         if (taskToAffiliate != null) {
1811             mStartActivity.setTaskToAffiliateWith(taskToAffiliate);
1812         }
1813
1814         if (mSupervisor.isLockTaskModeViolation(mStartActivity.getTask())) {
1815             Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
1816             return START_RETURN_LOCK_TASK_MODE_VIOLATION;
1817         }
1818
1819         if (!mMovedOtherTask) {
1820             // If stack id is specified in activity options, usually it means that activity is
1821             // launched not from currently focused stack (e.g. from SysUI or from shell) - in
1822             // that case we check the target stack.
1823             updateTaskReturnToType(mStartActivity.getTask(), mLaunchFlags,
1824                     preferredLaunchStackId != INVALID_STACK_ID ? mTargetStack : topStack);
1825         }
1826         if (mDoResume) {
1827             mTargetStack.moveToFront("reuseOrNewTask");
1828         }
1829         return START_SUCCESS;
1830     }
1831
1832     private void deliverNewIntent(ActivityRecord activity) {
1833         if (mIntentDelivered) {
1834             return;
1835         }
1836
1837         ActivityStack.logStartActivity(AM_NEW_INTENT, activity, activity.getTask());
1838         activity.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
1839                 mStartActivity.launchedFromPackage);
1840         mIntentDelivered = true;
1841     }
1842
1843     private int setTaskFromSourceRecord() {
1844         if (mSupervisor.isLockTaskModeViolation(mSourceRecord.getTask())) {
1845             Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
1846             return START_RETURN_LOCK_TASK_MODE_VIOLATION;
1847         }
1848
1849         final TaskRecord sourceTask = mSourceRecord.getTask();
1850         final ActivityStack sourceStack = mSourceRecord.getStack();
1851         // We only want to allow changing stack in two cases:
1852         // 1. If the target task is not the top one. Otherwise we would move the launching task to
1853         //    the other side, rather than show two side by side.
1854         // 2. If activity is not allowed on target display.
1855         final int targetDisplayId = mTargetStack != null ? mTargetStack.mDisplayId
1856                 : sourceStack.mDisplayId;
1857         final boolean moveStackAllowed = sourceStack.topTask() != sourceTask
1858                 || !mStartActivity.canBeLaunchedOnDisplay(targetDisplayId);
1859         if (moveStackAllowed) {
1860             mTargetStack = getLaunchStack(mStartActivity, mLaunchFlags, mStartActivity.getTask(),
1861                     mOptions);
1862             // If target stack is not found now - we can't just rely on the source stack, as it may
1863             // be not suitable. Let's check other displays.
1864             if (mTargetStack == null && targetDisplayId != sourceStack.mDisplayId) {
1865                 // Can't use target display, lets find a stack on the source display.
1866                 mTargetStack = mService.mStackSupervisor.getValidLaunchStackOnDisplay(
1867                         sourceStack.mDisplayId, mStartActivity);
1868             }
1869             if (mTargetStack == null) {
1870                 // There are no suitable stacks on the target and source display(s). Look on all
1871                 // displays.
1872                 mTargetStack = mService.mStackSupervisor.getNextValidLaunchStackLocked(
1873                         mStartActivity, -1 /* currentFocus */);
1874             }
1875         }
1876
1877         if (mTargetStack == null) {
1878             mTargetStack = sourceStack;
1879         } else if (mTargetStack != sourceStack) {
1880             sourceTask.reparent(mTargetStack.mStackId, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT,
1881                     !ANIMATE, DEFER_RESUME, "launchToSide");
1882         }
1883
1884         final TaskRecord topTask = mTargetStack.topTask();
1885         if (topTask != sourceTask && !mAvoidMoveToFront) {
1886             mTargetStack.moveTaskToFrontLocked(sourceTask, mNoAnimation, mOptions,
1887                     mStartActivity.appTimeTracker, "sourceTaskToFront");
1888         } else if (mDoResume) {
1889             mTargetStack.moveToFront("sourceStackToFront");
1890         }
1891
1892         if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1893             // In this case, we are adding the activity to an existing task, but the caller has
1894             // asked to clear that task if the activity is already running.
1895             ActivityRecord top = sourceTask.performClearTaskLocked(mStartActivity, mLaunchFlags);
1896             mKeepCurTransition = true;
1897             if (top != null) {
1898                 ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, top.getTask());
1899                 deliverNewIntent(top);
1900                 // For paranoia, make sure we have correctly resumed the top activity.
1901                 mTargetStack.mLastPausedActivity = null;
1902                 if (mDoResume) {
1903                     mSupervisor.resumeFocusedStackTopActivityLocked();
1904                 }
1905                 ActivityOptions.abort(mOptions);
1906                 return START_DELIVERED_TO_TOP;
1907             }
1908         } else if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1909             // In this case, we are launching an activity in our own task that may already be
1910             // running somewhere in the history, and we want to shuffle it to the front of the
1911             // stack if so.
1912             final ActivityRecord top = sourceTask.findActivityInHistoryLocked(mStartActivity);
1913             if (top != null) {
1914                 final TaskRecord task = top.getTask();
1915                 task.moveActivityToFrontLocked(top);
1916                 top.updateOptionsLocked(mOptions);
1917                 ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, task);
1918                 deliverNewIntent(top);
1919                 mTargetStack.mLastPausedActivity = null;
1920                 if (mDoResume) {
1921                     mSupervisor.resumeFocusedStackTopActivityLocked();
1922                 }
1923                 return START_DELIVERED_TO_TOP;
1924             }
1925         }
1926
1927         // An existing activity is starting this new activity, so we want to keep the new one in
1928         // the same task as the one that is starting it.
1929         addOrReparentStartingActivity(sourceTask, "setTaskFromSourceRecord");
1930         if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
1931                 + " in existing task " + mStartActivity.getTask() + " from source " + mSourceRecord);
1932         return START_SUCCESS;
1933     }
1934
1935     private int setTaskFromInTask() {
1936         // The caller is asking that the new activity be started in an explicit
1937         // task it has provided to us.
1938         if (mSupervisor.isLockTaskModeViolation(mInTask)) {
1939             Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
1940             return START_RETURN_LOCK_TASK_MODE_VIOLATION;
1941         }
1942
1943         mTargetStack = mInTask.getStack();
1944
1945         // Check whether we should actually launch the new activity in to the task,
1946         // or just reuse the current activity on top.
1947         ActivityRecord top = mInTask.getTopActivity();
1948         if (top != null && top.realActivity.equals(mStartActivity.realActivity)
1949                 && top.userId == mStartActivity.userId) {
1950             if ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
1951                     || mLaunchSingleTop || mLaunchSingleTask) {
1952                 mTargetStack.moveTaskToFrontLocked(mInTask, mNoAnimation, mOptions,
1953                         mStartActivity.appTimeTracker, "inTaskToFront");
1954                 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1955                     // We don't need to start a new activity, and the client said not to do
1956                     // anything if that is the case, so this is it!
1957                     return START_RETURN_INTENT_TO_CALLER;
1958                 }
1959                 deliverNewIntent(top);
1960                 return START_DELIVERED_TO_TOP;
1961             }
1962         }
1963
1964         if (!mAddingToTask) {
1965             mTargetStack.moveTaskToFrontLocked(mInTask, mNoAnimation, mOptions,
1966                     mStartActivity.appTimeTracker, "inTaskToFront");
1967             // We don't actually want to have this activity added to the task, so just
1968             // stop here but still tell the caller that we consumed the intent.
1969             ActivityOptions.abort(mOptions);
1970             return START_TASK_TO_FRONT;
1971         }
1972
1973         if (mLaunchBounds != null) {
1974             mInTask.updateOverrideConfiguration(mLaunchBounds);
1975             int stackId = mInTask.getLaunchStackId();
1976             if (stackId != mInTask.getStackId()) {
1977                 mInTask.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, !ANIMATE,
1978                         DEFER_RESUME, "inTaskToFront");
1979                 stackId = mInTask.getStackId();
1980                 mTargetStack = mInTask.getStack();
1981             }
1982             if (StackId.resizeStackWithLaunchBounds(stackId)) {
1983                 mService.resizeStack(stackId, mLaunchBounds, true, !PRESERVE_WINDOWS, ANIMATE, -1);
1984             }
1985         }
1986
1987         mTargetStack.moveTaskToFrontLocked(
1988                 mInTask, mNoAnimation, mOptions, mStartActivity.appTimeTracker, "inTaskToFront");
1989
1990         addOrReparentStartingActivity(mInTask, "setTaskFromInTask");
1991         if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
1992                 + " in explicit task " + mStartActivity.getTask());
1993
1994         return START_SUCCESS;
1995     }
1996
1997     private void setTaskToCurrentTopOrCreateNewTask() {
1998         mTargetStack = computeStackFocus(mStartActivity, false, null /* bounds */, mLaunchFlags,
1999                 mOptions);
2000         if (mDoResume) {
2001             mTargetStack.moveToFront("addingToTopTask");
2002         }
2003         final ActivityRecord prev = mTargetStack.topActivity();
2004         final TaskRecord task = (prev != null) ? prev.getTask() : mTargetStack.createTaskRecord(
2005                 mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId), mStartActivity.info,
2006                 mIntent, null, null, true, mStartActivity.mActivityType);
2007         addOrReparentStartingActivity(task, "setTaskToCurrentTopOrCreateNewTask");
2008         mTargetStack.positionChildWindowContainerAtTop(task);
2009         if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
2010                 + " in new guessed " + mStartActivity.getTask());
2011     }
2012
2013     private void addOrReparentStartingActivity(TaskRecord parent, String reason) {
2014         if (mStartActivity.getTask() == null || mStartActivity.getTask() == parent) {
2015             parent.addActivityToTop(mStartActivity);
2016         } else {
2017             mStartActivity.reparent(parent, parent.mActivities.size() /* top */, reason);
2018         }
2019     }
2020
2021     private int adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance,
2022             boolean launchSingleTask, int launchFlags) {
2023         if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2024                 (launchSingleInstance || launchSingleTask)) {
2025             // We have a conflict between the Intent and the Activity manifest, manifest wins.
2026             Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " +
2027                     "\"singleInstance\" or \"singleTask\"");
2028             launchFlags &=
2029                     ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK);
2030         } else {
2031             switch (r.info.documentLaunchMode) {
2032                 case ActivityInfo.DOCUMENT_LAUNCH_NONE:
2033                     break;
2034                 case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
2035                     launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2036                     break;
2037                 case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
2038                     launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2039                     break;
2040                 case ActivityInfo.DOCUMENT_LAUNCH_NEVER:
2041                     launchFlags &= ~FLAG_ACTIVITY_MULTIPLE_TASK;
2042                     break;
2043             }
2044         }
2045         return launchFlags;
2046     }
2047
2048     final void doPendingActivityLaunchesLocked(boolean doResume) {
2049         while (!mPendingActivityLaunches.isEmpty()) {
2050             final PendingActivityLaunch pal = mPendingActivityLaunches.remove(0);
2051             final boolean resume = doResume && mPendingActivityLaunches.isEmpty();
2052             try {
2053                 startActivity(pal.r, pal.sourceRecord, null, null, pal.startFlags, resume, null,
2054                         null, null /*outRecords*/);
2055             } catch (Exception e) {
2056                 Slog.e(TAG, "Exception during pending activity launch pal=" + pal, e);
2057                 pal.sendErrorResult(e.getMessage());
2058             }
2059         }
2060     }
2061
2062     private ActivityStack computeStackFocus(ActivityRecord r, boolean newTask, Rect bounds,
2063             int launchFlags, ActivityOptions aOptions) {
2064         final TaskRecord task = r.getTask();
2065         ActivityStack stack = getLaunchStack(r, launchFlags, task, aOptions);
2066         if (stack != null) {
2067             return stack;
2068         }
2069
2070         final ActivityStack currentStack = task != null ? task.getStack() : null;
2071         if (currentStack != null) {
2072             if (mSupervisor.mFocusedStack != currentStack) {
2073                 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
2074                         "computeStackFocus: Setting " + "focused stack to r=" + r
2075                                 + " task=" + task);
2076             } else {
2077                 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
2078                         "computeStackFocus: Focused stack already="
2079                                 + mSupervisor.mFocusedStack);
2080             }
2081             return currentStack;
2082         }
2083
2084         if (canLaunchIntoFocusedStack(r, newTask)) {
2085             if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
2086                     "computeStackFocus: Have a focused stack=" + mSupervisor.mFocusedStack);
2087             return mSupervisor.mFocusedStack;
2088         }
2089
2090         if (mSourceDisplayId != DEFAULT_DISPLAY) {
2091             // Try to put the activity in a stack on a secondary display.
2092             stack = mSupervisor.getValidLaunchStackOnDisplay(mSourceDisplayId, r);
2093             if (stack == null) {
2094                 // If source display is not suitable - look for topmost valid stack in the system.
2095                 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
2096                         "computeStackFocus: Can't launch on mSourceDisplayId=" + mSourceDisplayId
2097                                 + ", looking on all displays.");
2098                 stack = mSupervisor.getNextValidLaunchStackLocked(r, mSourceDisplayId);
2099             }
2100         }
2101         if (stack == null) {
2102             // We first try to put the task in the first dynamic stack on home display.
2103             final ArrayList<ActivityStack> homeDisplayStacks = mSupervisor.mHomeStack.mStacks;
2104             for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2105                 stack = homeDisplayStacks.get(stackNdx);
2106                 if (isDynamicStack(stack.mStackId)) {
2107                     if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
2108                             "computeStackFocus: Setting focused stack=" + stack);
2109                     return stack;
2110                 }
2111             }
2112             // If there is no suitable dynamic stack then we figure out which static stack to use.
2113             final int stackId = task != null ? task.getLaunchStackId() :
2114                     bounds != null ? FREEFORM_WORKSPACE_STACK_ID :
2115                             FULLSCREEN_WORKSPACE_STACK_ID;
2116             stack = mSupervisor.getStack(stackId, CREATE_IF_NEEDED, ON_TOP);
2117         }
2118         if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, "computeStackFocus: New stack r="
2119                 + r + " stackId=" + stack.mStackId);
2120         return stack;
2121     }
2122
2123     /** Check if provided activity record can launch in currently focused stack. */
2124     private boolean canLaunchIntoFocusedStack(ActivityRecord r, boolean newTask) {
2125         final ActivityStack focusedStack = mSupervisor.mFocusedStack;
2126         final int focusedStackId = mSupervisor.mFocusedStack.mStackId;
2127         final boolean canUseFocusedStack;
2128         switch (focusedStackId) {
2129             case FULLSCREEN_WORKSPACE_STACK_ID:
2130                 // The fullscreen stack can contain any task regardless of if the task is resizeable
2131                 // or not. So, we let the task go in the fullscreen task if it is the focus stack.
2132                 canUseFocusedStack = true;
2133                 break;
2134             case ASSISTANT_STACK_ID:
2135                 canUseFocusedStack = r.isAssistantActivity();
2136                 break;
2137             case DOCKED_STACK_ID:
2138                 // Any activity which supports split screen can go in the docked stack.
2139                 canUseFocusedStack = r.supportsSplitScreen();
2140                 break;
2141             case FREEFORM_WORKSPACE_STACK_ID:
2142                 // Any activity which supports freeform can go in the freeform stack.
2143                 canUseFocusedStack = r.supportsFreeform();
2144                 break;
2145             default:
2146                 // Dynamic stacks behave similarly to the fullscreen stack and can contain any
2147                 // resizeable task.
2148                 canUseFocusedStack = isDynamicStack(focusedStackId)
2149                         && r.canBeLaunchedOnDisplay(focusedStack.mDisplayId);
2150         }
2151
2152         return canUseFocusedStack && !newTask
2153                 // We strongly prefer to launch activities on the same display as their source.
2154                 && (mSourceDisplayId == focusedStack.mDisplayId);
2155     }
2156
2157     private ActivityStack getLaunchStack(ActivityRecord r, int launchFlags, TaskRecord task,
2158             ActivityOptions aOptions) {
2159         // We are reusing a task, keep the stack!
2160         if (mReuseTask != null) {
2161             return mReuseTask.getStack();
2162         }
2163
2164         // If the activity is of a specific type, return the associated stack, creating it if
2165         // necessary
2166         if (r.isHomeActivity()) {
2167             return mSupervisor.mHomeStack;
2168         }
2169         if (r.isRecentsActivity()) {
2170             return mSupervisor.getStack(RECENTS_STACK_ID, CREATE_IF_NEEDED, ON_TOP);
2171         }
2172         if (r.isAssistantActivity()) {
2173             return mSupervisor.getStack(ASSISTANT_STACK_ID, CREATE_IF_NEEDED, ON_TOP);
2174         }
2175
2176         final int launchDisplayId =
2177                 (aOptions != null) ? aOptions.getLaunchDisplayId() : INVALID_DISPLAY;
2178
2179         final int launchStackId =
2180                 (aOptions != null) ? aOptions.getLaunchStackId() : INVALID_STACK_ID;
2181
2182         if (launchStackId != INVALID_STACK_ID && launchDisplayId != INVALID_DISPLAY) {
2183             throw new IllegalArgumentException(
2184                     "Stack and display id can't be set at the same time.");
2185         }
2186
2187         if (isValidLaunchStackId(launchStackId, launchDisplayId, r)) {
2188             return mSupervisor.getStack(launchStackId, CREATE_IF_NEEDED, ON_TOP);
2189         }
2190         if (launchStackId == DOCKED_STACK_ID) {
2191             // The preferred launch stack is the docked stack, but it isn't a valid launch stack
2192             // for this activity, so we put the activity in the fullscreen stack.
2193             return mSupervisor.getStack(FULLSCREEN_WORKSPACE_STACK_ID, CREATE_IF_NEEDED, ON_TOP);
2194         }
2195         if (launchDisplayId != INVALID_DISPLAY) {
2196             // Stack id has higher priority than display id.
2197             return mSupervisor.getValidLaunchStackOnDisplay(launchDisplayId, r);
2198         }
2199
2200         // If we are using Vr2d display, find the virtual display stack.
2201         if (mUsingVr2dDisplay) {
2202             ActivityStack as = mSupervisor.getValidLaunchStackOnDisplay(mSourceDisplayId, r);
2203             if (DEBUG_STACK) {
2204                 Slog.v(TAG, "Launch stack for app: " + r.toString() +
2205                     ", on virtual display stack:" + as.toString());
2206             }
2207             return as;
2208         }
2209
2210         if (((launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) == 0)
2211                  || mSourceDisplayId != DEFAULT_DISPLAY) {
2212             return null;
2213         }
2214         // Otherwise handle adjacent launch.
2215
2216         // The parent activity doesn't want to launch the activity on top of itself, but
2217         // instead tries to put it onto other side in side-by-side mode.
2218         final ActivityStack parentStack = task != null ? task.getStack(): mSupervisor.mFocusedStack;
2219
2220         if (parentStack != mSupervisor.mFocusedStack) {
2221             // If task's parent stack is not focused - use it during adjacent launch.
2222             return parentStack;
2223         } else {
2224             if (mSupervisor.mFocusedStack != null && task == mSupervisor.mFocusedStack.topTask()) {
2225                 // If task is already on top of focused stack - use it. We don't want to move the
2226                 // existing focused task to adjacent stack, just deliver new intent in this case.
2227                 return mSupervisor.mFocusedStack;
2228             }
2229
2230             if (parentStack != null && parentStack.isDockedStack()) {
2231                 // If parent was in docked stack, the natural place to launch another activity
2232                 // will be fullscreen, so it can appear alongside the docked window.
2233                 return mSupervisor.getStack(FULLSCREEN_WORKSPACE_STACK_ID, CREATE_IF_NEEDED,
2234                         ON_TOP);
2235             } else {
2236                 // If the parent is not in the docked stack, we check if there is docked window
2237                 // and if yes, we will launch into that stack. If not, we just put the new
2238                 // activity into parent's stack, because we can't find a better place.
2239                 final ActivityStack dockedStack = mSupervisor.getStack(DOCKED_STACK_ID);
2240                 if (dockedStack != null
2241                         && dockedStack.shouldBeVisible(r) == STACK_INVISIBLE) {
2242                     // There is a docked stack, but it isn't visible, so we can't launch into that.
2243                     return null;
2244                 } else {
2245                     return dockedStack;
2246                 }
2247             }
2248         }
2249     }
2250
2251     boolean isValidLaunchStackId(int stackId, int displayId, ActivityRecord r) {
2252         switch (stackId) {
2253             case INVALID_STACK_ID:
2254             case HOME_STACK_ID:
2255                 return false;
2256             case FULLSCREEN_WORKSPACE_STACK_ID:
2257                 return true;
2258             case FREEFORM_WORKSPACE_STACK_ID:
2259                 return r.supportsFreeform();
2260             case DOCKED_STACK_ID:
2261                 return r.supportsSplitScreen();
2262             case PINNED_STACK_ID:
2263                 return r.supportsPictureInPicture();
2264             case RECENTS_STACK_ID:
2265                 return r.isRecentsActivity();
2266             case ASSISTANT_STACK_ID:
2267                 return r.isAssistantActivity();
2268             default:
2269                 if (StackId.isDynamicStack(stackId)) {
2270                     return r.canBeLaunchedOnDisplay(displayId);
2271                 }
2272                 Slog.e(TAG, "isValidLaunchStackId: Unexpected stackId=" + stackId);
2273                 return false;
2274         }
2275     }
2276
2277     Rect getOverrideBounds(ActivityRecord r, ActivityOptions options, TaskRecord inTask) {
2278         Rect newBounds = null;
2279         if (options != null && (r.isResizeable() || (inTask != null && inTask.isResizeable()))) {
2280             if (mSupervisor.canUseActivityOptionsLaunchBounds(
2281                     options, options.getLaunchStackId())) {
2282                 newBounds = TaskRecord.validateBounds(options.getLaunchBounds());
2283             }
2284         }
2285         return newBounds;
2286     }
2287
2288     void setWindowManager(WindowManagerService wm) {
2289         mWindowManager = wm;
2290     }
2291
2292     void removePendingActivityLaunchesLocked(ActivityStack stack) {
2293         for (int palNdx = mPendingActivityLaunches.size() - 1; palNdx >= 0; --palNdx) {
2294             PendingActivityLaunch pal = mPendingActivityLaunches.get(palNdx);
2295             if (pal.stack == stack) {
2296                 mPendingActivityLaunches.remove(palNdx);
2297             }
2298         }
2299     }
2300
2301     static boolean isDocumentLaunchesIntoExisting(int flags) {
2302         return (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2303                 (flags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0;
2304     }
2305
2306     boolean clearPendingActivityLaunchesLocked(String packageName) {
2307         boolean didSomething = false;
2308
2309         for (int palNdx = mPendingActivityLaunches.size() - 1; palNdx >= 0; --palNdx) {
2310             PendingActivityLaunch pal = mPendingActivityLaunches.get(palNdx);
2311             ActivityRecord r = pal.r;
2312             if (r != null && r.packageName.equals(packageName)) {
2313                 mPendingActivityLaunches.remove(palNdx);
2314                 didSomething = true;
2315             }
2316         }
2317         return didSomething;
2318     }
2319
2320     void dump(PrintWriter pw, String prefix, String dumpPackage) {
2321         prefix = prefix + "  ";
2322
2323         if (dumpPackage != null) {
2324             if ((mLastStartActivityRecord[0] == null ||
2325                     !dumpPackage.equals(mLastHomeActivityStartRecord[0].packageName)) &&
2326                     (mLastHomeActivityStartRecord[0] == null ||
2327                     !dumpPackage.equals(mLastHomeActivityStartRecord[0].packageName)) &&
2328                     (mStartActivity == null || !dumpPackage.equals(mStartActivity.packageName))) {
2329                 pw.print(prefix);
2330                 pw.println("(nothing)");
2331                 return;
2332             }
2333         }
2334
2335         pw.print(prefix);
2336         pw.print("mCurrentUser=");
2337         pw.println(mSupervisor.mCurrentUser);
2338         pw.print(prefix);
2339         pw.print("mLastStartReason=");
2340         pw.println(mLastStartReason);
2341         pw.print(prefix);
2342         pw.print("mLastStartActivityTimeMs=");
2343         pw.println(DateFormat.getDateTimeInstance().format(new Date(mLastStartActivityTimeMs)));
2344         pw.print(prefix);
2345         pw.print("mLastStartActivityResult=");
2346         pw.println(mLastStartActivityResult);
2347         ActivityRecord r = mLastStartActivityRecord[0];
2348         if (r != null) {
2349             pw.print(prefix);
2350             pw.println("mLastStartActivityRecord:");
2351             r.dump(pw, prefix + "  ");
2352         }
2353         pw.print(prefix);
2354         pw.print("mLastHomeActivityStartResult=");
2355         pw.println(mLastHomeActivityStartResult);
2356         r = mLastHomeActivityStartRecord[0];
2357         if (r != null) {
2358             pw.print(prefix);
2359             pw.println("mLastHomeActivityStartRecord:");
2360             r.dump(pw, prefix + "  ");
2361         }
2362         if (mStartActivity != null) {
2363             pw.print(prefix);
2364             pw.println("mStartActivity:");
2365             mStartActivity.dump(pw, prefix + "  ");
2366         }
2367         if (mIntent != null) {
2368             pw.print(prefix);
2369             pw.print("mIntent=");
2370             pw.println(mIntent);
2371         }
2372         if (mOptions != null) {
2373             pw.print(prefix);
2374             pw.print("mOptions=");
2375             pw.println(mOptions);
2376         }
2377         pw.print(prefix);
2378         pw.print("mLaunchSingleTop=");
2379         pw.print(mLaunchSingleTop);
2380         pw.print(" mLaunchSingleInstance=");
2381         pw.print(mLaunchSingleInstance);
2382         pw.print(" mLaunchSingleTask=");
2383         pw.println(mLaunchSingleTask);
2384         pw.print(prefix);
2385         pw.print("mLaunchFlags=0x");
2386         pw.print(Integer.toHexString(mLaunchFlags));
2387         pw.print(" mDoResume=");
2388         pw.print(mDoResume);
2389         pw.print(" mAddingToTask=");
2390         pw.println(mAddingToTask);
2391     }
2392 }