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

Commit f5358585 authored by Antony Sargent's avatar Antony Sargent
Browse files

Workaround for doze/AOD problem with global wakefulness

When the global wakefulness is dozing and a non-default group
VirtualDisplay wakes up, the global wakefulness becomes awake and the
default display's individual wakefulness remains dozing. But some of
our code in Notifier and PhoneWindowManager that listen to the global
wakefulness kick off a chain of events that results in
KeyguardViewMediator thinking dozing has stopped, and the display gets
stuck in what feels like a sort of half on / half off state where it
shows keyguard at the low brightness and refresh rate we're supposed
to use for AOD, but it isn't responsive to touch inputs.

The workaround in this CL is to restart dreaming in this case to get
the AOD unstuck.

Bug: 187231320
Test: atest PowerManagerServiceTest
Change-Id: I8e348ffe52c7f2d5cbdd11b058254cb087b1021d
parent fe8b17d4
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -2185,6 +2185,15 @@ public final class PowerManagerService extends SystemService
                    if (sQuiescent) {
                        mDirty |= DIRTY_QUIESCENT;
                    }
                    PowerGroup defaultGroup = mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP);
                    if (defaultGroup.getWakefulnessLocked() == WAKEFULNESS_DOZING) {
                        // Workaround for b/187231320 where the AOD can get stuck in a "half on /
                        // half off" state when a non-default-group VirtualDisplay causes the global
                        // wakefulness to change to awake, even though the default display is
                        // dozing. We set sandman summoned to restart dreaming to get it unstuck.
                        // TODO(b/255688811) - fix this so that AOD never gets interrupted at all.
                        defaultGroup.setSandmanSummonedLocked(true);
                    }
                    break;

                case WAKEFULNESS_ASLEEP:
+44 −0
Original line number Diff line number Diff line
@@ -1819,6 +1819,50 @@ public class PowerManagerServiceTest {
        verify(mDreamManagerInternalMock).startDream(eq(true), anyString());
    }

    @Test
    public void testMultiDisplay_defaultDozing_addNewDisplayDefaultGoesBackToDoze() {
        final int nonDefaultDisplayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1;
        final int nonDefaultDisplay = Display.DEFAULT_DISPLAY + 1;
        final AtomicReference<DisplayManagerInternal.DisplayGroupListener> listener =
                new AtomicReference<>();
        doAnswer((Answer<Void>) invocation -> {
            listener.set(invocation.getArgument(0));
            return null;
        }).when(mDisplayManagerInternalMock).registerDisplayGroupListener(any());
        final DisplayInfo info = new DisplayInfo();
        info.displayGroupId = nonDefaultDisplayGroupId;
        when(mDisplayManagerInternalMock.getDisplayInfo(nonDefaultDisplay)).thenReturn(info);

        doAnswer(inv -> {
            when(mDreamManagerInternalMock.isDreaming()).thenReturn(true);
            return null;
        }).when(mDreamManagerInternalMock).startDream(anyBoolean(), anyString());

        createService();
        startSystem();

        assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo(
                WAKEFULNESS_AWAKE);

        forceDozing();
        advanceTime(500);

        assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo(
                WAKEFULNESS_DOZING);
        assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
        verify(mDreamManagerInternalMock).startDream(eq(true), anyString());

        listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId);
        advanceTime(500);

        assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
        assertThat(mService.getWakefulnessLocked(nonDefaultDisplayGroupId)).isEqualTo(
                WAKEFULNESS_AWAKE);
        assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo(
                WAKEFULNESS_DOZING);
        verify(mDreamManagerInternalMock, times(2)).startDream(eq(true), anyString());
    }

    @Test
    public void testLastSleepTime_notUpdatedWhenDreaming() {
        createService();