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

Commit 64900ad1 authored by Jorim Jaggi's avatar Jorim Jaggi Committed by Android (Google) Code Review
Browse files

Merge "Take snapshot when screen is turning off" into oc-dev

parents 009d0460 51304d73
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -589,6 +589,13 @@ public interface WindowManagerPolicy {
         * Notifies window manager that {@link #isKeyguardTrustedLw} has changed.
         */
        void notifyKeyguardTrustedChanged();

        /**
         * Notifies the window manager that screen is being turned off.
         *
         * @param listener callback to call when display can be turned off
         */
        void screenTurningOff(ScreenOffListener listener);
    }

    public interface PointerEventListener {
@@ -1266,6 +1273,15 @@ public interface WindowManagerPolicy {
     */
    public void screenTurnedOn();

    /**
     * Called when the display would like to be turned off. This gives policy a chance to do some
     * things before the display power state is actually changed to off.
     *
     * @param screenOffListener Must be called to tell that the display power state can actually be
     *                          changed now after policy has done its work.
     */
    public void screenTurningOff(ScreenOffListener screenOffListener);

    /**
     * Called when the device has turned the screen off.
     */
@@ -1275,6 +1291,13 @@ public interface WindowManagerPolicy {
        void onScreenOn();
    }

    /**
     * See {@link #screenTurnedOff}
     */
    public interface ScreenOffListener {
        void onScreenOff();
    }

    /**
     * Return whether the default display is on and not blocked by a black surface.
     */
+66 −3
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ import java.io.PrintWriter;
final class DisplayPowerController implements AutomaticBrightnessController.Callbacks {
    private static final String TAG = "DisplayPowerController";
    private static final String SCREEN_ON_BLOCKED_TRACE_NAME = "Screen on blocked";
    private static final String SCREEN_OFF_BLOCKED_TRACE_NAME = "Screen off blocked";

    private static final boolean DEBUG = false;
    private static final boolean DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT = false;
@@ -90,6 +91,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
    private static final int MSG_UPDATE_POWER_STATE = 1;
    private static final int MSG_PROXIMITY_SENSOR_DEBOUNCED = 2;
    private static final int MSG_SCREEN_ON_UNBLOCKED = 3;
    private static final int MSG_SCREEN_OFF_UNBLOCKED = 4;

    private static final int PROXIMITY_UNKNOWN = -1;
    private static final int PROXIMITY_NEGATIVE = 0;
@@ -105,6 +107,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
    private static final int REPORTED_TO_POLICY_SCREEN_OFF = 0;
    private static final int REPORTED_TO_POLICY_SCREEN_TURNING_ON = 1;
    private static final int REPORTED_TO_POLICY_SCREEN_ON = 2;
    private static final int REPORTED_TO_POLICY_SCREEN_TURNING_OFF = 3;

    private final Object mLock = new Object();

@@ -219,6 +222,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
    // The currently active screen on unblocker.  This field is non-null whenever
    // we are waiting for a callback to release it and unblock the screen.
    private ScreenOnUnblocker mPendingScreenOnUnblocker;
    private ScreenOffUnblocker mPendingScreenOffUnblocker;

    // True if we were in the process of turning off the screen.
    // This allows us to recover more gracefully from situations where we abort
@@ -230,6 +234,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call

    // The elapsed real time when the screen on was blocked.
    private long mScreenOnBlockStartRealTime;
    private long mScreenOffBlockStartRealTime;

    // Screen state we reported to policy. Must be one of REPORTED_TO_POLICY_SCREEN_* fields.
    private int mReportedScreenStateToPolicy;
@@ -810,9 +815,43 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        }
    }

    private void blockScreenOff() {
        if (mPendingScreenOffUnblocker == null) {
            Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, SCREEN_OFF_BLOCKED_TRACE_NAME, 0);
            mPendingScreenOffUnblocker = new ScreenOffUnblocker();
            mScreenOffBlockStartRealTime = SystemClock.elapsedRealtime();
            Slog.i(TAG, "Blocking screen off");
        }
    }

    private void unblockScreenOff() {
        if (mPendingScreenOffUnblocker != null) {
            mPendingScreenOffUnblocker = null;
            long delay = SystemClock.elapsedRealtime() - mScreenOffBlockStartRealTime;
            Slog.i(TAG, "Unblocked screen off after " + delay + " ms");
            Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, SCREEN_OFF_BLOCKED_TRACE_NAME, 0);
        }
    }

    private boolean setScreenState(int state) {
        final boolean isOff = (state == Display.STATE_OFF);
        if (mPowerState.getScreenState() != state) {
            final boolean wasOn = (mPowerState.getScreenState() != Display.STATE_OFF);

            // If we are trying to turn screen off, give policy a chance to do something before we
            // actually turn the screen off.
            if (isOff && !mScreenOffBecauseOfProximity) {
                if (mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_ON) {
                    mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_TURNING_OFF;
                    blockScreenOff();
                    mWindowManagerPolicy.screenTurningOff(mPendingScreenOffUnblocker);
                    return false;
                } else if (mPendingScreenOffUnblocker != null) {

                    // Abort doing the state change until screen off is unblocked.
                    return false;
                }
            }

            mPowerState.setScreenState(state);

            // Tell battery stats about the transition.
@@ -829,13 +868,21 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        // This surface is essentially the final state of the color fade animation and
        // it is only removed once the window manager tells us that the activity has
        // finished drawing underneath.
        final boolean isOff = (state == Display.STATE_OFF);
        if (isOff && mReportedScreenStateToPolicy != REPORTED_TO_POLICY_SCREEN_OFF
                && !mScreenOffBecauseOfProximity) {
            mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_OFF;
            unblockScreenOn();
            mWindowManagerPolicy.screenTurnedOff();
        } else if (!isOff && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF) {
        } else if (!isOff
                && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_OFF) {

            // We told policy already that screen was turning off, but now we changed our minds.
            // Complete the full state transition on -> turningOff -> off.
            unblockScreenOff();
            mWindowManagerPolicy.screenTurnedOff();
            mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_OFF;
        }
        if (!isOff && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF) {
            mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_TURNING_ON;
            if (mPowerState.getColorFadeLevel() == 0.0f) {
                blockScreenOn();
@@ -1282,6 +1329,12 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
                        updatePowerState();
                    }
                    break;
                case MSG_SCREEN_OFF_UNBLOCKED:
                    if (mPendingScreenOffUnblocker == msg.obj) {
                        unblockScreenOff();
                        updatePowerState();
                    }
                    break;
            }
        }
    }
@@ -1311,4 +1364,14 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
            mHandler.sendMessage(msg);
        }
    }

    private final class ScreenOffUnblocker implements WindowManagerPolicy.ScreenOffListener {

        @Override
        public void onScreenOff() {
            Message msg = mHandler.obtainMessage(MSG_SCREEN_OFF_UNBLOCKED, this);
            msg.setAsynchronous(true);
            mHandler.sendMessage(msg);
        }
    }
}
+5 −0
Original line number Diff line number Diff line
@@ -6667,6 +6667,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        reportScreenStateToVrManager(true);
    }

    @Override
    public void screenTurningOff(ScreenOffListener screenOffListener) {
        mWindowManagerFuncs.screenTurningOff(screenOffListener);
    }

    private void reportScreenStateToVrManager(boolean isScreenOn) {
        if (mVrManagerInternal == null) {
            return;
+5 −0
Original line number Diff line number Diff line
@@ -2903,6 +2903,11 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
                * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
        final MutableBoolean mutableIncludeFullDisplay = new MutableBoolean(includeFullDisplay);
        synchronized(mService.mWindowMap) {
            if (!mService.mPolicy.isScreenOn()) {
                if (DEBUG_SCREENSHOT) Slog.i(TAG_WM, "Attempted to take screenshot while display"
                        + " was off.");
                return null;
            }
            // Figure out the part of the screen that is actually the app.
            mScreenshotApplicationState.appWin = null;
            forAllWindows(w -> {
+6 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import android.view.Surface;
import com.android.internal.annotations.VisibleForTesting;

import java.io.PrintWriter;
import java.util.function.Consumer;

class Task extends WindowContainer<AppWindowToken> implements DimLayer.DimLayerUser {
    static final String TAG = TAG_WITH_CLASS_NAME ? "Task" : TAG_WM;
@@ -683,6 +684,11 @@ class Task extends WindowContainer<AppWindowToken> implements DimLayer.DimLayerU
        return (TaskWindowContainerController) super.getController();
    }

    @Override
    void forAllTasks(Consumer<Task> callback) {
        callback.accept(this);
    }

    @Override
    public String toString() {
        return "{taskId=" + mTaskId + " appTokens=" + mChildren + " mdr=" + mDeferRemoval + "}";
Loading