Loading core/res/res/values/config.xml +8 −0 Original line number Diff line number Diff line Loading @@ -3183,6 +3183,14 @@ as private. {@see android.view.Display#FLAG_PRIVATE} --> <integer-array translatable="false" name="config_localPrivateDisplayPorts"></integer-array> <!-- Controls if local secondary displays should be able to steal focus and become top display. Value specified in the array represents physical port address of each display and displays in this list due to flag dependencies will be marked with the following flags: {@see android.view.Display#FLAG_STEAL_TOP_FOCUS_DISABLED} {@see android.view.Display#FLAG_OWN_FOCUS} --> <integer-array translatable="false" name="config_localNotStealTopFocusDisplayPorts"> </integer-array> <!-- The default mode for the default display. One of the following values (See Display.java): 0 - COLOR_MODE_DEFAULT 7 - COLOR_MODE_SRGB Loading core/res/res/values/symbols.xml +1 −0 Original line number Diff line number Diff line Loading @@ -425,6 +425,7 @@ <java-symbol type="bool" name="config_enableProximityService" /> <java-symbol type="bool" name="config_enableVirtualDeviceManager" /> <java-symbol type="array" name="config_localPrivateDisplayPorts" /> <java-symbol type="array" name="config_localNotStealTopFocusDisplayPorts" /> <java-symbol type="integer" name="config_defaultDisplayDefaultColorMode" /> <java-symbol type="bool" name="config_enableAppWidgetService" /> <java-symbol type="dimen" name="config_pictureInPictureMinAspectRatio" /> Loading services/core/java/com/android/server/display/LocalDisplayAdapter.java +22 −0 Original line number Diff line number Diff line Loading @@ -725,6 +725,11 @@ final class LocalDisplayAdapter extends DisplayAdapter { if (isDisplayPrivate(physicalAddress)) { mInfo.flags |= DisplayDeviceInfo.FLAG_PRIVATE; } if (isDisplayStealTopFocusDisabled(physicalAddress)) { mInfo.flags |= DisplayDeviceInfo.FLAG_OWN_FOCUS; mInfo.flags |= DisplayDeviceInfo.FLAG_STEAL_TOP_FOCUS_DISABLED; } } if (DisplayCutout.getMaskBuiltInDisplayCutout(res, mInfo.uniqueId)) { Loading Loading @@ -1395,6 +1400,23 @@ final class LocalDisplayAdapter extends DisplayAdapter { } return false; } private boolean isDisplayStealTopFocusDisabled(DisplayAddress.Physical physicalAddress) { if (physicalAddress == null) { return false; } final Resources res = getOverlayContext().getResources(); int[] ports = res.getIntArray(R.array.config_localNotStealTopFocusDisplayPorts); if (ports != null) { int port = physicalAddress.getPort(); for (int p : ports) { if (p == port) { return true; } } } return false; } } private boolean hdrTypesEqual(int[] modeHdrTypes, int[] recordHdrTypes) { Loading services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java +64 −0 Original line number Diff line number Diff line Loading @@ -250,6 +250,34 @@ public class LocalDisplayAdapterTest { PORT_C, false); } /** * Confirm that display is marked as trusted, has own focus, disables steal top focus when it * is listed in com.android.internal.R.array.config_localNotStealTopFocusDisplayPorts. */ @Test public void testStealTopFocusDisabledDisplay() throws Exception { setUpDisplay(new FakeDisplay(PORT_A)); setUpDisplay(new FakeDisplay(PORT_B)); setUpDisplay(new FakeDisplay(PORT_C)); updateAvailableDisplays(); doReturn(new int[]{ PORT_B }).when(mMockedResources).getIntArray( com.android.internal.R.array.config_localNotStealTopFocusDisplayPorts); mAdapter.registerLocked(); waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS); // This should not have the flags assertNotStealTopFocusFlag(mListener.addedDisplays.get(0).getDisplayDeviceInfoLocked(), PORT_A, false); // This should have the flags assertNotStealTopFocusFlag(mListener.addedDisplays.get(1).getDisplayDeviceInfoLocked(), PORT_B, true); // This should not have the flags assertNotStealTopFocusFlag(mListener.addedDisplays.get(2).getDisplayDeviceInfoLocked(), PORT_C, false); } @Test public void testSupportedDisplayModesGetOverriddenWhenDisplayIsUpdated() throws InterruptedException { Loading Loading @@ -313,6 +341,42 @@ public class LocalDisplayAdapterTest { assertEquals(shouldBePrivate, (info.flags & DisplayDeviceInfo.FLAG_PRIVATE) != 0); } /** * Confirm that all local displays are not trusted, do not have their own focus, and do not * steal top focus when config_localNotStealTopFocusDisplayPorts is empty: */ @Test public void testDisplayFlagsForNoConfigLocalNotStealTopFocusDisplayPorts() throws Exception { setUpDisplay(new FakeDisplay(PORT_A)); setUpDisplay(new FakeDisplay(PORT_C)); updateAvailableDisplays(); // config_localNotStealTopFocusDisplayPorts is null mAdapter.registerLocked(); waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS); // This should not have the flags assertNotStealTopFocusFlag(mListener.addedDisplays.get(0).getDisplayDeviceInfoLocked(), PORT_A, false); // This should not have the flags assertNotStealTopFocusFlag(mListener.addedDisplays.get(1).getDisplayDeviceInfoLocked(), PORT_C, false); } private static void assertNotStealTopFocusFlag( DisplayDeviceInfo info, int expectedPort, boolean shouldHaveFlags) { final DisplayAddress.Physical address = (DisplayAddress.Physical) info.address; assertNotNull(address); assertEquals(expectedPort, address.getPort()); assertEquals(DISPLAY_MODEL, address.getModel()); assertEquals(shouldHaveFlags, (info.flags & DisplayDeviceInfo.FLAG_STEAL_TOP_FOCUS_DISABLED) != 0); assertEquals(shouldHaveFlags, (info.flags & DisplayDeviceInfo.FLAG_OWN_FOCUS) != 0); // display is always trusted since it is created by the system assertEquals(true, (info.flags & DisplayDeviceInfo.FLAG_TRUSTED) != 0); } /** * Confirm that external display uses physical density. */ Loading Loading
core/res/res/values/config.xml +8 −0 Original line number Diff line number Diff line Loading @@ -3183,6 +3183,14 @@ as private. {@see android.view.Display#FLAG_PRIVATE} --> <integer-array translatable="false" name="config_localPrivateDisplayPorts"></integer-array> <!-- Controls if local secondary displays should be able to steal focus and become top display. Value specified in the array represents physical port address of each display and displays in this list due to flag dependencies will be marked with the following flags: {@see android.view.Display#FLAG_STEAL_TOP_FOCUS_DISABLED} {@see android.view.Display#FLAG_OWN_FOCUS} --> <integer-array translatable="false" name="config_localNotStealTopFocusDisplayPorts"> </integer-array> <!-- The default mode for the default display. One of the following values (See Display.java): 0 - COLOR_MODE_DEFAULT 7 - COLOR_MODE_SRGB Loading
core/res/res/values/symbols.xml +1 −0 Original line number Diff line number Diff line Loading @@ -425,6 +425,7 @@ <java-symbol type="bool" name="config_enableProximityService" /> <java-symbol type="bool" name="config_enableVirtualDeviceManager" /> <java-symbol type="array" name="config_localPrivateDisplayPorts" /> <java-symbol type="array" name="config_localNotStealTopFocusDisplayPorts" /> <java-symbol type="integer" name="config_defaultDisplayDefaultColorMode" /> <java-symbol type="bool" name="config_enableAppWidgetService" /> <java-symbol type="dimen" name="config_pictureInPictureMinAspectRatio" /> Loading
services/core/java/com/android/server/display/LocalDisplayAdapter.java +22 −0 Original line number Diff line number Diff line Loading @@ -725,6 +725,11 @@ final class LocalDisplayAdapter extends DisplayAdapter { if (isDisplayPrivate(physicalAddress)) { mInfo.flags |= DisplayDeviceInfo.FLAG_PRIVATE; } if (isDisplayStealTopFocusDisabled(physicalAddress)) { mInfo.flags |= DisplayDeviceInfo.FLAG_OWN_FOCUS; mInfo.flags |= DisplayDeviceInfo.FLAG_STEAL_TOP_FOCUS_DISABLED; } } if (DisplayCutout.getMaskBuiltInDisplayCutout(res, mInfo.uniqueId)) { Loading Loading @@ -1395,6 +1400,23 @@ final class LocalDisplayAdapter extends DisplayAdapter { } return false; } private boolean isDisplayStealTopFocusDisabled(DisplayAddress.Physical physicalAddress) { if (physicalAddress == null) { return false; } final Resources res = getOverlayContext().getResources(); int[] ports = res.getIntArray(R.array.config_localNotStealTopFocusDisplayPorts); if (ports != null) { int port = physicalAddress.getPort(); for (int p : ports) { if (p == port) { return true; } } } return false; } } private boolean hdrTypesEqual(int[] modeHdrTypes, int[] recordHdrTypes) { Loading
services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java +64 −0 Original line number Diff line number Diff line Loading @@ -250,6 +250,34 @@ public class LocalDisplayAdapterTest { PORT_C, false); } /** * Confirm that display is marked as trusted, has own focus, disables steal top focus when it * is listed in com.android.internal.R.array.config_localNotStealTopFocusDisplayPorts. */ @Test public void testStealTopFocusDisabledDisplay() throws Exception { setUpDisplay(new FakeDisplay(PORT_A)); setUpDisplay(new FakeDisplay(PORT_B)); setUpDisplay(new FakeDisplay(PORT_C)); updateAvailableDisplays(); doReturn(new int[]{ PORT_B }).when(mMockedResources).getIntArray( com.android.internal.R.array.config_localNotStealTopFocusDisplayPorts); mAdapter.registerLocked(); waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS); // This should not have the flags assertNotStealTopFocusFlag(mListener.addedDisplays.get(0).getDisplayDeviceInfoLocked(), PORT_A, false); // This should have the flags assertNotStealTopFocusFlag(mListener.addedDisplays.get(1).getDisplayDeviceInfoLocked(), PORT_B, true); // This should not have the flags assertNotStealTopFocusFlag(mListener.addedDisplays.get(2).getDisplayDeviceInfoLocked(), PORT_C, false); } @Test public void testSupportedDisplayModesGetOverriddenWhenDisplayIsUpdated() throws InterruptedException { Loading Loading @@ -313,6 +341,42 @@ public class LocalDisplayAdapterTest { assertEquals(shouldBePrivate, (info.flags & DisplayDeviceInfo.FLAG_PRIVATE) != 0); } /** * Confirm that all local displays are not trusted, do not have their own focus, and do not * steal top focus when config_localNotStealTopFocusDisplayPorts is empty: */ @Test public void testDisplayFlagsForNoConfigLocalNotStealTopFocusDisplayPorts() throws Exception { setUpDisplay(new FakeDisplay(PORT_A)); setUpDisplay(new FakeDisplay(PORT_C)); updateAvailableDisplays(); // config_localNotStealTopFocusDisplayPorts is null mAdapter.registerLocked(); waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS); // This should not have the flags assertNotStealTopFocusFlag(mListener.addedDisplays.get(0).getDisplayDeviceInfoLocked(), PORT_A, false); // This should not have the flags assertNotStealTopFocusFlag(mListener.addedDisplays.get(1).getDisplayDeviceInfoLocked(), PORT_C, false); } private static void assertNotStealTopFocusFlag( DisplayDeviceInfo info, int expectedPort, boolean shouldHaveFlags) { final DisplayAddress.Physical address = (DisplayAddress.Physical) info.address; assertNotNull(address); assertEquals(expectedPort, address.getPort()); assertEquals(DISPLAY_MODEL, address.getModel()); assertEquals(shouldHaveFlags, (info.flags & DisplayDeviceInfo.FLAG_STEAL_TOP_FOCUS_DISABLED) != 0); assertEquals(shouldHaveFlags, (info.flags & DisplayDeviceInfo.FLAG_OWN_FOCUS) != 0); // display is always trusted since it is created by the system assertEquals(true, (info.flags & DisplayDeviceInfo.FLAG_TRUSTED) != 0); } /** * Confirm that external display uses physical density. */ Loading