/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.settings.fuelgauge;

import static android.os.BatteryStats.Uid.PROCESS_STATE_BACKGROUND;
import static android.os.BatteryStats.Uid.PROCESS_STATE_FOREGROUND;
import static android.os.BatteryStats.Uid.PROCESS_STATE_FOREGROUND_SERVICE;
import static android.os.BatteryStats.Uid.PROCESS_STATE_TOP;
import static android.os.BatteryStats.Uid.PROCESS_STATE_TOP_SLEEPING;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.app.AppOpsManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.BatteryStats;
import android.os.Build;
import android.os.Bundle;
import android.os.Process;
import android.os.SystemClock;
import android.os.UserManager;
import android.text.format.DateUtils;

import com.android.internal.os.BatterySipper;
import com.android.internal.os.BatteryStatsHelper;
import com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper;
import com.android.settings.fuelgauge.batterytip.AnomalyInfo;
import com.android.settings.fuelgauge.batterytip.BatteryDatabaseManager;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.shadow.ShadowThreadUtils;
import com.android.settingslib.fuelgauge.Estimate;
import com.android.settingslib.fuelgauge.PowerWhitelistBackend;

import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;

import java.util.ArrayList;
import java.util.List;

@RunWith(RobolectricTestRunner.class)
public class BatteryUtilsTest {

    private static final String TAG = "BatteryUtilsTest";

    // unit that used to converted ms to us
    private static final long UNIT = 1000;
    private static final long TIME_STATE_TOP = 1500 * UNIT;
    private static final long TIME_STATE_FOREGROUND_SERVICE = 2000 * UNIT;
    private static final long TIME_STATE_TOP_SLEEPING = 2500 * UNIT;
    private static final long TIME_STATE_FOREGROUND = 3000 * UNIT;
    private static final long TIME_STATE_BACKGROUND = 6000 * UNIT;
    private static final long TIME_FOREGROUND_ZERO = 0;
    private static final long TIME_FOREGROUND = 100 * DateUtils.MINUTE_IN_MILLIS;
    private static final long TIME_SINCE_LAST_FULL_CHARGE_MS = 120 * 60 * 1000;
    private static final long TIME_SINCE_LAST_FULL_CHARGE_US =
            TIME_SINCE_LAST_FULL_CHARGE_MS * 1000;

    private static final int UID = 12345;
    private static final long TIME_EXPECTED_FOREGROUND = 1500;
    private static final long TIME_EXPECTED_BACKGROUND = 6000;
    private static final long TIME_EXPECTED_ALL = 7500;
    private static final double BATTERY_SCREEN_USAGE = 300;
    private static final double BATTERY_IDLE_USAGE = 600;
    private static final double BATTERY_SYSTEM_USAGE = 600;
    private static final double BATTERY_OVERACCOUNTED_USAGE = 500;
    private static final double BATTERY_UNACCOUNTED_USAGE = 700;
    private static final double BATTERY_APP_USAGE = 100;
    private static final double BATTERY_WIFI_USAGE = 200;
    private static final double BATTERY_BLUETOOTH_USAGE = 300;
    private static final double TOTAL_BATTERY_USAGE = 1000;
    private static final double HIDDEN_USAGE = 200;
    private static final int DISCHARGE_AMOUNT = 80;
    private static final double PERCENT_SYSTEM_USAGE = 60;
    private static final double PRECISION = 0.001;
    private static final int SDK_VERSION = Build.VERSION_CODES.L;
    private static final String PACKAGE_NAME = "com.android.app";
    private static final String HIGH_SDK_PACKAGE = "com.android.package.high";
    private static final String LOW_SDK_PACKAGE = "com.android.package.low";

    private static final String INFO_EXCESSIVE = "anomaly_type=4,auto_restriction=false";
    private static final String INFO_WAKELOCK = "anomaly_type=1,auto_restriction=false";

    @Mock
    private BatteryStats.Uid mUid;
    @Mock
    private BatteryStats.Timer mTimer;
    @Mock
    private BatterySipper mNormalBatterySipper;
    @Mock
    private BatterySipper mWifiBatterySipper;
    @Mock
    private BatterySipper mBluetoothBatterySipper;
    @Mock
    private BatterySipper mScreenBatterySipper;
    @Mock
    private BatterySipper mOvercountedBatterySipper;
    @Mock
    private BatterySipper mUnaccountedBatterySipper;
    @Mock
    private BatterySipper mSystemBatterySipper;
    @Mock
    private BatterySipper mCellBatterySipper;
    @Mock
    private BatterySipper mIdleBatterySipper;
    @Mock
    private BatteryInfo mBatteryInfo;
    @Mock
    private Bundle mBundle;
    @Mock
    private UserManager mUserManager;
    @Mock
    private PackageManager mPackageManager;
    @Mock
    private AppOpsManager mAppOpsManager;
    @Mock
    private ApplicationInfo mApplicationInfo;
    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
    private BatteryStatsHelper mBatteryStatsHelper;
    @Mock
    private ApplicationInfo mHighApplicationInfo;
    @Mock
    private ApplicationInfo mLowApplicationInfo;
    @Mock
    private PowerWhitelistBackend mPowerWhitelistBackend;
    @Mock
    private BatteryDatabaseManager mBatteryDatabaseManager;
    private AnomalyInfo mAnomalyInfo;
    private BatteryUtils mBatteryUtils;
    private FakeFeatureFactory mFeatureFactory;
    private PowerUsageFeatureProvider mProvider;
    private List<BatterySipper> mUsageList;
    private Context mContext;

    @Before
    public void setUp() throws PackageManager.NameNotFoundException {
        MockitoAnnotations.initMocks(this);

        mFeatureFactory = FakeFeatureFactory.setupForTest();
        mProvider = mFeatureFactory.powerUsageFeatureProvider;

        doReturn(TIME_STATE_TOP).when(mUid).getProcessStateTime(eq(PROCESS_STATE_TOP), anyLong(),
                anyInt());
        doReturn(TIME_STATE_FOREGROUND_SERVICE).when(mUid).getProcessStateTime(
                eq(PROCESS_STATE_FOREGROUND_SERVICE), anyLong(), anyInt());
        doReturn(TIME_STATE_TOP_SLEEPING).when(mUid).getProcessStateTime(
                eq(PROCESS_STATE_TOP_SLEEPING), anyLong(), anyInt());
        doReturn(TIME_STATE_FOREGROUND).when(mUid).getProcessStateTime(eq(PROCESS_STATE_FOREGROUND),
                anyLong(), anyInt());
        doReturn(TIME_STATE_BACKGROUND).when(mUid).getProcessStateTime(eq(PROCESS_STATE_BACKGROUND),
                anyLong(), anyInt());
        when(mBatteryStatsHelper.getStats().computeBatteryRealtime(anyLong(), anyInt())).thenReturn(
                TIME_SINCE_LAST_FULL_CHARGE_US);

        when(mPackageManager.getApplicationInfo(eq(HIGH_SDK_PACKAGE), anyInt()))
                .thenReturn(mHighApplicationInfo);
        when(mPackageManager.getApplicationInfo(eq(LOW_SDK_PACKAGE), anyInt()))
                .thenReturn(mLowApplicationInfo);
        mHighApplicationInfo.targetSdkVersion = Build.VERSION_CODES.O;
        mLowApplicationInfo.targetSdkVersion = Build.VERSION_CODES.L;

        mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
        mNormalBatterySipper.totalPowerMah = TOTAL_BATTERY_USAGE;
        doReturn(UID).when(mNormalBatterySipper).getUid();

        mWifiBatterySipper.drainType = BatterySipper.DrainType.WIFI;
        mWifiBatterySipper.totalPowerMah = BATTERY_WIFI_USAGE;

        mBluetoothBatterySipper.drainType = BatterySipper.DrainType.BLUETOOTH;
        mBluetoothBatterySipper.totalPowerMah = BATTERY_BLUETOOTH_USAGE;

        mScreenBatterySipper.drainType = BatterySipper.DrainType.SCREEN;
        mScreenBatterySipper.totalPowerMah = BATTERY_SCREEN_USAGE;

        mSystemBatterySipper.drainType = BatterySipper.DrainType.APP;
        mSystemBatterySipper.totalPowerMah = BATTERY_SYSTEM_USAGE;
        when(mSystemBatterySipper.getUid()).thenReturn(Process.SYSTEM_UID);

        mOvercountedBatterySipper.drainType = BatterySipper.DrainType.OVERCOUNTED;
        mOvercountedBatterySipper.totalPowerMah = BATTERY_OVERACCOUNTED_USAGE;

        mUnaccountedBatterySipper.drainType = BatterySipper.DrainType.UNACCOUNTED;
        mUnaccountedBatterySipper.totalPowerMah = BATTERY_UNACCOUNTED_USAGE;

        mIdleBatterySipper.drainType = BatterySipper.DrainType.IDLE;
        mIdleBatterySipper.totalPowerMah = BATTERY_IDLE_USAGE;

        mContext = spy(RuntimeEnvironment.application);
        doReturn(mPackageManager).when(mContext).getPackageManager();
        doReturn(mAppOpsManager).when(mContext).getSystemService(Context.APP_OPS_SERVICE);
        mBatteryUtils = spy(new BatteryUtils(mContext));
        mBatteryUtils.mPowerUsageFeatureProvider = mProvider;
        doReturn(0L).when(mBatteryUtils)
            .getForegroundServiceTotalTimeUs(any(BatteryStats.Uid.class), anyLong());
        mAnomalyInfo = new AnomalyInfo(INFO_WAKELOCK);

        mUsageList = new ArrayList<>();
        mUsageList.add(mNormalBatterySipper);
        mUsageList.add(mScreenBatterySipper);
        mUsageList.add(mCellBatterySipper);
        when(mBatteryStatsHelper.getUsageList()).thenReturn(mUsageList);
        when(mBatteryStatsHelper.getTotalPower())
            .thenReturn(TOTAL_BATTERY_USAGE + BATTERY_SCREEN_USAGE);
        when(mBatteryStatsHelper.getStats().getDischargeAmount(anyInt()))
            .thenReturn(DISCHARGE_AMOUNT);
        BatteryDatabaseManager.setUpForTest(mBatteryDatabaseManager);
        ShadowThreadUtils.setIsMainThread(true);
    }

    @Test
    public void testGetProcessTimeMs_typeForeground_timeCorrect() {
        doReturn(TIME_STATE_FOREGROUND + 500).when(mBatteryUtils)
            .getForegroundActivityTotalTimeUs(eq(mUid), anyLong());

        final long time = mBatteryUtils.getProcessTimeMs(BatteryUtils.StatusType.FOREGROUND, mUid,
                BatteryStats.STATS_SINCE_CHARGED);

        assertThat(time).isEqualTo(TIME_EXPECTED_FOREGROUND);
    }

    @Test
    public void testGetProcessTimeMs_typeBackground_timeCorrect() {
        final long time = mBatteryUtils.getProcessTimeMs(BatteryUtils.StatusType.BACKGROUND, mUid,
                BatteryStats.STATS_SINCE_CHARGED);

        assertThat(time).isEqualTo(TIME_EXPECTED_BACKGROUND);
    }

    @Test
    public void testGetProcessTimeMs_typeAll_timeCorrect() {
        doReturn(TIME_STATE_FOREGROUND + 500).when(mBatteryUtils)
            .getForegroundActivityTotalTimeUs(eq(mUid), anyLong());

        final long time = mBatteryUtils.getProcessTimeMs(BatteryUtils.StatusType.ALL, mUid,
                BatteryStats.STATS_SINCE_CHARGED);

        assertThat(time).isEqualTo(TIME_EXPECTED_ALL);
    }

    @Test
    public void testGetProcessTimeMs_uidNull_returnZero() {
        final long time = mBatteryUtils.getProcessTimeMs(BatteryUtils.StatusType.ALL, null,
                BatteryStats.STATS_SINCE_CHARGED);

        assertThat(time).isEqualTo(0);
    }

    @Test
    public void testRemoveHiddenBatterySippers_ContainsHiddenSippers_RemoveAndReturnValue() {
        final List<BatterySipper> sippers = new ArrayList<>();
        sippers.add(mNormalBatterySipper);
        sippers.add(mScreenBatterySipper);
        sippers.add(mSystemBatterySipper);
        sippers.add(mOvercountedBatterySipper);
        sippers.add(mUnaccountedBatterySipper);
        sippers.add(mWifiBatterySipper);
        sippers.add(mBluetoothBatterySipper);
        sippers.add(mIdleBatterySipper);
        when(mProvider.isTypeSystem(mSystemBatterySipper)).thenReturn(true);
        doNothing().when(mBatteryUtils).smearScreenBatterySipper(any(), any());

        final double totalUsage = mBatteryUtils.removeHiddenBatterySippers(sippers);

        assertThat(sippers).containsExactly(mNormalBatterySipper);
        assertThat(totalUsage).isWithin(PRECISION).of(BATTERY_SYSTEM_USAGE);
    }

    @Test
    public void testShouldHideSipper_TypeUnAccounted_ReturnTrue() {
        mNormalBatterySipper.drainType = BatterySipper.DrainType.UNACCOUNTED;
        assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isTrue();
    }

    @Test
    public void testShouldHideSipper_TypeOverAccounted_ReturnTrue() {
        mNormalBatterySipper.drainType = BatterySipper.DrainType.OVERCOUNTED;
        assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isTrue();
    }

    @Test
    public void testShouldHideSipper_TypeIdle_ReturnTrue() {
        mNormalBatterySipper.drainType = BatterySipper.DrainType.IDLE;
        assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isTrue();
    }

    @Test
    public void testShouldHideSipper_TypeCell_ReturnTrue() {
        mNormalBatterySipper.drainType = BatterySipper.DrainType.CELL;
        assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isTrue();
    }

    @Test
    public void testShouldHideSipper_TypeScreen_ReturnTrue() {
        mNormalBatterySipper.drainType = BatterySipper.DrainType.SCREEN;
        assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isTrue();
    }

    @Test
    public void testShouldHideSipper_TypeWifi_ReturnTrue() {
        mNormalBatterySipper.drainType = BatterySipper.DrainType.WIFI;
        assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isTrue();
    }

    @Test
    public void testShouldHideSipper_TypeBluetooth_ReturnTrue() {
        mNormalBatterySipper.drainType = BatterySipper.DrainType.BLUETOOTH;
        assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isTrue();
    }

    @Test
    public void testShouldHideSipper_TypeSystem_ReturnTrue() {
        mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
        when(mNormalBatterySipper.getUid()).thenReturn(Process.ROOT_UID);
        when(mProvider.isTypeSystem(any())).thenReturn(true);
        assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isTrue();
    }

    @Test
    public void testShouldHideSipper_UidNormal_ReturnFalse() {
        mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
        when(mNormalBatterySipper.getUid()).thenReturn(UID);
        assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isFalse();
    }

    @Test
    public void testShouldHideSipper_TypeService_ReturnTrue() {
        mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
        when(mNormalBatterySipper.getUid()).thenReturn(UID);
        when(mProvider.isTypeService(any())).thenReturn(true);

        assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isTrue();
    }

    @Test
    public void testShouldHideSipper_hiddenSystemModule_ReturnTrue() {
        mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
        when(mNormalBatterySipper.getUid()).thenReturn(UID);
        when(mBatteryUtils.isHiddenSystemModule(mNormalBatterySipper)).thenReturn(true);

        assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isTrue();
    }

    @Test
    public void testCalculateBatteryPercent() {
        assertThat(mBatteryUtils.calculateBatteryPercent(BATTERY_SYSTEM_USAGE, TOTAL_BATTERY_USAGE,
                HIDDEN_USAGE, DISCHARGE_AMOUNT))
                .isWithin(PRECISION).of(PERCENT_SYSTEM_USAGE);
    }

    @Test
    public void testSmearScreenBatterySipper() {
        final BatterySipper sipperNull = createTestSmearBatterySipper(TIME_FOREGROUND_ZERO,
                BATTERY_APP_USAGE, 0 /* uid */, true /* isUidNull */);
        final BatterySipper sipperBg = createTestSmearBatterySipper(TIME_FOREGROUND_ZERO,
                BATTERY_APP_USAGE, 1 /* uid */, false /* isUidNull */);
        final BatterySipper sipperFg = createTestSmearBatterySipper(TIME_FOREGROUND,
                BATTERY_APP_USAGE, 2 /* uid */, false /* isUidNull */);
        final BatterySipper sipperFg2 = createTestSmearBatterySipper(TIME_FOREGROUND,
                BATTERY_APP_USAGE, 3 /* uid */, false /* isUidNull */);

        final List<BatterySipper> sippers = new ArrayList<>();
        sippers.add(sipperNull);
        sippers.add(sipperBg);
        sippers.add(sipperFg);
        sippers.add(sipperFg2);

        mBatteryUtils.smearScreenBatterySipper(sippers, mScreenBatterySipper);

        assertThat(sipperNull.totalPowerMah).isWithin(PRECISION).of(BATTERY_APP_USAGE);
        assertThat(sipperBg.totalPowerMah).isWithin(PRECISION).of(BATTERY_APP_USAGE);
        assertThat(sipperFg.totalPowerMah).isWithin(PRECISION).of(
                BATTERY_APP_USAGE + BATTERY_SCREEN_USAGE / 2);
        assertThat(sipperFg2.totalPowerMah).isWithin(PRECISION).of(
                BATTERY_APP_USAGE + BATTERY_SCREEN_USAGE / 2);
    }

    @Test
    public void testSmearScreenBatterySipper_screenSipperNull_shouldNotCrash() {
        final BatterySipper sipperFg = createTestSmearBatterySipper(TIME_FOREGROUND,
                BATTERY_APP_USAGE, 2 /* uid */, false /* isUidNull */);

        final List<BatterySipper> sippers = new ArrayList<>();
        sippers.add(sipperFg);

        // Shouldn't crash
        mBatteryUtils.smearScreenBatterySipper(sippers, null /* screenSipper */);
    }

    @Test
    public void testCalculateRunningTimeBasedOnStatsType() {
        assertThat(mBatteryUtils.calculateRunningTimeBasedOnStatsType(mBatteryStatsHelper,
                BatteryStats.STATS_SINCE_CHARGED)).isEqualTo(TIME_SINCE_LAST_FULL_CHARGE_MS);
    }

    @Test
    public void testSortUsageList() {
        final List<BatterySipper> sippers = new ArrayList<>();
        sippers.add(mNormalBatterySipper);
        sippers.add(mScreenBatterySipper);
        sippers.add(mSystemBatterySipper);

        mBatteryUtils.sortUsageList(sippers);

        assertThat(sippers).containsExactly(mNormalBatterySipper, mSystemBatterySipper,
                mScreenBatterySipper);
    }

    @Test
    public void testCalculateLastFullChargeTime() {
        final long currentTimeMs = System.currentTimeMillis();
        when(mBatteryStatsHelper.getStats().getStartClockTime()).thenReturn(
                currentTimeMs - TIME_SINCE_LAST_FULL_CHARGE_MS);

        assertThat(mBatteryUtils.calculateLastFullChargeTime(
                mBatteryStatsHelper, currentTimeMs)).isEqualTo(TIME_SINCE_LAST_FULL_CHARGE_MS);
    }

    @Test
    public void testGetForegroundActivityTotalTimeMs_returnMilliseconds() {
        final long rawRealtimeUs = SystemClock.elapsedRealtime() * 1000;
        doReturn(mTimer).when(mUid).getForegroundActivityTimer();
        doReturn(TIME_SINCE_LAST_FULL_CHARGE_US).when(mTimer)
                .getTotalTimeLocked(rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED);

        assertThat(mBatteryUtils.getForegroundActivityTotalTimeUs(mUid, rawRealtimeUs)).isEqualTo(
                TIME_SINCE_LAST_FULL_CHARGE_US);
    }

    @Test
    public void testGetTargetSdkVersion_packageExist_returnSdk() throws
            PackageManager.NameNotFoundException {
        doReturn(mApplicationInfo).when(mPackageManager).getApplicationInfo(PACKAGE_NAME,
                PackageManager.GET_META_DATA);
        mApplicationInfo.targetSdkVersion = SDK_VERSION;

        assertThat(mBatteryUtils.getTargetSdkVersion(PACKAGE_NAME)).isEqualTo(SDK_VERSION);
    }

    @Test
    public void testGetTargetSdkVersion_packageNotExist_returnSdkNull() throws
            PackageManager.NameNotFoundException {
        doThrow(new PackageManager.NameNotFoundException()).when(
                mPackageManager).getApplicationInfo(PACKAGE_NAME, PackageManager.GET_META_DATA);

        assertThat(mBatteryUtils.getTargetSdkVersion(PACKAGE_NAME)).isEqualTo(
                BatteryUtils.SDK_NULL);
    }

    @Test
    public void testBackgroundRestrictionOn_restrictionOn_returnTrue() {
        doReturn(AppOpsManager.MODE_IGNORED).when(mAppOpsManager).checkOpNoThrow(
                AppOpsManager.OP_RUN_IN_BACKGROUND, UID, PACKAGE_NAME);

        assertThat(mBatteryUtils.isBackgroundRestrictionEnabled(SDK_VERSION, UID,
                PACKAGE_NAME)).isTrue();
    }

    @Test
    public void testBackgroundRestrictionOn_restrictionOff_returnFalse() {
        doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager).checkOpNoThrow(
                AppOpsManager.OP_RUN_IN_BACKGROUND, UID, PACKAGE_NAME);

        assertThat(mBatteryUtils.isBackgroundRestrictionEnabled(SDK_VERSION, UID, PACKAGE_NAME))
            .isFalse();
    }

    private BatterySipper createTestSmearBatterySipper(
        long topTime, double totalPowerMah, int uidCode, boolean isUidNull) {
        final BatterySipper sipper = mock(BatterySipper.class);
        sipper.drainType = BatterySipper.DrainType.APP;
        sipper.totalPowerMah = totalPowerMah;
        doReturn(uidCode).when(sipper).getUid();
        if (!isUidNull) {
            final BatteryStats.Uid uid = mock(BatteryStats.Uid.class, RETURNS_DEEP_STUBS);
            doReturn(topTime).when(mBatteryUtils).getProcessTimeMs(
                    eq(BatteryUtils.StatusType.SCREEN_USAGE), eq(uid), anyInt());
            doReturn(uidCode).when(uid).getUid();
            sipper.uidObj = uid;
        }

        return sipper;
    }

    @Test
    public void testInitBatteryStatsHelper_init() {
        mBatteryUtils.initBatteryStatsHelper(mBatteryStatsHelper, mBundle, mUserManager);

        verify(mBatteryStatsHelper).create(mBundle);
        verify(mBatteryStatsHelper).refreshStats(BatteryStats.STATS_SINCE_CHARGED,
                mUserManager.getUserProfiles());
    }

    @Test
    public void testFindBatterySipperByType_findTypeScreen() {
        BatterySipper sipper = mBatteryUtils.findBatterySipperByType(mUsageList,
                BatterySipper.DrainType.SCREEN);

        assertThat(sipper).isSameInstanceAs(mScreenBatterySipper);
    }

    @Test
    public void testFindBatterySipperByType_findTypeApp() {
        BatterySipper sipper = mBatteryUtils.findBatterySipperByType(mUsageList,
                BatterySipper.DrainType.APP);

        assertThat(sipper).isSameInstanceAs(mNormalBatterySipper);
    }

    @Test
    public void testCalculateScreenUsageTime_returnCorrectTime() {
        mScreenBatterySipper.usageTimeMs = TIME_EXPECTED_FOREGROUND;

        assertThat(mBatteryUtils.calculateScreenUsageTime(mBatteryStatsHelper)).isEqualTo(
                TIME_EXPECTED_FOREGROUND);
    }

    @Test
    public void testIsPreOApp_SdkLowerThanO_ReturnTrue() {
        assertThat(mBatteryUtils.isPreOApp(LOW_SDK_PACKAGE)).isTrue();
    }

    @Test
    public void testIsPreOApp_SdkLargerOrEqualThanO_ReturnFalse() {
        assertThat(mBatteryUtils.isPreOApp(HIGH_SDK_PACKAGE)).isFalse();
    }

    @Test
    public void testIsPreOApp_containPreOApp_ReturnTrue() {
        assertThat(
                mBatteryUtils.isPreOApp(new String[]{HIGH_SDK_PACKAGE, LOW_SDK_PACKAGE})).isTrue();
    }

    @Test
    public void testIsPreOApp_emptyList_ReturnFalse() {
        assertThat(mBatteryUtils.isPreOApp(new String[]{})).isFalse();
    }

    @Ignore
    @Test
    public void testSetForceAppStandby_forcePreOApp_forceTwoRestrictions() {
        mBatteryUtils.setForceAppStandby(UID, LOW_SDK_PACKAGE, AppOpsManager.MODE_IGNORED);

        // Restrict both OP_RUN_IN_BACKGROUND and OP_RUN_ANY_IN_BACKGROUND
        verify(mAppOpsManager).setMode(AppOpsManager.OP_RUN_IN_BACKGROUND, UID, LOW_SDK_PACKAGE,
                AppOpsManager.MODE_IGNORED);
        verify(mAppOpsManager).setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID, LOW_SDK_PACKAGE,
                AppOpsManager.MODE_IGNORED);
    }

    @Ignore
    @Test
    public void testSetForceAppStandby_forceOApp_forceOneRestriction() {
        mBatteryUtils.setForceAppStandby(UID, HIGH_SDK_PACKAGE, AppOpsManager.MODE_IGNORED);

        // Don't restrict OP_RUN_IN_BACKGROUND because it is already been restricted for O app
        verify(mAppOpsManager, never()).setMode(AppOpsManager.OP_RUN_IN_BACKGROUND, UID,
                HIGH_SDK_PACKAGE, AppOpsManager.MODE_IGNORED);
        // Restrict OP_RUN_ANY_IN_BACKGROUND
        verify(mAppOpsManager).setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID,
                HIGH_SDK_PACKAGE, AppOpsManager.MODE_IGNORED);
    }

    @Test
    public void testSetForceAppStandby_restrictApp_recordTime() {
        mBatteryUtils.setForceAppStandby(UID, HIGH_SDK_PACKAGE, AppOpsManager.MODE_IGNORED);

        verify(mBatteryDatabaseManager).insertAction(
                eq(AnomalyDatabaseHelper.ActionType.RESTRICTION), eq(UID),
                eq(HIGH_SDK_PACKAGE), anyLong());
    }

    @Test
    public void testSetForceAppStandby_unrestrictApp_deleteTime() {
        mBatteryUtils.setForceAppStandby(UID, HIGH_SDK_PACKAGE, AppOpsManager.MODE_ALLOWED);

        verify(mBatteryDatabaseManager).deleteAction(AnomalyDatabaseHelper.ActionType.RESTRICTION,
                UID, HIGH_SDK_PACKAGE);
    }

    @Test
    public void testIsForceAppStandbyEnabled_enabled_returnTrue() {
        when(mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID,
                PACKAGE_NAME)).thenReturn(AppOpsManager.MODE_IGNORED);

        assertThat(mBatteryUtils.isForceAppStandbyEnabled(UID, PACKAGE_NAME)).isTrue();
    }

    @Test
    public void testIsForceAppStandbyEnabled_disabled_returnFalse() {
        when(mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID,
                PACKAGE_NAME)).thenReturn(AppOpsManager.MODE_ALLOWED);

        assertThat(mBatteryUtils.isForceAppStandbyEnabled(UID, PACKAGE_NAME)).isFalse();
    }

    @Test
    public void testShouldHideAnomaly_systemAppWithLauncher_returnTrue() {
        final List<ResolveInfo> resolveInfos = new ArrayList<>();
        final ResolveInfo resolveInfo = new ResolveInfo();
        resolveInfo.activityInfo = new ActivityInfo();
        resolveInfo.activityInfo.packageName = HIGH_SDK_PACKAGE;

        doReturn(resolveInfos).when(mPackageManager).queryIntentActivities(any(), anyInt());
        doReturn(new String[]{HIGH_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(UID);
        mHighApplicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;

        assertThat(mBatteryUtils.shouldHideAnomaly(mPowerWhitelistBackend, UID,
                mAnomalyInfo)).isTrue();
    }

    @Test
    public void testShouldHideAnomaly_systemAppWithoutLauncher_returnTrue() {
        doReturn(new ArrayList<>()).when(mPackageManager).queryIntentActivities(any(), anyInt());
        doReturn(new String[]{HIGH_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(UID);
        mHighApplicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;

        assertThat(mBatteryUtils.shouldHideAnomaly(mPowerWhitelistBackend, UID,
                mAnomalyInfo)).isTrue();
    }

    @Test
    public void testShouldHideAnomaly_systemUid_returnTrue() {
        final int systemUid = Process.ROOT_UID;
        doReturn(new String[]{HIGH_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(systemUid);

        assertThat(mBatteryUtils.shouldHideAnomaly(mPowerWhitelistBackend, systemUid,
                mAnomalyInfo)).isTrue();
    }

    @Test
    public void testShouldHideAnomaly_AppInDozeList_returnTrue() {
        doReturn(new String[]{HIGH_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(UID);
        doReturn(true).when(mPowerWhitelistBackend).isWhitelisted(new String[]{HIGH_SDK_PACKAGE});

        assertThat(mBatteryUtils.shouldHideAnomaly(mPowerWhitelistBackend, UID,
                mAnomalyInfo)).isTrue();
    }

    @Test
    public void testShouldHideAnomaly_normalApp_returnFalse() {
        doReturn(new String[]{HIGH_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(UID);

        assertThat(mBatteryUtils.shouldHideAnomaly(mPowerWhitelistBackend, UID,
                mAnomalyInfo)).isFalse();
    }

    @Test
    public void testShouldHideAnomaly_excessivePriorOApp_returnFalse() {
        doReturn(new String[]{LOW_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(UID);
        mAnomalyInfo = new AnomalyInfo(INFO_EXCESSIVE);

        assertThat(mBatteryUtils.shouldHideAnomaly(mPowerWhitelistBackend, UID,
                mAnomalyInfo)).isFalse();
    }

    @Test
    public void testShouldHideAnomaly_excessiveOApp_returnTrue() {
        doReturn(new String[]{HIGH_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(UID);
        mAnomalyInfo = new AnomalyInfo(INFO_EXCESSIVE);

        assertThat(mBatteryUtils.shouldHideAnomaly(mPowerWhitelistBackend, UID,
                mAnomalyInfo)).isTrue();
    }

    @Test
    public void clearForceAppStandby_appRestricted_clearAndReturnTrue() {
        when(mBatteryUtils.getPackageUid(HIGH_SDK_PACKAGE)).thenReturn(UID);
        when(mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID,
                HIGH_SDK_PACKAGE)).thenReturn(AppOpsManager.MODE_IGNORED);

        assertThat(mBatteryUtils.clearForceAppStandby(HIGH_SDK_PACKAGE)).isTrue();
        verify(mAppOpsManager).setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID,
                HIGH_SDK_PACKAGE, AppOpsManager.MODE_ALLOWED);
    }

    @Test
    public void clearForceAppStandby_appInvalid_returnFalse() {
        when(mBatteryUtils.getPackageUid(PACKAGE_NAME)).thenReturn(BatteryUtils.UID_NULL);

        assertThat(mBatteryUtils.clearForceAppStandby(PACKAGE_NAME)).isFalse();
        verify(mAppOpsManager, never()).setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID,
                PACKAGE_NAME, AppOpsManager.MODE_ALLOWED);
    }

    @Test
    public void clearForceAppStandby_appUnrestricted_returnFalse() {
        when(mBatteryUtils.getPackageUid(PACKAGE_NAME)).thenReturn(UID);
        when(mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID,
                PACKAGE_NAME)).thenReturn(AppOpsManager.MODE_ALLOWED);

        assertThat(mBatteryUtils.clearForceAppStandby(PACKAGE_NAME)).isFalse();
        verify(mAppOpsManager, never()).setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID,
                PACKAGE_NAME, AppOpsManager.MODE_ALLOWED);
    }

    @Test
    public void getBatteryInfo_providerNull_shouldNotCrash() {
        when(mProvider.isEnhancedBatteryPredictionEnabled(mContext)).thenReturn(true);
        when(mProvider.getEnhancedBatteryPrediction(mContext)).thenReturn(null);
        when(mContext.registerReceiver(nullable(BroadcastReceiver.class),
                any(IntentFilter.class))).thenReturn(new Intent());

        //Should not crash
        assertThat(mBatteryUtils.getBatteryInfo(mBatteryStatsHelper, TAG)).isNotNull();
    }

    @Test
    public void getEnhancedEstimate_doesNotUpdateCache_ifEstimateFresh() {
        Estimate estimate = new Estimate(1000, true, 1000);
        Estimate.storeCachedEstimate(mContext, estimate);

        estimate = mBatteryUtils.getEnhancedEstimate();

        // only pass if estimate has not changed
        assertThat(estimate).isNotNull();
        assertThat(estimate.isBasedOnUsage()).isTrue();
        assertThat(estimate.getAverageDischargeTime()).isEqualTo(1000);
    }

    @Test
    public void testIsBatteryDefenderOn_isOverheatedAndIsCharging_returnTrue() {
        mBatteryInfo.isOverheated = true;
        mBatteryInfo.discharging = false;

        assertThat(mBatteryUtils.isBatteryDefenderOn(mBatteryInfo)).isTrue();
    }

    @Test
    public void testIsBatteryDefenderOn_isOverheatedAndDischarging_returnFalse() {
        mBatteryInfo.isOverheated = true;
        mBatteryInfo.discharging = true;

        assertThat(mBatteryUtils.isBatteryDefenderOn(mBatteryInfo)).isFalse();
    }

    @Test
    public void testIsBatteryDefenderOn_notOverheatedAndDischarging_returnFalse() {
        mBatteryInfo.isOverheated = false;
        mBatteryInfo.discharging = true;

        assertThat(mBatteryUtils.isBatteryDefenderOn(mBatteryInfo)).isFalse();
    }

    @Test
    public void testIsBatteryDefenderOn_notOverheatedAndIsCharging_returnFalse() {
        mBatteryInfo.isOverheated = false;
        mBatteryInfo.discharging = false;

        assertThat(mBatteryUtils.isBatteryDefenderOn(mBatteryInfo)).isFalse();
    }
}
