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 17 package com.android.settings.fuelgauge; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.mockito.ArgumentMatchers.any; 22 import static org.mockito.Matchers.anyInt; 23 import static org.mockito.Matchers.anyLong; 24 import static org.mockito.Mockito.doReturn; 25 import static org.mockito.Mockito.never; 26 import static org.mockito.Mockito.spy; 27 import static org.mockito.Mockito.verify; 28 import static org.mockito.Mockito.when; 29 30 import android.app.settings.SettingsEnums; 31 import android.content.Context; 32 import android.content.ContentValues; 33 import android.content.pm.PackageManager; 34 import android.content.res.Configuration; 35 import android.content.res.Resources; 36 import android.graphics.drawable.Drawable; 37 import android.os.Bundle; 38 import android.os.LocaleList; 39 import android.text.format.DateUtils; 40 import android.util.Pair; 41 42 import androidx.preference.Preference; 43 import androidx.preference.PreferenceCategory; 44 import androidx.preference.PreferenceGroup; 45 46 import com.android.settings.R; 47 import com.android.settings.SettingsActivity; 48 import com.android.settings.core.InstrumentedPreferenceFragment; 49 import com.android.settings.testutils.FakeFeatureFactory; 50 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; 51 52 import org.junit.Before; 53 import org.junit.Test; 54 import org.junit.runner.RunWith; 55 import org.mockito.ArgumentCaptor; 56 import org.mockito.Mock; 57 import org.mockito.MockitoAnnotations; 58 import org.robolectric.RobolectricTestRunner; 59 import org.robolectric.RuntimeEnvironment; 60 61 import java.util.Arrays; 62 import java.util.ArrayList; 63 import java.util.HashMap; 64 import java.util.Locale; 65 import java.util.List; 66 import java.util.Map; 67 68 @RunWith(RobolectricTestRunner.class) 69 public final class BatteryChartPreferenceControllerTest { 70 private static final String PREF_KEY = "pref_key"; 71 private static final String PREF_SUMMARY = "fake preference summary"; 72 private static final int DESIRED_HISTORY_SIZE = 73 BatteryChartPreferenceController.DESIRED_HISTORY_SIZE; 74 75 @Mock private InstrumentedPreferenceFragment mFragment; 76 @Mock private SettingsActivity mSettingsActivity; 77 @Mock private PreferenceGroup mAppListGroup; 78 @Mock private PackageManager mPackageManager; 79 @Mock private Drawable mDrawable; 80 @Mock private BatteryHistEntry mBatteryHistEntry; 81 @Mock private BatteryChartView mBatteryChartView; 82 @Mock private PowerGaugePreference mPowerGaugePreference; 83 @Mock private ExpandDividerPreference mExpandDividerPreference; 84 @Mock private BatteryUtils mBatteryUtils; 85 @Mock private Configuration mConfiguration; 86 @Mock private Resources mResources; 87 88 private Context mContext; 89 private FakeFeatureFactory mFeatureFactory; 90 private BatteryDiffEntry mBatteryDiffEntry; 91 private MetricsFeatureProvider mMetricsFeatureProvider; 92 private BatteryChartPreferenceController mBatteryChartPreferenceController; 93 94 @Before setUp()95 public void setUp() { 96 MockitoAnnotations.initMocks(this); 97 Locale.setDefault(new Locale("en_US")); 98 org.robolectric.shadows.ShadowSettings.set24HourTimeFormat(false); 99 mFeatureFactory = FakeFeatureFactory.setupForTest(); 100 mMetricsFeatureProvider = mFeatureFactory.metricsFeatureProvider; 101 mContext = spy(RuntimeEnvironment.application); 102 final Resources resources = spy(mContext.getResources()); 103 resources.getConfiguration().setLocales(new LocaleList(new Locale("en_US"))); 104 doReturn(resources).when(mContext).getResources(); 105 doReturn(new String[] {"com.android.googlequicksearchbox"}) 106 .when(mFeatureFactory.powerUsageFeatureProvider) 107 .getHideApplicationSummary(mContext); 108 doReturn(new String[] {"com.android.gms.persistent"}) 109 .when(mFeatureFactory.powerUsageFeatureProvider) 110 .getHideApplicationEntries(mContext); 111 mBatteryChartPreferenceController = createController(); 112 mBatteryChartPreferenceController.mPrefContext = mContext; 113 mBatteryChartPreferenceController.mAppListPrefGroup = mAppListGroup; 114 mBatteryChartPreferenceController.mBatteryChartView = mBatteryChartView; 115 mBatteryDiffEntry = new BatteryDiffEntry( 116 mContext, 117 /*foregroundUsageTimeInMs=*/ 1, 118 /*backgroundUsageTimeInMs=*/ 2, 119 /*consumePower=*/ 3, 120 mBatteryHistEntry); 121 mBatteryDiffEntry = spy(mBatteryDiffEntry); 122 // Adds fake testing data. 123 BatteryDiffEntry.sResourceCache.put( 124 "fakeBatteryDiffEntryKey", 125 new BatteryEntry.NameAndIcon("fakeName", /*icon=*/ null, /*iconId=*/ 1)); 126 mBatteryChartPreferenceController.setBatteryHistoryMap( 127 createBatteryHistoryMap()); 128 } 129 130 @Test testOnDestroy_activityIsChanging_clearBatteryEntryCache()131 public void testOnDestroy_activityIsChanging_clearBatteryEntryCache() { 132 doReturn(true).when(mSettingsActivity).isChangingConfigurations(); 133 // Ensures the testing environment is correct. 134 assertThat(BatteryDiffEntry.sResourceCache).hasSize(1); 135 136 mBatteryChartPreferenceController.onDestroy(); 137 assertThat(BatteryDiffEntry.sResourceCache).isEmpty(); 138 } 139 140 @Test testOnDestroy_activityIsNotChanging_notClearBatteryEntryCache()141 public void testOnDestroy_activityIsNotChanging_notClearBatteryEntryCache() { 142 doReturn(false).when(mSettingsActivity).isChangingConfigurations(); 143 // Ensures the testing environment is correct. 144 assertThat(BatteryDiffEntry.sResourceCache).hasSize(1); 145 146 mBatteryChartPreferenceController.onDestroy(); 147 assertThat(BatteryDiffEntry.sResourceCache).isNotEmpty(); 148 } 149 150 @Test testOnDestroy_clearPreferenceCache()151 public void testOnDestroy_clearPreferenceCache() { 152 // Ensures the testing environment is correct. 153 mBatteryChartPreferenceController.mPreferenceCache.put( 154 PREF_KEY, mPowerGaugePreference); 155 assertThat(mBatteryChartPreferenceController.mPreferenceCache).hasSize(1); 156 157 mBatteryChartPreferenceController.onDestroy(); 158 // Verifies the result after onDestroy. 159 assertThat(mBatteryChartPreferenceController.mPreferenceCache).isEmpty(); 160 } 161 162 @Test testOnDestroy_removeAllPreferenceFromPreferenceGroup()163 public void testOnDestroy_removeAllPreferenceFromPreferenceGroup() { 164 mBatteryChartPreferenceController.onDestroy(); 165 verify(mAppListGroup).removeAll(); 166 } 167 168 @Test testSetBatteryHistoryMap_createExpectedKeysAndLevels()169 public void testSetBatteryHistoryMap_createExpectedKeysAndLevels() { 170 mBatteryChartPreferenceController.setBatteryHistoryMap( 171 createBatteryHistoryMap()); 172 173 // Verifies the created battery keys array. 174 for (int index = 0; index < DESIRED_HISTORY_SIZE; index++) { 175 assertThat(mBatteryChartPreferenceController.mBatteryHistoryKeys[index]) 176 // These values is are calculated by hand from createBatteryHistoryMap(). 177 .isEqualTo(index + 1); 178 } 179 // Verifies the created battery levels array. 180 for (int index = 0; index < 13; index++) { 181 assertThat(mBatteryChartPreferenceController.mBatteryHistoryLevels[index]) 182 // These values is are calculated by hand from createBatteryHistoryMap(). 183 .isEqualTo(100 - index * 2); 184 } 185 assertThat(mBatteryChartPreferenceController.mBatteryIndexedMap).hasSize(13); 186 } 187 188 @Test testSetBatteryHistoryMap_largeSize_createExpectedKeysAndLevels()189 public void testSetBatteryHistoryMap_largeSize_createExpectedKeysAndLevels() { 190 mBatteryChartPreferenceController.setBatteryHistoryMap( 191 createBatteryHistoryMap()); 192 193 // Verifies the created battery keys array. 194 for (int index = 0; index < DESIRED_HISTORY_SIZE; index++) { 195 assertThat(mBatteryChartPreferenceController.mBatteryHistoryKeys[index]) 196 // These values is are calculated by hand from createBatteryHistoryMap(). 197 .isEqualTo(index + 1); 198 } 199 // Verifies the created battery levels array. 200 for (int index = 0; index < 13; index++) { 201 assertThat(mBatteryChartPreferenceController.mBatteryHistoryLevels[index]) 202 // These values is are calculated by hand from createBatteryHistoryMap(). 203 .isEqualTo(100 - index * 2); 204 } 205 assertThat(mBatteryChartPreferenceController.mBatteryIndexedMap).hasSize(13); 206 } 207 208 @Test testRefreshUi_batteryIndexedMapIsNull_ignoreRefresh()209 public void testRefreshUi_batteryIndexedMapIsNull_ignoreRefresh() { 210 mBatteryChartPreferenceController.setBatteryHistoryMap(null); 211 assertThat(mBatteryChartPreferenceController.refreshUi( 212 /*trapezoidIndex=*/ 1, /*isForce=*/ false)).isFalse(); 213 } 214 215 @Test testRefreshUi_batteryChartViewIsNull_ignoreRefresh()216 public void testRefreshUi_batteryChartViewIsNull_ignoreRefresh() { 217 mBatteryChartPreferenceController.mBatteryChartView = null; 218 assertThat(mBatteryChartPreferenceController.refreshUi( 219 /*trapezoidIndex=*/ 1, /*isForce=*/ false)).isFalse(); 220 } 221 222 @Test testRefreshUi_trapezoidIndexIsNotChanged_ignoreRefresh()223 public void testRefreshUi_trapezoidIndexIsNotChanged_ignoreRefresh() { 224 final int trapezoidIndex = 1; 225 mBatteryChartPreferenceController.mTrapezoidIndex = trapezoidIndex; 226 assertThat(mBatteryChartPreferenceController.refreshUi( 227 trapezoidIndex, /*isForce=*/ false)).isFalse(); 228 } 229 230 @Test testRefreshUi_forceUpdate_refreshUi()231 public void testRefreshUi_forceUpdate_refreshUi() { 232 final int trapezoidIndex = 1; 233 mBatteryChartPreferenceController.mTrapezoidIndex = trapezoidIndex; 234 assertThat(mBatteryChartPreferenceController.refreshUi( 235 trapezoidIndex, /*isForce=*/ true)).isTrue(); 236 } 237 238 @Test testForceRefreshUi_updateTrapezoidIndexIntoSelectAll()239 public void testForceRefreshUi_updateTrapezoidIndexIntoSelectAll() { 240 mBatteryChartPreferenceController.mTrapezoidIndex = 241 BatteryChartView.SELECTED_INDEX_INVALID; 242 mBatteryChartPreferenceController.setBatteryHistoryMap( 243 createBatteryHistoryMap()); 244 245 assertThat(mBatteryChartPreferenceController.mTrapezoidIndex) 246 .isEqualTo(BatteryChartView.SELECTED_INDEX_ALL); 247 } 248 249 @Test testRemoveAndCacheAllPrefs_emptyContent_ignoreRemoveAll()250 public void testRemoveAndCacheAllPrefs_emptyContent_ignoreRemoveAll() { 251 final int trapezoidIndex = 1; 252 doReturn(0).when(mAppListGroup).getPreferenceCount(); 253 254 mBatteryChartPreferenceController.refreshUi( 255 trapezoidIndex, /*isForce=*/ true); 256 verify(mAppListGroup, never()).removeAll(); 257 } 258 259 @Test testRemoveAndCacheAllPrefs_buildCacheAndRemoveAllPreference()260 public void testRemoveAndCacheAllPrefs_buildCacheAndRemoveAllPreference() { 261 final int trapezoidIndex = 1; 262 doReturn(1).when(mAppListGroup).getPreferenceCount(); 263 doReturn(mPowerGaugePreference).when(mAppListGroup).getPreference(0); 264 doReturn(PREF_KEY).when(mPowerGaugePreference).getKey(); 265 // Ensures the testing data is correct. 266 assertThat(mBatteryChartPreferenceController.mPreferenceCache).isEmpty(); 267 268 mBatteryChartPreferenceController.refreshUi( 269 trapezoidIndex, /*isForce=*/ true); 270 271 assertThat(mBatteryChartPreferenceController.mPreferenceCache.get(PREF_KEY)) 272 .isEqualTo(mPowerGaugePreference); 273 verify(mAppListGroup).removeAll(); 274 } 275 276 @Test testAddPreferenceToScreen_emptyContent_ignoreAddPreference()277 public void testAddPreferenceToScreen_emptyContent_ignoreAddPreference() { 278 mBatteryChartPreferenceController.addPreferenceToScreen( 279 new ArrayList<BatteryDiffEntry>()); 280 verify(mAppListGroup, never()).addPreference(any()); 281 } 282 283 @Test testAddPreferenceToScreen_addPreferenceIntoScreen()284 public void testAddPreferenceToScreen_addPreferenceIntoScreen() { 285 final String appLabel = "fake app label"; 286 doReturn(1).when(mAppListGroup).getPreferenceCount(); 287 doReturn(mDrawable).when(mBatteryDiffEntry).getAppIcon(); 288 doReturn(appLabel).when(mBatteryDiffEntry).getAppLabel(); 289 doReturn(PREF_KEY).when(mBatteryHistEntry).getKey(); 290 doReturn(null).when(mAppListGroup).findPreference(PREF_KEY); 291 doReturn(false).when(mBatteryDiffEntry).validForRestriction(); 292 293 mBatteryChartPreferenceController.addPreferenceToScreen( 294 Arrays.asList(mBatteryDiffEntry)); 295 296 // Verifies the preference cache. 297 final PowerGaugePreference pref = 298 (PowerGaugePreference) mBatteryChartPreferenceController.mPreferenceCache 299 .get(PREF_KEY); 300 assertThat(pref).isNotNull(); 301 // Verifies the added preference configuration. 302 verify(mAppListGroup).addPreference(pref); 303 assertThat(pref.getKey()).isEqualTo(PREF_KEY); 304 assertThat(pref.getTitle()).isEqualTo(appLabel); 305 assertThat(pref.getIcon()).isEqualTo(mDrawable); 306 assertThat(pref.getOrder()).isEqualTo(1); 307 assertThat(pref.getBatteryDiffEntry()).isSameInstanceAs(mBatteryDiffEntry); 308 assertThat(pref.isSingleLineTitle()).isTrue(); 309 assertThat(pref.isEnabled()).isFalse(); 310 } 311 312 @Test testAddPreferenceToScreen_alreadyInScreen_notAddPreferenceAgain()313 public void testAddPreferenceToScreen_alreadyInScreen_notAddPreferenceAgain() { 314 final String appLabel = "fake app label"; 315 doReturn(1).when(mAppListGroup).getPreferenceCount(); 316 doReturn(mDrawable).when(mBatteryDiffEntry).getAppIcon(); 317 doReturn(appLabel).when(mBatteryDiffEntry).getAppLabel(); 318 doReturn(PREF_KEY).when(mBatteryHistEntry).getKey(); 319 doReturn(mPowerGaugePreference).when(mAppListGroup).findPreference(PREF_KEY); 320 321 mBatteryChartPreferenceController.addPreferenceToScreen( 322 Arrays.asList(mBatteryDiffEntry)); 323 324 verify(mAppListGroup, never()).addPreference(any()); 325 } 326 327 @Test testHandlePreferenceTreeiClick_notPowerGaugePreference_returnFalse()328 public void testHandlePreferenceTreeiClick_notPowerGaugePreference_returnFalse() { 329 assertThat(mBatteryChartPreferenceController.handlePreferenceTreeClick(mAppListGroup)) 330 .isFalse(); 331 332 verify(mMetricsFeatureProvider, never()) 333 .action(mContext, SettingsEnums.ACTION_BATTERY_USAGE_APP_ITEM); 334 verify(mMetricsFeatureProvider, never()) 335 .action(mContext, SettingsEnums.ACTION_BATTERY_USAGE_SYSTEM_ITEM); 336 } 337 338 @Test testHandlePreferenceTreeClick_forAppEntry_returnTrue()339 public void testHandlePreferenceTreeClick_forAppEntry_returnTrue() { 340 doReturn(false).when(mBatteryHistEntry).isAppEntry(); 341 doReturn(mBatteryDiffEntry).when(mPowerGaugePreference).getBatteryDiffEntry(); 342 343 assertThat(mBatteryChartPreferenceController.handlePreferenceTreeClick( 344 mPowerGaugePreference)).isTrue(); 345 verify(mMetricsFeatureProvider) 346 .action( 347 SettingsEnums.OPEN_BATTERY_USAGE, 348 SettingsEnums.ACTION_BATTERY_USAGE_SYSTEM_ITEM, 349 SettingsEnums.OPEN_BATTERY_USAGE, 350 /* package name */ "none", 351 /* percentage of total */ 0); 352 } 353 354 @Test testHandlePreferenceTreeClick_forSystemEntry_returnTrue()355 public void testHandlePreferenceTreeClick_forSystemEntry_returnTrue() { 356 mBatteryChartPreferenceController.mBatteryUtils = mBatteryUtils; 357 doReturn(true).when(mBatteryHistEntry).isAppEntry(); 358 doReturn(mBatteryDiffEntry).when(mPowerGaugePreference).getBatteryDiffEntry(); 359 360 assertThat(mBatteryChartPreferenceController.handlePreferenceTreeClick( 361 mPowerGaugePreference)).isTrue(); 362 verify(mMetricsFeatureProvider) 363 .action( 364 SettingsEnums.OPEN_BATTERY_USAGE, 365 SettingsEnums.ACTION_BATTERY_USAGE_APP_ITEM, 366 SettingsEnums.OPEN_BATTERY_USAGE, 367 /* package name */ "none", 368 /* percentage of total */ 0); 369 } 370 371 @Test testSetPreferenceSummary_setNullContentIfTotalUsageTimeIsZero()372 public void testSetPreferenceSummary_setNullContentIfTotalUsageTimeIsZero() { 373 final PowerGaugePreference pref = new PowerGaugePreference(mContext); 374 pref.setSummary(PREF_SUMMARY); 375 376 mBatteryChartPreferenceController.setPreferenceSummary( 377 pref, createBatteryDiffEntry( 378 /*foregroundUsageTimeInMs=*/ 0, 379 /*backgroundUsageTimeInMs=*/ 0)); 380 assertThat(pref.getSummary()).isNull(); 381 } 382 383 @Test testSetPreferenceSummary_setBackgroundUsageTimeOnly()384 public void testSetPreferenceSummary_setBackgroundUsageTimeOnly() { 385 final PowerGaugePreference pref = new PowerGaugePreference(mContext); 386 pref.setSummary(PREF_SUMMARY); 387 388 mBatteryChartPreferenceController.setPreferenceSummary( 389 pref, createBatteryDiffEntry( 390 /*foregroundUsageTimeInMs=*/ 0, 391 /*backgroundUsageTimeInMs=*/ DateUtils.MINUTE_IN_MILLIS)); 392 assertThat(pref.getSummary()).isEqualTo("Background: 1 min"); 393 } 394 395 @Test testSetPreferenceSummary_setTotalUsageTimeLessThanAMinute()396 public void testSetPreferenceSummary_setTotalUsageTimeLessThanAMinute() { 397 final PowerGaugePreference pref = new PowerGaugePreference(mContext); 398 pref.setSummary(PREF_SUMMARY); 399 400 mBatteryChartPreferenceController.setPreferenceSummary( 401 pref, createBatteryDiffEntry( 402 /*foregroundUsageTimeInMs=*/ 100, 403 /*backgroundUsageTimeInMs=*/ 200)); 404 assertThat(pref.getSummary()).isEqualTo("Total: less than a min"); 405 } 406 407 @Test testSetPreferenceSummary_setTotalTimeIfBackgroundTimeLessThanAMinute()408 public void testSetPreferenceSummary_setTotalTimeIfBackgroundTimeLessThanAMinute() { 409 final PowerGaugePreference pref = new PowerGaugePreference(mContext); 410 pref.setSummary(PREF_SUMMARY); 411 412 mBatteryChartPreferenceController.setPreferenceSummary( 413 pref, createBatteryDiffEntry( 414 /*foregroundUsageTimeInMs=*/ DateUtils.MINUTE_IN_MILLIS, 415 /*backgroundUsageTimeInMs=*/ 200)); 416 assertThat(pref.getSummary()) 417 .isEqualTo("Total: 1 min\nBackground: less than a min"); 418 } 419 420 @Test testSetPreferenceSummary_setTotalAndBackgroundUsageTime()421 public void testSetPreferenceSummary_setTotalAndBackgroundUsageTime() { 422 final PowerGaugePreference pref = new PowerGaugePreference(mContext); 423 pref.setSummary(PREF_SUMMARY); 424 425 mBatteryChartPreferenceController.setPreferenceSummary( 426 pref, createBatteryDiffEntry( 427 /*foregroundUsageTimeInMs=*/ DateUtils.MINUTE_IN_MILLIS, 428 /*backgroundUsageTimeInMs=*/ DateUtils.MINUTE_IN_MILLIS)); 429 assertThat(pref.getSummary()).isEqualTo("Total: 2 min\nBackground: 1 min"); 430 } 431 432 @Test testSetPreferenceSummary_notAllowShownPackage_setSummayAsNull()433 public void testSetPreferenceSummary_notAllowShownPackage_setSummayAsNull() { 434 final PowerGaugePreference pref = new PowerGaugePreference(mContext); 435 pref.setSummary(PREF_SUMMARY); 436 final BatteryDiffEntry batteryDiffEntry = 437 spy(createBatteryDiffEntry( 438 /*foregroundUsageTimeInMs=*/ DateUtils.MINUTE_IN_MILLIS, 439 /*backgroundUsageTimeInMs=*/ DateUtils.MINUTE_IN_MILLIS)); 440 doReturn("com.android.googlequicksearchbox").when(batteryDiffEntry) 441 .getPackageName(); 442 443 mBatteryChartPreferenceController.setPreferenceSummary(pref, batteryDiffEntry); 444 assertThat(pref.getSummary()).isNull(); 445 } 446 447 @Test testValidateUsageTime_returnTrueIfBatteryDiffEntryIsValid()448 public void testValidateUsageTime_returnTrueIfBatteryDiffEntryIsValid() { 449 assertThat(BatteryChartPreferenceController.validateUsageTime( 450 createBatteryDiffEntry( 451 /*foregroundUsageTimeInMs=*/ DateUtils.MINUTE_IN_MILLIS, 452 /*backgroundUsageTimeInMs=*/ DateUtils.MINUTE_IN_MILLIS))) 453 .isTrue(); 454 } 455 456 @Test testValidateUsageTime_foregroundTimeExceedThreshold_returnFalse()457 public void testValidateUsageTime_foregroundTimeExceedThreshold_returnFalse() { 458 assertThat(BatteryChartPreferenceController.validateUsageTime( 459 createBatteryDiffEntry( 460 /*foregroundUsageTimeInMs=*/ DateUtils.HOUR_IN_MILLIS * 3, 461 /*backgroundUsageTimeInMs=*/ 0))) 462 .isFalse(); 463 } 464 465 @Test testValidateUsageTime_backgroundTimeExceedThreshold_returnFalse()466 public void testValidateUsageTime_backgroundTimeExceedThreshold_returnFalse() { 467 assertThat(BatteryChartPreferenceController.validateUsageTime( 468 createBatteryDiffEntry( 469 /*foregroundUsageTimeInMs=*/ 0, 470 /*backgroundUsageTimeInMs=*/ DateUtils.HOUR_IN_MILLIS * 3))) 471 .isFalse(); 472 } 473 474 @Test testOnExpand_expandedIsTrue_addSystemEntriesToPreferenceGroup()475 public void testOnExpand_expandedIsTrue_addSystemEntriesToPreferenceGroup() { 476 doReturn(1).when(mAppListGroup).getPreferenceCount(); 477 mBatteryChartPreferenceController.mSystemEntries.add(mBatteryDiffEntry); 478 doReturn("label").when(mBatteryDiffEntry).getAppLabel(); 479 doReturn(mDrawable).when(mBatteryDiffEntry).getAppIcon(); 480 doReturn(PREF_KEY).when(mBatteryHistEntry).getKey(); 481 482 mBatteryChartPreferenceController.onExpand(/*isExpanded=*/ true); 483 484 final ArgumentCaptor<Preference> captor = ArgumentCaptor.forClass(Preference.class); 485 verify(mAppListGroup).addPreference(captor.capture()); 486 // Verifies the added preference. 487 assertThat(captor.getValue().getKey()).isEqualTo(PREF_KEY); 488 verify(mMetricsFeatureProvider) 489 .action( 490 mContext, 491 SettingsEnums.ACTION_BATTERY_USAGE_EXPAND_ITEM, 492 true /*isExpanded*/); 493 } 494 495 @Test testOnExpand_expandedIsFalse_removeSystemEntriesFromPreferenceGroup()496 public void testOnExpand_expandedIsFalse_removeSystemEntriesFromPreferenceGroup() { 497 doReturn(PREF_KEY).when(mBatteryHistEntry).getKey(); 498 doReturn(mPowerGaugePreference).when(mAppListGroup).findPreference(PREF_KEY); 499 mBatteryChartPreferenceController.mSystemEntries.add(mBatteryDiffEntry); 500 // Verifies the cache is empty first. 501 assertThat(mBatteryChartPreferenceController.mPreferenceCache).isEmpty(); 502 503 mBatteryChartPreferenceController.onExpand(/*isExpanded=*/ false); 504 505 verify(mAppListGroup).findPreference(PREF_KEY); 506 verify(mAppListGroup).removePreference(mPowerGaugePreference); 507 assertThat(mBatteryChartPreferenceController.mPreferenceCache).hasSize(1); 508 verify(mMetricsFeatureProvider) 509 .action( 510 mContext, 511 SettingsEnums.ACTION_BATTERY_USAGE_EXPAND_ITEM, 512 false /*isExpanded*/); 513 } 514 515 @Test testOnSelect_selectSpecificTimeSlot_logMetric()516 public void testOnSelect_selectSpecificTimeSlot_logMetric() { 517 mBatteryChartPreferenceController.onSelect(1 /*slot index*/); 518 519 verify(mMetricsFeatureProvider) 520 .action(mContext, SettingsEnums.ACTION_BATTERY_USAGE_TIME_SLOT); 521 } 522 523 @Test testOnSelect_selectAll_logMetric()524 public void testOnSelect_selectAll_logMetric() { 525 mBatteryChartPreferenceController.onSelect( 526 BatteryChartView.SELECTED_INDEX_ALL /*slot index*/); 527 528 verify(mMetricsFeatureProvider) 529 .action(mContext, SettingsEnums.ACTION_BATTERY_USAGE_SHOW_ALL); 530 } 531 532 @Test testRefreshCategoryTitle_setHourIntoBothTitleTextView()533 public void testRefreshCategoryTitle_setHourIntoBothTitleTextView() { 534 mBatteryChartPreferenceController = createController(); 535 setUpBatteryHistoryKeys(); 536 mBatteryChartPreferenceController.mAppListPrefGroup = 537 spy(new PreferenceCategory(mContext)); 538 mBatteryChartPreferenceController.mExpandDividerPreference = 539 spy(new ExpandDividerPreference(mContext)); 540 // Simulates select the first slot. 541 mBatteryChartPreferenceController.mTrapezoidIndex = 0; 542 543 mBatteryChartPreferenceController.refreshCategoryTitle(); 544 545 ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class); 546 // Verifies the title in the preference group. 547 verify(mBatteryChartPreferenceController.mAppListPrefGroup) 548 .setTitle(captor.capture()); 549 assertThat(captor.getValue()).isNotEqualTo("App usage for past 24 hr"); 550 // Verifies the title in the expandable divider. 551 captor = ArgumentCaptor.forClass(String.class); 552 verify(mBatteryChartPreferenceController.mExpandDividerPreference) 553 .setTitle(captor.capture()); 554 assertThat(captor.getValue()).isNotEqualTo("System usage for past 24 hr"); 555 } 556 557 @Test testRefreshCategoryTitle_setLast24HrIntoBothTitleTextView()558 public void testRefreshCategoryTitle_setLast24HrIntoBothTitleTextView() { 559 mBatteryChartPreferenceController = createController(); 560 mBatteryChartPreferenceController.mAppListPrefGroup = 561 spy(new PreferenceCategory(mContext)); 562 mBatteryChartPreferenceController.mExpandDividerPreference = 563 spy(new ExpandDividerPreference(mContext)); 564 // Simulates select all condition. 565 mBatteryChartPreferenceController.mTrapezoidIndex = 566 BatteryChartView.SELECTED_INDEX_ALL; 567 568 mBatteryChartPreferenceController.refreshCategoryTitle(); 569 570 ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class); 571 // Verifies the title in the preference group. 572 verify(mBatteryChartPreferenceController.mAppListPrefGroup) 573 .setTitle(captor.capture()); 574 assertThat(captor.getValue()) 575 .isEqualTo("App usage for past 24 hr"); 576 // Verifies the title in the expandable divider. 577 captor = ArgumentCaptor.forClass(String.class); 578 verify(mBatteryChartPreferenceController.mExpandDividerPreference) 579 .setTitle(captor.capture()); 580 assertThat(captor.getValue()) 581 .isEqualTo("System usage for past 24 hr"); 582 } 583 584 @Test testSetTimestampLabel_nullBatteryHistoryKeys_ignore()585 public void testSetTimestampLabel_nullBatteryHistoryKeys_ignore() { 586 mBatteryChartPreferenceController = createController(); 587 mBatteryChartPreferenceController.mBatteryHistoryKeys = null; 588 mBatteryChartPreferenceController.mBatteryChartView = 589 spy(new BatteryChartView(mContext)); 590 mBatteryChartPreferenceController.setTimestampLabel(); 591 592 verify(mBatteryChartPreferenceController.mBatteryChartView, never()) 593 .setLatestTimestamp(anyLong()); 594 } 595 596 @Test testSetTimestampLabel_setExpectedTimestampData()597 public void testSetTimestampLabel_setExpectedTimestampData() { 598 mBatteryChartPreferenceController = createController(); 599 mBatteryChartPreferenceController.mBatteryChartView = 600 spy(new BatteryChartView(mContext)); 601 setUpBatteryHistoryKeys(); 602 603 mBatteryChartPreferenceController.setTimestampLabel(); 604 605 verify(mBatteryChartPreferenceController.mBatteryChartView) 606 .setLatestTimestamp(1619247636826L); 607 } 608 609 @Test testSetTimestampLabel_withoutValidTimestamp_setExpectedTimestampData()610 public void testSetTimestampLabel_withoutValidTimestamp_setExpectedTimestampData() { 611 mBatteryChartPreferenceController = createController(); 612 mBatteryChartPreferenceController.mBatteryChartView = 613 spy(new BatteryChartView(mContext)); 614 mBatteryChartPreferenceController.mBatteryHistoryKeys = new long[] {0L}; 615 616 mBatteryChartPreferenceController.setTimestampLabel(); 617 618 verify(mBatteryChartPreferenceController.mBatteryChartView) 619 .setLatestTimestamp(anyLong()); 620 } 621 622 @Test testOnSaveInstanceState_restoreSelectedIndexAndExpandState()623 public void testOnSaveInstanceState_restoreSelectedIndexAndExpandState() { 624 final int expectedIndex = 1; 625 final boolean isExpanded = true; 626 final Bundle bundle = new Bundle(); 627 mBatteryChartPreferenceController.mTrapezoidIndex = expectedIndex; 628 mBatteryChartPreferenceController.mIsExpanded = isExpanded; 629 mBatteryChartPreferenceController.onSaveInstanceState(bundle); 630 // Replaces the original controller with other values. 631 mBatteryChartPreferenceController.mTrapezoidIndex = -1; 632 mBatteryChartPreferenceController.mIsExpanded = false; 633 634 mBatteryChartPreferenceController.onCreate(bundle); 635 mBatteryChartPreferenceController.setBatteryHistoryMap( 636 createBatteryHistoryMap()); 637 638 assertThat(mBatteryChartPreferenceController.mTrapezoidIndex) 639 .isEqualTo(expectedIndex); 640 assertThat(mBatteryChartPreferenceController.mIsExpanded).isTrue(); 641 } 642 643 @Test testIsValidToShowSummary_returnExpectedResult()644 public void testIsValidToShowSummary_returnExpectedResult() { 645 assertThat(mBatteryChartPreferenceController 646 .isValidToShowSummary("com.google.android.apps.scone")) 647 .isTrue(); 648 649 // Verifies the item which is defined in the array list. 650 assertThat(mBatteryChartPreferenceController 651 .isValidToShowSummary("com.android.googlequicksearchbox")) 652 .isFalse(); 653 } 654 655 @Test testIsValidToShowEntry_returnExpectedResult()656 public void testIsValidToShowEntry_returnExpectedResult() { 657 assertThat(mBatteryChartPreferenceController 658 .isValidToShowEntry("com.google.android.apps.scone")) 659 .isTrue(); 660 661 // Verifies the items which are defined in the array list. 662 assertThat(mBatteryChartPreferenceController 663 .isValidToShowEntry("com.android.gms.persistent")) 664 .isFalse(); 665 } 666 createBatteryHistoryMap()667 private static Map<Long, Map<String, BatteryHistEntry>> createBatteryHistoryMap() { 668 final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap = new HashMap<>(); 669 for (int index = 0; index < DESIRED_HISTORY_SIZE; index++) { 670 final ContentValues values = new ContentValues(); 671 values.put("batteryLevel", Integer.valueOf(100 - index)); 672 final BatteryHistEntry entry = new BatteryHistEntry(values); 673 final Map<String, BatteryHistEntry> entryMap = new HashMap<>(); 674 entryMap.put("fake_entry_key" + index, entry); 675 batteryHistoryMap.put(Long.valueOf(index + 1), entryMap); 676 } 677 return batteryHistoryMap; 678 } 679 createBatteryDiffEntry( long foregroundUsageTimeInMs, long backgroundUsageTimeInMs)680 private BatteryDiffEntry createBatteryDiffEntry( 681 long foregroundUsageTimeInMs, long backgroundUsageTimeInMs) { 682 return new BatteryDiffEntry( 683 mContext, foregroundUsageTimeInMs, backgroundUsageTimeInMs, 684 /*consumePower=*/ 0, mBatteryHistEntry); 685 } 686 setUpBatteryHistoryKeys()687 private void setUpBatteryHistoryKeys() { 688 mBatteryChartPreferenceController.mBatteryHistoryKeys = 689 new long[] {1619196786769L, 0L, 1619247636826L}; 690 ConvertUtils.utcToLocalTimeHour( 691 mContext, /*timestamp=*/ 0, /*is24HourFormat=*/ false); 692 } 693 createController()694 private BatteryChartPreferenceController createController() { 695 final BatteryChartPreferenceController controller = 696 new BatteryChartPreferenceController( 697 mContext, "app_list", /*lifecycle=*/ null, 698 mSettingsActivity, mFragment); 699 controller.mPrefContext = mContext; 700 return controller; 701 } 702 } 703