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