• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.wm;
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_PERMISSION_DENIED;
26 import static android.app.ActivityManager.START_RETURN_INTENT_TO_CALLER;
27 import static android.app.ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
28 import static android.app.ActivityManager.START_SUCCESS;
29 import static android.app.ActivityManager.START_TASK_TO_FRONT;
30 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
31 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
32 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
33 import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
34 import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
35 import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT;
36 import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
37 import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
38 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
39 import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION;
40 import static android.content.Intent.FLAG_ACTIVITY_NO_USER_ACTION;
41 import static android.content.Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP;
42 import static android.content.Intent.FLAG_ACTIVITY_REORDER_TO_FRONT;
43 import static android.content.Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED;
44 import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
45 import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP;
46 import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
47 import static android.content.pm.ActivityInfo.DOCUMENT_LAUNCH_ALWAYS;
48 import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
49 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
50 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE_PER_TASK;
51 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
52 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
53 import static android.content.pm.ActivityInfo.launchModeToString;
54 import static android.os.Process.INVALID_UID;
55 import static android.view.Display.DEFAULT_DISPLAY;
56 import static android.view.WindowManager.TRANSIT_NONE;
57 import static android.view.WindowManager.TRANSIT_OPEN;
58 import static android.view.WindowManager.TRANSIT_TO_FRONT;
59 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT;
60 
61 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
62 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS;
63 import static com.android.server.wm.ActivityRecord.State.RESUMED;
64 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
65 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS;
66 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_USER_LEAVING;
67 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
68 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS;
69 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RESULTS;
70 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_USER_LEAVING;
71 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
72 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
73 import static com.android.server.wm.ActivityTaskManagerService.ANIMATE;
74 import static com.android.server.wm.ActivityTaskSupervisor.DEFER_RESUME;
75 import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP;
76 import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS;
77 import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_DEFAULT;
78 import static com.android.server.wm.BackgroundActivityStartController.BAL_BLOCK;
79 import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_BOUNDS;
80 import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_DISPLAY;
81 import static com.android.server.wm.Task.REPARENT_MOVE_ROOT_TASK_TO_FRONT;
82 import static com.android.server.wm.TaskFragment.EMBEDDING_ALLOWED;
83 import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_MIN_DIMENSION_VIOLATION;
84 import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_NEW_TASK;
85 import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_UNTRUSTED_HOST;
86 import static com.android.server.wm.WindowContainer.POSITION_TOP;
87 
88 import android.annotation.NonNull;
89 import android.annotation.Nullable;
90 import android.app.ActivityManager;
91 import android.app.ActivityOptions;
92 import android.app.IApplicationThread;
93 import android.app.PendingIntent;
94 import android.app.ProfilerInfo;
95 import android.app.WaitResult;
96 import android.app.WindowConfiguration;
97 import android.compat.annotation.ChangeId;
98 import android.compat.annotation.EnabledSince;
99 import android.content.IIntentSender;
100 import android.content.Intent;
101 import android.content.IntentSender;
102 import android.content.pm.ActivityInfo;
103 import android.content.pm.ApplicationInfo;
104 import android.content.pm.AuxiliaryResolveInfo;
105 import android.content.pm.PackageManager;
106 import android.content.pm.PackageManagerInternal;
107 import android.content.pm.ResolveInfo;
108 import android.content.pm.UserInfo;
109 import android.content.res.Configuration;
110 import android.os.Binder;
111 import android.os.Build;
112 import android.os.Bundle;
113 import android.os.IBinder;
114 import android.os.RemoteException;
115 import android.os.Trace;
116 import android.os.UserHandle;
117 import android.os.UserManager;
118 import android.service.voice.IVoiceInteractionSession;
119 import android.text.TextUtils;
120 import android.util.Pools.SynchronizedPool;
121 import android.util.Slog;
122 import android.window.RemoteTransition;
123 
124 import com.android.internal.annotations.VisibleForTesting;
125 import com.android.internal.app.HeavyWeightSwitcherActivity;
126 import com.android.internal.app.IVoiceInteractor;
127 import com.android.internal.protolog.common.ProtoLog;
128 import com.android.internal.util.FrameworkStatsLog;
129 import com.android.server.am.PendingIntentRecord;
130 import com.android.server.pm.InstantAppResolver;
131 import com.android.server.power.ShutdownCheckPoints;
132 import com.android.server.statusbar.StatusBarManagerInternal;
133 import com.android.server.uri.NeededUriGrants;
134 import com.android.server.wm.ActivityMetricsLogger.LaunchingState;
135 import com.android.server.wm.BackgroundActivityStartController.BalCode;
136 import com.android.server.wm.LaunchParamsController.LaunchParams;
137 import com.android.server.wm.TaskFragment.EmbeddingCheckResult;
138 
139 import java.io.PrintWriter;
140 import java.text.DateFormat;
141 import java.util.Date;
142 
143 /**
144  * Controller for interpreting how and then launching an activity.
145  *
146  * This class collects all the logic for determining how an intent and flags should be turned into
147  * an activity and associated task and root task.
148  */
149 class ActivityStarter {
150     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStarter" : TAG_ATM;
151     private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS;
152     private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
153     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
154     private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING;
155     private static final int INVALID_LAUNCH_MODE = -1;
156 
157     /**
158      * Feature flag to protect PendingIntent being abused to start background activity.
159      */
160     @ChangeId
161     @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
162     static final long ENABLE_PENDING_INTENT_BAL_OPTION = 192341120L;
163 
164     private final ActivityTaskManagerService mService;
165     private final RootWindowContainer mRootWindowContainer;
166     private final ActivityTaskSupervisor mSupervisor;
167     private final ActivityStartInterceptor mInterceptor;
168     private final ActivityStartController mController;
169 
170     // Share state variable among methods when starting an activity.
171     @VisibleForTesting
172     ActivityRecord mStartActivity;
173     private Intent mIntent;
174     private int mCallingUid;
175     private ActivityOptions mOptions;
176 
177     // If it is BAL_BLOCK, background activity can only be started in an existing task that contains
178     // an activity with same uid, or if activity starts are enabled in developer options.
179     @BalCode
180     private int mBalCode;
181 
182     private int mLaunchMode;
183     private boolean mLaunchTaskBehind;
184     private int mLaunchFlags;
185 
186     private LaunchParams mLaunchParams = new LaunchParams();
187 
188     private ActivityRecord mNotTop;
189     private boolean mDoResume;
190     private int mStartFlags;
191     private ActivityRecord mSourceRecord;
192 
193     // The task display area to launch the activity onto, barring any strong reason to do otherwise.
194     private TaskDisplayArea mPreferredTaskDisplayArea;
195     private int mPreferredWindowingMode;
196 
197     private Task mInTask;
198     private TaskFragment mInTaskFragment;
199     private TaskFragment mAddingToTaskFragment;
200     @VisibleForTesting
201     boolean mAddingToTask;
202     // Activity that was moved to the top of its task in situations where activity-order changes
203     // due to launch flags (eg. REORDER_TO_TOP).
204     @VisibleForTesting
205     ActivityRecord mMovedToTopActivity;
206 
207     private Task mSourceRootTask;
208     private Task mTargetRootTask;
209     // The task that the last activity was started into. We currently reset the actual start
210     // activity's task and as a result may not have a reference to the task in all cases
211     private Task mTargetTask;
212     private boolean mIsTaskCleared;
213     private boolean mMovedToFront;
214     private boolean mNoAnimation;
215     private boolean mAvoidMoveToFront;
216     private boolean mFrozeTaskList;
217     private boolean mTransientLaunch;
218     // The task which was above the targetTask before starting this activity. null if the targetTask
219     // was already on top or if the activity is in a new task.
220     private Task mPriorAboveTask;
221     private boolean mDisplayLockAndOccluded;
222 
223     // We must track when we deliver the new intent since multiple code paths invoke
224     // {@link #deliverNewIntent}. This is due to early returns in the code path. This flag is used
225     // inside {@link #deliverNewIntent} to suppress duplicate requests and ensure the intent is
226     // delivered at most once.
227     private boolean mIntentDelivered;
228 
229     private IVoiceInteractionSession mVoiceSession;
230     private IVoiceInteractor mVoiceInteractor;
231 
232     // Last activity record we attempted to start
233     private ActivityRecord mLastStartActivityRecord;
234     // The result of the last activity we attempted to start.
235     private int mLastStartActivityResult;
236     // Time in milli seconds we attempted to start the last activity.
237     private long mLastStartActivityTimeMs;
238     // The reason we were trying to start the last activity
239     private String mLastStartReason;
240 
241     /*
242      * Request details provided through setter methods. Should be reset after {@link #execute()}
243      * to avoid unnecessarily retaining parameters. Note that the request is ignored when
244      * {@link #startResolvedActivity} is invoked directly.
245      */
246     @VisibleForTesting
247     Request mRequest = new Request();
248 
249     /**
250      * An interface that to provide {@link ActivityStarter} instances to the controller. This is
251      * used by tests to inject their own starter implementations for verification purposes.
252      */
253     @VisibleForTesting
254     interface Factory {
255         /**
256          * Sets the {@link ActivityStartController} to be passed to {@link ActivityStarter}.
257          */
setController(ActivityStartController controller)258         void setController(ActivityStartController controller);
259 
260         /**
261          * Generates an {@link ActivityStarter} that is ready to handle a new start request.
262          * @return an {@link ActivityStarter}
263          */
obtain()264         ActivityStarter obtain();
265 
266         /**
267          * Recycles a starter for reuse.
268          */
recycle(ActivityStarter starter)269         void recycle(ActivityStarter starter);
270     }
271 
272     /**
273      * Default implementation of {@link StarterFactory}.
274      */
275     static class DefaultFactory implements Factory {
276         /**
277          * The maximum count of starters that should be active at one time:
278          * 1. last ran starter (for logging and post activity processing)
279          * 2. current running starter
280          * 3. starter from re-entry in (2)
281          */
282         private final int MAX_STARTER_COUNT = 3;
283 
284         private ActivityStartController mController;
285         private ActivityTaskManagerService mService;
286         private ActivityTaskSupervisor mSupervisor;
287         private ActivityStartInterceptor mInterceptor;
288 
289         private SynchronizedPool<ActivityStarter> mStarterPool =
290                 new SynchronizedPool<>(MAX_STARTER_COUNT);
291 
DefaultFactory(ActivityTaskManagerService service, ActivityTaskSupervisor supervisor, ActivityStartInterceptor interceptor)292         DefaultFactory(ActivityTaskManagerService service,
293                 ActivityTaskSupervisor supervisor, ActivityStartInterceptor interceptor) {
294             mService = service;
295             mSupervisor = supervisor;
296             mInterceptor = interceptor;
297         }
298 
299         @Override
setController(ActivityStartController controller)300         public void setController(ActivityStartController controller) {
301             mController = controller;
302         }
303 
304         @Override
obtain()305         public ActivityStarter obtain() {
306             ActivityStarter starter = mStarterPool.acquire();
307 
308             if (starter == null) {
309                 if (mService.mRootWindowContainer == null) {
310                     throw new IllegalStateException("Too early to start activity.");
311                 }
312                 starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
313             }
314 
315             return starter;
316         }
317 
318         @Override
recycle(ActivityStarter starter)319         public void recycle(ActivityStarter starter) {
320             starter.reset(true /* clearRequest*/);
321             mStarterPool.release(starter);
322         }
323     }
324 
325     /**
326      * Container for capturing initial start request details. This information is NOT reset until
327      * the {@link ActivityStarter} is recycled, allowing for multiple invocations with the same
328      * parameters.
329      *
330      * TODO(b/64750076): Investigate consolidating member variables of {@link ActivityStarter} with
331      * the request object. Note that some member variables are referenced in
332      * {@link #dump(PrintWriter, String)} and therefore cannot be cleared immediately after
333      * execution.
334      */
335     @VisibleForTesting
336     static class Request {
337         private static final int DEFAULT_CALLING_UID = -1;
338         private static final int DEFAULT_CALLING_PID = 0;
339         static final int DEFAULT_REAL_CALLING_UID = -1;
340         static final int DEFAULT_REAL_CALLING_PID = 0;
341 
342         IApplicationThread caller;
343         Intent intent;
344         NeededUriGrants intentGrants;
345         // A copy of the original requested intent, in case for ephemeral app launch.
346         Intent ephemeralIntent;
347         String resolvedType;
348         ActivityInfo activityInfo;
349         ResolveInfo resolveInfo;
350         IVoiceInteractionSession voiceSession;
351         IVoiceInteractor voiceInteractor;
352         IBinder resultTo;
353         String resultWho;
354         int requestCode;
355         int callingPid = DEFAULT_CALLING_PID;
356         int callingUid = DEFAULT_CALLING_UID;
357         String callingPackage;
358         @Nullable String callingFeatureId;
359         int realCallingPid = DEFAULT_REAL_CALLING_PID;
360         int realCallingUid = DEFAULT_REAL_CALLING_UID;
361         int startFlags;
362         SafeActivityOptions activityOptions;
363         boolean ignoreTargetSecurity;
364         boolean componentSpecified;
365         boolean avoidMoveToFront;
366         ActivityRecord[] outActivity;
367         Task inTask;
368         TaskFragment inTaskFragment;
369         String reason;
370         ProfilerInfo profilerInfo;
371         Configuration globalConfig;
372         int userId;
373         WaitResult waitResult;
374         int filterCallingUid;
375         PendingIntentRecord originatingPendingIntent;
376         boolean allowBackgroundActivityStart;
377         /**
378          * The error callback token passed in {@link android.window.WindowContainerTransaction}
379          * for TaskFragment operation error handling via
380          * {@link android.window.TaskFragmentOrganizer#onTaskFragmentError(IBinder, Throwable)}.
381          */
382         @Nullable
383         IBinder errorCallbackToken;
384 
385         /**
386          * If set to {@code true}, allows this activity start to look into
387          * {@link PendingRemoteAnimationRegistry}
388          */
389         boolean allowPendingRemoteAnimationRegistryLookup;
390 
391         /**
392          * Ensure constructed request matches reset instance.
393          */
Request()394         Request() {
395             reset();
396         }
397 
398         /**
399          * Sets values back to the initial state, clearing any held references.
400          */
reset()401         void reset() {
402             caller = null;
403             intent = null;
404             intentGrants = null;
405             ephemeralIntent = null;
406             resolvedType = null;
407             activityInfo = null;
408             resolveInfo = null;
409             voiceSession = null;
410             voiceInteractor = null;
411             resultTo = null;
412             resultWho = null;
413             requestCode = 0;
414             callingPid = DEFAULT_CALLING_PID;
415             callingUid = DEFAULT_CALLING_UID;
416             callingPackage = null;
417             callingFeatureId = null;
418             realCallingPid = DEFAULT_REAL_CALLING_PID;
419             realCallingUid = DEFAULT_REAL_CALLING_UID;
420             startFlags = 0;
421             activityOptions = null;
422             ignoreTargetSecurity = false;
423             componentSpecified = false;
424             outActivity = null;
425             inTask = null;
426             inTaskFragment = null;
427             reason = null;
428             profilerInfo = null;
429             globalConfig = null;
430             userId = 0;
431             waitResult = null;
432             avoidMoveToFront = false;
433             allowPendingRemoteAnimationRegistryLookup = true;
434             filterCallingUid = UserHandle.USER_NULL;
435             originatingPendingIntent = null;
436             allowBackgroundActivityStart = false;
437             errorCallbackToken = null;
438         }
439 
440         /**
441          * Adopts all values from passed in request.
442          */
set(@onNull Request request)443         void set(@NonNull Request request) {
444             caller = request.caller;
445             intent = request.intent;
446             intentGrants = request.intentGrants;
447             ephemeralIntent = request.ephemeralIntent;
448             resolvedType = request.resolvedType;
449             activityInfo = request.activityInfo;
450             resolveInfo = request.resolveInfo;
451             voiceSession = request.voiceSession;
452             voiceInteractor = request.voiceInteractor;
453             resultTo = request.resultTo;
454             resultWho = request.resultWho;
455             requestCode = request.requestCode;
456             callingPid = request.callingPid;
457             callingUid = request.callingUid;
458             callingPackage = request.callingPackage;
459             callingFeatureId = request.callingFeatureId;
460             realCallingPid = request.realCallingPid;
461             realCallingUid = request.realCallingUid;
462             startFlags = request.startFlags;
463             activityOptions = request.activityOptions;
464             ignoreTargetSecurity = request.ignoreTargetSecurity;
465             componentSpecified = request.componentSpecified;
466             outActivity = request.outActivity;
467             inTask = request.inTask;
468             inTaskFragment = request.inTaskFragment;
469             reason = request.reason;
470             profilerInfo = request.profilerInfo;
471             globalConfig = request.globalConfig;
472             userId = request.userId;
473             waitResult = request.waitResult;
474             avoidMoveToFront = request.avoidMoveToFront;
475             allowPendingRemoteAnimationRegistryLookup
476                     = request.allowPendingRemoteAnimationRegistryLookup;
477             filterCallingUid = request.filterCallingUid;
478             originatingPendingIntent = request.originatingPendingIntent;
479             allowBackgroundActivityStart = request.allowBackgroundActivityStart;
480             errorCallbackToken = request.errorCallbackToken;
481         }
482 
483         /**
484          * Resolve activity from the given intent for this launch.
485          */
resolveActivity(ActivityTaskSupervisor supervisor)486         void resolveActivity(ActivityTaskSupervisor supervisor) {
487             if (realCallingPid == Request.DEFAULT_REAL_CALLING_PID) {
488                 realCallingPid = Binder.getCallingPid();
489             }
490             if (realCallingUid == Request.DEFAULT_REAL_CALLING_UID) {
491                 realCallingUid = Binder.getCallingUid();
492             }
493 
494             if (callingUid >= 0) {
495                 callingPid = -1;
496             } else if (caller == null) {
497                 callingPid = realCallingPid;
498                 callingUid = realCallingUid;
499             } else {
500                 callingPid = callingUid = -1;
501             }
502 
503             // To determine the set of needed Uri permission grants, we need the
504             // "resolved" calling UID, where we try our best to identify the
505             // actual caller that is starting this activity
506             int resolvedCallingUid = callingUid;
507             if (caller != null) {
508                 synchronized (supervisor.mService.mGlobalLock) {
509                     final WindowProcessController callerApp = supervisor.mService
510                             .getProcessController(caller);
511                     if (callerApp != null) {
512                         resolvedCallingUid = callerApp.mInfo.uid;
513                     }
514                 }
515             }
516 
517             // Save a copy in case ephemeral needs it
518             ephemeralIntent = new Intent(intent);
519             // Don't modify the client's object!
520             intent = new Intent(intent);
521             if (intent.getComponent() != null
522                     && !(Intent.ACTION_VIEW.equals(intent.getAction()) && intent.getData() == null)
523                     && !Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE.equals(intent.getAction())
524                     && !Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE.equals(intent.getAction())
525                     && supervisor.mService.getPackageManagerInternalLocked()
526                             .isInstantAppInstallerComponent(intent.getComponent())) {
527                 // Intercept intents targeted directly to the ephemeral installer the ephemeral
528                 // installer should never be started with a raw Intent; instead adjust the intent
529                 // so it looks like a "normal" instant app launch.
530                 intent.setComponent(null /* component */);
531             }
532 
533             resolveInfo = supervisor.resolveIntent(intent, resolvedType, userId,
534                     0 /* matchFlags */,
535                     computeResolveFilterUid(callingUid, realCallingUid, filterCallingUid));
536             if (resolveInfo == null) {
537                 final UserInfo userInfo = supervisor.getUserInfo(userId);
538                 if (userInfo != null && userInfo.isManagedProfile()) {
539                     // Special case for managed profiles, if attempting to launch non-cryto aware
540                     // app in a locked managed profile from an unlocked parent allow it to resolve
541                     // as user will be sent via confirm credentials to unlock the profile.
542                     final UserManager userManager = UserManager.get(supervisor.mService.mContext);
543                     boolean profileLockedAndParentUnlockingOrUnlocked = false;
544                     final long token = Binder.clearCallingIdentity();
545                     try {
546                         final UserInfo parent = userManager.getProfileParent(userId);
547                         profileLockedAndParentUnlockingOrUnlocked = (parent != null)
548                                 && userManager.isUserUnlockingOrUnlocked(parent.id)
549                                 && !userManager.isUserUnlockingOrUnlocked(userId);
550                     } finally {
551                         Binder.restoreCallingIdentity(token);
552                     }
553                     if (profileLockedAndParentUnlockingOrUnlocked) {
554                         resolveInfo = supervisor.resolveIntent(intent, resolvedType, userId,
555                                 PackageManager.MATCH_DIRECT_BOOT_AWARE
556                                         | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
557                                 computeResolveFilterUid(callingUid, realCallingUid,
558                                         filterCallingUid));
559                     }
560                 }
561             }
562 
563             // Collect information about the target of the Intent.
564             activityInfo = supervisor.resolveActivity(intent, resolveInfo, startFlags,
565                     profilerInfo);
566 
567             // Carefully collect grants without holding lock
568             if (activityInfo != null) {
569                 intentGrants = supervisor.mService.mUgmInternal.checkGrantUriPermissionFromIntent(
570                         intent, resolvedCallingUid, activityInfo.applicationInfo.packageName,
571                         UserHandle.getUserId(activityInfo.applicationInfo.uid));
572             }
573         }
574     }
575 
ActivityStarter(ActivityStartController controller, ActivityTaskManagerService service, ActivityTaskSupervisor supervisor, ActivityStartInterceptor interceptor)576     ActivityStarter(ActivityStartController controller, ActivityTaskManagerService service,
577             ActivityTaskSupervisor supervisor, ActivityStartInterceptor interceptor) {
578         mController = controller;
579         mService = service;
580         mRootWindowContainer = service.mRootWindowContainer;
581         mSupervisor = supervisor;
582         mInterceptor = interceptor;
583         reset(true);
584     }
585 
586     /**
587      * Effectively duplicates the starter passed in. All state and request values will be
588      * mirrored.
589      * @param starter
590      */
set(ActivityStarter starter)591     void set(ActivityStarter starter) {
592         mStartActivity = starter.mStartActivity;
593         mIntent = starter.mIntent;
594         mCallingUid = starter.mCallingUid;
595         mOptions = starter.mOptions;
596         mBalCode = starter.mBalCode;
597 
598         mLaunchTaskBehind = starter.mLaunchTaskBehind;
599         mLaunchFlags = starter.mLaunchFlags;
600         mLaunchMode = starter.mLaunchMode;
601 
602         mLaunchParams.set(starter.mLaunchParams);
603 
604         mNotTop = starter.mNotTop;
605         mDoResume = starter.mDoResume;
606         mStartFlags = starter.mStartFlags;
607         mSourceRecord = starter.mSourceRecord;
608         mPreferredTaskDisplayArea = starter.mPreferredTaskDisplayArea;
609         mPreferredWindowingMode = starter.mPreferredWindowingMode;
610 
611         mInTask = starter.mInTask;
612         mInTaskFragment = starter.mInTaskFragment;
613         mAddingToTask = starter.mAddingToTask;
614 
615         mSourceRootTask = starter.mSourceRootTask;
616 
617         mTargetTask = starter.mTargetTask;
618         mTargetRootTask = starter.mTargetRootTask;
619         mIsTaskCleared = starter.mIsTaskCleared;
620         mMovedToFront = starter.mMovedToFront;
621         mNoAnimation = starter.mNoAnimation;
622         mAvoidMoveToFront = starter.mAvoidMoveToFront;
623         mFrozeTaskList = starter.mFrozeTaskList;
624 
625         mVoiceSession = starter.mVoiceSession;
626         mVoiceInteractor = starter.mVoiceInteractor;
627 
628         mIntentDelivered = starter.mIntentDelivered;
629         mLastStartActivityResult = starter.mLastStartActivityResult;
630         mLastStartActivityTimeMs = starter.mLastStartActivityTimeMs;
631         mLastStartReason = starter.mLastStartReason;
632 
633         mRequest.set(starter.mRequest);
634     }
635 
relatedToPackage(String packageName)636     boolean relatedToPackage(String packageName) {
637         return (mLastStartActivityRecord != null
638                 && packageName.equals(mLastStartActivityRecord.packageName))
639                 || (mStartActivity != null && packageName.equals(mStartActivity.packageName));
640     }
641 
642     /**
643      * Resolve necessary information according the request parameters provided earlier, and execute
644      * the request which begin the journey of starting an activity.
645      * @return The starter result.
646      */
execute()647     int execute() {
648         try {
649             onExecutionStarted();
650 
651             // Refuse possible leaked file descriptors
652             if (mRequest.intent != null && mRequest.intent.hasFileDescriptors()) {
653                 throw new IllegalArgumentException("File descriptors passed in Intent");
654             }
655 
656             final LaunchingState launchingState;
657             synchronized (mService.mGlobalLock) {
658                 final ActivityRecord caller = ActivityRecord.forTokenLocked(mRequest.resultTo);
659                 final int callingUid = mRequest.realCallingUid == Request.DEFAULT_REAL_CALLING_UID
660                         ?  Binder.getCallingUid() : mRequest.realCallingUid;
661                 launchingState = mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(
662                         mRequest.intent, caller, callingUid);
663             }
664 
665             // If the caller hasn't already resolved the activity, we're willing
666             // to do so here. If the caller is already holding the WM lock here,
667             // and we need to check dynamic Uri permissions, then we're forced
668             // to assume those permissions are denied to avoid deadlocking.
669             if (mRequest.activityInfo == null) {
670                 mRequest.resolveActivity(mSupervisor);
671             }
672 
673             // Add checkpoint for this shutdown or reboot attempt, so we can record the original
674             // intent action and package name.
675             if (mRequest.intent != null) {
676                 String intentAction = mRequest.intent.getAction();
677                 String callingPackage = mRequest.callingPackage;
678                 if (intentAction != null && callingPackage != null
679                         && (Intent.ACTION_REQUEST_SHUTDOWN.equals(intentAction)
680                                 || Intent.ACTION_SHUTDOWN.equals(intentAction)
681                                 || Intent.ACTION_REBOOT.equals(intentAction))) {
682                     ShutdownCheckPoints.recordCheckPoint(intentAction, callingPackage, null);
683                 }
684             }
685 
686             int res;
687             synchronized (mService.mGlobalLock) {
688                 final boolean globalConfigWillChange = mRequest.globalConfig != null
689                         && mService.getGlobalConfiguration().diff(mRequest.globalConfig) != 0;
690                 final Task rootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
691                 if (rootTask != null) {
692                     rootTask.mConfigWillChange = globalConfigWillChange;
693                 }
694                 ProtoLog.v(WM_DEBUG_CONFIGURATION, "Starting activity when config "
695                         + "will change = %b", globalConfigWillChange);
696 
697                 final long origId = Binder.clearCallingIdentity();
698 
699                 res = resolveToHeavyWeightSwitcherIfNeeded();
700                 if (res != START_SUCCESS) {
701                     return res;
702                 }
703                 res = executeRequest(mRequest);
704 
705                 Binder.restoreCallingIdentity(origId);
706 
707                 if (globalConfigWillChange) {
708                     // If the caller also wants to switch to a new configuration, do so now.
709                     // This allows a clean switch, as we are waiting for the current activity
710                     // to pause (so we will not destroy it), and have not yet started the
711                     // next activity.
712                     mService.mAmInternal.enforceCallingPermission(
713                             android.Manifest.permission.CHANGE_CONFIGURATION,
714                             "updateConfiguration()");
715                     if (rootTask != null) {
716                         rootTask.mConfigWillChange = false;
717                     }
718                     ProtoLog.v(WM_DEBUG_CONFIGURATION,
719                                 "Updating to new configuration after starting activity.");
720 
721                     mService.updateConfigurationLocked(mRequest.globalConfig, null, false);
722                 }
723 
724                 // The original options may have additional info about metrics. The mOptions is not
725                 // used here because it may be cleared in setTargetRootTaskIfNeeded.
726                 final ActivityOptions originalOptions = mRequest.activityOptions != null
727                         ? mRequest.activityOptions.getOriginalOptions() : null;
728                 // If the new record is the one that started, a new activity has created.
729                 final boolean newActivityCreated = mStartActivity == mLastStartActivityRecord;
730                 // Notify ActivityMetricsLogger that the activity has launched.
731                 // ActivityMetricsLogger will then wait for the windows to be drawn and populate
732                 // WaitResult.
733                 mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState, res,
734                         newActivityCreated, mLastStartActivityRecord, originalOptions);
735                 if (mRequest.waitResult != null) {
736                     mRequest.waitResult.result = res;
737                     res = waitResultIfNeeded(mRequest.waitResult, mLastStartActivityRecord,
738                             launchingState);
739                 }
740                 return getExternalResult(res);
741             }
742         } finally {
743             onExecutionComplete();
744         }
745     }
746 
747     /**
748      * Updates the request to heavy-weight switch if this is a heavy-weight process while there
749      * already have another, different heavy-weight process running.
750      */
resolveToHeavyWeightSwitcherIfNeeded()751     private int resolveToHeavyWeightSwitcherIfNeeded() {
752         if (mRequest.activityInfo == null || !mService.mHasHeavyWeightFeature
753                 || (mRequest.activityInfo.applicationInfo.privateFlags
754                         & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) == 0) {
755             return START_SUCCESS;
756         }
757 
758         if (!mRequest.activityInfo.processName.equals(
759                 mRequest.activityInfo.applicationInfo.packageName)) {
760             return START_SUCCESS;
761         }
762 
763         final WindowProcessController heavy = mService.mHeavyWeightProcess;
764         if (heavy == null || (heavy.mInfo.uid == mRequest.activityInfo.applicationInfo.uid
765                 && heavy.mName.equals(mRequest.activityInfo.processName))) {
766             return START_SUCCESS;
767         }
768 
769         int appCallingUid = mRequest.callingUid;
770         if (mRequest.caller != null) {
771             WindowProcessController callerApp = mService.getProcessController(mRequest.caller);
772             if (callerApp != null) {
773                 appCallingUid = callerApp.mInfo.uid;
774             } else {
775                 Slog.w(TAG, "Unable to find app for caller " + mRequest.caller + " (pid="
776                         + mRequest.callingPid + ") when starting: " + mRequest.intent.toString());
777                 SafeActivityOptions.abort(mRequest.activityOptions);
778                 return START_PERMISSION_DENIED;
779             }
780         }
781 
782         final IIntentSender target = mService.getIntentSenderLocked(
783                 ActivityManager.INTENT_SENDER_ACTIVITY, "android" /* packageName */,
784                 null /* featureId */, appCallingUid, mRequest.userId, null /* token */,
785                 null /* resultWho*/, 0 /* requestCode*/, new Intent[]{mRequest.intent},
786                 new String[]{mRequest.resolvedType},
787                 PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT,
788                 null /* bOptions */);
789 
790         final Intent newIntent = new Intent();
791         if (mRequest.requestCode >= 0) {
792             // Caller is requesting a result.
793             newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
794         }
795         newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT, new IntentSender(target));
796         heavy.updateIntentForHeavyWeightActivity(newIntent);
797         newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
798                 mRequest.activityInfo.packageName);
799         newIntent.setFlags(mRequest.intent.getFlags());
800         newIntent.setClassName("android" /* packageName */,
801                 HeavyWeightSwitcherActivity.class.getName());
802         mRequest.intent = newIntent;
803         mRequest.resolvedType = null;
804         mRequest.caller = null;
805         mRequest.callingUid = Binder.getCallingUid();
806         mRequest.callingPid = Binder.getCallingPid();
807         mRequest.componentSpecified = true;
808         mRequest.resolveInfo = mSupervisor.resolveIntent(mRequest.intent, null /* resolvedType */,
809                 mRequest.userId, 0 /* matchFlags */,
810                 computeResolveFilterUid(mRequest.callingUid, mRequest.realCallingUid,
811                         mRequest.filterCallingUid));
812         mRequest.activityInfo =
813                 mRequest.resolveInfo != null ? mRequest.resolveInfo.activityInfo : null;
814         if (mRequest.activityInfo != null) {
815             mRequest.activityInfo = mService.mAmInternal.getActivityInfoForUser(
816                     mRequest.activityInfo, mRequest.userId);
817         }
818 
819         return START_SUCCESS;
820     }
821 
822     /**
823      * Wait for activity launch completes.
824      */
waitResultIfNeeded(WaitResult waitResult, ActivityRecord r, LaunchingState launchingState)825     private int waitResultIfNeeded(WaitResult waitResult, ActivityRecord r,
826             LaunchingState launchingState) {
827         final int res = waitResult.result;
828         if (res == START_DELIVERED_TO_TOP
829                 || (res == START_TASK_TO_FRONT && r.nowVisible && r.isState(RESUMED))) {
830             // The activity should already be visible, so nothing to wait.
831             waitResult.timeout = false;
832             waitResult.who = r.mActivityComponent;
833             waitResult.totalTime = 0;
834             return res;
835         }
836         mSupervisor.waitActivityVisibleOrLaunched(waitResult, r, launchingState);
837         if (res == START_SUCCESS && waitResult.result == START_TASK_TO_FRONT) {
838             // A trampoline activity is launched and it brings another existing activity to front.
839             return START_TASK_TO_FRONT;
840         }
841         return res;
842     }
843 
844     /**
845      * Executing activity start request and starts the journey of starting an activity. Here
846      * begins with performing several preliminary checks. The normally activity launch flow will
847      * go through {@link #startActivityUnchecked} to {@link #startActivityInner}.
848      */
executeRequest(Request request)849     private int executeRequest(Request request) {
850         if (TextUtils.isEmpty(request.reason)) {
851             throw new IllegalArgumentException("Need to specify a reason.");
852         }
853         mLastStartReason = request.reason;
854         mLastStartActivityTimeMs = System.currentTimeMillis();
855         mLastStartActivityRecord = null;
856 
857         final IApplicationThread caller = request.caller;
858         Intent intent = request.intent;
859         NeededUriGrants intentGrants = request.intentGrants;
860         String resolvedType = request.resolvedType;
861         ActivityInfo aInfo = request.activityInfo;
862         ResolveInfo rInfo = request.resolveInfo;
863         final IVoiceInteractionSession voiceSession = request.voiceSession;
864         final IBinder resultTo = request.resultTo;
865         String resultWho = request.resultWho;
866         int requestCode = request.requestCode;
867         int callingPid = request.callingPid;
868         int callingUid = request.callingUid;
869         String callingPackage = request.callingPackage;
870         String callingFeatureId = request.callingFeatureId;
871         final int realCallingPid = request.realCallingPid;
872         final int realCallingUid = request.realCallingUid;
873         final int startFlags = request.startFlags;
874         final SafeActivityOptions options = request.activityOptions;
875         Task inTask = request.inTask;
876         TaskFragment inTaskFragment = request.inTaskFragment;
877 
878         int err = ActivityManager.START_SUCCESS;
879         // Pull the optional Ephemeral Installer-only bundle out of the options early.
880         final Bundle verificationBundle =
881                 options != null ? options.popAppVerificationBundle() : null;
882 
883         WindowProcessController callerApp = null;
884         if (caller != null) {
885             callerApp = mService.getProcessController(caller);
886             if (callerApp != null) {
887                 callingPid = callerApp.getPid();
888                 callingUid = callerApp.mInfo.uid;
889             } else {
890                 Slog.w(TAG, "Unable to find app for caller " + caller + " (pid=" + callingPid
891                         + ") when starting: " + intent.toString());
892                 err = START_PERMISSION_DENIED;
893             }
894         }
895 
896         final int userId = aInfo != null && aInfo.applicationInfo != null
897                 ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
898         if (err == ActivityManager.START_SUCCESS) {
899             Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
900                     + "} from uid " + callingUid);
901         }
902 
903         ActivityRecord sourceRecord = null;
904         ActivityRecord resultRecord = null;
905         if (resultTo != null) {
906             sourceRecord = ActivityRecord.isInAnyTask(resultTo);
907             if (DEBUG_RESULTS) {
908                 Slog.v(TAG_RESULTS, "Will send result to " + resultTo + " " + sourceRecord);
909             }
910             if (sourceRecord != null) {
911                 if (requestCode >= 0 && !sourceRecord.finishing) {
912                     resultRecord = sourceRecord;
913                 }
914             }
915         }
916 
917         final int launchFlags = intent.getFlags();
918         if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
919             // Transfer the result target from the source activity to the new one being started,
920             // including any failures.
921             if (requestCode >= 0) {
922                 SafeActivityOptions.abort(options);
923                 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
924             }
925             resultRecord = sourceRecord.resultTo;
926             if (resultRecord != null && !resultRecord.isInRootTaskLocked()) {
927                 resultRecord = null;
928             }
929             resultWho = sourceRecord.resultWho;
930             requestCode = sourceRecord.requestCode;
931             sourceRecord.resultTo = null;
932             if (resultRecord != null) {
933                 resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
934             }
935             if (sourceRecord.launchedFromUid == callingUid) {
936                 // The new activity is being launched from the same uid as the previous activity
937                 // in the flow, and asking to forward its result back to the previous.  In this
938                 // case the activity is serving as a trampoline between the two, so we also want
939                 // to update its launchedFromPackage to be the same as the previous activity.
940                 // Note that this is safe, since we know these two packages come from the same
941                 // uid; the caller could just as well have supplied that same package name itself
942                 // . This specifially deals with the case of an intent picker/chooser being
943                 // launched in the app flow to redirect to an activity picked by the user, where
944                 // we want the final activity to consider it to have been launched by the
945                 // previous app activity.
946                 callingPackage = sourceRecord.launchedFromPackage;
947                 callingFeatureId = sourceRecord.launchedFromFeatureId;
948             }
949         }
950 
951         if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
952             // We couldn't find a class that can handle the given Intent.
953             // That's the end of that!
954             err = ActivityManager.START_INTENT_NOT_RESOLVED;
955         }
956 
957         if (err == ActivityManager.START_SUCCESS && aInfo == null) {
958             // We couldn't find the specific class specified in the Intent.
959             // Also the end of the line.
960             err = ActivityManager.START_CLASS_NOT_FOUND;
961         }
962 
963         if (err == ActivityManager.START_SUCCESS && sourceRecord != null
964                 && sourceRecord.getTask().voiceSession != null) {
965             // If this activity is being launched as part of a voice session, we need to ensure
966             // that it is safe to do so.  If the upcoming activity will also be part of the voice
967             // session, we can only launch it if it has explicitly said it supports the VOICE
968             // category, or it is a part of the calling app.
969             if ((launchFlags & FLAG_ACTIVITY_NEW_TASK) == 0
970                     && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
971                 try {
972                     intent.addCategory(Intent.CATEGORY_VOICE);
973                     if (!mService.getPackageManager().activitySupportsIntent(
974                             intent.getComponent(), intent, resolvedType)) {
975                         Slog.w(TAG, "Activity being started in current voice task does not support "
976                                 + "voice: " + intent);
977                         err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
978                     }
979                 } catch (RemoteException e) {
980                     Slog.w(TAG, "Failure checking voice capabilities", e);
981                     err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
982                 }
983             }
984         }
985 
986         if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
987             // If the caller is starting a new voice session, just make sure the target
988             // is actually allowing it to run this way.
989             try {
990                 if (!mService.getPackageManager().activitySupportsIntent(intent.getComponent(),
991                         intent, resolvedType)) {
992                     Slog.w(TAG,
993                             "Activity being started in new voice task does not support: " + intent);
994                     err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
995                 }
996             } catch (RemoteException e) {
997                 Slog.w(TAG, "Failure checking voice capabilities", e);
998                 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
999             }
1000         }
1001 
1002         final Task resultRootTask = resultRecord == null
1003                 ? null : resultRecord.getRootTask();
1004 
1005         if (err != START_SUCCESS) {
1006             if (resultRecord != null) {
1007                 resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED,
1008                         null /* data */, null /* dataGrants */);
1009             }
1010             SafeActivityOptions.abort(options);
1011             return err;
1012         }
1013 
1014         boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
1015                 requestCode, callingPid, callingUid, callingPackage, callingFeatureId,
1016                 request.ignoreTargetSecurity, inTask != null, callerApp, resultRecord,
1017                 resultRootTask);
1018         abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
1019                 callingPid, resolvedType, aInfo.applicationInfo);
1020         abort |= !mService.getPermissionPolicyInternal().checkStartActivity(intent, callingUid,
1021                 callingPackage);
1022 
1023         // Merge the two options bundles, while realCallerOptions takes precedence.
1024         ActivityOptions checkedOptions = options != null
1025                 ? options.getOptions(intent, aInfo, callerApp, mSupervisor) : null;
1026 
1027         @BalCode int balCode = BAL_ALLOW_DEFAULT;
1028         if (!abort) {
1029             try {
1030                 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER,
1031                         "shouldAbortBackgroundActivityStart");
1032                 BackgroundActivityStartController balController =
1033                         mController.getBackgroundActivityLaunchController();
1034                 balCode =
1035                         balController.checkBackgroundActivityStart(
1036                                 callingUid,
1037                                 callingPid,
1038                                 callingPackage,
1039                                 realCallingUid,
1040                                 realCallingPid,
1041                                 callerApp,
1042                                 request.originatingPendingIntent,
1043                                 request.allowBackgroundActivityStart,
1044                                 intent,
1045                                 checkedOptions);
1046             } finally {
1047                 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
1048             }
1049         }
1050 
1051         if (request.allowPendingRemoteAnimationRegistryLookup) {
1052             checkedOptions = mService.getActivityStartController()
1053                     .getPendingRemoteAnimationRegistry()
1054                     .overrideOptionsIfNeeded(callingPackage, checkedOptions);
1055         }
1056         if (mService.mController != null) {
1057             try {
1058                 // The Intent we give to the watcher has the extra data stripped off, since it
1059                 // can contain private information.
1060                 Intent watchIntent = intent.cloneFilter();
1061                 abort |= !mService.mController.activityStarting(watchIntent,
1062                         aInfo.applicationInfo.packageName);
1063             } catch (RemoteException e) {
1064                 mService.mController = null;
1065             }
1066         }
1067 
1068         mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage,
1069                 callingFeatureId);
1070         if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, inTaskFragment,
1071                 callingPid, callingUid, checkedOptions)) {
1072             // activity start was intercepted, e.g. because the target user is currently in quiet
1073             // mode (turn off work) or the target application is suspended
1074             intent = mInterceptor.mIntent;
1075             rInfo = mInterceptor.mRInfo;
1076             aInfo = mInterceptor.mAInfo;
1077             resolvedType = mInterceptor.mResolvedType;
1078             inTask = mInterceptor.mInTask;
1079             callingPid = mInterceptor.mCallingPid;
1080             callingUid = mInterceptor.mCallingUid;
1081             checkedOptions = mInterceptor.mActivityOptions;
1082 
1083             // The interception target shouldn't get any permission grants
1084             // intended for the original destination
1085             intentGrants = null;
1086         }
1087 
1088         if (abort) {
1089             if (resultRecord != null) {
1090                 resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED,
1091                         null /* data */, null /* dataGrants */);
1092             }
1093             // We pretend to the caller that it was really started, but they will just get a
1094             // cancel result.
1095             ActivityOptions.abort(checkedOptions);
1096             return START_ABORTED;
1097         }
1098 
1099         // If permissions need a review before any of the app components can run, we
1100         // launch the review activity and pass a pending intent to start the activity
1101         // we are to launching now after the review is completed.
1102         if (aInfo != null) {
1103             if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
1104                     aInfo.packageName, userId)) {
1105                 final IIntentSender target = mService.getIntentSenderLocked(
1106                         ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage, callingFeatureId,
1107                         callingUid, userId, null, null, 0, new Intent[]{intent},
1108                         new String[]{resolvedType}, PendingIntent.FLAG_CANCEL_CURRENT
1109                                 | PendingIntent.FLAG_ONE_SHOT, null);
1110 
1111                 Intent newIntent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
1112 
1113                 int flags = intent.getFlags();
1114                 flags |= Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
1115 
1116                 /*
1117                  * Prevent reuse of review activity: Each app needs their own review activity. By
1118                  * default activities launched with NEW_TASK or NEW_DOCUMENT try to reuse activities
1119                  * with the same launch parameters (extras are ignored). Hence to avoid possible
1120                  * reuse force a new activity via the MULTIPLE_TASK flag.
1121                  *
1122                  * Activities that are not launched with NEW_TASK or NEW_DOCUMENT are not re-used,
1123                  * hence no need to add the flag in this case.
1124                  */
1125                 if ((flags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_NEW_DOCUMENT)) != 0) {
1126                     flags |= Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
1127                 }
1128                 newIntent.setFlags(flags);
1129 
1130                 newIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, aInfo.packageName);
1131                 newIntent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target));
1132                 if (resultRecord != null) {
1133                     newIntent.putExtra(Intent.EXTRA_RESULT_NEEDED, true);
1134                 }
1135                 intent = newIntent;
1136 
1137                 // The permissions review target shouldn't get any permission
1138                 // grants intended for the original destination
1139                 intentGrants = null;
1140 
1141                 resolvedType = null;
1142                 callingUid = realCallingUid;
1143                 callingPid = realCallingPid;
1144 
1145                 rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0,
1146                         computeResolveFilterUid(
1147                                 callingUid, realCallingUid, request.filterCallingUid));
1148                 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
1149                         null /*profilerInfo*/);
1150 
1151                 if (DEBUG_PERMISSIONS_REVIEW) {
1152                     final Task focusedRootTask =
1153                             mRootWindowContainer.getTopDisplayFocusedRootTask();
1154                     Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true,
1155                             true, false) + "} from uid " + callingUid + " on display "
1156                             + (focusedRootTask == null ? DEFAULT_DISPLAY
1157                                     : focusedRootTask.getDisplayId()));
1158                 }
1159             }
1160         }
1161 
1162         // If we have an ephemeral app, abort the process of launching the resolved intent.
1163         // Instead, launch the ephemeral installer. Once the installer is finished, it
1164         // starts either the intent we resolved here [on install error] or the ephemeral
1165         // app [on install success].
1166         if (rInfo != null && rInfo.auxiliaryInfo != null) {
1167             intent = createLaunchIntent(rInfo.auxiliaryInfo, request.ephemeralIntent,
1168                     callingPackage, callingFeatureId, verificationBundle, resolvedType, userId);
1169             resolvedType = null;
1170             callingUid = realCallingUid;
1171             callingPid = realCallingPid;
1172 
1173             // The ephemeral installer shouldn't get any permission grants
1174             // intended for the original destination
1175             intentGrants = null;
1176 
1177             aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
1178         }
1179         // TODO (b/187680964) Correcting the caller/pid/uid when start activity from shortcut
1180         // Pending intent launched from systemui also depends on caller app
1181         if (callerApp == null && realCallingPid > 0) {
1182             final WindowProcessController wpc = mService.mProcessMap.getProcess(realCallingPid);
1183             if (wpc != null) {
1184                 callerApp = wpc;
1185             }
1186         }
1187         final ActivityRecord r = new ActivityRecord.Builder(mService)
1188                 .setCaller(callerApp)
1189                 .setLaunchedFromPid(callingPid)
1190                 .setLaunchedFromUid(callingUid)
1191                 .setLaunchedFromPackage(callingPackage)
1192                 .setLaunchedFromFeature(callingFeatureId)
1193                 .setIntent(intent)
1194                 .setResolvedType(resolvedType)
1195                 .setActivityInfo(aInfo)
1196                 .setConfiguration(mService.getGlobalConfiguration())
1197                 .setResultTo(resultRecord)
1198                 .setResultWho(resultWho)
1199                 .setRequestCode(requestCode)
1200                 .setComponentSpecified(request.componentSpecified)
1201                 .setRootVoiceInteraction(voiceSession != null)
1202                 .setActivityOptions(checkedOptions)
1203                 .setSourceRecord(sourceRecord)
1204                 .build();
1205 
1206         mLastStartActivityRecord = r;
1207 
1208         if (r.appTimeTracker == null && sourceRecord != null) {
1209             // If the caller didn't specify an explicit time tracker, we want to continue
1210             // tracking under any it has.
1211             r.appTimeTracker = sourceRecord.appTimeTracker;
1212         }
1213 
1214         // Only allow app switching to be resumed if activity is not a restricted background
1215         // activity and target app is not home process, otherwise any background activity
1216         // started in background task can stop home button protection mode.
1217         // As the targeted app is not a home process and we don't need to wait for the 2nd
1218         // activity to be started to resume app switching, we can just enable app switching
1219         // directly.
1220         WindowProcessController homeProcess = mService.mHomeProcess;
1221         boolean isHomeProcess = homeProcess != null
1222                 && aInfo.applicationInfo.uid == homeProcess.mUid;
1223         if (balCode != BAL_BLOCK && !isHomeProcess) {
1224             mService.resumeAppSwitches();
1225         }
1226 
1227         mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
1228                 request.voiceInteractor, startFlags, true /* doResume */, checkedOptions,
1229                 inTask, inTaskFragment, balCode, intentGrants);
1230 
1231         if (request.outActivity != null) {
1232             request.outActivity[0] = mLastStartActivityRecord;
1233         }
1234 
1235         return mLastStartActivityResult;
1236     }
1237 
1238     /**
1239      * Return true if background activity is really aborted.
1240      *
1241      * TODO(b/131748165): Refactor the logic so we don't need to call this method everywhere.
1242      */
handleBackgroundActivityAbort(ActivityRecord r)1243     private boolean handleBackgroundActivityAbort(ActivityRecord r) {
1244         // TODO(b/131747138): Remove toast and refactor related code in R release.
1245         final boolean abort = !mService.isBackgroundActivityStartsEnabled();
1246         if (!abort) {
1247             return false;
1248         }
1249         final ActivityRecord resultRecord = r.resultTo;
1250         final String resultWho = r.resultWho;
1251         int requestCode = r.requestCode;
1252         if (resultRecord != null) {
1253             resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED,
1254                     null /* data */, null /* dataGrants */);
1255         }
1256         // We pretend to the caller that it was really started to make it backward compatible, but
1257         // they will just get a cancel result.
1258         ActivityOptions.abort(r.getOptions());
1259         return true;
1260     }
1261 
getExternalResult(int result)1262     static int getExternalResult(int result) {
1263         // Aborted results are treated as successes externally, but we must track them internally.
1264         return result != START_ABORTED ? result : START_SUCCESS;
1265     }
1266 
1267     /**
1268      * Called when execution is complete. Sets state indicating completion and proceeds with
1269      * recycling if appropriate.
1270      */
onExecutionComplete()1271     private void onExecutionComplete() {
1272         mController.onExecutionComplete(this);
1273     }
1274 
onExecutionStarted()1275     private void onExecutionStarted() {
1276         mController.onExecutionStarted();
1277     }
1278 
1279     /**
1280      * Creates a launch intent for the given auxiliary resolution data.
1281      */
createLaunchIntent(@ullable AuxiliaryResolveInfo auxiliaryResponse, Intent originalIntent, String callingPackage, @Nullable String callingFeatureId, Bundle verificationBundle, String resolvedType, int userId)1282     private @NonNull Intent createLaunchIntent(@Nullable AuxiliaryResolveInfo auxiliaryResponse,
1283             Intent originalIntent, String callingPackage, @Nullable String callingFeatureId,
1284             Bundle verificationBundle, String resolvedType, int userId) {
1285         if (auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo) {
1286             // request phase two resolution
1287             PackageManagerInternal packageManager = mService.getPackageManagerInternalLocked();
1288             boolean isRequesterInstantApp = packageManager.isInstantApp(callingPackage, userId);
1289             packageManager.requestInstantAppResolutionPhaseTwo(
1290                     auxiliaryResponse, originalIntent, resolvedType, callingPackage,
1291                     callingFeatureId, isRequesterInstantApp, verificationBundle, userId);
1292         }
1293         return InstantAppResolver.buildEphemeralInstallerIntent(
1294                 originalIntent,
1295                 InstantAppResolver.sanitizeIntent(originalIntent),
1296                 auxiliaryResponse == null ? null : auxiliaryResponse.failureIntent,
1297                 callingPackage,
1298                 callingFeatureId,
1299                 verificationBundle,
1300                 resolvedType,
1301                 userId,
1302                 auxiliaryResponse == null ? null : auxiliaryResponse.installFailureActivity,
1303                 auxiliaryResponse == null ? null : auxiliaryResponse.token,
1304                 auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo,
1305                 auxiliaryResponse == null ? null : auxiliaryResponse.filters);
1306     }
1307 
postStartActivityProcessing(ActivityRecord r, int result, Task startedActivityRootTask)1308     void postStartActivityProcessing(ActivityRecord r, int result,
1309             Task startedActivityRootTask) {
1310         if (!ActivityManager.isStartResultSuccessful(result)) {
1311             if (mFrozeTaskList) {
1312                 // If we specifically froze the task list as part of starting an activity, then
1313                 // reset the frozen list state if it failed to start. This is normally otherwise
1314                 // called when the freeze-timeout has elapsed.
1315                 mSupervisor.mRecentTasks.resetFreezeTaskListReorderingOnTimeout();
1316             }
1317         }
1318         if (ActivityManager.isStartResultFatalError(result)) {
1319             return;
1320         }
1321 
1322         // We're waiting for an activity launch to finish, but that activity simply
1323         // brought another activity to front. We must also handle the case where the task is already
1324         // in the front as a result of the trampoline activity being in the same task (it will be
1325         // considered focused as the trampoline will be finished). Let them know about this, so
1326         // it waits for the new activity to become visible instead, {@link #waitResultIfNeeded}.
1327         mSupervisor.reportWaitingActivityLaunchedIfNeeded(r, result);
1328 
1329         final Task targetTask = r.getTask() != null
1330                 ? r.getTask()
1331                 : mTargetTask;
1332         if (startedActivityRootTask == null || targetTask == null || !targetTask.isAttached()) {
1333             return;
1334         }
1335 
1336         if (result == START_TASK_TO_FRONT || result == START_DELIVERED_TO_TOP) {
1337             // The activity was already running so it wasn't started, but either brought to the
1338             // front or the new intent was delivered to it since it was already in front. Notify
1339             // anyone interested in this piece of information.
1340             final Task rootHomeTask = targetTask.getDisplayArea().getRootHomeTask();
1341             final boolean homeTaskVisible = rootHomeTask != null
1342                     && rootHomeTask.shouldBeVisible(null);
1343             final ActivityRecord top = targetTask.getTopNonFinishingActivity();
1344             final boolean visible = top != null && top.isVisible();
1345             mService.getTaskChangeNotificationController().notifyActivityRestartAttempt(
1346                     targetTask.getTaskInfo(), homeTaskVisible, mIsTaskCleared, visible);
1347         }
1348 
1349         if (ActivityManager.isStartResultSuccessful(result)) {
1350             mInterceptor.onActivityLaunched(targetTask.getTaskInfo(), r);
1351         }
1352     }
1353 
1354     /**
1355      * Compute the logical UID based on which the package manager would filter
1356      * app components i.e. based on which the instant app policy would be applied
1357      * because it is the logical calling UID.
1358      *
1359      * @param customCallingUid The UID on whose behalf to make the call.
1360      * @param actualCallingUid The UID actually making the call.
1361      * @param filterCallingUid The UID to be used to filter for instant apps.
1362      * @return The logical UID making the call.
1363      */
computeResolveFilterUid(int customCallingUid, int actualCallingUid, int filterCallingUid)1364     static int computeResolveFilterUid(int customCallingUid, int actualCallingUid,
1365             int filterCallingUid) {
1366         return filterCallingUid != UserHandle.USER_NULL
1367                 ? filterCallingUid
1368                 : (customCallingUid >= 0 ? customCallingUid : actualCallingUid);
1369     }
1370 
1371     /**
1372      * Start an activity while most of preliminary checks has been done and caller has been
1373      * confirmed that holds necessary permissions to do so.
1374      * Here also ensures that the starting activity is removed if the start wasn't successful.
1375      */
startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, Task inTask, TaskFragment inTaskFragment, @BalCode int balCode, NeededUriGrants intentGrants)1376     private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
1377             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1378             int startFlags, boolean doResume, ActivityOptions options, Task inTask,
1379             TaskFragment inTaskFragment, @BalCode int balCode,
1380             NeededUriGrants intentGrants) {
1381         int result = START_CANCELED;
1382         final Task startedActivityRootTask;
1383 
1384         // Create a transition now to record the original intent of actions taken within
1385         // startActivityInner. Otherwise, logic in startActivityInner could start a different
1386         // transition based on a sub-action.
1387         // Only do the create here (and defer requestStart) since startActivityInner might abort.
1388         final TransitionController transitionController = r.mTransitionController;
1389         Transition newTransition = (!transitionController.isCollecting()
1390                 && transitionController.getTransitionPlayer() != null)
1391                 ? transitionController.createTransition(TRANSIT_OPEN) : null;
1392         RemoteTransition remoteTransition = r.takeRemoteTransition();
1393         try {
1394             mService.deferWindowLayout();
1395             transitionController.collect(r);
1396             try {
1397                 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
1398                 result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
1399                         startFlags, doResume, options, inTask, inTaskFragment, balCode,
1400                         intentGrants);
1401             } finally {
1402                 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
1403                 startedActivityRootTask = handleStartResult(r, options, result, newTransition,
1404                         remoteTransition);
1405             }
1406         } finally {
1407             mService.continueWindowLayout();
1408         }
1409         postStartActivityProcessing(r, result, startedActivityRootTask);
1410 
1411         return result;
1412     }
1413 
1414     /**
1415      * If the start result is success, ensure that the configuration of the started activity matches
1416      * the current display. Otherwise clean up unassociated containers to avoid leakage.
1417      *
1418      * @return the root task where the successful started activity resides.
1419      */
handleStartResult(@onNull ActivityRecord started, ActivityOptions options, int result, Transition newTransition, RemoteTransition remoteTransition)1420     private @Nullable Task handleStartResult(@NonNull ActivityRecord started,
1421             ActivityOptions options, int result, Transition newTransition,
1422             RemoteTransition remoteTransition) {
1423         final boolean userLeaving = mSupervisor.mUserLeaving;
1424         mSupervisor.mUserLeaving = false;
1425         final Task currentRootTask = started.getRootTask();
1426         final Task startedActivityRootTask =
1427                 currentRootTask != null ? currentRootTask : mTargetRootTask;
1428 
1429         if (!ActivityManager.isStartResultSuccessful(result) || startedActivityRootTask == null) {
1430             // If we are not able to proceed, disassociate the activity from the task. Leaving an
1431             // activity in an incomplete state can lead to issues, such as performing operations
1432             // without a window container.
1433             if (mStartActivity.getTask() != null) {
1434                 mStartActivity.finishIfPossible("startActivity", true /* oomAdj */);
1435             } else if (mStartActivity.getParent() != null) {
1436                 mStartActivity.getParent().removeChild(mStartActivity);
1437             }
1438 
1439             // Root task should also be detached from display and be removed if it's empty.
1440             if (startedActivityRootTask != null && startedActivityRootTask.isAttached()
1441                     && !startedActivityRootTask.hasActivity()
1442                     && !startedActivityRootTask.isActivityTypeHome()
1443                     && !startedActivityRootTask.mCreatedByOrganizer) {
1444                 startedActivityRootTask.removeIfPossible("handleStartResult");
1445             }
1446             if (newTransition != null) {
1447                 newTransition.abort();
1448             }
1449             return null;
1450         }
1451 
1452         // Apply setAlwaysOnTop when starting an activity is successful regardless of creating
1453         // a new Activity or reusing the existing activity.
1454         if (options != null && options.getTaskAlwaysOnTop()) {
1455             startedActivityRootTask.setAlwaysOnTop(true);
1456         }
1457 
1458         // If there is no state change (e.g. a resumed activity is reparented to top of
1459         // another display) to trigger a visibility/configuration checking, we have to
1460         // update the configuration for changing to different display.
1461         final ActivityRecord currentTop = startedActivityRootTask.topRunningActivity();
1462         if (currentTop != null && currentTop.shouldUpdateConfigForDisplayChanged()) {
1463             mRootWindowContainer.ensureVisibilityAndConfig(
1464                     currentTop, currentTop.getDisplayId(),
1465                     true /* markFrozenIfConfigChanged */, false /* deferResume */);
1466         }
1467 
1468         if (!mAvoidMoveToFront && mDoResume && mRootWindowContainer
1469                 .hasVisibleWindowAboveButDoesNotOwnNotificationShade(started.launchedFromUid)) {
1470             // If the UID launching the activity has a visible window on top of the notification
1471             // shade and it's launching an activity that's going to be at the front, we should move
1472             // the shade out of the way so the user can see it. We want to avoid the case where the
1473             // activity is launched on top of a background task which is not moved to the front.
1474             final StatusBarManagerInternal statusBar = mService.getStatusBarManagerInternal();
1475             if (statusBar != null) {
1476                 // This results in a async call since the interface is one-way.
1477                 statusBar.collapsePanels();
1478             }
1479         }
1480 
1481         // Transition housekeeping.
1482         final TransitionController transitionController = started.mTransitionController;
1483         final boolean isStarted = result == START_SUCCESS || result == START_TASK_TO_FRONT;
1484         final boolean isTransientLaunch = options != null && options.getTransientLaunch();
1485         // Start transient launch while keyguard locked and occluded by other app, for this
1486         // condition we would like to play the remote transition without modify any visible state
1487         // for the hierarchy in core, so here will force execute this transition.
1488         final boolean forceTransientTransition = isTransientLaunch && mPriorAboveTask != null
1489                 && mDisplayLockAndOccluded;
1490         if (isStarted) {
1491             // The activity is started new rather than just brought forward, so record it as an
1492             // existence change.
1493             transitionController.collectExistenceChange(started);
1494         } else if (result == START_DELIVERED_TO_TOP && newTransition != null
1495                 // An activity has changed order/visibility so this isn't just deliver-to-top
1496                 && mMovedToTopActivity == null) {
1497             // We just delivered to top, so there isn't an actual transition here.
1498             if (!forceTransientTransition) {
1499                 newTransition.abort();
1500                 newTransition = null;
1501             }
1502         }
1503         if (isTransientLaunch) {
1504             if (forceTransientTransition && newTransition != null) {
1505                 newTransition.collect(mLastStartActivityRecord);
1506                 newTransition.collect(mPriorAboveTask);
1507             }
1508             // `started` isn't guaranteed to be the actual relevant activity, so we must wait
1509             // until after we launched to identify the relevant activity.
1510             transitionController.setTransientLaunch(mLastStartActivityRecord, mPriorAboveTask);
1511             if (forceTransientTransition && newTransition != null) {
1512                 final DisplayContent dc = mLastStartActivityRecord.getDisplayContent();
1513                 // update wallpaper target to TransientHide
1514                 dc.mWallpaperController.adjustWallpaperWindows();
1515                 // execute transition because there is no change
1516                 newTransition.setReady(dc, true /* ready */);
1517             }
1518         }
1519         if (!userLeaving) {
1520             // no-user-leaving implies not entering PiP.
1521             transitionController.setCanPipOnFinish(false /* canPipOnFinish */);
1522         }
1523         if (newTransition != null) {
1524             transitionController.requestStartTransition(newTransition,
1525                     mTargetTask == null ? started.getTask() : mTargetTask,
1526                     remoteTransition, null /* displayChange */);
1527         } else if (isStarted) {
1528             // Make the collecting transition wait until this request is ready.
1529             transitionController.setReady(started, false);
1530         }
1531         return startedActivityRootTask;
1532     }
1533 
1534     /**
1535      * Start an activity and determine if the activity should be adding to the top of an existing
1536      * task or delivered new intent to an existing activity. Also manipulating the activity task
1537      * onto requested or valid root-task/display.
1538      *
1539      * Note: This method should only be called from {@link #startActivityUnchecked}.
1540      */
1541     // TODO(b/152429287): Make it easier to exercise code paths through startActivityInner
1542     @VisibleForTesting
startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, Task inTask, TaskFragment inTaskFragment, @BalCode int balCode, NeededUriGrants intentGrants)1543     int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
1544             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1545             int startFlags, boolean doResume, ActivityOptions options, Task inTask,
1546             TaskFragment inTaskFragment, @BalCode int balCode,
1547             NeededUriGrants intentGrants) {
1548         setInitialState(r, options, inTask, inTaskFragment, doResume, startFlags, sourceRecord,
1549                 voiceSession, voiceInteractor, balCode);
1550 
1551         computeLaunchingTaskFlags();
1552         mIntent.setFlags(mLaunchFlags);
1553 
1554         boolean dreamStopping = false;
1555 
1556         for (ActivityRecord stoppingActivity : mSupervisor.mStoppingActivities) {
1557             if (stoppingActivity.getActivityType()
1558                     == WindowConfiguration.ACTIVITY_TYPE_DREAM) {
1559                 dreamStopping = true;
1560                 break;
1561             }
1562         }
1563 
1564         // Get top task at beginning because the order may be changed when reusing existing task.
1565         final Task prevTopRootTask = mPreferredTaskDisplayArea.getFocusedRootTask();
1566         final Task prevTopTask = prevTopRootTask != null ? prevTopRootTask.getTopLeafTask() : null;
1567         final Task reusedTask = getReusableTask();
1568 
1569         // If requested, freeze the task list
1570         if (mOptions != null && mOptions.freezeRecentTasksReordering()
1571                 && mSupervisor.mRecentTasks.isCallerRecents(r.launchedFromUid)
1572                 && !mSupervisor.mRecentTasks.isFreezeTaskListReorderingSet()) {
1573             mFrozeTaskList = true;
1574             mSupervisor.mRecentTasks.setFreezeTaskListReordering();
1575         }
1576 
1577         // Compute if there is an existing task that should be used for.
1578         final Task targetTask = reusedTask != null ? reusedTask : computeTargetTask();
1579         final boolean newTask = targetTask == null;
1580         mTargetTask = targetTask;
1581 
1582         computeLaunchParams(r, sourceRecord, targetTask);
1583 
1584         // Check if starting activity on given task or on a new task is allowed.
1585         int startResult = isAllowedToStart(r, newTask, targetTask);
1586         if (startResult != START_SUCCESS) {
1587             if (r.resultTo != null) {
1588                 r.resultTo.sendResult(INVALID_UID, r.resultWho, r.requestCode, RESULT_CANCELED,
1589                         null /* data */, null /* dataGrants */);
1590             }
1591             return startResult;
1592         }
1593 
1594         if (targetTask != null) {
1595             mPriorAboveTask = TaskDisplayArea.getRootTaskAbove(targetTask.getRootTask());
1596         }
1597 
1598         final ActivityRecord targetTaskTop = newTask
1599                 ? null : targetTask.getTopNonFinishingActivity();
1600         if (targetTaskTop != null) {
1601             // Recycle the target task for this launch.
1602             startResult = recycleTask(targetTask, targetTaskTop, reusedTask, intentGrants);
1603             if (startResult != START_SUCCESS) {
1604                 return startResult;
1605             }
1606         } else {
1607             mAddingToTask = true;
1608         }
1609 
1610         // If the activity being launched is the same as the one currently at the top, then
1611         // we need to check if it should only be launched once.
1612         final Task topRootTask = mPreferredTaskDisplayArea.getFocusedRootTask();
1613         if (topRootTask != null) {
1614             startResult = deliverToCurrentTopIfNeeded(topRootTask, intentGrants);
1615             if (startResult != START_SUCCESS) {
1616                 return startResult;
1617             }
1618         }
1619 
1620         if (mTargetRootTask == null) {
1621             mTargetRootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags, targetTask,
1622                     mOptions);
1623         }
1624         if (newTask) {
1625             final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
1626                     ? mSourceRecord.getTask() : null;
1627             setNewTask(taskToAffiliate);
1628         } else if (mAddingToTask) {
1629             addOrReparentStartingActivity(targetTask, "adding to task");
1630         }
1631 
1632         if (!mAvoidMoveToFront && mDoResume) {
1633             mTargetRootTask.getRootTask().moveToFront("reuseOrNewTask", targetTask);
1634             if (!mTargetRootTask.isTopRootTaskInDisplayArea() && mService.isDreaming()
1635                     && !dreamStopping) {
1636                 // Launching underneath dream activity (fullscreen, always-on-top). Run the launch-
1637                 // -behind transition so the Activity gets created and starts in visible state.
1638                 mLaunchTaskBehind = true;
1639                 r.mLaunchTaskBehind = true;
1640             }
1641         }
1642 
1643         mService.mUgmInternal.grantUriPermissionUncheckedFromIntent(intentGrants,
1644                 mStartActivity.getUriPermissionsLocked());
1645         if (mStartActivity.resultTo != null && mStartActivity.resultTo.info != null) {
1646             // we need to resolve resultTo to a uid as grantImplicitAccess deals explicitly in UIDs
1647             final PackageManagerInternal pmInternal =
1648                     mService.getPackageManagerInternalLocked();
1649             final int resultToUid = pmInternal.getPackageUid(
1650                     mStartActivity.resultTo.info.packageName, 0 /* flags */,
1651                     mStartActivity.mUserId);
1652             pmInternal.grantImplicitAccess(mStartActivity.mUserId, mIntent,
1653                     UserHandle.getAppId(mStartActivity.info.applicationInfo.uid) /*recipient*/,
1654                     resultToUid /*visible*/, true /*direct*/);
1655         }
1656         final Task startedTask = mStartActivity.getTask();
1657         if (newTask) {
1658             EventLogTags.writeWmCreateTask(mStartActivity.mUserId, startedTask.mTaskId);
1659         }
1660         mStartActivity.logStartActivity(EventLogTags.WM_CREATE_ACTIVITY, startedTask);
1661 
1662         mStartActivity.getTaskFragment().clearLastPausedActivity();
1663 
1664         mRootWindowContainer.startPowerModeLaunchIfNeeded(
1665                 false /* forceSend */, mStartActivity);
1666 
1667         final boolean isTaskSwitch = startedTask != prevTopTask && !startedTask.isEmbedded();
1668         mTargetRootTask.startActivityLocked(mStartActivity, topRootTask, newTask, isTaskSwitch,
1669                 mOptions, sourceRecord);
1670         if (mDoResume) {
1671             final ActivityRecord topTaskActivity = startedTask.topRunningActivityLocked();
1672             if (!mTargetRootTask.isTopActivityFocusable()
1673                     || (topTaskActivity != null && topTaskActivity.isTaskOverlay()
1674                     && mStartActivity != topTaskActivity)) {
1675                 // If the activity is not focusable, we can't resume it, but still would like to
1676                 // make sure it becomes visible as it starts (this will also trigger entry
1677                 // animation). An example of this are PIP activities.
1678                 // Also, we don't want to resume activities in a task that currently has an overlay
1679                 // as the starting activity just needs to be in the visible paused state until the
1680                 // over is removed.
1681                 // Passing {@code null} as the start parameter ensures all activities are made
1682                 // visible.
1683                 mTargetRootTask.ensureActivitiesVisible(null /* starting */,
1684                         0 /* configChanges */, !PRESERVE_WINDOWS);
1685                 // Go ahead and tell window manager to execute app transition for this activity
1686                 // since the app transition will not be triggered through the resume channel.
1687                 mTargetRootTask.mDisplayContent.executeAppTransition();
1688             } else {
1689                 // If the target root-task was not previously focusable (previous top running
1690                 // activity on that root-task was not visible) then any prior calls to move the
1691                 // root-task to the will not update the focused root-task.  If starting the new
1692                 // activity now allows the task root-task to be focusable, then ensure that we
1693                 // now update the focused root-task accordingly.
1694                 if (mTargetRootTask.isTopActivityFocusable()
1695                         && !mRootWindowContainer.isTopDisplayFocusedRootTask(mTargetRootTask)) {
1696                     mTargetRootTask.moveToFront("startActivityInner");
1697                 }
1698                 mRootWindowContainer.resumeFocusedTasksTopActivities(
1699                         mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);
1700             }
1701         }
1702         mRootWindowContainer.updateUserRootTask(mStartActivity.mUserId, mTargetRootTask);
1703 
1704         // Update the recent tasks list immediately when the activity starts
1705         mSupervisor.mRecentTasks.add(startedTask);
1706         mSupervisor.handleNonResizableTaskIfNeeded(startedTask,
1707                 mPreferredWindowingMode, mPreferredTaskDisplayArea, mTargetRootTask);
1708 
1709         // If Activity's launching into PiP, move the mStartActivity immediately to pinned mode.
1710         // Note that mStartActivity and source should be in the same Task at this point.
1711         if (mOptions != null && mOptions.isLaunchIntoPip()
1712                 && sourceRecord != null && sourceRecord.getTask() == mStartActivity.getTask()
1713                 && balCode != BAL_BLOCK) {
1714             mRootWindowContainer.moveActivityToPinnedRootTask(mStartActivity,
1715                     sourceRecord, "launch-into-pip");
1716         }
1717 
1718         return START_SUCCESS;
1719     }
1720 
1721     /** Returns the leaf task where the target activity may be placed. */
computeTargetTask()1722     private Task computeTargetTask() {
1723         if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
1724                 && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1725             // A new task should be created instead of using existing one.
1726             return null;
1727         } else if (mSourceRecord != null) {
1728             return mSourceRecord.getTask();
1729         } else if (mInTask != null) {
1730             // The task is specified from AppTaskImpl, so it may not be attached yet.
1731             if (!mInTask.isAttached()) {
1732                 // Attach the task to display area. Ignore the returned root task (though usually
1733                 // they are the same) because "target task" should be leaf task.
1734                 getOrCreateRootTask(mStartActivity, mLaunchFlags, mInTask, mOptions);
1735             }
1736             return mInTask;
1737         } else {
1738             final Task rootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags, null /* task */,
1739                     mOptions);
1740             final ActivityRecord top = rootTask.getTopNonFinishingActivity();
1741             if (top != null) {
1742                 return top.getTask();
1743             } else {
1744                 // Remove the root task if no activity in the root task.
1745                 rootTask.removeIfPossible("computeTargetTask");
1746             }
1747         }
1748         return null;
1749     }
1750 
computeLaunchParams(ActivityRecord r, ActivityRecord sourceRecord, Task targetTask)1751     private void computeLaunchParams(ActivityRecord r, ActivityRecord sourceRecord,
1752             Task targetTask) {
1753         mSupervisor.getLaunchParamsController().calculate(targetTask, r.info.windowLayout, r,
1754                 sourceRecord, mOptions, mRequest, PHASE_BOUNDS, mLaunchParams);
1755         mPreferredTaskDisplayArea = mLaunchParams.hasPreferredTaskDisplayArea()
1756                 ? mLaunchParams.mPreferredTaskDisplayArea
1757                 : mRootWindowContainer.getDefaultTaskDisplayArea();
1758         mPreferredWindowingMode = mLaunchParams.mWindowingMode;
1759     }
1760 
1761     @VisibleForTesting
isAllowedToStart(ActivityRecord r, boolean newTask, Task targetTask)1762     int isAllowedToStart(ActivityRecord r, boolean newTask, Task targetTask) {
1763         if (r.packageName == null) {
1764             ActivityOptions.abort(mOptions);
1765             return START_CLASS_NOT_FOUND;
1766         }
1767 
1768         // Do not start home activity if it cannot be launched on preferred display. We are not
1769         // doing this in ActivityTaskSupervisor#canPlaceEntityOnDisplay because it might
1770         // fallback to launch on other displays.
1771         if (r.isActivityTypeHome()) {
1772             if (!mRootWindowContainer.canStartHomeOnDisplayArea(r.info, mPreferredTaskDisplayArea,
1773                     true /* allowInstrumenting */)) {
1774                 Slog.w(TAG, "Cannot launch home on display area " + mPreferredTaskDisplayArea);
1775                 return START_CANCELED;
1776             }
1777         }
1778 
1779         // Do not allow background activity start in new task or in a task that uid is not present.
1780         // Also do not allow pinned window to start single instance activity in background,
1781         // as it will recreate the window and makes it to foreground.
1782         boolean blockBalInTask = (newTask
1783                 || !targetTask.isUidPresent(mCallingUid)
1784                 || (LAUNCH_SINGLE_INSTANCE == mLaunchMode && targetTask.inPinnedWindowingMode()));
1785 
1786         if (mBalCode == BAL_BLOCK && blockBalInTask
1787                 && handleBackgroundActivityAbort(r)) {
1788             Slog.e(TAG, "Abort background activity starts from " + mCallingUid);
1789             return START_ABORTED;
1790         }
1791 
1792         // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but still
1793         // needs to be a lock task mode violation since the task gets cleared out and the device
1794         // would otherwise leave the locked task.
1795         final boolean isNewClearTask =
1796                 (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1797                         == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
1798         if (!newTask) {
1799             if (mService.getLockTaskController().isLockTaskModeViolation(targetTask,
1800                     isNewClearTask)) {
1801                 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
1802                 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
1803             }
1804         } else {
1805             if (mService.getLockTaskController().isNewTaskLockTaskModeViolation(r)) {
1806                 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
1807                 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
1808             }
1809         }
1810 
1811         // Do not start the activity if target display's DWPC does not allow it.
1812         // We can't return fatal error code here because it will crash the caller of
1813         // startActivity() if they don't catch the exception. We don't expect 3P apps to make
1814         // changes.
1815         if (mPreferredTaskDisplayArea != null) {
1816             final DisplayContent displayContent = mRootWindowContainer.getDisplayContentOrCreate(
1817                     mPreferredTaskDisplayArea.getDisplayId());
1818             if (displayContent != null && displayContent.mDwpcHelper.hasController()) {
1819                 final int targetWindowingMode = (targetTask != null)
1820                         ? targetTask.getWindowingMode() : displayContent.getWindowingMode();
1821                 final int launchingFromDisplayId =
1822                         mSourceRecord != null ? mSourceRecord.getDisplayId() : DEFAULT_DISPLAY;
1823                 if (!displayContent.mDwpcHelper
1824                         .canActivityBeLaunched(r.info, targetWindowingMode, launchingFromDisplayId,
1825                           newTask)) {
1826                     Slog.w(TAG, "Abort to launch " + r.info.getComponentName()
1827                             + " on display area " + mPreferredTaskDisplayArea);
1828                     return START_ABORTED;
1829                 }
1830             }
1831         }
1832 
1833         // Log activity starts which violate one of the following rules of the
1834         // activity security model (ASM):
1835         // 1. Only the top activity on a task can start activities on that task
1836         // 2. Only the top activity on the top task can create new (top) tasks
1837         // We don't currently block, but these checks may later become blocks
1838         // TODO(b/236234252): Shift to BackgroundActivityStartController once
1839         // class is ready
1840         if (mSourceRecord != null) {
1841             int callerUid = mSourceRecord.getUid();
1842             ActivityRecord targetTopActivity =
1843                     targetTask != null ? targetTask.getTopNonFinishingActivity() : null;
1844             boolean passesAsmChecks = newTask
1845                     ? mService.mVisibleActivityProcessTracker.hasResumedActivity(callerUid)
1846                     : targetTopActivity != null && targetTopActivity.getUid() == callerUid;
1847 
1848             if (!passesAsmChecks) {
1849                 Slog.i(TAG, "Launching r: " + r
1850                         + " from background: " + mSourceRecord
1851                         + ". New task: " + newTask);
1852                 boolean newOrEmptyTask = newTask || (targetTopActivity == null);
1853                 FrameworkStatsLog.write(FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED,
1854                         /* caller_uid */
1855                         callerUid,
1856                         /* caller_activity_class_name */
1857                         mSourceRecord.info.name,
1858                         /* target_task_top_activity_uid */
1859                         newOrEmptyTask ? -1 : targetTopActivity.getUid(),
1860                         /* target_task_top_activity_class_name */
1861                         newOrEmptyTask ? null : targetTopActivity.info.name,
1862                         /* target_task_is_different */
1863                         newTask || !mSourceRecord.getTask().equals(targetTask),
1864                         /* target_activity_uid */
1865                         r.getUid(),
1866                         /* target_activity_class_name */
1867                         r.info.name,
1868                         /* target_intent_action */
1869                         r.intent.getAction(),
1870                         /* target_intent_flags */
1871                         r.intent.getFlags()
1872                 );
1873             }
1874         }
1875 
1876         return START_SUCCESS;
1877     }
1878 
1879     /**
1880      * Returns whether embedding of {@code starting} is allowed.
1881      *
1882      * @param taskFragment the TaskFragment for embedding.
1883      * @param starting the starting activity.
1884      * @param targetTask the target task for launching activity, which could be different from
1885      *                   the one who hosting the embedding.
1886      */
1887     @VisibleForTesting
1888     @EmbeddingCheckResult
canEmbedActivity(@onNull TaskFragment taskFragment, @NonNull ActivityRecord starting, @NonNull Task targetTask)1889     static int canEmbedActivity(@NonNull TaskFragment taskFragment,
1890             @NonNull ActivityRecord starting, @NonNull Task targetTask) {
1891         final Task hostTask = taskFragment.getTask();
1892         // Not allowed embedding a separate task or without host task.
1893         if (hostTask == null || targetTask != hostTask) {
1894             return EMBEDDING_DISALLOWED_NEW_TASK;
1895         }
1896 
1897         return taskFragment.isAllowedToEmbedActivity(starting);
1898     }
1899 
1900     /**
1901      * Prepare the target task to be reused for this launch, which including:
1902      * - Position the target task on valid root task on preferred display.
1903      * - Comply to the specified activity launch flags
1904      * - Determine whether need to add a new activity on top or just brought the task to front.
1905      */
1906     @VisibleForTesting
recycleTask(Task targetTask, ActivityRecord targetTaskTop, Task reusedTask, NeededUriGrants intentGrants)1907     int recycleTask(Task targetTask, ActivityRecord targetTaskTop, Task reusedTask,
1908             NeededUriGrants intentGrants) {
1909         // Should not recycle task which is from a different user, just adding the starting
1910         // activity to the task.
1911         if (targetTask.mUserId != mStartActivity.mUserId) {
1912             mTargetRootTask = targetTask.getRootTask();
1913             mAddingToTask = true;
1914             return START_SUCCESS;
1915         }
1916 
1917         if (reusedTask != null) {
1918             if (targetTask.intent == null) {
1919                 // This task was started because of movement of the activity based on
1920                 // affinity...
1921                 // Now that we are actually launching it, we can assign the base intent.
1922                 targetTask.setIntent(mStartActivity);
1923             } else {
1924                 final boolean taskOnHome =
1925                         (mStartActivity.intent.getFlags() & FLAG_ACTIVITY_TASK_ON_HOME) != 0;
1926                 if (taskOnHome) {
1927                     targetTask.intent.addFlags(FLAG_ACTIVITY_TASK_ON_HOME);
1928                 } else {
1929                     targetTask.intent.removeFlags(FLAG_ACTIVITY_TASK_ON_HOME);
1930                 }
1931             }
1932         }
1933 
1934         mRootWindowContainer.startPowerModeLaunchIfNeeded(false /* forceSend */,
1935                 targetTaskTop);
1936 
1937         setTargetRootTaskIfNeeded(targetTaskTop);
1938 
1939         // When there is a reused activity and the current result is a trampoline activity,
1940         // set the reused activity as the result.
1941         if (mLastStartActivityRecord != null
1942                 && (mLastStartActivityRecord.finishing || mLastStartActivityRecord.noDisplay)) {
1943             mLastStartActivityRecord = targetTaskTop;
1944         }
1945 
1946         if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1947             // We don't need to start a new activity, and the client said not to do anything
1948             // if that is the case, so this is it!  And for paranoia, make sure we have
1949             // correctly resumed the top activity.
1950             if (!mMovedToFront && mDoResume) {
1951                 ProtoLog.d(WM_DEBUG_TASKS, "Bring to front target: %s from %s", mTargetRootTask,
1952                         targetTaskTop);
1953                 mTargetRootTask.moveToFront("intentActivityFound");
1954             }
1955             resumeTargetRootTaskIfNeeded();
1956             return START_RETURN_INTENT_TO_CALLER;
1957         }
1958 
1959         complyActivityFlags(targetTask,
1960                 reusedTask != null ? reusedTask.getTopNonFinishingActivity() : null, intentGrants);
1961 
1962         if (mAddingToTask) {
1963             return START_SUCCESS;
1964         }
1965 
1966         // The reusedActivity could be finishing, for example of starting an activity with
1967         // FLAG_ACTIVITY_CLEAR_TOP flag. In that case, use the top running activity in the
1968         // task instead.
1969         targetTaskTop = targetTaskTop.finishing
1970                 ? targetTask.getTopNonFinishingActivity()
1971                 : targetTaskTop;
1972 
1973         if (mMovedToFront) {
1974             // We moved the task to front, use starting window to hide initial drawn delay.
1975             targetTaskTop.showStartingWindow(true /* taskSwitch */);
1976         } else if (mDoResume) {
1977             // Make sure the root task and its belonging display are moved to topmost.
1978             mTargetRootTask.moveToFront("intentActivityFound");
1979         }
1980         // We didn't do anything...  but it was needed (a.k.a., client don't use that intent!)
1981         // And for paranoia, make sure we have correctly resumed the top activity.
1982         resumeTargetRootTaskIfNeeded();
1983 
1984         // This is moving an existing task to front. But since dream activity has a higher z-order
1985         // to cover normal activities, it needs the awakening event to be dismissed.
1986         if (mService.isDreaming() && targetTaskTop.canTurnScreenOn()) {
1987             targetTaskTop.mTaskSupervisor.wakeUp("recycleTask#turnScreenOnFlag");
1988         }
1989 
1990         mLastStartActivityRecord = targetTaskTop;
1991         return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP;
1992     }
1993 
1994     /**
1995      * Check if the activity being launched is the same as the one currently at the top and it
1996      * should only be launched once.
1997      */
deliverToCurrentTopIfNeeded(Task topRootTask, NeededUriGrants intentGrants)1998     private int deliverToCurrentTopIfNeeded(Task topRootTask, NeededUriGrants intentGrants) {
1999         final ActivityRecord top = topRootTask.topRunningNonDelayedActivityLocked(mNotTop);
2000         final boolean dontStart = top != null
2001                 && top.mActivityComponent.equals(mStartActivity.mActivityComponent)
2002                 && top.mUserId == mStartActivity.mUserId
2003                 && top.attachedToProcess()
2004                 && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
2005                 || LAUNCH_SINGLE_TOP == mLaunchMode)
2006                 // This allows home activity to automatically launch on secondary task display area
2007                 // when it was added, if home was the top activity on default task display area,
2008                 // instead of sending new intent to the home activity on default display area.
2009                 && (!top.isActivityTypeHome() || top.getDisplayArea() == mPreferredTaskDisplayArea);
2010         if (!dontStart) {
2011             return START_SUCCESS;
2012         }
2013 
2014         // For paranoia, make sure we have correctly resumed the top activity.
2015         top.getTaskFragment().clearLastPausedActivity();
2016         if (mDoResume) {
2017             mRootWindowContainer.resumeFocusedTasksTopActivities();
2018         }
2019         ActivityOptions.abort(mOptions);
2020         if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
2021             // We don't need to start a new activity, and the client said not to do anything if
2022             // that is the case, so this is it!
2023             return START_RETURN_INTENT_TO_CALLER;
2024         }
2025 
2026         if (mStartActivity.resultTo != null) {
2027             mStartActivity.resultTo.sendResult(INVALID_UID, mStartActivity.resultWho,
2028                     mStartActivity.requestCode, RESULT_CANCELED,
2029                     null /* data */, null /* dataGrants */);
2030             mStartActivity.resultTo = null;
2031         }
2032 
2033         deliverNewIntent(top, intentGrants);
2034 
2035         // Don't use mStartActivity.task to show the toast. We're not starting a new activity but
2036         // reusing 'top'. Fields in mStartActivity may not be fully initialized.
2037         mSupervisor.handleNonResizableTaskIfNeeded(top.getTask(),
2038                 mLaunchParams.mWindowingMode, mPreferredTaskDisplayArea, topRootTask);
2039 
2040         return START_DELIVERED_TO_TOP;
2041     }
2042 
2043     /**
2044      * Applying the launching flags to the task, which might clear few or all the activities in the
2045      * task.
2046      */
complyActivityFlags(Task targetTask, ActivityRecord reusedActivity, NeededUriGrants intentGrants)2047     private void complyActivityFlags(Task targetTask, ActivityRecord reusedActivity,
2048             NeededUriGrants intentGrants) {
2049         ActivityRecord targetTaskTop = targetTask.getTopNonFinishingActivity();
2050         final boolean resetTask =
2051                 reusedActivity != null && (mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0;
2052         if (resetTask) {
2053             targetTaskTop = mTargetRootTask.resetTaskIfNeeded(targetTaskTop, mStartActivity);
2054         }
2055 
2056         if ((mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
2057                 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {
2058             // The caller has requested to completely replace any existing task with its new
2059             // activity. Well that should not be too hard...
2060             // Note: we must persist the {@link Task} first as intentActivity could be
2061             // removed from calling performClearTaskLocked (For example, if it is being brought out
2062             // of history or if it is finished immediately), thus disassociating the task. Keep the
2063             // task-overlay activity because the targetTask will be reused to launch new activity.
2064             targetTask.performClearTaskForReuse(true /* excludingTaskOverlay*/);
2065             targetTask.setIntent(mStartActivity);
2066             mAddingToTask = true;
2067             mIsTaskCleared = true;
2068         } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
2069                 || isDocumentLaunchesIntoExisting(mLaunchFlags)
2070                 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK,
2071                         LAUNCH_SINGLE_INSTANCE_PER_TASK)) {
2072             // In this situation we want to remove all activities from the task up to the one
2073             // being started. In most cases this means we are resetting the task to its initial
2074             // state.
2075             int[] finishCount = new int[1];
2076             final ActivityRecord clearTop = targetTask.performClearTop(mStartActivity,
2077                     mLaunchFlags, finishCount);
2078 
2079             if (clearTop != null && !clearTop.finishing) {
2080                 if (finishCount[0] > 0) {
2081                     // Only record if actually moved to top.
2082                     mMovedToTopActivity = clearTop;
2083                 }
2084                 if (clearTop.isRootOfTask()) {
2085                     // Activity aliases may mean we use different intents for the top activity,
2086                     // so make sure the task now has the identity of the new intent.
2087                     clearTop.getTask().setIntent(mStartActivity);
2088                 }
2089                 deliverNewIntent(clearTop, intentGrants);
2090             } else {
2091                 // A special case: we need to start the activity because it is not currently
2092                 // running, and the caller has asked to clear the current task to have this
2093                 // activity at the top.
2094                 mAddingToTask = true;
2095                 // Adding the new activity to the same embedded TF of the clear-top activity if
2096                 // possible.
2097                 if (clearTop != null && clearTop.getTaskFragment() != null
2098                         && clearTop.getTaskFragment().isEmbedded()) {
2099                     mAddingToTaskFragment = clearTop.getTaskFragment();
2100                 }
2101                 if (targetTask.getRootTask() == null) {
2102                     // Target root task got cleared when we all activities were removed above.
2103                     // Go ahead and reset it.
2104                     mTargetRootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags,
2105                         null /* task */, mOptions);
2106                     mTargetRootTask.addChild(targetTask, !mLaunchTaskBehind /* toTop */,
2107                             (mStartActivity.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0);
2108                 }
2109             }
2110         } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) == 0 && !mAddingToTask
2111                 && (mLaunchFlags & FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
2112             // In this case, we are launching an activity in our own task that may
2113             // already be running somewhere in the history, and we want to shuffle it to
2114             // the front of the root task if so.
2115             final ActivityRecord act =
2116                     targetTask.findActivityInHistory(mStartActivity.mActivityComponent,
2117                             mStartActivity.mUserId);
2118             if (act != null) {
2119                 final Task task = act.getTask();
2120                 boolean actuallyMoved = task.moveActivityToFront(act);
2121                 if (actuallyMoved) {
2122                     // Only record if the activity actually moved.
2123                     mMovedToTopActivity = act;
2124                     if (mNoAnimation) {
2125                         act.mDisplayContent.prepareAppTransition(TRANSIT_NONE);
2126                     } else {
2127                         act.mDisplayContent.prepareAppTransition(TRANSIT_TO_FRONT);
2128                     }
2129                 }
2130                 act.updateOptionsLocked(mOptions);
2131                 deliverNewIntent(act, intentGrants);
2132                 act.getTaskFragment().clearLastPausedActivity();
2133             } else {
2134                 mAddingToTask = true;
2135             }
2136         } else if (mStartActivity.mActivityComponent.equals(targetTask.realActivity)) {
2137             if (targetTask == mInTask) {
2138                 // In this case we are bringing up an existing activity from a recent task. We
2139                 // don't need to add a new activity instance on top.
2140             } else if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
2141                             || LAUNCH_SINGLE_TOP == mLaunchMode)
2142                     && targetTaskTop.mActivityComponent.equals(mStartActivity.mActivityComponent)
2143                     && mStartActivity.resultTo == null) {
2144                 // In this case the top activity on the task is the same as the one being launched,
2145                 // so we take that as a request to bring the task to the foreground. If the top
2146                 // activity in the task is the root activity, deliver this new intent to it if it
2147                 // desires.
2148                 if (targetTaskTop.isRootOfTask()) {
2149                     targetTaskTop.getTask().setIntent(mStartActivity);
2150                 }
2151                 deliverNewIntent(targetTaskTop, intentGrants);
2152             } else if (!targetTask.isSameIntentFilter(mStartActivity)) {
2153                 // In this case we are launching the root activity of the task, but with a
2154                 // different intent. We should start a new instance on top.
2155                 mAddingToTask = true;
2156             } else if (reusedActivity == null) {
2157                 mAddingToTask = true;
2158             }
2159         } else if (!resetTask) {
2160             // In this case an activity is being launched in to an existing task, without
2161             // resetting that task. This is typically the situation of launching an activity
2162             // from a notification or shortcut. We want to place the new activity on top of the
2163             // current task.
2164             mAddingToTask = true;
2165         } else if (!targetTask.rootWasReset) {
2166             // In this case we are launching into an existing task that has not yet been started
2167             // from its front door. The current task has been brought to the front. Ideally,
2168             // we'd probably like to place this new task at the bottom of its root task, but that's
2169             // a little hard to do with the current organization of the code so for now we'll
2170             // just drop it.
2171             targetTask.setIntent(mStartActivity);
2172         }
2173     }
2174 
2175     /**
2176      * Resets the {@link ActivityStarter} state.
2177      * @param clearRequest whether the request should be reset to default values.
2178      */
reset(boolean clearRequest)2179     void reset(boolean clearRequest) {
2180         mStartActivity = null;
2181         mIntent = null;
2182         mCallingUid = -1;
2183         mOptions = null;
2184         mBalCode = BAL_ALLOW_DEFAULT;
2185 
2186         mLaunchTaskBehind = false;
2187         mLaunchFlags = 0;
2188         mLaunchMode = INVALID_LAUNCH_MODE;
2189 
2190         mLaunchParams.reset();
2191 
2192         mNotTop = null;
2193         mDoResume = false;
2194         mStartFlags = 0;
2195         mSourceRecord = null;
2196         mPreferredTaskDisplayArea = null;
2197         mPreferredWindowingMode = WINDOWING_MODE_UNDEFINED;
2198 
2199         mInTask = null;
2200         mInTaskFragment = null;
2201         mAddingToTaskFragment = null;
2202         mAddingToTask = false;
2203 
2204         mSourceRootTask = null;
2205 
2206         mTargetRootTask = null;
2207         mTargetTask = null;
2208         mIsTaskCleared = false;
2209         mMovedToFront = false;
2210         mNoAnimation = false;
2211         mAvoidMoveToFront = false;
2212         mFrozeTaskList = false;
2213         mTransientLaunch = false;
2214         mDisplayLockAndOccluded = false;
2215 
2216         mVoiceSession = null;
2217         mVoiceInteractor = null;
2218 
2219         mIntentDelivered = false;
2220 
2221         if (clearRequest) {
2222             mRequest.reset();
2223         }
2224     }
2225 
setInitialState(ActivityRecord r, ActivityOptions options, Task inTask, TaskFragment inTaskFragment, boolean doResume, int startFlags, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, @BalCode int balCode)2226     private void setInitialState(ActivityRecord r, ActivityOptions options, Task inTask,
2227             TaskFragment inTaskFragment, boolean doResume, int startFlags,
2228             ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession,
2229             IVoiceInteractor voiceInteractor, @BalCode int balCode) {
2230         reset(false /* clearRequest */);
2231 
2232         mStartActivity = r;
2233         mIntent = r.intent;
2234         mOptions = options;
2235         mCallingUid = r.launchedFromUid;
2236         mSourceRecord = sourceRecord;
2237         mSourceRootTask = mSourceRecord != null ? mSourceRecord.getRootTask() : null;
2238         mVoiceSession = voiceSession;
2239         mVoiceInteractor = voiceInteractor;
2240         mBalCode = balCode;
2241 
2242         mLaunchParams.reset();
2243 
2244         // Preferred display id is the only state we need for now and it could be updated again
2245         // after we located a reusable task (which might be resided in another display).
2246         mSupervisor.getLaunchParamsController().calculate(inTask, r.info.windowLayout, r,
2247                 sourceRecord, options, mRequest, PHASE_DISPLAY, mLaunchParams);
2248         mPreferredTaskDisplayArea = mLaunchParams.hasPreferredTaskDisplayArea()
2249                 ? mLaunchParams.mPreferredTaskDisplayArea
2250                 : mRootWindowContainer.getDefaultTaskDisplayArea();
2251         mPreferredWindowingMode = mLaunchParams.mWindowingMode;
2252 
2253         mLaunchMode = r.launchMode;
2254 
2255         mLaunchFlags = adjustLaunchFlagsToDocumentMode(
2256                 r, LAUNCH_SINGLE_INSTANCE == mLaunchMode,
2257                 LAUNCH_SINGLE_TASK == mLaunchMode, mIntent.getFlags());
2258         mLaunchTaskBehind = r.mLaunchTaskBehind
2259                 && !isLaunchModeOneOf(LAUNCH_SINGLE_TASK, LAUNCH_SINGLE_INSTANCE)
2260                 && (mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0;
2261 
2262         if (mLaunchMode == LAUNCH_SINGLE_INSTANCE_PER_TASK) {
2263             // Adding NEW_TASK flag for singleInstancePerTask launch mode activity, so that the
2264             // activity won't be launched in source record's task.
2265             mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2266         }
2267 
2268         sendNewTaskResultRequestIfNeeded();
2269 
2270         if ((mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
2271             mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2272         }
2273 
2274         // If we are actually going to launch in to a new task, there are some cases where
2275         // we further want to do multiple task.
2276         if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
2277             if (mLaunchTaskBehind
2278                     || r.info.documentLaunchMode == DOCUMENT_LAUNCH_ALWAYS) {
2279                 mLaunchFlags |= FLAG_ACTIVITY_MULTIPLE_TASK;
2280             }
2281         }
2282 
2283         // We'll invoke onUserLeaving before onPause only if the launching
2284         // activity did not explicitly state that this is an automated launch.
2285         mSupervisor.mUserLeaving = (mLaunchFlags & FLAG_ACTIVITY_NO_USER_ACTION) == 0;
2286         if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
2287                 "startActivity() => mUserLeaving=" + mSupervisor.mUserLeaving);
2288 
2289         // If the caller has asked not to resume at this point, we make note
2290         // of this in the record so that we can skip it when trying to find
2291         // the top running activity.
2292         mDoResume = doResume;
2293         if (!doResume || !r.showToCurrentUser() || mLaunchTaskBehind) {
2294             r.delayedResume = true;
2295             mDoResume = false;
2296         }
2297 
2298         if (mOptions != null) {
2299             if (mOptions.getLaunchTaskId() != INVALID_TASK_ID && mOptions.getTaskOverlay()) {
2300                 r.setTaskOverlay(true);
2301                 if (!mOptions.canTaskOverlayResume()) {
2302                     final Task task = mRootWindowContainer.anyTaskForId(
2303                             mOptions.getLaunchTaskId());
2304                     final ActivityRecord top = task != null
2305                             ? task.getTopNonFinishingActivity() : null;
2306                     if (top != null && !top.isState(RESUMED)) {
2307 
2308                         // The caller specifies that we'd like to be avoided to be moved to the
2309                         // front, so be it!
2310                         mDoResume = false;
2311                         mAvoidMoveToFront = true;
2312                     }
2313                 }
2314             } else if (mOptions.getAvoidMoveToFront()) {
2315                 mDoResume = false;
2316                 mAvoidMoveToFront = true;
2317             }
2318             mTransientLaunch = mOptions.getTransientLaunch();
2319             final KeyguardController kc = mSupervisor.getKeyguardController();
2320             final int displayId = mPreferredTaskDisplayArea.getDisplayId();
2321             mDisplayLockAndOccluded = kc.isKeyguardLocked(displayId)
2322                     && kc.isDisplayOccluded(displayId);
2323             // Recents animation on lock screen, do not resume & move launcher to top.
2324             if (mTransientLaunch && mDisplayLockAndOccluded
2325                     && mService.getTransitionController().isShellTransitionsEnabled()) {
2326                 mDoResume = false;
2327                 mAvoidMoveToFront = true;
2328             }
2329             mTargetRootTask = Task.fromWindowContainerToken(mOptions.getLaunchRootTask());
2330 
2331             if (inTaskFragment == null) {
2332                 inTaskFragment = TaskFragment.fromTaskFragmentToken(
2333                         mOptions.getLaunchTaskFragmentToken(), mService);
2334                 if (inTaskFragment != null && inTaskFragment.isEmbeddedTaskFragmentInPip()) {
2335                     // Do not start activity in TaskFragment in a PIP Task.
2336                     Slog.w(TAG, "Can not start activity in TaskFragment in PIP: "
2337                             + inTaskFragment);
2338                     inTaskFragment = null;
2339                 }
2340             }
2341         }
2342 
2343         mNotTop = (mLaunchFlags & FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? sourceRecord : null;
2344 
2345         mInTask = inTask;
2346         // In some flows in to this function, we retrieve the task record and hold on to it
2347         // without a lock before calling back in to here...  so the task at this point may
2348         // not actually be in recents.  Check for that, and if it isn't in recents just
2349         // consider it invalid.
2350         if (inTask != null && !inTask.inRecents) {
2351             Slog.w(TAG, "Starting activity in task not in recents: " + inTask);
2352             mInTask = null;
2353         }
2354         mInTaskFragment = inTaskFragment;
2355 
2356         mStartFlags = startFlags;
2357         // If the onlyIfNeeded flag is set, then we can do this if the activity being launched
2358         // is the same as the one making the call...  or, as a special case, if we do not know
2359         // the caller then we count the current top activity as the caller.
2360         if ((startFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
2361             ActivityRecord checkedCaller = sourceRecord;
2362             if (checkedCaller == null) {
2363                 Task topFocusedRootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
2364                 if (topFocusedRootTask != null) {
2365                     checkedCaller = topFocusedRootTask.topRunningNonDelayedActivityLocked(mNotTop);
2366                 }
2367             }
2368             if (checkedCaller == null
2369                     || !checkedCaller.mActivityComponent.equals(r.mActivityComponent)) {
2370                 // Caller is not the same as launcher, so always needed.
2371                 mStartFlags &= ~START_FLAG_ONLY_IF_NEEDED;
2372             }
2373         }
2374 
2375         mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0;
2376 
2377         if (mBalCode == BAL_BLOCK && !mService.isBackgroundActivityStartsEnabled()) {
2378             mAvoidMoveToFront = true;
2379             mDoResume = false;
2380         }
2381     }
2382 
sendNewTaskResultRequestIfNeeded()2383     private void sendNewTaskResultRequestIfNeeded() {
2384         if (mStartActivity.resultTo != null && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
2385             // For whatever reason this activity is being launched into a new task...
2386             // yet the caller has requested a result back.  Well, that is pretty messed up,
2387             // so instead immediately send back a cancel and let the new task continue launched
2388             // as normal without a dependency on its originator.
2389             Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
2390             mStartActivity.resultTo.sendResult(INVALID_UID, mStartActivity.resultWho,
2391                     mStartActivity.requestCode, RESULT_CANCELED,
2392                     null /* data */, null /* dataGrants */);
2393             mStartActivity.resultTo = null;
2394         }
2395     }
2396 
computeLaunchingTaskFlags()2397     private void computeLaunchingTaskFlags() {
2398         // If the caller is not coming from another activity, but has given us an explicit task into
2399         // which they would like us to launch the new activity, then let's see about doing that.
2400         if (mSourceRecord == null && mInTask != null && mInTask.getRootTask() != null) {
2401             final Intent baseIntent = mInTask.getBaseIntent();
2402             final ActivityRecord root = mInTask.getRootActivity();
2403             if (baseIntent == null) {
2404                 ActivityOptions.abort(mOptions);
2405                 throw new IllegalArgumentException("Launching into task without base intent: "
2406                         + mInTask);
2407             }
2408 
2409             // If this task is empty, then we are adding the first activity -- it
2410             // determines the root, and must be launching as a NEW_TASK.
2411             if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
2412                 if (!baseIntent.getComponent().equals(mStartActivity.intent.getComponent())) {
2413                     ActivityOptions.abort(mOptions);
2414                     throw new IllegalArgumentException("Trying to launch singleInstance/Task "
2415                             + mStartActivity + " into different task " + mInTask);
2416                 }
2417                 if (root != null) {
2418                     ActivityOptions.abort(mOptions);
2419                     throw new IllegalArgumentException("Caller with mInTask " + mInTask
2420                             + " has root " + root + " but target is singleInstance/Task");
2421                 }
2422             }
2423 
2424             // If task is empty, then adopt the interesting intent launch flags in to the
2425             // activity being started.
2426             if (root == null) {
2427                 final int flagsOfInterest = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK
2428                         | FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS;
2429                 mLaunchFlags = (mLaunchFlags & ~flagsOfInterest)
2430                         | (baseIntent.getFlags() & flagsOfInterest);
2431                 mIntent.setFlags(mLaunchFlags);
2432                 mInTask.setIntent(mStartActivity);
2433                 mAddingToTask = true;
2434 
2435                 // If the task is not empty and the caller is asking to start it as the root of
2436                 // a new task, then we don't actually want to start this on the task. We will
2437                 // bring the task to the front, and possibly give it a new intent.
2438             } else if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
2439                 mAddingToTask = false;
2440 
2441             } else {
2442                 mAddingToTask = true;
2443             }
2444         } else {
2445             mInTask = null;
2446             // Launch ResolverActivity in the source task, so that it stays in the task bounds
2447             // when in freeform workspace.
2448             // Also put noDisplay activities in the source task. These by itself can be placed
2449             // in any task/root-task, however it could launch other activities like
2450             // ResolverActivity, and we want those to stay in the original task.
2451             if ((mStartActivity.isResolverOrDelegateActivity() || mStartActivity.noDisplay)
2452                     && mSourceRecord != null && mSourceRecord.inFreeformWindowingMode()) {
2453                 mAddingToTask = true;
2454             }
2455         }
2456 
2457         if (mInTask == null) {
2458             if (mSourceRecord == null) {
2459                 // This activity is not being started from another...  in this
2460                 // case we -always- start a new task.
2461                 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) {
2462                     Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
2463                             "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
2464                     mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2465                 }
2466             } else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) {
2467                 // The original activity who is starting us is running as a single
2468                 // instance...  this new activity it is starting must go on its
2469                 // own task.
2470                 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2471             } else if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
2472                 // The activity being started is a single instance...  it always
2473                 // gets launched into its own task.
2474                 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2475             }
2476         }
2477 
2478         if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0
2479                 && ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 || mSourceRecord == null)) {
2480             // ignore the flag if there is no the sourceRecord or without new_task flag
2481             mLaunchFlags &= ~FLAG_ACTIVITY_LAUNCH_ADJACENT;
2482         }
2483     }
2484 
2485     /**
2486      * Decide whether the new activity should be inserted into an existing task. Returns null
2487      * if not or an ActivityRecord with the task into which the new activity should be added.
2488      */
getReusableTask()2489     private Task getReusableTask() {
2490         // If a target task is specified, try to reuse that one
2491         if (mOptions != null && mOptions.getLaunchTaskId() != INVALID_TASK_ID) {
2492             Task launchTask = mRootWindowContainer.anyTaskForId(mOptions.getLaunchTaskId());
2493             if (launchTask != null) {
2494                 return launchTask;
2495             }
2496             return null;
2497         }
2498 
2499         // We may want to try to place the new activity in to an existing task.  We always
2500         // do this if the target activity is singleTask or singleInstance; we will also do
2501         // this if NEW_TASK has been requested, and there is not an additional qualifier telling
2502         // us to still place it in a new task: multi task, always doc mode, or being asked to
2503         // launch this as a new task behind the current one.
2504         boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 &&
2505                 (mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
2506                 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK);
2507         // If bring to front is requested, and no result is requested and we have not been given
2508         // an explicit task to launch in to, and we can find a task that was started with this
2509         // same component, then instead of launching bring that one to the front.
2510         putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null;
2511         ActivityRecord intentActivity = null;
2512         if (putIntoExistingTask) {
2513             if (LAUNCH_SINGLE_INSTANCE == mLaunchMode) {
2514                 // There can be one and only one instance of single instance activity in the
2515                 // history, and it is always in its own unique task, so we do a special search.
2516                 intentActivity = mRootWindowContainer.findActivity(mIntent, mStartActivity.info,
2517                        mStartActivity.isActivityTypeHome());
2518             } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
2519                 // For the launch adjacent case we only want to put the activity in an existing
2520                 // task if the activity already exists in the history.
2521                 intentActivity = mRootWindowContainer.findActivity(mIntent, mStartActivity.info,
2522                         !(LAUNCH_SINGLE_TASK == mLaunchMode));
2523             } else {
2524                 // Otherwise find the best task to put the activity in.
2525                 intentActivity =
2526                         mRootWindowContainer.findTask(mStartActivity, mPreferredTaskDisplayArea);
2527             }
2528         }
2529 
2530         if (intentActivity != null && mLaunchMode == LAUNCH_SINGLE_INSTANCE_PER_TASK
2531                 && !intentActivity.getTask().getRootActivity().mActivityComponent.equals(
2532                 mStartActivity.mActivityComponent)) {
2533             // The task could be selected due to same task affinity. Do not reuse the task while
2534             // starting the singleInstancePerTask activity if it is not the task root activity.
2535             intentActivity = null;
2536         }
2537 
2538         if (intentActivity != null
2539                 && (mStartActivity.isActivityTypeHome() || intentActivity.isActivityTypeHome())
2540                 && intentActivity.getDisplayArea() != mPreferredTaskDisplayArea) {
2541             // Do not reuse home activity on other display areas.
2542             intentActivity = null;
2543         }
2544 
2545         return intentActivity != null ? intentActivity.getTask() : null;
2546     }
2547 
2548     /**
2549      * Figure out which task and activity to bring to front when we have found an existing matching
2550      * activity record in history. May also clear the task if needed.
2551      *
2552      * @param intentActivity Existing matching activity.
2553      * @return {@link ActivityRecord} brought to front.
2554      */
setTargetRootTaskIfNeeded(ActivityRecord intentActivity)2555     private void setTargetRootTaskIfNeeded(ActivityRecord intentActivity) {
2556         intentActivity.getTaskFragment().clearLastPausedActivity();
2557         Task intentTask = intentActivity.getTask();
2558 
2559         if (mTargetRootTask == null) {
2560             // Update launch target task when it is not indicated.
2561             if (mSourceRecord != null && mSourceRecord.mLaunchRootTask != null) {
2562                 // Inherit the target-root-task from source to ensure trampoline activities will be
2563                 // launched into the same root task.
2564                 mTargetRootTask = Task.fromWindowContainerToken(mSourceRecord.mLaunchRootTask);
2565             } else {
2566                 mTargetRootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags, intentTask,
2567                         mOptions);
2568             }
2569         }
2570 
2571         // If the matching task is already in the adjacent task of the launch target. Adjust to use
2572         // the adjacent task as its launch target. So the existing task will be launched into the
2573         // closer one and won't be reparent redundantly.
2574         final Task adjacentTargetTask = mTargetRootTask.getAdjacentTaskFragment() != null
2575                 ? mTargetRootTask.getAdjacentTaskFragment().asTask() : null;
2576         if (adjacentTargetTask != null && intentActivity.isDescendantOf(adjacentTargetTask)) {
2577             mTargetRootTask = adjacentTargetTask;
2578         }
2579 
2580         // If the target task is not in the front, then we need to bring it to the front...
2581         // except...  well, with SINGLE_TASK_LAUNCH it's not entirely clear. We'd like to have
2582         // the same behavior as if a new instance was being started, which means not bringing it
2583         // to the front if the caller is not itself in the front.
2584         final boolean differentTopTask;
2585         if (mTargetRootTask.getDisplayArea() == mPreferredTaskDisplayArea) {
2586             final Task focusRootTask = mTargetRootTask.mDisplayContent.getFocusedRootTask();
2587             final ActivityRecord curTop = (focusRootTask == null)
2588                     ? null : focusRootTask.topRunningNonDelayedActivityLocked(mNotTop);
2589             final Task topTask = curTop != null ? curTop.getTask() : null;
2590             differentTopTask = topTask != intentTask
2591                     || (focusRootTask != null && topTask != focusRootTask.getTopMostTask());
2592         } else {
2593             // The existing task should always be different from those in other displays.
2594             differentTopTask = true;
2595         }
2596 
2597         if (differentTopTask && !mAvoidMoveToFront) {
2598             mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
2599             // TODO(b/264487981): Consider using BackgroundActivityStartController to determine
2600             //  whether to bring the launching activity to the front.
2601             if (mSourceRecord == null || inTopNonFinishingTask(mSourceRecord)) {
2602                 // We really do want to push this one into the user's face, right now.
2603                 if (mLaunchTaskBehind && mSourceRecord != null) {
2604                     intentActivity.setTaskToAffiliateWith(mSourceRecord.getTask());
2605                 }
2606 
2607                 if (intentActivity.isDescendantOf(mTargetRootTask)) {
2608                     // TODO(b/151572268): Figure out a better way to move tasks in above 2-levels
2609                     //  tasks hierarchies.
2610                     if (mTargetRootTask != intentTask
2611                             && mTargetRootTask != intentTask.getParent().asTask()) {
2612                         intentTask.getParent().positionChildAt(POSITION_TOP, intentTask,
2613                                 false /* includingParents */);
2614                         intentTask = intentTask.getParent().asTaskFragment().getTask();
2615                     }
2616                     // If the activity is visible in multi-windowing mode, it may already be on
2617                     // the top (visible to user but not the global top), then the result code
2618                     // should be START_DELIVERED_TO_TOP instead of START_TASK_TO_FRONT.
2619                     final boolean wasTopOfVisibleRootTask = intentActivity.isVisibleRequested()
2620                             && intentActivity.inMultiWindowMode()
2621                             && intentActivity == mTargetRootTask.topRunningActivity();
2622                     // We only want to move to the front, if we aren't going to launch on a
2623                     // different root task. If we launch on a different root task, we will put the
2624                     // task on top there.
2625                     // Defer resuming the top activity while moving task to top, since the
2626                     // current task-top activity may not be the activity that should be resumed.
2627                     mTargetRootTask.moveTaskToFront(intentTask, mNoAnimation, mOptions,
2628                             mStartActivity.appTimeTracker, DEFER_RESUME,
2629                             "bringingFoundTaskToFront");
2630                     mMovedToFront = !wasTopOfVisibleRootTask;
2631                 } else if (intentActivity.getWindowingMode() != WINDOWING_MODE_PINNED) {
2632                     // Leaves reparenting pinned task operations to task organizer to make sure it
2633                     // dismisses pinned task properly.
2634                     // TODO(b/199997762): Consider leaving all reparent operation of organized tasks
2635                     //  to task organizer.
2636                     intentTask.reparent(mTargetRootTask, ON_TOP, REPARENT_MOVE_ROOT_TASK_TO_FRONT,
2637                             ANIMATE, DEFER_RESUME, "reparentToTargetRootTask");
2638                     mMovedToFront = true;
2639                 }
2640                 mOptions = null;
2641             }
2642         }
2643 
2644         // Update the target's launch cookie and pending remote animation to those specified in the
2645         // options if set.
2646         if (mStartActivity.mLaunchCookie != null) {
2647             intentActivity.mLaunchCookie = mStartActivity.mLaunchCookie;
2648         }
2649         if (mStartActivity.mPendingRemoteAnimation != null) {
2650             intentActivity.mPendingRemoteAnimation = mStartActivity.mPendingRemoteAnimation;
2651         }
2652 
2653         // Need to update mTargetRootTask because if task was moved out of it, the original root
2654         // task may be destroyed.
2655         mTargetRootTask = intentActivity.getRootTask();
2656         mSupervisor.handleNonResizableTaskIfNeeded(intentTask, WINDOWING_MODE_UNDEFINED,
2657                 mRootWindowContainer.getDefaultTaskDisplayArea(), mTargetRootTask);
2658     }
2659 
inTopNonFinishingTask(ActivityRecord r)2660     private boolean inTopNonFinishingTask(ActivityRecord r) {
2661         if (r == null || r.getTask() == null) {
2662             return false;
2663         }
2664 
2665         final Task rTask = r.getTask();
2666         final Task parent = rTask.getCreatedByOrganizerTask() != null
2667                 ? rTask.getCreatedByOrganizerTask() : r.getRootTask();
2668         final ActivityRecord topNonFinishingActivity = parent != null
2669                 ? parent.getTopNonFinishingActivity() : null;
2670 
2671         return topNonFinishingActivity != null && topNonFinishingActivity.getTask() == rTask;
2672     }
2673 
resumeTargetRootTaskIfNeeded()2674     private void resumeTargetRootTaskIfNeeded() {
2675         if (mDoResume) {
2676             final ActivityRecord next = mTargetRootTask.topRunningActivity(
2677                     true /* focusableOnly */);
2678             if (next != null) {
2679                 next.setCurrentLaunchCanTurnScreenOn(true);
2680             }
2681             if (mTargetRootTask.isFocusable()) {
2682                 mRootWindowContainer.resumeFocusedTasksTopActivities(mTargetRootTask, null,
2683                         mOptions, mTransientLaunch);
2684             } else {
2685                 mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
2686             }
2687         } else {
2688             ActivityOptions.abort(mOptions);
2689         }
2690         mRootWindowContainer.updateUserRootTask(mStartActivity.mUserId, mTargetRootTask);
2691     }
2692 
setNewTask(Task taskToAffiliate)2693     private void setNewTask(Task taskToAffiliate) {
2694         final boolean toTop = !mLaunchTaskBehind && !mAvoidMoveToFront;
2695         final Task task = mTargetRootTask.reuseOrCreateTask(
2696                 mStartActivity.info, mIntent, mVoiceSession,
2697                 mVoiceInteractor, toTop, mStartActivity, mSourceRecord, mOptions);
2698         task.mTransitionController.collectExistenceChange(task);
2699         addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask");
2700 
2701         ProtoLog.v(WM_DEBUG_TASKS, "Starting new activity %s in new task %s",
2702                 mStartActivity, mStartActivity.getTask());
2703 
2704         if (taskToAffiliate != null) {
2705             mStartActivity.setTaskToAffiliateWith(taskToAffiliate);
2706         }
2707     }
2708 
deliverNewIntent(ActivityRecord activity, NeededUriGrants intentGrants)2709     private void deliverNewIntent(ActivityRecord activity, NeededUriGrants intentGrants) {
2710         if (mIntentDelivered) {
2711             return;
2712         }
2713 
2714         activity.logStartActivity(EventLogTags.WM_NEW_INTENT, activity.getTask());
2715         activity.deliverNewIntentLocked(mCallingUid, mStartActivity.intent, intentGrants,
2716                 mStartActivity.launchedFromPackage);
2717         mIntentDelivered = true;
2718     }
2719 
2720     /** Places {@link #mStartActivity} in {@code task} or an embedded {@link TaskFragment}. */
addOrReparentStartingActivity(@onNull Task task, String reason)2721     private void addOrReparentStartingActivity(@NonNull Task task, String reason) {
2722         TaskFragment newParent = task;
2723         if (mInTaskFragment != null) {
2724             int embeddingCheckResult = canEmbedActivity(mInTaskFragment, mStartActivity, task);
2725             if (embeddingCheckResult == EMBEDDING_ALLOWED) {
2726                 newParent = mInTaskFragment;
2727             } else {
2728                 // Start mStartActivity to task instead if it can't be embedded to mInTaskFragment.
2729                 sendCanNotEmbedActivityError(mInTaskFragment, embeddingCheckResult);
2730             }
2731         } else {
2732             TaskFragment candidateTf = mAddingToTaskFragment != null ? mAddingToTaskFragment : null;
2733             if (candidateTf == null) {
2734                 final ActivityRecord top = task.topRunningActivity(false /* focusableOnly */,
2735                         false /* includingEmbeddedTask */);
2736                 if (top != null) {
2737                     candidateTf = top.getTaskFragment();
2738                 }
2739             }
2740             if (candidateTf != null && candidateTf.isEmbedded()
2741                     && canEmbedActivity(candidateTf, mStartActivity, task) == EMBEDDING_ALLOWED) {
2742                 // Use the embedded TaskFragment of the top activity as the new parent if the
2743                 // activity can be embedded.
2744                 newParent = candidateTf;
2745             }
2746         }
2747         if (mStartActivity.getTaskFragment() == null
2748                 || mStartActivity.getTaskFragment() == newParent) {
2749             newParent.addChild(mStartActivity, POSITION_TOP);
2750         } else {
2751             mStartActivity.reparent(newParent, newParent.getChildCount() /* top */, reason);
2752         }
2753     }
2754 
2755     /**
2756      * Notifies the client side that {@link #mStartActivity} cannot be embedded to
2757      * {@code taskFragment}.
2758      */
sendCanNotEmbedActivityError(TaskFragment taskFragment, @EmbeddingCheckResult int result)2759     private void sendCanNotEmbedActivityError(TaskFragment taskFragment,
2760             @EmbeddingCheckResult int result) {
2761         final String errMsg;
2762         switch(result) {
2763             case EMBEDDING_DISALLOWED_NEW_TASK: {
2764                 errMsg = "Cannot embed " + mStartActivity + " that launched on another task"
2765                         + ",mLaunchMode=" + launchModeToString(mLaunchMode)
2766                         + ",mLaunchFlag=" + Integer.toHexString(mLaunchFlags);
2767                 break;
2768             }
2769             case EMBEDDING_DISALLOWED_MIN_DIMENSION_VIOLATION: {
2770                 errMsg = "Cannot embed " + mStartActivity
2771                         + ". TaskFragment's bounds:" + taskFragment.getBounds()
2772                         + ", minimum dimensions:" + mStartActivity.getMinDimensions();
2773                 break;
2774             }
2775             case EMBEDDING_DISALLOWED_UNTRUSTED_HOST: {
2776                 errMsg = "The app:" + mCallingUid + "is not trusted to " + mStartActivity;
2777                 break;
2778             }
2779             default:
2780                 errMsg = "Unhandled embed result:" + result;
2781         }
2782         if (taskFragment.isOrganized()) {
2783             mService.mWindowOrganizerController.sendTaskFragmentOperationFailure(
2784                     taskFragment.getTaskFragmentOrganizer(), mRequest.errorCallbackToken,
2785                     taskFragment, HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT,
2786                     new SecurityException(errMsg));
2787         } else {
2788             // If the taskFragment is not organized, just dump error message as warning logs.
2789             Slog.w(TAG, errMsg);
2790         }
2791     }
2792 
adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance, boolean launchSingleTask, int launchFlags)2793     private int adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance,
2794             boolean launchSingleTask, int launchFlags) {
2795         if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2796                 (launchSingleInstance || launchSingleTask)) {
2797             // We have a conflict between the Intent and the Activity manifest, manifest wins.
2798             Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " +
2799                     "\"singleInstance\" or \"singleTask\"");
2800             launchFlags &=
2801                     ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK);
2802         } else {
2803             switch (r.info.documentLaunchMode) {
2804                 case ActivityInfo.DOCUMENT_LAUNCH_NONE:
2805                     break;
2806                 case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
2807                     launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2808                     break;
2809                 case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
2810                     launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2811                     break;
2812                 case ActivityInfo.DOCUMENT_LAUNCH_NEVER:
2813                     if (mLaunchMode == LAUNCH_SINGLE_INSTANCE_PER_TASK) {
2814                         // Remove MULTIPLE_TASK flag along with NEW_DOCUMENT only if NEW_DOCUMENT
2815                         // is set, otherwise we still want to keep the MULTIPLE_TASK flag (if
2816                         // any) for singleInstancePerTask that the multiple tasks can be created,
2817                         // or a singleInstancePerTask activity is basically the same as a
2818                         // singleTask activity when documentLaunchMode set to never.
2819                         if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
2820                             launchFlags &= ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT
2821                                     | FLAG_ACTIVITY_MULTIPLE_TASK);
2822                         }
2823                     } else {
2824                         // TODO(b/184903976): Should FLAG_ACTIVITY_MULTIPLE_TASK always be
2825                         // removed for document-never activity?
2826                         launchFlags &=
2827                                 ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK);
2828                     }
2829                     break;
2830             }
2831         }
2832         return launchFlags;
2833     }
2834 
getOrCreateRootTask(ActivityRecord r, int launchFlags, Task task, ActivityOptions aOptions)2835     private Task getOrCreateRootTask(ActivityRecord r, int launchFlags, Task task,
2836             ActivityOptions aOptions) {
2837         final boolean onTop =
2838                 (aOptions == null || !aOptions.getAvoidMoveToFront()) && !mLaunchTaskBehind;
2839         final Task sourceTask = mSourceRecord != null ? mSourceRecord.getTask() : null;
2840         return mRootWindowContainer.getOrCreateRootTask(r, aOptions, task, sourceTask, onTop,
2841                 mLaunchParams, launchFlags);
2842     }
2843 
isLaunchModeOneOf(int mode1, int mode2)2844     private boolean isLaunchModeOneOf(int mode1, int mode2) {
2845         return mode1 == mLaunchMode || mode2 == mLaunchMode;
2846     }
2847 
isLaunchModeOneOf(int mode1, int mode2, int mode3)2848     private boolean isLaunchModeOneOf(int mode1, int mode2, int mode3) {
2849         return mode1 == mLaunchMode || mode2 == mLaunchMode || mode3 == mLaunchMode;
2850     }
2851 
isDocumentLaunchesIntoExisting(int flags)2852     static boolean isDocumentLaunchesIntoExisting(int flags) {
2853         return (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2854                 (flags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0;
2855     }
2856 
setIntent(Intent intent)2857     ActivityStarter setIntent(Intent intent) {
2858         mRequest.intent = intent;
2859         return this;
2860     }
2861 
getIntent()2862     Intent getIntent() {
2863         return mRequest.intent;
2864     }
2865 
setIntentGrants(NeededUriGrants intentGrants)2866     ActivityStarter setIntentGrants(NeededUriGrants intentGrants) {
2867         mRequest.intentGrants = intentGrants;
2868         return this;
2869     }
2870 
setReason(String reason)2871     ActivityStarter setReason(String reason) {
2872         mRequest.reason = reason;
2873         return this;
2874     }
2875 
setCaller(IApplicationThread caller)2876     ActivityStarter setCaller(IApplicationThread caller) {
2877         mRequest.caller = caller;
2878         return this;
2879     }
2880 
setResolvedType(String type)2881     ActivityStarter setResolvedType(String type) {
2882         mRequest.resolvedType = type;
2883         return this;
2884     }
2885 
setActivityInfo(ActivityInfo info)2886     ActivityStarter setActivityInfo(ActivityInfo info) {
2887         mRequest.activityInfo = info;
2888         return this;
2889     }
2890 
setResolveInfo(ResolveInfo info)2891     ActivityStarter setResolveInfo(ResolveInfo info) {
2892         mRequest.resolveInfo = info;
2893         return this;
2894     }
2895 
setVoiceSession(IVoiceInteractionSession voiceSession)2896     ActivityStarter setVoiceSession(IVoiceInteractionSession voiceSession) {
2897         mRequest.voiceSession = voiceSession;
2898         return this;
2899     }
2900 
setVoiceInteractor(IVoiceInteractor voiceInteractor)2901     ActivityStarter setVoiceInteractor(IVoiceInteractor voiceInteractor) {
2902         mRequest.voiceInteractor = voiceInteractor;
2903         return this;
2904     }
2905 
setResultTo(IBinder resultTo)2906     ActivityStarter setResultTo(IBinder resultTo) {
2907         mRequest.resultTo = resultTo;
2908         return this;
2909     }
2910 
setResultWho(String resultWho)2911     ActivityStarter setResultWho(String resultWho) {
2912         mRequest.resultWho = resultWho;
2913         return this;
2914     }
2915 
setRequestCode(int requestCode)2916     ActivityStarter setRequestCode(int requestCode) {
2917         mRequest.requestCode = requestCode;
2918         return this;
2919     }
2920 
2921     /**
2922      * Sets the pid of the caller who originally started the activity.
2923      *
2924      * Normally, the pid/uid would be the calling pid from the binder call.
2925      * However, in case of a {@link PendingIntent}, the pid/uid pair of the caller is considered
2926      * the original entity that created the pending intent, in contrast to setRealCallingPid/Uid,
2927      * which represents the entity who invoked pending intent via {@link PendingIntent#send}.
2928      */
setCallingPid(int pid)2929     ActivityStarter setCallingPid(int pid) {
2930         mRequest.callingPid = pid;
2931         return this;
2932     }
2933 
2934     /**
2935      * Sets the uid of the caller who originally started the activity.
2936      *
2937      * @see #setCallingPid
2938      */
setCallingUid(int uid)2939     ActivityStarter setCallingUid(int uid) {
2940         mRequest.callingUid = uid;
2941         return this;
2942     }
2943 
setCallingPackage(String callingPackage)2944     ActivityStarter setCallingPackage(String callingPackage) {
2945         mRequest.callingPackage = callingPackage;
2946         return this;
2947     }
2948 
setCallingFeatureId(String callingFeatureId)2949     ActivityStarter setCallingFeatureId(String callingFeatureId) {
2950         mRequest.callingFeatureId = callingFeatureId;
2951         return this;
2952     }
2953 
2954     /**
2955      * Sets the pid of the caller who requested to launch the activity.
2956      *
2957      * The pid/uid represents the caller who launches the activity in this request.
2958      * It will almost same as setCallingPid/Uid except when processing {@link PendingIntent}:
2959      * the pid/uid will be the caller who called {@link PendingIntent#send()}.
2960      *
2961      * @see #setCallingPid
2962      */
setRealCallingPid(int pid)2963     ActivityStarter setRealCallingPid(int pid) {
2964         mRequest.realCallingPid = pid;
2965         return this;
2966     }
2967 
2968     /**
2969      * Sets the uid of the caller who requested to launch the activity.
2970      *
2971      * @see #setRealCallingPid
2972      */
setRealCallingUid(int uid)2973     ActivityStarter setRealCallingUid(int uid) {
2974         mRequest.realCallingUid = uid;
2975         return this;
2976     }
2977 
setStartFlags(int startFlags)2978     ActivityStarter setStartFlags(int startFlags) {
2979         mRequest.startFlags = startFlags;
2980         return this;
2981     }
2982 
setActivityOptions(SafeActivityOptions options)2983     ActivityStarter setActivityOptions(SafeActivityOptions options) {
2984         mRequest.activityOptions = options;
2985         return this;
2986     }
2987 
setActivityOptions(Bundle bOptions)2988     ActivityStarter setActivityOptions(Bundle bOptions) {
2989         return setActivityOptions(SafeActivityOptions.fromBundle(bOptions));
2990     }
2991 
setIgnoreTargetSecurity(boolean ignoreTargetSecurity)2992     ActivityStarter setIgnoreTargetSecurity(boolean ignoreTargetSecurity) {
2993         mRequest.ignoreTargetSecurity = ignoreTargetSecurity;
2994         return this;
2995     }
2996 
setFilterCallingUid(int filterCallingUid)2997     ActivityStarter setFilterCallingUid(int filterCallingUid) {
2998         mRequest.filterCallingUid = filterCallingUid;
2999         return this;
3000     }
3001 
setComponentSpecified(boolean componentSpecified)3002     ActivityStarter setComponentSpecified(boolean componentSpecified) {
3003         mRequest.componentSpecified = componentSpecified;
3004         return this;
3005     }
3006 
setOutActivity(ActivityRecord[] outActivity)3007     ActivityStarter setOutActivity(ActivityRecord[] outActivity) {
3008         mRequest.outActivity = outActivity;
3009         return this;
3010     }
3011 
setInTask(Task inTask)3012     ActivityStarter setInTask(Task inTask) {
3013         mRequest.inTask = inTask;
3014         return this;
3015     }
3016 
setInTaskFragment(TaskFragment taskFragment)3017     ActivityStarter setInTaskFragment(TaskFragment taskFragment) {
3018         mRequest.inTaskFragment = taskFragment;
3019         return this;
3020     }
3021 
setWaitResult(WaitResult result)3022     ActivityStarter setWaitResult(WaitResult result) {
3023         mRequest.waitResult = result;
3024         return this;
3025     }
3026 
setProfilerInfo(ProfilerInfo info)3027     ActivityStarter setProfilerInfo(ProfilerInfo info) {
3028         mRequest.profilerInfo = info;
3029         return this;
3030     }
3031 
setGlobalConfiguration(Configuration config)3032     ActivityStarter setGlobalConfiguration(Configuration config) {
3033         mRequest.globalConfig = config;
3034         return this;
3035     }
3036 
setUserId(int userId)3037     ActivityStarter setUserId(int userId) {
3038         mRequest.userId = userId;
3039         return this;
3040     }
3041 
setAllowPendingRemoteAnimationRegistryLookup(boolean allowLookup)3042     ActivityStarter setAllowPendingRemoteAnimationRegistryLookup(boolean allowLookup) {
3043         mRequest.allowPendingRemoteAnimationRegistryLookup = allowLookup;
3044         return this;
3045     }
3046 
setOriginatingPendingIntent(PendingIntentRecord originatingPendingIntent)3047     ActivityStarter setOriginatingPendingIntent(PendingIntentRecord originatingPendingIntent) {
3048         mRequest.originatingPendingIntent = originatingPendingIntent;
3049         return this;
3050     }
3051 
setAllowBackgroundActivityStart(boolean allowBackgroundActivityStart)3052     ActivityStarter setAllowBackgroundActivityStart(boolean allowBackgroundActivityStart) {
3053         mRequest.allowBackgroundActivityStart = allowBackgroundActivityStart;
3054         return this;
3055     }
3056 
setErrorCallbackToken(@ullable IBinder errorCallbackToken)3057     ActivityStarter setErrorCallbackToken(@Nullable IBinder errorCallbackToken) {
3058         mRequest.errorCallbackToken = errorCallbackToken;
3059         return this;
3060     }
3061 
dump(PrintWriter pw, String prefix)3062     void dump(PrintWriter pw, String prefix) {
3063         pw.print(prefix);
3064         pw.print("mCurrentUser=");
3065         pw.println(mRootWindowContainer.mCurrentUser);
3066         pw.print(prefix);
3067         pw.print("mLastStartReason=");
3068         pw.println(mLastStartReason);
3069         pw.print(prefix);
3070         pw.print("mLastStartActivityTimeMs=");
3071         pw.println(DateFormat.getDateTimeInstance().format(new Date(mLastStartActivityTimeMs)));
3072         pw.print(prefix);
3073         pw.print("mLastStartActivityResult=");
3074         pw.println(mLastStartActivityResult);
3075         if (mLastStartActivityRecord != null) {
3076             pw.print(prefix);
3077             pw.println("mLastStartActivityRecord:");
3078             mLastStartActivityRecord.dump(pw, prefix + "  ", true /* dumpAll */);
3079         }
3080         if (mStartActivity != null) {
3081             pw.print(prefix);
3082             pw.println("mStartActivity:");
3083             mStartActivity.dump(pw, prefix + "  ", true /* dumpAll */);
3084         }
3085         if (mIntent != null) {
3086             pw.print(prefix);
3087             pw.print("mIntent=");
3088             pw.println(mIntent);
3089         }
3090         if (mOptions != null) {
3091             pw.print(prefix);
3092             pw.print("mOptions=");
3093             pw.println(mOptions);
3094         }
3095         pw.print(prefix);
3096         pw.print("mLaunchMode=");
3097         pw.print(launchModeToString(mLaunchMode));
3098         pw.print(prefix);
3099         pw.print("mLaunchFlags=0x");
3100         pw.print(Integer.toHexString(mLaunchFlags));
3101         pw.print(" mDoResume=");
3102         pw.print(mDoResume);
3103         pw.print(" mAddingToTask=");
3104         pw.print(mAddingToTask);
3105         pw.print(" mInTaskFragment=");
3106         pw.println(mInTaskFragment);
3107     }
3108 }
3109