OSDN Git Service

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