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