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

Commit dce110aa authored by Robert Horvath's avatar Robert Horvath Committed by David Zhao
Browse files

Prevent SurfaceFlinger from turning on display on quiescent boot

During a quiescent boot the screen is supposed to stay off, until the
user explicitly wakes the device again.
Therefore SurfaceFlinger should not unconditionally power on the display
when initializing.

Test: manual: `adb reboot quiescent` and observe calls to setPowerMode
Bug: 230576393
Bug: 230818009
Change-Id: Iaf5a9aabb484cdc4645dcb0e819b2cbf49d179e8
parent 76488200
Loading
Loading
Loading
Loading
+11 −4
Original line number Diff line number Diff line
@@ -424,7 +424,8 @@ SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag)
        mInternalDisplayDensity(
                getDensityFromProperty("ro.sf.lcd_density", !mEmulatedDisplayDensity)),
        mPowerAdvisor(std::make_unique<Hwc2::impl::PowerAdvisor>(*this)),
        mWindowInfosListenerInvoker(sp<WindowInfosListenerInvoker>::make()) {
        mWindowInfosListenerInvoker(sp<WindowInfosListenerInvoker>::make()),
        mSkipPowerOnForQuiescent(base::GetBoolProperty("ro.boot.quiescent"s, false)) {
    ALOGI("Using HWComposer service: %s", mHwcServiceName.c_str());
}

@@ -3882,7 +3883,9 @@ void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken,

        if (currentState.physical) {
            const auto display = getDisplayDeviceLocked(displayToken);
            if (!mSkipPowerOnForQuiescent) {
                setPowerModeInternal(display, hal::PowerMode::ON);
            }

            // TODO(b/175678251) Call a listener instead.
            if (currentState.physical->hwcDisplayId == getHwComposer().getPrimaryHwcDisplayId()) {
@@ -6101,11 +6104,14 @@ void SurfaceFlinger::initializeDisplays() {
        // Power on all displays. The primary display is first, so becomes the active display. Also,
        // the DisplayCapability set of a display is populated on its first powering on. Do this now
        // before responding to any Binder query from DisplayManager about display capabilities.
        // Additionally, do not turn on displays if the boot should be quiescent.
        if (!mSkipPowerOnForQuiescent) {
            for (const auto& [id, display] : mPhysicalDisplays) {
                setPowerModeInternal(getDisplayDeviceLocked(id), hal::PowerMode::ON);
            }
        }
    }
}

void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal::PowerMode mode) {
    if (display->isVirtual()) {
@@ -6261,6 +6267,7 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal:
void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) {
    auto future = mScheduler->schedule([=, this]() FTL_FAKE_GUARD(mStateLock) FTL_FAKE_GUARD(
                                               kMainThreadContext) {
        mSkipPowerOnForQuiescent = false;
        const auto display = getDisplayDeviceLocked(displayToken);
        if (!display) {
            ALOGE("Attempt to set power mode %d for invalid display token %p", mode,
+2 −0
Original line number Diff line number Diff line
@@ -1491,6 +1491,8 @@ private:
    bool mPowerHintSessionEnabled;

    bool mLayerLifecycleManagerEnabled = false;
    // Whether a display should be turned on when initialized
    bool mSkipPowerOnForQuiescent;

    frontend::LayerLifecycleManager mLayerLifecycleManager GUARDED_BY(kMainThreadContext);
    frontend::LayerHierarchyBuilder mLayerHierarchyBuilder GUARDED_BY(kMainThreadContext);