Loading services/core/java/com/android/server/display/DisplayModeDirector.java +25 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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) { Loading @@ -351,6 +370,7 @@ public class DisplayModeDirector { boolean allowGroupSwitching = mModeSwitchingType == DisplayManager.SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS; return new DesiredDisplayModeSpecs(baseModeId, allowGroupSwitching, new RefreshRateRange( Loading services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java +1 −0 Original line number Diff line number Diff line Loading @@ -592,6 +592,7 @@ public class LocalDisplayAdapterTest { new DisplayModeDirector.RefreshRateRange(60f, 60f), new DisplayModeDirector.RefreshRateRange(60f, 60f) )); waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS); verify(mSurfaceControlProxy).setDesiredDisplayModeSpecs(display.token, new SurfaceControl.DesiredDisplayModeSpecs( /* baseModeId */ 0, Loading services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java +52 −38 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; } Loading @@ -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); Loading @@ -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)); Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading @@ -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); } Loading @@ -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); Loading @@ -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); Loading @@ -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) Loading Loading @@ -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)); Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading @@ -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)); Loading @@ -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); Loading @@ -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); Loading @@ -427,28 +432,37 @@ 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 = Loading Loading
services/core/java/com/android/server/display/DisplayModeDirector.java +25 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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) { Loading @@ -351,6 +370,7 @@ public class DisplayModeDirector { boolean allowGroupSwitching = mModeSwitchingType == DisplayManager.SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS; return new DesiredDisplayModeSpecs(baseModeId, allowGroupSwitching, new RefreshRateRange( Loading
services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java +1 −0 Original line number Diff line number Diff line Loading @@ -592,6 +592,7 @@ public class LocalDisplayAdapterTest { new DisplayModeDirector.RefreshRateRange(60f, 60f), new DisplayModeDirector.RefreshRateRange(60f, 60f) )); waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS); verify(mSurfaceControlProxy).setDesiredDisplayModeSpecs(display.token, new SurfaceControl.DesiredDisplayModeSpecs( /* baseModeId */ 0, Loading
services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java +52 −38 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; } Loading @@ -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); Loading @@ -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)); Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading @@ -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); } Loading @@ -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); Loading @@ -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); Loading @@ -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) Loading Loading @@ -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)); Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading @@ -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)); Loading @@ -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); Loading @@ -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); Loading @@ -427,28 +432,37 @@ 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 = Loading