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