diff options
15 files changed, 417 insertions, 293 deletions
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java index 7fd0211215c5..925b15deff29 100644 --- a/core/java/android/app/ActivityOptions.java +++ b/core/java/android/app/ActivityOptions.java @@ -51,6 +51,7 @@ import android.view.RemoteAnimationAdapter; import android.view.View; import android.view.ViewGroup; import android.view.Window; +import android.window.WindowContainerToken; import java.util.ArrayList; @@ -184,6 +185,14 @@ public class ActivityOptions { private static final String KEY_CALLER_DISPLAY_ID = "android.activity.callerDisplayId"; /** + * The task display area token the activity should be launched into. + * @see #setLaunchTaskDisplayArea(WindowContainerToken) + * @hide + */ + private static final String KEY_LAUNCH_TASK_DISPLAY_AREA_TOKEN = + "android.activity.launchTaskDisplayAreaToken"; + + /** * The windowing mode the activity should be launched into. * @hide */ @@ -334,6 +343,7 @@ public class ActivityOptions { private PendingIntent mUsageTimeReport; private int mLaunchDisplayId = INVALID_DISPLAY; private int mCallerDisplayId = INVALID_DISPLAY; + private WindowContainerToken mLaunchTaskDisplayArea; @WindowConfiguration.WindowingMode private int mLaunchWindowingMode = WINDOWING_MODE_UNDEFINED; @WindowConfiguration.ActivityType @@ -974,6 +984,7 @@ public class ActivityOptions { mLockTaskMode = opts.getBoolean(KEY_LOCK_TASK_MODE, false); mLaunchDisplayId = opts.getInt(KEY_LAUNCH_DISPLAY_ID, INVALID_DISPLAY); mCallerDisplayId = opts.getInt(KEY_CALLER_DISPLAY_ID, INVALID_DISPLAY); + mLaunchTaskDisplayArea = opts.getParcelable(KEY_LAUNCH_TASK_DISPLAY_AREA_TOKEN); mLaunchWindowingMode = opts.getInt(KEY_LAUNCH_WINDOWING_MODE, WINDOWING_MODE_UNDEFINED); mLaunchActivityType = opts.getInt(KEY_LAUNCH_ACTIVITY_TYPE, ACTIVITY_TYPE_UNDEFINED); mLaunchTaskId = opts.getInt(KEY_LAUNCH_TASK_ID, -1); @@ -1245,6 +1256,18 @@ public class ActivityOptions { } /** @hide */ + public WindowContainerToken getLaunchTaskDisplayArea() { + return mLaunchTaskDisplayArea; + } + + /** @hide */ + public ActivityOptions setLaunchTaskDisplayArea( + WindowContainerToken windowContainerToken) { + mLaunchTaskDisplayArea = windowContainerToken; + return this; + } + + /** @hide */ public int getLaunchWindowingMode() { return mLaunchWindowingMode; } @@ -1568,6 +1591,9 @@ public class ActivityOptions { if (mCallerDisplayId != INVALID_DISPLAY) { b.putInt(KEY_CALLER_DISPLAY_ID, mCallerDisplayId); } + if (mLaunchTaskDisplayArea != null) { + b.putParcelable(KEY_LAUNCH_TASK_DISPLAY_AREA_TOKEN, mLaunchTaskDisplayArea); + } if (mLaunchWindowingMode != WINDOWING_MODE_UNDEFINED) { b.putInt(KEY_LAUNCH_WINDOWING_MODE, mLaunchWindowingMode); } diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 521ffa50f869..a03beee3a32f 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -292,6 +292,7 @@ import android.view.SurfaceControl.Transaction; import android.view.WindowManager; import android.view.WindowManager.LayoutParams; import android.view.animation.Animation; +import android.window.WindowContainerToken; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; @@ -432,6 +433,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final boolean stateNotNeeded; // As per ActivityInfo.flags @VisibleForTesting int mHandoverLaunchDisplayId = INVALID_DISPLAY; // Handover launch display id to next activity. + @VisibleForTesting + TaskDisplayArea mHandoverTaskDisplayArea; // Handover launch task display area. private final boolean componentSpecified; // did caller specify an explicit component? final boolean rootVoiceInteraction; // was this the root activity of a voice interaction? @@ -1657,7 +1660,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (usageReport != null) { appTimeTracker = new AppTimeTracker(usageReport); } - // Gets launch display id from options. It returns INVALID_DISPLAY if not set. + // Gets launch task display area and display id from options. Returns + // null/INVALID_DISPLAY if not set. + final WindowContainerToken daToken = options.getLaunchTaskDisplayArea(); + mHandoverTaskDisplayArea = daToken != null + ? (TaskDisplayArea) WindowContainer.fromBinder(daToken.asBinder()) : null; mHandoverLaunchDisplayId = options.getLaunchDisplayId(); } } diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java index 3bcccedb6de5..fe9e5f3ca09e 100644 --- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java @@ -1053,6 +1053,13 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { return true; } + /** Check if caller is allowed to launch activities on specified task display area. */ + boolean isCallerAllowedToLaunchOnTaskDisplayArea(int callingPid, int callingUid, + TaskDisplayArea taskDisplayArea, ActivityInfo aInfo) { + return isCallerAllowedToLaunchOnDisplay(callingPid, callingUid, + taskDisplayArea != null ? taskDisplayArea.getDisplayId() : DEFAULT_DISPLAY, aInfo); + } + /** Check if caller is allowed to launch activities on specified display. */ boolean isCallerAllowedToLaunchOnDisplay(int callingPid, int callingUid, int launchDisplayId, ActivityInfo aInfo) { @@ -2133,18 +2140,6 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { WindowManagerService.WINDOW_FREEZE_TIMEOUT_DURATION); } - // TODO(b/152116619): Remove after complete switch to TaskDisplayArea - void handleNonResizableTaskIfNeeded(Task task, int preferredWindowingMode, - int preferredDisplayId, ActivityStack actualStack) { - final DisplayContent preferredDisplayContent = mRootWindowContainer - .getDisplayContent(preferredDisplayId); - final TaskDisplayArea preferredDisplayArea = preferredDisplayContent != null - ? preferredDisplayContent.getDefaultTaskDisplayArea() - : null; - handleNonResizableTaskIfNeeded(task, preferredWindowingMode, preferredDisplayArea, - actualStack); - } - void handleNonResizableTaskIfNeeded(Task task, int preferredWindowingMode, TaskDisplayArea preferredTaskDisplayArea, ActivityStack actualStack) { handleNonResizableTaskIfNeeded(task, preferredWindowingMode, preferredTaskDisplayArea, diff --git a/services/core/java/com/android/server/wm/ActivityStartController.java b/services/core/java/com/android/server/wm/ActivityStartController.java index ad54356bced6..7fad395fb51d 100644 --- a/services/core/java/com/android/server/wm/ActivityStartController.java +++ b/services/core/java/com/android/server/wm/ActivityStartController.java @@ -184,8 +184,8 @@ public class ActivityStartController { } final int displayId = taskDisplayArea.getDisplayId(); options.setLaunchDisplayId(displayId); - // TODO(b/152116619): Enable after complete switch to WindowContainerToken - //options.setLaunchWindowContainerToken(taskDisplayArea.getWindowContainerToken()); + options.setLaunchTaskDisplayArea(taskDisplayArea.mRemoteToken + .toWindowContainerToken()); // The home activity will be started later, defer resuming to avoid unneccerary operations // (e.g. start home recursively) when creating home stack. diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index 0bd1aca4030a..0754a348740b 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -55,7 +55,6 @@ import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.os.Process.INVALID_UID; import static android.view.Display.DEFAULT_DISPLAY; -import static android.view.Display.INVALID_DISPLAY; import static com.android.server.wm.ActivityStack.ActivityState.RESUMED; import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME; @@ -167,8 +166,8 @@ class ActivityStarter { private int mStartFlags; private ActivityRecord mSourceRecord; - // The display to launch the activity onto, barring any strong reason to do otherwise. - private int mPreferredDisplayId; + // The task display area to launch the activity onto, barring any strong reason to do otherwise. + private TaskDisplayArea mPreferredTaskDisplayArea; // The windowing mode to apply to the root task, if possible private int mPreferredWindowingMode; @@ -538,7 +537,7 @@ class ActivityStarter { mDoResume = starter.mDoResume; mStartFlags = starter.mStartFlags; mSourceRecord = starter.mSourceRecord; - mPreferredDisplayId = starter.mPreferredDisplayId; + mPreferredTaskDisplayArea = starter.mPreferredTaskDisplayArea; mPreferredWindowingMode = starter.mPreferredWindowingMode; mInTask = starter.mInTask; @@ -1631,7 +1630,7 @@ class ActivityStarter { // Update the recent tasks list immediately when the activity starts mSupervisor.mRecentTasks.add(mStartActivity.getTask()); mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(), - mPreferredWindowingMode, mPreferredDisplayId, mTargetStack); + mPreferredWindowingMode, mPreferredTaskDisplayArea, mTargetStack); return START_SUCCESS; } @@ -1684,9 +1683,9 @@ class ActivityStarter { mSupervisor.getLaunchParamsController().calculate(targetTask, r.info.windowLayout, r, sourceRecord, mOptions, PHASE_BOUNDS, mLaunchParams); - mPreferredDisplayId = mLaunchParams.hasPreferredDisplay() - ? mLaunchParams.mPreferredDisplayId - : DEFAULT_DISPLAY; + mPreferredTaskDisplayArea = mLaunchParams.hasPreferredTaskDisplayArea() + ? mLaunchParams.mPreferredTaskDisplayArea + : mRootWindowContainer.getDefaultTaskDisplayArea(); mPreferredWindowingMode = mLaunchParams.mWindowingMode; } @@ -1703,10 +1702,12 @@ class ActivityStarter { // Do not start home activity if it cannot be launched on preferred display. We are not // doing this in ActivityStackSupervisor#canPlaceEntityOnDisplay because it might // fallback to launch on other displays. - if (r.isActivityTypeHome() && !mRootWindowContainer.canStartHomeOnDisplay(r.info, - mPreferredDisplayId, true /* allowInstrumenting */)) { - Slog.w(TAG, "Cannot launch home on display " + mPreferredDisplayId); - return START_CANCELED; + if (r.isActivityTypeHome()) { + if (!mRootWindowContainer.canStartHomeOnDisplayArea(r.info, mPreferredTaskDisplayArea, + true /* allowInstrumenting */)) { + Slog.w(TAG, "Cannot launch home on display area " + mPreferredTaskDisplayArea); + return START_CANCELED; + } } if (mRestrictedBgActivity && (newTask || !targetTask.isUidPresent(mCallingUid)) @@ -1841,10 +1842,10 @@ class ActivityStarter { && top.attachedToProcess() && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0 || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK)) - // This allows home activity to automatically launch on secondary display when - // display added, if home was the top activity on default display, instead of - // sending new intent to the home activity on default display. - && (!top.isActivityTypeHome() || top.getDisplayId() == mPreferredDisplayId); + // This allows home activity to automatically launch on secondary task display area + // when it was added, if home was the top activity on default task display area, + // instead of sending new intent to the home activity on default display area. + && (!top.isActivityTypeHome() || top.getDisplayArea() == mPreferredTaskDisplayArea); if (!dontStart) { return START_SUCCESS; } @@ -1866,7 +1867,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(), - mLaunchParams.mWindowingMode, mPreferredDisplayId, topStack); + mLaunchParams.mWindowingMode, mPreferredTaskDisplayArea, topStack); return START_DELIVERED_TO_TOP; } @@ -2010,7 +2011,7 @@ class ActivityStarter { mDoResume = false; mStartFlags = 0; mSourceRecord = null; - mPreferredDisplayId = INVALID_DISPLAY; + mPreferredTaskDisplayArea = null; mPreferredWindowingMode = WINDOWING_MODE_UNDEFINED; mInTask = null; @@ -2060,9 +2061,9 @@ class ActivityStarter { // after we located a reusable task (which might be resided in another display). mSupervisor.getLaunchParamsController().calculate(inTask, r.info.windowLayout, r, sourceRecord, options, PHASE_DISPLAY, mLaunchParams); - mPreferredDisplayId = mLaunchParams.hasPreferredDisplay() - ? mLaunchParams.mPreferredDisplayId - : DEFAULT_DISPLAY; + mPreferredTaskDisplayArea = mLaunchParams.hasPreferredTaskDisplayArea() + ? mLaunchParams.mPreferredTaskDisplayArea + : mRootWindowContainer.getDefaultTaskDisplayArea(); mPreferredWindowingMode = mLaunchParams.mWindowingMode; mLaunchMode = r.launchMode; @@ -2334,14 +2335,14 @@ class ActivityStarter { } else { // Otherwise find the best task to put the activity in. intentActivity = - mRootWindowContainer.findTask(mStartActivity, mPreferredDisplayId); + mRootWindowContainer.findTask(mStartActivity, mPreferredTaskDisplayArea); } } if (intentActivity != null && (mStartActivity.isActivityTypeHome() || intentActivity.isActivityTypeHome()) - && intentActivity.getDisplayId() != mPreferredDisplayId) { - // Do not reuse home activity on other displays. + && intentActivity.getDisplayArea() != mPreferredTaskDisplayArea) { + // Do not reuse home activity on other display areas. intentActivity = null; } @@ -2363,7 +2364,7 @@ class ActivityStarter { // the same behavior as if a new instance was being started, which means not bringing it // to the front if the caller is not itself in the front. final boolean differentTopTask; - if (mPreferredDisplayId == mTargetStack.getDisplayId()) { + if (mTargetStack.getDisplayArea() == mPreferredTaskDisplayArea) { final ActivityStack focusStack = mTargetStack.getDisplay().getFocusedStack(); final ActivityRecord curTop = (focusStack == null) ? null : focusStack.topRunningNonDelayedActivityLocked(mNotTop); diff --git a/services/core/java/com/android/server/wm/LaunchParamsController.java b/services/core/java/com/android/server/wm/LaunchParamsController.java index a9820ef1c081..4cd31806f99d 100644 --- a/services/core/java/com/android/server/wm/LaunchParamsController.java +++ b/services/core/java/com/android/server/wm/LaunchParamsController.java @@ -17,7 +17,6 @@ package com.android.server.wm; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; -import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_BOUNDS; @@ -26,6 +25,7 @@ import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier. import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_SKIP; import android.annotation.IntDef; +import android.annotation.Nullable; import android.app.ActivityOptions; import android.content.pm.ActivityInfo.WindowLayout; import android.graphics.Rect; @@ -108,11 +108,13 @@ class LaunchParamsController { if (activity != null && activity.requestedVrComponent != null) { // Check if the Activity is a VR activity. If so, it should be launched in main display. - result.mPreferredDisplayId = DEFAULT_DISPLAY; + result.mPreferredTaskDisplayArea = mService.mRootWindowContainer + .getDefaultTaskDisplayArea(); } else if (mService.mVr2dDisplayId != INVALID_DISPLAY) { // Get the virtual display ID from ActivityTaskManagerService. If that's set we // should always use that. - result.mPreferredDisplayId = mService.mVr2dDisplayId; + result.mPreferredTaskDisplayArea = mService.mRootWindowContainer + .getDisplayContent(mService.mVr2dDisplayId).getDefaultTaskDisplayArea(); } } @@ -136,9 +138,10 @@ class LaunchParamsController { mService.deferWindowLayout(); try { - if (mTmpParams.hasPreferredDisplay() - && mTmpParams.mPreferredDisplayId != task.getStack().getDisplay().mDisplayId) { - mService.moveStackToDisplay(task.getRootTaskId(), mTmpParams.mPreferredDisplayId); + if (mTmpParams.mPreferredTaskDisplayArea != null + && task.getDisplayArea() != mTmpParams.mPreferredTaskDisplayArea) { + mService.mRootWindowContainer.moveStackToTaskDisplayArea(task.getRootTaskId(), + mTmpParams.mPreferredTaskDisplayArea, true /* onTop */); } if (mTmpParams.hasWindowingMode() @@ -184,8 +187,9 @@ class LaunchParamsController { /** The bounds within the parent container. */ final Rect mBounds = new Rect(); - /** The id of the display the {@link Task} would prefer to be on. */ - int mPreferredDisplayId; + /** The display area the {@link Task} would prefer to be on. */ + @Nullable + TaskDisplayArea mPreferredTaskDisplayArea; /** The windowing mode to be in. */ int mWindowingMode; @@ -193,20 +197,20 @@ class LaunchParamsController { /** Sets values back to default. {@link #isEmpty} will return {@code true} once called. */ void reset() { mBounds.setEmpty(); - mPreferredDisplayId = INVALID_DISPLAY; + mPreferredTaskDisplayArea = null; mWindowingMode = WINDOWING_MODE_UNDEFINED; } /** Copies the values set on the passed in {@link LaunchParams}. */ void set(LaunchParams params) { mBounds.set(params.mBounds); - mPreferredDisplayId = params.mPreferredDisplayId; + mPreferredTaskDisplayArea = params.mPreferredTaskDisplayArea; mWindowingMode = params.mWindowingMode; } /** Returns {@code true} if no values have been explicitly set. */ boolean isEmpty() { - return mBounds.isEmpty() && mPreferredDisplayId == INVALID_DISPLAY + return mBounds.isEmpty() && mPreferredTaskDisplayArea == null && mWindowingMode == WINDOWING_MODE_UNDEFINED; } @@ -214,8 +218,8 @@ class LaunchParamsController { return mWindowingMode != WINDOWING_MODE_UNDEFINED; } - boolean hasPreferredDisplay() { - return mPreferredDisplayId != INVALID_DISPLAY; + boolean hasPreferredTaskDisplayArea() { + return mPreferredTaskDisplayArea != null; } @Override @@ -225,7 +229,7 @@ class LaunchParamsController { LaunchParams that = (LaunchParams) o; - if (mPreferredDisplayId != that.mPreferredDisplayId) return false; + if (mPreferredTaskDisplayArea != that.mPreferredTaskDisplayArea) return false; if (mWindowingMode != that.mWindowingMode) return false; return mBounds != null ? mBounds.equals(that.mBounds) : that.mBounds == null; } @@ -233,7 +237,8 @@ class LaunchParamsController { @Override public int hashCode() { int result = mBounds != null ? mBounds.hashCode() : 0; - result = 31 * result + mPreferredDisplayId; + result = 31 * result + (mPreferredTaskDisplayArea != null + ? mPreferredTaskDisplayArea.hashCode() : 0); result = 31 * result + mWindowingMode; return result; } diff --git a/services/core/java/com/android/server/wm/LaunchParamsPersister.java b/services/core/java/com/android/server/wm/LaunchParamsPersister.java index 9371c0eec26f..a974332fd852 100644 --- a/services/core/java/com/android/server/wm/LaunchParamsPersister.java +++ b/services/core/java/com/android/server/wm/LaunchParamsPersister.java @@ -318,7 +318,9 @@ class LaunchParamsPersister { final DisplayContent display = mSupervisor.mRootWindowContainer.getDisplayContent( persistableParams.mDisplayUniqueId); if (display != null) { - outParams.mPreferredDisplayId = display.mDisplayId; + // TODO(b/153764726): Investigate if task display area needs to be persisted vs + // always choosing the default one. + outParams.mPreferredTaskDisplayArea = display.getDefaultTaskDisplayArea(); } outParams.mWindowingMode = persistableParams.mWindowingMode; outParams.mBounds.set(persistableParams.mBounds); diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index e8f7ba550bd8..6b9054bde868 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -139,6 +139,7 @@ import android.view.Display; import android.view.DisplayInfo; import android.view.SurfaceControl; import android.view.WindowManager; +import android.window.WindowContainerToken; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.ResolverActivity; @@ -1519,8 +1520,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> if (taskDisplayArea == getDefaultTaskDisplayArea()) { homeIntent = mService.getHomeIntent(); aInfo = resolveHomeActivity(userId, homeIntent); - } else if (taskDisplayArea.getDisplayId() == DEFAULT_DISPLAY - || shouldPlaceSecondaryHomeOnDisplay(taskDisplayArea.getDisplayId())) { + } else if (shouldPlaceSecondaryHomeOnDisplayArea(taskDisplayArea)) { Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, taskDisplayArea); aInfo = info.first; homeIntent = info.second; @@ -1529,7 +1529,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> return false; } - if (!canStartHomeOnDisplay(aInfo, taskDisplayArea.getDisplayId(), allowInstrumenting)) { + if (!canStartHomeOnDisplayArea(aInfo, taskDisplayArea, allowInstrumenting)) { return false; } @@ -1625,8 +1625,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } if (aInfo != null) { - if (!canStartHomeOnDisplay(aInfo, taskDisplayArea.getDisplayId(), - false /* allowInstrumenting */)) { + if (!canStartHomeOnDisplayArea(aInfo, taskDisplayArea, false /* allowInstrumenting */)) { aInfo = null; } } @@ -1683,19 +1682,19 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } /** - * Check if the display is valid for secondary home activity. - * @param displayId The id of the target display. + * Check if the display area is valid for secondary home activity. + * @param taskDisplayArea The target display area. * @return {@code true} if allow to launch, {@code false} otherwise. */ - boolean shouldPlaceSecondaryHomeOnDisplay(int displayId) { - if (displayId == DEFAULT_DISPLAY) { + boolean shouldPlaceSecondaryHomeOnDisplayArea(TaskDisplayArea taskDisplayArea) { + if (getDefaultTaskDisplayArea() == taskDisplayArea) { throw new IllegalArgumentException( - "shouldPlaceSecondaryHomeOnDisplay: Should not be DEFAULT_DISPLAY"); - } else if (displayId == INVALID_DISPLAY) { + "shouldPlaceSecondaryHomeOnDisplay: Should not be on default task container"); + } else if (taskDisplayArea == null) { return false; } - if (!mService.mSupportsMultiDisplay) { + if (taskDisplayArea.getDisplayId() != DEFAULT_DISPLAY && !mService.mSupportsMultiDisplay) { // Can't launch home on secondary display if device does not support multi-display. return false; } @@ -1704,16 +1703,16 @@ class RootWindowContainer extends WindowContainer<DisplayContent> mService.mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0) != 0; if (!deviceProvisioned) { - // Can't launch home on secondary display before device is provisioned. + // Can't launch home on secondary display areas before device is provisioned. return false; } if (!StorageManager.isUserKeyUnlocked(mCurrentUser)) { - // Can't launch home on secondary displays if device is still locked. + // Can't launch home on secondary display areas if device is still locked. return false; } - final DisplayContent display = getDisplayContent(displayId); + final DisplayContent display = taskDisplayArea.getDisplayContent(); if (display == null || display.isRemoved() || !display.supportsSystemDecorations()) { // Can't launch home on display that doesn't support system decorations. return false; @@ -1725,11 +1724,11 @@ class RootWindowContainer extends WindowContainer<DisplayContent> /** * Check if home activity start should be allowed on a display. * @param homeInfo {@code ActivityInfo} of the home activity that is going to be launched. - * @param displayId The id of the target display. + * @param taskDisplayArea The target display area. * @param allowInstrumenting Whether launching home should be allowed if being instrumented. * @return {@code true} if allow to launch, {@code false} otherwise. */ - boolean canStartHomeOnDisplay(ActivityInfo homeInfo, int displayId, + boolean canStartHomeOnDisplayArea(ActivityInfo homeInfo, TaskDisplayArea taskDisplayArea, boolean allowInstrumenting) { if (mService.mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL && mService.mTopAction == null) { @@ -1745,13 +1744,15 @@ class RootWindowContainer extends WindowContainer<DisplayContent> return false; } + final int displayId = taskDisplayArea != null ? taskDisplayArea.getDisplayId() + : INVALID_DISPLAY; if (displayId == DEFAULT_DISPLAY || (displayId != INVALID_DISPLAY && displayId == mService.mVr2dDisplayId)) { // No restrictions to default display or vr 2d display. return true; } - if (!shouldPlaceSecondaryHomeOnDisplay(displayId)) { + if (!shouldPlaceSecondaryHomeOnDisplayArea(taskDisplayArea)) { return false; } @@ -2208,15 +2209,14 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } } - ActivityRecord findTask(ActivityRecord r, int preferredDisplayId) { + ActivityRecord findTask(ActivityRecord r, TaskDisplayArea preferredTaskDisplayArea) { if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r); mTmpFindTaskResult.clear(); - // Looking up task on preferred display first - final DisplayContent preferredDisplay = getDisplayContent(preferredDisplayId); - if (preferredDisplay != null) { - preferredDisplay.getDefaultTaskDisplayArea().findTaskLocked(r, - true /* isPreferredDisplay */, mTmpFindTaskResult); + // Looking up task on preferred display area first + if (preferredTaskDisplayArea != null) { + preferredTaskDisplayArea.findTaskLocked(r, true /* isPreferredDisplay */, + mTmpFindTaskResult); if (mTmpFindTaskResult.mIdealMatch) { return mTmpFindTaskResult.mRecord; } @@ -2224,14 +2224,17 @@ class RootWindowContainer extends WindowContainer<DisplayContent> for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { final DisplayContent display = getChildAt(displayNdx); - if (display.mDisplayId == preferredDisplayId) { - continue; - } + for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { + final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx); + if (taskDisplayArea == preferredTaskDisplayArea) { + continue; + } - display.getDefaultTaskDisplayArea().findTaskLocked(r, false /* isPreferredDisplay */, - mTmpFindTaskResult); - if (mTmpFindTaskResult.mIdealMatch) { - return mTmpFindTaskResult.mRecord; + taskDisplayArea.findTaskLocked(r, false /* isPreferredDisplay */, + mTmpFindTaskResult); + if (mTmpFindTaskResult.mIdealMatch) { + return mTmpFindTaskResult.mRecord; + } } } @@ -2823,11 +2826,15 @@ class RootWindowContainer extends WindowContainer<DisplayContent> int realCallingUid) { int taskId = INVALID_TASK_ID; int displayId = INVALID_DISPLAY; + TaskDisplayArea taskDisplayArea = null; // We give preference to the launch preference in activity options. if (options != null) { taskId = options.getLaunchTaskId(); displayId = options.getLaunchDisplayId(); + final WindowContainerToken daToken = options.getLaunchTaskDisplayArea(); + taskDisplayArea = daToken != null + ? (TaskDisplayArea) WindowContainer.fromBinder(daToken.asBinder()) : null; } // First preference for stack goes to the task Id set in the activity options. Use the stack @@ -2846,30 +2853,34 @@ class RootWindowContainer extends WindowContainer<DisplayContent> final int activityType = resolveActivityType(r, options, candidateTask); ActivityStack stack = null; - // Next preference for stack goes to the display Id set the candidate display. - if (launchParams != null && launchParams.mPreferredDisplayId != INVALID_DISPLAY) { - displayId = launchParams.mPreferredDisplayId; - } - final boolean canLaunchOnDisplayFromStartRequest = - realCallingPid != 0 && realCallingUid > 0 && r != null - && mStackSupervisor.canPlaceEntityOnDisplay(displayId, realCallingPid, - realCallingUid, r.info); - // Checking if the activity's launch caller, or the realCallerId of the activity from - // start request (i.e. entity that invokes PendingIntent) is allowed to launch on the - // display. - if (displayId != INVALID_DISPLAY && (canLaunchOnDisplay(r, displayId) - || canLaunchOnDisplayFromStartRequest)) { - if (r != null) { - stack = getValidLaunchStackOnDisplay(displayId, r, candidateTask, options, - launchParams); - if (stack != null) { - return stack; - } + // Next preference for stack goes to the taskDisplayArea candidate. + if (launchParams != null && launchParams.mPreferredTaskDisplayArea != null) { + taskDisplayArea = launchParams.mPreferredTaskDisplayArea; + } + + if (taskDisplayArea == null && displayId != INVALID_DISPLAY) { + final DisplayContent displayContent = getDisplayContent(displayId); + if (displayContent != null) { + taskDisplayArea = displayContent.getDefaultTaskDisplayArea(); } - final DisplayContent display = getDisplayContentOrCreate(displayId); - if (display != null) { + } + + if (taskDisplayArea != null) { + final int tdaDisplayId = taskDisplayArea.getDisplayId(); + final boolean canLaunchOnDisplayFromStartRequest = + realCallingPid != 0 && realCallingUid > 0 && r != null + && mStackSupervisor.canPlaceEntityOnDisplay(tdaDisplayId, + realCallingPid, realCallingUid, r.info); + if (canLaunchOnDisplayFromStartRequest || canLaunchOnDisplay(r, tdaDisplayId)) { + if (r != null) { + final ActivityStack result = getValidLaunchStackInTaskDisplayArea( + taskDisplayArea, r, candidateTask, options, launchParams); + if (result != null) { + return result; + } + } // Falling back to default task container - final TaskDisplayArea taskDisplayArea = display.getDefaultTaskDisplayArea(); + taskDisplayArea = taskDisplayArea.mDisplayContent.getDefaultTaskDisplayArea(); stack = taskDisplayArea.getOrCreateStack(r, options, candidateTask, activityType, onTop); if (stack != null) { @@ -2936,40 +2947,37 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } /** - * Get a topmost stack on the display, that is a valid launch stack for specified activity. + * Get a topmost stack on the display area, that is a valid launch stack for specified activity. * If there is no such stack, new dynamic stack can be created. - * @param displayId Target display. + * @param taskDisplayArea Target display area. * @param r Activity that should be launched there. * @param candidateTask The possible task the activity might be put in. * @return Existing stack if there is a valid one, new dynamic stack if it is valid or null. */ @VisibleForTesting - ActivityStack getValidLaunchStackOnDisplay(int displayId, @NonNull ActivityRecord r, - @Nullable Task candidateTask, @Nullable ActivityOptions options, + ActivityStack getValidLaunchStackInTaskDisplayArea(@NonNull TaskDisplayArea taskDisplayArea, + @NonNull ActivityRecord r, @Nullable Task candidateTask, + @Nullable ActivityOptions options, @Nullable LaunchParamsController.LaunchParams launchParams) { - final DisplayContent displayContent = getDisplayContentOrCreate(displayId); - if (displayContent == null) { - throw new IllegalArgumentException( - "Display with displayId=" + displayId + " not found."); - } - - if (!r.canBeLaunchedOnDisplay(displayId)) { + if (!r.canBeLaunchedOnDisplay(taskDisplayArea.getDisplayId())) { return null; } - // If {@code r} is already in target display and its task is the same as the candidate task, - // the intention should be getting a launch stack for the reusable activity, so we can use - // the existing stack. + // If {@code r} is already in target display area and its task is the same as the candidate + // task, the intention should be getting a launch stack for the reusable activity, so we can + // use the existing stack. if (candidateTask != null && (r.getTask() == null || r.getTask() == candidateTask)) { - final int attachedDisplayId = r.getDisplayId(); - if (attachedDisplayId == INVALID_DISPLAY || attachedDisplayId == displayId) { + // TODO(b/153920825): Fix incorrect evaluation of attached state + final TaskDisplayArea attachedTaskDisplayArea = r.getTask() != null + ? r.getTask().getDisplayArea() : r.getDisplayArea(); + if (attachedTaskDisplayArea == null || attachedTaskDisplayArea == taskDisplayArea) { return candidateTask.getStack(); } // Or the candidate task is already a root task that can be reused by reparenting // it to the target display. if (candidateTask.isRootTask()) { final ActivityStack stack = candidateTask.getStack(); - stack.reparent(displayContent.getDefaultTaskDisplayArea(), true /* onTop */); + stack.reparent(taskDisplayArea, true /* onTop */); return stack; } } @@ -2984,39 +2992,30 @@ class RootWindowContainer extends WindowContainer<DisplayContent> windowingMode = options != null ? options.getLaunchWindowingMode() : r.getWindowingMode(); } + windowingMode = taskDisplayArea.validateWindowingMode(windowingMode, r, candidateTask, + r.getActivityType()); // Return the topmost valid stack on the display. - for (int tdaNdx = displayContent.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { - final TaskDisplayArea taskDisplayArea = displayContent.getTaskDisplayAreaAt(tdaNdx); - final int validatedWindowingMode = taskDisplayArea - .validateWindowingMode(windowingMode, r, candidateTask, r.getActivityType()); - for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { - final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); - if (isValidLaunchStack(stack, r, validatedWindowingMode)) { - return stack; - } + for (int i = taskDisplayArea.getStackCount() - 1; i >= 0; --i) { + final ActivityStack stack = taskDisplayArea.getStackAt(i); + if (isValidLaunchStack(stack, r, windowingMode)) { + return stack; } } - // If there is no valid stack on the external display - check if new dynamic stack will do. - if (displayId != DEFAULT_DISPLAY) { + // If there is no valid stack on the secondary display area - check if new dynamic stack + // will do. + if (taskDisplayArea != getDisplayContent(taskDisplayArea.getDisplayId()) + .getDefaultTaskDisplayArea()) { final int activityType = options != null && options.getLaunchActivityType() != ACTIVITY_TYPE_UNDEFINED ? options.getLaunchActivityType() : r.getActivityType(); - final TaskDisplayArea taskDisplayArea = displayContent.getDefaultTaskDisplayArea(); return taskDisplayArea.createStack(windowingMode, activityType, true /*onTop*/); } return null; } - ActivityStack getValidLaunchStackOnDisplay(int displayId, @NonNull ActivityRecord r, - @Nullable ActivityOptions options, - @Nullable LaunchParamsController.LaunchParams launchParams) { - return getValidLaunchStackOnDisplay(displayId, r, null /* candidateTask */, options, - launchParams); - } - // TODO: Can probably be consolidated into getLaunchStack()... private boolean isValidLaunchStack(ActivityStack stack, ActivityRecord r, int windowingMode) { switch (stack.getActivityType()) { diff --git a/services/core/java/com/android/server/wm/SafeActivityOptions.java b/services/core/java/com/android/server/wm/SafeActivityOptions.java index a7b53688dbdc..b71ecbb8a72d 100644 --- a/services/core/java/com/android/server/wm/SafeActivityOptions.java +++ b/services/core/java/com/android/server/wm/SafeActivityOptions.java @@ -18,10 +18,11 @@ package com.android.server.wm; import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS; import static android.Manifest.permission.START_TASKS_FROM_RECENTS; +import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.content.pm.PackageManager.PERMISSION_DENIED; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.view.Display.INVALID_DISPLAY; -import static android.app.ActivityTaskManager.INVALID_TASK_ID; + import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM; import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME; @@ -36,6 +37,7 @@ import android.os.Process; import android.os.UserHandle; import android.util.Slog; import android.view.RemoteAnimationAdapter; +import android.window.WindowContainerToken; import com.android.internal.annotations.VisibleForTesting; @@ -206,8 +208,20 @@ public class SafeActivityOptions { throw new SecurityException(msg); } } - // Check if someone tries to launch an activity on a private display with a different - // owner. + // Check if the caller is allowed to launch on the specified display area. + final WindowContainerToken daToken = options.getLaunchTaskDisplayArea(); + final TaskDisplayArea taskDisplayArea = daToken != null + ? (TaskDisplayArea) WindowContainer.fromBinder(daToken.asBinder()) : null; + if (aInfo != null && taskDisplayArea != null + && !supervisor.isCallerAllowedToLaunchOnTaskDisplayArea(callingPid, callingUid, + taskDisplayArea, aInfo)) { + final String msg = "Permission Denial: starting " + getIntentString(intent) + + " from " + callerApp + " (pid=" + callingPid + + ", uid=" + callingUid + ") with launchTaskDisplayArea=" + taskDisplayArea; + Slog.w(TAG, msg); + throw new SecurityException(msg); + } + // Check if the caller is allowed to launch on the specified display. final int launchDisplayId = options.getLaunchDisplayId(); if (aInfo != null && launchDisplayId != INVALID_DISPLAY && !supervisor.isCallerAllowedToLaunchOnDisplay(callingPid, callingUid, diff --git a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java index da4401a68e7c..11c20b6d9133 100644 --- a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java +++ b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java @@ -48,6 +48,7 @@ import android.graphics.Rect; import android.util.Slog; import android.view.Gravity; import android.view.View; +import android.window.WindowContainerToken; import com.android.internal.annotations.VisibleForTesting; import com.android.server.wm.LaunchParamsController.LaunchParams; @@ -134,13 +135,15 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier { return RESULT_SKIP; } - // STEP 1: Determine the display to launch the activity/task. - final int displayId = getPreferredLaunchDisplay(task, options, source, currentParams); - outParams.mPreferredDisplayId = displayId; - DisplayContent display = mSupervisor.mRootWindowContainer.getDisplayContent(displayId); + // STEP 1: Determine the display area to launch the activity/task. + final TaskDisplayArea taskDisplayArea = getPreferredLaunchTaskDisplayArea(task, + options, source, currentParams); + outParams.mPreferredTaskDisplayArea = taskDisplayArea; + // TODO(b/152116619): Update the usages of display to use taskDisplayArea below. + final DisplayContent display = taskDisplayArea.mDisplayContent; if (DEBUG) { - appendLog("display-id=" + outParams.mPreferredDisplayId + " display-windowing-mode=" - + display.getWindowingMode()); + appendLog("task-display-area=" + outParams.mPreferredTaskDisplayArea + + " display-area-windowing-mode=" + taskDisplayArea.getWindowingMode()); } if (phase == PHASE_DISPLAY) { @@ -210,8 +213,8 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier { // layout and display conditions are not contradictory to their suggestions. It's important // to carry over their values because LaunchParamsController doesn't automatically do that. if (!currentParams.isEmpty() && !hasInitialBounds - && (!currentParams.hasPreferredDisplay() - || displayId == currentParams.mPreferredDisplayId)) { + && (currentParams.mPreferredTaskDisplayArea == null + || currentParams.mPreferredTaskDisplayArea == taskDisplayArea)) { // Only set windowing mode if display is in freeform. If the display is in fullscreen // mode we should only launch a task in fullscreen mode. if (currentParams.hasWindowingMode() && display.inFreeformWindowingMode()) { @@ -270,19 +273,19 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier { : display.getWindowingMode(); if (fullyResolvedCurrentParam) { if (resolvedMode == WINDOWING_MODE_FREEFORM) { - // Make sure bounds are in the display if it's possibly in a different display. - if (currentParams.mPreferredDisplayId != displayId) { + // Make sure bounds are in the display if it's possibly in a different display/area. + if (currentParams.mPreferredTaskDisplayArea != taskDisplayArea) { adjustBoundsToFitInDisplay(display, outParams.mBounds); } // Even though we want to keep original bounds, we still don't want it to stomp on // an existing task. adjustBoundsToAvoidConflictInDisplay(display, outParams.mBounds); } - } else if (display.inFreeformWindowingMode()) { + } else if (taskDisplayArea.inFreeformWindowingMode()) { if (source != null && source.inFreeformWindowingMode() && resolvedMode == WINDOWING_MODE_FREEFORM && outParams.mBounds.isEmpty() - && source.getDisplayId() == display.getDisplayId()) { + && source.getDisplayArea() == taskDisplayArea) { // Set bounds to be not very far from source activity. cascadeBounds(source.getConfiguration().windowConfiguration.getBounds(), display, outParams.mBounds); @@ -293,54 +296,87 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier { return RESULT_CONTINUE; } - private int getPreferredLaunchDisplay(@Nullable Task task, + private TaskDisplayArea getPreferredLaunchTaskDisplayArea(@Nullable Task task, @Nullable ActivityOptions options, ActivityRecord source, LaunchParams currentParams) { - if (!mSupervisor.mService.mSupportsMultiDisplay) { - return DEFAULT_DISPLAY; - } - - int displayId = INVALID_DISPLAY; - final int optionLaunchId = options != null ? options.getLaunchDisplayId() : INVALID_DISPLAY; - if (optionLaunchId != INVALID_DISPLAY) { - if (DEBUG) appendLog("display-from-option=" + optionLaunchId); - displayId = optionLaunchId; + TaskDisplayArea taskDisplayArea = null; + + final WindowContainerToken optionLaunchTaskDisplayAreaToken = options != null + ? options.getLaunchTaskDisplayArea() : null; + if (optionLaunchTaskDisplayAreaToken != null) { + taskDisplayArea = (TaskDisplayArea) WindowContainer.fromBinder( + optionLaunchTaskDisplayAreaToken.asBinder()); + if (DEBUG) appendLog("display-area-from-option=" + taskDisplayArea); + } + + // If task display area is not specified in options - try display id + if (taskDisplayArea == null) { + final int optionLaunchId = + options != null ? options.getLaunchDisplayId() : INVALID_DISPLAY; + if (optionLaunchId != INVALID_DISPLAY) { + final DisplayContent dc = mSupervisor.mRootWindowContainer + .getDisplayContent(optionLaunchId); + if (dc != null) { + taskDisplayArea = dc.getDefaultTaskDisplayArea(); + if (DEBUG) appendLog("display-from-option=" + optionLaunchId); + } + } } - // If the source activity is a no-display activity, pass on the launch display id from - // source activity as currently preferred. - if (displayId == INVALID_DISPLAY && source != null && source.noDisplay) { - displayId = source.mHandoverLaunchDisplayId; - if (DEBUG) appendLog("display-from-no-display-source=" + displayId); + // If the source activity is a no-display activity, pass on the launch display area token + // from source activity as currently preferred. + if (taskDisplayArea == null && source != null + && source.noDisplay) { + taskDisplayArea = source.mHandoverTaskDisplayArea; + if (taskDisplayArea != null) { + if (DEBUG) appendLog("display-area-from-no-display-source=" + taskDisplayArea); + } else { + // Try handover display id + final int displayId = source.mHandoverLaunchDisplayId; + final DisplayContent dc = + mSupervisor.mRootWindowContainer.getDisplayContent(displayId); + if (dc != null) { + taskDisplayArea = dc.getDefaultTaskDisplayArea(); + if (DEBUG) appendLog("display-from-no-display-source=" + displayId); + } + } } - ActivityStack stack = - (displayId == INVALID_DISPLAY && task != null) ? task.getStack() : null; + ActivityStack stack = (taskDisplayArea == null && task != null) + ? task.getStack() : null; if (stack != null) { if (DEBUG) appendLog("display-from-task=" + stack.getDisplayId()); - displayId = stack.getDisplayId(); + taskDisplayArea = stack.getDisplayArea(); } - if (displayId == INVALID_DISPLAY && source != null) { - final int sourceDisplayId = source.getDisplayId(); - if (DEBUG) appendLog("display-from-source=" + sourceDisplayId); - displayId = sourceDisplayId; + if (taskDisplayArea == null && source != null) { + final TaskDisplayArea sourceDisplayArea = source.getDisplayArea(); + if (DEBUG) appendLog("display-area-from-source=" + sourceDisplayArea); + taskDisplayArea = sourceDisplayArea; } - if (displayId == INVALID_DISPLAY && options != null) { + if (taskDisplayArea == null && options != null) { final int callerDisplayId = options.getCallerDisplayId(); - if (DEBUG) appendLog("display-from-caller=" + callerDisplayId); - displayId = callerDisplayId; + final DisplayContent dc = + mSupervisor.mRootWindowContainer.getDisplayContent(callerDisplayId); + if (dc != null) { + taskDisplayArea = dc.getDefaultTaskDisplayArea(); + if (DEBUG) appendLog("display-from-caller=" + callerDisplayId); + } + } + + if (taskDisplayArea == null) { + taskDisplayArea = currentParams.mPreferredTaskDisplayArea; } - if (displayId != INVALID_DISPLAY - && mSupervisor.mRootWindowContainer.getDisplayContent(displayId) == null) { - displayId = currentParams.mPreferredDisplayId; + // Fallback to default display if the device didn't declare support for multi-display + if (taskDisplayArea != null && !mSupervisor.mService.mSupportsMultiDisplay + && taskDisplayArea.getDisplayId() != DEFAULT_DISPLAY) { + taskDisplayArea = mSupervisor.mRootWindowContainer.getDefaultTaskDisplayArea(); } - displayId = (displayId == INVALID_DISPLAY) ? currentParams.mPreferredDisplayId : displayId; - return (displayId != INVALID_DISPLAY - && mSupervisor.mRootWindowContainer.getDisplayContent(displayId) != null) - ? displayId : DEFAULT_DISPLAY; + return (taskDisplayArea != null) + ? taskDisplayArea + : mSupervisor.mRootWindowContainer.getDefaultTaskDisplayArea(); } private boolean canInheritWindowingModeFromSource(@NonNull DisplayContent display, diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java index 97734ff32de2..a84a0a2260b2 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java @@ -426,7 +426,7 @@ public class ActivityStarterTests extends ActivityTestsBase { // Start activity and delivered new intent. starter.getIntent().setComponent(splitSecondReusableActivity.mActivityComponent); - doReturn(splitSecondReusableActivity).when(mRootWindowContainer).findTask(any(), anyInt()); + doReturn(splitSecondReusableActivity).when(mRootWindowContainer).findTask(any(), any()); final int result = starter.setReason("testSplitScreenDeliverToTop").execute(); // Ensure result is delivering intent to top. @@ -462,7 +462,7 @@ public class ActivityStarterTests extends ActivityTestsBase { // Start activity and delivered new intent. starter.getIntent().setComponent(splitSecondReusableActivity.mActivityComponent); - doReturn(splitSecondReusableActivity).when(mRootWindowContainer).findTask(any(), anyInt()); + doReturn(splitSecondReusableActivity).when(mRootWindowContainer).findTask(any(), any()); final int result = starter.setReason("testSplitScreenMoveToFront").execute(); // Ensure result is moving task to front. diff --git a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java index 8a9504dd11b5..61de7d83fa1a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java @@ -19,7 +19,6 @@ package com.android.server.wm; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; -import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; import static com.android.dx.mockito.inline.extended.ExtendedMockito.any; @@ -112,7 +111,7 @@ public class LaunchParamsControllerTests extends ActivityTestsBase { final ActivityRecord activity = new ActivityBuilder(mService).setComponent(name) .setUid(userId).build(); final LaunchParams expected = new LaunchParams(); - expected.mPreferredDisplayId = 3; + expected.mPreferredTaskDisplayArea = mock(TaskDisplayArea.class); expected.mWindowingMode = WINDOWING_MODE_PINNED; expected.mBounds.set(200, 300, 400, 500); @@ -183,7 +182,7 @@ public class LaunchParamsControllerTests extends ActivityTestsBase { final LaunchParams params = new LaunchParams(); params.mWindowingMode = WINDOWING_MODE_FREEFORM; params.mBounds.set(0, 0, 30, 20); - params.mPreferredDisplayId = 3; + params.mPreferredTaskDisplayArea = mock(TaskDisplayArea.class); final InstrumentedPositioner positioner2 = new InstrumentedPositioner(RESULT_CONTINUE, params); @@ -228,8 +227,8 @@ public class LaunchParamsControllerTests extends ActivityTestsBase { */ @Test public void testVrPreferredDisplay() { - final int vr2dDisplayId = 1; - mService.mVr2dDisplayId = vr2dDisplayId; + final TestDisplayContent vrDisplay = createNewDisplayContent(); + mService.mVr2dDisplayId = vrDisplay.mDisplayId; final LaunchParams result = new LaunchParams(); final ActivityRecord vrActivity = new ActivityBuilder(mService).build(); @@ -238,16 +237,17 @@ public class LaunchParamsControllerTests extends ActivityTestsBase { // VR activities should always land on default display. mController.calculate(null /*task*/, null /*layout*/, vrActivity /*activity*/, null /*source*/, null /*options*/, PHASE_BOUNDS, result); - assertEquals(DEFAULT_DISPLAY, result.mPreferredDisplayId); + assertEquals(mRootWindowContainer.getDefaultTaskDisplayArea(), + result.mPreferredTaskDisplayArea); // Otherwise, always lands on VR 2D display. final ActivityRecord vr2dActivity = new ActivityBuilder(mService).build(); mController.calculate(null /*task*/, null /*layout*/, vr2dActivity /*activity*/, null /*source*/, null /*options*/, PHASE_BOUNDS, result); - assertEquals(vr2dDisplayId, result.mPreferredDisplayId); + assertEquals(vrDisplay.getDefaultTaskDisplayArea(), result.mPreferredTaskDisplayArea); mController.calculate(null /*task*/, null /*layout*/, null /*activity*/, null /*source*/, null /*options*/, PHASE_BOUNDS, result); - assertEquals(vr2dDisplayId, result.mPreferredDisplayId); + assertEquals(vrDisplay.getDefaultTaskDisplayArea(), result.mPreferredTaskDisplayArea); mService.mVr2dDisplayId = INVALID_DISPLAY; } @@ -282,9 +282,7 @@ public class LaunchParamsControllerTests extends ActivityTestsBase { final LaunchParams params = new LaunchParams(); final TestDisplayContent display = createNewDisplayContent(); final TaskDisplayArea preferredTaskDisplayArea = display.getDefaultTaskDisplayArea(); - // TODO(b/152116619): Enable after complete switch to WindowContainerToken - //params.mPreferredWindowContainerToken = preferredTaskDisplayAreaToken; - params.mPreferredDisplayId = display.mDisplayId; + params.mPreferredTaskDisplayArea = preferredTaskDisplayArea; final InstrumentedPositioner positioner = new InstrumentedPositioner(RESULT_DONE, params); final Task task = new TaskBuilder(mService.mStackSupervisor).build(); @@ -433,7 +431,7 @@ public class LaunchParamsControllerTests extends ActivityTestsBase { void saveTask(Task task, DisplayContent display) { final int userId = task.mUserId; final ComponentName realActivity = task.realActivity; - mTmpParams.mPreferredDisplayId = task.getDisplayId(); + mTmpParams.mPreferredTaskDisplayArea = task.getDisplayArea(); mTmpParams.mWindowingMode = task.getWindowingMode(); if (task.mLastNonFullscreenBounds != null) { mTmpParams.mBounds.set(task.mLastNonFullscreenBounds); diff --git a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java index 6a71a7dd24dd..9bf86d2c4704 100644 --- a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java @@ -19,7 +19,6 @@ package com.android.server.wm; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; -import static android.view.Display.INVALID_DISPLAY; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; @@ -27,6 +26,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Matchers.any; @@ -163,7 +163,7 @@ public class LaunchParamsPersisterTests extends ActivityTestsBase { mTarget.getLaunchParams(mTestTask, null, mResult); - assertEquals(mTestDisplay.mDisplayId, mResult.mPreferredDisplayId); + assertEquals(mTestDisplay.getDefaultTaskDisplayArea(), mResult.mPreferredTaskDisplayArea); assertEquals(TEST_WINDOWING_MODE, mResult.mWindowingMode); assertEquals(TEST_BOUNDS, mResult.mBounds); } @@ -177,7 +177,7 @@ public class LaunchParamsPersisterTests extends ActivityTestsBase { mTarget.getLaunchParams(null, activity, mResult); - assertEquals(mTestDisplay.mDisplayId, mResult.mPreferredDisplayId); + assertEquals(mTestDisplay.getDefaultTaskDisplayArea(), mResult.mPreferredTaskDisplayArea); assertEquals(TEST_WINDOWING_MODE, mResult.mWindowingMode); assertEquals(TEST_BOUNDS, mResult.mBounds); } @@ -190,7 +190,7 @@ public class LaunchParamsPersisterTests extends ActivityTestsBase { mTarget.getLaunchParams(mTestTask, null, mResult); - assertEquals(INVALID_DISPLAY, mResult.mPreferredDisplayId); + assertNull(mResult.mPreferredTaskDisplayArea); assertEquals(TEST_WINDOWING_MODE, mResult.mWindowingMode); assertEquals(TEST_BOUNDS, mResult.mBounds); } @@ -223,7 +223,7 @@ public class LaunchParamsPersisterTests extends ActivityTestsBase { mTaskWithDifferentComponent.mWindowLayoutAffinity = TEST_WINDOW_LAYOUT_AFFINITY; mTarget.getLaunchParams(mTaskWithDifferentComponent, null, mResult); - assertEquals(mTestDisplay.mDisplayId, mResult.mPreferredDisplayId); + assertEquals(mTestDisplay.getDefaultTaskDisplayArea(), mResult.mPreferredTaskDisplayArea); assertEquals(TEST_WINDOWING_MODE, mResult.mWindowingMode); assertEquals(TEST_BOUNDS, mResult.mBounds); } @@ -241,7 +241,7 @@ public class LaunchParamsPersisterTests extends ActivityTestsBase { mTarget.getLaunchParams(mTaskWithDifferentComponent, null, mResult); - assertEquals(mTestDisplay.mDisplayId, mResult.mPreferredDisplayId); + assertEquals(mTestDisplay.getDefaultTaskDisplayArea(), mResult.mPreferredTaskDisplayArea); assertEquals(TEST_WINDOWING_MODE, mResult.mWindowingMode); assertEquals(TEST_BOUNDS, mResult.mBounds); } @@ -282,7 +282,7 @@ public class LaunchParamsPersisterTests extends ActivityTestsBase { target.getLaunchParams(mTestTask, null, mResult); - assertEquals(mTestDisplay.mDisplayId, mResult.mPreferredDisplayId); + assertEquals(mTestDisplay.getDefaultTaskDisplayArea(), mResult.mPreferredTaskDisplayArea); assertEquals(TEST_WINDOWING_MODE, mResult.mWindowingMode); assertEquals(TEST_BOUNDS, mResult.mBounds); } @@ -301,7 +301,7 @@ public class LaunchParamsPersisterTests extends ActivityTestsBase { mTaskWithDifferentComponent.mWindowLayoutAffinity = TEST_WINDOW_LAYOUT_AFFINITY; target.getLaunchParams(mTaskWithDifferentComponent, null, mResult); - assertEquals(mTestDisplay.mDisplayId, mResult.mPreferredDisplayId); + assertEquals(mTestDisplay.getDefaultTaskDisplayArea(), mResult.mPreferredTaskDisplayArea); assertEquals(TEST_WINDOWING_MODE, mResult.mWindowingMode); assertEquals(TEST_BOUNDS, mResult.mBounds); } @@ -328,7 +328,7 @@ public class LaunchParamsPersisterTests extends ActivityTestsBase { target.getLaunchParams(mTaskWithDifferentComponent, null, mResult); - assertEquals(mTestDisplay.mDisplayId, mResult.mPreferredDisplayId); + assertEquals(mTestDisplay.getDefaultTaskDisplayArea(), mResult.mPreferredTaskDisplayArea); assertEquals(TEST_WINDOWING_MODE, mResult.mWindowingMode); assertEquals(TEST_BOUNDS, mResult.mBounds); } diff --git a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java index 3c9051547eed..5dba00455913 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java @@ -537,8 +537,8 @@ public class RootActivityContainerTests extends ActivityTestsBase { doReturn(true).when(mRootWindowContainer) .ensureVisibilityAndConfig(any(), anyInt(), anyBoolean(), anyBoolean()); - doReturn(true).when(mRootWindowContainer).canStartHomeOnDisplay( - any(), anyInt(), anyBoolean()); + doReturn(true).when(mRootWindowContainer).canStartHomeOnDisplayArea(any(), any(), + anyBoolean()); mRootWindowContainer.startHomeOnAllDisplays(0, "testStartHome"); @@ -578,17 +578,19 @@ public class RootActivityContainerTests extends ActivityTestsBase { // Can not start home if we don't want to start home while home is being instrumented. doReturn(true).when(app).isInstrumenting(); - assertFalse(mRootWindowContainer.canStartHomeOnDisplay(info, DEFAULT_DISPLAY, + final TaskDisplayArea defaultTaskDisplayArea = mRootWindowContainer + .getDefaultTaskDisplayArea(); + assertFalse(mRootWindowContainer.canStartHomeOnDisplayArea(info, defaultTaskDisplayArea, false /* allowInstrumenting*/)); // Can start home for other cases. - assertTrue(mRootWindowContainer.canStartHomeOnDisplay(info, DEFAULT_DISPLAY, + assertTrue(mRootWindowContainer.canStartHomeOnDisplayArea(info, defaultTaskDisplayArea, true /* allowInstrumenting*/)); doReturn(false).when(app).isInstrumenting(); - assertTrue(mRootWindowContainer.canStartHomeOnDisplay(info, DEFAULT_DISPLAY, + assertTrue(mRootWindowContainer.canStartHomeOnDisplayArea(info, defaultTaskDisplayArea, false /* allowInstrumenting*/)); - assertTrue(mRootWindowContainer.canStartHomeOnDisplay(info, DEFAULT_DISPLAY, + assertTrue(mRootWindowContainer.canStartHomeOnDisplayArea(info, defaultTaskDisplayArea, true /* allowInstrumenting*/)); } @@ -694,8 +696,8 @@ public class RootActivityContainerTests extends ActivityTestsBase { resolutions.add(resolveInfo); doReturn(resolutions).when(mRootWindowContainer).resolveActivities(anyInt(), refEq(secondaryHomeIntent)); - doReturn(true).when(mRootWindowContainer).canStartHomeOnDisplay( - any(), anyInt(), anyBoolean()); + doReturn(true).when(mRootWindowContainer).canStartHomeOnDisplayArea(any(), any(), + anyBoolean()); // Run the test. final Pair<ActivityInfo, Intent> resolvedInfo = mRootWindowContainer @@ -747,8 +749,8 @@ public class RootActivityContainerTests extends ActivityTestsBase { resolutions.add(infoFake2); doReturn(resolutions).when(mRootWindowContainer).resolveActivities(anyInt(), any()); - doReturn(true).when(mRootWindowContainer).canStartHomeOnDisplay( - any(), anyInt(), anyBoolean()); + doReturn(true).when(mRootWindowContainer).canStartHomeOnDisplayArea(any(), any(), + anyBoolean()); // Run the test. final Pair<ActivityInfo, Intent> resolvedInfo = mRootWindowContainer @@ -781,8 +783,8 @@ public class RootActivityContainerTests extends ActivityTestsBase { resolutions.add(infoFake2); doReturn(resolutions).when(mRootWindowContainer).resolveActivities(anyInt(), any()); - doReturn(true).when(mRootWindowContainer).canStartHomeOnDisplay( - any(), anyInt(), anyBoolean()); + doReturn(true).when(mRootWindowContainer).canStartHomeOnDisplayArea(any(), any(), + anyBoolean()); // Use the first one of matched activities in the same package as selected primary home. final Pair<ActivityInfo, Intent> resolvedInfo = mRootWindowContainer @@ -836,8 +838,9 @@ public class RootActivityContainerTests extends ActivityTestsBase { .setTask(task).build(); // Make sure the root task is valid and can be reused on default display. - final ActivityStack stack = mRootWindowContainer.getValidLaunchStackOnDisplay( - DEFAULT_DISPLAY, activity, task, null, null); + final ActivityStack stack = mRootWindowContainer.getValidLaunchStackInTaskDisplayArea( + mRootWindowContainer.getDefaultTaskDisplayArea(), activity, task, null, + null); assertEquals(task, stack); } diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java index 1a38ff283477..a69231b9e03a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java @@ -30,6 +30,7 @@ import static android.util.DisplayMetrics.DENSITY_DEFAULT; import static android.view.Display.DEFAULT_DISPLAY; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE; import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_SKIP; @@ -44,7 +45,6 @@ import android.content.res.Configuration; import android.graphics.Rect; import android.os.Build; import android.platform.test.annotations.Presubmit; -import android.view.Display; import android.view.Gravity; import androidx.test.filters.SmallTest; @@ -106,53 +106,45 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { // Display ID Related Tests // ============================= @Test - public void testDefaultToPrimaryDisplay() { + public void testDefaultToPrimaryDisplayArea() { createNewDisplayContent(WINDOWING_MODE_FREEFORM); assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null, mActivity, /* source */ null, /* options */ null, mCurrent, mResult)); - assertEquals(DEFAULT_DISPLAY, mResult.mPreferredDisplayId); + assertEquals(mRootWindowContainer.getDefaultTaskDisplayArea(), + mResult.mPreferredTaskDisplayArea); } @Test - public void testUsesDefaultDisplayIfPreviousDisplayNotExists() { - mCurrent.mPreferredDisplayId = 19; - - assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null, - mActivity, /* source */ null, /* options */ null, mCurrent, mResult)); - - assertEquals(DEFAULT_DISPLAY, mResult.mPreferredDisplayId); - } - - @Test - public void testUsesPreviousDisplayIdIfSet() { + public void testUsesPreviousDisplayAreaIfSet() { createNewDisplayContent(WINDOWING_MODE_FREEFORM); final TestDisplayContent display = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN); - mCurrent.mPreferredDisplayId = display.mDisplayId; + mCurrent.mPreferredTaskDisplayArea = display.getDefaultTaskDisplayArea(); assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null, mActivity, /* source */ null, /* options */ null, mCurrent, mResult)); - assertEquals(display.mDisplayId, mResult.mPreferredDisplayId); + assertEquals(display.getDefaultTaskDisplayArea(), mResult.mPreferredTaskDisplayArea); } @Test - public void testUsesSourcesDisplayIdIfSet() { + public void testUsesSourcesDisplayAreaIfSet() { final TestDisplayContent freeformDisplay = createNewDisplayContent( WINDOWING_MODE_FREEFORM); final TestDisplayContent fullscreenDisplay = createNewDisplayContent( WINDOWING_MODE_FULLSCREEN); - mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId; + mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); ActivityRecord source = createSourceActivity(fullscreenDisplay); assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null, mActivity, source, /* options */ null, mCurrent, mResult)); - assertEquals(fullscreenDisplay.mDisplayId, mResult.mPreferredDisplayId); + assertEquals(fullscreenDisplay.getDefaultTaskDisplayArea(), + mResult.mPreferredTaskDisplayArea); } @Test @@ -162,7 +154,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { final TestDisplayContent fullscreenDisplay = createNewDisplayContent( WINDOWING_MODE_FULLSCREEN); - mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId; + mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); ActivityRecord source = createSourceActivity(freeformDisplay); ActivityOptions options = ActivityOptions.makeBasic(); @@ -171,28 +163,51 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null, mActivity, source, options, mCurrent, mResult)); - assertEquals(fullscreenDisplay.mDisplayId, mResult.mPreferredDisplayId); + assertEquals(fullscreenDisplay.getDefaultTaskDisplayArea(), + mResult.mPreferredTaskDisplayArea); } @Test - public void testUsesTasksDisplayIdPriorToSourceIfSet() { + public void testUsesOptionsDisplayAreaTokenIfSet() { final TestDisplayContent freeformDisplay = createNewDisplayContent( WINDOWING_MODE_FREEFORM); final TestDisplayContent fullscreenDisplay = createNewDisplayContent( WINDOWING_MODE_FULLSCREEN); - mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId; + mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); + ActivityRecord source = createSourceActivity(freeformDisplay); + + ActivityOptions options = ActivityOptions.makeBasic(); + options.setLaunchTaskDisplayArea(fullscreenDisplay.getDefaultTaskDisplayArea() + .mRemoteToken.toWindowContainerToken()); + + assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null, + mActivity, source, options, mCurrent, mResult)); + + assertEquals(fullscreenDisplay.getDefaultTaskDisplayArea(), + mResult.mPreferredTaskDisplayArea); + } + + @Test + public void testUsesTasksDisplayAreaIdPriorToSourceIfSet() { + final TestDisplayContent freeformDisplay = createNewDisplayContent( + WINDOWING_MODE_FREEFORM); + final TestDisplayContent fullscreenDisplay = createNewDisplayContent( + WINDOWING_MODE_FULLSCREEN); + + mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); ActivityRecord reusableActivity = createSourceActivity(fullscreenDisplay); ActivityRecord source = createSourceActivity(freeformDisplay); assertEquals(RESULT_CONTINUE, mTarget.onCalculate(reusableActivity.getTask(), /* layout */ null, mActivity, source, /* options */ null, mCurrent, mResult)); - assertEquals(fullscreenDisplay.mDisplayId, mResult.mPreferredDisplayId); + assertEquals(fullscreenDisplay.getDefaultTaskDisplayArea(), + mResult.mPreferredTaskDisplayArea); } @Test - public void testUsesTaskDisplayIdIfSet() { + public void testUsesTaskDisplayAreaIdIfSet() { final TestDisplayContent freeformDisplay = createNewDisplayContent( WINDOWING_MODE_FREEFORM); ActivityRecord source = createSourceActivity(freeformDisplay); @@ -200,7 +215,8 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { assertEquals(RESULT_CONTINUE, mTarget.onCalculate(source.getTask(), null /* layout */, null /* activity */, null /* source */, null /* options */, mCurrent, mResult)); - assertEquals(freeformDisplay.mDisplayId, mResult.mPreferredDisplayId); + assertEquals(freeformDisplay.getDefaultTaskDisplayArea(), + mResult.mPreferredTaskDisplayArea); } @Test @@ -210,7 +226,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { final TestDisplayContent fullscreenDisplay = createNewDisplayContent( WINDOWING_MODE_FULLSCREEN); - mCurrent.mPreferredDisplayId = fullscreenDisplay.mDisplayId; + mCurrent.mPreferredTaskDisplayArea = fullscreenDisplay.getDefaultTaskDisplayArea(); ActivityRecord reusableActivity = createSourceActivity(fullscreenDisplay); ActivityRecord source = createSourceActivity(freeformDisplay); source.mHandoverLaunchDisplayId = freeformDisplay.mDisplayId; @@ -219,7 +235,28 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { assertEquals(RESULT_CONTINUE, mTarget.onCalculate(reusableActivity.getTask(), null /* layout */, mActivity, source, null /* options */, mCurrent, mResult)); - assertEquals(freeformDisplay.mDisplayId, mResult.mPreferredDisplayId); + assertEquals(freeformDisplay.getDefaultTaskDisplayArea(), + mResult.mPreferredTaskDisplayArea); + } + + @Test + public void testUsesNoDisplaySourceHandoverDisplayAreaIdIfSet() { + final TestDisplayContent freeformDisplay = createNewDisplayContent( + WINDOWING_MODE_FREEFORM); + final TestDisplayContent fullscreenDisplay = createNewDisplayContent( + WINDOWING_MODE_FULLSCREEN); + + mCurrent.mPreferredTaskDisplayArea = fullscreenDisplay.getDefaultTaskDisplayArea(); + ActivityRecord reusableActivity = createSourceActivity(fullscreenDisplay); + ActivityRecord source = createSourceActivity(freeformDisplay); + source.mHandoverTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); + source.noDisplay = true; + + assertEquals(RESULT_CONTINUE, mTarget.onCalculate(reusableActivity.getTask(), + null /* layout */, mActivity, source, null /* options */, mCurrent, mResult)); + + assertEquals(freeformDisplay.getDefaultTaskDisplayArea(), + mResult.mPreferredTaskDisplayArea); } // ===================================== @@ -233,7 +270,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { final ActivityOptions options = ActivityOptions.makeBasic(); options.setLaunchBounds(new Rect(0, 0, 100, 100)); - mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId; + mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null, mActivity, /* source */ null, options, mCurrent, mResult)); @@ -247,7 +284,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { final ActivityOptions options = ActivityOptions.makeBasic(); options.setLaunchBounds(new Rect(0, 0, 100, 100)); - mCurrent.mPreferredDisplayId = DEFAULT_DISPLAY; + mCurrent.mPreferredTaskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea(); assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null, mActivity, /* source */ null, options, mCurrent, mResult)); @@ -278,7 +315,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { final ActivityOptions options = ActivityOptions.makeBasic(); options.setLaunchWindowingMode(WINDOWING_MODE_PINNED); - mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId; + mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null, mActivity, /* source */ null, options, mCurrent, mResult)); @@ -296,7 +333,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { options.setLaunchWindowingMode(WINDOWING_MODE_PINNED); options.setLaunchBounds(new Rect(0, 0, 100, 100)); - mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId; + mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null, mActivity, /* source */ null, options, mCurrent, mResult)); @@ -310,7 +347,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { final ActivityOptions options = ActivityOptions.makeBasic(); options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN); - mCurrent.mPreferredDisplayId = DEFAULT_DISPLAY; + mCurrent.mPreferredTaskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea(); assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null, mActivity, /* source */ null, options, mCurrent, mResult)); @@ -324,7 +361,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { final TestDisplayContent freeformDisplay = createNewDisplayContent( WINDOWING_MODE_FREEFORM); - mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId; + mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() .setWidth(120).setHeight(80).build(); @@ -341,7 +378,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { final TestDisplayContent freeformDisplay = createNewDisplayContent( WINDOWING_MODE_FREEFORM); - mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId; + mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() .setGravity(Gravity.LEFT).build(); @@ -358,7 +395,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() .setWidth(120).setHeight(80).build(); - mCurrent.mPreferredDisplayId = DEFAULT_DISPLAY; + mCurrent.mPreferredTaskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea(); assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity, /* source */ null, /* options */ null, mCurrent, mResult)); @@ -369,7 +406,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { @Test public void testLaunchesFullscreenOnFullscreenDisplayWithFreeformHistory() { - mCurrent.mPreferredDisplayId = Display.INVALID_DISPLAY; + mCurrent.mPreferredTaskDisplayArea = null; mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM; mCurrent.mBounds.set(0, 0, 200, 100); @@ -385,7 +422,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { final TestDisplayContent freeformDisplay = createNewDisplayContent( WINDOWING_MODE_FREEFORM); - mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId; + mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); mCurrent.mWindowingMode = WINDOWING_MODE_FULLSCREEN; assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null, @@ -400,7 +437,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { final TestDisplayContent freeformDisplay = createNewDisplayContent( WINDOWING_MODE_FREEFORM); - mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId; + mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM; mCurrent.mBounds.set(0, 0, 200, 100); @@ -421,7 +458,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { options.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM); options.setLaunchBounds(new Rect(0, 0, 200, 100)); - mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId; + mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM; mCurrent.mBounds.set(0, 0, 200, 100); @@ -446,7 +483,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { options.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM); options.setLaunchBounds(expectedLaunchBounds); - mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId; + mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM; mCurrent.mBounds.set(expectedLaunchBounds); @@ -467,7 +504,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { options.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM); options.setLaunchBounds(new Rect(0, 0, 200, 100)); - mCurrent.mPreferredDisplayId = DEFAULT_DISPLAY; + mCurrent.mPreferredTaskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea(); mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM; mCurrent.mBounds.set(0, 0, 200, 100); @@ -568,7 +605,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { final Rect expected = new Rect(0, 0, 100, 100); options.setLaunchBounds(expected); - mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId; + mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null, mActivity, /* source */ null, options, mCurrent, mResult)); @@ -598,7 +635,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { final TestDisplayContent freeformDisplay = createNewDisplayContent( WINDOWING_MODE_FREEFORM); - mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId; + mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() .setGravity(Gravity.LEFT).build(); @@ -614,7 +651,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { final TestDisplayContent freeformDisplay = createNewDisplayContent( WINDOWING_MODE_FREEFORM); - mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId; + mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() .setGravity(Gravity.TOP).build(); @@ -630,7 +667,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { final TestDisplayContent freeformDisplay = createNewDisplayContent( WINDOWING_MODE_FREEFORM); - mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId; + mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() .setGravity(Gravity.TOP | Gravity.LEFT).build(); @@ -647,7 +684,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { final TestDisplayContent freeformDisplay = createNewDisplayContent( WINDOWING_MODE_FREEFORM); - mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId; + mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() .setGravity(Gravity.RIGHT).build(); @@ -663,7 +700,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { final TestDisplayContent freeformDisplay = createNewDisplayContent( WINDOWING_MODE_FREEFORM); - mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId; + mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() .setGravity(Gravity.BOTTOM).build(); @@ -679,7 +716,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { final TestDisplayContent freeformDisplay = createNewDisplayContent( WINDOWING_MODE_FREEFORM); - mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId; + mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() .setGravity(Gravity.BOTTOM | Gravity.RIGHT).build(); @@ -696,7 +733,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { final TestDisplayContent freeformDisplay = createNewDisplayContent( WINDOWING_MODE_FREEFORM); - mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId; + mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() .setWidth(120).setHeight(80).build(); @@ -712,7 +749,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { final TestDisplayContent freeformDisplay = createNewDisplayContent( WINDOWING_MODE_FREEFORM); - mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId; + mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() .setWidth(120).setHeight(80).setGravity(Gravity.LEFT).build(); @@ -728,7 +765,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { final TestDisplayContent freeformDisplay = createNewDisplayContent( WINDOWING_MODE_FREEFORM); - mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId; + mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() .setWidth(120).setHeight(80).setGravity(Gravity.TOP).build(); @@ -744,7 +781,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { final TestDisplayContent freeformDisplay = createNewDisplayContent( WINDOWING_MODE_FREEFORM); - mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId; + mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() .setWidth(120).setHeight(80).setGravity(Gravity.TOP | Gravity.LEFT).build(); @@ -760,7 +797,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { final TestDisplayContent freeformDisplay = createNewDisplayContent( WINDOWING_MODE_FREEFORM); - mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId; + mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() .setWidth(120).setHeight(80).setGravity(Gravity.RIGHT).build(); @@ -776,7 +813,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { final TestDisplayContent freeformDisplay = createNewDisplayContent( WINDOWING_MODE_FREEFORM); - mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId; + mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() .setWidth(120).setHeight(80).setGravity(Gravity.BOTTOM).build(); @@ -792,7 +829,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { final TestDisplayContent freeformDisplay = createNewDisplayContent( WINDOWING_MODE_FREEFORM); - mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId; + mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() .setWidth(120).setHeight(80).setGravity(Gravity.BOTTOM | Gravity.RIGHT).build(); @@ -808,7 +845,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { final TestDisplayContent freeformDisplay = createNewDisplayContent( WINDOWING_MODE_FREEFORM); - mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId; + mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() .setWidthFraction(0.125f).setHeightFraction(0.1f).build(); @@ -824,7 +861,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { final TestDisplayContent freeformDisplay = createNewDisplayContent( WINDOWING_MODE_FREEFORM); - mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId; + mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM; mCurrent.mBounds.set(0, 0, 200, 100); @@ -839,7 +876,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { final TestDisplayContent freeformDisplay = createNewDisplayContent( WINDOWING_MODE_FREEFORM); - mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId; + mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); mCurrent.mWindowingMode = WINDOWING_MODE_FULLSCREEN; mCurrent.mBounds.set(0, 0, 200, 100); @@ -1217,7 +1254,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { @Test public void returnsNonFullscreenBoundsOnFullscreenDisplayWithFreeformHistory() { - mCurrent.mPreferredDisplayId = Display.INVALID_DISPLAY; + mCurrent.mPreferredTaskDisplayArea = null; mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM; mCurrent.mBounds.set(0, 0, 200, 100); @@ -1233,7 +1270,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { final TestDisplayContent freeformDisplay = createNewDisplayContent( WINDOWING_MODE_FREEFORM); - mCurrent.mPreferredDisplayId = Display.INVALID_DISPLAY; + mCurrent.mPreferredTaskDisplayArea = null; mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM; mCurrent.mBounds.set(-100, -200, 200, 100); @@ -1253,7 +1290,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { addFreeformTaskTo(freeformDisplay, new Rect(0, 0, 200, 100)); - mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId; + mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM; mCurrent.mBounds.set(0, 0, 200, 100); @@ -1284,13 +1321,14 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { public void testNoMultiDisplaySupports() { final boolean orgValue = mService.mSupportsMultiDisplay; final TestDisplayContent display = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN); - mCurrent.mPreferredDisplayId = display.mDisplayId; + mCurrent.mPreferredTaskDisplayArea = display.getDefaultTaskDisplayArea(); try { mService.mSupportsMultiDisplay = false; assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null, mActivity, /* source */ null, /* options */ null, mCurrent, mResult)); - assertEquals(DEFAULT_DISPLAY, mResult.mPreferredDisplayId); + assertEquals(mRootWindowContainer.getDefaultTaskDisplayArea(), + mResult.mPreferredTaskDisplayArea); } finally { mService.mSupportsMultiDisplay = orgValue; } |