OSDN Git Service

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