Transition BatteryInfo and BatteryUtils to BatteryUsageStats API

Bug: 173745486
Test: make RunSettingsRoboTests ROBOTEST_FILTER=com.android.settings.fuelgauge.BatteryHistoryPreferenceTest
Test: make RunSettingsRoboTests ROBOTEST_FILTER=com.android.settings.fuelgauge.BatteryInfoLoaderTest
Test: make RunSettingsRoboTests ROBOTEST_FILTER=com.android.settings.fuelgauge.BatteryInfoTest
Test: make RunSettingsRoboTests ROBOTEST_FILTER=com.android.settings.fuelgauge.BatteryUtilsTest
Test: make RunSettingsRoboTests ROBOTEST_FILTER=com.android.settings.fuelgauge.batterytip.detectors

Change-Id: I469ff8b88aa3307422c02f51943df4ef1759db56
diff --git a/src/com/android/settings/applications/appinfo/AppBatteryPreferenceController.java b/src/com/android/settings/applications/appinfo/AppBatteryPreferenceController.java
index 83b4241..307ceb1 100644
--- a/src/com/android/settings/applications/appinfo/AppBatteryPreferenceController.java
+++ b/src/com/android/settings/applications/appinfo/AppBatteryPreferenceController.java
@@ -230,7 +230,7 @@
         @Override
         @NonNull
         public Loader<BatteryUsageStats> onCreateLoader(int id, Bundle args) {
-            return new BatteryUsageStatsLoader(mContext);
+            return new BatteryUsageStatsLoader(mContext, /* includeBatteryHistory */ false);
         }
 
         @Override
diff --git a/src/com/android/settings/fuelgauge/BatteryHistoryPreference.java b/src/com/android/settings/fuelgauge/BatteryHistoryPreference.java
index faca9fb..4d3b9cd 100644
--- a/src/com/android/settings/fuelgauge/BatteryHistoryPreference.java
+++ b/src/com/android/settings/fuelgauge/BatteryHistoryPreference.java
@@ -17,15 +17,16 @@
 package com.android.settings.fuelgauge;
 
 import android.content.Context;
+import android.os.BatteryUsageStats;
 import android.util.AttributeSet;
 import android.view.View;
 import android.widget.TextView;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.VisibleForTesting;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceViewHolder;
 
-import com.android.internal.os.BatteryStatsHelper;
 import com.android.settings.R;
 import com.android.settings.widget.UsageView;
 
@@ -50,11 +51,11 @@
         setSelectable(false);
     }
 
-    public void setStats(BatteryStatsHelper batteryStats) {
+    void setBatteryUsageStats(@NonNull BatteryUsageStats batteryUsageStats) {
         BatteryInfo.getBatteryInfo(getContext(), info -> {
             mBatteryInfo = info;
             notifyChanged();
-        }, batteryStats, false);
+        }, batteryUsageStats, false);
     }
 
     public void setBottomSummary(CharSequence text) {
diff --git a/src/com/android/settings/fuelgauge/BatteryInfo.java b/src/com/android/settings/fuelgauge/BatteryInfo.java
index 5d7b325..a4dd86c 100644
--- a/src/com/android/settings/fuelgauge/BatteryInfo.java
+++ b/src/com/android/settings/fuelgauge/BatteryInfo.java
@@ -20,16 +20,18 @@
 import android.content.res.Resources;
 import android.os.AsyncTask;
 import android.os.BatteryManager;
-import android.os.BatteryStats;
 import android.os.BatteryStats.HistoryItem;
-import android.os.Bundle;
+import android.os.BatteryStatsManager;
+import android.os.BatteryUsageStats;
 import android.os.SystemClock;
 import android.text.format.Formatter;
 import android.util.SparseIntArray;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.annotation.WorkerThread;
 
-import com.android.internal.os.BatteryStatsHelper;
+import com.android.internal.os.BatteryStatsHistoryIterator;
 import com.android.settings.Utils;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.widget.UsageView;
@@ -52,7 +54,7 @@
     public String statusLabel;
     public String suggestionLabel;
     private boolean mCharging;
-    private BatteryStats mStats;
+    private BatteryUsageStats mBatteryUsageStats;
     private static final String LOG_TAG = "BatteryInfo";
     private long timePeriod;
 
@@ -126,7 +128,7 @@
             parserList[i] = parsers[i];
         }
         parserList[parsers.length] = parser;
-        parse(mStats, parserList);
+        parseBatteryHistory(parserList);
         String timeString = context.getString(R.string.charge_length_format,
                 Formatter.formatShortElapsedTime(context, timePeriod));
         String remaining = "";
@@ -137,22 +139,25 @@
         view.setBottomLabels(new CharSequence[]{timeString, remaining});
     }
 
-    public static void getBatteryInfo(final Context context, final Callback callback) {
-        BatteryInfo.getBatteryInfo(context, callback, null /* statsHelper */,
-                false /* shortString */);
-    }
-
     public static void getBatteryInfo(final Context context, final Callback callback,
             boolean shortString) {
-        BatteryInfo.getBatteryInfo(context, callback, null /* statsHelper */, shortString);
+        BatteryInfo.getBatteryInfo(context, callback,  /* batteryUsageStats */ null, shortString);
     }
 
     public static void getBatteryInfo(final Context context, final Callback callback,
-            final BatteryStatsHelper statsHelper, boolean shortString) {
+            @Nullable final BatteryUsageStats batteryUsageStats,
+            boolean shortString) {
         new AsyncTask<Void, Void, BatteryInfo>() {
             @Override
             protected BatteryInfo doInBackground(Void... params) {
-                return getBatteryInfo(context, statsHelper, shortString);
+                BatteryUsageStats stats;
+                if (batteryUsageStats != null) {
+                    stats = batteryUsageStats;
+                } else {
+                    stats = context.getSystemService(BatteryStatsManager.class)
+                            .getBatteryUsageStats();
+                }
+                return getBatteryInfo(context, stats, shortString);
             }
 
             @Override
@@ -164,18 +169,13 @@
         }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
     }
 
+    /**
+     * Creates a BatteryInfo based on BatteryUsageStats
+     */
+    @WorkerThread
     public static BatteryInfo getBatteryInfo(final Context context,
-            final BatteryStatsHelper statsHelper, boolean shortString) {
-        final BatteryStats stats;
+            @NonNull final BatteryUsageStats batteryUsageStats, boolean shortString) {
         final long batteryStatsTime = System.currentTimeMillis();
-        if (statsHelper == null) {
-            final BatteryStatsHelper localStatsHelper = new BatteryStatsHelper(context,
-                    true);
-            localStatsHelper.create((Bundle) null);
-            stats = localStatsHelper.getStats();
-        } else {
-            stats = statsHelper.getStats();
-        }
         BatteryUtils.logRuntime(LOG_TAG, "time for getStats", batteryStatsTime);
 
         final long startTime = System.currentTimeMillis();
@@ -197,38 +197,38 @@
                 Estimate.storeCachedEstimate(context, estimate);
                 BatteryUtils
                         .logRuntime(LOG_TAG, "time for enhanced BatteryInfo", startTime);
-                return BatteryInfo.getBatteryInfo(context, batteryBroadcast, stats,
+                return BatteryInfo.getBatteryInfo(context, batteryBroadcast, batteryUsageStats,
                         estimate, elapsedRealtimeUs, shortString);
             }
         }
-        final long prediction = discharging
-                ? stats.computeBatteryTimeRemaining(elapsedRealtimeUs) : 0;
+        final long prediction = discharging ? batteryUsageStats.getBatteryTimeRemainingMs() : 0;
         final Estimate estimate = new Estimate(
                 PowerUtil.convertUsToMs(prediction),
                 false, /* isBasedOnUsage */
                 EstimateKt.AVERAGE_TIME_TO_DISCHARGE_UNKNOWN);
         BatteryUtils.logRuntime(LOG_TAG, "time for regular BatteryInfo", startTime);
-        return BatteryInfo.getBatteryInfo(context, batteryBroadcast, stats,
+        return BatteryInfo.getBatteryInfo(context, batteryBroadcast, batteryUsageStats,
                 estimate, elapsedRealtimeUs, shortString);
     }
 
     @WorkerThread
     public static BatteryInfo getBatteryInfoOld(Context context, Intent batteryBroadcast,
-            BatteryStats stats, long elapsedRealtimeUs, boolean shortString) {
+            BatteryUsageStats batteryUsageStats, long elapsedRealtimeUs, boolean shortString) {
         Estimate estimate = new Estimate(
-                PowerUtil.convertUsToMs(stats.computeBatteryTimeRemaining(elapsedRealtimeUs)),
+                batteryUsageStats.getBatteryTimeRemainingMs(),
                 false,
                 EstimateKt.AVERAGE_TIME_TO_DISCHARGE_UNKNOWN);
-        return getBatteryInfo(context, batteryBroadcast, stats, estimate, elapsedRealtimeUs,
-                shortString);
+        return getBatteryInfo(context, batteryBroadcast, batteryUsageStats, estimate,
+                elapsedRealtimeUs, shortString);
     }
 
     @WorkerThread
     public static BatteryInfo getBatteryInfo(Context context, Intent batteryBroadcast,
-            BatteryStats stats, Estimate estimate, long elapsedRealtimeUs, boolean shortString) {
+            @NonNull BatteryUsageStats batteryUsageStats, Estimate estimate,
+            long elapsedRealtimeUs, boolean shortString) {
         final long startTime = System.currentTimeMillis();
         BatteryInfo info = new BatteryInfo();
-        info.mStats = stats;
+        info.mBatteryUsageStats = batteryUsageStats;
         info.batteryLevel = Utils.getBatteryLevel(batteryBroadcast);
         info.batteryPercentString = Utils.formatPercentage(info.batteryLevel);
         info.mCharging = batteryBroadcast.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0;
@@ -241,16 +241,17 @@
         if (!info.mCharging) {
             updateBatteryInfoDischarging(context, shortString, estimate, info);
         } else {
-            updateBatteryInfoCharging(context, batteryBroadcast, stats, elapsedRealtimeUs, info);
+            updateBatteryInfoCharging(context, batteryBroadcast, batteryUsageStats,
+                    info);
         }
         BatteryUtils.logRuntime(LOG_TAG, "time for getBatteryInfo", startTime);
         return info;
     }
 
     private static void updateBatteryInfoCharging(Context context, Intent batteryBroadcast,
-            BatteryStats stats, long elapsedRealtimeUs, BatteryInfo info) {
+            BatteryUsageStats stats, BatteryInfo info) {
         final Resources resources = context.getResources();
-        final long chargeTime = stats.computeChargeTimeRemaining(elapsedRealtimeUs);
+        final long chargeTimeMs = stats.getChargeTimeRemainingMs();
         final int status = batteryBroadcast.getIntExtra(BatteryManager.EXTRA_STATUS,
                 BatteryManager.BATTERY_STATUS_UNKNOWN);
         info.discharging = false;
@@ -260,8 +261,8 @@
             int chargingLimitedResId = R.string.power_charging_limited;
             info.chargeLabel =
                 context.getString(chargingLimitedResId, info.batteryPercentString);
-        } else if (chargeTime > 0 && status != BatteryManager.BATTERY_STATUS_FULL) {
-            info.remainingTimeUs = chargeTime;
+        } else if (chargeTimeMs > 0 && status != BatteryManager.BATTERY_STATUS_FULL) {
+            info.remainingTimeUs = PowerUtil.convertMsToUs(chargeTimeMs);
             CharSequence timeString = StringUtil.formatElapsedTime(context,
                     PowerUtil.convertUsToMs(info.remainingTimeUs), false /* withSeconds */);
             int resId = R.string.power_charging_duration;
@@ -313,7 +314,11 @@
         void onParsingDone();
     }
 
-    public static void parse(BatteryStats stats, BatteryDataParser... parsers) {
+    /**
+     * Iterates over battery history included in the BatteryUsageStats that this object
+     * was initialized with.
+     */
+    public void parseBatteryHistory(BatteryDataParser... parsers) {
         long startWalltime = 0;
         long endWalltime = 0;
         long historyStart = 0;
@@ -324,41 +329,41 @@
         int lastInteresting = 0;
         int pos = 0;
         boolean first = true;
-        if (stats.startIteratingHistoryLocked()) {
-            final HistoryItem rec = new HistoryItem();
-            while (stats.getNextHistoryLocked(rec)) {
-                pos++;
-                if (first) {
-                    first = false;
-                    historyStart = rec.time;
+        final BatteryStatsHistoryIterator iterator1 =
+                mBatteryUsageStats.iterateBatteryStatsHistory();
+        final HistoryItem rec = new HistoryItem();
+        while (iterator1.next(rec)) {
+            pos++;
+            if (first) {
+                first = false;
+                historyStart = rec.time;
+            }
+            if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
+                    || rec.cmd == HistoryItem.CMD_RESET) {
+                // If there is a ridiculously large jump in time, then we won't be
+                // able to create a good chart with that data, so just ignore the
+                // times we got before and pretend like our data extends back from
+                // the time we have now.
+                // Also, if we are getting a time change and we are less than 5 minutes
+                // since the start of the history real time, then also use this new
+                // time to compute the base time, since whatever time we had before is
+                // pretty much just noise.
+                if (rec.currentTime > (lastWallTime + (180 * 24 * 60 * 60 * 1000L))
+                        || rec.time < (historyStart + (5 * 60 * 1000L))) {
+                    startWalltime = 0;
                 }
-                if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
-                        || rec.cmd == HistoryItem.CMD_RESET) {
-                    // If there is a ridiculously large jump in time, then we won't be
-                    // able to create a good chart with that data, so just ignore the
-                    // times we got before and pretend like our data extends back from
-                    // the time we have now.
-                    // Also, if we are getting a time change and we are less than 5 minutes
-                    // since the start of the history real time, then also use this new
-                    // time to compute the base time, since whatever time we had before is
-                    // pretty much just noise.
-                    if (rec.currentTime > (lastWallTime + (180 * 24 * 60 * 60 * 1000L))
-                            || rec.time < (historyStart + (5 * 60 * 1000L))) {
-                        startWalltime = 0;
-                    }
-                    lastWallTime = rec.currentTime;
-                    lastRealtime = rec.time;
-                    if (startWalltime == 0) {
-                        startWalltime = lastWallTime - (lastRealtime - historyStart);
-                    }
-                }
-                if (rec.isDeltaData()) {
-                    lastInteresting = pos;
-                    historyEnd = rec.time;
+                lastWallTime = rec.currentTime;
+                lastRealtime = rec.time;
+                if (startWalltime == 0) {
+                    startWalltime = lastWallTime - (lastRealtime - historyStart);
                 }
             }
+            if (rec.isDeltaData()) {
+                lastInteresting = pos;
+                historyEnd = rec.time;
+            }
         }
-        stats.finishIteratingHistoryLocked();
+
         endWalltime = lastWallTime + historyEnd - lastRealtime;
 
         int i = 0;
@@ -367,9 +372,11 @@
         for (int j = 0; j < parsers.length; j++) {
             parsers[j].onParsingStarted(startWalltime, endWalltime);
         }
-        if (endWalltime > startWalltime && stats.startIteratingHistoryLocked()) {
-            final HistoryItem rec = new HistoryItem();
-            while (stats.getNextHistoryLocked(rec) && i < N) {
+
+        if (endWalltime > startWalltime) {
+            final BatteryStatsHistoryIterator iterator2 =
+                    mBatteryUsageStats.iterateBatteryStatsHistory();
+            while (iterator2.next(rec) && i < N) {
                 if (rec.isDeltaData()) {
                     curWalltime += rec.time - lastRealtime;
                     lastRealtime = rec.time;
@@ -404,8 +411,6 @@
             }
         }
 
-        stats.finishIteratingHistoryLocked();
-
         for (int j = 0; j < parsers.length; j++) {
             parsers[j].onParsingDone();
         }
diff --git a/src/com/android/settings/fuelgauge/BatteryInfoLoader.java b/src/com/android/settings/fuelgauge/BatteryInfoLoader.java
index cd87612..ffee462 100644
--- a/src/com/android/settings/fuelgauge/BatteryInfoLoader.java
+++ b/src/com/android/settings/fuelgauge/BatteryInfoLoader.java
@@ -19,7 +19,6 @@
 
 import androidx.annotation.VisibleForTesting;
 
-import com.android.internal.os.BatteryStatsHelper;
 import com.android.settingslib.utils.AsyncLoaderCompat;
 
 /**
@@ -28,17 +27,14 @@
  * when not available.
  */
 public class BatteryInfoLoader extends AsyncLoaderCompat<BatteryInfo>{
-
-    BatteryStatsHelper mStatsHelper;
     private static final String LOG_TAG = "BatteryInfoLoader";
 
     @VisibleForTesting
-    BatteryUtils batteryUtils;
+    BatteryUtils mBatteryUtils;
 
-    public BatteryInfoLoader(Context context, BatteryStatsHelper batteryStatsHelper) {
+    public BatteryInfoLoader(Context context) {
         super(context);
-        mStatsHelper = batteryStatsHelper;
-        batteryUtils = BatteryUtils.getInstance(context);
+        mBatteryUtils = BatteryUtils.getInstance(context);
     }
 
     @Override
@@ -48,6 +44,6 @@
 
     @Override
     public BatteryInfo loadInBackground() {
-        return batteryUtils.getBatteryInfo(mStatsHelper, LOG_TAG);
+        return mBatteryUtils.getBatteryInfo(LOG_TAG);
     }
 }
diff --git a/src/com/android/settings/fuelgauge/BatteryUsageStatsLoader.java b/src/com/android/settings/fuelgauge/BatteryUsageStatsLoader.java
index 5b184a9..d35ef82 100644
--- a/src/com/android/settings/fuelgauge/BatteryUsageStatsLoader.java
+++ b/src/com/android/settings/fuelgauge/BatteryUsageStatsLoader.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.os.BatteryStatsManager;
 import android.os.BatteryUsageStats;
+import android.os.BatteryUsageStatsQuery;
 
 import com.android.settingslib.utils.AsyncLoaderCompat;
 
@@ -27,15 +28,21 @@
  */
 public class BatteryUsageStatsLoader extends AsyncLoaderCompat<BatteryUsageStats> {
     private final BatteryStatsManager mBatteryStatsManager;
+    private final boolean mIncludeBatteryHistory;
 
-    public BatteryUsageStatsLoader(Context context) {
+    public BatteryUsageStatsLoader(Context context, boolean includeBatteryHistory) {
         super(context);
         mBatteryStatsManager = context.getSystemService(BatteryStatsManager.class);
+        mIncludeBatteryHistory = includeBatteryHistory;
     }
 
     @Override
     public BatteryUsageStats loadInBackground() {
-        return mBatteryStatsManager.getBatteryUsageStats();
+        final BatteryUsageStatsQuery.Builder builder = new BatteryUsageStatsQuery.Builder();
+        if (mIncludeBatteryHistory) {
+            builder.includeBatteryHistory();
+        }
+        return mBatteryStatsManager.getBatteryUsageStats(builder.build());
     }
 
     @Override
diff --git a/src/com/android/settings/fuelgauge/BatteryUtils.java b/src/com/android/settings/fuelgauge/BatteryUtils.java
index 5b1f096..8c0ab46 100644
--- a/src/com/android/settings/fuelgauge/BatteryUtils.java
+++ b/src/com/android/settings/fuelgauge/BatteryUtils.java
@@ -24,6 +24,9 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.os.BatteryStats;
+import android.os.BatteryStatsManager;
+import android.os.BatteryUsageStats;
+import android.os.BatteryUsageStatsQuery;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Process;
@@ -103,7 +106,7 @@
     }
 
     @VisibleForTesting
-    BatteryUtils(Context context) {
+    public BatteryUtils(Context context) {
         mContext = context;
         mPackageManager = context.getPackageManager();
         mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
@@ -472,29 +475,35 @@
     }
 
     @WorkerThread
-    public BatteryInfo getBatteryInfo(final BatteryStatsHelper statsHelper, final String tag) {
+    public BatteryInfo getBatteryInfo(final String tag) {
+        final BatteryStatsManager systemService = mContext.getSystemService(
+                BatteryStatsManager.class);
+        final BatteryUsageStats batteryUsageStats = systemService.getBatteryUsageStats(
+                new BatteryUsageStatsQuery.Builder().includeBatteryHistory().build());
+
         final long startTime = System.currentTimeMillis();
 
         // Stuff we always need to get BatteryInfo
         final Intent batteryBroadcast = mContext.registerReceiver(null,
                 new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
+
         final long elapsedRealtimeUs = PowerUtil.convertMsToUs(
                 SystemClock.elapsedRealtime());
-        final BatteryStats stats = statsHelper.getStats();
+
         BatteryInfo batteryInfo;
         Estimate estimate = getEnhancedEstimate();
 
         // couldn't get estimate from cache or provider, use fallback
         if (estimate == null) {
             estimate = new Estimate(
-                    PowerUtil.convertUsToMs(stats.computeBatteryTimeRemaining(elapsedRealtimeUs)),
+                    PowerUtil.convertUsToMs(batteryUsageStats.getBatteryTimeRemainingMs()),
                     false /* isBasedOnUsage */,
                     EstimateKt.AVERAGE_TIME_TO_DISCHARGE_UNKNOWN);
         }
 
         BatteryUtils.logRuntime(tag, "BatteryInfoLoader post query", startTime);
-        batteryInfo = BatteryInfo.getBatteryInfo(mContext, batteryBroadcast, stats,
-                estimate, elapsedRealtimeUs, false /* shortString */);
+        batteryInfo = BatteryInfo.getBatteryInfo(mContext, batteryBroadcast,
+                batteryUsageStats, estimate, elapsedRealtimeUs, false /* shortString */);
         BatteryUtils.logRuntime(tag, "BatteryInfoLoader.loadInBackground", startTime);
 
         return batteryInfo;
diff --git a/src/com/android/settings/fuelgauge/DebugEstimatesLoader.java b/src/com/android/settings/fuelgauge/DebugEstimatesLoader.java
index c8dbb59..0623bcb 100644
--- a/src/com/android/settings/fuelgauge/DebugEstimatesLoader.java
+++ b/src/com/android/settings/fuelgauge/DebugEstimatesLoader.java
@@ -19,6 +19,8 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.os.BatteryStats;
+import android.os.BatteryStatsManager;
+import android.os.BatteryUsageStats;
 import android.os.SystemClock;
 
 import com.android.internal.os.BatteryStatsHelper;
@@ -56,15 +58,17 @@
         Intent batteryBroadcast = getContext().registerReceiver(null,
                 new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
         BatteryStats stats = mStatsHelper.getStats();
-
+        BatteryUsageStats batteryUsageStats =
+                context.getSystemService(BatteryStatsManager.class).getBatteryUsageStats();
         BatteryInfo oldinfo = BatteryInfo.getBatteryInfoOld(getContext(), batteryBroadcast,
-                stats, elapsedRealtimeUs, false);
+                batteryUsageStats, elapsedRealtimeUs, false);
 
         Estimate estimate = powerUsageFeatureProvider.getEnhancedBatteryPrediction(context);
         if (estimate == null) {
             estimate = new Estimate(0, false, EstimateKt.AVERAGE_TIME_TO_DISCHARGE_UNKNOWN);
         }
-        BatteryInfo newInfo = BatteryInfo.getBatteryInfo(getContext(), batteryBroadcast, stats,
+        BatteryInfo newInfo = BatteryInfo.getBatteryInfo(getContext(), batteryBroadcast,
+                batteryUsageStats,
                 estimate, elapsedRealtimeUs, false);
 
         List<BatteryInfo> infos = new ArrayList<>();
diff --git a/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java b/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java
index befede4..86e52d9 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java
@@ -142,6 +142,11 @@
     }
 
     @Override
+    protected boolean isBatteryHistoryNeeded() {
+        return true;
+    }
+
+    @Override
     protected void refreshUi(@BatteryUpdateType int refreshType) {
         final Context context = getContext();
         if (context == null) {
diff --git a/src/com/android/settings/fuelgauge/PowerUsageBase.java b/src/com/android/settings/fuelgauge/PowerUsageBase.java
index 3a5ed6c..29ecedc 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageBase.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageBase.java
@@ -19,10 +19,12 @@
 
 import android.app.Activity;
 import android.content.Context;
+import android.os.BatteryUsageStats;
 import android.os.Bundle;
 import android.os.UserManager;
 import android.view.Menu;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.VisibleForTesting;
 import androidx.loader.app.LoaderManager;
 import androidx.loader.content.Loader;
@@ -40,12 +42,29 @@
     static final int MENU_STATS_REFRESH = Menu.FIRST + 1;
     private static final String TAG = "PowerUsageBase";
     private static final String KEY_REFRESH_TYPE = "refresh_type";
+    private static final String KEY_INCLUDE_HISTORY = "include_history";
+
+    private static final int LOADER_BATTERY_STATS_HELPER = 0;
+    private static final int LOADER_BATTERY_USAGE_STATS = 1;
 
     protected BatteryStatsHelper mStatsHelper;
+    @VisibleForTesting
+    BatteryUsageStats mBatteryUsageStats;
+
     protected UserManager mUm;
     private BatteryBroadcastReceiver mBatteryBroadcastReceiver;
     protected boolean mIsBatteryPresent = true;
 
+    // TODO(b/180630447): switch to BatteryUsageStatsLoader and remove all references to
+    // BatteryStatsHelper and BatterySipper
+    @VisibleForTesting
+    final BatteryStatsHelperLoaderCallbacks mBatteryStatsHelperLoaderCallbacks =
+            new BatteryStatsHelperLoaderCallbacks();
+
+    @VisibleForTesting
+    final BatteryUsageStatsLoaderCallbacks mBatteryUsageStatsLoaderCallbacks =
+            new BatteryUsageStatsLoaderCallbacks();
+
     @Override
     public void onAttach(Activity activity) {
         super.onAttach(activity);
@@ -83,42 +102,73 @@
     protected void restartBatteryStatsLoader(int refreshType) {
         final Bundle bundle = new Bundle();
         bundle.putInt(KEY_REFRESH_TYPE, refreshType);
+        bundle.putBoolean(KEY_INCLUDE_HISTORY, isBatteryHistoryNeeded());
+        getLoaderManager().restartLoader(LOADER_BATTERY_STATS_HELPER, bundle,
+                mBatteryStatsHelperLoaderCallbacks);
+        getLoaderManager().restartLoader(LOADER_BATTERY_USAGE_STATS, bundle,
+                mBatteryUsageStatsLoaderCallbacks);
+    }
 
-        getLoaderManager().restartLoader(0, bundle, new PowerLoaderCallback());
+    private void onLoadFinished(@BatteryUpdateType int refreshType) {
+        // Wait for both loaders to finish before proceeding.
+        if (mStatsHelper == null || mBatteryUsageStats == null) {
+            return;
+        }
+
+        refreshUi(refreshType);
     }
 
     protected abstract void refreshUi(@BatteryUpdateType int refreshType);
+    protected abstract boolean isBatteryHistoryNeeded();
 
     protected void updatePreference(BatteryHistoryPreference historyPref) {
         final long startTime = System.currentTimeMillis();
-        historyPref.setStats(mStatsHelper);
+        historyPref.setBatteryUsageStats(mBatteryUsageStats);
         BatteryUtils.logRuntime(TAG, "updatePreference", startTime);
     }
 
-    /**
-     * {@link android.app.LoaderManager.LoaderCallbacks} for {@link PowerUsageBase} to load
-     * the {@link BatteryStatsHelper}
-     */
-    public class PowerLoaderCallback implements LoaderManager.LoaderCallbacks<BatteryStatsHelper> {
+    private class BatteryStatsHelperLoaderCallbacks
+            implements LoaderManager.LoaderCallbacks<BatteryStatsHelper> {
         private int mRefreshType;
 
         @Override
-        public Loader<BatteryStatsHelper> onCreateLoader(int id,
-                Bundle args) {
+        public Loader<BatteryStatsHelper> onCreateLoader(int id, Bundle args) {
             mRefreshType = args.getInt(KEY_REFRESH_TYPE);
             return new BatteryStatsHelperLoader(getContext());
         }
 
         @Override
         public void onLoadFinished(Loader<BatteryStatsHelper> loader,
-                BatteryStatsHelper statsHelper) {
-            mStatsHelper = statsHelper;
-            refreshUi(mRefreshType);
+                BatteryStatsHelper batteryHelper) {
+            mStatsHelper = batteryHelper;
+            PowerUsageBase.this.onLoadFinished(mRefreshType);
         }
 
         @Override
         public void onLoaderReset(Loader<BatteryStatsHelper> loader) {
+        }
+    }
 
+    private class BatteryUsageStatsLoaderCallbacks
+            implements LoaderManager.LoaderCallbacks<BatteryUsageStats> {
+        private int mRefreshType;
+
+        @Override
+        @NonNull
+        public Loader<BatteryUsageStats> onCreateLoader(int id, Bundle args) {
+            mRefreshType = args.getInt(KEY_REFRESH_TYPE);
+            return new BatteryUsageStatsLoader(getContext(), args.getBoolean(KEY_INCLUDE_HISTORY));
+        }
+
+        @Override
+        public void onLoadFinished(Loader<BatteryUsageStats> loader,
+                BatteryUsageStats batteryUsageStats) {
+            mBatteryUsageStats = batteryUsageStats;
+            PowerUsageBase.this.onLoadFinished(mRefreshType);
+        }
+
+        @Override
+        public void onLoaderReset(Loader<BatteryUsageStats> loader) {
         }
     }
 }
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
index c00c131..4f8ac62 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
@@ -88,7 +88,7 @@
 
                 @Override
                 public Loader<BatteryInfo> onCreateLoader(int i, Bundle bundle) {
-                    return new BatteryInfoLoader(getContext(), mStatsHelper);
+                    return new BatteryInfoLoader(getContext());
                 }
 
                 @Override
@@ -190,6 +190,11 @@
         return R.string.help_url_battery;
     }
 
+    @Override
+    protected boolean isBatteryHistoryNeeded() {
+        return false;
+    }
+
     protected void refreshUi(@BatteryUpdateType int refreshType) {
         final Context context = getContext();
         if (context == null) {
diff --git a/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoader.java b/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoader.java
index 0c916b2..9b80a1f 100644
--- a/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoader.java
+++ b/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoader.java
@@ -65,12 +65,11 @@
         }
         final List<BatteryTip> tips = new ArrayList<>();
         final BatteryTipPolicy policy = new BatteryTipPolicy(getContext());
-        final BatteryInfo batteryInfo = mBatteryUtils.getBatteryInfo(mBatteryStatsHelper, TAG);
+        final BatteryInfo batteryInfo = mBatteryUtils.getBatteryInfo(TAG);
         final Context context = getContext();
 
         tips.add(new LowBatteryDetector(context, policy, batteryInfo).detect());
-        tips.add(new HighUsageDetector(context, policy, mBatteryStatsHelper,
-                batteryInfo.discharging).detect());
+        tips.add(new HighUsageDetector(context, policy, mBatteryStatsHelper, batteryInfo).detect());
         tips.add(new SmartBatteryDetector(policy, context.getContentResolver()).detect());
         tips.add(new EarlyWarningDetector(policy, context).detect());
         tips.add(new BatteryDefenderDetector(batteryInfo).detect());
diff --git a/src/com/android/settings/fuelgauge/batterytip/detectors/HighUsageDetector.java b/src/com/android/settings/fuelgauge/batterytip/detectors/HighUsageDetector.java
index 067046c..928ae52 100644
--- a/src/com/android/settings/fuelgauge/batterytip/detectors/HighUsageDetector.java
+++ b/src/com/android/settings/fuelgauge/batterytip/detectors/HighUsageDetector.java
@@ -45,6 +45,7 @@
 public class HighUsageDetector implements BatteryTipDetector {
     private BatteryTipPolicy mPolicy;
     private BatteryStatsHelper mBatteryStatsHelper;
+    private final BatteryInfo mBatteryInfo;
     private List<AppInfo> mHighUsageAppList;
     @VisibleForTesting
     HighUsageDataParser mDataParser;
@@ -54,14 +55,15 @@
     boolean mDischarging;
 
     public HighUsageDetector(Context context, BatteryTipPolicy policy,
-            BatteryStatsHelper batteryStatsHelper, boolean discharging) {
+            BatteryStatsHelper batteryStatsHelper, BatteryInfo batteryInfo) {
         mPolicy = policy;
         mBatteryStatsHelper = batteryStatsHelper;
+        mBatteryInfo = batteryInfo;
         mHighUsageAppList = new ArrayList<>();
         mBatteryUtils = BatteryUtils.getInstance(context);
         mDataParser = new HighUsageDataParser(mPolicy.highUsagePeriodMs,
                 mPolicy.highUsageBatteryDraining);
-        mDischarging = discharging;
+        mDischarging = batteryInfo.discharging;
     }
 
     @Override
@@ -115,6 +117,6 @@
 
     @VisibleForTesting
     void parseBatteryData() {
-        BatteryInfo.parse(mBatteryStatsHelper.getStats(), mDataParser);
+        mBatteryInfo.parseBatteryHistory(mDataParser);
     }
 }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryInfoLoaderTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryInfoLoaderTest.java
index 6593767..5bcaf0a 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryInfoLoaderTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryInfoLoaderTest.java
@@ -19,23 +19,23 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.content.Intent;
-import android.os.BatteryStats;
+import android.os.BatteryStatsManager;
+import android.os.BatteryUsageStats;
+import android.os.BatteryUsageStatsQuery;
 
-import com.android.internal.os.BatteryStatsHelper;
 import com.android.settings.testutils.BatteryTestUtils;
 import com.android.settings.testutils.FakeFeatureFactory;
 
 import org.junit.Before;
 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;
@@ -46,10 +46,10 @@
 
     private static final long TEST_TIME_REMAINING = 1000L;
 
-    @Mock (answer = Answers.RETURNS_DEEP_STUBS)
-    private BatteryStatsHelper mHelper;
-    @Mock (answer = Answers.RETURNS_DEEP_STUBS)
-    private BatteryStats mStats;
+    @Mock
+    private BatteryStatsManager mBatteryStatsManager;
+    @Mock
+    private BatteryUsageStats mBatteryUsageStats;
 
     private Context mContext;
 
@@ -60,8 +60,11 @@
         FakeFeatureFactory.setupForTest().getPowerUsageFeatureProvider(mContext);
 
         doReturn(mContext).when(mContext).getApplicationContext();
-        when(mStats.computeBatteryTimeRemaining(anyLong())).thenReturn(TEST_TIME_REMAINING);
-        doReturn(mStats).when(mHelper).getStats();
+        when(mContext.getSystemService(eq(Context.BATTERY_STATS_SERVICE)))
+                .thenReturn(mBatteryStatsManager);
+        when(mBatteryUsageStats.getBatteryTimeRemainingMs()).thenReturn(TEST_TIME_REMAINING);
+        when(mBatteryStatsManager.getBatteryUsageStats(any(BatteryUsageStatsQuery.class)))
+                .thenReturn(mBatteryUsageStats);
 
         final Intent dischargingBatteryBroadcast = BatteryTestUtils.getDischargingIntent();
         doReturn(dischargingBatteryBroadcast).when(mContext).registerReceiver(any(), any());
@@ -69,8 +72,8 @@
 
     @Test
     public void test_loadInBackground_dischargingOldEstimate_dischargingLabelNotNull() {
-        BatteryInfoLoader loader = new BatteryInfoLoader(mContext, mHelper);
-        loader.batteryUtils = new BatteryUtils(mContext);
+        BatteryInfoLoader loader = new BatteryInfoLoader(mContext);
+        loader.mBatteryUtils = new BatteryUtils(mContext);
 
         BatteryInfo info = loader.loadInBackground();
 
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryInfoTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryInfoTest.java
index 4c19477..18c5326 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryInfoTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryInfoTest.java
@@ -34,9 +34,11 @@
 import android.content.Intent;
 import android.os.BatteryManager;
 import android.os.BatteryStats;
+import android.os.BatteryUsageStats;
 import android.os.SystemClock;
 import android.util.SparseIntArray;
 
+import com.android.internal.os.BatteryStatsHistoryIterator;
 import com.android.settings.testutils.BatteryTestUtils;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.widget.UsageView;
@@ -46,7 +48,6 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.Answers;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
@@ -83,9 +84,8 @@
     private Intent mChargingBatteryBroadcast;
     private Context mContext;
     private FakeFeatureFactory mFeatureFactory;
-
-    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
-    private BatteryStats mBatteryStats;
+    @Mock
+    private BatteryUsageStats mBatteryUsageStats;
 
     @Before
     public void setUp() {
@@ -100,9 +100,10 @@
 
     @Test
     public void testGetBatteryInfo_hasStatusLabel() {
-        doReturn(REMAINING_TIME_NULL).when(mBatteryStats).computeBatteryTimeRemaining(anyLong());
+        doReturn(REMAINING_TIME_NULL).when(mBatteryUsageStats).getBatteryTimeRemainingMs();
         BatteryInfo info = BatteryInfo.getBatteryInfoOld(mContext,
-                mDisChargingBatteryBroadcast, mBatteryStats, SystemClock.elapsedRealtime() * 1000,
+                mDisChargingBatteryBroadcast, mBatteryUsageStats,
+                SystemClock.elapsedRealtime() * 1000,
                 true /* shortString */);
 
         assertThat(info.statusLabel).isEqualTo(STATUS_NOT_CHARGING);
@@ -110,28 +111,28 @@
 
     @Test
     public void testGetBatteryInfo_doNotShowChargingMethod_hasRemainingTime() {
-        doReturn(REMAINING_TIME).when(mBatteryStats).computeChargeTimeRemaining(anyLong());
+        doReturn(REMAINING_TIME).when(mBatteryUsageStats).getChargeTimeRemainingMs();
         BatteryInfo info = BatteryInfo.getBatteryInfoOld(mContext, mChargingBatteryBroadcast,
-                mBatteryStats, SystemClock.elapsedRealtime() * 1000, false /* shortString */);
+                mBatteryUsageStats, SystemClock.elapsedRealtime() * 1000, false /* shortString */);
 
         assertThat(info.chargeLabel.toString()).isEqualTo(STATUS_CHARGING_TIME);
     }
 
     @Test
     public void testGetBatteryInfo_doNotShowChargingMethod_noRemainingTime() {
-        doReturn(REMAINING_TIME_NULL).when(mBatteryStats).computeChargeTimeRemaining(anyLong());
+        doReturn(REMAINING_TIME_NULL).when(mBatteryUsageStats).getChargeTimeRemainingMs();
         BatteryInfo info = BatteryInfo.getBatteryInfoOld(mContext, mChargingBatteryBroadcast,
-                mBatteryStats, SystemClock.elapsedRealtime() * 1000, false /* shortString */);
+                mBatteryUsageStats, SystemClock.elapsedRealtime() * 1000, false /* shortString */);
 
         assertThat(info.chargeLabel.toString()).isEqualTo(STATUS_CHARGING_NO_TIME);
     }
 
     @Test
     public void testGetBatteryInfo_pluggedInUsingShortString_usesCorrectData() {
-        doReturn(TEST_CHARGE_TIME_REMAINING).when(mBatteryStats).computeChargeTimeRemaining(
-                anyLong());
+        doReturn(TEST_CHARGE_TIME_REMAINING / 1000)
+                .when(mBatteryUsageStats).getChargeTimeRemainingMs();
         BatteryInfo info = BatteryInfo.getBatteryInfoOld(mContext, mChargingBatteryBroadcast,
-                mBatteryStats, SystemClock.elapsedRealtime() * 1000, true /* shortString */);
+                mBatteryUsageStats, SystemClock.elapsedRealtime() * 1000, true /* shortString */);
 
         assertThat(info.discharging).isEqualTo(false);
         assertThat(info.chargeLabel.toString()).isEqualTo("50% - 1 min until charged");
@@ -143,10 +144,10 @@
                 true /* isBasedOnUsage */,
                 1000 /* averageDischargeTime */);
         BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast,
-                mBatteryStats, estimate, SystemClock.elapsedRealtime() * 1000,
+                mBatteryUsageStats, estimate, SystemClock.elapsedRealtime() * 1000,
                 false /* shortString */);
         BatteryInfo info2 = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast,
-                mBatteryStats, estimate, SystemClock.elapsedRealtime() * 1000,
+                mBatteryUsageStats, estimate, SystemClock.elapsedRealtime() * 1000,
                 true /* shortString */);
 
         // We only add special mention for the long string
@@ -163,10 +164,10 @@
                 true /* isBasedOnUsage */,
                 1000 /* averageDischargeTime */);
         BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast,
-                mBatteryStats, estimate, SystemClock.elapsedRealtime() * 1000,
+                mBatteryUsageStats, estimate, SystemClock.elapsedRealtime() * 1000,
                 false /* shortString */);
         BatteryInfo info2 = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast,
-                mBatteryStats, estimate, SystemClock.elapsedRealtime() * 1000,
+                mBatteryUsageStats, estimate, SystemClock.elapsedRealtime() * 1000,
                 true /* shortString */);
 
         // These should be identical in either case
@@ -183,7 +184,7 @@
                 true /* isBasedOnUsage */,
                 1000 /* averageDischargeTime */);
         BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast,
-                mBatteryStats, estimate, SystemClock.elapsedRealtime() * 1000,
+                mBatteryUsageStats, estimate, SystemClock.elapsedRealtime() * 1000,
                 false /* shortString */);
 
         assertThat(info.suggestionLabel).doesNotContain(BATTERY_RUN_OUT_PREFIX);
@@ -196,7 +197,7 @@
                 true /* isBasedOnUsage */,
                 1000 /* averageDischargeTime */);
         BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast,
-                mBatteryStats, estimate, SystemClock.elapsedRealtime() * 1000,
+                mBatteryUsageStats, estimate, SystemClock.elapsedRealtime() * 1000,
                 false /* shortString */);
 
         // Check that strings are showing less than 15 minutes remaining regardless of exact time.
@@ -211,10 +212,10 @@
     @Test
     public void testGetBatteryInfo_basedOnUsageFalse_usesDefaultString() {
         BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast,
-                mBatteryStats, MOCK_ESTIMATE, SystemClock.elapsedRealtime() * 1000,
+                mBatteryUsageStats, MOCK_ESTIMATE, SystemClock.elapsedRealtime() * 1000,
                 false /* shortString */);
         BatteryInfo info2 = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast,
-                mBatteryStats, MOCK_ESTIMATE, SystemClock.elapsedRealtime() * 1000,
+                mBatteryUsageStats, MOCK_ESTIMATE, SystemClock.elapsedRealtime() * 1000,
                 true /* shortString */);
 
         assertThat(info.remainingLabel.toString()).doesNotContain(ENHANCED_STRING_SUFFIX);
@@ -223,12 +224,11 @@
 
     @Test
     public void testGetBatteryInfo_charging_usesChargeTime() {
-        doReturn(TEST_CHARGE_TIME_REMAINING)
-                .when(mBatteryStats)
-                .computeChargeTimeRemaining(anyLong());
+        doReturn(TEST_CHARGE_TIME_REMAINING / 1000)
+                .when(mBatteryUsageStats).getChargeTimeRemainingMs();
 
         BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mChargingBatteryBroadcast,
-                mBatteryStats, MOCK_ESTIMATE, SystemClock.elapsedRealtime() * 1000,
+                mBatteryUsageStats, MOCK_ESTIMATE, SystemClock.elapsedRealtime() * 1000,
                 false /* shortString */);
         assertThat(info.remainingTimeUs).isEqualTo(TEST_CHARGE_TIME_REMAINING);
         assertThat(info.remainingLabel.toString())
@@ -240,7 +240,7 @@
         mChargingBatteryBroadcast.putExtra(BatteryManager.EXTRA_LEVEL, 100);
 
         BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mChargingBatteryBroadcast,
-                mBatteryStats, MOCK_ESTIMATE, SystemClock.elapsedRealtime() * 1000,
+                mBatteryUsageStats, MOCK_ESTIMATE, SystemClock.elapsedRealtime() * 1000,
                 false /* shortString */);
 
         assertThat(info.chargeLabel).isEqualTo("100%");
@@ -249,13 +249,13 @@
     @Test
     public void testGetBatteryInfo_chargingWithOverheated_updateChargeLabel() {
         doReturn(TEST_CHARGE_TIME_REMAINING)
-                .when(mBatteryStats)
-                .computeChargeTimeRemaining(anyLong());
+                .when(mBatteryUsageStats)
+                .getChargeTimeRemainingMs();
         mChargingBatteryBroadcast
                 .putExtra(BatteryManager.EXTRA_HEALTH, BatteryManager.BATTERY_HEALTH_OVERHEAT);
 
         BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mChargingBatteryBroadcast,
-                mBatteryStats, MOCK_ESTIMATE, SystemClock.elapsedRealtime() * 1000,
+                mBatteryUsageStats, MOCK_ESTIMATE, SystemClock.elapsedRealtime() * 1000,
                 false /* shortString */);
 
         assertThat(info.isOverheated).isTrue();
@@ -264,28 +264,29 @@
 
     // Make our battery stats return a sequence of battery events.
     private void mockBatteryStatsHistory() {
-        // Mock out new data every time start...Locked is called.
+        // Mock out new data every time iterateBatteryStatsHistory is called.
         doAnswer(invocation -> {
-            doAnswer(new Answer() {
-                private int count = 0;
-                private long[] times = {1000, 1500, 2000};
-                private byte[] levels = {99, 98, 97};
+            BatteryStatsHistoryIterator iterator = mock(BatteryStatsHistoryIterator.class);
+            doAnswer(new Answer<Boolean>() {
+                private int mCount = 0;
+                private final long[] mTimes = {1000, 1500, 2000};
+                private final byte[] mLevels = {99, 98, 97};
 
                 @Override
-                public Object answer(InvocationOnMock invocation) throws Throwable {
-                    if (count == times.length) {
+                public Boolean answer(InvocationOnMock invocation) throws Throwable {
+                    if (mCount == mTimes.length) {
                         return false;
                     }
                     BatteryStats.HistoryItem record = invocation.getArgument(0);
                     record.cmd = BatteryStats.HistoryItem.CMD_UPDATE;
-                    record.time = times[count];
-                    record.batteryLevel = levels[count];
-                    count++;
+                    record.time = mTimes[mCount];
+                    record.batteryLevel = mLevels[mCount];
+                    mCount++;
                     return true;
                 }
-            }).when(mBatteryStats).getNextHistoryLocked(any(BatteryStats.HistoryItem.class));
-            return true;
-        }).when(mBatteryStats).startIteratingHistoryLocked();
+            }).when(iterator).next(any(BatteryStats.HistoryItem.class));
+            return iterator;
+        }).when(mBatteryUsageStats).iterateBatteryStatsHistory();
     }
 
     private void assertOnlyHistory(BatteryInfo info) {
@@ -337,9 +338,9 @@
 
     private BatteryInfo getBatteryInfo(boolean charging, boolean enhanced, boolean estimate) {
         if (charging && estimate) {
-            doReturn(1000L).when(mBatteryStats).computeChargeTimeRemaining(anyLong());
+            doReturn(1000L).when(mBatteryUsageStats).getChargeTimeRemainingMs();
         } else {
-            doReturn(0L).when(mBatteryStats).computeChargeTimeRemaining(anyLong());
+            doReturn(0L).when(mBatteryUsageStats).getChargeTimeRemainingMs();
         }
         Estimate batteryEstimate = new Estimate(
                 estimate ? 1000 : 0,
@@ -347,7 +348,7 @@
                 1000 /* averageDischargeTime */);
         BatteryInfo info = BatteryInfo.getBatteryInfo(mContext,
                 charging ? mChargingBatteryBroadcast : mDisChargingBatteryBroadcast,
-                mBatteryStats, batteryEstimate, SystemClock.elapsedRealtime() * 1000, false);
+                mBatteryUsageStats, batteryEstimate, SystemClock.elapsedRealtime() * 1000, false);
         doReturn(enhanced).when(mFeatureFactory.powerUsageFeatureProvider)
                 .isEnhancedBatteryPredictionEnabled(mContext);
         return info;
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
index f393da8..c8fdf8c 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
@@ -48,6 +48,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.os.BatteryStats;
+import android.os.BatteryStatsManager;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Process;
@@ -157,6 +158,8 @@
     private ApplicationInfo mApplicationInfo;
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private BatteryStatsHelper mBatteryStatsHelper;
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private BatteryStatsManager mBatteryStatsManager;
     @Mock
     private ApplicationInfo mHighApplicationInfo;
     @Mock
@@ -228,6 +231,8 @@
         mContext = spy(RuntimeEnvironment.application);
         doReturn(mPackageManager).when(mContext).getPackageManager();
         doReturn(mAppOpsManager).when(mContext).getSystemService(Context.APP_OPS_SERVICE);
+        doReturn(mBatteryStatsManager).when(mContext)
+                .getSystemService(Context.BATTERY_STATS_SERVICE);
         mBatteryUtils = spy(new BatteryUtils(mContext));
         mBatteryUtils.mPowerUsageFeatureProvider = mProvider;
         doReturn(0L).when(mBatteryUtils)
@@ -741,7 +746,7 @@
                 any(IntentFilter.class))).thenReturn(new Intent());
 
         //Should not crash
-        assertThat(mBatteryUtils.getBatteryInfo(mBatteryStatsHelper, TAG)).isNotNull();
+        assertThat(mBatteryUtils.getBatteryInfo(TAG)).isNotNull();
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageBaseTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageBaseTest.java
index cd1b178..8754700 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageBaseTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageBaseTest.java
@@ -75,6 +75,11 @@
         }
 
         @Override
+        protected boolean isBatteryHistoryNeeded() {
+            return false;
+        }
+
+        @Override
         protected void refreshUi(int refreshType) {
             // Do nothing
         }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoaderTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoaderTest.java
index 8cc17d8..c97d79f 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoaderTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoaderTest.java
@@ -77,7 +77,7 @@
         doReturn(mContext).when(mContext).getApplicationContext();
         doReturn(mPowerManager).when(mContext).getSystemService(Context.POWER_SERVICE);
         doReturn(mIntent).when(mContext).registerReceiver(any(), any());
-        doReturn(mBatteryInfo).when(mBatteryUtils).getBatteryInfo(any(), any());
+        doReturn(mBatteryInfo).when(mBatteryUtils).getBatteryInfo(any());
         mBatteryTipLoader = new BatteryTipLoader(mContext, mBatteryStatsHelper);
         mBatteryTipLoader.mBatteryUtils = mBatteryUtils;
     }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/HighUsageDetectorTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/HighUsageDetectorTest.java
index 5c56f46..93005d5 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/HighUsageDetectorTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/HighUsageDetectorTest.java
@@ -18,7 +18,9 @@
 
 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.eq;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
@@ -26,8 +28,11 @@
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
+import android.content.Intent;
 import android.os.BatteryStats;
-import android.text.format.DateUtils;
+import android.os.BatteryStatsManager;
+import android.os.BatteryUsageStats;
+import android.os.BatteryUsageStatsQuery;
 
 import com.android.internal.os.BatterySipper;
 import com.android.internal.os.BatteryStatsHelper;
@@ -53,6 +58,8 @@
 
 @RunWith(RobolectricTestRunner.class)
 public class HighUsageDetectorTest {
+    private static final String TAG = "HighUsageDetectorTest";
+
     private static final int UID_HIGH = 123;
     private static final int UID_LOW = 345;
     private static final double POWER_HIGH = 20000;
@@ -68,6 +75,10 @@
     private BatterySipper mSystemBatterySipper;
     @Mock
     private HighUsageDataParser mDataParser;
+    @Mock
+    private BatteryUsageStats mBatteryUsageStats;
+    @Mock
+    private BatteryStatsManager mBatteryStatsManager;
 
     private AppInfo mHighAppInfo;
     private AppInfo mLowAppInfo;
@@ -80,11 +91,19 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
 
-        mContext = RuntimeEnvironment.application;
+        mContext = spy(RuntimeEnvironment.application);
         mPolicy = spy(new BatteryTipPolicy(mContext));
-        mBatteryUtils = spy(BatteryUtils.getInstance(mContext));
+        mBatteryUtils = spy(new BatteryUtils(mContext));
+
+        when(mContext.getSystemService(eq(Context.BATTERY_STATS_SERVICE)))
+                .thenReturn(mBatteryStatsManager);
+        when(mBatteryStatsManager.getBatteryUsageStats(any(BatteryUsageStatsQuery.class)))
+                .thenReturn(mBatteryUsageStats);
+
+        mContext.sendStickyBroadcast(new Intent(Intent.ACTION_BATTERY_CHANGED));
+
         mHighUsageDetector = spy(new HighUsageDetector(mContext, mPolicy, mBatteryStatsHelper,
-                true /* mDischarging */));
+                mBatteryUtils.getBatteryInfo(TAG)));
         mHighUsageDetector.mBatteryUtils = mBatteryUtils;
         mHighUsageDetector.mDataParser = mDataParser;
         doNothing().when(mHighUsageDetector).parseBatteryData();