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