diff options
4 files changed, 121 insertions, 25 deletions
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 845798f697bf..8d039f19db8c 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -5859,8 +5859,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; } @@ -5874,8 +5874,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; } @@ -6223,7 +6223,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) { diff --git a/services/core/java/com/android/server/policy/WindowWakeUpPolicy.java b/services/core/java/com/android/server/policy/WindowWakeUpPolicy.java index af1ad13f1d15..04dbd1fea5d6 100644 --- a/services/core/java/com/android/server/policy/WindowWakeUpPolicy.java +++ b/services/core/java/com/android/server/policy/WindowWakeUpPolicy.java @@ -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; } - wakeUp( - eventTime, - keyCode == KEYCODE_POWER ? WAKE_REASON_POWER_BUTTON : WAKE_REASON_WAKE_KEY, - keyCode == KEYCODE_POWER ? "POWER" : "KEY"); + 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; } - wakeUp(eventTime, WAKE_REASON_WAKE_MOTION, "MOTION"); + 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); + } } diff --git a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java index 6596ee935b4b..a51ce9951ab4 100644 --- a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java +++ b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java @@ -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() { diff --git a/services/tests/wmtests/src/com/android/server/policy/WindowWakeUpPolicyTests.java b/services/tests/wmtests/src/com/android/server/policy/WindowWakeUpPolicyTests.java index 7322e5a3b681..3ca352cfa60d 100644 --- a/services/tests/wmtests/src/com/android/server/policy/WindowWakeUpPolicyTests.java +++ b/services/tests/wmtests/src/com/android/server/policy/WindowWakeUpPolicyTests.java @@ -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 |