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