Merge "Revert "Revert "Do not send updates for disabled displays.""" into tm-dev
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index b505395..69c6ba9 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -559,18 +559,21 @@
* @see #DISPLAY_CATEGORY_PRESENTATION
*/
public Display[] getDisplays(String category) {
- final int[] displayIds = mGlobal.getDisplayIds();
+ boolean includeDisabledDisplays = (category != null
+ && category.equals(DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED));
+ final int[] displayIds = mGlobal.getDisplayIds(includeDisabledDisplays);
synchronized (mLock) {
try {
- if (category == null
- || DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED.equals(category)) {
- addAllDisplaysLocked(mTempDisplays, displayIds);
- } else if (category.equals(DISPLAY_CATEGORY_PRESENTATION)) {
+ if (category != null && category.equals(DISPLAY_CATEGORY_PRESENTATION)) {
addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_WIFI);
addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_EXTERNAL);
addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_OVERLAY);
addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_VIRTUAL);
addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_INTERNAL);
+ } else if ((category == null
+ || DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED.equals(category))) {
+ // All displays requested.
+ addAllDisplaysLocked(mTempDisplays, displayIds);
}
return mTempDisplays.toArray(new Display[mTempDisplays.size()]);
} finally {
diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java
index 74356dd..da3a580 100644
--- a/core/java/android/hardware/display/DisplayManagerGlobal.java
+++ b/core/java/android/hardware/display/DisplayManagerGlobal.java
@@ -206,6 +206,16 @@
*/
@UnsupportedAppUsage
public int[] getDisplayIds() {
+ return getDisplayIds(/* includeDisabledDisplays= */ false);
+ }
+
+ /**
+ * Gets all valid logical display ids and invalid ones if specified.
+ *
+ * @return An array containing all display ids.
+ */
+ @UnsupportedAppUsage
+ public int[] getDisplayIds(boolean includeDisabledDisplays) {
try {
synchronized (mLock) {
if (USE_CACHE) {
@@ -214,7 +224,8 @@
}
}
- int[] displayIds = mDm.getDisplayIds();
+ int[] displayIds =
+ mDm.getDisplayIds(includeDisabledDisplays);
if (USE_CACHE) {
mDisplayIdCache = displayIds;
}
diff --git a/core/java/android/hardware/display/IDisplayManager.aidl b/core/java/android/hardware/display/IDisplayManager.aidl
index ca3e580..a4115d1 100644
--- a/core/java/android/hardware/display/IDisplayManager.aidl
+++ b/core/java/android/hardware/display/IDisplayManager.aidl
@@ -36,7 +36,7 @@
interface IDisplayManager {
@UnsupportedAppUsage
DisplayInfo getDisplayInfo(int displayId);
- int[] getDisplayIds();
+ int[] getDisplayIds(boolean includeDisabled);
boolean isUidPresentOnDisplay(int uid, int displayId);
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 6285ef1..d3e2966 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -485,7 +485,7 @@
mUiHandler = UiThread.getHandler();
mDisplayDeviceRepo = new DisplayDeviceRepository(mSyncRoot, mPersistentDataStore);
mLogicalDisplayMapper = new LogicalDisplayMapper(mContext, mDisplayDeviceRepo,
- new LogicalDisplayListener(), mSyncRoot, mHandler);
+ new LogicalDisplayListener(), mSyncRoot, mHandler, new DeviceStateToLayoutMap());
mDisplayModeDirector = new DisplayModeDirector(context, mHandler);
mBrightnessSynchronizer = new BrightnessSynchronizer(mContext);
Resources resources = mContext.getResources();
@@ -945,7 +945,8 @@
private DisplayInfo getDisplayInfoInternal(int displayId, int callingUid) {
synchronized (mSyncRoot) {
- final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId);
+ final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId,
+ /* includeDisabledDisplays= */ true);
if (display != null) {
final DisplayInfo info =
getDisplayInfoForFrameRateOverride(display.getFrameRateOverrides(),
@@ -2128,16 +2129,18 @@
}
void resetBrightnessConfigurations() {
- mPersistentDataStore.setBrightnessConfigurationForUser(null, mContext.getUserId(),
- mContext.getPackageName());
- mLogicalDisplayMapper.forEachLocked((logicalDisplay -> {
- if (logicalDisplay.getDisplayInfoLocked().type != Display.TYPE_INTERNAL) {
- return;
- }
- final String uniqueId = logicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId();
- setBrightnessConfigurationForDisplayInternal(null, uniqueId, mContext.getUserId(),
+ synchronized (mSyncRoot) {
+ mPersistentDataStore.setBrightnessConfigurationForUser(null, mContext.getUserId(),
mContext.getPackageName());
- }));
+ mLogicalDisplayMapper.forEachLocked((logicalDisplay -> {
+ if (logicalDisplay.getDisplayInfoLocked().type != Display.TYPE_INTERNAL) {
+ return;
+ }
+ String uniqueId = logicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId();
+ setBrightnessConfigurationForDisplayInternal(null, uniqueId, mContext.getUserId(),
+ mContext.getPackageName());
+ }));
+ }
}
void setAutoBrightnessLoggingEnabled(boolean enabled) {
@@ -2814,15 +2817,16 @@
}
/**
- * Returns the list of all display ids.
+ * Returns the list of all enabled display ids, and disabled ones if specified.
*/
@Override // Binder call
- public int[] getDisplayIds() {
+ public int[] getDisplayIds(boolean includeDisabledDisplays) {
final int callingUid = Binder.getCallingUid();
final long token = Binder.clearCallingIdentity();
try {
synchronized (mSyncRoot) {
- return mLogicalDisplayMapper.getDisplayIdsLocked(callingUid);
+ return mLogicalDisplayMapper.getDisplayIdsLocked(callingUid,
+ includeDisabledDisplays);
}
} finally {
Binder.restoreCallingIdentity(token);
diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
index 70c9e23..34e8e75 100644
--- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java
+++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
@@ -79,8 +79,12 @@
private static final int MSG_TRANSITION_TO_PENDING_DEVICE_STATE = 1;
private static final int UPDATE_STATE_NEW = 0;
- private static final int UPDATE_STATE_TRANSITION = 1;
- private static final int UPDATE_STATE_UPDATED = 2;
+ private static final int UPDATE_STATE_UPDATED = 1;
+ private static final int UPDATE_STATE_DISABLED = 2;
+
+ private static final int UPDATE_STATE_MASK = 0x3;
+
+ private static final int UPDATE_STATE_FLAG_TRANSITION = 0x100;
/**
* Temporary display info, used for comparing display configurations.
@@ -166,7 +170,7 @@
LogicalDisplayMapper(@NonNull Context context, @NonNull DisplayDeviceRepository repo,
@NonNull Listener listener, @NonNull DisplayManagerService.SyncRoot syncRoot,
- @NonNull Handler handler) {
+ @NonNull Handler handler, @NonNull DeviceStateToLayoutMap deviceStateToLayoutMap) {
mSyncRoot = syncRoot;
mPowerManager = context.getSystemService(PowerManager.class);
mInteractive = mPowerManager.isInteractive();
@@ -181,7 +185,7 @@
mDeviceStatesOnWhichToSleep = toSparseBooleanArray(context.getResources().getIntArray(
com.android.internal.R.array.config_deviceStatesOnWhichToSleep));
mDisplayDeviceRepo.addListener(this);
- mDeviceStateToLayoutMap = new DeviceStateToLayoutMap();
+ mDeviceStateToLayoutMap = deviceStateToLayoutMap;
}
@Override
@@ -218,10 +222,29 @@
}
public LogicalDisplay getDisplayLocked(int displayId) {
- return mLogicalDisplays.get(displayId);
+ return getDisplayLocked(displayId, /* includeDisabled= */ false);
+ }
+
+ LogicalDisplay getDisplayLocked(int displayId, boolean includeDisabled) {
+ LogicalDisplay display = mLogicalDisplays.get(displayId);
+ if (display != null && (display.isEnabled() || includeDisabled)) {
+ return display;
+ }
+ return null;
}
public LogicalDisplay getDisplayLocked(DisplayDevice device) {
+ return getDisplayLocked(device, /* includeDisabled= */ false);
+ }
+
+ /**
+ * Loops through the existing list of displays and returns one that is associated with the
+ * specified display device.
+ *
+ * @param device The display device that should be associated with the LogicalDisplay.
+ * @param includeDisabled True if this method should return disabled displays as well.
+ */
+ private LogicalDisplay getDisplayLocked(DisplayDevice device, boolean includeDisabled) {
if (device == null) {
return null;
}
@@ -229,18 +252,32 @@
for (int i = 0; i < count; i++) {
final LogicalDisplay display = mLogicalDisplays.valueAt(i);
if (display.getPrimaryDisplayDeviceLocked() == device) {
- return display;
+ if (display.isEnabled() || includeDisabled) {
+ return display;
+ } else {
+ return null;
+ }
}
}
return null;
}
+ // Returns display Ids, defaults to enabled only.
public int[] getDisplayIdsLocked(int callingUid) {
+ return getDisplayIdsLocked(callingUid, /* includeDisabledDisplays= */ false);
+ }
+
+ // Returns display Ids, specified whether enabled only, or all displays.
+ public int[] getDisplayIdsLocked(int callingUid, boolean includeDisabledDisplays) {
final int count = mLogicalDisplays.size();
int[] displayIds = new int[count];
int n = 0;
for (int i = 0; i < count; i++) {
LogicalDisplay display = mLogicalDisplays.valueAt(i);
+ if (!includeDisabledDisplays && !display.isEnabled()) {
+ continue; // Ignore disabled displays.
+ }
+
DisplayInfo info = display.getDisplayInfoLocked();
if (info.hasAccess(callingUid)) {
displayIds[n++] = mLogicalDisplays.keyAt(i);
@@ -255,7 +292,10 @@
public void forEachLocked(Consumer<LogicalDisplay> consumer) {
final int count = mLogicalDisplays.size();
for (int i = 0; i < count; i++) {
- consumer.accept(mLogicalDisplays.valueAt(i));
+ LogicalDisplay display = mLogicalDisplays.valueAt(i);
+ if (display.isEnabled()) {
+ consumer.accept(display);
+ }
}
}
@@ -316,7 +356,8 @@
// Find or create the LogicalDisplay to map the DisplayDevice to.
final int logicalDisplayId = displayLayout.getLogicalDisplayId();
- final LogicalDisplay logicalDisplay = getDisplayLocked(logicalDisplayId);
+ final LogicalDisplay logicalDisplay =
+ getDisplayLocked(logicalDisplayId, /* includeDisabled= */ true);
if (logicalDisplay == null) {
Slog.w(TAG, "The logical display (" + address + "), is not available"
+ " for the display state " + deviceState);
@@ -452,7 +493,7 @@
}
/**
- * Returns if the device should be put to sleep or not.
+ * Returns true if the device should be put to sleep or not.
*
* Includes a check to verify that the device state that we are moving to, {@code pendingState},
* is the same as the physical state of the device, {@code baseState}. Different values for
@@ -598,9 +639,12 @@
display.getNonOverrideDisplayInfoLocked(mTempNonOverrideDisplayInfo);
display.updateLocked(mDisplayDeviceRepo);
- final DisplayInfo newDisplayInfo = display.getDisplayInfoLocked();
- final int updateState = mUpdatedLogicalDisplays.get(displayId, UPDATE_STATE_NEW);
- final boolean wasPreviouslyUpdated = updateState != UPDATE_STATE_NEW;
+ DisplayInfo newDisplayInfo = display.getDisplayInfoLocked();
+
+ final int storedState = mUpdatedLogicalDisplays.get(displayId, UPDATE_STATE_NEW);
+ final int updateState = storedState & UPDATE_STATE_MASK;
+ final boolean isTransitioning = (storedState & UPDATE_STATE_FLAG_TRANSITION) != 0;
+ final boolean wasPreviouslyUpdated = updateState == UPDATE_STATE_UPDATED;
// The display is no longer valid and needs to be removed.
if (!display.isValidLocked()) {
@@ -624,6 +668,35 @@
}
continue;
+ // The display has been newly disabled, we report this as a removed display but
+ // don't actually remove it from our internal list in LogicalDisplayMapper. The reason
+ // is that LogicalDisplayMapper assumes and relies on the fact that every DisplayDevice
+ // has a LogicalDisplay wrapper, but certain displays that are unusable (like the inner
+ // display on a folded foldable device) are not available for use by the system and
+ // we keep them hidden. To do this, we mark those LogicalDisplays as "disabled".
+ // Also, if the display is in TRANSITION but was previously reported as disabled
+ // then keep it unreported.
+ } else if (!display.isEnabled()
+ || (display.getPhase() == LogicalDisplay.DISPLAY_PHASE_LAYOUT_TRANSITION
+ && updateState == UPDATE_STATE_DISABLED)) {
+ mUpdatedLogicalDisplays.put(displayId, UPDATE_STATE_DISABLED);
+
+ // If we never told anyone about this display, nothing to do
+ if (!wasPreviouslyUpdated) {
+ continue;
+ }
+
+ // Remove from group
+ final DisplayGroup displayGroup = getDisplayGroupLocked(
+ getDisplayGroupIdFromDisplayIdLocked(displayId));
+ if (displayGroup != null) {
+ displayGroup.removeDisplayLocked(display);
+ }
+
+ Slog.i(TAG, "Removing (disabled) display: " + displayId);
+ mLogicalDisplaysToUpdate.put(displayId, LOGICAL_DISPLAY_EVENT_REMOVED);
+ continue;
+
// The display is new.
} else if (!wasPreviouslyUpdated) {
Slog.i(TAG, "Adding new display: " + displayId + ": " + newDisplayInfo);
@@ -643,7 +716,7 @@
mLogicalDisplaysToUpdate.put(displayId, LOGICAL_DISPLAY_EVENT_CHANGED);
// The display is involved in a display layout transition
- } else if (updateState == UPDATE_STATE_TRANSITION) {
+ } else if (isTransitioning) {
mLogicalDisplaysToUpdate.put(displayId,
LOGICAL_DISPLAY_EVENT_DEVICE_STATE_TRANSITION);
@@ -717,7 +790,7 @@
}
final int id = mLogicalDisplaysToUpdate.keyAt(i);
- final LogicalDisplay display = getDisplayLocked(id);
+ final LogicalDisplay display = getDisplayLocked(id, /* includeDisabled= */ true);
if (DEBUG) {
final DisplayDevice device = display.getPrimaryDisplayDeviceLocked();
final String uniqueId = device == null ? "null" : device.getUniqueId();
@@ -725,7 +798,7 @@
+ " with device=" + uniqueId);
}
mListener.onLogicalDisplayEventLocked(display, msg);
- if (msg == LOGICAL_DISPLAY_EVENT_REMOVED) {
+ if (msg == LOGICAL_DISPLAY_EVENT_REMOVED && !display.isValidLocked()) {
// We wait until we sent the EVENT_REMOVED event before actually removing the
// display.
mLogicalDisplays.delete(id);
@@ -845,7 +918,8 @@
if (isTransitioning) {
setDisplayPhase(logicalDisplay, phase);
if (phase == LogicalDisplay.DISPLAY_PHASE_LAYOUT_TRANSITION) {
- mUpdatedLogicalDisplays.put(displayId, UPDATE_STATE_TRANSITION);
+ int oldState = mUpdatedLogicalDisplays.get(displayId, UPDATE_STATE_NEW);
+ mUpdatedLogicalDisplays.put(displayId, oldState | UPDATE_STATE_FLAG_TRANSITION);
}
}
}
@@ -879,14 +953,15 @@
// Now that we have a display-device, we need a LogicalDisplay to map it to. Find the
// right one, if it doesn't exist, create a new one.
final int logicalDisplayId = displayLayout.getLogicalDisplayId();
- LogicalDisplay newDisplay = getDisplayLocked(logicalDisplayId);
+ LogicalDisplay newDisplay =
+ getDisplayLocked(logicalDisplayId, /* includeDisabled= */ true);
if (newDisplay == null) {
newDisplay = createNewLogicalDisplayLocked(
- null /*displayDevice*/, logicalDisplayId);
+ /* displayDevice= */ null, logicalDisplayId);
}
// Now swap the underlying display devices between the old display and the new display
- final LogicalDisplay oldDisplay = getDisplayLocked(device);
+ final LogicalDisplay oldDisplay = getDisplayLocked(device, /* includeDisabled= */ true);
if (newDisplay != oldDisplay) {
newDisplay.swapDisplaysLocked(oldDisplay);
}
@@ -903,13 +978,14 @@
* Creates a new logical display for the specified device and display Id and adds it to the list
* of logical displays.
*
- * @param device The device to associate with the LogicalDisplay.
+ * @param displayDevice The displayDevice to associate with the LogicalDisplay.
* @param displayId The display ID to give the new display. If invalid, a new ID is assigned.
* @return The new logical display if created, null otherwise.
*/
- private LogicalDisplay createNewLogicalDisplayLocked(DisplayDevice device, int displayId) {
+ private LogicalDisplay createNewLogicalDisplayLocked(DisplayDevice displayDevice,
+ int displayId) {
final int layerStack = assignLayerStackLocked(displayId);
- final LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device);
+ final LogicalDisplay display = new LogicalDisplay(displayId, layerStack, displayDevice);
display.updateLocked(mDisplayDeviceRepo);
mLogicalDisplays.put(displayId, display);
setDisplayPhase(display, LogicalDisplay.DISPLAY_PHASE_ENABLED);
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
index 1e97c1c..5f1ff6b 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -287,7 +287,7 @@
when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
- final int displayIds[] = bs.getDisplayIds();
+ final int[] displayIds = bs.getDisplayIds(/* includeDisabled= */ false);
final int size = displayIds.length;
assertTrue(size > 0);
@@ -297,7 +297,9 @@
);
for (int i = 0; i < size; i++) {
DisplayInfo info = bs.getDisplayInfo(displayIds[i]);
- assertTrue(expectedDisplayTypeToViewPortTypeMapping.keySet().contains(info.type));
+ if (info != null) {
+ assertTrue(expectedDisplayTypeToViewPortTypeMapping.keySet().contains(info.type));
+ }
}
displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
@@ -1174,7 +1176,8 @@
DisplayManagerService.BinderService displayManagerBinderService,
FakeDisplayDevice displayDevice) {
- final int[] displayIds = displayManagerBinderService.getDisplayIds();
+ final int[] displayIds = displayManagerBinderService.getDisplayIds(
+ /* includeDisabled= */ false);
assertTrue(displayIds.length > 0);
int displayId = Display.INVALID_DISPLAY;
for (int i = 0; i < displayIds.length; i++) {
diff --git a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java
index cc68ba8..5b13145 100644
--- a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java
@@ -33,6 +33,7 @@
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -53,6 +54,8 @@
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.server.display.layout.Layout;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -79,6 +82,7 @@
private TestLooper mLooper;
private Handler mHandler;
private PowerManager mPowerManager;
+ private DeviceStateToLayoutMap mDeviceStateToLayoutMapSpy;
@Mock LogicalDisplayMapper.Listener mListenerMock;
@Mock Context mContextMock;
@@ -133,8 +137,11 @@
mLooper = new TestLooper();
mHandler = new Handler(mLooper.getLooper());
+
+ mDeviceStateToLayoutMapSpy = spy(new DeviceStateToLayoutMap());
mLogicalDisplayMapper = new LogicalDisplayMapper(mContextMock, mDisplayDeviceRepo,
- mListenerMock, new DisplayManagerService.SyncRoot(), mHandler);
+ mListenerMock, new DisplayManagerService.SyncRoot(), mHandler,
+ mDeviceStateToLayoutMapSpy);
}
@@ -413,6 +420,86 @@
/* isBootCompleted= */true));
}
+ @Test public void testEnabledAndDisabledDisplays() {
+ DisplayAddress displayAddressOne = new TestUtils.TestDisplayAddress();
+ DisplayAddress displayAddressTwo = new TestUtils.TestDisplayAddress();
+ DisplayAddress displayAddressThree = new TestUtils.TestDisplayAddress();
+
+ TestDisplayDevice device1 = createDisplayDevice(displayAddressOne, Display.TYPE_INTERNAL,
+ 600, 800,
+ DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
+ TestDisplayDevice device2 = createDisplayDevice(displayAddressTwo, Display.TYPE_INTERNAL,
+ 200, 800,
+ DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP);
+ TestDisplayDevice device3 = createDisplayDevice(displayAddressThree, Display.TYPE_INTERNAL,
+ 600, 900, DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP);
+
+ Layout threeDevicesEnabledLayout = new Layout();
+ threeDevicesEnabledLayout.createDisplayLocked(
+ displayAddressOne,
+ /* isDefault= */ true,
+ /* isEnabled= */ true);
+
+ threeDevicesEnabledLayout.createDisplayLocked(
+ displayAddressTwo,
+ /* isDefault= */ false,
+ /* isEnabled= */ true);
+ threeDevicesEnabledLayout.createDisplayLocked(
+ displayAddressThree,
+ /* isDefault= */ false,
+ /* isEnabled= */ true);
+
+ when(mDeviceStateToLayoutMapSpy.get(DeviceStateToLayoutMap.STATE_DEFAULT))
+ .thenReturn(threeDevicesEnabledLayout);
+
+ LogicalDisplay display1 = add(device1);
+ LogicalDisplay display2 = add(device2);
+ LogicalDisplay display3 = add(device3);
+
+ // ensure 3 displays are returned
+ int [] ids = mLogicalDisplayMapper.getDisplayIdsLocked(Process.SYSTEM_UID);
+ assertEquals(3, ids.length);
+ Arrays.sort(ids);
+ assertEquals(DEFAULT_DISPLAY, ids[0]);
+
+ Layout oneDeviceEnabledLayout = new Layout();
+ oneDeviceEnabledLayout.createDisplayLocked(
+ display1.getDisplayInfoLocked().address,
+ /* isDefault= */ true,
+ /* isEnabled= */ true);
+ oneDeviceEnabledLayout.createDisplayLocked(
+ display2.getDisplayInfoLocked().address,
+ /* isDefault= */ false,
+ /* isEnabled= */ false);
+ oneDeviceEnabledLayout.createDisplayLocked(
+ display3.getDisplayInfoLocked().address,
+ /* isDefault= */ false,
+ /* isEnabled= */ false);
+
+ when(mDeviceStateToLayoutMapSpy.get(0)).thenReturn(oneDeviceEnabledLayout);
+ when(mDeviceStateToLayoutMapSpy.get(1)).thenReturn(threeDevicesEnabledLayout);
+
+ mLogicalDisplayMapper
+ .setDeviceStateLocked(0, false);
+ mDisplayDeviceRepo.onDisplayDeviceEvent(device3, DISPLAY_DEVICE_EVENT_CHANGED);
+ final int[] allDisplayIds = mLogicalDisplayMapper.getDisplayIdsLocked(
+ Process.SYSTEM_UID, false);
+ mLooper.dispatchAll();
+
+ // ensure only one display is returned
+ assertEquals(1, allDisplayIds.length);
+
+ mLogicalDisplayMapper
+ .setDeviceStateLocked(1, false);
+ mDisplayDeviceRepo.onDisplayDeviceEvent(device3, DISPLAY_DEVICE_EVENT_CHANGED);
+ final int[] threeDisplaysEnabled = mLogicalDisplayMapper.getDisplayIdsLocked(
+ Process.SYSTEM_UID, false);
+ mLooper.dispatchAll();
+
+ // ensure all three displays are returned
+ assertEquals(3, threeDisplaysEnabled.length);
+ }
+
/////////////////
// Helper Methods
/////////////////