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

Commit d6ee2304 authored by Lucas Silva's avatar Lucas Silva Committed by Automerger Merge Worker
Browse files

Merge "Update dream battery drain monitoring to exclude when charging is being...

Merge "Update dream battery drain monitoring to exclude when charging is being artificially limited." into tm-qpr-dev am: e223e2bd

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20476147



Change-Id: Ie1f2f2936122639d00f8af7529c95a770590a9dd
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 46b091cf e223e2bd
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -46,6 +46,14 @@ public abstract class BatteryManagerInternal {
     */
    public abstract int getBatteryLevel();

    /**
     * Returns battery health status as an integer representing the current battery health constant.
     *
     * This is a simple accessor that's safe to be called from any locks, but internally it may
     * wait on the battery service lock.
     */
    public abstract int getBatteryHealth();

    /**
     * Instantaneous battery capacity in uA-h, as defined in the HealthInfo HAL struct.
     * Please note apparently it could be bigger than {@link #getBatteryFullCharge}.
+2 −0
Original line number Diff line number Diff line
@@ -189,6 +189,8 @@ message PowerManagerServiceDumpProto {
    optional bool is_enhanced_discharge_prediction_personalized = 54;
    optional bool is_low_power_standby_active = 55;
    optional LowPowerStandbyControllerDumpProto low_power_standby_controller = 56;
    // The battery level drained by the dream.
    optional int32 battery_level_drained_while_dreaming = 57;
}

// A com.android.server.power.PowerManagerService.SuspendBlockerImpl object.
+7 −0
Original line number Diff line number Diff line
@@ -1286,6 +1286,13 @@ public final class BatteryService extends SystemService {
            }
        }

        @Override
        public int getBatteryHealth() {
            synchronized (mLock) {
                return mHealthInfo.batteryHealth;
            }
        }

        @Override
        public boolean getBatteryLevelLow() {
            synchronized (mLock) {
+26 −14
Original line number Diff line number Diff line
@@ -419,6 +419,9 @@ public final class PowerManagerService extends SystemService
    // The current battery level percentage.
    private int mBatteryLevel;

    // The amount of battery drained while the device has been in a dream state.
    private int mDreamsBatteryLevelDrain;

    // True if updatePowerStateLocked() is already in progress.
    // TODO(b/215518989): Remove this once transactions are in place
    private boolean mUpdatePowerStateInProgress;
@@ -451,11 +454,6 @@ public final class PowerManagerService extends SystemService
    @GuardedBy("mEnhancedDischargeTimeLock")
    private boolean mEnhancedDischargePredictionIsPersonalized;

    // The battery level percentage at the time the dream started.
    // This is used to terminate a dream and go to sleep if the battery is
    // draining faster than it is charging and the user activity timeout has expired.
    private int mBatteryLevelWhenDreamStarted;

    // The current dock state.
    private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;

@@ -2462,15 +2460,25 @@ public final class PowerManagerService extends SystemService
            final int oldPlugType = mPlugType;
            mIsPowered = mBatteryManagerInternal.isPowered(BatteryManager.BATTERY_PLUGGED_ANY);
            mPlugType = mBatteryManagerInternal.getPlugType();
            final int oldBatteryLevel = mBatteryLevel;
            mBatteryLevel = mBatteryManagerInternal.getBatteryLevel();
            mBatteryLevelLow = mBatteryManagerInternal.getBatteryLevelLow();
            final boolean isOverheat = mBatteryManagerInternal.getBatteryHealth()
                    == BatteryManager.BATTERY_HEALTH_OVERHEAT;

            if (DEBUG_SPEW) {
                Slog.d(TAG, "updateIsPoweredLocked: wasPowered=" + wasPowered
                        + ", mIsPowered=" + mIsPowered
                        + ", oldPlugType=" + oldPlugType
                        + ", mPlugType=" + mPlugType
                        + ", mBatteryLevel=" + mBatteryLevel);
                        + ", oldBatteryLevel=" + oldBatteryLevel
                        + ", mBatteryLevel=" + mBatteryLevel
                        + ", isOverheat=" + isOverheat);
            }

            if (!isOverheat && oldBatteryLevel > 0
                    && getGlobalWakefulnessLocked() == WAKEFULNESS_DREAMING) {
                mDreamsBatteryLevelDrain += (oldBatteryLevel - mBatteryLevel);
            }

            if (wasPowered != mIsPowered || oldPlugType != mPlugType) {
@@ -3292,7 +3300,7 @@ public final class PowerManagerService extends SystemService

            // Remember the initial battery level when the dream started.
            if (startDreaming && isDreaming) {
                mBatteryLevelWhenDreamStarted = mBatteryLevel;
                mDreamsBatteryLevelDrain = 0;
                if (wakefulness == WAKEFULNESS_DOZING) {
                    Slog.i(TAG, "Dozing...");
                } else {
@@ -3313,16 +3321,15 @@ public final class PowerManagerService extends SystemService
            if (wakefulness == WAKEFULNESS_DREAMING) {
                if (isDreaming && canDreamLocked(powerGroup)) {
                    if (mDreamsBatteryLevelDrainCutoffConfig >= 0
                            && mBatteryLevel < mBatteryLevelWhenDreamStarted
                                    - mDreamsBatteryLevelDrainCutoffConfig
                            && mDreamsBatteryLevelDrain > mDreamsBatteryLevelDrainCutoffConfig
                            && !isBeingKeptAwakeLocked(powerGroup)) {
                        // If the user activity timeout expired and the battery appears
                        // to be draining faster than it is charging then stop dreaming
                        // and go to sleep.
                        Slog.i(TAG, "Stopping dream because the battery appears to "
                                + "be draining faster than it is charging.  "
                                + "Battery level when dream started: "
                                + mBatteryLevelWhenDreamStarted + "%.  "
                                + "Battery level drained while dreaming: "
                                + mDreamsBatteryLevelDrain + "%.  "
                                + "Battery level now: " + mBatteryLevel + "%.");
                    } else {
                        return; // continue dreaming
@@ -3553,6 +3560,11 @@ public final class PowerManagerService extends SystemService
                mScreenBrightnessBoostInProgress);
    }

    @VisibleForTesting
    int getDreamsBatteryLevelDrain() {
        return mDreamsBatteryLevelDrain;
    }

    private final DisplayManagerInternal.DisplayPowerCallbacks mDisplayPowerCallbacks =
            new DisplayManagerInternal.DisplayPowerCallbacks() {

@@ -4397,7 +4409,7 @@ public final class PowerManagerService extends SystemService
            pw.println("  mIsPowered=" + mIsPowered);
            pw.println("  mPlugType=" + mPlugType);
            pw.println("  mBatteryLevel=" + mBatteryLevel);
            pw.println("  mBatteryLevelWhenDreamStarted=" + mBatteryLevelWhenDreamStarted);
            pw.println("  mDreamsBatteryLevelDrain=" + mDreamsBatteryLevelDrain);
            pw.println("  mDockState=" + mDockState);
            pw.println("  mStayOn=" + mStayOn);
            pw.println("  mProximityPositive=" + mProximityPositive);
@@ -4638,8 +4650,8 @@ public final class PowerManagerService extends SystemService
            proto.write(PowerManagerServiceDumpProto.PLUG_TYPE, mPlugType);
            proto.write(PowerManagerServiceDumpProto.BATTERY_LEVEL, mBatteryLevel);
            proto.write(
                    PowerManagerServiceDumpProto.BATTERY_LEVEL_WHEN_DREAM_STARTED,
                    mBatteryLevelWhenDreamStarted);
                    PowerManagerServiceDumpProto.BATTERY_LEVEL_DRAINED_WHILE_DREAMING,
                    mDreamsBatteryLevelDrain);
            proto.write(PowerManagerServiceDumpProto.DOCK_STATE, mDockState);
            proto.write(PowerManagerServiceDumpProto.IS_STAY_ON, mStayOn);
            proto.write(PowerManagerServiceDumpProto.IS_PROXIMITY_POSITIVE, mProximityPositive);
+53 −0
Original line number Diff line number Diff line
@@ -375,6 +375,18 @@ public class PowerManagerServiceTest {
        mBatteryReceiver.onReceive(mContextSpy, new Intent(Intent.ACTION_BATTERY_CHANGED));
    }

    private void setBatteryLevel(int batteryLevel) {
        when(mBatteryManagerInternalMock.getBatteryLevel())
                .thenReturn(batteryLevel);
        mBatteryReceiver.onReceive(mContextSpy, new Intent(Intent.ACTION_BATTERY_CHANGED));
    }

    private void setBatteryHealth(int batteryHealth) {
        when(mBatteryManagerInternalMock.getBatteryHealth())
                .thenReturn(batteryHealth);
        mBatteryReceiver.onReceive(mContextSpy, new Intent(Intent.ACTION_BATTERY_CHANGED));
    }

    private void setAttentiveTimeout(int attentiveTimeoutMillis) {
        Settings.Secure.putInt(
                mContextSpy.getContentResolver(), Settings.Secure.ATTENTIVE_TIMEOUT,
@@ -399,6 +411,12 @@ public class PowerManagerServiceTest {
                .thenReturn(disable);
    }

    private void setDreamsBatteryLevelDrainConfig(int threshold) {
        when(mResourcesSpy.getInteger(
                com.android.internal.R.integer.config_dreamsBatteryLevelDrainCutoff)).thenReturn(
                threshold);
    }

    private void advanceTime(long timeMs) {
        mClock.fastForward(timeMs);
        mTestLooper.dispatchAll();
@@ -937,6 +955,41 @@ public class PowerManagerServiceTest {
        assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING);
    }

    @Test
    public void testBatteryDrainDuringDream() {
        Settings.Secure.putInt(mContextSpy.getContentResolver(),
                Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, 1);
        Settings.Secure.putInt(mContextSpy.getContentResolver(),
                Settings.Secure.SCREENSAVER_ENABLED, 1);

        setMinimumScreenOffTimeoutConfig(100);
        setDreamsBatteryLevelDrainConfig(5);
        createService();
        startSystem();

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

        setBatteryLevel(100);
        setPluggedIn(true);

        forceAwake();  // Needs to be awake first before it can dream.
        forceDream();
        advanceTime(10); // Allow async calls to happen
        assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING);
        setBatteryLevel(90);
        advanceTime(10); // Allow async calls to happen
        assertThat(mService.getDreamsBatteryLevelDrain()).isEqualTo(10);

        // If battery overheat protection is enabled, we shouldn't count battery drain
        setBatteryHealth(BatteryManager.BATTERY_HEALTH_OVERHEAT);
        setBatteryLevel(70);
        advanceTime(10); // Allow async calls to happen
        assertThat(mService.getDreamsBatteryLevelDrain()).isEqualTo(10);
    }

    @Test
    public void testSetDozeOverrideFromDreamManager_triggersSuspendBlocker() {
        final String suspendBlockerName = "PowerManagerService.Display";