diff options
7 files changed, 162 insertions, 77 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index 57bfc2979636..36701ea599dc 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -73,6 +73,8 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_USER_ import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM; import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.ActivityTaskManagerService.ANIMATE; +import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_BOUNDS; +import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_DISPLAY; import static com.android.server.wm.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT; import static com.android.server.wm.TaskRecord.REPARENT_MOVE_STACK_TO_FRONT; @@ -1339,6 +1341,21 @@ class ActivityStarter { voiceInteractor); final int preferredWindowingMode = mLaunchParams.mWindowingMode; + computeLaunchingTaskFlags(); + + computeSourceStack(); + + mIntent.setFlags(mLaunchFlags); + + ActivityRecord reusedActivity = getReusableIntentActivity(); + + mSupervisor.getLaunchParamsController().calculate( + reusedActivity != null ? reusedActivity.getTaskRecord() : mInTask, + r.info.windowLayout, r, sourceRecord, options, PHASE_BOUNDS, mLaunchParams); + mPreferredDisplayId = + mLaunchParams.hasPreferredDisplay() ? mLaunchParams.mPreferredDisplayId + : DEFAULT_DISPLAY; + // 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. @@ -1348,14 +1365,6 @@ class ActivityStarter { return START_CANCELED; } - computeLaunchingTaskFlags(); - - computeSourceStack(); - - mIntent.setFlags(mLaunchFlags); - - ActivityRecord reusedActivity = getReusableIntentActivity(); - if (reusedActivity != null) { // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but // still needs to be a lock task mode violation since the task gets cleared out and @@ -1651,14 +1660,13 @@ class ActivityStarter { mLaunchParams.reset(); + // Preferred display id is the only state we need for now and it could be updated again + // after we located a reusable task (which might be resided in another display). mSupervisor.getLaunchParamsController().calculate(inTask, r.info.windowLayout, r, - sourceRecord, options, mLaunchParams); - - if (mLaunchParams.hasPreferredDisplay()) { - mPreferredDisplayId = mLaunchParams.mPreferredDisplayId; - } else { - mPreferredDisplayId = DEFAULT_DISPLAY; - } + sourceRecord, options, PHASE_DISPLAY, mLaunchParams); + mPreferredDisplayId = + mLaunchParams.hasPreferredDisplay() ? mLaunchParams.mPreferredDisplayId + : DEFAULT_DISPLAY; mLaunchMode = r.launchMode; @@ -2502,14 +2510,9 @@ class ActivityStarter { if (((launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) == 0) || mPreferredDisplayId != DEFAULT_DISPLAY) { - // We don't pass in the default display id into the get launch stack call so it can do a - // full resolution. - mLaunchParams.mPreferredDisplayId = - mPreferredDisplayId != DEFAULT_DISPLAY ? mPreferredDisplayId : INVALID_DISPLAY; final boolean onTop = aOptions == null || !aOptions.getAvoidMoveToFront(); final ActivityStack stack = mRootActivityContainer.getLaunchStack(r, aOptions, task, onTop, mLaunchParams); - mLaunchParams.mPreferredDisplayId = mPreferredDisplayId; return stack; } // Otherwise handle adjacent launch. diff --git a/services/core/java/com/android/server/wm/LaunchParamsController.java b/services/core/java/com/android/server/wm/LaunchParamsController.java index 09475777cb6e..59c02f736513 100644 --- a/services/core/java/com/android/server/wm/LaunchParamsController.java +++ b/services/core/java/com/android/server/wm/LaunchParamsController.java @@ -20,6 +20,7 @@ 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; import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE; import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_DONE; import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_SKIP; @@ -74,7 +75,7 @@ class LaunchParamsController { * @param result The resulting params. */ void calculate(TaskRecord task, WindowLayout layout, ActivityRecord activity, - ActivityRecord source, ActivityOptions options, LaunchParams result) { + ActivityRecord source, ActivityOptions options, int phase, LaunchParams result) { result.reset(); if (task != null || activity != null) { @@ -89,7 +90,7 @@ class LaunchParamsController { mTmpResult.reset(); final LaunchParamsModifier modifier = mModifiers.get(i); - switch(modifier.onCalculate(task, layout, activity, source, options, mTmpCurrent, + switch(modifier.onCalculate(task, layout, activity, source, options, phase, mTmpCurrent, mTmpResult)) { case RESULT_SKIP: // Do not apply any results when we are told to skip @@ -125,7 +126,7 @@ class LaunchParamsController { boolean layoutTask(TaskRecord task, WindowLayout layout, ActivityRecord activity, ActivityRecord source, ActivityOptions options) { - calculate(task, layout, activity, source, options, mTmpParams); + calculate(task, layout, activity, source, options, PHASE_BOUNDS, mTmpParams); // No changes, return. if (mTmpParams.isEmpty()) { @@ -259,6 +260,25 @@ class LaunchParamsController { */ int RESULT_CONTINUE = 2; + @Retention(RetentionPolicy.SOURCE) + @IntDef({PHASE_DISPLAY, PHASE_WINDOWING_MODE, PHASE_BOUNDS}) + @interface Phase {} + + /** + * Stops once we are done with preferred display calculation. + */ + int PHASE_DISPLAY = 0; + + /** + * Stops once we are done with windowing mode calculation. + */ + int PHASE_WINDOWING_MODE = 1; + + /** + * Stops once we are done with window bounds calculation. + */ + int PHASE_BOUNDS = 2; + /** * Returns the launch params that the provided activity launch params should be overridden * to. {@link LaunchParamsModifier} can use this for various purposes, including: 1) @@ -277,6 +297,7 @@ class LaunchParamsController { * launched should have this be non-null. * @param source the Activity that launched a new task. Could be {@code null}. * @param options {@link ActivityOptions} used to start the activity with. + * @param phase the calculation phase, see {@link LaunchParamsModifier.Phase} * @param currentParams launching params after the process of last {@link * LaunchParamsModifier}. * @param outParams the result params to be set. @@ -284,7 +305,7 @@ class LaunchParamsController { */ @Result int onCalculate(TaskRecord task, WindowLayout layout, ActivityRecord activity, - ActivityRecord source, ActivityOptions options, LaunchParams currentParams, - LaunchParams outParams); + ActivityRecord source, ActivityOptions options, @Phase int phase, + LaunchParams currentParams, LaunchParams outParams); } } diff --git a/services/core/java/com/android/server/wm/RootActivityContainer.java b/services/core/java/com/android/server/wm/RootActivityContainer.java index c5b42f99fcda..c6cfa492dc76 100644 --- a/services/core/java/com/android/server/wm/RootActivityContainer.java +++ b/services/core/java/com/android/server/wm/RootActivityContainer.java @@ -1606,33 +1606,35 @@ class RootActivityContainer extends ConfigurationContainer return candidateTask.getStack(); } + int windowingMode; + if (launchParams != null) { + // When launch params is not null, we always defer to its windowing mode. Sometimes + // it could be unspecified, which indicates it should inherit windowing mode from + // display. + windowingMode = launchParams.mWindowingMode; + } else { + windowingMode = options != null ? options.getLaunchWindowingMode() + : r.getWindowingMode(); + } + windowingMode = activityDisplay.validateWindowingMode(windowingMode, r, candidateTask, + r.getActivityType()); + // Return the topmost valid stack on the display. for (int i = activityDisplay.getChildCount() - 1; i >= 0; --i) { final ActivityStack stack = activityDisplay.getChildAt(i); - if (isValidLaunchStack(stack, r)) { + 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) { - final int windowingMode; - if (launchParams != null) { - // When launch params is not null, we always defer to its windowing mode. Sometimes - // it could be unspecified, which indicates it should inherit windowing mode from - // display. - windowingMode = launchParams.mWindowingMode; - } else { - windowingMode = options != null ? options.getLaunchWindowingMode() - : r.getWindowingMode(); - } final int activityType = options != null && options.getLaunchActivityType() != ACTIVITY_TYPE_UNDEFINED ? options.getLaunchActivityType() : r.getActivityType(); return activityDisplay.createStack(windowingMode, activityType, true /*onTop*/); } - Slog.w(TAG, "getValidLaunchStackOnDisplay: can't launch on displayId " + displayId); return null; } @@ -1644,7 +1646,7 @@ class RootActivityContainer extends ConfigurationContainer } // TODO: Can probably be consolidated into getLaunchStack()... - private boolean isValidLaunchStack(ActivityStack stack, ActivityRecord r) { + private boolean isValidLaunchStack(ActivityStack stack, ActivityRecord r, int windowingMode) { switch (stack.getActivityType()) { case ACTIVITY_TYPE_HOME: return r.isActivityTypeHome(); case ACTIVITY_TYPE_RECENTS: return r.isActivityTypeRecents(); @@ -1652,11 +1654,13 @@ class RootActivityContainer extends ConfigurationContainer } // There is a 1-to-1 relationship between stack and task when not in // primary split-windowing mode. - if (stack.getWindowingMode() != WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) { - return false; - } else { - return r.supportsSplitScreenWindowingMode(); + if (stack.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY + && r.supportsSplitScreenWindowingMode() + && (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY + || windowingMode == WINDOWING_MODE_UNDEFINED)) { + return true; } + return false; } int resolveActivityType(@Nullable ActivityRecord r, @Nullable ActivityOptions options, diff --git a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java index 1fb7979fa3e2..5107b522c33b 100644 --- a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java +++ b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java @@ -51,6 +51,7 @@ import android.util.Slog; import android.view.Gravity; import android.view.View; +import com.android.internal.annotations.VisibleForTesting; import com.android.server.wm.LaunchParamsController.LaunchParams; import com.android.server.wm.LaunchParamsController.LaunchParamsModifier; @@ -102,19 +103,27 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier { mSupervisor = supervisor; } + @VisibleForTesting + int onCalculate(TaskRecord task, ActivityInfo.WindowLayout layout, ActivityRecord activity, + ActivityRecord source, ActivityOptions options, LaunchParams currentParams, + LaunchParams outParams) { + return onCalculate(task, layout, activity, source, options, PHASE_BOUNDS, currentParams, + outParams); + } + @Override public int onCalculate(TaskRecord task, ActivityInfo.WindowLayout layout, ActivityRecord activity, ActivityRecord source, ActivityOptions options, - LaunchParams currentParams, LaunchParams outParams) { + int phase, LaunchParams currentParams, LaunchParams outParams) { initLogBuilder(task, activity); - final int result = calculate(task, layout, activity, source, options, currentParams, + final int result = calculate(task, layout, activity, source, options, phase, currentParams, outParams); outputLog(); return result; } private int calculate(TaskRecord task, ActivityInfo.WindowLayout layout, - ActivityRecord activity, ActivityRecord source, ActivityOptions options, + ActivityRecord activity, ActivityRecord source, ActivityOptions options, int phase, LaunchParams currentParams, LaunchParams outParams) { final ActivityRecord root; if (task != null) { @@ -145,6 +154,10 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier { + display.getWindowingMode()); } + if (phase == PHASE_DISPLAY) { + return RESULT_CONTINUE; + } + // STEP 2: Resolve launch windowing mode. // STEP 2.1: Determine if any parameter has specified initial bounds. That might be the // launch bounds from activity options, or size/gravity passed in layout. It also treats the @@ -247,6 +260,10 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier { outParams.mWindowingMode = launchMode == display.getWindowingMode() ? WINDOWING_MODE_UNDEFINED : launchMode; + if (phase == PHASE_WINDOWING_MODE) { + return RESULT_CONTINUE; + } + // STEP 3: Determine final launch bounds based on resolved windowing mode and activity // requested orientation. We set bounds to empty for fullscreen mode and keep bounds as is // for all other windowing modes that's not freeform mode. One can read comments in @@ -288,12 +305,6 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier { displayId = optionLaunchId; } - if (displayId == INVALID_DISPLAY && source != null) { - final int sourceDisplayId = source.getDisplayId(); - if (DEBUG) appendLog("display-from-source=" + sourceDisplayId); - displayId = sourceDisplayId; - } - ActivityStack stack = (displayId == INVALID_DISPLAY && task != null) ? task.getStack() : null; if (stack != null) { @@ -301,6 +312,12 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier { displayId = stack.mDisplayId; } + if (displayId == INVALID_DISPLAY && source != null) { + final int sourceDisplayId = source.getDisplayId(); + if (DEBUG) appendLog("display-from-source=" + sourceDisplayId); + displayId = sourceDisplayId; + } + if (displayId != INVALID_DISPLAY && mSupervisor.mRootActivityContainer.getActivityDisplay(displayId) == null) { displayId = currentParams.mPreferredDisplayId; 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 7c43cf3fba83..61e968d6da00 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java @@ -414,10 +414,10 @@ public class ActivityStarterTests extends ActivityTestsBase { .setActivityOptions(new SafeActivityOptions(options)) .execute(); - // verify that values are passed to the modifier. Values are passed twice -- once for + // verify that values are passed to the modifier. Values are passed thrice -- two for // setting initial state, another when task is created. - verify(modifier, times(2)).onCalculate(any(), eq(windowLayout), any(), any(), eq(options), - any(), any()); + verify(modifier, times(3)).onCalculate(any(), eq(windowLayout), any(), any(), eq(options), + anyInt(), any(), any()); } /** 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 3720c8566e74..8c3dec7f1e75 100644 --- a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java @@ -31,6 +31,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; import static com.android.dx.mockito.inline.extended.ExtendedMockito.times; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; +import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_BOUNDS; import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE; import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_DONE; import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_SKIP; @@ -89,10 +90,10 @@ public class LaunchParamsControllerTests extends ActivityTestsBase { final WindowLayout layout = new WindowLayout(0, 0, 0, 0, 0, 0, 0); final ActivityOptions options = mock(ActivityOptions.class); - mController.calculate(record.getTaskRecord(), layout, record, source, options, + mController.calculate(record.getTaskRecord(), layout, record, source, options, PHASE_BOUNDS, new LaunchParams()); verify(positioner, times(1)).onCalculate(eq(record.getTaskRecord()), eq(layout), eq(record), - eq(source), eq(options), any(), any()); + eq(source), eq(options), anyInt(), any(), any()); } /** @@ -115,9 +116,9 @@ public class LaunchParamsControllerTests extends ActivityTestsBase { mPersister.putLaunchParams(userId, name, expected); mController.calculate(activity.getTaskRecord(), null /*layout*/, activity, null /*source*/, - null /*options*/, new LaunchParams()); - verify(positioner, times(1)).onCalculate(any(), any(), any(), any(), any(), eq(expected), - any()); + null /*options*/, PHASE_BOUNDS, new LaunchParams()); + verify(positioner, times(1)).onCalculate(any(), any(), any(), any(), any(), anyInt(), + eq(expected), any()); } /** @@ -128,14 +129,15 @@ public class LaunchParamsControllerTests extends ActivityTestsBase { final LaunchParamsModifier ignoredPositioner = mock(LaunchParamsModifier.class); final LaunchParamsModifier earlyExitPositioner = - (task, layout, activity, source, options, currentParams, outParams) -> RESULT_DONE; + (task, layout, activity, source, options, phase, currentParams, outParams) + -> RESULT_DONE; mController.registerModifier(ignoredPositioner); mController.registerModifier(earlyExitPositioner); mController.calculate(null /*task*/, null /*layout*/, null /*activity*/, - null /*source*/, null /*options*/, new LaunchParams()); - verify(ignoredPositioner, never()).onCalculate(any(), any(), any(), any(), any(), + null /*source*/, null /*options*/, PHASE_BOUNDS, new LaunchParams()); + verify(ignoredPositioner, never()).onCalculate(any(), any(), any(), any(), any(), anyInt(), any(), any()); } @@ -152,20 +154,20 @@ public class LaunchParamsControllerTests extends ActivityTestsBase { mController.registerModifier(firstPositioner); mController.calculate(null /*task*/, null /*layout*/, null /*activity*/, - null /*source*/, null /*options*/, new LaunchParams()); - verify(firstPositioner, times(1)).onCalculate(any(), any(), any(), any(), any(), any(), - any()); + null /*source*/, null /*options*/, PHASE_BOUNDS, new LaunchParams()); + verify(firstPositioner, times(1)).onCalculate(any(), any(), any(), any(), any(), anyInt(), + any(), any()); final LaunchParamsModifier secondPositioner = spy(earlyExitPositioner); mController.registerModifier(secondPositioner); mController.calculate(null /*task*/, null /*layout*/, null /*activity*/, - null /*source*/, null /*options*/, new LaunchParams()); - verify(firstPositioner, times(1)).onCalculate(any(), any(), any(), any(), any(), any(), - any()); - verify(secondPositioner, times(1)).onCalculate(any(), any(), any(), any(), any(), any(), - any()); + null /*source*/, null /*options*/, PHASE_BOUNDS, new LaunchParams()); + verify(firstPositioner, times(1)).onCalculate(any(), any(), any(), any(), any(), anyInt(), + any(), any()); + verify(secondPositioner, times(1)).onCalculate(any(), any(), any(), any(), any(), anyInt(), + any(), any()); } /** @@ -187,9 +189,9 @@ public class LaunchParamsControllerTests extends ActivityTestsBase { mController.registerModifier(positioner2); mController.calculate(null /*task*/, null /*layout*/, null /*activity*/, null /*source*/, - null /*options*/, new LaunchParams()); + null /*options*/, PHASE_BOUNDS, new LaunchParams()); - verify(positioner1, times(1)).onCalculate(any(), any(), any(), any(), any(), + verify(positioner1, times(1)).onCalculate(any(), any(), any(), any(), any(), anyInt(), eq(positioner2.getLaunchParams()), any()); } @@ -213,7 +215,7 @@ public class LaunchParamsControllerTests extends ActivityTestsBase { final LaunchParams result = new LaunchParams(); mController.calculate(null /*task*/, null /*layout*/, null /*activity*/, null /*source*/, - null /*options*/, result); + null /*options*/, PHASE_BOUNDS, result); assertEquals(result, positioner2.getLaunchParams()); } @@ -232,21 +234,42 @@ 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*/, result); + null /*source*/, null /*options*/, PHASE_BOUNDS, result); assertEquals(DEFAULT_DISPLAY, result.mPreferredDisplayId); // 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*/, result); + null /*source*/, null /*options*/, PHASE_BOUNDS, result); assertEquals(vr2dDisplayId, result.mPreferredDisplayId); mController.calculate(null /*task*/, null /*layout*/, null /*activity*/, null /*source*/, - null /*options*/, result); + null /*options*/, PHASE_BOUNDS, result); assertEquals(vr2dDisplayId, result.mPreferredDisplayId); mService.mVr2dDisplayId = INVALID_DISPLAY; } + + /** + * Ensures that {@link LaunchParamsController} calculates to {@link PHASE_BOUNDS} phase by + * default. + */ + @Test + public void testCalculatePhase() { + final LaunchParamsModifier positioner = mock(LaunchParamsModifier.class); + mController.registerModifier(positioner); + + final ActivityRecord record = new ActivityBuilder(mService).build(); + final ActivityRecord source = new ActivityBuilder(mService).build(); + final WindowLayout layout = new WindowLayout(0, 0, 0, 0, 0, 0, 0); + final ActivityOptions options = mock(ActivityOptions.class); + + mController.calculate(record.getTaskRecord(), layout, record, source, options, PHASE_BOUNDS, + new LaunchParams()); + verify(positioner, times(1)).onCalculate(eq(record.getTaskRecord()), eq(layout), eq(record), + eq(source), eq(options), eq(PHASE_BOUNDS), any(), any()); + } + /** * Ensures that {@link LaunchParamsModifier} requests specifying display id during * layout are honored. @@ -348,7 +371,7 @@ public class LaunchParamsControllerTests extends ActivityTestsBase { @Override public int onCalculate(TaskRecord task, WindowLayout layout, ActivityRecord activity, - ActivityRecord source, ActivityOptions options, + ActivityRecord source, ActivityOptions options, int phase, LaunchParams currentParams, LaunchParams outParams) { outParams.set(mParams); return mReturnVal; 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 fe632d4ab01e..0bd681bd69a2 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java @@ -173,6 +173,23 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { } @Test + public void testUsesTasksDisplayIdPriorToSourceIfSet() { + final TestActivityDisplay freeformDisplay = createNewActivityDisplay( + WINDOWING_MODE_FREEFORM); + final TestActivityDisplay fullscreenDisplay = createNewActivityDisplay( + WINDOWING_MODE_FULLSCREEN); + + mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId; + ActivityRecord reusableActivity = createSourceActivity(fullscreenDisplay); + ActivityRecord source = createSourceActivity(freeformDisplay); + + assertEquals(RESULT_CONTINUE, mTarget.onCalculate(reusableActivity.getTaskRecord(), + /* layout */ null, mActivity, source, /* options */ null, mCurrent, mResult)); + + assertEquals(fullscreenDisplay.mDisplayId, mResult.mPreferredDisplayId); + } + + @Test public void testUsesTaskDisplayIdIfSet() { final TestActivityDisplay freeformDisplay = createNewActivityDisplay( WINDOWING_MODE_FREEFORM); |