Loading services/core/java/com/android/server/display/feature/DisplayManagerFlags.java +10 −0 Original line number Diff line number Diff line Loading @@ -314,6 +314,11 @@ public class DisplayManagerFlags { Flags::ensureColorFadeWhenTurningOn ); private final FlagState mIsOnDisplayAddedInObserverEnabled = new FlagState( Flags.FLAG_ENABLE_ON_DISPLAY_ADDED_IN_OBSERVER, Flags::enableOnDisplayAddedInObserver ); /** * @return {@code true} if 'port' is allowed in display layout configuration file. */ Loading Loading @@ -662,6 +667,10 @@ public class DisplayManagerFlags { return mEnsureColorFadeWhenTurningOn.isEnabled(); } public boolean isOnDisplayAddedInObserverEnabled() { return mIsOnDisplayAddedInObserverEnabled.isEnabled(); } /** * dumps all flagstates * @param pw printWriter Loading Loading @@ -726,6 +735,7 @@ public class DisplayManagerFlags { pw.println(" " + mEnableDefaultDisplayInTopologySwitch); pw.println(" " + mModeSwitchWithoutSaving); pw.println(" " + mEnsureColorFadeWhenTurningOn); pw.println(" " + mIsOnDisplayAddedInObserverEnabled); } private static class FlagState { Loading services/core/java/com/android/server/display/feature/display_flags.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -567,3 +567,13 @@ flag { purpose: PURPOSE_BUGFIX } } flag { name: "enable_on_display_added_in_observer" namespace: "display_manager" description: "On display added should be called after the display listener is registered." bug: "414778119" metadata { purpose: PURPOSE_BUGFIX } } services/core/java/com/android/server/display/mode/DisplayModeDirector.java +49 −24 Original line number Diff line number Diff line Loading @@ -1479,7 +1479,17 @@ public class DisplayModeDirector { public void observe() { mInjector.registerDisplayListener(this, mHandler); if (mDisplayManagerFlags.isOnDisplayAddedInObserverEnabled()) { final var enabledDisplays = mInjector.getEnabledDisplays(); // Populate existing displays if (enabledDisplays != null && enabledDisplays.length > 0) { mHandler.post(() -> { for (Display d : enabledDisplays) { onDisplayAdded(d.getDisplayId()); } }); } } else { // Populate existing displays SparseArray<Display.Mode[]> modes = new SparseArray<>(); SparseArray<Display.Mode[]> appModes = new SparseArray<>(); Loading @@ -1501,14 +1511,19 @@ public class DisplayModeDirector { mAppSupportedModesByDisplay.put(appModes.keyAt(i), appModes.valueAt(i)); mDefaultModeByDisplay.put(defaultModes.keyAt(i), defaultModes.valueAt(i)); } mDisplayDeviceConfigByDisplay.put(Display.DEFAULT_DISPLAY, defaultDisplayConfig); mDisplayDeviceConfigByDisplay.put(Display.DEFAULT_DISPLAY, defaultDisplayConfig); } } } @Override public void onDisplayAdded(int displayId) { updateDisplayDeviceConfig(displayId); DisplayInfo displayInfo = getDisplayInfo(displayId); if (displayInfo == null) { return; } updateDisplayDeviceConfig(displayId); registerExternalDisplay(displayInfo); updateDisplayModes(displayId, displayInfo); updateHasArrSupport(displayId, displayInfo); Loading @@ -1535,8 +1550,11 @@ public class DisplayModeDirector { @Override public void onDisplayChanged(int displayId) { updateDisplayDeviceConfig(displayId); DisplayInfo displayInfo = getDisplayInfo(displayId); if (displayInfo == null) { return; } updateDisplayDeviceConfig(displayId); updateHasArrSupport(displayId, displayInfo); updateDisplayModes(displayId, displayInfo); updateLayoutLimitedFrameRate(displayId, displayInfo); Loading Loading @@ -3139,6 +3157,8 @@ public class DisplayModeDirector { Display[] getDisplays(); Display[] getEnabledDisplays(); boolean getDisplayInfo(int displayId, DisplayInfo displayInfo); BrightnessInfo getBrightnessInfo(int displayId); Loading Loading @@ -3219,6 +3239,11 @@ public class DisplayModeDirector { return getDisplayManager().getDisplays(DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED); } @Override public Display[] getEnabledDisplays() { return getDisplayManager().getDisplays(); } @Override public boolean getDisplayInfo(int displayId, DisplayInfo displayInfo) { Display display = getDisplayManager().getDisplay(displayId); Loading services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java +29 −8 Original line number Diff line number Diff line Loading @@ -343,6 +343,9 @@ public class DisplayModeDirectorTest { mInjector = spy(new FakesInjector(mDisplayManagerInternalMock, mStatusBarMock, mSensorManagerInternalMock)); mHandler = new Handler(Looper.getMainLooper()); mInjector.setEnabledDisplays(Map.of(DISPLAY_ID, Display.TYPE_INTERNAL, DISPLAY_ID_2, Display.TYPE_INTERNAL)); when(mDisplayManagerFlags.isOnDisplayAddedInObserverEnabled()).thenReturn(true); } private Resources mockResources() { Loading Loading @@ -1901,12 +1904,18 @@ public class DisplayModeDirectorTest { public void testPeakRefreshRate_notAppliedToExternalDisplays() { when(mDisplayManagerFlags.isBackUpSmoothDisplayAndForcePeakRefreshRateEnabled()) .thenReturn(true); mInjector.mDisplayInfo.type = Display.TYPE_EXTERNAL; mInjector.setEnabledDisplays(Map.of(DISPLAY_ID, Display.TYPE_EXTERNAL)); DisplayModeDirector director = new DisplayModeDirector(mContext, mHandler, mInjector, mDisplayManagerFlags, mDisplayDeviceConfigProvider); director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON); director.getDisplayObserver().onDisplayAdded(DISPLAY_ID); Sensor lightSensor = createLightSensor(); SensorManager sensorManager = createMockSensorManager(lightSensor); director.start(sensorManager); mInjector.setEnabledDisplays(Map.of(DISPLAY_ID, Display.TYPE_EXTERNAL, DISPLAY_ID_2, Display.TYPE_EXTERNAL)); director.getDisplayObserver().onDisplayAdded(DISPLAY_ID_2); Display.Mode[] modes1 = new Display.Mode[] { Loading @@ -1925,9 +1934,6 @@ public class DisplayModeDirectorTest { supportedModesByDisplay.put(DISPLAY_ID, modes1); supportedModesByDisplay.put(DISPLAY_ID_2, modes2); Sensor lightSensor = createLightSensor(); SensorManager sensorManager = createMockSensorManager(lightSensor); director.start(sensorManager); director.injectSupportedModesByDisplay(supportedModesByDisplay); // Disable Smooth Display Loading Loading @@ -2058,9 +2064,8 @@ public class DisplayModeDirectorTest { .thenReturn(isRefreshRateSynchronizationEnabled); when(mResources.getBoolean(R.bool.config_refreshRateSynchronizationEnabled)) .thenReturn(isRefreshRateSynchronizationEnabled); mInjector.mDisplayInfo.type = isExternalDisplay ? Display.TYPE_EXTERNAL : Display.TYPE_INTERNAL; mInjector.mDisplayInfo.displayId = DISPLAY_ID_2; mInjector.setEnabledDisplays(Map.of(DISPLAY_ID_2, isExternalDisplay ? Display.TYPE_EXTERNAL : Display.TYPE_INTERNAL)); DisplayModeDirector director = createDirectorFromModeArray(TEST_MODES, DEFAULT_MODE_60); director.start(createMockSensorManager()); Loading Loading @@ -3873,6 +3878,8 @@ public class DisplayModeDirectorTest { private final FakeDeviceConfig mDeviceConfig; private final DisplayInfo mDisplayInfo; private final Map<Integer, Display> mDisplays; private Display[] mEnabledDisplays = new Display[0]; private Map<Integer, Integer> mEnabledDisplayTypes = Map.of(); private boolean mDisplayInfoValid = true; private final DisplayManagerInternal mDisplayManagerInternal; private final StatusBarManagerInternal mStatusBarManagerInternal; Loading Loading @@ -3901,6 +3908,14 @@ public class DisplayModeDirectorTest { mSensorManagerInternal = sensorManagerInternal; } void setEnabledDisplays(Map<Integer, Integer> enabledDisplayTypes) { // Display ids from enabledDisplayTypes, which are external displays. mEnabledDisplayTypes = enabledDisplayTypes; mEnabledDisplays = mDisplays.values().stream() .filter(display -> enabledDisplayTypes.containsKey(display.getDisplayId())) .toArray(size -> new Display[size]); } @NonNull public FakeDeviceConfig getDeviceConfig() { return mDeviceConfig; Loading Loading @@ -3939,10 +3954,16 @@ public class DisplayModeDirectorTest { return mDisplays.values().toArray(new Display[0]); } @Override public Display[] getEnabledDisplays() { return mEnabledDisplays; } @Override public boolean getDisplayInfo(int displayId, DisplayInfo displayInfo) { displayInfo.copyFrom(mDisplayInfo); displayInfo.displayId = displayId; displayInfo.type = mEnabledDisplayTypes.getOrDefault(displayId, Display.TYPE_INTERNAL); return mDisplayInfoValid; } Loading Loading
services/core/java/com/android/server/display/feature/DisplayManagerFlags.java +10 −0 Original line number Diff line number Diff line Loading @@ -314,6 +314,11 @@ public class DisplayManagerFlags { Flags::ensureColorFadeWhenTurningOn ); private final FlagState mIsOnDisplayAddedInObserverEnabled = new FlagState( Flags.FLAG_ENABLE_ON_DISPLAY_ADDED_IN_OBSERVER, Flags::enableOnDisplayAddedInObserver ); /** * @return {@code true} if 'port' is allowed in display layout configuration file. */ Loading Loading @@ -662,6 +667,10 @@ public class DisplayManagerFlags { return mEnsureColorFadeWhenTurningOn.isEnabled(); } public boolean isOnDisplayAddedInObserverEnabled() { return mIsOnDisplayAddedInObserverEnabled.isEnabled(); } /** * dumps all flagstates * @param pw printWriter Loading Loading @@ -726,6 +735,7 @@ public class DisplayManagerFlags { pw.println(" " + mEnableDefaultDisplayInTopologySwitch); pw.println(" " + mModeSwitchWithoutSaving); pw.println(" " + mEnsureColorFadeWhenTurningOn); pw.println(" " + mIsOnDisplayAddedInObserverEnabled); } private static class FlagState { Loading
services/core/java/com/android/server/display/feature/display_flags.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -567,3 +567,13 @@ flag { purpose: PURPOSE_BUGFIX } } flag { name: "enable_on_display_added_in_observer" namespace: "display_manager" description: "On display added should be called after the display listener is registered." bug: "414778119" metadata { purpose: PURPOSE_BUGFIX } }
services/core/java/com/android/server/display/mode/DisplayModeDirector.java +49 −24 Original line number Diff line number Diff line Loading @@ -1479,7 +1479,17 @@ public class DisplayModeDirector { public void observe() { mInjector.registerDisplayListener(this, mHandler); if (mDisplayManagerFlags.isOnDisplayAddedInObserverEnabled()) { final var enabledDisplays = mInjector.getEnabledDisplays(); // Populate existing displays if (enabledDisplays != null && enabledDisplays.length > 0) { mHandler.post(() -> { for (Display d : enabledDisplays) { onDisplayAdded(d.getDisplayId()); } }); } } else { // Populate existing displays SparseArray<Display.Mode[]> modes = new SparseArray<>(); SparseArray<Display.Mode[]> appModes = new SparseArray<>(); Loading @@ -1501,14 +1511,19 @@ public class DisplayModeDirector { mAppSupportedModesByDisplay.put(appModes.keyAt(i), appModes.valueAt(i)); mDefaultModeByDisplay.put(defaultModes.keyAt(i), defaultModes.valueAt(i)); } mDisplayDeviceConfigByDisplay.put(Display.DEFAULT_DISPLAY, defaultDisplayConfig); mDisplayDeviceConfigByDisplay.put(Display.DEFAULT_DISPLAY, defaultDisplayConfig); } } } @Override public void onDisplayAdded(int displayId) { updateDisplayDeviceConfig(displayId); DisplayInfo displayInfo = getDisplayInfo(displayId); if (displayInfo == null) { return; } updateDisplayDeviceConfig(displayId); registerExternalDisplay(displayInfo); updateDisplayModes(displayId, displayInfo); updateHasArrSupport(displayId, displayInfo); Loading @@ -1535,8 +1550,11 @@ public class DisplayModeDirector { @Override public void onDisplayChanged(int displayId) { updateDisplayDeviceConfig(displayId); DisplayInfo displayInfo = getDisplayInfo(displayId); if (displayInfo == null) { return; } updateDisplayDeviceConfig(displayId); updateHasArrSupport(displayId, displayInfo); updateDisplayModes(displayId, displayInfo); updateLayoutLimitedFrameRate(displayId, displayInfo); Loading Loading @@ -3139,6 +3157,8 @@ public class DisplayModeDirector { Display[] getDisplays(); Display[] getEnabledDisplays(); boolean getDisplayInfo(int displayId, DisplayInfo displayInfo); BrightnessInfo getBrightnessInfo(int displayId); Loading Loading @@ -3219,6 +3239,11 @@ public class DisplayModeDirector { return getDisplayManager().getDisplays(DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED); } @Override public Display[] getEnabledDisplays() { return getDisplayManager().getDisplays(); } @Override public boolean getDisplayInfo(int displayId, DisplayInfo displayInfo) { Display display = getDisplayManager().getDisplay(displayId); Loading
services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java +29 −8 Original line number Diff line number Diff line Loading @@ -343,6 +343,9 @@ public class DisplayModeDirectorTest { mInjector = spy(new FakesInjector(mDisplayManagerInternalMock, mStatusBarMock, mSensorManagerInternalMock)); mHandler = new Handler(Looper.getMainLooper()); mInjector.setEnabledDisplays(Map.of(DISPLAY_ID, Display.TYPE_INTERNAL, DISPLAY_ID_2, Display.TYPE_INTERNAL)); when(mDisplayManagerFlags.isOnDisplayAddedInObserverEnabled()).thenReturn(true); } private Resources mockResources() { Loading Loading @@ -1901,12 +1904,18 @@ public class DisplayModeDirectorTest { public void testPeakRefreshRate_notAppliedToExternalDisplays() { when(mDisplayManagerFlags.isBackUpSmoothDisplayAndForcePeakRefreshRateEnabled()) .thenReturn(true); mInjector.mDisplayInfo.type = Display.TYPE_EXTERNAL; mInjector.setEnabledDisplays(Map.of(DISPLAY_ID, Display.TYPE_EXTERNAL)); DisplayModeDirector director = new DisplayModeDirector(mContext, mHandler, mInjector, mDisplayManagerFlags, mDisplayDeviceConfigProvider); director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON); director.getDisplayObserver().onDisplayAdded(DISPLAY_ID); Sensor lightSensor = createLightSensor(); SensorManager sensorManager = createMockSensorManager(lightSensor); director.start(sensorManager); mInjector.setEnabledDisplays(Map.of(DISPLAY_ID, Display.TYPE_EXTERNAL, DISPLAY_ID_2, Display.TYPE_EXTERNAL)); director.getDisplayObserver().onDisplayAdded(DISPLAY_ID_2); Display.Mode[] modes1 = new Display.Mode[] { Loading @@ -1925,9 +1934,6 @@ public class DisplayModeDirectorTest { supportedModesByDisplay.put(DISPLAY_ID, modes1); supportedModesByDisplay.put(DISPLAY_ID_2, modes2); Sensor lightSensor = createLightSensor(); SensorManager sensorManager = createMockSensorManager(lightSensor); director.start(sensorManager); director.injectSupportedModesByDisplay(supportedModesByDisplay); // Disable Smooth Display Loading Loading @@ -2058,9 +2064,8 @@ public class DisplayModeDirectorTest { .thenReturn(isRefreshRateSynchronizationEnabled); when(mResources.getBoolean(R.bool.config_refreshRateSynchronizationEnabled)) .thenReturn(isRefreshRateSynchronizationEnabled); mInjector.mDisplayInfo.type = isExternalDisplay ? Display.TYPE_EXTERNAL : Display.TYPE_INTERNAL; mInjector.mDisplayInfo.displayId = DISPLAY_ID_2; mInjector.setEnabledDisplays(Map.of(DISPLAY_ID_2, isExternalDisplay ? Display.TYPE_EXTERNAL : Display.TYPE_INTERNAL)); DisplayModeDirector director = createDirectorFromModeArray(TEST_MODES, DEFAULT_MODE_60); director.start(createMockSensorManager()); Loading Loading @@ -3873,6 +3878,8 @@ public class DisplayModeDirectorTest { private final FakeDeviceConfig mDeviceConfig; private final DisplayInfo mDisplayInfo; private final Map<Integer, Display> mDisplays; private Display[] mEnabledDisplays = new Display[0]; private Map<Integer, Integer> mEnabledDisplayTypes = Map.of(); private boolean mDisplayInfoValid = true; private final DisplayManagerInternal mDisplayManagerInternal; private final StatusBarManagerInternal mStatusBarManagerInternal; Loading Loading @@ -3901,6 +3908,14 @@ public class DisplayModeDirectorTest { mSensorManagerInternal = sensorManagerInternal; } void setEnabledDisplays(Map<Integer, Integer> enabledDisplayTypes) { // Display ids from enabledDisplayTypes, which are external displays. mEnabledDisplayTypes = enabledDisplayTypes; mEnabledDisplays = mDisplays.values().stream() .filter(display -> enabledDisplayTypes.containsKey(display.getDisplayId())) .toArray(size -> new Display[size]); } @NonNull public FakeDeviceConfig getDeviceConfig() { return mDeviceConfig; Loading Loading @@ -3939,10 +3954,16 @@ public class DisplayModeDirectorTest { return mDisplays.values().toArray(new Display[0]); } @Override public Display[] getEnabledDisplays() { return mEnabledDisplays; } @Override public boolean getDisplayInfo(int displayId, DisplayInfo displayInfo) { displayInfo.copyFrom(mDisplayInfo); displayInfo.displayId = displayId; displayInfo.type = mEnabledDisplayTypes.getOrDefault(displayId, Display.TYPE_INTERNAL); return mDisplayInfoValid; } Loading