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