Merge "8/n Allow targeting task containers for activity launch" into rvc-dev am: 1a261f2f65 am: 2d0397bef1

Change-Id: I4834195333e455836e50de795ad7368db695e0df
This commit is contained in:
Andrii Kulian
2020-04-16 23:44:30 +00:00
committed by Automerger Merge Worker
15 changed files with 414 additions and 290 deletions

View File

@@ -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;
@@ -183,6 +184,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);
@@ -1244,6 +1255,18 @@ public class ActivityOptions {
return this;
}
/** @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);
}

View File

@@ -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();
}
}

View File

@@ -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,

View File

@@ -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.

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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;
// Next preference for stack goes to the taskDisplayArea candidate.
if (launchParams != null && launchParams.mPreferredTaskDisplayArea != null) {
taskDisplayArea = launchParams.mPreferredTaskDisplayArea;
}
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;
}
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()) {

View File

@@ -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,

View File

@@ -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;
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);
}
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;
// 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 (displayId != INVALID_DISPLAY
&& mSupervisor.mRootWindowContainer.getDisplayContent(displayId) == null) {
displayId = currentParams.mPreferredDisplayId;
if (taskDisplayArea == null) {
taskDisplayArea = currentParams.mPreferredTaskDisplayArea;
}
displayId = (displayId == INVALID_DISPLAY) ? currentParams.mPreferredDisplayId : displayId;
return (displayId != INVALID_DISPLAY
&& mSupervisor.mRootWindowContainer.getDisplayContent(displayId) != null)
? displayId : DEFAULT_DISPLAY;
// 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();
}
return (taskDisplayArea != null)
? taskDisplayArea
: mSupervisor.mRootWindowContainer.getDefaultTaskDisplayArea();
}
private boolean canInheritWindowingModeFromSource(@NonNull DisplayContent display,

View File

@@ -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.

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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;
}