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