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