diff options
| author | 2023-02-03 15:56:17 +0000 | |
|---|---|---|
| committer | 2023-02-17 14:05:18 +0000 | |
| commit | c2aba03600de67544609d53b43a07062d82ec8d7 (patch) | |
| tree | 64ccc59beb0329e2f438c35c0ae28cf0c9ecada2 | |
| parent | 7137d9165d25c7ddec6fe92e9d83a83ceceeafb0 (diff) | |
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
(cherry picked from commit b6b448765890bab25751cd606aea1087d43e30f7)
Merged-In: I11f65f008791470b00a1677beab3f6168589608f
6 files changed, 117 insertions, 10 deletions
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 850f6da7e35f..81e550e3d62f 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -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); } diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index 82e6e308cab3..40c879a3c5e7 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -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; } } } diff --git a/services/core/java/com/android/server/display/DisplayPowerController2.java b/services/core/java/com/android/server/display/DisplayPowerController2.java index 0861a37247c4..5ea8aaa5e814 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController2.java +++ b/services/core/java/com/android/server/display/DisplayPowerController2.java @@ -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; } } } diff --git a/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java b/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java index 0bc8154b610c..73edb970ff95 100644 --- a/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java +++ b/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java @@ -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(); } diff --git a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java index 6e63315d2830..b9f2059c0799 100644 --- a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java +++ b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java @@ -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, /* bootCompleted= */ false); return new DisplayPowerControllerHolder(dpc, displayPowerState, brightnessSetting, animator, automaticBrightnessController, wakelockController); diff --git a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java index a8c3e4e9dc7e..1e9041c48e44 100644 --- a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java @@ -464,6 +464,25 @@ public final class DisplayPowerControllerTest { verify(secondFollowerHolder.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); @@ -489,7 +508,7 @@ public final class DisplayPowerControllerTest { mContextSpy, injector, mDisplayPowerCallbacksMock, mHandler, mSensorManagerMock, mDisplayBlankerMock, display, mBrightnessTrackerMock, brightnessSetting, () -> {}, - hbmMetadata); + hbmMetadata, /* bootCompleted= */ false); return new DisplayPowerControllerHolder(dpc, displayPowerState, brightnessSetting, animator, automaticBrightnessController); |