Merge "Make LaunchingTaskPositioner stateless."

This commit is contained in:
Bryce Lee
2017-10-12 14:44:46 +00:00
committed by Android (Google) Code Review
3 changed files with 88 additions and 104 deletions

View File

@@ -358,8 +358,6 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
/** Run all ActivityStacks through this */
protected final ActivityStackSupervisor mStackSupervisor;
private final LaunchingTaskPositioner mTaskPositioner;
private boolean mTopActivityOccludesKeyguard;
private ActivityRecord mTopDismissingKeyguardActivity;
@@ -462,8 +460,6 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
mWindowManager = mService.mWindowManager;
mStackId = stackId;
mCurrentUser = mService.mUserController.getCurrentUserId();
mTaskPositioner = windowingMode == WINDOWING_MODE_FREEFORM
? new LaunchingTaskPositioner() : null;
mTmpRect2.setEmpty();
setWindowingMode(windowingMode);
setActivityType(activityType);
@@ -504,11 +500,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
mDisplayId = activityDisplay.mDisplayId;
mBounds = bounds != null ? new Rect(bounds) : null;
mFullscreen = mBounds == null;
if (mTaskPositioner != null) {
activityDisplay.mDisplay.getSize(mTmpSize);
mTaskPositioner.setDisplaySize(mTmpSize);
mTaskPositioner.configure(mBounds);
}
onParentChanged();
activityDisplay.addChild(this, onTop ? POSITION_TOP : POSITION_BOTTOM);
@@ -536,9 +528,6 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
display.removeChild(this);
}
mDisplayId = INVALID_DISPLAY;
if (mTaskPositioner != null) {
mTaskPositioner.reset();
}
}
/** Removes the stack completely. Also calls WindowManager to do the same on its side. */
@@ -642,9 +631,6 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
void setBounds(Rect bounds) {
mBounds = mFullscreen ? null : new Rect(bounds);
if (mTaskPositioner != null) {
mTaskPositioner.configure(bounds);
}
}
ActivityRecord topRunningActivityLocked() {
@@ -5137,10 +5123,12 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
}
boolean layoutTaskInStack(TaskRecord task, ActivityInfo.WindowLayout windowLayout) {
if (mTaskPositioner == null) {
if (!task.inFreeformWindowingMode()) {
return false;
}
mTaskPositioner.updateDefaultBounds(task, mTaskHistory, windowLayout);
mStackSupervisor.getLaunchingTaskPositioner()
.updateDefaultBounds(task, mTaskHistory, windowLayout);
return true;
}

View File

@@ -293,6 +293,8 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
WindowManagerService mWindowManager;
DisplayManager mDisplayManager;
LaunchingTaskPositioner mTaskPositioner = new LaunchingTaskPositioner();
/** Counter for next free stack ID to use for dynamic activity stacks. */
private int mNextFreeStackId = 0;
@@ -2138,6 +2140,10 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
|| mService.mSupportsFreeformWindowManagement;
}
LaunchingTaskPositioner getLaunchingTaskPositioner() {
return mTaskPositioner;
}
protected <T extends ActivityStack> T getStack(int stackId) {
for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
final T stack = mActivityDisplays.valueAt(i).getStack(stackId);

View File

@@ -64,23 +64,12 @@ class LaunchingTaskPositioner {
private static final int SHIFT_POLICY_HORIZONTAL_RIGHT = 2;
private static final int SHIFT_POLICY_HORIZONTAL_LEFT = 3;
private boolean mDefaultStartBoundsConfigurationSet = false;
private final Rect mAvailableRect = new Rect();
private final Rect mTmpProposal = new Rect();
private final Rect mTmpOriginal = new Rect();
private int mDefaultFreeformStartX;
private int mDefaultFreeformStartY;
private int mDefaultFreeformWidth;
private int mDefaultFreeformHeight;
private int mDefaultFreeformStepHorizontal;
private int mDefaultFreeformStepVertical;
private final Point mDisplaySize = new Point();
void setDisplaySize(Point size) {
mDisplaySize.set(size.x, size.y);
}
/**
* Tries to set task's bound in a way that it won't collide with any other task. By colliding
* we mean that two tasks have left-top corner very close to each other, so one might get
@@ -93,52 +82,47 @@ class LaunchingTaskPositioner {
*/
void updateDefaultBounds(TaskRecord task, ArrayList<TaskRecord> tasks,
@Nullable ActivityInfo.WindowLayout windowLayout) {
if (!mDefaultStartBoundsConfigurationSet) {
return;
}
updateAvailableRect(task, mAvailableRect);
if (windowLayout == null) {
positionCenter(task, tasks, mDefaultFreeformWidth, mDefaultFreeformHeight);
positionCenter(task, tasks, mAvailableRect, getFreeformWidth(mAvailableRect),
getFreeformHeight(mAvailableRect));
return;
}
int width = getFinalWidth(windowLayout);
int height = getFinalHeight(windowLayout);
int width = getFinalWidth(windowLayout, mAvailableRect);
int height = getFinalHeight(windowLayout, mAvailableRect);
int verticalGravity = windowLayout.gravity & Gravity.VERTICAL_GRAVITY_MASK;
int horizontalGravity = windowLayout.gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
if (verticalGravity == Gravity.TOP) {
if (horizontalGravity == Gravity.RIGHT) {
positionTopRight(task, tasks, width, height);
positionTopRight(task, tasks, mAvailableRect, width, height);
} else {
positionTopLeft(task, tasks, width, height);
positionTopLeft(task, tasks, mAvailableRect, width, height);
}
} else if (verticalGravity == Gravity.BOTTOM) {
if (horizontalGravity == Gravity.RIGHT) {
positionBottomRight(task, tasks, width, height);
positionBottomRight(task, tasks, mAvailableRect, width, height);
} else {
positionBottomLeft(task, tasks, width, height);
positionBottomLeft(task, tasks, mAvailableRect, width, height);
}
} else {
// Some fancy gravity setting that we don't support yet. We just put the activity in the
// center.
Slog.w(TAG, "Received unsupported gravity: " + windowLayout.gravity
+ ", positioning in the center instead.");
positionCenter(task, tasks, width, height);
positionCenter(task, tasks, mAvailableRect, width, height);
}
}
void configure(Rect availableSpace) {
if (availableSpace == null) {
mAvailableRect.set(0, 0, mDisplaySize.x, mDisplaySize.y);
} else {
mAvailableRect.set(availableSpace);
}
private void updateAvailableRect(TaskRecord task, Rect availableRect) {
final Rect stackBounds = task.getStack().mBounds;
mDefaultFreeformStartX = getFreeformStartLeft(mAvailableRect);
mDefaultFreeformStartY = getFreeformStartTop(mAvailableRect);
mDefaultFreeformWidth = getFreeformWidth(mAvailableRect);
mDefaultFreeformHeight = getFreeformHeight(mAvailableRect);
mDefaultFreeformStepHorizontal = getHorizontalStep(mAvailableRect);
mDefaultFreeformStepVertical = getVerticalStep(mAvailableRect);
mDefaultStartBoundsConfigurationSet = true;
if (stackBounds != null) {
availableRect.set(stackBounds);
} else {
task.getStack().getDisplay().mDisplay.getSize(mDisplaySize);
availableRect.set(0, 0, mDisplaySize.x, mDisplaySize.y);
}
}
@VisibleForTesting
@@ -173,72 +157,79 @@ class LaunchingTaskPositioner {
private int getFinalWidth(ActivityInfo.WindowLayout windowLayout) {
int width = mDefaultFreeformWidth;
private int getFinalWidth(ActivityInfo.WindowLayout windowLayout, Rect availableRect) {
int width = getFreeformWidth(availableRect);
if (windowLayout.width > 0) {
width = windowLayout.width;
}
if (windowLayout.widthFraction > 0) {
width = (int) (mAvailableRect.width() * windowLayout.widthFraction);
width = (int) (availableRect.width() * windowLayout.widthFraction);
}
return width;
}
private int getFinalHeight(ActivityInfo.WindowLayout windowLayout) {
int height = mDefaultFreeformHeight;
private int getFinalHeight(ActivityInfo.WindowLayout windowLayout, Rect availableRect) {
int height = getFreeformHeight(availableRect);
if (windowLayout.height > 0) {
height = windowLayout.height;
}
if (windowLayout.heightFraction > 0) {
height = (int) (mAvailableRect.height() * windowLayout.heightFraction);
height = (int) (availableRect.height() * windowLayout.heightFraction);
}
return height;
}
private void positionBottomLeft(TaskRecord task, ArrayList<TaskRecord> tasks, int width,
int height) {
mTmpProposal.set(mAvailableRect.left, mAvailableRect.bottom - height,
mAvailableRect.left + width, mAvailableRect.bottom);
position(task, tasks, mTmpProposal, !ALLOW_RESTART, SHIFT_POLICY_HORIZONTAL_RIGHT);
private void positionBottomLeft(TaskRecord task, ArrayList<TaskRecord> tasks,
Rect availableRect, int width, int height) {
mTmpProposal.set(availableRect.left, availableRect.bottom - height,
availableRect.left + width, availableRect.bottom);
position(task, tasks, availableRect, mTmpProposal, !ALLOW_RESTART,
SHIFT_POLICY_HORIZONTAL_RIGHT);
}
private void positionBottomRight(TaskRecord task, ArrayList<TaskRecord> tasks, int width,
int height) {
mTmpProposal.set(mAvailableRect.right - width, mAvailableRect.bottom - height,
mAvailableRect.right, mAvailableRect.bottom);
position(task, tasks, mTmpProposal, !ALLOW_RESTART, SHIFT_POLICY_HORIZONTAL_LEFT);
private void positionBottomRight(TaskRecord task, ArrayList<TaskRecord> tasks,
Rect availableRect, int width, int height) {
mTmpProposal.set(availableRect.right - width, availableRect.bottom - height,
availableRect.right, availableRect.bottom);
position(task, tasks, availableRect, mTmpProposal, !ALLOW_RESTART,
SHIFT_POLICY_HORIZONTAL_LEFT);
}
private void positionTopLeft(TaskRecord task, ArrayList<TaskRecord> tasks, int width,
int height) {
mTmpProposal.set(mAvailableRect.left, mAvailableRect.top,
mAvailableRect.left + width, mAvailableRect.top + height);
position(task, tasks, mTmpProposal, !ALLOW_RESTART, SHIFT_POLICY_HORIZONTAL_RIGHT);
private void positionTopLeft(TaskRecord task, ArrayList<TaskRecord> tasks,
Rect availableRect, int width, int height) {
mTmpProposal.set(availableRect.left, availableRect.top,
availableRect.left + width, availableRect.top + height);
position(task, tasks, availableRect, mTmpProposal, !ALLOW_RESTART,
SHIFT_POLICY_HORIZONTAL_RIGHT);
}
private void positionTopRight(TaskRecord task, ArrayList<TaskRecord> tasks, int width,
int height) {
mTmpProposal.set(mAvailableRect.right - width, mAvailableRect.top,
mAvailableRect.right, mAvailableRect.top + height);
position(task, tasks, mTmpProposal, !ALLOW_RESTART, SHIFT_POLICY_HORIZONTAL_LEFT);
private void positionTopRight(TaskRecord task, ArrayList<TaskRecord> tasks,
Rect availableRect, int width, int height) {
mTmpProposal.set(availableRect.right - width, availableRect.top,
availableRect.right, availableRect.top + height);
position(task, tasks, availableRect, mTmpProposal, !ALLOW_RESTART,
SHIFT_POLICY_HORIZONTAL_LEFT);
}
private void positionCenter(TaskRecord task, ArrayList<TaskRecord> tasks, int width,
int height) {
mTmpProposal.set(mDefaultFreeformStartX, mDefaultFreeformStartY,
mDefaultFreeformStartX + width, mDefaultFreeformStartY + height);
position(task, tasks, mTmpProposal, ALLOW_RESTART, SHIFT_POLICY_DIAGONAL_DOWN);
private void positionCenter(TaskRecord task, ArrayList<TaskRecord> tasks,
Rect availableRect, int width, int height) {
final int defaultFreeformLeft = getFreeformStartLeft(availableRect);
final int defaultFreeformTop = getFreeformStartTop(availableRect);
mTmpProposal.set(defaultFreeformLeft, defaultFreeformTop,
defaultFreeformLeft + width, defaultFreeformTop + height);
position(task, tasks, availableRect, mTmpProposal, ALLOW_RESTART,
SHIFT_POLICY_DIAGONAL_DOWN);
}
private void position(TaskRecord task, ArrayList<TaskRecord> tasks, Rect proposal,
boolean allowRestart, int shiftPolicy) {
private void position(TaskRecord task, ArrayList<TaskRecord> tasks, Rect availableRect,
Rect proposal, boolean allowRestart, int shiftPolicy) {
mTmpOriginal.set(proposal);
boolean restarted = false;
while (boundsConflict(proposal, tasks)) {
// Unfortunately there is already a task at that spot, so we need to look for some
// other place.
shiftStartingPoint(proposal, shiftPolicy);
if (shiftedTooFar(proposal, shiftPolicy)) {
shiftStartingPoint(proposal, availableRect, shiftPolicy);
if (shiftedTooFar(proposal, availableRect, shiftPolicy)) {
// We don't want the task to go outside of the stack, because it won't look
// nice. Depending on the starting point we either restart, or immediately give up.
if (!allowRestart) {
@@ -247,13 +238,13 @@ class LaunchingTaskPositioner {
}
// We must have started not from the top. Let's restart from there because there
// might be some space there.
proposal.set(mAvailableRect.left, mAvailableRect.top,
mAvailableRect.left + proposal.width(),
mAvailableRect.top + proposal.height());
proposal.set(availableRect.left, availableRect.top,
availableRect.left + proposal.width(),
availableRect.top + proposal.height());
restarted = true;
}
if (restarted && (proposal.left > mDefaultFreeformStartX
|| proposal.top > mDefaultFreeformStartY)) {
if (restarted && (proposal.left > getFreeformStartLeft(availableRect)
|| proposal.top > getFreeformStartTop(availableRect))) {
// If we restarted and crossed the initial position, let's not struggle anymore.
// The user already must have ton of tasks visible, we can just smack the new
// one in the center.
@@ -264,27 +255,30 @@ class LaunchingTaskPositioner {
task.updateOverrideConfiguration(proposal);
}
private boolean shiftedTooFar(Rect start, int shiftPolicy) {
private boolean shiftedTooFar(Rect start, Rect availableRect, int shiftPolicy) {
switch (shiftPolicy) {
case SHIFT_POLICY_HORIZONTAL_LEFT:
return start.left < mAvailableRect.left;
return start.left < availableRect.left;
case SHIFT_POLICY_HORIZONTAL_RIGHT:
return start.right > mAvailableRect.right;
return start.right > availableRect.right;
default: // SHIFT_POLICY_DIAGONAL_DOWN
return start.right > mAvailableRect.right || start.bottom > mAvailableRect.bottom;
return start.right > availableRect.right || start.bottom > availableRect.bottom;
}
}
private void shiftStartingPoint(Rect posposal, int shiftPolicy) {
private void shiftStartingPoint(Rect posposal, Rect availableRect, int shiftPolicy) {
final int defaultFreeformStepHorizontal = getHorizontalStep(availableRect);
final int defaultFreeformStepVertical = getVerticalStep(availableRect);
switch (shiftPolicy) {
case SHIFT_POLICY_HORIZONTAL_LEFT:
posposal.offset(-mDefaultFreeformStepHorizontal, 0);
posposal.offset(-defaultFreeformStepHorizontal, 0);
break;
case SHIFT_POLICY_HORIZONTAL_RIGHT:
posposal.offset(mDefaultFreeformStepHorizontal, 0);
posposal.offset(defaultFreeformStepHorizontal, 0);
break;
default: // SHIFT_POLICY_DIAGONAL_DOWN:
posposal.offset(mDefaultFreeformStepHorizontal, mDefaultFreeformStepVertical);
posposal.offset(defaultFreeformStepHorizontal, defaultFreeformStepVertical);
break;
}
}
@@ -323,8 +317,4 @@ class LaunchingTaskPositioner {
return Math.abs(first.right - second.right) < BOUNDS_CONFLICT_MIN_DISTANCE
&& Math.abs(first.bottom - second.bottom) < BOUNDS_CONFLICT_MIN_DISTANCE;
}
void reset() {
mDefaultStartBoundsConfigurationSet = false;
}
}