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