Home | History | Annotate | Download | only in batterysaver
      1 /*
      2  * Copyright (C) 2018 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of 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,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package com.android.server.power.batterysaver;
     17 
     18 import static org.junit.Assert.assertEquals;
     19 import static org.mockito.ArgumentMatchers.any;
     20 import static org.mockito.ArgumentMatchers.anyInt;
     21 import static org.mockito.ArgumentMatchers.anyString;
     22 import static org.mockito.Mockito.mock;
     23 import static org.mockito.Mockito.reset;
     24 import static org.mockito.Mockito.times;
     25 import static org.mockito.Mockito.verify;
     26 
     27 import android.metrics.LogMaker;
     28 import android.support.test.filters.SmallTest;
     29 import android.support.test.runner.AndroidJUnit4;
     30 
     31 import com.android.internal.logging.MetricsLogger;
     32 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
     33 import com.android.server.power.batterysaver.BatterySavingStats.BatterySaverState;
     34 import com.android.server.power.batterysaver.BatterySavingStats.DozeState;
     35 import com.android.server.power.batterysaver.BatterySavingStats.InteractiveState;
     36 
     37 import org.junit.Test;
     38 import org.junit.runner.RunWith;
     39 import org.mockito.ArgumentCaptor;
     40 
     41 import java.io.ByteArrayOutputStream;
     42 import java.io.PrintWriter;
     43 
     44 /**
     45  atest $ANDROID_BUILD_TOP/frameworks/base/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySavingStatsTest.java
     46  */
     47 @SmallTest
     48 @RunWith(AndroidJUnit4.class)
     49 public class BatterySavingStatsTest {
     50     private class BatterySavingStatsTestable extends BatterySavingStats {
     51         private long mTime = 1_000_000; // Some random starting time.
     52 
     53         private int mBatteryLevel = 1_000_000_000;
     54 
     55         private BatterySavingStatsTestable() {
     56             super(new Object(), mMetricsLogger);
     57         }
     58 
     59         @Override
     60         long injectCurrentTime() {
     61             return mTime;
     62         }
     63 
     64         @Override
     65         int injectBatteryLevel() {
     66             return mBatteryLevel;
     67         }
     68 
     69         @Override
     70         int injectBatteryPercent() {
     71             return mBatteryLevel / 10;
     72         }
     73 
     74         void assertDumpable() {
     75             final ByteArrayOutputStream out = new ByteArrayOutputStream();
     76             dump(new PrintWriter(out), ""); // Just make sure it won't crash.
     77         }
     78 
     79         void advanceClock(int minutes) {
     80             mTime += 60_000 * minutes;
     81         }
     82 
     83         void drainBattery(int value) {
     84             mBatteryLevel -= value;
     85             if (mBatteryLevel < 0) {
     86                 mBatteryLevel = 0;
     87             }
     88         }
     89 
     90         String toDebugString() {
     91             final StringBuilder sb = new StringBuilder();
     92             String sep = "";
     93             for (int i = 0; i < mStats.size(); i++) {
     94                 sb.append(sep);
     95                 sb.append(stateToString(mStats.keyAt(i)));
     96                 sb.append(":");
     97                 sb.append(mStats.valueAt(i).toStringForTest());
     98                 sep = "\n";
     99             }
    100             return sb.toString();
    101         }
    102     }
    103 
    104     public MetricsLogger mMetricsLogger = mock(MetricsLogger.class);
    105 
    106     private boolean sendTronEvents;
    107 
    108     @Test
    109     public void testAll_withTron() {
    110         sendTronEvents = true;
    111         checkAll();
    112     }
    113 
    114     @Test
    115     public void testAll_noTron() {
    116         sendTronEvents = false;
    117         checkAll();
    118     }
    119 
    120     private void checkAll() {
    121         final BatterySavingStatsTestable target = new BatterySavingStatsTestable();
    122         target.setSendTronLog(sendTronEvents);
    123 
    124         target.assertDumpable();
    125 
    126         target.advanceClock(1);
    127         target.drainBattery(200);
    128 
    129         target.transitionState(
    130                 BatterySaverState.OFF,
    131                 InteractiveState.INTERACTIVE,
    132                 DozeState.NOT_DOZING);
    133 
    134         target.advanceClock(4);
    135         target.drainBattery(100);
    136 
    137         target.transitionState(
    138                 BatterySaverState.OFF,
    139                 InteractiveState.NON_INTERACTIVE,
    140                 DozeState.NOT_DOZING);
    141 
    142         target.advanceClock(2);
    143         target.drainBattery(500);
    144 
    145         target.transitionState(
    146                 BatterySaverState.OFF,
    147                 InteractiveState.INTERACTIVE,
    148                 DozeState.NOT_DOZING);
    149 
    150         target.advanceClock(4);
    151         target.drainBattery(100);
    152 
    153         target.transitionState(
    154                 BatterySaverState.OFF,
    155                 InteractiveState.NON_INTERACTIVE,
    156                 DozeState.NOT_DOZING);
    157 
    158         target.advanceClock(2);
    159         target.drainBattery(500);
    160 
    161         target.transitionState(
    162                 BatterySaverState.OFF,
    163                 InteractiveState.INTERACTIVE,
    164                 DozeState.NOT_DOZING);
    165 
    166         target.advanceClock(3);
    167         target.drainBattery(100);
    168 
    169         target.transitionState(
    170                 BatterySaverState.OFF,
    171                 InteractiveState.NON_INTERACTIVE,
    172                 DozeState.LIGHT);
    173 
    174         target.advanceClock(5);
    175         target.drainBattery(100);
    176 
    177         target.transitionState(
    178                 BatterySaverState.OFF,
    179                 InteractiveState.NON_INTERACTIVE,
    180                 DozeState.DEEP);
    181 
    182         target.advanceClock(1);
    183         target.drainBattery(200);
    184 
    185         target.transitionState(
    186                 BatterySaverState.ON,
    187                 InteractiveState.INTERACTIVE,
    188                 DozeState.NOT_DOZING);
    189 
    190         target.advanceClock(1);
    191         target.drainBattery(300);
    192 
    193         target.transitionState(
    194                 BatterySaverState.OFF,
    195                 InteractiveState.INTERACTIVE,
    196                 DozeState.NOT_DOZING);
    197 
    198         target.advanceClock(3);
    199         target.drainBattery(500);
    200 
    201         target.transitionState(
    202                 BatterySaverState.ON,
    203                 InteractiveState.INTERACTIVE,
    204                 DozeState.NOT_DOZING);
    205 
    206         target.advanceClock(3);
    207         target.drainBattery(500);
    208 
    209         target.startCharging();
    210 
    211         target.advanceClock(5);
    212         target.drainBattery(1000);
    213 
    214         target.transitionState(
    215                 BatterySaverState.ON,
    216                 InteractiveState.INTERACTIVE,
    217                 DozeState.NOT_DOZING);
    218 
    219         target.advanceClock(5);
    220         target.drainBattery(100);
    221 
    222         target.startCharging();
    223 
    224         target.assertDumpable();
    225 
    226         assertEquals(
    227                 "BS=0,I=0,D=0:{4m,1000,15000.00uA/H,1500.00%}\n" +
    228                 "BS=1,I=0,D=0:{0m,0,0.00uA/H,0.00%}\n" +
    229                 "BS=0,I=1,D=0:{14m,800,3428.57uA/H,342.86%}\n" +
    230                 "BS=1,I=1,D=0:{9m,900,6000.00uA/H,600.00%}\n" +
    231                 "BS=0,I=0,D=1:{5m,100,1200.00uA/H,120.00%}\n" +
    232                 "BS=1,I=0,D=1:{0m,0,0.00uA/H,0.00%}\n" +
    233                 "BS=0,I=1,D=1:{0m,0,0.00uA/H,0.00%}\n" +
    234                 "BS=1,I=1,D=1:{0m,0,0.00uA/H,0.00%}\n" +
    235                 "BS=0,I=0,D=2:{1m,200,12000.00uA/H,1200.00%}\n" +
    236                 "BS=1,I=0,D=2:{0m,0,0.00uA/H,0.00%}\n" +
    237                 "BS=0,I=1,D=2:{0m,0,0.00uA/H,0.00%}\n" +
    238                 "BS=1,I=1,D=2:{0m,0,0.00uA/H,0.00%}",
    239                 target.toDebugString());
    240     }
    241 
    242     private void assertLog(boolean batterySaver, boolean interactive, long deltaTimeMs,
    243             int deltaBatteryLevelUa, int deltaBatteryLevelPercent) {
    244         if (sendTronEvents) {
    245             ArgumentCaptor<LogMaker> ac = ArgumentCaptor.forClass(LogMaker.class);
    246             verify(mMetricsLogger, times(1)).write(ac.capture());
    247 
    248             LogMaker lm = ac.getValue();
    249             assertEquals(MetricsEvent.BATTERY_SAVER, lm.getCategory());
    250             assertEquals(batterySaver ? 1 : 0,
    251                     lm.getTaggedData(MetricsEvent.RESERVED_FOR_LOGBUILDER_SUBTYPE));
    252             assertEquals(interactive ? 1 : 0, lm.getTaggedData(MetricsEvent.FIELD_INTERACTIVE));
    253             assertEquals(deltaTimeMs, lm.getTaggedData(MetricsEvent.FIELD_DURATION_MILLIS));
    254 
    255             assertEquals(deltaBatteryLevelUa,
    256                     (int) lm.getTaggedData(MetricsEvent.FIELD_START_BATTERY_UA)
    257                             - (int) lm.getTaggedData(MetricsEvent.FIELD_END_BATTERY_UA));
    258             assertEquals(deltaBatteryLevelPercent,
    259                     (int) lm.getTaggedData(MetricsEvent.FIELD_START_BATTERY_PERCENT)
    260                             - (int) lm.getTaggedData(MetricsEvent.FIELD_END_BATTERY_PERCENT));
    261         } else {
    262             verify(mMetricsLogger, times(0)).write(any(LogMaker.class));
    263         }
    264     }
    265 
    266 
    267     @Test
    268     public void testMetricsLogger_withTron() {
    269         sendTronEvents = true;
    270         checkMetricsLogger();
    271     }
    272 
    273     @Test
    274     public void testMetricsLogger_noTron() {
    275         sendTronEvents = false;
    276         checkMetricsLogger();
    277     }
    278 
    279     private void checkMetricsLogger() {
    280         final BatterySavingStatsTestable target = new BatterySavingStatsTestable();
    281         target.setSendTronLog(sendTronEvents);
    282 
    283         target.advanceClock(1);
    284         target.drainBattery(1000);
    285 
    286         target.transitionState(
    287                 BatterySaverState.OFF,
    288                 InteractiveState.INTERACTIVE,
    289                 DozeState.NOT_DOZING);
    290 
    291         verify(mMetricsLogger, times(0)).count(anyString(), anyInt());
    292 
    293         target.advanceClock(1);
    294         target.drainBattery(2000);
    295 
    296         reset(mMetricsLogger);
    297         target.transitionState(
    298                 BatterySaverState.OFF,
    299                 InteractiveState.NON_INTERACTIVE,
    300                 DozeState.NOT_DOZING);
    301 
    302         assertLog(false, true, 60_000, 2000, 200);
    303 
    304         target.advanceClock(1);
    305         target.drainBattery(2000);
    306 
    307         reset(mMetricsLogger);
    308         target.transitionState(
    309                 BatterySaverState.OFF,
    310                 InteractiveState.NON_INTERACTIVE,
    311                 DozeState.DEEP);
    312 
    313         target.advanceClock(1);
    314         target.drainBattery(2000);
    315 
    316         verify(mMetricsLogger, times(0)).count(anyString(), anyInt());
    317 
    318         target.transitionState(
    319                 BatterySaverState.OFF,
    320                 InteractiveState.NON_INTERACTIVE,
    321                 DozeState.LIGHT);
    322 
    323         target.advanceClock(1);
    324         target.drainBattery(2000);
    325 
    326         verify(mMetricsLogger, times(0)).count(anyString(), anyInt());
    327 
    328         target.transitionState(
    329                 BatterySaverState.ON,
    330                 InteractiveState.INTERACTIVE,
    331                 DozeState.NOT_DOZING);
    332 
    333         assertLog(false, false, 60_000 * 3, 2000 * 3, 200 * 3);
    334 
    335         target.advanceClock(10);
    336         target.drainBattery(10000);
    337 
    338         reset(mMetricsLogger);
    339         target.startCharging();
    340 
    341         assertLog(true, true, 60_000 * 10, 10000, 1000);
    342 
    343         target.advanceClock(1);
    344         target.drainBattery(2000);
    345 
    346         reset(mMetricsLogger);
    347         target.transitionState(
    348                 BatterySaverState.ON,
    349                 InteractiveState.NON_INTERACTIVE,
    350                 DozeState.NOT_DOZING);
    351 
    352         verify(mMetricsLogger, times(0)).count(anyString(), anyInt());
    353 
    354         target.advanceClock(1);
    355         target.drainBattery(2000);
    356 
    357         target.startCharging();
    358 
    359         assertLog(true, false, 60_000, 2000, 200);
    360     }
    361 }
    362