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 testDisplayInfoFrameRateOverrideModeCompat(boolean compatChangeEnabled)888 private void testDisplayInfoFrameRateOverrideModeCompat(boolean compatChangeEnabled) 889 throws Exception { 890 DisplayManagerService displayManager = 891 new DisplayManagerService(mContext, mShortMockedInjector); 892 DisplayManagerService.BinderService displayManagerBinderService = 893 displayManager.new BinderService(); 894 registerDefaultDisplays(displayManager); 895 displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); 896 897 FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, 898 new float[]{60f, 30f, 20f}); 899 int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService, 900 displayDevice); 901 DisplayInfo displayInfo = displayManagerBinderService.getDisplayInfo(displayId); 902 assertEquals(60f, displayInfo.getRefreshRate(), 0.01f); 903 904 updateFrameRateOverride(displayManager, displayDevice, 905 new DisplayEventReceiver.FrameRateOverride[]{ 906 new DisplayEventReceiver.FrameRateOverride( 907 Process.myUid(), 20f), 908 new DisplayEventReceiver.FrameRateOverride( 909 Process.myUid() + 1, 30f) 910 }); 911 displayInfo = displayManagerBinderService.getDisplayInfo(displayId); 912 assertEquals(20f, displayInfo.getRefreshRate(), 0.01f); 913 Display.Mode expectedMode; 914 if (compatChangeEnabled) { 915 expectedMode = new Display.Mode(1, 100, 200, 60f); 916 } else { 917 expectedMode = new Display.Mode(3, 100, 200, 20f); 918 } 919 assertEquals(expectedMode, displayInfo.getMode()); 920 } 921 testDisplayInfoNonNativeFrameRateOverrideMode( DisplayManagerService.Injector injector, boolean compatChangeEnabled)922 private void testDisplayInfoNonNativeFrameRateOverrideMode( 923 DisplayManagerService.Injector injector, boolean compatChangeEnabled) { 924 DisplayManagerService displayManager = 925 new DisplayManagerService(mContext, injector); 926 DisplayManagerService.BinderService displayManagerBinderService = 927 displayManager.new BinderService(); 928 registerDefaultDisplays(displayManager); 929 displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); 930 931 FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, 932 new float[]{60f}); 933 int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService, 934 displayDevice); 935 DisplayInfo displayInfo = displayManagerBinderService.getDisplayInfo(displayId); 936 assertEquals(60f, displayInfo.getRefreshRate(), 0.01f); 937 938 updateFrameRateOverride(displayManager, displayDevice, 939 new DisplayEventReceiver.FrameRateOverride[]{ 940 new DisplayEventReceiver.FrameRateOverride( 941 Process.myUid(), 20f) 942 }); 943 displayInfo = displayManagerBinderService.getDisplayInfo(displayId); 944 Display.Mode expectedMode; 945 if (compatChangeEnabled) { 946 expectedMode = new Display.Mode(1, 100, 200, 60f); 947 } else if (injector.getAllowNonNativeRefreshRateOverride()) { 948 expectedMode = new Display.Mode(255, 100, 200, 20f); 949 } else { 950 expectedMode = new Display.Mode(1, 100, 200, 60f); 951 } 952 assertEquals(expectedMode, displayInfo.getMode()); 953 } 954 testDisplayInfoNonNativeFrameRateOverride( DisplayManagerService.Injector injector)955 private void testDisplayInfoNonNativeFrameRateOverride( 956 DisplayManagerService.Injector injector) { 957 DisplayManagerService displayManager = 958 new DisplayManagerService(mContext, injector); 959 DisplayManagerService.BinderService displayManagerBinderService = 960 displayManager.new BinderService(); 961 registerDefaultDisplays(displayManager); 962 displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); 963 964 FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, 965 new float[]{60f}); 966 int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService, 967 displayDevice); 968 DisplayInfo displayInfo = displayManagerBinderService.getDisplayInfo(displayId); 969 assertEquals(60f, displayInfo.getRefreshRate(), 0.01f); 970 971 updateFrameRateOverride(displayManager, displayDevice, 972 new DisplayEventReceiver.FrameRateOverride[]{ 973 new DisplayEventReceiver.FrameRateOverride( 974 Process.myUid(), 20f) 975 }); 976 displayInfo = displayManagerBinderService.getDisplayInfo(displayId); 977 float expectedRefreshRate = injector.getAllowNonNativeRefreshRateOverride() ? 20f : 60f; 978 assertEquals(expectedRefreshRate, displayInfo.getRefreshRate(), 0.01f); 979 } 980 getDisplayIdForDisplayDevice( DisplayManagerService displayManager, DisplayManagerService.BinderService displayManagerBinderService, FakeDisplayDevice displayDevice)981 private int getDisplayIdForDisplayDevice( 982 DisplayManagerService displayManager, 983 DisplayManagerService.BinderService displayManagerBinderService, 984 FakeDisplayDevice displayDevice) { 985 986 final int[] displayIds = displayManagerBinderService.getDisplayIds(); 987 assertTrue(displayIds.length > 0); 988 int displayId = Display.INVALID_DISPLAY; 989 for (int i = 0; i < displayIds.length; i++) { 990 DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayIds[i]); 991 if (displayDevice.getDisplayDeviceInfoLocked().equals(ddi)) { 992 displayId = displayIds[i]; 993 break; 994 } 995 } 996 assertFalse(displayId == Display.INVALID_DISPLAY); 997 return displayId; 998 } 999 updateDisplayDeviceInfo(DisplayManagerService displayManager, FakeDisplayDevice displayDevice, DisplayDeviceInfo displayDeviceInfo)1000 private void updateDisplayDeviceInfo(DisplayManagerService displayManager, 1001 FakeDisplayDevice displayDevice, 1002 DisplayDeviceInfo displayDeviceInfo) { 1003 displayDevice.setDisplayDeviceInfo(displayDeviceInfo); 1004 displayManager.getDisplayDeviceRepository() 1005 .onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_CHANGED); 1006 Handler handler = displayManager.getDisplayHandler(); 1007 waitForIdleHandler(handler); 1008 } 1009 updateFrameRateOverride(DisplayManagerService displayManager, FakeDisplayDevice displayDevice, DisplayEventReceiver.FrameRateOverride[] frameRateOverrides)1010 private void updateFrameRateOverride(DisplayManagerService displayManager, 1011 FakeDisplayDevice displayDevice, 1012 DisplayEventReceiver.FrameRateOverride[] frameRateOverrides) { 1013 DisplayDeviceInfo displayDeviceInfo = new DisplayDeviceInfo(); 1014 displayDeviceInfo.copyFrom(displayDevice.getDisplayDeviceInfoLocked()); 1015 displayDeviceInfo.frameRateOverrides = frameRateOverrides; 1016 updateDisplayDeviceInfo(displayManager, displayDevice, displayDeviceInfo); 1017 } 1018 updateModeId(DisplayManagerService displayManager, FakeDisplayDevice displayDevice, int modeId)1019 private void updateModeId(DisplayManagerService displayManager, 1020 FakeDisplayDevice displayDevice, 1021 int modeId) { 1022 DisplayDeviceInfo displayDeviceInfo = new DisplayDeviceInfo(); 1023 displayDeviceInfo.copyFrom(displayDevice.getDisplayDeviceInfoLocked()); 1024 displayDeviceInfo.modeId = modeId; 1025 updateDisplayDeviceInfo(displayManager, displayDevice, displayDeviceInfo); 1026 } 1027 registerDisplayListenerCallback( DisplayManagerService displayManager, DisplayManagerService.BinderService displayManagerBinderService, FakeDisplayDevice displayDevice)1028 private FakeDisplayManagerCallback registerDisplayListenerCallback( 1029 DisplayManagerService displayManager, 1030 DisplayManagerService.BinderService displayManagerBinderService, 1031 FakeDisplayDevice displayDevice) { 1032 // Find the display id of the added FakeDisplayDevice 1033 int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService, 1034 displayDevice); 1035 1036 Handler handler = displayManager.getDisplayHandler(); 1037 waitForIdleHandler(handler); 1038 1039 // register display listener callback 1040 FakeDisplayManagerCallback callback = new FakeDisplayManagerCallback(displayId); 1041 displayManagerBinderService.registerCallbackWithEventMask( 1042 callback, STANDARD_DISPLAY_EVENTS); 1043 return callback; 1044 } 1045 createFakeDisplayDevice(DisplayManagerService displayManager, float[] refreshRates)1046 private FakeDisplayDevice createFakeDisplayDevice(DisplayManagerService displayManager, 1047 float[] refreshRates) { 1048 FakeDisplayDevice displayDevice = new FakeDisplayDevice(); 1049 DisplayDeviceInfo displayDeviceInfo = new DisplayDeviceInfo(); 1050 int width = 100; 1051 int height = 200; 1052 displayDeviceInfo.supportedModes = new Display.Mode[refreshRates.length]; 1053 for (int i = 0; i < refreshRates.length; i++) { 1054 displayDeviceInfo.supportedModes[i] = 1055 new Display.Mode(i + 1, width, height, refreshRates[i]); 1056 } 1057 displayDeviceInfo.modeId = 1; 1058 displayDeviceInfo.width = width; 1059 displayDeviceInfo.height = height; 1060 final Rect zeroRect = new Rect(); 1061 displayDeviceInfo.displayCutout = new DisplayCutout( 1062 Insets.of(0, 10, 0, 0), 1063 zeroRect, new Rect(0, 0, 10, 10), zeroRect, zeroRect); 1064 displayDeviceInfo.flags = DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY; 1065 displayDevice.setDisplayDeviceInfo(displayDeviceInfo); 1066 displayManager.getDisplayDeviceRepository() 1067 .onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED); 1068 return displayDevice; 1069 } 1070 registerDefaultDisplays(DisplayManagerService displayManager)1071 private void registerDefaultDisplays(DisplayManagerService displayManager) { 1072 Handler handler = displayManager.getDisplayHandler(); 1073 // Would prefer to call displayManager.onStart() directly here but it performs binderService 1074 // registration which triggers security exceptions when running from a test. 1075 handler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS); 1076 waitForIdleHandler(handler); 1077 } 1078 waitForIdleHandler(Handler handler)1079 private void waitForIdleHandler(Handler handler) { 1080 waitForIdleHandler(handler, Duration.ofSeconds(1)); 1081 } 1082 waitForIdleHandler(Handler handler, Duration timeout)1083 private void waitForIdleHandler(Handler handler, Duration timeout) { 1084 final MessageQueue queue = handler.getLooper().getQueue(); 1085 final CountDownLatch latch = new CountDownLatch(1); 1086 queue.addIdleHandler(() -> { 1087 latch.countDown(); 1088 // Remove idle handler 1089 return false; 1090 }); 1091 try { 1092 latch.await(timeout.toMillis(), TimeUnit.MILLISECONDS); 1093 } catch (InterruptedException e) { 1094 fail("Interrupted unexpectedly: " + e); 1095 } 1096 } 1097 1098 private class FakeDisplayManagerCallback extends IDisplayManagerCallback.Stub { 1099 int mDisplayId; 1100 boolean mDisplayAddedCalled = false; 1101 boolean mDisplayChangedCalled = false; 1102 boolean mDisplayRemovedCalled = false; 1103 FakeDisplayManagerCallback(int displayId)1104 FakeDisplayManagerCallback(int displayId) { 1105 mDisplayId = displayId; 1106 } 1107 FakeDisplayManagerCallback()1108 FakeDisplayManagerCallback() { 1109 mDisplayId = -1; 1110 } 1111 1112 @Override onDisplayEvent(int displayId, int event)1113 public void onDisplayEvent(int displayId, int event) { 1114 if (mDisplayId != -1 && displayId != mDisplayId) { 1115 return; 1116 } 1117 1118 if (event == DisplayManagerGlobal.EVENT_DISPLAY_ADDED) { 1119 mDisplayAddedCalled = true; 1120 } 1121 1122 if (event == DisplayManagerGlobal.EVENT_DISPLAY_CHANGED) { 1123 mDisplayChangedCalled = true; 1124 } 1125 1126 if (event == DisplayManagerGlobal.EVENT_DISPLAY_REMOVED) { 1127 mDisplayRemovedCalled = true; 1128 } 1129 } 1130 clear()1131 public void clear() { 1132 mDisplayAddedCalled = false; 1133 mDisplayChangedCalled = false; 1134 mDisplayRemovedCalled = false; 1135 } 1136 } 1137 1138 private class FakeDisplayDevice extends DisplayDevice { 1139 private DisplayDeviceInfo mDisplayDeviceInfo; 1140 FakeDisplayDevice()1141 FakeDisplayDevice() { 1142 super(null, null, "", mContext); 1143 } 1144 setDisplayDeviceInfo(DisplayDeviceInfo displayDeviceInfo)1145 public void setDisplayDeviceInfo(DisplayDeviceInfo displayDeviceInfo) { 1146 mDisplayDeviceInfo = displayDeviceInfo; 1147 } 1148 1149 @Override hasStableUniqueId()1150 public boolean hasStableUniqueId() { 1151 return false; 1152 } 1153 1154 @Override getDisplayDeviceInfoLocked()1155 public DisplayDeviceInfo getDisplayDeviceInfoLocked() { 1156 return mDisplayDeviceInfo; 1157 } 1158 } 1159 } 1160