summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Piotr Wilczyński <wilczynskip@google.com> 2023-02-03 15:56:17 +0000
committer Piotr Wilczyński <wilczynskip@google.com> 2023-02-17 14:05:18 +0000
commitc2aba03600de67544609d53b43a07062d82ec8d7 (patch)
tree64ccc59beb0329e2f438c35c0ae28cf0c9ecada2
parent7137d9165d25c7ddec6fe92e9d83a83ceceeafb0 (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
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java12
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController.java34
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController2.java34
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerControllerInterface.java5
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java21
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java21
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);