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

Commit b28de1f4 authored by chaviw's avatar chaviw
Browse files

Only set appToken.setCanTurnScreenOn to false if screen was turned on.

The appToken setCanTurnScreenOn value is used to ensure that a relayout
doesn't cause the screen to get turned on again within a single launch.
Previously, it was being set to false for the first window that called
relayout. This is incorrect since an app can have multiple windows
displayed. Only one of the windows needs to have the flag TURN_SCREEN_ON
in order to wakeup the screen.

Only set appToken setCanTurnScreenOn to false if all the conditions were
met to turn the screen on. This way if the first window doesn't have the
TURN_SCREEN_ON flag, other windows could still trigger the screen
getting turned on.

Change-Id: If8ff9ba1afb1f7f9632e8c911ed475aed531b880
Fixes: 74086704
Test: Incoming call turns screen on
Test: testPrepareWindowToDisplayDuringRelayout
Test: atest WindowManagerSmokeTest
parent 0db51ad5
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -2291,10 +2291,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
            }
            mPowerManagerWrapper.wakeUp(SystemClock.uptimeMillis(),
                    "android.server.wm:TURN_ON");
        }

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

        // If we were already visible, skip rest of preparation.
        if (wasVisible) {
+58 −0
Original line number Diff line number Diff line
@@ -27,6 +27,8 @@ import android.support.test.runner.AndroidJUnit4;

import java.util.LinkedList;

import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
@@ -36,6 +38,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;

import static org.junit.Assert.assertEquals;
@@ -44,6 +47,7 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;

@@ -218,6 +222,60 @@ public class WindowStateTests extends WindowTestsBase {
    public void testPrepareWindowToDisplayDuringRelayout() throws Exception {
        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.
        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(mPowerManagerWrapper);
        first.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
        verify(mPowerManagerWrapper, never()).wakeUp(anyLong(), anyString());
        assertTrue(appWindowToken.canTurnScreenOn());

        reset(mPowerManagerWrapper);
        second.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
        verify(mPowerManagerWrapper).wakeUp(anyLong(), anyString());
        assertFalse(appWindowToken.canTurnScreenOn());

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

        reset(mPowerManagerWrapper);
        first.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
        verify(mPowerManagerWrapper).wakeUp(anyLong(), anyString());
        assertFalse(appWindowToken.canTurnScreenOn());

        reset(mPowerManagerWrapper);
        second.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
        verify(mPowerManagerWrapper, never()).wakeUp(anyLong(), anyString());
        assertFalse(appWindowToken.canTurnScreenOn());

        // 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
        final WindowToken windowToken = new WindowTestUtils.TestWindowToken(FIRST_SUB_WINDOW,
                mDisplayContent);
        final WindowState firstWindow = createWindow(null, TYPE_APPLICATION, windowToken,
                "firstWindow");
        final WindowState secondWindow = createWindow(null, TYPE_APPLICATION, windowToken,
                "secondWindow");
        firstWindow.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
        secondWindow.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;

        reset(mPowerManagerWrapper);
        firstWindow.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
        verify(mPowerManagerWrapper).wakeUp(anyLong(), anyString());

        reset(mPowerManagerWrapper);
        secondWindow.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
        verify(mPowerManagerWrapper).wakeUp(anyLong(), anyString());
    }

    @Test
+10 −5
Original line number Diff line number Diff line
@@ -198,12 +198,17 @@ class WindowTestsBase {
            return new WindowTestUtils.TestWindowToken(type, dc);
        }

        final TaskStack stack =
                createStackControllerOnStackOnDisplay(windowingMode, activityType, dc).mContainer;
        return createAppWindowToken(dc, windowingMode, activityType);
    }

    AppWindowToken createAppWindowToken(DisplayContent dc, int windowingMode, int activityType) {
        final TaskStack stack = createStackControllerOnStackOnDisplay(windowingMode, activityType,
                dc).mContainer;
        final Task task = createTaskInStack(stack, 0 /* userId */);
        final WindowTestUtils.TestAppWindowToken token = new WindowTestUtils.TestAppWindowToken(dc);
        task.addChild(token, 0);
        return token;
        final WindowTestUtils.TestAppWindowToken appWindowToken =
                new WindowTestUtils.TestAppWindowToken(mDisplayContent);
        task.addChild(appWindowToken, 0);
        return appWindowToken;
    }

    WindowState createWindow(WindowState parent, int type, String name) {