• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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.view;
18 
19 import static android.view.Display.DEFAULT_DISPLAY;
20 import static android.view.Surface.ROTATION_0;
21 import static android.view.Surface.ROTATION_90;
22 
23 import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt;
24 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
25 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
26 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
27 
28 import static com.google.common.truth.Truth.assertThat;
29 
30 import static org.junit.Assert.assertArrayEquals;
31 
32 import android.app.WindowConfiguration;
33 import android.content.Context;
34 import android.content.res.Resources;
35 import android.graphics.Point;
36 import android.graphics.Rect;
37 import android.hardware.display.DisplayManagerGlobal;
38 import android.platform.test.annotations.Presubmit;
39 import android.util.DisplayMetrics;
40 
41 import androidx.test.core.app.ApplicationProvider;
42 import androidx.test.ext.junit.runners.AndroidJUnit4;
43 import androidx.test.filters.SmallTest;
44 
45 import com.android.dx.mockito.inline.extended.StaticMockitoSession;
46 
47 import org.junit.After;
48 import org.junit.Before;
49 import org.junit.Test;
50 import org.junit.runner.RunWith;
51 import org.mockito.Mockito;
52 import org.mockito.quality.Strictness;
53 
54 /**
55  * Tests for {@link Display}.
56  *
57  * <p>Build/Install/Run:
58  *
59  * atest FrameworksMockingCoreTests:android.view.DisplayTest
60  *
61  * <p>This test class is a part of Window Manager Service tests and specified in
62  * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
63  */
64 @RunWith(AndroidJUnit4.class)
65 @SmallTest
66 @Presubmit
67 public class DisplayTest {
68 
69     private static final int APP_WIDTH = 272;
70     private static final int APP_HEIGHT = 700;
71     // Tablet size device, ROTATION_0 corresponds to portrait.
72     private static final int LOGICAL_WIDTH = 700;
73     private static final int LOGICAL_HEIGHT = 1800;
74 
75     // Bounds of the app when the device is in portrait mode.
76     private static Rect sAppBoundsPortrait = buildAppBounds(LOGICAL_WIDTH, LOGICAL_HEIGHT);
77     private static Rect sAppBoundsLandscape = buildAppBounds(LOGICAL_HEIGHT, LOGICAL_WIDTH);
78 
79     // Bounds of the device.
80     private static Rect sDeviceBoundsPortrait = new Rect(0, 0, LOGICAL_WIDTH, LOGICAL_HEIGHT);
81     private static Rect sDeviceBoundsLandscape = new Rect(0, 0, LOGICAL_HEIGHT, LOGICAL_WIDTH);
82 
83 
84     private StaticMockitoSession mMockitoSession;
85 
86     private DisplayManagerGlobal mDisplayManagerGlobal;
87     private Context mApplicationContext;
88     private DisplayInfo mDisplayInfo = new DisplayInfo();
89 
90     @Before
setupTests()91     public void setupTests() {
92         mMockitoSession = mockitoSession()
93                 .mockStatic(DisplayManagerGlobal.class)
94                 .strictness(Strictness.LENIENT)
95                 .startMocking();
96 
97         // Ensure no adjustments are set before each test.
98         mApplicationContext = ApplicationProvider.getApplicationContext();
99         mApplicationContext.getResources().getConfiguration().windowConfiguration.setAppBounds(
100                 null);
101         mApplicationContext.getResources().getConfiguration().windowConfiguration.setMaxBounds(
102                 null);
103         mApplicationContext.getResources().getConfiguration().windowConfiguration
104                 .setDisplayRotation(WindowConfiguration.ROTATION_UNDEFINED);
105         mDisplayInfo.rotation = ROTATION_0;
106 
107         mDisplayManagerGlobal = mock(DisplayManagerGlobal.class);
108         doReturn(mDisplayInfo).when(mDisplayManagerGlobal).getDisplayInfo(anyInt());
109     }
110 
111     @After
teardownTests()112     public void teardownTests() {
113         if (mMockitoSession != null) {
114             mMockitoSession.finishMocking();
115         }
116         Mockito.framework().clearInlineMocks();
117     }
118 
119     @Test
testGetReportedHdrTypes_returns_mode_specific_hdr_types()120     public void testGetReportedHdrTypes_returns_mode_specific_hdr_types() {
121         setDisplayInfoPortrait(mDisplayInfo);
122         float[] alternativeRefreshRates = new float[0];
123         int[] hdrTypesWithDv = new int[] {1, 2, 3, 4};
124         Display.Mode modeWithDv = new Display.Mode(/* modeId= */ 0, 0, 0, 0f,
125                 alternativeRefreshRates, hdrTypesWithDv);
126 
127         int[] hdrTypesWithoutDv = new int[]{2, 3, 4};
128         Display.Mode modeWithoutDv = new Display.Mode(/* modeId= */ 1, 0, 0, 0f,
129                 alternativeRefreshRates, hdrTypesWithoutDv);
130 
131         mDisplayInfo.supportedModes = new Display.Mode[] {modeWithoutDv, modeWithDv};
132         mDisplayInfo.hdrCapabilities = new Display.HdrCapabilities(hdrTypesWithDv, 0, 0, 0);
133 
134         final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
135                 DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
136 
137         mDisplayInfo.modeId = 0;
138         assertArrayEquals(hdrTypesWithDv, display.getReportedHdrTypes());
139 
140         mDisplayInfo.modeId = 1;
141         assertArrayEquals(hdrTypesWithoutDv, display.getReportedHdrTypes());
142     }
143 
144     @Test
testGetHdrCapabilities_getSupportedHdrTypes_returns_mode_specific_hdr_types()145     public void testGetHdrCapabilities_getSupportedHdrTypes_returns_mode_specific_hdr_types() {
146         setDisplayInfoPortrait(mDisplayInfo);
147         float[] alternativeRefreshRates = new float[0];
148         int[] hdrTypesWithDv = new int[] {1, 2, 3, 4};
149         Display.Mode modeWithDv = new Display.Mode(/* modeId= */ 0, 0, 0, 0f,
150                 alternativeRefreshRates, hdrTypesWithDv);
151 
152         int[] hdrTypesWithoutDv = new int[]{2, 3, 4};
153         Display.Mode modeWithoutDv = new Display.Mode(/* modeId= */ 1, 0, 0, 0f,
154                 alternativeRefreshRates, hdrTypesWithoutDv);
155 
156         mDisplayInfo.supportedModes = new Display.Mode[] {modeWithoutDv, modeWithDv};
157         mDisplayInfo.hdrCapabilities = new Display.HdrCapabilities(hdrTypesWithDv, 0, 0, 0);
158 
159         final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
160                 DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
161 
162         mDisplayInfo.modeId = 0;
163         assertArrayEquals(hdrTypesWithDv, display.getHdrCapabilities().getSupportedHdrTypes());
164 
165         mDisplayInfo.modeId = 1;
166         assertArrayEquals(hdrTypesWithoutDv, display.getHdrCapabilities().getSupportedHdrTypes());
167     }
168 
169     @Test
testConstructor_defaultDisplayAdjustments_matchesDisplayInfo()170     public void testConstructor_defaultDisplayAdjustments_matchesDisplayInfo() {
171         setDisplayInfoPortrait(mDisplayInfo);
172         final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
173                 DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
174         assertThat(display.getDisplayAdjustments()).isEqualTo(
175                 DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
176         DisplayInfo actualDisplayInfo = new DisplayInfo();
177         display.getDisplayInfo(actualDisplayInfo);
178         verifyDisplayInfo(actualDisplayInfo, mDisplayInfo);
179     }
180 
181     @Test
testConstructor_defaultResources_matchesDisplayInfo()182     public void testConstructor_defaultResources_matchesDisplayInfo() {
183         setDisplayInfoPortrait(mDisplayInfo);
184         final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
185                 mApplicationContext.getResources());
186         assertThat(display.getDisplayAdjustments()).isEqualTo(
187                 mApplicationContext.getResources().getDisplayAdjustments());
188         DisplayInfo actualDisplayInfo = new DisplayInfo();
189         display.getDisplayInfo(actualDisplayInfo);
190         verifyDisplayInfo(actualDisplayInfo, mDisplayInfo);
191     }
192 
193     @Test
testGetRotation_defaultDisplayAdjustments_rotationNotAdjusted()194     public void testGetRotation_defaultDisplayAdjustments_rotationNotAdjusted() {
195         setDisplayInfoPortrait(mDisplayInfo);
196         final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
197                 DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
198         assertThat(display.getRotation()).isEqualTo(ROTATION_0);
199     }
200 
201     @Test
testGetRotation_resourcesWithOverrideDisplayAdjustments_rotationAdjusted()202     public void testGetRotation_resourcesWithOverrideDisplayAdjustments_rotationAdjusted() {
203         // GIVEN display is not rotated.
204         setDisplayInfoPortrait(mDisplayInfo);
205         // GIVEN fixed rotation adjustments are rotated, and an override is set.
206         setLocalDisplayInConfig(mApplicationContext.getResources(), ROTATION_90);
207         // GIVEN display is constructed with default resources.
208         final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
209                 mApplicationContext.getResources());
210         // THEN rotation is adjusted since an override is set.
211         assertThat(display.getRotation()).isEqualTo(ROTATION_90);
212     }
213 
214     @Test
testGetRealSize_defaultResourcesPortrait_matchesLogicalSize()215     public void testGetRealSize_defaultResourcesPortrait_matchesLogicalSize() {
216         // GIVEN display is not rotated.
217         setDisplayInfoPortrait(mDisplayInfo);
218         final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
219                 mApplicationContext.getResources());
220         // THEN real size matches display orientation.
221         verifyRealSizeIsPortrait(display);
222     }
223 
224     @Test
testGetRealSize_defaultResourcesLandscape_matchesRotatedLogicalSize()225     public void testGetRealSize_defaultResourcesLandscape_matchesRotatedLogicalSize() {
226         // GIVEN display is rotated.
227         setDisplayInfoLandscape(mDisplayInfo);
228         final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
229                 mApplicationContext.getResources());
230         // THEN real size matches display orientation.
231         verifyRealSizeIsLandscape(display);
232     }
233 
234     @Test
testGetRealSize_defaultDisplayAdjustmentsPortrait_matchesLogicalSize()235     public void testGetRealSize_defaultDisplayAdjustmentsPortrait_matchesLogicalSize() {
236         // GIVEN display is not rotated.
237         setDisplayInfoPortrait(mDisplayInfo);
238         final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
239                 DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
240         // THEN real size matches display orientation.
241         verifyRealSizeIsPortrait(display);
242     }
243 
244     @Test
testGetRealSize_defaultDisplayAdjustmentsLandscape_matchesLogicalSize()245     public void testGetRealSize_defaultDisplayAdjustmentsLandscape_matchesLogicalSize() {
246         // GIVEN display is rotated.
247         setDisplayInfoLandscape(mDisplayInfo);
248         final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
249                 DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
250         // THEN real size matches display orientation.
251         verifyRealSizeIsLandscape(display);
252     }
253 
254     @Test
testGetRealSize_resourcesWithPortraitOverrideRotation_rotatedLogicalSize()255     public void testGetRealSize_resourcesWithPortraitOverrideRotation_rotatedLogicalSize() {
256         // GIVEN display is rotated.
257         setDisplayInfoLandscape(mDisplayInfo);
258         // GIVEN fixed rotation adjustments are rotated, and an override is set.
259         setLocalDisplayInConfig(mApplicationContext.getResources(), ROTATION_0);
260         // GIVEN display is constructed with default resources.
261         final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
262                 mApplicationContext.getResources());
263         // THEN real size matches app orientation.
264         verifyRealSizeIsPortrait(display);
265     }
266 
267     @Test
testGetRealSize_resourcesWithLandscapeOverrideRotation_rotatedLogicalSize()268     public void testGetRealSize_resourcesWithLandscapeOverrideRotation_rotatedLogicalSize() {
269         // GIVEN display is not rotated.
270         setDisplayInfoPortrait(mDisplayInfo);
271         // GIVEN fixed rotation adjustments are rotated, and an override is set.
272         setLocalDisplayInConfig(mApplicationContext.getResources(), ROTATION_90);
273         // GIVEN display is constructed with default resources.
274         final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
275                 mApplicationContext.getResources());
276         // THEN real size matches app orientation.
277         verifyRealSizeIsLandscape(display);
278     }
279 
280     @Test
testGetRealSize_resourcesPortraitSandboxed_matchesAppSandboxBounds()281     public void testGetRealSize_resourcesPortraitSandboxed_matchesAppSandboxBounds() {
282         // GIVEN display is not rotated.
283         setDisplayInfoPortrait(mDisplayInfo);
284         // GIVEN app is letterboxed.
285         setMaxBoundsSandboxed(mApplicationContext.getResources(), sAppBoundsPortrait);
286         final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
287                 mApplicationContext.getResources());
288         // THEN real size matches app bounds.
289         verifyRealSizeMatchesBounds(display, sAppBoundsPortrait);
290     }
291 
292     @Test
testGetRealSize_resourcesPortraitSandboxed_matchesDisplayAreaSandboxBounds()293     public void testGetRealSize_resourcesPortraitSandboxed_matchesDisplayAreaSandboxBounds() {
294         // GIVEN display is not rotated.
295         setDisplayInfoPortrait(mDisplayInfo);
296         // GIVEN max bounds reflect DisplayArea size, which is the same size as the display.
297         setMaxBoundsSandboxed(mApplicationContext.getResources(), sDeviceBoundsPortrait);
298         // GIVEN app bounds do not stretch to include the full DisplayArea.
299         mApplicationContext.getResources().getConfiguration().windowConfiguration
300                 .setAppBounds(buildAppBounds(LOGICAL_WIDTH, LOGICAL_HEIGHT - 10));
301         final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
302                 mApplicationContext.getResources());
303         // THEN real metrics matches max bounds for the DisplayArea.
304         verifyRealSizeMatchesBounds(display, sDeviceBoundsPortrait);
305     }
306 
307     @Test
testGetRealSize_resourcesLandscapeSandboxed_matchesAppSandboxBounds()308     public void testGetRealSize_resourcesLandscapeSandboxed_matchesAppSandboxBounds() {
309         // GIVEN display is rotated.
310         setDisplayInfoLandscape(mDisplayInfo);
311         // GIVEN app is letterboxed.
312         setMaxBoundsSandboxed(mApplicationContext.getResources(), sAppBoundsLandscape);
313         final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
314                 mApplicationContext.getResources());
315         // THEN real size matches app bounds.
316         verifyRealSizeMatchesBounds(display, sAppBoundsLandscape);
317     }
318 
319     @Test
testGetRealSize_resourcesLandscapeSandboxed_matchesDisplayAreaSandboxBounds()320     public void testGetRealSize_resourcesLandscapeSandboxed_matchesDisplayAreaSandboxBounds() {
321         // GIVEN display is rotated.
322         setDisplayInfoLandscape(mDisplayInfo);
323         // GIVEN max bounds reflect DisplayArea size, which is the same size as the display.
324         setMaxBoundsSandboxed(mApplicationContext.getResources(), sDeviceBoundsLandscape);
325         // GIVEN app bounds do not stretch to include the full DisplayArea.
326         mApplicationContext.getResources().getConfiguration().windowConfiguration
327                 .setAppBounds(buildAppBounds(LOGICAL_HEIGHT, LOGICAL_WIDTH - 10));
328         final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
329                 mApplicationContext.getResources());
330         // THEN real metrics matches max bounds for the DisplayArea.
331         verifyRealSizeMatchesBounds(display, sDeviceBoundsLandscape);
332     }
333 
334     @Test
testGetRealMetrics_defaultResourcesPortrait_matchesLogicalSize()335     public void testGetRealMetrics_defaultResourcesPortrait_matchesLogicalSize() {
336         // GIVEN display is not rotated.
337         setDisplayInfoPortrait(mDisplayInfo);
338         final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
339                 mApplicationContext.getResources());
340         // THEN real metrics matches display orientation.
341         verifyRealMetricsIsPortrait(display);
342     }
343 
344     @Test
testGetRealMetrics_defaultResourcesLandscape_matchesRotatedLogicalSize()345     public void testGetRealMetrics_defaultResourcesLandscape_matchesRotatedLogicalSize() {
346         // GIVEN display is rotated.
347         setDisplayInfoLandscape(mDisplayInfo);
348         final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
349                 mApplicationContext.getResources());
350         // THEN real metrics matches display orientation.
351         verifyRealMetricsIsLandscape(display);
352     }
353 
354     @Test
testGetRealMetrics_defaultDisplayAdjustmentsPortrait_matchesLogicalSize()355     public void testGetRealMetrics_defaultDisplayAdjustmentsPortrait_matchesLogicalSize() {
356         // GIVEN display is not rotated.
357         setDisplayInfoPortrait(mDisplayInfo);
358         final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
359                 DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
360         // THEN real metrics matches display orientation.
361         verifyRealMetricsIsPortrait(display);
362     }
363 
364     @Test
testGetRealMetrics_defaultDisplayAdjustmentsLandscape_matchesLogicalSize()365     public void testGetRealMetrics_defaultDisplayAdjustmentsLandscape_matchesLogicalSize() {
366         // GIVEN display is rotated.
367         setDisplayInfoLandscape(mDisplayInfo);
368         final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
369                 DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
370         // THEN real metrics matches display orientation.
371         verifyRealMetricsIsLandscape(display);
372     }
373 
374     @Test
testGetRealMetrics_resourcesWithPortraitOverrideRotation_rotatedLogicalSize()375     public void testGetRealMetrics_resourcesWithPortraitOverrideRotation_rotatedLogicalSize() {
376         // GIVEN display is rotated.
377         setDisplayInfoLandscape(mDisplayInfo);
378         // GIVEN fixed rotation adjustments are rotated with an override.
379         setLocalDisplayInConfig(mApplicationContext.getResources(), ROTATION_0);
380         // GIVEN display is constructed with default resources.
381         final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
382                 mApplicationContext.getResources());
383         // THEN real metrics matches app orientation.
384         verifyRealMetricsIsPortrait(display);
385     }
386 
387     @Test
testGetRealMetrics_resourcesWithLandscapeOverrideRotation_rotatedLogicalSize()388     public void testGetRealMetrics_resourcesWithLandscapeOverrideRotation_rotatedLogicalSize() {
389         // GIVEN display is not rotated.
390         setDisplayInfoPortrait(mDisplayInfo);
391         // GIVEN fixed rotation adjustments are rotated.
392         setLocalDisplayInConfig(mApplicationContext.getResources(), ROTATION_90);
393         // GIVEN display is constructed with default resources.
394         final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
395                 mApplicationContext.getResources());
396         // THEN real metrics matches app orientation.
397         verifyRealMetricsIsLandscape(display);
398     }
399 
400     @Test
testGetRealMetrics_resourcesPortraitSandboxed_matchesAppSandboxBounds()401     public void testGetRealMetrics_resourcesPortraitSandboxed_matchesAppSandboxBounds() {
402         // GIVEN display is not rotated.
403         setDisplayInfoPortrait(mDisplayInfo);
404         // GIVEN app is letterboxed.
405         setMaxBoundsSandboxed(mApplicationContext.getResources(), sAppBoundsPortrait);
406         final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
407                 mApplicationContext.getResources());
408         // THEN real metrics matches app bounds.
409         verifyRealMetricsMatchesBounds(display, sAppBoundsPortrait);
410     }
411 
412     @Test
testGetRealMetrics_resourcesPortraitSandboxed_matchesDisplayAreaSandboxBounds()413     public void testGetRealMetrics_resourcesPortraitSandboxed_matchesDisplayAreaSandboxBounds() {
414         // GIVEN display is not rotated.
415         setDisplayInfoPortrait(mDisplayInfo);
416         // GIVEN max bounds reflect DisplayArea size, which is the same size as the display.
417         setMaxBoundsSandboxed(mApplicationContext.getResources(), sDeviceBoundsPortrait);
418         // GIVEN app bounds do not stretch to include the full DisplayArea.
419         mApplicationContext.getResources().getConfiguration().windowConfiguration
420                 .setAppBounds(buildAppBounds(LOGICAL_WIDTH, LOGICAL_HEIGHT - 10));
421         final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
422                 mApplicationContext.getResources());
423         // THEN real metrics matches max bounds for the DisplayArea.
424         verifyRealMetricsMatchesBounds(display, sDeviceBoundsPortrait);
425     }
426 
427     @Test
testGetRealMetrics_resourcesLandscapeSandboxed_matchesAppSandboxBounds()428     public void testGetRealMetrics_resourcesLandscapeSandboxed_matchesAppSandboxBounds() {
429         // GIVEN display is rotated.
430         setDisplayInfoLandscape(mDisplayInfo);
431         // GIVEN app is letterboxed.
432         setMaxBoundsSandboxed(mApplicationContext.getResources(), sAppBoundsLandscape);
433         final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
434                 mApplicationContext.getResources());
435         // THEN real metrics matches app bounds.
436         verifyRealMetricsMatchesBounds(display, sAppBoundsLandscape);
437     }
438 
439     @Test
testGetRealMetrics_resourcesLandscapeSandboxed_matchesDisplayAreaSandboxBounds()440     public void testGetRealMetrics_resourcesLandscapeSandboxed_matchesDisplayAreaSandboxBounds() {
441         // GIVEN display is rotated.
442         setDisplayInfoLandscape(mDisplayInfo);
443         // GIVEN max bounds reflect DisplayArea size, which is the same size as the display.
444         setMaxBoundsSandboxed(mApplicationContext.getResources(), sDeviceBoundsLandscape);
445         // GIVEN app bounds do not stretch to include the full DisplayArea.
446         mApplicationContext.getResources().getConfiguration().windowConfiguration
447                 .setAppBounds(buildAppBounds(LOGICAL_HEIGHT, LOGICAL_WIDTH - 10));
448         final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
449                 mApplicationContext.getResources());
450         // THEN real metrics matches max bounds for the DisplayArea.
451         verifyRealMetricsMatchesBounds(display, sDeviceBoundsLandscape);
452     }
453 
454     @Test
testSupportedHdrTypesForDisplayModeAreSorted()455     public void testSupportedHdrTypesForDisplayModeAreSorted() {
456         int[] nonSortedHdrTypes = new int[]{3, 2, 1};
457         Display.Mode displayMode = new Display.Mode(0, 0, 0, 0, new float[0], nonSortedHdrTypes);
458 
459         int[] sortedHdrTypes = new int[]{1, 2, 3};
460         assertArrayEquals(sortedHdrTypes, displayMode.getSupportedHdrTypes());
461     }
462 
463     @Test
testGetSupportedHdrTypesReturnsCopy()464     public void testGetSupportedHdrTypesReturnsCopy() {
465         int[] hdrTypes = new int[]{1, 2, 3};
466         Display.Mode displayMode = new Display.Mode(0, 0, 0, 0, new float[0], hdrTypes);
467 
468         int[] hdrTypesCopy = displayMode.getSupportedHdrTypes();
469         hdrTypesCopy[0] = 0;
470         assertArrayEquals(hdrTypes, displayMode.getSupportedHdrTypes());
471     }
472 
473     @Test
testGetAlternativeRefreshRatesReturnsCopy()474     public void testGetAlternativeRefreshRatesReturnsCopy() {
475         float[] alternativeRates = new float[]{1.0f, 2.0f};
476         Display.Mode displayMode = new Display.Mode(0, 0, 0, 0, alternativeRates, new int[0]);
477 
478         float[] alternativeRatesCopy = displayMode.getAlternativeRefreshRates();
479         alternativeRatesCopy[0] = 0.0f;
480         assertArrayEquals(alternativeRates, displayMode.getAlternativeRefreshRates(), 0.0f);
481     }
482 
483     @Test
testHdrCapabilitiesGetSupportedHdrTypesReturnsCopy()484     public void testHdrCapabilitiesGetSupportedHdrTypesReturnsCopy() {
485         int[] hdrTypes = new int[]{1, 2, 3};
486         Display.HdrCapabilities hdrCapabilities = new Display.HdrCapabilities(hdrTypes, 0, 0, 0);
487 
488         int[] hdrTypesCopy = hdrCapabilities.getSupportedHdrTypes();
489         hdrTypesCopy[0] = 0;
490         assertArrayEquals(hdrTypes, hdrCapabilities.getSupportedHdrTypes());
491     }
492 
493     // Given rotated display dimensions, calculate the letterboxed app bounds.
buildAppBounds(int displayWidth, int displayHeight)494     private static Rect buildAppBounds(int displayWidth, int displayHeight) {
495         final int midWidth = displayWidth / 2;
496         final int left = midWidth - (APP_WIDTH / 2);
497         final int right = midWidth + (APP_WIDTH / 2);
498         final int midHeight = displayHeight / 2;
499         // Coordinate system starts at top left.
500         final int top = midHeight - (APP_HEIGHT / 2);
501         final int bottom = midHeight + (APP_HEIGHT / 2);
502         return new Rect(left, top, right, bottom);
503     }
504 
setDisplayInfoLandscape(DisplayInfo displayInfo)505     private static void setDisplayInfoLandscape(DisplayInfo displayInfo) {
506         displayInfo.rotation = ROTATION_90;
507         // Flip width & height assignment since the device is rotated.
508         displayInfo.logicalWidth = LOGICAL_HEIGHT;
509         displayInfo.logicalHeight = LOGICAL_WIDTH;
510     }
511 
setDisplayInfoPortrait(DisplayInfo displayInfo)512     private static void setDisplayInfoPortrait(DisplayInfo displayInfo) {
513         displayInfo.rotation = ROTATION_0;
514         displayInfo.logicalWidth = LOGICAL_WIDTH;
515         displayInfo.logicalHeight = LOGICAL_HEIGHT;
516     }
517 
518     /**
519      * Set max bounds to be sandboxed to the app bounds, indicating the app is in
520      * size compat mode or letterbox.
521      */
setMaxBoundsSandboxed(Resources resources, Rect bounds)522     private static void setMaxBoundsSandboxed(Resources resources, Rect bounds) {
523         resources.getConfiguration().windowConfiguration.setMaxBounds(bounds);
524     }
525 
526     /**
527      * Do not compare entire display info, since it is updated to match display the test is run on.
528      */
verifyDisplayInfo(DisplayInfo actual, DisplayInfo expected)529     private static void verifyDisplayInfo(DisplayInfo actual, DisplayInfo expected) {
530         assertThat(actual.displayId).isEqualTo(expected.displayId);
531         assertThat(actual.rotation).isEqualTo(expected.rotation);
532         assertThat(actual.logicalWidth).isEqualTo(LOGICAL_WIDTH);
533         assertThat(actual.logicalHeight).isEqualTo(LOGICAL_HEIGHT);
534     }
535 
verifyRealSizeIsLandscape(Display display)536     private static void verifyRealSizeIsLandscape(Display display) {
537         Point size = new Point();
538         display.getRealSize(size);
539         // Flip the width and height check since the device is rotated.
540         assertThat(size).isEqualTo(new Point(LOGICAL_HEIGHT, LOGICAL_WIDTH));
541     }
542 
verifyRealMetricsIsLandscape(Display display)543     private static void verifyRealMetricsIsLandscape(Display display) {
544         DisplayMetrics metrics = new DisplayMetrics();
545         display.getRealMetrics(metrics);
546         // Flip the width and height check since the device is rotated.
547         assertThat(metrics.widthPixels).isEqualTo(LOGICAL_HEIGHT);
548         assertThat(metrics.heightPixels).isEqualTo(LOGICAL_WIDTH);
549     }
550 
verifyRealSizeIsPortrait(Display display)551     private static void verifyRealSizeIsPortrait(Display display) {
552         Point size = new Point();
553         display.getRealSize(size);
554         assertThat(size).isEqualTo(new Point(LOGICAL_WIDTH, LOGICAL_HEIGHT));
555     }
556 
verifyRealMetricsIsPortrait(Display display)557     private static void verifyRealMetricsIsPortrait(Display display) {
558         DisplayMetrics metrics = new DisplayMetrics();
559         display.getRealMetrics(metrics);
560         assertThat(metrics.widthPixels).isEqualTo(LOGICAL_WIDTH);
561         assertThat(metrics.heightPixels).isEqualTo(LOGICAL_HEIGHT);
562     }
563 
verifyRealSizeMatchesBounds(Display display, Rect bounds)564     private static void verifyRealSizeMatchesBounds(Display display, Rect bounds) {
565         Point size = new Point();
566         display.getRealSize(size);
567         assertThat(size).isEqualTo(new Point(bounds.width(), bounds.height()));
568     }
569 
verifyRealMetricsMatchesBounds(Display display, Rect bounds)570     private static void verifyRealMetricsMatchesBounds(Display display, Rect bounds) {
571         DisplayMetrics metrics = new DisplayMetrics();
572         display.getRealMetrics(metrics);
573         assertThat(metrics.widthPixels).isEqualTo(bounds.width());
574         assertThat(metrics.heightPixels).isEqualTo(bounds.height());
575     }
576 
setLocalDisplayInConfig(Resources resources, @Surface.Rotation int rotation)577     private static void setLocalDisplayInConfig(Resources resources,
578             @Surface.Rotation int rotation) {
579         resources.getConfiguration().windowConfiguration.setDisplayRotation(rotation);
580     }
581 }
582