ActivityStarter.java revision 13dbfff19eeee73133c976ef6b23298e271a1985
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        // For safety, check null here in case users changed the setting after the checking.
624        if (credential == null) {
625            return;
626        }
627        final ActivityRecord activityRecord = targetStack.topRunningActivityLocked();
628        if (activityRecord != null) {
629            final IIntentSender target = mService.getIntentSenderLocked(
630                    ActivityManager.INTENT_SENDER_ACTIVITY,
631                    activityRecord.launchedFromPackage,
632                    activityRecord.launchedFromUid,
633                    activityRecord.userId,
634                    null, null, 0,
635                    new Intent[] { activityRecord.intent },
636                    new String[] { activityRecord.resolvedType },
637                    PendingIntent.FLAG_CANCEL_CURRENT |
638                            PendingIntent.FLAG_ONE_SHOT |
639                            PendingIntent.FLAG_IMMUTABLE,
640                    null);
641            credential.putExtra(Intent.EXTRA_INTENT, new IntentSender(target));
642            // Show confirm credentials activity.
643            startConfirmCredentialIntent(credential);
644        }
645    }
646
647    void startConfirmCredentialIntent(Intent intent) {
648        intent.addFlags(FLAG_ACTIVITY_NEW_TASK |
649                FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
650                FLAG_ACTIVITY_TASK_ON_HOME);
651        final ActivityOptions options = ActivityOptions.makeBasic();
652        options.setLaunchTaskId(mSupervisor.getHomeActivity().task.taskId);
653        mService.mContext.startActivityAsUser(intent, options.toBundle(),
654                UserHandle.CURRENT);
655    }
656
657    final int startActivityMayWait(IApplicationThread caller, int callingUid,
658            String callingPackage, Intent intent, String resolvedType,
659            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
660            IBinder resultTo, String resultWho, int requestCode, int startFlags,
661            ProfilerInfo profilerInfo, IActivityManager.WaitResult outResult, Configuration config,
662            Bundle bOptions, boolean ignoreTargetSecurity, int userId,
663            IActivityContainer iContainer, TaskRecord inTask) {
664        // Refuse possible leaked file descriptors
665        if (intent != null && intent.hasFileDescriptors()) {
666            throw new IllegalArgumentException("File descriptors passed in Intent");
667        }
668        mSupervisor.mActivityMetricsLogger.notifyActivityLaunching();
669        boolean componentSpecified = intent.getComponent() != null;
670
671        // Save a copy in case ephemeral needs it
672        final Intent ephemeralIntent = new Intent(intent);
673        // Don't modify the client's object!
674        intent = new Intent(intent);
675
676        ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
677        if (rInfo == null) {
678            UserInfo userInfo = mSupervisor.getUserInfo(userId);
679            if (userInfo != null && userInfo.isManagedProfile()) {
680                // Special case for managed profiles, if attempting to launch non-cryto aware
681                // app in a locked managed profile from an unlocked parent allow it to resolve
682                // as user will be sent via confirm credentials to unlock the profile.
683                UserManager userManager = UserManager.get(mService.mContext);
684                boolean profileLockedAndParentUnlockingOrUnlocked = false;
685                long token = Binder.clearCallingIdentity();
686                try {
687                    UserInfo parent = userManager.getProfileParent(userId);
688                    profileLockedAndParentUnlockingOrUnlocked = (parent != null)
689                            && userManager.isUserUnlockingOrUnlocked(parent.id)
690                            && !userManager.isUserUnlockingOrUnlocked(userId);
691                } finally {
692                    Binder.restoreCallingIdentity(token);
693                }
694                if (profileLockedAndParentUnlockingOrUnlocked) {
695                    rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
696                            PackageManager.MATCH_DIRECT_BOOT_AWARE
697                                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
698                }
699            }
700        }
701        // Collect information about the target of the Intent.
702        ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
703
704        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
705        ActivityStackSupervisor.ActivityContainer container =
706                (ActivityStackSupervisor.ActivityContainer)iContainer;
707        synchronized (mService) {
708            if (container != null && container.mParentActivity != null &&
709                    container.mParentActivity.state != RESUMED) {
710                // Cannot start a child activity if the parent is not resumed.
711                return ActivityManager.START_CANCELED;
712            }
713            final int realCallingPid = Binder.getCallingPid();
714            final int realCallingUid = Binder.getCallingUid();
715            int callingPid;
716            if (callingUid >= 0) {
717                callingPid = -1;
718            } else if (caller == null) {
719                callingPid = realCallingPid;
720                callingUid = realCallingUid;
721            } else {
722                callingPid = callingUid = -1;
723            }
724
725            final ActivityStack stack;
726            if (container == null || container.mStack.isOnHomeDisplay()) {
727                stack = mSupervisor.mFocusedStack;
728            } else {
729                stack = container.mStack;
730            }
731            stack.mConfigWillChange = config != null && mService.mConfiguration.diff(config) != 0;
732            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
733                    "Starting activity when config will change = " + stack.mConfigWillChange);
734
735            final long origId = Binder.clearCallingIdentity();
736
737            if (aInfo != null &&
738                    (aInfo.applicationInfo.privateFlags
739                            & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
740                // This may be a heavy-weight process!  Check to see if we already
741                // have another, different heavy-weight process running.
742                if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
743                    final ProcessRecord heavy = mService.mHeavyWeightProcess;
744                    if (heavy != null && (heavy.info.uid != aInfo.applicationInfo.uid
745                            || !heavy.processName.equals(aInfo.processName))) {
746                        int appCallingUid = callingUid;
747                        if (caller != null) {
748                            ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
749                            if (callerApp != null) {
750                                appCallingUid = callerApp.info.uid;
751                            } else {
752                                Slog.w(TAG, "Unable to find app for caller " + caller
753                                        + " (pid=" + callingPid + ") when starting: "
754                                        + intent.toString());
755                                ActivityOptions.abort(options);
756                                return ActivityManager.START_PERMISSION_DENIED;
757                            }
758                        }
759
760                        IIntentSender target = mService.getIntentSenderLocked(
761                                ActivityManager.INTENT_SENDER_ACTIVITY, "android",
762                                appCallingUid, userId, null, null, 0, new Intent[] { intent },
763                                new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
764                                        | PendingIntent.FLAG_ONE_SHOT, null);
765
766                        Intent newIntent = new Intent();
767                        if (requestCode >= 0) {
768                            // Caller is requesting a result.
769                            newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
770                        }
771                        newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
772                                new IntentSender(target));
773                        if (heavy.activities.size() > 0) {
774                            ActivityRecord hist = heavy.activities.get(0);
775                            newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
776                                    hist.packageName);
777                            newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
778                                    hist.task.taskId);
779                        }
780                        newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
781                                aInfo.packageName);
782                        newIntent.setFlags(intent.getFlags());
783                        newIntent.setClassName("android",
784                                HeavyWeightSwitcherActivity.class.getName());
785                        intent = newIntent;
786                        resolvedType = null;
787                        caller = null;
788                        callingUid = Binder.getCallingUid();
789                        callingPid = Binder.getCallingPid();
790                        componentSpecified = true;
791                        rInfo = mSupervisor.resolveIntent(intent, null /*resolvedType*/, userId);
792                        aInfo = rInfo != null ? rInfo.activityInfo : null;
793                        if (aInfo != null) {
794                            aInfo = mService.getActivityInfoForUser(aInfo, userId);
795                        }
796                    }
797                }
798            }
799
800            final ActivityRecord[] outRecord = new ActivityRecord[1];
801            int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
802                    aInfo, rInfo, voiceSession, voiceInteractor,
803                    resultTo, resultWho, requestCode, callingPid,
804                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
805                    options, ignoreTargetSecurity, componentSpecified, outRecord, container,
806                    inTask);
807
808            Binder.restoreCallingIdentity(origId);
809
810            if (stack.mConfigWillChange) {
811                // If the caller also wants to switch to a new configuration,
812                // do so now.  This allows a clean switch, as we are waiting
813                // for the current activity to pause (so we will not destroy
814                // it), and have not yet started the next activity.
815                mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
816                        "updateConfiguration()");
817                stack.mConfigWillChange = false;
818                if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
819                        "Updating to new configuration after starting activity.");
820                mService.updateConfigurationLocked(config, null, false);
821            }
822
823            if (outResult != null) {
824                outResult.result = res;
825                if (res == ActivityManager.START_SUCCESS) {
826                    mSupervisor.mWaitingActivityLaunched.add(outResult);
827                    do {
828                        try {
829                            mService.wait();
830                        } catch (InterruptedException e) {
831                        }
832                    } while (!outResult.timeout && outResult.who == null);
833                } else if (res == START_TASK_TO_FRONT) {
834                    ActivityRecord r = stack.topRunningActivityLocked();
835                    if (r.nowVisible && r.state == RESUMED) {
836                        outResult.timeout = false;
837                        outResult.who = new ComponentName(r.info.packageName, r.info.name);
838                        outResult.totalTime = 0;
839                        outResult.thisTime = 0;
840                    } else {
841                        outResult.thisTime = SystemClock.uptimeMillis();
842                        mSupervisor.mWaitingActivityVisible.add(outResult);
843                        do {
844                            try {
845                                mService.wait();
846                            } catch (InterruptedException e) {
847                            }
848                        } while (!outResult.timeout && outResult.who == null);
849                    }
850                }
851            }
852
853            final ActivityRecord launchedActivity = mReusedActivity != null
854                    ? mReusedActivity : outRecord[0];
855            mSupervisor.mActivityMetricsLogger.notifyActivityLaunched(res, launchedActivity);
856            return res;
857        }
858    }
859
860    final int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
861            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
862            Bundle bOptions, int userId) {
863        if (intents == null) {
864            throw new NullPointerException("intents is null");
865        }
866        if (resolvedTypes == null) {
867            throw new NullPointerException("resolvedTypes is null");
868        }
869        if (intents.length != resolvedTypes.length) {
870            throw new IllegalArgumentException("intents are length different than resolvedTypes");
871        }
872
873
874        int callingPid;
875        if (callingUid >= 0) {
876            callingPid = -1;
877        } else if (caller == null) {
878            callingPid = Binder.getCallingPid();
879            callingUid = Binder.getCallingUid();
880        } else {
881            callingPid = callingUid = -1;
882        }
883        final long origId = Binder.clearCallingIdentity();
884        try {
885            synchronized (mService) {
886                ActivityRecord[] outActivity = new ActivityRecord[1];
887                for (int i=0; i<intents.length; i++) {
888                    Intent intent = intents[i];
889                    if (intent == null) {
890                        continue;
891                    }
892
893                    // Refuse possible leaked file descriptors
894                    if (intent != null && intent.hasFileDescriptors()) {
895                        throw new IllegalArgumentException("File descriptors passed in Intent");
896                    }
897
898                    boolean componentSpecified = intent.getComponent() != null;
899
900                    // Don't modify the client's object!
901                    intent = new Intent(intent);
902
903                    // Collect information about the target of the Intent.
904                    ActivityInfo aInfo = mSupervisor.resolveActivity(intent, resolvedTypes[i], 0,
905                            null, userId);
906                    // TODO: New, check if this is correct
907                    aInfo = mService.getActivityInfoForUser(aInfo, userId);
908
909                    if (aInfo != null &&
910                            (aInfo.applicationInfo.privateFlags
911                                    & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE)  != 0) {
912                        throw new IllegalArgumentException(
913                                "FLAG_CANT_SAVE_STATE not supported here");
914                    }
915
916                    ActivityOptions options = ActivityOptions.fromBundle(
917                            i == intents.length - 1 ? bOptions : null);
918                    int res = startActivityLocked(caller, intent, null /*ephemeralIntent*/,
919                            resolvedTypes[i], aInfo, null /*rInfo*/, null, null, resultTo, null, -1,
920                            callingPid, callingUid, callingPackage, callingPid, callingUid, 0,
921                            options, false, componentSpecified, outActivity, null, null);
922                    if (res < 0) {
923                        return res;
924                    }
925
926                    resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
927                }
928            }
929        } finally {
930            Binder.restoreCallingIdentity(origId);
931        }
932
933        return START_SUCCESS;
934    }
935
936    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
937            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
938            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {
939
940        setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
941                voiceInteractor);
942
943        computeLaunchingTaskFlags();
944
945        computeSourceStack();
946
947        mIntent.setFlags(mLaunchFlags);
948
949        mReusedActivity = getReusableIntentActivity();
950
951        final int preferredLaunchStackId =
952                (mOptions != null) ? mOptions.getLaunchStackId() : INVALID_STACK_ID;
953
954        if (mReusedActivity != null) {
955            // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but
956            // still needs to be a lock task mode violation since the task gets cleared out and
957            // the device would otherwise leave the locked task.
958            if (mSupervisor.isLockTaskModeViolation(mReusedActivity.task,
959                    (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
960                            == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
961                mSupervisor.showLockTaskToast();
962                Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
963                return START_RETURN_LOCK_TASK_MODE_VIOLATION;
964            }
965
966            if (mStartActivity.task == null) {
967                mStartActivity.task = mReusedActivity.task;
968            }
969            if (mReusedActivity.task.intent == null) {
970                // This task was started because of movement of the activity based on affinity...
971                // Now that we are actually launching it, we can assign the base intent.
972                mReusedActivity.task.setIntent(mStartActivity);
973            }
974
975            // This code path leads to delivering a new intent, we want to make sure we schedule it
976            // as the first operation, in case the activity will be resumed as a result of later
977            // operations.
978            if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
979                    || mLaunchSingleInstance || mLaunchSingleTask) {
980                // In this situation we want to remove all activities from the task up to the one
981                // being started. In most cases this means we are resetting the task to its initial
982                // state.
983                final ActivityRecord top = mReusedActivity.task.performClearTaskForReuseLocked(
984                        mStartActivity, mLaunchFlags);
985                if (top != null) {
986                    if (top.frontOfTask) {
987                        // Activity aliases may mean we use different intents for the top activity,
988                        // so make sure the task now has the identity of the new intent.
989                        top.task.setIntent(mStartActivity);
990                    }
991                    ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, top.task);
992                    top.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
993                            mStartActivity.launchedFromPackage);
994                }
995            }
996
997            mReusedActivity = setTargetStackAndMoveToFrontIfNeeded(mReusedActivity);
998
999            if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1000                // We don't need to start a new activity, and the client said not to do anything
1001                // if that is the case, so this is it!  And for paranoia, make sure we have
1002                // correctly resumed the top activity.
1003                resumeTargetStackIfNeeded();
1004                return START_RETURN_INTENT_TO_CALLER;
1005            }
1006
1007            setTaskFromIntentActivity(mReusedActivity);
1008
1009            if (!mAddingToTask && mReuseTask == null) {
1010                // We didn't do anything...  but it was needed (a.k.a., client don't use that
1011                // intent!)  And for paranoia, make sure we have correctly resumed the top activity.
1012                resumeTargetStackIfNeeded();
1013                return START_TASK_TO_FRONT;
1014            }
1015        }
1016
1017        if (mStartActivity.packageName == null) {
1018            if (mStartActivity.resultTo != null && mStartActivity.resultTo.task.stack != null) {
1019                mStartActivity.resultTo.task.stack.sendActivityResultLocked(
1020                        -1, mStartActivity.resultTo, mStartActivity.resultWho,
1021                        mStartActivity.requestCode, RESULT_CANCELED, null);
1022            }
1023            ActivityOptions.abort(mOptions);
1024            return START_CLASS_NOT_FOUND;
1025        }
1026
1027        // If the activity being launched is the same as the one currently at the top, then
1028        // we need to check if it should only be launched once.
1029        final ActivityStack topStack = mSupervisor.mFocusedStack;
1030        final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
1031        final boolean dontStart = top != null && mStartActivity.resultTo == null
1032                && top.realActivity.equals(mStartActivity.realActivity)
1033                && top.userId == mStartActivity.userId
1034                && top.app != null && top.app.thread != null
1035                && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
1036                || mLaunchSingleTop || mLaunchSingleTask);
1037        if (dontStart) {
1038            ActivityStack.logStartActivity(AM_NEW_INTENT, top, top.task);
1039            // For paranoia, make sure we have correctly resumed the top activity.
1040            topStack.mLastPausedActivity = null;
1041            if (mDoResume) {
1042                mSupervisor.resumeFocusedStackTopActivityLocked();
1043            }
1044            ActivityOptions.abort(mOptions);
1045            if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1046                // We don't need to start a new activity, and the client said not to do
1047                // anything if that is the case, so this is it!
1048                return START_RETURN_INTENT_TO_CALLER;
1049            }
1050            top.deliverNewIntentLocked(
1051                    mCallingUid, mStartActivity.intent, mStartActivity.launchedFromPackage);
1052
1053            // Don't use mStartActivity.task to show the toast. We're not starting a new activity
1054            // but reusing 'top'. Fields in mStartActivity may not be fully initialized.
1055            mSupervisor.handleNonResizableTaskIfNeeded(
1056                    top.task, preferredLaunchStackId, topStack.mStackId);
1057
1058            return START_DELIVERED_TO_TOP;
1059        }
1060
1061        boolean newTask = false;
1062        final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
1063                ? mSourceRecord.task : null;
1064
1065        // Should this be considered a new task?
1066        if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
1067                && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1068            newTask = true;
1069            setTaskFromReuseOrCreateNewTask(taskToAffiliate);
1070
1071            if (mSupervisor.isLockTaskModeViolation(mStartActivity.task)) {
1072                Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
1073                return START_RETURN_LOCK_TASK_MODE_VIOLATION;
1074            }
1075            if (!mMovedHome) {
1076                updateTaskReturnToType(mStartActivity.task, mLaunchFlags, topStack);
1077            }
1078        } else if (mSourceRecord != null) {
1079            if (mSupervisor.isLockTaskModeViolation(mSourceRecord.task)) {
1080                Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
1081                return START_RETURN_LOCK_TASK_MODE_VIOLATION;
1082            }
1083
1084            final int result = setTaskFromSourceRecord();
1085            if (result != START_SUCCESS) {
1086                return result;
1087            }
1088        } else if (mInTask != null) {
1089            // The caller is asking that the new activity be started in an explicit
1090            // task it has provided to us.
1091            if (mSupervisor.isLockTaskModeViolation(mInTask)) {
1092                Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
1093                return START_RETURN_LOCK_TASK_MODE_VIOLATION;
1094            }
1095
1096            final int result = setTaskFromInTask();
1097            if (result != START_SUCCESS) {
1098                return result;
1099            }
1100        } else {
1101            // This not being started from an existing activity, and not part of a new task...
1102            // just put it in the top task, though these days this case should never happen.
1103            setTaskToCurrentTopOrCreateNewTask();
1104        }
1105
1106        mService.grantUriPermissionFromIntentLocked(mCallingUid, mStartActivity.packageName,
1107                mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.userId);
1108
1109        if (mSourceRecord != null && mSourceRecord.isRecentsActivity()) {
1110            mStartActivity.task.setTaskToReturnTo(RECENTS_ACTIVITY_TYPE);
1111        }
1112        if (newTask) {
1113            EventLog.writeEvent(
1114                    EventLogTags.AM_CREATE_TASK, mStartActivity.userId, mStartActivity.task.taskId);
1115        }
1116        ActivityStack.logStartActivity(
1117                EventLogTags.AM_CREATE_ACTIVITY, mStartActivity, mStartActivity.task);
1118        mTargetStack.mLastPausedActivity = null;
1119        mTargetStack.startActivityLocked(mStartActivity, newTask, mKeepCurTransition, mOptions);
1120        if (mDoResume) {
1121            if (!mLaunchTaskBehind) {
1122                // TODO(b/26381750): Remove this code after verification that all the decision
1123                // points above moved targetStack to the front which will also set the focus
1124                // activity.
1125                mService.setFocusedActivityLocked(mStartActivity, "startedActivity");
1126            }
1127            final ActivityRecord topTaskActivity = mStartActivity.task.topRunningActivityLocked();
1128            if (!mTargetStack.isFocusable()
1129                    || (topTaskActivity != null && topTaskActivity.mTaskOverlay
1130                    && mStartActivity != topTaskActivity)) {
1131                // If the activity is not focusable, we can't resume it, but still would like to
1132                // make sure it becomes visible as it starts (this will also trigger entry
1133                // animation). An example of this are PIP activities.
1134                // Also, we don't want to resume activities in a task that currently has an overlay
1135                // as the starting activity just needs to be in the visible paused state until the
1136                // over is removed.
1137                mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
1138                // Go ahead and tell window manager to execute app transition for this activity
1139                // since the app transition will not be triggered through the resume channel.
1140                mWindowManager.executeAppTransition();
1141            } else {
1142                mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
1143                        mOptions);
1144            }
1145        } else {
1146            mTargetStack.addRecentActivityLocked(mStartActivity);
1147        }
1148        mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);
1149
1150        mSupervisor.handleNonResizableTaskIfNeeded(
1151                mStartActivity.task, preferredLaunchStackId, mTargetStack.mStackId);
1152
1153        return START_SUCCESS;
1154    }
1155
1156    private void setInitialState(ActivityRecord r, ActivityOptions options, TaskRecord inTask,
1157            boolean doResume, int startFlags, ActivityRecord sourceRecord,
1158            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
1159        reset();
1160
1161        mStartActivity = r;
1162        mIntent = r.intent;
1163        mOptions = options;
1164        mCallingUid = r.launchedFromUid;
1165        mSourceRecord = sourceRecord;
1166        mVoiceSession = voiceSession;
1167        mVoiceInteractor = voiceInteractor;
1168
1169        mLaunchBounds = getOverrideBounds(r, options, inTask);
1170
1171        mLaunchSingleTop = r.launchMode == LAUNCH_SINGLE_TOP;
1172        mLaunchSingleInstance = r.launchMode == LAUNCH_SINGLE_INSTANCE;
1173        mLaunchSingleTask = r.launchMode == LAUNCH_SINGLE_TASK;
1174        mLaunchFlags = adjustLaunchFlagsToDocumentMode(
1175                r, mLaunchSingleInstance, mLaunchSingleTask, mIntent.getFlags());
1176        mLaunchTaskBehind = r.mLaunchTaskBehind
1177                && !mLaunchSingleTask && !mLaunchSingleInstance
1178                && (mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0;
1179
1180        sendNewTaskResultRequestIfNeeded();
1181
1182        if ((mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
1183            mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1184        }
1185
1186        // If we are actually going to launch in to a new task, there are some cases where
1187        // we further want to do multiple task.
1188        if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1189            if (mLaunchTaskBehind
1190                    || r.info.documentLaunchMode == DOCUMENT_LAUNCH_ALWAYS) {
1191                mLaunchFlags |= FLAG_ACTIVITY_MULTIPLE_TASK;
1192            }
1193        }
1194
1195        // We'll invoke onUserLeaving before onPause only if the launching
1196        // activity did not explicitly state that this is an automated launch.
1197        mSupervisor.mUserLeaving = (mLaunchFlags & FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1198        if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
1199                "startActivity() => mUserLeaving=" + mSupervisor.mUserLeaving);
1200
1201        // If the caller has asked not to resume at this point, we make note
1202        // of this in the record so that we can skip it when trying to find
1203        // the top running activity.
1204        mDoResume = doResume;
1205        if (!doResume || !mSupervisor.okToShowLocked(r)) {
1206            r.delayedResume = true;
1207            mDoResume = false;
1208        }
1209
1210        if (mOptions != null && mOptions.getLaunchTaskId() != -1 && mOptions.getTaskOverlay()) {
1211            r.mTaskOverlay = true;
1212            final TaskRecord task = mSupervisor.anyTaskForIdLocked(mOptions.getLaunchTaskId());
1213            final ActivityRecord top = task != null ? task.getTopActivity() : null;
1214            if (top != null && !top.visible) {
1215
1216                // The caller specifies that we'd like to be avoided to be moved to the front, so be
1217                // it!
1218                mDoResume = false;
1219                mAvoidMoveToFront = true;
1220            }
1221        }
1222
1223        mNotTop = (mLaunchFlags & FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1224
1225        mInTask = inTask;
1226        // In some flows in to this function, we retrieve the task record and hold on to it
1227        // without a lock before calling back in to here...  so the task at this point may
1228        // not actually be in recents.  Check for that, and if it isn't in recents just
1229        // consider it invalid.
1230        if (inTask != null && !inTask.inRecents) {
1231            Slog.w(TAG, "Starting activity in task not in recents: " + inTask);
1232            mInTask = null;
1233        }
1234
1235        mStartFlags = startFlags;
1236        // If the onlyIfNeeded flag is set, then we can do this if the activity being launched
1237        // is the same as the one making the call...  or, as a special case, if we do not know
1238        // the caller then we count the current top activity as the caller.
1239        if ((startFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1240            ActivityRecord checkedCaller = sourceRecord;
1241            if (checkedCaller == null) {
1242                checkedCaller = mSupervisor.mFocusedStack.topRunningNonDelayedActivityLocked(
1243                        mNotTop);
1244            }
1245            if (!checkedCaller.realActivity.equals(r.realActivity)) {
1246                // Caller is not the same as launcher, so always needed.
1247                mStartFlags &= ~START_FLAG_ONLY_IF_NEEDED;
1248            }
1249        }
1250
1251        mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0;
1252    }
1253
1254    private void sendNewTaskResultRequestIfNeeded() {
1255        if (mStartActivity.resultTo != null && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0
1256                && mStartActivity.resultTo.task.stack != null) {
1257            // For whatever reason this activity is being launched into a new task...
1258            // yet the caller has requested a result back.  Well, that is pretty messed up,
1259            // so instead immediately send back a cancel and let the new task continue launched
1260            // as normal without a dependency on its originator.
1261            Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1262            mStartActivity.resultTo.task.stack.sendActivityResultLocked(-1, mStartActivity.resultTo,
1263                    mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED, null);
1264            mStartActivity.resultTo = null;
1265        }
1266    }
1267
1268    private void computeLaunchingTaskFlags() {
1269        // If the caller is not coming from another activity, but has given us an explicit task into
1270        // which they would like us to launch the new activity, then let's see about doing that.
1271        if (mSourceRecord == null && mInTask != null && mInTask.stack != null) {
1272            final Intent baseIntent = mInTask.getBaseIntent();
1273            final ActivityRecord root = mInTask.getRootActivity();
1274            if (baseIntent == null) {
1275                ActivityOptions.abort(mOptions);
1276                throw new IllegalArgumentException("Launching into task without base intent: "
1277                        + mInTask);
1278            }
1279
1280            // If this task is empty, then we are adding the first activity -- it
1281            // determines the root, and must be launching as a NEW_TASK.
1282            if (mLaunchSingleInstance || mLaunchSingleTask) {
1283                if (!baseIntent.getComponent().equals(mStartActivity.intent.getComponent())) {
1284                    ActivityOptions.abort(mOptions);
1285                    throw new IllegalArgumentException("Trying to launch singleInstance/Task "
1286                            + mStartActivity + " into different task " + mInTask);
1287                }
1288                if (root != null) {
1289                    ActivityOptions.abort(mOptions);
1290                    throw new IllegalArgumentException("Caller with mInTask " + mInTask
1291                            + " has root " + root + " but target is singleInstance/Task");
1292                }
1293            }
1294
1295            // If task is empty, then adopt the interesting intent launch flags in to the
1296            // activity being started.
1297            if (root == null) {
1298                final int flagsOfInterest = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK
1299                        | FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS;
1300                mLaunchFlags = (mLaunchFlags & ~flagsOfInterest)
1301                        | (baseIntent.getFlags() & flagsOfInterest);
1302                mIntent.setFlags(mLaunchFlags);
1303                mInTask.setIntent(mStartActivity);
1304                mAddingToTask = true;
1305
1306                // If the task is not empty and the caller is asking to start it as the root of
1307                // a new task, then we don't actually want to start this on the task. We will
1308                // bring the task to the front, and possibly give it a new intent.
1309            } else if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1310                mAddingToTask = false;
1311
1312            } else {
1313                mAddingToTask = true;
1314            }
1315
1316            mReuseTask = mInTask;
1317        } else {
1318            mInTask = null;
1319            // Launch ResolverActivity in the source task, so that it stays in the task bounds
1320            // when in freeform workspace.
1321            // Also put noDisplay activities in the source task. These by itself can be placed
1322            // in any task/stack, however it could launch other activities like ResolverActivity,
1323            // and we want those to stay in the original task.
1324            if ((mStartActivity.isResolverActivity() || mStartActivity.noDisplay) && mSourceRecord != null
1325                    && mSourceRecord.isFreeform())  {
1326                mAddingToTask = true;
1327            }
1328        }
1329
1330        if (mInTask == null) {
1331            if (mSourceRecord == null) {
1332                // This activity is not being started from another...  in this
1333                // case we -always- start a new task.
1334                if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) {
1335                    Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1336                            "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
1337                    mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1338                }
1339            } else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) {
1340                // The original activity who is starting us is running as a single
1341                // instance...  this new activity it is starting must go on its
1342                // own task.
1343                mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1344            } else if (mLaunchSingleInstance || mLaunchSingleTask) {
1345                // The activity being started is a single instance...  it always
1346                // gets launched into its own task.
1347                mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1348            }
1349        }
1350    }
1351
1352    private void computeSourceStack() {
1353        if (mSourceRecord == null) {
1354            mSourceStack = null;
1355            return;
1356        }
1357        if (!mSourceRecord.finishing) {
1358            mSourceStack = mSourceRecord.task.stack;
1359            return;
1360        }
1361
1362        // If the source is finishing, we can't further count it as our source. This is because the
1363        // task it is associated with may now be empty and on its way out, so we don't want to
1364        // blindly throw it in to that task.  Instead we will take the NEW_TASK flow and try to find
1365        // a task for it. But save the task information so it can be used when creating the new task.
1366        if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0) {
1367            Slog.w(TAG, "startActivity called from finishing " + mSourceRecord
1368                    + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
1369            mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1370            mNewTaskInfo = mSourceRecord.info;
1371            mNewTaskIntent = mSourceRecord.task.intent;
1372        }
1373        mSourceRecord = null;
1374        mSourceStack = null;
1375    }
1376
1377    /**
1378     * Decide whether the new activity should be inserted into an existing task. Returns null
1379     * if not or an ActivityRecord with the task into which the new activity should be added.
1380     */
1381    private ActivityRecord getReusableIntentActivity() {
1382        // We may want to try to place the new activity in to an existing task.  We always
1383        // do this if the target activity is singleTask or singleInstance; we will also do
1384        // this if NEW_TASK has been requested, and there is not an additional qualifier telling
1385        // us to still place it in a new task: multi task, always doc mode, or being asked to
1386        // launch this as a new task behind the current one.
1387        boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 &&
1388                (mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1389                || mLaunchSingleInstance || mLaunchSingleTask;
1390        // If bring to front is requested, and no result is requested and we have not been given
1391        // an explicit task to launch in to, and we can find a task that was started with this
1392        // same component, then instead of launching bring that one to the front.
1393        putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null;
1394        ActivityRecord intentActivity = null;
1395        if (mOptions != null && mOptions.getLaunchTaskId() != -1) {
1396            final TaskRecord task = mSupervisor.anyTaskForIdLocked(mOptions.getLaunchTaskId());
1397            intentActivity = task != null ? task.getTopActivity() : null;
1398        } else if (putIntoExistingTask) {
1399            if (mLaunchSingleInstance) {
1400                // There can be one and only one instance of single instance activity in the
1401                // history, and it is always in its own unique task, so we do a special search.
1402               intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info);
1403            } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
1404                // For the launch adjacent case we only want to put the activity in an existing
1405                // task if the activity already exists in the history.
1406                intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info);
1407            } else {
1408                // Otherwise find the best task to put the activity in.
1409                intentActivity = mSupervisor.findTaskLocked(mStartActivity);
1410            }
1411        }
1412        return intentActivity;
1413    }
1414
1415    private ActivityRecord setTargetStackAndMoveToFrontIfNeeded(ActivityRecord intentActivity) {
1416        mTargetStack = intentActivity.task.stack;
1417        mTargetStack.mLastPausedActivity = null;
1418        // If the target task is not in the front, then we need to bring it to the front...
1419        // except...  well, with SINGLE_TASK_LAUNCH it's not entirely clear. We'd like to have
1420        // the same behavior as if a new instance was being started, which means not bringing it
1421        // to the front if the caller is not itself in the front.
1422        final ActivityStack focusStack = mSupervisor.getFocusedStack();
1423        ActivityRecord curTop = (focusStack == null)
1424                ? null : focusStack.topRunningNonDelayedActivityLocked(mNotTop);
1425
1426        if (curTop != null
1427                && (curTop.task != intentActivity.task || curTop.task != focusStack.topTask())
1428                && !mAvoidMoveToFront) {
1429            mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
1430            if (mSourceRecord == null || (mSourceStack.topActivity() != null &&
1431                    mSourceStack.topActivity().task == mSourceRecord.task)) {
1432                // We really do want to push this one into the user's face, right now.
1433                if (mLaunchTaskBehind && mSourceRecord != null) {
1434                    intentActivity.setTaskToAffiliateWith(mSourceRecord.task);
1435                }
1436                mMovedHome = true;
1437
1438                // If the launch flags carry both NEW_TASK and CLEAR_TASK, the task's activities
1439                // will be cleared soon by ActivityStarter in setTaskFromIntentActivity().
1440                // So no point resuming any of the activities here, it just wastes one extra
1441                // resuming, plus enter AND exit transitions.
1442                // Here we only want to bring the target stack forward. Transition will be applied
1443                // to the new activity that's started after the old ones are gone.
1444                final boolean willClearTask =
1445                        (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1446                            == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
1447                if (!willClearTask) {
1448                    final ActivityStack launchStack = getLaunchStack(
1449                            mStartActivity, mLaunchFlags, mStartActivity.task, mOptions);
1450                    if (launchStack == null || launchStack == mTargetStack) {
1451                        // We only want to move to the front, if we aren't going to launch on a
1452                        // different stack. If we launch on a different stack, we will put the
1453                        // task on top there.
1454                        mTargetStack.moveTaskToFrontLocked(
1455                                intentActivity.task, mNoAnimation, mOptions,
1456                                mStartActivity.appTimeTracker, "bringingFoundTaskToFront");
1457                        mMovedToFront = true;
1458                    } else if ((launchStack.mStackId == DOCKED_STACK_ID
1459                            || launchStack.mStackId == FULLSCREEN_WORKSPACE_STACK_ID)
1460                            && (mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
1461                        // If we want to launch adjacent and mTargetStack is not the computed
1462                        // launch stack - move task to top of computed stack.
1463                        mSupervisor.moveTaskToStackLocked(intentActivity.task.taskId,
1464                                launchStack.mStackId, ON_TOP, FORCE_FOCUS, "launchToSide",
1465                                ANIMATE);
1466                        mMovedToFront = true;
1467                    }
1468                    mOptions = null;
1469                }
1470                updateTaskReturnToType(intentActivity.task, mLaunchFlags, focusStack);
1471            }
1472        }
1473        if (!mMovedToFront && mDoResume) {
1474            if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Bring to front target: " + mTargetStack
1475                    + " from " + intentActivity);
1476            mTargetStack.moveToFront("intentActivityFound");
1477        }
1478
1479        mSupervisor.handleNonResizableTaskIfNeeded(intentActivity.task, INVALID_STACK_ID,
1480                mTargetStack.mStackId);
1481
1482        // If the caller has requested that the target task be reset, then do so.
1483        if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1484            return mTargetStack.resetTaskIfNeededLocked(intentActivity, mStartActivity);
1485        }
1486        return intentActivity;
1487    }
1488
1489    private void updateTaskReturnToType(
1490            TaskRecord task, int launchFlags, ActivityStack focusedStack) {
1491        if ((launchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1492                == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
1493            // Caller wants to appear on home activity.
1494            task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
1495            return;
1496        } else if (focusedStack == null || focusedStack.mStackId == HOME_STACK_ID) {
1497            // Task will be launched over the home stack, so return home.
1498            task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
1499            return;
1500        }
1501
1502        // Else we are coming from an application stack so return to an application.
1503        task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
1504    }
1505
1506    private void setTaskFromIntentActivity(ActivityRecord intentActivity) {
1507        if ((mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1508                == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {
1509            // The caller has requested to completely replace any existing task with its new
1510            // activity. Well that should not be too hard...
1511            mReuseTask = intentActivity.task;
1512            mReuseTask.performClearTaskLocked();
1513            mReuseTask.setIntent(mStartActivity);
1514        } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
1515                || mLaunchSingleInstance || mLaunchSingleTask) {
1516            ActivityRecord top = intentActivity.task.performClearTaskLocked(mStartActivity,
1517                    mLaunchFlags);
1518            if (top == null) {
1519                // A special case: we need to start the activity because it is not currently
1520                // running, and the caller has asked to clear the current task to have this
1521                // activity at the top.
1522                mAddingToTask = true;
1523                // Now pretend like this activity is being started by the top of its task, so it
1524                // is put in the right place.
1525                mSourceRecord = intentActivity;
1526                final TaskRecord task = mSourceRecord.task;
1527                if (task != null && task.stack == null) {
1528                    // Target stack got cleared when we all activities were removed above.
1529                    // Go ahead and reset it.
1530                    mTargetStack = computeStackFocus(mSourceRecord, false /* newTask */,
1531                            null /* bounds */, mLaunchFlags, mOptions);
1532                    mTargetStack.addTask(task,
1533                            !mLaunchTaskBehind /* toTop */, "startActivityUnchecked");
1534                }
1535            }
1536        } else if (mStartActivity.realActivity.equals(intentActivity.task.realActivity)) {
1537            // In this case the top activity on the task is the same as the one being launched,
1538            // so we take that as a request to bring the task to the foreground. If the top
1539            // activity in the task is the root activity, deliver this new intent to it if it
1540            // desires.
1541            if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0 || mLaunchSingleTop)
1542                    && intentActivity.realActivity.equals(mStartActivity.realActivity)) {
1543                ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity,
1544                        intentActivity.task);
1545                if (intentActivity.frontOfTask) {
1546                    intentActivity.task.setIntent(mStartActivity);
1547                }
1548                intentActivity.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
1549                        mStartActivity.launchedFromPackage);
1550            } else if (!intentActivity.task.isSameIntentResolution(mStartActivity)) {
1551                // In this case we are launching the root activity of the task, but with a
1552                // different intent. We should start a new instance on top.
1553                mAddingToTask = true;
1554                mSourceRecord = intentActivity;
1555            }
1556        } else if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1557            // In this case an activity is being launched in to an existing task, without
1558            // resetting that task. This is typically the situation of launching an activity
1559            // from a notification or shortcut. We want to place the new activity on top of the
1560            // current task.
1561            mAddingToTask = true;
1562            mSourceRecord = intentActivity;
1563        } else if (!intentActivity.task.rootWasReset) {
1564            // In this case we are launching into an existing task that has not yet been started
1565            // from its front door. The current task has been brought to the front. Ideally,
1566            // we'd probably like to place this new task at the bottom of its stack, but that's
1567            // a little hard to do with the current organization of the code so for now we'll
1568            // just drop it.
1569            intentActivity.task.setIntent(mStartActivity);
1570        }
1571    }
1572
1573    private void resumeTargetStackIfNeeded() {
1574        if (mDoResume) {
1575            mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, null, mOptions);
1576            if (!mMovedToFront) {
1577                // Make sure to notify Keyguard as well if we are not running an app transition
1578                // later.
1579                mSupervisor.notifyActivityDrawnForKeyguard();
1580            }
1581        } else {
1582            ActivityOptions.abort(mOptions);
1583        }
1584        mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);
1585    }
1586
1587    private void setTaskFromReuseOrCreateNewTask(TaskRecord taskToAffiliate) {
1588        mTargetStack = computeStackFocus(mStartActivity, true, mLaunchBounds, mLaunchFlags,
1589                mOptions);
1590
1591        if (mReuseTask == null) {
1592            final TaskRecord task = mTargetStack.createTaskRecord(
1593                    mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId),
1594                    mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
1595                    mNewTaskIntent != null ? mNewTaskIntent : mIntent,
1596                    mVoiceSession, mVoiceInteractor, !mLaunchTaskBehind /* toTop */);
1597            mStartActivity.setTask(task, taskToAffiliate);
1598            if (mLaunchBounds != null) {
1599                final int stackId = mTargetStack.mStackId;
1600                if (StackId.resizeStackWithLaunchBounds(stackId)) {
1601                    mService.resizeStack(
1602                            stackId, mLaunchBounds, true, !PRESERVE_WINDOWS, ANIMATE, -1);
1603                } else {
1604                    mStartActivity.task.updateOverrideConfiguration(mLaunchBounds);
1605                }
1606            }
1607            if (DEBUG_TASKS) Slog.v(TAG_TASKS,
1608                    "Starting new activity " +
1609                            mStartActivity + " in new task " + mStartActivity.task);
1610        } else {
1611            mStartActivity.setTask(mReuseTask, taskToAffiliate);
1612        }
1613    }
1614
1615    private int setTaskFromSourceRecord() {
1616        final TaskRecord sourceTask = mSourceRecord.task;
1617        // We only want to allow changing stack if the target task is not the top one,
1618        // otherwise we would move the launching task to the other side, rather than show
1619        // two side by side.
1620        final boolean moveStackAllowed = sourceTask.stack.topTask() != sourceTask;
1621        if (moveStackAllowed) {
1622            mTargetStack = getLaunchStack(mStartActivity, mLaunchFlags, mStartActivity.task,
1623                    mOptions);
1624        }
1625
1626        if (mTargetStack == null) {
1627            mTargetStack = sourceTask.stack;
1628        } else if (mTargetStack != sourceTask.stack) {
1629            mSupervisor.moveTaskToStackLocked(sourceTask.taskId, mTargetStack.mStackId,
1630                    ON_TOP, FORCE_FOCUS, "launchToSide", !ANIMATE);
1631        }
1632        if (mDoResume) {
1633            mTargetStack.moveToFront("sourceStackToFront");
1634        }
1635        final TaskRecord topTask = mTargetStack.topTask();
1636        if (topTask != sourceTask && !mAvoidMoveToFront) {
1637            mTargetStack.moveTaskToFrontLocked(sourceTask, mNoAnimation, mOptions,
1638                    mStartActivity.appTimeTracker, "sourceTaskToFront");
1639        }
1640        if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1641            // In this case, we are adding the activity to an existing task, but the caller has
1642            // asked to clear that task if the activity is already running.
1643            ActivityRecord top = sourceTask.performClearTaskLocked(mStartActivity, mLaunchFlags);
1644            mKeepCurTransition = true;
1645            if (top != null) {
1646                ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, top.task);
1647                top.deliverNewIntentLocked(mCallingUid, mStartActivity.intent, mStartActivity.launchedFromPackage);
1648                // For paranoia, make sure we have correctly resumed the top activity.
1649                mTargetStack.mLastPausedActivity = null;
1650                if (mDoResume) {
1651                    mSupervisor.resumeFocusedStackTopActivityLocked();
1652                }
1653                ActivityOptions.abort(mOptions);
1654                return START_DELIVERED_TO_TOP;
1655            }
1656        } else if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1657            // In this case, we are launching an activity in our own task that may already be
1658            // running somewhere in the history, and we want to shuffle it to the front of the
1659            // stack if so.
1660            final ActivityRecord top = sourceTask.findActivityInHistoryLocked(mStartActivity);
1661            if (top != null) {
1662                final TaskRecord task = top.task;
1663                task.moveActivityToFrontLocked(top);
1664                top.updateOptionsLocked(mOptions);
1665                ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, task);
1666                top.deliverNewIntentLocked(mCallingUid, mStartActivity.intent, mStartActivity.launchedFromPackage);
1667                mTargetStack.mLastPausedActivity = null;
1668                if (mDoResume) {
1669                    mSupervisor.resumeFocusedStackTopActivityLocked();
1670                }
1671                return START_DELIVERED_TO_TOP;
1672            }
1673        }
1674
1675        // An existing activity is starting this new activity, so we want to keep the new one in
1676        // the same task as the one that is starting it.
1677        mStartActivity.setTask(sourceTask, null);
1678        if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
1679                + " in existing task " + mStartActivity.task + " from source " + mSourceRecord);
1680        return START_SUCCESS;
1681    }
1682
1683    private int setTaskFromInTask() {
1684        if (mLaunchBounds != null) {
1685            mInTask.updateOverrideConfiguration(mLaunchBounds);
1686            int stackId = mInTask.getLaunchStackId();
1687            if (stackId != mInTask.stack.mStackId) {
1688                final ActivityStack stack = mSupervisor.moveTaskToStackUncheckedLocked(
1689                        mInTask, stackId, ON_TOP, !FORCE_FOCUS, "inTaskToFront");
1690                stackId = stack.mStackId;
1691            }
1692            if (StackId.resizeStackWithLaunchBounds(stackId)) {
1693                mService.resizeStack(stackId, mLaunchBounds, true, !PRESERVE_WINDOWS, ANIMATE, -1);
1694            }
1695        }
1696        mTargetStack = mInTask.stack;
1697        mTargetStack.moveTaskToFrontLocked(
1698                mInTask, mNoAnimation, mOptions, mStartActivity.appTimeTracker, "inTaskToFront");
1699
1700        // Check whether we should actually launch the new activity in to the task,
1701        // or just reuse the current activity on top.
1702        ActivityRecord top = mInTask.getTopActivity();
1703        if (top != null && top.realActivity.equals(mStartActivity.realActivity) && top.userId == mStartActivity.userId) {
1704            if ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
1705                    || mLaunchSingleTop || mLaunchSingleTask) {
1706                ActivityStack.logStartActivity(AM_NEW_INTENT, top, top.task);
1707                if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1708                    // We don't need to start a new activity, and the client said not to do
1709                    // anything if that is the case, so this is it!
1710                    return START_RETURN_INTENT_TO_CALLER;
1711                }
1712                top.deliverNewIntentLocked(mCallingUid, mStartActivity.intent, mStartActivity.launchedFromPackage);
1713                return START_DELIVERED_TO_TOP;
1714            }
1715        }
1716
1717        if (!mAddingToTask) {
1718            // We don't actually want to have this activity added to the task, so just
1719            // stop here but still tell the caller that we consumed the intent.
1720            ActivityOptions.abort(mOptions);
1721            return START_TASK_TO_FRONT;
1722        }
1723
1724        mStartActivity.setTask(mInTask, null);
1725        if (DEBUG_TASKS) Slog.v(TAG_TASKS,
1726                "Starting new activity " + mStartActivity + " in explicit task " + mStartActivity.task);
1727
1728        return START_SUCCESS;
1729    }
1730
1731    private void setTaskToCurrentTopOrCreateNewTask() {
1732        mTargetStack = computeStackFocus(mStartActivity, false, null /* bounds */, mLaunchFlags,
1733                mOptions);
1734        if (mDoResume) {
1735            mTargetStack.moveToFront("addingToTopTask");
1736        }
1737        final ActivityRecord prev = mTargetStack.topActivity();
1738        final TaskRecord task = (prev != null) ? prev.task : mTargetStack.createTaskRecord(
1739                        mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId),
1740                        mStartActivity.info, mIntent, null, null, true);
1741        mStartActivity.setTask(task, null);
1742        mWindowManager.moveTaskToTop(mStartActivity.task.taskId);
1743        if (DEBUG_TASKS) Slog.v(TAG_TASKS,
1744                "Starting new activity " + mStartActivity + " in new guessed " + mStartActivity.task);
1745    }
1746
1747    private int adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance,
1748            boolean launchSingleTask, int launchFlags) {
1749        if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
1750                (launchSingleInstance || launchSingleTask)) {
1751            // We have a conflict between the Intent and the Activity manifest, manifest wins.
1752            Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " +
1753                    "\"singleInstance\" or \"singleTask\"");
1754            launchFlags &=
1755                    ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK);
1756        } else {
1757            switch (r.info.documentLaunchMode) {
1758                case ActivityInfo.DOCUMENT_LAUNCH_NONE:
1759                    break;
1760                case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
1761                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
1762                    break;
1763                case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
1764                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
1765                    break;
1766                case ActivityInfo.DOCUMENT_LAUNCH_NEVER:
1767                    launchFlags &= ~FLAG_ACTIVITY_MULTIPLE_TASK;
1768                    break;
1769            }
1770        }
1771        return launchFlags;
1772    }
1773
1774    final void doPendingActivityLaunchesLocked(boolean doResume) {
1775        while (!mPendingActivityLaunches.isEmpty()) {
1776            final PendingActivityLaunch pal = mPendingActivityLaunches.remove(0);
1777            final boolean resume = doResume && mPendingActivityLaunches.isEmpty();
1778            try {
1779                final int result = startActivityUnchecked(
1780                        pal.r, pal.sourceRecord, null, null, pal.startFlags, resume, null, null);
1781                postStartActivityUncheckedProcessing(
1782                        pal.r, result, mSupervisor.mFocusedStack.mStackId);
1783            } catch (Exception e) {
1784                Slog.e(TAG, "Exception during pending activity launch pal=" + pal, e);
1785                pal.sendErrorResult(e.getMessage());
1786            }
1787        }
1788    }
1789
1790    private ActivityStack computeStackFocus(ActivityRecord r, boolean newTask, Rect bounds,
1791            int launchFlags, ActivityOptions aOptions) {
1792        final TaskRecord task = r.task;
1793        if (!(r.isApplicationActivity() || (task != null && task.isApplicationTask()))) {
1794            return mSupervisor.mHomeStack;
1795        }
1796
1797        ActivityStack stack = getLaunchStack(r, launchFlags, task, aOptions);
1798        if (stack != null) {
1799            return stack;
1800        }
1801
1802        if (task != null && task.stack != null) {
1803            stack = task.stack;
1804            if (stack.isOnHomeDisplay()) {
1805                if (mSupervisor.mFocusedStack != stack) {
1806                    if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
1807                            "computeStackFocus: Setting " + "focused stack to r=" + r
1808                                    + " task=" + task);
1809                } else {
1810                    if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
1811                            "computeStackFocus: Focused stack already="
1812                                    + mSupervisor.mFocusedStack);
1813                }
1814            }
1815            return stack;
1816        }
1817
1818        final ActivityStackSupervisor.ActivityContainer container = r.mInitialActivityContainer;
1819        if (container != null) {
1820            // The first time put it on the desired stack, after this put on task stack.
1821            r.mInitialActivityContainer = null;
1822            return container.mStack;
1823        }
1824
1825        // The fullscreen stack can contain any task regardless of if the task is resizeable
1826        // or not. So, we let the task go in the fullscreen task if it is the focus stack.
1827        // If the freeform or docked stack has focus, and the activity to be launched is resizeable,
1828        // we can also put it in the focused stack.
1829        final int focusedStackId = mSupervisor.mFocusedStack.mStackId;
1830        final boolean canUseFocusedStack = focusedStackId == FULLSCREEN_WORKSPACE_STACK_ID
1831                || (focusedStackId == DOCKED_STACK_ID && r.canGoInDockedStack())
1832                || (focusedStackId == FREEFORM_WORKSPACE_STACK_ID && r.isResizeableOrForced());
1833        if (canUseFocusedStack && (!newTask
1834                || mSupervisor.mFocusedStack.mActivityContainer.isEligibleForNewTasks())) {
1835            if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
1836                    "computeStackFocus: Have a focused stack=" + mSupervisor.mFocusedStack);
1837            return mSupervisor.mFocusedStack;
1838        }
1839
1840        // We first try to put the task in the first dynamic stack.
1841        final ArrayList<ActivityStack> homeDisplayStacks = mSupervisor.mHomeStack.mStacks;
1842        for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1843            stack = homeDisplayStacks.get(stackNdx);
1844            if (!ActivityManager.StackId.isStaticStack(stack.mStackId)) {
1845                if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
1846                        "computeStackFocus: Setting focused stack=" + stack);
1847                return stack;
1848            }
1849        }
1850
1851        // If there is no suitable dynamic stack then we figure out which static stack to use.
1852        final int stackId = task != null ? task.getLaunchStackId() :
1853                bounds != null ? FREEFORM_WORKSPACE_STACK_ID :
1854                        FULLSCREEN_WORKSPACE_STACK_ID;
1855        stack = mSupervisor.getStack(stackId, CREATE_IF_NEEDED, ON_TOP);
1856        if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, "computeStackFocus: New stack r="
1857                + r + " stackId=" + stack.mStackId);
1858        return stack;
1859    }
1860
1861    private ActivityStack getLaunchStack(ActivityRecord r, int launchFlags, TaskRecord task,
1862            ActivityOptions aOptions) {
1863
1864        // We are reusing a task, keep the stack!
1865        if (mReuseTask != null) {
1866            return mReuseTask.stack;
1867        }
1868
1869        final int launchStackId =
1870                (aOptions != null) ? aOptions.getLaunchStackId() : INVALID_STACK_ID;
1871
1872        if (isValidLaunchStackId(launchStackId, r)) {
1873            return mSupervisor.getStack(launchStackId, CREATE_IF_NEEDED, ON_TOP);
1874        } else if (launchStackId == DOCKED_STACK_ID) {
1875            // The preferred launch stack is the docked stack, but it isn't a valid launch stack
1876            // for this activity, so we put the activity in the fullscreen stack.
1877            return mSupervisor.getStack(FULLSCREEN_WORKSPACE_STACK_ID, CREATE_IF_NEEDED, ON_TOP);
1878        }
1879
1880        if ((launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) == 0) {
1881            return null;
1882        }
1883        // Otherwise handle adjacent launch.
1884
1885        // The parent activity doesn't want to launch the activity on top of itself, but
1886        // instead tries to put it onto other side in side-by-side mode.
1887        final ActivityStack parentStack = task != null ? task.stack
1888                : r.mInitialActivityContainer != null ? r.mInitialActivityContainer.mStack
1889                : mSupervisor.mFocusedStack;
1890
1891        if (parentStack != mSupervisor.mFocusedStack) {
1892            // If task's parent stack is not focused - use it during adjacent launch.
1893            return parentStack;
1894        } else {
1895            if (mSupervisor.mFocusedStack != null && task == mSupervisor.mFocusedStack.topTask()) {
1896                // If task is already on top of focused stack - use it. We don't want to move the
1897                // existing focused task to adjacent stack, just deliver new intent in this case.
1898                return mSupervisor.mFocusedStack;
1899            }
1900
1901            if (parentStack != null && parentStack.mStackId == DOCKED_STACK_ID) {
1902                // If parent was in docked stack, the natural place to launch another activity
1903                // will be fullscreen, so it can appear alongside the docked window.
1904                return mSupervisor.getStack(FULLSCREEN_WORKSPACE_STACK_ID, CREATE_IF_NEEDED,
1905                        ON_TOP);
1906            } else {
1907                // If the parent is not in the docked stack, we check if there is docked window
1908                // and if yes, we will launch into that stack. If not, we just put the new
1909                // activity into parent's stack, because we can't find a better place.
1910                final ActivityStack dockedStack = mSupervisor.getStack(DOCKED_STACK_ID);
1911                if (dockedStack != null
1912                        && dockedStack.getStackVisibilityLocked(r) == STACK_INVISIBLE) {
1913                    // There is a docked stack, but it isn't visible, so we can't launch into that.
1914                    return null;
1915                } else {
1916                    return dockedStack;
1917                }
1918            }
1919        }
1920    }
1921
1922    private boolean isValidLaunchStackId(int stackId, ActivityRecord r) {
1923        if (stackId == INVALID_STACK_ID || stackId == HOME_STACK_ID
1924                || !StackId.isStaticStack(stackId)) {
1925            return false;
1926        }
1927
1928        if (stackId != FULLSCREEN_WORKSPACE_STACK_ID
1929                && (!mService.mSupportsMultiWindow || !r.isResizeableOrForced())) {
1930            return false;
1931        }
1932
1933        if (stackId == DOCKED_STACK_ID && r.canGoInDockedStack()) {
1934            return true;
1935        }
1936
1937        if (stackId == FREEFORM_WORKSPACE_STACK_ID && !mService.mSupportsFreeformWindowManagement) {
1938            return false;
1939        }
1940
1941        final boolean supportsPip = mService.mSupportsPictureInPicture
1942                && (r.supportsPictureInPicture() || mService.mForceResizableActivities);
1943        if (stackId == PINNED_STACK_ID && !supportsPip) {
1944            return false;
1945        }
1946        return true;
1947    }
1948
1949    Rect getOverrideBounds(ActivityRecord r, ActivityOptions options, TaskRecord inTask) {
1950        Rect newBounds = null;
1951        if (options != null && (r.isResizeable() || (inTask != null && inTask.isResizeable()))) {
1952            if (mSupervisor.canUseActivityOptionsLaunchBounds(
1953                    options, options.getLaunchStackId())) {
1954                newBounds = TaskRecord.validateBounds(options.getLaunchBounds());
1955            }
1956        }
1957        return newBounds;
1958    }
1959
1960    void setWindowManager(WindowManagerService wm) {
1961        mWindowManager = wm;
1962    }
1963
1964    void removePendingActivityLaunchesLocked(ActivityStack stack) {
1965        for (int palNdx = mPendingActivityLaunches.size() - 1; palNdx >= 0; --palNdx) {
1966            PendingActivityLaunch pal = mPendingActivityLaunches.get(palNdx);
1967            if (pal.stack == stack) {
1968                mPendingActivityLaunches.remove(palNdx);
1969            }
1970        }
1971    }
1972}
1973