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 android.Manifest.permission.ADD_ALWAYS_UNLOCKED_DISPLAY; 20 import static android.Manifest.permission.ADD_TRUSTED_DISPLAY; 21 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED; 22 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY; 23 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP; 24 import static android.view.ContentRecordingSession.RECORD_CONTENT_DISPLAY; 25 import static android.view.ContentRecordingSession.RECORD_CONTENT_TASK; 26 27 import static com.android.server.display.VirtualDisplayAdapter.UNIQUE_ID_PREFIX; 28 29 import static com.google.common.truth.Truth.assertThat; 30 31 import static org.junit.Assert.assertEquals; 32 import static org.junit.Assert.assertFalse; 33 import static org.junit.Assert.assertNotEquals; 34 import static org.junit.Assert.assertNotNull; 35 import static org.junit.Assert.assertNull; 36 import static org.junit.Assert.assertThrows; 37 import static org.junit.Assert.assertTrue; 38 import static org.junit.Assert.fail; 39 import static org.mockito.ArgumentMatchers.anyInt; 40 import static org.mockito.ArgumentMatchers.anyLong; 41 import static org.mockito.ArgumentMatchers.eq; 42 import static org.mockito.ArgumentMatchers.nullable; 43 import static org.mockito.Mockito.any; 44 import static org.mockito.Mockito.atLeastOnce; 45 import static org.mockito.Mockito.doReturn; 46 import static org.mockito.Mockito.inOrder; 47 import static org.mockito.Mockito.mock; 48 import static org.mockito.Mockito.never; 49 import static org.mockito.Mockito.spy; 50 import static org.mockito.Mockito.verify; 51 import static org.mockito.Mockito.when; 52 53 import android.app.PropertyInvalidatedCache; 54 import android.companion.virtual.IVirtualDevice; 55 import android.companion.virtual.IVirtualDeviceManager; 56 import android.companion.virtual.VirtualDeviceManager; 57 import android.compat.testing.PlatformCompatChangeRule; 58 import android.content.Context; 59 import android.content.ContextWrapper; 60 import android.content.pm.PackageManager; 61 import android.content.pm.PackageManagerInternal; 62 import android.content.res.Resources; 63 import android.graphics.Insets; 64 import android.graphics.Rect; 65 import android.hardware.Sensor; 66 import android.hardware.SensorManager; 67 import android.hardware.display.BrightnessConfiguration; 68 import android.hardware.display.Curve; 69 import android.hardware.display.DisplayManager; 70 import android.hardware.display.DisplayManagerGlobal; 71 import android.hardware.display.DisplayManagerInternal; 72 import android.hardware.display.DisplayViewport; 73 import android.hardware.display.DisplayedContentSample; 74 import android.hardware.display.DisplayedContentSamplingAttributes; 75 import android.hardware.display.HdrConversionMode; 76 import android.hardware.display.IDisplayManagerCallback; 77 import android.hardware.display.IVirtualDisplayCallback; 78 import android.hardware.display.VirtualDisplayConfig; 79 import android.media.projection.IMediaProjection; 80 import android.media.projection.IMediaProjectionManager; 81 import android.os.Binder; 82 import android.os.Handler; 83 import android.os.IBinder; 84 import android.os.MessageQueue; 85 import android.os.Process; 86 import android.os.RemoteException; 87 import android.view.ContentRecordingSession; 88 import android.view.Display; 89 import android.view.DisplayCutout; 90 import android.view.DisplayEventReceiver; 91 import android.view.DisplayInfo; 92 import android.view.Surface; 93 import android.view.SurfaceControl; 94 import android.window.DisplayWindowPolicyController; 95 96 import androidx.test.InstrumentationRegistry; 97 import androidx.test.core.app.ApplicationProvider; 98 import androidx.test.filters.FlakyTest; 99 import androidx.test.filters.SmallTest; 100 import androidx.test.runner.AndroidJUnit4; 101 102 import com.android.internal.R; 103 import com.android.server.LocalServices; 104 import com.android.server.SystemService; 105 import com.android.server.companion.virtual.VirtualDeviceManagerInternal; 106 import com.android.server.display.DisplayManagerService.DeviceStateListener; 107 import com.android.server.display.DisplayManagerService.SyncRoot; 108 import com.android.server.input.InputManagerInternal; 109 import com.android.server.lights.LightsManager; 110 import com.android.server.pm.UserManagerInternal; 111 import com.android.server.sensors.SensorManagerInternal; 112 import com.android.server.wm.WindowManagerInternal; 113 114 import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges; 115 import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges; 116 117 import org.junit.Before; 118 import org.junit.Rule; 119 import org.junit.Test; 120 import org.junit.rules.TestRule; 121 import org.junit.runner.RunWith; 122 import org.mockito.ArgumentCaptor; 123 import org.mockito.Captor; 124 import org.mockito.InOrder; 125 import org.mockito.Mock; 126 import org.mockito.Mockito; 127 import org.mockito.MockitoAnnotations; 128 129 import java.time.Duration; 130 import java.util.Arrays; 131 import java.util.Collections; 132 import java.util.List; 133 import java.util.Map; 134 import java.util.concurrent.CountDownLatch; 135 import java.util.concurrent.TimeUnit; 136 import java.util.stream.LongStream; 137 138 @SmallTest 139 @RunWith(AndroidJUnit4.class) 140 public class DisplayManagerServiceTest { 141 private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS = 1; 142 private static final long SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS = 10; 143 144 private static final float FLOAT_TOLERANCE = 0.01f; 145 146 private static final String VIRTUAL_DISPLAY_NAME = "Test Virtual Display"; 147 private static final String PACKAGE_NAME = "com.android.frameworks.displayservicetests"; 148 private static final long STANDARD_DISPLAY_EVENTS = DisplayManager.EVENT_FLAG_DISPLAY_ADDED 149 | DisplayManager.EVENT_FLAG_DISPLAY_CHANGED 150 | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED; 151 152 @Rule 153 public TestRule compatChangeRule = new PlatformCompatChangeRule(); 154 155 private Context mContext; 156 157 private int mHdrConversionMode; 158 159 private int mPreferredHdrOutputType; 160 161 private final DisplayManagerService.Injector mShortMockedInjector = 162 new DisplayManagerService.Injector() { 163 @Override 164 VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, 165 Context context, Handler handler, DisplayAdapter.Listener listener) { 166 return mMockVirtualDisplayAdapter; 167 } 168 169 @Override 170 LocalDisplayAdapter getLocalDisplayAdapter(SyncRoot syncRoot, Context context, 171 Handler handler, DisplayAdapter.Listener displayAdapterListener) { 172 return new LocalDisplayAdapter(syncRoot, context, handler, 173 displayAdapterListener, new LocalDisplayAdapter.Injector() { 174 @Override 175 public LocalDisplayAdapter.SurfaceControlProxy getSurfaceControlProxy() { 176 return mSurfaceControlProxy; 177 } 178 }); 179 } 180 181 @Override 182 long getDefaultDisplayDelayTimeout() { 183 return SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS; 184 } 185 }; 186 187 class BasicInjector extends DisplayManagerService.Injector { 188 @Override getProjectionService()189 IMediaProjectionManager getProjectionService() { 190 return mMockProjectionService; 191 } 192 193 @Override getVirtualDisplayAdapter(SyncRoot syncRoot, Context context, Handler handler, DisplayAdapter.Listener displayAdapterListener)194 VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, Context context, 195 Handler handler, DisplayAdapter.Listener displayAdapterListener) { 196 return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener, 197 new VirtualDisplayAdapter.SurfaceControlDisplayFactory() { 198 @Override 199 public IBinder createDisplay(String name, boolean secure, 200 float requestedRefreshRate) { 201 return mMockDisplayToken; 202 } 203 204 @Override 205 public void destroyDisplay(IBinder displayToken) { 206 } 207 }); 208 } 209 210 @Override getLocalDisplayAdapter(SyncRoot syncRoot, Context context, Handler handler, DisplayAdapter.Listener displayAdapterListener)211 LocalDisplayAdapter getLocalDisplayAdapter(SyncRoot syncRoot, Context context, 212 Handler handler, DisplayAdapter.Listener displayAdapterListener) { 213 return new LocalDisplayAdapter(syncRoot, context, handler, 214 displayAdapterListener, new LocalDisplayAdapter.Injector() { 215 @Override 216 public LocalDisplayAdapter.SurfaceControlProxy getSurfaceControlProxy() { 217 return mSurfaceControlProxy; 218 } 219 }); 220 } 221 222 @Override 223 int setHdrConversionMode(int conversionMode, int preferredHdrOutputType, 224 int[] autoHdrTypes) { 225 mHdrConversionMode = conversionMode; 226 mPreferredHdrOutputType = preferredHdrOutputType; 227 return Display.HdrCapabilities.HDR_TYPE_INVALID; 228 } 229 230 @Override 231 int[] getSupportedHdrOutputTypes() { 232 return new int[]{}; 233 } 234 235 @Override 236 int[] getHdrOutputTypesWithLatency() { 237 return new int[]{Display.HdrCapabilities.HDR_TYPE_DOLBY_VISION}; 238 } 239 240 boolean getHdrOutputConversionSupport() { 241 return true; 242 } 243 } 244 245 private final DisplayManagerService.Injector mBasicInjector = new BasicInjector(); 246 247 @Mock IMediaProjectionManager mMockProjectionService; 248 @Mock IVirtualDeviceManager mIVirtualDeviceManager; 249 @Mock InputManagerInternal mMockInputManagerInternal; 250 @Mock VirtualDeviceManagerInternal mMockVirtualDeviceManagerInternal; 251 @Mock IVirtualDisplayCallback.Stub mMockAppToken; 252 @Mock IVirtualDisplayCallback.Stub mMockAppToken2; 253 @Mock WindowManagerInternal mMockWindowManagerInternal; 254 @Mock LightsManager mMockLightsManager; 255 @Mock VirtualDisplayAdapter mMockVirtualDisplayAdapter; 256 @Mock LocalDisplayAdapter.SurfaceControlProxy mSurfaceControlProxy; 257 @Mock IBinder mMockDisplayToken; 258 @Mock SensorManagerInternal mMockSensorManagerInternal; 259 @Mock SensorManager mSensorManager; 260 @Mock DisplayDeviceConfig mMockDisplayDeviceConfig; 261 @Mock PackageManagerInternal mMockPackageManagerInternal; 262 @Mock UserManagerInternal mMockUserManagerInternal; 263 264 265 @Captor ArgumentCaptor<ContentRecordingSession> mContentRecordingSessionCaptor; 266 267 @Before 268 public void setUp() throws Exception { 269 MockitoAnnotations.initMocks(this); 270 271 LocalServices.removeServiceForTest(InputManagerInternal.class); 272 LocalServices.addService(InputManagerInternal.class, mMockInputManagerInternal); 273 LocalServices.removeServiceForTest(WindowManagerInternal.class); 274 LocalServices.addService(WindowManagerInternal.class, mMockWindowManagerInternal); 275 LocalServices.removeServiceForTest(LightsManager.class); 276 LocalServices.addService(LightsManager.class, mMockLightsManager); 277 LocalServices.removeServiceForTest(SensorManagerInternal.class); 278 LocalServices.addService(SensorManagerInternal.class, mMockSensorManagerInternal); 279 LocalServices.removeServiceForTest(VirtualDeviceManagerInternal.class); 280 LocalServices.addService( 281 VirtualDeviceManagerInternal.class, mMockVirtualDeviceManagerInternal); 282 LocalServices.removeServiceForTest(PackageManagerInternal.class); 283 LocalServices.addService(PackageManagerInternal.class, mMockPackageManagerInternal); 284 LocalServices.removeServiceForTest(UserManagerInternal.class); 285 LocalServices.addService(UserManagerInternal.class, mMockUserManagerInternal); 286 // TODO: b/287945043 287 mContext = spy(new ContextWrapper(ApplicationProvider.getApplicationContext())); 288 289 VirtualDeviceManager vdm = new VirtualDeviceManager(mIVirtualDeviceManager, mContext); 290 when(mContext.getSystemService(VirtualDeviceManager.class)).thenReturn(vdm); 291 // Disable binder caches in this process. 292 PropertyInvalidatedCache.disableForTestMode(); 293 setUpDisplay(); 294 } 295 296 private void setUpDisplay() { 297 long[] ids = new long[] {100}; 298 when(mSurfaceControlProxy.getPhysicalDisplayIds()).thenReturn(ids); 299 when(mSurfaceControlProxy.getPhysicalDisplayToken(anyLong())) 300 .thenReturn(mMockDisplayToken); 301 SurfaceControl.StaticDisplayInfo staticDisplayInfo = new SurfaceControl.StaticDisplayInfo(); 302 staticDisplayInfo.isInternal = true; 303 when(mSurfaceControlProxy.getStaticDisplayInfo(anyLong())) 304 .thenReturn(staticDisplayInfo); 305 SurfaceControl.DynamicDisplayInfo dynamicDisplayMode = 306 new SurfaceControl.DynamicDisplayInfo(); 307 SurfaceControl.DisplayMode displayMode = new SurfaceControl.DisplayMode(); 308 displayMode.width = 100; 309 displayMode.height = 200; 310 displayMode.supportedHdrTypes = new int[]{1, 2}; 311 dynamicDisplayMode.supportedDisplayModes = new SurfaceControl.DisplayMode[] {displayMode}; 312 when(mSurfaceControlProxy.getDynamicDisplayInfo(anyLong())) 313 .thenReturn(dynamicDisplayMode); 314 when(mSurfaceControlProxy.getDesiredDisplayModeSpecs(mMockDisplayToken)) 315 .thenReturn(new SurfaceControl.DesiredDisplayModeSpecs()); 316 } 317 318 @Test 319 public void testCreateVirtualDisplay_sentToInputManager() throws RemoteException { 320 // This is to update the display device config such that DisplayManagerService can ignore 321 // the usage of SensorManager, which is available only after the PowerManagerService 322 // is ready. 323 resetConfigToIgnoreSensorManager(mContext); 324 DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); 325 registerDefaultDisplays(displayManager); 326 displayManager.systemReady(false /* safeMode */); 327 displayManager.windowManagerAndInputReady(); 328 329 // This is effectively the DisplayManager service published to ServiceManager. 330 DisplayManagerService.BinderService bs = displayManager.new BinderService(); 331 332 String uniqueId = "uniqueId --- Test"; 333 String uniqueIdPrefix = UNIQUE_ID_PREFIX + mContext.getPackageName() + ":"; 334 int width = 600; 335 int height = 800; 336 int dpi = 320; 337 int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH; 338 339 when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); 340 final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder( 341 VIRTUAL_DISPLAY_NAME, width, height, dpi); 342 builder.setUniqueId(uniqueId); 343 builder.setFlags(flags); 344 int displayId = bs.createVirtualDisplay(builder.build(), mMockAppToken /* callback */, 345 null /* projection */, PACKAGE_NAME); 346 verify(mMockProjectionService, never()).setContentRecordingSession(any(), 347 nullable(IMediaProjection.class)); 348 349 displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class)); 350 351 // flush the handler 352 displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */); 353 354 ArgumentCaptor<List<DisplayViewport>> viewportCaptor = ArgumentCaptor.forClass(List.class); 355 verify(mMockInputManagerInternal).setDisplayViewports(viewportCaptor.capture()); 356 List<DisplayViewport> viewports = viewportCaptor.getValue(); 357 358 // Expect to receive at least 2 viewports: at least 1 internal, and 1 virtual 359 assertTrue(viewports.size() >= 2); 360 361 DisplayViewport virtualViewport = null; 362 DisplayViewport internalViewport = null; 363 for (int i = 0; i < viewports.size(); i++) { 364 DisplayViewport v = viewports.get(i); 365 switch (v.type) { 366 case DisplayViewport.VIEWPORT_INTERNAL: { 367 // If more than one internal viewport, this will get overwritten several times, 368 // which for the purposes of this test is fine. 369 internalViewport = v; 370 assertTrue(internalViewport.valid); 371 break; 372 } 373 case DisplayViewport.VIEWPORT_EXTERNAL: { 374 // External view port is present for auto devices in the form of instrument 375 // cluster. 376 break; 377 } 378 case DisplayViewport.VIEWPORT_VIRTUAL: { 379 virtualViewport = v; 380 break; 381 } 382 } 383 } 384 // INTERNAL viewport gets created upon access. 385 assertNotNull(internalViewport); 386 assertNotNull(virtualViewport); 387 388 // VIRTUAL 389 assertEquals(height, virtualViewport.deviceHeight); 390 assertEquals(width, virtualViewport.deviceWidth); 391 assertEquals(uniqueIdPrefix + uniqueId, virtualViewport.uniqueId); 392 assertEquals(displayId, virtualViewport.displayId); 393 } 394 395 @Test 396 public void testPhysicalViewports() { 397 // This is to update the display device config such that DisplayManagerService can ignore 398 // the usage of SensorManager, which is available only after the PowerManagerService 399 // is ready. 400 resetConfigToIgnoreSensorManager(mContext); 401 DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); 402 registerDefaultDisplays(displayManager); 403 displayManager.systemReady(false /* safeMode */); 404 displayManager.windowManagerAndInputReady(); 405 406 // This is effectively the DisplayManager service published to ServiceManager. 407 DisplayManagerService.BinderService bs = displayManager.new BinderService(); 408 409 when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); 410 411 final int[] displayIds = bs.getDisplayIds(/* includeDisabled= */ true); 412 final int size = displayIds.length; 413 assertTrue(size > 0); 414 415 Map<Integer, Integer> expectedDisplayTypeToViewPortTypeMapping = Map.of( 416 Display.TYPE_INTERNAL, DisplayViewport.VIEWPORT_INTERNAL, 417 Display.TYPE_EXTERNAL, DisplayViewport.VIEWPORT_EXTERNAL 418 ); 419 for (int i = 0; i < size; i++) { 420 DisplayInfo info = bs.getDisplayInfo(displayIds[i]); 421 assertTrue(expectedDisplayTypeToViewPortTypeMapping.keySet().contains(info.type)); 422 } 423 424 displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class)); 425 426 // flush the handler 427 displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */); 428 429 ArgumentCaptor<List<DisplayViewport>> viewportCaptor = ArgumentCaptor.forClass(List.class); 430 verify(mMockInputManagerInternal).setDisplayViewports(viewportCaptor.capture()); 431 List<DisplayViewport> viewports = viewportCaptor.getValue(); 432 433 // Due to the nature of foldables, we may have a different number of viewports than 434 // displays, just verify there's at least one. 435 final int viewportSize = viewports.size(); 436 assertTrue(viewportSize > 0); 437 438 // Now verify that each viewport's displayId is valid. 439 Arrays.sort(displayIds); 440 for (int i = 0; i < viewportSize; i++) { 441 DisplayViewport viewport = viewports.get(i); 442 assertNotNull(viewport); 443 DisplayInfo displayInfo = bs.getDisplayInfo(viewport.displayId); 444 assertTrue(expectedDisplayTypeToViewPortTypeMapping.get(displayInfo.type) 445 == viewport.type); 446 assertTrue(viewport.valid); 447 assertTrue(Arrays.binarySearch(displayIds, viewport.displayId) >= 0); 448 } 449 } 450 451 @Test 452 public void testCreateVirtualDisplayRotatesWithContent() throws Exception { 453 DisplayManagerService displayManager = 454 new DisplayManagerService(mContext, mBasicInjector); 455 registerDefaultDisplays(displayManager); 456 457 // This is effectively the DisplayManager service published to ServiceManager. 458 DisplayManagerService.BinderService bs = displayManager.new BinderService(); 459 460 String uniqueId = "uniqueId --- Rotates With Content Test"; 461 int width = 600; 462 int height = 800; 463 int dpi = 320; 464 int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT; 465 466 when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); 467 final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder( 468 VIRTUAL_DISPLAY_NAME, width, height, dpi); 469 builder.setFlags(flags); 470 builder.setUniqueId(uniqueId); 471 int displayId = bs.createVirtualDisplay(builder.build(), mMockAppToken /* callback */, 472 null /* projection */, PACKAGE_NAME); 473 verify(mMockProjectionService, never()).setContentRecordingSession(any(), 474 nullable(IMediaProjection.class)); 475 476 displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class)); 477 478 // flush the handler 479 displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */); 480 481 DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayId); 482 assertNotNull(ddi); 483 assertTrue((ddi.flags & DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT) != 0); 484 } 485 486 @Test 487 public void testCreateVirtualRotatesWithContent() throws RemoteException { 488 DisplayManagerService displayManager = 489 new DisplayManagerService(mContext, mBasicInjector); 490 registerDefaultDisplays(displayManager); 491 492 // This is effectively the DisplayManager service published to ServiceManager. 493 DisplayManagerService.BinderService bs = displayManager.new BinderService(); 494 495 String uniqueId = "uniqueId --- Rotates with Content Test"; 496 int width = 600; 497 int height = 800; 498 int dpi = 320; 499 int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT; 500 501 when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); 502 final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder( 503 VIRTUAL_DISPLAY_NAME, width, height, dpi); 504 builder.setFlags(flags); 505 builder.setUniqueId(uniqueId); 506 int displayId = bs.createVirtualDisplay(builder.build(), /* callback= */ mMockAppToken, 507 /* projection= */ null, PACKAGE_NAME); 508 verify(mMockProjectionService, never()).setContentRecordingSession(any(), 509 nullable(IMediaProjection.class)); 510 511 displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class)); 512 513 // flush the handler 514 displayManager.getDisplayHandler().runWithScissors(() -> {}, /* now= */ 0); 515 516 DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayId); 517 assertNotNull(ddi); 518 assertTrue((ddi.flags & DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT) != 0); 519 } 520 521 @Test 522 public void testCreateVirtualDisplayOwnFocus() throws RemoteException { 523 DisplayManagerService displayManager = 524 new DisplayManagerService(mContext, mBasicInjector); 525 registerDefaultDisplays(displayManager); 526 527 // This is effectively the DisplayManager service published to ServiceManager. 528 DisplayManagerService.BinderService bs = displayManager.new BinderService(); 529 530 String uniqueId = "uniqueId --- Own Focus Test"; 531 int width = 600; 532 int height = 800; 533 int dpi = 320; 534 int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_FOCUS 535 | DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED; 536 537 when(mContext.checkCallingPermission(ADD_TRUSTED_DISPLAY)).thenReturn( 538 PackageManager.PERMISSION_GRANTED); 539 when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); 540 final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder( 541 VIRTUAL_DISPLAY_NAME, width, height, dpi); 542 builder.setFlags(flags); 543 builder.setUniqueId(uniqueId); 544 int displayId = bs.createVirtualDisplay(builder.build(), /* callback= */ mMockAppToken, 545 /* projection= */ null, PACKAGE_NAME); 546 verify(mMockProjectionService, never()).setContentRecordingSession(any(), 547 nullable(IMediaProjection.class)); 548 549 displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class)); 550 551 // flush the handler 552 displayManager.getDisplayHandler().runWithScissors(() -> {}, /* now= */ 0); 553 554 DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayId); 555 assertNotNull(ddi); 556 assertTrue((ddi.flags & DisplayDeviceInfo.FLAG_OWN_FOCUS) != 0); 557 } 558 559 @Test 560 public void testCreateVirtualDisplayOwnFocus_nonTrustedDisplay() throws RemoteException { 561 DisplayManagerService displayManager = 562 new DisplayManagerService(mContext, mBasicInjector); 563 registerDefaultDisplays(displayManager); 564 565 // This is effectively the DisplayManager service published to ServiceManager. 566 DisplayManagerService.BinderService bs = displayManager.new BinderService(); 567 568 String uniqueId = "uniqueId --- Own Focus Test -- nonTrustedDisplay"; 569 int width = 600; 570 int height = 800; 571 int dpi = 320; 572 int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_FOCUS; 573 574 when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); 575 final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder( 576 VIRTUAL_DISPLAY_NAME, width, height, dpi); 577 builder.setFlags(flags); 578 builder.setUniqueId(uniqueId); 579 int displayId = bs.createVirtualDisplay(builder.build(), /* callback= */ mMockAppToken, 580 /* projection= */ null, PACKAGE_NAME); 581 verify(mMockProjectionService, never()).setContentRecordingSession(any(), 582 nullable(IMediaProjection.class)); 583 584 displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class)); 585 586 // flush the handler 587 displayManager.getDisplayHandler().runWithScissors(() -> {}, /* now= */ 0); 588 589 DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayId); 590 assertNotNull(ddi); 591 assertTrue((ddi.flags & DisplayDeviceInfo.FLAG_OWN_FOCUS) == 0); 592 } 593 594 /** 595 * Tests that the virtual display is created along-side the default display. 596 */ 597 @Test 598 public void testStartVirtualDisplayWithDefaultDisplay_Succeeds() throws Exception { 599 DisplayManagerService displayManager = 600 new DisplayManagerService(mContext, mShortMockedInjector); 601 registerDefaultDisplays(displayManager); 602 displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); 603 } 604 605 /** 606 * Tests that we send the device state to window manager 607 */ 608 @Test 609 public void testOnStateChanged_sendsStateChangedEventToWm() throws Exception { 610 DisplayManagerService displayManager = 611 new DisplayManagerService(mContext, mShortMockedInjector); 612 registerDefaultDisplays(displayManager); 613 displayManager.windowManagerAndInputReady(); 614 displayManager.onBootPhase(SystemService.PHASE_BOOT_COMPLETED); 615 DeviceStateListener listener = displayManager.new DeviceStateListener(); 616 Handler handler = displayManager.getDisplayHandler(); 617 IDisplayManagerCallback displayChangesCallback = registerDisplayChangeCallback( 618 displayManager); 619 620 listener.onStateChanged(123); 621 waitForIdleHandler(handler); 622 623 InOrder inOrder = inOrder(mMockWindowManagerInternal, displayChangesCallback); 624 // Verify there are no display events before WM call 625 inOrder.verify(displayChangesCallback, never()).onDisplayEvent(anyInt(), anyInt()); 626 inOrder.verify(mMockWindowManagerInternal).onDisplayManagerReceivedDeviceState(123); 627 } 628 629 /** 630 * Tests that there should be a display change notification to WindowManager to update its own 631 * internal state for things like display cutout when nonOverrideDisplayInfo is changed. 632 */ 633 @Test 634 public void testShouldNotifyChangeWhenNonOverrideDisplayInfoChanged() throws Exception { 635 DisplayManagerService displayManager = 636 new DisplayManagerService(mContext, mShortMockedInjector); 637 registerDefaultDisplays(displayManager); 638 displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); 639 640 // Add the FakeDisplayDevice 641 FakeDisplayDevice displayDevice = new FakeDisplayDevice(); 642 DisplayDeviceInfo displayDeviceInfo = new DisplayDeviceInfo(); 643 displayDeviceInfo.width = 100; 644 displayDeviceInfo.height = 200; 645 displayDeviceInfo.supportedModes = new Display.Mode[1]; 646 displayDeviceInfo.supportedModes[0] = new Display.Mode(1, 100, 200, 60f); 647 displayDeviceInfo.modeId = 1; 648 final Rect zeroRect = new Rect(); 649 displayDeviceInfo.displayCutout = new DisplayCutout( 650 Insets.of(0, 10, 0, 0), 651 zeroRect, new Rect(0, 0, 10, 10), zeroRect, zeroRect); 652 displayDeviceInfo.flags = DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY; 653 displayDeviceInfo.address = new TestUtils.TestDisplayAddress(); 654 displayDevice.setDisplayDeviceInfo(displayDeviceInfo); 655 displayManager.getDisplayDeviceRepository() 656 .onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED); 657 658 // Find the display id of the added FakeDisplayDevice 659 DisplayManagerService.BinderService bs = displayManager.new BinderService(); 660 int displayId = getDisplayIdForDisplayDevice(displayManager, bs, displayDevice); 661 // Setup override DisplayInfo 662 DisplayInfo overrideInfo = bs.getDisplayInfo(displayId); 663 displayManager.setDisplayInfoOverrideFromWindowManagerInternal(displayId, overrideInfo); 664 665 FakeDisplayManagerCallback callback = registerDisplayListenerCallback( 666 displayManager, bs, displayDevice); 667 668 // Simulate DisplayDevice change 669 DisplayDeviceInfo displayDeviceInfo2 = new DisplayDeviceInfo(); 670 displayDeviceInfo2.copyFrom(displayDeviceInfo); 671 displayDeviceInfo2.displayCutout = null; 672 displayDevice.setDisplayDeviceInfo(displayDeviceInfo2); 673 displayManager.getDisplayDeviceRepository() 674 .onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_CHANGED); 675 676 Handler handler = displayManager.getDisplayHandler(); 677 waitForIdleHandler(handler); 678 assertTrue(callback.mDisplayChangedCalled); 679 } 680 681 /** 682 * Tests that we get a Runtime exception when we cannot initialize the default display. 683 */ 684 @Test 685 public void testStartVirtualDisplayWithDefDisplay_NoDefaultDisplay() throws Exception { 686 DisplayManagerService displayManager = 687 new DisplayManagerService(mContext, mShortMockedInjector); 688 Handler handler = displayManager.getDisplayHandler(); 689 waitForIdleHandler(handler); 690 691 try { 692 displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); 693 } catch (RuntimeException e) { 694 return; 695 } 696 fail("Expected DisplayManager to throw RuntimeException when it cannot initialize the" 697 + " default display"); 698 } 699 700 /** 701 * Tests that we get a Runtime exception when we cannot initialize the virtual display. 702 */ 703 @Test 704 public void testStartVirtualDisplayWithDefDisplay_NoVirtualDisplayAdapter() throws Exception { 705 DisplayManagerService displayManager = new DisplayManagerService(mContext, 706 new DisplayManagerService.Injector() { 707 @Override 708 VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, 709 Context context, Handler handler, DisplayAdapter.Listener listener) { 710 return null; // return null for the adapter. This should cause a failure. 711 } 712 713 @Override 714 long getDefaultDisplayDelayTimeout() { 715 return SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS; 716 } 717 }); 718 try { 719 displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); 720 } catch (RuntimeException e) { 721 return; 722 } 723 fail("Expected DisplayManager to throw RuntimeException when it cannot initialize the" 724 + " virtual display adapter"); 725 } 726 727 /** 728 * Tests that an exception is raised for too dark a brightness configuration. 729 */ 730 @Test 731 public void testTooDarkBrightnessConfigurationThrowException() { 732 DisplayManagerService displayManager = 733 new DisplayManagerService(mContext, mShortMockedInjector); 734 Curve minimumBrightnessCurve = displayManager.getMinimumBrightnessCurveInternal(); 735 float[] lux = minimumBrightnessCurve.getX(); 736 float[] minimumNits = minimumBrightnessCurve.getY(); 737 float[] nits = new float[minimumNits.length]; 738 // For every control point, assert that making it slightly lower than the minimum throws an 739 // exception. 740 for (int i = 0; i < nits.length; i++) { 741 for (int j = 0; j < nits.length; j++) { 742 nits[j] = minimumNits[j]; 743 if (j == i) { 744 nits[j] -= 0.1f; 745 } 746 if (nits[j] < 0) { 747 nits[j] = 0; 748 } 749 } 750 BrightnessConfiguration config = 751 new BrightnessConfiguration.Builder(lux, nits).build(); 752 Exception thrown = null; 753 try { 754 displayManager.validateBrightnessConfiguration(config); 755 } catch (IllegalArgumentException e) { 756 thrown = e; 757 } 758 assertNotNull("Building too dark a brightness configuration must throw an exception"); 759 } 760 } 761 762 /** 763 * Tests that no exception is raised for not too dark a brightness configuration. 764 */ 765 @Test 766 public void testBrightEnoughBrightnessConfigurationDoesNotThrowException() { 767 DisplayManagerService displayManager = 768 new DisplayManagerService(mContext, mShortMockedInjector); 769 Curve minimumBrightnessCurve = displayManager.getMinimumBrightnessCurveInternal(); 770 float[] lux = minimumBrightnessCurve.getX(); 771 float[] nits = minimumBrightnessCurve.getY(); 772 BrightnessConfiguration config = new BrightnessConfiguration.Builder(lux, nits).build(); 773 displayManager.validateBrightnessConfiguration(config); 774 } 775 776 /** 777 * Tests that null brightness configurations are alright. 778 */ 779 @Test 780 public void testNullBrightnessConfiguration() { 781 DisplayManagerService displayManager = 782 new DisplayManagerService(mContext, mShortMockedInjector); 783 displayManager.validateBrightnessConfiguration(null); 784 } 785 786 /** 787 * Tests that collection of display color sampling results are sensible. 788 */ 789 @Test 790 public void testDisplayedContentSampling() { 791 DisplayManagerService displayManager = 792 new DisplayManagerService(mContext, mShortMockedInjector); 793 registerDefaultDisplays(displayManager); 794 795 DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(0); 796 assertNotNull(ddi); 797 798 DisplayedContentSamplingAttributes attr = 799 displayManager.getDisplayedContentSamplingAttributesInternal(0); 800 if (attr == null) return; //sampling not supported on device, skip remainder of test. 801 802 boolean enabled = displayManager.setDisplayedContentSamplingEnabledInternal(0, true, 0, 0); 803 assertTrue(enabled); 804 805 displayManager.setDisplayedContentSamplingEnabledInternal(0, false, 0, 0); 806 DisplayedContentSample sample = displayManager.getDisplayedContentSampleInternal(0, 0, 0); 807 assertNotNull(sample); 808 809 long numPixels = ddi.width * ddi.height * sample.getNumFrames(); 810 long[] samples = sample.getSampleComponent(DisplayedContentSample.ColorComponent.CHANNEL0); 811 assertTrue(samples.length == 0 || LongStream.of(samples).sum() == numPixels); 812 813 samples = sample.getSampleComponent(DisplayedContentSample.ColorComponent.CHANNEL1); 814 assertTrue(samples.length == 0 || LongStream.of(samples).sum() == numPixels); 815 816 samples = sample.getSampleComponent(DisplayedContentSample.ColorComponent.CHANNEL2); 817 assertTrue(samples.length == 0 || LongStream.of(samples).sum() == numPixels); 818 819 samples = sample.getSampleComponent(DisplayedContentSample.ColorComponent.CHANNEL3); 820 assertTrue(samples.length == 0 || LongStream.of(samples).sum() == numPixels); 821 } 822 823 /** 824 * Tests that the virtual display is created with 825 * {@link VirtualDisplayConfig.Builder#setDisplayIdToMirror(int)} 826 */ 827 @Test 828 @FlakyTest(bugId = 127687569) 829 public void testCreateVirtualDisplay_displayIdToMirror() throws Exception { 830 DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); 831 registerDefaultDisplays(displayManager); 832 833 // This is effectively the DisplayManager service published to ServiceManager. 834 DisplayManagerService.BinderService binderService = displayManager.new BinderService(); 835 DisplayManagerService.LocalService localDisplayManager = displayManager.new LocalService(); 836 837 final String uniqueId = "uniqueId --- displayIdToMirrorTest"; 838 final int width = 600; 839 final int height = 800; 840 final int dpi = 320; 841 842 when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); 843 final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder( 844 VIRTUAL_DISPLAY_NAME, width, height, dpi); 845 builder.setUniqueId(uniqueId); 846 final int firstDisplayId = binderService.createVirtualDisplay(builder.build(), 847 mMockAppToken /* callback */, null /* projection */, PACKAGE_NAME); 848 verify(mMockProjectionService, never()).setContentRecordingSession(any(), 849 nullable(IMediaProjection.class)); 850 851 // The second virtual display requests to mirror the first virtual display. 852 final String uniqueId2 = "uniqueId --- displayIdToMirrorTest #2"; 853 when(mMockAppToken2.asBinder()).thenReturn(mMockAppToken2); 854 final VirtualDisplayConfig.Builder builder2 = new VirtualDisplayConfig.Builder( 855 VIRTUAL_DISPLAY_NAME, width, height, dpi).setUniqueId(uniqueId2); 856 builder2.setUniqueId(uniqueId2); 857 builder2.setDisplayIdToMirror(firstDisplayId); 858 final int secondDisplayId = binderService.createVirtualDisplay(builder2.build(), 859 mMockAppToken2 /* callback */, null /* projection */, 860 PACKAGE_NAME); 861 verify(mMockProjectionService, never()).setContentRecordingSession(any(), 862 nullable(IMediaProjection.class)); 863 displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class)); 864 865 // flush the handler 866 displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */); 867 868 // The displayId to mirror should be a default display if there is none initially. 869 assertEquals(localDisplayManager.getDisplayIdToMirror(firstDisplayId), 870 Display.DEFAULT_DISPLAY); 871 assertEquals(localDisplayManager.getDisplayIdToMirror(secondDisplayId), 872 firstDisplayId); 873 } 874 875 /** Tests that the virtual device is created in a device display group. */ 876 @Test 877 public void createVirtualDisplay_addsDisplaysToDeviceDisplayGroups() throws Exception { 878 DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); 879 DisplayManagerInternal localService = displayManager.new LocalService(); 880 881 registerDefaultDisplays(displayManager); 882 when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); 883 884 IVirtualDevice virtualDevice = mock(IVirtualDevice.class); 885 when(virtualDevice.getDeviceId()).thenReturn(1); 886 when(mIVirtualDeviceManager.isValidVirtualDeviceId(1)).thenReturn(true); 887 // Create a first virtual display. A display group should be created for this display on the 888 // virtual device. 889 final VirtualDisplayConfig.Builder builder1 = 890 new VirtualDisplayConfig.Builder(VIRTUAL_DISPLAY_NAME, 600, 800, 320) 891 .setUniqueId("uniqueId --- device display group 1"); 892 893 int displayId1 = 894 localService.createVirtualDisplay( 895 builder1.build(), 896 mMockAppToken /* callback */, 897 virtualDevice /* virtualDeviceToken */, 898 mock(DisplayWindowPolicyController.class), 899 PACKAGE_NAME); 900 verify(mMockProjectionService, never()).setContentRecordingSession(any(), 901 nullable(IMediaProjection.class)); 902 int displayGroupId1 = localService.getDisplayInfo(displayId1).displayGroupId; 903 904 // Create a second virtual display. This should be added to the previously created display 905 // group. 906 final VirtualDisplayConfig.Builder builder2 = 907 new VirtualDisplayConfig.Builder(VIRTUAL_DISPLAY_NAME, 600, 800, 320) 908 .setUniqueId("uniqueId --- device display group 1"); 909 910 int displayId2 = 911 localService.createVirtualDisplay( 912 builder2.build(), 913 mMockAppToken /* callback */, 914 virtualDevice /* virtualDeviceToken */, 915 mock(DisplayWindowPolicyController.class), 916 PACKAGE_NAME); 917 verify(mMockProjectionService, never()).setContentRecordingSession(any(), 918 nullable(IMediaProjection.class)); 919 int displayGroupId2 = localService.getDisplayInfo(displayId2).displayGroupId; 920 921 assertEquals( 922 "Both displays should be added to the same displayGroup.", 923 displayGroupId1, 924 displayGroupId2); 925 } 926 927 /** 928 * Tests that the virtual display is not added to the device display group when 929 * VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP is set. 930 */ 931 @Test 932 public void createVirtualDisplay_addsDisplaysToOwnDisplayGroups() throws Exception { 933 DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); 934 DisplayManagerInternal localService = displayManager.new LocalService(); 935 936 registerDefaultDisplays(displayManager); 937 when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); 938 939 IVirtualDevice virtualDevice = mock(IVirtualDevice.class); 940 when(virtualDevice.getDeviceId()).thenReturn(1); 941 when(mIVirtualDeviceManager.isValidVirtualDeviceId(1)).thenReturn(true); 942 943 // Create a first virtual display. A display group should be created for this display on the 944 // virtual device. 945 final VirtualDisplayConfig.Builder builder1 = 946 new VirtualDisplayConfig.Builder(VIRTUAL_DISPLAY_NAME, 600, 800, 320) 947 .setUniqueId("uniqueId --- device display group"); 948 949 int displayId1 = 950 localService.createVirtualDisplay( 951 builder1.build(), 952 mMockAppToken /* callback */, 953 virtualDevice /* virtualDeviceToken */, 954 mock(DisplayWindowPolicyController.class), 955 PACKAGE_NAME); 956 verify(mMockProjectionService, never()).setContentRecordingSession(any(), 957 nullable(IMediaProjection.class)); 958 int displayGroupId1 = localService.getDisplayInfo(displayId1).displayGroupId; 959 960 // Create a second virtual display. With the flag VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP, 961 // the display should not be added to the previously created display group. 962 final VirtualDisplayConfig.Builder builder2 = 963 new VirtualDisplayConfig.Builder(VIRTUAL_DISPLAY_NAME, 600, 800, 320) 964 .setFlags(VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP) 965 .setUniqueId("uniqueId --- own display group"); 966 967 when(mIVirtualDeviceManager.isValidVirtualDeviceId(1)).thenReturn(true); 968 969 int displayId2 = 970 localService.createVirtualDisplay( 971 builder2.build(), 972 mMockAppToken /* callback */, 973 virtualDevice /* virtualDeviceToken */, 974 mock(DisplayWindowPolicyController.class), 975 PACKAGE_NAME); 976 verify(mMockProjectionService, never()).setContentRecordingSession(any(), 977 nullable(IMediaProjection.class)); 978 int displayGroupId2 = localService.getDisplayInfo(displayId2).displayGroupId; 979 980 assertNotEquals( 981 "Display 1 should be in the device display group and display 2 in its own display" 982 + " group.", 983 displayGroupId1, 984 displayGroupId2); 985 } 986 987 @Test 988 public void displaysInDeviceOrOwnDisplayGroupShouldPreserveAlwaysUnlockedFlag() 989 throws Exception { 990 DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); 991 DisplayManagerInternal localService = displayManager.new LocalService(); 992 993 registerDefaultDisplays(displayManager); 994 when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); 995 996 IVirtualDevice virtualDevice = mock(IVirtualDevice.class); 997 when(virtualDevice.getDeviceId()).thenReturn(1); 998 when(mIVirtualDeviceManager.isValidVirtualDeviceId(1)).thenReturn(true); 999 1000 // Allow an ALWAYS_UNLOCKED display to be created. 1001 when(mContext.checkCallingPermission(ADD_TRUSTED_DISPLAY)) 1002 .thenReturn(PackageManager.PERMISSION_GRANTED); 1003 1004 when(mContext.checkCallingPermission(ADD_ALWAYS_UNLOCKED_DISPLAY)) 1005 .thenReturn(PackageManager.PERMISSION_GRANTED); 1006 1007 // Create a virtual display in a device display group. 1008 final VirtualDisplayConfig deviceDisplayGroupDisplayConfig = 1009 new VirtualDisplayConfig.Builder(VIRTUAL_DISPLAY_NAME, 600, 800, 320) 1010 .setUniqueId("uniqueId --- device display group 1") 1011 .setFlags(VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED) 1012 .build(); 1013 1014 int deviceDisplayGroupDisplayId = 1015 localService.createVirtualDisplay( 1016 deviceDisplayGroupDisplayConfig, 1017 mMockAppToken /* callback */, 1018 virtualDevice /* virtualDeviceToken */, 1019 mock(DisplayWindowPolicyController.class), 1020 PACKAGE_NAME); 1021 verify(mMockProjectionService, never()).setContentRecordingSession(any(), 1022 nullable(IMediaProjection.class)); 1023 1024 // Check that FLAG_ALWAYS_UNLOCKED is set. 1025 assertNotEquals( 1026 "FLAG_ALWAYS_UNLOCKED should be set for displays created in a device display" 1027 + " group.", 1028 (displayManager.getDisplayDeviceInfoInternal(deviceDisplayGroupDisplayId).flags 1029 & DisplayDeviceInfo.FLAG_ALWAYS_UNLOCKED), 1030 0); 1031 1032 // Create a virtual display in its own display group. 1033 final VirtualDisplayConfig ownDisplayGroupConfig = 1034 new VirtualDisplayConfig.Builder(VIRTUAL_DISPLAY_NAME, 600, 800, 320) 1035 .setUniqueId("uniqueId --- own display group 1") 1036 .setFlags( 1037 VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED 1038 | VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP) 1039 .build(); 1040 1041 int ownDisplayGroupDisplayId = 1042 localService.createVirtualDisplay( 1043 ownDisplayGroupConfig, 1044 mMockAppToken /* callback */, 1045 virtualDevice /* virtualDeviceToken */, 1046 mock(DisplayWindowPolicyController.class), 1047 PACKAGE_NAME); 1048 verify(mMockProjectionService, never()).setContentRecordingSession(any(), 1049 nullable(IMediaProjection.class)); 1050 1051 // Check that FLAG_ALWAYS_UNLOCKED is set. 1052 assertNotEquals( 1053 "FLAG_ALWAYS_UNLOCKED should be set for displays created in their own display" 1054 + " group.", 1055 (displayManager.getDisplayDeviceInfoInternal(ownDisplayGroupDisplayId).flags 1056 & DisplayDeviceInfo.FLAG_ALWAYS_UNLOCKED), 1057 0); 1058 1059 // Create a virtual display in a device display group. 1060 final VirtualDisplayConfig defaultDisplayGroupConfig = 1061 new VirtualDisplayConfig.Builder(VIRTUAL_DISPLAY_NAME, 600, 800, 320) 1062 .setUniqueId("uniqueId --- default display group 1") 1063 .setFlags(VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED) 1064 .build(); 1065 1066 int defaultDisplayGroupDisplayId = 1067 localService.createVirtualDisplay( 1068 defaultDisplayGroupConfig, 1069 mMockAppToken /* callback */, 1070 null /* virtualDeviceToken */, 1071 mock(DisplayWindowPolicyController.class), 1072 PACKAGE_NAME); 1073 verify(mMockProjectionService, never()).setContentRecordingSession(any(), 1074 nullable(IMediaProjection.class)); 1075 1076 // Check that FLAG_ALWAYS_UNLOCKED is not set. 1077 assertEquals( 1078 "FLAG_ALWAYS_UNLOCKED should not be set for displays created in the default" 1079 + " display group.", 1080 (displayManager.getDisplayDeviceInfoInternal(defaultDisplayGroupDisplayId).flags 1081 & DisplayDeviceInfo.FLAG_ALWAYS_UNLOCKED), 1082 0); 1083 } 1084 1085 @Test 1086 public void testGetDisplayIdToMirror() throws Exception { 1087 DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); 1088 registerDefaultDisplays(displayManager); 1089 1090 // This is effectively the DisplayManager service published to ServiceManager. 1091 DisplayManagerService.BinderService binderService = displayManager.new BinderService(); 1092 DisplayManagerService.LocalService localDisplayManager = displayManager.new LocalService(); 1093 1094 final String uniqueId = "uniqueId --- displayIdToMirrorTest"; 1095 final int width = 600; 1096 final int height = 800; 1097 final int dpi = 320; 1098 1099 when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); 1100 final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder( 1101 VIRTUAL_DISPLAY_NAME, width, height, dpi) 1102 .setUniqueId(uniqueId) 1103 .setFlags(VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY); 1104 final int firstDisplayId = binderService.createVirtualDisplay(builder.build(), 1105 mMockAppToken /* callback */, null /* projection */, PACKAGE_NAME); 1106 verify(mMockProjectionService, never()).setContentRecordingSession(any(), 1107 nullable(IMediaProjection.class)); 1108 1109 // The second virtual display requests to mirror the first virtual display. 1110 final String uniqueId2 = "uniqueId --- displayIdToMirrorTest #2"; 1111 when(mMockAppToken2.asBinder()).thenReturn(mMockAppToken2); 1112 final VirtualDisplayConfig.Builder builder2 = new VirtualDisplayConfig.Builder( 1113 VIRTUAL_DISPLAY_NAME, width, height, dpi) 1114 .setUniqueId(uniqueId2) 1115 .setWindowManagerMirroringEnabled(true); 1116 final int secondDisplayId = binderService.createVirtualDisplay(builder2.build(), 1117 mMockAppToken2 /* callback */, null /* projection */, 1118 PACKAGE_NAME); 1119 verify(mMockProjectionService, never()).setContentRecordingSession(any(), 1120 nullable(IMediaProjection.class)); 1121 displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class)); 1122 1123 // flush the handler 1124 displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */); 1125 1126 // The displayId to mirror should be a invalid since the display had flag OWN_CONTENT_ONLY 1127 assertEquals(localDisplayManager.getDisplayIdToMirror(firstDisplayId), 1128 Display.INVALID_DISPLAY); 1129 // The second display has mirroring managed by WindowManager so the mirror displayId should 1130 // be invalid. 1131 assertEquals(localDisplayManager.getDisplayIdToMirror(secondDisplayId), 1132 Display.INVALID_DISPLAY); 1133 } 1134 1135 @Test 1136 public void testCreateVirtualDisplay_isValidProjection_notValid() 1137 throws RemoteException { 1138 when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); 1139 IMediaProjection projection = mock(IMediaProjection.class); 1140 doReturn(false).when(projection).isValid(); 1141 when(mMockProjectionService 1142 .setContentRecordingSession(any(ContentRecordingSession.class), eq(projection))) 1143 .thenReturn(true); 1144 doReturn(true).when(mMockProjectionService).isCurrentProjection(eq(projection)); 1145 1146 final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder( 1147 VIRTUAL_DISPLAY_NAME, 600, 800, 320); 1148 builder.setUniqueId("uniqueId --- isValid false"); 1149 1150 DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); 1151 registerDefaultDisplays(displayManager); 1152 displayManager.windowManagerAndInputReady(); 1153 1154 // Pass in a non-null projection. 1155 DisplayManagerService.BinderService binderService = displayManager.new BinderService(); 1156 final int displayId = binderService.createVirtualDisplay(builder.build(), 1157 mMockAppToken /* callback */, projection, PACKAGE_NAME); 1158 1159 // VirtualDisplay is created for mirroring. 1160 assertThat(displayId).isNotEqualTo(Display.INVALID_DISPLAY); 1161 verify(mMockProjectionService, atLeastOnce()).setContentRecordingSession( 1162 any(ContentRecordingSession.class), nullable(IMediaProjection.class)); 1163 // But mirroring doesn't begin. 1164 verify(mMockProjectionService, atLeastOnce()).setContentRecordingSession( 1165 mContentRecordingSessionCaptor.capture(), nullable(IMediaProjection.class)); 1166 ContentRecordingSession session = mContentRecordingSessionCaptor.getValue(); 1167 assertThat(session.isWaitingForConsent()).isTrue(); 1168 } 1169 1170 @Test 1171 public void testCreateVirtualDisplay_setContentRecordingSessionSuccess() 1172 throws RemoteException { 1173 final int displayToRecord = 50; 1174 when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); 1175 IMediaProjection projection = mock(IMediaProjection.class); 1176 doReturn(true).when(projection).isValid(); 1177 when(mMockProjectionService 1178 .setContentRecordingSession(any(ContentRecordingSession.class), eq(projection))) 1179 .thenReturn(true); 1180 doReturn(true).when(mMockProjectionService).isCurrentProjection(eq(projection)); 1181 1182 final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder( 1183 VIRTUAL_DISPLAY_NAME, 600, 800, 320); 1184 builder.setUniqueId("uniqueId --- setContentRecordingSession true"); 1185 builder.setDisplayIdToMirror(displayToRecord); 1186 1187 DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); 1188 registerDefaultDisplays(displayManager); 1189 displayManager.windowManagerAndInputReady(); 1190 1191 DisplayManagerService.BinderService binderService = displayManager.new BinderService(); 1192 final int displayId = binderService.createVirtualDisplay(builder.build(), 1193 mMockAppToken /* callback */, projection, PACKAGE_NAME); 1194 1195 assertThat(displayId).isNotEqualTo(Display.INVALID_DISPLAY); 1196 verify(mMockProjectionService, atLeastOnce()).setContentRecordingSession( 1197 mContentRecordingSessionCaptor.capture(), nullable(IMediaProjection.class)); 1198 ContentRecordingSession session = mContentRecordingSessionCaptor.getValue(); 1199 assertThat(session.getContentToRecord()).isEqualTo(RECORD_CONTENT_DISPLAY); 1200 assertThat(session.getVirtualDisplayId()).isEqualTo(displayId); 1201 assertThat(session.getDisplayToRecord()).isEqualTo(displayToRecord); 1202 assertThat(session.isWaitingForConsent()).isFalse(); 1203 } 1204 1205 @Test 1206 public void testCreateVirtualDisplay_setContentRecordingSessionFail() throws RemoteException { 1207 when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); 1208 IMediaProjection projection = mock(IMediaProjection.class); 1209 doReturn(true).when(projection).isValid(); 1210 when(mMockProjectionService 1211 .setContentRecordingSession(any(ContentRecordingSession.class), eq(projection))) 1212 .thenReturn(false); 1213 doReturn(true).when(mMockProjectionService).isCurrentProjection(eq(projection)); 1214 1215 final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder( 1216 VIRTUAL_DISPLAY_NAME, 600, 800, 320); 1217 builder.setUniqueId("uniqueId --- setContentRecordingSession false"); 1218 1219 DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); 1220 registerDefaultDisplays(displayManager); 1221 displayManager.windowManagerAndInputReady(); 1222 1223 DisplayManagerService.BinderService binderService = displayManager.new BinderService(); 1224 final int displayId = binderService.createVirtualDisplay(builder.build(), 1225 mMockAppToken /* callback */, projection, PACKAGE_NAME); 1226 1227 assertThat(displayId).isEqualTo(Display.INVALID_DISPLAY); 1228 } 1229 1230 @Test 1231 public void testCreateVirtualDisplay_setContentRecordingSession_taskSession() 1232 throws RemoteException { 1233 final int displayToRecord = 50; 1234 when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); 1235 IMediaProjection projection = mock(IMediaProjection.class); 1236 doReturn(true).when(projection).isValid(); 1237 when(mMockProjectionService 1238 .setContentRecordingSession(any(ContentRecordingSession.class), eq(projection))) 1239 .thenReturn(true); 1240 doReturn(mock(IBinder.class)).when(projection).getLaunchCookie(); 1241 doReturn(true).when(mMockProjectionService).isCurrentProjection(eq(projection)); 1242 1243 final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder( 1244 VIRTUAL_DISPLAY_NAME, 600, 800, 320); 1245 builder.setUniqueId("uniqueId --- setContentRecordingSession false"); 1246 builder.setDisplayIdToMirror(displayToRecord); 1247 1248 DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); 1249 registerDefaultDisplays(displayManager); 1250 displayManager.windowManagerAndInputReady(); 1251 1252 DisplayManagerService.BinderService binderService = displayManager.new BinderService(); 1253 final int displayId = binderService.createVirtualDisplay(builder.build(), 1254 mMockAppToken /* callback */, projection, PACKAGE_NAME); 1255 1256 assertThat(displayId).isNotEqualTo(Display.INVALID_DISPLAY); 1257 verify(mMockProjectionService, atLeastOnce()).setContentRecordingSession( 1258 mContentRecordingSessionCaptor.capture(), nullable(IMediaProjection.class)); 1259 ContentRecordingSession session = mContentRecordingSessionCaptor.getValue(); 1260 assertThat(session.getContentToRecord()).isEqualTo(RECORD_CONTENT_TASK); 1261 assertThat(session.getVirtualDisplayId()).isEqualTo(displayId); 1262 assertThat(session.getTokenToRecord()).isNotNull(); 1263 } 1264 1265 @Test 1266 public void testCreateVirtualDisplay_setContentRecordingSession_noProjection_noFlags() 1267 throws RemoteException { 1268 when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); 1269 1270 // Set no flags for the VirtualDisplay. 1271 final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder( 1272 VIRTUAL_DISPLAY_NAME, 600, 800, 320); 1273 builder.setUniqueId("uniqueId --- setContentRecordingSession false"); 1274 1275 DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); 1276 registerDefaultDisplays(displayManager); 1277 displayManager.windowManagerAndInputReady(); 1278 1279 // Pass in a null projection. 1280 DisplayManagerService.BinderService binderService = displayManager.new BinderService(); 1281 final int displayId = binderService.createVirtualDisplay(builder.build(), 1282 mMockAppToken /* callback */, null /* projection */, PACKAGE_NAME); 1283 1284 // VirtualDisplay is created but not for mirroring. 1285 assertThat(displayId).isNotEqualTo(Display.INVALID_DISPLAY); 1286 verify(mMockProjectionService, never()).setContentRecordingSession( 1287 any(ContentRecordingSession.class), nullable(IMediaProjection.class)); 1288 } 1289 1290 @Test 1291 public void testCreateVirtualDisplay_setContentRecordingSession_noProjection_noMirroringFlag() 1292 throws RemoteException { 1293 when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); 1294 1295 // Set a non-mirroring flag for the VirtualDisplay. 1296 final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder( 1297 VIRTUAL_DISPLAY_NAME, 600, 800, 320); 1298 builder.setUniqueId("uniqueId --- setContentRecordingSession false"); 1299 builder.setFlags(VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY); 1300 1301 DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); 1302 registerDefaultDisplays(displayManager); 1303 displayManager.windowManagerAndInputReady(); 1304 1305 // Pass in a null projection. 1306 DisplayManagerService.BinderService binderService = displayManager.new BinderService(); 1307 final int displayId = binderService.createVirtualDisplay(builder.build(), 1308 mMockAppToken /* callback */, null /* projection */, PACKAGE_NAME); 1309 1310 // VirtualDisplay is created but not for mirroring. 1311 assertThat(displayId).isNotEqualTo(Display.INVALID_DISPLAY); 1312 verify(mMockProjectionService, never()).setContentRecordingSession( 1313 any(ContentRecordingSession.class), nullable(IMediaProjection.class)); 1314 } 1315 1316 @Test 1317 public void testCreateVirtualDisplay_setContentRecordingSession_projection_noMirroringFlag() 1318 throws RemoteException { 1319 when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); 1320 IMediaProjection projection = mock(IMediaProjection.class); 1321 doReturn(true).when(projection).isValid(); 1322 when(mMockProjectionService 1323 .setContentRecordingSession(any(ContentRecordingSession.class), eq(projection))) 1324 .thenReturn(true); 1325 doReturn(true).when(mMockProjectionService).isCurrentProjection(eq(projection)); 1326 1327 // Set no flags for the VirtualDisplay. 1328 final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder( 1329 VIRTUAL_DISPLAY_NAME, 600, 800, 320); 1330 builder.setUniqueId("uniqueId --- setContentRecordingSession false"); 1331 1332 DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); 1333 registerDefaultDisplays(displayManager); 1334 displayManager.windowManagerAndInputReady(); 1335 1336 // Pass in a non-null projection. 1337 DisplayManagerService.BinderService binderService = displayManager.new BinderService(); 1338 final int displayId = binderService.createVirtualDisplay(builder.build(), 1339 mMockAppToken /* callback */, projection, PACKAGE_NAME); 1340 1341 // VirtualDisplay is created for mirroring. 1342 assertThat(displayId).isNotEqualTo(Display.INVALID_DISPLAY); 1343 verify(mMockProjectionService, atLeastOnce()).setContentRecordingSession( 1344 any(ContentRecordingSession.class), nullable(IMediaProjection.class)); 1345 } 1346 1347 /** 1348 * Tests that the virtual display is created with 1349 * {@link VirtualDisplayConfig.Builder#setSurface(Surface)} 1350 */ 1351 @Test 1352 @FlakyTest(bugId = 127687569) 1353 public void testCreateVirtualDisplay_setSurface() throws Exception { 1354 DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); 1355 registerDefaultDisplays(displayManager); 1356 1357 // This is effectively the DisplayManager service published to ServiceManager. 1358 DisplayManagerService.BinderService binderService = displayManager.new BinderService(); 1359 1360 final String uniqueId = "uniqueId --- setSurface"; 1361 final int width = 600; 1362 final int height = 800; 1363 final int dpi = 320; 1364 final Surface surface = new Surface(); 1365 1366 when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); 1367 final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder( 1368 VIRTUAL_DISPLAY_NAME, width, height, dpi); 1369 builder.setSurface(surface); 1370 builder.setUniqueId(uniqueId); 1371 final int displayId = binderService.createVirtualDisplay(builder.build(), 1372 mMockAppToken /* callback */, null /* projection */, PACKAGE_NAME); 1373 verify(mMockProjectionService, never()).setContentRecordingSession(any(), 1374 nullable(IMediaProjection.class)); 1375 1376 displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class)); 1377 1378 // flush the handler 1379 displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */); 1380 1381 assertEquals(displayManager.getVirtualDisplaySurfaceInternal(mMockAppToken), surface); 1382 } 1383 1384 /** 1385 * Tests that specifying VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP is allowed when the permission 1386 * ADD_TRUSTED_DISPLAY is granted. 1387 */ 1388 @Test 1389 public void testOwnDisplayGroup_allowCreationWithAddTrustedDisplayPermission() 1390 throws RemoteException { 1391 DisplayManagerService displayManager = 1392 new DisplayManagerService(mContext, mBasicInjector); 1393 registerDefaultDisplays(displayManager); 1394 1395 DisplayManagerService.BinderService bs = displayManager.new BinderService(); 1396 when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); 1397 1398 when(mContext.checkCallingPermission(ADD_TRUSTED_DISPLAY)).thenReturn( 1399 PackageManager.PERMISSION_GRANTED); 1400 1401 final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder( 1402 VIRTUAL_DISPLAY_NAME, 600, 800, 320); 1403 builder.setFlags(DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP); 1404 builder.setUniqueId("uniqueId --- OWN_DISPLAY_GROUP"); 1405 1406 int displayId = bs.createVirtualDisplay(builder.build(), mMockAppToken /* callback */, 1407 null /* projection */, PACKAGE_NAME); 1408 verify(mMockProjectionService, never()).setContentRecordingSession(any(), 1409 nullable(IMediaProjection.class)); 1410 displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class)); 1411 displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */); 1412 DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayId); 1413 assertNotNull(ddi); 1414 assertNotEquals(0, ddi.flags & DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP); 1415 } 1416 1417 /** 1418 * Tests that specifying VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP is blocked when the permission 1419 * ADD_TRUSTED_DISPLAY is denied. 1420 */ 1421 @Test 1422 public void testOwnDisplayGroup_withoutAddTrustedDisplayPermission_throwsSecurityException() { 1423 DisplayManagerService displayManager = 1424 new DisplayManagerService(mContext, mBasicInjector); 1425 registerDefaultDisplays(displayManager); 1426 1427 DisplayManagerService.BinderService bs = displayManager.new BinderService(); 1428 when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); 1429 1430 when(mContext.checkCallingPermission(ADD_TRUSTED_DISPLAY)).thenReturn( 1431 PackageManager.PERMISSION_DENIED); 1432 1433 final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder( 1434 VIRTUAL_DISPLAY_NAME, 600, 800, 320); 1435 builder.setFlags(DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP); 1436 builder.setUniqueId("uniqueId --- OWN_DISPLAY_GROUP"); 1437 1438 try { 1439 bs.createVirtualDisplay(builder.build(), mMockAppToken /* callback */, 1440 null /* projection */, PACKAGE_NAME); 1441 fail("Creating virtual display with VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP without " 1442 + "ADD_TRUSTED_DISPLAY permission should throw SecurityException."); 1443 } catch (SecurityException e) { 1444 // SecurityException is expected 1445 } 1446 } 1447 1448 /** 1449 * Tests that specifying VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP is allowed when called with 1450 * a virtual device, even if ADD_TRUSTED_DISPLAY is not granted. 1451 */ 1452 @Test 1453 public void testOwnDisplayGroup_allowCreationWithVirtualDevice() throws Exception { 1454 DisplayManagerService displayManager = 1455 new DisplayManagerService(mContext, mBasicInjector); 1456 DisplayManagerInternal localService = displayManager.new LocalService(); 1457 1458 registerDefaultDisplays(displayManager); 1459 1460 when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); 1461 1462 when(mContext.checkCallingPermission(ADD_TRUSTED_DISPLAY)).thenReturn( 1463 PackageManager.PERMISSION_DENIED); 1464 1465 final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder( 1466 VIRTUAL_DISPLAY_NAME, 600, 800, 320); 1467 builder.setFlags(DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP); 1468 builder.setUniqueId("uniqueId --- OWN_DISPLAY_GROUP"); 1469 1470 IVirtualDevice virtualDevice = mock(IVirtualDevice.class); 1471 when(virtualDevice.getDeviceId()).thenReturn(1); 1472 when(mIVirtualDeviceManager.isValidVirtualDeviceId(1)).thenReturn(true); 1473 1474 int displayId = localService.createVirtualDisplay(builder.build(), 1475 mMockAppToken /* callback */, virtualDevice /* virtualDeviceToken */, 1476 mock(DisplayWindowPolicyController.class), PACKAGE_NAME); 1477 verify(mMockProjectionService, never()).setContentRecordingSession(any(), 1478 nullable(IMediaProjection.class)); 1479 displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class)); 1480 displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */); 1481 DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayId); 1482 assertNotNull(ddi); 1483 assertNotEquals(0, ddi.flags & DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP); 1484 } 1485 1486 /** 1487 * Tests that there is a display change notification if the frame rate override 1488 * list is updated. 1489 */ 1490 @Test 1491 public void testShouldNotifyChangeWhenDisplayInfoFrameRateOverrideChanged() throws Exception { 1492 DisplayManagerService displayManager = 1493 new DisplayManagerService(mContext, mShortMockedInjector); 1494 DisplayManagerService.BinderService displayManagerBinderService = 1495 displayManager.new BinderService(); 1496 registerDefaultDisplays(displayManager); 1497 displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); 1498 1499 FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, new float[]{60f}); 1500 FakeDisplayManagerCallback callback = registerDisplayListenerCallback(displayManager, 1501 displayManagerBinderService, displayDevice); 1502 1503 int myUid = Process.myUid(); 1504 updateFrameRateOverride(displayManager, displayDevice, 1505 new DisplayEventReceiver.FrameRateOverride[]{ 1506 new DisplayEventReceiver.FrameRateOverride(myUid, 30f), 1507 }); 1508 assertTrue(callback.mDisplayChangedCalled); 1509 callback.clear(); 1510 1511 updateFrameRateOverride(displayManager, displayDevice, 1512 new DisplayEventReceiver.FrameRateOverride[]{ 1513 new DisplayEventReceiver.FrameRateOverride(myUid, 30f), 1514 new DisplayEventReceiver.FrameRateOverride(1234, 30f), 1515 }); 1516 assertFalse(callback.mDisplayChangedCalled); 1517 1518 updateFrameRateOverride(displayManager, displayDevice, 1519 new DisplayEventReceiver.FrameRateOverride[]{ 1520 new DisplayEventReceiver.FrameRateOverride(myUid, 20f), 1521 new DisplayEventReceiver.FrameRateOverride(1234, 30f), 1522 new DisplayEventReceiver.FrameRateOverride(5678, 30f), 1523 }); 1524 assertTrue(callback.mDisplayChangedCalled); 1525 callback.clear(); 1526 1527 updateFrameRateOverride(displayManager, displayDevice, 1528 new DisplayEventReceiver.FrameRateOverride[]{ 1529 new DisplayEventReceiver.FrameRateOverride(1234, 30f), 1530 new DisplayEventReceiver.FrameRateOverride(5678, 30f), 1531 }); 1532 assertTrue(callback.mDisplayChangedCalled); 1533 callback.clear(); 1534 1535 updateFrameRateOverride(displayManager, displayDevice, 1536 new DisplayEventReceiver.FrameRateOverride[]{ 1537 new DisplayEventReceiver.FrameRateOverride(5678, 30f), 1538 }); 1539 assertFalse(callback.mDisplayChangedCalled); 1540 } 1541 1542 /** 1543 * Tests that the DisplayInfo is updated correctly with a frame rate override 1544 */ 1545 @Test 1546 public void testDisplayInfoFrameRateOverride() throws Exception { 1547 DisplayManagerService displayManager = 1548 new DisplayManagerService(mContext, mShortMockedInjector); 1549 DisplayManagerService.BinderService displayManagerBinderService = 1550 displayManager.new BinderService(); 1551 registerDefaultDisplays(displayManager); 1552 displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); 1553 1554 FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, 1555 new float[]{60f, 30f, 20f}); 1556 int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService, 1557 displayDevice); 1558 DisplayInfo displayInfo = displayManagerBinderService.getDisplayInfo(displayId); 1559 assertEquals(60f, displayInfo.getRefreshRate(), 0.01f); 1560 1561 updateFrameRateOverride(displayManager, displayDevice, 1562 new DisplayEventReceiver.FrameRateOverride[]{ 1563 new DisplayEventReceiver.FrameRateOverride( 1564 Process.myUid(), 20f), 1565 new DisplayEventReceiver.FrameRateOverride( 1566 Process.myUid() + 1, 30f) 1567 }); 1568 displayInfo = displayManagerBinderService.getDisplayInfo(displayId); 1569 assertEquals(20f, displayInfo.getRefreshRate(), 0.01f); 1570 1571 // Changing the mode to 30Hz should not override the refresh rate to 20Hz anymore 1572 // as 20 is not a divider of 30. 1573 updateModeId(displayManager, displayDevice, 2); 1574 displayInfo = displayManagerBinderService.getDisplayInfo(displayId); 1575 assertEquals(30f, displayInfo.getRefreshRate(), 0.01f); 1576 } 1577 1578 /** 1579 * Tests that the frame rate override is returning the correct value from 1580 * DisplayInfo#getRefreshRate 1581 */ 1582 @Test 1583 public void testDisplayInfoNonNativeFrameRateOverride() throws Exception { 1584 DisplayManagerService displayManager = 1585 new DisplayManagerService(mContext, mBasicInjector); 1586 DisplayManagerService.BinderService displayManagerBinderService = 1587 displayManager.new BinderService(); 1588 registerDefaultDisplays(displayManager); 1589 displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); 1590 1591 FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, 1592 new float[]{60f}); 1593 int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService, 1594 displayDevice); 1595 DisplayInfo displayInfo = displayManagerBinderService.getDisplayInfo(displayId); 1596 assertEquals(60f, displayInfo.getRefreshRate(), 0.01f); 1597 1598 updateFrameRateOverride(displayManager, displayDevice, 1599 new DisplayEventReceiver.FrameRateOverride[]{ 1600 new DisplayEventReceiver.FrameRateOverride( 1601 Process.myUid(), 20f) 1602 }); 1603 displayInfo = displayManagerBinderService.getDisplayInfo(displayId); 1604 assertEquals(20f, displayInfo.getRefreshRate(), 0.01f); 1605 } 1606 1607 /** 1608 * Tests that the mode reflects the frame rate override is in compat mode 1609 */ 1610 @Test 1611 @DisableCompatChanges({DisplayManagerService.DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE}) 1612 public void testDisplayInfoFrameRateOverrideModeCompat() throws Exception { 1613 testDisplayInfoFrameRateOverrideModeCompat(/*compatChangeEnabled*/ false); 1614 } 1615 1616 /** 1617 * Tests that the mode reflects the physical display refresh rate when not in compat mode. 1618 */ 1619 @Test 1620 @EnableCompatChanges({DisplayManagerService.DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE}) 1621 public void testDisplayInfoFrameRateOverrideMode() throws Exception { 1622 testDisplayInfoFrameRateOverrideModeCompat(/*compatChangeEnabled*/ true); 1623 } 1624 1625 /** 1626 * Tests that the mode reflects the frame rate override is in compat mode and accordingly to the 1627 * allowNonNativeRefreshRateOverride policy. 1628 */ 1629 @Test 1630 @DisableCompatChanges({DisplayManagerService.DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE}) 1631 public void testDisplayInfoNonNativeFrameRateOverrideModeCompat() throws Exception { 1632 testDisplayInfoNonNativeFrameRateOverrideMode(/*compatChangeEnabled*/ false); 1633 } 1634 1635 /** 1636 * Tests that the mode reflects the physical display refresh rate when not in compat mode. 1637 */ 1638 @Test 1639 @EnableCompatChanges({DisplayManagerService.DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE}) 1640 public void testDisplayInfoNonNativeFrameRateOverrideMode() throws Exception { 1641 testDisplayInfoNonNativeFrameRateOverrideMode(/*compatChangeEnabled*/ true); 1642 } 1643 1644 /** 1645 * Tests that there is a display change notification if the render frame rate is updated 1646 */ 1647 @Test 1648 public void testShouldNotifyChangeWhenDisplayInfoRenderFrameRateChanged() throws Exception { 1649 DisplayManagerService displayManager = 1650 new DisplayManagerService(mContext, mShortMockedInjector); 1651 DisplayManagerService.BinderService displayManagerBinderService = 1652 displayManager.new BinderService(); 1653 registerDefaultDisplays(displayManager); 1654 displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); 1655 1656 FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, new float[]{60f}); 1657 FakeDisplayManagerCallback callback = registerDisplayListenerCallback(displayManager, 1658 displayManagerBinderService, displayDevice); 1659 1660 updateRenderFrameRate(displayManager, displayDevice, 30f); 1661 assertTrue(callback.mDisplayChangedCalled); 1662 callback.clear(); 1663 1664 updateRenderFrameRate(displayManager, displayDevice, 30f); 1665 assertFalse(callback.mDisplayChangedCalled); 1666 1667 updateRenderFrameRate(displayManager, displayDevice, 20f); 1668 assertTrue(callback.mDisplayChangedCalled); 1669 callback.clear(); 1670 } 1671 1672 /** 1673 * Tests that the DisplayInfo is updated correctly with a render frame rate 1674 */ 1675 @Test 1676 public void testDisplayInfoRenderFrameRate() throws Exception { 1677 DisplayManagerService displayManager = 1678 new DisplayManagerService(mContext, mShortMockedInjector); 1679 DisplayManagerService.BinderService displayManagerBinderService = 1680 displayManager.new BinderService(); 1681 registerDefaultDisplays(displayManager); 1682 displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); 1683 1684 FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, 1685 new float[]{60f, 30f, 20f}); 1686 int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService, 1687 displayDevice); 1688 DisplayInfo displayInfo = displayManagerBinderService.getDisplayInfo(displayId); 1689 assertEquals(60f, displayInfo.getRefreshRate(), 0.01f); 1690 1691 updateRenderFrameRate(displayManager, displayDevice, 20f); 1692 displayInfo = displayManagerBinderService.getDisplayInfo(displayId); 1693 assertEquals(20f, displayInfo.getRefreshRate(), 0.01f); 1694 } 1695 1696 /** 1697 * Tests that the mode reflects the render frame rate is in compat mode 1698 */ 1699 @Test 1700 @DisableCompatChanges({DisplayManagerService.DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE}) 1701 public void testDisplayInfoRenderFrameRateModeCompat() throws Exception { 1702 testDisplayInfoRenderFrameRateModeCompat(/*compatChangeEnabled*/ false); 1703 } 1704 1705 /** 1706 * Tests that the mode reflects the physical display refresh rate when not in compat mode. 1707 */ 1708 @Test 1709 @EnableCompatChanges({DisplayManagerService.DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE}) 1710 public void testDisplayInfoRenderFrameRateMode() throws Exception { 1711 testDisplayInfoRenderFrameRateModeCompat(/*compatChangeEnabled*/ true); 1712 } 1713 1714 /** 1715 * Tests that EVENT_DISPLAY_ADDED is sent when a display is added. 1716 */ 1717 @Test 1718 public void testShouldNotifyDisplayAdded_WhenNewDisplayDeviceIsAdded() { 1719 DisplayManagerService displayManager = 1720 new DisplayManagerService(mContext, mShortMockedInjector); 1721 DisplayManagerService.BinderService displayManagerBinderService = 1722 displayManager.new BinderService(); 1723 1724 Handler handler = displayManager.getDisplayHandler(); 1725 waitForIdleHandler(handler); 1726 1727 // register display listener callback 1728 FakeDisplayManagerCallback callback = new FakeDisplayManagerCallback(); 1729 displayManagerBinderService.registerCallbackWithEventMask( 1730 callback, STANDARD_DISPLAY_EVENTS); 1731 1732 waitForIdleHandler(handler); 1733 1734 createFakeDisplayDevice(displayManager, new float[]{60f}); 1735 1736 waitForIdleHandler(handler); 1737 1738 assertFalse(callback.mDisplayChangedCalled); 1739 assertFalse(callback.mDisplayRemovedCalled); 1740 assertTrue(callback.mDisplayAddedCalled); 1741 } 1742 1743 /** 1744 * Tests that EVENT_DISPLAY_ADDED is not sent when a display is added and the 1745 * client has a callback which is not subscribed to this event type. 1746 */ 1747 @Test 1748 public void testShouldNotNotifyDisplayAdded_WhenClientIsNotSubscribed() { 1749 DisplayManagerService displayManager = 1750 new DisplayManagerService(mContext, mShortMockedInjector); 1751 DisplayManagerService.BinderService displayManagerBinderService = 1752 displayManager.new BinderService(); 1753 1754 Handler handler = displayManager.getDisplayHandler(); 1755 waitForIdleHandler(handler); 1756 1757 // register display listener callback 1758 FakeDisplayManagerCallback callback = new FakeDisplayManagerCallback(); 1759 long allEventsExceptDisplayAdded = STANDARD_DISPLAY_EVENTS 1760 & ~DisplayManager.EVENT_FLAG_DISPLAY_ADDED; 1761 displayManagerBinderService.registerCallbackWithEventMask(callback, 1762 allEventsExceptDisplayAdded); 1763 1764 waitForIdleHandler(handler); 1765 1766 createFakeDisplayDevice(displayManager, new float[]{60f}); 1767 1768 waitForIdleHandler(handler); 1769 1770 assertFalse(callback.mDisplayChangedCalled); 1771 assertFalse(callback.mDisplayRemovedCalled); 1772 assertFalse(callback.mDisplayAddedCalled); 1773 } 1774 1775 /** 1776 * Tests that EVENT_DISPLAY_REMOVED is sent when a display is removed. 1777 */ 1778 @Test 1779 public void testShouldNotifyDisplayRemoved_WhenDisplayDeviceIsRemoved() { 1780 DisplayManagerService displayManager = 1781 new DisplayManagerService(mContext, mShortMockedInjector); 1782 DisplayManagerService.BinderService displayManagerBinderService = 1783 displayManager.new BinderService(); 1784 1785 Handler handler = displayManager.getDisplayHandler(); 1786 waitForIdleHandler(handler); 1787 1788 FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, 1789 new float[]{60f}); 1790 1791 waitForIdleHandler(handler); 1792 1793 FakeDisplayManagerCallback callback = registerDisplayListenerCallback( 1794 displayManager, displayManagerBinderService, displayDevice); 1795 1796 waitForIdleHandler(handler); 1797 1798 displayManager.getDisplayDeviceRepository() 1799 .onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED); 1800 1801 waitForIdleHandler(handler); 1802 1803 assertFalse(callback.mDisplayChangedCalled); 1804 assertTrue(callback.mDisplayRemovedCalled); 1805 assertFalse(callback.mDisplayAddedCalled); 1806 } 1807 1808 /** 1809 * Tests that EVENT_DISPLAY_REMOVED is not sent when a display is added and the 1810 * client has a callback which is not subscribed to this event type. 1811 */ 1812 @Test 1813 public void testShouldNotNotifyDisplayRemoved_WhenClientIsNotSubscribed() { 1814 DisplayManagerService displayManager = 1815 new DisplayManagerService(mContext, mShortMockedInjector); 1816 DisplayManagerService.BinderService displayManagerBinderService = 1817 displayManager.new BinderService(); 1818 1819 Handler handler = displayManager.getDisplayHandler(); 1820 waitForIdleHandler(handler); 1821 1822 FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, 1823 new float[]{60f}); 1824 1825 waitForIdleHandler(handler); 1826 1827 FakeDisplayManagerCallback callback = new FakeDisplayManagerCallback(); 1828 long allEventsExceptDisplayRemoved = STANDARD_DISPLAY_EVENTS 1829 & ~DisplayManager.EVENT_FLAG_DISPLAY_REMOVED; 1830 displayManagerBinderService.registerCallbackWithEventMask(callback, 1831 allEventsExceptDisplayRemoved); 1832 1833 waitForIdleHandler(handler); 1834 1835 displayManager.getDisplayDeviceRepository() 1836 .onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED); 1837 1838 waitForIdleHandler(handler); 1839 1840 assertFalse(callback.mDisplayChangedCalled); 1841 assertFalse(callback.mDisplayRemovedCalled); 1842 assertFalse(callback.mDisplayAddedCalled); 1843 } 1844 1845 1846 1847 @Test 1848 public void testSettingTwoBrightnessConfigurationsOnMultiDisplay() { 1849 Context mContext = InstrumentationRegistry.getInstrumentation().getContext(); 1850 DisplayManager displayManager = mContext.getSystemService(DisplayManager.class); 1851 1852 // get the first two internal displays 1853 Display[] displays = displayManager.getDisplays(); 1854 Display internalDisplayOne = null; 1855 Display internalDisplayTwo = null; 1856 for (Display display : displays) { 1857 if (display.getType() == Display.TYPE_INTERNAL) { 1858 if (internalDisplayOne == null) { 1859 internalDisplayOne = display; 1860 } else { 1861 internalDisplayTwo = display; 1862 break; 1863 } 1864 } 1865 } 1866 1867 // return if there are fewer than 2 displays on this device 1868 if (internalDisplayOne == null || internalDisplayTwo == null) { 1869 return; 1870 } 1871 1872 final String uniqueDisplayIdOne = internalDisplayOne.getUniqueId(); 1873 final String uniqueDisplayIdTwo = internalDisplayTwo.getUniqueId(); 1874 1875 BrightnessConfiguration configOne = 1876 new BrightnessConfiguration.Builder( 1877 new float[]{0.0f, 12345.0f}, new float[]{15.0f, 400.0f}) 1878 .setDescription("model:1").build(); 1879 BrightnessConfiguration configTwo = 1880 new BrightnessConfiguration.Builder( 1881 new float[]{0.0f, 6789.0f}, new float[]{12.0f, 300.0f}) 1882 .setDescription("model:2").build(); 1883 1884 displayManager.setBrightnessConfigurationForDisplay(configOne, 1885 uniqueDisplayIdOne); 1886 displayManager.setBrightnessConfigurationForDisplay(configTwo, 1887 uniqueDisplayIdTwo); 1888 1889 BrightnessConfiguration configFromOne = 1890 displayManager.getBrightnessConfigurationForDisplay(uniqueDisplayIdOne); 1891 BrightnessConfiguration configFromTwo = 1892 displayManager.getBrightnessConfigurationForDisplay(uniqueDisplayIdTwo); 1893 1894 assertNotNull(configFromOne); 1895 assertEquals(configOne, configFromOne); 1896 assertEquals(configTwo, configFromTwo); 1897 1898 } 1899 1900 @Test 1901 public void testHdrConversionModeEquals() { 1902 assertEquals( 1903 new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_FORCE, 2), 1904 new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_FORCE, 2)); 1905 assertNotEquals( 1906 new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_FORCE, 2), 1907 new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_FORCE, 3)); 1908 assertEquals( 1909 new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_SYSTEM), 1910 new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_SYSTEM)); 1911 assertNotEquals( 1912 new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_FORCE, 2), 1913 new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_SYSTEM)); 1914 } 1915 1916 @Test 1917 public void testCreateHdrConversionMode_withInvalidArguments_throwsException() { 1918 assertThrows( 1919 "preferredHdrOutputType must not be set if the conversion mode is " 1920 + "HDR_CONVERSION_PASSTHROUGH", 1921 IllegalArgumentException.class, 1922 () -> new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_PASSTHROUGH, 1923 Display.HdrCapabilities.HDR_TYPE_DOLBY_VISION)); 1924 } 1925 1926 @Test 1927 public void testSetHdrConversionModeInternal_withInvalidArguments_throwsException() { 1928 DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); 1929 assertThrows("Expected DisplayManager to throw IllegalArgumentException when " 1930 + "preferredHdrOutputType is set and the conversion mode is " 1931 + "HDR_CONVERSION_SYSTEM", 1932 IllegalArgumentException.class, 1933 () -> displayManager.setHdrConversionModeInternal(new HdrConversionMode( 1934 HdrConversionMode.HDR_CONVERSION_SYSTEM, 1935 Display.HdrCapabilities.HDR_TYPE_DOLBY_VISION))); 1936 } 1937 1938 @Test 1939 public void testSetAndGetHdrConversionModeInternal() { 1940 DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); 1941 final HdrConversionMode mode = new HdrConversionMode( 1942 HdrConversionMode.HDR_CONVERSION_FORCE, 1943 Display.HdrCapabilities.HDR_TYPE_DOLBY_VISION); 1944 displayManager.setHdrConversionModeInternal(mode); 1945 assertEquals(mode, displayManager.getHdrConversionModeSettingInternal()); 1946 assertEquals(mode.getConversionMode(), mHdrConversionMode); 1947 assertEquals(mode.getPreferredHdrOutputType(), mPreferredHdrOutputType); 1948 } 1949 1950 @Test 1951 public void testHdrConversionMode_withMinimalPostProcessing() { 1952 DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); 1953 DisplayManagerService.BinderService displayManagerBinderService = 1954 displayManager.new BinderService(); 1955 registerDefaultDisplays(displayManager); 1956 displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); 1957 FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, 1958 new float[]{60f, 30f, 20f}); 1959 int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService, 1960 displayDevice); 1961 1962 final HdrConversionMode mode = new HdrConversionMode( 1963 HdrConversionMode.HDR_CONVERSION_FORCE, 1964 Display.HdrCapabilities.HDR_TYPE_DOLBY_VISION); 1965 displayManager.setHdrConversionModeInternal(mode); 1966 assertEquals(mode, displayManager.getHdrConversionModeSettingInternal()); 1967 1968 displayManager.setMinimalPostProcessingAllowed(true); 1969 displayManager.setDisplayPropertiesInternal(displayId, false /* hasContent */, 1970 30.0f /* requestedRefreshRate */, 1971 displayDevice.getDisplayDeviceInfoLocked().modeId /* requestedModeId */, 1972 30.0f /* requestedMinRefreshRate */, 120.0f /* requestedMaxRefreshRate */, 1973 true /* preferMinimalPostProcessing */, false /* disableHdrConversion */, 1974 true /* inTraversal */); 1975 1976 assertEquals(new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_PASSTHROUGH), 1977 displayManager.getHdrConversionModeInternal()); 1978 1979 displayManager.setDisplayPropertiesInternal(displayId, false /* hasContent */, 1980 30.0f /* requestedRefreshRate */, 1981 displayDevice.getDisplayDeviceInfoLocked().modeId /* requestedModeId */, 1982 30.0f /* requestedMinRefreshRate */, 120.0f /* requestedMaxRefreshRate */, 1983 false /* preferMinimalPostProcessing */, false /* disableHdrConversion */, 1984 true /* inTraversal */); 1985 assertEquals(mode, displayManager.getHdrConversionModeInternal()); 1986 } 1987 1988 @Test 1989 public void testReturnsRefreshRateForDisplayAndSensor_proximitySensorSet() { 1990 DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); 1991 DisplayManagerInternal localService = displayManager.new LocalService(); 1992 DisplayManagerService.BinderService displayManagerBinderService = 1993 displayManager.new BinderService(); 1994 displayManager.overrideSensorManager(mSensorManager); 1995 1996 FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, new float[]{60f}); 1997 displayDevice.mDisplayDeviceConfig = mMockDisplayDeviceConfig; 1998 int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService, 1999 displayDevice); 2000 2001 String testSensorName = "testName"; 2002 String testSensorType = "testType"; 2003 Sensor testSensor = TestUtils.createSensor(testSensorType, testSensorName); 2004 2005 DisplayDeviceConfig.SensorData sensorData = new DisplayDeviceConfig.SensorData(); 2006 sensorData.type = testSensorType; 2007 sensorData.name = testSensorName; 2008 sensorData.minRefreshRate = 10f; 2009 sensorData.maxRefreshRate = 100f; 2010 2011 when(mMockDisplayDeviceConfig.getProximitySensor()).thenReturn(sensorData); 2012 when(mSensorManager.getSensorList(Sensor.TYPE_ALL)).thenReturn(Collections.singletonList( 2013 testSensor)); 2014 2015 SurfaceControl.RefreshRateRange result = localService.getRefreshRateForDisplayAndSensor( 2016 displayId, testSensorName, testSensorType); 2017 2018 assertNotNull(result); 2019 assertEquals(result.min, sensorData.minRefreshRate, FLOAT_TOLERANCE); 2020 assertEquals(result.max, sensorData.maxRefreshRate, FLOAT_TOLERANCE); 2021 } 2022 2023 @Test 2024 public void testReturnsRefreshRateForDisplayAndSensor_proximitySensorNotSet() { 2025 DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); 2026 DisplayManagerInternal localService = displayManager.new LocalService(); 2027 DisplayManagerService.BinderService displayManagerBinderService = 2028 displayManager.new BinderService(); 2029 displayManager.overrideSensorManager(mSensorManager); 2030 2031 FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, new float[]{60f}); 2032 displayDevice.mDisplayDeviceConfig = mMockDisplayDeviceConfig; 2033 int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService, 2034 displayDevice); 2035 2036 String testSensorName = "testName"; 2037 String testSensorType = "testType"; 2038 Sensor testSensor = TestUtils.createSensor(testSensorType, testSensorName); 2039 2040 DisplayDeviceConfig.SensorData sensorData = new DisplayDeviceConfig.SensorData(); 2041 sensorData.type = testSensorType; 2042 sensorData.name = testSensorName; 2043 sensorData.minRefreshRate = 10f; 2044 sensorData.maxRefreshRate = 100f; 2045 2046 when(mMockDisplayDeviceConfig.getProximitySensor()).thenReturn(null); 2047 when(mSensorManager.getSensorList(Sensor.TYPE_ALL)).thenReturn(Collections.singletonList( 2048 testSensor)); 2049 2050 SurfaceControl.RefreshRateRange result = localService.getRefreshRateForDisplayAndSensor( 2051 displayId, testSensorName, testSensorType); 2052 2053 assertNull(result); 2054 } 2055 2056 private void testDisplayInfoFrameRateOverrideModeCompat(boolean compatChangeEnabled) 2057 throws Exception { 2058 DisplayManagerService displayManager = 2059 new DisplayManagerService(mContext, mShortMockedInjector); 2060 DisplayManagerService.BinderService displayManagerBinderService = 2061 displayManager.new BinderService(); 2062 registerDefaultDisplays(displayManager); 2063 displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); 2064 2065 FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, 2066 new float[]{60f, 30f, 20f}); 2067 int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService, 2068 displayDevice); 2069 DisplayInfo displayInfo = displayManagerBinderService.getDisplayInfo(displayId); 2070 assertEquals(60f, displayInfo.getRefreshRate(), 0.01f); 2071 2072 updateFrameRateOverride(displayManager, displayDevice, 2073 new DisplayEventReceiver.FrameRateOverride[]{ 2074 new DisplayEventReceiver.FrameRateOverride( 2075 Process.myUid(), 20f), 2076 new DisplayEventReceiver.FrameRateOverride( 2077 Process.myUid() + 1, 30f) 2078 }); 2079 displayInfo = displayManagerBinderService.getDisplayInfo(displayId); 2080 assertEquals(20f, displayInfo.getRefreshRate(), 0.01f); 2081 Display.Mode expectedMode; 2082 if (compatChangeEnabled) { 2083 expectedMode = new Display.Mode(1, 100, 200, 60f); 2084 } else { 2085 expectedMode = new Display.Mode(3, 100, 200, 20f); 2086 } 2087 assertEquals(expectedMode, displayInfo.getMode()); 2088 } 2089 2090 private void testDisplayInfoRenderFrameRateModeCompat(boolean compatChangeEnabled) 2091 throws Exception { 2092 DisplayManagerService displayManager = 2093 new DisplayManagerService(mContext, mShortMockedInjector); 2094 DisplayManagerService.BinderService displayManagerBinderService = 2095 displayManager.new BinderService(); 2096 registerDefaultDisplays(displayManager); 2097 displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); 2098 2099 FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, 2100 new float[]{60f, 30f, 20f}); 2101 int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService, 2102 displayDevice); 2103 DisplayInfo displayInfo = displayManagerBinderService.getDisplayInfo(displayId); 2104 assertEquals(60f, displayInfo.getRefreshRate(), 0.01f); 2105 2106 updateRenderFrameRate(displayManager, displayDevice, 20f); 2107 displayInfo = displayManagerBinderService.getDisplayInfo(displayId); 2108 assertEquals(20f, displayInfo.getRefreshRate(), 0.01f); 2109 Display.Mode expectedMode; 2110 if (compatChangeEnabled) { 2111 expectedMode = new Display.Mode(1, 100, 200, 60f); 2112 } else { 2113 expectedMode = new Display.Mode(3, 100, 200, 20f); 2114 } 2115 assertEquals(expectedMode, displayInfo.getMode()); 2116 } 2117 2118 private void testDisplayInfoNonNativeFrameRateOverrideMode(boolean compatChangeEnabled) { 2119 DisplayManagerService displayManager = 2120 new DisplayManagerService(mContext, mBasicInjector); 2121 DisplayManagerService.BinderService displayManagerBinderService = 2122 displayManager.new BinderService(); 2123 registerDefaultDisplays(displayManager); 2124 displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); 2125 2126 FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, 2127 new float[]{60f}); 2128 int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService, 2129 displayDevice); 2130 DisplayInfo displayInfo = displayManagerBinderService.getDisplayInfo(displayId); 2131 assertEquals(60f, displayInfo.getRefreshRate(), 0.01f); 2132 2133 updateFrameRateOverride(displayManager, displayDevice, 2134 new DisplayEventReceiver.FrameRateOverride[]{ 2135 new DisplayEventReceiver.FrameRateOverride( 2136 Process.myUid(), 20f) 2137 }); 2138 displayInfo = displayManagerBinderService.getDisplayInfo(displayId); 2139 Display.Mode expectedMode; 2140 if (compatChangeEnabled) { 2141 expectedMode = new Display.Mode(1, 100, 200, 60f); 2142 } else { 2143 expectedMode = new Display.Mode(255, 100, 200, 20f); 2144 } 2145 assertEquals(expectedMode, displayInfo.getMode()); 2146 } 2147 2148 private int getDisplayIdForDisplayDevice( 2149 DisplayManagerService displayManager, 2150 DisplayManagerService.BinderService displayManagerBinderService, 2151 FakeDisplayDevice displayDevice) { 2152 2153 final int[] displayIds = displayManagerBinderService.getDisplayIds( 2154 /* includeDisabled= */ true); 2155 assertTrue(displayIds.length > 0); 2156 int displayId = Display.INVALID_DISPLAY; 2157 for (int i = 0; i < displayIds.length; i++) { 2158 DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayIds[i]); 2159 if (displayDevice.getDisplayDeviceInfoLocked().equals(ddi)) { 2160 displayId = displayIds[i]; 2161 break; 2162 } 2163 } 2164 assertFalse(displayId == Display.INVALID_DISPLAY); 2165 return displayId; 2166 } 2167 2168 private void updateDisplayDeviceInfo(DisplayManagerService displayManager, 2169 FakeDisplayDevice displayDevice, 2170 DisplayDeviceInfo displayDeviceInfo) { 2171 displayDevice.setDisplayDeviceInfo(displayDeviceInfo); 2172 displayManager.getDisplayDeviceRepository() 2173 .onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_CHANGED); 2174 Handler handler = displayManager.getDisplayHandler(); 2175 waitForIdleHandler(handler); 2176 } 2177 2178 private void updateFrameRateOverride(DisplayManagerService displayManager, 2179 FakeDisplayDevice displayDevice, 2180 DisplayEventReceiver.FrameRateOverride[] frameRateOverrides) { 2181 DisplayDeviceInfo displayDeviceInfo = new DisplayDeviceInfo(); 2182 displayDeviceInfo.copyFrom(displayDevice.getDisplayDeviceInfoLocked()); 2183 displayDeviceInfo.frameRateOverrides = frameRateOverrides; 2184 updateDisplayDeviceInfo(displayManager, displayDevice, displayDeviceInfo); 2185 } 2186 2187 private void updateRenderFrameRate(DisplayManagerService displayManager, 2188 FakeDisplayDevice displayDevice, 2189 float renderFrameRate) { 2190 DisplayDeviceInfo displayDeviceInfo = new DisplayDeviceInfo(); 2191 displayDeviceInfo.copyFrom(displayDevice.getDisplayDeviceInfoLocked()); 2192 displayDeviceInfo.renderFrameRate = renderFrameRate; 2193 updateDisplayDeviceInfo(displayManager, displayDevice, displayDeviceInfo); 2194 } 2195 2196 private void updateModeId(DisplayManagerService displayManager, 2197 FakeDisplayDevice displayDevice, 2198 int modeId) { 2199 DisplayDeviceInfo displayDeviceInfo = new DisplayDeviceInfo(); 2200 displayDeviceInfo.copyFrom(displayDevice.getDisplayDeviceInfoLocked()); 2201 displayDeviceInfo.modeId = modeId; 2202 updateDisplayDeviceInfo(displayManager, displayDevice, displayDeviceInfo); 2203 } 2204 2205 private IDisplayManagerCallback registerDisplayChangeCallback( 2206 DisplayManagerService displayManager) { 2207 IDisplayManagerCallback displayChangesCallback = mock(IDisplayManagerCallback.class); 2208 when(displayChangesCallback.asBinder()).thenReturn(new Binder()); 2209 DisplayManagerService.BinderService binderService = displayManager.new BinderService(); 2210 binderService.registerCallback(displayChangesCallback); 2211 return displayChangesCallback; 2212 } 2213 2214 private FakeDisplayManagerCallback registerDisplayListenerCallback( 2215 DisplayManagerService displayManager, 2216 DisplayManagerService.BinderService displayManagerBinderService, 2217 FakeDisplayDevice displayDevice) { 2218 // Find the display id of the added FakeDisplayDevice 2219 int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService, 2220 displayDevice); 2221 2222 Handler handler = displayManager.getDisplayHandler(); 2223 waitForIdleHandler(handler); 2224 2225 // register display listener callback 2226 FakeDisplayManagerCallback callback = new FakeDisplayManagerCallback(displayId); 2227 displayManagerBinderService.registerCallbackWithEventMask( 2228 callback, STANDARD_DISPLAY_EVENTS); 2229 return callback; 2230 } 2231 2232 private FakeDisplayDevice createFakeDisplayDevice(DisplayManagerService displayManager, 2233 float[] refreshRates) { 2234 FakeDisplayDevice displayDevice = new FakeDisplayDevice(); 2235 DisplayDeviceInfo displayDeviceInfo = new DisplayDeviceInfo(); 2236 int width = 100; 2237 int height = 200; 2238 displayDeviceInfo.supportedModes = new Display.Mode[refreshRates.length]; 2239 for (int i = 0; i < refreshRates.length; i++) { 2240 displayDeviceInfo.supportedModes[i] = 2241 new Display.Mode(i + 1, width, height, refreshRates[i]); 2242 } 2243 displayDeviceInfo.modeId = 1; 2244 displayDeviceInfo.renderFrameRate = displayDeviceInfo.supportedModes[0].getRefreshRate(); 2245 displayDeviceInfo.width = width; 2246 displayDeviceInfo.height = height; 2247 final Rect zeroRect = new Rect(); 2248 displayDeviceInfo.displayCutout = new DisplayCutout( 2249 Insets.of(0, 10, 0, 0), 2250 zeroRect, new Rect(0, 0, 10, 10), zeroRect, zeroRect); 2251 displayDeviceInfo.flags = DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY; 2252 displayDeviceInfo.address = new TestUtils.TestDisplayAddress(); 2253 displayDevice.setDisplayDeviceInfo(displayDeviceInfo); 2254 displayManager.getDisplayDeviceRepository() 2255 .onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED); 2256 return displayDevice; 2257 } 2258 2259 private void registerDefaultDisplays(DisplayManagerService displayManager) { 2260 Handler handler = displayManager.getDisplayHandler(); 2261 // Would prefer to call displayManager.onStart() directly here but it performs binderService 2262 // registration which triggers security exceptions when running from a test. 2263 handler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS); 2264 waitForIdleHandler(handler); 2265 } 2266 2267 private void waitForIdleHandler(Handler handler) { 2268 waitForIdleHandler(handler, Duration.ofSeconds(1)); 2269 } 2270 2271 private void waitForIdleHandler(Handler handler, Duration timeout) { 2272 final MessageQueue queue = handler.getLooper().getQueue(); 2273 final CountDownLatch latch = new CountDownLatch(1); 2274 queue.addIdleHandler(() -> { 2275 latch.countDown(); 2276 // Remove idle handler 2277 return false; 2278 }); 2279 try { 2280 latch.await(timeout.toMillis(), TimeUnit.MILLISECONDS); 2281 } catch (InterruptedException e) { 2282 fail("Interrupted unexpectedly: " + e); 2283 } 2284 } 2285 2286 private void resetConfigToIgnoreSensorManager(Context context) { 2287 final Resources res = Mockito.spy(context.getResources()); 2288 doReturn(new int[]{-1}).when(res).getIntArray(R.array 2289 .config_ambientThresholdsOfPeakRefreshRate); 2290 doReturn(new int[]{-1}).when(res).getIntArray(R.array 2291 .config_brightnessThresholdsOfPeakRefreshRate); 2292 doReturn(new int[]{-1}).when(res).getIntArray(R.array 2293 .config_highDisplayBrightnessThresholdsOfFixedRefreshRate); 2294 doReturn(new int[]{-1}).when(res).getIntArray(R.array 2295 .config_highAmbientBrightnessThresholdsOfFixedRefreshRate); 2296 2297 when(context.getResources()).thenReturn(res); 2298 } 2299 2300 private class FakeDisplayManagerCallback extends IDisplayManagerCallback.Stub { 2301 int mDisplayId; 2302 boolean mDisplayAddedCalled = false; 2303 boolean mDisplayChangedCalled = false; 2304 boolean mDisplayRemovedCalled = false; 2305 2306 FakeDisplayManagerCallback(int displayId) { 2307 mDisplayId = displayId; 2308 } 2309 2310 FakeDisplayManagerCallback() { 2311 mDisplayId = -1; 2312 } 2313 2314 @Override 2315 public void onDisplayEvent(int displayId, int event) { 2316 if (mDisplayId != -1 && displayId != mDisplayId) { 2317 return; 2318 } 2319 2320 if (event == DisplayManagerGlobal.EVENT_DISPLAY_ADDED) { 2321 mDisplayAddedCalled = true; 2322 } 2323 2324 if (event == DisplayManagerGlobal.EVENT_DISPLAY_CHANGED) { 2325 mDisplayChangedCalled = true; 2326 } 2327 2328 if (event == DisplayManagerGlobal.EVENT_DISPLAY_REMOVED) { 2329 mDisplayRemovedCalled = true; 2330 } 2331 } 2332 2333 public void clear() { 2334 mDisplayAddedCalled = false; 2335 mDisplayChangedCalled = false; 2336 mDisplayRemovedCalled = false; 2337 } 2338 } 2339 2340 private class FakeDisplayDevice extends DisplayDevice { 2341 private DisplayDeviceInfo mDisplayDeviceInfo; 2342 2343 FakeDisplayDevice() { 2344 super(null, null, "", mContext); 2345 } 2346 2347 public void setDisplayDeviceInfo(DisplayDeviceInfo displayDeviceInfo) { 2348 mDisplayDeviceInfo = displayDeviceInfo; 2349 } 2350 2351 @Override 2352 public boolean hasStableUniqueId() { 2353 return false; 2354 } 2355 2356 @Override 2357 public DisplayDeviceInfo getDisplayDeviceInfoLocked() { 2358 return mDisplayDeviceInfo; 2359 } 2360 } 2361 } 2362