1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16package com.android.internal.os; 17 18import android.os.BatteryStats; 19import android.os.Parcel; 20import android.support.test.filters.SmallTest; 21 22import junit.framework.TestCase; 23 24import org.mockito.Mockito; 25 26public class BatteryStatsSamplingTimerTest extends TestCase { 27 28 @SmallTest 29 public void testSettingStalePreservesData() throws Exception { 30 final MockClocks clocks = new MockClocks(); 31 final BatteryStatsImpl.SamplingTimer timer = new BatteryStatsImpl.SamplingTimer(clocks, 32 Mockito.mock(BatteryStatsImpl.TimeBase.class)); 33 34 timer.onTimeStarted(100, 100, 100); 35 36 // First update is absorbed. 37 timer.update(10, 1); 38 39 timer.update(20, 2); 40 41 assertEquals(1, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); 42 assertEquals(10, timer.getTotalTimeLocked(200, BatteryStats.STATS_SINCE_CHARGED)); 43 44 timer.endSample(); 45 46 assertEquals(1, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); 47 assertEquals(10, timer.getTotalTimeLocked(200, BatteryStats.STATS_SINCE_CHARGED)); 48 49 timer.onTimeStopped(200, 200, 200); 50 51 assertEquals(1, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); 52 assertEquals(10, timer.getTotalTimeLocked(200, BatteryStats.STATS_SINCE_CHARGED)); 53 } 54 55 @SmallTest 56 public void testEndSampleAndContinueWhenTimeOrCountDecreases() throws Exception { 57 final MockClocks clocks = new MockClocks(); 58 final BatteryStatsImpl.TimeBase timeBase = Mockito.mock(BatteryStatsImpl.TimeBase.class); 59 final BatteryStatsImpl.SamplingTimer timer = new BatteryStatsImpl.SamplingTimer(clocks, 60 timeBase); 61 62 // First once is absorbed. 63 timer.update(10, 1); 64 65 timer.add(10, 1); 66 67 assertEquals(0, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); 68 assertEquals(0, timer.getTotalTimeLocked(200, BatteryStats.STATS_SINCE_CHARGED)); 69 70 // This is less than we currently have, so we will end the sample. Time isn't running, so 71 // nothing should happen. 72 timer.update(0, 0); 73 74 assertEquals(0, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); 75 assertEquals(0, timer.getTotalTimeLocked(200, BatteryStats.STATS_SINCE_CHARGED)); 76 77 timer.onTimeStarted(100, 100, 100); 78 79 // This should add. 80 timer.add(100, 10); 81 82 assertEquals(100, timer.getTotalTimeLocked(200, BatteryStats.STATS_SINCE_CHARGED)); 83 assertEquals(10, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); 84 85 // This is less than we currently have, so we should end our sample and continue with the 86 // entire amount updated here. 87 timer.update(50, 5); 88 89 assertEquals(150, timer.getTotalTimeLocked(200, BatteryStats.STATS_SINCE_CHARGED)); 90 assertEquals(15, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); 91 92 timer.onTimeStopped(200, 200, 200); 93 94 assertEquals(150, timer.getTotalTimeLocked(200, BatteryStats.STATS_SINCE_CHARGED)); 95 assertEquals(15, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); 96 } 97 98 @SmallTest 99 public void testFirstUpdateIsAbsorbed() throws Exception { 100 final MockClocks clocks = new MockClocks(); 101 final BatteryStatsImpl.TimeBase timeBase = Mockito.mock(BatteryStatsImpl.TimeBase.class); 102 103 BatteryStatsImpl.SamplingTimer timer = new BatteryStatsImpl.SamplingTimer(clocks, timeBase); 104 105 // This should be absorbed because it is our first update and we don't know what 106 // was being counted before. 107 timer.update(10, 1); 108 109 assertEquals(0, timer.getTotalTimeLocked(10, BatteryStats.STATS_SINCE_CHARGED)); 110 assertEquals(0, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); 111 112 timer = new BatteryStatsImpl.SamplingTimer(clocks, timeBase); 113 timer.onTimeStarted(100, 100, 100); 114 115 // This should be absorbed. 116 timer.update(10, 1); 117 118 assertEquals(0, timer.getTotalTimeLocked(100, BatteryStats.STATS_SINCE_CHARGED)); 119 assertEquals(0, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); 120 121 // This should NOT be aborbed, since we've already done that. 122 timer.add(10, 1); 123 124 assertEquals(10, timer.getTotalTimeLocked(100, BatteryStats.STATS_SINCE_CHARGED)); 125 assertEquals(1, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); 126 127 timer.onTimeStopped(200, 200, 200); 128 timer.onTimeStarted(300, 300, 300); 129 130 // This should NOT be absorbed. 131 timer.add(10, 1); 132 133 assertEquals(20, timer.getTotalTimeLocked(300, BatteryStats.STATS_SINCE_CHARGED)); 134 assertEquals(2, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); 135 } 136 137 @SmallTest 138 public void testSampleTimerSummaryParceling() throws Exception { 139 final MockClocks clocks = new MockClocks(); 140 clocks.realtime = 0; 141 clocks.uptime = 0; 142 143 final BatteryStatsImpl.TimeBase timeBase = new BatteryStatsImpl.TimeBase(); 144 timeBase.init(clocks.uptimeMillis(), clocks.elapsedRealtime()); 145 146 BatteryStatsImpl.SamplingTimer timer = new BatteryStatsImpl.SamplingTimer(clocks, timeBase); 147 148 // Start running on battery. 149 // (Note that the wrong units are used in this class. setRunning is actually supposed to 150 // take us, not the ms that clocks uses.) 151 timeBase.setRunning(true, clocks.uptimeMillis(), clocks.elapsedRealtime()); 152 153 // The first update on battery consumes the values as a way of starting cleanly. 154 timer.add(10, 1); 155 156 timer.add(10, 1); 157 158 clocks.realtime = 20; 159 clocks.uptime = 20; 160 161 assertEquals(10, timer.getTotalTimeLocked(clocks.elapsedRealtime(), 162 BatteryStats.STATS_SINCE_CHARGED)); 163 assertEquals(1, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); 164 165 // Grab a summary parcel while on battery. 166 final Parcel onBatterySummaryParcel = Parcel.obtain(); 167 timer.writeSummaryFromParcelLocked(onBatterySummaryParcel, clocks.elapsedRealtime() * 1000); 168 onBatterySummaryParcel.setDataPosition(0); 169 170 // Stop running on battery. 171 timeBase.setRunning(false, clocks.uptimeMillis(), clocks.elapsedRealtime()); 172 173 assertEquals(10, timer.getTotalTimeLocked(clocks.elapsedRealtime(), 174 BatteryStats.STATS_SINCE_CHARGED)); 175 assertEquals(1, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); 176 177 // Grab a summary parcel while not on battery. 178 final Parcel offBatterySummaryParcel = Parcel.obtain(); 179 timer.writeSummaryFromParcelLocked(offBatterySummaryParcel, 180 clocks.elapsedRealtime() * 1000); 181 offBatterySummaryParcel.setDataPosition(0); 182 183 // Set the timebase running again. That way any issues with tracking reported values 184 // get tested when we unparcel the timers below. 185 timeBase.setRunning(true, clocks.uptimeMillis(), clocks.elapsedRealtime()); 186 187 // Read the on battery summary from the parcel. 188 BatteryStatsImpl.SamplingTimer unparceledOnBatteryTimer = 189 new BatteryStatsImpl.SamplingTimer(clocks, timeBase); 190 unparceledOnBatteryTimer.readSummaryFromParcelLocked(onBatterySummaryParcel); 191 192 assertEquals(10, unparceledOnBatteryTimer.getTotalTimeLocked(0, 193 BatteryStats.STATS_SINCE_CHARGED)); 194 assertEquals(1, unparceledOnBatteryTimer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); 195 196 // Read the off battery summary from the parcel. 197 BatteryStatsImpl.SamplingTimer unparceledOffBatteryTimer = 198 new BatteryStatsImpl.SamplingTimer(clocks, timeBase); 199 unparceledOffBatteryTimer.readSummaryFromParcelLocked(offBatterySummaryParcel); 200 201 assertEquals(10, unparceledOffBatteryTimer.getTotalTimeLocked(0, 202 BatteryStats.STATS_SINCE_CHARGED)); 203 assertEquals(1, unparceledOffBatteryTimer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); 204 205 // Now, just like with a fresh timer, the first update should be absorbed to account for 206 // data being collected when we weren't recording. 207 unparceledOnBatteryTimer.update(10, 10); 208 209 assertEquals(10, unparceledOnBatteryTimer.getTotalTimeLocked(0, 210 BatteryStats.STATS_SINCE_CHARGED)); 211 assertEquals(1, unparceledOnBatteryTimer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); 212 213 unparceledOffBatteryTimer.update(10, 10); 214 215 assertEquals(10, unparceledOffBatteryTimer.getTotalTimeLocked(0, 216 BatteryStats.STATS_SINCE_CHARGED)); 217 assertEquals(1, unparceledOffBatteryTimer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); 218 } 219} 220