Loading services/core/java/com/android/server/display/mode/DisplayModeDirector.java +20 −9 Original line number Diff line number Diff line Loading @@ -156,6 +156,8 @@ public class DisplayModeDirector { private SparseArray<Display.Mode> mDefaultModeByDisplay; // a map from display id to display device config private SparseArray<DisplayDeviceConfig> mDisplayDeviceConfigByDisplay = new SparseArray<>(); // set containing connected external display ids private final Set<Integer> mExternalDisplaysConnected = new HashSet<>(); private SparseBooleanArray mHasArrSupport; Loading Loading @@ -425,7 +427,7 @@ public class DisplayModeDirector { // Some external displays physical refresh rate modes are slightly above 60hz. // SurfaceFlinger will not enable these display modes unless it is configured to allow // render rate at least at this frame rate. if (mDisplayObserver.isExternalDisplayLocked(displayId)) { if (isExternalDisplayLocked(displayId)) { primarySummary.maxRenderFrameRate = Math.max(baseMode.getRefreshRate(), primarySummary.maxRenderFrameRate); appRequestSummary.maxRenderFrameRate = Math.max(baseMode.getRefreshRate(), Loading Loading @@ -653,6 +655,10 @@ public class DisplayModeDirector { } } boolean isExternalDisplayLocked(int displayId) { return mExternalDisplaysConnected.contains(displayId); } private static String switchingTypeToString(@DisplayManager.SwitchingType int type) { switch (type) { case DisplayManager.SWITCHING_TYPE_NONE: Loading Loading @@ -693,6 +699,11 @@ public class DisplayModeDirector { mVotesStorage.injectVotesByDisplay(votesByDisplay); } @VisibleForTesting void addExternalDisplayId(int externalDisplayId) { mExternalDisplaysConnected.add(externalDisplayId); } @VisibleForTesting void injectBrightnessObserver(BrightnessObserver brightnessObserver) { mBrightnessObserver = brightnessObserver; Loading Loading @@ -1210,7 +1221,7 @@ public class DisplayModeDirector { @GuardedBy("mLock") private void updateRefreshRateSettingLocked(float minRefreshRate, float peakRefreshRate, float defaultRefreshRate, int displayId) { if (mDisplayObserver.isExternalDisplayLocked(displayId)) { if (isExternalDisplayLocked(displayId)) { if (mLoggingEnabled) { Slog.d(TAG, "skip updateRefreshRateSettingLocked for external display " + displayId); Loading Loading @@ -1309,21 +1320,26 @@ public class DisplayModeDirector { public void setAppRequest(int displayId, int modeId, float requestedRefreshRate, float requestedMinRefreshRateRange, float requestedMaxRefreshRateRange) { Display.Mode requestedMode; boolean isExternalDisplay; synchronized (mLock) { requestedMode = findModeLocked(displayId, modeId, requestedRefreshRate); isExternalDisplay = isExternalDisplayLocked(displayId); } Vote frameRateVote = getFrameRateVote( requestedMinRefreshRateRange, requestedMaxRefreshRateRange); Vote baseModeRefreshRateVote = getBaseModeVote(requestedMode, requestedRefreshRate); Vote sizeVote = getSizeVote(requestedMode); mVotesStorage.updateVote(displayId, Vote.PRIORITY_APP_REQUEST_RENDER_FRAME_RATE_RANGE, frameRateVote); mVotesStorage.updateVote(displayId, Vote.PRIORITY_APP_REQUEST_BASE_MODE_REFRESH_RATE, baseModeRefreshRateVote); if (!isExternalDisplay) { Vote sizeVote = getSizeVote(requestedMode); mVotesStorage.updateVote(displayId, Vote.PRIORITY_APP_REQUEST_SIZE, sizeVote); } } private Display.Mode findModeLocked(int displayId, int modeId, float requestedRefreshRate) { Display.Mode mode = null; Loading Loading @@ -1420,7 +1436,6 @@ public class DisplayModeDirector { private int mExternalDisplayPeakHeight; private int mExternalDisplayPeakRefreshRate; private final boolean mRefreshRateSynchronizationEnabled; private final Set<Integer> mExternalDisplaysConnected = new HashSet<>(); DisplayObserver(Context context, Handler handler, VotesStorage votesStorage, Injector injector) { Loading Loading @@ -1541,10 +1556,6 @@ public class DisplayModeDirector { } } boolean isExternalDisplayLocked(int displayId) { return mExternalDisplaysConnected.contains(displayId); } @Nullable private DisplayInfo getDisplayInfo(int displayId) { DisplayInfo info = new DisplayInfo(); Loading services/tests/displayservicetests/src/com/android/server/display/mode/AppRequestObserverTest.kt +33 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,39 @@ class AppRequestObserverTest { assertThat(renderRateVote).isEqualTo(testCase.expectedRenderRateVote) } @Test fun testAppRequestVote_externalDisplay() { val displayModeDirector = DisplayModeDirector( context, testHandler, mockInjector, mockFlags, mockDisplayDeviceConfigProvider) val modes = arrayOf( Display.Mode(1, 1000, 1000, 60f), Display.Mode(2, 1000, 1000, 90f), ) displayModeDirector.injectAppSupportedModesByDisplay( SparseArray<Array<Display.Mode>>().apply { append(Display.DEFAULT_DISPLAY, modes) }) displayModeDirector.injectDefaultModeByDisplay(SparseArray<Display.Mode>().apply { append(Display.DEFAULT_DISPLAY, modes[0]) }) displayModeDirector.addExternalDisplayId(Display.DEFAULT_DISPLAY) displayModeDirector.appRequestObserver.setAppRequest(Display.DEFAULT_DISPLAY, 1, 0f, 0f, 0f) val baseModeVote = displayModeDirector.getVote(Display.DEFAULT_DISPLAY, Vote.PRIORITY_APP_REQUEST_BASE_MODE_REFRESH_RATE) assertThat(baseModeVote).isEqualTo(BaseModeRefreshRateVote(60f)) val sizeVote = displayModeDirector.getVote(Display.DEFAULT_DISPLAY, Vote.PRIORITY_APP_REQUEST_SIZE) assertThat(sizeVote).isNull() val renderRateVote = displayModeDirector.getVote(Display.DEFAULT_DISPLAY, Vote.PRIORITY_APP_REQUEST_RENDER_FRAME_RATE_RANGE) assertThat(renderRateVote).isNull() } enum class AppRequestTestCase( val ignoreRefreshRateRequest: Boolean, val modeId: Int, Loading Loading
services/core/java/com/android/server/display/mode/DisplayModeDirector.java +20 −9 Original line number Diff line number Diff line Loading @@ -156,6 +156,8 @@ public class DisplayModeDirector { private SparseArray<Display.Mode> mDefaultModeByDisplay; // a map from display id to display device config private SparseArray<DisplayDeviceConfig> mDisplayDeviceConfigByDisplay = new SparseArray<>(); // set containing connected external display ids private final Set<Integer> mExternalDisplaysConnected = new HashSet<>(); private SparseBooleanArray mHasArrSupport; Loading Loading @@ -425,7 +427,7 @@ public class DisplayModeDirector { // Some external displays physical refresh rate modes are slightly above 60hz. // SurfaceFlinger will not enable these display modes unless it is configured to allow // render rate at least at this frame rate. if (mDisplayObserver.isExternalDisplayLocked(displayId)) { if (isExternalDisplayLocked(displayId)) { primarySummary.maxRenderFrameRate = Math.max(baseMode.getRefreshRate(), primarySummary.maxRenderFrameRate); appRequestSummary.maxRenderFrameRate = Math.max(baseMode.getRefreshRate(), Loading Loading @@ -653,6 +655,10 @@ public class DisplayModeDirector { } } boolean isExternalDisplayLocked(int displayId) { return mExternalDisplaysConnected.contains(displayId); } private static String switchingTypeToString(@DisplayManager.SwitchingType int type) { switch (type) { case DisplayManager.SWITCHING_TYPE_NONE: Loading Loading @@ -693,6 +699,11 @@ public class DisplayModeDirector { mVotesStorage.injectVotesByDisplay(votesByDisplay); } @VisibleForTesting void addExternalDisplayId(int externalDisplayId) { mExternalDisplaysConnected.add(externalDisplayId); } @VisibleForTesting void injectBrightnessObserver(BrightnessObserver brightnessObserver) { mBrightnessObserver = brightnessObserver; Loading Loading @@ -1210,7 +1221,7 @@ public class DisplayModeDirector { @GuardedBy("mLock") private void updateRefreshRateSettingLocked(float minRefreshRate, float peakRefreshRate, float defaultRefreshRate, int displayId) { if (mDisplayObserver.isExternalDisplayLocked(displayId)) { if (isExternalDisplayLocked(displayId)) { if (mLoggingEnabled) { Slog.d(TAG, "skip updateRefreshRateSettingLocked for external display " + displayId); Loading Loading @@ -1309,21 +1320,26 @@ public class DisplayModeDirector { public void setAppRequest(int displayId, int modeId, float requestedRefreshRate, float requestedMinRefreshRateRange, float requestedMaxRefreshRateRange) { Display.Mode requestedMode; boolean isExternalDisplay; synchronized (mLock) { requestedMode = findModeLocked(displayId, modeId, requestedRefreshRate); isExternalDisplay = isExternalDisplayLocked(displayId); } Vote frameRateVote = getFrameRateVote( requestedMinRefreshRateRange, requestedMaxRefreshRateRange); Vote baseModeRefreshRateVote = getBaseModeVote(requestedMode, requestedRefreshRate); Vote sizeVote = getSizeVote(requestedMode); mVotesStorage.updateVote(displayId, Vote.PRIORITY_APP_REQUEST_RENDER_FRAME_RATE_RANGE, frameRateVote); mVotesStorage.updateVote(displayId, Vote.PRIORITY_APP_REQUEST_BASE_MODE_REFRESH_RATE, baseModeRefreshRateVote); if (!isExternalDisplay) { Vote sizeVote = getSizeVote(requestedMode); mVotesStorage.updateVote(displayId, Vote.PRIORITY_APP_REQUEST_SIZE, sizeVote); } } private Display.Mode findModeLocked(int displayId, int modeId, float requestedRefreshRate) { Display.Mode mode = null; Loading Loading @@ -1420,7 +1436,6 @@ public class DisplayModeDirector { private int mExternalDisplayPeakHeight; private int mExternalDisplayPeakRefreshRate; private final boolean mRefreshRateSynchronizationEnabled; private final Set<Integer> mExternalDisplaysConnected = new HashSet<>(); DisplayObserver(Context context, Handler handler, VotesStorage votesStorage, Injector injector) { Loading Loading @@ -1541,10 +1556,6 @@ public class DisplayModeDirector { } } boolean isExternalDisplayLocked(int displayId) { return mExternalDisplaysConnected.contains(displayId); } @Nullable private DisplayInfo getDisplayInfo(int displayId) { DisplayInfo info = new DisplayInfo(); Loading
services/tests/displayservicetests/src/com/android/server/display/mode/AppRequestObserverTest.kt +33 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,39 @@ class AppRequestObserverTest { assertThat(renderRateVote).isEqualTo(testCase.expectedRenderRateVote) } @Test fun testAppRequestVote_externalDisplay() { val displayModeDirector = DisplayModeDirector( context, testHandler, mockInjector, mockFlags, mockDisplayDeviceConfigProvider) val modes = arrayOf( Display.Mode(1, 1000, 1000, 60f), Display.Mode(2, 1000, 1000, 90f), ) displayModeDirector.injectAppSupportedModesByDisplay( SparseArray<Array<Display.Mode>>().apply { append(Display.DEFAULT_DISPLAY, modes) }) displayModeDirector.injectDefaultModeByDisplay(SparseArray<Display.Mode>().apply { append(Display.DEFAULT_DISPLAY, modes[0]) }) displayModeDirector.addExternalDisplayId(Display.DEFAULT_DISPLAY) displayModeDirector.appRequestObserver.setAppRequest(Display.DEFAULT_DISPLAY, 1, 0f, 0f, 0f) val baseModeVote = displayModeDirector.getVote(Display.DEFAULT_DISPLAY, Vote.PRIORITY_APP_REQUEST_BASE_MODE_REFRESH_RATE) assertThat(baseModeVote).isEqualTo(BaseModeRefreshRateVote(60f)) val sizeVote = displayModeDirector.getVote(Display.DEFAULT_DISPLAY, Vote.PRIORITY_APP_REQUEST_SIZE) assertThat(sizeVote).isNull() val renderRateVote = displayModeDirector.getVote(Display.DEFAULT_DISPLAY, Vote.PRIORITY_APP_REQUEST_RENDER_FRAME_RATE_RANGE) assertThat(renderRateVote).isNull() } enum class AppRequestTestCase( val ignoreRefreshRateRequest: Boolean, val modeId: Int, Loading