Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d471adc9 authored by Oleg Petšjonkin's avatar Oleg Petšjonkin Committed by Android (Google) Code Review
Browse files

Merge "Do not allow app to change resolution on ext. display" into main

parents fe06ce7a cdd7a5c0
Loading
Loading
Loading
Loading
+20 −9
Original line number Diff line number Diff line
@@ -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;

@@ -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(),
@@ -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:
@@ -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;
@@ -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);
@@ -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;
@@ -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) {
@@ -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();
+33 −0
Original line number Diff line number Diff line
@@ -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,