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

Commit 330417cf authored by Philip Junker's avatar Philip Junker Committed by Android (Google) Code Review
Browse files

Merge "Move logic from dreamDisplayGroupNoUpdateLocked into PowerGroup."

parents 44a753f5 f4fa114c
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -704,6 +704,21 @@ public final class PowerManager {
        public long wakeTime;
        public @WakeReason int wakeReason;
        public long sleepDuration;

        @Override
        public boolean equals(@Nullable Object o) {
            if (o instanceof WakeData) {
                final WakeData other = (WakeData) o;
                return wakeTime == other.wakeTime && wakeReason == other.wakeReason
                        && sleepDuration == other.sleepDuration;
            }
            return false;
        }

        @Override
        public int hashCode() {
            return Objects.hash(wakeTime, wakeReason, sleepDuration);
        }
    }

    /**
+134 −23
Original line number Diff line number Diff line
@@ -16,9 +16,16 @@

package com.android.server.power;

import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP;
import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE;
import static android.os.PowerManagerInternal.WAKEFULNESS_DOZING;
import static android.os.PowerManagerInternal.WAKEFULNESS_DREAMING;
import static android.os.PowerManagerInternal.isInteractive;

import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
import android.os.PowerManager;
import android.os.Trace;
import android.util.Slog;
import android.view.Display;

/**
@@ -31,47 +38,66 @@ import android.view.Display;
 */
public class PowerGroup {
    private static final String TAG = PowerGroup.class.getSimpleName();
    private static final boolean DEBUG = false;

    private final DisplayPowerRequest mDisplayPowerRequest;
    private final PowerGroupListener mWakefulnessListener;
    private final boolean mSupportsSandman;
    private final int mGroupId;

    // True if DisplayManagerService has applied all the latest display states that were requested
    // for this group
    /** True if DisplayManagerService has applied all the latest display states that were requested
     *  for this group. */
    private boolean mReady;
    // True if this group is in the process of powering on
    /** True if this group is in the process of powering on */
    private boolean mPoweringOn;
    // True if this group is about to dream
    /** True if this group is about to dream */
    private boolean mIsSandmanSummoned;
    private int mUserActivitySummary;
    // The current wakefulness of this group
    /** The current wakefulness of this group */
    private int mWakefulness;
    private int mWakeLockSummary;
    private long mLastPowerOnTime;
    private long mLastUserActivityTime;
    private long mLastUserActivityTimeNoChangeLights;
    /** Timestamp (milliseconds since boot) of the last time the power group was awoken.*/
    private long mLastWakeTime;
    /** Timestamp (milliseconds since boot) of the last time the power group was put to sleep. */
    private long mLastSleepTime;

    PowerGroup(int groupId, DisplayPowerRequest displayPowerRequest, int wakefulness, boolean ready,
            boolean supportsSandman) {
        this.mGroupId = groupId;
        this.mDisplayPowerRequest = displayPowerRequest;
        this.mWakefulness = wakefulness;
        this.mReady = ready;
        this.mSupportsSandman = supportsSandman;
    PowerGroup(int groupId, PowerGroupListener wakefulnessListener,
            DisplayPowerRequest displayPowerRequest, int wakefulness, boolean ready,
            boolean supportsSandman, long eventTime) {
        mGroupId = groupId;
        mWakefulnessListener = wakefulnessListener;
        mDisplayPowerRequest = displayPowerRequest;
        mWakefulness = wakefulness;
        mReady = ready;
        mSupportsSandman = supportsSandman;
        mLastWakeTime = eventTime;
        mLastSleepTime = eventTime;
    }

    PowerGroup() {
        this.mGroupId = Display.DEFAULT_DISPLAY_GROUP;
        this.mDisplayPowerRequest = new DisplayPowerRequest();
        this.mWakefulness = WAKEFULNESS_AWAKE;
        this.mReady = false;
        this.mSupportsSandman = true;
    }
    PowerGroup(int wakefulness, PowerGroupListener wakefulnessListener, long eventTime) {
        mGroupId = Display.DEFAULT_DISPLAY_GROUP;
        mWakefulnessListener = wakefulnessListener;
        mDisplayPowerRequest = new DisplayPowerRequest();
        mWakefulness = wakefulness;
        mReady = false;
        mSupportsSandman = true;
        mLastWakeTime = eventTime;
        mLastSleepTime = eventTime;    }

    DisplayPowerRequest getDisplayPowerRequestLocked() {
        return mDisplayPowerRequest;
    }

    long getLastWakeTimeLocked() {
        return mLastWakeTime;
    }

    long getLastSleepTimeLocked() {
        return mLastSleepTime;
    }

    int getWakefulnessLocked() {
        return mWakefulness;
    }
@@ -85,9 +111,19 @@ public class PowerGroup {
     *
     * @return {@code true} if the wakefulness value was changed; {@code false} otherwise.
     */
    boolean setWakefulnessLocked(int newWakefulness) {
    boolean setWakefulnessLocked(int newWakefulness, long eventTime, int uid, int reason, int opUid,
            String opPackageName, String details) {
        if (mWakefulness != newWakefulness) {
            if (newWakefulness == WAKEFULNESS_AWAKE) {
                setLastPowerOnTimeLocked(eventTime);
                setIsPoweringOnLocked(true);
                mLastWakeTime = eventTime;
            } else if (isInteractive(mWakefulness) && !isInteractive(newWakefulness)) {
                mLastSleepTime = eventTime;
            }
            mWakefulness = newWakefulness;
            mWakefulnessListener.onWakefulnessChangedLocked(mGroupId, mWakefulness, eventTime,
                    reason, uid, opUid, opPackageName, details);
            return true;
        }
        return false;
@@ -105,8 +141,9 @@ public class PowerGroup {
     * Sets whether the displays of this group are all ready.
     *
     * <p>A display is ready if its reported
     * {@link DisplayManagerInternal.DisplayPowerCallbacks#onStateChanged() actual state} matches
     * its {@link DisplayManagerInternal#requestPowerState requested state}.
     * {@link android.hardware.display.DisplayManagerInternal.DisplayPowerCallbacks#onStateChanged()
     * actual state} matches its
     * {@link android.hardware.display.DisplayManagerInternal#requestPowerState requested state}.
     *
     * @param isReady {@code true} if every display in the group is ready; otherwise {@code false}.
     * @return {@code true} if the ready state changed; otherwise {@code false}.
@@ -148,6 +185,62 @@ public class PowerGroup {
        mIsSandmanSummoned = isSandmanSummoned;
    }

    boolean dreamLocked(long eventTime, int uid) {
        if (eventTime < mLastWakeTime || mWakefulness != WAKEFULNESS_AWAKE) {
            return false;
        }

        Trace.traceBegin(Trace.TRACE_TAG_POWER, "dreamPowerGroup" + getGroupId());
        try {
            Slog.i(TAG, "Napping power group (groupId=" + getGroupId() + ", uid=" + uid + ")...");
            setSandmanSummonedLocked(true);
            setWakefulnessLocked(WAKEFULNESS_DREAMING, eventTime, uid, /* reason= */0,
                    /* opUid= */ 0, /* opPackageName= */ null, /* details= */ null);
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_POWER);
        }
        return true;
    }

    boolean dozeLocked(long eventTime, int uid, int reason) {
        if (eventTime < getLastWakeTimeLocked() || !isInteractive(mWakefulness)) {
            return false;
        }

        Trace.traceBegin(Trace.TRACE_TAG_POWER, "powerOffDisplay");
        try {
            reason = Math.min(PowerManager.GO_TO_SLEEP_REASON_MAX,
                    Math.max(reason, PowerManager.GO_TO_SLEEP_REASON_MIN));
            Slog.i(TAG, "Powering off display group due to "
                    + PowerManager.sleepReasonToString(reason)  + " (groupId= " + getGroupId()
                    + ", uid= " + uid + ")...");

            setSandmanSummonedLocked(/* isSandmanSummoned= */ true);
            setWakefulnessLocked(WAKEFULNESS_DOZING, eventTime, uid, reason, /* opUid= */ 0,
                    /* opPackageName= */ null, /* details= */ null);
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_POWER);
        }
        return true;
    }

    boolean sleepLocked(long eventTime, int uid, int reason) {
        if (eventTime < mLastWakeTime || getWakefulnessLocked() == WAKEFULNESS_ASLEEP) {
            return false;
        }

        Trace.traceBegin(Trace.TRACE_TAG_POWER, "sleepPowerGroup");
        try {
            Slog.i(TAG, "Sleeping power group (groupId=" + getGroupId() + ", uid=" + uid + ")...");
            setSandmanSummonedLocked(/* isSandmanSummoned= */ true);
            setWakefulnessLocked(WAKEFULNESS_ASLEEP, eventTime, uid, reason, /* opUid= */0,
                    /* opPackageName= */ null, /* details= */ null);
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_POWER);
        }
        return true;
    }

    long getLastUserActivityTimeLocked() {
        return mLastUserActivityTime;
    }
@@ -187,4 +280,22 @@ public class PowerGroup {
    public boolean supportsSandmanLocked() {
        return mSupportsSandman;
    }

    protected interface PowerGroupListener {
        /**
         * Informs the recipient about a wakefulness change of a {@link PowerGroup}.
         *
         * @param groupId The PowerGroup's id for which the wakefulness has changed.
         * @param wakefulness The new wakefulness.
         * @param eventTime The time of the event.
         * @param reason The reason, any of {@link android.os.PowerManager.WakeReason} or
         *               {@link android.os.PowerManager.GoToSleepReason}.
         * @param uid The uid which caused the wakefulness change.
         * @param opUid The uid used for AppOps.
         * @param opPackageName The Package name used for AppOps.
         * @param details Details about the event.
         */
        void onWakefulnessChangedLocked(int groupId, int wakefulness, long eventTime, int reason,
                int uid, int opUid, String opPackageName, String details);
    }
}
+185 −236

File changed.

Preview size limit exceeded, changes collapsed.

+129 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.power;


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_TIMEOUT;
import static android.os.PowerManager.WAKE_REASON_GESTURE;
import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP;
import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE;
import static android.os.PowerManagerInternal.WAKEFULNESS_DOZING;
import static android.os.PowerManagerInternal.WAKEFULNESS_DREAMING;

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

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

import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;

import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

/**
 * Tests for {@link com.android.server.power.PowerGroup}.
 *
 * Build/Install/Run:
 *  atest FrameworksServicesTests:PowerManagerServiceTest
 */
public class PowerGroupTest {

    private static final int GROUP_ID = 0;
    private static final long TIMESTAMP_CREATE = 1;
    private static final long TIMESTAMP1 = 999;
    private static final long TIMESTAMP2 = TIMESTAMP1 + 10;
    private static final long TIMESTAMP3 = TIMESTAMP2 + 10;
    private static final int UID = 11;

    private PowerGroup mPowerGroup;
    @Mock
    private PowerGroup.PowerGroupListener mWakefulnessCallbackMock;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        mPowerGroup = new PowerGroup(GROUP_ID, mWakefulnessCallbackMock, new DisplayPowerRequest(),
                WAKEFULNESS_AWAKE, /* ready= */ true, /* supportsSandman= */true, TIMESTAMP_CREATE);
    }

    @Test
    public void testDreamPowerGroupTriggersOnWakefulnessChangedCallback() {
        mPowerGroup.dreamLocked(TIMESTAMP1, UID);
        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 testLastWakeAndSleepTimeIsUpdated() {
        assertThat(mPowerGroup.getLastWakeTimeLocked()).isEqualTo(TIMESTAMP_CREATE);
        assertThat(mPowerGroup.getLastSleepTimeLocked()).isEqualTo(TIMESTAMP_CREATE);

        // Verify that the transition to WAKEFULNESS_DOZING updates the last sleep time
        String details = "PowerGroup1 Timeout";
        mPowerGroup.setWakefulnessLocked(WAKEFULNESS_DOZING, TIMESTAMP1, UID,
                GO_TO_SLEEP_REASON_TIMEOUT, /* opUid= */ 0, /* opPackageName= */ null, details);
        assertThat(mPowerGroup.getLastSleepTimeLocked()).isEqualTo(TIMESTAMP1);
        assertThat(mPowerGroup.getLastWakeTimeLocked()).isEqualTo(TIMESTAMP_CREATE);
        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
        verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID),
                eq(WAKEFULNESS_DOZING), eq(TIMESTAMP1), eq(GO_TO_SLEEP_REASON_TIMEOUT),
                eq(UID), /* opUid= */anyInt(), /* opPackageName= */ isNull(), eq(details));

        // Verify that the transition to WAKEFULNESS_ASLEEP after dozing does not update the last
        // wake or sleep time
        mPowerGroup.setWakefulnessLocked(WAKEFULNESS_ASLEEP, TIMESTAMP2, UID,
                GO_TO_SLEEP_REASON_DEVICE_ADMIN, /* opUid= */ 0, /* opPackageName= */ null,
                details);
        assertThat(mPowerGroup.getLastSleepTimeLocked()).isEqualTo(TIMESTAMP1);
        assertThat(mPowerGroup.getLastWakeTimeLocked()).isEqualTo(TIMESTAMP_CREATE);
        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
        verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID),
                eq(WAKEFULNESS_ASLEEP), eq(TIMESTAMP2), eq(GO_TO_SLEEP_REASON_DEVICE_ADMIN),
                eq(UID), /* opUid= */anyInt(), /* opPackageName= */ isNull(), eq(details));

        // Verify that waking up the power group only updates the last wake time
        details = "PowerGroup1 Gesture";
        mPowerGroup.setWakefulnessLocked(WAKEFULNESS_AWAKE, TIMESTAMP2, UID,
                WAKE_REASON_GESTURE, /* opUid= */ 0, /* opPackageName= */ null, details);
        assertThat(mPowerGroup.getLastWakeTimeLocked()).isEqualTo(TIMESTAMP2);
        assertThat(mPowerGroup.getLastSleepTimeLocked()).isEqualTo(TIMESTAMP1);
        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
        verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID),
                eq(WAKEFULNESS_AWAKE), eq(TIMESTAMP2), eq(WAKE_REASON_GESTURE),
                eq(UID), /* opUid= */ anyInt(), /* opPackageName= */ isNull(), eq(details));

        // Verify that a transition to WAKEFULNESS_ASLEEP from an interactive state updates the last
        // sleep time
        mPowerGroup.setWakefulnessLocked(WAKEFULNESS_ASLEEP, TIMESTAMP3, UID,
                GO_TO_SLEEP_REASON_DEVICE_ADMIN, /* opUid= */ 0, /* opPackageName= */ null,
                details);
        assertThat(mPowerGroup.getLastSleepTimeLocked()).isEqualTo(TIMESTAMP3);
        assertThat(mPowerGroup.getLastWakeTimeLocked()).isEqualTo(TIMESTAMP2);
        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
        verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID),
                eq(WAKEFULNESS_ASLEEP), eq(TIMESTAMP3), eq(GO_TO_SLEEP_REASON_DEVICE_ADMIN),
                eq(UID), /* opUid= */anyInt(), /* opPackageName= */ isNull(), eq(details));
    }
}
+113 −51

File changed.

Preview size limit exceeded, changes collapsed.