1ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz/*
2ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz * Copyright (C) 2017 The Android Open Source Project
3ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz *
4ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz * use this file except in compliance with the License. You may obtain a copy of
6ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz * the License at
7ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz *
8ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz * http://www.apache.org/licenses/LICENSE-2.0
9ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz *
10ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz * Unless required by applicable law or agreed to in writing, software
11ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz * License for the specific language governing permissions and limitations under
14ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz * the License.
15ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz */
16ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatzpackage com.android.internal.os;
17ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz
18ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatzimport android.os.BatteryStats;
19ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatzimport android.support.test.filters.SmallTest;
20ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz
21ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatzimport junit.framework.TestCase;
22ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz
23ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz/**
24ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz * Test BatteryStatsImpl.StopwatchTimer.
25ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz */
26ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatzpublic class BatteryStatsStopwatchTimerTest extends TestCase {
27ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz
28ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz    // Primarily testing previous bug that incremented count when timeBase was off and bug that gave
29ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz    // negative values of count.
30ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz    @SmallTest
31ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz    public void testCount() throws Exception {
32ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms
33ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        final BatteryStatsImpl.TimeBase timeBase = new BatteryStatsImpl.TimeBase();
34ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timeBase.init(clocks.uptimeMillis(), clocks.elapsedRealtime());
35ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        final BatteryStatsImpl.StopwatchTimer timer = new BatteryStatsImpl.StopwatchTimer(clocks,
36ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz                null, BatteryStats.SENSOR, null, timeBase);
37ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        int expectedCount = 0;
38ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz
39ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        // for timeBase off tests
40ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timeBase.setRunning(false, 1000 * clocks.realtime, 1000 * clocks.realtime);
41ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz
42ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        // timeBase off, start, stop
43ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timer.startRunningLocked(updateTime(clocks, 100)); // start
44ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        // Used to fail due to b/36730213 increasing count.
45ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        assertEquals(expectedCount, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
46ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timer.startRunningLocked(updateTime(clocks, 110)); // start
47ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        assertEquals(expectedCount, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
48ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timer.stopRunningLocked(updateTime(clocks, 120)); // stop
49ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        assertEquals(expectedCount, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
50ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timer.stopRunningLocked(updateTime(clocks, 130)); // stop
51ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        assertEquals(expectedCount, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
52ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz
53ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        // timeBase off, start and immediately stop
54ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timer.startRunningLocked(updateTime(clocks, 200)); // start
55ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timer.stopRunningLocked(updateTime(clocks, 200)); // stop
56ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        assertEquals(expectedCount, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
57ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz
58ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        // timeBase off, start, reset, stop
59ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timer.startRunningLocked(updateTime(clocks, 300)); // start
60ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        updateTime(clocks, 310);
61ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timeBase.init(clocks.uptimeMillis(), clocks.elapsedRealtime());
62ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timer.reset(false);
63ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        expectedCount = 0; // count will be reset by reset()
64ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        assertEquals(expectedCount, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
65ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timer.stopRunningLocked(updateTime(clocks, 350)); // stop
66ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        // Used to fail due to b/30099724 giving -1.
67ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        assertEquals(expectedCount, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
68ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz
69ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        // timeBase off, start and immediately reset, stop
70ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timer.startRunningLocked(updateTime(clocks, 400)); // start
71ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timer.reset(false);
72ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        expectedCount = 0; // count will be reset by reset()
73ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        assertEquals(expectedCount, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
74ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timer.stopRunningLocked(updateTime(clocks, 450)); // stop
75ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        // Used to fail due to b/30099724 giving -1.
76ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        assertEquals(expectedCount, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
77ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz
78ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz
79ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        // for timeBase on tests
80ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        updateTime(clocks, 2000);
81ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timeBase.setRunning(true, 1000 * clocks.realtime, 1000 * clocks.realtime);
82ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        assertFalse(timer.isRunningLocked());
83ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz
84ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        // timeBase on, start, stop
85ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timer.startRunningLocked(updateTime(clocks, 2100)); // start
86ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        expectedCount++;
87ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        assertEquals(expectedCount, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
88ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timer.startRunningLocked(updateTime(clocks, 2110)); // start
89ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        assertEquals(expectedCount, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
90ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timer.stopRunningLocked(updateTime(clocks, 2120)); // stop
91ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        assertEquals(expectedCount, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
92ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timer.stopRunningLocked(updateTime(clocks, 2130)); // stop
93ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        assertEquals(expectedCount, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
94ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz
95ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        // timeBase on, start and immediately stop
96ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timer.startRunningLocked(updateTime(clocks, 2200)); // start
97ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timer.stopRunningLocked(updateTime(clocks, 2200)); // stop
98ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        assertEquals(expectedCount, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
99ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz
100ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        // timeBase on, start, reset, stop
101ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timer.startRunningLocked(updateTime(clocks, 2300)); // start
102ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        updateTime(clocks, 2310);
103ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timeBase.init(clocks.uptimeMillis(), clocks.elapsedRealtime());
104ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timer.reset(false);
105ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        expectedCount = 0; // count will be reset by reset()
106ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        assertEquals(expectedCount, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
107ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timer.stopRunningLocked(updateTime(clocks, 2350)); // stop
108ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        assertEquals(expectedCount, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
109ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz
110ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        // timeBase on, start and immediately reset, stop
111ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timer.startRunningLocked(updateTime(clocks, 2400)); // start
112ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timer.reset(false);
113ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        expectedCount = 0; // count will be reset by reset()
114ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        assertEquals(expectedCount, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
115ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timer.stopRunningLocked(updateTime(clocks, 2450)); // stop
116ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        assertEquals(expectedCount, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
117ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz
118ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz
119ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        // change timeBase tests
120ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        // timeBase off, start
121ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        updateTime(clocks, 3000);
122ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timeBase.setRunning(false, 1000 * clocks.realtime, 1000 * clocks.realtime);
123ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timer.startRunningLocked(updateTime(clocks, 3100)); // start
124ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        // Used to fail due to b/36730213 increasing count.
125ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        assertEquals(expectedCount, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
126ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        // timeBase on, stop
127ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        updateTime(clocks, 3200);
128ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timeBase.setRunning(true, 1000 * clocks.realtime, 1000 * clocks.realtime);
129ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timer.stopRunningLocked(updateTime(clocks, 3300)); // stop
130ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        assertEquals(expectedCount, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
131ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz
132ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        // timeBase on, start
133ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timer.startRunningLocked(updateTime(clocks, 3400)); // start
134ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        expectedCount++;
135ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        assertEquals(expectedCount, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
136ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        // timeBase off, stop
137ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        updateTime(clocks, 3500);
138ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timeBase.setRunning(false, 1000 * clocks.realtime, 1000 * clocks.realtime);
139ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        timer.stopRunningLocked(updateTime(clocks, 3600)); // stop
140ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        assertEquals(expectedCount, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
141ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz    }
142ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz
143ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz    private static long updateTime(MockClocks clocks, long time) {
144ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz        return clocks.realtime = clocks.uptime = time;
145ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz    }
146ceebafe41a127c18213ca39ddf692ae1cbfb100eBookatz}
147