1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.server.wm; 18 19 import org.junit.Before; 20 import org.junit.Ignore; 21 import org.junit.Test; 22 import org.junit.runner.RunWith; 23 24 import android.graphics.Rect; 25 import android.support.test.filters.SmallTest; 26 import android.support.test.runner.AndroidJUnit4; 27 import android.util.DisplayMetrics; 28 import android.util.Log; 29 import android.view.Display; 30 31 import static com.android.server.wm.TaskPositioner.MIN_ASPECT; 32 import static com.android.server.wm.WindowManagerService.dipToPixel; 33 import static com.android.server.wm.WindowState.MINIMUM_VISIBLE_HEIGHT_IN_DP; 34 import static com.android.server.wm.WindowState.MINIMUM_VISIBLE_WIDTH_IN_DP; 35 import static org.junit.Assert.assertEquals; 36 import static org.junit.Assert.assertNull; 37 import static org.junit.Assert.assertTrue; 38 39 /** 40 * Tests for the {@link TaskPositioner} class. 41 * 42 * runtest frameworks-services -c com.android.server.wm.TaskPositionerTests 43 */ 44 @SmallTest 45 @RunWith(AndroidJUnit4.class) 46 public class TaskPositionerTests extends WindowTestsBase { 47 48 private final boolean DEBUGGING = false; 49 private final String TAG = "TaskPositionerTest"; 50 51 private final static int MOUSE_DELTA_X = 5; 52 private final static int MOUSE_DELTA_Y = 5; 53 54 private int mMinVisibleWidth; 55 private int mMinVisibleHeight; 56 private TaskPositioner mPositioner; 57 58 @Before 59 public void setUp() throws Exception { 60 super.setUp(); 61 62 TaskPositioner.setFactory(null); 63 64 final Display display = mDisplayContent.getDisplay(); 65 final DisplayMetrics dm = new DisplayMetrics(); 66 display.getMetrics(dm); 67 68 // This should be the same calculation as the TaskPositioner uses. 69 mMinVisibleWidth = dipToPixel(MINIMUM_VISIBLE_WIDTH_IN_DP, dm); 70 mMinVisibleHeight = dipToPixel(MINIMUM_VISIBLE_HEIGHT_IN_DP, dm); 71 72 mPositioner = TaskPositioner.create(sWm); 73 mPositioner.register(mDisplayContent); 74 } 75 76 @Test 77 public void testOverrideFactory() throws Exception { 78 final boolean[] created = new boolean[1]; 79 created[0] = false; 80 TaskPositioner.setFactory(new TaskPositioner.Factory() { 81 @Override 82 public TaskPositioner create(WindowManagerService service) { 83 created[0] = true; 84 return null; 85 } 86 }); 87 88 assertNull(TaskPositioner.create(sWm)); 89 assertTrue(created[0]); 90 } 91 92 /** 93 * This tests that free resizing will allow to change the orientation as well 94 * as does some basic tests (e.g. dragging in Y only will keep X stable). 95 */ 96 @Test 97 @Ignore 98 public void testBasicFreeWindowResizing() throws Exception { 99 final Rect r = new Rect(100, 220, 700, 520); 100 final int midY = (r.top + r.bottom) / 2; 101 102 // Start a drag resize starting upper left. 103 mPositioner.startDrag(true /*resizing*/, 104 false /*preserveOrientation*/, r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y, r); 105 assertBoundsEquals(r, mPositioner.getWindowDragBounds()); 106 107 // Drag to a good landscape size. 108 mPositioner.resizeDrag(0.0f, 0.0f); 109 assertBoundsEquals(new Rect(MOUSE_DELTA_X, MOUSE_DELTA_Y, r.right, r.bottom), 110 mPositioner.getWindowDragBounds()); 111 112 // Drag to a good portrait size. 113 mPositioner.resizeDrag(400.0f, 0.0f); 114 assertBoundsEquals(new Rect(400 + MOUSE_DELTA_X, MOUSE_DELTA_Y, r.right, r.bottom), 115 mPositioner.getWindowDragBounds()); 116 117 // Drag to a too small size for the width. 118 mPositioner.resizeDrag(2000.0f, r.top); 119 assertBoundsEquals( 120 new Rect(r.right - mMinVisibleWidth, r.top + MOUSE_DELTA_Y, r.right, r.bottom), 121 mPositioner.getWindowDragBounds()); 122 123 // Drag to a too small size for the height. 124 mPositioner.resizeDrag(r.left, 2000.0f); 125 assertBoundsEquals( 126 new Rect(r.left + MOUSE_DELTA_X, r.bottom - mMinVisibleHeight, r.right, r.bottom), 127 mPositioner.getWindowDragBounds()); 128 129 // Start a drag resize left and see that only the left coord changes.. 130 mPositioner.startDrag(true /*resizing*/, 131 false /*preserveOrientation*/, r.left - MOUSE_DELTA_X, midY, r); 132 133 // Drag to the left. 134 mPositioner.resizeDrag(0.0f, midY); 135 assertBoundsEquals(new Rect(MOUSE_DELTA_X, r.top, r.right, r.bottom), 136 mPositioner.getWindowDragBounds()); 137 138 // Drag to the right. 139 mPositioner.resizeDrag(200.0f, midY); 140 assertBoundsEquals(new Rect(200 + MOUSE_DELTA_X, r.top, r.right, r.bottom), 141 mPositioner.getWindowDragBounds()); 142 143 // Drag to the top 144 mPositioner.resizeDrag(r.left, 0.0f); 145 assertBoundsEquals(new Rect(r.left + MOUSE_DELTA_X, r.top, r.right, r.bottom), 146 mPositioner.getWindowDragBounds()); 147 148 // Drag to the bottom 149 mPositioner.resizeDrag(r.left, 1000.0f); 150 assertBoundsEquals(new Rect(r.left + MOUSE_DELTA_X, r.top, r.right, r.bottom), 151 mPositioner.getWindowDragBounds()); 152 } 153 154 /** 155 * This tests that by dragging any edge, the fixed / opposite edge(s) remains anchored. 156 */ 157 @Test 158 @Ignore 159 public void testFreeWindowResizingTestAllEdges() throws Exception { 160 final Rect r = new Rect(100, 220, 700, 520); 161 final int midX = (r.left + r.right) / 2; 162 final int midY = (r.top + r.bottom) / 2; 163 164 // Drag upper left. 165 mPositioner.startDrag(true /*resizing*/, 166 false /*preserveOrientation*/, r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y, r); 167 mPositioner.resizeDrag(0.0f, 0.0f); 168 assertTrue(r.left != mPositioner.getWindowDragBounds().left); 169 assertEquals(r.right, mPositioner.getWindowDragBounds().right); 170 assertTrue(r.top != mPositioner.getWindowDragBounds().top); 171 assertEquals(r.bottom, mPositioner.getWindowDragBounds().bottom); 172 173 // Drag upper. 174 mPositioner.startDrag(true /*resizing*/, 175 false /*preserveOrientation*/, midX, r.top - MOUSE_DELTA_Y, r); 176 mPositioner.resizeDrag(0.0f, 0.0f); 177 assertEquals(r.left, mPositioner.getWindowDragBounds().left); 178 assertEquals(r.right, mPositioner.getWindowDragBounds().right); 179 assertTrue(r.top != mPositioner.getWindowDragBounds().top); 180 assertEquals(r.bottom, mPositioner.getWindowDragBounds().bottom); 181 182 // Drag upper right. 183 mPositioner.startDrag(true /*resizing*/, 184 false /*preserveOrientation*/, r.right + MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y, r); 185 mPositioner.resizeDrag(r.right + 100, 0.0f); 186 assertEquals(r.left, mPositioner.getWindowDragBounds().left); 187 assertTrue(r.right != mPositioner.getWindowDragBounds().right); 188 assertTrue(r.top != mPositioner.getWindowDragBounds().top); 189 assertEquals(r.bottom, mPositioner.getWindowDragBounds().bottom); 190 191 // Drag right. 192 mPositioner.startDrag(true /*resizing*/, 193 false /*preserveOrientation*/, r.right + MOUSE_DELTA_X, midY, r); 194 mPositioner.resizeDrag(r.right + 100, 0.0f); 195 assertEquals(r.left, mPositioner.getWindowDragBounds().left); 196 assertTrue(r.right != mPositioner.getWindowDragBounds().right); 197 assertEquals(r.top, mPositioner.getWindowDragBounds().top); 198 assertEquals(r.bottom, mPositioner.getWindowDragBounds().bottom); 199 200 // Drag bottom right. 201 mPositioner.startDrag(true /*resizing*/, 202 false /*preserveOrientation*/, 203 r.right + MOUSE_DELTA_X, r.bottom + MOUSE_DELTA_Y, r); 204 mPositioner.resizeDrag(r.right + 100, r.bottom + 100); 205 assertEquals(r.left, mPositioner.getWindowDragBounds().left); 206 assertTrue(r.right != mPositioner.getWindowDragBounds().right); 207 assertEquals(r.top, mPositioner.getWindowDragBounds().top); 208 assertTrue(r.bottom != mPositioner.getWindowDragBounds().bottom); 209 210 // Drag bottom. 211 mPositioner.startDrag(true /*resizing*/, 212 false /*preserveOrientation*/, midX, r.bottom + MOUSE_DELTA_Y, r); 213 mPositioner.resizeDrag(r.right + 100, r.bottom + 100); 214 assertEquals(r.left, mPositioner.getWindowDragBounds().left); 215 assertEquals(r.right, mPositioner.getWindowDragBounds().right); 216 assertEquals(r.top, mPositioner.getWindowDragBounds().top); 217 assertTrue(r.bottom != mPositioner.getWindowDragBounds().bottom); 218 219 // Drag bottom left. 220 mPositioner.startDrag(true /*resizing*/, 221 false /*preserveOrientation*/, r.left - MOUSE_DELTA_X, r.bottom + MOUSE_DELTA_Y, r); 222 mPositioner.resizeDrag(0.0f, r.bottom + 100); 223 assertTrue(r.left != mPositioner.getWindowDragBounds().left); 224 assertEquals(r.right, mPositioner.getWindowDragBounds().right); 225 assertEquals(r.top, mPositioner.getWindowDragBounds().top); 226 assertTrue(r.bottom != mPositioner.getWindowDragBounds().bottom); 227 228 // Drag left. 229 mPositioner.startDrag(true /*resizing*/, 230 false /*preserveOrientation*/, r.left - MOUSE_DELTA_X, midX, r); 231 mPositioner.resizeDrag(0.0f, r.bottom + 100); 232 assertTrue(r.left != mPositioner.getWindowDragBounds().left); 233 assertEquals(r.right, mPositioner.getWindowDragBounds().right); 234 assertEquals(r.top, mPositioner.getWindowDragBounds().top); 235 assertEquals(r.bottom, mPositioner.getWindowDragBounds().bottom); 236 } 237 238 /** 239 * This tests that a constrained landscape window will keep the aspect and do the 240 * right things upon resizing when dragged from the top left corner. 241 */ 242 @Test 243 @Ignore 244 public void testLandscapePreservedWindowResizingDragTopLeft() throws Exception { 245 final Rect r = new Rect(100, 220, 700, 520); 246 247 mPositioner.startDrag(true /*resizing*/, 248 true /*preserveOrientation*/, r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y, r); 249 assertBoundsEquals(r, mPositioner.getWindowDragBounds()); 250 251 // Drag to a good landscape size. 252 mPositioner.resizeDrag(0.0f, 0.0f); 253 assertBoundsEquals(new Rect(MOUSE_DELTA_X, MOUSE_DELTA_Y, r.right, r.bottom), 254 mPositioner.getWindowDragBounds()); 255 256 // Drag to a good portrait size. 257 mPositioner.resizeDrag(400.0f, 0.0f); 258 int width = Math.round((float) (r.bottom - MOUSE_DELTA_Y) * MIN_ASPECT); 259 assertBoundsEquals(new Rect(r.right - width, MOUSE_DELTA_Y, r.right, r.bottom), 260 mPositioner.getWindowDragBounds()); 261 262 // Drag to a too small size for the width. 263 mPositioner.resizeDrag(2000.0f, r.top); 264 final int w = mMinVisibleWidth; 265 final int h = Math.round(w / MIN_ASPECT); 266 assertBoundsEquals(new Rect(r.right - w, r.bottom - h, r.right, r.bottom), 267 mPositioner.getWindowDragBounds()); 268 269 // Drag to a too small size for the height. 270 mPositioner.resizeDrag(r.left, 2000.0f); 271 assertBoundsEquals( 272 new Rect(r.left + MOUSE_DELTA_X, r.bottom - mMinVisibleHeight, r.right, r.bottom), 273 mPositioner.getWindowDragBounds()); 274 } 275 276 /** 277 * This tests that a constrained landscape window will keep the aspect and do the 278 * right things upon resizing when dragged from the left corner. 279 */ 280 @Test 281 @Ignore 282 public void testLandscapePreservedWindowResizingDragLeft() throws Exception { 283 final Rect r = new Rect(100, 220, 700, 520); 284 final int midY = (r.top + r.bottom) / 2; 285 286 mPositioner.startDrag(true /*resizing*/, 287 true /*preserveOrientation*/, r.left - MOUSE_DELTA_X, midY, r); 288 289 // Drag to the left. 290 mPositioner.resizeDrag(0.0f, midY); 291 assertBoundsEquals(new Rect(MOUSE_DELTA_X, r.top, r.right, r.bottom), 292 mPositioner.getWindowDragBounds()); 293 294 // Drag to the right. 295 mPositioner.resizeDrag(200.0f, midY); 296 assertBoundsEquals(new Rect(200 + MOUSE_DELTA_X, r.top, r.right, r.bottom), 297 mPositioner.getWindowDragBounds()); 298 299 // Drag all the way to the right and see the height also shrinking. 300 mPositioner.resizeDrag(2000.0f, midY); 301 final int w = mMinVisibleWidth; 302 final int h = Math.round((float)w / MIN_ASPECT); 303 assertBoundsEquals(new Rect(r.right - w, r.top, r.right, r.top + h), 304 mPositioner.getWindowDragBounds()); 305 306 // Drag to the top. 307 mPositioner.resizeDrag(r.left, 0.0f); 308 assertBoundsEquals(new Rect(r.left + MOUSE_DELTA_X, r.top, r.right, r.bottom), 309 mPositioner.getWindowDragBounds()); 310 311 // Drag to the bottom. 312 mPositioner.resizeDrag(r.left, 1000.0f); 313 assertBoundsEquals(new Rect(r.left + MOUSE_DELTA_X, r.top, r.right, r.bottom), 314 mPositioner.getWindowDragBounds()); 315 } 316 317 /** 318 * This tests that a constrained landscape window will keep the aspect and do the 319 * right things upon resizing when dragged from the top corner. 320 */ 321 @Test 322 @Ignore 323 public void testLandscapePreservedWindowResizingDragTop() throws Exception { 324 final Rect r = new Rect(100, 220, 700, 520); 325 final int midX = (r.left + r.right) / 2; 326 327 mPositioner.startDrag(true /*resizing*/, 328 true /*preserveOrientation*/, midX, r.top - MOUSE_DELTA_Y, r); 329 330 // Drag to the left (no change). 331 mPositioner.resizeDrag(0.0f, r.top); 332 assertBoundsEquals(new Rect(r.left, r.top + MOUSE_DELTA_Y, r.right, r.bottom), 333 mPositioner.getWindowDragBounds()); 334 335 // Drag to the right (no change). 336 mPositioner.resizeDrag(2000.0f, r.top); 337 assertBoundsEquals(new Rect(r.left , r.top + MOUSE_DELTA_Y, r.right, r.bottom), 338 mPositioner.getWindowDragBounds()); 339 340 // Drag to the top. 341 mPositioner.resizeDrag(300.0f, 0.0f); 342 int h = r.bottom - MOUSE_DELTA_Y; 343 int w = Math.max(r.right - r.left, Math.round(h * MIN_ASPECT)); 344 assertBoundsEquals(new Rect(r.left, MOUSE_DELTA_Y, r.left + w, r.bottom), 345 mPositioner.getWindowDragBounds()); 346 347 // Drag to the bottom. 348 mPositioner.resizeDrag(r.left, 1000.0f); 349 h = mMinVisibleHeight; 350 assertBoundsEquals(new Rect(r.left, r.bottom - h, r.right, r.bottom), 351 mPositioner.getWindowDragBounds()); 352 } 353 354 /** 355 * This tests that a constrained portrait window will keep the aspect and do the 356 * right things upon resizing when dragged from the top left corner. 357 */ 358 @Test 359 @Ignore 360 public void testPortraitPreservedWindowResizingDragTopLeft() throws Exception { 361 final Rect r = new Rect(330, 100, 630, 600); 362 363 mPositioner.startDrag(true /*resizing*/, 364 true /*preserveOrientation*/, r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y, r); 365 assertBoundsEquals(r, mPositioner.getWindowDragBounds()); 366 367 // Drag to a good landscape size. 368 mPositioner.resizeDrag(0.0f, 0.0f); 369 int height = Math.round((float) (r.right - MOUSE_DELTA_X) * MIN_ASPECT); 370 assertBoundsEquals(new Rect(MOUSE_DELTA_X, r.bottom - height, r.right, r.bottom), 371 mPositioner.getWindowDragBounds()); 372 373 // Drag to a good portrait size. 374 mPositioner.resizeDrag(500.0f, 0.0f); 375 assertBoundsEquals(new Rect(500 + MOUSE_DELTA_X, MOUSE_DELTA_Y, r.right, r.bottom), 376 mPositioner.getWindowDragBounds()); 377 378 // Drag to a too small size for the height and the the width shrinking. 379 mPositioner.resizeDrag(r.left + MOUSE_DELTA_X, 2000.0f); 380 final int w = Math.max(mMinVisibleWidth, Math.round(mMinVisibleHeight / MIN_ASPECT)); 381 final int h = Math.max(mMinVisibleHeight, Math.round(w * MIN_ASPECT)); 382 assertBoundsEquals( 383 new Rect(r.right - w, r.bottom - h, r.right, r.bottom), 384 mPositioner.getWindowDragBounds()); 385 } 386 387 /** 388 * This tests that a constrained portrait window will keep the aspect and do the 389 * right things upon resizing when dragged from the left corner. 390 */ 391 @Test 392 @Ignore 393 public void testPortraitPreservedWindowResizingDragLeft() throws Exception { 394 final Rect r = new Rect(330, 100, 630, 600); 395 final int midY = (r.top + r.bottom) / 2; 396 397 mPositioner.startDrag(true /*resizing*/, 398 true /*preserveOrientation*/, r.left - MOUSE_DELTA_X, midY, r); 399 400 // Drag to the left. 401 mPositioner.resizeDrag(0.0f, midY); 402 int w = r.right - MOUSE_DELTA_X; 403 int h = Math.round(w * MIN_ASPECT); 404 assertBoundsEquals(new Rect(MOUSE_DELTA_X, r.top, r.right, r.top + h), 405 mPositioner.getWindowDragBounds()); 406 407 // Drag to the right. 408 mPositioner.resizeDrag(450.0f, midY); 409 assertBoundsEquals(new Rect(450 + MOUSE_DELTA_X, r.top, r.right, r.bottom), 410 mPositioner.getWindowDragBounds()); 411 412 // Drag all the way to the right. 413 mPositioner.resizeDrag(2000.0f, midY); 414 w = mMinVisibleWidth; 415 h = Math.max(Math.round((float)w * MIN_ASPECT), r.height()); 416 assertBoundsEquals(new Rect(r.right - w, r.top, r.right, r.top + h), 417 mPositioner.getWindowDragBounds()); 418 419 // Drag to the top. 420 mPositioner.resizeDrag(r.left, 0.0f); 421 assertBoundsEquals(new Rect(r.left + MOUSE_DELTA_X, r.top, r.right, r.bottom), 422 mPositioner.getWindowDragBounds()); 423 424 // Drag to the bottom. 425 mPositioner.resizeDrag(r.left, 1000.0f); 426 assertBoundsEquals(new Rect(r.left + MOUSE_DELTA_X, r.top, r.right, r.bottom), 427 mPositioner.getWindowDragBounds()); 428 } 429 430 /** 431 * This tests that a constrained portrait window will keep the aspect and do the 432 * right things upon resizing when dragged from the top corner. 433 */ 434 @Test 435 @Ignore 436 public void testPortraitPreservedWindowResizingDragTop() throws Exception { 437 final Rect r = new Rect(330, 100, 630, 600); 438 final int midX = (r.left + r.right) / 2; 439 440 mPositioner.startDrag(true /*resizing*/, 441 true /*preserveOrientation*/, midX, r.top - MOUSE_DELTA_Y, r); 442 443 // Drag to the left (no change). 444 mPositioner.resizeDrag(0.0f, r.top); 445 assertBoundsEquals(new Rect(r.left, r.top + MOUSE_DELTA_Y, r.right, r.bottom), 446 mPositioner.getWindowDragBounds()); 447 448 // Drag to the right (no change). 449 mPositioner.resizeDrag(2000.0f, r.top); 450 assertBoundsEquals(new Rect(r.left , r.top + MOUSE_DELTA_Y, r.right, r.bottom), 451 mPositioner.getWindowDragBounds()); 452 453 // Drag to the top. 454 mPositioner.resizeDrag(300.0f, 0.0f); 455 int h = r.bottom - MOUSE_DELTA_Y; 456 int w = Math.min(r.width(), Math.round(h / MIN_ASPECT)); 457 assertBoundsEquals(new Rect(r.left, MOUSE_DELTA_Y, r.left + w, r.bottom), 458 mPositioner.getWindowDragBounds()); 459 460 // Drag to the bottom. 461 mPositioner.resizeDrag(r.left, 1000.0f); 462 h = Math.max(mMinVisibleHeight, Math.round(mMinVisibleWidth * MIN_ASPECT)); 463 w = Math.round(h / MIN_ASPECT); 464 assertBoundsEquals(new Rect(r.left, r.bottom - h, r.left + w, r.bottom), 465 mPositioner.getWindowDragBounds()); 466 } 467 468 private void assertBoundsEquals(Rect expected, Rect actual) { 469 if (DEBUGGING) { 470 if (!expected.equals(actual)) { 471 Log.e(TAG, "rect(" + actual.toString() + ") != isRect(" + actual.toString() 472 + ") " + Log.getStackTraceString(new Throwable())); 473 } 474 } 475 assertEquals(expected.left, actual.left); 476 assertEquals(expected.right, actual.right); 477 assertEquals(expected.top, actual.top); 478 assertEquals(expected.bottom, actual.bottom); 479 } 480 } 481