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