Merge "[wm] Add tests to check adjust bounds logic will always exit" into qt-dev

This commit is contained in:
TreeHugger Robot
2019-04-23 15:57:37 +00:00
committed by Android (Google) Code Review
2 changed files with 60 additions and 22 deletions

View File

@@ -274,7 +274,7 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
}
// Even though we want to keep original bounds, we still don't want it to stomp on
// an existing task.
adjustBoundsToAvoidConflict(display, outParams.mBounds);
adjustBoundsToAvoidConflictInDisplay(display, outParams.mBounds);
}
} else {
if (source != null && source.inFreeformWindowingMode()
@@ -534,7 +534,7 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
}
// Lastly we adjust bounds to avoid conflicts with other tasks as much as possible.
adjustBoundsToAvoidConflict(display, inOutBounds);
adjustBoundsToAvoidConflictInDisplay(display, inOutBounds);
}
private int convertOrientationToScreenOrientation(int orientation) {
@@ -678,16 +678,9 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
* @param display the display which tasks are to check
* @param inOutBounds the bounds used to input initial bounds and output result bounds
*/
private void adjustBoundsToAvoidConflict(@NonNull ActivityDisplay display,
private void adjustBoundsToAvoidConflictInDisplay(@NonNull ActivityDisplay display,
@NonNull Rect inOutBounds) {
final Rect displayBounds = display.getBounds();
if (!displayBounds.contains(inOutBounds)) {
// The initial bounds are already out of display. The scanning algorithm below doesn't
// work so well with them.
return;
}
final List<TaskRecord> tasksToCheck = new ArrayList<>();
final List<Rect> taskBoundsToCheck = new ArrayList<>();
for (int i = 0; i < display.getChildCount(); ++i) {
final ActivityStack stack = display.getChildAt(i);
if (!stack.inFreeformWindowingMode()) {
@@ -695,11 +688,35 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
}
for (int j = 0; j < stack.getChildCount(); ++j) {
tasksToCheck.add(stack.getChildAt(j));
taskBoundsToCheck.add(stack.getChildAt(j).getBounds());
}
}
adjustBoundsToAvoidConflict(display.getBounds(), taskBoundsToCheck, inOutBounds);
}
if (!boundsConflict(tasksToCheck, inOutBounds)) {
/**
* Adjusts input bounds to avoid conflict with provided display bounds and list of tasks bounds
* for the display.
*
* Scans the bounds in directions to find a candidate location that does not conflict with the
* provided list of task bounds. If starting bounds are outside the display bounds or if no
* suitable candidate bounds are found, the method returns the input bounds.
*
* @param displayBounds display bounds used to restrict the candidate bounds
* @param taskBoundsToCheck list of task bounds to check for conflict
* @param inOutBounds the bounds used to input initial bounds and output result bounds
*/
@VisibleForTesting
void adjustBoundsToAvoidConflict(@NonNull Rect displayBounds,
@NonNull List<Rect> taskBoundsToCheck,
@NonNull Rect inOutBounds) {
if (!displayBounds.contains(inOutBounds)) {
// The initial bounds are already out of display. The scanning algorithm below doesn't
// work so well with them.
return;
}
if (!boundsConflict(taskBoundsToCheck, inOutBounds)) {
// Current proposal doesn't conflict with any task. Early return to avoid unnecessary
// calculation.
return;
@@ -713,11 +730,13 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
}
mTmpBounds.set(inOutBounds);
while (boundsConflict(tasksToCheck, mTmpBounds) && displayBounds.contains(mTmpBounds)) {
while (boundsConflict(taskBoundsToCheck, mTmpBounds)
&& displayBounds.contains(mTmpBounds)) {
shiftBounds(direction, displayBounds, mTmpBounds);
}
if (!boundsConflict(tasksToCheck, mTmpBounds) && displayBounds.contains(mTmpBounds)) {
if (!boundsConflict(taskBoundsToCheck, mTmpBounds)
&& displayBounds.contains(mTmpBounds)) {
// Found a candidate. Just use this.
inOutBounds.set(mTmpBounds);
if (DEBUG) appendLog("avoid-bounds-conflict=" + inOutBounds);
@@ -772,16 +791,16 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
mTmpDirections[1] = Gravity.TOP | Gravity.LEFT;
}
private boolean boundsConflict(@NonNull List<TaskRecord> tasks, @NonNull Rect bounds) {
for (TaskRecord task : tasks) {
final Rect taskBounds = task.getBounds();
final boolean leftClose = Math.abs(taskBounds.left - bounds.left)
private boolean boundsConflict(@NonNull List<Rect> taskBoundsToCheck,
@NonNull Rect candidateBounds) {
for (Rect taskBounds : taskBoundsToCheck) {
final boolean leftClose = Math.abs(taskBounds.left - candidateBounds.left)
< BOUNDS_CONFLICT_THRESHOLD;
final boolean topClose = Math.abs(taskBounds.top - bounds.top)
final boolean topClose = Math.abs(taskBounds.top - candidateBounds.top)
< BOUNDS_CONFLICT_THRESHOLD;
final boolean rightClose = Math.abs(taskBounds.right - bounds.right)
final boolean rightClose = Math.abs(taskBounds.right - candidateBounds.right)
< BOUNDS_CONFLICT_THRESHOLD;
final boolean bottomClose = Math.abs(taskBounds.bottom - bounds.bottom)
final boolean bottomClose = Math.abs(taskBounds.bottom - candidateBounds.bottom)
< BOUNDS_CONFLICT_THRESHOLD;
if ((leftClose && topClose) || (leftClose && bottomClose) || (rightClose && topClose)

View File

@@ -52,6 +52,8 @@ import com.android.server.wm.LaunchParamsController.LaunchParams;
import org.junit.Before;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
/**
@@ -1206,6 +1208,23 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase {
assertEquals(new Rect(120, 0, 320, 100), mResult.mBounds);
}
@Test
public void testAdjustBoundsToAvoidConflictAlwaysExits() {
Rect displayBounds = new Rect(0, 0, 40, 40);
List<Rect> existingTaskBounds = new ArrayList<>();
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
int left = i * 5;
int top = j * 5;
existingTaskBounds.add(new Rect(left, top, left + 20, top + 20));
}
}
Rect startingBounds = new Rect(0, 0, 20, 20);
Rect adjustedBounds = new Rect(startingBounds);
mTarget.adjustBoundsToAvoidConflict(displayBounds, existingTaskBounds, adjustedBounds);
assertEquals(startingBounds, adjustedBounds);
}
private TestActivityDisplay createNewActivityDisplay(int windowingMode) {
final TestActivityDisplay display = addNewActivityDisplayAt(ActivityDisplay.POSITION_TOP);
display.setWindowingMode(windowingMode);