OSDN Git Service

Limit IsSeparateProfileChallengeAllowed to system callers
[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_ABORTED;
21 import static android.app.ActivityManager.START_CANCELED;
22 import static android.app.ActivityManager.START_CLASS_NOT_FOUND;
23 import static android.app.ActivityManager.START_DELIVERED_TO_TOP;
24 import static android.app.ActivityManager.START_FLAG_ONLY_IF_NEEDED;
25 import static android.app.ActivityManager.START_RETURN_INTENT_TO_CALLER;
26 import static android.app.ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
27 import static android.app.ActivityManager.START_SUCCESS;
28 import static android.app.ActivityManager.START_TASK_TO_FRONT;
29 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
30 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
31 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
32 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
33 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
34 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
35 import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
36 import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
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.pm.ActivityInfo.DOCUMENT_LAUNCH_ALWAYS;
49 import static android.content.pm.ActivityInfo.LAUNCH_MULTIPLE;
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 android.view.Display.DEFAULT_DISPLAY;
54 import static android.view.Display.INVALID_DISPLAY;
55 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
56 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
57 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
58 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RESULTS;
59 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
60 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
61 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USER_LEAVING;
62 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
63 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
64 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RESULTS;
65 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_USER_LEAVING;
66 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
67 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
68 import static com.android.server.am.ActivityManagerService.ANIMATE;
69 import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
70 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
71 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
72 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
73 import static com.android.server.am.ActivityStackSupervisor.TAG_TASKS;
74 import static com.android.server.am.EventLogTags.AM_NEW_INTENT;
75 import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
76 import static com.android.server.am.TaskRecord.REPARENT_MOVE_STACK_TO_FRONT;
77
78 import android.annotation.NonNull;
79 import android.annotation.Nullable;
80 import android.app.ActivityManager;
81 import android.app.ActivityOptions;
82 import android.app.IApplicationThread;
83 import android.app.PendingIntent;
84 import android.app.ProfilerInfo;
85 import android.app.WaitResult;
86 import android.content.IIntentSender;
87 import android.content.Intent;
88 import android.content.IntentSender;
89 import android.content.pm.ActivityInfo;
90 import android.content.pm.ApplicationInfo;
91 import android.content.pm.AuxiliaryResolveInfo;
92 import android.content.pm.PackageManager;
93 import android.content.pm.ResolveInfo;
94 import android.content.pm.UserInfo;
95 import android.content.res.Configuration;
96 import android.graphics.Rect;
97 import android.os.Binder;
98 import android.os.Bundle;
99 import android.os.IBinder;
100 import android.os.RemoteException;
101 import android.os.SystemClock;
102 import android.os.Trace;
103 import android.os.UserHandle;
104 import android.os.UserManager;
105 import android.service.voice.IVoiceInteractionSession;
106 import android.text.TextUtils;
107 import android.util.EventLog;
108 import android.util.Pools.SynchronizedPool;
109 import android.util.Slog;
110
111 import com.android.internal.annotations.VisibleForTesting;
112 import com.android.internal.app.HeavyWeightSwitcherActivity;
113 import com.android.internal.app.IVoiceInteractor;
114 import com.android.server.am.ActivityStackSupervisor.PendingActivityLaunch;
115 import com.android.server.am.LaunchParamsController.LaunchParams;
116 import com.android.server.pm.InstantAppResolver;
117
118 import java.io.PrintWriter;
119 import java.text.DateFormat;
120 import java.util.Date;
121
122 /**
123  * Controller for interpreting how and then launching an activity.
124  *
125  * This class collects all the logic for determining how an intent and flags should be turned into
126  * an activity and associated task and stack.
127  */
128 class ActivityStarter {
129     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStarter" : TAG_AM;
130     private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS;
131     private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
132     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
133     private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING;
134     private static final int INVALID_LAUNCH_MODE = -1;
135
136     private final ActivityManagerService mService;
137     private final ActivityStackSupervisor mSupervisor;
138     private final ActivityStartInterceptor mInterceptor;
139     private final ActivityStartController mController;
140
141     // Share state variable among methods when starting an activity.
142     private ActivityRecord mStartActivity;
143     private Intent mIntent;
144     private int mCallingUid;
145     private ActivityOptions mOptions;
146
147     private int mLaunchMode;
148     private boolean mLaunchTaskBehind;
149     private int mLaunchFlags;
150
151     private LaunchParams mLaunchParams = new LaunchParams();
152
153     private ActivityRecord mNotTop;
154     private boolean mDoResume;
155     private int mStartFlags;
156     private ActivityRecord mSourceRecord;
157
158     // The display to launch the activity onto, barring any strong reason to do otherwise.
159     private int mPreferredDisplayId;
160
161     private TaskRecord mInTask;
162     private boolean mAddingToTask;
163     private TaskRecord mReuseTask;
164
165     private ActivityInfo mNewTaskInfo;
166     private Intent mNewTaskIntent;
167     private ActivityStack mSourceStack;
168     private ActivityStack mTargetStack;
169     private boolean mMovedToFront;
170     private boolean mNoAnimation;
171     private boolean mKeepCurTransition;
172     private boolean mAvoidMoveToFront;
173
174     // We must track when we deliver the new intent since multiple code paths invoke
175     // {@link #deliverNewIntent}. This is due to early returns in the code path. This flag is used
176     // inside {@link #deliverNewIntent} to suppress duplicate requests and ensure the intent is
177     // delivered at most once.
178     private boolean mIntentDelivered;
179
180     private IVoiceInteractionSession mVoiceSession;
181     private IVoiceInteractor mVoiceInteractor;
182
183     // Last activity record we attempted to start
184     private final ActivityRecord[] mLastStartActivityRecord = new ActivityRecord[1];
185     // The result of the last activity we attempted to start.
186     private int mLastStartActivityResult;
187     // Time in milli seconds we attempted to start the last activity.
188     private long mLastStartActivityTimeMs;
189     // The reason we were trying to start the last activity
190     private String mLastStartReason;
191
192     /*
193      * Request details provided through setter methods. Should be reset after {@link #execute()}
194      * to avoid unnecessarily retaining parameters. Note that the request is ignored when
195      * {@link #startResolvedActivity} is invoked directly.
196      */
197     private Request mRequest = new Request();
198
199     /**
200      * An interface that to provide {@link ActivityStarter} instances to the controller. This is
201      * used by tests to inject their own starter implementations for verification purposes.
202      */
203     @VisibleForTesting
204     interface Factory {
205         /**
206          * Sets the {@link ActivityStartController} to be passed to {@link ActivityStarter}.
207          */
208         void setController(ActivityStartController controller);
209
210         /**
211          * Generates an {@link ActivityStarter} that is ready to handle a new start request.
212          * @param controller The {@link ActivityStartController} which the starter who will own
213          *                   this instance.
214          * @return an {@link ActivityStarter}
215          */
216         ActivityStarter obtain();
217
218         /**
219          * Recycles a starter for reuse.
220          */
221         void recycle(ActivityStarter starter);
222     }
223
224     /**
225      * Default implementation of {@link StarterFactory}.
226      */
227     static class DefaultFactory implements Factory {
228         /**
229          * The maximum count of starters that should be active at one time:
230          * 1. last ran starter (for logging and post activity processing)
231          * 2. current running starter
232          * 3. starter from re-entry in (2)
233          */
234         private final int MAX_STARTER_COUNT = 3;
235
236         private ActivityStartController mController;
237         private ActivityManagerService mService;
238         private ActivityStackSupervisor mSupervisor;
239         private ActivityStartInterceptor mInterceptor;
240
241         private SynchronizedPool<ActivityStarter> mStarterPool =
242                 new SynchronizedPool<>(MAX_STARTER_COUNT);
243
244         DefaultFactory(ActivityManagerService service,
245                 ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
246             mService = service;
247             mSupervisor = supervisor;
248             mInterceptor = interceptor;
249         }
250
251         @Override
252         public void setController(ActivityStartController controller) {
253             mController = controller;
254         }
255
256         @Override
257         public ActivityStarter obtain() {
258             ActivityStarter starter = mStarterPool.acquire();
259
260             if (starter == null) {
261                 starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
262             }
263
264             return starter;
265         }
266
267         @Override
268         public void recycle(ActivityStarter starter) {
269             starter.reset(true /* clearRequest*/);
270             mStarterPool.release(starter);
271         }
272     }
273
274     /**
275      * Container for capturing initial start request details. This information is NOT reset until
276      * the {@link ActivityStarter} is recycled, allowing for multiple invocations with the same
277      * parameters.
278      *
279      * TODO(b/64750076): Investigate consolidating member variables of {@link ActivityStarter} with
280      * the request object. Note that some member variables are referenced in
281      * {@link #dump(PrintWriter, String)} and therefore cannot be cleared immediately after
282      * execution.
283      */
284     private static class Request {
285         private static final int DEFAULT_CALLING_UID = -1;
286         private static final int DEFAULT_CALLING_PID = 0;
287
288         IApplicationThread caller;
289         Intent intent;
290         Intent ephemeralIntent;
291         String resolvedType;
292         ActivityInfo activityInfo;
293         ResolveInfo resolveInfo;
294         IVoiceInteractionSession voiceSession;
295         IVoiceInteractor voiceInteractor;
296         IBinder resultTo;
297         String resultWho;
298         int requestCode;
299         int callingPid = DEFAULT_CALLING_UID;
300         int callingUid = DEFAULT_CALLING_PID;
301         String callingPackage;
302         int realCallingPid;
303         int realCallingUid;
304         int startFlags;
305         SafeActivityOptions activityOptions;
306         boolean ignoreTargetSecurity;
307         boolean componentSpecified;
308         boolean avoidMoveToFront;
309         ActivityRecord[] outActivity;
310         TaskRecord inTask;
311         String reason;
312         ProfilerInfo profilerInfo;
313         Configuration globalConfig;
314         int userId;
315         WaitResult waitResult;
316         int filterCallingUid;
317         PendingIntentRecord originatingPendingIntent;
318
319         /**
320          * If set to {@code true}, allows this activity start to look into
321          * {@link PendingRemoteAnimationRegistry}
322          */
323         boolean allowPendingRemoteAnimationRegistryLookup;
324
325         /**
326          * Indicates that we should wait for the result of the start request. This flag is set when
327          * {@link ActivityStarter#setMayWait(int)} is called.
328          * {@see ActivityStarter#startActivityMayWait}.
329          */
330         boolean mayWait;
331
332         /**
333          * Ensure constructed request matches reset instance.
334          */
335         Request() {
336             reset();
337         }
338
339         /**
340          * Sets values back to the initial state, clearing any held references.
341          */
342         void reset() {
343             caller = null;
344             intent = null;
345             ephemeralIntent = null;
346             resolvedType = null;
347             activityInfo = null;
348             resolveInfo = null;
349             voiceSession = null;
350             voiceInteractor = null;
351             resultTo = null;
352             resultWho = null;
353             requestCode = 0;
354             callingPid = DEFAULT_CALLING_PID;
355             callingUid = DEFAULT_CALLING_UID;
356             callingPackage = null;
357             realCallingPid = 0;
358             realCallingUid = 0;
359             startFlags = 0;
360             activityOptions = null;
361             ignoreTargetSecurity = false;
362             componentSpecified = false;
363             outActivity = null;
364             inTask = null;
365             reason = null;
366             profilerInfo = null;
367             globalConfig = null;
368             userId = 0;
369             waitResult = null;
370             mayWait = false;
371             avoidMoveToFront = false;
372             allowPendingRemoteAnimationRegistryLookup = true;
373             filterCallingUid = UserHandle.USER_NULL;
374             originatingPendingIntent = null;
375         }
376
377         /**
378          * Adopts all values from passed in request.
379          */
380         void set(Request request) {
381             caller = request.caller;
382             intent = request.intent;
383             ephemeralIntent = request.ephemeralIntent;
384             resolvedType = request.resolvedType;
385             activityInfo = request.activityInfo;
386             resolveInfo = request.resolveInfo;
387             voiceSession = request.voiceSession;
388             voiceInteractor = request.voiceInteractor;
389             resultTo = request.resultTo;
390             resultWho = request.resultWho;
391             requestCode = request.requestCode;
392             callingPid = request.callingPid;
393             callingUid = request.callingUid;
394             callingPackage = request.callingPackage;
395             realCallingPid = request.realCallingPid;
396             realCallingUid = request.realCallingUid;
397             startFlags = request.startFlags;
398             activityOptions = request.activityOptions;
399             ignoreTargetSecurity = request.ignoreTargetSecurity;
400             componentSpecified = request.componentSpecified;
401             outActivity = request.outActivity;
402             inTask = request.inTask;
403             reason = request.reason;
404             profilerInfo = request.profilerInfo;
405             globalConfig = request.globalConfig;
406             userId = request.userId;
407             waitResult = request.waitResult;
408             mayWait = request.mayWait;
409             avoidMoveToFront = request.avoidMoveToFront;
410             allowPendingRemoteAnimationRegistryLookup
411                     = request.allowPendingRemoteAnimationRegistryLookup;
412             filterCallingUid = request.filterCallingUid;
413             originatingPendingIntent = request.originatingPendingIntent;
414         }
415     }
416
417     ActivityStarter(ActivityStartController controller, ActivityManagerService service,
418             ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
419         mController = controller;
420         mService = service;
421         mSupervisor = supervisor;
422         mInterceptor = interceptor;
423         reset(true);
424     }
425
426     /**
427      * Effectively duplicates the starter passed in. All state and request values will be
428      * mirrored.
429      * @param starter
430      */
431     void set(ActivityStarter starter) {
432         mStartActivity = starter.mStartActivity;
433         mIntent = starter.mIntent;
434         mCallingUid = starter.mCallingUid;
435         mOptions = starter.mOptions;
436
437         mLaunchTaskBehind = starter.mLaunchTaskBehind;
438         mLaunchFlags = starter.mLaunchFlags;
439         mLaunchMode = starter.mLaunchMode;
440
441         mLaunchParams.set(starter.mLaunchParams);
442
443         mNotTop = starter.mNotTop;
444         mDoResume = starter.mDoResume;
445         mStartFlags = starter.mStartFlags;
446         mSourceRecord = starter.mSourceRecord;
447         mPreferredDisplayId = starter.mPreferredDisplayId;
448
449         mInTask = starter.mInTask;
450         mAddingToTask = starter.mAddingToTask;
451         mReuseTask = starter.mReuseTask;
452
453         mNewTaskInfo = starter.mNewTaskInfo;
454         mNewTaskIntent = starter.mNewTaskIntent;
455         mSourceStack = starter.mSourceStack;
456
457         mTargetStack = starter.mTargetStack;
458         mMovedToFront = starter.mMovedToFront;
459         mNoAnimation = starter.mNoAnimation;
460         mKeepCurTransition = starter.mKeepCurTransition;
461         mAvoidMoveToFront = starter.mAvoidMoveToFront;
462
463         mVoiceSession = starter.mVoiceSession;
464         mVoiceInteractor = starter.mVoiceInteractor;
465
466         mIntentDelivered = starter.mIntentDelivered;
467
468         mRequest.set(starter.mRequest);
469     }
470
471     ActivityRecord getStartActivity() {
472         return mStartActivity;
473     }
474
475     boolean relatedToPackage(String packageName) {
476         return (mLastStartActivityRecord[0] != null
477                 && packageName.equals(mLastStartActivityRecord[0].packageName))
478                 || (mStartActivity != null && packageName.equals(mStartActivity.packageName));
479     }
480
481     /**
482      * Starts an activity based on the request parameters provided earlier.
483      * @return The starter result.
484      */
485     int execute() {
486         try {
487             // TODO(b/64750076): Look into passing request directly to these methods to allow
488             // for transactional diffs and preprocessing.
489             if (mRequest.mayWait) {
490                 return startActivityMayWait(mRequest.caller, mRequest.callingUid,
491                         mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
492                         mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
493                         mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
494                         mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
495                         mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
496                         mRequest.inTask, mRequest.reason,
497                         mRequest.allowPendingRemoteAnimationRegistryLookup,
498                         mRequest.originatingPendingIntent);
499             } else {
500                 return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
501                         mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
502                         mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
503                         mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
504                         mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
505                         mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
506                         mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
507                         mRequest.outActivity, mRequest.inTask, mRequest.reason,
508                         mRequest.allowPendingRemoteAnimationRegistryLookup,
509                         mRequest.originatingPendingIntent);
510             }
511         } finally {
512             onExecutionComplete();
513         }
514     }
515
516     /**
517      * Starts an activity based on the provided {@link ActivityRecord} and environment parameters.
518      * Note that this method is called internally as well as part of {@link #startActivity}.
519      *
520      * @return The start result.
521      */
522     int startResolvedActivity(final ActivityRecord r, ActivityRecord sourceRecord,
523             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
524             int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
525             ActivityRecord[] outActivity) {
526         try {
527             return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
528                     doResume, options, inTask, outActivity);
529         } finally {
530             onExecutionComplete();
531         }
532     }
533
534     private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
535             String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
536             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
537             IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
538             String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
539             SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
540             ActivityRecord[] outActivity, TaskRecord inTask, String reason,
541             boolean allowPendingRemoteAnimationRegistryLookup,
542             PendingIntentRecord originatingPendingIntent) {
543
544         if (TextUtils.isEmpty(reason)) {
545             throw new IllegalArgumentException("Need to specify a reason.");
546         }
547         mLastStartReason = reason;
548         mLastStartActivityTimeMs = System.currentTimeMillis();
549         mLastStartActivityRecord[0] = null;
550
551         mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
552                 aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
553                 callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
554                 options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
555                 inTask, allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent);
556
557         if (outActivity != null) {
558             // mLastStartActivityRecord[0] is set in the call to startActivity above.
559             outActivity[0] = mLastStartActivityRecord[0];
560         }
561
562         return getExternalResult(mLastStartActivityResult);
563     }
564
565     static int getExternalResult(int result) {
566         // Aborted results are treated as successes externally, but we must track them internally.
567         return result != START_ABORTED ? result : START_SUCCESS;
568     }
569
570     /**
571      * Called when execution is complete. Sets state indicating completion and proceeds with
572      * recycling if appropriate.
573      */
574     private void onExecutionComplete() {
575         mController.onExecutionComplete(this);
576     }
577
578     private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
579             String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
580             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
581             IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
582             String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
583             SafeActivityOptions options,
584             boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
585             TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup,
586             PendingIntentRecord originatingPendingIntent) {
587         int err = ActivityManager.START_SUCCESS;
588         // Pull the optional Ephemeral Installer-only bundle out of the options early.
589         final Bundle verificationBundle
590                 = options != null ? options.popAppVerificationBundle() : null;
591
592         ProcessRecord callerApp = null;
593         if (caller != null) {
594             callerApp = mService.getRecordForAppLocked(caller);
595             if (callerApp != null) {
596                 callingPid = callerApp.pid;
597                 callingUid = callerApp.info.uid;
598             } else {
599                 Slog.w(TAG, "Unable to find app for caller " + caller
600                         + " (pid=" + callingPid + ") when starting: "
601                         + intent.toString());
602                 err = ActivityManager.START_PERMISSION_DENIED;
603             }
604         }
605
606         final int userId = aInfo != null && aInfo.applicationInfo != null
607                 ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
608
609         if (err == ActivityManager.START_SUCCESS) {
610             Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
611                     + "} from uid " + callingUid);
612         }
613
614         ActivityRecord sourceRecord = null;
615         ActivityRecord resultRecord = null;
616         if (resultTo != null) {
617             sourceRecord = mSupervisor.isInAnyStackLocked(resultTo);
618             if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
619                     "Will send result to " + resultTo + " " + sourceRecord);
620             if (sourceRecord != null) {
621                 if (requestCode >= 0 && !sourceRecord.finishing) {
622                     resultRecord = sourceRecord;
623                 }
624             }
625         }
626
627         final int launchFlags = intent.getFlags();
628
629         if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
630             // Transfer the result target from the source activity to the new
631             // one being started, including any failures.
632             if (requestCode >= 0) {
633                 SafeActivityOptions.abort(options);
634                 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
635             }
636             resultRecord = sourceRecord.resultTo;
637             if (resultRecord != null && !resultRecord.isInStackLocked()) {
638                 resultRecord = null;
639             }
640             resultWho = sourceRecord.resultWho;
641             requestCode = sourceRecord.requestCode;
642             sourceRecord.resultTo = null;
643             if (resultRecord != null) {
644                 resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
645             }
646             if (sourceRecord.launchedFromUid == callingUid) {
647                 // The new activity is being launched from the same uid as the previous
648                 // activity in the flow, and asking to forward its result back to the
649                 // previous.  In this case the activity is serving as a trampoline between
650                 // the two, so we also want to update its launchedFromPackage to be the
651                 // same as the previous activity.  Note that this is safe, since we know
652                 // these two packages come from the same uid; the caller could just as
653                 // well have supplied that same package name itself.  This specifially
654                 // deals with the case of an intent picker/chooser being launched in the app
655                 // flow to redirect to an activity picked by the user, where we want the final
656                 // activity to consider it to have been launched by the previous app activity.
657                 callingPackage = sourceRecord.launchedFromPackage;
658             }
659         }
660
661         if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
662             // We couldn't find a class that can handle the given Intent.
663             // That's the end of that!
664             err = ActivityManager.START_INTENT_NOT_RESOLVED;
665         }
666
667         if (err == ActivityManager.START_SUCCESS && aInfo == null) {
668             // We couldn't find the specific class specified in the Intent.
669             // Also the end of the line.
670             err = ActivityManager.START_CLASS_NOT_FOUND;
671         }
672
673         if (err == ActivityManager.START_SUCCESS && sourceRecord != null
674                 && sourceRecord.getTask().voiceSession != null) {
675             // If this activity is being launched as part of a voice session, we need
676             // to ensure that it is safe to do so.  If the upcoming activity will also
677             // be part of the voice session, we can only launch it if it has explicitly
678             // said it supports the VOICE category, or it is a part of the calling app.
679             if ((launchFlags & FLAG_ACTIVITY_NEW_TASK) == 0
680                     && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
681                 try {
682                     intent.addCategory(Intent.CATEGORY_VOICE);
683                     if (!mService.getPackageManager().activitySupportsIntent(
684                             intent.getComponent(), intent, resolvedType)) {
685                         Slog.w(TAG,
686                                 "Activity being started in current voice task does not support voice: "
687                                         + intent);
688                         err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
689                     }
690                 } catch (RemoteException e) {
691                     Slog.w(TAG, "Failure checking voice capabilities", e);
692                     err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
693                 }
694             }
695         }
696
697         if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
698             // If the caller is starting a new voice session, just make sure the target
699             // is actually allowing it to run this way.
700             try {
701                 if (!mService.getPackageManager().activitySupportsIntent(intent.getComponent(),
702                         intent, resolvedType)) {
703                     Slog.w(TAG,
704                             "Activity being started in new voice task does not support: "
705                                     + intent);
706                     err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
707                 }
708             } catch (RemoteException e) {
709                 Slog.w(TAG, "Failure checking voice capabilities", e);
710                 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
711             }
712         }
713
714         final ActivityStack resultStack = resultRecord == null ? null : resultRecord.getStack();
715
716         if (err != START_SUCCESS) {
717             if (resultRecord != null) {
718                 resultStack.sendActivityResultLocked(
719                         -1, resultRecord, resultWho, requestCode, RESULT_CANCELED, null);
720             }
721             SafeActivityOptions.abort(options);
722             return err;
723         }
724
725         boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
726                 requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity,
727                 inTask != null, callerApp, resultRecord, resultStack);
728         abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
729                 callingPid, resolvedType, aInfo.applicationInfo);
730
731         // Merge the two options bundles, while realCallerOptions takes precedence.
732         ActivityOptions checkedOptions = options != null
733                 ? options.getOptions(intent, aInfo, callerApp, mSupervisor)
734                 : null;
735         if (allowPendingRemoteAnimationRegistryLookup) {
736             checkedOptions = mService.getActivityStartController()
737                     .getPendingRemoteAnimationRegistry()
738                     .overrideOptionsIfNeeded(callingPackage, checkedOptions);
739         }
740         if (mService.mController != null) {
741             try {
742                 // The Intent we give to the watcher has the extra data
743                 // stripped off, since it can contain private information.
744                 Intent watchIntent = intent.cloneFilter();
745                 abort |= !mService.mController.activityStarting(watchIntent,
746                         aInfo.applicationInfo.packageName);
747             } catch (RemoteException e) {
748                 mService.mController = null;
749             }
750         }
751
752         mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage);
753         if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid,
754                 callingUid, checkedOptions)) {
755             // activity start was intercepted, e.g. because the target user is currently in quiet
756             // mode (turn off work) or the target application is suspended
757             intent = mInterceptor.mIntent;
758             rInfo = mInterceptor.mRInfo;
759             aInfo = mInterceptor.mAInfo;
760             resolvedType = mInterceptor.mResolvedType;
761             inTask = mInterceptor.mInTask;
762             callingPid = mInterceptor.mCallingPid;
763             callingUid = mInterceptor.mCallingUid;
764             checkedOptions = mInterceptor.mActivityOptions;
765         }
766
767         if (abort) {
768             if (resultRecord != null) {
769                 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
770                         RESULT_CANCELED, null);
771             }
772             // We pretend to the caller that it was really started, but
773             // they will just get a cancel result.
774             ActivityOptions.abort(checkedOptions);
775             return START_ABORTED;
776         }
777
778         // If permissions need a review before any of the app components can run, we
779         // launch the review activity and pass a pending intent to start the activity
780         // we are to launching now after the review is completed.
781         if (mService.mPermissionReviewRequired && aInfo != null) {
782             if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
783                     aInfo.packageName, userId)) {
784                 IIntentSender target = mService.getIntentSenderLocked(
785                         ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
786                         callingUid, userId, null, null, 0, new Intent[]{intent},
787                         new String[]{resolvedType}, PendingIntent.FLAG_CANCEL_CURRENT
788                                 | PendingIntent.FLAG_ONE_SHOT, null);
789
790                 final int flags = intent.getFlags();
791                 Intent newIntent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
792                 newIntent.setFlags(flags
793                         | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
794                 newIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, aInfo.packageName);
795                 newIntent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target));
796                 if (resultRecord != null) {
797                     newIntent.putExtra(Intent.EXTRA_RESULT_NEEDED, true);
798                 }
799                 intent = newIntent;
800
801                 resolvedType = null;
802                 callingUid = realCallingUid;
803                 callingPid = realCallingPid;
804
805                 rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0,
806                         computeResolveFilterUid(
807                                 callingUid, realCallingUid, mRequest.filterCallingUid));
808                 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
809                         null /*profilerInfo*/);
810
811                 if (DEBUG_PERMISSIONS_REVIEW) {
812                     Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true,
813                             true, false) + "} from uid " + callingUid + " on display "
814                             + (mSupervisor.mFocusedStack == null
815                             ? DEFAULT_DISPLAY : mSupervisor.mFocusedStack.mDisplayId));
816                 }
817             }
818         }
819
820         // If we have an ephemeral app, abort the process of launching the resolved intent.
821         // Instead, launch the ephemeral installer. Once the installer is finished, it
822         // starts either the intent we resolved here [on install error] or the ephemeral
823         // app [on install success].
824         if (rInfo != null && rInfo.auxiliaryInfo != null) {
825             intent = createLaunchIntent(rInfo.auxiliaryInfo, ephemeralIntent,
826                     callingPackage, verificationBundle, resolvedType, userId);
827             resolvedType = null;
828             callingUid = realCallingUid;
829             callingPid = realCallingPid;
830
831             aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
832         }
833
834         ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
835                 callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
836                 resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
837                 mSupervisor, checkedOptions, sourceRecord);
838         if (outActivity != null) {
839             outActivity[0] = r;
840         }
841
842         if (r.appTimeTracker == null && sourceRecord != null) {
843             // If the caller didn't specify an explicit time tracker, we want to continue
844             // tracking under any it has.
845             r.appTimeTracker = sourceRecord.appTimeTracker;
846         }
847
848         final ActivityStack stack = mSupervisor.mFocusedStack;
849
850         // If we are starting an activity that is not from the same uid as the currently resumed
851         // one, check whether app switches are allowed.
852         if (voiceSession == null && (stack.getResumedActivity() == null
853                 || stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {
854             if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
855                     realCallingPid, realCallingUid, "Activity start")) {
856                 mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
857                         sourceRecord, startFlags, stack, callerApp));
858                 ActivityOptions.abort(checkedOptions);
859                 return ActivityManager.START_SWITCHES_CANCELED;
860             }
861         }
862
863         if (mService.mDidAppSwitch) {
864             // This is the second allowed switch since we stopped switches,
865             // so now just generally allow switches.  Use case: user presses
866             // home (switches disabled, switch to home, mDidAppSwitch now true);
867             // user taps a home icon (coming from home so allowed, we hit here
868             // and now allow anyone to switch again).
869             mService.mAppSwitchesAllowedTime = 0;
870         } else {
871             mService.mDidAppSwitch = true;
872         }
873
874         mController.doPendingActivityLaunches(false);
875
876         maybeLogActivityStart(callingUid, callingPackage, realCallingUid, intent, callerApp, r,
877                 originatingPendingIntent);
878
879         return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
880                 true /* doResume */, checkedOptions, inTask, outActivity);
881     }
882
883     private void maybeLogActivityStart(int callingUid, String callingPackage, int realCallingUid,
884             Intent intent, ProcessRecord callerApp, ActivityRecord r,
885             PendingIntentRecord originatingPendingIntent) {
886         boolean callerAppHasForegroundActivity = (callerApp != null)
887                 ? callerApp.foregroundActivities
888                 : false;
889         if (!mService.isActivityStartsLoggingEnabled() || callerAppHasForegroundActivity
890                 || r == null) {
891             // skip logging in this case
892             return;
893         }
894
895         try {
896             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "logActivityStart");
897             final int callingUidProcState = mService.getUidStateLocked(callingUid);
898             final boolean callingUidHasAnyVisibleWindow =
899                     mService.mWindowManager.isAnyWindowVisibleForUid(callingUid);
900             final int realCallingUidProcState = (callingUid == realCallingUid)
901                     ? callingUidProcState
902                     : mService.getUidStateLocked(realCallingUid);
903             final boolean realCallingUidHasAnyVisibleWindow = (callingUid == realCallingUid)
904                     ? callingUidHasAnyVisibleWindow
905                     : mService.mWindowManager.isAnyWindowVisibleForUid(realCallingUid);
906             final String targetPackage = r.packageName;
907             final int targetUid = (r.appInfo != null) ? r.appInfo.uid : -1;
908             final int targetUidProcState = mService.getUidStateLocked(targetUid);
909             final boolean targetUidHasAnyVisibleWindow = (targetUid != -1)
910                     ? mService.mWindowManager.isAnyWindowVisibleForUid(targetUid)
911                     : false;
912             final String targetWhitelistTag = (targetUid != -1)
913                     ? mService.getPendingTempWhitelistTagForUidLocked(targetUid)
914                     : null;
915
916             mSupervisor.getActivityMetricsLogger().logActivityStart(intent, callerApp, r,
917                     callingUid, callingPackage, callingUidProcState,
918                     callingUidHasAnyVisibleWindow,
919                     realCallingUid, realCallingUidProcState,
920                     realCallingUidHasAnyVisibleWindow,
921                     targetUid, targetPackage, targetUidProcState,
922                     targetUidHasAnyVisibleWindow, targetWhitelistTag,
923                     (originatingPendingIntent != null));
924         } finally {
925             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
926         }
927     }
928
929     /**
930      * Creates a launch intent for the given auxiliary resolution data.
931      */
932     private @NonNull Intent createLaunchIntent(@Nullable AuxiliaryResolveInfo auxiliaryResponse,
933             Intent originalIntent, String callingPackage, Bundle verificationBundle,
934             String resolvedType, int userId) {
935         if (auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo) {
936             // request phase two resolution
937             mService.getPackageManagerInternalLocked().requestInstantAppResolutionPhaseTwo(
938                     auxiliaryResponse, originalIntent, resolvedType, callingPackage,
939                     verificationBundle, userId);
940         }
941         return InstantAppResolver.buildEphemeralInstallerIntent(
942                 originalIntent,
943                 InstantAppResolver.sanitizeIntent(originalIntent),
944                 auxiliaryResponse == null ? null : auxiliaryResponse.failureIntent,
945                 callingPackage,
946                 verificationBundle,
947                 resolvedType,
948                 userId,
949                 auxiliaryResponse == null ? null : auxiliaryResponse.installFailureActivity,
950                 auxiliaryResponse == null ? null : auxiliaryResponse.token,
951                 auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo,
952                 auxiliaryResponse == null ? null : auxiliaryResponse.filters);
953     }
954
955     void postStartActivityProcessing(ActivityRecord r, int result, ActivityStack targetStack) {
956         if (ActivityManager.isStartResultFatalError(result)) {
957             return;
958         }
959
960         // We're waiting for an activity launch to finish, but that activity simply
961         // brought another activity to front. We must also handle the case where the task is already
962         // in the front as a result of the trampoline activity being in the same task (it will be
963         // considered focused as the trampoline will be finished). Let startActivityMayWait() know
964         // about this, so it waits for the new activity to become visible instead.
965         mSupervisor.reportWaitingActivityLaunchedIfNeeded(r, result);
966
967         ActivityStack startedActivityStack = null;
968         final ActivityStack currentStack = r.getStack();
969         if (currentStack != null) {
970             startedActivityStack = currentStack;
971         } else if (mTargetStack != null) {
972             startedActivityStack = targetStack;
973         }
974
975         if (startedActivityStack == null) {
976             return;
977         }
978
979         final int clearTaskFlags = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK;
980         boolean clearedTask = (mLaunchFlags & clearTaskFlags) == clearTaskFlags
981                 && mReuseTask != null;
982         if (result == START_TASK_TO_FRONT || result == START_DELIVERED_TO_TOP || clearedTask) {
983             // The activity was already running so it wasn't started, but either brought to the
984             // front or the new intent was delivered to it since it was already in front. Notify
985             // anyone interested in this piece of information.
986             switch (startedActivityStack.getWindowingMode()) {
987                 case WINDOWING_MODE_PINNED:
988                     mService.mTaskChangeNotificationController.notifyPinnedActivityRestartAttempt(
989                             clearedTask);
990                     break;
991                 case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
992                     final ActivityStack homeStack = mSupervisor.mHomeStack;
993                     if (homeStack != null && homeStack.shouldBeVisible(null /* starting */)) {
994                         mService.mWindowManager.showRecentApps();
995                     }
996                     break;
997             }
998         }
999     }
1000
1001     private int startActivityMayWait(IApplicationThread caller, int callingUid,
1002             String callingPackage, Intent intent, String resolvedType,
1003             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1004             IBinder resultTo, String resultWho, int requestCode, int startFlags,
1005             ProfilerInfo profilerInfo, WaitResult outResult,
1006             Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
1007             int userId, TaskRecord inTask, String reason,
1008             boolean allowPendingRemoteAnimationRegistryLookup,
1009             PendingIntentRecord originatingPendingIntent) {
1010         // Refuse possible leaked file descriptors
1011         if (intent != null && intent.hasFileDescriptors()) {
1012             throw new IllegalArgumentException("File descriptors passed in Intent");
1013         }
1014         mSupervisor.getActivityMetricsLogger().notifyActivityLaunching();
1015         boolean componentSpecified = intent.getComponent() != null;
1016
1017         final int realCallingPid = Binder.getCallingPid();
1018         final int realCallingUid = Binder.getCallingUid();
1019
1020         int callingPid;
1021         if (callingUid >= 0) {
1022             callingPid = -1;
1023         } else if (caller == null) {
1024             callingPid = realCallingPid;
1025             callingUid = realCallingUid;
1026         } else {
1027             callingPid = callingUid = -1;
1028         }
1029
1030         // Save a copy in case ephemeral needs it
1031         final Intent ephemeralIntent = new Intent(intent);
1032         // Don't modify the client's object!
1033         intent = new Intent(intent);
1034         if (componentSpecified
1035                 && !(Intent.ACTION_VIEW.equals(intent.getAction()) && intent.getData() == null)
1036                 && !Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE.equals(intent.getAction())
1037                 && !Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE.equals(intent.getAction())
1038                 && mService.getPackageManagerInternalLocked()
1039                         .isInstantAppInstallerComponent(intent.getComponent())) {
1040             // intercept intents targeted directly to the ephemeral installer the
1041             // ephemeral installer should never be started with a raw Intent; instead
1042             // adjust the intent so it looks like a "normal" instant app launch
1043             intent.setComponent(null /*component*/);
1044             componentSpecified = false;
1045         }
1046
1047         ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
1048                 0 /* matchFlags */,
1049                         computeResolveFilterUid(
1050                                 callingUid, realCallingUid, mRequest.filterCallingUid));
1051         if (rInfo == null) {
1052             UserInfo userInfo = mSupervisor.getUserInfo(userId);
1053             if (userInfo != null && userInfo.isManagedProfile()) {
1054                 // Special case for managed profiles, if attempting to launch non-cryto aware
1055                 // app in a locked managed profile from an unlocked parent allow it to resolve
1056                 // as user will be sent via confirm credentials to unlock the profile.
1057                 UserManager userManager = UserManager.get(mService.mContext);
1058                 boolean profileLockedAndParentUnlockingOrUnlocked = false;
1059                 long token = Binder.clearCallingIdentity();
1060                 try {
1061                     UserInfo parent = userManager.getProfileParent(userId);
1062                     profileLockedAndParentUnlockingOrUnlocked = (parent != null)
1063                             && userManager.isUserUnlockingOrUnlocked(parent.id)
1064                             && !userManager.isUserUnlockingOrUnlocked(userId);
1065                 } finally {
1066                     Binder.restoreCallingIdentity(token);
1067                 }
1068                 if (profileLockedAndParentUnlockingOrUnlocked) {
1069                     rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
1070                             PackageManager.MATCH_DIRECT_BOOT_AWARE
1071                                     | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
1072                             computeResolveFilterUid(
1073                                     callingUid, realCallingUid, mRequest.filterCallingUid));
1074                 }
1075             }
1076         }
1077         // Collect information about the target of the Intent.
1078         ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
1079
1080         synchronized (mService) {
1081             final ActivityStack stack = mSupervisor.mFocusedStack;
1082             stack.mConfigWillChange = globalConfig != null
1083                     && mService.getGlobalConfiguration().diff(globalConfig) != 0;
1084             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
1085                     "Starting activity when config will change = " + stack.mConfigWillChange);
1086
1087             final long origId = Binder.clearCallingIdentity();
1088
1089             if (aInfo != null &&
1090                     (aInfo.applicationInfo.privateFlags
1091                             & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0 &&
1092                     mService.mHasHeavyWeightFeature) {
1093                 // This may be a heavy-weight process!  Check to see if we already
1094                 // have another, different heavy-weight process running.
1095                 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
1096                     final ProcessRecord heavy = mService.mHeavyWeightProcess;
1097                     if (heavy != null && (heavy.info.uid != aInfo.applicationInfo.uid
1098                             || !heavy.processName.equals(aInfo.processName))) {
1099                         int appCallingUid = callingUid;
1100                         if (caller != null) {
1101                             ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
1102                             if (callerApp != null) {
1103                                 appCallingUid = callerApp.info.uid;
1104                             } else {
1105                                 Slog.w(TAG, "Unable to find app for caller " + caller
1106                                         + " (pid=" + callingPid + ") when starting: "
1107                                         + intent.toString());
1108                                 SafeActivityOptions.abort(options);
1109                                 return ActivityManager.START_PERMISSION_DENIED;
1110                             }
1111                         }
1112
1113                         IIntentSender target = mService.getIntentSenderLocked(
1114                                 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
1115                                 appCallingUid, userId, null, null, 0, new Intent[] { intent },
1116                                 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
1117                                         | PendingIntent.FLAG_ONE_SHOT, null);
1118
1119                         Intent newIntent = new Intent();
1120                         if (requestCode >= 0) {
1121                             // Caller is requesting a result.
1122                             newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
1123                         }
1124                         newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
1125                                 new IntentSender(target));
1126                         if (heavy.activities.size() > 0) {
1127                             ActivityRecord hist = heavy.activities.get(0);
1128                             newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
1129                                     hist.packageName);
1130                             newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
1131                                     hist.getTask().taskId);
1132                         }
1133                         newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
1134                                 aInfo.packageName);
1135                         newIntent.setFlags(intent.getFlags());
1136                         newIntent.setClassName("android",
1137                                 HeavyWeightSwitcherActivity.class.getName());
1138                         intent = newIntent;
1139                         resolvedType = null;
1140                         caller = null;
1141                         callingUid = Binder.getCallingUid();
1142                         callingPid = Binder.getCallingPid();
1143                         componentSpecified = true;
1144                         rInfo = mSupervisor.resolveIntent(intent, null /*resolvedType*/, userId,
1145                                 0 /* matchFlags */, computeResolveFilterUid(
1146                                         callingUid, realCallingUid, mRequest.filterCallingUid));
1147                         aInfo = rInfo != null ? rInfo.activityInfo : null;
1148                         if (aInfo != null) {
1149                             aInfo = mService.getActivityInfoForUser(aInfo, userId);
1150                         }
1151                     }
1152                 }
1153             }
1154
1155             final ActivityRecord[] outRecord = new ActivityRecord[1];
1156             int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
1157                     voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
1158                     callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
1159                     ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
1160                     allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent);
1161
1162             Binder.restoreCallingIdentity(origId);
1163
1164             if (stack.mConfigWillChange) {
1165                 // If the caller also wants to switch to a new configuration,
1166                 // do so now.  This allows a clean switch, as we are waiting
1167                 // for the current activity to pause (so we will not destroy
1168                 // it), and have not yet started the next activity.
1169                 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
1170                         "updateConfiguration()");
1171                 stack.mConfigWillChange = false;
1172                 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
1173                         "Updating to new configuration after starting activity.");
1174                 mService.updateConfigurationLocked(globalConfig, null, false);
1175             }
1176
1177             // Notify ActivityMetricsLogger that the activity has launched. ActivityMetricsLogger
1178             // will then wait for the windows to be drawn and populate WaitResult.
1179             mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outRecord[0]);
1180             if (outResult != null) {
1181                 outResult.result = res;
1182
1183                 final ActivityRecord r = outRecord[0];
1184
1185                 switch(res) {
1186                     case START_SUCCESS: {
1187                         mSupervisor.mWaitingActivityLaunched.add(outResult);
1188                         do {
1189                             try {
1190                                 mService.wait();
1191                             } catch (InterruptedException e) {
1192                             }
1193                         } while (outResult.result != START_TASK_TO_FRONT
1194                                 && !outResult.timeout && outResult.who == null);
1195                         if (outResult.result == START_TASK_TO_FRONT) {
1196                             res = START_TASK_TO_FRONT;
1197                         }
1198                         break;
1199                     }
1200                     case START_DELIVERED_TO_TOP: {
1201                         outResult.timeout = false;
1202                         outResult.who = r.realActivity;
1203                         outResult.totalTime = 0;
1204                         break;
1205                     }
1206                     case START_TASK_TO_FRONT: {
1207                         // ActivityRecord may represent a different activity, but it should not be
1208                         // in the resumed state.
1209                         if (r.nowVisible && r.isState(RESUMED)) {
1210                             outResult.timeout = false;
1211                             outResult.who = r.realActivity;
1212                             outResult.totalTime = 0;
1213                         } else {
1214                             final long startTimeMs = SystemClock.uptimeMillis();
1215                             mSupervisor.waitActivityVisible(r.realActivity, outResult, startTimeMs);
1216                             // Note: the timeout variable is not currently not ever set.
1217                             do {
1218                                 try {
1219                                     mService.wait();
1220                                 } catch (InterruptedException e) {
1221                                 }
1222                             } while (!outResult.timeout && outResult.who == null);
1223                         }
1224                         break;
1225                     }
1226                 }
1227             }
1228
1229             return res;
1230         }
1231     }
1232
1233     /**
1234      * Compute the logical UID based on which the package manager would filter
1235      * app components i.e. based on which the instant app policy would be applied
1236      * because it is the logical calling UID.
1237      *
1238      * @param customCallingUid The UID on whose behalf to make the call.
1239      * @param actualCallingUid The UID actually making the call.
1240      * @param filterCallingUid The UID to be used to filter for instant apps.
1241      * @return The logical UID making the call.
1242      */
1243     static int computeResolveFilterUid(int customCallingUid, int actualCallingUid,
1244             int filterCallingUid) {
1245         return filterCallingUid != UserHandle.USER_NULL
1246                 ? filterCallingUid
1247                 : (customCallingUid >= 0 ? customCallingUid : actualCallingUid);
1248     }
1249
1250     private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
1251                 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1252                 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
1253                 ActivityRecord[] outActivity) {
1254         int result = START_CANCELED;
1255         try {
1256             mService.mWindowManager.deferSurfaceLayout();
1257             result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
1258                     startFlags, doResume, options, inTask, outActivity);
1259         } finally {
1260             // If we are not able to proceed, disassociate the activity from the task. Leaving an
1261             // activity in an incomplete state can lead to issues, such as performing operations
1262             // without a window container.
1263             final ActivityStack stack = mStartActivity.getStack();
1264             if (!ActivityManager.isStartResultSuccessful(result) && stack != null) {
1265                 stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,
1266                         null /* intentResultData */, "startActivity", true /* oomAdj */);
1267             }
1268             mService.mWindowManager.continueSurfaceLayout();
1269         }
1270
1271         postStartActivityProcessing(r, result, mTargetStack);
1272
1273         return result;
1274     }
1275
1276     // Note: This method should only be called from {@link startActivity}.
1277     private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
1278             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1279             int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
1280             ActivityRecord[] outActivity) {
1281
1282         setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
1283                 voiceInteractor);
1284
1285         computeLaunchingTaskFlags();
1286
1287         computeSourceStack();
1288
1289         mIntent.setFlags(mLaunchFlags);
1290
1291         ActivityRecord reusedActivity = getReusableIntentActivity();
1292
1293         int preferredWindowingMode = WINDOWING_MODE_UNDEFINED;
1294         int preferredLaunchDisplayId = DEFAULT_DISPLAY;
1295         if (mOptions != null) {
1296             preferredWindowingMode = mOptions.getLaunchWindowingMode();
1297             preferredLaunchDisplayId = mOptions.getLaunchDisplayId();
1298         }
1299
1300         // windowing mode and preferred launch display values from {@link LaunchParams} take
1301         // priority over those specified in {@link ActivityOptions}.
1302         if (!mLaunchParams.isEmpty()) {
1303             if (mLaunchParams.hasPreferredDisplay()) {
1304                 preferredLaunchDisplayId = mLaunchParams.mPreferredDisplayId;
1305             }
1306
1307             if (mLaunchParams.hasWindowingMode()) {
1308                 preferredWindowingMode = mLaunchParams.mWindowingMode;
1309             }
1310         }
1311
1312         if (reusedActivity != null) {
1313             // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but
1314             // still needs to be a lock task mode violation since the task gets cleared out and
1315             // the device would otherwise leave the locked task.
1316             if (mService.getLockTaskController().isLockTaskModeViolation(reusedActivity.getTask(),
1317                     (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1318                             == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
1319                 Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
1320                 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
1321             }
1322
1323             // True if we are clearing top and resetting of a standard (default) launch mode
1324             // ({@code LAUNCH_MULTIPLE}) activity. The existing activity will be finished.
1325             final boolean clearTopAndResetStandardLaunchMode =
1326                     (mLaunchFlags & (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED))
1327                             == (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
1328                     && mLaunchMode == LAUNCH_MULTIPLE;
1329
1330             // If mStartActivity does not have a task associated with it, associate it with the
1331             // reused activity's task. Do not do so if we're clearing top and resetting for a
1332             // standard launchMode activity.
1333             if (mStartActivity.getTask() == null && !clearTopAndResetStandardLaunchMode) {
1334                 mStartActivity.setTask(reusedActivity.getTask());
1335             }
1336
1337             if (reusedActivity.getTask().intent == null) {
1338                 // This task was started because of movement of the activity based on affinity...
1339                 // Now that we are actually launching it, we can assign the base intent.
1340                 reusedActivity.getTask().setIntent(mStartActivity);
1341             }
1342
1343             // This code path leads to delivering a new intent, we want to make sure we schedule it
1344             // as the first operation, in case the activity will be resumed as a result of later
1345             // operations.
1346             if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
1347                     || isDocumentLaunchesIntoExisting(mLaunchFlags)
1348                     || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
1349                 final TaskRecord task = reusedActivity.getTask();
1350
1351                 // In this situation we want to remove all activities from the task up to the one
1352                 // being started. In most cases this means we are resetting the task to its initial
1353                 // state.
1354                 final ActivityRecord top = task.performClearTaskForReuseLocked(mStartActivity,
1355                         mLaunchFlags);
1356
1357                 // The above code can remove {@code reusedActivity} from the task, leading to the
1358                 // the {@code ActivityRecord} removing its reference to the {@code TaskRecord}. The
1359                 // task reference is needed in the call below to
1360                 // {@link setTargetStackAndMoveToFrontIfNeeded}.
1361                 if (reusedActivity.getTask() == null) {
1362                     reusedActivity.setTask(task);
1363                 }
1364
1365                 if (top != null) {
1366                     if (top.frontOfTask) {
1367                         // Activity aliases may mean we use different intents for the top activity,
1368                         // so make sure the task now has the identity of the new intent.
1369                         top.getTask().setIntent(mStartActivity);
1370                     }
1371                     deliverNewIntent(top);
1372                 }
1373             }
1374
1375             mSupervisor.sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, reusedActivity);
1376
1377             reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);
1378
1379             final ActivityRecord outResult =
1380                     outActivity != null && outActivity.length > 0 ? outActivity[0] : null;
1381
1382             // When there is a reused activity and the current result is a trampoline activity,
1383             // set the reused activity as the result.
1384             if (outResult != null && (outResult.finishing || outResult.noDisplay)) {
1385                 outActivity[0] = reusedActivity;
1386             }
1387
1388             if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1389                 // We don't need to start a new activity, and the client said not to do anything
1390                 // if that is the case, so this is it!  And for paranoia, make sure we have
1391                 // correctly resumed the top activity.
1392                 resumeTargetStackIfNeeded();
1393                 return START_RETURN_INTENT_TO_CALLER;
1394             }
1395
1396             if (reusedActivity != null) {
1397                 setTaskFromIntentActivity(reusedActivity);
1398
1399                 if (!mAddingToTask && mReuseTask == null) {
1400                     // We didn't do anything...  but it was needed (a.k.a., client don't use that
1401                     // intent!)  And for paranoia, make sure we have correctly resumed the top activity.
1402
1403                     resumeTargetStackIfNeeded();
1404                     if (outActivity != null && outActivity.length > 0) {
1405                         outActivity[0] = reusedActivity;
1406                     }
1407
1408                     return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP;
1409                 }
1410             }
1411         }
1412
1413         if (mStartActivity.packageName == null) {
1414             final ActivityStack sourceStack = mStartActivity.resultTo != null
1415                     ? mStartActivity.resultTo.getStack() : null;
1416             if (sourceStack != null) {
1417                 sourceStack.sendActivityResultLocked(-1 /* callingUid */, mStartActivity.resultTo,
1418                         mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,
1419                         null /* data */);
1420             }
1421             ActivityOptions.abort(mOptions);
1422             return START_CLASS_NOT_FOUND;
1423         }
1424
1425         // If the activity being launched is the same as the one currently at the top, then
1426         // we need to check if it should only be launched once.
1427         final ActivityStack topStack = mSupervisor.mFocusedStack;
1428         final ActivityRecord topFocused = topStack.getTopActivity();
1429         final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
1430         final boolean dontStart = top != null && mStartActivity.resultTo == null
1431                 && top.realActivity.equals(mStartActivity.realActivity)
1432                 && top.userId == mStartActivity.userId
1433                 && top.app != null && top.app.thread != null
1434                 && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
1435                 || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK));
1436         if (dontStart) {
1437             // For paranoia, make sure we have correctly resumed the top activity.
1438             topStack.mLastPausedActivity = null;
1439             if (mDoResume) {
1440                 mSupervisor.resumeFocusedStackTopActivityLocked();
1441             }
1442             ActivityOptions.abort(mOptions);
1443             if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1444                 // We don't need to start a new activity, and the client said not to do
1445                 // anything if that is the case, so this is it!
1446                 return START_RETURN_INTENT_TO_CALLER;
1447             }
1448
1449             deliverNewIntent(top);
1450
1451             // Don't use mStartActivity.task to show the toast. We're not starting a new activity
1452             // but reusing 'top'. Fields in mStartActivity may not be fully initialized.
1453             mSupervisor.handleNonResizableTaskIfNeeded(top.getTask(), preferredWindowingMode,
1454                     preferredLaunchDisplayId, topStack);
1455
1456             return START_DELIVERED_TO_TOP;
1457         }
1458
1459         boolean newTask = false;
1460         final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
1461                 ? mSourceRecord.getTask() : null;
1462
1463         // Should this be considered a new task?
1464         int result = START_SUCCESS;
1465         if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
1466                 && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1467             newTask = true;
1468             result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, topStack);
1469         } else if (mSourceRecord != null) {
1470             result = setTaskFromSourceRecord();
1471         } else if (mInTask != null) {
1472             result = setTaskFromInTask();
1473         } else {
1474             // This not being started from an existing activity, and not part of a new task...
1475             // just put it in the top task, though these days this case should never happen.
1476             setTaskToCurrentTopOrCreateNewTask();
1477         }
1478         if (result != START_SUCCESS) {
1479             return result;
1480         }
1481
1482         mService.grantUriPermissionFromIntentLocked(mCallingUid, mStartActivity.packageName,
1483                 mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.userId);
1484         mService.grantEphemeralAccessLocked(mStartActivity.userId, mIntent,
1485                 mStartActivity.appInfo.uid, UserHandle.getAppId(mCallingUid));
1486         if (newTask) {
1487             EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, mStartActivity.userId,
1488                     mStartActivity.getTask().taskId);
1489         }
1490         ActivityStack.logStartActivity(
1491                 EventLogTags.AM_CREATE_ACTIVITY, mStartActivity, mStartActivity.getTask());
1492         mTargetStack.mLastPausedActivity = null;
1493
1494         mSupervisor.sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, mStartActivity);
1495
1496         mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
1497                 mOptions);
1498         if (mDoResume) {
1499             final ActivityRecord topTaskActivity =
1500                     mStartActivity.getTask().topRunningActivityLocked();
1501             if (!mTargetStack.isFocusable()
1502                     || (topTaskActivity != null && topTaskActivity.mTaskOverlay
1503                     && mStartActivity != topTaskActivity)) {
1504                 // If the activity is not focusable, we can't resume it, but still would like to
1505                 // make sure it becomes visible as it starts (this will also trigger entry
1506                 // animation). An example of this are PIP activities.
1507                 // Also, we don't want to resume activities in a task that currently has an overlay
1508                 // as the starting activity just needs to be in the visible paused state until the
1509                 // over is removed.
1510                 mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
1511                 // Go ahead and tell window manager to execute app transition for this activity
1512                 // since the app transition will not be triggered through the resume channel.
1513                 mService.mWindowManager.executeAppTransition();
1514             } else {
1515                 // If the target stack was not previously focusable (previous top running activity
1516                 // on that stack was not visible) then any prior calls to move the stack to the
1517                 // will not update the focused stack.  If starting the new activity now allows the
1518                 // task stack to be focusable, then ensure that we now update the focused stack
1519                 // accordingly.
1520                 if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
1521                     mTargetStack.moveToFront("startActivityUnchecked");
1522                 }
1523                 mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
1524                         mOptions);
1525             }
1526         } else if (mStartActivity != null) {
1527             mSupervisor.mRecentTasks.add(mStartActivity.getTask());
1528         }
1529         mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);
1530
1531         mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(), preferredWindowingMode,
1532                 preferredLaunchDisplayId, mTargetStack);
1533
1534         return START_SUCCESS;
1535     }
1536
1537     /**
1538      * Resets the {@link ActivityStarter} state.
1539      * @param clearRequest whether the request should be reset to default values.
1540      */
1541     void reset(boolean clearRequest) {
1542         mStartActivity = null;
1543         mIntent = null;
1544         mCallingUid = -1;
1545         mOptions = null;
1546
1547         mLaunchTaskBehind = false;
1548         mLaunchFlags = 0;
1549         mLaunchMode = INVALID_LAUNCH_MODE;
1550
1551         mLaunchParams.reset();
1552
1553         mNotTop = null;
1554         mDoResume = false;
1555         mStartFlags = 0;
1556         mSourceRecord = null;
1557         mPreferredDisplayId = INVALID_DISPLAY;
1558
1559         mInTask = null;
1560         mAddingToTask = false;
1561         mReuseTask = null;
1562
1563         mNewTaskInfo = null;
1564         mNewTaskIntent = null;
1565         mSourceStack = null;
1566
1567         mTargetStack = null;
1568         mMovedToFront = false;
1569         mNoAnimation = false;
1570         mKeepCurTransition = false;
1571         mAvoidMoveToFront = false;
1572
1573         mVoiceSession = null;
1574         mVoiceInteractor = null;
1575
1576         mIntentDelivered = false;
1577
1578         if (clearRequest) {
1579             mRequest.reset();
1580         }
1581     }
1582
1583     private void setInitialState(ActivityRecord r, ActivityOptions options, TaskRecord inTask,
1584             boolean doResume, int startFlags, ActivityRecord sourceRecord,
1585             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
1586         reset(false /* clearRequest */);
1587
1588         mStartActivity = r;
1589         mIntent = r.intent;
1590         mOptions = options;
1591         mCallingUid = r.launchedFromUid;
1592         mSourceRecord = sourceRecord;
1593         mVoiceSession = voiceSession;
1594         mVoiceInteractor = voiceInteractor;
1595
1596         mPreferredDisplayId = getPreferedDisplayId(mSourceRecord, mStartActivity, options);
1597
1598         mLaunchParams.reset();
1599
1600         mSupervisor.getLaunchParamsController().calculate(inTask, null /*layout*/, r, sourceRecord,
1601                 options, mLaunchParams);
1602
1603         mLaunchMode = r.launchMode;
1604
1605         mLaunchFlags = adjustLaunchFlagsToDocumentMode(
1606                 r, LAUNCH_SINGLE_INSTANCE == mLaunchMode,
1607                 LAUNCH_SINGLE_TASK == mLaunchMode, mIntent.getFlags());
1608         mLaunchTaskBehind = r.mLaunchTaskBehind
1609                 && !isLaunchModeOneOf(LAUNCH_SINGLE_TASK, LAUNCH_SINGLE_INSTANCE)
1610                 && (mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0;
1611
1612         sendNewTaskResultRequestIfNeeded();
1613
1614         if ((mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
1615             mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1616         }
1617
1618         // If we are actually going to launch in to a new task, there are some cases where
1619         // we further want to do multiple task.
1620         if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1621             if (mLaunchTaskBehind
1622                     || r.info.documentLaunchMode == DOCUMENT_LAUNCH_ALWAYS) {
1623                 mLaunchFlags |= FLAG_ACTIVITY_MULTIPLE_TASK;
1624             }
1625         }
1626
1627         // We'll invoke onUserLeaving before onPause only if the launching
1628         // activity did not explicitly state that this is an automated launch.
1629         mSupervisor.mUserLeaving = (mLaunchFlags & FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1630         if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
1631                 "startActivity() => mUserLeaving=" + mSupervisor.mUserLeaving);
1632
1633         // If the caller has asked not to resume at this point, we make note
1634         // of this in the record so that we can skip it when trying to find
1635         // the top running activity.
1636         mDoResume = doResume;
1637         if (!doResume || !r.okToShowLocked()) {
1638             r.delayedResume = true;
1639             mDoResume = false;
1640         }
1641
1642         if (mOptions != null) {
1643             if (mOptions.getLaunchTaskId() != -1 && mOptions.getTaskOverlay()) {
1644                 r.mTaskOverlay = true;
1645                 if (!mOptions.canTaskOverlayResume()) {
1646                     final TaskRecord task = mSupervisor.anyTaskForIdLocked(
1647                             mOptions.getLaunchTaskId());
1648                     final ActivityRecord top = task != null ? task.getTopActivity() : null;
1649                     if (top != null && !top.isState(RESUMED)) {
1650
1651                         // The caller specifies that we'd like to be avoided to be moved to the
1652                         // front, so be it!
1653                         mDoResume = false;
1654                         mAvoidMoveToFront = true;
1655                     }
1656                 }
1657             } else if (mOptions.getAvoidMoveToFront()) {
1658                 mDoResume = false;
1659                 mAvoidMoveToFront = true;
1660             }
1661         }
1662
1663         mNotTop = (mLaunchFlags & FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1664
1665         mInTask = inTask;
1666         // In some flows in to this function, we retrieve the task record and hold on to it
1667         // without a lock before calling back in to here...  so the task at this point may
1668         // not actually be in recents.  Check for that, and if it isn't in recents just
1669         // consider it invalid.
1670         if (inTask != null && !inTask.inRecents) {
1671             Slog.w(TAG, "Starting activity in task not in recents: " + inTask);
1672             mInTask = null;
1673         }
1674
1675         mStartFlags = startFlags;
1676         // If the onlyIfNeeded flag is set, then we can do this if the activity being launched
1677         // is the same as the one making the call...  or, as a special case, if we do not know
1678         // the caller then we count the current top activity as the caller.
1679         if ((startFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1680             ActivityRecord checkedCaller = sourceRecord;
1681             if (checkedCaller == null) {
1682                 checkedCaller = mSupervisor.mFocusedStack.topRunningNonDelayedActivityLocked(
1683                         mNotTop);
1684             }
1685             if (!checkedCaller.realActivity.equals(r.realActivity)) {
1686                 // Caller is not the same as launcher, so always needed.
1687                 mStartFlags &= ~START_FLAG_ONLY_IF_NEEDED;
1688             }
1689         }
1690
1691         mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0;
1692     }
1693
1694     private void sendNewTaskResultRequestIfNeeded() {
1695         final ActivityStack sourceStack = mStartActivity.resultTo != null
1696                 ? mStartActivity.resultTo.getStack() : null;
1697         if (sourceStack != null && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1698             // For whatever reason this activity is being launched into a new task...
1699             // yet the caller has requested a result back.  Well, that is pretty messed up,
1700             // so instead immediately send back a cancel and let the new task continue launched
1701             // as normal without a dependency on its originator.
1702             Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1703             sourceStack.sendActivityResultLocked(-1 /* callingUid */, mStartActivity.resultTo,
1704                     mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,
1705                     null /* data */);
1706             mStartActivity.resultTo = null;
1707         }
1708     }
1709
1710     private void computeLaunchingTaskFlags() {
1711         // If the caller is not coming from another activity, but has given us an explicit task into
1712         // which they would like us to launch the new activity, then let's see about doing that.
1713         if (mSourceRecord == null && mInTask != null && mInTask.getStack() != null) {
1714             final Intent baseIntent = mInTask.getBaseIntent();
1715             final ActivityRecord root = mInTask.getRootActivity();
1716             if (baseIntent == null) {
1717                 ActivityOptions.abort(mOptions);
1718                 throw new IllegalArgumentException("Launching into task without base intent: "
1719                         + mInTask);
1720             }
1721
1722             // If this task is empty, then we are adding the first activity -- it
1723             // determines the root, and must be launching as a NEW_TASK.
1724             if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
1725                 if (!baseIntent.getComponent().equals(mStartActivity.intent.getComponent())) {
1726                     ActivityOptions.abort(mOptions);
1727                     throw new IllegalArgumentException("Trying to launch singleInstance/Task "
1728                             + mStartActivity + " into different task " + mInTask);
1729                 }
1730                 if (root != null) {
1731                     ActivityOptions.abort(mOptions);
1732                     throw new IllegalArgumentException("Caller with mInTask " + mInTask
1733                             + " has root " + root + " but target is singleInstance/Task");
1734                 }
1735             }
1736
1737             // If task is empty, then adopt the interesting intent launch flags in to the
1738             // activity being started.
1739             if (root == null) {
1740                 final int flagsOfInterest = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK
1741                         | FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS;
1742                 mLaunchFlags = (mLaunchFlags & ~flagsOfInterest)
1743                         | (baseIntent.getFlags() & flagsOfInterest);
1744                 mIntent.setFlags(mLaunchFlags);
1745                 mInTask.setIntent(mStartActivity);
1746                 mAddingToTask = true;
1747
1748                 // If the task is not empty and the caller is asking to start it as the root of
1749                 // a new task, then we don't actually want to start this on the task. We will
1750                 // bring the task to the front, and possibly give it a new intent.
1751             } else if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1752                 mAddingToTask = false;
1753
1754             } else {
1755                 mAddingToTask = true;
1756             }
1757
1758             mReuseTask = mInTask;
1759         } else {
1760             mInTask = null;
1761             // Launch ResolverActivity in the source task, so that it stays in the task bounds
1762             // when in freeform workspace.
1763             // Also put noDisplay activities in the source task. These by itself can be placed
1764             // in any task/stack, however it could launch other activities like ResolverActivity,
1765             // and we want those to stay in the original task.
1766             if ((mStartActivity.isResolverActivity() || mStartActivity.noDisplay) && mSourceRecord != null
1767                     && mSourceRecord.inFreeformWindowingMode())  {
1768                 mAddingToTask = true;
1769             }
1770         }
1771
1772         if (mInTask == null) {
1773             if (mSourceRecord == null) {
1774                 // This activity is not being started from another...  in this
1775                 // case we -always- start a new task.
1776                 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) {
1777                     Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1778                             "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
1779                     mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1780                 }
1781             } else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) {
1782                 // The original activity who is starting us is running as a single
1783                 // instance...  this new activity it is starting must go on its
1784                 // own task.
1785                 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1786             } else if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
1787                 // The activity being started is a single instance...  it always
1788                 // gets launched into its own task.
1789                 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1790             }
1791         }
1792     }
1793
1794     private void computeSourceStack() {
1795         if (mSourceRecord == null) {
1796             mSourceStack = null;
1797             return;
1798         }
1799         if (!mSourceRecord.finishing) {
1800             mSourceStack = mSourceRecord.getStack();
1801             return;
1802         }
1803
1804         // If the source is finishing, we can't further count it as our source. This is because the
1805         // task it is associated with may now be empty and on its way out, so we don't want to
1806         // blindly throw it in to that task.  Instead we will take the NEW_TASK flow and try to find
1807         // a task for it. But save the task information so it can be used when creating the new task.
1808         if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0) {
1809             Slog.w(TAG, "startActivity called from finishing " + mSourceRecord
1810                     + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
1811             mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1812             mNewTaskInfo = mSourceRecord.info;
1813
1814             // It is not guaranteed that the source record will have a task associated with it. For,
1815             // example, if this method is being called for processing a pending activity launch, it
1816             // is possible that the activity has been removed from the task after the launch was
1817             // enqueued.
1818             final TaskRecord sourceTask = mSourceRecord.getTask();
1819             mNewTaskIntent = sourceTask != null ? sourceTask.intent : null;
1820         }
1821         mSourceRecord = null;
1822         mSourceStack = null;
1823     }
1824
1825     /**
1826      * Decide whether the new activity should be inserted into an existing task. Returns null
1827      * if not or an ActivityRecord with the task into which the new activity should be added.
1828      */
1829     private ActivityRecord getReusableIntentActivity() {
1830         // We may want to try to place the new activity in to an existing task.  We always
1831         // do this if the target activity is singleTask or singleInstance; we will also do
1832         // this if NEW_TASK has been requested, and there is not an additional qualifier telling
1833         // us to still place it in a new task: multi task, always doc mode, or being asked to
1834         // launch this as a new task behind the current one.
1835         boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 &&
1836                 (mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1837                 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK);
1838         // If bring to front is requested, and no result is requested and we have not been given
1839         // an explicit task to launch in to, and we can find a task that was started with this
1840         // same component, then instead of launching bring that one to the front.
1841         putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null;
1842         ActivityRecord intentActivity = null;
1843         if (mOptions != null && mOptions.getLaunchTaskId() != -1) {
1844             final TaskRecord task = mSupervisor.anyTaskForIdLocked(mOptions.getLaunchTaskId());
1845             intentActivity = task != null ? task.getTopActivity() : null;
1846         } else if (putIntoExistingTask) {
1847             if (LAUNCH_SINGLE_INSTANCE == mLaunchMode) {
1848                 // There can be one and only one instance of single instance activity in the
1849                 // history, and it is always in its own unique task, so we do a special search.
1850                intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info,
1851                        mStartActivity.isActivityTypeHome());
1852             } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
1853                 // For the launch adjacent case we only want to put the activity in an existing
1854                 // task if the activity already exists in the history.
1855                 intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info,
1856                         !(LAUNCH_SINGLE_TASK == mLaunchMode));
1857             } else {
1858                 // Otherwise find the best task to put the activity in.
1859                 intentActivity = mSupervisor.findTaskLocked(mStartActivity, mPreferredDisplayId);
1860             }
1861         }
1862         return intentActivity;
1863     }
1864
1865     /**
1866      * Returns the ID of the display to use for a new activity. If the device is in VR mode,
1867      * then return the Vr mode's virtual display ID. If not,  if the activity was started with
1868      * a launchDisplayId, use that. Otherwise, if the source activity has a explicit display ID
1869      * set, use that to launch the activity.
1870      */
1871     private int getPreferedDisplayId(
1872             ActivityRecord sourceRecord, ActivityRecord startingActivity, ActivityOptions options) {
1873         // Check if the Activity is a VR activity. If so, the activity should be launched in
1874         // main display.
1875         if (startingActivity != null && startingActivity.requestedVrComponent != null) {
1876             return DEFAULT_DISPLAY;
1877         }
1878
1879         // Get the virtual display id from ActivityManagerService.
1880         int displayId = mService.mVr2dDisplayId;
1881         if (displayId != INVALID_DISPLAY) {
1882             if (DEBUG_STACK) {
1883                 Slog.d(TAG, "getSourceDisplayId :" + displayId);
1884             }
1885             return displayId;
1886         }
1887
1888         // If the caller requested a display, prefer that display.
1889         final int launchDisplayId =
1890                 (options != null) ? options.getLaunchDisplayId() : INVALID_DISPLAY;
1891         if (launchDisplayId != INVALID_DISPLAY) {
1892             return launchDisplayId;
1893         }
1894
1895         displayId = sourceRecord != null ? sourceRecord.getDisplayId() : INVALID_DISPLAY;
1896         // If the activity has a displayId set explicitly, launch it on the same displayId.
1897         if (displayId != INVALID_DISPLAY) {
1898             return displayId;
1899         }
1900         return DEFAULT_DISPLAY;
1901     }
1902
1903     /**
1904      * Figure out which task and activity to bring to front when we have found an existing matching
1905      * activity record in history. May also clear the task if needed.
1906      * @param intentActivity Existing matching activity.
1907      * @return {@link ActivityRecord} brought to front.
1908      */
1909     private ActivityRecord setTargetStackAndMoveToFrontIfNeeded(ActivityRecord intentActivity) {
1910         mTargetStack = intentActivity.getStack();
1911         mTargetStack.mLastPausedActivity = null;
1912         // If the target task is not in the front, then we need to bring it to the front...
1913         // except...  well, with SINGLE_TASK_LAUNCH it's not entirely clear. We'd like to have
1914         // the same behavior as if a new instance was being started, which means not bringing it
1915         // to the front if the caller is not itself in the front.
1916         final ActivityStack focusStack = mSupervisor.getFocusedStack();
1917         ActivityRecord curTop = (focusStack == null)
1918                 ? null : focusStack.topRunningNonDelayedActivityLocked(mNotTop);
1919
1920         final TaskRecord topTask = curTop != null ? curTop.getTask() : null;
1921         if (topTask != null
1922                 && (topTask != intentActivity.getTask() || topTask != focusStack.topTask())
1923                 && !mAvoidMoveToFront) {
1924             mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
1925             if (mSourceRecord == null || (mSourceStack.getTopActivity() != null &&
1926                     mSourceStack.getTopActivity().getTask() == mSourceRecord.getTask())) {
1927                 // We really do want to push this one into the user's face, right now.
1928                 if (mLaunchTaskBehind && mSourceRecord != null) {
1929                     intentActivity.setTaskToAffiliateWith(mSourceRecord.getTask());
1930                 }
1931
1932                 // If the launch flags carry both NEW_TASK and CLEAR_TASK, the task's activities
1933                 // will be cleared soon by ActivityStarter in setTaskFromIntentActivity().
1934                 // So no point resuming any of the activities here, it just wastes one extra
1935                 // resuming, plus enter AND exit transitions.
1936                 // Here we only want to bring the target stack forward. Transition will be applied
1937                 // to the new activity that's started after the old ones are gone.
1938                 final boolean willClearTask =
1939                         (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1940                             == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
1941                 if (!willClearTask) {
1942                     final ActivityStack launchStack = getLaunchStack(
1943                             mStartActivity, mLaunchFlags, mStartActivity.getTask(), mOptions);
1944                     final TaskRecord intentTask = intentActivity.getTask();
1945                     if (launchStack == null || launchStack == mTargetStack) {
1946                         // We only want to move to the front, if we aren't going to launch on a
1947                         // different stack. If we launch on a different stack, we will put the
1948                         // task on top there.
1949                         mTargetStack.moveTaskToFrontLocked(intentTask, mNoAnimation, mOptions,
1950                                 mStartActivity.appTimeTracker, "bringingFoundTaskToFront");
1951                         mMovedToFront = true;
1952                     } else if (launchStack.inSplitScreenWindowingMode()) {
1953                         if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
1954                             // If we want to launch adjacent and mTargetStack is not the computed
1955                             // launch stack - move task to top of computed stack.
1956                             intentTask.reparent(launchStack, ON_TOP,
1957                                     REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
1958                                     "launchToSide");
1959                         } else {
1960                             // TODO: This should be reevaluated in MW v2.
1961                             // We choose to move task to front instead of launching it adjacent
1962                             // when specific stack was requested explicitly and it appeared to be
1963                             // adjacent stack, but FLAG_ACTIVITY_LAUNCH_ADJACENT was not set.
1964                             mTargetStack.moveTaskToFrontLocked(intentTask,
1965                                     mNoAnimation, mOptions, mStartActivity.appTimeTracker,
1966                                     "bringToFrontInsteadOfAdjacentLaunch");
1967                         }
1968                         mMovedToFront = launchStack != launchStack.getDisplay()
1969                                 .getTopStackInWindowingMode(launchStack.getWindowingMode());
1970                     } else if (launchStack.mDisplayId != mTargetStack.mDisplayId) {
1971                         // Target and computed stacks are on different displays and we've
1972                         // found a matching task - move the existing instance to that display and
1973                         // move it to front.
1974                         intentActivity.getTask().reparent(launchStack, ON_TOP,
1975                                 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
1976                                 "reparentToDisplay");
1977                         mMovedToFront = true;
1978                     } else if (launchStack.isActivityTypeHome()
1979                             && !mTargetStack.isActivityTypeHome()) {
1980                         // It is possible for the home activity to be in another stack initially.
1981                         // For example, the activity may have been initially started with an intent
1982                         // which placed it in the fullscreen stack. To ensure the proper handling of
1983                         // the activity based on home stack assumptions, we must move it over.
1984                         intentActivity.getTask().reparent(launchStack, ON_TOP,
1985                                 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
1986                                 "reparentingHome");
1987                         mMovedToFront = true;
1988                     }
1989                     mOptions = null;
1990
1991                     // We are moving a task to the front, use starting window to hide initial drawn
1992                     // delay.
1993                     intentActivity.showStartingWindow(null /* prev */, false /* newTask */,
1994                             true /* taskSwitch */);
1995                 }
1996             }
1997         }
1998         // Need to update mTargetStack because if task was moved out of it, the original stack may
1999         // be destroyed.
2000         mTargetStack = intentActivity.getStack();
2001         if (!mMovedToFront && mDoResume) {
2002             if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Bring to front target: " + mTargetStack
2003                     + " from " + intentActivity);
2004             mTargetStack.moveToFront("intentActivityFound");
2005         }
2006
2007         mSupervisor.handleNonResizableTaskIfNeeded(intentActivity.getTask(),
2008                 WINDOWING_MODE_UNDEFINED, DEFAULT_DISPLAY, mTargetStack);
2009
2010         // If the caller has requested that the target task be reset, then do so.
2011         if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
2012             return mTargetStack.resetTaskIfNeededLocked(intentActivity, mStartActivity);
2013         }
2014         return intentActivity;
2015     }
2016
2017     private void setTaskFromIntentActivity(ActivityRecord intentActivity) {
2018         if ((mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
2019                 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {
2020             // The caller has requested to completely replace any existing task with its new
2021             // activity. Well that should not be too hard...
2022             // Note: we must persist the {@link TaskRecord} first as intentActivity could be
2023             // removed from calling performClearTaskLocked (For example, if it is being brought out
2024             // of history or if it is finished immediately), thus disassociating the task. Also note
2025             // that mReuseTask is reset as a result of {@link TaskRecord#performClearTaskLocked}
2026             // launching another activity.
2027             // TODO(b/36119896):  We shouldn't trigger activity launches in this path since we are
2028             // already launching one.
2029             final TaskRecord task = intentActivity.getTask();
2030             task.performClearTaskLocked();
2031             mReuseTask = task;
2032             mReuseTask.setIntent(mStartActivity);
2033         } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
2034                 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
2035             ActivityRecord top = intentActivity.getTask().performClearTaskLocked(mStartActivity,
2036                     mLaunchFlags);
2037             if (top == null) {
2038                 // A special case: we need to start the activity because it is not currently
2039                 // running, and the caller has asked to clear the current task to have this
2040                 // activity at the top.
2041                 mAddingToTask = true;
2042
2043                 // We are no longer placing the activity in the task we previously thought we were.
2044                 mStartActivity.setTask(null);
2045                 // Now pretend like this activity is being started by the top of its task, so it
2046                 // is put in the right place.
2047                 mSourceRecord = intentActivity;
2048                 final TaskRecord task = mSourceRecord.getTask();
2049                 if (task != null && task.getStack() == null) {
2050                     // Target stack got cleared when we all activities were removed above.
2051                     // Go ahead and reset it.
2052                     mTargetStack = computeStackFocus(mSourceRecord, false /* newTask */,
2053                             mLaunchFlags, mOptions);
2054                     mTargetStack.addTask(task,
2055                             !mLaunchTaskBehind /* toTop */, "startActivityUnchecked");
2056                 }
2057             }
2058         } else if (mStartActivity.realActivity.equals(intentActivity.getTask().realActivity)) {
2059             // In this case the top activity on the task is the same as the one being launched,
2060             // so we take that as a request to bring the task to the foreground. If the top
2061             // activity in the task is the root activity, deliver this new intent to it if it
2062             // desires.
2063             if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
2064                         || LAUNCH_SINGLE_TOP == mLaunchMode)
2065                     && intentActivity.realActivity.equals(mStartActivity.realActivity)) {
2066                 if (intentActivity.frontOfTask) {
2067                     intentActivity.getTask().setIntent(mStartActivity);
2068                 }
2069                 deliverNewIntent(intentActivity);
2070             } else if (!intentActivity.getTask().isSameIntentFilter(mStartActivity)) {
2071                 // In this case we are launching the root activity of the task, but with a
2072                 // different intent. We should start a new instance on top.
2073                 mAddingToTask = true;
2074                 mSourceRecord = intentActivity;
2075             }
2076         } else if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
2077             // In this case an activity is being launched in to an existing task, without
2078             // resetting that task. This is typically the situation of launching an activity
2079             // from a notification or shortcut. We want to place the new activity on top of the
2080             // current task.
2081             mAddingToTask = true;
2082             mSourceRecord = intentActivity;
2083         } else if (!intentActivity.getTask().rootWasReset) {
2084             // In this case we are launching into an existing task that has not yet been started
2085             // from its front door. The current task has been brought to the front. Ideally,
2086             // we'd probably like to place this new task at the bottom of its stack, but that's
2087             // a little hard to do with the current organization of the code so for now we'll
2088             // just drop it.
2089             intentActivity.getTask().setIntent(mStartActivity);
2090         }
2091     }
2092
2093     private void resumeTargetStackIfNeeded() {
2094         if (mDoResume) {
2095             mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, null, mOptions);
2096         } else {
2097             ActivityOptions.abort(mOptions);
2098         }
2099         mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);
2100     }
2101
2102     private int setTaskFromReuseOrCreateNewTask(
2103             TaskRecord taskToAffiliate, ActivityStack topStack) {
2104         mTargetStack = computeStackFocus(mStartActivity, true, mLaunchFlags, mOptions);
2105
2106         // Do no move the target stack to front yet, as we might bail if
2107         // isLockTaskModeViolation fails below.
2108
2109         if (mReuseTask == null) {
2110             final TaskRecord task = mTargetStack.createTaskRecord(
2111                     mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId),
2112                     mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
2113                     mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
2114                     mVoiceInteractor, !mLaunchTaskBehind /* toTop */, mStartActivity, mSourceRecord,
2115                     mOptions);
2116             addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
2117             updateBounds(mStartActivity.getTask(), mLaunchParams.mBounds);
2118
2119             if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
2120                     + " in new task " + mStartActivity.getTask());
2121         } else {
2122             addOrReparentStartingActivity(mReuseTask, "setTaskFromReuseOrCreateNewTask");
2123         }
2124
2125         if (taskToAffiliate != null) {
2126             mStartActivity.setTaskToAffiliateWith(taskToAffiliate);
2127         }
2128
2129         if (mService.getLockTaskController().isLockTaskModeViolation(mStartActivity.getTask())) {
2130             Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
2131             return START_RETURN_LOCK_TASK_MODE_VIOLATION;
2132         }
2133
2134         if (mDoResume) {
2135             mTargetStack.moveToFront("reuseOrNewTask");
2136         }
2137         return START_SUCCESS;
2138     }
2139
2140     private void deliverNewIntent(ActivityRecord activity) {
2141         if (mIntentDelivered) {
2142             return;
2143         }
2144
2145         ActivityStack.logStartActivity(AM_NEW_INTENT, activity, activity.getTask());
2146         activity.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
2147                 mStartActivity.launchedFromPackage);
2148         mIntentDelivered = true;
2149     }
2150
2151     private int setTaskFromSourceRecord() {
2152         if (mService.getLockTaskController().isLockTaskModeViolation(mSourceRecord.getTask())) {
2153             Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
2154             return START_RETURN_LOCK_TASK_MODE_VIOLATION;
2155         }
2156
2157         final TaskRecord sourceTask = mSourceRecord.getTask();
2158         final ActivityStack sourceStack = mSourceRecord.getStack();
2159         // We only want to allow changing stack in two cases:
2160         // 1. If the target task is not the top one. Otherwise we would move the launching task to
2161         //    the other side, rather than show two side by side.
2162         // 2. If activity is not allowed on target display.
2163         final int targetDisplayId = mTargetStack != null ? mTargetStack.mDisplayId
2164                 : sourceStack.mDisplayId;
2165         final boolean moveStackAllowed = sourceStack.topTask() != sourceTask
2166                 || !mStartActivity.canBeLaunchedOnDisplay(targetDisplayId);
2167         if (moveStackAllowed) {
2168             mTargetStack = getLaunchStack(mStartActivity, mLaunchFlags, mStartActivity.getTask(),
2169                     mOptions);
2170             // If target stack is not found now - we can't just rely on the source stack, as it may
2171             // be not suitable. Let's check other displays.
2172             if (mTargetStack == null && targetDisplayId != sourceStack.mDisplayId) {
2173                 // Can't use target display, lets find a stack on the source display.
2174                 mTargetStack = mService.mStackSupervisor.getValidLaunchStackOnDisplay(
2175                         sourceStack.mDisplayId, mStartActivity);
2176             }
2177             if (mTargetStack == null) {
2178                 // There are no suitable stacks on the target and source display(s). Look on all
2179                 // displays.
2180                 mTargetStack = mService.mStackSupervisor.getNextValidLaunchStackLocked(
2181                         mStartActivity, -1 /* currentFocus */);
2182             }
2183         }
2184
2185         if (mTargetStack == null) {
2186             mTargetStack = sourceStack;
2187         } else if (mTargetStack != sourceStack) {
2188             sourceTask.reparent(mTargetStack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE,
2189                     DEFER_RESUME, "launchToSide");
2190         }
2191
2192         final TaskRecord topTask = mTargetStack.topTask();
2193         if (topTask != sourceTask && !mAvoidMoveToFront) {
2194             mTargetStack.moveTaskToFrontLocked(sourceTask, mNoAnimation, mOptions,
2195                     mStartActivity.appTimeTracker, "sourceTaskToFront");
2196         } else if (mDoResume) {
2197             mTargetStack.moveToFront("sourceStackToFront");
2198         }
2199
2200         if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0) {
2201             // In this case, we are adding the activity to an existing task, but the caller has
2202             // asked to clear that task if the activity is already running.
2203             ActivityRecord top = sourceTask.performClearTaskLocked(mStartActivity, mLaunchFlags);
2204             mKeepCurTransition = true;
2205             if (top != null) {
2206                 ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, top.getTask());
2207                 deliverNewIntent(top);
2208                 // For paranoia, make sure we have correctly resumed the top activity.
2209                 mTargetStack.mLastPausedActivity = null;
2210                 if (mDoResume) {
2211                     mSupervisor.resumeFocusedStackTopActivityLocked();
2212                 }
2213                 ActivityOptions.abort(mOptions);
2214                 return START_DELIVERED_TO_TOP;
2215             }
2216         } else if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
2217             // In this case, we are launching an activity in our own task that may already be
2218             // running somewhere in the history, and we want to shuffle it to the front of the
2219             // stack if so.
2220             final ActivityRecord top = sourceTask.findActivityInHistoryLocked(mStartActivity);
2221             if (top != null) {
2222                 final TaskRecord task = top.getTask();
2223                 task.moveActivityToFrontLocked(top);
2224                 top.updateOptionsLocked(mOptions);
2225                 ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, task);
2226                 deliverNewIntent(top);
2227                 mTargetStack.mLastPausedActivity = null;
2228                 if (mDoResume) {
2229                     mSupervisor.resumeFocusedStackTopActivityLocked();
2230                 }
2231                 return START_DELIVERED_TO_TOP;
2232             }
2233         }
2234
2235         // An existing activity is starting this new activity, so we want to keep the new one in
2236         // the same task as the one that is starting it.
2237         addOrReparentStartingActivity(sourceTask, "setTaskFromSourceRecord");
2238         if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
2239                 + " in existing task " + mStartActivity.getTask() + " from source " + mSourceRecord);
2240         return START_SUCCESS;
2241     }
2242
2243     private int setTaskFromInTask() {
2244         // The caller is asking that the new activity be started in an explicit
2245         // task it has provided to us.
2246         if (mService.getLockTaskController().isLockTaskModeViolation(mInTask)) {
2247             Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
2248             return START_RETURN_LOCK_TASK_MODE_VIOLATION;
2249         }
2250
2251         mTargetStack = mInTask.getStack();
2252
2253         // Check whether we should actually launch the new activity in to the task,
2254         // or just reuse the current activity on top.
2255         ActivityRecord top = mInTask.getTopActivity();
2256         if (top != null && top.realActivity.equals(mStartActivity.realActivity)
2257                 && top.userId == mStartActivity.userId) {
2258             if ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
2259                     || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK)) {
2260                 mTargetStack.moveTaskToFrontLocked(mInTask, mNoAnimation, mOptions,
2261                         mStartActivity.appTimeTracker, "inTaskToFront");
2262                 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
2263                     // We don't need to start a new activity, and the client said not to do
2264                     // anything if that is the case, so this is it!
2265                     return START_RETURN_INTENT_TO_CALLER;
2266                 }
2267                 deliverNewIntent(top);
2268                 return START_DELIVERED_TO_TOP;
2269             }
2270         }
2271
2272         if (!mAddingToTask) {
2273             mTargetStack.moveTaskToFrontLocked(mInTask, mNoAnimation, mOptions,
2274                     mStartActivity.appTimeTracker, "inTaskToFront");
2275             // We don't actually want to have this activity added to the task, so just
2276             // stop here but still tell the caller that we consumed the intent.
2277             ActivityOptions.abort(mOptions);
2278             return START_TASK_TO_FRONT;
2279         }
2280
2281         if (!mLaunchParams.mBounds.isEmpty()) {
2282             // TODO: Shouldn't we already know what stack to use by the time we get here?
2283             ActivityStack stack = mSupervisor.getLaunchStack(null, null, mInTask, ON_TOP);
2284             if (stack != mInTask.getStack()) {
2285                 mInTask.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, !ANIMATE,
2286                         DEFER_RESUME, "inTaskToFront");
2287                 mTargetStack = mInTask.getStack();
2288             }
2289
2290             updateBounds(mInTask, mLaunchParams.mBounds);
2291         }
2292
2293         mTargetStack.moveTaskToFrontLocked(
2294                 mInTask, mNoAnimation, mOptions, mStartActivity.appTimeTracker, "inTaskToFront");
2295
2296         addOrReparentStartingActivity(mInTask, "setTaskFromInTask");
2297         if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
2298                 + " in explicit task " + mStartActivity.getTask());
2299
2300         return START_SUCCESS;
2301     }
2302
2303     @VisibleForTesting
2304     void updateBounds(TaskRecord task, Rect bounds) {
2305         if (bounds.isEmpty()) {
2306             return;
2307         }
2308
2309         final ActivityStack stack = task.getStack();
2310         if (stack != null && stack.resizeStackWithLaunchBounds()) {
2311             mService.resizeStack(stack.mStackId, bounds, true, !PRESERVE_WINDOWS, ANIMATE, -1);
2312         } else {
2313             task.updateOverrideConfiguration(bounds);
2314         }
2315     }
2316
2317     private void setTaskToCurrentTopOrCreateNewTask() {
2318         mTargetStack = computeStackFocus(mStartActivity, false, mLaunchFlags, mOptions);
2319         if (mDoResume) {
2320             mTargetStack.moveToFront("addingToTopTask");
2321         }
2322         final ActivityRecord prev = mTargetStack.getTopActivity();
2323         final TaskRecord task = (prev != null) ? prev.getTask() : mTargetStack.createTaskRecord(
2324                 mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId), mStartActivity.info,
2325                 mIntent, null, null, true, mStartActivity, mSourceRecord, mOptions);
2326         addOrReparentStartingActivity(task, "setTaskToCurrentTopOrCreateNewTask");
2327         mTargetStack.positionChildWindowContainerAtTop(task);
2328         if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
2329                 + " in new guessed " + mStartActivity.getTask());
2330     }
2331
2332     private void addOrReparentStartingActivity(TaskRecord parent, String reason) {
2333         if (mStartActivity.getTask() == null || mStartActivity.getTask() == parent) {
2334             parent.addActivityToTop(mStartActivity);
2335         } else {
2336             mStartActivity.reparent(parent, parent.mActivities.size() /* top */, reason);
2337         }
2338     }
2339
2340     private int adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance,
2341             boolean launchSingleTask, int launchFlags) {
2342         if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2343                 (launchSingleInstance || launchSingleTask)) {
2344             // We have a conflict between the Intent and the Activity manifest, manifest wins.
2345             Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " +
2346                     "\"singleInstance\" or \"singleTask\"");
2347             launchFlags &=
2348                     ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK);
2349         } else {
2350             switch (r.info.documentLaunchMode) {
2351                 case ActivityInfo.DOCUMENT_LAUNCH_NONE:
2352                     break;
2353                 case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
2354                     launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2355                     break;
2356                 case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
2357                     launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2358                     break;
2359                 case ActivityInfo.DOCUMENT_LAUNCH_NEVER:
2360                     launchFlags &= ~FLAG_ACTIVITY_MULTIPLE_TASK;
2361                     break;
2362             }
2363         }
2364         return launchFlags;
2365     }
2366
2367     private ActivityStack computeStackFocus(ActivityRecord r, boolean newTask, int launchFlags,
2368             ActivityOptions aOptions) {
2369         final TaskRecord task = r.getTask();
2370         ActivityStack stack = getLaunchStack(r, launchFlags, task, aOptions);
2371         if (stack != null) {
2372             return stack;
2373         }
2374
2375         final ActivityStack currentStack = task != null ? task.getStack() : null;
2376         if (currentStack != null) {
2377             if (mSupervisor.mFocusedStack != currentStack) {
2378                 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
2379                         "computeStackFocus: Setting " + "focused stack to r=" + r
2380                                 + " task=" + task);
2381             } else {
2382                 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
2383                         "computeStackFocus: Focused stack already="
2384                                 + mSupervisor.mFocusedStack);
2385             }
2386             return currentStack;
2387         }
2388
2389         if (canLaunchIntoFocusedStack(r, newTask)) {
2390             if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
2391                     "computeStackFocus: Have a focused stack=" + mSupervisor.mFocusedStack);
2392             return mSupervisor.mFocusedStack;
2393         }
2394
2395         if (mPreferredDisplayId != DEFAULT_DISPLAY) {
2396             // Try to put the activity in a stack on a secondary display.
2397             stack = mSupervisor.getValidLaunchStackOnDisplay(mPreferredDisplayId, r);
2398             if (stack == null) {
2399                 // If source display is not suitable - look for topmost valid stack in the system.
2400                 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
2401                         "computeStackFocus: Can't launch on mPreferredDisplayId="
2402                                 + mPreferredDisplayId + ", looking on all displays.");
2403                 stack = mSupervisor.getNextValidLaunchStackLocked(r, mPreferredDisplayId);
2404             }
2405         }
2406         if (stack == null) {
2407             // We first try to put the task in the first dynamic stack on home display.
2408             final ActivityDisplay display = mSupervisor.getDefaultDisplay();
2409             for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
2410                 stack = display.getChildAt(stackNdx);
2411                 if (!stack.isOnHomeDisplay()) {
2412                     if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
2413                             "computeStackFocus: Setting focused stack=" + stack);
2414                     return stack;
2415                 }
2416             }
2417             // If there is no suitable dynamic stack then we figure out which static stack to use.
2418             stack = mSupervisor.getLaunchStack(r, aOptions, task, ON_TOP);
2419         }
2420         if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, "computeStackFocus: New stack r="
2421                 + r + " stackId=" + stack.mStackId);
2422         return stack;
2423     }
2424
2425     /** Check if provided activity record can launch in currently focused stack. */
2426     // TODO: This method can probably be consolidated into getLaunchStack() below.
2427     private boolean canLaunchIntoFocusedStack(ActivityRecord r, boolean newTask) {
2428         final ActivityStack focusedStack = mSupervisor.mFocusedStack;
2429         final boolean canUseFocusedStack;
2430         if (focusedStack.isActivityTypeAssistant()) {
2431             canUseFocusedStack = r.isActivityTypeAssistant();
2432         } else {
2433             switch (focusedStack.getWindowingMode()) {
2434                 case WINDOWING_MODE_FULLSCREEN:
2435                     // The fullscreen stack can contain any task regardless of if the task is
2436                     // resizeable or not. So, we let the task go in the fullscreen task if it is the
2437                     // focus stack.
2438                     canUseFocusedStack = true;
2439                     break;
2440                 case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
2441                 case WINDOWING_MODE_SPLIT_SCREEN_SECONDARY:
2442                     // Any activity which supports split screen can go in the docked stack.
2443                     canUseFocusedStack = r.supportsSplitScreenWindowingMode();
2444                     break;
2445                 case WINDOWING_MODE_FREEFORM:
2446                     // Any activity which supports freeform can go in the freeform stack.
2447                     canUseFocusedStack = r.supportsFreeform();
2448                     break;
2449                 default:
2450                     // Dynamic stacks behave similarly to the fullscreen stack and can contain any
2451                     // resizeable task.
2452                     canUseFocusedStack = !focusedStack.isOnHomeDisplay()
2453                             && r.canBeLaunchedOnDisplay(focusedStack.mDisplayId);
2454             }
2455         }
2456         return canUseFocusedStack && !newTask
2457                 // Using the focus stack isn't important enough to override the preferred display.
2458                 && (mPreferredDisplayId == focusedStack.mDisplayId);
2459     }
2460
2461     private ActivityStack getLaunchStack(ActivityRecord r, int launchFlags, TaskRecord task,
2462             ActivityOptions aOptions) {
2463         // We are reusing a task, keep the stack!
2464         if (mReuseTask != null) {
2465             return mReuseTask.getStack();
2466         }
2467
2468         if (((launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) == 0)
2469                  || mPreferredDisplayId != DEFAULT_DISPLAY) {
2470             // We don't pass in the default display id into the get launch stack call so it can do a
2471             // full resolution.
2472             final int candidateDisplay =
2473                     mPreferredDisplayId != DEFAULT_DISPLAY ? mPreferredDisplayId : INVALID_DISPLAY;
2474             return mSupervisor.getLaunchStack(r, aOptions, task, ON_TOP, candidateDisplay);
2475         }
2476         // Otherwise handle adjacent launch.
2477
2478         // The parent activity doesn't want to launch the activity on top of itself, but
2479         // instead tries to put it onto other side in side-by-side mode.
2480         final ActivityStack parentStack = task != null ? task.getStack(): mSupervisor.mFocusedStack;
2481
2482         if (parentStack != mSupervisor.mFocusedStack) {
2483             // If task's parent stack is not focused - use it during adjacent launch.
2484             return parentStack;
2485         } else {
2486             if (mSupervisor.mFocusedStack != null && task == mSupervisor.mFocusedStack.topTask()) {
2487                 // If task is already on top of focused stack - use it. We don't want to move the
2488                 // existing focused task to adjacent stack, just deliver new intent in this case.
2489                 return mSupervisor.mFocusedStack;
2490             }
2491
2492             if (parentStack != null && parentStack.inSplitScreenPrimaryWindowingMode()) {
2493                 // If parent was in docked stack, the natural place to launch another activity
2494                 // will be fullscreen, so it can appear alongside the docked window.
2495                 final int activityType = mSupervisor.resolveActivityType(r, mOptions, task);
2496                 return parentStack.getDisplay().getOrCreateStack(
2497                         WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, activityType, ON_TOP);
2498             } else {
2499                 // If the parent is not in the docked stack, we check if there is docked window
2500                 // and if yes, we will launch into that stack. If not, we just put the new
2501                 // activity into parent's stack, because we can't find a better place.
2502                 final ActivityStack dockedStack =
2503                         mSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
2504                 if (dockedStack != null && !dockedStack.shouldBeVisible(r)) {
2505                     // There is a docked stack, but it isn't visible, so we can't launch into that.
2506                     return mSupervisor.getLaunchStack(r, aOptions, task, ON_TOP);
2507                 } else {
2508                     return dockedStack;
2509                 }
2510             }
2511         }
2512     }
2513
2514     private boolean isLaunchModeOneOf(int mode1, int mode2) {
2515         return mode1 == mLaunchMode || mode2 == mLaunchMode;
2516     }
2517
2518     static boolean isDocumentLaunchesIntoExisting(int flags) {
2519         return (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2520                 (flags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0;
2521     }
2522
2523     ActivityStarter setIntent(Intent intent) {
2524         mRequest.intent = intent;
2525         return this;
2526     }
2527
2528     @VisibleForTesting
2529     Intent getIntent() {
2530         return mRequest.intent;
2531     }
2532
2533     ActivityStarter setReason(String reason) {
2534         mRequest.reason = reason;
2535         return this;
2536     }
2537
2538     ActivityStarter setCaller(IApplicationThread caller) {
2539         mRequest.caller = caller;
2540         return this;
2541     }
2542
2543     ActivityStarter setEphemeralIntent(Intent intent) {
2544         mRequest.ephemeralIntent = intent;
2545         return this;
2546     }
2547
2548
2549     ActivityStarter setResolvedType(String type) {
2550         mRequest.resolvedType = type;
2551         return this;
2552     }
2553
2554     ActivityStarter setActivityInfo(ActivityInfo info) {
2555         mRequest.activityInfo = info;
2556         return this;
2557     }
2558
2559     ActivityStarter setResolveInfo(ResolveInfo info) {
2560         mRequest.resolveInfo = info;
2561         return this;
2562     }
2563
2564     ActivityStarter setVoiceSession(IVoiceInteractionSession voiceSession) {
2565         mRequest.voiceSession = voiceSession;
2566         return this;
2567     }
2568
2569     ActivityStarter setVoiceInteractor(IVoiceInteractor voiceInteractor) {
2570         mRequest.voiceInteractor = voiceInteractor;
2571         return this;
2572     }
2573
2574     ActivityStarter setResultTo(IBinder resultTo) {
2575         mRequest.resultTo = resultTo;
2576         return this;
2577     }
2578
2579     ActivityStarter setResultWho(String resultWho) {
2580         mRequest.resultWho = resultWho;
2581         return this;
2582     }
2583
2584     ActivityStarter setRequestCode(int requestCode) {
2585         mRequest.requestCode = requestCode;
2586         return this;
2587     }
2588
2589     ActivityStarter setCallingPid(int pid) {
2590         mRequest.callingPid = pid;
2591         return this;
2592     }
2593
2594     ActivityStarter setCallingUid(int uid) {
2595         mRequest.callingUid = uid;
2596         return this;
2597     }
2598
2599     ActivityStarter setCallingPackage(String callingPackage) {
2600         mRequest.callingPackage = callingPackage;
2601         return this;
2602     }
2603
2604     ActivityStarter setRealCallingPid(int pid) {
2605         mRequest.realCallingPid = pid;
2606         return this;
2607     }
2608
2609     ActivityStarter setRealCallingUid(int uid) {
2610         mRequest.realCallingUid = uid;
2611         return this;
2612     }
2613
2614     ActivityStarter setStartFlags(int startFlags) {
2615         mRequest.startFlags = startFlags;
2616         return this;
2617     }
2618
2619     ActivityStarter setActivityOptions(SafeActivityOptions options) {
2620         mRequest.activityOptions = options;
2621         return this;
2622     }
2623
2624     ActivityStarter setActivityOptions(Bundle bOptions) {
2625         return setActivityOptions(SafeActivityOptions.fromBundle(bOptions));
2626     }
2627
2628     ActivityStarter setIgnoreTargetSecurity(boolean ignoreTargetSecurity) {
2629         mRequest.ignoreTargetSecurity = ignoreTargetSecurity;
2630         return this;
2631     }
2632
2633     ActivityStarter setFilterCallingUid(int filterCallingUid) {
2634         mRequest.filterCallingUid = filterCallingUid;
2635         return this;
2636     }
2637
2638     ActivityStarter setComponentSpecified(boolean componentSpecified) {
2639         mRequest.componentSpecified = componentSpecified;
2640         return this;
2641     }
2642
2643     ActivityStarter setOutActivity(ActivityRecord[] outActivity) {
2644         mRequest.outActivity = outActivity;
2645         return this;
2646     }
2647
2648     ActivityStarter setInTask(TaskRecord inTask) {
2649         mRequest.inTask = inTask;
2650         return this;
2651     }
2652
2653     ActivityStarter setWaitResult(WaitResult result) {
2654         mRequest.waitResult = result;
2655         return this;
2656     }
2657
2658     ActivityStarter setProfilerInfo(ProfilerInfo info) {
2659         mRequest.profilerInfo = info;
2660         return this;
2661     }
2662
2663     ActivityStarter setGlobalConfiguration(Configuration config) {
2664         mRequest.globalConfig = config;
2665         return this;
2666     }
2667
2668     ActivityStarter setUserId(int userId) {
2669         mRequest.userId = userId;
2670         return this;
2671     }
2672
2673     ActivityStarter setMayWait(int userId) {
2674         mRequest.mayWait = true;
2675         mRequest.userId = userId;
2676
2677         return this;
2678     }
2679
2680     ActivityStarter setAllowPendingRemoteAnimationRegistryLookup(boolean allowLookup) {
2681         mRequest.allowPendingRemoteAnimationRegistryLookup = allowLookup;
2682         return this;
2683     }
2684
2685     ActivityStarter setOriginatingPendingIntent(PendingIntentRecord originatingPendingIntent) {
2686         mRequest.originatingPendingIntent = originatingPendingIntent;
2687         return this;
2688     }
2689
2690     void dump(PrintWriter pw, String prefix) {
2691         prefix = prefix + "  ";
2692         pw.print(prefix);
2693         pw.print("mCurrentUser=");
2694         pw.println(mSupervisor.mCurrentUser);
2695         pw.print(prefix);
2696         pw.print("mLastStartReason=");
2697         pw.println(mLastStartReason);
2698         pw.print(prefix);
2699         pw.print("mLastStartActivityTimeMs=");
2700         pw.println(DateFormat.getDateTimeInstance().format(new Date(mLastStartActivityTimeMs)));
2701         pw.print(prefix);
2702         pw.print("mLastStartActivityResult=");
2703         pw.println(mLastStartActivityResult);
2704         ActivityRecord r = mLastStartActivityRecord[0];
2705         if (r != null) {
2706             pw.print(prefix);
2707             pw.println("mLastStartActivityRecord:");
2708             r.dump(pw, prefix + "  ");
2709         }
2710         if (mStartActivity != null) {
2711             pw.print(prefix);
2712             pw.println("mStartActivity:");
2713             mStartActivity.dump(pw, prefix + "  ");
2714         }
2715         if (mIntent != null) {
2716             pw.print(prefix);
2717             pw.print("mIntent=");
2718             pw.println(mIntent);
2719         }
2720         if (mOptions != null) {
2721             pw.print(prefix);
2722             pw.print("mOptions=");
2723             pw.println(mOptions);
2724         }
2725         pw.print(prefix);
2726         pw.print("mLaunchSingleTop=");
2727         pw.print(LAUNCH_SINGLE_TOP == mLaunchMode);
2728         pw.print(" mLaunchSingleInstance=");
2729         pw.print(LAUNCH_SINGLE_INSTANCE == mLaunchMode);
2730         pw.print(" mLaunchSingleTask=");
2731         pw.println(LAUNCH_SINGLE_TASK == mLaunchMode);
2732         pw.print(prefix);
2733         pw.print("mLaunchFlags=0x");
2734         pw.print(Integer.toHexString(mLaunchFlags));
2735         pw.print(" mDoResume=");
2736         pw.print(mDoResume);
2737         pw.print(" mAddingToTask=");
2738         pw.println(mAddingToTask);
2739     }
2740 }