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