Loading services/core/java/com/android/server/display/DisplayTopologyCoordinator.java +23 −2 Original line number Original line Diff line number Diff line Loading @@ -250,8 +250,29 @@ class DisplayTopologyCoordinator { } } private boolean isDisplayAllowedInTopology(DisplayInfo info) { private boolean isDisplayAllowedInTopology(DisplayInfo info) { return mIsExtendedDisplayEnabled.getAsBoolean() if (info.type != Display.TYPE_INTERNAL && info.type != Display.TYPE_EXTERNAL && info.displayGroupId == Display.DEFAULT_DISPLAY_GROUP; && info.type != Display.TYPE_OVERLAY) { Slog.d(TAG, "Display " + info.displayId + " not allowed in topology because " + "type is not INTERNAL, EXTERNAL or OVERLAY"); return false; } if (info.type == Display.TYPE_INTERNAL && info.displayId != Display.DEFAULT_DISPLAY) { Slog.d(TAG, "Display " + info.displayId + " not allowed in topology because " + "it is a non-default internal display"); return false; } if ((info.type == Display.TYPE_EXTERNAL || info.type == Display.TYPE_OVERLAY) && !mIsExtendedDisplayEnabled.getAsBoolean()) { Slog.d(TAG, "Display " + info.displayId + " not allowed in topology because " + "type is EXTERNAL or OVERLAY and !mIsExtendedDisplayEnabled"); return false; } if (info.displayGroupId != Display.DEFAULT_DISPLAY_GROUP) { Slog.d(TAG, "Display " + info.displayId + " not allowed in topology because " + "it is not in the default display group"); return false; } return true; } } /** /** Loading services/tests/displayservicetests/src/com/android/server/display/DisplayTopologyCoordinatorTest.kt +162 −8 Original line number Original line Diff line number Diff line Loading @@ -61,6 +61,7 @@ class DisplayTopologyCoordinatorTest { info.logicalWidth = i * 300 info.logicalWidth = i * 300 info.logicalHeight = i * 200 info.logicalHeight = i * 200 info.logicalDensityDpi = i * 100 info.logicalDensityDpi = i * 100 info.type = Display.TYPE_EXTERNAL return@map info return@map info } } Loading Loading @@ -115,7 +116,98 @@ class DisplayTopologyCoordinatorTest { } } @Test @Test fun addDisplay_extendedDisplaysDisabled() { fun addDisplay_internal() { displayInfos[0].displayId = Display.DEFAULT_DISPLAY displayInfos[0].type = Display.TYPE_INTERNAL coordinator.onDisplayAdded(displayInfos[0]) val widthDp = pxToDp(displayInfos[0].logicalWidth.toFloat(), displayInfos[0].logicalDensityDpi) val heightDp = pxToDp(displayInfos[0].logicalHeight.toFloat(), displayInfos[0].logicalDensityDpi) verify(mockTopology).addDisplay(displayInfos[0].displayId, widthDp, heightDp) verify(mockTopologyChangedCallback).invoke( android.util.Pair( mockTopologyCopy, mockTopologyGraph ) ) } @Test fun addDisplay_overlay() { displayInfos[0].type = Display.TYPE_OVERLAY coordinator.onDisplayAdded(displayInfos[0]) val widthDp = pxToDp(displayInfos[0].logicalWidth.toFloat(), displayInfos[0].logicalDensityDpi) val heightDp = pxToDp(displayInfos[0].logicalHeight.toFloat(), displayInfos[0].logicalDensityDpi) verify(mockTopology).addDisplay(displayInfos[0].displayId, widthDp, heightDp) verify(mockTopologyChangedCallback).invoke( android.util.Pair( mockTopologyCopy, mockTopologyGraph ) ) } @Test fun addDisplay_typeUnknown() { displayInfos[0].type = Display.TYPE_UNKNOWN coordinator.onDisplayAdded(displayInfos[0]) verify(mockTopology, never()).addDisplay(anyInt(), anyFloat(), anyFloat()) verify(mockTopologyChangedCallback, never()).invoke(any()) } @Test fun addDisplay_wifi() { displayInfos[0].type = Display.TYPE_WIFI coordinator.onDisplayAdded(displayInfos[0]) verify(mockTopology, never()).addDisplay(anyInt(), anyFloat(), anyFloat()) verify(mockTopologyChangedCallback, never()).invoke(any()) } @Test fun addDisplay_virtual() { displayInfos[0].type = Display.TYPE_VIRTUAL coordinator.onDisplayAdded(displayInfos[0]) verify(mockTopology, never()).addDisplay(anyInt(), anyFloat(), anyFloat()) verify(mockTopologyChangedCallback, never()).invoke(any()) } @Test fun addDisplay_internal_nonDefault() { displayInfos[0].displayId = 2 displayInfos[0].type = Display.TYPE_INTERNAL coordinator.onDisplayAdded(displayInfos[0]) verify(mockTopology, never()).addDisplay(anyInt(), anyFloat(), anyFloat()) verify(mockTopologyChangedCallback, never()).invoke(any()) } @Test fun addDisplay_external_extendedDisplaysDisabled() { whenever(mockIsExtendedDisplayEnabled()).thenReturn(false) for (displayInfo in displayInfos) { coordinator.onDisplayAdded(displayInfo) } verify(mockTopology, never()).addDisplay(anyInt(), anyFloat(), anyFloat()) verify(mockTopologyChangedCallback, never()).invoke(any()) } @Test fun addDisplay_overlay_extendedDisplaysDisabled() { displayInfos[0].type = Display.TYPE_OVERLAY whenever(mockIsExtendedDisplayEnabled()).thenReturn(false) whenever(mockIsExtendedDisplayEnabled()).thenReturn(false) for (displayInfo in displayInfos) { for (displayInfo in displayInfos) { Loading Loading @@ -144,9 +236,16 @@ class DisplayTopologyCoordinatorTest { .thenReturn(true) .thenReturn(true) addDisplay() addDisplay() displayInfos[0].logicalDensityDpi += 10 displayInfos[0].logicalWidth += 100 displayInfos[0].logicalHeight += 100 coordinator.onDisplayChanged(displayInfos[0]) coordinator.onDisplayChanged(displayInfos[0]) val widthDp = pxToDp(displayInfos[0].logicalWidth.toFloat(), displayInfos[0].logicalDensityDpi) val heightDp = pxToDp(displayInfos[0].logicalHeight.toFloat(), displayInfos[0].logicalDensityDpi) verify(mockTopology).updateDisplay(displayInfos[0].displayId, widthDp, heightDp) val captor = ArgumentCaptor.forClass(SparseIntArray::class.java) val captor = ArgumentCaptor.forClass(SparseIntArray::class.java) verify(mockTopologyCopy).getGraph(captor.capture()) verify(mockTopologyCopy).getGraph(captor.capture()) val densities = captor.value val densities = captor.value Loading Loading @@ -180,11 +279,56 @@ class DisplayTopologyCoordinatorTest { } } @Test @Test fun updateDisplay_extendedDisplaysDisabled() { fun updateDisplay_typeUnknown() { displayInfos[0].type = Display.TYPE_UNKNOWN coordinator.onDisplayChanged(displayInfos[0]) verify(mockTopology, never()).updateDisplay(anyInt(), anyFloat(), anyFloat()) verify(mockTopologyCopy, never()).getGraph(any()) verify(mockTopologyChangedCallback, never()).invoke(any()) } @Test fun updateDisplay_wifi() { displayInfos[0].type = Display.TYPE_WIFI coordinator.onDisplayChanged(displayInfos[0]) verify(mockTopology, never()).updateDisplay(anyInt(), anyFloat(), anyFloat()) verify(mockTopologyCopy, never()).getGraph(any()) verify(mockTopologyChangedCallback, never()).invoke(any()) } @Test fun updateDisplay_virtual() { displayInfos[0].type = Display.TYPE_VIRTUAL coordinator.onDisplayChanged(displayInfos[0]) verify(mockTopology, never()).updateDisplay(anyInt(), anyFloat(), anyFloat()) verify(mockTopologyCopy, never()).getGraph(any()) verify(mockTopologyChangedCallback, never()).invoke(any()) } @Test fun updateDisplay_internal_nonDefault() { displayInfos[0].displayId = 2 displayInfos[0].type = Display.TYPE_INTERNAL coordinator.onDisplayChanged(displayInfos[0]) verify(mockTopology, never()).updateDisplay(anyInt(), anyFloat(), anyFloat()) verify(mockTopologyCopy, never()).getGraph(any()) verify(mockTopologyChangedCallback, never()).invoke(any()) } @Test fun updateDisplay_external_extendedDisplaysDisabled() { whenever(mockIsExtendedDisplayEnabled()).thenReturn(false) whenever(mockIsExtendedDisplayEnabled()).thenReturn(false) for (displayInfo in displayInfos) { for (displayInfo in displayInfos) { coordinator.onDisplayAdded(displayInfo) coordinator.onDisplayChanged(displayInfo) } } verify(mockTopology, never()).updateDisplay(anyInt(), anyFloat(), anyFloat()) verify(mockTopology, never()).updateDisplay(anyInt(), anyFloat(), anyFloat()) Loading @@ -192,11 +336,23 @@ class DisplayTopologyCoordinatorTest { verify(mockTopologyChangedCallback, never()).invoke(any()) verify(mockTopologyChangedCallback, never()).invoke(any()) } } @Test fun updateDisplay_overlay_extendedDisplaysDisabled() { displayInfos[0].type = Display.TYPE_OVERLAY whenever(mockIsExtendedDisplayEnabled()).thenReturn(false) coordinator.onDisplayChanged(displayInfos[0]) verify(mockTopology, never()).updateDisplay(anyInt(), anyFloat(), anyFloat()) verify(mockTopologyChangedCallback, never()).invoke(any()) verify(mockTopologyStore, never()).restoreTopology(any()) } @Test @Test fun updateDisplay_notInDefaultDisplayGroup() { fun updateDisplay_notInDefaultDisplayGroup() { displayInfos[0].displayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1 displayInfos[0].displayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1 coordinator.onDisplayAdded(displayInfos[0]) coordinator.onDisplayChanged(displayInfos[0]) verify(mockTopology, never()).updateDisplay(anyInt(), anyFloat(), anyFloat()) verify(mockTopology, never()).updateDisplay(anyInt(), anyFloat(), anyFloat()) verify(mockTopologyCopy, never()).getGraph(any()) verify(mockTopologyCopy, never()).getGraph(any()) Loading Loading @@ -233,9 +389,7 @@ class DisplayTopologyCoordinatorTest { @Test @Test fun removeDisplay_notChanged() { fun removeDisplay_notChanged() { for (displayInfo in displayInfos) { coordinator.onDisplayRemoved(100) coordinator.onDisplayRemoved(displayInfo.displayId) } verify(mockTopologyChangedCallback, never()).invoke(any()) verify(mockTopologyChangedCallback, never()).invoke(any()) verify(mockTopologyStore, never()).restoreTopology(any()) verify(mockTopologyStore, never()).restoreTopology(any()) Loading Loading
services/core/java/com/android/server/display/DisplayTopologyCoordinator.java +23 −2 Original line number Original line Diff line number Diff line Loading @@ -250,8 +250,29 @@ class DisplayTopologyCoordinator { } } private boolean isDisplayAllowedInTopology(DisplayInfo info) { private boolean isDisplayAllowedInTopology(DisplayInfo info) { return mIsExtendedDisplayEnabled.getAsBoolean() if (info.type != Display.TYPE_INTERNAL && info.type != Display.TYPE_EXTERNAL && info.displayGroupId == Display.DEFAULT_DISPLAY_GROUP; && info.type != Display.TYPE_OVERLAY) { Slog.d(TAG, "Display " + info.displayId + " not allowed in topology because " + "type is not INTERNAL, EXTERNAL or OVERLAY"); return false; } if (info.type == Display.TYPE_INTERNAL && info.displayId != Display.DEFAULT_DISPLAY) { Slog.d(TAG, "Display " + info.displayId + " not allowed in topology because " + "it is a non-default internal display"); return false; } if ((info.type == Display.TYPE_EXTERNAL || info.type == Display.TYPE_OVERLAY) && !mIsExtendedDisplayEnabled.getAsBoolean()) { Slog.d(TAG, "Display " + info.displayId + " not allowed in topology because " + "type is EXTERNAL or OVERLAY and !mIsExtendedDisplayEnabled"); return false; } if (info.displayGroupId != Display.DEFAULT_DISPLAY_GROUP) { Slog.d(TAG, "Display " + info.displayId + " not allowed in topology because " + "it is not in the default display group"); return false; } return true; } } /** /** Loading
services/tests/displayservicetests/src/com/android/server/display/DisplayTopologyCoordinatorTest.kt +162 −8 Original line number Original line Diff line number Diff line Loading @@ -61,6 +61,7 @@ class DisplayTopologyCoordinatorTest { info.logicalWidth = i * 300 info.logicalWidth = i * 300 info.logicalHeight = i * 200 info.logicalHeight = i * 200 info.logicalDensityDpi = i * 100 info.logicalDensityDpi = i * 100 info.type = Display.TYPE_EXTERNAL return@map info return@map info } } Loading Loading @@ -115,7 +116,98 @@ class DisplayTopologyCoordinatorTest { } } @Test @Test fun addDisplay_extendedDisplaysDisabled() { fun addDisplay_internal() { displayInfos[0].displayId = Display.DEFAULT_DISPLAY displayInfos[0].type = Display.TYPE_INTERNAL coordinator.onDisplayAdded(displayInfos[0]) val widthDp = pxToDp(displayInfos[0].logicalWidth.toFloat(), displayInfos[0].logicalDensityDpi) val heightDp = pxToDp(displayInfos[0].logicalHeight.toFloat(), displayInfos[0].logicalDensityDpi) verify(mockTopology).addDisplay(displayInfos[0].displayId, widthDp, heightDp) verify(mockTopologyChangedCallback).invoke( android.util.Pair( mockTopologyCopy, mockTopologyGraph ) ) } @Test fun addDisplay_overlay() { displayInfos[0].type = Display.TYPE_OVERLAY coordinator.onDisplayAdded(displayInfos[0]) val widthDp = pxToDp(displayInfos[0].logicalWidth.toFloat(), displayInfos[0].logicalDensityDpi) val heightDp = pxToDp(displayInfos[0].logicalHeight.toFloat(), displayInfos[0].logicalDensityDpi) verify(mockTopology).addDisplay(displayInfos[0].displayId, widthDp, heightDp) verify(mockTopologyChangedCallback).invoke( android.util.Pair( mockTopologyCopy, mockTopologyGraph ) ) } @Test fun addDisplay_typeUnknown() { displayInfos[0].type = Display.TYPE_UNKNOWN coordinator.onDisplayAdded(displayInfos[0]) verify(mockTopology, never()).addDisplay(anyInt(), anyFloat(), anyFloat()) verify(mockTopologyChangedCallback, never()).invoke(any()) } @Test fun addDisplay_wifi() { displayInfos[0].type = Display.TYPE_WIFI coordinator.onDisplayAdded(displayInfos[0]) verify(mockTopology, never()).addDisplay(anyInt(), anyFloat(), anyFloat()) verify(mockTopologyChangedCallback, never()).invoke(any()) } @Test fun addDisplay_virtual() { displayInfos[0].type = Display.TYPE_VIRTUAL coordinator.onDisplayAdded(displayInfos[0]) verify(mockTopology, never()).addDisplay(anyInt(), anyFloat(), anyFloat()) verify(mockTopologyChangedCallback, never()).invoke(any()) } @Test fun addDisplay_internal_nonDefault() { displayInfos[0].displayId = 2 displayInfos[0].type = Display.TYPE_INTERNAL coordinator.onDisplayAdded(displayInfos[0]) verify(mockTopology, never()).addDisplay(anyInt(), anyFloat(), anyFloat()) verify(mockTopologyChangedCallback, never()).invoke(any()) } @Test fun addDisplay_external_extendedDisplaysDisabled() { whenever(mockIsExtendedDisplayEnabled()).thenReturn(false) for (displayInfo in displayInfos) { coordinator.onDisplayAdded(displayInfo) } verify(mockTopology, never()).addDisplay(anyInt(), anyFloat(), anyFloat()) verify(mockTopologyChangedCallback, never()).invoke(any()) } @Test fun addDisplay_overlay_extendedDisplaysDisabled() { displayInfos[0].type = Display.TYPE_OVERLAY whenever(mockIsExtendedDisplayEnabled()).thenReturn(false) whenever(mockIsExtendedDisplayEnabled()).thenReturn(false) for (displayInfo in displayInfos) { for (displayInfo in displayInfos) { Loading Loading @@ -144,9 +236,16 @@ class DisplayTopologyCoordinatorTest { .thenReturn(true) .thenReturn(true) addDisplay() addDisplay() displayInfos[0].logicalDensityDpi += 10 displayInfos[0].logicalWidth += 100 displayInfos[0].logicalHeight += 100 coordinator.onDisplayChanged(displayInfos[0]) coordinator.onDisplayChanged(displayInfos[0]) val widthDp = pxToDp(displayInfos[0].logicalWidth.toFloat(), displayInfos[0].logicalDensityDpi) val heightDp = pxToDp(displayInfos[0].logicalHeight.toFloat(), displayInfos[0].logicalDensityDpi) verify(mockTopology).updateDisplay(displayInfos[0].displayId, widthDp, heightDp) val captor = ArgumentCaptor.forClass(SparseIntArray::class.java) val captor = ArgumentCaptor.forClass(SparseIntArray::class.java) verify(mockTopologyCopy).getGraph(captor.capture()) verify(mockTopologyCopy).getGraph(captor.capture()) val densities = captor.value val densities = captor.value Loading Loading @@ -180,11 +279,56 @@ class DisplayTopologyCoordinatorTest { } } @Test @Test fun updateDisplay_extendedDisplaysDisabled() { fun updateDisplay_typeUnknown() { displayInfos[0].type = Display.TYPE_UNKNOWN coordinator.onDisplayChanged(displayInfos[0]) verify(mockTopology, never()).updateDisplay(anyInt(), anyFloat(), anyFloat()) verify(mockTopologyCopy, never()).getGraph(any()) verify(mockTopologyChangedCallback, never()).invoke(any()) } @Test fun updateDisplay_wifi() { displayInfos[0].type = Display.TYPE_WIFI coordinator.onDisplayChanged(displayInfos[0]) verify(mockTopology, never()).updateDisplay(anyInt(), anyFloat(), anyFloat()) verify(mockTopologyCopy, never()).getGraph(any()) verify(mockTopologyChangedCallback, never()).invoke(any()) } @Test fun updateDisplay_virtual() { displayInfos[0].type = Display.TYPE_VIRTUAL coordinator.onDisplayChanged(displayInfos[0]) verify(mockTopology, never()).updateDisplay(anyInt(), anyFloat(), anyFloat()) verify(mockTopologyCopy, never()).getGraph(any()) verify(mockTopologyChangedCallback, never()).invoke(any()) } @Test fun updateDisplay_internal_nonDefault() { displayInfos[0].displayId = 2 displayInfos[0].type = Display.TYPE_INTERNAL coordinator.onDisplayChanged(displayInfos[0]) verify(mockTopology, never()).updateDisplay(anyInt(), anyFloat(), anyFloat()) verify(mockTopologyCopy, never()).getGraph(any()) verify(mockTopologyChangedCallback, never()).invoke(any()) } @Test fun updateDisplay_external_extendedDisplaysDisabled() { whenever(mockIsExtendedDisplayEnabled()).thenReturn(false) whenever(mockIsExtendedDisplayEnabled()).thenReturn(false) for (displayInfo in displayInfos) { for (displayInfo in displayInfos) { coordinator.onDisplayAdded(displayInfo) coordinator.onDisplayChanged(displayInfo) } } verify(mockTopology, never()).updateDisplay(anyInt(), anyFloat(), anyFloat()) verify(mockTopology, never()).updateDisplay(anyInt(), anyFloat(), anyFloat()) Loading @@ -192,11 +336,23 @@ class DisplayTopologyCoordinatorTest { verify(mockTopologyChangedCallback, never()).invoke(any()) verify(mockTopologyChangedCallback, never()).invoke(any()) } } @Test fun updateDisplay_overlay_extendedDisplaysDisabled() { displayInfos[0].type = Display.TYPE_OVERLAY whenever(mockIsExtendedDisplayEnabled()).thenReturn(false) coordinator.onDisplayChanged(displayInfos[0]) verify(mockTopology, never()).updateDisplay(anyInt(), anyFloat(), anyFloat()) verify(mockTopologyChangedCallback, never()).invoke(any()) verify(mockTopologyStore, never()).restoreTopology(any()) } @Test @Test fun updateDisplay_notInDefaultDisplayGroup() { fun updateDisplay_notInDefaultDisplayGroup() { displayInfos[0].displayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1 displayInfos[0].displayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1 coordinator.onDisplayAdded(displayInfos[0]) coordinator.onDisplayChanged(displayInfos[0]) verify(mockTopology, never()).updateDisplay(anyInt(), anyFloat(), anyFloat()) verify(mockTopology, never()).updateDisplay(anyInt(), anyFloat(), anyFloat()) verify(mockTopologyCopy, never()).getGraph(any()) verify(mockTopologyCopy, never()).getGraph(any()) Loading Loading @@ -233,9 +389,7 @@ class DisplayTopologyCoordinatorTest { @Test @Test fun removeDisplay_notChanged() { fun removeDisplay_notChanged() { for (displayInfo in displayInfos) { coordinator.onDisplayRemoved(100) coordinator.onDisplayRemoved(displayInfo.displayId) } verify(mockTopologyChangedCallback, never()).invoke(any()) verify(mockTopologyChangedCallback, never()).invoke(any()) verify(mockTopologyStore, never()).restoreTopology(any()) verify(mockTopologyStore, never()).restoreTopology(any()) Loading