OSDN Git Service

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