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

Commit b68749be authored by Yeabkal Wubshit's avatar Yeabkal Wubshit
Browse files

Remove theater-mode wake checks if screen is already on

The purpose of the theater-mode checks before the WindowWakeUpPolicy
wakes is to prevent the screen from turning ON while the user is in
theater mode (by extension, when the user is in an environment where
they do not want the screen to be ON).

Therefore, let's disable the theater-mode guards if a "wake" attempt is
being done while the screen is already ON.

Note that we flagged this new behavior with
FLAG_SUPPORT_INPUT_WAKEUP_DELEGATE, since the situation we're trying
to fix is relevant only when FLAG_SUPPORT_INPUT_WAKEUP_DELEGATE
is ON.

Flag: com.android.server.policy.support_input_wakeup_delegate
Bug: 333762937
Test: atest WindowWakeUpPolicyTests
Change-Id: I5804a5adfd51bed12ca02bc3fea13689adbd24a0
parent 697bd2a1
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -34,7 +34,9 @@ import android.os.PowerManager.WakeReason;
import android.os.SystemClock;
import android.provider.Settings;
import android.util.Slog;
import android.view.Display;
import android.view.KeyEvent;
import android.view.WindowManager;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.Clock;
@@ -48,6 +50,7 @@ class WindowWakeUpPolicy {

    private final Context mContext;
    private final PowerManager mPowerManager;
    private final WindowManager mWindowManager;
    private final Clock mClock;

    private final boolean mAllowTheaterModeWakeFromKey;
@@ -68,6 +71,7 @@ class WindowWakeUpPolicy {
    WindowWakeUpPolicy(Context context, Clock clock) {
        mContext = context;
        mPowerManager = context.getSystemService(PowerManager.class);
        mWindowManager = context.getSystemService(WindowManager.class);
        mClock = clock;

        final Resources res = context.getResources();
@@ -212,12 +216,23 @@ class WindowWakeUpPolicy {
    }

    private boolean canWakeUp(boolean wakeInTheaterMode) {
        if (supportInputWakeupDelegate() && isDefaultDisplayOn()) {
            // If the default display is on, theater mode should not influence whether or not
            // waking up is allowed. This is because the theater mode checks are there to block
            // the display from being on in situations where the user may not want it to be
            // on (so if the display is already on, no need to check for theater mode at all).
            return true;
        }
        final boolean isTheaterModeEnabled =
                Settings.Global.getInt(
                        mContext.getContentResolver(), Settings.Global.THEATER_MODE_ON, 0) == 1;
        return wakeInTheaterMode || !isTheaterModeEnabled;
    }

    private boolean isDefaultDisplayOn() {
        return Display.isOnState(mWindowManager.getDefaultDisplay().getState());
    }

    /** Wakes up {@link PowerManager}. */
    private void wakeUp(long wakeTime, @WakeReason int reason, String details) {
        mPowerManager.wakeUp(wakeTime, reason, "android.policy:" + details);
+28 −0
Original line number Diff line number Diff line
@@ -54,6 +54,8 @@ import android.content.res.Resources;
import android.os.PowerManager;
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
import android.view.Display;
import android.view.WindowManager;

import androidx.test.InstrumentationRegistry;

@@ -82,6 +84,8 @@ public final class WindowWakeUpPolicyTests {
    @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();

    @Mock PowerManager mPowerManager;
    @Mock WindowManager mWindowManager;
    @Mock Display mDefaultDisplay;
    @Mock Clock mClock;
    @Mock WindowWakeUpPolicyInternal.InputWakeUpDelegate mInputWakeUpDelegate;

@@ -96,7 +100,10 @@ public final class WindowWakeUpPolicyTests {
        mResourcesSpy = spy(mContextSpy.getResources());
        when(mContextSpy.getResources()).thenReturn(mResourcesSpy);
        when(mContextSpy.getSystemService(PowerManager.class)).thenReturn(mPowerManager);
        when(mContextSpy.getSystemService(WindowManager.class)).thenReturn(mWindowManager);
        when(mWindowManager.getDefaultDisplay()).thenReturn(mDefaultDisplay);
        LocalServices.removeServiceForTest(WindowWakeUpPolicyInternal.class);
        setDefaultDisplayState(Display.STATE_OFF);
    }

    @Test
@@ -198,6 +205,19 @@ public final class WindowWakeUpPolicyTests {
        verify(mInputWakeUpDelegate, never()).wakeUpFromMotion(anyLong(), anyInt(), anyBoolean());
    }

    @Test
    public void testTheaterModeChecksNotAppliedWhenScreenIsOn() {
        mSetFlagsRule.enableFlags(FLAG_SUPPORT_INPUT_WAKEUP_DELEGATE);
        setDefaultDisplayState(Display.STATE_ON);
        setTheaterModeEnabled(true);
        setBooleanRes(config_allowTheaterModeWakeFromMotion, false);
        mPolicy = new WindowWakeUpPolicy(mContextSpy, mClock);

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

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

    @Test
    public void testWakeUpFromMotion() {
        runPowerManagerUpChecks(
@@ -291,6 +311,7 @@ public final class WindowWakeUpPolicyTests {

        Mockito.reset(mPowerManager);
        setBooleanRes(theatherModeWakeResId, true);
        LocalServices.removeServiceForTest(WindowWakeUpPolicyInternal.class);
        mPolicy = new WindowWakeUpPolicy(mContextSpy, mClock);
        setUptimeMillis(200);
        assertWithMessage("Wake should happen in theater mode when config allows it.")
@@ -299,6 +320,7 @@ public final class WindowWakeUpPolicyTests {

        Mockito.reset(mPowerManager);
        setBooleanRes(theatherModeWakeResId, false);
        LocalServices.removeServiceForTest(WindowWakeUpPolicyInternal.class);
        mPolicy = new WindowWakeUpPolicy(mContextSpy, mClock);
        setUptimeMillis(250);
        assertWithMessage("Wake should not happen in theater mode when config disallows it.")
@@ -310,6 +332,7 @@ public final class WindowWakeUpPolicyTests {

        Mockito.reset(mPowerManager);
        setBooleanRes(theatherModeWakeResId, true);
        LocalServices.removeServiceForTest(WindowWakeUpPolicyInternal.class);
        mPolicy = new WindowWakeUpPolicy(mContextSpy, mClock);
        setUptimeMillis(300);
        assertWithMessage("Wake should happen when not in theater mode.")
@@ -318,6 +341,7 @@ public final class WindowWakeUpPolicyTests {

        Mockito.reset(mPowerManager);
        setBooleanRes(theatherModeWakeResId, false);
        LocalServices.removeServiceForTest(WindowWakeUpPolicyInternal.class);
        mPolicy = new WindowWakeUpPolicy(mContextSpy, mClock);
        setUptimeMillis(350);
        assertWithMessage("Wake should happen when not in theater mode.")
@@ -351,4 +375,8 @@ public final class WindowWakeUpPolicyTests {
        when(mInputWakeUpDelegate.wakeUpFromKey(anyLong(), anyInt(), anyBoolean()))
                .thenReturn(result);
    }

    private void setDefaultDisplayState(int displayState) {
        when(mDefaultDisplay.getState()).thenReturn(displayState);
    }
}