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