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