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

Commit c9424ac5 authored by Antony Sargent's avatar Antony Sargent
Browse files

Improve PowerGroup event notification

When the default display group is asleep/dozing and some other display
in another group becomes awake, we were sending incorrect and
misleading information from PowerManagerService to
PhoneWindowManager. In particular, we were conflating the "global
wakefulness" with the wakefulness of the default display, which led to
problems like the default display waking up when it shouldn't and
Always On Display ceasing to work.

This CL refactors things to make the distinction more clear between
global wakefulness changes and specific display PowerGroup changes.

Bug: 255688811
Test: atest PowerManagerServiceTest
Change-Id: I809d5fcd8eaa61dc2d07b63a0ae3b5aa924faa1c
parent 0c71d059
Loading
Loading
Loading
Loading
+54 −31
Original line number Diff line number Diff line
@@ -1004,7 +1004,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            return;
        }

        final boolean interactive = Display.isOnState(mDefaultDisplay.getState());
        final boolean interactive = mDefaultDisplayPolicy.isAwake();

        Slog.d(TAG, "powerPress: eventTime=" + eventTime + " interactive=" + interactive
                + " count=" + count + " beganFromNonInteractive=" + beganFromNonInteractive
@@ -2201,8 +2201,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {

        // Match current screen state.
        if (!mPowerManager.isInteractive()) {
            startedGoingToSleep(PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
            finishedGoingToSleep(PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
            startedGoingToSleep(Display.DEFAULT_DISPLAY_GROUP,
                    PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
            finishedGoingToSleep(Display.DEFAULT_DISPLAY_GROUP,
                    PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
        }

        mWindowManagerInternal.registerAppTransitionListener(new AppTransitionListener() {
@@ -4095,7 +4097,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {

        // This could prevent some wrong state in multi-displays environment,
        // the default display may turned off but interactive is true.
        final boolean isDefaultDisplayOn = Display.isOnState(mDefaultDisplay.getState());
        final boolean isDefaultDisplayOn = mDefaultDisplayPolicy.isAwake();
        final boolean interactiveAndOn = interactive && isDefaultDisplayOn;
        if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
            handleKeyGesture(event, interactiveAndOn);
@@ -4795,17 +4797,40 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        }
    };

    @Override
    public void startedWakingUpGlobal(@WakeReason int reason) {

    }

    @Override
    public void finishedWakingUpGlobal(@WakeReason int reason) {

    }

    @Override
    public void startedGoingToSleepGlobal(@PowerManager.GoToSleepReason int reason) {
        mDeviceGoingToSleep = true;
    }

    @Override
    public void finishedGoingToSleepGlobal(@PowerManager.GoToSleepReason int reason) {
        mDeviceGoingToSleep = false;
    }

    // Called on the PowerManager's Notifier thread.
    @Override
    public void startedGoingToSleep(@PowerManager.GoToSleepReason int pmSleepReason) {
    public void startedGoingToSleep(int displayGroupId,
            @PowerManager.GoToSleepReason int pmSleepReason) {
        if (DEBUG_WAKEUP) {
            Slog.i(TAG, "Started going to sleep... (why="
            Slog.i(TAG, "Started going to sleep... (groupId=" + displayGroupId + " why="
                    + WindowManagerPolicyConstants.offReasonToString(
                            WindowManagerPolicyConstants.translateSleepReasonToOffReason(
                                    pmSleepReason)) + ")");
        }
        if (displayGroupId != Display.DEFAULT_DISPLAY_GROUP) {
            return;
        }

        mDeviceGoingToSleep = true;
        mRequestedOrSleepingDefaultDisplay = true;

        if (mKeyguardDelegate != null) {
@@ -4815,17 +4840,20 @@ public class PhoneWindowManager implements WindowManagerPolicy {

    // Called on the PowerManager's Notifier thread.
    @Override
    public void finishedGoingToSleep(@PowerManager.GoToSleepReason int pmSleepReason) {
    public void finishedGoingToSleep(int displayGroupId,
            @PowerManager.GoToSleepReason int pmSleepReason) {
        if (displayGroupId != Display.DEFAULT_DISPLAY_GROUP) {
            return;
        }
        EventLogTags.writeScreenToggled(0);
        if (DEBUG_WAKEUP) {
            Slog.i(TAG, "Finished going to sleep... (why="
            Slog.i(TAG, "Finished going to sleep... (groupId=" + displayGroupId + " why="
                    + WindowManagerPolicyConstants.offReasonToString(
                            WindowManagerPolicyConstants.translateSleepReasonToOffReason(
                                    pmSleepReason)) + ")");
        }
        MetricsLogger.histogram(mContext, "screen_timeout", mLockScreenTimeout / 1000);

        mDeviceGoingToSleep = false;
        mRequestedOrSleepingDefaultDisplay = false;
        mDefaultDisplayPolicy.setAwake(false);

@@ -4850,26 +4878,18 @@ public class PhoneWindowManager implements WindowManagerPolicy {

    // Called on the PowerManager's Notifier thread.
    @Override
    public void onPowerGroupWakefulnessChanged(int groupId, int wakefulness,
            @PowerManager.GoToSleepReason int pmSleepReason, int globalWakefulness) {
        if (wakefulness != globalWakefulness
                && wakefulness != PowerManagerInternal.WAKEFULNESS_AWAKE
                && groupId == Display.DEFAULT_DISPLAY_GROUP
                && mKeyguardDelegate != null) {
            mKeyguardDelegate.doKeyguardTimeout(null);
        }
    }

    // Called on the PowerManager's Notifier thread.
    @Override
    public void startedWakingUp(@PowerManager.WakeReason int pmWakeReason) {
        EventLogTags.writeScreenToggled(1);
    public void startedWakingUp(int displayGroupId, @WakeReason int pmWakeReason) {
        if (DEBUG_WAKEUP) {
            Slog.i(TAG, "Started waking up... (why="
            Slog.i(TAG, "Started waking up... (groupId=" + displayGroupId + " why="
                    + WindowManagerPolicyConstants.onReasonToString(
                    WindowManagerPolicyConstants.translateWakeReasonToOnReason(
                            pmWakeReason)) + ")");
        }
        if (displayGroupId != Display.DEFAULT_DISPLAY_GROUP) {
            return;
        }
        EventLogTags.writeScreenToggled(1);


        mDefaultDisplayPolicy.setAwake(true);

@@ -4892,13 +4912,16 @@ public class PhoneWindowManager implements WindowManagerPolicy {

    // Called on the PowerManager's Notifier thread.
    @Override
    public void finishedWakingUp(@PowerManager.WakeReason int pmWakeReason) {
    public void finishedWakingUp(int displayGroupId, @WakeReason int pmWakeReason) {
        if (DEBUG_WAKEUP) {
            Slog.i(TAG, "Finished waking up... (why="
            Slog.i(TAG, "Finished waking up... (groupId=" + displayGroupId + " why="
                    + WindowManagerPolicyConstants.onReasonToString(
                            WindowManagerPolicyConstants.translateWakeReasonToOnReason(
                                    pmWakeReason)) + ")");
        }
        if (displayGroupId != Display.DEFAULT_DISPLAY_GROUP) {
            return;
        }

        if (mKeyguardDelegate != null) {
            mKeyguardDelegate.onFinishedWakingUp();
@@ -5378,8 +5401,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            }
        }
        mSideFpsEventHandler.onFingerprintSensorReady();
        startedWakingUp(PowerManager.WAKE_REASON_UNKNOWN);
        finishedWakingUp(PowerManager.WAKE_REASON_UNKNOWN);
        startedWakingUp(Display.DEFAULT_DISPLAY_GROUP, PowerManager.WAKE_REASON_UNKNOWN);
        finishedWakingUp(Display.DEFAULT_DISPLAY_GROUP, PowerManager.WAKE_REASON_UNKNOWN);

        int defaultDisplayState = mDisplayManager.getDisplay(DEFAULT_DISPLAY).getState();
        boolean defaultDisplayOn = defaultDisplayState == Display.STATE_ON;
+60 −24
Original line number Diff line number Diff line
@@ -67,10 +67,12 @@ import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.companion.virtual.VirtualDevice;
import android.content.ComponentName;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.hardware.display.VirtualDisplay;
import android.os.Bundle;
import android.os.IBinder;
import android.os.PowerManager;
@@ -761,51 +763,85 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
     */
    void setAllowLockscreenWhenOn(int displayId, boolean allow);

    /**
     * Called when the global wakefulness is becoming awake.
     *
     * @param reason One of PowerManager.WAKE_REASON_*, detailing the reason for the change.
     */
    void startedWakingUpGlobal(@PowerManager.WakeReason int reason);

    /**
     * Called when the global wakefulness has finished becoming awake.
     *
     * @param reason One of PowerManager.WAKE_REASON_*, detailing the reason for the change.
     */
    void finishedWakingUpGlobal(@PowerManager.WakeReason int reason);

    /**
     * Called when the global wakefulness has started going to sleep.
     *
     * @param reason One of PowerManager.WAKE_REASON_*, detailing the reason for the change.
     */
    void startedGoingToSleepGlobal(@PowerManager.GoToSleepReason int reason);

    /**
     * Called when the global wakefulness has finished going to sleep.
     *
     * @param reason One of PowerManager.WAKE_REASON_*, detailing the reason for the change.
     */
    void finishedGoingToSleepGlobal(@PowerManager.GoToSleepReason int reason);

    /**
     * Called when the device has started waking up.
     *
     * @param pmWakeReason One of PowerManager.WAKE_REASON_*, detailing the specific reason we're
     * waking up, such as WAKE_REASON_POWER_BUTTON or WAKE_REASON_GESTURE.
     * @param displayGroupId The id of the display group that has started waking up. This will often
     *                       be {@link Display#DEFAULT_DISPLAY_GROUP}, but it is possible for other
     *                       display groups to exist, for example when there is a
     *                       {@link VirtualDevice} with one or more {@link VirtualDisplay}s.
     * @param pmWakeReason One of PowerManager.WAKE_REASON_*, detailing the specific reason this
     *                     display group is waking up, such as WAKE_REASON_POWER_BUTTON or
     *                     WAKE_REASON_GESTURE.
     */
    void startedWakingUp(@PowerManager.WakeReason int pmWakeReason);
    void startedWakingUp(int displayGroupId, @PowerManager.WakeReason int pmWakeReason);

    /**
     * Called when the device has finished waking up.
     *
     * @param pmWakeReason One of PowerManager.WAKE_REASON_*, detailing the specific reason we're
     * waking up, such as WAKE_REASON_POWER_BUTTON or WAKE_REASON_GESTURE.
     * @param displayGroupId The id of the display group that has finished waking. This will often
     *                       be {@link Display#DEFAULT_DISPLAY_GROUP}, but it is possible for other
     *                       display groups to exist, for example when there is a
     *                       {@link VirtualDevice} with one or more {@link VirtualDisplay}s.
     * @param pmWakeReason One of PowerManager.WAKE_REASON_*, detailing the specific reason this
     *                     display group is waking up, such as WAKE_REASON_POWER_BUTTON or
     *                     WAKE_REASON_GESTURE.
     */
    void finishedWakingUp(@PowerManager.WakeReason int pmWakeReason);
    void finishedWakingUp(int displayGroupId, @PowerManager.WakeReason int pmWakeReason);

    /**
     * Called when the device has started going to sleep.
     *
     * @param displayGroupId The id of the display group that has started going to sleep. This
     *                       will often be {@link Display#DEFAULT_DISPLAY_GROUP}, but it is
     *                       possible for other display groups to exist, for example when there is a
     *                       {@link VirtualDevice} with one or more {@link VirtualDisplay}s.
     * @param pmSleepReason One of PowerManager.GO_TO_SLEEP_REASON_*, detailing the specific reason
     * we're going to sleep, such as GO_TO_SLEEP_REASON_POWER_BUTTON or GO_TO_SLEEP_REASON_TIMEOUT.
     *                      this display group is going to sleep, such as
     *                      GO_TO_SLEEP_REASON_POWER_BUTTON or GO_TO_SLEEP_REASON_TIMEOUT.
     */
    public void startedGoingToSleep(@PowerManager.GoToSleepReason int pmSleepReason);
    void startedGoingToSleep(int displayGroupId, @PowerManager.GoToSleepReason int pmSleepReason);

    /**
     * Called when the device has finished going to sleep.
     *
     * @param displayGroupId The id of the display group that has finished going to sleep. This
     *                       will often be {@link Display#DEFAULT_DISPLAY_GROUP}, but it is
     *                       possible for other display groups to exist, for example when there is a
     *                       {@link VirtualDevice} with one or more {@link VirtualDisplay}s.
     * @param pmSleepReason One of PowerManager.GO_TO_SLEEP_REASON_*, detailing the specific reason
     * we're going to sleep, such as GO_TO_SLEEP_REASON_POWER_BUTTON or GO_TO_SLEEP_REASON_TIMEOUT.
     */
    public void finishedGoingToSleep(@PowerManager.GoToSleepReason int pmSleepReason);

    /**
     * Called when a particular PowerGroup has changed wakefulness.
     *
     * @param groupId The id of the PowerGroup.
     * @param wakefulness One of PowerManagerInternal.WAKEFULNESS_* indicating the wake state for
     * the group
     * @param pmSleepReason One of PowerManager.GO_TO_SLEEP_REASON_*, detailing the reason this
     * group is going to sleep.
     * @param globalWakefulness The global wakefulness, which may or may not match that of this
     * group. One of PowerManagerInternal.WAKEFULNESS_*
     *                      we're going to sleep, such as GO_TO_SLEEP_REASON_POWER_BUTTON or
     *                      GO_TO_SLEEP_REASON_TIMEOUT.
     */
    void onPowerGroupWakefulnessChanged(int groupId, int wakefulness,
            @PowerManager.GoToSleepReason int pmSleepReason, int globalWakefulness);
    void finishedGoingToSleep(int displayGroupId, @PowerManager.GoToSleepReason int pmSleepReason);

    /**
     * Called when the display is about to turn on to show content.
+124 −41

File changed.

Preview size limit exceeded, changes collapsed.

+11 −12
Original line number Diff line number Diff line
@@ -686,6 +686,8 @@ public final class PowerManagerService extends SystemService
        @Override
        public void onWakefulnessChangedLocked(int groupId, int wakefulness, long eventTime,
                int reason, int uid, int opUid, String opPackageName, String details) {
            mWakefulnessChanging = true;
            mDirty |= DIRTY_WAKEFULNESS;
            if (wakefulness == WAKEFULNESS_AWAKE) {
                // Kick user activity to prevent newly awake group from timing out instantly.
                // The dream may end without user activity if the dream app crashes / is updated,
@@ -696,9 +698,8 @@ public final class PowerManagerService extends SystemService
                        PowerManager.USER_ACTIVITY_EVENT_OTHER, flags, uid);
            }
            mDirty |= DIRTY_DISPLAY_GROUP_WAKEFULNESS;
            mNotifier.onGroupWakefulnessChangeStarted(groupId, wakefulness, reason, eventTime);
            updateGlobalWakefulnessLocked(eventTime, reason, uid, opUid, opPackageName, details);
            mNotifier.onPowerGroupWakefulnessChanged(groupId, wakefulness, reason,
                    getGlobalWakefulnessLocked());
            updatePowerStateLocked();
        }
    }
@@ -2152,7 +2153,7 @@ public final class PowerManagerService extends SystemService
            mDozeStartInProgress &= (newWakefulness == WAKEFULNESS_DOZING);

            if (mNotifier != null) {
                mNotifier.onWakefulnessChangeStarted(newWakefulness, reason, eventTime);
                mNotifier.onGlobalWakefulnessChangeStarted(newWakefulness, reason, eventTime);
            }
            mAttentionDetector.onWakefulnessChangeStarted(newWakefulness);

@@ -2163,15 +2164,6 @@ public final class PowerManagerService extends SystemService
                    if (sQuiescent) {
                        mDirty |= DIRTY_QUIESCENT;
                    }
                    PowerGroup defaultGroup = mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP);
                    if (defaultGroup.getWakefulnessLocked() == WAKEFULNESS_DOZING) {
                        // Workaround for b/187231320 where the AOD can get stuck in a "half on /
                        // half off" state when a non-default-group VirtualDisplay causes the global
                        // wakefulness to change to awake, even though the default display is
                        // dozing. We set sandman summoned to restart dreaming to get it unstuck.
                        // TODO(b/255688811) - fix this so that AOD never gets interrupted at all.
                        defaultGroup.setSandmanSummonedLocked(true);
                    }
                    break;

                case WAKEFULNESS_ASLEEP:
@@ -2248,6 +2240,8 @@ public final class PowerManagerService extends SystemService

    @GuardedBy("mLock")
    void onPowerGroupEventLocked(int event, PowerGroup powerGroup) {
        mWakefulnessChanging = true;
        mDirty |= DIRTY_WAKEFULNESS;
        final int groupId = powerGroup.getGroupId();
        if (event == DisplayGroupPowerChangeListener.DISPLAY_GROUP_REMOVED) {
            mPowerGroups.delete(groupId);
@@ -2260,6 +2254,11 @@ public final class PowerManagerService extends SystemService
            // Kick user activity to prevent newly added group from timing out instantly.
            userActivityNoUpdateLocked(powerGroup, mClock.uptimeMillis(),
                    PowerManager.USER_ACTIVITY_EVENT_OTHER, /* flags= */ 0, Process.SYSTEM_UID);
            mNotifier.onGroupWakefulnessChangeStarted(groupId,
                    powerGroup.getWakefulnessLocked(), WAKE_REASON_DISPLAY_GROUP_ADDED,
                    mClock.uptimeMillis());
        } else if (event == DisplayGroupPowerChangeListener.DISPLAY_GROUP_REMOVED) {
            mNotifier.onGroupRemoved(groupId);
        }

        if (oldWakefulness != newWakefulness) {
+74 −21

File changed.

Preview size limit exceeded, changes collapsed.

Loading