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

Commit a8451896 authored by Oleg Blinnikov's avatar Oleg Blinnikov
Browse files

Initial call to addDisplay in DisplayModeDirector

If display is added during boot, it does not trigger onDisplayAdded during DisplayModeDirector start upon systemReady call.

This CL fixes this by explicitly calling onDisplayAdded method for all enabled displays.

Bug: 414778119
Test: atest DisplayModeDirectorTest
Flag: com.android.server.display.feature.flags.enable_on_display_added_in_observer
Change-Id: I6dfdc32db54471682ce120fe0851274ae1340f0d
parent 7d29380a
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -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.
     */
@@ -662,6 +667,10 @@ public class DisplayManagerFlags {
        return mEnsureColorFadeWhenTurningOn.isEnabled();
    }

    public boolean isOnDisplayAddedInObserverEnabled() {
        return mIsOnDisplayAddedInObserverEnabled.isEnabled();
    }

    /**
     * dumps all flagstates
     * @param pw printWriter
@@ -726,6 +735,7 @@ public class DisplayManagerFlags {
        pw.println(" " + mEnableDefaultDisplayInTopologySwitch);
        pw.println(" " + mModeSwitchWithoutSaving);
        pw.println(" " + mEnsureColorFadeWhenTurningOn);
        pw.println(" " + mIsOnDisplayAddedInObserverEnabled);
    }

    private static class FlagState {
+10 −0
Original line number Diff line number Diff line
@@ -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
    }
}
+49 −24
Original line number Diff line number Diff line
@@ -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<>();
@@ -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);
@@ -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);
@@ -3139,6 +3157,8 @@ public class DisplayModeDirector {

        Display[] getDisplays();

        Display[] getEnabledDisplays();

        boolean getDisplayInfo(int displayId, DisplayInfo displayInfo);

        BrightnessInfo getBrightnessInfo(int displayId);
@@ -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);
+29 −8
Original line number Diff line number Diff line
@@ -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() {
@@ -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[] {
@@ -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
@@ -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());
@@ -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;
@@ -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;
@@ -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;
        }