diff options
Diffstat (limited to 'com/android/server/am/ActivityStarter.java')
-rw-r--r-- | com/android/server/am/ActivityStarter.java | 133 |
1 files changed, 73 insertions, 60 deletions
diff --git a/com/android/server/am/ActivityStarter.java b/com/android/server/am/ActivityStarter.java index 6f74d851..d444c663 100644 --- a/com/android/server/am/ActivityStarter.java +++ b/com/android/server/am/ActivityStarter.java @@ -26,9 +26,15 @@ import static android.app.ActivityManager.START_RETURN_INTENT_TO_CALLER; import static android.app.ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; import static android.app.ActivityManager.START_SUCCESS; import static android.app.ActivityManager.START_TASK_TO_FRONT; +import static android.app.ActivityManager.StackId; +import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; +import static android.app.ActivityManager.StackId.INVALID_STACK_ID; +import static android.app.ActivityManager.StackId.PINNED_STACK_ID; +import static android.app.ActivityManager.StackId.isDynamicStack; import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; @@ -115,6 +121,7 @@ import com.android.internal.app.HeavyWeightSwitcherActivity; import com.android.internal.app.IVoiceInteractor; import com.android.server.am.ActivityStackSupervisor.PendingActivityLaunch; import com.android.server.pm.InstantAppResolver; +import com.android.server.wm.WindowManagerService; import java.io.PrintWriter; import java.text.DateFormat; @@ -133,11 +140,11 @@ class ActivityStarter { private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS; private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION; private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING; - private static final int INVALID_LAUNCH_MODE = -1; private final ActivityManagerService mService; private final ActivityStackSupervisor mSupervisor; private final ActivityStartInterceptor mInterceptor; + private WindowManagerService mWindowManager; final ArrayList<PendingActivityLaunch> mPendingActivityLaunches = new ArrayList<>(); @@ -147,7 +154,9 @@ class ActivityStarter { private int mCallingUid; private ActivityOptions mOptions; - private int mLaunchMode; + private boolean mLaunchSingleTop; + private boolean mLaunchSingleInstance; + private boolean mLaunchSingleTask; private boolean mLaunchTaskBehind; private int mLaunchFlags; @@ -157,7 +166,6 @@ class ActivityStarter { private boolean mDoResume; private int mStartFlags; private ActivityRecord mSourceRecord; - // The display to launch the activity onto, barring any strong reason to do otherwise. private int mPreferredDisplayId; @@ -187,6 +195,8 @@ class ActivityStarter { private IVoiceInteractionSession mVoiceSession; private IVoiceInteractor mVoiceInteractor; + private boolean mUsingVr2dDisplay; + // Last home activity record we attempted to start private final ActivityRecord[] mLastHomeActivityStartRecord = new ActivityRecord[1]; // The result of the last home activity we attempted to start. @@ -206,9 +216,11 @@ class ActivityStarter { mCallingUid = -1; mOptions = null; + mLaunchSingleTop = false; + mLaunchSingleInstance = false; + mLaunchSingleTask = false; mLaunchTaskBehind = false; mLaunchFlags = 0; - mLaunchMode = INVALID_LAUNCH_MODE; mLaunchBounds = null; @@ -236,13 +248,16 @@ class ActivityStarter { mVoiceSession = null; mVoiceInteractor = null; + mUsingVr2dDisplay = false; + mIntentDelivered = false; } - ActivityStarter(ActivityManagerService service) { + ActivityStarter(ActivityManagerService service, ActivityStackSupervisor supervisor) { mService = service; - mSupervisor = mService.mStackSupervisor; + mSupervisor = supervisor; mInterceptor = new ActivityStartInterceptor(mService, mSupervisor); + mUsingVr2dDisplay = false; } int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent, @@ -595,41 +610,38 @@ class ActivityStarter { mSupervisor.reportTaskToFrontNoLaunch(mStartActivity); } - ActivityStack startedActivityStack = null; + int startedActivityStackId = INVALID_STACK_ID; final ActivityStack currentStack = r.getStack(); if (currentStack != null) { - startedActivityStack = currentStack; + startedActivityStackId = currentStack.mStackId; } else if (mTargetStack != null) { - startedActivityStack = targetStack; + startedActivityStackId = targetStack.mStackId; } - if (startedActivityStack == null) { - return; - } - - if (startedActivityStack.inSplitScreenPrimaryWindowingMode()) { - final ActivityStack homeStack = mSupervisor.mHomeStack; + if (startedActivityStackId == DOCKED_STACK_ID) { + final ActivityStack homeStack = mSupervisor.getDefaultDisplay().getStack( + WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME); final boolean homeStackVisible = homeStack != null && homeStack.isVisible(); if (homeStackVisible) { // We launch an activity while being in home stack, which means either launcher or // recents into docked stack. We don't want the launched activity to be alone in a // docked stack, so we want to immediately launch recents too. if (DEBUG_RECENTS) Slog.d(TAG, "Scheduling recents launch."); - mService.mWindowManager.showRecentApps(true /* fromHome */); + mWindowManager.showRecentApps(true /* fromHome */); } return; } boolean clearedTask = (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK) && (mReuseTask != null); - if (startedActivityStack.inPinnedWindowingMode() - && (result == START_TASK_TO_FRONT || result == START_DELIVERED_TO_TOP - || clearedTask)) { + if (startedActivityStackId == PINNED_STACK_ID && (result == START_TASK_TO_FRONT + || result == START_DELIVERED_TO_TOP || clearedTask)) { // The activity was already running in the pinned stack so it wasn't started, but either // brought to the front or the new intent was delivered to it since it was already in // front. Notify anyone interested in this piece of information. mService.mTaskChangeNotificationController.notifyPinnedActivityRestartAttempt( clearedTask); + return; } } @@ -1050,7 +1062,7 @@ class ActivityStarter { // operations. if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0 || isDocumentLaunchesIntoExisting(mLaunchFlags) - || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) { + || mLaunchSingleInstance || mLaunchSingleTask) { final TaskRecord task = reusedActivity.getTask(); // In this situation we want to remove all activities from the task up to the one @@ -1133,7 +1145,7 @@ class ActivityStarter { && top.userId == mStartActivity.userId && top.app != null && top.app.thread != null && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0 - || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK)); + || mLaunchSingleTop || mLaunchSingleTask); if (dontStart) { // For paranoia, make sure we have correctly resumed the top activity. topStack.mLastPausedActivity = null; @@ -1152,7 +1164,7 @@ class ActivityStarter { // Don't use mStartActivity.task to show the toast. We're not starting a new activity // but reusing 'top'. Fields in mStartActivity may not be fully initialized. mSupervisor.handleNonResizableTaskIfNeeded(top.getTask(), preferredWindowingMode, - preferredLaunchDisplayId, topStack); + preferredLaunchDisplayId, topStack.mStackId); return START_DELIVERED_TO_TOP; } @@ -1215,7 +1227,7 @@ class ActivityStarter { mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); // Go ahead and tell window manager to execute app transition for this activity // since the app transition will not be triggered through the resume channel. - mService.mWindowManager.executeAppTransition(); + mWindowManager.executeAppTransition(); } else { // If the target stack was not previously focusable (previous top running activity // on that stack was not visible) then any prior calls to move the stack to the @@ -1228,13 +1240,13 @@ class ActivityStarter { mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity, mOptions); } - } else if (mStartActivity != null) { - mSupervisor.mRecentTasks.add(mStartActivity.getTask()); + } else { + mSupervisor.addRecentActivity(mStartActivity); } mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack); mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(), preferredWindowingMode, - preferredLaunchDisplayId, mTargetStack); + preferredLaunchDisplayId, mTargetStack.mStackId); return START_SUCCESS; } @@ -1256,13 +1268,13 @@ class ActivityStarter { mLaunchBounds = getOverrideBounds(r, options, inTask); - mLaunchMode = r.launchMode; - + mLaunchSingleTop = r.launchMode == LAUNCH_SINGLE_TOP; + mLaunchSingleInstance = r.launchMode == LAUNCH_SINGLE_INSTANCE; + mLaunchSingleTask = r.launchMode == LAUNCH_SINGLE_TASK; mLaunchFlags = adjustLaunchFlagsToDocumentMode( - r, LAUNCH_SINGLE_INSTANCE == mLaunchMode, - LAUNCH_SINGLE_TASK == mLaunchMode, mIntent.getFlags()); + r, mLaunchSingleInstance, mLaunchSingleTask, mIntent.getFlags()); mLaunchTaskBehind = r.mLaunchTaskBehind - && !isLaunchModeOneOf(LAUNCH_SINGLE_TASK, LAUNCH_SINGLE_INSTANCE) + && !mLaunchSingleTask && !mLaunchSingleInstance && (mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0; sendNewTaskResultRequestIfNeeded(); @@ -1372,7 +1384,7 @@ class ActivityStarter { // If this task is empty, then we are adding the first activity -- it // determines the root, and must be launching as a NEW_TASK. - if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) { + if (mLaunchSingleInstance || mLaunchSingleTask) { if (!baseIntent.getComponent().equals(mStartActivity.intent.getComponent())) { ActivityOptions.abort(mOptions); throw new IllegalArgumentException("Trying to launch singleInstance/Task " @@ -1415,7 +1427,7 @@ class ActivityStarter { // in any task/stack, however it could launch other activities like ResolverActivity, // and we want those to stay in the original task. if ((mStartActivity.isResolverActivity() || mStartActivity.noDisplay) && mSourceRecord != null - && mSourceRecord.inFreeformWindowingMode()) { + && mSourceRecord.isFreeform()) { mAddingToTask = true; } } @@ -1434,7 +1446,7 @@ class ActivityStarter { // instance... this new activity it is starting must go on its // own task. mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK; - } else if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) { + } else if (mLaunchSingleInstance || mLaunchSingleTask) { // The activity being started is a single instance... it always // gets launched into its own task. mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK; @@ -1485,7 +1497,7 @@ class ActivityStarter { // launch this as a new task behind the current one. boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 && (mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0) - || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK); + || mLaunchSingleInstance || mLaunchSingleTask; // If bring to front is requested, and no result is requested and we have not been given // an explicit task to launch in to, and we can find a task that was started with this // same component, then instead of launching bring that one to the front. @@ -1495,7 +1507,7 @@ class ActivityStarter { final TaskRecord task = mSupervisor.anyTaskForIdLocked(mOptions.getLaunchTaskId()); intentActivity = task != null ? task.getTopActivity() : null; } else if (putIntoExistingTask) { - if (LAUNCH_SINGLE_INSTANCE == mLaunchMode) { + if (mLaunchSingleInstance) { // There can be one and only one instance of single instance activity in the // history, and it is always in its own unique task, so we do a special search. intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info, @@ -1504,7 +1516,7 @@ class ActivityStarter { // For the launch adjacent case we only want to put the activity in an existing // task if the activity already exists in the history. intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info, - !(LAUNCH_SINGLE_TASK == mLaunchMode)); + !mLaunchSingleTask); } else { // Otherwise find the best task to put the activity in. intentActivity = mSupervisor.findTaskLocked(mStartActivity, mPreferredDisplayId); @@ -1533,6 +1545,7 @@ class ActivityStarter { if (DEBUG_STACK) { Slog.d(TAG, "getSourceDisplayId :" + displayId); } + mUsingVr2dDisplay = true; return displayId; } @@ -1654,7 +1667,7 @@ class ActivityStarter { } mSupervisor.handleNonResizableTaskIfNeeded(intentActivity.getTask(), - WINDOWING_MODE_UNDEFINED, DEFAULT_DISPLAY, mTargetStack); + WINDOWING_MODE_UNDEFINED, DEFAULT_DISPLAY, mTargetStack.mStackId); // If the caller has requested that the target task be reset, then do so. if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { @@ -1706,7 +1719,7 @@ class ActivityStarter { // mTaskToReturnTo values and we don't want to overwrite them accidentally. mMovedOtherTask = true; } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0 - || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) { + || mLaunchSingleInstance || mLaunchSingleTask) { ActivityRecord top = intentActivity.getTask().performClearTaskLocked(mStartActivity, mLaunchFlags); if (top == null) { @@ -1735,8 +1748,7 @@ class ActivityStarter { // so we take that as a request to bring the task to the foreground. If the top // activity in the task is the root activity, deliver this new intent to it if it // desires. - if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0 - || LAUNCH_SINGLE_TOP == mLaunchMode) + if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0 || mLaunchSingleTop) && intentActivity.realActivity.equals(mStartActivity.realActivity)) { if (intentActivity.frontOfTask) { intentActivity.getTask().setIntent(mStartActivity); @@ -1940,7 +1952,7 @@ class ActivityStarter { if (top != null && top.realActivity.equals(mStartActivity.realActivity) && top.userId == mStartActivity.userId) { if ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0 - || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK)) { + || mLaunchSingleTop || mLaunchSingleTask) { mTargetStack.moveTaskToFrontLocked(mInTask, mNoAnimation, mOptions, mStartActivity.appTimeTracker, "inTaskToFront"); if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) { @@ -1989,9 +2001,9 @@ class ActivityStarter { return; } - final ActivityStack stack = task.getStack(); - if (stack != null && stack.resizeStackWithLaunchBounds()) { - mService.resizeStack(stack.mStackId, bounds, true, !PRESERVE_WINDOWS, ANIMATE, -1); + final int stackId = task.getStackId(); + if (StackId.resizeStackWithLaunchBounds(stackId)) { + mService.resizeStack(stackId, bounds, true, !PRESERVE_WINDOWS, ANIMATE, -1); } else { task.updateOverrideConfiguration(bounds); } @@ -2103,10 +2115,11 @@ class ActivityStarter { } if (stack == null) { // We first try to put the task in the first dynamic stack on home display. - final ActivityDisplay display = mSupervisor.getDefaultDisplay(); - for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { - stack = display.getChildAt(stackNdx); - if (!stack.isOnHomeDisplay()) { + final ArrayList<ActivityStack> homeDisplayStacks = + mSupervisor.getStacksOnDefaultDisplay(); + for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) { + stack = homeDisplayStacks.get(stackNdx); + if (isDynamicStack(stack.mStackId)) { if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, "computeStackFocus: Setting focused stack=" + stack); return stack; @@ -2125,6 +2138,7 @@ class ActivityStarter { private boolean canLaunchIntoFocusedStack(ActivityRecord r, boolean newTask) { final ActivityStack focusedStack = mSupervisor.mFocusedStack; final boolean canUseFocusedStack; + final int focusedStackId = mSupervisor.mFocusedStack.mStackId; if (focusedStack.isActivityTypeAssistant()) { canUseFocusedStack = r.isActivityTypeAssistant(); } else { @@ -2147,7 +2161,7 @@ class ActivityStarter { default: // Dynamic stacks behave similarly to the fullscreen stack and can contain any // resizeable task. - canUseFocusedStack = !focusedStack.isOnHomeDisplay() + canUseFocusedStack = isDynamicStack(focusedStackId) && r.canBeLaunchedOnDisplay(focusedStack.mDisplayId); } } @@ -2163,8 +2177,7 @@ class ActivityStarter { return mReuseTask.getStack(); } - final int vrDisplayId = mPreferredDisplayId == mService.mVr2dDisplayId - ? mPreferredDisplayId : INVALID_DISPLAY; + final int vrDisplayId = mUsingVr2dDisplay ? mPreferredDisplayId : INVALID_DISPLAY; final ActivityStack launchStack = mSupervisor.getLaunchStack(r, aOptions, task, ON_TOP, vrDisplayId); @@ -2192,7 +2205,7 @@ class ActivityStarter { return mSupervisor.mFocusedStack; } - if (parentStack != null && parentStack.inSplitScreenPrimaryWindowingMode()) { + if (parentStack != null && parentStack.isDockedStack()) { // If parent was in docked stack, the natural place to launch another activity // will be fullscreen, so it can appear alongside the docked window. final int activityType = mSupervisor.resolveActivityType(r, mOptions, task); @@ -2202,8 +2215,8 @@ class ActivityStarter { // If the parent is not in the docked stack, we check if there is docked window // and if yes, we will launch into that stack. If not, we just put the new // activity into parent's stack, because we can't find a better place. - final ActivityStack dockedStack = - mSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack(); + final ActivityStack dockedStack = mSupervisor.getDefaultDisplay().getStack( + WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_UNDEFINED); if (dockedStack != null && !dockedStack.shouldBeVisible(r)) { // There is a docked stack, but it isn't visible, so we can't launch into that. return null; @@ -2223,8 +2236,8 @@ class ActivityStarter { return newBounds; } - private boolean isLaunchModeOneOf(int mode1, int mode2) { - return mode1 == mLaunchMode || mode2 == mLaunchMode; + void setWindowManager(WindowManagerService wm) { + mWindowManager = wm; } static boolean isDocumentLaunchesIntoExisting(int flags) { @@ -2305,11 +2318,11 @@ class ActivityStarter { } pw.print(prefix); pw.print("mLaunchSingleTop="); - pw.print(LAUNCH_SINGLE_TOP == mLaunchMode); + pw.print(mLaunchSingleTop); pw.print(" mLaunchSingleInstance="); - pw.print(LAUNCH_SINGLE_INSTANCE == mLaunchMode); + pw.print(mLaunchSingleInstance); pw.print(" mLaunchSingleTask="); - pw.println(LAUNCH_SINGLE_TASK == mLaunchMode); + pw.println(mLaunchSingleTask); pw.print(prefix); pw.print("mLaunchFlags=0x"); pw.print(Integer.toHexString(mLaunchFlags)); |