1 /* 2 * Copyright (C) 2016 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 17 package com.android.internal.os; 18 19 import android.os.BatteryStats; 20 import android.os.Parcel; 21 import android.util.Log; 22 23 import androidx.test.filters.SmallTest; 24 25 import junit.framework.Assert; 26 import junit.framework.TestCase; 27 28 import org.mockito.Mockito; 29 30 import java.io.PrintWriter; 31 import java.io.StringWriter; 32 33 /** 34 * Provides test cases for android.os.BatteryStats. 35 */ 36 public class BatteryStatsTimeBaseTest extends TestCase { 37 private static final String TAG = "BatteryStatsTimeBaseTest"; 38 39 static class TestTimeBase extends BatteryStatsImpl.TimeBase { 40 populate(long uptime, long realtime, boolean running, long pastUptime, long uptimeStart, long pastRealtime, long realtimeStart, long unpluggedUptime, long unpluggedRealtime)41 public void populate(long uptime, long realtime, boolean running, long pastUptime, 42 long uptimeStart, long pastRealtime, long realtimeStart, 43 long unpluggedUptime, long unpluggedRealtime) { 44 mUptime = uptime; 45 mRealtime = realtime; 46 mRunning = running; 47 mPastUptime = pastUptime; 48 mUptimeStart = uptimeStart; 49 mPastRealtime = pastRealtime; 50 mRealtimeStart = realtimeStart; 51 mUnpluggedUptime = unpluggedUptime; 52 mUnpluggedRealtime = unpluggedRealtime; 53 } 54 verify(long uptime, long realtime, boolean running, long pastUptime, long uptimeStart, long pastRealtime, long realtimeStart, long unpluggedUptime, long unpluggedRealtime)55 public void verify(long uptime, long realtime, boolean running, long pastUptime, 56 long uptimeStart, long pastRealtime, long realtimeStart, 57 long unpluggedUptime, long unpluggedRealtime) { 58 Assert.assertEquals(uptime, mUptime); 59 Assert.assertEquals(realtime, mRealtime); 60 Assert.assertEquals(running, mRunning); 61 Assert.assertEquals(pastUptime, mPastUptime); 62 Assert.assertEquals(uptimeStart, mUptimeStart); 63 Assert.assertEquals(pastRealtime, mPastRealtime); 64 Assert.assertEquals(realtimeStart, mRealtimeStart); 65 Assert.assertEquals(unpluggedUptime, mUnpluggedUptime); 66 Assert.assertEquals(unpluggedRealtime, mUnpluggedRealtime); 67 } 68 } 69 70 /** 71 * Test the observers and the setRunning call. 72 */ 73 @SmallTest testRunning()74 public void testRunning() throws Exception { 75 TestTimeBase tb = new TestTimeBase(); 76 77 // Toggle running once, to accumulate past uptime and past realtime 78 // so the test values aren't 0. 79 tb.setRunning(true, 100, 10000); 80 tb.setRunning(false, 200, 11000); 81 Assert.assertEquals(100, tb.getUptimeStart()); 82 Assert.assertEquals(10000, tb.getRealtimeStart()); 83 84 // Create some observers 85 BatteryStatsImpl.TimeBaseObs observer1 = Mockito.mock(BatteryStatsImpl.TimeBaseObs.class); 86 BatteryStatsImpl.TimeBaseObs observer2 = Mockito.mock(BatteryStatsImpl.TimeBaseObs.class); 87 BatteryStatsImpl.TimeBaseObs observer3 = Mockito.mock(BatteryStatsImpl.TimeBaseObs.class); 88 89 // Add them 90 tb.add(observer1); 91 tb.add(observer2); 92 tb.add(observer3); 93 Assert.assertTrue(tb.hasObserver(observer1)); 94 Assert.assertTrue(tb.hasObserver(observer2)); 95 Assert.assertTrue(tb.hasObserver(observer3)); 96 97 // Remove one 98 tb.remove(observer3); 99 Assert.assertTrue(tb.hasObserver(observer1)); 100 Assert.assertTrue(tb.hasObserver(observer2)); 101 Assert.assertFalse(tb.hasObserver(observer3)); 102 103 // Start running, make sure we get a started call on the two active observers 104 // and not the third. 105 tb.setRunning(true, 250, 14000); 106 107 Assert.assertTrue(tb.isRunning()); 108 109 if (false) { 110 Log.d(TAG, "mUptimeStart=" + tb.getUptimeStart() 111 + " mRealtimeStart=" + tb.getRealtimeStart() 112 + " mUptime=" + tb.getUptime(250) 113 + " mRealtime=" + tb.getRealtime(14000) 114 + " isRunning=" + tb.isRunning()); 115 } 116 117 Assert.assertEquals(250, tb.getUptimeStart()); 118 Assert.assertEquals(14000, tb.getRealtimeStart()); 119 Assert.assertEquals(100, tb.getUptime(250)); 120 Assert.assertEquals(1000, tb.getRealtime(14000)); 121 122 Mockito.verify(observer1).onTimeStarted(14000, 100, 1000); 123 Mockito.verify(observer1, Mockito.never()).onTimeStopped(-1, -1, -1); 124 Mockito.verifyNoMoreInteractions(observer1); 125 Mockito.verify(observer2).onTimeStarted(14000, 100, 1000); 126 Mockito.verify(observer2, Mockito.never()).onTimeStopped(-1, -1, -1); 127 Mockito.verifyNoMoreInteractions(observer2); 128 129 Mockito.reset(observer1); 130 Mockito.reset(observer2); 131 Mockito.reset(observer3); 132 133 // Advance the "timer" and make sure the getters account for the current time passed in 134 Assert.assertEquals(400, tb.getUptime(550)); 135 Assert.assertEquals(1555, tb.getRealtime(14555)); 136 137 // Stop running, make sure we get a stopped call on the two active observers 138 // and not the third. 139 tb.setRunning(false, 402, 14002); 140 141 Assert.assertFalse(tb.isRunning()); 142 143 if (false) { 144 Log.d(TAG, "mUptimeStart=" + tb.getUptimeStart() 145 + " mRealtimeStart=" + tb.getRealtimeStart() 146 + " mUptime=" + tb.getUptime(250) 147 + " mRealtime=" + tb.getRealtime(14000) 148 + " isRunning=" + tb.isRunning()); 149 } 150 151 Assert.assertEquals(252, tb.getUptime(402)); 152 Assert.assertEquals(1002, tb.getRealtime(14002)); 153 154 Mockito.verify(observer1).onTimeStopped(14002, 252, 1002); 155 Mockito.verify(observer1, Mockito.never()).onTimeStopped(-1, -1, -1); 156 Mockito.verifyNoMoreInteractions(observer1); 157 Mockito.verify(observer2).onTimeStopped(14002, 252, 1002); 158 Mockito.verify(observer2, Mockito.never()).onTimeStopped(-1, -1, -1); 159 Mockito.verifyNoMoreInteractions(observer2); 160 161 // Advance the "timer" and make sure the getters account for the current time passed in 162 // is the same as the time when running went to false. 163 Assert.assertEquals(252, tb.getUptime(600)); 164 Assert.assertEquals(1002, tb.getRealtime(17000)); 165 } 166 167 /** 168 * Test that reset while running updates the plugged and unplugged times 169 */ 170 @SmallTest testResetWhileRunning()171 public void testResetWhileRunning() throws Exception { 172 TestTimeBase tb = new TestTimeBase(); 173 tb.populate(100, 200, true, 300, 400, 500, 600, 700, 800); 174 175 tb.reset(666, 6666); 176 177 // Not sure if this is a bug: reset while running does not 178 // reset mPastUptime, but while it is running it does. 179 tb.verify(100, 200, true, 300, 666, 500, 6666, 300, 500); 180 } 181 182 /** 183 * Test that reset while running updates the plugged and unplugged times 184 */ 185 @SmallTest testResetWhileNotRunning()186 public void testResetWhileNotRunning() throws Exception { 187 TestTimeBase tb = new TestTimeBase(); 188 tb.populate(100, 200, false, 300, 400, 500, 600, 700, 800); 189 190 tb.reset(666, 6666); 191 192 tb.verify(100, 200, false, 0, 400, 0, 600, 700, 800); 193 } 194 195 /** 196 * Test init 197 */ 198 @SmallTest testInit()199 public void testInit() throws Exception { 200 TestTimeBase tb = new TestTimeBase(); 201 tb.populate(100, 200, false, 300, 400, 500, 600, 700, 800); 202 203 tb.init(666, 6666); 204 205 tb.verify(0, 0, false, 0, 666, 0, 6666, 0, 0); 206 } 207 208 /** 209 * Test writeToParcel and readFromParcel 210 */ 211 @SmallTest testParcellingWhileRunning()212 public void testParcellingWhileRunning() throws Exception { 213 TestTimeBase tb1 = new TestTimeBase(); 214 215 tb1.populate(100, 200, true, 300, 400, 500, 600, 700, 800); 216 217 Parcel parcel = Parcel.obtain(); 218 tb1.writeToParcel(parcel, 666, 6666); 219 220 parcel.setDataPosition(0); 221 222 TestTimeBase tb2 = new TestTimeBase(); 223 tb2.readFromParcel(parcel); 224 225 // Running is not preserved across parceling 226 tb2.verify(100, 200, false, 300+666-400, 400, 500+6666-600, 600, 700, 800); 227 } 228 229 /** 230 * Test writeToParcel and readFromParcel 231 */ 232 @SmallTest testParcellingWhileNotRunning()233 public void testParcellingWhileNotRunning() throws Exception { 234 TestTimeBase tb1 = new TestTimeBase(); 235 236 tb1.populate(100, 200, false, 300, 400, 500, 600, 700, 800); 237 238 Parcel parcel = Parcel.obtain(); 239 tb1.writeToParcel(parcel, 666, 6666); 240 241 parcel.setDataPosition(0); 242 243 TestTimeBase tb2 = new TestTimeBase(); 244 tb2.readFromParcel(parcel); 245 246 tb2.verify(100, 200, false, 300, 400, 500, 600, 700, 800); 247 } 248 249 /** 250 * Test writeSummaryToParcel and readSummaryFromParcel 251 */ 252 @SmallTest testSummary()253 public void testSummary() throws Exception { 254 TestTimeBase tb1 = new TestTimeBase(); 255 256 tb1.populate(100, 200, true, 300, 400, 500, 600, 700, 800); 257 258 Parcel parcel = Parcel.obtain(); 259 tb1.writeSummaryToParcel(parcel, 666, 6666); 260 261 parcel.setDataPosition(0); 262 263 TestTimeBase tb2 = new TestTimeBase(); 264 265 // readSummaryFromParcel doesn't affect the other fields. 266 // Not sure if this is deliberate 267 tb2.populate(1, 2, true, 3, 4, 5, 6, 7, 8); 268 269 tb2.readSummaryFromParcel(parcel); 270 271 tb2.verify(666, 6766, true, 3, 4, 5, 6, 7, 8); 272 } 273 274 /** 275 * Test computeUptime 276 */ 277 @SmallTest testComputeUptime()278 public void testComputeUptime() throws Exception { 279 TestTimeBase tb = new TestTimeBase(); 280 281 tb.populate(100, 200, true, 300, 400, 500, 600, 50, 60); 282 283 Assert.assertEquals(100+300+666-400, 284 tb.computeUptime(666, BatteryStats.STATS_SINCE_CHARGED)); 285 } 286 287 /** 288 * Test computeUptime 289 */ 290 @SmallTest testComputeRealtime()291 public void testComputeRealtime() throws Exception { 292 TestTimeBase tb = new TestTimeBase(); 293 294 tb.populate(100, 200, true, 300, 400, 500, 600, 50, 60); 295 296 Assert.assertEquals(200+500+6666-600, 297 tb.computeRealtime(6666, BatteryStats.STATS_SINCE_CHARGED)); 298 } 299 300 /** 301 * Test dump 302 */ 303 @SmallTest testDump()304 public void testDump() throws Exception { 305 TestTimeBase tb = new TestTimeBase(); 306 307 tb.populate(100, 200, true, 300, 400, 500, 600, 50, 60); 308 309 StringWriter sw = new StringWriter(); 310 PrintWriter pw = new PrintWriter(sw); 311 312 tb.dump(pw, "+++++ "); 313 314 pw.close(); 315 316 // note the spaces at the ends of the lines which come from formatTimeMs. 317 final String CORRECT = "+++++ mRunning=true\n" 318 + "+++++ mUptime=0ms \n" 319 + "+++++ mRealtime=0ms \n" 320 + "+++++ mPastUptime=0ms mUptimeStart=0ms mUnpluggedUptime=0ms \n" 321 + "+++++ mPastRealtime=0ms mRealtimeStart=0ms mUnpluggedRealtime=0ms \n"; 322 323 Assert.assertEquals(CORRECT, sw.toString()); 324 } 325 326 } 327 328