OSDN Git Service

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