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

Commit b6b44876 authored by Piotr Wilczyński's avatar Piotr Wilczyński
Browse files

Don't set screen state until boot is completed

Setting the screen state of non-default displays during boot removes the static logo and results in either a black screen (if the display is off) or the boot animation with an incorrect size (if the display is on).

Bug: 267484164
Test: atest com.android.server.display
Change-Id: I11f65f008791470b00a1677beab3f6168589608f
parent 8f59bc4a
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -466,6 +466,8 @@ public final class DisplayManagerService extends SystemService {
    private boolean mIsDocked;
    private boolean mIsDreaming;

    private boolean mBootCompleted = false;

    private final BroadcastReceiver mIdleModeReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
@@ -602,6 +604,12 @@ public final class DisplayManagerService extends SystemService {
                }
            }
        } else if (phase == PHASE_BOOT_COMPLETED) {
            synchronized (mSyncRoot) {
                mBootCompleted = true;
                for (int i = 0; i < mDisplayPowerControllers.size(); i++) {
                    mDisplayPowerControllers.valueAt(i).onBootCompleted();
                }
            }
            mDisplayModeDirector.onBootCompleted();
            mLogicalDisplayMapper.onBootCompleted();
        }
@@ -2998,12 +3006,12 @@ public final class DisplayManagerService extends SystemService {
            displayPowerController = new DisplayPowerController2(
                    mContext, /* injector= */ null, mDisplayPowerCallbacks, mPowerHandler,
                    mSensorManager, mDisplayBlanker, display, mBrightnessTracker, brightnessSetting,
                    () -> handleBrightnessChange(display), hbmMetadata);
                    () -> handleBrightnessChange(display), hbmMetadata, mBootCompleted);
        } else {
            displayPowerController = new DisplayPowerController(
                    mContext, /* injector= */ null, mDisplayPowerCallbacks, mPowerHandler,
                    mSensorManager, mDisplayBlanker, display, mBrightnessTracker, brightnessSetting,
                    () -> handleBrightnessChange(display), hbmMetadata);
                    () -> handleBrightnessChange(display), hbmMetadata, mBootCompleted);
        }
        mDisplayPowerControllers.append(display.getDisplayIdLocked(), displayPowerController);
    }
+31 −3
Original line number Diff line number Diff line
@@ -139,6 +139,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
    private static final int MSG_BRIGHTNESS_RAMP_DONE = 12;
    private static final int MSG_STATSD_HBM_BRIGHTNESS = 13;
    private static final int MSG_SWITCH_USER = 14;
    private static final int MSG_BOOT_COMPLETED = 15;

    private static final int PROXIMITY_UNKNOWN = -1;
    private static final int PROXIMITY_NEGATIVE = 0;
@@ -518,6 +519,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
    private final SparseArray<DisplayPowerControllerInterface> mDisplayBrightnessFollowers =
            new SparseArray<>();

    private boolean mBootCompleted;

    /**
     * Creates the display power controller.
     */
@@ -525,7 +528,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
            DisplayPowerCallbacks callbacks, Handler handler,
            SensorManager sensorManager, DisplayBlanker blanker, LogicalDisplay logicalDisplay,
            BrightnessTracker brightnessTracker, BrightnessSetting brightnessSetting,
            Runnable onBrightnessChangeRunnable, HighBrightnessModeMetadata hbmMetadata) {
            Runnable onBrightnessChangeRunnable, HighBrightnessModeMetadata hbmMetadata,
            boolean bootCompleted) {

        mInjector = injector != null ? injector : new Injector();
        mClock = mInjector.getClock();
@@ -662,6 +666,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        mTemporaryAutoBrightnessAdjustment = PowerManager.BRIGHTNESS_INVALID_FLOAT;
        mPendingAutoBrightnessAdjustment = PowerManager.BRIGHTNESS_INVALID_FLOAT;

        mBootCompleted = bootCompleted;
    }

    private void applyReduceBrightColorsSplineAdjustment() {
@@ -1448,7 +1453,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call

        // Initialize things the first time the power state is changed.
        if (mustInitialize) {
            initialize(state);
            initialize(readyToUpdateDisplayState() ? state : Display.STATE_UNKNOWN);
        }

        // Animate the screen state change unless already animating.
@@ -2154,7 +2159,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
                }
            }

            if (!reportOnly && mPowerState.getScreenState() != state) {
            if (!reportOnly && mPowerState.getScreenState() != state
                    && readyToUpdateDisplayState()) {
                Trace.traceCounter(Trace.TRACE_TAG_POWER, "ScreenState", state);
                // TODO(b/153319140) remove when we can get this from the above trace invocation
                SystemProperties.set("debug.tracing.screen_state", String.valueOf(state));
@@ -2567,6 +2573,12 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        mBrightnessSetting.setBrightness(brightnessValue);
    }

    @Override
    public void onBootCompleted() {
        Message msg = mHandler.obtainMessage(MSG_BOOT_COMPLETED);
        mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
    }

    private void updateScreenBrightnessSetting(float brightnessValue) {
        if (!isValidBrightnessValue(brightnessValue)
                || brightnessValue == mCurrentScreenBrightnessSetting) {
@@ -2712,6 +2724,17 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        }
    };

    /**
     * Indicates whether the display state is ready to update. If this is the default display, we
     * want to update it right away so that we can draw the boot animation on it. If it is not
     * the default display, drawing the boot animation on it would look incorrect, so we need
     * to wait until boot is completed.
     * @return True if the display state is ready to update
     */
    private boolean readyToUpdateDisplayState() {
        return mDisplayId == Display.DEFAULT_DISPLAY || mBootCompleted;
    }

    @Override
    public void dump(final PrintWriter pw) {
        synchronized (mLock) {
@@ -3235,6 +3258,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
                case MSG_SWITCH_USER:
                    handleOnSwitchUser(msg.arg1);
                    break;

                case MSG_BOOT_COMPLETED:
                    mBootCompleted = true;
                    updatePowerState();
                    break;
            }
        }
    }
+31 −3
Original line number Diff line number Diff line
@@ -137,6 +137,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
    private static final int MSG_BRIGHTNESS_RAMP_DONE = 10;
    private static final int MSG_STATSD_HBM_BRIGHTNESS = 11;
    private static final int MSG_SWITCH_USER = 12;
    private static final int MSG_BOOT_COMPLETED = 13;

    private static final int BRIGHTNESS_CHANGE_STATSD_REPORT_INTERVAL_MS = 500;

@@ -425,6 +426,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
    private SparseArray<DisplayPowerControllerInterface> mDisplayBrightnessFollowers =
            new SparseArray();

    private boolean mBootCompleted;

    /**
     * Creates the display power controller.
     */
@@ -432,7 +435,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
            DisplayPowerCallbacks callbacks, Handler handler,
            SensorManager sensorManager, DisplayBlanker blanker, LogicalDisplay logicalDisplay,
            BrightnessTracker brightnessTracker, BrightnessSetting brightnessSetting,
            Runnable onBrightnessChangeRunnable, HighBrightnessModeMetadata hbmMetadata) {
            Runnable onBrightnessChangeRunnable, HighBrightnessModeMetadata hbmMetadata,
            boolean bootCompleted) {

        mInjector = injector != null ? injector : new Injector();
        mClock = mInjector.getClock();
@@ -555,6 +559,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
        mTemporaryAutoBrightnessAdjustment = PowerManager.BRIGHTNESS_INVALID_FLOAT;
        mPendingAutoBrightnessAdjustment = PowerManager.BRIGHTNESS_INVALID_FLOAT;

        mBootCompleted = bootCompleted;
    }

    private void applyReduceBrightColorsSplineAdjustment() {
@@ -1190,7 +1195,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal

        // Initialize things the first time the power state is changed.
        if (mustInitialize) {
            initialize(state);
            initialize(readyToUpdateDisplayState() ? state : Display.STATE_UNKNOWN);
        }

        // Animate the screen state change unless already animating.
@@ -1720,6 +1725,12 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
        }
    }

    @Override
    public void onBootCompleted() {
        Message msg = mHandler.obtainMessage(MSG_BOOT_COMPLETED);
        mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
    }

    private boolean saveBrightnessInfo(float brightness) {
        return saveBrightnessInfo(brightness, brightness);
    }
@@ -1861,7 +1872,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
                }
            }

            if (!reportOnly && mPowerState.getScreenState() != state) {
            if (!reportOnly && mPowerState.getScreenState() != state
                    && readyToUpdateDisplayState()) {
                Trace.traceCounter(Trace.TRACE_TAG_POWER, "ScreenState", state);
                // TODO(b/153319140) remove when we can get this from the above trace invocation
                SystemProperties.set("debug.tracing.screen_state", String.valueOf(state));
@@ -2519,6 +2531,17 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
        }
    }

    /**
     * Indicates whether the display state is ready to update. If this is the default display, we
     * want to update it right away so that we can draw the boot animation on it. If it is not
     * the default display, drawing the boot animation on it would look incorrect, so we need
     * to wait until boot is completed.
     * @return True if the display state is ready to update
     */
    private boolean readyToUpdateDisplayState() {
        return mDisplayId == Display.DEFAULT_DISPLAY || mBootCompleted;
    }

    // Return bucket index of range_[left]_[right] where
    // left <= nits < right
    private int nitsToRangeIndex(float nits) {
@@ -2738,6 +2761,11 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
                case MSG_SWITCH_USER:
                    handleOnSwitchUser(msg.arg1);
                    break;

                case MSG_BOOT_COMPLETED:
                    mBootCompleted = true;
                    updatePowerState();
                    break;
            }
        }
    }
+5 −0
Original line number Diff line number Diff line
@@ -206,4 +206,9 @@ public interface DisplayPowerControllerInterface {
     * @param follower The DPC to remove from the followers list
     */
    void removeDisplayBrightnessFollower(DisplayPowerControllerInterface follower);

    /**
     * Indicate that boot has been completed and the screen is ready to update.
     */
    void onBootCompleted();
}
+20 −1
Original line number Diff line number Diff line
@@ -460,6 +460,25 @@ public final class DisplayPowerController2Test {
        verify(secondFollowerDpc.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
    }

    @Test
    public void testDoesNotSetScreenStateForNonDefaultDisplayUntilBootCompleted() {
        // We should still set screen state for the default display
        DisplayPowerRequest dpr = new DisplayPowerRequest();
        mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
        advanceTime(1);
        verify(mHolder.displayPowerState).setScreenState(anyInt());

        mHolder = createDisplayPowerController(42, UNIQUE_ID);

        mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
        advanceTime(1);
        verify(mHolder.displayPowerState, never()).setScreenState(anyInt());

        mHolder.dpc.onBootCompleted();
        advanceTime(1);
        verify(mHolder.displayPowerState).setScreenState(anyInt());
    }

    private DisplayPowerControllerHolder createDisplayPowerController(int displayId,
            String uniqueId) {
        final DisplayPowerState displayPowerState = mock(DisplayPowerState.class);
@@ -487,7 +506,7 @@ public final class DisplayPowerController2Test {
                mContextSpy, injector, mDisplayPowerCallbacksMock, mHandler,
                mSensorManagerMock, mDisplayBlankerMock, display,
                mBrightnessTrackerMock, brightnessSetting, () -> {},
                hbmMetadata);
                hbmMetadata, false);

        return new DisplayPowerControllerHolder(dpc, displayPowerState, brightnessSetting, animator,
                automaticBrightnessController, wakelockController);
Loading