Merge "7/n Use display area instead of display id in ATM methods" into rvc-dev am: bba1891e80 am: 248a3e7c98 am: 8a8456aaf4

Change-Id: Ic0a276ab824ce75eee3560392de4338db3158e6f
This commit is contained in:
Andrii Kulian
2020-04-11 17:27:35 +00:00
committed by Automerger Merge Worker
11 changed files with 169 additions and 98 deletions

View File

@@ -2272,7 +2272,7 @@ class ActivityStack extends Task {
ActivityOptions.abort(options);
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeNextFocusableActivityWhenStackIsEmpty: " + reason + ", go home");
return mRootWindowContainer.resumeHomeActivity(prev, reason, getDisplayId());
return mRootWindowContainer.resumeHomeActivity(prev, reason, getDisplayArea());
}
void startActivityLocked(ActivityRecord r, ActivityRecord focusedTopActivity,

View File

@@ -44,7 +44,6 @@ import static android.os.Process.INVALID_UID;
import static android.os.Process.SYSTEM_UID;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.Display.TYPE_VIRTUAL;
import static android.view.WindowManager.TRANSIT_DOCK_TASK_FROM_RECENTS;
@@ -1378,8 +1377,8 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
if (DEBUG_STACK) Slog.d(TAG_STACK,
"findTaskToMoveToFront: moved to front of stack=" + currentStack);
handleNonResizableTaskIfNeeded(task, WINDOWING_MODE_UNDEFINED, DEFAULT_DISPLAY,
currentStack, forceNonResizeable);
handleNonResizableTaskIfNeeded(task, WINDOWING_MODE_UNDEFINED,
mRootWindowContainer.getDefaultTaskDisplayArea(), currentStack, forceNonResizeable);
}
private void moveHomeStackToFrontIfNeeded(int flags, TaskDisplayArea taskDisplayArea,
@@ -2134,16 +2133,29 @@ 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) {
handleNonResizableTaskIfNeeded(task, preferredWindowingMode, preferredDisplayId,
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,
actualStack, false /* forceNonResizable */);
}
void handleNonResizableTaskIfNeeded(Task task, int preferredWindowingMode,
int preferredDisplayId, ActivityStack actualStack, boolean forceNonResizable) {
final boolean isSecondaryDisplayPreferred =
(preferredDisplayId != DEFAULT_DISPLAY && preferredDisplayId != INVALID_DISPLAY);
TaskDisplayArea preferredTaskDisplayArea, ActivityStack actualStack,
boolean forceNonResizable) {
final boolean isSecondaryDisplayPreferred = preferredTaskDisplayArea != null
&& preferredTaskDisplayArea.getDisplayId() != DEFAULT_DISPLAY;
final boolean inSplitScreenMode = actualStack != null
&& actualStack.getDisplayArea().isSplitScreenModeActivated();
if (((!inSplitScreenMode && preferredWindowingMode != WINDOWING_MODE_SPLIT_SCREEN_PRIMARY)
@@ -2153,33 +2165,31 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
// Handle incorrect launch/move to secondary display if needed.
if (isSecondaryDisplayPreferred) {
final int actualDisplayId = task.getDisplayId();
if (!task.canBeLaunchedOnDisplay(actualDisplayId)) {
if (!task.canBeLaunchedOnDisplay(task.getDisplayId())) {
throw new IllegalStateException("Task resolved to incompatible display");
}
final DisplayContent preferredDisplay =
mRootWindowContainer.getDisplayContent(preferredDisplayId);
final DisplayContent preferredDisplay = preferredTaskDisplayArea.mDisplayContent;
final boolean singleTaskInstance = preferredDisplay != null
&& preferredDisplay.isSingleTaskInstance();
if (preferredDisplayId != actualDisplayId) {
if (preferredDisplay != task.getDisplayContent()) {
// Suppress the warning toast if the preferredDisplay was set to singleTask.
// The singleTaskInstance displays will only contain one task and any attempt to
// launch new task will re-route to the default display.
if (singleTaskInstance) {
mService.getTaskChangeNotificationController()
.notifyActivityLaunchOnSecondaryDisplayRerouted(task.getTaskInfo(),
preferredDisplayId);
preferredDisplay.mDisplayId);
return;
}
Slog.w(TAG, "Failed to put " + task + " on display " + preferredDisplayId);
Slog.w(TAG, "Failed to put " + task + " on display " + preferredDisplay.mDisplayId);
// Display a warning toast that we failed to put a task on a secondary display.
mService.getTaskChangeNotificationController()
.notifyActivityLaunchOnSecondaryDisplayFailed(task.getTaskInfo(),
preferredDisplayId);
preferredDisplay.mDisplayId);
} else if (!forceNonResizable) {
handleForcedResizableTaskIfNeeded(task, FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY);
}

View File

@@ -172,7 +172,8 @@ public class ActivityStartController {
mLastStarter.postStartActivityProcessing(r, result, targetStack);
}
void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, int displayId) {
void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason,
TaskDisplayArea taskDisplayArea) {
final ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
if (!ActivityRecord.isResolverActivity(aInfo.name)) {
@@ -181,20 +182,20 @@ public class ActivityStartController {
// foreground instead of bring home stack to front.
options.setLaunchActivityType(ACTIVITY_TYPE_HOME);
}
final int displayId = taskDisplayArea.getDisplayId();
options.setLaunchDisplayId(displayId);
// TODO(b/152116619): Enable after complete switch to WindowContainerToken
//options.setLaunchWindowContainerToken(taskDisplayArea.getWindowContainerToken());
final DisplayContent display =
mService.mRootWindowContainer.getDisplayContent(displayId);
// The home activity will be started later, defer resuming to avoid unneccerary operations
// (e.g. start home recursively) when creating home stack.
mSupervisor.beginDeferResume();
final ActivityStack homeStack;
try {
// TODO(multi-display-area): Support starting home in a task display area
// Make sure home stack exist on display.
// Make sure home stack exists on display area.
// TODO(b/153624902): Replace with TaskDisplayArea#getOrCreateRootHomeTask()
homeStack = display.getDefaultTaskDisplayArea().getOrCreateStack(
WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME, ON_TOP);
homeStack = taskDisplayArea.getOrCreateStack(WINDOWING_MODE_UNDEFINED,
ACTIVITY_TYPE_HOME, ON_TOP);
} finally {
mSupervisor.endDeferResume();
}

View File

@@ -2422,7 +2422,7 @@ class ActivityStarter {
// be destroyed.
mTargetStack = intentActivity.getRootTask();
mSupervisor.handleNonResizableTaskIfNeeded(intentTask, WINDOWING_MODE_UNDEFINED,
DEFAULT_DISPLAY, mTargetStack);
mRootWindowContainer.getDefaultTaskDisplayArea(), mTargetStack);
}
private void resumeTargetStackIfNeeded() {

View File

@@ -28,7 +28,6 @@ import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER;
import static android.os.UserHandle.USER_ALL;
import static android.os.UserHandle.USER_CURRENT;
import static android.telecom.TelecomManager.EMERGENCY_DIALER_COMPONENT;
import static android.view.Display.DEFAULT_DISPLAY;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_LOCKTASK;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_LOCKTASK;
@@ -619,7 +618,8 @@ public class LockTaskController {
}
} else if (lockTaskModeState != LOCK_TASK_MODE_NONE) {
mSupervisor.handleNonResizableTaskIfNeeded(task, WINDOWING_MODE_UNDEFINED,
DEFAULT_DISPLAY, task.getStack(), true /* forceNonResizable */);
mSupervisor.mRootWindowContainer.getDefaultTaskDisplayArea(),
task.getStack(), true /* forceNonResizable */);
}
}

View File

@@ -1461,8 +1461,12 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
void startHomeOnEmptyDisplays(String reason) {
for (int i = getChildCount() - 1; i >= 0; i--) {
final DisplayContent display = getChildAt(i);
if (display.topRunningActivity() == null) {
startHomeOnDisplay(mCurrentUser, reason, display.mDisplayId);
for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
if (taskDisplayArea.topRunningActivity() == null) {
startHomeOnTaskDisplayArea(mCurrentUser, reason, taskDisplayArea,
false /* allowInstrumenting */, false /* fromHomeKey */);
}
}
}
}
@@ -1472,32 +1476,52 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
false /* fromHomeKey */);
}
boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
boolean fromHomeKey) {
// Fallback to top focused display or default display if the displayId is invalid.
if (displayId == INVALID_DISPLAY) {
final ActivityStack stack = getTopDisplayFocusedStack();
displayId = stack != null ? stack.getDisplayId() : DEFAULT_DISPLAY;
}
final DisplayContent display = getDisplayContent(displayId);
boolean result = false;
for (int tcNdx = display.getTaskDisplayAreaCount() - 1; tcNdx >= 0; --tcNdx) {
final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tcNdx);
result |= startHomeOnTaskDisplayArea(userId, reason, taskDisplayArea,
allowInstrumenting, fromHomeKey);
}
return result;
}
/**
* This starts home activity on displays that can have system decorations based on displayId -
* Default display always use primary home component.
* For Secondary displays, the home activity must have category SECONDARY_HOME and then resolves
* according to the priorities listed below.
* This starts home activity on display areas that can have system decorations based on
* displayId - default display area always uses primary home component.
* For secondary display areas, the home activity must have category SECONDARY_HOME and then
* resolves according to the priorities listed below.
* - If default home is not set, always use the secondary home defined in the config.
* - Use currently selected primary home activity.
* - Use the activity in the same package as currently selected primary home activity.
* If there are multiple activities matched, use first one.
* - Use the secondary home defined in the config.
*/
boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
boolean fromHomeKey) {
// Fallback to top focused display if the displayId is invalid.
if (displayId == INVALID_DISPLAY) {
boolean startHomeOnTaskDisplayArea(int userId, String reason, TaskDisplayArea taskDisplayArea,
boolean allowInstrumenting, boolean fromHomeKey) {
// Fallback to top focused display area if the provided one is invalid.
if (taskDisplayArea == null) {
final ActivityStack stack = getTopDisplayFocusedStack();
displayId = stack != null ? stack.getDisplayId() : DEFAULT_DISPLAY;
taskDisplayArea = stack != null ? stack.getDisplayArea()
: getDefaultTaskDisplayArea();
}
Intent homeIntent = null;
ActivityInfo aInfo = null;
if (displayId == DEFAULT_DISPLAY) {
if (taskDisplayArea == getDefaultTaskDisplayArea()) {
homeIntent = mService.getHomeIntent();
aInfo = resolveHomeActivity(userId, homeIntent);
} else if (shouldPlaceSecondaryHomeOnDisplay(displayId)) {
Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, displayId);
} else if (taskDisplayArea.getDisplayId() == DEFAULT_DISPLAY
|| shouldPlaceSecondaryHomeOnDisplay(taskDisplayArea.getDisplayId())) {
Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, taskDisplayArea);
aInfo = info.first;
homeIntent = info.second;
}
@@ -1505,7 +1529,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
return false;
}
if (!canStartHomeOnDisplay(aInfo, displayId, allowInstrumenting)) {
if (!canStartHomeOnDisplay(aInfo, taskDisplayArea.getDisplayId(), allowInstrumenting)) {
return false;
}
@@ -1520,9 +1544,9 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
// Update the reason for ANR debugging to verify if the user activity is the one that
// actually launched.
final String myReason = reason + ":" + userId + ":" + UserHandle.getUserId(
aInfo.applicationInfo.uid) + ":" + displayId;
aInfo.applicationInfo.uid) + ":" + taskDisplayArea.getDisplayId();
mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
displayId);
taskDisplayArea);
return true;
}
@@ -1563,10 +1587,11 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
}
@VisibleForTesting
Pair<ActivityInfo, Intent> resolveSecondaryHomeActivity(int userId, int displayId) {
if (displayId == DEFAULT_DISPLAY) {
Pair<ActivityInfo, Intent> resolveSecondaryHomeActivity(int userId,
@NonNull TaskDisplayArea taskDisplayArea) {
if (taskDisplayArea == getDefaultTaskDisplayArea()) {
throw new IllegalArgumentException(
"resolveSecondaryHomeActivity: Should not be DEFAULT_DISPLAY");
"resolveSecondaryHomeActivity: Should not be default task container");
}
// Resolve activities in the same package as currently selected primary home activity.
Intent homeIntent = mService.getHomeIntent();
@@ -1600,7 +1625,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
}
if (aInfo != null) {
if (!canStartHomeOnDisplay(aInfo, displayId, false /* allowInstrumenting */)) {
if (!canStartHomeOnDisplay(aInfo, taskDisplayArea.getDisplayId(),
false /* allowInstrumenting */)) {
aInfo = null;
}
}
@@ -1633,19 +1659,18 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
return resolutions;
}
boolean resumeHomeActivity(ActivityRecord prev, String reason, int displayId) {
boolean resumeHomeActivity(ActivityRecord prev, String reason,
TaskDisplayArea taskDisplayArea) {
if (!mService.isBooting() && !mService.isBooted()) {
// Not ready yet!
return false;
}
if (displayId == INVALID_DISPLAY) {
displayId = DEFAULT_DISPLAY;
if (taskDisplayArea == null) {
taskDisplayArea = getDefaultTaskDisplayArea();
}
// TODO(multi-display-area): Resume home on the right task container
final ActivityRecord r = getDisplayContent(displayId).getDefaultTaskDisplayArea()
.getHomeActivity();
final ActivityRecord r = taskDisplayArea.getHomeActivity();
final String myReason = reason + " resumeHomeActivity";
// Only resume home activity if isn't finishing.
@@ -1653,7 +1678,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
r.moveFocusableActivityToTop(myReason);
return resumeFocusedStacksTopActivities(r.getRootTask(), prev, null);
}
return startHomeOnDisplay(mCurrentUser, myReason, displayId);
return startHomeOnTaskDisplayArea(mCurrentUser, myReason, taskDisplayArea,
false /* allowInstrumenting */, false /* fromHomeKey */);
}
/**
@@ -2023,7 +2049,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
stack.moveToFront("switchUserOnHomeDisplay");
} else {
// Stack was moved to another display while user was swapped out.
resumeHomeActivity(null, "switchUserOnOtherDisplay", DEFAULT_DISPLAY);
resumeHomeActivity(null, "switchUserOnOtherDisplay", getDefaultTaskDisplayArea());
}
return homeInFront;
}
@@ -2046,6 +2072,38 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
}
}
/**
* Move stack with all its existing content to specified task display area.
* @param stackId Id of stack to move.
* @param taskDisplayArea The task display area to move stack to.
* @param onTop Indicates whether container should be place on top or on bottom.
*/
void moveStackToTaskDisplayArea(int stackId, TaskDisplayArea taskDisplayArea, boolean onTop) {
final ActivityStack stack = getStack(stackId);
if (stack == null) {
throw new IllegalArgumentException("moveStackToTaskDisplayArea: Unknown stackId="
+ stackId);
}
final TaskDisplayArea currentTaskDisplayArea = stack.getDisplayArea();
if (currentTaskDisplayArea == null) {
throw new IllegalStateException("moveStackToTaskDisplayArea: stack=" + stack
+ " is not attached to any task display area.");
}
if (taskDisplayArea == null) {
throw new IllegalArgumentException(
"moveStackToTaskDisplayArea: Unknown taskDisplayArea=" + taskDisplayArea);
}
if (currentTaskDisplayArea == taskDisplayArea) {
throw new IllegalArgumentException("Trying to move stack=" + stack
+ " to its current taskDisplayArea=" + taskDisplayArea);
}
stack.reparent(taskDisplayArea, onTop);
// TODO(multi-display): resize stacks properly if moved from split-screen.
}
/**
* Move stack with all its existing content to specified display.
* @param stackId Id of stack to move.
@@ -2058,32 +2116,15 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
throw new IllegalArgumentException("moveStackToDisplay: Unknown displayId="
+ displayId);
}
final ActivityStack stack = getStack(stackId);
if (stack == null) {
throw new IllegalArgumentException("moveStackToDisplay: Unknown stackId="
+ stackId);
}
final DisplayContent currentDisplay = stack.getDisplay();
if (currentDisplay == null) {
throw new IllegalStateException("moveStackToDisplay: Stack with stack=" + stack
+ " is not attached to any display.");
}
if (currentDisplay.mDisplayId == displayId) {
throw new IllegalArgumentException("Trying to move stack=" + stack
+ " to its current displayId=" + displayId);
}
if (displayContent.isSingleTaskInstance() && displayContent.getStackCount() > 0) {
// We don't allow moving stacks to single instance display that already has a child.
Slog.e(TAG, "Can not move stack=" + stack
Slog.e(TAG, "Can not move stackId=" + stackId
+ " to single task instance display=" + displayContent);
return;
}
stack.reparent(displayContent.getDefaultTaskDisplayArea(), onTop);
// TODO(multi-display): resize stacks properly if moved from split-screen.
moveStackToTaskDisplayArea(stackId, displayContent.getDefaultTaskDisplayArea(), onTop);
}
boolean moveTopStackActivityToPinnedStack(int stackId) {
@@ -2281,7 +2322,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
result |= focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
} else if (targetStack == null) {
result |= resumeHomeActivity(null /* prev */, "no-focusable-task",
display.mDisplayId);
display.getDefaultTaskDisplayArea());
}
}
}

View File

@@ -58,7 +58,6 @@ import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.SurfaceControl.METADATA_TASK_ID;
import static android.view.WindowManager.TRANSIT_TASK_CHANGE_WINDOWING_MODE;
@@ -900,7 +899,7 @@ class Task extends WindowContainer<WindowContainer> {
// TODO: Handle incorrect request to move before the actual move, not after.
supervisor.handleNonResizableTaskIfNeeded(this, preferredStack.getWindowingMode(),
DEFAULT_DISPLAY, toStack);
mRootWindowContainer.getDefaultTaskDisplayArea(), toStack);
return (preferredStack == toStack);
}

View File

@@ -70,7 +70,9 @@ import java.util.List;
* {@link DisplayArea} that represents a section of a screen that contains app window containers.
*/
final class TaskDisplayArea extends DisplayArea<ActivityStack> {
DisplayContent mDisplayContent;
/**
* A control placed at the appropriate level for transitions to occur.
*/
@@ -1068,7 +1070,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
/**
* Find task for putting the Activity in.
*/
void findTaskLocked(final ActivityRecord r, final boolean isPreferredDisplay,
void findTaskLocked(final ActivityRecord r, final boolean isPreferredDisplayArea,
RootWindowContainer.FindTaskResult result) {
mTmpFindTaskResult.clear();
for (int stackNdx = getStackCount() - 1; stackNdx >= 0; --stackNdx) {
@@ -1090,7 +1092,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
if (mTmpFindTaskResult.mIdealMatch) {
result.setTo(mTmpFindTaskResult);
return;
} else if (isPreferredDisplay) {
} else if (isPreferredDisplayArea) {
// Note: since the traversing through the stacks is top down, the floating
// tasks should always have lower priority than any affinity-matching tasks
// in the fullscreen stacks

View File

@@ -125,7 +125,7 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase {
spyOn(taskChangeNotifier);
mSupervisor.handleNonResizableTaskIfNeeded(task, newDisplay.getWindowingMode(),
newDisplay.mDisplayId, stack);
newDisplay.getDefaultTaskDisplayArea(), stack);
// The top activity is unresizable, so it should notify the activity is forced resizing.
verify(taskChangeNotifier).notifyActivityForcedResizable(eq(task.mTaskId),
eq(FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY),
@@ -138,7 +138,7 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase {
resizableActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
mSupervisor.handleNonResizableTaskIfNeeded(task, newDisplay.getWindowingMode(),
newDisplay.mDisplayId, stack);
newDisplay.getDefaultTaskDisplayArea(), stack);
// For the resizable activity, it is no need to force resizing or dismiss the docked stack.
verify(taskChangeNotifier, never()).notifyActivityForcedResizable(anyInt() /* taskId */,
anyInt() /* reason */, anyString() /* packageName */);

View File

@@ -23,12 +23,14 @@ import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
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.spyOn;
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;
@@ -54,6 +56,7 @@ import com.android.server.wm.LaunchParamsController.LaunchParamsModifier;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.Map;
@@ -65,6 +68,7 @@ import java.util.Map;
*/
@MediumTest
@Presubmit
@RunWith(WindowTestRunner.class)
public class LaunchParamsControllerTests extends ActivityTestsBase {
private LaunchParamsController mController;
private TestLaunchParamsPersister mPersister;
@@ -276,16 +280,21 @@ public class LaunchParamsControllerTests extends ActivityTestsBase {
@Test
public void testLayoutTaskPreferredDisplayChange() {
final LaunchParams params = new LaunchParams();
params.mPreferredDisplayId = 2;
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;
final InstrumentedPositioner positioner = new InstrumentedPositioner(RESULT_DONE, params);
final Task task = new TaskBuilder(mService.mStackSupervisor).build();
mController.registerModifier(positioner);
doNothing().when(mService).moveStackToDisplay(anyInt(), anyInt());
doNothing().when(mRootWindowContainer).moveStackToTaskDisplayArea(anyInt(), any(),
anyBoolean());
mController.layoutTask(task, null /* windowLayout */);
verify(mService, times(1)).moveStackToDisplay(eq(task.getRootTaskId()),
eq(params.mPreferredDisplayId));
verify(mRootWindowContainer, times(1)).moveStackToTaskDisplayArea(eq(task.getRootTaskId()),
eq(preferredTaskDisplayArea), anyBoolean());
}
/**
@@ -452,4 +461,14 @@ public class LaunchParamsControllerTests extends ActivityTestsBase {
}
}
}
private TestDisplayContent createNewDisplayContent() {
final TestDisplayContent display = addNewDisplayContentAt(DisplayContent.POSITION_TOP);
spyOn(display.mDisplayContent.mDisplayFrames);
// We didn't set up the overall environment for this test, so we need to mute the side
// effect of layout passes that loosen the stable frame.
doNothing().when(display.mDisplayContent.mDisplayFrames).onBeginLayout();
return display;
}
}

View File

@@ -439,7 +439,7 @@ public class RootActivityContainerTests extends ActivityTestsBase {
taskDisplayArea.getRootHomeTask().removeIfPossible();
taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
doReturn(true).when(mRootWindowContainer).resumeHomeActivity(any(), any(), anyInt());
doReturn(true).when(mRootWindowContainer).resumeHomeActivity(any(), any(), any());
mService.setBooted(true);
@@ -447,7 +447,7 @@ public class RootActivityContainerTests extends ActivityTestsBase {
mRootWindowContainer.resumeFocusedStacksTopActivities();
// Verify that home activity was started on the default display
verify(mRootWindowContainer).resumeHomeActivity(any(), any(), eq(DEFAULT_DISPLAY));
verify(mRootWindowContainer).resumeHomeActivity(any(), any(), eq(taskDisplayArea));
}
/**
@@ -469,7 +469,7 @@ public class RootActivityContainerTests extends ActivityTestsBase {
final Task task = new TaskBuilder(mSupervisor).setStack(stack).build();
new ActivityBuilder(mService).setTask(task).build();
doReturn(true).when(mRootWindowContainer).resumeHomeActivity(any(), any(), anyInt());
doReturn(true).when(mRootWindowContainer).resumeHomeActivity(any(), any(), any());
mService.setBooted(true);
@@ -477,7 +477,7 @@ public class RootActivityContainerTests extends ActivityTestsBase {
mRootWindowContainer.resumeFocusedStacksTopActivities();
// Verify that home activity was started on the default display
verify(mRootWindowContainer).resumeHomeActivity(any(), any(), eq(DEFAULT_DISPLAY));
verify(mRootWindowContainer).resumeHomeActivity(any(), any(), eq(taskDisplayArea));
}
/**
@@ -614,8 +614,7 @@ public class RootActivityContainerTests extends ActivityTestsBase {
secondDisplay.mDisplayId, true /* allowInstrumenting */, true /* fromHomeKey */);
try {
verify(mRootWindowContainer, never()).resolveSecondaryHomeActivity(anyInt(),
anyInt());
verify(mRootWindowContainer, never()).resolveSecondaryHomeActivity(anyInt(), any());
} finally {
mRootWindowContainer.mCurrentUser = currentUser;
}
@@ -635,7 +634,7 @@ public class RootActivityContainerTests extends ActivityTestsBase {
mRootWindowContainer.startHomeOnDisplay(0 /* userId */, "testStartSecondaryHome",
secondDisplay.mDisplayId, true /* allowInstrumenting */, true /* fromHomeKey */);
verify(mRootWindowContainer, never()).resolveSecondaryHomeActivity(anyInt(), anyInt());
verify(mRootWindowContainer, never()).resolveSecondaryHomeActivity(anyInt(), any());
}
/**
@@ -673,7 +672,7 @@ public class RootActivityContainerTests extends ActivityTestsBase {
// Run the test.
final Pair<ActivityInfo, Intent> resolvedInfo = mRootWindowContainer
.resolveSecondaryHomeActivity(0 /* userId */, 1 /* displayId */);
.resolveSecondaryHomeActivity(0 /* userId */, mock(TaskDisplayArea.class));
final ActivityInfo aInfoSecondary = getFakeHomeActivityInfo(false /* primaryHome*/);
assertEquals(aInfoSecondary.name, resolvedInfo.first.name);
assertEquals(aInfoSecondary.applicationInfo.packageName,
@@ -704,7 +703,7 @@ public class RootActivityContainerTests extends ActivityTestsBase {
// Run the test.
final Pair<ActivityInfo, Intent> resolvedInfo = mRootWindowContainer
.resolveSecondaryHomeActivity(0 /* userId */, 1 /* displayId */);
.resolveSecondaryHomeActivity(0 /* userId */, mock(TaskDisplayArea.class));
assertEquals(aInfoSecondary.name, resolvedInfo.first.name);
assertEquals(aInfoSecondary.applicationInfo.packageName,
resolvedInfo.first.applicationInfo.packageName);
@@ -725,7 +724,7 @@ public class RootActivityContainerTests extends ActivityTestsBase {
// Run the test.
final Pair<ActivityInfo, Intent> resolvedInfo = mRootWindowContainer
.resolveSecondaryHomeActivity(0 /* userId */, 1 /* displayId */);
.resolveSecondaryHomeActivity(0 /* userId */, mock(TaskDisplayArea.class));
final ActivityInfo aInfoSecondary = getFakeHomeActivityInfo(false /* primaryHome*/);
assertEquals(aInfoSecondary.name, resolvedInfo.first.name);
assertEquals(aInfoSecondary.applicationInfo.packageName,
@@ -757,7 +756,7 @@ public class RootActivityContainerTests extends ActivityTestsBase {
// Run the test.
final Pair<ActivityInfo, Intent> resolvedInfo = mRootWindowContainer
.resolveSecondaryHomeActivity(0 /* userId */, 1 /* displayId */);
.resolveSecondaryHomeActivity(0 /* userId */, mock(TaskDisplayArea.class));
assertEquals(aInfoPrimary.name, resolvedInfo.first.name);
assertEquals(aInfoPrimary.applicationInfo.packageName,
resolvedInfo.first.applicationInfo.packageName);
@@ -791,7 +790,7 @@ public class RootActivityContainerTests extends ActivityTestsBase {
// Use the first one of matched activities in the same package as selected primary home.
final Pair<ActivityInfo, Intent> resolvedInfo = mRootWindowContainer
.resolveSecondaryHomeActivity(0 /* userId */, 1 /* displayId */);
.resolveSecondaryHomeActivity(0 /* userId */, mock(TaskDisplayArea.class));
assertEquals(infoFake1.activityInfo.applicationInfo.packageName,
resolvedInfo.first.applicationInfo.packageName);
@@ -901,7 +900,7 @@ public class RootActivityContainerTests extends ActivityTestsBase {
.getSecondaryHomeIntent(null /* preferredPackage */);
final ActivityInfo aInfoSecondary = getFakeHomeActivityInfo(false);
doReturn(Pair.create(aInfoSecondary, secondaryHomeIntent)).when(mRootWindowContainer)
.resolveSecondaryHomeActivity(anyInt(), anyInt());
.resolveSecondaryHomeActivity(anyInt(), any());
}
private ActivityInfo getFakeHomeActivityInfo(boolean primaryHome) {