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 static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
20 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
21 
22 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
23 import static com.android.internal.policy.TaskResizingAlgorithm.MIN_ASPECT;
24 import static com.android.server.wm.WindowManagerService.dipToPixel;
25 import static com.android.server.wm.WindowState.MINIMUM_VISIBLE_HEIGHT_IN_DP;
26 import static com.android.server.wm.WindowState.MINIMUM_VISIBLE_WIDTH_IN_DP;
27 
28 import static org.junit.Assert.assertEquals;
29 import static org.junit.Assert.assertNotEquals;
30 import static org.junit.Assert.assertNull;
31 import static org.junit.Assert.assertTrue;
32 import static org.mockito.Mockito.never;
33 import static org.mockito.Mockito.verify;
34 
35 import android.graphics.Rect;
36 import android.platform.test.annotations.Presubmit;
37 import android.util.DisplayMetrics;
38 import android.util.Log;
39 
40 import androidx.test.filters.SmallTest;
41 
42 import org.junit.After;
43 import org.junit.Before;
44 import org.junit.Test;
45 import org.junit.runner.RunWith;
46 
47 /**
48  * Tests for the {@link TaskPositioner} class.
49  *
50  * Build/Install/Run:
51  *  atest WmTests:TaskPositionerTests
52  */
53 @SmallTest
54 @Presubmit
55 @RunWith(WindowTestRunner.class)
56 public class TaskPositionerTests extends WindowTestsBase {
57 
58     private static final boolean DEBUGGING = false;
59     private static final String TAG = "TaskPositionerTest";
60 
61     private static final int MOUSE_DELTA_X = 5;
62     private static final int MOUSE_DELTA_Y = 5;
63 
64     private int mMinVisibleWidth;
65     private int mMinVisibleHeight;
66     private TaskPositioner mPositioner;
67 
68     @Before
setUp()69     public void setUp() {
70         TaskPositioner.setFactory(null);
71 
72         final DisplayMetrics dm = mDisplayContent.getDisplayMetrics();
73 
74         // This should be the same calculation as the TaskPositioner uses.
75         mMinVisibleWidth = dipToPixel(MINIMUM_VISIBLE_WIDTH_IN_DP, dm);
76         mMinVisibleHeight = dipToPixel(MINIMUM_VISIBLE_HEIGHT_IN_DP, dm);
77         removeGlobalMinSizeRestriction();
78 
79         final ActivityRecord activity = new ActivityBuilder(mAtm)
80                 .setCreateTask(true)
81                 .build();
82         final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, activity, "window");
83         mPositioner = new TaskPositioner(mWm);
84         mPositioner.register(mDisplayContent, win);
85 
86         win.getRootTask().setWindowingMode(WINDOWING_MODE_FREEFORM);
87     }
88 
89     @After
tearDown()90     public void tearDown() {
91         TaskPositioner.setFactory(null);
92     }
93 
94     @Test
testOverrideFactory()95     public void testOverrideFactory() {
96         final boolean[] created = new boolean[1];
97         created[0] = false;
98         TaskPositioner.setFactory(new TaskPositioner.Factory() {
99             @Override
100             public TaskPositioner create(WindowManagerService service) {
101                 created[0] = true;
102                 return null;
103             }
104         });
105 
106         assertNull(TaskPositioner.create(mWm));
107         assertTrue(created[0]);
108     }
109 
110     /** This tests that the window can move in all directions. */
111     @Test
testMoveWindow()112     public void testMoveWindow() {
113         final Rect displayBounds = mDisplayContent.getBounds();
114         final int windowSize = Math.min(displayBounds.width(), displayBounds.height()) / 2;
115         final int left = displayBounds.centerX() - windowSize / 2;
116         final int top = displayBounds.centerY() - windowSize / 2;
117         final Rect r = new Rect(left, top, left + windowSize, top + windowSize);
118         mPositioner.mTask.setBounds(r);
119         mPositioner.startDrag(false /* resizing */, false /* preserveOrientation */, left, top);
120 
121         // Move upper left.
122         mPositioner.notifyMoveLocked(left - MOUSE_DELTA_X, top - MOUSE_DELTA_Y);
123         r.offset(-MOUSE_DELTA_X, -MOUSE_DELTA_Y);
124         assertBoundsEquals(r, mPositioner.getWindowDragBounds());
125 
126         // Move bottom right.
127         mPositioner.notifyMoveLocked(left, top);
128         r.offset(MOUSE_DELTA_X, MOUSE_DELTA_Y);
129         assertBoundsEquals(r, mPositioner.getWindowDragBounds());
130     }
131 
132     /**
133      * This tests that free resizing will allow to change the orientation as well
134      * as does some basic tests (e.g. dragging in Y only will keep X stable).
135      */
136     @Test
testBasicFreeWindowResizing()137     public void testBasicFreeWindowResizing() {
138         final Rect r = new Rect(100, 220, 700, 520);
139         final int midY = (r.top + r.bottom) / 2;
140         mPositioner.mTask.setBounds(r, true);
141 
142         // Start a drag resize starting upper left.
143         mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */,
144                 r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y);
145         assertBoundsEquals(r, mPositioner.getWindowDragBounds());
146 
147         // Drag to a good landscape size.
148         mPositioner.resizeDrag(0.0f, 0.0f);
149         assertBoundsEquals(new Rect(MOUSE_DELTA_X, MOUSE_DELTA_Y, r.right, r.bottom),
150                 mPositioner.getWindowDragBounds());
151 
152         // Drag to a good portrait size.
153         mPositioner.resizeDrag(400.0f, 0.0f);
154         assertBoundsEquals(new Rect(400 + MOUSE_DELTA_X, MOUSE_DELTA_Y, r.right, r.bottom),
155                 mPositioner.getWindowDragBounds());
156 
157         // Drag to a too small size for the width.
158         mPositioner.resizeDrag(2000.0f, r.top);
159         assertBoundsEquals(
160                 new Rect(r.right - mMinVisibleWidth, r.top + MOUSE_DELTA_Y, r.right, r.bottom),
161                 mPositioner.getWindowDragBounds());
162 
163         // Drag to a too small size for the height.
164         mPositioner.resizeDrag(r.left, 2000.0f);
165         assertBoundsEquals(
166                 new Rect(r.left + MOUSE_DELTA_X, r.bottom - mMinVisibleHeight, r.right, r.bottom),
167                 mPositioner.getWindowDragBounds());
168 
169         // Start a drag resize left and see that only the left coord changes..
170         mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */,
171                 r.left - MOUSE_DELTA_X, midY);
172 
173         // Drag to the left.
174         mPositioner.resizeDrag(0.0f, midY);
175         assertBoundsEquals(new Rect(MOUSE_DELTA_X, r.top, r.right, r.bottom),
176                 mPositioner.getWindowDragBounds());
177 
178         // Drag to the right.
179         mPositioner.resizeDrag(200.0f, midY);
180         assertBoundsEquals(new Rect(200 + MOUSE_DELTA_X, r.top, r.right, r.bottom),
181                 mPositioner.getWindowDragBounds());
182 
183         // Drag to the top
184         mPositioner.resizeDrag(r.left, 0.0f);
185         assertBoundsEquals(new Rect(r.left + MOUSE_DELTA_X, r.top, r.right, r.bottom),
186                 mPositioner.getWindowDragBounds());
187 
188         // Drag to the bottom
189         mPositioner.resizeDrag(r.left, 1000.0f);
190         assertBoundsEquals(new Rect(r.left + MOUSE_DELTA_X, r.top, r.right, r.bottom),
191                 mPositioner.getWindowDragBounds());
192     }
193 
194     /**
195      * This tests that by dragging any edge, the fixed / opposite edge(s) remains anchored.
196      */
197     @Test
testFreeWindowResizingTestAllEdges()198     public void testFreeWindowResizingTestAllEdges() {
199         final Rect r = new Rect(100, 220, 700, 520);
200         final int midX = (r.left + r.right) / 2;
201         final int midY = (r.top + r.bottom) / 2;
202         mPositioner.mTask.setBounds(r, true);
203 
204         // Drag upper left.
205         mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */,
206                 r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y);
207         mPositioner.resizeDrag(0.0f, 0.0f);
208         assertNotEquals(r.left, mPositioner.getWindowDragBounds().left);
209         assertEquals(r.right, mPositioner.getWindowDragBounds().right);
210         assertNotEquals(r.top, mPositioner.getWindowDragBounds().top);
211         assertEquals(r.bottom, mPositioner.getWindowDragBounds().bottom);
212 
213         // Drag upper.
214         mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */, midX,
215                 r.top - MOUSE_DELTA_Y);
216         mPositioner.resizeDrag(0.0f, 0.0f);
217         assertEquals(r.left, mPositioner.getWindowDragBounds().left);
218         assertEquals(r.right, mPositioner.getWindowDragBounds().right);
219         assertNotEquals(r.top, mPositioner.getWindowDragBounds().top);
220         assertEquals(r.bottom, mPositioner.getWindowDragBounds().bottom);
221 
222         // Drag upper right.
223         mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */,
224                 r.right + MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y);
225         mPositioner.resizeDrag(r.right + 100, 0.0f);
226         assertEquals(r.left, mPositioner.getWindowDragBounds().left);
227         assertNotEquals(r.right, mPositioner.getWindowDragBounds().right);
228         assertNotEquals(r.top, mPositioner.getWindowDragBounds().top);
229         assertEquals(r.bottom, mPositioner.getWindowDragBounds().bottom);
230 
231         // Drag right.
232         mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */,
233                 r.right + MOUSE_DELTA_X, midY);
234         mPositioner.resizeDrag(r.right + 100, 0.0f);
235         assertEquals(r.left, mPositioner.getWindowDragBounds().left);
236         assertNotEquals(r.right, mPositioner.getWindowDragBounds().right);
237         assertEquals(r.top, mPositioner.getWindowDragBounds().top);
238         assertEquals(r.bottom, mPositioner.getWindowDragBounds().bottom);
239 
240         // Drag bottom right.
241         mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */,
242                 r.right + MOUSE_DELTA_X, r.bottom + MOUSE_DELTA_Y);
243         mPositioner.resizeDrag(r.right + 100, r.bottom + 100);
244         assertEquals(r.left, mPositioner.getWindowDragBounds().left);
245         assertNotEquals(r.right, mPositioner.getWindowDragBounds().right);
246         assertEquals(r.top, mPositioner.getWindowDragBounds().top);
247         assertNotEquals(r.bottom, mPositioner.getWindowDragBounds().bottom);
248 
249         // Drag bottom.
250         mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */, midX,
251                 r.bottom + MOUSE_DELTA_Y);
252         mPositioner.resizeDrag(r.right + 100, r.bottom + 100);
253         assertEquals(r.left, mPositioner.getWindowDragBounds().left);
254         assertEquals(r.right, mPositioner.getWindowDragBounds().right);
255         assertEquals(r.top, mPositioner.getWindowDragBounds().top);
256         assertNotEquals(r.bottom, mPositioner.getWindowDragBounds().bottom);
257 
258         // Drag bottom left.
259         mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */,
260                 r.left - MOUSE_DELTA_X, r.bottom + MOUSE_DELTA_Y);
261         mPositioner.resizeDrag(0.0f, r.bottom + 100);
262         assertNotEquals(r.left, mPositioner.getWindowDragBounds().left);
263         assertEquals(r.right, mPositioner.getWindowDragBounds().right);
264         assertEquals(r.top, mPositioner.getWindowDragBounds().top);
265         assertNotEquals(r.bottom, mPositioner.getWindowDragBounds().bottom);
266 
267         // Drag left.
268         mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */,
269                 r.left - MOUSE_DELTA_X, midY);
270         mPositioner.resizeDrag(0.0f, r.bottom + 100);
271         assertNotEquals(r.left, mPositioner.getWindowDragBounds().left);
272         assertEquals(r.right, mPositioner.getWindowDragBounds().right);
273         assertEquals(r.top, mPositioner.getWindowDragBounds().top);
274         assertEquals(r.bottom, mPositioner.getWindowDragBounds().bottom);
275     }
276 
277     /**
278      * This tests that a constrained landscape window will keep the aspect and do the
279      * right things upon resizing when dragged from the top left corner.
280      */
281     @Test
testLandscapePreservedWindowResizingDragTopLeft()282     public void testLandscapePreservedWindowResizingDragTopLeft() {
283         final Rect r = new Rect(100, 220, 700, 520);
284         mPositioner.mTask.setBounds(r, true);
285 
286         mPositioner.startDrag(true /* resizing */, true /* preserveOrientation */,
287                 r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y);
288         assertBoundsEquals(r, mPositioner.getWindowDragBounds());
289 
290         // Drag to a good landscape size.
291         mPositioner.resizeDrag(0.0f, 0.0f);
292         assertBoundsEquals(new Rect(MOUSE_DELTA_X, MOUSE_DELTA_Y, r.right, r.bottom),
293                 mPositioner.getWindowDragBounds());
294 
295         // Drag to a good portrait size.
296         mPositioner.resizeDrag(400.0f, 0.0f);
297         int width = Math.round((float) (r.bottom - MOUSE_DELTA_Y) * MIN_ASPECT);
298         assertBoundsEquals(new Rect(r.right - width, MOUSE_DELTA_Y, r.right, r.bottom),
299                 mPositioner.getWindowDragBounds());
300 
301         // Drag to a too small size for the width.
302         mPositioner.resizeDrag(2000.0f, r.top);
303         final int w = mMinVisibleWidth;
304         final int h = Math.round(w / MIN_ASPECT);
305         assertBoundsEquals(new Rect(r.right - w, r.bottom - h, r.right, r.bottom),
306                 mPositioner.getWindowDragBounds());
307 
308         // Drag to a too small size for the height.
309         mPositioner.resizeDrag(r.left, 2000.0f);
310         assertBoundsEquals(
311                 new Rect(r.left + MOUSE_DELTA_X, r.bottom - mMinVisibleHeight, r.right, r.bottom),
312                 mPositioner.getWindowDragBounds());
313     }
314 
315     /**
316      * This tests that a constrained landscape window will keep the aspect and do the
317      * right things upon resizing when dragged from the left corner.
318      */
319     @Test
testLandscapePreservedWindowResizingDragLeft()320     public void testLandscapePreservedWindowResizingDragLeft() {
321         final Rect r = new Rect(100, 220, 700, 520);
322         final int midY = (r.top + r.bottom) / 2;
323         mPositioner.mTask.setBounds(r, true);
324 
325         mPositioner.startDrag(true /* resizing */, true /* preserveOrientation */,
326                 r.left - MOUSE_DELTA_X, midY);
327 
328         // Drag to the left.
329         mPositioner.resizeDrag(0.0f, midY);
330         assertBoundsEquals(new Rect(MOUSE_DELTA_X, r.top, r.right, r.bottom),
331                 mPositioner.getWindowDragBounds());
332 
333         // Drag to the right.
334         mPositioner.resizeDrag(200.0f, midY);
335         assertBoundsEquals(new Rect(200 + MOUSE_DELTA_X, r.top, r.right, r.bottom),
336                 mPositioner.getWindowDragBounds());
337 
338         // Drag all the way to the right and see the height also shrinking.
339         mPositioner.resizeDrag(2000.0f, midY);
340         final int w = mMinVisibleWidth;
341         final int h = Math.round((float) w / MIN_ASPECT);
342         assertBoundsEquals(new Rect(r.right - w, r.top, r.right, r.top + h),
343                 mPositioner.getWindowDragBounds());
344 
345         // Drag to the top.
346         mPositioner.resizeDrag(r.left, 0.0f);
347         assertBoundsEquals(new Rect(r.left + MOUSE_DELTA_X, r.top, r.right, r.bottom),
348                 mPositioner.getWindowDragBounds());
349 
350         // Drag to the bottom.
351         mPositioner.resizeDrag(r.left, 1000.0f);
352         assertBoundsEquals(new Rect(r.left + MOUSE_DELTA_X, r.top, r.right, r.bottom),
353                 mPositioner.getWindowDragBounds());
354     }
355 
356     /**
357      * This tests that a constrained landscape window will keep the aspect and do the
358      * right things upon resizing when dragged from the top corner.
359      */
360     @Test
testLandscapePreservedWindowResizingDragTop()361     public void testLandscapePreservedWindowResizingDragTop() {
362         final Rect r = new Rect(100, 220, 700, 520);
363         final int midX = (r.left + r.right) / 2;
364         mPositioner.mTask.setBounds(r, true);
365 
366         mPositioner.startDrag(true /*resizing*/, true /*preserveOrientation*/, midX,
367                 r.top - MOUSE_DELTA_Y);
368 
369         // Drag to the left (no change).
370         mPositioner.resizeDrag(0.0f, r.top);
371         assertBoundsEquals(new Rect(r.left, r.top + MOUSE_DELTA_Y, r.right, r.bottom),
372                 mPositioner.getWindowDragBounds());
373 
374         // Drag to the right (no change).
375         mPositioner.resizeDrag(2000.0f, r.top);
376         assertBoundsEquals(new Rect(r.left , r.top + MOUSE_DELTA_Y, r.right, r.bottom),
377                 mPositioner.getWindowDragBounds());
378 
379         // Drag to the top.
380         mPositioner.resizeDrag(300.0f, 0.0f);
381         int h = r.bottom - MOUSE_DELTA_Y;
382         int w = Math.max(r.right - r.left, Math.round(h * MIN_ASPECT));
383         assertBoundsEquals(new Rect(r.left, MOUSE_DELTA_Y, r.left + w, r.bottom),
384                 mPositioner.getWindowDragBounds());
385 
386         // Drag to the bottom.
387         mPositioner.resizeDrag(r.left, 1000.0f);
388         h = mMinVisibleHeight;
389         assertBoundsEquals(new Rect(r.left, r.bottom - h, r.right, r.bottom),
390                 mPositioner.getWindowDragBounds());
391     }
392 
393     /**
394      * This tests that a constrained portrait window will keep the aspect and do the
395      * right things upon resizing when dragged from the top left corner.
396      */
397     @Test
testPortraitPreservedWindowResizingDragTopLeft()398     public void testPortraitPreservedWindowResizingDragTopLeft() {
399         final Rect r = new Rect(330, 100, 630, 600);
400         mPositioner.mTask.setBounds(r, true);
401 
402         mPositioner.startDrag(true /*resizing*/, true /*preserveOrientation*/,
403                 r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y);
404         assertBoundsEquals(r, mPositioner.getWindowDragBounds());
405 
406         // Drag to a good landscape size.
407         mPositioner.resizeDrag(0.0f, 0.0f);
408         int height = Math.round((float) (r.right - MOUSE_DELTA_X) * MIN_ASPECT);
409         assertBoundsEquals(new Rect(MOUSE_DELTA_X, r.bottom - height, r.right, r.bottom),
410                 mPositioner.getWindowDragBounds());
411 
412         // Drag to a good portrait size.
413         mPositioner.resizeDrag(400.0f, 0.0f);
414         assertBoundsEquals(new Rect(400 + MOUSE_DELTA_X, MOUSE_DELTA_Y, r.right, r.bottom),
415                 mPositioner.getWindowDragBounds());
416 
417         // Drag to a too small size for the height and the the width shrinking.
418         mPositioner.resizeDrag(r.left + MOUSE_DELTA_X, 2000.0f);
419         final int w = Math.max(mMinVisibleWidth, Math.round(mMinVisibleHeight / MIN_ASPECT));
420         final int h = Math.max(mMinVisibleHeight, Math.round(w * MIN_ASPECT));
421         assertBoundsEquals(
422                 new Rect(r.right - w, r.bottom - h, r.right, r.bottom),
423                 mPositioner.getWindowDragBounds());
424     }
425 
426     /**
427      * This tests that a constrained portrait window will keep the aspect and do the
428      * right things upon resizing when dragged from the left corner.
429      */
430     @Test
testPortraitPreservedWindowResizingDragLeft()431     public void testPortraitPreservedWindowResizingDragLeft() {
432         final Rect r = new Rect(330, 100, 630, 600);
433         final int midY = (r.top + r.bottom) / 2;
434         mPositioner.mTask.setBounds(r, true);
435 
436         mPositioner.startDrag(true /* resizing */, true /* preserveOrientation */,
437                 r.left - MOUSE_DELTA_X, midY);
438 
439         // Drag to the left.
440         mPositioner.resizeDrag(0.0f, midY);
441         int w = r.right - MOUSE_DELTA_X;
442         int h = Math.round(w * MIN_ASPECT);
443         assertBoundsEquals(new Rect(MOUSE_DELTA_X, r.top, r.right, r.top + h),
444                 mPositioner.getWindowDragBounds());
445 
446         // Drag to the right.
447         mPositioner.resizeDrag(450.0f, midY);
448         assertBoundsEquals(new Rect(450 + MOUSE_DELTA_X, r.top, r.right, r.bottom),
449                 mPositioner.getWindowDragBounds());
450 
451         // Drag all the way to the right.
452         mPositioner.resizeDrag(2000.0f, midY);
453         w = mMinVisibleWidth;
454         h = Math.max(Math.round((float) w * MIN_ASPECT), r.height());
455         assertBoundsEquals(new Rect(r.right - w, r.top, r.right, r.top + h),
456                 mPositioner.getWindowDragBounds());
457 
458         // Drag to the top.
459         mPositioner.resizeDrag(r.left, 0.0f);
460         assertBoundsEquals(new Rect(r.left + MOUSE_DELTA_X, r.top, r.right, r.bottom),
461                 mPositioner.getWindowDragBounds());
462 
463         // Drag to the bottom.
464         mPositioner.resizeDrag(r.left, 1000.0f);
465         assertBoundsEquals(new Rect(r.left + MOUSE_DELTA_X, r.top, r.right, r.bottom),
466                 mPositioner.getWindowDragBounds());
467     }
468 
469     /**
470      * This tests that a constrained portrait window will keep the aspect and do the
471      * right things upon resizing when dragged from the top corner.
472      */
473     @Test
testPortraitPreservedWindowResizingDragTop()474     public void testPortraitPreservedWindowResizingDragTop() {
475         final Rect r = new Rect(330, 100, 630, 600);
476         final int midX = (r.left + r.right) / 2;
477         mPositioner.mTask.setBounds(r, true);
478 
479         mPositioner.startDrag(true /* resizing */, true /* preserveOrientation */, midX,
480                 r.top - MOUSE_DELTA_Y);
481 
482         // Drag to the left (no change).
483         mPositioner.resizeDrag(0.0f, r.top);
484         assertBoundsEquals(new Rect(r.left, r.top + MOUSE_DELTA_Y, r.right, r.bottom),
485                 mPositioner.getWindowDragBounds());
486 
487         // Drag to the right (no change).
488         mPositioner.resizeDrag(2000.0f, r.top);
489         assertBoundsEquals(new Rect(r.left , r.top + MOUSE_DELTA_Y, r.right, r.bottom),
490                 mPositioner.getWindowDragBounds());
491 
492         // Drag to the top.
493         mPositioner.resizeDrag(300.0f, 0.0f);
494         int h = r.bottom - MOUSE_DELTA_Y;
495         int w = Math.min(r.width(), Math.round(h / MIN_ASPECT));
496         assertBoundsEquals(new Rect(r.left, MOUSE_DELTA_Y, r.left + w, r.bottom),
497                 mPositioner.getWindowDragBounds());
498 
499         // Drag to the bottom.
500         mPositioner.resizeDrag(r.left, 1000.0f);
501         h = Math.max(mMinVisibleHeight, Math.round(mMinVisibleWidth * MIN_ASPECT));
502         w = Math.round(h / MIN_ASPECT);
503         assertBoundsEquals(new Rect(r.left, r.bottom - h, r.left + w, r.bottom),
504                 mPositioner.getWindowDragBounds());
505     }
506 
assertBoundsEquals(Rect expected, Rect actual)507     private static void assertBoundsEquals(Rect expected, Rect actual) {
508         if (DEBUGGING) {
509             if (!expected.equals(actual)) {
510                 Log.e(TAG, "rect(" + actual.toString() + ") != isRect(" + actual.toString()
511                         + ") " + Log.getStackTraceString(new Throwable()));
512             }
513         }
514         assertEquals(expected, actual);
515     }
516 
517     @Test
testFinishingMovingWhenBinderDied()518     public void testFinishingMovingWhenBinderDied() {
519         spyOn(mWm.mTaskPositioningController);
520 
521         mPositioner.startDrag(false, false, 0 /* startX */, 0 /* startY */);
522         verify(mWm.mTaskPositioningController, never()).finishTaskPositioning();
523         mPositioner.binderDied();
524         verify(mWm.mTaskPositioningController).finishTaskPositioning();
525     }
526 }
527