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 */ 16 package com.android.internal.os; 17 18 import android.app.ActivityManager; 19 import android.os.BatteryStats; 20 import android.support.test.filters.SmallTest; 21 22 import junit.framework.TestCase; 23 24 /** 25 * Test BatteryStatsImpl Sensor Timers. 26 */ 27 public class BatteryStatsSensorTest extends TestCase { 28 29 private static final int UID = 10500; 30 private static final int SENSOR_ID = -10000; 31 32 @SmallTest 33 public void testSensorStartStop() throws Exception { 34 final MockClocks clocks = new MockClocks(); 35 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 36 bi.mForceOnBattery = true; 37 clocks.realtime = 100; 38 clocks.uptime = 100; 39 bi.getOnBatteryTimeBase().setRunning(true, 100_000, 100_000); 40 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_CACHED_EMPTY); 41 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND); 42 bi.noteStartSensorLocked(UID, SENSOR_ID); 43 clocks.realtime = 200; 44 clocks.uptime = 200; 45 bi.noteStopSensorLocked(UID, SENSOR_ID); 46 47 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_RECEIVER); 48 bi.noteStartSensorLocked(UID, SENSOR_ID); 49 bi.noteStartSensorLocked(UID, SENSOR_ID); 50 clocks.realtime = 400; 51 clocks.uptime = 400; 52 bi.noteStopSensorLocked(UID, SENSOR_ID); 53 bi.noteStopSensorLocked(UID, SENSOR_ID); 54 55 BatteryStats.Timer sensorTimer = bi.getUidStats().get(UID).getSensorStats() 56 .get(SENSOR_ID).getSensorTime(); 57 BatteryStats.Timer sensorBgTimer = bi.getUidStats().get(UID).getSensorStats() 58 .get(SENSOR_ID).getSensorBackgroundTime(); 59 60 assertEquals(2, sensorTimer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); 61 assertEquals(300_000, sensorTimer.getTotalTimeLocked( 62 clocks.realtime * 1000, BatteryStats.STATS_SINCE_CHARGED)); 63 64 assertEquals(1, sensorBgTimer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); 65 assertEquals(200_000, sensorBgTimer.getTotalTimeLocked( 66 clocks.realtime * 1000, BatteryStats.STATS_SINCE_CHARGED)); 67 } 68 69 @SmallTest 70 public void testCountingWhileOffBattery() throws Exception { 71 final MockClocks clocks = new MockClocks(); 72 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 73 long curr = 0; // realtime in us 74 75 // Plugged-in (battery=off, sensor=off) 76 curr = 1000 * (clocks.realtime = clocks.uptime = 100); 77 bi.updateTimeBasesLocked(false, false, curr, curr); 78 79 80 // Start sensor (battery=off, sensor=on) 81 curr = 1000 * (clocks.realtime = clocks.uptime = 200); 82 bi.noteStartSensorLocked(UID, SENSOR_ID); 83 84 // Test situation 85 curr = 1000 * (clocks.realtime = clocks.uptime = 215); 86 BatteryStats.Timer sensorTimer = bi.getUidStats().get(UID).getSensorStats() 87 .get(SENSOR_ID).getSensorTime(); 88 assertEquals(0, 89 sensorTimer.getTotalTimeLocked(curr, BatteryStats.STATS_SINCE_CHARGED)); 90 assertEquals(0, sensorTimer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); 91 92 // Stop sensor (battery=off, sensor=off) 93 curr = 1000 * (clocks.realtime = clocks.uptime = 550); 94 bi.noteStopSensorLocked(UID, SENSOR_ID); 95 96 // Test situation 97 curr = 1000 * (clocks.realtime = clocks.uptime = 678); 98 sensorTimer = bi.getUidStats().get(UID).getSensorStats() 99 .get(SENSOR_ID).getSensorTime(); 100 assertEquals(0, 101 sensorTimer.getTotalTimeLocked(curr, BatteryStats.STATS_SINCE_CHARGED)); 102 assertEquals(0, sensorTimer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); 103 } 104 105 @SmallTest 106 public void testCountingWhileOnBattery() throws Exception { 107 final MockClocks clocks = new MockClocks(); 108 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 109 long curr = 0; // realtime in us 110 111 // Unplugged (battery=on, sensor=off) 112 curr = 1000 * (clocks.realtime = clocks.uptime = 100); 113 bi.updateTimeBasesLocked(true, false, curr, curr); 114 115 // Start sensor (battery=on, sensor=on) 116 curr = 1000 * (clocks.realtime = clocks.uptime = 200); 117 bi.noteStartSensorLocked(UID, SENSOR_ID); 118 119 // Test situation 120 curr = 1000 * (clocks.realtime = clocks.uptime = 215); 121 BatteryStats.Timer sensorTimer = bi.getUidStats().get(UID).getSensorStats() 122 .get(SENSOR_ID).getSensorTime(); 123 assertEquals((215-200)*1000, 124 sensorTimer.getTotalTimeLocked(curr, BatteryStats.STATS_SINCE_CHARGED)); 125 assertEquals(1, sensorTimer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); 126 127 // Stop sensor (battery=on, sensor=off) 128 curr = 1000 * (clocks.realtime = clocks.uptime = 550); 129 bi.noteStopSensorLocked(UID, SENSOR_ID); 130 131 // Test situation 132 curr = 1000 * (clocks.realtime = clocks.uptime = 678); 133 sensorTimer = bi.getUidStats().get(UID).getSensorStats() 134 .get(SENSOR_ID).getSensorTime(); 135 assertEquals((550-200)*1000, 136 sensorTimer.getTotalTimeLocked(curr, BatteryStats.STATS_SINCE_CHARGED)); 137 assertEquals(1, sensorTimer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); 138 } 139 140 @SmallTest 141 public void testBatteryStatusOnToOff() throws Exception { 142 final MockClocks clocks = new MockClocks(); 143 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 144 long curr = 0; // realtime in us 145 146 // On battery (battery=on, sensor=off) 147 curr = 1000 * (clocks.realtime = clocks.uptime = 100); 148 bi.updateTimeBasesLocked(true, false, curr, curr); 149 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND); 150 151 // Start sensor (battery=on, sensor=on) 152 curr = 1000 * (clocks.realtime = clocks.uptime = 202); 153 bi.noteStartSensorLocked(UID, SENSOR_ID); 154 155 // Off battery (battery=off, sensor=on) 156 curr = 1000 * (clocks.realtime = clocks.uptime = 305); 157 bi.updateTimeBasesLocked(false, false, curr, curr); 158 159 // Stop sensor while off battery (battery=off, sensor=off) 160 curr = 1000 * (clocks.realtime = clocks.uptime = 409); 161 bi.noteStopSensorLocked(UID, SENSOR_ID); 162 163 // Start sensor while off battery (battery=off, sensor=on) 164 curr = 1000 * (clocks.realtime = clocks.uptime = 519); 165 bi.noteStartSensorLocked(UID, SENSOR_ID); 166 167 // Test while still running (but off battery) 168 curr = 1000 * (clocks.realtime = clocks.uptime = 657); 169 BatteryStats.Timer sensorTimer = bi.getUidStats().get(UID).getSensorStats() 170 .get(SENSOR_ID).getSensorTime(); 171 assertEquals(1, sensorTimer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); 172 assertEquals((305-202)*1000, 173 sensorTimer.getTotalTimeLocked(curr, BatteryStats.STATS_SINCE_CHARGED)); 174 175 // Now stop running (still off battery) (battery=off, sensor=off) 176 curr = 1000 * (clocks.realtime = clocks.uptime = 693); 177 bi.noteStopSensorLocked(UID, SENSOR_ID); 178 179 sensorTimer = bi.getUidStats().get(UID).getSensorStats() 180 .get(SENSOR_ID).getSensorTime(); 181 assertEquals(1, sensorTimer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); 182 assertEquals((305-202)*1000, 183 sensorTimer.getTotalTimeLocked(curr, BatteryStats.STATS_SINCE_CHARGED)); 184 } 185 186 @SmallTest 187 public void testBatteryStatusOffToOn() throws Exception { 188 final MockClocks clocks = new MockClocks(); 189 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 190 long curr = 0; // realtime in us 191 192 // Plugged-in (battery=off, sensor=off) 193 curr = 1000 * (clocks.realtime = clocks.uptime = 100); 194 bi.updateTimeBasesLocked(false, false, curr, curr); 195 196 // Start sensor (battery=off, sensor=on) 197 curr = 1000 * (clocks.realtime = clocks.uptime = 200); 198 bi.noteStartSensorLocked(UID, SENSOR_ID); 199 200 // Test situation 201 curr = 1000 * (clocks.realtime = clocks.uptime = 215); 202 BatteryStats.Timer sensorTimer = bi.getUidStats().get(UID).getSensorStats() 203 .get(SENSOR_ID).getSensorTime(); 204 // Time was entirely off battery, so time=0. 205 assertEquals(0, 206 sensorTimer.getTotalTimeLocked(curr, BatteryStats.STATS_SINCE_CHARGED)); 207 // Acquired off battery, so count=0. 208 assertEquals(0, sensorTimer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); 209 210 // Unplug (battery=on, sensor=on) 211 curr = 1000 * (clocks.realtime = clocks.uptime = 305); 212 bi.updateTimeBasesLocked(true, false, curr, curr); 213 214 //Test situation 215 curr = 1000 * (clocks.realtime = clocks.uptime = 410); 216 sensorTimer = bi.getUidStats().get(UID).getSensorStats().get(SENSOR_ID).getSensorTime(); 217 // Part of the time it was on battery. 218 assertEquals((410-305)*1000, 219 sensorTimer.getTotalTimeLocked(curr, BatteryStats.STATS_SINCE_CHARGED)); 220 // Only ever acquired off battery, so count=0. 221 assertEquals(0, sensorTimer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); 222 223 // Stop sensor (battery=on, sensor=off) 224 curr = 1000 * (clocks.realtime = clocks.uptime = 550); 225 bi.noteStopSensorLocked(UID, SENSOR_ID); 226 227 // Test situation 228 curr = 1000 * (clocks.realtime = clocks.uptime = 678); 229 sensorTimer = bi.getUidStats().get(UID).getSensorStats().get(SENSOR_ID).getSensorTime(); 230 // Part of the time it was on battery. 231 assertEquals((550-305)*1000, 232 sensorTimer.getTotalTimeLocked(curr, BatteryStats.STATS_SINCE_CHARGED)); 233 // Only ever acquired off battery, so count=0. 234 assertEquals(0, sensorTimer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); 235 } 236 237 @SmallTest 238 public void testPooledBackgroundUsage() throws Exception { 239 final int UID_2 = 20000; // second uid for testing pool usage 240 final MockClocks clocks = new MockClocks(); 241 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 242 bi.mForceOnBattery = true; 243 long curr = 0; // realtime in us 244 // Entire test is on-battery 245 curr = 1000 * (clocks.realtime = clocks.uptime = 1000); 246 bi.updateTimeBasesLocked(true, false, curr, curr); 247 248 // See below for a diagram of events. 249 250 // UID in foreground 251 curr = 1000 * (clocks.realtime = clocks.uptime = 2002); 252 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND); 253 254 // UID starts the sensor (foreground) 255 curr = 1000 * (clocks.realtime = clocks.uptime = 3004); 256 bi.noteStartSensorLocked(UID, SENSOR_ID); 257 258 // UID_2 in background 259 curr = 1000 * (clocks.realtime = clocks.uptime = 4008); 260 bi.noteUidProcessStateLocked(UID_2, ActivityManager.PROCESS_STATE_RECEIVER); // background 261 262 // UID_2 starts the sensor (background) 263 curr = 1000 * (clocks.realtime = clocks.uptime = 5016); 264 bi.noteStartSensorLocked(UID_2, SENSOR_ID); 265 266 // UID enters background 267 curr = 1000 * (clocks.realtime = clocks.uptime = 6032); 268 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); 269 270 // UID enters background again (from a different background state) 271 curr = 1000 * (clocks.realtime = clocks.uptime = 7004); 272 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_LAST_ACTIVITY); 273 274 // UID_2 stops the sensor (background), then starts it again, then stops again 275 curr = 1000 * (clocks.realtime = clocks.uptime = 8064); 276 bi.noteStopSensorLocked(UID_2, SENSOR_ID); 277 curr = 1000 * (clocks.realtime = clocks.uptime = 9128); 278 bi.noteStartSensorLocked(UID_2, SENSOR_ID); 279 curr = 1000 * (clocks.realtime = clocks.uptime = 10256); 280 bi.noteStopSensorLocked(UID_2, SENSOR_ID); 281 282 // UID re-enters foreground 283 curr = 1000 * (clocks.realtime = clocks.uptime = 11512); 284 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND); 285 286 // UID starts the sensor a second time (foreground) 287 curr = 1000 * (clocks.realtime = clocks.uptime = 12000); 288 bi.noteStartSensorLocked(UID, SENSOR_ID); 289 290 // UID re-enters background 291 curr = 1000 * (clocks.realtime = clocks.uptime = 13002); 292 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); 293 294 // UID stops the sensor completely (background) 295 curr = 1000 * (clocks.realtime = clocks.uptime = 14004); 296 bi.noteStopSensorLocked(UID, SENSOR_ID); 297 curr = 1000 * (clocks.realtime = clocks.uptime = 14024); 298 bi.noteStopSensorLocked(UID, SENSOR_ID); 299 300 // UID starts the sensor anew (background) 301 curr = 1000 * (clocks.realtime = clocks.uptime = 15010); 302 bi.noteStartSensorLocked(UID, SENSOR_ID); 303 304 // UID stops the sensor (background) 305 curr = 1000 * (clocks.realtime = clocks.uptime = 16020); 306 bi.noteStopSensorLocked(UID, SENSOR_ID); 307 308 // Summary 309 // UID 310 // foreground: 2002---6032, 11512---13002 311 // background: 6032---------------11512, 13002-------------------------- 312 // sensor running: 3004-----------------------------14024, 15010-16020 313 // 314 // UID2 315 // foreground: 316 // background: 4008------------------------------------------------------- 317 // sensor running: 5016--8064, 9128-10256 318 319 BatteryStats.Timer timer1 = bi.getUidStats().get(UID).getSensorStats() 320 .get(SENSOR_ID).getSensorTime(); 321 BatteryStats.Timer bgTimer1 = bi.getUidStats().get(UID).getSensorStats() 322 .get(SENSOR_ID).getSensorBackgroundTime(); 323 324 BatteryStats.Timer timer2 = bi.getUidStats().get(UID_2).getSensorStats() 325 .get(SENSOR_ID).getSensorTime(); 326 BatteryStats.Timer bgTimer2 = bi.getUidStats().get(UID_2).getSensorStats() 327 .get(SENSOR_ID).getSensorBackgroundTime(); 328 329 // Expected values 330 long expActualTime1 = (14024 - 3004) + (16020 - 15010); 331 long expBgTime1 = (11512 - 6032) + (14024 - 13002) + (16020 - 15010); 332 333 long expActualTime2 = (8064 - 5016) + (10256 - 9128); 334 long expBgTime2 = (8064 - 5016) + (10256 - 9128); 335 336 long expBlamedTime1 = (5016 - 3004) + (8064 - 5016)/2 + (9128 - 8064) + (10256 - 9128)/2 337 + (14024 - 10256) + (16020 - 15010); 338 long expBlamedTime2 = (8064 - 5016)/2 + (10256 - 9128)/2; 339 340 // Test: UID - blamed time 341 assertEquals(expBlamedTime1 * 1000, 342 timer1.getTotalTimeLocked(curr, BatteryStats.STATS_SINCE_CHARGED)); 343 // Test: UID - actual time 344 assertEquals(expActualTime1 * 1000, 345 timer1.getTotalDurationMsLocked(clocks.realtime) * 1000 ); 346 // Test: UID - background time 347 // bg timer ignores pools, so both totalTime and totalDuration should give the same result 348 assertEquals(expBgTime1 * 1000, 349 bgTimer1.getTotalTimeLocked(curr, BatteryStats.STATS_SINCE_CHARGED)); 350 assertEquals(expBgTime1 * 1000, 351 bgTimer1.getTotalDurationMsLocked(clocks.realtime) * 1000 ); 352 // Test: UID - count 353 assertEquals(2, timer1.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); 354 // Test: UID - background count 355 assertEquals(1, bgTimer1.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); 356 357 // Test: UID_2 - blamed time 358 assertEquals(expBlamedTime2 * 1000, 359 timer2.getTotalTimeLocked(curr, BatteryStats.STATS_SINCE_CHARGED)); 360 // Test: UID_2 - actual time 361 assertEquals(expActualTime2 * 1000, 362 timer2.getTotalDurationMsLocked(clocks.realtime) * 1000); 363 // Test: UID_2 - background time 364 // bg timer ignores pools, so both totalTime and totalDuration should give the same result 365 assertEquals(expBgTime2 * 1000, 366 bgTimer2.getTotalTimeLocked(curr, BatteryStats.STATS_SINCE_CHARGED)); 367 assertEquals(expBgTime2 * 1000, 368 bgTimer2.getTotalDurationMsLocked(clocks.realtime) * 1000 ); 369 // Test: UID_2 - count 370 assertEquals(2, timer2.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); 371 // Test: UID_2 - background count 372 assertEquals(2, bgTimer2.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); 373 } 374 375 @SmallTest 376 public void testSensorReset() throws Exception { 377 final MockClocks clocks = new MockClocks(); 378 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 379 bi.mForceOnBattery = true; 380 clocks.realtime = 100; 381 clocks.uptime = 100; 382 bi.getOnBatteryTimeBase().setRunning(true, 100_000, 100_000); 383 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_RECEIVER); 384 385 clocks.realtime += 100; 386 clocks.uptime += 100; 387 388 bi.noteStartSensorLocked(UID, SENSOR_ID); 389 390 clocks.realtime += 100; 391 clocks.uptime += 100; 392 393 // The sensor is started and the timer has been created. 394 final BatteryStats.Uid uid = bi.getUidStats().get(UID); 395 assertNotNull(uid); 396 397 BatteryStats.Uid.Sensor sensor = uid.getSensorStats().get(SENSOR_ID); 398 assertNotNull(sensor); 399 assertNotNull(sensor.getSensorTime()); 400 assertNotNull(sensor.getSensorBackgroundTime()); 401 402 // Reset the stats. Since the sensor is still running, we should still see the timer 403 bi.getUidStatsLocked(UID).reset(); 404 405 sensor = uid.getSensorStats().get(SENSOR_ID); 406 assertNotNull(sensor); 407 assertNotNull(sensor.getSensorTime()); 408 assertNotNull(sensor.getSensorBackgroundTime()); 409 410 bi.noteStopSensorLocked(UID, SENSOR_ID); 411 412 // Now the sensor timer has stopped so this reset should also take out the sensor. 413 bi.getUidStatsLocked(UID).reset(); 414 415 sensor = uid.getSensorStats().get(SENSOR_ID); 416 assertNull(sensor); 417 } 418 } 419