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

Commit de73c05b authored by Michael Wachenschwanz's avatar Michael Wachenschwanz
Browse files

Skip collecting radio data on procstate change when radio is off.

Fixes: 229042376
Test: atest BatteryStatsNoteTest
Change-Id: I6b3c5a5c9416bc47b8dbb00e28c81d93e3507613
parent 965e705c
Loading
Loading
Loading
Loading
+14 −5
Original line number Diff line number Diff line
@@ -644,7 +644,7 @@ public class BatteryStatsImpl extends BatteryStats {
        /** Schedule removal of UIDs corresponding to a removed user */
        Future<?> scheduleCleanupDueToRemovedUser(int userId);
        /** Schedule a sync because of a process state change */
        Future<?> scheduleSyncDueToProcessStateChange(long delayMillis);
        void scheduleSyncDueToProcessStateChange(int flags, long delayMillis);
    }
    public Handler mHandler;
@@ -6216,9 +6216,7 @@ public class BatteryStatsImpl extends BatteryStats {
            long elapsedRealtimeMs, long uptimeMs) {
        if (mMobileRadioPowerState != powerState) {
            long realElapsedRealtimeMs;
            final boolean active =
                    powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM
                            || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH;
            final boolean active = isActiveRadioPowerState(powerState);
            if (active) {
                if (uid > 0) {
                    noteMobileRadioApWakeupLocked(elapsedRealtimeMs, uptimeMs, uid);
@@ -6260,6 +6258,11 @@ public class BatteryStatsImpl extends BatteryStats {
        return false;
    }
    private static boolean isActiveRadioPowerState(int powerState) {
        return powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM
                || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH;
    }
    @GuardedBy("this")
    public void notePowerSaveModeLocked(boolean enabled) {
        notePowerSaveModeLocked(enabled, mClock.elapsedRealtime(), mClock.uptimeMillis());
@@ -12044,7 +12047,13 @@ public class BatteryStatsImpl extends BatteryStats {
                return;
            }
            mBsi.mExternalSync.scheduleSyncDueToProcessStateChange(
            int flags = ExternalStatsSync.UPDATE_ON_PROC_STATE_CHANGE;
            // Skip querying for inactive radio, where power usage is probably negligible.
            if (!BatteryStatsImpl.isActiveRadioPowerState(mBsi.mMobileRadioPowerState)) {
                flags &= ~ExternalStatsSync.UPDATE_RADIO;
            }
            mBsi.mExternalSync.scheduleSyncDueToProcessStateChange(flags,
                    mBsi.mConstants.PROC_STATE_CHANGE_COLLECTION_DELAY_MS);
        }
+49 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ import android.telephony.DataConnectionRealTimeInfo;
import android.telephony.ModemActivityInfo;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.util.MutableInt;
import android.util.SparseIntArray;
import android.util.SparseLongArray;
import android.view.Display;
@@ -1982,6 +1983,54 @@ public class BatteryStatsNoteTest extends TestCase {
                expectedTxDurationsMs, bi, state.currentTimeMs);
    }

    @SmallTest
    @SuppressWarnings("GuardedBy")
    public void testProcStateSyncScheduling_mobileRadioActiveState() {
        final MockClock clock = new MockClock(); // holds realtime and uptime in ms
        final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clock);
        final MutableInt lastProcStateChangeFlags = new MutableInt(0);

        MockBatteryStatsImpl.DummyExternalStatsSync externalStatsSync =
                new MockBatteryStatsImpl.DummyExternalStatsSync() {
                    @Override
                    public void scheduleSyncDueToProcessStateChange(int flags,
                            long delayMillis) {
                        lastProcStateChangeFlags.value = flags;
                    }
                };

        bi.setDummyExternalStatsSync(externalStatsSync);

        bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0);

        // Note mobile radio is on.
        long curr = 1000L * (clock.realtime = clock.uptime = 1001);
        bi.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH, curr,
                UID);

        lastProcStateChangeFlags.value = 0;
        clock.realtime = clock.uptime = 2002;
        bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND);

        final int allProcFlags = BatteryStatsImpl.ExternalStatsSync.UPDATE_ON_PROC_STATE_CHANGE;
        assertEquals(allProcFlags, lastProcStateChangeFlags.value);

        // Note mobile radio is off.
        curr = 1000L * (clock.realtime = clock.uptime = 3003);
        bi.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_LOW, curr,
                UID);

        lastProcStateChangeFlags.value = 0;
        clock.realtime = clock.uptime = 4004;
        bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_CACHED_EMPTY);

        final int noRadioProcFlags = BatteryStatsImpl.ExternalStatsSync.UPDATE_ON_PROC_STATE_CHANGE
                & ~BatteryStatsImpl.ExternalStatsSync.UPDATE_RADIO;
        assertEquals(
                "An inactive radio should not be queried on proc state change",
                noRadioProcFlags, lastProcStateChangeFlags.value);
    }

    private void setFgState(int uid, boolean fgOn, MockBatteryStatsImpl bi) {
        // Note that noteUidProcessStateLocked uses ActivityManager process states.
        if (fgOn) {
+7 −3
Original line number Diff line number Diff line
@@ -212,7 +212,12 @@ public class MockBatteryStatsImpl extends BatteryStatsImpl {
        return flags;
    }

    private class DummyExternalStatsSync implements ExternalStatsSync {
    public void setDummyExternalStatsSync(DummyExternalStatsSync externalStatsSync) {
        mExternalStatsSync = externalStatsSync;
        setExternalStatsSyncLocked(mExternalStatsSync);
    }

    public static class DummyExternalStatsSync implements ExternalStatsSync {
        public int flags = 0;

        @Override
@@ -257,8 +262,7 @@ public class MockBatteryStatsImpl extends BatteryStatsImpl {
        }

        @Override
        public Future<?> scheduleSyncDueToProcessStateChange(long delayMillis) {
            return null;
        public void scheduleSyncDueToProcessStateChange(int flags, long delayMillis) {
        }
    }
}
+2 −3
Original line number Diff line number Diff line
@@ -320,12 +320,11 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync {
    }

    @Override
    public Future<?> scheduleSyncDueToProcessStateChange(long delayMillis) {
    public void scheduleSyncDueToProcessStateChange(int flags, long delayMillis) {
        synchronized (BatteryExternalStatsWorker.this) {
            mProcessStateSync = scheduleDelayedSyncLocked(mProcessStateSync,
                    () -> scheduleSync("procstate-change", UPDATE_ON_PROC_STATE_CHANGE),
                    () -> scheduleSync("procstate-change", flags),
                    delayMillis);
            return mProcessStateSync;
        }
    }