ActivityStarter.java revision 14810c7e3e5c8153183e36a819779cff4a979c89
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            mSupervisor.showNonResizeableDockToastIfNeeded(mStartActivity.task,
990                    preferredLaunchStackId, topStack.mStackId);
991            return START_DELIVERED_TO_TOP;
992        }
993
994        boolean newTask = false;
995        final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
996                ? mSourceRecord.task : null;
997
998        // Should this be considered a new task?
999        if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
1000                && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1001            newTask = true;
1002            setTaskFromReuseOrCreateNewTask(taskToAffiliate);
1003
1004            if (mSupervisor.isLockTaskModeViolation(mStartActivity.task)) {
1005                Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
1006                return START_RETURN_LOCK_TASK_MODE_VIOLATION;
1007            }
1008            if (!mMovedHome) {
1009                updateTaskReturnToType(mStartActivity.task, mLaunchFlags, topStack);
1010            }
1011        } else if (mSourceRecord != null) {
1012            if (mSupervisor.isLockTaskModeViolation(mSourceRecord.task)) {
1013                Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
1014                return START_RETURN_LOCK_TASK_MODE_VIOLATION;
1015            }
1016
1017            final int result = setTaskFromSourceRecord();
1018            if (result != START_SUCCESS) {
1019                return result;
1020            }
1021        } else if (mInTask != null) {
1022            // The caller is asking that the new activity be started in an explicit
1023            // task it has provided to us.
1024            if (mSupervisor.isLockTaskModeViolation(mInTask)) {
1025                Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
1026                return START_RETURN_LOCK_TASK_MODE_VIOLATION;
1027            }
1028
1029            final int result = setTaskFromInTask();
1030            if (result != START_SUCCESS) {
1031                return result;
1032            }
1033        } else {
1034            // This not being started from an existing activity, and not part of a new task...
1035            // just put it in the top task, though these days this case should never happen.
1036            setTaskToCurrentTopOrCreateNewTask();
1037        }
1038
1039        mService.grantUriPermissionFromIntentLocked(mCallingUid, mStartActivity.packageName,
1040                mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.userId);
1041
1042        if (mSourceRecord != null && mSourceRecord.isRecentsActivity()) {
1043            mStartActivity.task.setTaskToReturnTo(RECENTS_ACTIVITY_TYPE);
1044        }
1045        if (newTask) {
1046            EventLog.writeEvent(
1047                    EventLogTags.AM_CREATE_TASK, mStartActivity.userId, mStartActivity.task.taskId);
1048        }
1049        ActivityStack.logStartActivity(
1050                EventLogTags.AM_CREATE_ACTIVITY, mStartActivity, mStartActivity.task);
1051        mTargetStack.mLastPausedActivity = null;
1052        mTargetStack.startActivityLocked(mStartActivity, newTask, mKeepCurTransition, mOptions);
1053        if (mDoResume) {
1054            if (!mLaunchTaskBehind) {
1055                // TODO(b/26381750): Remove this code after verification that all the decision
1056                // points above moved targetStack to the front which will also set the focus
1057                // activity.
1058                mService.setFocusedActivityLocked(mStartActivity, "startedActivity");
1059            }
1060            if (mTargetStack.isFocusable()) {
1061                mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
1062                        mOptions);
1063            } else {
1064                // If the activity is not focusable, we can't resume it, but still would like to
1065                // make sure it becomes visible as it starts (this will also trigger entry
1066                // animation). An example of this are PIP activities.
1067                mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
1068                // Go ahead and tell window manager to execute app transition for this activity
1069                // since the app transition will not be triggered through the resume channel.
1070                mWindowManager.executeAppTransition();
1071            }
1072        } else {
1073            mTargetStack.addRecentActivityLocked(mStartActivity);
1074        }
1075        mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);
1076
1077        mSupervisor.showNonResizeableDockToastIfNeeded(
1078                mStartActivity.task, preferredLaunchStackId, mTargetStack.mStackId);
1079
1080        return START_SUCCESS;
1081    }
1082
1083    private void setInitialState(ActivityRecord r, ActivityOptions options, TaskRecord inTask,
1084            boolean doResume, int startFlags, ActivityRecord sourceRecord,
1085            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
1086        reset();
1087
1088        mStartActivity = r;
1089        mIntent = r.intent;
1090        mOptions = options;
1091        mCallingUid = r.launchedFromUid;
1092        mSourceRecord = sourceRecord;
1093        mVoiceSession = voiceSession;
1094        mVoiceInteractor = voiceInteractor;
1095
1096        mLaunchBounds = getOverrideBounds(r, options, inTask);
1097
1098        mLaunchSingleTop = r.launchMode == LAUNCH_SINGLE_TOP;
1099        mLaunchSingleInstance = r.launchMode == LAUNCH_SINGLE_INSTANCE;
1100        mLaunchSingleTask = r.launchMode == LAUNCH_SINGLE_TASK;
1101        mLaunchFlags = adjustLaunchFlagsToDocumentMode(
1102                r, mLaunchSingleInstance, mLaunchSingleTask, mIntent.getFlags());
1103        mLaunchTaskBehind = r.mLaunchTaskBehind
1104                && !mLaunchSingleTask && !mLaunchSingleInstance
1105                && (mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0;
1106
1107        sendNewTaskResultRequestIfNeeded();
1108
1109        if ((mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
1110            mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1111        }
1112
1113        // If we are actually going to launch in to a new task, there are some cases where
1114        // we further want to do multiple task.
1115        if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1116            if (mLaunchTaskBehind
1117                    || r.info.documentLaunchMode == DOCUMENT_LAUNCH_ALWAYS) {
1118                mLaunchFlags |= FLAG_ACTIVITY_MULTIPLE_TASK;
1119            }
1120        }
1121
1122        // We'll invoke onUserLeaving before onPause only if the launching
1123        // activity did not explicitly state that this is an automated launch.
1124        mSupervisor.mUserLeaving = (mLaunchFlags & FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1125        if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
1126                "startActivity() => mUserLeaving=" + mSupervisor.mUserLeaving);
1127
1128        // If the caller has asked not to resume at this point, we make note
1129        // of this in the record so that we can skip it when trying to find
1130        // the top running activity.
1131        mDoResume = doResume;
1132        if (!doResume || !mSupervisor.okToShowLocked(r)) {
1133            r.delayedResume = true;
1134            mDoResume = false;
1135        }
1136
1137        mNotTop = (mLaunchFlags & FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1138
1139        mInTask = inTask;
1140        // In some flows in to this function, we retrieve the task record and hold on to it
1141        // without a lock before calling back in to here...  so the task at this point may
1142        // not actually be in recents.  Check for that, and if it isn't in recents just
1143        // consider it invalid.
1144        if (inTask != null && !inTask.inRecents) {
1145            Slog.w(TAG, "Starting activity in task not in recents: " + inTask);
1146            mInTask = null;
1147        }
1148
1149        mStartFlags = startFlags;
1150        // If the onlyIfNeeded flag is set, then we can do this if the activity being launched
1151        // is the same as the one making the call...  or, as a special case, if we do not know
1152        // the caller then we count the current top activity as the caller.
1153        if ((startFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1154            ActivityRecord checkedCaller = sourceRecord;
1155            if (checkedCaller == null) {
1156                checkedCaller = mSupervisor.mFocusedStack.topRunningNonDelayedActivityLocked(
1157                        mNotTop);
1158            }
1159            if (!checkedCaller.realActivity.equals(r.realActivity)) {
1160                // Caller is not the same as launcher, so always needed.
1161                mStartFlags &= ~START_FLAG_ONLY_IF_NEEDED;
1162            }
1163        }
1164
1165        mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0;
1166    }
1167
1168    private void sendNewTaskResultRequestIfNeeded() {
1169        if (mStartActivity.resultTo != null && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0
1170                && mStartActivity.resultTo.task.stack != null) {
1171            // For whatever reason this activity is being launched into a new task...
1172            // yet the caller has requested a result back.  Well, that is pretty messed up,
1173            // so instead immediately send back a cancel and let the new task continue launched
1174            // as normal without a dependency on its originator.
1175            Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1176            mStartActivity.resultTo.task.stack.sendActivityResultLocked(-1, mStartActivity.resultTo,
1177                    mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED, null);
1178            mStartActivity.resultTo = null;
1179        }
1180    }
1181
1182    private void computeLaunchingTaskFlags() {
1183        // If the caller is not coming from another activity, but has given us an explicit task into
1184        // which they would like us to launch the new activity, then let's see about doing that.
1185        if (mSourceRecord == null && mInTask != null && mInTask.stack != null) {
1186            final Intent baseIntent = mInTask.getBaseIntent();
1187            final ActivityRecord root = mInTask.getRootActivity();
1188            if (baseIntent == null) {
1189                ActivityOptions.abort(mOptions);
1190                throw new IllegalArgumentException("Launching into task without base intent: "
1191                        + mInTask);
1192            }
1193
1194            // If this task is empty, then we are adding the first activity -- it
1195            // determines the root, and must be launching as a NEW_TASK.
1196            if (mLaunchSingleInstance || mLaunchSingleTask) {
1197                if (!baseIntent.getComponent().equals(mStartActivity.intent.getComponent())) {
1198                    ActivityOptions.abort(mOptions);
1199                    throw new IllegalArgumentException("Trying to launch singleInstance/Task "
1200                            + mStartActivity + " into different task " + mInTask);
1201                }
1202                if (root != null) {
1203                    ActivityOptions.abort(mOptions);
1204                    throw new IllegalArgumentException("Caller with mInTask " + mInTask
1205                            + " has root " + root + " but target is singleInstance/Task");
1206                }
1207            }
1208
1209            // If task is empty, then adopt the interesting intent launch flags in to the
1210            // activity being started.
1211            if (root == null) {
1212                final int flagsOfInterest = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK
1213                        | FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS;
1214                mLaunchFlags = (mLaunchFlags & ~flagsOfInterest)
1215                        | (baseIntent.getFlags() & flagsOfInterest);
1216                mIntent.setFlags(mLaunchFlags);
1217                mInTask.setIntent(mStartActivity);
1218                mAddingToTask = true;
1219
1220                // If the task is not empty and the caller is asking to start it as the root of
1221                // a new task, then we don't actually want to start this on the task. We will
1222                // bring the task to the front, and possibly give it a new intent.
1223            } else if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1224                mAddingToTask = false;
1225
1226            } else {
1227                mAddingToTask = true;
1228            }
1229
1230            mReuseTask = mInTask;
1231        } else {
1232            mInTask = null;
1233            // Launch ResolverActivity in the source task, so that it stays in the task bounds
1234            // when in freeform workspace.
1235            // Also put noDisplay activities in the source task. These by itself can be placed
1236            // in any task/stack, however it could launch other activities like ResolverActivity,
1237            // and we want those to stay in the original task.
1238            if ((mStartActivity.isResolverActivity() || mStartActivity.noDisplay) && mSourceRecord != null
1239                    && mSourceRecord.isFreeform())  {
1240                mAddingToTask = true;
1241            }
1242        }
1243
1244        if (mInTask == null) {
1245            if (mSourceRecord == null) {
1246                // This activity is not being started from another...  in this
1247                // case we -always- start a new task.
1248                if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) {
1249                    Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1250                            "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
1251                    mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1252                }
1253            } else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) {
1254                // The original activity who is starting us is running as a single
1255                // instance...  this new activity it is starting must go on its
1256                // own task.
1257                mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1258            } else if (mLaunchSingleInstance || mLaunchSingleTask) {
1259                // The activity being started is a single instance...  it always
1260                // gets launched into its own task.
1261                mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1262            }
1263        }
1264    }
1265
1266    private void computeSourceStack() {
1267        if (mSourceRecord == null) {
1268            mSourceStack = null;
1269            return;
1270        }
1271        if (!mSourceRecord.finishing) {
1272            mSourceStack = mSourceRecord.task.stack;
1273            return;
1274        }
1275
1276        // If the source is finishing, we can't further count it as our source. This is because the
1277        // task it is associated with may now be empty and on its way out, so we don't want to
1278        // blindly throw it in to that task.  Instead we will take the NEW_TASK flow and try to find
1279        // a task for it. But save the task information so it can be used when creating the new task.
1280        if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0) {
1281            Slog.w(TAG, "startActivity called from finishing " + mSourceRecord
1282                    + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
1283            mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1284            mNewTaskInfo = mSourceRecord.info;
1285            mNewTaskIntent = mSourceRecord.task.intent;
1286        }
1287        mSourceRecord = null;
1288        mSourceStack = null;
1289    }
1290
1291    /**
1292     * Decide whether the new activity should be inserted into an existing task. Returns null
1293     * if not or an ActivityRecord with the task into which the new activity should be added.
1294     */
1295    private ActivityRecord getReusableIntentActivity() {
1296        // We may want to try to place the new activity in to an existing task.  We always
1297        // do this if the target activity is singleTask or singleInstance; we will also do
1298        // this if NEW_TASK has been requested, and there is not an additional qualifier telling
1299        // us to still place it in a new task: multi task, always doc mode, or being asked to
1300        // launch this as a new task behind the current one.
1301        boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 &&
1302                (mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1303                || mLaunchSingleInstance || mLaunchSingleTask;
1304        // If bring to front is requested, and no result is requested and we have not been given
1305        // an explicit task to launch in to, and we can find a task that was started with this
1306        // same component, then instead of launching bring that one to the front.
1307        putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null;
1308        ActivityRecord intentActivity = null;
1309        if (mOptions != null && mOptions.getLaunchTaskId() != -1) {
1310            final TaskRecord task = mSupervisor.anyTaskForIdLocked(mOptions.getLaunchTaskId());
1311            intentActivity = task != null ? task.getTopActivity() : null;
1312        } else if (putIntoExistingTask) {
1313            // See if there is a task to bring to the front.  If this is a SINGLE_INSTANCE
1314            // activity, there can be one and only one instance of it in the history, and it is
1315            // always in its own unique task, so we do a special search.
1316            intentActivity = mLaunchSingleInstance ? mSupervisor.findActivityLocked(mIntent, mStartActivity.info)
1317                    : mSupervisor.findTaskLocked(mStartActivity);
1318        }
1319        return intentActivity;
1320    }
1321
1322    private ActivityRecord setTargetStackAndMoveToFrontIfNeeded(ActivityRecord intentActivity) {
1323        mTargetStack = intentActivity.task.stack;
1324        mTargetStack.mLastPausedActivity = null;
1325        // If the target task is not in the front, then we need to bring it to the front...
1326        // except...  well, with SINGLE_TASK_LAUNCH it's not entirely clear. We'd like to have
1327        // the same behavior as if a new instance was being started, which means not bringing it
1328        // to the front if the caller is not itself in the front.
1329        final ActivityStack focusStack = mSupervisor.getFocusedStack();
1330        ActivityRecord curTop = (focusStack == null)
1331                ? null : focusStack.topRunningNonDelayedActivityLocked(mNotTop);
1332
1333        if (curTop != null && (curTop.task != intentActivity.task ||
1334                curTop.task != focusStack.topTask())) {
1335            mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
1336            if (mSourceRecord == null || (mSourceStack.topActivity() != null &&
1337                    mSourceStack.topActivity().task == mSourceRecord.task)) {
1338                // We really do want to push this one into the user's face, right now.
1339                if (mLaunchTaskBehind && mSourceRecord != null) {
1340                    intentActivity.setTaskToAffiliateWith(mSourceRecord.task);
1341                }
1342                mMovedHome = true;
1343
1344                // If the launch flags carry both NEW_TASK and CLEAR_TASK, the task's activities
1345                // will be cleared soon by ActivityStarter in setTaskFromIntentActivity().
1346                // So no point resuming any of the activities here, it just wastes one extra
1347                // resuming, plus enter AND exit transitions.
1348                // Here we only want to bring the target stack forward. Transition will be applied
1349                // to the new activity that's started after the old ones are gone.
1350                final boolean willClearTask =
1351                        (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1352                            == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
1353                if (!willClearTask) {
1354                    final ActivityStack launchStack = getLaunchStack(
1355                            mStartActivity, mLaunchFlags, mStartActivity.task, mOptions, true);
1356                    if (launchStack == null || launchStack == mTargetStack) {
1357                        // We only want to move to the front, if we aren't going to launch on a
1358                        // different stack. If we launch on a different stack, we will put the
1359                        // task on top there.
1360                        mTargetStack.moveTaskToFrontLocked(
1361                                intentActivity.task, mNoAnimation, mOptions,
1362                                mStartActivity.appTimeTracker, "bringingFoundTaskToFront");
1363                        mMovedToFront = true;
1364                    } else if ((launchStack.mStackId == DOCKED_STACK_ID
1365                            || launchStack.mStackId == FULLSCREEN_WORKSPACE_STACK_ID)
1366                            && (mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
1367                        // If we want to launch adjacent and mTargetStack is not the computed
1368                        // launch stack - move task to top of computed stack.
1369                        mSupervisor.moveTaskToStackLocked(intentActivity.task.taskId,
1370                                launchStack.mStackId, ON_TOP, FORCE_FOCUS, "launchToSide",
1371                                ANIMATE);
1372                        mMovedToFront = true;
1373                    }
1374                    mOptions = null;
1375                }
1376                updateTaskReturnToType(intentActivity.task, mLaunchFlags, focusStack);
1377            }
1378        }
1379        if (!mMovedToFront && mDoResume) {
1380            if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Bring to front target: " + mTargetStack
1381                    + " from " + intentActivity);
1382            mTargetStack.moveToFront("intentActivityFound");
1383        }
1384
1385        // If the caller has requested that the target task be reset, then do so.
1386        if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1387            return mTargetStack.resetTaskIfNeededLocked(intentActivity, mStartActivity);
1388        }
1389        return intentActivity;
1390    }
1391
1392    private void updateTaskReturnToType(
1393            TaskRecord task, int launchFlags, ActivityStack focusedStack) {
1394        if ((launchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1395                == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
1396            // Caller wants to appear on home activity.
1397            task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
1398            return;
1399        } else if (focusedStack == null || focusedStack.mStackId == HOME_STACK_ID) {
1400            // Task will be launched over the home stack, so return home.
1401            task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
1402            return;
1403        }
1404
1405        // Else we are coming from an application stack so return to an application.
1406        task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
1407    }
1408
1409    private void setTaskFromIntentActivity(ActivityRecord intentActivity) {
1410        if ((mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1411                == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {
1412            // The caller has requested to completely replace any existing task with its new
1413            // activity. Well that should not be too hard...
1414            mReuseTask = intentActivity.task;
1415            mReuseTask.performClearTaskLocked();
1416            mReuseTask.setIntent(mStartActivity);
1417        } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
1418                || mLaunchSingleInstance || mLaunchSingleTask) {
1419            ActivityRecord top = intentActivity.task.performClearTaskLocked(mStartActivity,
1420                    mLaunchFlags);
1421            if (top == null) {
1422                // A special case: we need to start the activity because it is not currently
1423                // running, and the caller has asked to clear the current task to have this
1424                // activity at the top.
1425                mAddingToTask = true;
1426                // Now pretend like this activity is being started by the top of its task, so it
1427                // is put in the right place.
1428                mSourceRecord = intentActivity;
1429                final TaskRecord task = mSourceRecord.task;
1430                if (task != null && task.stack == null) {
1431                    // Target stack got cleared when we all activities were removed above.
1432                    // Go ahead and reset it.
1433                    mTargetStack = computeStackFocus(mSourceRecord, false /* newTask */,
1434                            null /* bounds */, mLaunchFlags, mOptions);
1435                    mTargetStack.addTask(task,
1436                            !mLaunchTaskBehind /* toTop */, "startActivityUnchecked");
1437                }
1438            }
1439        } else if (mStartActivity.realActivity.equals(intentActivity.task.realActivity)) {
1440            // In this case the top activity on the task is the same as the one being launched,
1441            // so we take that as a request to bring the task to the foreground. If the top
1442            // activity in the task is the root activity, deliver this new intent to it if it
1443            // desires.
1444            if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0 || mLaunchSingleTop)
1445                    && intentActivity.realActivity.equals(mStartActivity.realActivity)) {
1446                ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity,
1447                        intentActivity.task);
1448                if (intentActivity.frontOfTask) {
1449                    intentActivity.task.setIntent(mStartActivity);
1450                }
1451                intentActivity.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
1452                        mStartActivity.launchedFromPackage);
1453            } else if (!intentActivity.task.isSameIntentResolution(mStartActivity)) {
1454                // In this case we are launching the root activity of the task, but with a
1455                // different intent. We should start a new instance on top.
1456                mAddingToTask = true;
1457                mSourceRecord = intentActivity;
1458            }
1459        } else if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1460            // In this case an activity is being launched in to an existing task, without
1461            // resetting that task. This is typically the situation of launching an activity
1462            // from a notification or shortcut. We want to place the new activity on top of the
1463            // current task.
1464            mAddingToTask = true;
1465            mSourceRecord = intentActivity;
1466        } else if (!intentActivity.task.rootWasReset) {
1467            // In this case we are launching into an existing task that has not yet been started
1468            // from its front door. The current task has been brought to the front. Ideally,
1469            // we'd probably like to place this new task at the bottom of its stack, but that's
1470            // a little hard to do with the current organization of the code so for now we'll
1471            // just drop it.
1472            intentActivity.task.setIntent(mStartActivity);
1473        }
1474    }
1475
1476    private void resumeTargetStackIfNeeded() {
1477        if (mDoResume) {
1478            mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, null, mOptions);
1479            if (!mMovedToFront) {
1480                // Make sure to notify Keyguard as well if we are not running an app transition
1481                // later.
1482                mSupervisor.notifyActivityDrawnForKeyguard();
1483            }
1484        } else {
1485            ActivityOptions.abort(mOptions);
1486        }
1487        mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);
1488    }
1489
1490    private void setTaskFromReuseOrCreateNewTask(TaskRecord taskToAffiliate) {
1491        mTargetStack = computeStackFocus(mStartActivity, true, mLaunchBounds, mLaunchFlags,
1492                mOptions);
1493        if (mDoResume) {
1494            mTargetStack.moveToFront("startingNewTask");
1495        }
1496
1497        if (mReuseTask == null) {
1498            final TaskRecord task = mTargetStack.createTaskRecord(
1499                    mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId),
1500                    mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
1501                    mNewTaskIntent != null ? mNewTaskIntent : mIntent,
1502                    mVoiceSession, mVoiceInteractor, !mLaunchTaskBehind /* toTop */);
1503            mStartActivity.setTask(task, taskToAffiliate);
1504            if (mLaunchBounds != null) {
1505                final int stackId = mTargetStack.mStackId;
1506                if (StackId.resizeStackWithLaunchBounds(stackId)) {
1507                    mService.resizeStack(
1508                            stackId, mLaunchBounds, true, !PRESERVE_WINDOWS, ANIMATE, -1);
1509                } else {
1510                    mStartActivity.task.updateOverrideConfiguration(mLaunchBounds);
1511                }
1512            }
1513            if (DEBUG_TASKS) Slog.v(TAG_TASKS,
1514                    "Starting new activity " +
1515                            mStartActivity + " in new task " + mStartActivity.task);
1516        } else {
1517            mStartActivity.setTask(mReuseTask, taskToAffiliate);
1518        }
1519    }
1520
1521    private int setTaskFromSourceRecord() {
1522        final TaskRecord sourceTask = mSourceRecord.task;
1523        // We only want to allow changing stack if the target task is not the top one,
1524        // otherwise we would move the launching task to the other side, rather than show
1525        // two side by side.
1526        final boolean launchToSideAllowed = sourceTask.stack.topTask() != sourceTask;
1527        mTargetStack = getLaunchStack(mStartActivity, mLaunchFlags, mStartActivity.task, mOptions, launchToSideAllowed);
1528
1529        if (mTargetStack == null) {
1530            mTargetStack = sourceTask.stack;
1531        } else if (mTargetStack != sourceTask.stack) {
1532            mSupervisor.moveTaskToStackLocked(sourceTask.taskId, mTargetStack.mStackId,
1533                    ON_TOP, FORCE_FOCUS, "launchToSide", !ANIMATE);
1534        }
1535        if (mDoResume) {
1536            mTargetStack.moveToFront("sourceStackToFront");
1537        }
1538        final TaskRecord topTask = mTargetStack.topTask();
1539        if (topTask != sourceTask) {
1540            mTargetStack.moveTaskToFrontLocked(sourceTask, mNoAnimation, mOptions,
1541                    mStartActivity.appTimeTracker, "sourceTaskToFront");
1542        }
1543        if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1544            // In this case, we are adding the activity to an existing task, but the caller has
1545            // asked to clear that task if the activity is already running.
1546            ActivityRecord top = sourceTask.performClearTaskLocked(mStartActivity, mLaunchFlags);
1547            mKeepCurTransition = true;
1548            if (top != null) {
1549                ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, top.task);
1550                top.deliverNewIntentLocked(mCallingUid, mStartActivity.intent, mStartActivity.launchedFromPackage);
1551                // For paranoia, make sure we have correctly resumed the top activity.
1552                mTargetStack.mLastPausedActivity = null;
1553                if (mDoResume) {
1554                    mSupervisor.resumeFocusedStackTopActivityLocked();
1555                }
1556                ActivityOptions.abort(mOptions);
1557                return START_DELIVERED_TO_TOP;
1558            }
1559        } else if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1560            // In this case, we are launching an activity in our own task that may already be
1561            // running somewhere in the history, and we want to shuffle it to the front of the
1562            // stack if so.
1563            final ActivityRecord top = sourceTask.findActivityInHistoryLocked(mStartActivity);
1564            if (top != null) {
1565                final TaskRecord task = top.task;
1566                task.moveActivityToFrontLocked(top);
1567                top.updateOptionsLocked(mOptions);
1568                ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, task);
1569                top.deliverNewIntentLocked(mCallingUid, mStartActivity.intent, mStartActivity.launchedFromPackage);
1570                mTargetStack.mLastPausedActivity = null;
1571                if (mDoResume) {
1572                    mSupervisor.resumeFocusedStackTopActivityLocked();
1573                }
1574                return START_DELIVERED_TO_TOP;
1575            }
1576        }
1577
1578        // An existing activity is starting this new activity, so we want to keep the new one in
1579        // the same task as the one that is starting it.
1580        mStartActivity.setTask(sourceTask, null);
1581        if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
1582                + " in existing task " + mStartActivity.task + " from source " + mSourceRecord);
1583        return START_SUCCESS;
1584    }
1585
1586    private int setTaskFromInTask() {
1587        if (mLaunchBounds != null) {
1588            mInTask.updateOverrideConfiguration(mLaunchBounds);
1589            int stackId = mInTask.getLaunchStackId();
1590            if (stackId != mInTask.stack.mStackId) {
1591                final ActivityStack stack = mSupervisor.moveTaskToStackUncheckedLocked(
1592                        mInTask, stackId, ON_TOP, !FORCE_FOCUS, "inTaskToFront");
1593                stackId = stack.mStackId;
1594            }
1595            if (StackId.resizeStackWithLaunchBounds(stackId)) {
1596                mService.resizeStack(stackId, mLaunchBounds, true, !PRESERVE_WINDOWS, ANIMATE, -1);
1597            }
1598        }
1599        mTargetStack = mInTask.stack;
1600        mTargetStack.moveTaskToFrontLocked(
1601                mInTask, mNoAnimation, mOptions, mStartActivity.appTimeTracker, "inTaskToFront");
1602
1603        // Check whether we should actually launch the new activity in to the task,
1604        // or just reuse the current activity on top.
1605        ActivityRecord top = mInTask.getTopActivity();
1606        if (top != null && top.realActivity.equals(mStartActivity.realActivity) && top.userId == mStartActivity.userId) {
1607            if ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
1608                    || mLaunchSingleTop || mLaunchSingleTask) {
1609                ActivityStack.logStartActivity(AM_NEW_INTENT, top, top.task);
1610                if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1611                    // We don't need to start a new activity, and the client said not to do
1612                    // anything if that is the case, so this is it!
1613                    return START_RETURN_INTENT_TO_CALLER;
1614                }
1615                top.deliverNewIntentLocked(mCallingUid, mStartActivity.intent, mStartActivity.launchedFromPackage);
1616                return START_DELIVERED_TO_TOP;
1617            }
1618        }
1619
1620        if (!mAddingToTask) {
1621            // We don't actually want to have this activity added to the task, so just
1622            // stop here but still tell the caller that we consumed the intent.
1623            ActivityOptions.abort(mOptions);
1624            return START_TASK_TO_FRONT;
1625        }
1626
1627        mStartActivity.setTask(mInTask, null);
1628        if (DEBUG_TASKS) Slog.v(TAG_TASKS,
1629                "Starting new activity " + mStartActivity + " in explicit task " + mStartActivity.task);
1630
1631        return START_SUCCESS;
1632    }
1633
1634    private void setTaskToCurrentTopOrCreateNewTask() {
1635        mTargetStack = computeStackFocus(mStartActivity, false, null /* bounds */, mLaunchFlags,
1636                mOptions);
1637        if (mDoResume) {
1638            mTargetStack.moveToFront("addingToTopTask");
1639        }
1640        final ActivityRecord prev = mTargetStack.topActivity();
1641        final TaskRecord task = (prev != null) ? prev.task : mTargetStack.createTaskRecord(
1642                        mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId),
1643                        mStartActivity.info, mIntent, null, null, true);
1644        mStartActivity.setTask(task, null);
1645        mWindowManager.moveTaskToTop(mStartActivity.task.taskId);
1646        if (DEBUG_TASKS) Slog.v(TAG_TASKS,
1647                "Starting new activity " + mStartActivity + " in new guessed " + mStartActivity.task);
1648    }
1649
1650    private int adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance,
1651            boolean launchSingleTask, int launchFlags) {
1652        if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
1653                (launchSingleInstance || launchSingleTask)) {
1654            // We have a conflict between the Intent and the Activity manifest, manifest wins.
1655            Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " +
1656                    "\"singleInstance\" or \"singleTask\"");
1657            launchFlags &=
1658                    ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK);
1659        } else {
1660            switch (r.info.documentLaunchMode) {
1661                case ActivityInfo.DOCUMENT_LAUNCH_NONE:
1662                    break;
1663                case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
1664                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
1665                    break;
1666                case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
1667                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
1668                    break;
1669                case ActivityInfo.DOCUMENT_LAUNCH_NEVER:
1670                    launchFlags &= ~FLAG_ACTIVITY_MULTIPLE_TASK;
1671                    break;
1672            }
1673        }
1674        return launchFlags;
1675    }
1676
1677    final void doPendingActivityLaunchesLocked(boolean doResume) {
1678        while (!mPendingActivityLaunches.isEmpty()) {
1679            final PendingActivityLaunch pal = mPendingActivityLaunches.remove(0);
1680            final boolean resume = doResume && mPendingActivityLaunches.isEmpty();
1681            try {
1682                final int result = startActivityUnchecked(
1683                        pal.r, pal.sourceRecord, null, null, pal.startFlags, resume, null, null);
1684                postStartActivityUncheckedProcessing(
1685                        pal.r, result, mSupervisor.mFocusedStack.mStackId);
1686            } catch (Exception e) {
1687                Slog.e(TAG, "Exception during pending activity launch pal=" + pal, e);
1688                pal.sendErrorResult(e.getMessage());
1689            }
1690        }
1691    }
1692
1693    private ActivityStack computeStackFocus(ActivityRecord r, boolean newTask, Rect bounds,
1694            int launchFlags, ActivityOptions aOptions) {
1695        final TaskRecord task = r.task;
1696        if (!(r.isApplicationActivity() || (task != null && task.isApplicationTask()))) {
1697            return mSupervisor.mHomeStack;
1698        }
1699
1700        ActivityStack stack = getLaunchStack(r, launchFlags, task, aOptions, true);
1701        if (stack != null) {
1702            return stack;
1703        }
1704
1705        if (task != null && task.stack != null) {
1706            stack = task.stack;
1707            if (stack.isOnHomeDisplay()) {
1708                if (mSupervisor.mFocusedStack != stack) {
1709                    if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
1710                            "computeStackFocus: Setting " + "focused stack to r=" + r
1711                                    + " task=" + task);
1712                } else {
1713                    if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
1714                            "computeStackFocus: Focused stack already="
1715                                    + mSupervisor.mFocusedStack);
1716                }
1717            }
1718            return stack;
1719        }
1720
1721        final ActivityStackSupervisor.ActivityContainer container = r.mInitialActivityContainer;
1722        if (container != null) {
1723            // The first time put it on the desired stack, after this put on task stack.
1724            r.mInitialActivityContainer = null;
1725            return container.mStack;
1726        }
1727
1728        // The fullscreen stack can contain any task regardless of if the task is resizeable
1729        // or not. So, we let the task go in the fullscreen task if it is the focus stack.
1730        // If the freeform or docked stack has focus, and the activity to be launched is resizeable,
1731        // we can also put it in the focused stack.
1732        final int focusedStackId = mSupervisor.mFocusedStack.mStackId;
1733        final boolean canUseFocusedStack = focusedStackId == FULLSCREEN_WORKSPACE_STACK_ID
1734                || (focusedStackId == DOCKED_STACK_ID && r.canGoInDockedStack())
1735                || (focusedStackId == FREEFORM_WORKSPACE_STACK_ID && r.isResizeableOrForced());
1736        if (canUseFocusedStack && (!newTask
1737                || mSupervisor.mFocusedStack.mActivityContainer.isEligibleForNewTasks())) {
1738            if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
1739                    "computeStackFocus: Have a focused stack=" + mSupervisor.mFocusedStack);
1740            return mSupervisor.mFocusedStack;
1741        }
1742
1743        // We first try to put the task in the first dynamic stack.
1744        final ArrayList<ActivityStack> homeDisplayStacks = mSupervisor.mHomeStack.mStacks;
1745        for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1746            stack = homeDisplayStacks.get(stackNdx);
1747            if (!ActivityManager.StackId.isStaticStack(stack.mStackId)) {
1748                if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
1749                        "computeStackFocus: Setting focused stack=" + stack);
1750                return stack;
1751            }
1752        }
1753
1754        // If there is no suitable dynamic stack then we figure out which static stack to use.
1755        final int stackId = task != null ? task.getLaunchStackId() :
1756                bounds != null ? FREEFORM_WORKSPACE_STACK_ID :
1757                        FULLSCREEN_WORKSPACE_STACK_ID;
1758        stack = mSupervisor.getStack(stackId, CREATE_IF_NEEDED, ON_TOP);
1759        if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, "computeStackFocus: New stack r="
1760                + r + " stackId=" + stack.mStackId);
1761        return stack;
1762    }
1763
1764    private ActivityStack getLaunchStack(ActivityRecord r, int launchFlags, TaskRecord task,
1765            ActivityOptions aOptions, boolean launchToSideAllowed) {
1766        final int launchStackId =
1767                (aOptions != null) ? aOptions.getLaunchStackId() : INVALID_STACK_ID;
1768
1769        if (isValidLaunchStackId(launchStackId, r)) {
1770            return mSupervisor.getStack(launchStackId, CREATE_IF_NEEDED, ON_TOP);
1771        } else if (launchStackId == DOCKED_STACK_ID) {
1772            // The preferred launch stack is the docked stack, but it isn't a valid launch stack
1773            // for this activity, so we put the activity in the fullscreen stack.
1774            return mSupervisor.getStack(FULLSCREEN_WORKSPACE_STACK_ID, CREATE_IF_NEEDED, ON_TOP);
1775        }
1776
1777        if (!launchToSideAllowed || (launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) == 0) {
1778            return null;
1779        }
1780        // Otherwise handle adjacent launch.
1781
1782        // The parent activity doesn't want to launch the activity on top of itself, but
1783        // instead tries to put it onto other side in side-by-side mode.
1784        final ActivityStack parentStack = task != null ? task.stack
1785                : r.mInitialActivityContainer != null ? r.mInitialActivityContainer.mStack
1786                : mSupervisor.mFocusedStack;
1787
1788        if (parentStack != mSupervisor.mFocusedStack) {
1789            // If task's parent stack is not focused - use it during adjacent launch.
1790            return parentStack;
1791        } else {
1792            if (mSupervisor.mFocusedStack != null && task == mSupervisor.mFocusedStack.topTask()) {
1793                // If task is already on top of focused stack - use it. We don't want to move the
1794                // existing focused task to adjacent stack, just deliver new intent in this case.
1795                return mSupervisor.mFocusedStack;
1796            }
1797
1798            if (parentStack != null && parentStack.mStackId == DOCKED_STACK_ID) {
1799                // If parent was in docked stack, the natural place to launch another activity
1800                // will be fullscreen, so it can appear alongside the docked window.
1801                return mSupervisor.getStack(FULLSCREEN_WORKSPACE_STACK_ID, CREATE_IF_NEEDED,
1802                        ON_TOP);
1803            } else {
1804                // If the parent is not in the docked stack, we check if there is docked window
1805                // and if yes, we will launch into that stack. If not, we just put the new
1806                // activity into parent's stack, because we can't find a better place.
1807                final ActivityStack dockedStack = mSupervisor.getStack(DOCKED_STACK_ID);
1808                if (dockedStack != null
1809                        && dockedStack.getStackVisibilityLocked(r) == STACK_INVISIBLE) {
1810                    // There is a docked stack, but it isn't visible, so we can't launch into that.
1811                    return null;
1812                } else {
1813                    return dockedStack;
1814                }
1815            }
1816        }
1817    }
1818
1819    private boolean isValidLaunchStackId(int stackId, ActivityRecord r) {
1820        if (stackId == INVALID_STACK_ID || stackId == HOME_STACK_ID
1821                || !StackId.isStaticStack(stackId)) {
1822            return false;
1823        }
1824
1825        if (stackId != FULLSCREEN_WORKSPACE_STACK_ID
1826                && (!mService.mSupportsMultiWindow || !r.isResizeableOrForced())) {
1827            return false;
1828        }
1829
1830        if (stackId == DOCKED_STACK_ID && r.canGoInDockedStack()) {
1831            return true;
1832        }
1833
1834        if (stackId == FREEFORM_WORKSPACE_STACK_ID && !mService.mSupportsFreeformWindowManagement) {
1835            return false;
1836        }
1837
1838        final boolean supportsPip = mService.mSupportsPictureInPicture
1839                && (r.supportsPictureInPicture() || mService.mForceResizableActivities);
1840        if (stackId == PINNED_STACK_ID && !supportsPip) {
1841            return false;
1842        }
1843        return true;
1844    }
1845
1846    Rect getOverrideBounds(ActivityRecord r, ActivityOptions options, TaskRecord inTask) {
1847        Rect newBounds = null;
1848        if (options != null && (r.isResizeable() || (inTask != null && inTask.isResizeable()))) {
1849            if (mSupervisor.canUseActivityOptionsLaunchBounds(
1850                    options, options.getLaunchStackId())) {
1851                newBounds = TaskRecord.validateBounds(options.getLaunchBounds());
1852            }
1853        }
1854        return newBounds;
1855    }
1856
1857    void setWindowManager(WindowManagerService wm) {
1858        mWindowManager = wm;
1859    }
1860
1861    void removePendingActivityLaunchesLocked(ActivityStack stack) {
1862        for (int palNdx = mPendingActivityLaunches.size() - 1; palNdx >= 0; --palNdx) {
1863            PendingActivityLaunch pal = mPendingActivityLaunches.get(palNdx);
1864            if (pal.stack == stack) {
1865                mPendingActivityLaunches.remove(palNdx);
1866            }
1867        }
1868    }
1869}
1870