1 /* 2 * Copyright (C) 2017 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 android.os.BatteryStats.Uid.PROCESS_STATE_BACKGROUND; 19 import static android.os.BatteryStats.Uid.PROCESS_STATE_FOREGROUND; 20 import static android.os.BatteryStats.Uid.PROCESS_STATE_FOREGROUND_SERVICE; 21 import static android.os.BatteryStats.Uid.PROCESS_STATE_TOP; 22 import static android.os.BatteryStats.Uid.PROCESS_STATE_TOP_SLEEPING; 23 24 import static com.google.common.truth.Truth.assertThat; 25 26 import static org.mockito.ArgumentMatchers.any; 27 import static org.mockito.ArgumentMatchers.anyInt; 28 import static org.mockito.ArgumentMatchers.anyLong; 29 import static org.mockito.ArgumentMatchers.eq; 30 import static org.mockito.ArgumentMatchers.nullable; 31 import static org.mockito.Mockito.doReturn; 32 import static org.mockito.Mockito.doThrow; 33 import static org.mockito.Mockito.never; 34 import static org.mockito.Mockito.spy; 35 import static org.mockito.Mockito.verify; 36 import static org.mockito.Mockito.when; 37 38 import android.app.AppOpsManager; 39 import android.content.BroadcastReceiver; 40 import android.content.Context; 41 import android.content.Intent; 42 import android.content.IntentFilter; 43 import android.content.pm.ActivityInfo; 44 import android.content.pm.ApplicationInfo; 45 import android.content.pm.PackageManager; 46 import android.content.pm.ResolveInfo; 47 import android.os.BatteryConsumer; 48 import android.os.BatteryStats; 49 import android.os.BatteryStatsManager; 50 import android.os.BatteryUsageStats; 51 import android.os.Build; 52 import android.os.Process; 53 import android.os.SystemClock; 54 55 import com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper; 56 import com.android.settings.fuelgauge.batterytip.AnomalyInfo; 57 import com.android.settings.fuelgauge.batterytip.BatteryDatabaseManager; 58 import com.android.settings.testutils.FakeFeatureFactory; 59 import com.android.settings.testutils.shadow.ShadowThreadUtils; 60 import com.android.settingslib.fuelgauge.Estimate; 61 import com.android.settingslib.fuelgauge.PowerAllowlistBackend; 62 63 import org.junit.Before; 64 import org.junit.Ignore; 65 import org.junit.Test; 66 import org.junit.runner.RunWith; 67 import org.mockito.Answers; 68 import org.mockito.Mock; 69 import org.mockito.MockitoAnnotations; 70 import org.robolectric.RobolectricTestRunner; 71 import org.robolectric.RuntimeEnvironment; 72 73 import java.util.ArrayList; 74 import java.util.List; 75 76 @RunWith(RobolectricTestRunner.class) 77 public class BatteryUtilsTest { 78 79 private static final String TAG = "BatteryUtilsTest"; 80 81 // unit that used to converted ms to us 82 private static final long UNIT = 1000; 83 private static final long TIME_STATE_TOP = 1500 * UNIT; 84 private static final long TIME_STATE_FOREGROUND_SERVICE = 2000 * UNIT; 85 private static final long TIME_STATE_TOP_SLEEPING = 2500 * UNIT; 86 private static final long TIME_STATE_FOREGROUND = 3000 * UNIT; 87 private static final long TIME_STATE_BACKGROUND = 6000 * UNIT; 88 private static final long TIME_SINCE_LAST_FULL_CHARGE_MS = 120 * 60 * 1000; 89 private static final long TIME_SINCE_LAST_FULL_CHARGE_US = 90 TIME_SINCE_LAST_FULL_CHARGE_MS * 1000; 91 92 private static final int UID = 12345; 93 private static final long TIME_EXPECTED_FOREGROUND = 1500; 94 private static final long TIME_EXPECTED_BACKGROUND = 6000; 95 private static final long TIME_EXPECTED_ALL = 7500; 96 private static final double BATTERY_SYSTEM_USAGE = 600; 97 private static final double TOTAL_BATTERY_USAGE = 1000; 98 private static final int DISCHARGE_AMOUNT = 80; 99 private static final double PERCENT_SYSTEM_USAGE = 48; 100 private static final double PRECISION = 0.001; 101 private static final int SDK_VERSION = Build.VERSION_CODES.L; 102 private static final String PACKAGE_NAME = "com.android.app"; 103 private static final String HIGH_SDK_PACKAGE = "com.android.package.high"; 104 private static final String LOW_SDK_PACKAGE = "com.android.package.low"; 105 106 private static final String INFO_EXCESSIVE = "anomaly_type=4,auto_restriction=false"; 107 private static final String INFO_WAKELOCK = "anomaly_type=1,auto_restriction=false"; 108 109 @Mock 110 private BatteryStats.Uid mUid; 111 @Mock 112 private BatteryStats.Timer mTimer; 113 @Mock 114 private BatteryUsageStats mBatteryUsageStats; 115 @Mock 116 private BatteryConsumer mAggregateBatteryConsumer; 117 @Mock 118 private BatteryInfo mBatteryInfo; 119 @Mock 120 private PackageManager mPackageManager; 121 @Mock 122 private AppOpsManager mAppOpsManager; 123 @Mock 124 private ApplicationInfo mApplicationInfo; 125 @Mock(answer = Answers.RETURNS_DEEP_STUBS) 126 private BatteryStatsManager mBatteryStatsManager; 127 @Mock 128 private ApplicationInfo mHighApplicationInfo; 129 @Mock 130 private ApplicationInfo mLowApplicationInfo; 131 @Mock 132 private PowerAllowlistBackend mPowerAllowlistBackend; 133 @Mock 134 private BatteryDatabaseManager mBatteryDatabaseManager; 135 private AnomalyInfo mAnomalyInfo; 136 private BatteryUtils mBatteryUtils; 137 private FakeFeatureFactory mFeatureFactory; 138 private PowerUsageFeatureProvider mProvider; 139 private Context mContext; 140 141 @Before setUp()142 public void setUp() throws PackageManager.NameNotFoundException { 143 MockitoAnnotations.initMocks(this); 144 145 mFeatureFactory = FakeFeatureFactory.setupForTest(); 146 mProvider = mFeatureFactory.powerUsageFeatureProvider; 147 148 doReturn(TIME_STATE_TOP).when(mUid).getProcessStateTime(eq(PROCESS_STATE_TOP), anyLong(), 149 anyInt()); 150 doReturn(TIME_STATE_FOREGROUND_SERVICE).when(mUid).getProcessStateTime( 151 eq(PROCESS_STATE_FOREGROUND_SERVICE), anyLong(), anyInt()); 152 doReturn(TIME_STATE_TOP_SLEEPING).when(mUid).getProcessStateTime( 153 eq(PROCESS_STATE_TOP_SLEEPING), anyLong(), anyInt()); 154 doReturn(TIME_STATE_FOREGROUND).when(mUid).getProcessStateTime(eq(PROCESS_STATE_FOREGROUND), 155 anyLong(), anyInt()); 156 doReturn(TIME_STATE_BACKGROUND).when(mUid).getProcessStateTime(eq(PROCESS_STATE_BACKGROUND), 157 anyLong(), anyInt()); 158 159 when(mPackageManager.getApplicationInfo(eq(HIGH_SDK_PACKAGE), anyInt())) 160 .thenReturn(mHighApplicationInfo); 161 when(mPackageManager.getApplicationInfo(eq(LOW_SDK_PACKAGE), anyInt())) 162 .thenReturn(mLowApplicationInfo); 163 mHighApplicationInfo.targetSdkVersion = Build.VERSION_CODES.O; 164 mLowApplicationInfo.targetSdkVersion = Build.VERSION_CODES.L; 165 166 mContext = spy(RuntimeEnvironment.application); 167 doReturn(mPackageManager).when(mContext).getPackageManager(); 168 doReturn(mAppOpsManager).when(mContext).getSystemService(Context.APP_OPS_SERVICE); 169 doReturn(mBatteryStatsManager).when(mContext) 170 .getSystemService(Context.BATTERY_STATS_SERVICE); 171 mBatteryUtils = spy(new BatteryUtils(mContext)); 172 mBatteryUtils.mPowerUsageFeatureProvider = mProvider; 173 doReturn(0L).when(mBatteryUtils) 174 .getForegroundServiceTotalTimeUs(any(BatteryStats.Uid.class), anyLong()); 175 mAnomalyInfo = new AnomalyInfo(INFO_WAKELOCK); 176 177 BatteryDatabaseManager.setUpForTest(mBatteryDatabaseManager); 178 ShadowThreadUtils.setIsMainThread(true); 179 } 180 181 @Test testGetProcessTimeMs_typeForeground_timeCorrect()182 public void testGetProcessTimeMs_typeForeground_timeCorrect() { 183 doReturn(TIME_STATE_FOREGROUND + 500).when(mBatteryUtils) 184 .getForegroundActivityTotalTimeUs(eq(mUid), anyLong()); 185 186 final long time = mBatteryUtils.getProcessTimeMs(BatteryUtils.StatusType.FOREGROUND, mUid, 187 BatteryStats.STATS_SINCE_CHARGED); 188 189 assertThat(time).isEqualTo(TIME_EXPECTED_FOREGROUND); 190 } 191 192 @Test testGetProcessTimeMs_typeBackground_timeCorrect()193 public void testGetProcessTimeMs_typeBackground_timeCorrect() { 194 final long time = mBatteryUtils.getProcessTimeMs(BatteryUtils.StatusType.BACKGROUND, mUid, 195 BatteryStats.STATS_SINCE_CHARGED); 196 197 assertThat(time).isEqualTo(TIME_EXPECTED_BACKGROUND); 198 } 199 200 @Test testGetProcessTimeMs_typeAll_timeCorrect()201 public void testGetProcessTimeMs_typeAll_timeCorrect() { 202 doReturn(TIME_STATE_FOREGROUND + 500).when(mBatteryUtils) 203 .getForegroundActivityTotalTimeUs(eq(mUid), anyLong()); 204 205 final long time = mBatteryUtils.getProcessTimeMs(BatteryUtils.StatusType.ALL, mUid, 206 BatteryStats.STATS_SINCE_CHARGED); 207 208 assertThat(time).isEqualTo(TIME_EXPECTED_ALL); 209 } 210 211 @Test testGetProcessTimeMs_uidNull_returnZero()212 public void testGetProcessTimeMs_uidNull_returnZero() { 213 final long time = mBatteryUtils.getProcessTimeMs(BatteryUtils.StatusType.ALL, null, 214 BatteryStats.STATS_SINCE_CHARGED); 215 216 assertThat(time).isEqualTo(0); 217 } 218 219 @Test testShouldHideSystemConsumer_TypeIdle_ReturnTrue()220 public void testShouldHideSystemConsumer_TypeIdle_ReturnTrue() { 221 assertThat(mBatteryUtils.shouldHideDevicePowerComponent(mAggregateBatteryConsumer, 222 BatteryConsumer.POWER_COMPONENT_IDLE)).isTrue(); 223 } 224 225 @Test testShouldHideSystemConsumer_TypeMobileRadio_ReturnTrue()226 public void testShouldHideSystemConsumer_TypeMobileRadio_ReturnTrue() { 227 assertThat(mBatteryUtils.shouldHideDevicePowerComponent(mAggregateBatteryConsumer, 228 BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO)).isTrue(); 229 } 230 231 @Test testShouldHideSystemConsumer_TypeScreen_ReturnTrue()232 public void testShouldHideSystemConsumer_TypeScreen_ReturnTrue() { 233 assertThat(mBatteryUtils.shouldHideDevicePowerComponent(mAggregateBatteryConsumer, 234 BatteryConsumer.POWER_COMPONENT_SCREEN)).isTrue(); 235 } 236 237 @Test testShouldHideSystemConsumer_TypeBluetooth_ReturnTrue()238 public void testShouldHideSystemConsumer_TypeBluetooth_ReturnTrue() { 239 assertThat(mBatteryUtils.shouldHideDevicePowerComponent(mAggregateBatteryConsumer, 240 BatteryConsumer.POWER_COMPONENT_BLUETOOTH)).isTrue(); } 241 242 @Test testShouldHideSystemConsumer_TypeWifi_ReturnTrue()243 public void testShouldHideSystemConsumer_TypeWifi_ReturnTrue() { 244 assertThat(mBatteryUtils.shouldHideDevicePowerComponent(mAggregateBatteryConsumer, 245 BatteryConsumer.POWER_COMPONENT_WIFI)).isTrue(); 246 } 247 248 @Test testShouldHideSystemConsumer_OtherType_ReturnFalse()249 public void testShouldHideSystemConsumer_OtherType_ReturnFalse() { 250 assertThat(mBatteryUtils.shouldHideDevicePowerComponent(mAggregateBatteryConsumer, 251 BatteryConsumer.POWER_COMPONENT_FLASHLIGHT)).isFalse(); 252 } 253 254 @Test testCalculateBatteryPercent()255 public void testCalculateBatteryPercent() { 256 assertThat(mBatteryUtils.calculateBatteryPercent(BATTERY_SYSTEM_USAGE, TOTAL_BATTERY_USAGE, 257 DISCHARGE_AMOUNT)) 258 .isWithin(PRECISION).of(PERCENT_SYSTEM_USAGE); 259 } 260 261 @Test testCalculateLastFullChargeTime()262 public void testCalculateLastFullChargeTime() { 263 final long currentTimeMs = System.currentTimeMillis(); 264 when(mBatteryUsageStats.getStatsStartTimestamp()).thenReturn( 265 currentTimeMs - TIME_SINCE_LAST_FULL_CHARGE_MS); 266 267 assertThat(mBatteryUtils.calculateLastFullChargeTime(mBatteryUsageStats, currentTimeMs)) 268 .isEqualTo(TIME_SINCE_LAST_FULL_CHARGE_MS); 269 } 270 271 @Test testGetForegroundActivityTotalTimeMs_returnMilliseconds()272 public void testGetForegroundActivityTotalTimeMs_returnMilliseconds() { 273 final long rawRealtimeUs = SystemClock.elapsedRealtime() * 1000; 274 doReturn(mTimer).when(mUid).getForegroundActivityTimer(); 275 doReturn(TIME_SINCE_LAST_FULL_CHARGE_US).when(mTimer) 276 .getTotalTimeLocked(rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED); 277 278 assertThat(mBatteryUtils.getForegroundActivityTotalTimeUs(mUid, rawRealtimeUs)).isEqualTo( 279 TIME_SINCE_LAST_FULL_CHARGE_US); 280 } 281 282 @Test testGetTargetSdkVersion_packageExist_returnSdk()283 public void testGetTargetSdkVersion_packageExist_returnSdk() throws 284 PackageManager.NameNotFoundException { 285 doReturn(mApplicationInfo).when(mPackageManager).getApplicationInfo(PACKAGE_NAME, 286 PackageManager.GET_META_DATA); 287 mApplicationInfo.targetSdkVersion = SDK_VERSION; 288 289 assertThat(mBatteryUtils.getTargetSdkVersion(PACKAGE_NAME)).isEqualTo(SDK_VERSION); 290 } 291 292 @Test testGetTargetSdkVersion_packageNotExist_returnSdkNull()293 public void testGetTargetSdkVersion_packageNotExist_returnSdkNull() throws 294 PackageManager.NameNotFoundException { 295 doThrow(new PackageManager.NameNotFoundException()).when( 296 mPackageManager).getApplicationInfo(PACKAGE_NAME, PackageManager.GET_META_DATA); 297 298 assertThat(mBatteryUtils.getTargetSdkVersion(PACKAGE_NAME)).isEqualTo( 299 BatteryUtils.SDK_NULL); 300 } 301 302 @Test testBackgroundRestrictionOn_restrictionOn_returnTrue()303 public void testBackgroundRestrictionOn_restrictionOn_returnTrue() { 304 doReturn(AppOpsManager.MODE_IGNORED).when(mAppOpsManager).checkOpNoThrow( 305 AppOpsManager.OP_RUN_IN_BACKGROUND, UID, PACKAGE_NAME); 306 307 assertThat(mBatteryUtils.isBackgroundRestrictionEnabled(SDK_VERSION, UID, 308 PACKAGE_NAME)).isTrue(); 309 } 310 311 @Test testBackgroundRestrictionOn_restrictionOff_returnFalse()312 public void testBackgroundRestrictionOn_restrictionOff_returnFalse() { 313 doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager).checkOpNoThrow( 314 AppOpsManager.OP_RUN_IN_BACKGROUND, UID, PACKAGE_NAME); 315 316 assertThat(mBatteryUtils.isBackgroundRestrictionEnabled(SDK_VERSION, UID, PACKAGE_NAME)) 317 .isFalse(); 318 } 319 320 @Test testIsPreOApp_SdkLowerThanO_ReturnTrue()321 public void testIsPreOApp_SdkLowerThanO_ReturnTrue() { 322 assertThat(mBatteryUtils.isPreOApp(LOW_SDK_PACKAGE)).isTrue(); 323 } 324 325 @Test testIsPreOApp_SdkLargerOrEqualThanO_ReturnFalse()326 public void testIsPreOApp_SdkLargerOrEqualThanO_ReturnFalse() { 327 assertThat(mBatteryUtils.isPreOApp(HIGH_SDK_PACKAGE)).isFalse(); 328 } 329 330 @Test testIsPreOApp_containPreOApp_ReturnTrue()331 public void testIsPreOApp_containPreOApp_ReturnTrue() { 332 assertThat( 333 mBatteryUtils.isPreOApp(new String[]{HIGH_SDK_PACKAGE, LOW_SDK_PACKAGE})).isTrue(); 334 } 335 336 @Test testIsPreOApp_emptyList_ReturnFalse()337 public void testIsPreOApp_emptyList_ReturnFalse() { 338 assertThat(mBatteryUtils.isPreOApp(new String[]{})).isFalse(); 339 } 340 341 @Ignore 342 @Test testSetForceAppStandby_forcePreOApp_forceTwoRestrictions()343 public void testSetForceAppStandby_forcePreOApp_forceTwoRestrictions() { 344 mBatteryUtils.setForceAppStandby(UID, LOW_SDK_PACKAGE, AppOpsManager.MODE_IGNORED); 345 346 // Restrict both OP_RUN_IN_BACKGROUND and OP_RUN_ANY_IN_BACKGROUND 347 verify(mAppOpsManager).setMode(AppOpsManager.OP_RUN_IN_BACKGROUND, UID, LOW_SDK_PACKAGE, 348 AppOpsManager.MODE_IGNORED); 349 verify(mAppOpsManager).setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID, LOW_SDK_PACKAGE, 350 AppOpsManager.MODE_IGNORED); 351 } 352 353 @Ignore 354 @Test testSetForceAppStandby_forceOApp_forceOneRestriction()355 public void testSetForceAppStandby_forceOApp_forceOneRestriction() { 356 mBatteryUtils.setForceAppStandby(UID, HIGH_SDK_PACKAGE, AppOpsManager.MODE_IGNORED); 357 358 // Don't restrict OP_RUN_IN_BACKGROUND because it is already been restricted for O app 359 verify(mAppOpsManager, never()).setMode(AppOpsManager.OP_RUN_IN_BACKGROUND, UID, 360 HIGH_SDK_PACKAGE, AppOpsManager.MODE_IGNORED); 361 // Restrict OP_RUN_ANY_IN_BACKGROUND 362 verify(mAppOpsManager).setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID, 363 HIGH_SDK_PACKAGE, AppOpsManager.MODE_IGNORED); 364 } 365 366 @Test testSetForceAppStandby_restrictApp_recordTime()367 public void testSetForceAppStandby_restrictApp_recordTime() { 368 mBatteryUtils.setForceAppStandby(UID, HIGH_SDK_PACKAGE, AppOpsManager.MODE_IGNORED); 369 370 verify(mBatteryDatabaseManager).insertAction( 371 eq(AnomalyDatabaseHelper.ActionType.RESTRICTION), eq(UID), 372 eq(HIGH_SDK_PACKAGE), anyLong()); 373 } 374 375 @Test testSetForceAppStandby_unrestrictApp_deleteTime()376 public void testSetForceAppStandby_unrestrictApp_deleteTime() { 377 mBatteryUtils.setForceAppStandby(UID, HIGH_SDK_PACKAGE, AppOpsManager.MODE_ALLOWED); 378 379 verify(mBatteryDatabaseManager).deleteAction(AnomalyDatabaseHelper.ActionType.RESTRICTION, 380 UID, HIGH_SDK_PACKAGE); 381 } 382 383 @Test testIsForceAppStandbyEnabled_enabled_returnTrue()384 public void testIsForceAppStandbyEnabled_enabled_returnTrue() { 385 when(mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID, 386 PACKAGE_NAME)).thenReturn(AppOpsManager.MODE_IGNORED); 387 388 assertThat(mBatteryUtils.isForceAppStandbyEnabled(UID, PACKAGE_NAME)).isTrue(); 389 } 390 391 @Test testIsForceAppStandbyEnabled_disabled_returnFalse()392 public void testIsForceAppStandbyEnabled_disabled_returnFalse() { 393 when(mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID, 394 PACKAGE_NAME)).thenReturn(AppOpsManager.MODE_ALLOWED); 395 396 assertThat(mBatteryUtils.isForceAppStandbyEnabled(UID, PACKAGE_NAME)).isFalse(); 397 } 398 399 @Test testShouldHideAnomaly_systemAppWithLauncher_returnTrue()400 public void testShouldHideAnomaly_systemAppWithLauncher_returnTrue() { 401 final List<ResolveInfo> resolveInfos = new ArrayList<>(); 402 final ResolveInfo resolveInfo = new ResolveInfo(); 403 resolveInfo.activityInfo = new ActivityInfo(); 404 resolveInfo.activityInfo.packageName = HIGH_SDK_PACKAGE; 405 406 doReturn(resolveInfos).when(mPackageManager).queryIntentActivities(any(), anyInt()); 407 doReturn(new String[]{HIGH_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(UID); 408 mHighApplicationInfo.flags = ApplicationInfo.FLAG_SYSTEM; 409 410 assertThat(mBatteryUtils.shouldHideAnomaly(mPowerAllowlistBackend, UID, 411 mAnomalyInfo)).isTrue(); 412 } 413 414 @Test testShouldHideAnomaly_systemAppWithoutLauncher_returnTrue()415 public void testShouldHideAnomaly_systemAppWithoutLauncher_returnTrue() { 416 doReturn(new ArrayList<>()).when(mPackageManager).queryIntentActivities(any(), anyInt()); 417 doReturn(new String[]{HIGH_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(UID); 418 mHighApplicationInfo.flags = ApplicationInfo.FLAG_SYSTEM; 419 420 assertThat(mBatteryUtils.shouldHideAnomaly(mPowerAllowlistBackend, UID, 421 mAnomalyInfo)).isTrue(); 422 } 423 424 @Test testShouldHideAnomaly_systemUid_returnTrue()425 public void testShouldHideAnomaly_systemUid_returnTrue() { 426 final int systemUid = Process.ROOT_UID; 427 doReturn(new String[]{HIGH_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(systemUid); 428 429 assertThat(mBatteryUtils.shouldHideAnomaly(mPowerAllowlistBackend, systemUid, 430 mAnomalyInfo)).isTrue(); 431 } 432 433 @Test testShouldHideAnomaly_AppInDozeList_returnTrue()434 public void testShouldHideAnomaly_AppInDozeList_returnTrue() { 435 doReturn(new String[]{HIGH_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(UID); 436 doReturn(true).when(mPowerAllowlistBackend).isAllowlisted(new String[]{HIGH_SDK_PACKAGE}); 437 438 assertThat(mBatteryUtils.shouldHideAnomaly(mPowerAllowlistBackend, UID, 439 mAnomalyInfo)).isTrue(); 440 } 441 442 @Test testShouldHideAnomaly_normalApp_returnFalse()443 public void testShouldHideAnomaly_normalApp_returnFalse() { 444 doReturn(new String[]{HIGH_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(UID); 445 446 assertThat(mBatteryUtils.shouldHideAnomaly(mPowerAllowlistBackend, UID, 447 mAnomalyInfo)).isFalse(); 448 } 449 450 @Test testShouldHideAnomaly_excessivePriorOApp_returnFalse()451 public void testShouldHideAnomaly_excessivePriorOApp_returnFalse() { 452 doReturn(new String[]{LOW_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(UID); 453 mAnomalyInfo = new AnomalyInfo(INFO_EXCESSIVE); 454 455 assertThat(mBatteryUtils.shouldHideAnomaly(mPowerAllowlistBackend, UID, 456 mAnomalyInfo)).isFalse(); 457 } 458 459 @Test testShouldHideAnomaly_excessiveOApp_returnTrue()460 public void testShouldHideAnomaly_excessiveOApp_returnTrue() { 461 doReturn(new String[]{HIGH_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(UID); 462 mAnomalyInfo = new AnomalyInfo(INFO_EXCESSIVE); 463 464 assertThat(mBatteryUtils.shouldHideAnomaly(mPowerAllowlistBackend, UID, 465 mAnomalyInfo)).isTrue(); 466 } 467 468 @Test clearForceAppStandby_appRestricted_clearAndReturnTrue()469 public void clearForceAppStandby_appRestricted_clearAndReturnTrue() { 470 when(mBatteryUtils.getPackageUid(HIGH_SDK_PACKAGE)).thenReturn(UID); 471 when(mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID, 472 HIGH_SDK_PACKAGE)).thenReturn(AppOpsManager.MODE_IGNORED); 473 474 assertThat(mBatteryUtils.clearForceAppStandby(HIGH_SDK_PACKAGE)).isTrue(); 475 verify(mAppOpsManager).setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID, 476 HIGH_SDK_PACKAGE, AppOpsManager.MODE_ALLOWED); 477 } 478 479 @Test clearForceAppStandby_appInvalid_returnFalse()480 public void clearForceAppStandby_appInvalid_returnFalse() { 481 when(mBatteryUtils.getPackageUid(PACKAGE_NAME)).thenReturn(BatteryUtils.UID_NULL); 482 483 assertThat(mBatteryUtils.clearForceAppStandby(PACKAGE_NAME)).isFalse(); 484 verify(mAppOpsManager, never()).setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID, 485 PACKAGE_NAME, AppOpsManager.MODE_ALLOWED); 486 } 487 488 @Test clearForceAppStandby_appUnrestricted_returnFalse()489 public void clearForceAppStandby_appUnrestricted_returnFalse() { 490 when(mBatteryUtils.getPackageUid(PACKAGE_NAME)).thenReturn(UID); 491 when(mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID, 492 PACKAGE_NAME)).thenReturn(AppOpsManager.MODE_ALLOWED); 493 494 assertThat(mBatteryUtils.clearForceAppStandby(PACKAGE_NAME)).isFalse(); 495 verify(mAppOpsManager, never()).setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID, 496 PACKAGE_NAME, AppOpsManager.MODE_ALLOWED); 497 } 498 499 @Test getBatteryInfo_providerNull_shouldNotCrash()500 public void getBatteryInfo_providerNull_shouldNotCrash() { 501 when(mProvider.isEnhancedBatteryPredictionEnabled(mContext)).thenReturn(true); 502 when(mProvider.getEnhancedBatteryPrediction(mContext)).thenReturn(null); 503 when(mContext.registerReceiver(nullable(BroadcastReceiver.class), 504 any(IntentFilter.class))).thenReturn(new Intent()); 505 506 //Should not crash 507 assertThat(mBatteryUtils.getBatteryInfo(TAG)).isNotNull(); 508 } 509 510 @Test getEnhancedEstimate_doesNotUpdateCache_ifEstimateFresh()511 public void getEnhancedEstimate_doesNotUpdateCache_ifEstimateFresh() { 512 Estimate estimate = new Estimate(1000, true, 1000); 513 Estimate.storeCachedEstimate(mContext, estimate); 514 515 estimate = mBatteryUtils.getEnhancedEstimate(); 516 517 // only pass if estimate has not changed 518 assertThat(estimate).isNotNull(); 519 assertThat(estimate.isBasedOnUsage()).isTrue(); 520 assertThat(estimate.getAverageDischargeTime()).isEqualTo(1000); 521 } 522 523 @Test testIsBatteryDefenderOn_isOverheatedAndIsCharging_returnTrue()524 public void testIsBatteryDefenderOn_isOverheatedAndIsCharging_returnTrue() { 525 mBatteryInfo.isOverheated = true; 526 mBatteryInfo.discharging = false; 527 528 assertThat(mBatteryUtils.isBatteryDefenderOn(mBatteryInfo)).isTrue(); 529 } 530 531 @Test testIsBatteryDefenderOn_isOverheatedAndDischarging_returnFalse()532 public void testIsBatteryDefenderOn_isOverheatedAndDischarging_returnFalse() { 533 mBatteryInfo.isOverheated = true; 534 mBatteryInfo.discharging = true; 535 536 assertThat(mBatteryUtils.isBatteryDefenderOn(mBatteryInfo)).isFalse(); 537 } 538 539 @Test testIsBatteryDefenderOn_notOverheatedAndDischarging_returnFalse()540 public void testIsBatteryDefenderOn_notOverheatedAndDischarging_returnFalse() { 541 mBatteryInfo.isOverheated = false; 542 mBatteryInfo.discharging = true; 543 544 assertThat(mBatteryUtils.isBatteryDefenderOn(mBatteryInfo)).isFalse(); 545 } 546 547 @Test testIsBatteryDefenderOn_notOverheatedAndIsCharging_returnFalse()548 public void testIsBatteryDefenderOn_notOverheatedAndIsCharging_returnFalse() { 549 mBatteryInfo.isOverheated = false; 550 mBatteryInfo.discharging = false; 551 552 assertThat(mBatteryUtils.isBatteryDefenderOn(mBatteryInfo)).isFalse(); 553 } 554 } 555