diff options
| -rw-r--r-- | services/core/java/com/android/server/display/DisplayModeDirector.java | 30 | ||||
| -rw-r--r-- | services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java | 90 |
2 files changed, 77 insertions, 43 deletions
diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java index dce6bd849953..645ca7ac33e0 100644 --- a/services/core/java/com/android/server/display/DisplayModeDirector.java +++ b/services/core/java/com/android/server/display/DisplayModeDirector.java @@ -31,7 +31,6 @@ import android.net.Uri; import android.os.Handler; import android.os.Looper; import android.os.Message; -import android.os.PowerManager; import android.os.SystemClock; import android.os.UserHandle; import android.provider.DeviceConfig; @@ -80,6 +79,8 @@ public class DisplayModeDirector { // specific display. private static final int GLOBAL_ID = -1; + private static final int INVALID_DISPLAY_MODE_ID = -1; + // The tolerance within which we consider something approximately equals. private static final float FLOAT_TOLERANCE = 0.01f; @@ -322,12 +323,30 @@ public class DisplayModeDirector { appRequestSummary.maxRefreshRate)); } - // If the application requests a given mode with preferredModeId function, it will be - // stored as baseModeId. - int baseModeId = defaultMode.getModeId(); - if (availableModes.length > 0) { + int baseModeId = INVALID_DISPLAY_MODE_ID; + + // Select the default mode if available. This is important because SurfaceFlinger + // can do only seamless switches by default. Some devices (e.g. TV) don't support + // seamless switching so the mode we select here won't be changed. + for (int availableMode : availableModes) { + if (availableMode == defaultMode.getModeId()) { + baseModeId = defaultMode.getModeId(); + break; + } + } + + // If the application requests a display mode by setting + // LayoutParams.preferredDisplayModeId, it will be the only available mode and it'll + // be stored as baseModeId. + if (baseModeId == INVALID_DISPLAY_MODE_ID && availableModes.length > 0) { baseModeId = availableModes[0]; } + + if (baseModeId == INVALID_DISPLAY_MODE_ID) { + throw new IllegalStateException("Can't select a base display mode for display " + + displayId + ". The votes are " + mVotesByDisplay.valueAt(displayId)); + } + if (mModeSwitchingType == DisplayManager.SWITCHING_TYPE_NONE) { Display.Mode baseMode = null; for (Display.Mode mode : modes) { @@ -351,6 +370,7 @@ public class DisplayModeDirector { boolean allowGroupSwitching = mModeSwitchingType == DisplayManager.SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS; + return new DesiredDisplayModeSpecs(baseModeId, allowGroupSwitching, new RefreshRateRange( diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java index 81b2381cd629..15ada896512b 100644 --- a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java +++ b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java @@ -88,6 +88,7 @@ public class DisplayModeDirectorTest { private static final String TAG = "DisplayModeDirectorTest"; private static final boolean DEBUG = false; private static final float FLOAT_TOLERANCE = 0.01f; + private static final int DISPLAY_ID = 0; private Context mContext; private FakesInjector mInjector; @@ -107,19 +108,29 @@ public class DisplayModeDirectorTest { private DisplayModeDirector createDirectorFromRefreshRateArray( float[] refreshRates, int baseModeId) { + return createDirectorFromRefreshRateArray(refreshRates, baseModeId, refreshRates[0]); + } + + private DisplayModeDirector createDirectorFromRefreshRateArray( + float[] refreshRates, int baseModeId, float defaultRefreshRate) { DisplayModeDirector director = new DisplayModeDirector(mContext, mHandler, mInjector); - int displayId = 0; Display.Mode[] modes = new Display.Mode[refreshRates.length]; + Display.Mode defaultMode = null; for (int i = 0; i < refreshRates.length; i++) { modes[i] = new Display.Mode( /*modeId=*/baseModeId + i, /*width=*/1000, /*height=*/1000, refreshRates[i]); + if (refreshRates[i] == defaultRefreshRate) { + defaultMode = modes[i]; + } } + assertThat(defaultMode).isNotNull(); + SparseArray<Display.Mode[]> supportedModesByDisplay = new SparseArray<>(); - supportedModesByDisplay.put(displayId, modes); + supportedModesByDisplay.put(DISPLAY_ID, modes); director.injectSupportedModesByDisplay(supportedModesByDisplay); SparseArray<Display.Mode> defaultModesByDisplay = new SparseArray<>(); - defaultModesByDisplay.put(displayId, modes[0]); + defaultModesByDisplay.put(DISPLAY_ID, defaultMode); director.injectDefaultModeByDisplay(defaultModesByDisplay); return director; } @@ -130,16 +141,15 @@ public class DisplayModeDirectorTest { for (int i = 0; i < numRefreshRates; i++) { refreshRates[i] = minFps + i; } - return createDirectorFromRefreshRateArray(refreshRates, /*baseModeId=*/minFps); + return createDirectorFromRefreshRateArray(refreshRates, /*baseModeId=*/minFps, + /*defaultRefreshRate=*/minFps); } @Test public void testDisplayModeVoting() { - int displayId = 0; - // With no votes present, DisplayModeDirector should allow any refresh rate. DesiredDisplayModeSpecs modeSpecs = - createDirectorFromFpsRange(60, 90).getDesiredDisplayModeSpecs(displayId); + createDirectorFromFpsRange(60, 90).getDesiredDisplayModeSpecs(DISPLAY_ID); assertThat(modeSpecs.baseModeId).isEqualTo(60); assertThat(modeSpecs.primaryRefreshRateRange.min).isEqualTo(0f); assertThat(modeSpecs.primaryRefreshRateRange.max).isEqualTo(Float.POSITIVE_INFINITY); @@ -156,12 +166,12 @@ public class DisplayModeDirectorTest { assertTrue(2 * numPriorities < maxFps - minFps + 1); SparseArray<Vote> votes = new SparseArray<>(); SparseArray<SparseArray<Vote>> votesByDisplay = new SparseArray<>(); - votesByDisplay.put(displayId, votes); + votesByDisplay.put(DISPLAY_ID, votes); for (int i = 0; i < numPriorities; i++) { int priority = Vote.MIN_PRIORITY + i; votes.put(priority, Vote.forRefreshRates(minFps + i, maxFps - i)); director.injectVotesByDisplay(votesByDisplay); - modeSpecs = director.getDesiredDisplayModeSpecs(displayId); + modeSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID); assertThat(modeSpecs.baseModeId).isEqualTo(minFps + i); assertThat(modeSpecs.primaryRefreshRateRange.min) .isEqualTo((float) (minFps + i)); @@ -177,11 +187,11 @@ public class DisplayModeDirectorTest { DisplayModeDirector director = createDirectorFromFpsRange(60, 90); SparseArray<Vote> votes = new SparseArray<>(); SparseArray<SparseArray<Vote>> votesByDisplay = new SparseArray<>(); - votesByDisplay.put(displayId, votes); + votesByDisplay.put(DISPLAY_ID, votes); votes.put(Vote.MAX_PRIORITY, Vote.forRefreshRates(65, 85)); votes.put(Vote.MIN_PRIORITY, Vote.forRefreshRates(70, 80)); director.injectVotesByDisplay(votesByDisplay); - modeSpecs = director.getDesiredDisplayModeSpecs(displayId); + modeSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID); assertThat(modeSpecs.baseModeId).isEqualTo(70); assertThat(modeSpecs.primaryRefreshRateRange.min).isEqualTo(70f); assertThat(modeSpecs.primaryRefreshRateRange.max).isEqualTo(80f); @@ -190,18 +200,17 @@ public class DisplayModeDirectorTest { @Test public void testVotingWithFloatingPointErrors() { - int displayId = 0; DisplayModeDirector director = createDirectorFromFpsRange(50, 90); SparseArray<Vote> votes = new SparseArray<>(); SparseArray<SparseArray<Vote>> votesByDisplay = new SparseArray<>(); - votesByDisplay.put(displayId, votes); + votesByDisplay.put(DISPLAY_ID, votes); float error = FLOAT_TOLERANCE / 4; votes.put(Vote.PRIORITY_USER_SETTING_PEAK_REFRESH_RATE, Vote.forRefreshRates(0, 60)); votes.put(Vote.PRIORITY_APP_REQUEST_SIZE, Vote.forRefreshRates(60 + error, 60 + error)); votes.put(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, Vote.forRefreshRates(60 - error, 60 - error)); director.injectVotesByDisplay(votesByDisplay); - DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); + DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID); assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60); assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60); @@ -213,15 +222,14 @@ public class DisplayModeDirectorTest { assertTrue(PRIORITY_FLICKER < Vote.PRIORITY_APP_REQUEST_REFRESH_RATE); assertTrue(PRIORITY_FLICKER < Vote.PRIORITY_APP_REQUEST_SIZE); - int displayId = 0; DisplayModeDirector director = createDirectorFromFpsRange(60, 90); SparseArray<Vote> votes = new SparseArray<>(); SparseArray<SparseArray<Vote>> votesByDisplay = new SparseArray<>(); - votesByDisplay.put(displayId, votes); + votesByDisplay.put(DISPLAY_ID, votes); votes.put(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, Vote.forRefreshRates(60, 90)); votes.put(PRIORITY_FLICKER, Vote.forRefreshRates(60, 60)); director.injectVotesByDisplay(votesByDisplay); - DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); + DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID); assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60); assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60); @@ -229,7 +237,7 @@ public class DisplayModeDirectorTest { votes.put(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, Vote.forRefreshRates(60, 90)); votes.put(PRIORITY_FLICKER, Vote.forRefreshRates(90, 90)); director.injectVotesByDisplay(votesByDisplay); - desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); + desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID); assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(90); assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(90); @@ -237,7 +245,7 @@ public class DisplayModeDirectorTest { votes.put(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, Vote.forRefreshRates(90, 90)); votes.put(PRIORITY_FLICKER, Vote.forRefreshRates(60, 60)); director.injectVotesByDisplay(votesByDisplay); - desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); + desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID); assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(90); assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(90); @@ -245,7 +253,7 @@ public class DisplayModeDirectorTest { votes.put(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, Vote.forRefreshRates(60, 60)); votes.put(PRIORITY_FLICKER, Vote.forRefreshRates(90, 90)); director.injectVotesByDisplay(votesByDisplay); - desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); + desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID); assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60); assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60); } @@ -261,14 +269,13 @@ public class DisplayModeDirectorTest { assertTrue(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE >= Vote.APP_REQUEST_REFRESH_RATE_RANGE_PRIORITY_CUTOFF); - int displayId = 0; DisplayModeDirector director = createDirectorFromFpsRange(60, 90); SparseArray<Vote> votes = new SparseArray<>(); SparseArray<SparseArray<Vote>> votesByDisplay = new SparseArray<>(); - votesByDisplay.put(displayId, votes); + votesByDisplay.put(DISPLAY_ID, votes); votes.put(PRIORITY_FLICKER, Vote.forRefreshRates(60, 60)); director.injectVotesByDisplay(votesByDisplay); - DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); + DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID); assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60); assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60); assertThat(desiredSpecs.appRequestRefreshRateRange.min).isAtMost(60f); @@ -277,7 +284,7 @@ public class DisplayModeDirectorTest { votes.put(Vote.PRIORITY_USER_SETTING_MIN_REFRESH_RATE, Vote.forRefreshRates(90, Float.POSITIVE_INFINITY)); director.injectVotesByDisplay(votesByDisplay); - desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); + desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID); assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(90); assertThat(desiredSpecs.primaryRefreshRateRange.max).isAtLeast(90f); assertThat(desiredSpecs.appRequestRefreshRateRange.min).isAtMost(60f); @@ -285,7 +292,7 @@ public class DisplayModeDirectorTest { votes.put(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, Vote.forRefreshRates(75, 75)); director.injectVotesByDisplay(votesByDisplay); - desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); + desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID); assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(75); assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(75); assertThat(desiredSpecs.appRequestRefreshRateRange.min) @@ -355,11 +362,10 @@ public class DisplayModeDirectorTest { @Test public void testVotingWithAlwaysRespectAppRequest() { - final int displayId = 0; DisplayModeDirector director = createDirectorFromFpsRange(50, 90); SparseArray<Vote> votes = new SparseArray<>(); SparseArray<SparseArray<Vote>> votesByDisplay = new SparseArray<>(); - votesByDisplay.put(displayId, votes); + votesByDisplay.put(DISPLAY_ID, votes); votes.put(PRIORITY_FLICKER, Vote.forRefreshRates(0, 60)); votes.put(Vote.PRIORITY_USER_SETTING_MIN_REFRESH_RATE, Vote.forRefreshRates(60, 90)); votes.put(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, Vote.forRefreshRates(90, 90)); @@ -369,7 +375,7 @@ public class DisplayModeDirectorTest { director.injectVotesByDisplay(votesByDisplay); assertThat(director.shouldAlwaysRespectAppRequestedMode()).isFalse(); - DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); + DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID); assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60); assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60); @@ -377,7 +383,7 @@ public class DisplayModeDirectorTest { director.setShouldAlwaysRespectAppRequestedMode(true); assertThat(director.shouldAlwaysRespectAppRequestedMode()).isTrue(); - desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); + desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID); assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(90); assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(90); assertThat(desiredSpecs.baseModeId).isEqualTo(90); @@ -385,7 +391,7 @@ public class DisplayModeDirectorTest { director.setShouldAlwaysRespectAppRequestedMode(false); assertThat(director.shouldAlwaysRespectAppRequestedMode()).isFalse(); - desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); + desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID); assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60); assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60); assertThat(desiredSpecs.baseModeId).isEqualTo(60); @@ -393,11 +399,10 @@ public class DisplayModeDirectorTest { @Test public void testVotingWithSwitchingTypeNone() { - final int displayId = 0; DisplayModeDirector director = createDirectorFromFpsRange(0, 90); SparseArray<Vote> votes = new SparseArray<>(); SparseArray<SparseArray<Vote>> votesByDisplay = new SparseArray<>(); - votesByDisplay.put(displayId, votes); + votesByDisplay.put(DISPLAY_ID, votes); votes.put(Vote.PRIORITY_USER_SETTING_MIN_REFRESH_RATE, Vote.forRefreshRates(30, 90)); votes.put(Vote.PRIORITY_LOW_POWER_MODE, Vote.forRefreshRates(0, 60)); @@ -405,7 +410,7 @@ public class DisplayModeDirectorTest { director.injectVotesByDisplay(votesByDisplay); assertThat(director.getModeSwitchingType()) .isNotEqualTo(DisplayManager.SWITCHING_TYPE_NONE); - DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); + DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID); assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(30); assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60); @@ -417,7 +422,7 @@ public class DisplayModeDirectorTest { assertThat(director.getModeSwitchingType()) .isEqualTo(DisplayManager.SWITCHING_TYPE_NONE); - desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); + desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID); assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(30); assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(30); assertThat(desiredSpecs.appRequestRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(30); @@ -427,29 +432,38 @@ public class DisplayModeDirectorTest { @Test public void testVotingWithSwitchingTypeWithinGroups() { - final int displayId = 0; DisplayModeDirector director = createDirectorFromFpsRange(0, 90); director.setModeSwitchingType(DisplayManager.SWITCHING_TYPE_WITHIN_GROUPS); assertThat(director.getModeSwitchingType()) .isEqualTo(DisplayManager.SWITCHING_TYPE_WITHIN_GROUPS); - DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); + DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID); assertThat(desiredSpecs.allowGroupSwitching).isFalse(); } @Test public void testVotingWithSwitchingTypeWithinAndAcrossGroups() { - final int displayId = 0; DisplayModeDirector director = createDirectorFromFpsRange(0, 90); director.setModeSwitchingType(DisplayManager.SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS); assertThat(director.getModeSwitchingType()) .isEqualTo(DisplayManager.SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS); - DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); + DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID); assertThat(desiredSpecs.allowGroupSwitching).isTrue(); } @Test + public void testDefaultDisplayModeIsSelectedIfAvailable() { + final float[] refreshRates = new float[]{24f, 25f, 30f, 60f, 90f}; + final int defaultModeId = 3; + DisplayModeDirector director = createDirectorFromRefreshRateArray( + refreshRates, /*baseModeId=*/0, refreshRates[defaultModeId]); + + DesiredDisplayModeSpecs specs = director.getDesiredDisplayModeSpecs(DISPLAY_ID); + assertThat(specs.baseModeId).isEqualTo(defaultModeId); + } + + @Test public void testBrightnessObserverGetsUpdatedRefreshRatesForZone() { DisplayModeDirector director = createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, /* baseModeId= */ 0); |