1 /* 2 * Copyright (C) 2021 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.settings.fuelgauge; 17 18 import static com.google.common.truth.Truth.assertThat; 19 20 import static org.mockito.Mockito.when; 21 22 import android.content.ContentValues; 23 import android.database.MatrixCursor; 24 import android.os.BatteryManager; 25 import android.os.BatteryUsageStats; 26 import android.os.UserHandle; 27 28 import org.junit.Before; 29 import org.junit.Test; 30 import org.junit.runner.RunWith; 31 import org.mockito.Mock; 32 import org.mockito.MockitoAnnotations; 33 import org.robolectric.RobolectricTestRunner; 34 35 import java.util.TimeZone; 36 37 @RunWith(RobolectricTestRunner.class) 38 public final class BatteryHistEntryTest { 39 40 @Mock 41 private BatteryEntry mockBatteryEntry; 42 @Mock 43 private BatteryUsageStats mBatteryUsageStats; 44 45 @Before setUp()46 public void setUp() { 47 MockitoAnnotations.initMocks(this); 48 } 49 50 @Test testConstructor_contentValues_returnsExpectedResult()51 public void testConstructor_contentValues_returnsExpectedResult() { 52 final int expectedType = 3; 53 when(mockBatteryEntry.getUid()).thenReturn(1001); 54 when(mockBatteryEntry.getLabel()).thenReturn("Settings"); 55 when(mockBatteryEntry.getDefaultPackageName()) 56 .thenReturn("com.google.android.settings.battery"); 57 when(mockBatteryEntry.isHidden()).thenReturn(true); 58 when(mBatteryUsageStats.getConsumedPower()).thenReturn(5.1); 59 when(mockBatteryEntry.getConsumedPower()).thenReturn(1.1); 60 mockBatteryEntry.percent = 0.3; 61 when(mockBatteryEntry.getTimeInForegroundMs()).thenReturn(1234L); 62 when(mockBatteryEntry.getTimeInBackgroundMs()).thenReturn(5689L); 63 when(mockBatteryEntry.getPowerComponentId()).thenReturn(expectedType); 64 when(mockBatteryEntry.getConsumerType()) 65 .thenReturn(ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY); 66 final ContentValues values = 67 ConvertUtils.convert( 68 mockBatteryEntry, 69 mBatteryUsageStats, 70 /*batteryLevel=*/ 12, 71 /*batteryStatus=*/ BatteryManager.BATTERY_STATUS_FULL, 72 /*batteryHealth=*/ BatteryManager.BATTERY_HEALTH_COLD, 73 /*bootTimestamp=*/ 101L, 74 /*timestamp=*/ 10001L); 75 76 assertBatteryHistEntry( 77 new BatteryHistEntry(values), 78 /*drainType=*/ expectedType, 79 /*percentOfTotal=*/ mockBatteryEntry.percent); 80 } 81 82 @Test testConstructor_invalidField_returnsInvalidEntry()83 public void testConstructor_invalidField_returnsInvalidEntry() { 84 final BatteryHistEntry entry = new BatteryHistEntry(new ContentValues()); 85 assertThat(entry.isValidEntry()).isFalse(); 86 } 87 88 @Test testConstructor_cursor_returnsExpectedResult()89 public void testConstructor_cursor_returnsExpectedResult() { 90 assertBatteryHistEntry( 91 createBatteryHistEntry( 92 /*bootTimestamp=*/ 101L, 93 /*timestamp=*/ 10001L, 94 /*totalPower=*/ 5.1, 95 /*consumePower=*/ 1.1, 96 /*foregroundUsageTimeInMs=*/ 1234L, 97 /*backgroundUsageTimeInMs=*/ 5689L, 98 /*batteryLevel=*/ 12), 99 /*drainType=*/ 3, 100 /*percentOfTotal=*/ 0.3); 101 } 102 103 @Test testGetKey_consumerUidType_returnExpectedString()104 public void testGetKey_consumerUidType_returnExpectedString() { 105 final ContentValues values = getContentValuesWithType( 106 ConvertUtils.CONSUMER_TYPE_UID_BATTERY); 107 values.put(BatteryHistEntry.KEY_UID, 3); 108 final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values); 109 110 assertThat(batteryHistEntry.getKey()).isEqualTo("3"); 111 } 112 113 @Test testGetKey_consumerUserType_returnExpectedString()114 public void testGetKey_consumerUserType_returnExpectedString() { 115 final ContentValues values = getContentValuesWithType( 116 ConvertUtils.CONSUMER_TYPE_USER_BATTERY); 117 values.put(BatteryHistEntry.KEY_USER_ID, 2); 118 final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values); 119 120 assertThat(batteryHistEntry.getKey()).isEqualTo("U|2"); 121 } 122 123 @Test testGetKey_consumerSystemType_returnExpectedString()124 public void testGetKey_consumerSystemType_returnExpectedString() { 125 final ContentValues values = getContentValuesWithType( 126 ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY); 127 values.put(BatteryHistEntry.KEY_DRAIN_TYPE, 1); 128 final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values); 129 130 assertThat(batteryHistEntry.getKey()).isEqualTo("S|1"); 131 } 132 133 @Test testIsAppEntry_returnExpectedResult()134 public void testIsAppEntry_returnExpectedResult() { 135 assertThat(createEntry(ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY).isAppEntry()) 136 .isFalse(); 137 assertThat(createEntry(ConvertUtils.CONSUMER_TYPE_USER_BATTERY).isAppEntry()) 138 .isFalse(); 139 assertThat(createEntry(ConvertUtils.CONSUMER_TYPE_UID_BATTERY).isAppEntry()) 140 .isTrue(); 141 } 142 143 @Test testIsUserEntry_returnExpectedResult()144 public void testIsUserEntry_returnExpectedResult() { 145 assertThat(createEntry(ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY).isUserEntry()) 146 .isFalse(); 147 assertThat(createEntry(ConvertUtils.CONSUMER_TYPE_USER_BATTERY).isUserEntry()) 148 .isTrue(); 149 assertThat(createEntry(ConvertUtils.CONSUMER_TYPE_UID_BATTERY).isUserEntry()) 150 .isFalse(); 151 } 152 153 @Test testIsSystemEntry_returnExpectedResult()154 public void testIsSystemEntry_returnExpectedResult() { 155 assertThat(createEntry(ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY).isSystemEntry()) 156 .isTrue(); 157 assertThat(createEntry(ConvertUtils.CONSUMER_TYPE_USER_BATTERY).isSystemEntry()) 158 .isFalse(); 159 assertThat(createEntry(ConvertUtils.CONSUMER_TYPE_UID_BATTERY).isSystemEntry()) 160 .isFalse(); 161 } 162 163 @Test testInterpolate_returnExpectedResult()164 public void testInterpolate_returnExpectedResult() { 165 final long slotTimestamp = 200L; 166 final long upperTimestamp = 300L; 167 final long lowerTimestamp = 100L; 168 final double ratio = 0.5; 169 final BatteryHistEntry lowerHistEntry = createBatteryHistEntry( 170 /*bootTimestamp=*/ 1000L, 171 lowerTimestamp, 172 /*totalPower=*/ 50, 173 /*consumePower=*/ 10, 174 /*foregroundUsageTimeInMs=*/ 100, 175 /*backgroundUsageTimeInMs=*/ 200, 176 /*batteryLevel=*/ 90); 177 final BatteryHistEntry upperHistEntry = createBatteryHistEntry( 178 /*bootTimestamp=*/ 1200L, 179 upperTimestamp, 180 /*totalPower=*/ 80, 181 /*consumePower=*/ 20, 182 /*foregroundUsageTimeInMs=*/ 200, 183 /*backgroundUsageTimeInMs=*/ 300, 184 /*batteryLevel=*/ 80); 185 186 final BatteryHistEntry newEntry = 187 BatteryHistEntry.interpolate( 188 slotTimestamp, 189 upperTimestamp, 190 ratio, 191 lowerHistEntry, 192 upperHistEntry); 193 194 assertBatteryHistEntry( 195 newEntry, 3, upperHistEntry.mPercentOfTotal, 196 /*bootTimestamp=*/ 1200 - 100, 197 /*timestamp=*/ slotTimestamp, 198 /*totalPower=*/ 50 + 0.5 * (80 - 50), 199 /*consumePower=*/ 10 + 0.5 * (20 - 10), 200 /*foregroundUsageTimeInMs=*/ Math.round(100 + 0.5 * (200 - 100)), 201 /*backgroundUsageTimeInMs=*/ Math.round(200 + 0.5 * (300 - 200)), 202 /*batteryLevel=*/ (int) Math.round(90 + 0.5 * (80 - 90))); 203 } 204 205 @Test testInterpolate_withoutLowerEntryData_returnExpectedResult()206 public void testInterpolate_withoutLowerEntryData_returnExpectedResult() { 207 final long slotTimestamp = 200L; 208 final long upperTimestamp = 300L; 209 final long lowerTimestamp = 100L; 210 final double ratio = 0.5; 211 final BatteryHistEntry upperHistEntry = createBatteryHistEntry( 212 /*bootTimestamp=*/ 1200L, 213 upperTimestamp, 214 /*totalPower=*/ 80, 215 /*consumePower=*/ 20, 216 /*foregroundUsageTimeInMs=*/ 200, 217 /*backgroundUsageTimeInMs=*/ 300, 218 /*batteryLevel=*/ 80); 219 220 final BatteryHistEntry newEntry = 221 BatteryHistEntry.interpolate( 222 slotTimestamp, 223 upperTimestamp, 224 ratio, 225 /*lowerHistEntry=*/ null, 226 upperHistEntry); 227 228 assertBatteryHistEntry( 229 newEntry, 3, upperHistEntry.mPercentOfTotal, 230 /*bootTimestamp=*/ 1200 - 100, 231 /*timestamp=*/ slotTimestamp, 232 /*totalPower=*/ 0.5 * 80, 233 /*consumePower=*/ 0.5 * 20, 234 /*foregroundUsageTimeInMs=*/ Math.round(0.5 * 200), 235 /*backgroundUsageTimeInMs=*/ Math.round(0.5 * 300), 236 /*batteryLevel=*/ upperHistEntry.mBatteryLevel); 237 } 238 createEntry(int consumerType)239 private static BatteryHistEntry createEntry(int consumerType) { 240 return new BatteryHistEntry(getContentValuesWithType(consumerType)); 241 } 242 getContentValuesWithType(int consumerType)243 private static ContentValues getContentValuesWithType(int consumerType) { 244 final ContentValues values = new ContentValues(); 245 values.put(BatteryHistEntry.KEY_CONSUMER_TYPE, 246 Integer.valueOf(consumerType)); 247 return values; 248 } 249 assertBatteryHistEntry( BatteryHistEntry entry, int drainType, double percentOfTotal)250 private void assertBatteryHistEntry( 251 BatteryHistEntry entry, int drainType, double percentOfTotal) { 252 assertBatteryHistEntry( 253 entry, drainType, percentOfTotal, 254 /*bootTimestamp=*/ 101L, 255 /*timestamp=*/ 10001L, 256 /*totalPower=*/ 5.1, 257 /*consumePower=*/ 1.1, 258 /*foregroundUsageTimeInMs=*/ 1234L, 259 /*backgroundUsageTimeInMs=*/ 5689L, 260 /*batteryLevel=*/ 12); 261 } 262 assertBatteryHistEntry( BatteryHistEntry entry, int drainType, double percentOfTotal, long bootTimestamp, long timestamp, double totalPower, double consumePower, long foregroundUsageTimeInMs, long backgroundUsageTimeInMs, int batteryLevel)263 private void assertBatteryHistEntry( 264 BatteryHistEntry entry, 265 int drainType, 266 double percentOfTotal, 267 long bootTimestamp, 268 long timestamp, 269 double totalPower, 270 double consumePower, 271 long foregroundUsageTimeInMs, 272 long backgroundUsageTimeInMs, 273 int batteryLevel) { 274 assertThat(entry.isValidEntry()).isTrue(); 275 assertThat(entry.mUid).isEqualTo(1001); 276 assertThat(entry.mUserId).isEqualTo(UserHandle.getUserId(1001)); 277 assertThat(entry.mAppLabel).isEqualTo("Settings"); 278 assertThat(entry.mPackageName) 279 .isEqualTo("com.google.android.settings.battery"); 280 assertThat(entry.mIsHidden).isTrue(); 281 assertThat(entry.mBootTimestamp).isEqualTo(bootTimestamp); 282 assertThat(entry.mTimestamp).isEqualTo(timestamp); 283 assertThat(entry.mZoneId).isEqualTo(TimeZone.getDefault().getID()); 284 assertThat(entry.mTotalPower).isEqualTo(totalPower); 285 assertThat(entry.mConsumePower).isEqualTo(consumePower); 286 assertThat(entry.mPercentOfTotal).isEqualTo(percentOfTotal); 287 assertThat(entry.mForegroundUsageTimeInMs).isEqualTo(foregroundUsageTimeInMs); 288 assertThat(entry.mBackgroundUsageTimeInMs).isEqualTo(backgroundUsageTimeInMs); 289 assertThat(entry.mDrainType).isEqualTo(drainType); 290 assertThat(entry.mConsumerType) 291 .isEqualTo(ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY); 292 assertThat(entry.mBatteryLevel).isEqualTo(batteryLevel); 293 assertThat(entry.mBatteryStatus) 294 .isEqualTo(BatteryManager.BATTERY_STATUS_FULL); 295 assertThat(entry.mBatteryHealth) 296 .isEqualTo(BatteryManager.BATTERY_HEALTH_COLD); 297 } 298 createBatteryHistEntry( long bootTimestamp, long timestamp, double totalPower, double consumePower, long foregroundUsageTimeInMs, long backgroundUsageTimeInMs, int batteryLevel)299 private BatteryHistEntry createBatteryHistEntry( 300 long bootTimestamp, 301 long timestamp, 302 double totalPower, 303 double consumePower, 304 long foregroundUsageTimeInMs, 305 long backgroundUsageTimeInMs, 306 int batteryLevel) { 307 final MatrixCursor cursor = new MatrixCursor( 308 new String[] { 309 BatteryHistEntry.KEY_UID, 310 BatteryHistEntry.KEY_USER_ID, 311 BatteryHistEntry.KEY_APP_LABEL, 312 BatteryHistEntry.KEY_PACKAGE_NAME, 313 BatteryHistEntry.KEY_IS_HIDDEN, 314 BatteryHistEntry.KEY_BOOT_TIMESTAMP, 315 BatteryHistEntry.KEY_TIMESTAMP, 316 BatteryHistEntry.KEY_ZONE_ID, 317 BatteryHistEntry.KEY_TOTAL_POWER, 318 BatteryHistEntry.KEY_CONSUME_POWER, 319 BatteryHistEntry.KEY_PERCENT_OF_TOTAL, 320 BatteryHistEntry.KEY_FOREGROUND_USAGE_TIME, 321 BatteryHistEntry.KEY_BACKGROUND_USAGE_TIME, 322 BatteryHistEntry.KEY_DRAIN_TYPE, 323 BatteryHistEntry.KEY_CONSUMER_TYPE, 324 BatteryHistEntry.KEY_BATTERY_LEVEL, 325 BatteryHistEntry.KEY_BATTERY_STATUS, 326 BatteryHistEntry.KEY_BATTERY_HEALTH}); 327 cursor.addRow( 328 new Object[] { 329 Long.valueOf(1001), 330 Long.valueOf(UserHandle.getUserId(1001)), 331 "Settings", 332 "com.google.android.settings.battery", 333 Integer.valueOf(1), 334 Long.valueOf(bootTimestamp), 335 Long.valueOf(timestamp), 336 TimeZone.getDefault().getID(), 337 Double.valueOf(totalPower), 338 Double.valueOf(consumePower), 339 Double.valueOf(0.3), 340 Long.valueOf(foregroundUsageTimeInMs), 341 Long.valueOf(backgroundUsageTimeInMs), 342 Integer.valueOf(3), 343 Integer.valueOf(ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY), 344 Integer.valueOf(batteryLevel), 345 Integer.valueOf(BatteryManager.BATTERY_STATUS_FULL), 346 Integer.valueOf(BatteryManager.BATTERY_HEALTH_COLD)}); 347 cursor.moveToFirst(); 348 return new BatteryHistEntry(cursor); 349 } 350 } 351