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 // Even though we want to keep original bounds, we still don't want it to stomp on
// an existing task. // an existing task.
adjustBoundsToAvoidConflict(display, outParams.mBounds); adjustBoundsToAvoidConflictInDisplay(display, outParams.mBounds);
} }
} else { } else {
if (source != null && source.inFreeformWindowingMode() 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. // 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) { private int convertOrientationToScreenOrientation(int orientation) {
@@ -678,16 +678,9 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
* @param display the display which tasks are to check * @param display the display which tasks are to check
* @param inOutBounds the bounds used to input initial bounds and output result bounds * @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) { @NonNull Rect inOutBounds) {
final Rect displayBounds = display.getBounds(); final List<Rect> taskBoundsToCheck = new ArrayList<>();
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<>();
for (int i = 0; i < display.getChildCount(); ++i) { for (int i = 0; i < display.getChildCount(); ++i) {
final ActivityStack stack = display.getChildAt(i); final ActivityStack stack = display.getChildAt(i);
if (!stack.inFreeformWindowingMode()) { if (!stack.inFreeformWindowingMode()) {
@@ -695,11 +688,35 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
} }
for (int j = 0; j < stack.getChildCount(); ++j) { 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 // Current proposal doesn't conflict with any task. Early return to avoid unnecessary
// calculation. // calculation.
return; return;
@@ -713,11 +730,13 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
} }
mTmpBounds.set(inOutBounds); mTmpBounds.set(inOutBounds);
while (boundsConflict(tasksToCheck, mTmpBounds) && displayBounds.contains(mTmpBounds)) { while (boundsConflict(taskBoundsToCheck, mTmpBounds)
&& displayBounds.contains(mTmpBounds)) {
shiftBounds(direction, displayBounds, 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. // Found a candidate. Just use this.
inOutBounds.set(mTmpBounds); inOutBounds.set(mTmpBounds);
if (DEBUG) appendLog("avoid-bounds-conflict=" + inOutBounds); if (DEBUG) appendLog("avoid-bounds-conflict=" + inOutBounds);
@@ -772,16 +791,16 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
mTmpDirections[1] = Gravity.TOP | Gravity.LEFT; mTmpDirections[1] = Gravity.TOP | Gravity.LEFT;
} }
private boolean boundsConflict(@NonNull List<TaskRecord> tasks, @NonNull Rect bounds) { private boolean boundsConflict(@NonNull List<Rect> taskBoundsToCheck,
for (TaskRecord task : tasks) { @NonNull Rect candidateBounds) {
final Rect taskBounds = task.getBounds(); for (Rect taskBounds : taskBoundsToCheck) {
final boolean leftClose = Math.abs(taskBounds.left - bounds.left) final boolean leftClose = Math.abs(taskBounds.left - candidateBounds.left)
< BOUNDS_CONFLICT_THRESHOLD; < BOUNDS_CONFLICT_THRESHOLD;
final boolean topClose = Math.abs(taskBounds.top - bounds.top) final boolean topClose = Math.abs(taskBounds.top - candidateBounds.top)
< BOUNDS_CONFLICT_THRESHOLD; < BOUNDS_CONFLICT_THRESHOLD;
final boolean rightClose = Math.abs(taskBounds.right - bounds.right) final boolean rightClose = Math.abs(taskBounds.right - candidateBounds.right)
< BOUNDS_CONFLICT_THRESHOLD; < BOUNDS_CONFLICT_THRESHOLD;
final boolean bottomClose = Math.abs(taskBounds.bottom - bounds.bottom) final boolean bottomClose = Math.abs(taskBounds.bottom - candidateBounds.bottom)
< BOUNDS_CONFLICT_THRESHOLD; < BOUNDS_CONFLICT_THRESHOLD;
if ((leftClose && topClose) || (leftClose && bottomClose) || (rightClose && topClose) 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.Before;
import org.junit.Test; import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale; import java.util.Locale;
/** /**
@@ -1206,6 +1208,23 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase {
assertEquals(new Rect(120, 0, 320, 100), mResult.mBounds); 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) { private TestActivityDisplay createNewActivityDisplay(int windowingMode) {
final TestActivityDisplay display = addNewActivityDisplayAt(ActivityDisplay.POSITION_TOP); final TestActivityDisplay display = addNewActivityDisplayAt(ActivityDisplay.POSITION_TOP);
display.setWindowingMode(windowingMode); display.setWindowingMode(windowingMode);