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

Commit 5f212c86 authored by Adam Lesinski's avatar Adam Lesinski
Browse files

BatteryStats: Prevent double-detaching Counter

Detaching a Counter from a TimeBase means you can't use it anymore.
Only newly constructed Counters are automatically attached to a TimeBase.

Bug: 34200689
Test: make FrameworkCoreTests && adb install ... && adb shell am instrument -w -e class com.android.internal.os.BatteryStatsSensorTest com.android.frameworks.coretests
Change-Id: I9309000d5625aa6fe61a3c05f135e5828137d8ce
parent 208e2644
Loading
Loading
Loading
Loading
+6 −2
Original line number Original line Diff line number Diff line
@@ -6027,7 +6027,8 @@ public class BatteryStatsImpl extends BatteryStats {
         * Clear all stats for this uid.  Returns true if the uid is completely
         * Clear all stats for this uid.  Returns true if the uid is completely
         * inactive so can be dropped.
         * inactive so can be dropped.
         */
         */
        boolean reset() {
        @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
        public boolean reset() {
            boolean active = false;
            boolean active = false;


            if (mWifiRunningTimer != null) {
            if (mWifiRunningTimer != null) {
@@ -6968,7 +6969,10 @@ public class BatteryStatsImpl extends BatteryStats {


            boolean reset() {
            boolean reset() {
                if (mBgCounter != null) {
                if (mBgCounter != null) {
                    mBgCounter.reset(true);
                    mBgCounter.reset(true /*detachIfReset*/);
                    // If we detach, we must null the mBgCounter reference so that it
                    // can be recreated and attached.
                    mBgCounter = null;
                }
                }
                if (mTimer.reset(true)) {
                if (mTimer.reset(true)) {
                    mTimer = null;
                    mTimer = null;
+45 −0
Original line number Original line Diff line number Diff line
@@ -65,4 +65,49 @@ public class BatteryStatsSensorTest extends TestCase {


        assertEquals(1, sensorBgCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
        assertEquals(1, sensorBgCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
    }
    }

    @SmallTest
    public void testNestedSensorReset() throws Exception {
        final MockClocks clocks = new MockClocks();
        MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
        bi.mForceOnBattery = true;
        clocks.realtime = 100;
        clocks.uptime = 100;
        bi.getOnBatteryTimeBase().setRunning(true, 100, 100);
        bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_RECEIVER);

        clocks.realtime += 100;
        clocks.uptime += 100;

        bi.noteStartSensorLocked(UID, SENSOR_ID);

        clocks.realtime += 100;
        clocks.uptime += 100;

        // The sensor is started and the background counter has been created.
        final BatteryStats.Uid uid = bi.getUidStats().get(UID);
        assertNotNull(uid);

        BatteryStats.Uid.Sensor sensor = uid.getSensorStats().get(SENSOR_ID);
        assertNotNull(sensor);
        assertNotNull(sensor.getSensorTime());
        assertNotNull(sensor.getSensorBgCount());

        // Reset the stats. Since the sensor is still running, we should still see the sensor
        // timer. Background counter should be gone though.
        bi.getUidStatsLocked(UID).reset();

        sensor = uid.getSensorStats().get(SENSOR_ID);
        assertNotNull(sensor);
        assertNotNull(sensor.getSensorTime());
        assertNull(sensor.getSensorBgCount());

        bi.noteStopSensorLocked(UID, SENSOR_ID);

        // Now the sensor timer has stopped so this reset should also take out the sensor.
        bi.getUidStatsLocked(UID).reset();

        sensor = uid.getSensorStats().get(SENSOR_ID);
        assertNull(sensor);
    }
}
}