1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.display; 18 19 import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE; 20 import static android.view.Display.DEFAULT_DISPLAY; 21 import static android.view.Display.DEFAULT_DISPLAY_GROUP; 22 import static android.view.Display.FLAG_REAR; 23 import static android.view.Display.TYPE_EXTERNAL; 24 import static android.view.Display.TYPE_INTERNAL; 25 import static android.view.Display.TYPE_VIRTUAL; 26 27 import static com.android.server.display.DeviceStateToLayoutMap.STATE_DEFAULT; 28 import static com.android.server.display.DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED; 29 import static com.android.server.display.DisplayAdapter.DISPLAY_DEVICE_EVENT_CHANGED; 30 import static com.android.server.display.DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED; 31 import static com.android.server.display.DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY; 32 import static com.android.server.display.LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_ADDED; 33 import static com.android.server.display.LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_REMOVED; 34 import static com.android.server.display.layout.Layout.Display.POSITION_REAR; 35 import static com.android.server.display.layout.Layout.Display.POSITION_UNKNOWN; 36 37 import static com.google.common.truth.Truth.assertThat; 38 39 import static org.junit.Assert.assertEquals; 40 import static org.junit.Assert.assertFalse; 41 import static org.junit.Assert.assertNotEquals; 42 import static org.junit.Assert.assertNotNull; 43 import static org.junit.Assert.assertNull; 44 import static org.junit.Assert.assertTrue; 45 import static org.mockito.ArgumentMatchers.anyInt; 46 import static org.mockito.ArgumentMatchers.anyLong; 47 import static org.mockito.ArgumentMatchers.eq; 48 import static org.mockito.Mockito.atLeastOnce; 49 import static org.mockito.Mockito.clearInvocations; 50 import static org.mockito.Mockito.never; 51 import static org.mockito.Mockito.verify; 52 import static org.mockito.Mockito.when; 53 54 import android.app.PropertyInvalidatedCache; 55 import android.content.Context; 56 import android.content.res.Resources; 57 import android.os.Handler; 58 import android.os.IPowerManager; 59 import android.os.IThermalService; 60 import android.os.PowerManager; 61 import android.os.Process; 62 import android.os.RemoteException; 63 import android.os.test.TestLooper; 64 import android.view.Display; 65 import android.view.DisplayAddress; 66 import android.view.DisplayInfo; 67 68 import androidx.test.ext.junit.runners.AndroidJUnit4; 69 import androidx.test.filters.SmallTest; 70 71 import com.android.server.display.layout.DisplayIdProducer; 72 import com.android.server.display.layout.Layout; 73 import com.android.server.utils.FoldSettingProvider; 74 75 import org.junit.Before; 76 import org.junit.Test; 77 import org.junit.runner.RunWith; 78 import org.mockito.ArgumentCaptor; 79 import org.mockito.Captor; 80 import org.mockito.Mock; 81 import org.mockito.MockitoAnnotations; 82 import org.mockito.Spy; 83 84 import java.io.File; 85 import java.io.InputStream; 86 import java.io.OutputStream; 87 import java.util.Arrays; 88 89 @SmallTest 90 @RunWith(AndroidJUnit4.class) 91 public class LogicalDisplayMapperTest { 92 private static int sUniqueTestDisplayId = 0; 93 private static final int DEVICE_STATE_CLOSED = 0; 94 private static final int DEVICE_STATE_OPEN = 2; 95 private static final int FLAG_GO_TO_SLEEP_ON_FOLD = 0; 96 private static int sNextNonDefaultDisplayId = DEFAULT_DISPLAY + 1; 97 private static final File NON_EXISTING_FILE = new File("/non_existing_folder/should_not_exist"); 98 99 private DisplayDeviceRepository mDisplayDeviceRepo; 100 private LogicalDisplayMapper mLogicalDisplayMapper; 101 private TestLooper mLooper; 102 private Handler mHandler; 103 private PowerManager mPowerManager; 104 105 private final DisplayIdProducer mIdProducer = (isDefault) -> 106 isDefault ? DEFAULT_DISPLAY : sNextNonDefaultDisplayId++; 107 108 @Mock LogicalDisplayMapper.Listener mListenerMock; 109 @Mock Context mContextMock; 110 @Mock FoldSettingProvider mFoldSettingProviderMock; 111 @Mock Resources mResourcesMock; 112 @Mock IPowerManager mIPowerManagerMock; 113 @Mock IThermalService mIThermalServiceMock; 114 @Spy DeviceStateToLayoutMap mDeviceStateToLayoutMapSpy = 115 new DeviceStateToLayoutMap(mIdProducer, NON_EXISTING_FILE); 116 117 @Captor ArgumentCaptor<LogicalDisplay> mDisplayCaptor; 118 119 @Before setUp()120 public void setUp() throws RemoteException { 121 // Share classloader to allow package private access. 122 System.setProperty("dexmaker.share_classloader", "true"); 123 MockitoAnnotations.initMocks(this); 124 125 mDisplayDeviceRepo = new DisplayDeviceRepository( 126 new DisplayManagerService.SyncRoot(), 127 new PersistentDataStore(new PersistentDataStore.Injector() { 128 @Override 129 public InputStream openRead() { 130 return null; 131 } 132 133 @Override 134 public OutputStream startWrite() { 135 return null; 136 } 137 138 @Override 139 public void finishWrite(OutputStream os, boolean success) {} 140 })); 141 142 // Disable binder caches in this process. 143 PropertyInvalidatedCache.disableForTestMode(); 144 145 mPowerManager = new PowerManager(mContextMock, mIPowerManagerMock, mIThermalServiceMock, 146 null); 147 148 when(mContextMock.getSystemServiceName(PowerManager.class)) 149 .thenReturn(Context.POWER_SERVICE); 150 when(mFoldSettingProviderMock.shouldStayAwakeOnFold()).thenReturn(false); 151 when(mFoldSettingProviderMock.shouldSleepOnFold()).thenReturn(false); 152 when(mIPowerManagerMock.isInteractive()).thenReturn(true); 153 when(mContextMock.getSystemService(PowerManager.class)).thenReturn(mPowerManager); 154 when(mContextMock.getResources()).thenReturn(mResourcesMock); 155 when(mResourcesMock.getBoolean( 156 com.android.internal.R.bool.config_supportsConcurrentInternalDisplays)) 157 .thenReturn(true); 158 when(mResourcesMock.getIntArray( 159 com.android.internal.R.array.config_deviceStatesOnWhichToWakeUp)) 160 .thenReturn(new int[]{1, 2}); 161 when(mResourcesMock.getIntArray( 162 com.android.internal.R.array.config_deviceStatesOnWhichToSleep)) 163 .thenReturn(new int[]{0}); 164 165 mLooper = new TestLooper(); 166 mHandler = new Handler(mLooper.getLooper()); 167 mLogicalDisplayMapper = new LogicalDisplayMapper(mContextMock, mFoldSettingProviderMock, 168 mDisplayDeviceRepo, 169 mListenerMock, new DisplayManagerService.SyncRoot(), mHandler, 170 mDeviceStateToLayoutMapSpy); 171 } 172 173 174 ///////////////// 175 // Test Methods 176 ///////////////// 177 178 @Test testDisplayDeviceAddAndRemove_Internal()179 public void testDisplayDeviceAddAndRemove_Internal() { 180 DisplayDevice device = createDisplayDevice(TYPE_INTERNAL, 600, 800, 181 FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY); 182 183 // add 184 LogicalDisplay displayAdded = add(device); 185 assertEquals(info(displayAdded).address, info(device).address); 186 assertEquals(DEFAULT_DISPLAY, id(displayAdded)); 187 188 // remove 189 mDisplayDeviceRepo.onDisplayDeviceEvent(device, DISPLAY_DEVICE_EVENT_REMOVED); 190 verify(mListenerMock).onLogicalDisplayEventLocked( 191 mDisplayCaptor.capture(), eq(LOGICAL_DISPLAY_EVENT_REMOVED)); 192 LogicalDisplay displayRemoved = mDisplayCaptor.getValue(); 193 assertEquals(DEFAULT_DISPLAY, id(displayRemoved)); 194 assertEquals(displayAdded, displayRemoved); 195 } 196 197 @Test testDisplayDeviceAddAndRemove_NonInternalTypes()198 public void testDisplayDeviceAddAndRemove_NonInternalTypes() { 199 testDisplayDeviceAddAndRemove_NonInternal(TYPE_EXTERNAL); 200 testDisplayDeviceAddAndRemove_NonInternal(Display.TYPE_WIFI); 201 testDisplayDeviceAddAndRemove_NonInternal(Display.TYPE_OVERLAY); 202 testDisplayDeviceAddAndRemove_NonInternal(TYPE_VIRTUAL); 203 testDisplayDeviceAddAndRemove_NonInternal(Display.TYPE_UNKNOWN); 204 205 // Call the internal test again, just to verify that adding non-internal displays 206 // doesn't affect the ability for an internal display to become the default display. 207 testDisplayDeviceAddAndRemove_Internal(); 208 } 209 210 @Test testDisplayDeviceAdd_TwoInternalOneDefault()211 public void testDisplayDeviceAdd_TwoInternalOneDefault() { 212 DisplayDevice device1 = createDisplayDevice(TYPE_INTERNAL, 600, 800, 0); 213 DisplayDevice device2 = createDisplayDevice(TYPE_INTERNAL, 600, 800, 214 FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY); 215 216 LogicalDisplay display1 = add(device1); 217 assertEquals(info(display1).address, info(device1).address); 218 assertNotEquals(DEFAULT_DISPLAY, id(display1)); 219 220 LogicalDisplay display2 = add(device2); 221 assertEquals(info(display2).address, info(device2).address); 222 assertEquals(DEFAULT_DISPLAY, id(display2)); 223 } 224 225 @Test testDisplayDeviceAdd_TwoInternalBothDefault()226 public void testDisplayDeviceAdd_TwoInternalBothDefault() { 227 DisplayDevice device1 = createDisplayDevice(TYPE_INTERNAL, 600, 800, 228 FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY); 229 DisplayDevice device2 = createDisplayDevice(TYPE_INTERNAL, 600, 800, 230 FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY); 231 232 LogicalDisplay display1 = add(device1); 233 assertEquals(info(display1).address, info(device1).address); 234 assertEquals(DEFAULT_DISPLAY, id(display1)); 235 236 LogicalDisplay display2 = add(device2); 237 assertEquals(info(display2).address, info(device2).address); 238 // Despite the flags, we can only have one default display 239 assertNotEquals(DEFAULT_DISPLAY, id(display2)); 240 } 241 242 @Test testDisplayDeviceAddAndRemove_OneExternalDefault()243 public void testDisplayDeviceAddAndRemove_OneExternalDefault() { 244 DisplayDevice device = createDisplayDevice(TYPE_EXTERNAL, 600, 800, 245 FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY); 246 247 // add 248 LogicalDisplay displayAdded = add(device); 249 assertEquals(info(displayAdded).address, info(device).address); 250 assertEquals(Display.DEFAULT_DISPLAY, id(displayAdded)); 251 252 // remove 253 mDisplayDeviceRepo.onDisplayDeviceEvent(device, DISPLAY_DEVICE_EVENT_REMOVED); 254 verify(mListenerMock).onLogicalDisplayEventLocked( 255 mDisplayCaptor.capture(), eq(LOGICAL_DISPLAY_EVENT_REMOVED)); 256 LogicalDisplay displayRemoved = mDisplayCaptor.getValue(); 257 assertEquals(DEFAULT_DISPLAY, id(displayRemoved)); 258 assertEquals(displayAdded, displayRemoved); 259 } 260 261 @Test testDisplayDeviceAddAndRemove_SwitchDefault()262 public void testDisplayDeviceAddAndRemove_SwitchDefault() { 263 DisplayDevice device1 = createDisplayDevice(TYPE_INTERNAL, 600, 800, 264 FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY); 265 DisplayDevice device2 = createDisplayDevice(TYPE_INTERNAL, 600, 800, 266 FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY); 267 268 LogicalDisplay display1 = add(device1); 269 assertEquals(info(display1).address, info(device1).address); 270 assertEquals(DEFAULT_DISPLAY, id(display1)); 271 272 LogicalDisplay display2 = add(device2); 273 assertEquals(info(display2).address, info(device2).address); 274 // We can only have one default display 275 assertEquals(DEFAULT_DISPLAY, id(display1)); 276 277 // remove 278 mDisplayDeviceRepo.onDisplayDeviceEvent(device1, DISPLAY_DEVICE_EVENT_REMOVED); 279 280 verify(mListenerMock).onLogicalDisplayEventLocked( 281 mDisplayCaptor.capture(), eq(LOGICAL_DISPLAY_EVENT_REMOVED)); 282 LogicalDisplay displayRemoved = mDisplayCaptor.getValue(); 283 // Display 1 is still the default logical display 284 assertEquals(DEFAULT_DISPLAY, id(display1)); 285 // The logical displays had their devices swapped and Display 2 was removed 286 assertEquals(display2, displayRemoved); 287 assertEquals(info(display1).address, info(device2).address); 288 } 289 290 @Test testGetDisplayIdsLocked()291 public void testGetDisplayIdsLocked() { 292 add(createDisplayDevice(TYPE_INTERNAL, 600, 800, 293 FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY)); 294 add(createDisplayDevice(TYPE_EXTERNAL, 600, 800, 0)); 295 add(createDisplayDevice(TYPE_VIRTUAL, 600, 800, 0)); 296 297 int [] ids = mLogicalDisplayMapper.getDisplayIdsLocked(Process.SYSTEM_UID, 298 /* includeDisabled= */ true); 299 assertEquals(3, ids.length); 300 Arrays.sort(ids); 301 assertEquals(DEFAULT_DISPLAY, ids[0]); 302 } 303 304 @Test testGetDisplayInfoForStateLocked_defaultLayout()305 public void testGetDisplayInfoForStateLocked_defaultLayout() { 306 final DisplayDevice device1 = createDisplayDevice(TYPE_INTERNAL, 600, 800, 307 FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY); 308 final DisplayDevice device2 = createDisplayDevice(TYPE_INTERNAL, 200, 800, 309 FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY); 310 311 add(device1); 312 add(device2); 313 314 Layout layout1 = new Layout(); 315 createDefaultDisplay(layout1, device1); 316 createNonDefaultDisplay(layout1, device2, /* enabled= */ true, /* group= */ null); 317 when(mDeviceStateToLayoutMapSpy.get(STATE_DEFAULT)).thenReturn(layout1); 318 assertThat(layout1.size()).isEqualTo(2); 319 final int logicalId2 = layout1.getByAddress(info(device2).address).getLogicalDisplayId(); 320 321 final DisplayInfo displayInfoDefault = mLogicalDisplayMapper.getDisplayInfoForStateLocked( 322 STATE_DEFAULT, DEFAULT_DISPLAY); 323 assertThat(displayInfoDefault.displayId).isEqualTo(DEFAULT_DISPLAY); 324 assertThat(displayInfoDefault.logicalWidth).isEqualTo(width(device1)); 325 assertThat(displayInfoDefault.logicalHeight).isEqualTo(height(device1)); 326 327 final DisplayInfo displayInfoOther = mLogicalDisplayMapper.getDisplayInfoForStateLocked( 328 STATE_DEFAULT, logicalId2); 329 assertThat(displayInfoOther).isNotNull(); 330 assertThat(displayInfoOther.displayId).isEqualTo(logicalId2); 331 assertThat(displayInfoOther.logicalWidth).isEqualTo(width(device2)); 332 assertThat(displayInfoOther.logicalHeight).isEqualTo(height(device2)); 333 } 334 335 @Test testGetDisplayInfoForStateLocked_multipleLayouts()336 public void testGetDisplayInfoForStateLocked_multipleLayouts() { 337 final DisplayDevice device1 = createDisplayDevice(TYPE_INTERNAL, 600, 800, 338 FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY); 339 final DisplayDevice device2 = createDisplayDevice(TYPE_INTERNAL, 200, 800, 340 FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY); 341 final DisplayDevice device3 = createDisplayDevice(TYPE_VIRTUAL, 700, 800, 342 DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP); 343 344 add(device1); 345 add(device2); 346 add(device3); 347 348 Layout layout1 = new Layout(); 349 createDefaultDisplay(layout1, device1); 350 when(mDeviceStateToLayoutMapSpy.get(STATE_DEFAULT)).thenReturn(layout1); 351 352 final int layoutState2 = 2; 353 Layout layout2 = new Layout(); 354 createNonDefaultDisplay(layout2, device2, /* enabled= */ true, /* group= */ null); 355 // Device3 is the default display. 356 createDefaultDisplay(layout2, device3); 357 when(mDeviceStateToLayoutMapSpy.get(layoutState2)).thenReturn(layout2); 358 assertThat(layout2.size()).isEqualTo(2); 359 final int logicalId2 = layout2.getByAddress(info(device2).address).getLogicalDisplayId(); 360 361 // Default layout. 362 final DisplayInfo displayInfoLayout1Default = 363 mLogicalDisplayMapper.getDisplayInfoForStateLocked( 364 STATE_DEFAULT, DEFAULT_DISPLAY); 365 assertThat(displayInfoLayout1Default.displayId).isEqualTo(DEFAULT_DISPLAY); 366 assertThat(displayInfoLayout1Default.logicalWidth).isEqualTo(width(device1)); 367 assertThat(displayInfoLayout1Default.logicalHeight).isEqualTo(height(device1)); 368 369 // Second layout, where device3 is the default display. 370 final DisplayInfo displayInfoLayout2Default = 371 mLogicalDisplayMapper.getDisplayInfoForStateLocked( 372 layoutState2, DEFAULT_DISPLAY); 373 assertThat(displayInfoLayout2Default.displayId).isEqualTo(DEFAULT_DISPLAY); 374 assertThat(displayInfoLayout2Default.logicalWidth).isEqualTo(width(device3)); 375 assertThat(displayInfoLayout2Default.logicalHeight).isEqualTo(height(device3)); 376 377 final DisplayInfo displayInfoLayout2Other = 378 mLogicalDisplayMapper.getDisplayInfoForStateLocked( 379 layoutState2, logicalId2); 380 assertThat(displayInfoLayout2Other).isNotNull(); 381 assertThat(displayInfoLayout2Other.displayId).isEqualTo(logicalId2); 382 assertThat(displayInfoLayout2Other.logicalWidth).isEqualTo(width(device2)); 383 assertThat(displayInfoLayout2Other.logicalHeight).isEqualTo(height(device2)); 384 } 385 386 @Test testGetDisplayInfoForStateLocked_multipleDisplayGroups()387 public void testGetDisplayInfoForStateLocked_multipleDisplayGroups() { 388 DisplayDevice device1 = createDisplayDevice(TYPE_INTERNAL, 600, 800, 389 FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY); 390 DisplayDevice device2 = createDisplayDevice(TYPE_INTERNAL, 200, 800, 391 FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY); 392 DisplayDevice device3 = createDisplayDevice(TYPE_INTERNAL, 700, 800, 393 FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY); 394 DisplayDevice device4 = createDisplayDevice(TYPE_INTERNAL, 400, 600, 395 FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY); 396 397 Layout layout = new Layout(); 398 createDefaultDisplay(layout, device1); 399 createNonDefaultDisplay(layout, device2, /* enabled= */ true, /* group= */ "group1"); 400 createNonDefaultDisplay(layout, device3, /* enabled= */ true, /* group= */ "group1"); 401 createNonDefaultDisplay(layout, device4, /* enabled= */ true, /* group= */ "group2"); 402 403 when(mDeviceStateToLayoutMapSpy.get(STATE_DEFAULT)).thenReturn(layout); 404 405 LogicalDisplay display1 = add(device1); 406 LogicalDisplay display2 = add(device2); 407 LogicalDisplay display3 = add(device3); 408 LogicalDisplay display4 = add(device4); 409 410 int displayGroupId1 = 411 mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display1)); 412 int displayGroupId2 = 413 mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display2)); 414 int displayGroupId3 = 415 mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display3)); 416 int displayGroupId4 = 417 mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display4)); 418 assertThat(displayGroupId1).isEqualTo(DEFAULT_DISPLAY_GROUP); 419 assertThat(displayGroupId2).isNotEqualTo(DEFAULT_DISPLAY_GROUP); 420 assertThat(displayGroupId2).isEqualTo(displayGroupId3); 421 assertThat(displayGroupId3).isNotEqualTo(DEFAULT_DISPLAY_GROUP); 422 assertThat(displayGroupId2).isNotEqualTo(displayGroupId4); 423 } 424 425 @Test testSingleDisplayGroup()426 public void testSingleDisplayGroup() { 427 LogicalDisplay display1 = add(createDisplayDevice(TYPE_INTERNAL, 600, 800, 428 FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY)); 429 LogicalDisplay display2 = add(createDisplayDevice(TYPE_INTERNAL, 600, 800, 0)); 430 LogicalDisplay display3 = add(createDisplayDevice(TYPE_VIRTUAL, 600, 800, 0)); 431 432 assertEquals(DEFAULT_DISPLAY_GROUP, 433 mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display1))); 434 assertEquals(DEFAULT_DISPLAY_GROUP, 435 mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display2))); 436 assertEquals(DEFAULT_DISPLAY_GROUP, 437 mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display3))); 438 } 439 440 @Test testMultipleDisplayGroups()441 public void testMultipleDisplayGroups() { 442 LogicalDisplay display1 = add(createDisplayDevice(TYPE_INTERNAL, 600, 800, 443 FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY)); 444 LogicalDisplay display2 = add(createDisplayDevice(TYPE_INTERNAL, 600, 800, 0)); 445 446 447 TestDisplayDevice device3 = createDisplayDevice(TYPE_VIRTUAL, 600, 800, 448 DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP); 449 LogicalDisplay display3 = add(device3); 450 451 assertEquals(DEFAULT_DISPLAY_GROUP, 452 mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display1))); 453 assertEquals(DEFAULT_DISPLAY_GROUP, 454 mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display2))); 455 assertNotEquals(DEFAULT_DISPLAY_GROUP, 456 mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display3))); 457 458 // Now switch it back to the default group by removing the flag and issuing an update 459 DisplayDeviceInfo info = device3.getSourceInfo(); 460 info.flags = info.flags & ~DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP; 461 mDisplayDeviceRepo.onDisplayDeviceEvent(device3, DISPLAY_DEVICE_EVENT_CHANGED); 462 463 // Verify the new group is correct. 464 assertEquals(DEFAULT_DISPLAY_GROUP, 465 mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display3))); 466 } 467 468 @Test testDevicesAreAddedToDeviceDisplayGroups()469 public void testDevicesAreAddedToDeviceDisplayGroups() { 470 // Create the default internal display of the device. 471 LogicalDisplay defaultDisplay = 472 add( 473 createDisplayDevice( 474 Display.TYPE_INTERNAL, 475 600, 476 800, 477 DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY)); 478 479 // Create 3 virtual displays associated with a first virtual device. 480 int deviceId1 = 1; 481 TestDisplayDevice display1 = 482 createDisplayDevice(Display.TYPE_VIRTUAL, "virtualDevice1Display1", 600, 800, 0); 483 mLogicalDisplayMapper.associateDisplayDeviceWithVirtualDevice(display1, deviceId1); 484 LogicalDisplay virtualDevice1Display1 = add(display1); 485 486 TestDisplayDevice display2 = 487 createDisplayDevice(Display.TYPE_VIRTUAL, "virtualDevice1Display2", 600, 800, 0); 488 mLogicalDisplayMapper.associateDisplayDeviceWithVirtualDevice(display2, deviceId1); 489 LogicalDisplay virtualDevice1Display2 = add(display2); 490 491 TestDisplayDevice display3 = 492 createDisplayDevice(Display.TYPE_VIRTUAL, "virtualDevice1Display3", 600, 800, 0); 493 mLogicalDisplayMapper.associateDisplayDeviceWithVirtualDevice(display3, deviceId1); 494 LogicalDisplay virtualDevice1Display3 = add(display3); 495 496 // Create another 3 virtual displays associated with a second virtual device. 497 int deviceId2 = 2; 498 TestDisplayDevice display4 = 499 createDisplayDevice(Display.TYPE_VIRTUAL, "virtualDevice2Display1", 600, 800, 0); 500 mLogicalDisplayMapper.associateDisplayDeviceWithVirtualDevice(display4, deviceId2); 501 LogicalDisplay virtualDevice2Display1 = add(display4); 502 503 TestDisplayDevice display5 = 504 createDisplayDevice(Display.TYPE_VIRTUAL, "virtualDevice2Display2", 600, 800, 0); 505 mLogicalDisplayMapper.associateDisplayDeviceWithVirtualDevice(display5, deviceId2); 506 LogicalDisplay virtualDevice2Display2 = add(display5); 507 508 // The final display is created with FLAG_OWN_DISPLAY_GROUP set. 509 TestDisplayDevice display6 = 510 createDisplayDevice( 511 Display.TYPE_VIRTUAL, 512 "virtualDevice2Display3", 513 600, 514 800, 515 DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP); 516 mLogicalDisplayMapper.associateDisplayDeviceWithVirtualDevice(display6, deviceId2); 517 LogicalDisplay virtualDevice2Display3 = add(display6); 518 519 // Verify that the internal display is in the default display group. 520 assertEquals( 521 DEFAULT_DISPLAY_GROUP, 522 mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(defaultDisplay))); 523 524 // Verify that all the displays for virtual device 1 are in the same (non-default) display 525 // group. 526 int virtualDevice1DisplayGroupId = 527 mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked( 528 id(virtualDevice1Display1)); 529 assertNotEquals(DEFAULT_DISPLAY_GROUP, virtualDevice1DisplayGroupId); 530 assertEquals( 531 virtualDevice1DisplayGroupId, 532 mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked( 533 id(virtualDevice1Display2))); 534 assertEquals( 535 virtualDevice1DisplayGroupId, 536 mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked( 537 id(virtualDevice1Display3))); 538 539 // The first 2 displays for virtual device 2 should be in the same non-default group. 540 int virtualDevice2DisplayGroupId = 541 mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked( 542 id(virtualDevice2Display1)); 543 assertNotEquals(DEFAULT_DISPLAY_GROUP, virtualDevice2DisplayGroupId); 544 assertEquals( 545 virtualDevice2DisplayGroupId, 546 mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked( 547 id(virtualDevice2Display2))); 548 // virtualDevice2Display3 was created with FLAG_OWN_DISPLAY_GROUP and shouldn't be grouped 549 // with other displays of this device or be in the default display group. 550 assertNotEquals( 551 virtualDevice2DisplayGroupId, 552 mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked( 553 id(virtualDevice2Display3))); 554 assertNotEquals( 555 DEFAULT_DISPLAY_GROUP, 556 mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked( 557 id(virtualDevice2Display3))); 558 } 559 560 @Test testDeviceShouldBeWoken()561 public void testDeviceShouldBeWoken() { 562 assertTrue(mLogicalDisplayMapper.shouldDeviceBeWoken(DEVICE_STATE_OPEN, 563 DEVICE_STATE_CLOSED, 564 /* isInteractive= */false, 565 /* isBootCompleted= */true)); 566 } 567 568 @Test testDeviceShouldNotBeWoken()569 public void testDeviceShouldNotBeWoken() { 570 assertFalse(mLogicalDisplayMapper.shouldDeviceBeWoken(DEVICE_STATE_CLOSED, 571 DEVICE_STATE_OPEN, 572 /* isInteractive= */false, 573 /* isBootCompleted= */true)); 574 } 575 576 @Test testDeviceShouldBePutToSleep()577 public void testDeviceShouldBePutToSleep() { 578 assertTrue(mLogicalDisplayMapper.shouldDeviceBePutToSleep(DEVICE_STATE_CLOSED, 579 DEVICE_STATE_OPEN, 580 /* isOverrideActive= */false, 581 /* isInteractive= */true, 582 /* isBootCompleted= */true)); 583 } 584 585 @Test testDeviceShouldNotSleepWhenStayAwakeSettingTrue()586 public void testDeviceShouldNotSleepWhenStayAwakeSettingTrue() { 587 when(mFoldSettingProviderMock.shouldStayAwakeOnFold()).thenReturn(true); 588 589 assertFalse(mLogicalDisplayMapper.shouldDeviceBePutToSleep(DEVICE_STATE_CLOSED, 590 DEVICE_STATE_OPEN, 591 /* isOverrideActive= */false, 592 /* isInteractive= */true, 593 /* isBootCompleted= */true)); 594 } 595 596 @Test testDeviceShouldNotBePutToSleep()597 public void testDeviceShouldNotBePutToSleep() { 598 assertFalse(mLogicalDisplayMapper.shouldDeviceBePutToSleep(DEVICE_STATE_OPEN, 599 DEVICE_STATE_CLOSED, 600 /* isOverrideActive= */false, 601 /* isInteractive= */true, 602 /* isBootCompleted= */true)); 603 assertFalse(mLogicalDisplayMapper.shouldDeviceBePutToSleep(DEVICE_STATE_CLOSED, 604 INVALID_DEVICE_STATE, 605 /* isOverrideActive= */false, 606 /* isInteractive= */true, 607 /* isBootCompleted= */true)); 608 } 609 610 @Test testDeviceShouldNotBePutToSleepDifferentBaseState()611 public void testDeviceShouldNotBePutToSleepDifferentBaseState() { 612 assertFalse(mLogicalDisplayMapper.shouldDeviceBePutToSleep(DEVICE_STATE_CLOSED, 613 DEVICE_STATE_OPEN, 614 /* isOverrideActive= */true, 615 /* isInteractive= */true, 616 /* isBootCompleted= */true)); 617 } 618 619 @Test testDeviceShouldPutToSleepWhenSleepSettingTrue()620 public void testDeviceShouldPutToSleepWhenSleepSettingTrue() throws RemoteException { 621 when(mFoldSettingProviderMock.shouldSleepOnFold()).thenReturn(true); 622 623 finishBootAndFoldDevice(); 624 625 verify(mIPowerManagerMock, atLeastOnce()).goToSleep(anyLong(), anyInt(), 626 eq(FLAG_GO_TO_SLEEP_ON_FOLD)); 627 } 628 629 @Test testDeviceShouldNotBePutToSleepWhenSleepSettingFalse()630 public void testDeviceShouldNotBePutToSleepWhenSleepSettingFalse() throws RemoteException { 631 when(mFoldSettingProviderMock.shouldSleepOnFold()).thenReturn(false); 632 633 finishBootAndFoldDevice(); 634 635 verify(mIPowerManagerMock, never()).goToSleep(anyLong(), anyInt(), 636 eq(FLAG_GO_TO_SLEEP_ON_FOLD)); 637 } 638 639 @Test testDeviceStateLocked()640 public void testDeviceStateLocked() { 641 DisplayDevice device1 = createDisplayDevice(TYPE_INTERNAL, 600, 800, 642 FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY); 643 DisplayDevice device2 = createDisplayDevice(TYPE_INTERNAL, 600, 800, 644 FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY); 645 646 Layout layout = new Layout(); 647 layout.createDisplayLocked(device1.getDisplayDeviceInfoLocked().address, 648 /* isDefault= */ true, /* isEnabled= */ true, /* displayGroup= */ null, 649 mIdProducer, POSITION_UNKNOWN, 650 /* leadDisplayAddress= */ null, 651 /* brightnessThrottlingMapId= */ "concurrent", 652 /* refreshRateZoneId= */ null, /* refreshRateThermalThrottlingMapId= */ null); 653 layout.createDisplayLocked(device2.getDisplayDeviceInfoLocked().address, 654 /* isDefault= */ false, /* isEnabled= */ true, /* displayGroup= */ null, 655 mIdProducer, POSITION_UNKNOWN, 656 /* leadDisplayAddress= */ null, 657 /* brightnessThrottlingMapId= */ "concurrent", 658 /* refreshRateZoneId= */ null, /* refreshRateThermalThrottlingMapId= */ null); 659 when(mDeviceStateToLayoutMapSpy.get(0)).thenReturn(layout); 660 661 layout = new Layout(); 662 createNonDefaultDisplay(layout, device1, /* enabled= */ false, /* group= */ null); 663 createDefaultDisplay(layout, device2); 664 when(mDeviceStateToLayoutMapSpy.get(1)).thenReturn(layout); 665 when(mDeviceStateToLayoutMapSpy.get(2)).thenReturn(layout); 666 667 when(mDeviceStateToLayoutMapSpy.size()).thenReturn(4); 668 669 LogicalDisplay display1 = add(device1); 670 assertEquals(info(display1).address, info(device1).address); 671 assertEquals(DEFAULT_DISPLAY, id(display1)); 672 673 LogicalDisplay display2 = add(device2); 674 assertEquals(info(display2).address, info(device2).address); 675 // We can only have one default display 676 assertEquals(DEFAULT_DISPLAY, id(display1)); 677 678 mLogicalDisplayMapper.setDeviceStateLocked(0, false); 679 advanceTime(1000); 680 // The new state is not applied until the boot is completed 681 assertTrue(mLogicalDisplayMapper.getDisplayLocked(device1).isEnabledLocked()); 682 assertFalse(mLogicalDisplayMapper.getDisplayLocked(device2).isEnabledLocked()); 683 684 mLogicalDisplayMapper.onBootCompleted(); 685 advanceTime(1000); 686 assertTrue(mLogicalDisplayMapper.getDisplayLocked(device1).isEnabledLocked()); 687 assertTrue(mLogicalDisplayMapper.getDisplayLocked(device2).isEnabledLocked()); 688 assertFalse(mLogicalDisplayMapper.getDisplayLocked(device1).isInTransitionLocked()); 689 assertFalse(mLogicalDisplayMapper.getDisplayLocked(device2).isInTransitionLocked()); 690 assertEquals(-1, mLogicalDisplayMapper.getDisplayLocked(device1) 691 .getLeadDisplayIdLocked()); 692 assertEquals(-1, mLogicalDisplayMapper.getDisplayLocked(device2) 693 .getLeadDisplayIdLocked()); 694 assertEquals("concurrent", mLogicalDisplayMapper.getDisplayLocked(device1) 695 .getDisplayInfoLocked().thermalBrightnessThrottlingDataId); 696 assertEquals("concurrent", mLogicalDisplayMapper.getDisplayLocked(device2) 697 .getDisplayInfoLocked().thermalBrightnessThrottlingDataId); 698 699 mLogicalDisplayMapper.setDeviceStateLocked(1, false); 700 advanceTime(1000); 701 assertFalse(mLogicalDisplayMapper.getDisplayLocked(device1).isEnabledLocked()); 702 assertTrue(mLogicalDisplayMapper.getDisplayLocked(device2).isEnabledLocked()); 703 assertFalse(mLogicalDisplayMapper.getDisplayLocked(device1).isInTransitionLocked()); 704 assertFalse(mLogicalDisplayMapper.getDisplayLocked(device2).isInTransitionLocked()); 705 assertEquals(DisplayDeviceConfig.DEFAULT_ID, 706 mLogicalDisplayMapper.getDisplayLocked(device1) 707 .getDisplayInfoLocked().thermalBrightnessThrottlingDataId); 708 assertEquals(DisplayDeviceConfig.DEFAULT_ID, 709 mLogicalDisplayMapper.getDisplayLocked(device2) 710 .getDisplayInfoLocked().thermalBrightnessThrottlingDataId); 711 712 mLogicalDisplayMapper.setDeviceStateLocked(2, false); 713 advanceTime(1000); 714 assertFalse(mLogicalDisplayMapper.getDisplayLocked(device1).isEnabledLocked()); 715 assertTrue(mLogicalDisplayMapper.getDisplayLocked(device2).isEnabledLocked()); 716 assertFalse(mLogicalDisplayMapper.getDisplayLocked(device1).isInTransitionLocked()); 717 assertFalse(mLogicalDisplayMapper.getDisplayLocked(device2).isInTransitionLocked()); 718 assertEquals(DisplayDeviceConfig.DEFAULT_ID, 719 mLogicalDisplayMapper.getDisplayLocked(device1) 720 .getDisplayInfoLocked().thermalBrightnessThrottlingDataId); 721 assertEquals(DisplayDeviceConfig.DEFAULT_ID, 722 mLogicalDisplayMapper.getDisplayLocked(device2) 723 .getDisplayInfoLocked().thermalBrightnessThrottlingDataId); 724 } 725 726 @Test testEnabledAndDisabledDisplays()727 public void testEnabledAndDisabledDisplays() { 728 DisplayAddress displayAddressOne = new TestUtils.TestDisplayAddress(); 729 DisplayAddress displayAddressTwo = new TestUtils.TestDisplayAddress(); 730 DisplayAddress displayAddressThree = new TestUtils.TestDisplayAddress(); 731 732 TestDisplayDevice device1 = createDisplayDevice(displayAddressOne, "one", 733 TYPE_INTERNAL, 600, 800, DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY); 734 TestDisplayDevice device2 = createDisplayDevice(displayAddressTwo, "two", 735 TYPE_INTERNAL, 200, 800, DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP); 736 TestDisplayDevice device3 = createDisplayDevice(displayAddressThree, "three", 737 TYPE_INTERNAL, 600, 900, DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP); 738 739 Layout threeDevicesEnabledLayout = new Layout(); 740 createDefaultDisplay(threeDevicesEnabledLayout, displayAddressOne); 741 createNonDefaultDisplay(threeDevicesEnabledLayout, displayAddressTwo, 742 /* enabled= */ true, /* group= */ null); 743 createNonDefaultDisplay(threeDevicesEnabledLayout, displayAddressThree, 744 /* enabled= */ true, /* group= */ null); 745 746 when(mDeviceStateToLayoutMapSpy.get(STATE_DEFAULT)) 747 .thenReturn(threeDevicesEnabledLayout); 748 749 LogicalDisplay display1 = add(device1); 750 LogicalDisplay display2 = add(device2); 751 LogicalDisplay display3 = add(device3); 752 753 // ensure 3 displays are returned 754 int [] ids = mLogicalDisplayMapper.getDisplayIdsLocked(Process.SYSTEM_UID, false); 755 assertEquals(3, ids.length); 756 Arrays.sort(ids); 757 assertEquals(DEFAULT_DISPLAY, ids[0]); 758 assertNotNull(mLogicalDisplayMapper.getDisplayLocked(device1, 759 /* includeDisabled= */ false)); 760 assertNotNull(mLogicalDisplayMapper.getDisplayLocked(device2, 761 /* includeDisabled= */ false)); 762 assertNotNull(mLogicalDisplayMapper.getDisplayLocked(device3, 763 /* includeDisabled= */ false)); 764 assertNotNull(mLogicalDisplayMapper.getDisplayLocked( 765 threeDevicesEnabledLayout.getByAddress(displayAddressOne).getLogicalDisplayId(), 766 /* includeDisabled= */ false)); 767 assertNotNull(mLogicalDisplayMapper.getDisplayLocked( 768 threeDevicesEnabledLayout.getByAddress(displayAddressTwo).getLogicalDisplayId(), 769 /* includeDisabled= */ false)); 770 assertNotNull(mLogicalDisplayMapper.getDisplayLocked( 771 threeDevicesEnabledLayout.getByAddress(displayAddressThree).getLogicalDisplayId(), 772 /* includeDisabled= */ false)); 773 774 Layout oneDeviceEnabledLayout = new Layout(); 775 createDefaultDisplay(oneDeviceEnabledLayout, displayAddressOne); 776 createNonDefaultDisplay(oneDeviceEnabledLayout, displayAddressTwo, 777 /* enabled= */ false, /* group= */ null); 778 createNonDefaultDisplay(oneDeviceEnabledLayout, displayAddressThree, 779 /* enabled= */ false, /* group= */ null); 780 781 when(mDeviceStateToLayoutMapSpy.get(0)).thenReturn(oneDeviceEnabledLayout); 782 when(mDeviceStateToLayoutMapSpy.get(1)).thenReturn(threeDevicesEnabledLayout); 783 784 // 1) Set the new state 785 // 2) Mark the displays as STATE_OFF so that it can continue with transition 786 // 3) Send DISPLAY_DEVICE_EVENT_CHANGE to inform the mapper of the new display state 787 // 4) Dispatch handler events. 788 mLogicalDisplayMapper.onBootCompleted(); 789 mLogicalDisplayMapper.setDeviceStateLocked(0, false); 790 mDisplayDeviceRepo.onDisplayDeviceEvent(device3, DISPLAY_DEVICE_EVENT_CHANGED); 791 advanceTime(1000); 792 final int[] allDisplayIds = mLogicalDisplayMapper.getDisplayIdsLocked( 793 Process.SYSTEM_UID, false); 794 if (allDisplayIds.length != 1) { 795 throw new RuntimeException("Displays: \n" 796 + mLogicalDisplayMapper.getDisplayLocked(device1).toString() 797 + "\n" + mLogicalDisplayMapper.getDisplayLocked(device2).toString() 798 + "\n" + mLogicalDisplayMapper.getDisplayLocked(device3).toString()); 799 } 800 // ensure only one display is returned 801 assertEquals(1, allDisplayIds.length); 802 assertNotNull(mLogicalDisplayMapper.getDisplayLocked(device1, 803 /* includeDisabled= */ false)); 804 assertNull(mLogicalDisplayMapper.getDisplayLocked(device2, 805 /* includeDisabled= */ false)); 806 assertNull(mLogicalDisplayMapper.getDisplayLocked(device3, 807 /* includeDisabled= */ false)); 808 assertNotNull(mLogicalDisplayMapper.getDisplayLocked( 809 oneDeviceEnabledLayout.getByAddress(displayAddressOne).getLogicalDisplayId(), 810 /* includeDisabled= */ false)); 811 assertNull(mLogicalDisplayMapper.getDisplayLocked( 812 oneDeviceEnabledLayout.getByAddress(displayAddressTwo).getLogicalDisplayId(), 813 /* includeDisabled= */ false)); 814 assertNull(mLogicalDisplayMapper.getDisplayLocked( 815 oneDeviceEnabledLayout.getByAddress(displayAddressThree).getLogicalDisplayId(), 816 /* includeDisabled= */ false)); 817 818 // Now do it again to go back to state 1 819 mLogicalDisplayMapper.setDeviceStateLocked(1, false); 820 mDisplayDeviceRepo.onDisplayDeviceEvent(device3, DISPLAY_DEVICE_EVENT_CHANGED); 821 advanceTime(1000); 822 final int[] threeDisplaysEnabled = mLogicalDisplayMapper.getDisplayIdsLocked( 823 Process.SYSTEM_UID, false); 824 825 // ensure all three displays are returned 826 assertEquals(3, threeDisplaysEnabled.length); 827 } 828 829 @Test testCreateNewLogicalDisplay()830 public void testCreateNewLogicalDisplay() { 831 DisplayDevice device1 = createDisplayDevice(TYPE_EXTERNAL, 600, 800, 832 FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY); 833 when(mDeviceStateToLayoutMapSpy.size()).thenReturn(1); 834 LogicalDisplay display1 = add(device1); 835 836 assertTrue(display1.isEnabledLocked()); 837 838 DisplayDevice device2 = createDisplayDevice(TYPE_INTERNAL, 600, 800, 839 FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY); 840 when(mDeviceStateToLayoutMapSpy.size()).thenReturn(2); 841 LogicalDisplay display2 = add(device2); 842 843 assertFalse(display2.isEnabledLocked()); 844 } 845 @Test testDisplayFlagRear()846 public void testDisplayFlagRear() { 847 DisplayDevice device1 = createDisplayDevice(TYPE_INTERNAL, 600, 800, 848 FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY); 849 DisplayDevice device2 = createDisplayDevice(TYPE_INTERNAL, 600, 800, 850 FLAG_REAR); 851 852 Layout layout = new Layout(); 853 layout.createDefaultDisplayLocked(device1.getDisplayDeviceInfoLocked().address, 854 mIdProducer); 855 layout.createDisplayLocked(device2.getDisplayDeviceInfoLocked().address, 856 /* isDefault= */ false, /* isEnabled= */ true, /* displayGroupName= */ null, 857 mIdProducer, POSITION_REAR, /* leadDisplayAddress= */ null, 858 /* brightnessThrottlingMapId= */ null, /* refreshRateZoneId= */ null, 859 /* refreshRateThermalThrottlingMapId= */null); 860 when(mDeviceStateToLayoutMapSpy.get(0)).thenReturn(layout); 861 862 when(mDeviceStateToLayoutMapSpy.size()).thenReturn(1); 863 864 LogicalDisplay display1 = add(device1); 865 assertEquals(info(display1).address, info(device1).address); 866 assertEquals(DEFAULT_DISPLAY, id(display1)); 867 868 LogicalDisplay display2 = add(device2); 869 assertEquals(info(display2).address, info(device2).address); 870 // We can only have one default display 871 assertEquals(DEFAULT_DISPLAY, id(display1)); 872 873 mLogicalDisplayMapper.setDeviceStateLocked(0, false); 874 advanceTime(1000); 875 mLogicalDisplayMapper.onBootCompleted(); 876 advanceTime(1000); 877 878 assertTrue(mLogicalDisplayMapper.getDisplayLocked(device1).isEnabledLocked()); 879 assertTrue(mLogicalDisplayMapper.getDisplayLocked(device2).isEnabledLocked()); 880 881 assertEquals(POSITION_UNKNOWN, 882 mLogicalDisplayMapper.getDisplayLocked(device1).getDevicePositionLocked()); 883 assertEquals(POSITION_REAR, 884 mLogicalDisplayMapper.getDisplayLocked(device2).getDevicePositionLocked()); 885 } 886 887 ///////////////// 888 // Helper Methods 889 ///////////////// 890 finishBootAndFoldDevice()891 private void finishBootAndFoldDevice() { 892 mLogicalDisplayMapper.setDeviceStateLocked(DEVICE_STATE_OPEN, false); 893 advanceTime(1000); 894 mLogicalDisplayMapper.onBootCompleted(); 895 advanceTime(1000); 896 mLogicalDisplayMapper.setDeviceStateLocked(DEVICE_STATE_CLOSED, false); 897 advanceTime(1000); 898 } 899 createDefaultDisplay(Layout layout, DisplayDevice device)900 private void createDefaultDisplay(Layout layout, DisplayDevice device) { 901 createDefaultDisplay(layout, info(device).address); 902 } 903 createDefaultDisplay(Layout layout, DisplayAddress address)904 private void createDefaultDisplay(Layout layout, DisplayAddress address) { 905 layout.createDefaultDisplayLocked(address, mIdProducer); 906 } 907 createNonDefaultDisplay(Layout layout, DisplayDevice device, boolean enabled, String group)908 private void createNonDefaultDisplay(Layout layout, DisplayDevice device, boolean enabled, 909 String group) { 910 createNonDefaultDisplay(layout, info(device).address, enabled, group); 911 } 912 createNonDefaultDisplay(Layout layout, DisplayAddress address, boolean enabled, String group)913 private void createNonDefaultDisplay(Layout layout, DisplayAddress address, boolean enabled, 914 String group) { 915 layout.createDisplayLocked(address, /* isDefault= */ false, enabled, group, mIdProducer, 916 Layout.Display.POSITION_UNKNOWN, /* leadDisplayAddress= */ null, 917 /* brightnessThrottlingMapId= */ null, /* refreshRateZoneId= */ null, 918 /* refreshRateThermalThrottlingMapId= */ null); 919 } 920 advanceTime(long timeMs)921 private void advanceTime(long timeMs) { 922 mLooper.moveTimeForward(1000); 923 mLooper.dispatchAll(); 924 } 925 createDisplayDevice(int type, int width, int height, int flags)926 private TestDisplayDevice createDisplayDevice(int type, int width, int height, int flags) { 927 return createDisplayDevice( 928 new TestUtils.TestDisplayAddress(), /* uniqueId */ "", type, width, height, flags); 929 } 930 createDisplayDevice( int type, String uniqueId, int width, int height, int flags)931 private TestDisplayDevice createDisplayDevice( 932 int type, String uniqueId, int width, int height, int flags) { 933 return createDisplayDevice( 934 new TestUtils.TestDisplayAddress(), uniqueId, type, width, height, flags); 935 } 936 createDisplayDevice( DisplayAddress address, String uniqueId, int type, int width, int height, int flags)937 private TestDisplayDevice createDisplayDevice( 938 DisplayAddress address, String uniqueId, int type, int width, int height, int flags) { 939 TestDisplayDevice device = new TestDisplayDevice(); 940 DisplayDeviceInfo displayDeviceInfo = device.getSourceInfo(); 941 displayDeviceInfo.type = type; 942 displayDeviceInfo.uniqueId = uniqueId; 943 displayDeviceInfo.width = width; 944 displayDeviceInfo.height = height; 945 displayDeviceInfo.flags = flags; 946 displayDeviceInfo.supportedModes = new Display.Mode[1]; 947 displayDeviceInfo.supportedModes[0] = new Display.Mode(1, width, height, 60f); 948 displayDeviceInfo.modeId = 1; 949 displayDeviceInfo.address = address; 950 return device; 951 } 952 info(DisplayDevice device)953 private DisplayDeviceInfo info(DisplayDevice device) { 954 return device.getDisplayDeviceInfoLocked(); 955 } 956 width(DisplayDevice device)957 private int width(DisplayDevice device) { 958 return info(device).width; 959 } 960 height(DisplayDevice device)961 private int height(DisplayDevice device) { 962 return info(device).height; 963 } 964 info(LogicalDisplay display)965 private DisplayInfo info(LogicalDisplay display) { 966 return display.getDisplayInfoLocked(); 967 } 968 id(LogicalDisplay display)969 private int id(LogicalDisplay display) { 970 return display.getDisplayIdLocked(); 971 } 972 add(DisplayDevice device)973 private LogicalDisplay add(DisplayDevice device) { 974 mDisplayDeviceRepo.onDisplayDeviceEvent(device, DISPLAY_DEVICE_EVENT_ADDED); 975 ArgumentCaptor<LogicalDisplay> displayCaptor = 976 ArgumentCaptor.forClass(LogicalDisplay.class); 977 verify(mListenerMock).onLogicalDisplayEventLocked( 978 displayCaptor.capture(), eq(LOGICAL_DISPLAY_EVENT_ADDED)); 979 clearInvocations(mListenerMock); 980 return displayCaptor.getValue(); 981 } 982 testDisplayDeviceAddAndRemove_NonInternal(int type)983 private void testDisplayDeviceAddAndRemove_NonInternal(int type) { 984 DisplayDevice device = createDisplayDevice(type, 600, 800, 0); 985 986 // add 987 LogicalDisplay displayAdded = add(device); 988 assertEquals(info(displayAdded).address, info(device).address); 989 assertNotEquals(DEFAULT_DISPLAY, id(displayAdded)); 990 991 // remove 992 mDisplayDeviceRepo.onDisplayDeviceEvent(device, DISPLAY_DEVICE_EVENT_REMOVED); 993 verify(mListenerMock).onLogicalDisplayEventLocked( 994 mDisplayCaptor.capture(), eq(LOGICAL_DISPLAY_EVENT_REMOVED)); 995 LogicalDisplay displayRemoved = mDisplayCaptor.getValue(); 996 assertNotEquals(DEFAULT_DISPLAY, id(displayRemoved)); 997 } 998 999 class TestDisplayDevice extends DisplayDevice { 1000 private DisplayDeviceInfo mInfo; 1001 private DisplayDeviceInfo mSentInfo; 1002 private int mState; 1003 TestDisplayDevice()1004 TestDisplayDevice() { 1005 super(null, null, "test_display_" + sUniqueTestDisplayId++, mContextMock); 1006 mInfo = new DisplayDeviceInfo(); 1007 } 1008 1009 @Override getDisplayDeviceInfoLocked()1010 public DisplayDeviceInfo getDisplayDeviceInfoLocked() { 1011 if (mSentInfo == null) { 1012 mSentInfo = new DisplayDeviceInfo(); 1013 mSentInfo.copyFrom(mInfo); 1014 } 1015 return mSentInfo; 1016 } 1017 1018 @Override applyPendingDisplayDeviceInfoChangesLocked()1019 public void applyPendingDisplayDeviceInfoChangesLocked() { 1020 mSentInfo = null; 1021 } 1022 1023 @Override hasStableUniqueId()1024 public boolean hasStableUniqueId() { 1025 return true; 1026 } 1027 getSourceInfo()1028 public DisplayDeviceInfo getSourceInfo() { 1029 return mInfo; 1030 } 1031 } 1032 } 1033