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

Commit c4bd42c1 authored by Jeff Brown's avatar Jeff Brown
Browse files

Fix reporting of wakelocks to battery stats.

Fixed certain wake lock types which were being incorrectly reported to
BatteryStats as WAKE_TYPE_FULL due to incomplete decoding of the wake
lock level.

Bug: 21949905
Change-Id: Ie3abfc9f473ce721ad042d228175592c7b8ede33
parent 6a8bd7bc
Loading
Loading
Loading
Loading
+65 −33
Original line number Diff line number Diff line
@@ -95,6 +95,9 @@ final class Notifier {
    private final Intent mScreenOffIntent;
    private final Intent mScreenBrightnessBoostIntent;

    // True if the device should suspend when the screen is off due to proximity.
    private final boolean mSuspendWhenScreenOffDueToProximityConfig;

    // The current interactive state.  This is set as soon as an interactive state
    // transition begins so as to capture the reason that it happened.  At some point
    // this state will propagate to the pending state then eventually to the
@@ -143,6 +146,9 @@ final class Notifier {
        mScreenBrightnessBoostIntent.addFlags(
                Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);

        mSuspendWhenScreenOffDueToProximityConfig = context.getResources().getBoolean(
                com.android.internal.R.bool.config_suspendWhenScreenOffDueToProximity);

        // Initialize interactive state for battery stats.
        try {
            mBatteryStats.noteInteractive(true);
@@ -161,13 +167,14 @@ final class Notifier {
                    + ", workSource=" + workSource);
        }

        try {
        final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
            boolean unimportantForLogging = (flags&PowerManager.UNIMPORTANT_FOR_LOGGING) != 0
                    && ownerUid == Process.SYSTEM_UID;
        if (monitorType >= 0) {
            try {
                final boolean unimportantForLogging = ownerUid == Process.SYSTEM_UID
                        && (flags & PowerManager.UNIMPORTANT_FOR_LOGGING) != 0;
                if (workSource != null) {
                mBatteryStats.noteStartWakelockFromSource(workSource, ownerPid, tag, historyTag,
                        monitorType, unimportantForLogging);
                    mBatteryStats.noteStartWakelockFromSource(workSource, ownerPid, tag,
                            historyTag, monitorType, unimportantForLogging);
                } else {
                    mBatteryStats.noteStartWakelock(ownerUid, ownerPid, tag, historyTag,
                            monitorType, unimportantForLogging);
@@ -179,6 +186,7 @@ final class Notifier {
                // Ignore
            }
        }
    }

    /**
     * Called when a wake lock is changing.
@@ -188,17 +196,19 @@ final class Notifier {
            int newFlags, String newTag, String newPackageName, int newOwnerUid,
            int newOwnerPid, WorkSource newWorkSource, String newHistoryTag) {

        if (workSource != null && newWorkSource != null) {
        final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
        final int newMonitorType = getBatteryStatsWakeLockMonitorType(newFlags);
            boolean unimportantForLogging = (newFlags&PowerManager.UNIMPORTANT_FOR_LOGGING) != 0
                    && newOwnerUid == Process.SYSTEM_UID;
        if (workSource != null && newWorkSource != null
                && monitorType >= 0 && newMonitorType >= 0) {
            if (DEBUG) {
                Slog.d(TAG, "onWakeLockChanging: flags=" + newFlags + ", tag=\"" + newTag
                        + "\", packageName=" + newPackageName
                        + ", ownerUid=" + newOwnerUid + ", ownerPid=" + newOwnerPid
                        + ", workSource=" + newWorkSource);
            }

            final boolean unimportantForLogging = newOwnerUid == Process.SYSTEM_UID
                    && (newFlags & PowerManager.UNIMPORTANT_FOR_LOGGING) != 0;
            try {
                mBatteryStats.noteChangeWakelockFromSource(workSource, ownerPid, tag, historyTag,
                        monitorType, newWorkSource, newOwnerPid, newTag, newHistoryTag,
@@ -225,13 +235,15 @@ final class Notifier {
                    + ", workSource=" + workSource);
        }

        try {
        final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
        if (monitorType >= 0) {
            try {
                if (workSource != null) {
                mBatteryStats.noteStopWakelockFromSource(workSource, ownerPid, tag, historyTag,
                        monitorType);
                    mBatteryStats.noteStopWakelockFromSource(workSource, ownerPid, tag,
                            historyTag, monitorType);
                } else {
                mBatteryStats.noteStopWakelock(ownerUid, ownerPid, tag, historyTag, monitorType);
                    mBatteryStats.noteStopWakelock(ownerUid, ownerPid, tag,
                            historyTag, monitorType);
                    mAppOps.finishOperation(AppOpsManager.getToken(mAppOps),
                            AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
                }
@@ -239,14 +251,34 @@ final class Notifier {
                // Ignore
            }
        }
    }

    private static int getBatteryStatsWakeLockMonitorType(int flags) {
    private int getBatteryStatsWakeLockMonitorType(int flags) {
        switch (flags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
            case PowerManager.PARTIAL_WAKE_LOCK:
                return BatteryStats.WAKE_TYPE_PARTIAL;

            case PowerManager.SCREEN_DIM_WAKE_LOCK:
            case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
                return BatteryStats.WAKE_TYPE_FULL;

            case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
                if (mSuspendWhenScreenOffDueToProximityConfig) {
                    return -1;
                }
                return BatteryStats.WAKE_TYPE_PARTIAL;

            case PowerManager.DRAW_WAKE_LOCK:
                return BatteryStats.WAKE_TYPE_DRAW;

            case PowerManager.DOZE_WAKE_LOCK:
                // Doze wake locks are an internal implementation detail of the
                // communication between dream manager service and power manager
                // service.  They have no additive battery impact.
                return -1;

            default:
                return BatteryStats.WAKE_TYPE_FULL;
                return -1;
        }
    }

+1 −0
Original line number Diff line number Diff line
@@ -970,6 +970,7 @@ public final class PowerManagerService extends SystemService
                case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
                case PowerManager.FULL_WAKE_LOCK:
                case PowerManager.DOZE_WAKE_LOCK:
                case PowerManager.DRAW_WAKE_LOCK:
                    return true;

                case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK: