Home | History | Annotate | Download | only in os
      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