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