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

Commit 1fde4358 authored by Chen Bai's avatar Chen Bai Committed by Android (Google) Code Review
Browse files

Merge "do wom: allow DisplayOffload to block screen turning on" into main

parents 37666605 eb57142b
Loading
Loading
Loading
Loading
+17 −0
Original line number Original line Diff line number Diff line
@@ -715,6 +715,14 @@ public abstract class DisplayManagerInternal {
        boolean startOffload();
        boolean startOffload();


        void stopOffload();
        void stopOffload();

        /**
         * Called when {@link DisplayOffloadSession} tries to block screen turning on.
         *
         * @param unblocker a {@link Runnable} executed upon all work required before screen turning
         *                  on is done.
         */
        void onBlockingScreenOn(Runnable unblocker);
    }
    }


    /** A session token that associates a internal display with a {@link DisplayOffloader}. */
    /** A session token that associates a internal display with a {@link DisplayOffloader}. */
@@ -734,6 +742,15 @@ public abstract class DisplayManagerInternal {
         */
         */
        void updateBrightness(float brightness);
        void updateBrightness(float brightness);


        /**
         * Called while display is turning to state ON to leave a small period for displayoffload
         * session to finish some work.
         *
         * @param unblocker a {@link Runnable} used by displayoffload session to notify
         *                  {@link DisplayManager} that it can continue turning screen on.
         */
        boolean blockScreenOn(Runnable unblocker);

        /** Returns whether displayoffload supports the given display state. */
        /** Returns whether displayoffload supports the given display state. */
        static boolean isSupportedOffloadState(int displayState) {
        static boolean isSupportedOffloadState(int displayState) {
            return Display.isSuspendedState(displayState);
            return Display.isSuspendedState(displayState);
+9 −0
Original line number Original line Diff line number Diff line
@@ -56,6 +56,15 @@ public class DisplayOffloadSessionImpl implements DisplayManagerInternal.Display
        }
        }
    }
    }


    @Override
    public boolean blockScreenOn(Runnable unblocker) {
        if (mDisplayOffloader == null) {
            return false;
        }
        mDisplayOffloader.onBlockingScreenOn(unblocker);
        return true;
    }

    /**
    /**
     * Start the offload session. The method returns if the session is already active.
     * Start the offload session. The method returns if the session is already active.
     * @return Whether the session was started successfully
     * @return Whether the session was started successfully
+85 −6
Original line number Original line Diff line number Diff line
@@ -126,6 +126,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
    // To enable these logs, run:
    // To enable these logs, run:
    // 'adb shell setprop persist.log.tag.DisplayPowerController2 DEBUG && adb reboot'
    // 'adb shell setprop persist.log.tag.DisplayPowerController2 DEBUG && adb reboot'
    private static final boolean DEBUG = DebugUtils.isDebuggable(TAG);
    private static final boolean DEBUG = DebugUtils.isDebuggable(TAG);
    private static final String SCREEN_ON_BLOCKED_BY_DISPLAYOFFLOAD_TRACE_NAME =
            "Screen on blocked by displayoffload";


    // If true, uses the color fade on animation.
    // If true, uses the color fade on animation.
    // We might want to turn this off if we cannot get a guarantee that the screen
    // We might want to turn this off if we cannot get a guarantee that the screen
@@ -155,6 +157,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
    private static final int MSG_SET_DWBC_COLOR_OVERRIDE = 15;
    private static final int MSG_SET_DWBC_COLOR_OVERRIDE = 15;
    private static final int MSG_SET_DWBC_LOGGING_ENABLED = 16;
    private static final int MSG_SET_DWBC_LOGGING_ENABLED = 16;
    private static final int MSG_SET_BRIGHTNESS_FROM_OFFLOAD = 17;
    private static final int MSG_SET_BRIGHTNESS_FROM_OFFLOAD = 17;
    private static final int MSG_OFFLOADING_SCREEN_ON_UNBLOCKED = 18;






@@ -339,6 +342,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
    // we are waiting for a callback to release it and unblock the screen.
    // we are waiting for a callback to release it and unblock the screen.
    private ScreenOnUnblocker mPendingScreenOnUnblocker;
    private ScreenOnUnblocker mPendingScreenOnUnblocker;
    private ScreenOffUnblocker mPendingScreenOffUnblocker;
    private ScreenOffUnblocker mPendingScreenOffUnblocker;
    private Runnable mPendingScreenOnUnblockerByDisplayOffload;


    // True if we were in the process of turning off the screen.
    // True if we were in the process of turning off the screen.
    // This allows us to recover more gracefully from situations where we abort
    // This allows us to recover more gracefully from situations where we abort
@@ -348,10 +352,15 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
    // The elapsed real time when the screen on was blocked.
    // The elapsed real time when the screen on was blocked.
    private long mScreenOnBlockStartRealTime;
    private long mScreenOnBlockStartRealTime;
    private long mScreenOffBlockStartRealTime;
    private long mScreenOffBlockStartRealTime;
    private long mScreenOnBlockByDisplayOffloadStartRealTime;


    // Screen state we reported to policy. Must be one of REPORTED_TO_POLICY_* fields.
    // Screen state we reported to policy. Must be one of REPORTED_TO_POLICY_* fields.
    private int mReportedScreenStateToPolicy = REPORTED_TO_POLICY_UNREPORTED;
    private int mReportedScreenStateToPolicy = REPORTED_TO_POLICY_UNREPORTED;


    // Used to deduplicate the displayoffload blocking screen on logic. One block per turning on.
    // This value is reset when screen on is reported or the blocking is cancelled.
    private boolean mScreenTurningOnWasBlockedByDisplayOffload;

    // If the last recorded screen state was dozing or not.
    // If the last recorded screen state was dozing or not.
    private boolean mDozing;
    private boolean mDozing;


@@ -472,7 +481,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
    private boolean mBootCompleted;
    private boolean mBootCompleted;
    private final DisplayManagerFlags mFlags;
    private final DisplayManagerFlags mFlags;


    private DisplayManagerInternal.DisplayOffloadSession mDisplayOffloadSession;
    private DisplayOffloadSession mDisplayOffloadSession;


    /**
    /**
     * Creates the display power controller.
     * Creates the display power controller.
@@ -772,6 +781,10 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal


    @Override
    @Override
    public void setDisplayOffloadSession(DisplayOffloadSession session) {
    public void setDisplayOffloadSession(DisplayOffloadSession session) {
        if (session == mDisplayOffloadSession) {
            return;
        }
        unblockScreenOnByDisplayOffload();
        mDisplayOffloadSession = session;
        mDisplayOffloadSession = session;
    }
    }


@@ -1735,6 +1748,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
        // reporting the display is ready because we only need to ensure the screen is in the
        // reporting the display is ready because we only need to ensure the screen is in the
        // right power state even as it continues to converge on the desired brightness.
        // right power state even as it continues to converge on the desired brightness.
        final boolean ready = mPendingScreenOnUnblocker == null
        final boolean ready = mPendingScreenOnUnblocker == null
                && mPendingScreenOnUnblockerByDisplayOffload == null
                && (!mColorFadeEnabled || (!mColorFadeOnAnimator.isStarted()
                && (!mColorFadeEnabled || (!mColorFadeOnAnimator.isStarted()
                        && !mColorFadeOffAnimator.isStarted()))
                        && !mColorFadeOffAnimator.isStarted()))
                && mPowerState.waitUntilClean(mCleanListener);
                && mPowerState.waitUntilClean(mCleanListener);
@@ -1983,15 +1997,69 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
        }
        }
    }
    }


    private void blockScreenOnByDisplayOffload(DisplayOffloadSession displayOffloadSession) {
        if (mPendingScreenOnUnblockerByDisplayOffload != null || displayOffloadSession == null) {
            return;
        }
        mScreenTurningOnWasBlockedByDisplayOffload = true;

        Trace.asyncTraceBegin(
                Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_BY_DISPLAYOFFLOAD_TRACE_NAME, 0);
        mScreenOnBlockByDisplayOffloadStartRealTime = SystemClock.elapsedRealtime();

        mPendingScreenOnUnblockerByDisplayOffload =
                () -> onDisplayOffloadUnblockScreenOn(displayOffloadSession);
        if (!displayOffloadSession.blockScreenOn(mPendingScreenOnUnblockerByDisplayOffload)) {
            mPendingScreenOnUnblockerByDisplayOffload = null;
            long delay =
                    SystemClock.elapsedRealtime() - mScreenOnBlockByDisplayOffloadStartRealTime;
            Slog.w(mTag, "Tried blocking screen on for offloading but failed. So, end trace after "
                    + delay + " ms.");
            Trace.asyncTraceEnd(
                    Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_BY_DISPLAYOFFLOAD_TRACE_NAME, 0);
            return;
        }
        Slog.i(mTag, "Blocking screen on for offloading.");
    }

    private void onDisplayOffloadUnblockScreenOn(DisplayOffloadSession displayOffloadSession) {
        Message msg = mHandler.obtainMessage(MSG_OFFLOADING_SCREEN_ON_UNBLOCKED,
                displayOffloadSession);
        mHandler.sendMessage(msg);
    }

    private void unblockScreenOnByDisplayOffload() {
        if (mPendingScreenOnUnblockerByDisplayOffload == null) {
            return;
        }
        mPendingScreenOnUnblockerByDisplayOffload = null;
        long delay = SystemClock.elapsedRealtime() - mScreenOnBlockByDisplayOffloadStartRealTime;
        Slog.i(mTag, "Unblocked screen on for offloading after " + delay + " ms");
        Trace.asyncTraceEnd(
                Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_BY_DISPLAYOFFLOAD_TRACE_NAME, 0);
    }

    private boolean setScreenState(int state) {
    private boolean setScreenState(int state) {
        return setScreenState(state, false /*reportOnly*/);
        return setScreenState(state, false /*reportOnly*/);
    }
    }


    private boolean setScreenState(int state, boolean reportOnly) {
    private boolean setScreenState(int state, boolean reportOnly) {
        final boolean isOff = (state == Display.STATE_OFF);
        final boolean isOff = (state == Display.STATE_OFF);
        final boolean isOn = (state == Display.STATE_ON);
        final boolean changed = mPowerState.getScreenState() != state;


        if (mPowerState.getScreenState() != state
        // If the screen is turning on, give displayoffload a chance to do something before the
                || mReportedScreenStateToPolicy == REPORTED_TO_POLICY_UNREPORTED) {
        // screen actually turns on.
        // TODO(b/316941732): add tests for this displayoffload screen-on blocker.
        if (isOn && changed && !mScreenTurningOnWasBlockedByDisplayOffload) {
            blockScreenOnByDisplayOffload(mDisplayOffloadSession);
        } else if (!isOn && mScreenTurningOnWasBlockedByDisplayOffload) {
            // No longer turning screen on, so unblock previous screen on blocking immediately.
            unblockScreenOnByDisplayOffload();
            mScreenTurningOnWasBlockedByDisplayOffload = false;
        }

        if (changed || mReportedScreenStateToPolicy == REPORTED_TO_POLICY_UNREPORTED) {
            // If we are trying to turn screen off, give policy a chance to do something before we
            // If we are trying to turn screen off, give policy a chance to do something before we
            // actually turn the screen off.
            // actually turn the screen off.
            if (isOff && !mDisplayPowerProximityStateController.isScreenOffBecauseOfProximity()) {
            if (isOff && !mDisplayPowerProximityStateController.isScreenOffBecauseOfProximity()) {
@@ -2007,8 +2075,9 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
                }
                }
            }
            }


            if (!reportOnly && mPowerState.getScreenState() != state
            if (!reportOnly && changed && readyToUpdateDisplayState()
                    && readyToUpdateDisplayState()) {
                    && mPendingScreenOffUnblocker == null
                    && mPendingScreenOnUnblockerByDisplayOffload == null) {
                Trace.traceCounter(Trace.TRACE_TAG_POWER, "ScreenState", state);
                Trace.traceCounter(Trace.TRACE_TAG_POWER, "ScreenState", state);


                String propertyKey = "debug.tracing.screen_state";
                String propertyKey = "debug.tracing.screen_state";
@@ -2060,12 +2129,16 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
        }
        }


        // Return true if the screen isn't blocked.
        // Return true if the screen isn't blocked.
        return mPendingScreenOnUnblocker == null;
        return mPendingScreenOnUnblocker == null
                && mPendingScreenOnUnblockerByDisplayOffload == null;
    }
    }


    private void setReportedScreenState(int state) {
    private void setReportedScreenState(int state) {
        Trace.traceCounter(Trace.TRACE_TAG_POWER, "ReportedScreenStateToPolicy", state);
        Trace.traceCounter(Trace.TRACE_TAG_POWER, "ReportedScreenStateToPolicy", state);
        mReportedScreenStateToPolicy = state;
        mReportedScreenStateToPolicy = state;
        if (state == REPORTED_TO_POLICY_SCREEN_ON) {
            mScreenTurningOnWasBlockedByDisplayOffload = false;
        }
    }
    }


    private void loadAmbientLightSensor() {
    private void loadAmbientLightSensor() {
@@ -2813,6 +2886,12 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
                        updatePowerState();
                        updatePowerState();
                    }
                    }
                    break;
                    break;
                case MSG_OFFLOADING_SCREEN_ON_UNBLOCKED:
                    if (mDisplayOffloadSession == msg.obj) {
                        unblockScreenOnByDisplayOffload();
                        updatePowerState();
                    }
                    break;
                case MSG_CONFIGURE_BRIGHTNESS:
                case MSG_CONFIGURE_BRIGHTNESS:
                    BrightnessConfiguration brightnessConfiguration =
                    BrightnessConfiguration brightnessConfiguration =
                            (BrightnessConfiguration) msg.obj;
                            (BrightnessConfiguration) msg.obj;
+9 −0
Original line number Original line Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.display;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verify;
@@ -88,4 +89,12 @@ public class DisplayOffloadSessionImplTest {


        verify(mDisplayPowerController).setBrightnessFromOffload(brightness);
        verify(mDisplayPowerController).setBrightnessFromOffload(brightness);
    }
    }

    @Test
    public void testBlockScreenOn() {
        Runnable unblocker = () -> {};
        mSession.blockScreenOn(unblocker);

        verify(mDisplayOffloader).onBlockingScreenOn(eq(unblocker));
    }
}
}
+3 −0
Original line number Original line Diff line number Diff line
@@ -1235,6 +1235,9 @@ public class LocalDisplayAdapterTest {


            @Override
            @Override
            public void stopOffload() {}
            public void stopOffload() {}

            @Override
            public void onBlockingScreenOn(Runnable unblocker) {}
        });
        });


        mDisplayOffloadSession = new DisplayOffloadSessionImpl(mDisplayOffloader,
        mDisplayOffloadSession = new DisplayOffloadSessionImpl(mDisplayOffloader,