1 /*
2  * Copyright (C) 2018 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 android.server.wm;
18 
19 import static android.view.WindowInsets.Type.captionBar;
20 import static android.view.WindowInsets.Type.displayCutout;
21 import static android.view.WindowInsets.Type.ime;
22 import static android.view.WindowInsets.Type.mandatorySystemGestures;
23 import static android.view.WindowInsets.Type.navigationBars;
24 import static android.view.WindowInsets.Type.statusBars;
25 import static android.view.WindowInsets.Type.systemGestures;
26 import static android.view.WindowInsets.Type.tappableElement;
27 
28 import static org.junit.Assert.assertEquals;
29 import static org.junit.Assert.assertFalse;
30 import static org.junit.Assert.assertNotEquals;
31 import static org.junit.Assert.assertNotNull;
32 import static org.junit.Assert.assertNotSame;
33 import static org.junit.Assert.assertNull;
34 import static org.junit.Assert.assertSame;
35 import static org.junit.Assert.assertTrue;
36 
37 import android.graphics.Insets;
38 import android.graphics.Rect;
39 import android.platform.test.annotations.Presubmit;
40 import android.view.DisplayCutout;
41 import android.view.RoundedCorner;
42 import android.view.WindowInsets;
43 import android.view.WindowInsets.Type;
44 
45 import androidx.test.filters.SmallTest;
46 import androidx.test.runner.AndroidJUnit4;
47 
48 import org.junit.Test;
49 import org.junit.runner.RunWith;
50 
51 import java.util.Collections;
52 
53 /**
54  * Test {@link WindowInsets}.
55  */
56 @SmallTest
57 @RunWith(AndroidJUnit4.class)
58 @Presubmit
59 public class WindowInsetsTest {
60 
61     private static final DisplayCutout CUTOUT = new DisplayCutout(new Rect(0, 10, 0, 0),
62             Collections.singletonList(new Rect(5, 0, 15, 10)));
63     private static final DisplayCutout CUTOUT2 = new DisplayCutout(new Rect(0, 15, 0, 0),
64             Collections.singletonList(new Rect(5, 0, 15, 15)));
65     private static final RoundedCorner ROUNDED_CORNER_TOP_LEFT =
66             new RoundedCorner(RoundedCorner.POSITION_TOP_LEFT, 10, 10, 10);
67     private static final RoundedCorner ROUNDED_CORNER_TOP_RIGHT =
68             new RoundedCorner(RoundedCorner.POSITION_TOP_RIGHT, 10, 90, 10);
69     private static final RoundedCorner ROUNDED_CORNER_BOTTOM_RIGHT =
70             new RoundedCorner(RoundedCorner.POSITION_BOTTOM_RIGHT, 10, 90, 190);
71     private static final RoundedCorner ROUNDED_CORNER_BOTTOM_LEFT =
72             new RoundedCorner(RoundedCorner.POSITION_BOTTOM_LEFT, 10, 10, 190);
73     private static final int INSET_LEFT = 1;
74     private static final int INSET_TOP = 2;
75     private static final int INSET_RIGHT = 3;
76     private static final int INSET_BOTTOM = 4;
77 
78     @Test
testBuilder()79     public void testBuilder() {
80         final WindowInsets insets = new WindowInsets.Builder()
81                 .setSystemWindowInsets(Insets.of(1, 2, 3, 4))
82                 .setStableInsets(Insets.of(5, 6, 7, 8))
83                 .setSystemGestureInsets(Insets.of(9, 10, 11, 12))
84                 .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
85                 .setTappableElementInsets(Insets.of(17, 18, 19, 20))
86                 .setDisplayCutout(CUTOUT)
87                 .setRoundedCorner(RoundedCorner.POSITION_TOP_LEFT, ROUNDED_CORNER_TOP_LEFT)
88                 .setRoundedCorner(RoundedCorner.POSITION_TOP_RIGHT, ROUNDED_CORNER_TOP_RIGHT)
89                 .setRoundedCorner(RoundedCorner.POSITION_BOTTOM_RIGHT, ROUNDED_CORNER_BOTTOM_RIGHT)
90                 .setRoundedCorner(RoundedCorner.POSITION_BOTTOM_LEFT, ROUNDED_CORNER_BOTTOM_LEFT)
91                 .build();
92 
93         assertEquals(Insets.of(1, 2, 3, 4), insets.getSystemWindowInsets());
94         assertEquals(Insets.of(5, 6, 7, 8), insets.getStableInsets());
95         assertEquals(Insets.of(9, 10, 11, 12), insets.getSystemGestureInsets());
96         assertEquals(Insets.of(13, 14, 15, 16), insets.getMandatorySystemGestureInsets());
97         assertEquals(Insets.of(17, 18, 19, 20), insets.getTappableElementInsets());
98         assertSame(CUTOUT, insets.getDisplayCutout());
99         assertEquals(getCutoutSafeInsets(insets), insets.getInsets(Type.displayCutout()));
100         assertEquals(ROUNDED_CORNER_TOP_LEFT,
101                 insets.getRoundedCorner(RoundedCorner.POSITION_TOP_LEFT));
102         assertEquals(ROUNDED_CORNER_TOP_RIGHT,
103                 insets.getRoundedCorner(RoundedCorner.POSITION_TOP_RIGHT));
104         assertEquals(ROUNDED_CORNER_BOTTOM_RIGHT,
105                 insets.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_RIGHT));
106         assertEquals(ROUNDED_CORNER_BOTTOM_LEFT,
107                 insets.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_LEFT));
108     }
109 
110     @Test
testBuilder_copy()111     public void testBuilder_copy() {
112         final WindowInsets insets = new WindowInsets.Builder()
113                 .setSystemWindowInsets(Insets.of(1, 2, 3, 4))
114                 .setStableInsets(Insets.of(5, 6, 7, 8))
115                 .setSystemGestureInsets(Insets.of(9, 10, 11, 12))
116                 .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
117                 .setTappableElementInsets(Insets.of(17, 18, 19, 20))
118                 .setDisplayCutout(CUTOUT)
119                 .setRoundedCorner(RoundedCorner.POSITION_TOP_LEFT, ROUNDED_CORNER_TOP_LEFT)
120                 .setRoundedCorner(RoundedCorner.POSITION_TOP_RIGHT, ROUNDED_CORNER_TOP_RIGHT)
121                 .setRoundedCorner(RoundedCorner.POSITION_BOTTOM_RIGHT, ROUNDED_CORNER_BOTTOM_RIGHT)
122                 .setRoundedCorner(RoundedCorner.POSITION_BOTTOM_LEFT, ROUNDED_CORNER_BOTTOM_LEFT)
123                 .build();
124         final WindowInsets copy = new WindowInsets.Builder(insets).build();
125 
126         assertEquals(insets, copy);
127     }
128 
129     @Test
testBuilder_consumed()130     public void testBuilder_consumed() {
131         final WindowInsets insets = new WindowInsets.Builder()
132                 .build();
133 
134         assertFalse(insets.hasSystemWindowInsets());
135         assertFalse(insets.hasStableInsets());
136         assertEquals(Insets.NONE, insets.getSystemGestureInsets());
137         assertNull(insets.getDisplayCutout());
138         assertNull(insets.getRoundedCorner(RoundedCorner.POSITION_TOP_LEFT));
139         assertNull(insets.getRoundedCorner(RoundedCorner.POSITION_TOP_RIGHT));
140         assertNull(insets.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_RIGHT));
141         assertNull(insets.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_LEFT));
142         assertTrue(insets.isConsumed());
143     }
144 
145     @Test
testBuilder_emptyCutout()146     public void testBuilder_emptyCutout() {
147         final WindowInsets insets = new WindowInsets.Builder()
148                 .setDisplayCutout(null)
149                 .build();
150 
151         assertFalse(insets.hasSystemWindowInsets());
152         assertFalse(insets.hasStableInsets());
153         assertEquals(Insets.NONE, insets.getSystemGestureInsets());
154 
155         assertNull(insets.getDisplayCutout());
156         assertFalse(insets.isConsumed());
157         assertTrue(insets.consumeDisplayCutout().isConsumed());
158         assertEquals(Insets.NONE, insets.getInsets(Type.displayCutout()));
159     }
160 
161     @Test
testBuilder_producesImmutableWindowInsets()162     public void testBuilder_producesImmutableWindowInsets() {
163         final WindowInsets.Builder builder = new WindowInsets.Builder()
164                 .setSystemWindowInsets(Insets.of(1, 2, 3, 4))
165                 .setStableInsets(Insets.of(5, 6, 7, 8))
166                 .setSystemGestureInsets(Insets.of(9, 10, 11, 12))
167                 .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
168                 .setTappableElementInsets(Insets.of(17, 18, 19, 20))
169                 .setDisplayCutout(CUTOUT);
170         final WindowInsets insets = builder.build();
171 
172         builder.setSystemWindowInsets(Insets.NONE);
173         builder.setStableInsets(Insets.NONE);
174         builder.setDisplayCutout(null);
175         builder.setSystemGestureInsets(Insets.NONE);
176         builder.setMandatorySystemGestureInsets(Insets.NONE);
177         builder.setTappableElementInsets(Insets.NONE);
178 
179         assertEquals(Insets.of(1, 2, 3, 4), insets.getSystemWindowInsets());
180         assertEquals(Insets.of(5, 6, 7, 8), insets.getStableInsets());
181         assertSame(CUTOUT, insets.getDisplayCutout());
182         assertEquals(getCutoutSafeInsets(insets), insets.getInsets(Type.displayCutout()));
183     }
184 
185     @Test
testBuilder_typeMap()186     public void testBuilder_typeMap() {
187         final WindowInsets insets = new WindowInsets.Builder()
188                 .setInsets(statusBars(), Insets.of(0, 50, 0, 0))
189                 .setInsets(navigationBars(), Insets.of(0, 0, 0, 100))
190                 .setInsets(tappableElement(), Insets.of(0, 10, 0, 10))
191                 .setInsets(mandatorySystemGestures(), Insets.of(0, 20, 0, 20))
192                 .setInsets(systemGestures(), Insets.of(0, 30, 0, 30))
193                 .setInsets(displayCutout(), Insets.of(0, 5, 0, 0))
194                 .setInsets(captionBar(), Insets.of(0, 50, 0, 0))
195                 .setInsets(ime(), Insets.of(0, 0, 0, 300))
196                 .build();
197         assertEquals(Insets.of(0, 50, 0, 0), insets.getInsets(statusBars()));
198         assertEquals(Insets.of(0, 0, 0, 100), insets.getInsets(navigationBars()));
199         assertEquals(Insets.of(0, 10, 0, 10), insets.getInsets(tappableElement()));
200         assertEquals(Insets.of(0, 20, 0, 20), insets.getInsets(mandatorySystemGestures()));
201         assertEquals(Insets.of(0, 30, 0, 30), insets.getInsets(systemGestures()));
202         assertEquals(Insets.of(0, 5, 0, 0), insets.getInsets(displayCutout()));
203         assertEquals(Insets.of(0, 50, 0, 0), insets.getInsets(captionBar()));
204         assertEquals(Insets.of(0, 50, 0, 100), insets.getSystemWindowInsets());
205         assertEquals(Insets.of(0, 0, 0, 300), insets.getInsets(ime()));
206     }
207 
208     @Test
testBuilder_typeMapIgnoringVisibility()209     public void testBuilder_typeMapIgnoringVisibility() {
210         final WindowInsets insets = new WindowInsets.Builder()
211                 .setInsetsIgnoringVisibility(statusBars(), Insets.of(0, 50, 0, 0))
212                 .setInsetsIgnoringVisibility(navigationBars(), Insets.of(0, 0, 0, 100))
213                 .setInsetsIgnoringVisibility(tappableElement(), Insets.of(0, 10, 0, 10))
214                 .setInsetsIgnoringVisibility(mandatorySystemGestures(), Insets.of(0, 20, 0, 20))
215                 .setInsetsIgnoringVisibility(systemGestures(), Insets.of(0, 30, 0, 30))
216                 .setInsetsIgnoringVisibility(displayCutout(), Insets.of(0, 5, 0, 0))
217                 .setInsetsIgnoringVisibility(captionBar(), Insets.of(0, 50, 0, 0))
218                 .build();
219         assertEquals(Insets.of(0, 50, 0, 0),
220                 insets.getInsetsIgnoringVisibility(statusBars()));
221         assertEquals(Insets.of(0, 0, 0, 100),
222                 insets.getInsetsIgnoringVisibility(navigationBars()));
223         assertEquals(Insets.of(0, 10, 0, 10),
224                 insets.getInsetsIgnoringVisibility(tappableElement()));
225         assertEquals(Insets.of(0, 20, 0, 20),
226                 insets.getInsetsIgnoringVisibility(mandatorySystemGestures()));
227         assertEquals(Insets.of(0, 30, 0, 30),
228                 insets.getInsetsIgnoringVisibility(systemGestures()));
229         assertEquals(Insets.of(0, 5, 0, 0),
230                 insets.getInsetsIgnoringVisibility(displayCutout()));
231         assertEquals(Insets.of(0, 50, 0, 0),
232                 insets.getInsetsIgnoringVisibility(captionBar()));
233         assertEquals(Insets.of(0, 50, 0, 100), insets.getStableInsets());
234 
235         Exception exception = null;
236         try {
237             new WindowInsets.Builder().setInsetsIgnoringVisibility(ime(), Insets.NONE);
238         } catch (Exception e) {
239             exception = e;
240         }
241         assertNotNull(exception);
242 
243         exception = null;
244         try {
245             insets.getInsetsIgnoringVisibility(ime());
246         } catch (Exception e) {
247             exception = e;
248         }
249         assertNotNull(exception);
250     }
251 
252     @Test
testBuilder_compatInsets()253     public void testBuilder_compatInsets() {
254         final WindowInsets insets = new WindowInsets.Builder()
255                 .setSystemWindowInsets(Insets.of(0, 50, 30, 10))
256                 .build();
257         assertEquals(Insets.of(0, 50, 0, 0), insets.getInsets(statusBars()));
258         assertEquals(Insets.of(0, 0, 30, 10), insets.getInsets(navigationBars()));
259     }
260 
261     @Test
testBuilder_visibility()262     public void testBuilder_visibility() {
263         final WindowInsets insets = new WindowInsets.Builder()
264                 .setInsets(navigationBars(), Insets.of(0, 0, 0, 100))
265                 .setInsets(ime(), Insets.of(0, 0, 0, 300))
266                 .setVisible(navigationBars(), true)
267                 .setVisible(ime(), true)
268                 .build();
269         assertTrue(insets.isVisible(navigationBars()));
270         assertTrue(insets.isVisible(navigationBars() | ime()));
271         assertFalse(insets.isVisible(navigationBars() | statusBars()));
272     }
273 
274     @Test
testEquality()275     public void testEquality() {
276         final WindowInsets insets = new WindowInsets.Builder()
277                 .setSystemWindowInsets(Insets.of(1, 2, 3, 4))
278                 .setStableInsets(Insets.of(5, 6, 7, 8))
279                 .setSystemGestureInsets(Insets.of(9, 10, 11, 12))
280                 .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
281                 .setTappableElementInsets(Insets.of(17, 18, 19, 20))
282                 .setDisplayCutout(CUTOUT).build();
283 
284         final WindowInsets insets2 = new WindowInsets.Builder()
285                 .setSystemWindowInsets(Insets.of(1, 2, 3, 4))
286                 .setStableInsets(Insets.of(5, 6, 7, 8))
287                 .setSystemGestureInsets(Insets.of(9, 10, 11, 12))
288                 .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
289                 .setTappableElementInsets(Insets.of(17, 18, 19, 20))
290                 .setDisplayCutout(CUTOUT).build();
291 
292         assertNotSame("Test setup failed, insets and insets2 should not be identical",
293                 insets, insets2);
294 
295         assertEquals(insets, insets2);
296         assertEquals(insets.hashCode(), insets2.hashCode());
297     }
298 
299     @Test
testInEquality_consuming()300     public void testInEquality_consuming() {
301         final WindowInsets insets = new WindowInsets.Builder()
302                 .setSystemWindowInsets(Insets.of(1, 2, 3, 4))
303                 .setStableInsets(Insets.of(5, 6, 7, 8))
304                 .setSystemGestureInsets(Insets.of(9, 10, 11, 12))
305                 .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
306                 .setTappableElementInsets(Insets.of(17, 18, 19, 20))
307                 .setDisplayCutout(CUTOUT).build();
308 
309         assertNotEquals(insets, insets.consumeSystemWindowInsets());
310         assertNotEquals(insets, insets.consumeDisplayCutout());
311     }
312 
313     @Test
testConsume_doesntChangeVisibility()314     public void testConsume_doesntChangeVisibility() {
315         final WindowInsets insets = new WindowInsets.Builder()
316                 .setInsets(ime(), Insets.of(0, 0, 0, 300))
317                 .setVisible(ime(), true)
318                 .build();
319 
320         final WindowInsets consumed = insets.consumeSystemWindowInsets();
321 
322         assertTrue(consumed.isVisible(ime()));
323     }
324 
325     @Test
testConsume_systemWindowInsets()326     public void testConsume_systemWindowInsets() {
327         final WindowInsets insets = new WindowInsets.Builder()
328                 .setSystemWindowInsets(Insets.of(1, 2, 3, 4))
329                 .setStableInsets(Insets.of(5, 6, 7, 8))
330                 .setSystemGestureInsets(Insets.of(9, 10, 11, 12))
331                 .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
332                 .setTappableElementInsets(Insets.of(17, 18, 19, 20))
333                 .setDisplayCutout(CUTOUT).build();
334 
335         final WindowInsets consumed = insets.consumeSystemWindowInsets();
336 
337         assertEquals(Insets.NONE, consumed.getSystemWindowInsets());
338         assertEquals(Insets.NONE, consumed.getStableInsets());
339         assertEquals(insets.getDisplayCutout(), consumed.getDisplayCutout());
340         assertEquals(Insets.NONE, consumed.getSystemGestureInsets());
341         assertEquals(Insets.NONE, consumed.getMandatorySystemGestureInsets());
342         assertEquals(Insets.NONE, consumed.getTappableElementInsets());
343         assertEquals(Insets.NONE, consumed.getInsets(Type.displayCutout()));
344     }
345 
346     @Test
testConsume_stableInsets()347     public void testConsume_stableInsets() {
348         final WindowInsets insets = new WindowInsets.Builder()
349                 .setSystemWindowInsets(Insets.of(1, 2, 3, 4))
350                 .setStableInsets(Insets.of(5, 6, 7, 8))
351                 .setSystemGestureInsets(Insets.of(9, 10, 11, 12))
352                 .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
353                 .setTappableElementInsets(Insets.of(17, 18, 19, 20))
354                 .setDisplayCutout(CUTOUT).build();
355 
356         final WindowInsets consumed = insets.consumeStableInsets();
357         assertSame(insets, consumed);
358     }
359 
360     @Test
testConsume_displayCutout()361     public void testConsume_displayCutout() {
362         final WindowInsets insets = new WindowInsets.Builder()
363                 .setSystemWindowInsets(Insets.of(1, 2, 3, 4))
364                 .setStableInsets(Insets.of(5, 6, 7, 8))
365                 .setSystemGestureInsets(Insets.of(9, 10, 11, 12))
366                 .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
367                 .setTappableElementInsets(Insets.of(17, 18, 19, 20))
368                 .setDisplayCutout(CUTOUT).build();
369 
370         final WindowInsets consumed = insets.consumeDisplayCutout();
371 
372         assertEquals(insets.getSystemWindowInsets(), consumed.getSystemWindowInsets());
373         assertEquals(insets.getStableInsets(), consumed.getStableInsets());
374         assertNull(consumed.getDisplayCutout());
375         assertEquals(insets.getSystemGestureInsets(), consumed.getSystemGestureInsets());
376         assertEquals(insets.getMandatorySystemGestureInsets(), consumed.getMandatorySystemGestureInsets());
377         assertEquals(insets.getTappableElementInsets(), consumed.getTappableElementInsets());
378         assertEquals(
379                 insets.getInsets(Type.displayCutout()), consumed.getInsets(Type.displayCutout()));
380     }
381 
382     @Test
testConsistency_individualSides()383     public void testConsistency_individualSides() {
384         final WindowInsets insets = new WindowInsets.Builder()
385                 .setSystemWindowInsets(Insets.of(1, 2, 3, 4))
386                 .setStableInsets(Insets.of(5, 6, 7, 8))
387                 .setSystemGestureInsets(Insets.of(9, 10, 11, 12))
388                 .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
389                 .setTappableElementInsets(Insets.of(17, 18, 19, 20))
390                 .setDisplayCutout(CUTOUT).build();
391 
392         assertEquals(insets.getSystemWindowInsets(), Insets.of(
393                 insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(),
394                 insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom()));
395         assertEquals(insets.getStableInsets(), Insets.of(
396                 insets.getStableInsetLeft(), insets.getStableInsetTop(),
397                 insets.getStableInsetRight(), insets.getStableInsetBottom()));
398     }
399 
400     @Test
401     @SuppressWarnings("deprecation")
testReplacingConsumedSystemWindowInset_staysZeroAndConsumed()402     public void testReplacingConsumedSystemWindowInset_staysZeroAndConsumed() {
403         final WindowInsets consumed = new WindowInsets.Builder().build();
404         final WindowInsets replaced = consumed.replaceSystemWindowInsets(new Rect(1, 2, 3, 4));
405 
406         assertEquals(Insets.NONE, replaced.getSystemWindowInsets());
407         assertTrue(replaced.isConsumed());
408     }
409 
410     @Test
411     @SuppressWarnings("deprecation")
testReplacingSystemWindowInsets_works()412     public void testReplacingSystemWindowInsets_works() {
413         final WindowInsets replaced = new WindowInsets.Builder()
414                 .setSystemWindowInsets(Insets.of(100, 200, 300, 400))
415                 .setStableInsets(Insets.of(5, 6, 7, 8))
416                 .setSystemGestureInsets(Insets.of(9, 10, 11, 12))
417                 .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
418                 .setTappableElementInsets(Insets.of(17, 18, 19, 20))
419                 .setDisplayCutout(CUTOUT).build()
420                 .replaceSystemWindowInsets(new Rect(1, 2, 3, 4));
421         final WindowInsets expected = new WindowInsets.Builder()
422                 .setSystemWindowInsets(Insets.of(1, 2, 3, 4))
423                 .setStableInsets(Insets.of(5, 6, 7, 8))
424                 .setSystemGestureInsets(Insets.of(9, 10, 11, 12))
425                 .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
426                 .setTappableElementInsets(Insets.of(17, 18, 19, 20))
427                 .setDisplayCutout(CUTOUT).build();
428 
429         assertEquals(expected, replaced);
430     }
431 
432     @Test
433     @SuppressWarnings("deprecation")
testReplacingSystemWindowInsets_consistencyAcrossOverloads()434     public void testReplacingSystemWindowInsets_consistencyAcrossOverloads() {
435         final Rect newInsets = new Rect(100, 200, 300, 400);
436         final WindowInsets insets = new WindowInsets.Builder()
437                 .setSystemWindowInsets(Insets.of(1, 2, 3, 4))
438                 .setStableInsets(Insets.of(5, 6, 7, 8))
439                 .setSystemGestureInsets(Insets.of(9, 10, 11, 12))
440                 .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
441                 .setTappableElementInsets(Insets.of(17, 18, 19, 20))
442                 .setDisplayCutout(CUTOUT).build();
443 
444         assertEquals(insets.replaceSystemWindowInsets(newInsets),
445                 insets.replaceSystemWindowInsets(newInsets.left, newInsets.top, newInsets.right,
446                         newInsets.bottom));
447     }
448 
449     @Test
testInEquality_difference()450     public void testInEquality_difference() {
451         final WindowInsets insets = new WindowInsets.Builder()
452                 .setSystemWindowInsets(Insets.of(1, 2, 3, 4))
453                 .setStableInsets(Insets.of(5, 6, 7, 8))
454                 .setSystemGestureInsets(Insets.of(9, 10, 11, 12))
455                 .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
456                 .setTappableElementInsets(Insets.of(17, 18, 19, 20))
457                 .setDisplayCutout(CUTOUT).build();
458 
459         final WindowInsets insetsChangedSysWindowInsets = new WindowInsets.Builder()
460                 .setSystemWindowInsets(Insets.of(10, 20, 30, 40))
461                 .setStableInsets(Insets.of(5, 6, 7, 8))
462                 .setSystemGestureInsets(Insets.of(9, 10, 11, 12))
463                 .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
464                 .setTappableElementInsets(Insets.of(17, 18, 19, 20))
465                 .setDisplayCutout(CUTOUT).build();
466 
467         final WindowInsets insetsChangedStableInsets = new WindowInsets.Builder()
468                 .setSystemWindowInsets(Insets.of(1, 2, 3, 4))
469                 .setStableInsets(Insets.of(50, 60, 70, 80))
470                 .setSystemGestureInsets(Insets.of(9, 10, 11, 12))
471                 .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
472                 .setTappableElementInsets(Insets.of(17, 18, 19, 20))
473                 .setDisplayCutout(CUTOUT).build();
474 
475         final WindowInsets insetsChangedCutout = new WindowInsets.Builder()
476                 .setSystemWindowInsets(Insets.of(1, 2, 3, 4))
477                 .setStableInsets(Insets.of(5, 6, 7, 8))
478                 .setSystemGestureInsets(Insets.of(9, 10, 11, 12))
479                 .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
480                 .setTappableElementInsets(Insets.of(17, 18, 19, 20))
481                 .setDisplayCutout(CUTOUT2).build();
482 
483         final WindowInsets insetsChangedGesture = new WindowInsets.Builder()
484                 .setSystemWindowInsets(Insets.of(1, 2, 3, 4))
485                 .setStableInsets(Insets.of(5, 6, 7, 8))
486                 .setSystemGestureInsets(Insets.of(90, 100, 110, 120))
487                 .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
488                 .setTappableElementInsets(Insets.of(17, 18, 19, 20))
489                 .setDisplayCutout(CUTOUT).build();
490 
491         final WindowInsets insetsChangedMandatoryGesture = new WindowInsets.Builder()
492                 .setSystemWindowInsets(Insets.of(1, 2, 3, 4))
493                 .setStableInsets(Insets.of(5, 6, 7, 8))
494                 .setSystemGestureInsets(Insets.of(9, 10, 11, 12))
495                 .setMandatorySystemGestureInsets(Insets.of(130, 140, 150, 160))
496                 .setTappableElementInsets(Insets.of(17, 18, 19, 20))
497                 .setDisplayCutout(CUTOUT).build();
498 
499         final WindowInsets insetsChangedTappableElement = new WindowInsets.Builder()
500                 .setSystemWindowInsets(Insets.of(1, 2, 3, 4))
501                 .setStableInsets(Insets.of(5, 6, 7, 8))
502                 .setSystemGestureInsets(Insets.of(9, 10, 11, 12))
503                 .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
504                 .setTappableElementInsets(Insets.of(170, 180, 190, 200))
505                 .setDisplayCutout(CUTOUT).build();
506 
507         assertNotEquals(insets, insetsChangedSysWindowInsets);
508         assertNotEquals(insets, insetsChangedStableInsets);
509         assertNotEquals(insets, insetsChangedCutout);
510         assertNotEquals(insets, insetsChangedGesture);
511         assertNotEquals(insets, insetsChangedMandatoryGesture);
512         assertNotEquals(insets, insetsChangedTappableElement);
513     }
514 
515     @Test
testInset()516     public void testInset() {
517         final WindowInsets insets = new WindowInsets.Builder()
518                 .setSystemWindowInsets(Insets.of(10, 20, 30, 40))
519                 .setStableInsets(Insets.of(50, 60, 70, 80))
520                 .setSystemGestureInsets(Insets.of(90, 100, 110, 120))
521                 .setMandatorySystemGestureInsets(Insets.of(130, 140, 150, 160))
522                 .setTappableElementInsets(Insets.of(170, 180, 190, 200))
523                 .setDisplayCutout(CUTOUT).build();
524 
525         final WindowInsets insetInsets = insets.inset(
526                 INSET_LEFT, INSET_TOP, INSET_RIGHT, INSET_BOTTOM);
527 
528         assertEquals(applyInset(insets.getSystemWindowInsets()),
529                 insetInsets.getSystemWindowInsets());
530         assertEquals(applyInset(insets.getStableInsets()), insetInsets.getStableInsets());
531         assertEquals(applyInset(insets.getSystemGestureInsets()),
532                 insetInsets.getSystemGestureInsets());
533         assertEquals(applyInset(insets.getMandatorySystemGestureInsets()),
534                 insetInsets.getMandatorySystemGestureInsets());
535         assertEquals(applyInset(insets.getTappableElementInsets()),
536                 insetInsets.getTappableElementInsets());
537         assertEquals(applyInset(getCutoutSafeInsets(insets)), getCutoutSafeInsets(insetInsets));
538         assertEquals(applyInset(getCutoutSafeInsets(insets)),
539                 insetInsets.getInsets(Type.displayCutout()));
540     }
541 
542     @Test
testInset_clipsToZero()543     public void testInset_clipsToZero() {
544         final WindowInsets insets = new WindowInsets.Builder()
545                 .setSystemWindowInsets(Insets.of(10, 20, 30, 40))
546                 .setStableInsets(Insets.of(50, 60, 70, 80))
547                 .setSystemGestureInsets(Insets.of(90, 100, 110, 120))
548                 .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
549                 .setTappableElementInsets(Insets.of(17, 18, 19, 20))
550                 .setDisplayCutout(CUTOUT).build();
551 
552         final WindowInsets insetInsets = insets.inset(1000, 1000, 1000, 1000);
553 
554         assertEquals(Insets.NONE, insetInsets.getSystemWindowInsets());
555         assertEquals(Insets.NONE, insetInsets.getStableInsets());
556         assertEquals(Insets.NONE, insetInsets.getSystemGestureInsets());
557         assertEquals(Insets.NONE, insetInsets.getMandatorySystemGestureInsets());
558         assertEquals(Insets.NONE, insetInsets.getTappableElementInsets());
559         assertNull(insetInsets.getDisplayCutout());
560         assertEquals(Insets.NONE, insetInsets.getInsets(Type.displayCutout()));
561     }
562 
563     @Test
testConsumed_copy()564     public void testConsumed_copy() {
565         final WindowInsets insets = new WindowInsets.Builder()
566                 .setSystemWindowInsets(Insets.of(10, 20, 30, 40))
567                 .setStableInsets(Insets.of(50, 60, 70, 80))
568                 .build();
569 
570         final WindowInsets consumed = insets.consumeSystemWindowInsets().consumeStableInsets();
571         final WindowInsets copy = new WindowInsets(consumed);
572         assertTrue(copy.isConsumed());
573     }
574 
575     @Test
testConsumedInstance()576     public void testConsumedInstance() {
577         assertTrue(WindowInsets.CONSUMED.isConsumed());
578     }
579 
applyInset(Insets res)580     private static Insets applyInset(Insets res) {
581         return Insets.of(Math.max(0, res.left - INSET_LEFT),
582                 Math.max(0, res.top - INSET_TOP),
583                 Math.max(0, res.right - INSET_RIGHT),
584                 Math.max(0, res.bottom - INSET_BOTTOM));
585     }
586 
getCutoutSafeInsets(WindowInsets insets)587     private static Insets getCutoutSafeInsets(WindowInsets insets) {
588         final DisplayCutout dc = insets.getDisplayCutout();
589         return Insets.of(dc.getSafeInsetLeft(), dc.getSafeInsetTop(), dc.getSafeInsetRight(),
590                 dc.getSafeInsetBottom());
591     }
592 }
593