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

Commit f1f93f2c authored by Philip Junker's avatar Philip Junker
Browse files

Move logic from PMS#wakePowerGroupLocked() into PowerGroup#wakeUpLocked().

Move quiescent check into PMS#wakeUp. Add tests for
PowerGroup#dreamLocked(), #dozeLocked(), #sleepLocked() and wakeUpLocked().

Test: atest FrameworksServicesTests:PowerManagerServiceTest
Test: atest FrameworksServicesTests:PowerGroupTest
Bug: 200653844
Change-Id: I88782a37be269b9c9d28c22f5add0ecd4f3217af
parent c840164d
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@ import static android.os.PowerManagerInternal.WAKEFULNESS_DOZING;
import static android.os.PowerManagerInternal.WAKEFULNESS_DREAMING;
import static android.os.PowerManagerInternal.isInteractive;

import static com.android.internal.util.LatencyTracker.ACTION_TURN_ON_SCREEN;
import static com.android.server.power.PowerManagerService.TRACE_SCREEN_ON;
import static com.android.server.power.PowerManagerService.USER_ACTIVITY_SCREEN_BRIGHT;
import static com.android.server.power.PowerManagerService.WAKE_LOCK_DOZE;
import static com.android.server.power.PowerManagerService.WAKE_LOCK_DRAW;
@@ -30,12 +32,14 @@ import static com.android.server.power.PowerManagerService.WAKE_LOCK_SCREEN_BRIG
import android.hardware.display.DisplayManagerInternal;
import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
import android.os.PowerManager;
import android.os.PowerManagerInternal;
import android.os.PowerSaveState;
import android.os.Trace;
import android.util.Slog;
import android.view.Display;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.LatencyTracker;

/**
 * Used to store power related requests to every display in a
@@ -197,6 +201,32 @@ public class PowerGroup {
        mIsSandmanSummoned = isSandmanSummoned;
    }

    void wakeUpLocked(long eventTime, @PowerManager.WakeReason int reason, String details, int uid,
            String opPackageName, int opUid, LatencyTracker latencyTracker) {
        if (eventTime < mLastSleepTime || mWakefulness == WAKEFULNESS_AWAKE) {
            return;
        }

        Trace.traceBegin(Trace.TRACE_TAG_POWER, "wakePowerGroup" + mGroupId);
        try {
            Slog.i(TAG, "Waking up power group from "
                    + PowerManagerInternal.wakefulnessToString(mWakefulness)
                    + " (groupId=" + mGroupId
                    + ", uid=" + uid
                    + ", reason=" + PowerManager.wakeReasonToString(reason)
                    + ", details=" + details
                    + ")...");
            Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, TRACE_SCREEN_ON, mGroupId);
            // The instrument will be timed out automatically after 2 seconds.
            latencyTracker.onActionStart(ACTION_TURN_ON_SCREEN, String.valueOf(mGroupId));

            setWakefulnessLocked(WAKEFULNESS_AWAKE, eventTime, uid, reason, opUid,
                    opPackageName, details);
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_POWER);
        }
    }

    boolean dreamLocked(long eventTime, int uid) {
        if (eventTime < mLastWakeTime || mWakefulness != WAKEFULNESS_AWAKE) {
            return false;
+10 −35
Original line number Diff line number Diff line
@@ -246,7 +246,7 @@ public final class PowerManagerService extends SystemService
    private static final String REASON_LOW_BATTERY = "shutdown,battery";
    private static final String REASON_BATTERY_THERMAL_STATE = "shutdown,thermal,battery";

    private static final String TRACE_SCREEN_ON = "Screen turning on";
    static final String TRACE_SCREEN_ON = "Screen turning on";

    /** If turning screen on takes more than this long, we show a warning on logcat. */
    private static final int SCREEN_ON_LATENCY_WARNING_MS = 200;
@@ -1945,45 +1945,15 @@ public final class PowerManagerService extends SystemService
    @GuardedBy("mLock")
    private void wakePowerGroupLocked(final PowerGroup powerGroup, long eventTime,
            @WakeReason int reason, String details, int uid, String opPackageName, int opUid) {
        final int groupId = powerGroup.getGroupId();
        if (DEBUG_SPEW) {
            Slog.d(TAG, "wakePowerGroupLocked: eventTime=" + eventTime
                    + ", groupId=" + groupId + ", uid=" + uid);
                    + ", groupId=" + powerGroup.getGroupId() + ", uid=" + uid);
        }

        if (eventTime < powerGroup.getLastSleepTimeLocked() || mForceSuspendActive
                || !mSystemReady) {
        if (mForceSuspendActive || !mSystemReady) {
            return;
        }

        final int currentWakefulness = powerGroup.getWakefulnessLocked();
        if (currentWakefulness == WAKEFULNESS_AWAKE) {
            if (!mBootCompleted && sQuiescent) {
                mDirty |= DIRTY_QUIESCENT;
                updatePowerStateLocked();
            }
            return;
        }

        Trace.traceBegin(Trace.TRACE_TAG_POWER, "powerOnDisplay");
        try {
            Slog.i(TAG, "Waking up power group from "
                    + PowerManagerInternal.wakefulnessToString(currentWakefulness)
                    + " (groupId=" + groupId
                    + ", uid=" + uid
                    + ", reason=" + PowerManager.wakeReasonToString(reason)
                    + ", details=" + details
                    + ")...");
            Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, TRACE_SCREEN_ON, groupId);
            // The instrument will be timed out automatically after 2 seconds.
            LatencyTracker.getInstance(mContext)
                    .onActionStart(ACTION_TURN_ON_SCREEN, String.valueOf(groupId));

            powerGroup.setWakefulnessLocked(WAKEFULNESS_AWAKE, eventTime, uid, reason, opUid,
                    opPackageName, details);
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_POWER);
        }
        powerGroup.wakeUpLocked(eventTime, reason, details, uid, opPackageName, opUid,
                LatencyTracker.getInstance(mContext));
    }

    @GuardedBy("mLock")
@@ -5531,6 +5501,11 @@ public final class PowerManagerService extends SystemService
            final long ident = Binder.clearCallingIdentity();
            try {
                synchronized (mLock) {
                    if (!mBootCompleted && sQuiescent) {
                        mDirty |= DIRTY_QUIESCENT;
                        updatePowerStateLocked();
                        return;
                    }
                    wakePowerGroupLocked(mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP), eventTime,
                            reason, details, uid, opPackageName, uid);
                }
+84 −1
Original line number Diff line number Diff line
@@ -24,8 +24,10 @@ import static android.hardware.display.DisplayManagerInternal.DisplayPowerReques
import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_VR;
import static android.os.PowerManager.GO_TO_SLEEP_REASON_APPLICATION;
import static android.os.PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN;
import static android.os.PowerManager.GO_TO_SLEEP_REASON_DEVICE_FOLD;
import static android.os.PowerManager.GO_TO_SLEEP_REASON_TIMEOUT;
import static android.os.PowerManager.WAKE_REASON_GESTURE;
import static android.os.PowerManager.WAKE_REASON_PLUGGED_IN;
import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP;
import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE;
import static android.os.PowerManagerInternal.WAKEFULNESS_DOZING;
@@ -37,9 +39,11 @@ import static com.android.server.power.PowerManagerService.WAKE_LOCK_SCREEN_BRIG

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;

import android.hardware.display.DisplayManagerInternal;
@@ -47,6 +51,10 @@ import android.os.PowerManager;
import android.os.PowerSaveState;
import android.view.Display;

import androidx.test.platform.app.InstrumentationRegistry;

import com.android.internal.util.LatencyTracker;

import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
@@ -89,14 +97,89 @@ public class PowerGroupTest {
    }

    @Test
    public void testDreamPowerGroupTriggersOnWakefulnessChangedCallback() {
    public void testWakePowerGroup() {
        mPowerGroup.sleepLocked(TIMESTAMP1, UID, GO_TO_SLEEP_REASON_APPLICATION);
        verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID),
                eq(WAKEFULNESS_ASLEEP), eq(TIMESTAMP1), eq(GO_TO_SLEEP_REASON_APPLICATION),
                eq(UID), /* opUid= */anyInt(), /* opPackageName= */ isNull(), /* details= */
                isNull());
        String details = "wake PowerGroup1";
        LatencyTracker latencyTracker = LatencyTracker.getInstance(
                InstrumentationRegistry.getInstrumentation().getContext());
        mPowerGroup.wakeUpLocked(TIMESTAMP2, WAKE_REASON_PLUGGED_IN, details, UID,
                /* opPackageName= */ null, /* opUid= */ 0, latencyTracker);
        verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID),
                eq(WAKEFULNESS_AWAKE), eq(TIMESTAMP2), eq(WAKE_REASON_PLUGGED_IN), eq(UID),
                /* opUid= */ anyInt(), /* opPackageName= */ isNull(), eq(details));
    }

    @Test
    public void testDreamPowerGroup() {
        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
        mPowerGroup.dreamLocked(TIMESTAMP1, UID);
        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING);
        assertThat(mPowerGroup.isSandmanSummonedLocked()).isTrue();
        verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID),
                eq(WAKEFULNESS_DREAMING), eq(TIMESTAMP1), eq(GO_TO_SLEEP_REASON_APPLICATION),
                eq(UID), /* opUid= */anyInt(), /* opPackageName= */ isNull(), /* details= */
                isNull());
    }

    @Test
    public void testDozePowerGroup() {
        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
        mPowerGroup.dozeLocked(TIMESTAMP1, UID, GO_TO_SLEEP_REASON_TIMEOUT);
        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
        assertThat(mPowerGroup.isSandmanSummonedLocked()).isTrue();
        verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID),
                eq(WAKEFULNESS_DOZING), eq(TIMESTAMP1), eq(GO_TO_SLEEP_REASON_TIMEOUT),
                eq(UID), /* opUid= */ anyInt(), /* opPackageName= */ isNull(),
                /* details= */ isNull());
    }

    @Test
    public void testDozePowerGroupWhenNonInteractiveHasNoEffect() {
        mPowerGroup.sleepLocked(TIMESTAMP1, UID, GO_TO_SLEEP_REASON_TIMEOUT);
        verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID),
                eq(WAKEFULNESS_ASLEEP), eq(TIMESTAMP1), eq(GO_TO_SLEEP_REASON_TIMEOUT),
                eq(UID), /* opUid= */ anyInt(), /* opPackageName= */ isNull(),
                /* details= */ isNull());
        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
        assertThat(mPowerGroup.dozeLocked(TIMESTAMP2, UID, GO_TO_SLEEP_REASON_TIMEOUT)).isFalse();
        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
        verify(mWakefulnessCallbackMock, never()).onWakefulnessChangedLocked(
                eq(GROUP_ID), eq(WAKEFULNESS_DOZING), eq(TIMESTAMP2), /* reason= */ anyInt(),
                eq(UID), /* opUid= */ anyInt(), /* opPackageName= */ any(), /* details= */ any());
    }

    @Test
    public void testSleepPowerGroup() {
        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
        mPowerGroup.sleepLocked(TIMESTAMP1, UID, GO_TO_SLEEP_REASON_DEVICE_FOLD);
        assertThat(mPowerGroup.isSandmanSummonedLocked()).isTrue();
        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
        verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID),
                eq(WAKEFULNESS_ASLEEP), eq(TIMESTAMP1), eq(GO_TO_SLEEP_REASON_DEVICE_FOLD),
                eq(UID), /* opUid= */ anyInt(), /* opPackageName= */ isNull(),
                /* details= */ isNull());
    }

    @Test
    public void testDreamPowerGroupWhenNotAwakeHasNoEffect() {
        mPowerGroup.dozeLocked(TIMESTAMP1, UID, GO_TO_SLEEP_REASON_TIMEOUT);
        verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID),
                eq(WAKEFULNESS_DOZING), eq(TIMESTAMP1), eq(GO_TO_SLEEP_REASON_TIMEOUT),
                eq(UID), /* opUid= */ anyInt(), /* opPackageName= */ isNull(),
                /* details= */ isNull());
        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
        assertThat(mPowerGroup.dreamLocked(TIMESTAMP2, UID)).isFalse();
        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
        verify(mWakefulnessCallbackMock, never()).onWakefulnessChangedLocked(
                eq(GROUP_ID), /* wakefulness= */ eq(WAKEFULNESS_DREAMING), eq(TIMESTAMP2),
                /* reason= */ anyInt(), eq(UID), /* opUid= */ anyInt(), /* opPackageName= */ any(),
                /* details= */ any());
    }

    @Test
    public void testLastWakeAndSleepTimeIsUpdated() {
        assertThat(mPowerGroup.getLastWakeTimeLocked()).isEqualTo(TIMESTAMP_CREATE);