blob: a7d594cbd256258573847af48bb2ba50203ab771 [file] [log] [blame]
Wale Ogunwaled63594a2016-07-18 07:48:30 -07001/*
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
Wale Ogunwalea7e3b642016-08-29 10:15:34 -070019import org.junit.Test;
20import org.junit.runner.RunWith;
21
Andrii Kulian441e4492016-09-29 15:25:00 -070022import android.content.res.Configuration;
Wale Ogunwale5fc70962016-09-09 22:36:19 -070023import android.platform.test.annotations.Presubmit;
Wale Ogunwalea7e3b642016-08-29 10:15:34 -070024import android.support.test.filters.SmallTest;
25import android.support.test.runner.AndroidJUnit4;
Wale Ogunwaled63594a2016-07-18 07:48:30 -070026
27import java.util.Comparator;
28
Wale Ogunwale51362492016-09-08 17:49:17 -070029import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
30import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
31import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
Andrii Kulian441e4492016-09-29 15:25:00 -070032import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
33import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
Wale Ogunwale51362492016-09-08 17:49:17 -070034import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
35import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Andrii Kuliand2765632016-12-12 22:26:34 -080036
37import static com.android.server.wm.WindowContainer.POSITION_BOTTOM;
38import static com.android.server.wm.WindowContainer.POSITION_TOP;
39
Wale Ogunwalea7e3b642016-08-29 10:15:34 -070040import static org.junit.Assert.assertEquals;
41import static org.junit.Assert.assertFalse;
42import static org.junit.Assert.assertNotNull;
43import static org.junit.Assert.assertNull;
44import static org.junit.Assert.assertTrue;
45
Wale Ogunwaled63594a2016-07-18 07:48:30 -070046/**
47 * Test class for {@link WindowContainer}.
48 *
Wale Ogunwalef7cab102016-10-25 15:25:14 -070049 * Build/Install/Run:
50 * bit FrameworksServicesTests:com.android.server.wm.WindowContainerTests
Wale Ogunwaled63594a2016-07-18 07:48:30 -070051 */
52@SmallTest
Wale Ogunwale5fc70962016-09-09 22:36:19 -070053@Presubmit
Wale Ogunwalea7e3b642016-08-29 10:15:34 -070054@RunWith(AndroidJUnit4.class)
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080055public class WindowContainerTests extends WindowTestsBase {
Wale Ogunwaled63594a2016-07-18 07:48:30 -070056
Wale Ogunwalea7e3b642016-08-29 10:15:34 -070057 @Test
Wale Ogunwaled63594a2016-07-18 07:48:30 -070058 public void testCreation() throws Exception {
Wale Ogunwaled1c37912016-08-16 03:19:39 -070059 final TestWindowContainer w = new TestWindowContainerBuilder().setLayer(0).build();
Wale Ogunwaled63594a2016-07-18 07:48:30 -070060 assertNull("window must have no parent", w.getParentWindow());
61 assertEquals("window must have no children", 0, w.getChildrenCount());
62 }
63
Wale Ogunwalea7e3b642016-08-29 10:15:34 -070064 @Test
Wale Ogunwaled63594a2016-07-18 07:48:30 -070065 public void testAdd() throws Exception {
Wale Ogunwaled1c37912016-08-16 03:19:39 -070066 final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
67 final TestWindowContainer root = builder.setLayer(0).build();
Wale Ogunwaled63594a2016-07-18 07:48:30 -070068
Wale Ogunwaled1c37912016-08-16 03:19:39 -070069 final TestWindowContainer layer1 = root.addChildWindow(builder.setLayer(1));
70 final TestWindowContainer secondLayer1 = root.addChildWindow(builder.setLayer(1));
71 final TestWindowContainer layer2 = root.addChildWindow(builder.setLayer(2));
72 final TestWindowContainer layerNeg1 = root.addChildWindow(builder.setLayer(-1));
73 final TestWindowContainer layerNeg2 = root.addChildWindow(builder.setLayer(-2));
74 final TestWindowContainer secondLayerNeg1 = root.addChildWindow(builder.setLayer(-1));
75 final TestWindowContainer layer0 = root.addChildWindow(builder.setLayer(0));
Wale Ogunwaled63594a2016-07-18 07:48:30 -070076
77 assertEquals(7, root.getChildrenCount());
78
79 assertEquals(root, layer1.getParentWindow());
80 assertEquals(root, secondLayer1.getParentWindow());
81 assertEquals(root, layer2.getParentWindow());
82 assertEquals(root, layerNeg1.getParentWindow());
83 assertEquals(root, layerNeg2.getParentWindow());
84 assertEquals(root, secondLayerNeg1.getParentWindow());
85 assertEquals(root, layer0.getParentWindow());
86
87 assertEquals(layerNeg2, root.getChildAt(0));
88 assertEquals(secondLayerNeg1, root.getChildAt(1));
89 assertEquals(layerNeg1, root.getChildAt(2));
90 assertEquals(layer0, root.getChildAt(3));
91 assertEquals(layer1, root.getChildAt(4));
92 assertEquals(secondLayer1, root.getChildAt(5));
93 assertEquals(layer2, root.getChildAt(6));
Andrii Kuliand2765632016-12-12 22:26:34 -080094
95 assertTrue(layer1.mOnParentSetCalled);
96 assertTrue(secondLayer1.mOnParentSetCalled);
97 assertTrue(layer2.mOnParentSetCalled);
98 assertTrue(layerNeg1.mOnParentSetCalled);
99 assertTrue(layerNeg2.mOnParentSetCalled);
100 assertTrue(secondLayerNeg1.mOnParentSetCalled);
101 assertTrue(layer0.mOnParentSetCalled);
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700102 }
103
Wale Ogunwalea7e3b642016-08-29 10:15:34 -0700104 @Test
Wale Ogunwalef6192862016-09-10 13:42:30 -0700105 public void testAdd_AlreadyHasParent() throws Exception {
106 final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
107 final TestWindowContainer root = builder.setLayer(0).build();
108
109 final TestWindowContainer child1 = root.addChildWindow();
110 final TestWindowContainer child2 = root.addChildWindow();
111
112 boolean gotException = false;
113 try {
114 child1.addChildWindow(child2);
115 } catch (IllegalArgumentException e) {
116 gotException = true;
117 }
118 assertTrue(gotException);
119
120 gotException = false;
121 try {
122 root.addChildWindow(child2);
123 } catch (IllegalArgumentException e) {
124 gotException = true;
125 }
126 assertTrue(gotException);
127 }
128
129 @Test
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700130 public void testHasChild() throws Exception {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700131 final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
132 final TestWindowContainer root = builder.setLayer(0).build();
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700133
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700134 final TestWindowContainer child1 = root.addChildWindow();
135 final TestWindowContainer child2 = root.addChildWindow();
136 final TestWindowContainer child11 = child1.addChildWindow();
137 final TestWindowContainer child12 = child1.addChildWindow();
138 final TestWindowContainer child21 = child2.addChildWindow();
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700139
140 assertEquals(2, root.getChildrenCount());
141 assertEquals(2, child1.getChildrenCount());
142 assertEquals(1, child2.getChildrenCount());
143
144 assertTrue(root.hasChild(child1));
145 assertTrue(root.hasChild(child2));
146 assertTrue(root.hasChild(child11));
147 assertTrue(root.hasChild(child12));
148 assertTrue(root.hasChild(child21));
149
150 assertTrue(child1.hasChild(child11));
151 assertTrue(child1.hasChild(child12));
152 assertFalse(child1.hasChild(child21));
153
154 assertTrue(child2.hasChild(child21));
155 assertFalse(child2.hasChild(child11));
156 assertFalse(child2.hasChild(child12));
Wale Ogunwalea7e3b642016-08-29 10:15:34 -0700157 }
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700158
Wale Ogunwalea7e3b642016-08-29 10:15:34 -0700159 @Test
Wale Ogunwale571771c2016-08-26 13:18:50 -0700160 public void testRemoveImmediately() throws Exception {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700161 final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
162 final TestWindowContainer root = builder.setLayer(0).build();
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700163
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700164 final TestWindowContainer child1 = root.addChildWindow();
165 final TestWindowContainer child2 = root.addChildWindow();
166 final TestWindowContainer child11 = child1.addChildWindow();
167 final TestWindowContainer child12 = child1.addChildWindow();
168 final TestWindowContainer child21 = child2.addChildWindow();
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700169
Wale Ogunwale571771c2016-08-26 13:18:50 -0700170 assertNotNull(child12.getParentWindow());
171 child12.removeImmediately();
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700172 assertNull(child12.getParentWindow());
173 assertEquals(1, child1.getChildrenCount());
174 assertFalse(child1.hasChild(child12));
175 assertFalse(root.hasChild(child12));
176
Wale Ogunwale571771c2016-08-26 13:18:50 -0700177 assertTrue(root.hasChild(child2));
178 assertNotNull(child2.getParentWindow());
179 child2.removeImmediately();
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700180 assertNull(child2.getParentWindow());
181 assertNull(child21.getParentWindow());
182 assertEquals(0, child2.getChildrenCount());
183 assertEquals(1, root.getChildrenCount());
184 assertFalse(root.hasChild(child2));
185 assertFalse(root.hasChild(child21));
186
187 assertTrue(root.hasChild(child1));
188 assertTrue(root.hasChild(child11));
189
Wale Ogunwale571771c2016-08-26 13:18:50 -0700190 root.removeImmediately();
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700191 assertEquals(0, root.getChildrenCount());
192 }
193
Wale Ogunwalea7e3b642016-08-29 10:15:34 -0700194 @Test
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800195 public void testRemoveImmediately_WithController() throws Exception {
196 final WindowContainer container = new WindowContainer();
197 final WindowContainerController controller = new WindowContainerController(null, sWm);
198
199 container.setController(controller);
200 assertEquals(controller, container.getController());
201 assertEquals(container, controller.mContainer);
202
203 container.removeImmediately();
204 assertNull(container.getController());
205 assertNull(controller.mContainer);
206 }
207
208 @Test
209 public void testSetController() throws Exception {
210 final WindowContainerController controller = new WindowContainerController(null, sWm);
211 final WindowContainer container = new WindowContainer();
212
213 container.setController(controller);
214 assertEquals(controller, container.getController());
215 assertEquals(container, controller.mContainer);
216
217 // Assert we can't change the controller to another one once set
218 boolean gotException = false;
219 try {
220 container.setController(new WindowContainerController(null, sWm));
221 } catch (IllegalArgumentException e) {
222 gotException = true;
223 }
224 assertTrue(gotException);
225
226 // Assert that we can set the controller to null.
227 container.setController(null);
228 assertNull(container.getController());
229 assertNull(controller.mContainer);
230 }
231
232 @Test
Andrii Kuliand2765632016-12-12 22:26:34 -0800233 public void testPositionChildAt() throws Exception {
234 final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
235 final TestWindowContainer root = builder.setLayer(0).build();
236
237 final TestWindowContainer child1 = root.addChildWindow();
238 final TestWindowContainer child2 = root.addChildWindow();
239 final TestWindowContainer child3 = root.addChildWindow();
240
241 // Test position at top.
242 root.positionChildAt(POSITION_TOP, child1, false /* includingParents */);
243 assertEquals(child1, root.getChildAt(root.getChildrenCount() - 1));
244
245 // Test position at bottom.
246 root.positionChildAt(POSITION_BOTTOM, child1, false /* includingParents */);
247 assertEquals(child1, root.getChildAt(0));
248
249 // Test position in the middle.
250 root.positionChildAt(1, child3, false /* includingParents */);
251 assertEquals(child1, root.getChildAt(0));
252 assertEquals(child3, root.getChildAt(1));
253 assertEquals(child2, root.getChildAt(2));
254 }
255
256 @Test
257 public void testPositionChildAtIncludeParents() throws Exception {
258 final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
259 final TestWindowContainer root = builder.setLayer(0).build();
260
261 final TestWindowContainer child1 = root.addChildWindow();
262 final TestWindowContainer child2 = root.addChildWindow();
263 final TestWindowContainer child11 = child1.addChildWindow();
264 final TestWindowContainer child12 = child1.addChildWindow();
265 final TestWindowContainer child13 = child1.addChildWindow();
266 final TestWindowContainer child21 = child2.addChildWindow();
267 final TestWindowContainer child22 = child2.addChildWindow();
268 final TestWindowContainer child23 = child2.addChildWindow();
269
270 // Test moving to top.
271 child1.positionChildAt(POSITION_TOP, child11, true /* includingParents */);
272 assertEquals(child12, child1.getChildAt(0));
273 assertEquals(child13, child1.getChildAt(1));
274 assertEquals(child11, child1.getChildAt(2));
275 assertEquals(child2, root.getChildAt(0));
276 assertEquals(child1, root.getChildAt(1));
277
278 // Test moving to bottom.
279 child1.positionChildAt(POSITION_BOTTOM, child11, true /* includingParents */);
280 assertEquals(child11, child1.getChildAt(0));
281 assertEquals(child12, child1.getChildAt(1));
282 assertEquals(child13, child1.getChildAt(2));
283 assertEquals(child1, root.getChildAt(0));
284 assertEquals(child2, root.getChildAt(1));
285
286 // Test moving to middle, includeParents shouldn't do anything.
287 child2.positionChildAt(1, child21, true /* includingParents */);
288 assertEquals(child11, child1.getChildAt(0));
289 assertEquals(child12, child1.getChildAt(1));
290 assertEquals(child13, child1.getChildAt(2));
291 assertEquals(child22, child2.getChildAt(0));
292 assertEquals(child21, child2.getChildAt(1));
293 assertEquals(child23, child2.getChildAt(2));
294 assertEquals(child1, root.getChildAt(0));
295 assertEquals(child2, root.getChildAt(1));
296 }
297
298 @Test
299 public void testPositionChildAtInvalid() throws Exception {
300 final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
301 final TestWindowContainer root = builder.setLayer(0).build();
302
303 final TestWindowContainer child1 = root.addChildWindow();
304 final TestWindowContainer child2 = root.addChildWindow();
305
306 boolean gotException = false;
307 try {
308 // Check response to negative position.
309 root.positionChildAt(-1, child1, false /* includingParents */);
310 } catch (IllegalArgumentException e) {
311 gotException = true;
312 }
313 assertTrue(gotException);
314
315 gotException = false;
316 try {
317 // Check response to position that's bigger than child number.
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800318 root.positionChildAt(3, child1, false /* includingParents */);
Andrii Kuliand2765632016-12-12 22:26:34 -0800319 } catch (IllegalArgumentException e) {
320 gotException = true;
321 }
322 assertTrue(gotException);
323 }
324
325 @Test
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700326 public void testIsAnimating() throws Exception {
327 final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
328 final TestWindowContainer root = builder.setLayer(0).build();
329
330 final TestWindowContainer child1 = root.addChildWindow(builder.setIsAnimating(true));
331 final TestWindowContainer child2 = root.addChildWindow();
332 final TestWindowContainer child11 = child1.addChildWindow();
333 final TestWindowContainer child12 = child1.addChildWindow(builder.setIsAnimating(true));
334 final TestWindowContainer child21 = child2.addChildWindow();
335
336 assertTrue(root.isAnimating());
337 assertTrue(child1.isAnimating());
338 assertFalse(child11.isAnimating());
339 assertTrue(child12.isAnimating());
340 assertFalse(child2.isAnimating());
341 assertFalse(child21.isAnimating());
342 }
343
Wale Ogunwalea7e3b642016-08-29 10:15:34 -0700344 @Test
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700345 public void testIsVisible() throws Exception {
346 final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
347 final TestWindowContainer root = builder.setLayer(0).build();
348
349 final TestWindowContainer child1 = root.addChildWindow(builder.setIsVisible(true));
350 final TestWindowContainer child2 = root.addChildWindow();
351 final TestWindowContainer child11 = child1.addChildWindow();
352 final TestWindowContainer child12 = child1.addChildWindow(builder.setIsVisible(true));
353 final TestWindowContainer child21 = child2.addChildWindow();
354
Wale Ogunwale51362492016-09-08 17:49:17 -0700355 assertFalse(root.isVisible());
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700356 assertTrue(child1.isVisible());
357 assertFalse(child11.isVisible());
358 assertTrue(child12.isVisible());
359 assertFalse(child2.isVisible());
360 assertFalse(child21.isVisible());
361 }
362
Wale Ogunwalea7e3b642016-08-29 10:15:34 -0700363 @Test
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700364 public void testOverrideConfigurationAncestorNotification() {
365 final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
366 final TestWindowContainer grandparent = builder.setLayer(0).build();
367
368 final TestWindowContainer parent = grandparent.addChildWindow();
369 final TestWindowContainer child = parent.addChildWindow();
370 child.onOverrideConfigurationChanged(new Configuration());
371
372 assertTrue(grandparent.mOnDescendantOverrideCalled);
373 }
374
375 @Test
Wale Ogunwalef6192862016-09-10 13:42:30 -0700376 public void testRemoveChild() throws Exception {
Wale Ogunwale571771c2016-08-26 13:18:50 -0700377 final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
378 final TestWindowContainer root = builder.setLayer(0).build();
379 final TestWindowContainer child1 = root.addChildWindow();
380 final TestWindowContainer child2 = root.addChildWindow();
381 final TestWindowContainer child11 = child1.addChildWindow();
382 final TestWindowContainer child21 = child2.addChildWindow();
383
384 assertTrue(root.hasChild(child2));
385 assertTrue(root.hasChild(child21));
Wale Ogunwalef6192862016-09-10 13:42:30 -0700386 root.removeChild(child2);
Wale Ogunwale571771c2016-08-26 13:18:50 -0700387 assertFalse(root.hasChild(child2));
388 assertFalse(root.hasChild(child21));
389 assertNull(child2.getParentWindow());
390
391 boolean gotException = false;
392 assertTrue(root.hasChild(child11));
393 try {
394 // Can only detach our direct children.
Wale Ogunwalef6192862016-09-10 13:42:30 -0700395 root.removeChild(child11);
Wale Ogunwale571771c2016-08-26 13:18:50 -0700396 } catch (IllegalArgumentException e) {
397 gotException = true;
398 }
399 assertTrue(gotException);
400 }
401
Wale Ogunwale51362492016-09-08 17:49:17 -0700402 @Test
Bryce Leea163b762017-01-24 11:05:01 -0800403 public void testGetOrientation_childSpecified() throws Exception {
404 testGetOrientation_childSpecifiedConfig(false, SCREEN_ORIENTATION_LANDSCAPE,
405 SCREEN_ORIENTATION_LANDSCAPE);
406 testGetOrientation_childSpecifiedConfig(false, SCREEN_ORIENTATION_UNSET,
Wale Ogunwale17f175c2017-02-07 16:54:10 -0800407 SCREEN_ORIENTATION_UNSPECIFIED);
Bryce Leea163b762017-01-24 11:05:01 -0800408 }
409
410 private void testGetOrientation_childSpecifiedConfig(boolean childVisible, int childOrientation,
411 int expectedOrientation) {
412 final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
413 final TestWindowContainer root = builder.setLayer(0).build();
414 root.setFillsParent(true);
415
416 builder.setIsVisible(childVisible);
417
418 if (childOrientation != SCREEN_ORIENTATION_UNSET) {
419 builder.setOrientation(childOrientation);
420 }
421
422 final TestWindowContainer child1 = root.addChildWindow(builder);
423 child1.setFillsParent(true);
424
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -0700425 assertEquals(expectedOrientation, root.getOrientation());
Bryce Leea163b762017-01-24 11:05:01 -0800426 }
427
428 @Test
Wale Ogunwale51362492016-09-08 17:49:17 -0700429 public void testGetOrientation_Unset() throws Exception {
430 final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
431 final TestWindowContainer root = builder.setLayer(0).setIsVisible(true).build();
432 // Unspecified well because we didn't specify anything...
433 assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, root.getOrientation());
434 }
435
436 @Test
437 public void testGetOrientation_InvisibleParentUnsetVisibleChildren() throws Exception {
438 final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
439 final TestWindowContainer root = builder.setLayer(0).setIsVisible(true).build();
440
441 builder.setIsVisible(false).setLayer(-1);
442 final TestWindowContainer invisible = root.addChildWindow(builder);
443 builder.setIsVisible(true).setLayer(-2);
444 final TestWindowContainer invisibleChild1VisibleAndSet = invisible.addChildWindow(builder);
445 invisibleChild1VisibleAndSet.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
446 // Landscape well because the container is visible and that is what we set on it above.
447 assertEquals(SCREEN_ORIENTATION_LANDSCAPE, invisibleChild1VisibleAndSet.getOrientation());
Bryce Leea163b762017-01-24 11:05:01 -0800448 // Landscape because even though the container isn't visible it has a child that is
449 // specifying it can influence the orientation by being visible.
450 assertEquals(SCREEN_ORIENTATION_LANDSCAPE, invisible.getOrientation());
451 // Landscape because the grandchild is visible and therefore can participate.
452 assertEquals(SCREEN_ORIENTATION_LANDSCAPE, root.getOrientation());
Wale Ogunwale51362492016-09-08 17:49:17 -0700453
454 builder.setIsVisible(true).setLayer(-3);
455 final TestWindowContainer visibleUnset = root.addChildWindow(builder);
456 visibleUnset.setOrientation(SCREEN_ORIENTATION_UNSET);
457 assertEquals(SCREEN_ORIENTATION_UNSET, visibleUnset.getOrientation());
Bryce Leea163b762017-01-24 11:05:01 -0800458 assertEquals(SCREEN_ORIENTATION_LANDSCAPE, root.getOrientation());
Wale Ogunwale51362492016-09-08 17:49:17 -0700459
460 }
461
462 @Test
463 public void testGetOrientation_setBehind() throws Exception {
464 final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
465 final TestWindowContainer root = builder.setLayer(0).setIsVisible(true).build();
466
467 builder.setIsVisible(true).setLayer(-1);
468 final TestWindowContainer visibleUnset = root.addChildWindow(builder);
469 visibleUnset.setOrientation(SCREEN_ORIENTATION_UNSET);
470
471 builder.setIsVisible(true).setLayer(-2);
472 final TestWindowContainer visibleUnsetChild1VisibleSetBehind =
473 visibleUnset.addChildWindow(builder);
474 visibleUnsetChild1VisibleSetBehind.setOrientation(SCREEN_ORIENTATION_BEHIND);
475 // Setting to visible behind will be used by the parents if there isn't another other
476 // container behind this one that has an orientation set.
477 assertEquals(SCREEN_ORIENTATION_BEHIND,
478 visibleUnsetChild1VisibleSetBehind.getOrientation());
479 assertEquals(SCREEN_ORIENTATION_BEHIND, visibleUnset.getOrientation());
480 assertEquals(SCREEN_ORIENTATION_BEHIND, root.getOrientation());
481 }
482
483 @Test
484 public void testGetOrientation_fillsParent() throws Exception {
485 final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
486 final TestWindowContainer root = builder.setLayer(0).setIsVisible(true).build();
487
488 builder.setIsVisible(true).setLayer(-1);
489 final TestWindowContainer visibleUnset = root.addChildWindow(builder);
490 visibleUnset.setOrientation(SCREEN_ORIENTATION_BEHIND);
491
492 builder.setLayer(1).setIsVisible(true);
493 final TestWindowContainer visibleUnspecifiedRootChild = root.addChildWindow(builder);
494 visibleUnspecifiedRootChild.setFillsParent(false);
495 visibleUnspecifiedRootChild.setOrientation(SCREEN_ORIENTATION_UNSPECIFIED);
496 // Unset because the child doesn't fill the parent. May as well be invisible...
497 assertEquals(SCREEN_ORIENTATION_UNSET, visibleUnspecifiedRootChild.getOrientation());
498 // The parent uses whatever orientation is set behind this container since it doesn't fill
499 // the parent.
500 assertEquals(SCREEN_ORIENTATION_BEHIND, root.getOrientation());
501
502 // Test case of child filling its parent, but its parent isn't filling its own parent.
503 builder.setLayer(2).setIsVisible(true);
504 final TestWindowContainer visibleUnspecifiedRootChildChildFillsParent =
505 visibleUnspecifiedRootChild.addChildWindow(builder);
506 visibleUnspecifiedRootChildChildFillsParent.setOrientation(
507 SCREEN_ORIENTATION_PORTRAIT);
508 assertEquals(SCREEN_ORIENTATION_PORTRAIT,
509 visibleUnspecifiedRootChildChildFillsParent.getOrientation());
510 assertEquals(SCREEN_ORIENTATION_UNSET, visibleUnspecifiedRootChild.getOrientation());
511 assertEquals(SCREEN_ORIENTATION_BEHIND, root.getOrientation());
512
513
514 visibleUnspecifiedRootChild.setFillsParent(true);
515 assertEquals(SCREEN_ORIENTATION_PORTRAIT, visibleUnspecifiedRootChild.getOrientation());
516 assertEquals(SCREEN_ORIENTATION_PORTRAIT, root.getOrientation());
517 }
518
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -0700519 @Test
520 public void testCompareTo() throws Exception {
521 final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
522 final TestWindowContainer root = builder.setLayer(0).build();
523
524 final TestWindowContainer child1 = root.addChildWindow();
525 final TestWindowContainer child11 = child1.addChildWindow();
526 final TestWindowContainer child12 = child1.addChildWindow();
527
528 final TestWindowContainer child2 = root.addChildWindow();
529 final TestWindowContainer child21 = child2.addChildWindow();
530 final TestWindowContainer child22 = child2.addChildWindow();
531 final TestWindowContainer child23 = child2.addChildWindow();
532 final TestWindowContainer child221 = child22.addChildWindow();
533 final TestWindowContainer child222 = child22.addChildWindow();
534 final TestWindowContainer child223 = child22.addChildWindow();
535 final TestWindowContainer child2221 = child222.addChildWindow();
536 final TestWindowContainer child2222 = child222.addChildWindow();
537 final TestWindowContainer child2223 = child222.addChildWindow();
538
539 final TestWindowContainer root2 = builder.setLayer(0).build();
540
541 assertEquals(0, root.compareTo(root));
542 assertEquals(-1, child1.compareTo(child2));
543 assertEquals(1, child2.compareTo(child1));
544
545 boolean inTheSameTree = true;
546 try {
547 root.compareTo(root2);
548 } catch (IllegalArgumentException e) {
549 inTheSameTree = false;
550 }
551 assertFalse(inTheSameTree);
552
553 assertEquals(-1, child1.compareTo(child11));
554 assertEquals(1, child21.compareTo(root));
555 assertEquals(1, child21.compareTo(child12));
556 assertEquals(-1, child11.compareTo(child2));
557 assertEquals(1, child2221.compareTo(child11));
558 assertEquals(-1, child2222.compareTo(child223));
559 assertEquals(1, child2223.compareTo(child21));
560 }
561
Andrii Kulian441e4492016-09-29 15:25:00 -0700562 @Test
563 public void testConfigurationInit() throws Exception {
564 final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
565
566 // Check root container initial config.
567 final TestWindowContainer root = builder.setLayer(0).build();
568 assertEquals(Configuration.EMPTY, root.getOverrideConfiguration());
569 assertEquals(Configuration.EMPTY, root.getMergedOverrideConfiguration());
570 assertEquals(Configuration.EMPTY, root.getConfiguration());
571
572 // Check child initial config.
573 final TestWindowContainer child1 = root.addChildWindow();
574 assertEquals(Configuration.EMPTY, child1.getOverrideConfiguration());
575 assertEquals(Configuration.EMPTY, child1.getMergedOverrideConfiguration());
576 assertEquals(Configuration.EMPTY, child1.getConfiguration());
577
578 // Check child initial config if root has overrides.
579 final Configuration rootOverrideConfig = new Configuration();
580 rootOverrideConfig.fontScale = 1.3f;
581 root.onOverrideConfigurationChanged(rootOverrideConfig);
582 final TestWindowContainer child2 = root.addChildWindow();
583 assertEquals(Configuration.EMPTY, child2.getOverrideConfiguration());
584 assertEquals(rootOverrideConfig, child2.getMergedOverrideConfiguration());
585 assertEquals(rootOverrideConfig, child2.getConfiguration());
586
587 // Check child initial config if root has parent config set.
588 final Configuration rootParentConfig = new Configuration();
589 rootParentConfig.fontScale = 0.8f;
590 rootParentConfig.orientation = SCREEN_ORIENTATION_LANDSCAPE;
591 root.onConfigurationChanged(rootParentConfig);
592 final Configuration rootFullConfig = new Configuration(rootParentConfig);
593 rootFullConfig.updateFrom(rootOverrideConfig);
594
595 final TestWindowContainer child3 = root.addChildWindow();
596 assertEquals(Configuration.EMPTY, child3.getOverrideConfiguration());
597 assertEquals(rootOverrideConfig, child3.getMergedOverrideConfiguration());
598 assertEquals(rootFullConfig, child3.getConfiguration());
599 }
600
601 @Test
602 public void testConfigurationChangeOnAddRemove() throws Exception {
603 final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
604
605 // Init root's config.
606 final TestWindowContainer root = builder.setLayer(0).build();
607 final Configuration rootOverrideConfig = new Configuration();
608 rootOverrideConfig.fontScale = 1.3f;
609 root.onOverrideConfigurationChanged(rootOverrideConfig);
610
611 // Init child's config.
612 final TestWindowContainer child = root.addChildWindow();
613 final Configuration childOverrideConfig = new Configuration();
614 childOverrideConfig.densityDpi = 320;
615 child.onOverrideConfigurationChanged(childOverrideConfig);
Andrii Kulianb94292e2016-10-19 13:30:58 -0700616 final Configuration mergedOverrideConfig = new Configuration(root.getConfiguration());
617 mergedOverrideConfig.updateFrom(childOverrideConfig);
Andrii Kulian441e4492016-09-29 15:25:00 -0700618
Andrii Kulianb94292e2016-10-19 13:30:58 -0700619 // Check configuration update when child is removed from parent - it should remain same.
Andrii Kulian441e4492016-09-29 15:25:00 -0700620 root.removeChild(child);
621 assertEquals(childOverrideConfig, child.getOverrideConfiguration());
Andrii Kulianb94292e2016-10-19 13:30:58 -0700622 assertEquals(mergedOverrideConfig, child.getMergedOverrideConfiguration());
623 assertEquals(mergedOverrideConfig, child.getConfiguration());
Andrii Kulian441e4492016-09-29 15:25:00 -0700624
625 // It may be paranoia... but let's check if parent's config didn't change after removal.
626 assertEquals(rootOverrideConfig, root.getOverrideConfiguration());
627 assertEquals(rootOverrideConfig, root.getMergedOverrideConfiguration());
628 assertEquals(rootOverrideConfig, root.getConfiguration());
629
Andrii Kulianb94292e2016-10-19 13:30:58 -0700630 // Init different root
631 final TestWindowContainer root2 = builder.setLayer(0).build();
632 final Configuration rootOverrideConfig2 = new Configuration();
633 rootOverrideConfig2.fontScale = 1.1f;
634 root2.onOverrideConfigurationChanged(rootOverrideConfig2);
635
636 // Check configuration update when child is added to different parent.
637 mergedOverrideConfig.setTo(rootOverrideConfig2);
Andrii Kulian441e4492016-09-29 15:25:00 -0700638 mergedOverrideConfig.updateFrom(childOverrideConfig);
Andrii Kulianb94292e2016-10-19 13:30:58 -0700639 root2.addChildWindow(child);
Andrii Kulian441e4492016-09-29 15:25:00 -0700640 assertEquals(childOverrideConfig, child.getOverrideConfiguration());
641 assertEquals(mergedOverrideConfig, child.getMergedOverrideConfiguration());
642 assertEquals(mergedOverrideConfig, child.getConfiguration());
643 }
644
645 @Test
646 public void testConfigurationChangePropagation() throws Exception {
647 final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
648
649 // Builds 3-level vertical hierarchy with one window container on each level.
650 // In addition to different overrides on each level, everyone in hierarchy will have one
651 // common overridden value - orientation;
652
653 // Init root's config.
654 final TestWindowContainer root = builder.setLayer(0).build();
655 final Configuration rootOverrideConfig = new Configuration();
656 rootOverrideConfig.fontScale = 1.3f;
657 rootOverrideConfig.orientation = SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
658 root.onOverrideConfigurationChanged(rootOverrideConfig);
659
660 // Init children.
661 final TestWindowContainer child1 = root.addChildWindow();
662 final Configuration childOverrideConfig1 = new Configuration();
663 childOverrideConfig1.densityDpi = 320;
664 childOverrideConfig1.orientation = SCREEN_ORIENTATION_LANDSCAPE;
665 child1.onOverrideConfigurationChanged(childOverrideConfig1);
666
667 final TestWindowContainer child2 = child1.addChildWindow();
668 final Configuration childOverrideConfig2 = new Configuration();
669 childOverrideConfig2.screenWidthDp = 150;
670 childOverrideConfig2.orientation = SCREEN_ORIENTATION_PORTRAIT;
671 child2.onOverrideConfigurationChanged(childOverrideConfig2);
672
673 // Check configuration on all levels when root override is updated.
674 rootOverrideConfig.smallestScreenWidthDp = 200;
675 root.onOverrideConfigurationChanged(rootOverrideConfig);
676
677 final Configuration mergedOverrideConfig1 = new Configuration(rootOverrideConfig);
678 mergedOverrideConfig1.updateFrom(childOverrideConfig1);
679 final Configuration mergedConfig1 = new Configuration(mergedOverrideConfig1);
680
681 final Configuration mergedOverrideConfig2 = new Configuration(mergedOverrideConfig1);
682 mergedOverrideConfig2.updateFrom(childOverrideConfig2);
683 final Configuration mergedConfig2 = new Configuration(mergedOverrideConfig2);
684
685 assertEquals(rootOverrideConfig, root.getOverrideConfiguration());
686 assertEquals(rootOverrideConfig, root.getMergedOverrideConfiguration());
687 assertEquals(rootOverrideConfig, root.getConfiguration());
688
689 assertEquals(childOverrideConfig1, child1.getOverrideConfiguration());
690 assertEquals(mergedOverrideConfig1, child1.getMergedOverrideConfiguration());
691 assertEquals(mergedConfig1, child1.getConfiguration());
692
693 assertEquals(childOverrideConfig2, child2.getOverrideConfiguration());
694 assertEquals(mergedOverrideConfig2, child2.getMergedOverrideConfiguration());
695 assertEquals(mergedConfig2, child2.getConfiguration());
696
697 // Check configuration on all levels when root parent config is updated.
698 final Configuration rootParentConfig = new Configuration();
699 rootParentConfig.screenHeightDp = 100;
700 rootParentConfig.orientation = SCREEN_ORIENTATION_REVERSE_PORTRAIT;
701 root.onConfigurationChanged(rootParentConfig);
702 final Configuration mergedRootConfig = new Configuration(rootParentConfig);
703 mergedRootConfig.updateFrom(rootOverrideConfig);
704
705 mergedConfig1.setTo(mergedRootConfig);
706 mergedConfig1.updateFrom(mergedOverrideConfig1);
707
708 mergedConfig2.setTo(mergedConfig1);
709 mergedConfig2.updateFrom(mergedOverrideConfig2);
710
711 assertEquals(rootOverrideConfig, root.getOverrideConfiguration());
712 assertEquals(rootOverrideConfig, root.getMergedOverrideConfiguration());
713 assertEquals(mergedRootConfig, root.getConfiguration());
714
715 assertEquals(childOverrideConfig1, child1.getOverrideConfiguration());
716 assertEquals(mergedOverrideConfig1, child1.getMergedOverrideConfiguration());
717 assertEquals(mergedConfig1, child1.getConfiguration());
718
719 assertEquals(childOverrideConfig2, child2.getOverrideConfiguration());
720 assertEquals(mergedOverrideConfig2, child2.getMergedOverrideConfiguration());
721 assertEquals(mergedConfig2, child2.getConfiguration());
722 }
723
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700724 /* Used so we can gain access to some protected members of the {@link WindowContainer} class */
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700725 private class TestWindowContainer extends WindowContainer<TestWindowContainer> {
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700726 private final int mLayer;
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700727 private boolean mIsAnimating;
728 private boolean mIsVisible;
Wale Ogunwale51362492016-09-08 17:49:17 -0700729 private boolean mFillsParent;
Bryce Leea163b762017-01-24 11:05:01 -0800730 private Integer mOrientation;
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700731
Andrii Kuliand2765632016-12-12 22:26:34 -0800732 private boolean mOnParentSetCalled;
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700733 private boolean mOnDescendantOverrideCalled;
Andrii Kuliand2765632016-12-12 22:26:34 -0800734
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700735 /**
736 * Compares 2 window layers and returns -1 if the first is lesser than the second in terms
737 * of z-order and 1 otherwise.
738 */
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700739 private final Comparator<TestWindowContainer> mWindowSubLayerComparator = (w1, w2) -> {
740 final int layer1 = w1.mLayer;
741 final int layer2 = w2.mLayer;
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700742 if (layer1 < layer2 || (layer1 == layer2 && layer2 < 0 )) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700743 // We insert the child window into the list ordered by the mLayer. For same layers,
744 // the negative one should go below others; the positive one should go above others.
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700745 return -1;
746 }
747 return 1;
748 };
749
Bryce Leea163b762017-01-24 11:05:01 -0800750 TestWindowContainer(int layer, boolean isAnimating, boolean isVisible,
751 Integer orientation) {
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700752 mLayer = layer;
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700753 mIsAnimating = isAnimating;
754 mIsVisible = isVisible;
Wale Ogunwale51362492016-09-08 17:49:17 -0700755 mFillsParent = true;
Bryce Leea163b762017-01-24 11:05:01 -0800756 mOrientation = orientation;
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700757 }
758
759 TestWindowContainer getParentWindow() {
760 return (TestWindowContainer) getParent();
761 }
762
763 int getChildrenCount() {
764 return mChildren.size();
765 }
766
Wale Ogunwalef6192862016-09-10 13:42:30 -0700767 TestWindowContainer addChildWindow(TestWindowContainer child) {
768 addChild(child, mWindowSubLayerComparator);
769 return child;
770 }
771
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700772 TestWindowContainer addChildWindow(TestWindowContainerBuilder childBuilder) {
773 TestWindowContainer child = childBuilder.build();
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700774 addChild(child, mWindowSubLayerComparator);
775 return child;
776 }
777
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700778 TestWindowContainer addChildWindow() {
779 return addChildWindow(new TestWindowContainerBuilder().setLayer(1));
780 }
781
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700782 TestWindowContainer getChildAt(int index) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700783 return mChildren.get(index);
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700784 }
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700785
786 @Override
Andrii Kuliand2765632016-12-12 22:26:34 -0800787 void onParentSet() {
788 mOnParentSetCalled = true;
789 }
790
791 @Override
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700792 void onDescendantOverrideConfigurationChanged() {
793 mOnDescendantOverrideCalled = true;
794 super.onDescendantOverrideConfigurationChanged();
795 }
796
797 @Override
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700798 boolean isAnimating() {
799 return mIsAnimating || super.isAnimating();
800 }
801
802 @Override
803 boolean isVisible() {
Wale Ogunwale51362492016-09-08 17:49:17 -0700804 return mIsVisible;
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700805 }
Wale Ogunwale571771c2016-08-26 13:18:50 -0700806
807 @Override
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -0700808 int getOrientation(int candidate) {
809 return mOrientation != null ? mOrientation : super.getOrientation(candidate);
810 }
811
812 @Override
Bryce Leea163b762017-01-24 11:05:01 -0800813 int getOrientation() {
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -0700814 return getOrientation(super.mOrientation);
Bryce Leea163b762017-01-24 11:05:01 -0800815 }
816
817 @Override
Wale Ogunwale51362492016-09-08 17:49:17 -0700818 boolean fillsParent() {
819 return mFillsParent;
Wale Ogunwale571771c2016-08-26 13:18:50 -0700820 }
821
Wale Ogunwale51362492016-09-08 17:49:17 -0700822 void setFillsParent(boolean fillsParent) {
823 mFillsParent = fillsParent;
Wale Ogunwale571771c2016-08-26 13:18:50 -0700824 }
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700825 }
826
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700827 private class TestWindowContainerBuilder {
828 private int mLayer;
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700829 private boolean mIsAnimating;
830 private boolean mIsVisible;
Bryce Leea163b762017-01-24 11:05:01 -0800831 private Integer mOrientation;
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700832
Wale Ogunwale51362492016-09-08 17:49:17 -0700833 public TestWindowContainerBuilder() {
834 reset();
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700835 }
836
Wale Ogunwale51362492016-09-08 17:49:17 -0700837 TestWindowContainerBuilder setLayer(int layer) {
838 mLayer = layer;
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700839 return this;
840 }
841
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700842 TestWindowContainerBuilder setIsAnimating(boolean isAnimating) {
843 mIsAnimating = isAnimating;
844 return this;
845 }
846
847 TestWindowContainerBuilder setIsVisible(boolean isVisible) {
848 mIsVisible = isVisible;
849 return this;
850 }
851
Bryce Leea163b762017-01-24 11:05:01 -0800852 TestWindowContainerBuilder setOrientation(int orientation) {
853 mOrientation = orientation;
854 return this;
855 }
856
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700857 TestWindowContainerBuilder reset() {
858 mLayer = 0;
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700859 mIsAnimating = false;
860 mIsVisible = false;
Bryce Leea163b762017-01-24 11:05:01 -0800861 mOrientation = null;
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700862 return this;
863 }
864
865 TestWindowContainer build() {
Bryce Leea163b762017-01-24 11:05:01 -0800866 return new TestWindowContainer(mLayer, mIsAnimating, mIsVisible, mOrientation);
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700867 }
868 }
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700869}