1 /* 2 * Copyright (C) 2017 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 com.android.server.display; 18 19 import static com.android.server.display.VirtualDisplayAdapter.UNIQUE_ID_PREFIX; 20 21 import static org.junit.Assert.assertEquals; 22 import static org.junit.Assert.assertFalse; 23 import static org.junit.Assert.assertNotNull; 24 import static org.junit.Assert.assertTrue; 25 import static org.junit.Assert.fail; 26 import static org.mockito.Mockito.mock; 27 import static org.mockito.Mockito.verify; 28 import static org.mockito.Mockito.when; 29 30 import android.app.PropertyInvalidatedCache; 31 import android.compat.testing.PlatformCompatChangeRule; 32 import android.content.Context; 33 import android.graphics.Insets; 34 import android.graphics.Rect; 35 import android.hardware.display.BrightnessConfiguration; 36 import android.hardware.display.Curve; 37 import android.hardware.display.DisplayManager; 38 import android.hardware.display.DisplayManagerGlobal; 39 import android.hardware.display.DisplayViewport; 40 import android.hardware.display.DisplayedContentSample; 41 import android.hardware.display.DisplayedContentSamplingAttributes; 42 import android.hardware.display.IDisplayManagerCallback; 43 import android.hardware.display.IVirtualDisplayCallback; 44 import android.hardware.display.VirtualDisplayConfig; 45 import android.hardware.input.InputManagerInternal; 46 import android.os.Handler; 47 import android.os.IBinder; 48 import android.os.MessageQueue; 49 import android.os.Process; 50 import android.platform.test.annotations.Presubmit; 51 import android.view.Display; 52 import android.view.DisplayCutout; 53 import android.view.DisplayEventReceiver; 54 import android.view.DisplayInfo; 55 import android.view.Surface; 56 import android.view.SurfaceControl; 57 58 import androidx.test.InstrumentationRegistry; 59 import androidx.test.filters.FlakyTest; 60 import androidx.test.filters.SmallTest; 61 import androidx.test.runner.AndroidJUnit4; 62 63 import com.android.server.LocalServices; 64 import com.android.server.SystemService; 65 import com.android.server.display.DisplayManagerService.SyncRoot; 66 import com.android.server.lights.LightsManager; 67 import com.android.server.sensors.SensorManagerInternal; 68 import com.android.server.wm.WindowManagerInternal; 69 70 import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges; 71 import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges; 72 73 import org.junit.Before; 74 import org.junit.Rule; 75 import org.junit.Test; 76 import org.junit.rules.TestRule; 77 import org.junit.runner.RunWith; 78 import org.mockito.ArgumentCaptor; 79 import org.mockito.Mock; 80 import org.mockito.MockitoAnnotations; 81 82 import java.time.Duration; 83 import java.util.Arrays; 84 import java.util.List; 85 import java.util.concurrent.CountDownLatch; 86 import java.util.concurrent.TimeUnit; 87 import java.util.stream.LongStream; 88 89 @SmallTest 90 @Presubmit 91 @RunWith(AndroidJUnit4.class) 92 public class DisplayManagerServiceTest { 93 private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS = 1; 94 private static final long SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS = 10; 95 private static final String VIRTUAL_DISPLAY_NAME = "Test Virtual Display"; 96 private static final String PACKAGE_NAME = "com.android.frameworks.servicestests"; 97 private static final long STANDARD_DISPLAY_EVENTS = DisplayManager.EVENT_FLAG_DISPLAY_ADDED 98 | DisplayManager.EVENT_FLAG_DISPLAY_CHANGED 99 | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED; 100 101 @Rule 102 public TestRule compatChangeRule = new PlatformCompatChangeRule(); 103 104 private Context mContext; 105 106 private final DisplayManagerService.Injector mShortMockedInjector = 107 new DisplayManagerService.Injector() { 108 @Override 109 VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, 110 Context context, Handler handler, DisplayAdapter.Listener listener) { 111 return mMockVirtualDisplayAdapter; 112 } 113 114 @Override 115 long getDefaultDisplayDelayTimeout() { 116 return SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS; 117 } 118 }; 119 120 class BasicInjector extends DisplayManagerService.Injector { 121 @Override getVirtualDisplayAdapter(SyncRoot syncRoot, Context context, Handler handler, DisplayAdapter.Listener displayAdapterListener)122 VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, Context context, 123 Handler handler, DisplayAdapter.Listener displayAdapterListener) { 124 return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener, 125 (String name, boolean secure) -> mMockDisplayToken); 126 } 127 } 128 129 private final DisplayManagerService.Injector mBasicInjector = new BasicInjector(); 130 131 private final DisplayManagerService.Injector mAllowNonNativeRefreshRateOverrideInjector = 132 new BasicInjector() { 133 @Override 134 boolean getAllowNonNativeRefreshRateOverride() { 135 return true; 136 } 137 }; 138 139 private final DisplayManagerService.Injector mDenyNonNativeRefreshRateOverrideInjector = 140 new BasicInjector() { 141 @Override 142 boolean getAllowNonNativeRefreshRateOverride() { 143 return false; 144 } 145 }; 146 147 @Mock InputManagerInternal mMockInputManagerInternal; 148 @Mock IVirtualDisplayCallback.Stub mMockAppToken; 149 @Mock IVirtualDisplayCallback.Stub mMockAppToken2; 150 @Mock WindowManagerInternal mMockWindowManagerInternal; 151 @Mock LightsManager mMockLightsManager; 152 @Mock VirtualDisplayAdapter mMockVirtualDisplayAdapter; 153 @Mock IBinder mMockDisplayToken; 154 @Mock SensorManagerInternal mMockSensorManagerInternal; 155 156 @Before setUp()157 public void setUp() throws Exception { 158 MockitoAnnotations.initMocks(this); 159 160 LocalServices.removeServiceForTest(InputManagerInternal.class); 161 LocalServices.addService(InputManagerInternal.class, mMockInputManagerInternal); 162 LocalServices.removeServiceForTest(WindowManagerInternal.class); 163 LocalServices.addService(WindowManagerInternal.class, mMockWindowManagerInternal); 164 LocalServices.removeServiceForTest(LightsManager.class); 165 LocalServices.addService(LightsManager.class, mMockLightsManager); 166 LocalServices.removeServiceForTest(SensorManagerInternal.class); 167 LocalServices.addService(SensorManagerInternal.class, mMockSensorManagerInternal); 168 169 mContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 170 171 // Disable binder caches in this process. 172 PropertyInvalidatedCache.disableForTestMode(); 173 } 174 175 @Test testCreateVirtualDisplay_sentToInputManager()176 public void testCreateVirtualDisplay_sentToInputManager() { 177 DisplayManagerService displayManager = 178 new DisplayManagerService(mContext, mBasicInjector); 179 registerDefaultDisplays(displayManager); 180 displayManager.systemReady(false /* safeMode */, true /* onlyCore */); 181 displayManager.windowManagerAndInputReady(); 182 183 // This is effectively the DisplayManager service published to ServiceManager. 184 DisplayManagerService.BinderService bs = displayManager.new BinderService(); 185 186 String uniqueId = "uniqueId --- Test"; 187 String uniqueIdPrefix = UNIQUE_ID_PREFIX + mContext.getPackageName() + ":"; 188 int width = 600; 189 int height = 800; 190 int dpi = 320; 191 int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH; 192 193 when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); 194 final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder( 195 VIRTUAL_DISPLAY_NAME, width, height, dpi); 196 builder.setUniqueId(uniqueId); 197 builder.setFlags(flags); 198 int displayId = bs.createVirtualDisplay(builder.build(), mMockAppToken /* callback */, 199 null /* projection */, PACKAGE_NAME); 200 201 displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class)); 202 203 // flush the handler 204 displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */); 205 206 ArgumentCaptor<List<DisplayViewport>> viewportCaptor = ArgumentCaptor.forClass(List.class); 207 verify(mMockInputManagerInternal).setDisplayViewports(viewportCaptor.capture()); 208 List<DisplayViewport> viewports = viewportCaptor.getValue(); 209 210 // Expect to receive at least 2 viewports: at least 1 internal, and 1 virtual 211 assertTrue(viewports.size() >= 2); 212 213 DisplayViewport virtualViewport = null; 214 DisplayViewport internalViewport = null; 215 for (int i = 0; i < viewports.size(); i++) { 216 DisplayViewport v = viewports.get(i); 217 switch (v.type) { 218 case DisplayViewport.VIEWPORT_INTERNAL: { 219 // If more than one internal viewport, this will get overwritten several times, 220 // which for the purposes of this test is fine. 221 internalViewport = v; 222 assertTrue(internalViewport.valid); 223 break; 224 } 225 case DisplayViewport.VIEWPORT_EXTERNAL: { 226 fail("EXTERNAL viewport should not exist."); 227 break; 228 } 229 case DisplayViewport.VIEWPORT_VIRTUAL: { 230 virtualViewport = v; 231 break; 232 } 233 } 234 } 235 // INTERNAL viewport gets created upon access. 236 assertNotNull(internalViewport); 237 assertNotNull(virtualViewport); 238 239 // VIRTUAL 240 assertEquals(height, virtualViewport.deviceHeight); 241 assertEquals(width, virtualViewport.deviceWidth); 242 assertEquals(uniqueIdPrefix + uniqueId, virtualViewport.uniqueId); 243 assertEquals(displayId, virtualViewport.displayId); 244 } 245 246 @Test testPhysicalViewports()247 public void testPhysicalViewports() { 248 DisplayManagerService displayManager = 249 new DisplayManagerService(mContext, mBasicInjector); 250 registerDefaultDisplays(displayManager); 251 displayManager.systemReady(false /* safeMode */, true /* onlyCore */); 252 displayManager.windowManagerAndInputReady(); 253 254 // This is effectively the DisplayManager service published to ServiceManager. 255 DisplayManagerService.BinderService bs = displayManager.new BinderService(); 256 257 when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); 258 259 final int displayIds[] = bs.getDisplayIds(); 260 final int size = displayIds.length; 261 assertTrue(size > 0); 262 for (int i = 0; i < size; i++) { 263 DisplayInfo info = bs.getDisplayInfo(displayIds[i]); 264 assertEquals(info.type, Display.TYPE_INTERNAL); 265 } 266 267 displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class)); 268 269 // flush the handler 270 displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */); 271 272 ArgumentCaptor<List<DisplayViewport>> viewportCaptor = ArgumentCaptor.forClass(List.class); 273 verify(mMockInputManagerInternal).setDisplayViewports(viewportCaptor.capture()); 274 List<DisplayViewport> viewports = viewportCaptor.getValue(); 275 276 // Due to the nature of foldables, we may have a different number of viewports than 277 // displays, just verify there's at least one. 278 final int viewportSize = viewports.size(); 279 assertTrue(viewportSize > 0); 280 281 // Now verify that each viewport's displayId is valid. 282 Arrays.sort(displayIds); 283 for (int i = 0; i < viewportSize; i++) { 284 DisplayViewport internalViewport = viewports.get(i); 285 286 // INTERNAL is the only one actual display. 287 assertNotNull(internalViewport); 288 assertEquals(DisplayViewport.VIEWPORT_INTERNAL, internalViewport.type); 289 assertTrue(internalViewport.valid); 290 assertTrue(Arrays.binarySearch(displayIds, internalViewport.displayId) >= 0); 291 } 292 } 293 294 @Test testCreateVirtualDisplayRotatesWithContent()295 public void testCreateVirtualDisplayRotatesWithContent() throws Exception { 296 DisplayManagerService displayManager = 297 new DisplayManagerService(mContext, mBasicInjector); 298 registerDefaultDisplays(displayManager); 299 300 // This is effectively the DisplayManager service published to ServiceManager. 301 DisplayManagerService.BinderService bs = displayManager.new BinderService(); 302 303 String uniqueId = "uniqueId --- Rotates With Content Test"; 304 int width = 600; 305 int height = 800; 306 int dpi = 320; 307 int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT; 308 309 when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); 310 final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder( 311 VIRTUAL_DISPLAY_NAME, width, height, dpi); 312 builder.setFlags(flags); 313 builder.setUniqueId(uniqueId); 314 int displayId = bs.createVirtualDisplay(builder.build(), mMockAppToken /* callback */, 315 null /* projection */, PACKAGE_NAME); 316 317 displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class)); 318 319 // flush the handler 320 displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */); 321 322 DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayId); 323 assertNotNull(ddi); 324 assertTrue((ddi.flags & DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT) != 0); 325 } 326 327 /** 328 * Tests that the virtual display is created along-side the default display. 329 */ 330 @Test testStartVirtualDisplayWithDefaultDisplay_Succeeds()331 public void testStartVirtualDisplayWithDefaultDisplay_Succeeds() throws Exception { 332 DisplayManagerService displayManager = 333 new DisplayManagerService(mContext, mShortMockedInjector); 334 registerDefaultDisplays(displayManager); 335 displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); 336 } 337 338 /** 339 * Tests that there should be a display change notification to WindowManager to update its own 340 * internal state for things like display cutout when nonOverrideDisplayInfo is changed. 341 */ 342 @Test testShouldNotifyChangeWhenNonOverrideDisplayInfoChanged()343 public void testShouldNotifyChangeWhenNonOverrideDisplayInfoChanged() throws Exception { 344 DisplayManagerService displayManager = 345 new DisplayManagerService(mContext, mShortMockedInjector); 346 registerDefaultDisplays(displayManager); 347 displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); 348 349 // Add the FakeDisplayDevice 350 FakeDisplayDevice displayDevice = new FakeDisplayDevice(); 351 DisplayDeviceInfo displayDeviceInfo = new DisplayDeviceInfo(); 352 displayDeviceInfo.width = 100; 353 displayDeviceInfo.height = 200; 354 displayDeviceInfo.supportedModes = new Display.Mode[1]; 355 displayDeviceInfo.supportedModes[0] = new Display.Mode(1, 100, 200, 60f); 356 displayDeviceInfo.modeId = 1; 357 final Rect zeroRect = new Rect(); 358 displayDeviceInfo.displayCutout = new DisplayCutout( 359 Insets.of(0, 10, 0, 0), 360 zeroRect, new Rect(0, 0, 10, 10), zeroRect, zeroRect); 361 displayDeviceInfo.flags = DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY; 362 displayDevice.setDisplayDeviceInfo(displayDeviceInfo); 363 displayManager.getDisplayDeviceRepository() 364 .onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED); 365 366 // Find the display id of the added FakeDisplayDevice 367 DisplayManagerService.BinderService bs = displayManager.new BinderService(); 368 int displayId = getDisplayIdForDisplayDevice(displayManager, bs, displayDevice); 369 // Setup override DisplayInfo 370 DisplayInfo overrideInfo = bs.getDisplayInfo(displayId); 371 displayManager.setDisplayInfoOverrideFromWindowManagerInternal(displayId, overrideInfo); 372 373 FakeDisplayManagerCallback callback = registerDisplayListenerCallback( 374 displayManager, bs, displayDevice); 375 376 // Simulate DisplayDevice change 377 DisplayDeviceInfo displayDeviceInfo2 = new DisplayDeviceInfo(); 378 displayDeviceInfo2.copyFrom(displayDeviceInfo); 379 displayDeviceInfo2.displayCutout = null; 380 displayDevice.setDisplayDeviceInfo(displayDeviceInfo2); 381 displayManager.getDisplayDeviceRepository() 382 .onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_CHANGED); 383 384 Handler handler = displayManager.getDisplayHandler(); 385 waitForIdleHandler(handler); 386 assertTrue(callback.mDisplayChangedCalled); 387 } 388 389 /** 390 * Tests that we get a Runtime exception when we cannot initialize the default display. 391 */ 392 @Test testStartVirtualDisplayWithDefDisplay_NoDefaultDisplay()393 public void testStartVirtualDisplayWithDefDisplay_NoDefaultDisplay() throws Exception { 394 DisplayManagerService displayManager = 395 new DisplayManagerService(mContext, mShortMockedInjector); 396 Handler handler = displayManager.getDisplayHandler(); 397 waitForIdleHandler(handler); 398 399 try { 400 displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); 401 } catch (RuntimeException e) { 402 return; 403 } 404 fail("Expected DisplayManager to throw RuntimeException when it cannot initialize the" 405 + " default display"); 406 } 407 408 /** 409 * Tests that we get a Runtime exception when we cannot initialize the virtual display. 410 */ 411 @Test testStartVirtualDisplayWithDefDisplay_NoVirtualDisplayAdapter()412 public void testStartVirtualDisplayWithDefDisplay_NoVirtualDisplayAdapter() throws Exception { 413 DisplayManagerService displayManager = new DisplayManagerService(mContext, 414 new DisplayManagerService.Injector() { 415 @Override 416 VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, 417 Context context, Handler handler, DisplayAdapter.Listener listener) { 418 return null; // return null for the adapter. This should cause a failure. 419 } 420 421 @Override 422 long getDefaultDisplayDelayTimeout() { 423 return SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS; 424 } 425 }); 426 try { 427 displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); 428 } catch (RuntimeException e) { 429 return; 430 } 431 fail("Expected DisplayManager to throw RuntimeException when it cannot initialize the" 432 + " virtual display adapter"); 433 } 434 435 /** 436 * Tests that an exception is raised for too dark a brightness configuration. 437 */ 438 @Test testTooDarkBrightnessConfigurationThrowException()439 public void testTooDarkBrightnessConfigurationThrowException() { 440 DisplayManagerService displayManager = 441 new DisplayManagerService(mContext, mShortMockedInjector); 442 Curve minimumBrightnessCurve = displayManager.getMinimumBrightnessCurveInternal(); 443 float[] lux = minimumBrightnessCurve.getX(); 444 float[] minimumNits = minimumBrightnessCurve.getY(); 445 float[] nits = new float[minimumNits.length]; 446 // For every control point, assert that making it slightly lower than the minimum throws an 447 // exception. 448 for (int i = 0; i < nits.length; i++) { 449 for (int j = 0; j < nits.length; j++) { 450 nits[j] = minimumNits[j]; 451 if (j == i) { 452 nits[j] -= 0.1f; 453 } 454 if (nits[j] < 0) { 455 nits[j] = 0; 456 } 457 } 458 BrightnessConfiguration config = 459 new BrightnessConfiguration.Builder(lux, nits).build(); 460 Exception thrown = null; 461 try { 462 displayManager.validateBrightnessConfiguration(config); 463 } catch (IllegalArgumentException e) { 464 thrown = e; 465 } 466 assertNotNull("Building too dark a brightness configuration must throw an exception"); 467 } 468 } 469 470 /** 471 * Tests that no exception is raised for not too dark a brightness configuration. 472 */ 473 @Test testBrightEnoughBrightnessConfigurationDoesNotThrowException()474 public void testBrightEnoughBrightnessConfigurationDoesNotThrowException() { 475 DisplayManagerService displayManager = 476 new DisplayManagerService(mContext, mShortMockedInjector); 477 Curve minimumBrightnessCurve = displayManager.getMinimumBrightnessCurveInternal(); 478 float[] lux = minimumBrightnessCurve.getX(); 479 float[] nits = minimumBrightnessCurve.getY(); 480 BrightnessConfiguration config = new BrightnessConfiguration.Builder(lux, nits).build(); 481 displayManager.validateBrightnessConfiguration(config); 482 } 483 484 /** 485 * Tests that null brightness configurations are alright. 486 */ 487 @Test testNullBrightnessConfiguration()488 public void testNullBrightnessConfiguration() { 489 DisplayManagerService displayManager = 490 new DisplayManagerService(mContext, mShortMockedInjector); 491 displayManager.validateBrightnessConfiguration(null); 492 } 493 494 /** 495 * Tests that collection of display color sampling results are sensible. 496 */ 497 @Test testDisplayedContentSampling()498 public void testDisplayedContentSampling() { 499 DisplayManagerService displayManager = 500 new DisplayManagerService(mContext, mShortMockedInjector); 501 registerDefaultDisplays(displayManager); 502 503 DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(0); 504 assertNotNull(ddi); 505 506 DisplayedContentSamplingAttributes attr = 507 displayManager.getDisplayedContentSamplingAttributesInternal(0); 508 if (attr == null) return; //sampling not supported on device, skip remainder of test. 509 510 boolean enabled = displayManager.setDisplayedContentSamplingEnabledInternal(0, true, 0, 0); 511 assertTrue(enabled); 512 513 displayManager.setDisplayedContentSamplingEnabledInternal(0, false, 0, 0); 514 DisplayedContentSample sample = displayManager.getDisplayedContentSampleInternal(0, 0, 0); 515 assertNotNull(sample); 516 517 long numPixels = ddi.width * ddi.height * sample.getNumFrames(); 518 long[] samples = sample.getSampleComponent(DisplayedContentSample.ColorComponent.CHANNEL0); 519 assertTrue(samples.length == 0 || LongStream.of(samples).sum() == numPixels); 520 521 samples = sample.getSampleComponent(DisplayedContentSample.ColorComponent.CHANNEL1); 522 assertTrue(samples.length == 0 || LongStream.of(samples).sum() == numPixels); 523 524 samples = sample.getSampleComponent(DisplayedContentSample.ColorComponent.CHANNEL2); 525 assertTrue(samples.length == 0 || LongStream.of(samples).sum() == numPixels); 526 527 samples = sample.getSampleComponent(DisplayedContentSample.ColorComponent.CHANNEL3); 528 assertTrue(samples.length == 0 || LongStream.of(samples).sum() == numPixels); 529 } 530 531 /** 532 * Tests that the virtual display is created with 533 * {@link VirtualDisplayConfig.Builder#setDisplayIdToMirror(int)} 534 */ 535 @Test 536 @FlakyTest(bugId = 127687569) testCreateVirtualDisplay_displayIdToMirror()537 public void testCreateVirtualDisplay_displayIdToMirror() throws Exception { 538 DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); 539 registerDefaultDisplays(displayManager); 540 541 // This is effectively the DisplayManager service published to ServiceManager. 542 DisplayManagerService.BinderService binderService = displayManager.new BinderService(); 543 544 final String uniqueId = "uniqueId --- displayIdToMirrorTest"; 545 final int width = 600; 546 final int height = 800; 547 final int dpi = 320; 548 549 when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); 550 final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder( 551 VIRTUAL_DISPLAY_NAME, width, height, dpi); 552 builder.setUniqueId(uniqueId); 553 final int firstDisplayId = binderService.createVirtualDisplay(builder.build(), 554 mMockAppToken /* callback */, null /* projection */, PACKAGE_NAME); 555 556 // The second virtual display requests to mirror the first virtual display. 557 final String uniqueId2 = "uniqueId --- displayIdToMirrorTest #2"; 558 when(mMockAppToken2.asBinder()).thenReturn(mMockAppToken2); 559 final VirtualDisplayConfig.Builder builder2 = new VirtualDisplayConfig.Builder( 560 VIRTUAL_DISPLAY_NAME, width, height, dpi).setUniqueId(uniqueId2); 561 builder2.setUniqueId(uniqueId2); 562 builder2.setDisplayIdToMirror(firstDisplayId); 563 final int secondDisplayId = binderService.createVirtualDisplay(builder2.build(), 564 mMockAppToken2 /* callback */, null /* projection */, PACKAGE_NAME); 565 displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class)); 566 567 // flush the handler 568 displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */); 569 570 // The displayId to mirror should be a default display if there is none initially. 571 assertEquals(displayManager.getDisplayIdToMirrorInternal(firstDisplayId), 572 Display.DEFAULT_DISPLAY); 573 assertEquals(displayManager.getDisplayIdToMirrorInternal(secondDisplayId), 574 firstDisplayId); 575 } 576 577 /** 578 * Tests that the virtual display is created with 579 * {@link VirtualDisplayConfig.Builder#setSurface(Surface)} 580 */ 581 @Test 582 @FlakyTest(bugId = 127687569) testCreateVirtualDisplay_setSurface()583 public void testCreateVirtualDisplay_setSurface() throws Exception { 584 DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); 585 registerDefaultDisplays(displayManager); 586 587 // This is effectively the DisplayManager service published to ServiceManager. 588 DisplayManagerService.BinderService binderService = displayManager.new BinderService(); 589 590 final String uniqueId = "uniqueId --- setSurface"; 591 final int width = 600; 592 final int height = 800; 593 final int dpi = 320; 594 final Surface surface = new Surface(); 595 596 when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); 597 final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder( 598 VIRTUAL_DISPLAY_NAME, width, height, dpi); 599 builder.setSurface(surface); 600 builder.setUniqueId(uniqueId); 601 final int displayId = binderService.createVirtualDisplay(builder.build(), 602 mMockAppToken /* callback */, null /* projection */, PACKAGE_NAME); 603 604 displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class)); 605 606 // flush the handler 607 displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */); 608 609 assertEquals(displayManager.getVirtualDisplaySurfaceInternal(mMockAppToken), surface); 610 } 611 612 /** 613 * Tests that there is a display change notification if the frame rate override 614 * list is updated. 615 */ 616 @Test testShouldNotifyChangeWhenDisplayInfoFrameRateOverrideChanged()617 public void testShouldNotifyChangeWhenDisplayInfoFrameRateOverrideChanged() throws Exception { 618 DisplayManagerService displayManager = 619 new DisplayManagerService(mContext, mShortMockedInjector); 620 DisplayManagerService.BinderService displayManagerBinderService = 621 displayManager.new BinderService(); 622 registerDefaultDisplays(displayManager); 623 displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); 624 625 FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, new float[]{60f}); 626 FakeDisplayManagerCallback callback = registerDisplayListenerCallback(displayManager, 627 displayManagerBinderService, displayDevice); 628 629 int myUid = Process.myUid(); 630 updateFrameRateOverride(displayManager, displayDevice, 631 new DisplayEventReceiver.FrameRateOverride[]{ 632 new DisplayEventReceiver.FrameRateOverride(myUid, 30f), 633 }); 634 assertTrue(callback.mDisplayChangedCalled); 635 callback.clear(); 636 637 updateFrameRateOverride(displayManager, displayDevice, 638 new DisplayEventReceiver.FrameRateOverride[]{ 639 new DisplayEventReceiver.FrameRateOverride(myUid, 30f), 640 new DisplayEventReceiver.FrameRateOverride(1234, 30f), 641 }); 642 assertFalse(callback.mDisplayChangedCalled); 643 644 updateFrameRateOverride(displayManager, displayDevice, 645 new DisplayEventReceiver.FrameRateOverride[]{ 646 new DisplayEventReceiver.FrameRateOverride(myUid, 20f), 647 new DisplayEventReceiver.FrameRateOverride(1234, 30f), 648 new DisplayEventReceiver.FrameRateOverride(5678, 30f), 649 }); 650 assertTrue(callback.mDisplayChangedCalled); 651 callback.clear(); 652 653 updateFrameRateOverride(displayManager, displayDevice, 654 new DisplayEventReceiver.FrameRateOverride[]{ 655 new DisplayEventReceiver.FrameRateOverride(1234, 30f), 656 new DisplayEventReceiver.FrameRateOverride(5678, 30f), 657 }); 658 assertTrue(callback.mDisplayChangedCalled); 659 callback.clear(); 660 661 updateFrameRateOverride(displayManager, displayDevice, 662 new DisplayEventReceiver.FrameRateOverride[]{ 663 new DisplayEventReceiver.FrameRateOverride(5678, 30f), 664 }); 665 assertFalse(callback.mDisplayChangedCalled); 666 } 667 668 /** 669 * Tests that the DisplayInfo is updated correctly with a frame rate override 670 */ 671 @Test testDisplayInfoFrameRateOverride()672 public void testDisplayInfoFrameRateOverride() throws Exception { 673 DisplayManagerService displayManager = 674 new DisplayManagerService(mContext, mShortMockedInjector); 675 DisplayManagerService.BinderService displayManagerBinderService = 676 displayManager.new BinderService(); 677 registerDefaultDisplays(displayManager); 678 displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); 679 680 FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, 681 new float[]{60f, 30f, 20f}); 682 int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService, 683 displayDevice); 684 DisplayInfo displayInfo = displayManagerBinderService.getDisplayInfo(displayId); 685 assertEquals(60f, displayInfo.getRefreshRate(), 0.01f); 686 687 updateFrameRateOverride(displayManager, displayDevice, 688 new DisplayEventReceiver.FrameRateOverride[]{ 689 new DisplayEventReceiver.FrameRateOverride( 690 Process.myUid(), 20f), 691 new DisplayEventReceiver.FrameRateOverride( 692 Process.myUid() + 1, 30f) 693 }); 694 displayInfo = displayManagerBinderService.getDisplayInfo(displayId); 695 assertEquals(20f, displayInfo.getRefreshRate(), 0.01f); 696 697 // Changing the mode to 30Hz should not override the refresh rate to 20Hz anymore 698 // as 20 is not a divider of 30. 699 updateModeId(displayManager, displayDevice, 2); 700 displayInfo = displayManagerBinderService.getDisplayInfo(displayId); 701 assertEquals(30f, displayInfo.getRefreshRate(), 0.01f); 702 } 703 704 /** 705 * Tests that the frame rate override is updated accordingly to the 706 * allowNonNativeRefreshRateOverride policy. 707 */ 708 @Test testDisplayInfoNonNativeFrameRateOverride()709 public void testDisplayInfoNonNativeFrameRateOverride() throws Exception { 710 testDisplayInfoNonNativeFrameRateOverride(mDenyNonNativeRefreshRateOverrideInjector); 711 testDisplayInfoNonNativeFrameRateOverride(mAllowNonNativeRefreshRateOverrideInjector); 712 } 713 714 /** 715 * Tests that the mode reflects the frame rate override is in compat mode 716 */ 717 @Test 718 @DisableCompatChanges({DisplayManagerService.DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE}) testDisplayInfoFrameRateOverrideModeCompat()719 public void testDisplayInfoFrameRateOverrideModeCompat() throws Exception { 720 testDisplayInfoFrameRateOverrideModeCompat(/*compatChangeEnabled*/ false); 721 } 722 723 /** 724 * Tests that the mode reflects the physical display refresh rate when not in compat mode. 725 */ 726 @Test 727 @EnableCompatChanges({DisplayManagerService.DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE}) testDisplayInfoFrameRateOverrideMode()728 public void testDisplayInfoFrameRateOverrideMode() throws Exception { 729 testDisplayInfoFrameRateOverrideModeCompat(/*compatChangeEnabled*/ true); 730 } 731 732 /** 733 * Tests that the mode reflects the frame rate override is in compat mode and accordingly to the 734 * allowNonNativeRefreshRateOverride policy. 735 */ 736 @Test 737 @DisableCompatChanges({DisplayManagerService.DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE}) testDisplayInfoNonNativeFrameRateOverrideModeCompat()738 public void testDisplayInfoNonNativeFrameRateOverrideModeCompat() throws Exception { 739 testDisplayInfoNonNativeFrameRateOverrideMode(mDenyNonNativeRefreshRateOverrideInjector, 740 /*compatChangeEnabled*/ false); 741 testDisplayInfoNonNativeFrameRateOverrideMode(mAllowNonNativeRefreshRateOverrideInjector, 742 /*compatChangeEnabled*/ false); 743 } 744 745 /** 746 * Tests that the mode reflects the physical display refresh rate when not in compat mode. 747 */ 748 @Test 749 @EnableCompatChanges({DisplayManagerService.DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE}) testDisplayInfoNonNativeFrameRateOverrideMode()750 public void testDisplayInfoNonNativeFrameRateOverrideMode() throws Exception { 751 testDisplayInfoNonNativeFrameRateOverrideMode(mDenyNonNativeRefreshRateOverrideInjector, 752 /*compatChangeEnabled*/ true); 753 testDisplayInfoNonNativeFrameRateOverrideMode(mAllowNonNativeRefreshRateOverrideInjector, 754 /*compatChangeEnabled*/ true); 755 } 756 757 /** 758 * Tests that EVENT_DISPLAY_ADDED is sent when a display is added. 759 */ 760 @Test testShouldNotifyDisplayAdded_WhenNewDisplayDeviceIsAdded()761 public void testShouldNotifyDisplayAdded_WhenNewDisplayDeviceIsAdded() { 762 DisplayManagerService displayManager = 763 new DisplayManagerService(mContext, mShortMockedInjector); 764 DisplayManagerService.BinderService displayManagerBinderService = 765 displayManager.new BinderService(); 766 767 Handler handler = displayManager.getDisplayHandler(); 768 waitForIdleHandler(handler); 769 770 // register display listener callback 771 FakeDisplayManagerCallback callback = new FakeDisplayManagerCallback(); 772 displayManagerBinderService.registerCallbackWithEventMask( 773 callback, STANDARD_DISPLAY_EVENTS); 774 775 waitForIdleHandler(handler); 776 777 createFakeDisplayDevice(displayManager, new float[]{60f}); 778 779 waitForIdleHandler(handler); 780 781 assertFalse(callback.mDisplayChangedCalled); 782 assertFalse(callback.mDisplayRemovedCalled); 783 assertTrue(callback.mDisplayAddedCalled); 784 } 785 786 /** 787 * Tests that EVENT_DISPLAY_ADDED is not sent when a display is added and the 788 * client has a callback which is not subscribed to this event type. 789 */ 790 @Test testShouldNotNotifyDisplayAdded_WhenClientIsNotSubscribed()791 public void testShouldNotNotifyDisplayAdded_WhenClientIsNotSubscribed() { 792 DisplayManagerService displayManager = 793 new DisplayManagerService(mContext, mShortMockedInjector); 794 DisplayManagerService.BinderService displayManagerBinderService = 795 displayManager.new BinderService(); 796 797 Handler handler = displayManager.getDisplayHandler(); 798 waitForIdleHandler(handler); 799 800 // register display listener callback 801 FakeDisplayManagerCallback callback = new FakeDisplayManagerCallback(); 802 long allEventsExceptDisplayAdded = STANDARD_DISPLAY_EVENTS 803 & ~DisplayManager.EVENT_FLAG_DISPLAY_ADDED; 804 displayManagerBinderService.registerCallbackWithEventMask(callback, 805 allEventsExceptDisplayAdded); 806 807 waitForIdleHandler(handler); 808 809 createFakeDisplayDevice(displayManager, new float[]{60f}); 810 811 waitForIdleHandler(handler); 812 813 assertFalse(callback.mDisplayChangedCalled); 814 assertFalse(callback.mDisplayRemovedCalled); 815 assertFalse(callback.mDisplayAddedCalled); 816 } 817 818 /** 819 * Tests that EVENT_DISPLAY_REMOVED is sent when a display is removed. 820 */ 821 @Test testShouldNotifyDisplayRemoved_WhenDisplayDeviceIsRemoved()822 public void testShouldNotifyDisplayRemoved_WhenDisplayDeviceIsRemoved() { 823 DisplayManagerService displayManager = 824 new DisplayManagerService(mContext, mShortMockedInjector); 825 DisplayManagerService.BinderService displayManagerBinderService = 826 displayManager.new BinderService(); 827 828 Handler handler = displayManager.getDisplayHandler(); 829 waitForIdleHandler(handler); 830 831 FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, 832 new float[]{60f}); 833 834 waitForIdleHandler(handler); 835 836 FakeDisplayManagerCallback callback = registerDisplayListenerCallback( 837 displayManager, displayManagerBinderService, displayDevice); 838 839 waitForIdleHandler(handler); 840 841 displayManager.getDisplayDeviceRepository() 842 .onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED); 843 844 waitForIdleHandler(handler); 845 846 assertFalse(callback.mDisplayChangedCalled); 847 assertTrue(callback.mDisplayRemovedCalled); 848 assertFalse(callback.mDisplayAddedCalled); 849 } 850 851 /** 852 * Tests that EVENT_DISPLAY_REMOVED is not sent when a display is added and the 853 * client has a callback which is not subscribed to this event type. 854 */ 855 @Test testShouldNotNotifyDisplayRemoved_WhenClientIsNotSubscribed()856 public void testShouldNotNotifyDisplayRemoved_WhenClientIsNotSubscribed() { 857 DisplayManagerService displayManager = 858 new DisplayManagerService(mContext, mShortMockedInjector); 859 DisplayManagerService.BinderService displayManagerBinderService = 860 displayManager.new BinderService(); 861 862 Handler handler = displayManager.getDisplayHandler(); 863 waitForIdleHandler(handler); 864 865 FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, 866 new float[]{60f}); 867 868 waitForIdleHandler(handler); 869 870 FakeDisplayManagerCallback callback = new FakeDisplayManagerCallback(); 871 long allEventsExceptDisplayRemoved = STANDARD_DISPLAY_EVENTS 872 & ~DisplayManager.EVENT_FLAG_DISPLAY_REMOVED; 873 displayManagerBinderService.registerCallbackWithEventMask(callback, 874 allEventsExceptDisplayRemoved); 875 876 waitForIdleHandler(handler); 877 878 displayManager.getDisplayDeviceRepository() 879 .onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED); 880 881 waitForIdleHandler(handler); 882 883 assertFalse(callback.mDisplayChangedCalled); 884 assertFalse(callback.mDisplayRemovedCalled); 885 assertFalse(callback.mDisplayAddedCalled); 886 } 887 888 889 890 @Test testSettingTwoBrightnessConfigurationsOnMultiDisplay()891 public void testSettingTwoBrightnessConfigurationsOnMultiDisplay() { 892 Context mContext = InstrumentationRegistry.getInstrumentation().getContext(); 893 DisplayManager displayManager = mContext.getSystemService(DisplayManager.class); 894 895 // get the first two internal displays 896 Display[] displays = displayManager.getDisplays(); 897 Display internalDisplayOne = null; 898 Display internalDisplayTwo = null; 899 for (Display display : displays) { 900 if (display.getType() == Display.TYPE_INTERNAL) { 901 if (internalDisplayOne == null) { 902 internalDisplayOne = display; 903 } else { 904 internalDisplayTwo = display; 905 break; 906 } 907 } 908 } 909 910 // return if there are fewer than 2 displays on this device 911 if (internalDisplayOne == null || internalDisplayTwo == null) { 912 return; 913 } 914 915 final String uniqueDisplayIdOne = internalDisplayOne.getUniqueId(); 916 final String uniqueDisplayIdTwo = internalDisplayTwo.getUniqueId(); 917 918 BrightnessConfiguration configOne = 919 new BrightnessConfiguration.Builder( 920 new float[]{0.0f, 12345.0f}, new float[]{15.0f, 400.0f}) 921 .setDescription("model:1").build(); 922 BrightnessConfiguration configTwo = 923 new BrightnessConfiguration.Builder( 924 new float[]{0.0f, 6789.0f}, new float[]{12.0f, 300.0f}) 925 .setDescription("model:2").build(); 926 927 displayManager.setBrightnessConfigurationForDisplay(configOne, 928 uniqueDisplayIdOne); 929 displayManager.setBrightnessConfigurationForDisplay(configTwo, 930 uniqueDisplayIdTwo); 931 932 BrightnessConfiguration configFromOne = 933 displayManager.getBrightnessConfigurationForDisplay(uniqueDisplayIdOne); 934 BrightnessConfiguration configFromTwo = 935 displayManager.getBrightnessConfigurationForDisplay(uniqueDisplayIdTwo); 936 937 assertNotNull(configFromOne); 938 assertEquals(configOne, configFromOne); 939 assertEquals(configTwo, configFromTwo); 940 941 } 942 testDisplayInfoFrameRateOverrideModeCompat(boolean compatChangeEnabled)943 private void testDisplayInfoFrameRateOverrideModeCompat(boolean compatChangeEnabled) 944 throws Exception { 945 DisplayManagerService displayManager = 946 new DisplayManagerService(mContext, mShortMockedInjector); 947 DisplayManagerService.BinderService displayManagerBinderService = 948 displayManager.new BinderService(); 949 registerDefaultDisplays(displayManager); 950 displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); 951 952 FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, 953 new float[]{60f, 30f, 20f}); 954 int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService, 955 displayDevice); 956 DisplayInfo displayInfo = displayManagerBinderService.getDisplayInfo(displayId); 957 assertEquals(60f, displayInfo.getRefreshRate(), 0.01f); 958 959 updateFrameRateOverride(displayManager, displayDevice, 960 new DisplayEventReceiver.FrameRateOverride[]{ 961 new DisplayEventReceiver.FrameRateOverride( 962 Process.myUid(), 20f), 963 new DisplayEventReceiver.FrameRateOverride( 964 Process.myUid() + 1, 30f) 965 }); 966 displayInfo = displayManagerBinderService.getDisplayInfo(displayId); 967 assertEquals(20f, displayInfo.getRefreshRate(), 0.01f); 968 Display.Mode expectedMode; 969 if (compatChangeEnabled) { 970 expectedMode = new Display.Mode(1, 100, 200, 60f); 971 } else { 972 expectedMode = new Display.Mode(3, 100, 200, 20f); 973 } 974 assertEquals(expectedMode, displayInfo.getMode()); 975 } 976 testDisplayInfoNonNativeFrameRateOverrideMode( DisplayManagerService.Injector injector, boolean compatChangeEnabled)977 private void testDisplayInfoNonNativeFrameRateOverrideMode( 978 DisplayManagerService.Injector injector, boolean compatChangeEnabled) { 979 DisplayManagerService displayManager = 980 new DisplayManagerService(mContext, injector); 981 DisplayManagerService.BinderService displayManagerBinderService = 982 displayManager.new BinderService(); 983 registerDefaultDisplays(displayManager); 984 displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); 985 986 FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, 987 new float[]{60f}); 988 int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService, 989 displayDevice); 990 DisplayInfo displayInfo = displayManagerBinderService.getDisplayInfo(displayId); 991 assertEquals(60f, displayInfo.getRefreshRate(), 0.01f); 992 993 updateFrameRateOverride(displayManager, displayDevice, 994 new DisplayEventReceiver.FrameRateOverride[]{ 995 new DisplayEventReceiver.FrameRateOverride( 996 Process.myUid(), 20f) 997 }); 998 displayInfo = displayManagerBinderService.getDisplayInfo(displayId); 999 Display.Mode expectedMode; 1000 if (compatChangeEnabled) { 1001 expectedMode = new Display.Mode(1, 100, 200, 60f); 1002 } else if (injector.getAllowNonNativeRefreshRateOverride()) { 1003 expectedMode = new Display.Mode(255, 100, 200, 20f); 1004 } else { 1005 expectedMode = new Display.Mode(1, 100, 200, 60f); 1006 } 1007 assertEquals(expectedMode, displayInfo.getMode()); 1008 } 1009 testDisplayInfoNonNativeFrameRateOverride( DisplayManagerService.Injector injector)1010 private void testDisplayInfoNonNativeFrameRateOverride( 1011 DisplayManagerService.Injector injector) { 1012 DisplayManagerService displayManager = 1013 new DisplayManagerService(mContext, injector); 1014 DisplayManagerService.BinderService displayManagerBinderService = 1015 displayManager.new BinderService(); 1016 registerDefaultDisplays(displayManager); 1017 displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); 1018 1019 FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, 1020 new float[]{60f}); 1021 int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService, 1022 displayDevice); 1023 DisplayInfo displayInfo = displayManagerBinderService.getDisplayInfo(displayId); 1024 assertEquals(60f, displayInfo.getRefreshRate(), 0.01f); 1025 1026 updateFrameRateOverride(displayManager, displayDevice, 1027 new DisplayEventReceiver.FrameRateOverride[]{ 1028 new DisplayEventReceiver.FrameRateOverride( 1029 Process.myUid(), 20f) 1030 }); 1031 displayInfo = displayManagerBinderService.getDisplayInfo(displayId); 1032 float expectedRefreshRate = injector.getAllowNonNativeRefreshRateOverride() ? 20f : 60f; 1033 assertEquals(expectedRefreshRate, displayInfo.getRefreshRate(), 0.01f); 1034 } 1035 getDisplayIdForDisplayDevice( DisplayManagerService displayManager, DisplayManagerService.BinderService displayManagerBinderService, FakeDisplayDevice displayDevice)1036 private int getDisplayIdForDisplayDevice( 1037 DisplayManagerService displayManager, 1038 DisplayManagerService.BinderService displayManagerBinderService, 1039 FakeDisplayDevice displayDevice) { 1040 1041 final int[] displayIds = displayManagerBinderService.getDisplayIds(); 1042 assertTrue(displayIds.length > 0); 1043 int displayId = Display.INVALID_DISPLAY; 1044 for (int i = 0; i < displayIds.length; i++) { 1045 DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayIds[i]); 1046 if (displayDevice.getDisplayDeviceInfoLocked().equals(ddi)) { 1047 displayId = displayIds[i]; 1048 break; 1049 } 1050 } 1051 assertFalse(displayId == Display.INVALID_DISPLAY); 1052 return displayId; 1053 } 1054 updateDisplayDeviceInfo(DisplayManagerService displayManager, FakeDisplayDevice displayDevice, DisplayDeviceInfo displayDeviceInfo)1055 private void updateDisplayDeviceInfo(DisplayManagerService displayManager, 1056 FakeDisplayDevice displayDevice, 1057 DisplayDeviceInfo displayDeviceInfo) { 1058 displayDevice.setDisplayDeviceInfo(displayDeviceInfo); 1059 displayManager.getDisplayDeviceRepository() 1060 .onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_CHANGED); 1061 Handler handler = displayManager.getDisplayHandler(); 1062 waitForIdleHandler(handler); 1063 } 1064 updateFrameRateOverride(DisplayManagerService displayManager, FakeDisplayDevice displayDevice, DisplayEventReceiver.FrameRateOverride[] frameRateOverrides)1065 private void updateFrameRateOverride(DisplayManagerService displayManager, 1066 FakeDisplayDevice displayDevice, 1067 DisplayEventReceiver.FrameRateOverride[] frameRateOverrides) { 1068 DisplayDeviceInfo displayDeviceInfo = new DisplayDeviceInfo(); 1069 displayDeviceInfo.copyFrom(displayDevice.getDisplayDeviceInfoLocked()); 1070 displayDeviceInfo.frameRateOverrides = frameRateOverrides; 1071 updateDisplayDeviceInfo(displayManager, displayDevice, displayDeviceInfo); 1072 } 1073 updateModeId(DisplayManagerService displayManager, FakeDisplayDevice displayDevice, int modeId)1074 private void updateModeId(DisplayManagerService displayManager, 1075 FakeDisplayDevice displayDevice, 1076 int modeId) { 1077 DisplayDeviceInfo displayDeviceInfo = new DisplayDeviceInfo(); 1078 displayDeviceInfo.copyFrom(displayDevice.getDisplayDeviceInfoLocked()); 1079 displayDeviceInfo.modeId = modeId; 1080 updateDisplayDeviceInfo(displayManager, displayDevice, displayDeviceInfo); 1081 } 1082 registerDisplayListenerCallback( DisplayManagerService displayManager, DisplayManagerService.BinderService displayManagerBinderService, FakeDisplayDevice displayDevice)1083 private FakeDisplayManagerCallback registerDisplayListenerCallback( 1084 DisplayManagerService displayManager, 1085 DisplayManagerService.BinderService displayManagerBinderService, 1086 FakeDisplayDevice displayDevice) { 1087 // Find the display id of the added FakeDisplayDevice 1088 int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService, 1089 displayDevice); 1090 1091 Handler handler = displayManager.getDisplayHandler(); 1092 waitForIdleHandler(handler); 1093 1094 // register display listener callback 1095 FakeDisplayManagerCallback callback = new FakeDisplayManagerCallback(displayId); 1096 displayManagerBinderService.registerCallbackWithEventMask( 1097 callback, STANDARD_DISPLAY_EVENTS); 1098 return callback; 1099 } 1100 createFakeDisplayDevice(DisplayManagerService displayManager, float[] refreshRates)1101 private FakeDisplayDevice createFakeDisplayDevice(DisplayManagerService displayManager, 1102 float[] refreshRates) { 1103 FakeDisplayDevice displayDevice = new FakeDisplayDevice(); 1104 DisplayDeviceInfo displayDeviceInfo = new DisplayDeviceInfo(); 1105 int width = 100; 1106 int height = 200; 1107 displayDeviceInfo.supportedModes = new Display.Mode[refreshRates.length]; 1108 for (int i = 0; i < refreshRates.length; i++) { 1109 displayDeviceInfo.supportedModes[i] = 1110 new Display.Mode(i + 1, width, height, refreshRates[i]); 1111 } 1112 displayDeviceInfo.modeId = 1; 1113 displayDeviceInfo.width = width; 1114 displayDeviceInfo.height = height; 1115 final Rect zeroRect = new Rect(); 1116 displayDeviceInfo.displayCutout = new DisplayCutout( 1117 Insets.of(0, 10, 0, 0), 1118 zeroRect, new Rect(0, 0, 10, 10), zeroRect, zeroRect); 1119 displayDeviceInfo.flags = DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY; 1120 displayDevice.setDisplayDeviceInfo(displayDeviceInfo); 1121 displayManager.getDisplayDeviceRepository() 1122 .onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED); 1123 return displayDevice; 1124 } 1125 registerDefaultDisplays(DisplayManagerService displayManager)1126 private void registerDefaultDisplays(DisplayManagerService displayManager) { 1127 Handler handler = displayManager.getDisplayHandler(); 1128 // Would prefer to call displayManager.onStart() directly here but it performs binderService 1129 // registration which triggers security exceptions when running from a test. 1130 handler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS); 1131 waitForIdleHandler(handler); 1132 } 1133 waitForIdleHandler(Handler handler)1134 private void waitForIdleHandler(Handler handler) { 1135 waitForIdleHandler(handler, Duration.ofSeconds(1)); 1136 } 1137 waitForIdleHandler(Handler handler, Duration timeout)1138 private void waitForIdleHandler(Handler handler, Duration timeout) { 1139 final MessageQueue queue = handler.getLooper().getQueue(); 1140 final CountDownLatch latch = new CountDownLatch(1); 1141 queue.addIdleHandler(() -> { 1142 latch.countDown(); 1143 // Remove idle handler 1144 return false; 1145 }); 1146 try { 1147 latch.await(timeout.toMillis(), TimeUnit.MILLISECONDS); 1148 } catch (InterruptedException e) { 1149 fail("Interrupted unexpectedly: " + e); 1150 } 1151 } 1152 1153 private class FakeDisplayManagerCallback extends IDisplayManagerCallback.Stub { 1154 int mDisplayId; 1155 boolean mDisplayAddedCalled = false; 1156 boolean mDisplayChangedCalled = false; 1157 boolean mDisplayRemovedCalled = false; 1158 FakeDisplayManagerCallback(int displayId)1159 FakeDisplayManagerCallback(int displayId) { 1160 mDisplayId = displayId; 1161 } 1162 FakeDisplayManagerCallback()1163 FakeDisplayManagerCallback() { 1164 mDisplayId = -1; 1165 } 1166 1167 @Override onDisplayEvent(int displayId, int event)1168 public void onDisplayEvent(int displayId, int event) { 1169 if (mDisplayId != -1 && displayId != mDisplayId) { 1170 return; 1171 } 1172 1173 if (event == DisplayManagerGlobal.EVENT_DISPLAY_ADDED) { 1174 mDisplayAddedCalled = true; 1175 } 1176 1177 if (event == DisplayManagerGlobal.EVENT_DISPLAY_CHANGED) { 1178 mDisplayChangedCalled = true; 1179 } 1180 1181 if (event == DisplayManagerGlobal.EVENT_DISPLAY_REMOVED) { 1182 mDisplayRemovedCalled = true; 1183 } 1184 } 1185 clear()1186 public void clear() { 1187 mDisplayAddedCalled = false; 1188 mDisplayChangedCalled = false; 1189 mDisplayRemovedCalled = false; 1190 } 1191 } 1192 1193 private class FakeDisplayDevice extends DisplayDevice { 1194 private DisplayDeviceInfo mDisplayDeviceInfo; 1195 FakeDisplayDevice()1196 FakeDisplayDevice() { 1197 super(null, null, "", mContext); 1198 } 1199 setDisplayDeviceInfo(DisplayDeviceInfo displayDeviceInfo)1200 public void setDisplayDeviceInfo(DisplayDeviceInfo displayDeviceInfo) { 1201 mDisplayDeviceInfo = displayDeviceInfo; 1202 } 1203 1204 @Override hasStableUniqueId()1205 public boolean hasStableUniqueId() { 1206 return false; 1207 } 1208 1209 @Override getDisplayDeviceInfoLocked()1210 public DisplayDeviceInfo getDisplayDeviceInfoLocked() { 1211 return mDisplayDeviceInfo; 1212 } 1213 } 1214 } 1215