diff options
Diffstat (limited to 'com/android/server/am/LaunchingTaskPositioner.java')
-rw-r--r-- | com/android/server/am/LaunchingTaskPositioner.java | 211 |
1 files changed, 114 insertions, 97 deletions
diff --git a/com/android/server/am/LaunchingTaskPositioner.java b/com/android/server/am/LaunchingTaskPositioner.java index d6523418..0dc73e98 100644 --- a/com/android/server/am/LaunchingTaskPositioner.java +++ b/com/android/server/am/LaunchingTaskPositioner.java @@ -24,8 +24,8 @@ import android.content.pm.ActivityInfo; import android.graphics.Point; import android.graphics.Rect; import android.util.Slog; -import android.view.Display; import android.view.Gravity; +import com.android.internal.annotations.VisibleForTesting; import java.util.ArrayList; @@ -64,43 +64,11 @@ 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 int mDisplayWidth; - private int mDisplayHeight; - - void setDisplay(Display display) { - Point size = new Point(); - display.getSize(size); - mDisplayWidth = size.x; - mDisplayHeight = size.y; - } - - void configure(Rect stackBounds) { - if (stackBounds == null) { - mAvailableRect.set(0, 0, mDisplayWidth, mDisplayHeight); - } else { - mAvailableRect.set(stackBounds); - } - int width = mAvailableRect.width(); - int height = mAvailableRect.height(); - mDefaultFreeformStartX = mAvailableRect.left + width / MARGIN_SIZE_DENOMINATOR; - mDefaultFreeformStartY = mAvailableRect.top + height / MARGIN_SIZE_DENOMINATOR; - mDefaultFreeformWidth = width / WINDOW_SIZE_DENOMINATOR; - mDefaultFreeformHeight = height / WINDOW_SIZE_DENOMINATOR; - mDefaultFreeformStepHorizontal = Math.max(width / STEP_DENOMINATOR, MINIMAL_STEP); - mDefaultFreeformStepVertical = Math.max(height / STEP_DENOMINATOR, MINIMAL_STEP); - mDefaultStartBoundsConfigurationSet = true; - } + private final Point mDisplaySize = new Point(); /** * Tries to set task's bound in a way that it won't collide with any other task. By colliding @@ -114,104 +82,154 @@ 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); } } - private int getFinalWidth(ActivityInfo.WindowLayout windowLayout) { - int width = mDefaultFreeformWidth; + private void updateAvailableRect(TaskRecord task, Rect availableRect) { + final Rect stackBounds = task.getStack().mBounds; + + if (stackBounds != null) { + availableRect.set(stackBounds); + } else { + task.getStack().getDisplay().mDisplay.getSize(mDisplaySize); + availableRect.set(0, 0, mDisplaySize.x, mDisplaySize.y); + } + } + + @VisibleForTesting + static int getFreeformStartLeft(Rect bounds) { + return bounds.left + bounds.width() / MARGIN_SIZE_DENOMINATOR; + } + + @VisibleForTesting + static int getFreeformStartTop(Rect bounds) { + return bounds.top + bounds.height() / MARGIN_SIZE_DENOMINATOR; + } + + @VisibleForTesting + static int getFreeformWidth(Rect bounds) { + return bounds.width() / WINDOW_SIZE_DENOMINATOR; + } + + @VisibleForTesting + static int getFreeformHeight(Rect bounds) { + return bounds.height() / WINDOW_SIZE_DENOMINATOR; + } + + @VisibleForTesting + static int getHorizontalStep(Rect bounds) { + return Math.max(bounds.width() / STEP_DENOMINATOR, MINIMAL_STEP); + } + + @VisibleForTesting + static int getVerticalStep(Rect bounds) { + return Math.max(bounds.height() / STEP_DENOMINATOR, MINIMAL_STEP); + } + + + + 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 (shiftedToFar(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) { @@ -220,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. @@ -237,27 +255,30 @@ class LaunchingTaskPositioner { task.updateOverrideConfiguration(proposal); } - private boolean shiftedToFar(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; } } @@ -296,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; - } } |