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

Commit 3f2a5050 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fix setCanTurnScreenOn for a launching activity"

parents e61c1d5d 4bb06bed
Loading
Loading
Loading
Loading
+13 −9
Original line number Diff line number Diff line
@@ -260,9 +260,9 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
    ActivityRecord mActivityRecord;

    /**
     * See {@link #canTurnScreenOn()}
     * @see #currentLaunchCanTurnScreenOn()
     */
    private boolean mCanTurnScreenOn = true;
    private boolean mCurrentLaunchCanTurnScreenOn = true;

    /**
     * If we are running an animation, this determines the transition type. Must be one of
@@ -1002,7 +1002,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
                + " " + this);
        mAppStopped = false;
        // Allow the window to turn the screen on once the app is resumed again.
        setCanTurnScreenOn(true);
        setCurrentLaunchCanTurnScreenOn(true);
        if (!wasStopped) {
            destroySurfaces(true /*cleanupOnResume*/);
        }
@@ -2420,21 +2420,25 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
    }

    /**
     * Sets whether the current launch can turn the screen on. See {@link #canTurnScreenOn()}
     * Sets whether the current launch can turn the screen on.
     * @see #currentLaunchCanTurnScreenOn()
     */
    void setCanTurnScreenOn(boolean canTurnScreenOn) {
        mCanTurnScreenOn = canTurnScreenOn;
    void setCurrentLaunchCanTurnScreenOn(boolean currentLaunchCanTurnScreenOn) {
        mCurrentLaunchCanTurnScreenOn = currentLaunchCanTurnScreenOn;
    }

    /**
     * Indicates whether the current launch can turn the screen on. This is to prevent multiple
     * relayouts from turning the screen back on. The screen should only turn on at most
     * once per activity resume.
     * <p>
     * Note this flag is only meaningful when {@link WindowManager.LayoutParams#FLAG_TURN_SCREEN_ON}
     * or {@link ActivityRecord#canTurnScreenOn} is set.
     *
     * @return true if the screen can be turned on.
     * @return {@code true} if the activity is ready to turn on the screen.
     */
    boolean canTurnScreenOn() {
        return mCanTurnScreenOn;
    boolean currentLaunchCanTurnScreenOn() {
        return mCurrentLaunchCanTurnScreenOn;
    }

    /**
+5 −4
Original line number Diff line number Diff line
@@ -2393,10 +2393,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP

    void prepareWindowToDisplayDuringRelayout(boolean wasVisible) {
        // We need to turn on screen regardless of visibility.
        boolean hasTurnScreenOnFlag = (mAttrs.flags & FLAG_TURN_SCREEN_ON) != 0;
        final boolean hasTurnScreenOnFlag = (mAttrs.flags & FLAG_TURN_SCREEN_ON) != 0
                || (mAppToken != null && mAppToken.mActivityRecord.canTurnScreenOn());

        // The screen will turn on if the following conditions are met
        // 1. The window has the flag FLAG_TURN_SCREEN_ON
        // 1. The window has the flag FLAG_TURN_SCREEN_ON or ActivityRecord#canTurnScreenOn.
        // 2. The WMS allows theater mode.
        // 3. No AWT or the AWT allows the screen to be turned on. This should only be true once
        // per resume to prevent the screen getting getting turned on for each relayout. Set
@@ -2410,7 +2411,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
            boolean allowTheaterMode = mWmService.mAllowTheaterModeWakeFromLayout
                    || Settings.Global.getInt(mWmService.mContext.getContentResolver(),
                            Settings.Global.THEATER_MODE_ON, 0) == 0;
            boolean canTurnScreenOn = mAppToken == null || mAppToken.canTurnScreenOn();
            boolean canTurnScreenOn = mAppToken == null || mAppToken.currentLaunchCanTurnScreenOn();

            if (allowTheaterMode && canTurnScreenOn && !mPowerManagerWrapper.isInteractive()) {
                if (DEBUG_VISIBILITY || DEBUG_POWER) {
@@ -2421,7 +2422,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
            }

            if (mAppToken != null) {
                mAppToken.setCanTurnScreenOn(false);
                mAppToken.setCurrentLaunchCanTurnScreenOn(false);
            }
        }

+35 −33
Original line number Diff line number Diff line
@@ -302,43 +302,38 @@ public class WindowStateTests extends WindowTestsBase {

    @Test
    public void testPrepareWindowToDisplayDuringRelayout() {
        testPrepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
        testPrepareWindowToDisplayDuringRelayout(true /*wasVisible*/);

        // Call prepareWindowToDisplayDuringRelayout for a window without FLAG_TURN_SCREEN_ON
        // before calling prepareWindowToDisplayDuringRelayout for windows with flag in the same
        // appWindowToken.
        // Call prepareWindowToDisplayDuringRelayout for a window without FLAG_TURN_SCREEN_ON before
        // calling setCurrentLaunchCanTurnScreenOn for windows with flag in the same appWindowToken.
        final AppWindowToken appWindowToken = createAppWindowToken(mDisplayContent,
                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
        final WindowState first = createWindow(null, TYPE_APPLICATION, appWindowToken, "first");
        final WindowState second = createWindow(null, TYPE_APPLICATION, appWindowToken, "second");
        second.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;

        reset(sPowerManagerWrapper);
        first.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
        verify(sPowerManagerWrapper, never()).wakeUp(anyLong(), anyInt(), anyString());
        assertTrue(appWindowToken.canTurnScreenOn());

        reset(sPowerManagerWrapper);
        second.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
        verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString());
        assertFalse(appWindowToken.canTurnScreenOn());
        testPrepareWindowToDisplayDuringRelayout(first, false /* expectedWakeupCalled */,
                true /* expectedCurrentLaunchCanTurnScreenOn */);
        testPrepareWindowToDisplayDuringRelayout(second, true /* expectedWakeupCalled */,
                false /* expectedCurrentLaunchCanTurnScreenOn */);

        // Call prepareWindowToDisplayDuringRelayout for two window that have FLAG_TURN_SCREEN_ON
        // from the same appWindowToken. Only one should trigger the wakeup.
        appWindowToken.setCanTurnScreenOn(true);
        appWindowToken.setCurrentLaunchCanTurnScreenOn(true);
        first.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
        second.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;

        reset(sPowerManagerWrapper);
        first.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
        verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString());
        assertFalse(appWindowToken.canTurnScreenOn());
        testPrepareWindowToDisplayDuringRelayout(first, true /* expectedWakeupCalled */,
                false /* expectedCurrentLaunchCanTurnScreenOn */);
        testPrepareWindowToDisplayDuringRelayout(second, false /* expectedWakeupCalled */,
                false /* expectedCurrentLaunchCanTurnScreenOn */);

        reset(sPowerManagerWrapper);
        second.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
        verify(sPowerManagerWrapper, never()).wakeUp(anyLong(), anyInt(), anyString());
        assertFalse(appWindowToken.canTurnScreenOn());
        // Without window flags, the state of ActivityRecord.canTurnScreenOn should still be able to
        // turn on the screen.
        appWindowToken.setCurrentLaunchCanTurnScreenOn(true);
        first.mAttrs.flags &= ~WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
        doReturn(true).when(appWindowToken.mActivityRecord).canTurnScreenOn();

        testPrepareWindowToDisplayDuringRelayout(first, true /* expectedWakeupCalled */,
                false /* expectedCurrentLaunchCanTurnScreenOn */);

        // Call prepareWindowToDisplayDuringRelayout for a windows that are not children of an
        // appWindowToken. Both windows have the FLAG_TURNS_SCREEN_ON so both should call wakeup
@@ -360,6 +355,22 @@ public class WindowStateTests extends WindowTestsBase {
        verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString());
    }

    private void testPrepareWindowToDisplayDuringRelayout(WindowState appWindow,
            boolean expectedWakeupCalled, boolean expectedCurrentLaunchCanTurnScreenOn) {
        reset(sPowerManagerWrapper);
        appWindow.prepareWindowToDisplayDuringRelayout(false /* wasVisible */);

        if (expectedWakeupCalled) {
            verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString());
        } else {
            verify(sPowerManagerWrapper, never()).wakeUp(anyLong(), anyInt(), anyString());
        }
        // If wakeup is expected to be called, the currentLaunchCanTurnScreenOn should be false
        // because the state will be consumed.
        assertThat(appWindow.mAppToken.currentLaunchCanTurnScreenOn(),
                is(expectedCurrentLaunchCanTurnScreenOn));
    }

    @Test
    public void testCanAffectSystemUiFlags() {
        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
@@ -487,15 +498,6 @@ public class WindowStateTests extends WindowTestsBase {
        assertThat(app.getWmDisplayCutout().getDisplayCutout(), is(cutout.inset(7, 10, 5, 20)));
    }

    private void testPrepareWindowToDisplayDuringRelayout(boolean wasVisible) {
        reset(sPowerManagerWrapper);
        final WindowState root = createWindow(null, TYPE_APPLICATION, "root");
        root.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;

        root.prepareWindowToDisplayDuringRelayout(wasVisible /*wasVisible*/);
        verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString());
    }

    @Test
    public void testVisibilityChangeSwitchUser() {
        final WindowState window = createWindow(null, TYPE_APPLICATION, "app");