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

Commit 856f818a authored by Ashley Holton's avatar Ashley Holton
Browse files

Add display ID parameter to window policy wakeUp()

Supports the per-display wake by touch project, as WindowWakeUpPolicy's
wakeUp() will need to pass on a display ID to PowerManager's wakeUP().

This also fixes a bug with the original CL where the power key failed to
wake the screen. This was due to the associated display ID for a power
key event being -1. To address this, changed PhoneWindowManager's
wakeUpFromWakeKey() to supply the default display ID to wake, instead of
the display ID from the key event.

Flag: com.android.server.power.feature.flags.per_display_wake_by_touch
Bug: 360916757
Test: atest WindowWakeUpPolicyTests PowerKeyGestureTests
KeyGestureEventTests KeyguardTests KeyguardLockedTests CtsInputTestCases

Change-Id: Iab3c8a07f6f89809582034945a759415842bce8d
parent e01bd635
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -5712,8 +5712,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    public int interceptMotionBeforeQueueingNonInteractive(int displayId, int source, int action,
            long whenNanos, int policyFlags) {
        if ((policyFlags & FLAG_WAKE) != 0) {
            if (mWindowWakeUpPolicy.wakeUpFromMotion(
                        whenNanos / 1000000, source, action == MotionEvent.ACTION_DOWN)) {
            if (mWindowWakeUpPolicy.wakeUpFromMotion(displayId, whenNanos / 1000000, source,
                    action == MotionEvent.ACTION_DOWN)) {
                // Woke up. Pass motion events to user.
                return ACTION_PASS_TO_USER;
            }
@@ -5727,8 +5727,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        // there will be no dream to intercept the touch and wake into ambient.  The device should
        // wake up in this case.
        if (isTheaterModeEnabled() && (policyFlags & FLAG_WAKE) != 0) {
            if (mWindowWakeUpPolicy.wakeUpFromMotion(
                        whenNanos / 1000000, source, action == MotionEvent.ACTION_DOWN)) {
            if (mWindowWakeUpPolicy.wakeUpFromMotion(displayId, whenNanos / 1000000, source,
                    action == MotionEvent.ACTION_DOWN)) {
                // Woke up. Pass motion events to user.
                return ACTION_PASS_TO_USER;
            }
@@ -6076,7 +6076,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    }

    private void wakeUpFromWakeKey(long eventTime, int keyCode, boolean isDown) {
        if (mWindowWakeUpPolicy.wakeUpFromKey(eventTime, keyCode, isDown)) {
        if (mWindowWakeUpPolicy.wakeUpFromKey(DEFAULT_DISPLAY, eventTime, keyCode, isDown)) {
            final boolean keyCanLaunchHome = keyCode == KEYCODE_HOME || keyCode == KEYCODE_POWER;
            // Start HOME with "reason" extra if sleeping for more than mWakeUpToLastStateTimeout
            if (shouldWakeUpWithHomeIntent() &&  keyCanLaunchHome) {
+30 −7
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import static android.os.PowerManager.WAKE_REASON_WAKE_MOTION;
import static android.view.KeyEvent.KEYCODE_POWER;

import static com.android.server.policy.Flags.supportInputWakeupDelegate;
import static com.android.server.power.feature.flags.Flags.perDisplayWakeByTouch;

import android.annotation.Nullable;
import android.content.Context;
@@ -107,13 +108,14 @@ class WindowWakeUpPolicy {
    /**
     * Wakes up from a key event.
     *
     * @param displayId the id of the display to wake.
     * @param eventTime the timestamp of the event in {@link SystemClock#uptimeMillis()}.
     * @param keyCode the {@link android.view.KeyEvent} key code of the key event.
     * @param isDown {@code true} if the event's action is {@link KeyEvent#ACTION_DOWN}.
     * @return {@code true} if the policy allows the requested wake up and the request has been
     *      executed; {@code false} otherwise.
     */
    boolean wakeUpFromKey(long eventTime, int keyCode, boolean isDown) {
    boolean wakeUpFromKey(int displayId, long eventTime, int keyCode, boolean isDown) {
        final boolean wakeAllowedDuringTheaterMode =
                keyCode == KEYCODE_POWER
                        ? mAllowTheaterModeWakeFromPowerKey
@@ -126,22 +128,31 @@ class WindowWakeUpPolicy {
                && mInputWakeUpDelegate.wakeUpFromKey(eventTime, keyCode, isDown)) {
            return true;
        }
        if (perDisplayWakeByTouch()) {
            wakeUp(
                    displayId,
                    eventTime,
                    keyCode == KEYCODE_POWER ? WAKE_REASON_POWER_BUTTON : WAKE_REASON_WAKE_KEY,
                    keyCode == KEYCODE_POWER ? "POWER" : "KEY");
        } else {
            wakeUp(
                    eventTime,
                    keyCode == KEYCODE_POWER ? WAKE_REASON_POWER_BUTTON : WAKE_REASON_WAKE_KEY,
                    keyCode == KEYCODE_POWER ? "POWER" : "KEY");
        }
        return true;
    }

    /**
     * Wakes up from a motion event.
     *
     * @param displayId the id of the display to wake.
     * @param eventTime the timestamp of the event in {@link SystemClock#uptimeMillis()}.
     * @param isDown {@code true} if the event's action is {@link MotionEvent#ACTION_DOWN}.
     * @return {@code true} if the policy allows the requested wake up and the request has been
     *      executed; {@code false} otherwise.
     */
    boolean wakeUpFromMotion(long eventTime, int source, boolean isDown) {
    boolean wakeUpFromMotion(int displayId, long eventTime, int source, boolean isDown) {
        if (!canWakeUp(mAllowTheaterModeWakeFromMotion)) {
            if (DEBUG) Slog.d(TAG, "Unable to wake up from motion.");
            return false;
@@ -150,7 +161,11 @@ class WindowWakeUpPolicy {
                && mInputWakeUpDelegate.wakeUpFromMotion(eventTime, source, isDown)) {
            return true;
        }
        if (perDisplayWakeByTouch()) {
            wakeUp(displayId, eventTime, WAKE_REASON_WAKE_MOTION, "MOTION");
        } else {
            wakeUp(eventTime, WAKE_REASON_WAKE_MOTION, "MOTION");
        }
        return true;
    }

@@ -237,4 +252,12 @@ class WindowWakeUpPolicy {
    private void wakeUp(long wakeTime, @WakeReason int reason, String details) {
        mPowerManager.wakeUp(wakeTime, reason, "android.policy:" + details);
    }

    /** Wakes up given display. */
    private void wakeUp(int displayId, long wakeTime, @WakeReason int reason, String details) {
        // If we're given an invalid display id to wake, fall back to waking default display
        final int displayIdToWake =
                displayId == Display.INVALID_DISPLAY ? Display.DEFAULT_DISPLAY : displayId;
        mPowerManager.wakeUp(wakeTime, reason, "android.policy:" + details, displayIdToWake);
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -699,8 +699,8 @@ class TestPhoneWindowManager {

    void assertPowerWakeUp() {
        mTestLooper.dispatchAll();
        verify(mWindowWakeUpPolicy)
                .wakeUpFromKey(anyLong(), eq(KeyEvent.KEYCODE_POWER), anyBoolean());
        verify(mWindowWakeUpPolicy).wakeUpFromKey(
                eq(DEFAULT_DISPLAY), anyLong(), eq(KeyEvent.KEYCODE_POWER), anyBoolean());
    }

    void assertNoPowerSleep() {
+84 −11
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static android.os.PowerManager.WAKE_REASON_GESTURE;
import static android.os.PowerManager.WAKE_REASON_POWER_BUTTON;
import static android.os.PowerManager.WAKE_REASON_WAKE_KEY;
import static android.os.PowerManager.WAKE_REASON_WAKE_MOTION;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.InputDevice.SOURCE_ROTARY_ENCODER;
import static android.view.InputDevice.SOURCE_TOUCHSCREEN;
import static android.view.KeyEvent.KEYCODE_HOME;
@@ -35,6 +36,7 @@ import static com.android.internal.R.bool.config_allowTheaterModeWakeFromCameraL
import static com.android.internal.R.bool.config_allowTheaterModeWakeFromLidSwitch;
import static com.android.internal.R.bool.config_allowTheaterModeWakeFromGesture;
import static com.android.server.policy.Flags.FLAG_SUPPORT_INPUT_WAKEUP_DELEGATE;
import static com.android.server.power.feature.flags.Flags.FLAG_PER_DISPLAY_WAKE_BY_TOUCH;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
@@ -43,6 +45,7 @@ import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
@@ -52,6 +55,8 @@ import android.content.Context;
import android.content.ContextWrapper;
import android.content.res.Resources;
import android.os.PowerManager;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
import android.view.Display;
@@ -125,6 +130,7 @@ public final class WindowWakeUpPolicyTests {
    }

    @Test
    @DisableFlags({FLAG_PER_DISPLAY_WAKE_BY_TOUCH})
    public void testMotionWakeUpDelegation_wakePowerManagerIfDelegateDoesNotHandleWake() {
        setTheaterModeEnabled(false);
        mSetFlagsRule.enableFlags(FLAG_SUPPORT_INPUT_WAKEUP_DELEGATE);
@@ -136,7 +142,8 @@ public final class WindowWakeUpPolicyTests {

        // Verify the policy wake up call succeeds because of the call on the delegate, and not
        // because of a PowerManager wake up.
        assertThat(mPolicy.wakeUpFromMotion(200, SOURCE_TOUCHSCREEN, true)).isTrue();
        assertThat(mPolicy.wakeUpFromMotion(
                mDefaultDisplay.getDisplayId(), 200, SOURCE_TOUCHSCREEN, true)).isTrue();
        verify(mInputWakeUpDelegate).wakeUpFromMotion(200, SOURCE_TOUCHSCREEN, true);
        verifyNoPowerManagerWakeUp();

@@ -144,12 +151,14 @@ public final class WindowWakeUpPolicyTests {

        // Verify the policy wake up call succeeds because of the PowerManager wake up, since the
        // delegate would not handle the wake up request.
        assertThat(mPolicy.wakeUpFromMotion(300, SOURCE_ROTARY_ENCODER, false)).isTrue();
        assertThat(mPolicy.wakeUpFromMotion(
                mDefaultDisplay.getDisplayId(), 300, SOURCE_ROTARY_ENCODER, false)).isTrue();
        verify(mInputWakeUpDelegate).wakeUpFromMotion(300, SOURCE_ROTARY_ENCODER, false);
        verify(mPowerManager).wakeUp(300, WAKE_REASON_WAKE_MOTION, "android.policy:MOTION");
    }

    @Test
    @DisableFlags({FLAG_PER_DISPLAY_WAKE_BY_TOUCH})
    public void testKeyWakeUpDelegation_wakePowerManagerIfDelegateDoesNotHandleWake() {
        setTheaterModeEnabled(false);
        mSetFlagsRule.enableFlags(FLAG_SUPPORT_INPUT_WAKEUP_DELEGATE);
@@ -161,7 +170,7 @@ public final class WindowWakeUpPolicyTests {

        // Verify the policy wake up call succeeds because of the call on the delegate, and not
        // because of a PowerManager wake up.
        assertThat(mPolicy.wakeUpFromKey(200, KEYCODE_POWER, true)).isTrue();
        assertThat(mPolicy.wakeUpFromKey(DEFAULT_DISPLAY, 200, KEYCODE_POWER, true)).isTrue();
        verify(mInputWakeUpDelegate).wakeUpFromKey(200, KEYCODE_POWER, true);
        verifyNoPowerManagerWakeUp();

@@ -169,7 +178,8 @@ public final class WindowWakeUpPolicyTests {

        // Verify the policy wake up call succeeds because of the PowerManager wake up, since the
        // delegate would not handle the wake up request.
        assertThat(mPolicy.wakeUpFromKey(300, KEYCODE_STEM_PRIMARY, false)).isTrue();
        assertThat(mPolicy.wakeUpFromKey(
                DEFAULT_DISPLAY, 300, KEYCODE_STEM_PRIMARY, false)).isTrue();
        verify(mInputWakeUpDelegate).wakeUpFromKey(300, KEYCODE_STEM_PRIMARY, false);
        verify(mPowerManager).wakeUp(300, WAKE_REASON_WAKE_KEY, "android.policy:KEY");
    }
@@ -186,7 +196,7 @@ public final class WindowWakeUpPolicyTests {
                .setInputWakeUpDelegate(mInputWakeUpDelegate);

        // Check that the wake up does not happen because the theater mode policy check fails.
        assertThat(mPolicy.wakeUpFromKey(200, KEYCODE_POWER, true)).isFalse();
        assertThat(mPolicy.wakeUpFromKey(DEFAULT_DISPLAY, 200, KEYCODE_POWER, true)).isFalse();
        verify(mInputWakeUpDelegate, never()).wakeUpFromKey(anyLong(), anyInt(), anyBoolean());
    }

@@ -201,11 +211,13 @@ public final class WindowWakeUpPolicyTests {
                .setInputWakeUpDelegate(mInputWakeUpDelegate);

        // Check that the wake up does not happen because the theater mode policy check fails.
        assertThat(mPolicy.wakeUpFromMotion(200, SOURCE_TOUCHSCREEN, true)).isFalse();
        assertThat(mPolicy.wakeUpFromMotion(
                mDefaultDisplay.getDisplayId(), 200, SOURCE_TOUCHSCREEN, true)).isFalse();
        verify(mInputWakeUpDelegate, never()).wakeUpFromMotion(anyLong(), anyInt(), anyBoolean());
    }

    @Test
    @DisableFlags({FLAG_PER_DISPLAY_WAKE_BY_TOUCH})
    public void testTheaterModeChecksNotAppliedWhenScreenIsOn() {
        mSetFlagsRule.enableFlags(FLAG_SUPPORT_INPUT_WAKEUP_DELEGATE);
        setDefaultDisplayState(Display.STATE_ON);
@@ -213,30 +225,69 @@ public final class WindowWakeUpPolicyTests {
        setBooleanRes(config_allowTheaterModeWakeFromMotion, false);
        mPolicy = new WindowWakeUpPolicy(mContextSpy, mClock);

        mPolicy.wakeUpFromMotion(200L, SOURCE_TOUCHSCREEN, true);
        mPolicy.wakeUpFromMotion(mDefaultDisplay.getDisplayId(), 200L, SOURCE_TOUCHSCREEN, true);

        verify(mPowerManager).wakeUp(200L, WAKE_REASON_WAKE_MOTION, "android.policy:MOTION");
    }

    @Test
    @DisableFlags({FLAG_PER_DISPLAY_WAKE_BY_TOUCH})
    public void testWakeUpFromMotion() {
        runPowerManagerUpChecks(
                () -> mPolicy.wakeUpFromMotion(mClock.uptimeMillis(), SOURCE_TOUCHSCREEN, true),
                () -> mPolicy.wakeUpFromMotion(mDefaultDisplay.getDisplayId(),
                        mClock.uptimeMillis(), SOURCE_TOUCHSCREEN, true),
                config_allowTheaterModeWakeFromMotion,
                WAKE_REASON_WAKE_MOTION,
                "android.policy:MOTION");
    }

    @Test
    @EnableFlags({FLAG_PER_DISPLAY_WAKE_BY_TOUCH})
    public void testWakeUpFromMotion_perDisplayWakeByTouchEnabled() {
        setTheaterModeEnabled(false);
        final int displayId = 555;
        mPolicy = new WindowWakeUpPolicy(mContextSpy, mClock);

        boolean displayWokeUp = mPolicy.wakeUpFromMotion(
                displayId, mClock.uptimeMillis(), SOURCE_TOUCHSCREEN, /* isDown= */ true);

        // Verify that display is woken up
        assertThat(displayWokeUp).isTrue();
        verify(mPowerManager).wakeUp(anyLong(), eq(WAKE_REASON_WAKE_MOTION),
                eq("android.policy:MOTION"), eq(displayId));
    }

    @Test
    @DisableFlags({FLAG_PER_DISPLAY_WAKE_BY_TOUCH})
    public void testWakeUpFromMotion_perDisplayWakeByTouchDisabled() {
        setTheaterModeEnabled(false);
        final int displayId = 555;
        mPolicy = new WindowWakeUpPolicy(mContextSpy, mClock);

        boolean displayWokeUp = mPolicy.wakeUpFromMotion(
                displayId, mClock.uptimeMillis(), SOURCE_TOUCHSCREEN, /* isDown= */ true);

        // Verify that power is woken up and display isn't woken up individually
        assertThat(displayWokeUp).isTrue();
        verify(mPowerManager).wakeUp(
                anyLong(), eq(WAKE_REASON_WAKE_MOTION), eq("android.policy:MOTION"));
        verify(mPowerManager, never()).wakeUp(anyLong(), eq(WAKE_REASON_WAKE_MOTION),
                eq("android.policy:MOTION"), eq(displayId));
    }

    @Test
    @DisableFlags({FLAG_PER_DISPLAY_WAKE_BY_TOUCH})
    public void testWakeUpFromKey_nonPowerKey() {
        runPowerManagerUpChecks(
                () -> mPolicy.wakeUpFromKey(mClock.uptimeMillis(), KEYCODE_HOME, true),
                () -> mPolicy.wakeUpFromKey(
                        DEFAULT_DISPLAY, mClock.uptimeMillis(), KEYCODE_HOME, true),
                config_allowTheaterModeWakeFromKey,
                WAKE_REASON_WAKE_KEY,
                "android.policy:KEY");
    }

    @Test
    @DisableFlags({FLAG_PER_DISPLAY_WAKE_BY_TOUCH})
    public void testWakeUpFromKey_powerKey() {
        // Disable the resource affecting all wake keys because it affects power key as well.
        // That way, power key wake during theater mode will solely be controlled by
@@ -245,7 +296,8 @@ public final class WindowWakeUpPolicyTests {

        // Test with power key
        runPowerManagerUpChecks(
                () -> mPolicy.wakeUpFromKey(mClock.uptimeMillis(), KEYCODE_POWER, true),
                () -> mPolicy.wakeUpFromKey(
                        DEFAULT_DISPLAY, mClock.uptimeMillis(), KEYCODE_POWER, true),
                config_allowTheaterModeWakeFromPowerKey,
                WAKE_REASON_POWER_BUTTON,
                "android.policy:POWER");
@@ -254,13 +306,31 @@ public final class WindowWakeUpPolicyTests {
        // even if the power-key specific theater mode config is disabled.
        setBooleanRes(config_allowTheaterModeWakeFromPowerKey, false);
        runPowerManagerUpChecks(
                () -> mPolicy.wakeUpFromKey(mClock.uptimeMillis(), KEYCODE_POWER, false),
                () -> mPolicy.wakeUpFromKey(
                        DEFAULT_DISPLAY, mClock.uptimeMillis(), KEYCODE_POWER, false),
                config_allowTheaterModeWakeFromKey,
                WAKE_REASON_POWER_BUTTON,
                "android.policy:POWER");
    }

    @Test
    @EnableFlags({FLAG_PER_DISPLAY_WAKE_BY_TOUCH})
    public void testWakeUpFromKey_invalidDisplay_perDisplayWakeByTouchEnabled() {
        setTheaterModeEnabled(false);
        final int displayId = Display.INVALID_DISPLAY;
        mPolicy = new WindowWakeUpPolicy(mContextSpy, mClock);

        boolean displayWokeUp = mPolicy.wakeUpFromKey(
                displayId, mClock.uptimeMillis(), KEYCODE_POWER, /* isDown= */ false);

        // Verify that default display is woken up
        assertThat(displayWokeUp).isTrue();
        verify(mPowerManager).wakeUp(anyLong(), eq(WAKE_REASON_POWER_BUTTON),
                eq("android.policy:POWER"), eq(DEFAULT_DISPLAY));
    }

    @Test
    @DisableFlags({FLAG_PER_DISPLAY_WAKE_BY_TOUCH})
    public void testWakeUpFromLid() {
        runPowerManagerUpChecks(
                () -> mPolicy.wakeUpFromLid(),
@@ -270,6 +340,7 @@ public final class WindowWakeUpPolicyTests {
    }

    @Test
    @DisableFlags({FLAG_PER_DISPLAY_WAKE_BY_TOUCH})
    public void testWakeUpFromWakeGesture() {
        runPowerManagerUpChecks(
                () -> mPolicy.wakeUpFromWakeGesture(),
@@ -279,6 +350,7 @@ public final class WindowWakeUpPolicyTests {
    }

    @Test
    @DisableFlags({FLAG_PER_DISPLAY_WAKE_BY_TOUCH})
    public void testwakeUpFromCameraCover() {
        runPowerManagerUpChecks(
                () -> mPolicy.wakeUpFromCameraCover(mClock.uptimeMillis()),
@@ -288,6 +360,7 @@ public final class WindowWakeUpPolicyTests {
    }

    @Test
    @DisableFlags({FLAG_PER_DISPLAY_WAKE_BY_TOUCH})
    public void testWakeUpFromPowerKeyCameraGesture() {
        // Disable the resource affecting all wake keys because it affects power key as well.
        // That way, power key wake during theater mode will solely be controlled by