diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 836fa75..e3fcd5c 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -158,7 +158,6 @@
     public static class NetworkDashboardActivity extends SettingsActivity {}
     public static class ConnectedDeviceDashboardActivity extends SettingsActivity {}
     public static class PowerUsageSummaryActivity extends SettingsActivity { /* empty */ }
-    public static class PowerUsageSummaryLegacyActivity extends SettingsActivity { /* empty */ }
     public static class AppAndNotificationDashboardActivity extends SettingsActivity {}
     public static class StorageDashboardActivity extends SettingsActivity {}
     public static class AccountDashboardActivity extends SettingsActivity {}
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index 16e1a7b..970692d 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -655,17 +655,9 @@
                 Utils.showSimCardTile(this), isAdmin)
                 || somethingChanged;
 
-        final boolean isBatterySettingsV2Enabled = featureFactory
-                .getPowerUsageFeatureProvider(this)
-                .isBatteryV2Enabled();
-        // Enable new battery page if v2 enabled
         somethingChanged = setTileEnabled(new ComponentName(packageName,
                         Settings.PowerUsageSummaryActivity.class.getName()),
-                mBatteryPresent && isBatterySettingsV2Enabled, isAdmin) || somethingChanged;
-        // Enable legacy battery page if v2 disabled
-        somethingChanged = setTileEnabled(new ComponentName(packageName,
-                        Settings.PowerUsageSummaryLegacyActivity.class.getName()),
-                mBatteryPresent && !isBatterySettingsV2Enabled, isAdmin) || somethingChanged;
+                mBatteryPresent, isAdmin) || somethingChanged;
 
         final boolean isDataUsageSettingsV2Enabled =
                 FeatureFlagUtils.isEnabled(this, FeatureFlags.DATA_USAGE_SETTINGS_V2);
diff --git a/src/com/android/settings/core/FeatureFlags.java b/src/com/android/settings/core/FeatureFlags.java
index a5edf3c..a6e961b 100644
--- a/src/com/android/settings/core/FeatureFlags.java
+++ b/src/com/android/settings/core/FeatureFlags.java
@@ -20,7 +20,6 @@
  * This class keeps track of all feature flags in Settings.
  */
 public class FeatureFlags {
-    public static final String BATTERY_SETTINGS_V2 = "settings_battery_v2";
     public static final String BATTERY_DISPLAY_APP_LIST = "settings_battery_display_app_list";
     public static final String ZONE_PICKER_V2 = "settings_zone_picker_v2";
     public static final String ABOUT_PHONE_V2 = "settings_about_phone_v2";
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index dbe8fba..bbba8ea 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -76,7 +76,6 @@
 import com.android.settings.enterprise.EnterprisePrivacySettings;
 import com.android.settings.fuelgauge.AdvancedPowerUsageDetail;
 import com.android.settings.fuelgauge.PowerUsageSummary;
-import com.android.settings.fuelgauge.PowerUsageSummaryLegacy;
 import com.android.settings.fuelgauge.batterysaver.BatterySaverSettings;
 import com.android.settings.gestures.AssistGestureSettings;
 import com.android.settings.gestures.DoubleTapPowerSettings;
@@ -184,7 +183,6 @@
             AndroidBeam.class.getName(),
             WifiDisplaySettings.class.getName(),
             PowerUsageSummary.class.getName(),
-            PowerUsageSummaryLegacy.class.getName(),
             AccountSyncSettings.class.getName(),
             AssistGestureSettings.class.getName(),
             SwipeToNotificationSettings.class.getName(),
@@ -270,7 +268,6 @@
             Settings.SoundSettingsActivity.class.getName(),
             Settings.StorageDashboardActivity.class.getName(),
             Settings.PowerUsageSummaryActivity.class.getName(),
-            Settings.PowerUsageSummaryLegacyActivity.class.getName(),
             Settings.AccountDashboardActivity.class.getName(),
             Settings.SecurityDashboardActivity.class.getName(),
             Settings.AccessibilitySettingsActivity.class.getName(),
diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
index 9666a6c..3ee5db1 100644
--- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
+++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
@@ -450,8 +450,6 @@
         controllers.add(new ShortcutManagerThrottlingPreferenceController(context));
         controllers.add(new EnableGnssRawMeasFullTrackingPreferenceController(context));
         controllers.add(new DefaultLaunchPreferenceController(context, "running_apps"));
-        controllers.add(
-            new DefaultLaunchPreferenceController(context, "android_o_battery_settings"));
         controllers.add(new DefaultLaunchPreferenceController(context, "demo_mode"));
         controllers.add(new DefaultLaunchPreferenceController(context, "quick_settings_tiles"));
         controllers.add(new DefaultLaunchPreferenceController(context, "feature_flags_dashboard"));
diff --git a/src/com/android/settings/fuelgauge/PowerUsageAdvancedLegacy.java b/src/com/android/settings/fuelgauge/PowerUsageAdvancedLegacy.java
deleted file mode 100644
index a4e3fef..0000000
--- a/src/com/android/settings/fuelgauge/PowerUsageAdvancedLegacy.java
+++ /dev/null
@@ -1,485 +0,0 @@
-/*
- * 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 android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
-import android.os.BatteryManager;
-import android.os.BatteryStats;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.UserManager;
-import android.provider.SearchIndexableResource;
-import android.support.annotation.ColorInt;
-import android.support.annotation.IntDef;
-import android.support.annotation.NonNull;
-import android.support.annotation.StringRes;
-import android.support.annotation.VisibleForTesting;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceGroup;
-import android.text.TextUtils;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.internal.os.BatterySipper;
-import com.android.internal.os.BatterySipper.DrainType;
-import com.android.internal.os.BatteryStatsHelper;
-import com.android.settings.R;
-import com.android.settings.Utils;
-import com.android.settings.datausage.DataUsageUtils;
-import com.android.settings.fuelgauge.PowerUsageAdvancedLegacy.PowerUsageData.UsageType;
-import com.android.settings.overlay.FeatureFactory;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.core.AbstractPreferenceController;
-
-import com.android.settingslib.utils.StringUtil;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class PowerUsageAdvancedLegacy extends PowerUsageBase {
-    private static final String TAG = "AdvancedBatteryUsage";
-    private static final String KEY_BATTERY_GRAPH = "battery_graph_legacy";
-    private static final String KEY_BATTERY_USAGE_LIST = "battery_usage_list_legacy";
-    private static final int STATUS_TYPE = BatteryStats.STATS_SINCE_CHARGED;
-
-    @VisibleForTesting
-    final int[] mUsageTypes = {
-            UsageType.WIFI,
-            UsageType.CELL,
-            UsageType.SYSTEM,
-            UsageType.BLUETOOTH,
-            UsageType.USER,
-            UsageType.IDLE,
-            UsageType.APP,
-            UsageType.UNACCOUNTED,
-            UsageType.OVERCOUNTED};
-
-    @VisibleForTesting BatteryHistoryPreference mHistPref;
-    @VisibleForTesting PreferenceGroup mUsageListGroup;
-    private BatteryUtils mBatteryUtils;
-    private PowerUsageFeatureProvider mPowerUsageFeatureProvider;
-    private PackageManager mPackageManager;
-    private UserManager mUserManager;
-    private Map<Integer, PowerUsageData> mBatteryDataMap;
-
-    Handler mHandler = new Handler() {
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case BatteryEntry.MSG_UPDATE_NAME_ICON:
-                    final int dischargeAmount = mStatsHelper.getStats().getDischargeAmount(
-                            STATUS_TYPE);
-                    final double totalPower = mStatsHelper.getTotalPower();
-                    final BatteryEntry entry = (BatteryEntry) msg.obj;
-                    final int usageType = extractUsageType(entry.sipper);
-
-                    PowerUsageData usageData = mBatteryDataMap.get(usageType);
-                    Preference pref = findPreference(String.valueOf(usageType));
-                    if (pref != null && usageData != null) {
-                        updateUsageDataSummary(usageData, totalPower, dischargeAmount);
-                        pref.setSummary(usageData.summary);
-                    }
-                    break;
-                case BatteryEntry.MSG_REPORT_FULLY_DRAWN:
-                    Activity activity = getActivity();
-                    if (activity != null) {
-                        activity.reportFullyDrawn();
-                    }
-                    break;
-            }
-            super.handleMessage(msg);
-        }
-    };
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-
-        mHistPref = (BatteryHistoryPreference) findPreference(KEY_BATTERY_GRAPH);
-        mUsageListGroup = (PreferenceGroup) findPreference(KEY_BATTERY_USAGE_LIST);
-
-        final Context context = getContext();
-        mPowerUsageFeatureProvider = FeatureFactory.getFactory(context)
-                .getPowerUsageFeatureProvider(context);
-        mPackageManager = context.getPackageManager();
-        mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
-        mBatteryUtils = BatteryUtils.getInstance(context);
-
-        // init the summary so other preferences won't have unnecessary move
-        updateHistPrefSummary(context);
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-    }
-
-    @Override
-    public void onPause() {
-        BatteryEntry.stopRequestQueue();
-        mHandler.removeMessages(BatteryEntry.MSG_UPDATE_NAME_ICON);
-        super.onPause();
-    }
-
-    @Override
-    public void onDestroy() {
-        super.onDestroy();
-        if (getActivity().isChangingConfigurations()) {
-            BatteryEntry.clearUidCache();
-        }
-    }
-
-    @Override
-    public int getMetricsCategory() {
-        return MetricsProto.MetricsEvent.FUELGAUGE_BATTERY_HISTORY_DETAIL;
-    }
-
-    @Override
-    protected String getLogTag() {
-        return TAG;
-    }
-
-    @Override
-    protected int getPreferenceScreenResId() {
-        return R.xml.power_usage_advanced_legacy;
-    }
-
-    @Override
-    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
-        return null;
-    }
-
-    @Override
-    protected void refreshUi() {
-        final long startTime = System.currentTimeMillis();
-        final Context context = getContext();
-        if (context == null) {
-            return;
-        }
-        updatePreference(mHistPref);
-        refreshPowerUsageDataList(mStatsHelper, mUsageListGroup);
-        updateHistPrefSummary(context);
-
-        BatteryEntry.startRequestQueue();
-        BatteryUtils.logRuntime(TAG, "refreshUI", startTime);
-    }
-
-    private void updateHistPrefSummary(Context context) {
-        Intent batteryIntent =
-                context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
-        final boolean plugged = batteryIntent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) != 0;
-
-        if (mPowerUsageFeatureProvider.isEnhancedBatteryPredictionEnabled(context) && !plugged) {
-            mHistPref.setBottomSummary(
-                    mPowerUsageFeatureProvider.getAdvancedUsageScreenInfoString());
-        } else {
-            mHistPref.hideBottomSummary();
-        }
-    }
-
-    @VisibleForTesting
-    void refreshPowerUsageDataList(BatteryStatsHelper statsHelper,
-            PreferenceGroup preferenceGroup) {
-        List<PowerUsageData> dataList = parsePowerUsageData(statsHelper);
-        preferenceGroup.removeAll();
-        for (int i = 0, size = dataList.size(); i < size; i++) {
-            final PowerUsageData batteryData = dataList.get(i);
-            if (shouldHideCategory(batteryData)) {
-                continue;
-            }
-            final PowerGaugePreference pref = new PowerGaugePreference(getPrefContext());
-
-            pref.setKey(String.valueOf(batteryData.usageType));
-            pref.setTitle(batteryData.titleResId);
-            pref.setSummary(batteryData.summary);
-            pref.setPercent(batteryData.percentage);
-            pref.setSelectable(false);
-            preferenceGroup.addPreference(pref);
-        }
-    }
-
-    @VisibleForTesting
-    @UsageType
-    int extractUsageType(BatterySipper sipper) {
-        final DrainType drainType = sipper.drainType;
-        final int uid = sipper.getUid();
-
-        if (drainType == DrainType.WIFI) {
-            return UsageType.WIFI;
-        } else if (drainType == DrainType.BLUETOOTH) {
-            return UsageType.BLUETOOTH;
-        } else if (drainType == DrainType.IDLE) {
-            return UsageType.IDLE;
-        } else if (drainType == DrainType.USER) {
-            return UsageType.USER;
-        } else if (drainType == DrainType.CELL) {
-            return UsageType.CELL;
-        } else if (drainType == DrainType.UNACCOUNTED) {
-            return UsageType.UNACCOUNTED;
-        } else if (drainType == DrainType.OVERCOUNTED) {
-            return UsageType.OVERCOUNTED;
-        } else if (mPowerUsageFeatureProvider.isTypeSystem(sipper)
-                || mPowerUsageFeatureProvider.isTypeService(sipper)) {
-            return UsageType.SYSTEM;
-        } else {
-            return UsageType.APP;
-        }
-    }
-
-    @VisibleForTesting
-    boolean shouldHideCategory(PowerUsageData powerUsageData) {
-        return powerUsageData.usageType == UsageType.UNACCOUNTED
-                || powerUsageData.usageType == UsageType.OVERCOUNTED
-                || (powerUsageData.usageType == UsageType.USER && isSingleNormalUser())
-                || (powerUsageData.usageType == UsageType.CELL
-                && !DataUsageUtils.hasMobileData(getContext()));
-    }
-
-    @VisibleForTesting
-    boolean shouldShowBatterySipper(BatterySipper batterySipper) {
-        return batterySipper.drainType != DrainType.SCREEN;
-    }
-
-    @VisibleForTesting
-    List<PowerUsageData> parsePowerUsageData(BatteryStatsHelper statusHelper) {
-        final List<BatterySipper> batterySippers = statusHelper.getUsageList();
-        final Map<Integer, PowerUsageData> batteryDataMap = new HashMap<>();
-
-        for (final @UsageType Integer type : mUsageTypes) {
-            batteryDataMap.put(type, new PowerUsageData(type));
-        }
-
-        // Accumulate power usage based on usage type
-        for (final BatterySipper sipper : batterySippers) {
-            sipper.mPackages = mPackageManager.getPackagesForUid(sipper.getUid());
-            final PowerUsageData usageData = batteryDataMap.get(extractUsageType(sipper));
-            usageData.totalPowerMah += sipper.totalPowerMah;
-            if (sipper.drainType == DrainType.APP && sipper.usageTimeMs != 0) {
-                sipper.usageTimeMs = mBatteryUtils.getProcessTimeMs(
-                        BatteryUtils.StatusType.FOREGROUND, sipper.uidObj, STATUS_TYPE);
-            }
-            usageData.totalUsageTimeMs += sipper.usageTimeMs;
-            if (shouldShowBatterySipper(sipper)) {
-                usageData.usageList.add(sipper);
-            }
-        }
-
-        final List<PowerUsageData> batteryDataList = new ArrayList<>(batteryDataMap.values());
-        final int dischargeAmount = statusHelper.getStats().getDischargeAmount(STATUS_TYPE);
-        final double totalPower = statusHelper.getTotalPower();
-        final double hiddenPower = calculateHiddenPower(batteryDataList);
-        for (final PowerUsageData usageData : batteryDataList) {
-            usageData.percentage = mBatteryUtils.calculateBatteryPercent(usageData.totalPowerMah,
-                    totalPower, hiddenPower, dischargeAmount);
-            updateUsageDataSummary(usageData, totalPower, dischargeAmount);
-        }
-
-        Collections.sort(batteryDataList);
-
-        mBatteryDataMap = batteryDataMap;
-        return batteryDataList;
-    }
-
-    @VisibleForTesting
-    double calculateHiddenPower(List<PowerUsageData> batteryDataList) {
-        for (final PowerUsageData usageData : batteryDataList) {
-            if (usageData.usageType == UsageType.UNACCOUNTED) {
-                return usageData.totalPowerMah;
-            }
-        }
-
-        return 0;
-    }
-
-    @VisibleForTesting
-    void updateUsageDataSummary(PowerUsageData usageData, double totalPower, int dischargeAmount) {
-        if (shouldHideSummary(usageData)) {
-            return;
-        }
-        if (usageData.usageList.size() <= 1) {
-            CharSequence timeSequence = StringUtil.formatElapsedTime(getContext(),
-                    usageData.totalUsageTimeMs, false);
-            usageData.summary = usageData.usageType == UsageType.IDLE ? timeSequence
-                    : TextUtils.expandTemplate(getText(R.string.battery_used_for), timeSequence);
-        } else {
-            BatterySipper sipper = findBatterySipperWithMaxBatteryUsage(usageData.usageList);
-            BatteryEntry batteryEntry = new BatteryEntry(getContext(), mHandler, mUserManager,
-                    sipper);
-            final double percentage = (sipper.totalPowerMah / totalPower) * dischargeAmount;
-            usageData.summary = getString(R.string.battery_used_by,
-                    Utils.formatPercentage(percentage, true), batteryEntry.name);
-        }
-    }
-
-    @VisibleForTesting
-    boolean shouldHideSummary(PowerUsageData powerUsageData) {
-        @UsageType final int usageType = powerUsageData.usageType;
-
-        return usageType == UsageType.CELL
-                || usageType == UsageType.BLUETOOTH
-                || usageType == UsageType.WIFI
-                || usageType == UsageType.APP
-                || usageType == UsageType.SYSTEM;
-    }
-
-    @VisibleForTesting
-    BatterySipper findBatterySipperWithMaxBatteryUsage(List<BatterySipper> usageList) {
-        BatterySipper sipper = usageList.get(0);
-        for (int i = 1, size = usageList.size(); i < size; i++) {
-            final BatterySipper comparedSipper = usageList.get(i);
-            if (comparedSipper.totalPowerMah > sipper.totalPowerMah) {
-                sipper = comparedSipper;
-            }
-        }
-
-        return sipper;
-    }
-
-    @VisibleForTesting
-    void setPackageManager(PackageManager packageManager) {
-        mPackageManager = packageManager;
-    }
-
-    @VisibleForTesting
-    void setPowerUsageFeatureProvider(PowerUsageFeatureProvider provider) {
-        mPowerUsageFeatureProvider = provider;
-    }
-    @VisibleForTesting
-    void setUserManager(UserManager userManager) {
-        mUserManager = userManager;
-    }
-    @VisibleForTesting
-    void setBatteryUtils(BatteryUtils batteryUtils) {
-        mBatteryUtils = batteryUtils;
-    }
-
-    @VisibleForTesting
-    boolean isSingleNormalUser() {
-        int count = 0;
-        for (UserInfo userInfo : mUserManager.getUsers()) {
-            if (userInfo.isEnabled() && !userInfo.isManagedProfile()) {
-                count++;
-            }
-        }
-
-        return count == 1;
-    }
-
-    /**
-     * Class that contains data used in {@link PowerGaugePreference}.
-     */
-    @VisibleForTesting
-    static class PowerUsageData implements Comparable<PowerUsageData> {
-
-        @Retention(RetentionPolicy.SOURCE)
-        @IntDef({UsageType.APP,
-                UsageType.WIFI,
-                UsageType.CELL,
-                UsageType.SYSTEM,
-                UsageType.BLUETOOTH,
-                UsageType.USER,
-                UsageType.IDLE,
-                UsageType.UNACCOUNTED,
-                UsageType.OVERCOUNTED})
-        public @interface UsageType {
-            int APP = 0;
-            int WIFI = 1;
-            int CELL = 2;
-            int SYSTEM = 3;
-            int BLUETOOTH = 4;
-            int USER = 5;
-            int IDLE = 6;
-            int UNACCOUNTED = 7;
-            int OVERCOUNTED = 8;
-        }
-
-        @StringRes
-        public int titleResId;
-        public CharSequence summary;
-        public double percentage;
-        public double totalPowerMah;
-        public long totalUsageTimeMs;
-        @ColorInt
-        public int iconColor;
-        @UsageType
-        public int usageType;
-        public List<BatterySipper> usageList;
-
-        public PowerUsageData(@UsageType int usageType) {
-            this(usageType, 0);
-        }
-
-        public PowerUsageData(@UsageType int usageType, double totalPower) {
-            this.usageType = usageType;
-            totalPowerMah = 0;
-            totalUsageTimeMs = 0;
-            titleResId = getTitleResId(usageType);
-            totalPowerMah = totalPower;
-            usageList = new ArrayList<>();
-        }
-
-        private int getTitleResId(@UsageType int usageType) {
-            switch (usageType) {
-                case UsageType.WIFI:
-                    return R.string.power_wifi;
-                case UsageType.CELL:
-                    return R.string.power_cell;
-                case UsageType.SYSTEM:
-                    return R.string.power_system;
-                case UsageType.BLUETOOTH:
-                    return R.string.power_bluetooth;
-                case UsageType.USER:
-                    return R.string.power_user;
-                case UsageType.IDLE:
-                    return R.string.power_idle;
-                case UsageType.UNACCOUNTED:
-                    return R.string.power_unaccounted;
-                case UsageType.OVERCOUNTED:
-                    return R.string.power_overcounted;
-                case UsageType.APP:
-                default:
-                    return R.string.power_apps;
-            }
-        }
-
-        @Override
-        public int compareTo(@NonNull PowerUsageData powerUsageData) {
-            final int diff = Double.compare(powerUsageData.totalPowerMah, totalPowerMah);
-            return diff != 0 ? diff : usageType - powerUsageData.usageType;
-        }
-    }
-
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider() {
-                @Override
-                public List<SearchIndexableResource> getXmlResourcesToIndex(
-                        Context context, boolean enabled) {
-                    final SearchIndexableResource sir = new SearchIndexableResource(context);
-                    sir.xmlResId = R.xml.power_usage_advanced_legacy;
-                    return Arrays.asList(sir);
-                }
-            };
-
-}
diff --git a/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java b/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java
index 861ee56..a6474fb 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java
@@ -106,11 +106,6 @@
     String getAdvancedUsageScreenInfoString();
 
     /**
-     * Checks whether to display the battery v2.
-     */
-    boolean isBatteryV2Enabled();
-
-    /**
      * Returns a signal to indicate if the device will need to warn the user they may not make it
      * to their next charging time.
      *
diff --git a/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java b/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
index 6c3897d..e727521 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
@@ -16,13 +16,10 @@
 
 package com.android.settings.fuelgauge;
 
-import static com.android.settings.core.FeatureFlags.BATTERY_SETTINGS_V2;
-
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.os.Process;
-import android.util.FeatureFlagUtils;
 import android.util.SparseIntArray;
 
 import com.android.internal.os.BatterySipper;
@@ -128,11 +125,6 @@
     }
 
     @Override
-    public boolean isBatteryV2Enabled() {
-        return FeatureFlagUtils.isEnabled(mContext, BATTERY_SETTINGS_V2);
-    }
-
-    @Override
     public boolean getEarlyWarningSignal(Context context, String id) {
         return false;
     }
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummaryLegacy.java b/src/com/android/settings/fuelgauge/PowerUsageSummaryLegacy.java
deleted file mode 100644
index d321bb7..0000000
--- a/src/com/android/settings/fuelgauge/PowerUsageSummaryLegacy.java
+++ /dev/null
@@ -1,911 +0,0 @@
-/*
- * Copyright (C) 2009 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 android.app.Activity;
-import android.app.LoaderManager;
-import android.app.LoaderManager.LoaderCallbacks;
-import android.content.Context;
-import android.content.Loader;
-import android.graphics.drawable.Drawable;
-import android.os.BatteryStats;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Process;
-import android.os.UserHandle;
-import android.support.annotation.VisibleForTesting;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceGroup;
-import android.text.TextUtils;
-import android.text.format.DateUtils;
-import android.text.format.Formatter;
-import android.util.Log;
-import android.util.SparseArray;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.View.OnLongClickListener;
-import android.widget.TextView;
-
-import com.android.internal.hardware.AmbientDisplayConfiguration;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.os.BatterySipper;
-import com.android.internal.os.BatterySipper.DrainType;
-import com.android.internal.os.PowerProfile;
-import com.android.settings.R;
-import com.android.settings.Settings.HighPowerApplicationsActivity;
-import com.android.settings.SettingsActivity;
-import com.android.settings.Utils;
-import com.android.settings.applications.LayoutPreference;
-import com.android.settings.applications.manageapplications.ManageApplications;
-import com.android.settings.core.SubSettingLauncher;
-import com.android.settings.dashboard.SummaryLoader;
-import com.android.settings.display.AmbientDisplayPreferenceController;
-import com.android.settings.display.AutoBrightnessPreferenceController;
-import com.android.settings.display.BatteryPercentagePreferenceController;
-import com.android.settings.display.TimeoutPreferenceController;
-import com.android.settings.fuelgauge.anomaly.Anomaly;
-import com.android.settings.fuelgauge.anomaly.AnomalyDetectionPolicy;
-import com.android.settings.fuelgauge.anomaly.AnomalyDialogFragment.AnomalyDialogListener;
-import com.android.settings.fuelgauge.anomaly.AnomalyLoader;
-import com.android.settings.fuelgauge.anomaly.AnomalySummaryPreferenceController;
-import com.android.settings.fuelgauge.anomaly.AnomalyUtils;
-import com.android.settings.overlay.FeatureFactory;
-import com.android.settingslib.core.AbstractPreferenceController;
-import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
-import com.android.settingslib.utils.PowerUtil;
-import com.android.settingslib.utils.StringUtil;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Displays a list of apps and subsystems that consume power, ordered by how much power was
- * consumed since the last time it was unplugged.
- *
- * This is the battery page used in Android O with the app usage list. It is also used for battery
- * debug.
- */
-public class PowerUsageSummaryLegacy extends PowerUsageBase implements
-        AnomalyDialogListener, OnLongClickListener, OnClickListener {
-
-    static final String TAG = "PowerUsageSummaryLegacy";
-
-    private static final boolean DEBUG = false;
-    private static final boolean USE_FAKE_DATA = false;
-    private static final String KEY_APP_LIST = "app_list";
-    private static final String KEY_BATTERY_HEADER = "battery_header";
-    private static final String KEY_SHOW_ALL_APPS = "show_all_apps";
-    private static final int MAX_ITEMS_TO_LIST = USE_FAKE_DATA ? 30 : 10;
-    private static final int MIN_AVERAGE_POWER_THRESHOLD_MILLI_AMP = 10;
-
-    private static final String KEY_SCREEN_USAGE = "screen_usage";
-    private static final String KEY_TIME_SINCE_LAST_FULL_CHARGE = "last_full_charge";
-
-    private static final String KEY_AUTO_BRIGHTNESS = "auto_brightness_battery";
-    private static final String KEY_SCREEN_TIMEOUT = "screen_timeout_battery";
-    private static final String KEY_AMBIENT_DISPLAY = "ambient_display_battery";
-    private static final String KEY_BATTERY_SAVER_SUMMARY = "battery_saver_summary";
-    private static final String KEY_HIGH_USAGE = "high_usage";
-
-    @VisibleForTesting
-    static final int ANOMALY_LOADER = 1;
-    @VisibleForTesting
-    static final int BATTERY_INFO_LOADER = 2;
-    private static final int MENU_STATS_TYPE = Menu.FIRST;
-    @VisibleForTesting
-    static final int MENU_HIGH_POWER_APPS = Menu.FIRST + 3;
-    @VisibleForTesting
-    static final int MENU_TOGGLE_APPS = Menu.FIRST + 4;
-    private static final int MENU_HELP = Menu.FIRST + 5;
-    public static final int DEBUG_INFO_LOADER = 3;
-
-    @VisibleForTesting
-    boolean mShowAllApps = false;
-    @VisibleForTesting
-    PowerGaugePreference mScreenUsagePref;
-    @VisibleForTesting
-    PowerGaugePreference mLastFullChargePref;
-    @VisibleForTesting
-    PowerUsageFeatureProvider mPowerFeatureProvider;
-    @VisibleForTesting
-    BatteryUtils mBatteryUtils;
-    @VisibleForTesting
-    LayoutPreference mBatteryLayoutPref;
-
-    /**
-     * SparseArray that maps uid to {@link Anomaly}, so we could find {@link Anomaly} by uid
-     */
-    @VisibleForTesting
-    SparseArray<List<Anomaly>> mAnomalySparseArray;
-    @VisibleForTesting
-    PreferenceGroup mAppListGroup;
-    @VisibleForTesting
-    BatteryHeaderPreferenceController mBatteryHeaderPreferenceController;
-    private AnomalySummaryPreferenceController mAnomalySummaryPreferenceController;
-    private int mStatsType = BatteryStats.STATS_SINCE_CHARGED;
-
-    private LoaderCallbacks<List<Anomaly>> mAnomalyLoaderCallbacks =
-            new LoaderCallbacks<List<Anomaly>>() {
-
-                @Override
-                public Loader<List<Anomaly>> onCreateLoader(int id, Bundle args) {
-                    return new AnomalyLoader(getContext(), mStatsHelper);
-                }
-
-                @Override
-                public void onLoadFinished(Loader<List<Anomaly>> loader, List<Anomaly> data) {
-                    final AnomalyUtils anomalyUtils = AnomalyUtils.getInstance(getContext());
-                    anomalyUtils.logAnomalies(mMetricsFeatureProvider, data,
-                            MetricsEvent.FUELGAUGE_POWER_USAGE_SUMMARY);
-
-                    // show high usage preference if possible
-                    mAnomalySummaryPreferenceController.updateAnomalySummaryPreference(data);
-
-                    updateAnomalySparseArray(data);
-                    refreshAnomalyIcon();
-                }
-
-                @Override
-                public void onLoaderReset(Loader<List<Anomaly>> loader) {
-
-                }
-            };
-
-    @VisibleForTesting
-    LoaderCallbacks<BatteryInfo> mBatteryInfoLoaderCallbacks =
-            new LoaderCallbacks<BatteryInfo>() {
-
-                @Override
-                public Loader<BatteryInfo> onCreateLoader(int i, Bundle bundle) {
-                    return new BatteryInfoLoader(getContext(), mStatsHelper);
-                }
-
-                @Override
-                public void onLoadFinished(Loader<BatteryInfo> loader, BatteryInfo batteryInfo) {
-                    mBatteryHeaderPreferenceController.updateHeaderPreference(batteryInfo);
-                }
-
-                @Override
-                public void onLoaderReset(Loader<BatteryInfo> loader) {
-                    // do nothing
-                }
-            };
-
-    LoaderManager.LoaderCallbacks<List<BatteryInfo>> mBatteryInfoDebugLoaderCallbacks =
-        new LoaderCallbacks<List<BatteryInfo>>() {
-            @Override
-            public Loader<List<BatteryInfo>> onCreateLoader(int i, Bundle bundle) {
-                return new DebugEstimatesLoader(getContext(), mStatsHelper);
-            }
-
-            @Override
-            public void onLoadFinished(Loader<List<BatteryInfo>> loader,
-                List<BatteryInfo> batteryInfos) {
-                updateViews(batteryInfos);
-            }
-
-            @Override
-            public void onLoaderReset(Loader<List<BatteryInfo>> loader) {
-            }
-        };
-
-    protected void updateViews(List<BatteryInfo> batteryInfos) {
-        final BatteryMeterView batteryView = mBatteryLayoutPref
-            .findViewById(R.id.battery_header_icon);
-        final TextView percentRemaining =
-            mBatteryLayoutPref.findViewById(R.id.battery_percent);
-        final TextView summary1 = mBatteryLayoutPref.findViewById(R.id.summary1);
-        final TextView summary2 = mBatteryLayoutPref.findViewById(R.id.summary2);
-        BatteryInfo oldInfo = batteryInfos.get(0);
-        BatteryInfo newInfo = batteryInfos.get(1);
-        percentRemaining.setText(Utils.formatPercentage(oldInfo.batteryLevel));
-
-        // set the text to the old estimate (copied from battery info). Note that this
-        // can sometimes say 0 time remaining because battery stats requires the phone
-        // be unplugged for a period of time before being willing ot make an estimate.
-        summary1.setText(mPowerFeatureProvider.getOldEstimateDebugString(
-            Formatter.formatShortElapsedTime(getContext(),
-                PowerUtil.convertUsToMs(oldInfo.remainingTimeUs))));
-
-        // for this one we can just set the string directly
-        summary2.setText(mPowerFeatureProvider.getEnhancedEstimateDebugString(
-            Formatter.formatShortElapsedTime(getContext(),
-                PowerUtil.convertUsToMs(newInfo.remainingTimeUs))));
-
-        batteryView.setBatteryLevel(oldInfo.batteryLevel);
-        batteryView.setCharging(!oldInfo.discharging);
-    }
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-        setAnimationAllowed(true);
-
-        initFeatureProvider();
-        mBatteryLayoutPref = (LayoutPreference) findPreference(KEY_BATTERY_HEADER);
-
-        mAppListGroup = (PreferenceGroup) findPreference(KEY_APP_LIST);
-        mScreenUsagePref = (PowerGaugePreference) findPreference(KEY_SCREEN_USAGE);
-        mLastFullChargePref = (PowerGaugePreference) findPreference(
-                KEY_TIME_SINCE_LAST_FULL_CHARGE);
-        mFooterPreferenceMixin.createFooterPreference().setTitle(R.string.battery_footer_summary);
-        mAnomalySummaryPreferenceController = new AnomalySummaryPreferenceController(
-                (SettingsActivity) getActivity(), this);
-        mBatteryUtils = BatteryUtils.getInstance(getContext());
-        mAnomalySparseArray = new SparseArray<>();
-
-        restartBatteryInfoLoader();
-        restoreSavedInstance(icicle);
-    }
-
-    @Override
-    public int getMetricsCategory() {
-        return MetricsEvent.FUELGAUGE_POWER_USAGE_SUMMARY;
-    }
-
-    @Override
-    public void onPause() {
-        BatteryEntry.stopRequestQueue();
-        mHandler.removeMessages(BatteryEntry.MSG_UPDATE_NAME_ICON);
-        super.onPause();
-    }
-
-    @Override
-    public void onDestroy() {
-        super.onDestroy();
-        if (getActivity().isChangingConfigurations()) {
-            BatteryEntry.clearUidCache();
-        }
-    }
-
-    @Override
-    public void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-        outState.putBoolean(KEY_SHOW_ALL_APPS, mShowAllApps);
-    }
-
-    @Override
-    public boolean onPreferenceTreeClick(Preference preference) {
-        if (mAnomalySummaryPreferenceController.onPreferenceTreeClick(preference)) {
-            return true;
-        }
-        if (KEY_BATTERY_HEADER.equals(preference.getKey())) {
-            performBatteryHeaderClick();
-            return true;
-        } else if (!(preference instanceof PowerGaugePreference)) {
-            return super.onPreferenceTreeClick(preference);
-        }
-        PowerGaugePreference pgp = (PowerGaugePreference) preference;
-        BatteryEntry entry = pgp.getInfo();
-        AdvancedPowerUsageDetail.startBatteryDetailPage((SettingsActivity) getActivity(),
-                this, mStatsHelper, mStatsType, entry, pgp.getPercent(),
-                mAnomalySparseArray.get(entry.sipper.getUid()));
-        return super.onPreferenceTreeClick(preference);
-    }
-
-    @Override
-    protected String getLogTag() {
-        return TAG;
-    }
-
-    @Override
-    protected int getPreferenceScreenResId() {
-        return R.xml.power_usage_summary_legacy;
-    }
-
-    @Override
-    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
-        final List<AbstractPreferenceController> controllers = new ArrayList<>();
-        mBatteryHeaderPreferenceController = new BatteryHeaderPreferenceController(
-                context, getActivity(), this /* host */, getLifecycle());
-        controllers.add(mBatteryHeaderPreferenceController);
-        controllers.add(new AutoBrightnessPreferenceController(context, KEY_AUTO_BRIGHTNESS));
-        controllers.add(new TimeoutPreferenceController(context, KEY_SCREEN_TIMEOUT));
-        controllers.add(new BatteryPercentagePreferenceController(context));
-        controllers.add(new AmbientDisplayPreferenceController(
-                context,
-                new AmbientDisplayConfiguration(context),
-                KEY_AMBIENT_DISPLAY));
-        BatterySaverController batterySaverController = new BatterySaverController(context);
-        controllers.add(batterySaverController);
-        getLifecycle().addObserver(batterySaverController);
-        return controllers;
-    }
-
-    @Override
-    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
-        if (DEBUG) {
-            menu.add(Menu.NONE, MENU_STATS_TYPE, Menu.NONE, R.string.menu_stats_total)
-                    .setIcon(com.android.internal.R.drawable.ic_menu_info_details)
-                    .setAlphabeticShortcut('t');
-        }
-
-        menu.add(Menu.NONE, MENU_HIGH_POWER_APPS, Menu.NONE, R.string.high_power_apps);
-
-        if (mPowerFeatureProvider.isPowerAccountingToggleEnabled()) {
-            menu.add(Menu.NONE, MENU_TOGGLE_APPS, Menu.NONE,
-                    mShowAllApps ? R.string.hide_extra_apps : R.string.show_all_apps);
-        }
-
-        super.onCreateOptionsMenu(menu, inflater);
-    }
-
-    @Override
-    public int getHelpResource() {
-        return R.string.help_url_battery;
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        final SettingsActivity sa = (SettingsActivity) getActivity();
-        final Context context = getContext();
-        final MetricsFeatureProvider metricsFeatureProvider =
-                FeatureFactory.getFactory(context).getMetricsFeatureProvider();
-
-        switch (item.getItemId()) {
-            case MENU_STATS_TYPE:
-                if (mStatsType == BatteryStats.STATS_SINCE_CHARGED) {
-                    mStatsType = BatteryStats.STATS_SINCE_UNPLUGGED;
-                } else {
-                    mStatsType = BatteryStats.STATS_SINCE_CHARGED;
-                }
-                refreshUi();
-                return true;
-            case MENU_HIGH_POWER_APPS:
-                Bundle args = new Bundle();
-                args.putString(ManageApplications.EXTRA_CLASSNAME,
-                        HighPowerApplicationsActivity.class.getName());
-                new SubSettingLauncher(context)
-                        .setDestination(ManageApplications.class.getName())
-                        .setArguments(args)
-                        .setTitle(R.string.high_power_apps)
-                        .setSourceMetricsCategory(getMetricsCategory())
-                        .launch();
-                metricsFeatureProvider.action(context,
-                        MetricsEvent.ACTION_SETTINGS_MENU_BATTERY_OPTIMIZATION);
-                return true;
-            case MENU_TOGGLE_APPS:
-                mShowAllApps = !mShowAllApps;
-                item.setTitle(mShowAllApps ? R.string.hide_extra_apps : R.string.show_all_apps);
-                metricsFeatureProvider.action(context,
-                        MetricsEvent.ACTION_SETTINGS_MENU_BATTERY_APPS_TOGGLE, mShowAllApps);
-                restartBatteryStatsLoader(false /* clearHeader */);
-                return true;
-            default:
-                return super.onOptionsItemSelected(item);
-        }
-    }
-
-    @VisibleForTesting
-    void restoreSavedInstance(Bundle savedInstance) {
-        if (savedInstance != null) {
-            mShowAllApps = savedInstance.getBoolean(KEY_SHOW_ALL_APPS, false);
-        }
-    }
-
-    private void addNotAvailableMessage() {
-        final String NOT_AVAILABLE = "not_available";
-        Preference notAvailable = getCachedPreference(NOT_AVAILABLE);
-        if (notAvailable == null) {
-            notAvailable = new Preference(getPrefContext());
-            notAvailable.setKey(NOT_AVAILABLE);
-            notAvailable.setTitle(R.string.power_usage_not_available);
-            mAppListGroup.addPreference(notAvailable);
-        }
-    }
-
-    private void performBatteryHeaderClick() {
-        if (mPowerFeatureProvider.isAdvancedUiEnabled()) {
-            new SubSettingLauncher(getContext())
-                    .setDestination(PowerUsageAdvancedLegacy.class.getName())
-                    .setSourceMetricsCategory(getMetricsCategory())
-                    .setTitle(R.string.advanced_battery_title)
-                    .launch();
-        } else {
-            mStatsHelper.storeStatsHistoryInFile(BatteryHistoryDetail.BATTERY_HISTORY_FILE);
-            Bundle args = new Bundle(2);
-            args.putString(BatteryHistoryDetail.EXTRA_STATS,
-                    BatteryHistoryDetail.BATTERY_HISTORY_FILE);
-            args.putParcelable(BatteryHistoryDetail.EXTRA_BROADCAST,
-                    mStatsHelper.getBatteryBroadcast());
-            new SubSettingLauncher(getContext())
-                    .setDestination(BatteryHistoryDetail.class.getName())
-                    .setSourceMetricsCategory(getMetricsCategory())
-                    .setArguments(args)
-                    .setTitle(R.string.history_details_title)
-                    .launch();
-        }
-    }
-
-    private static boolean isSharedGid(int uid) {
-        return UserHandle.getAppIdFromSharedAppGid(uid) > 0;
-    }
-
-    private static boolean isSystemUid(int uid) {
-        final int appUid = UserHandle.getAppId(uid);
-        return appUid >= Process.SYSTEM_UID && appUid < Process.FIRST_APPLICATION_UID;
-    }
-
-    /**
-     * We want to coalesce some UIDs. For example, dex2oat runs under a shared gid that
-     * exists for all users of the same app. We detect this case and merge the power use
-     * for dex2oat to the device OWNER's use of the app.
-     *
-     * @return A sorted list of apps using power.
-     */
-    private List<BatterySipper> getCoalescedUsageList(final List<BatterySipper> sippers) {
-        final SparseArray<BatterySipper> uidList = new SparseArray<>();
-
-        final ArrayList<BatterySipper> results = new ArrayList<>();
-        final int numSippers = sippers.size();
-        for (int i = 0; i < numSippers; i++) {
-            BatterySipper sipper = sippers.get(i);
-            if (sipper.getUid() > 0) {
-                int realUid = sipper.getUid();
-
-                // Check if this UID is a shared GID. If so, we combine it with the OWNER's
-                // actual app UID.
-                if (isSharedGid(sipper.getUid())) {
-                    realUid = UserHandle.getUid(UserHandle.USER_SYSTEM,
-                            UserHandle.getAppIdFromSharedAppGid(sipper.getUid()));
-                }
-
-                // Check if this UID is a system UID (mediaserver, logd, nfc, drm, etc).
-                if (isSystemUid(realUid)
-                        && !"mediaserver".equals(sipper.packageWithHighestDrain)) {
-                    // Use the system UID for all UIDs running in their own sandbox that
-                    // are not apps. We exclude mediaserver because we already are expected to
-                    // report that as a separate item.
-                    realUid = Process.SYSTEM_UID;
-                }
-
-                if (realUid != sipper.getUid()) {
-                    // Replace the BatterySipper with a new one with the real UID set.
-                    BatterySipper newSipper = new BatterySipper(sipper.drainType,
-                            new FakeUid(realUid), 0.0);
-                    newSipper.add(sipper);
-                    newSipper.packageWithHighestDrain = sipper.packageWithHighestDrain;
-                    newSipper.mPackages = sipper.mPackages;
-                    sipper = newSipper;
-                }
-
-                int index = uidList.indexOfKey(realUid);
-                if (index < 0) {
-                    // New entry.
-                    uidList.put(realUid, sipper);
-                } else {
-                    // Combine BatterySippers if we already have one with this UID.
-                    final BatterySipper existingSipper = uidList.valueAt(index);
-                    existingSipper.add(sipper);
-                    if (existingSipper.packageWithHighestDrain == null
-                            && sipper.packageWithHighestDrain != null) {
-                        existingSipper.packageWithHighestDrain = sipper.packageWithHighestDrain;
-                    }
-
-                    final int existingPackageLen = existingSipper.mPackages != null ?
-                            existingSipper.mPackages.length : 0;
-                    final int newPackageLen = sipper.mPackages != null ?
-                            sipper.mPackages.length : 0;
-                    if (newPackageLen > 0) {
-                        String[] newPackages = new String[existingPackageLen + newPackageLen];
-                        if (existingPackageLen > 0) {
-                            System.arraycopy(existingSipper.mPackages, 0, newPackages, 0,
-                                    existingPackageLen);
-                        }
-                        System.arraycopy(sipper.mPackages, 0, newPackages, existingPackageLen,
-                                newPackageLen);
-                        existingSipper.mPackages = newPackages;
-                    }
-                }
-            } else {
-                results.add(sipper);
-            }
-        }
-
-        final int numUidSippers = uidList.size();
-        for (int i = 0; i < numUidSippers; i++) {
-            results.add(uidList.valueAt(i));
-        }
-
-        // The sort order must have changed, so re-sort based on total power use.
-        mBatteryUtils.sortUsageList(results);
-        return results;
-    }
-
-    protected void refreshUi() {
-        final Context context = getContext();
-        if (context == null) {
-            return;
-        }
-
-        restartAnomalyDetectionIfPossible();
-
-        // reload BatteryInfo and updateUI
-        restartBatteryInfoLoader();
-        final long lastFullChargeTime = mBatteryUtils.calculateLastFullChargeTime(mStatsHelper,
-                System.currentTimeMillis());
-        updateScreenPreference();
-        updateLastFullChargePreference(lastFullChargeTime);
-
-        final CharSequence timeSequence = StringUtil.formatRelativeTime(context, lastFullChargeTime,
-                false);
-        final int resId = mShowAllApps ? R.string.power_usage_list_summary_device
-                : R.string.power_usage_list_summary;
-        mAppListGroup.setTitle(TextUtils.expandTemplate(getText(resId), timeSequence));
-
-        refreshAppListGroup();
-    }
-
-    private void refreshAppListGroup() {
-        final PowerProfile powerProfile = mStatsHelper.getPowerProfile();
-        final BatteryStats stats = mStatsHelper.getStats();
-        final double averagePower = powerProfile.getAveragePower(PowerProfile.POWER_SCREEN_FULL);
-        boolean addedSome = false;
-        final int dischargeAmount = USE_FAKE_DATA ? 5000
-                : stats != null ? stats.getDischargeAmount(mStatsType) : 0;
-
-        cacheRemoveAllPrefs(mAppListGroup);
-        mAppListGroup.setOrderingAsAdded(false);
-
-        if (averagePower >= MIN_AVERAGE_POWER_THRESHOLD_MILLI_AMP || USE_FAKE_DATA) {
-            final List<BatterySipper> usageList = getCoalescedUsageList(
-                    USE_FAKE_DATA ? getFakeStats() : mStatsHelper.getUsageList());
-            double hiddenPowerMah = mShowAllApps ? 0 :
-                    mBatteryUtils.removeHiddenBatterySippers(usageList);
-            mBatteryUtils.sortUsageList(usageList);
-
-            final int numSippers = usageList.size();
-            for (int i = 0; i < numSippers; i++) {
-                final BatterySipper sipper = usageList.get(i);
-                double totalPower = USE_FAKE_DATA ? 4000 : mStatsHelper.getTotalPower();
-
-                final double percentOfTotal = mBatteryUtils.calculateBatteryPercent(
-                        sipper.totalPowerMah, totalPower, hiddenPowerMah, dischargeAmount);
-
-                if (((int) (percentOfTotal + .5)) < 1) {
-                    continue;
-                }
-                if (shouldHideSipper(sipper)) {
-                    continue;
-                }
-                final UserHandle userHandle = new UserHandle(UserHandle.getUserId(sipper.getUid()));
-                final BatteryEntry entry = new BatteryEntry(getActivity(), mHandler, mUm, sipper);
-                final Drawable badgedIcon = mUm.getBadgedIconForUser(entry.getIcon(),
-                        userHandle);
-                final CharSequence contentDescription = mUm.getBadgedLabelForUser(entry.getLabel(),
-                        userHandle);
-
-                final String key = extractKeyFromSipper(sipper);
-                PowerGaugePreference pref = (PowerGaugePreference) getCachedPreference(key);
-                if (pref == null) {
-                    pref = new PowerGaugePreference(getPrefContext(), badgedIcon,
-                            contentDescription, entry);
-                    pref.setKey(key);
-                }
-                sipper.percent = percentOfTotal;
-                pref.setTitle(entry.getLabel());
-                pref.setOrder(i + 1);
-                pref.setPercent(percentOfTotal);
-                pref.shouldShowAnomalyIcon(false);
-                if (sipper.usageTimeMs == 0 && sipper.drainType == DrainType.APP) {
-                    sipper.usageTimeMs = mBatteryUtils.getProcessTimeMs(
-                            BatteryUtils.StatusType.FOREGROUND, sipper.uidObj, mStatsType);
-                }
-                setUsageSummary(pref, sipper);
-                addedSome = true;
-                mAppListGroup.addPreference(pref);
-                if (mAppListGroup.getPreferenceCount() - getCachedCount()
-                        > (MAX_ITEMS_TO_LIST + 1)) {
-                    break;
-                }
-            }
-        }
-        if (!addedSome) {
-            addNotAvailableMessage();
-        }
-        removeCachedPrefs(mAppListGroup);
-
-        BatteryEntry.startRequestQueue();
-    }
-
-    @VisibleForTesting
-    boolean shouldHideSipper(BatterySipper sipper) {
-        // Don't show over-counted and unaccounted in any condition
-        return sipper.drainType == DrainType.OVERCOUNTED
-                || sipper.drainType == DrainType.UNACCOUNTED;
-    }
-
-    @VisibleForTesting
-    void refreshAnomalyIcon() {
-        for (int i = 0, size = mAnomalySparseArray.size(); i < size; i++) {
-            final String key = extractKeyFromUid(mAnomalySparseArray.keyAt(i));
-            final PowerGaugePreference pref = (PowerGaugePreference) mAppListGroup.findPreference(
-                    key);
-            if (pref != null) {
-                pref.shouldShowAnomalyIcon(true);
-            }
-        }
-    }
-
-    @VisibleForTesting
-    void restartAnomalyDetectionIfPossible() {
-        if (getAnomalyDetectionPolicy().isAnomalyDetectionEnabled()) {
-            getLoaderManager().restartLoader(ANOMALY_LOADER, Bundle.EMPTY, mAnomalyLoaderCallbacks);
-        }
-    }
-
-    @VisibleForTesting
-    AnomalyDetectionPolicy getAnomalyDetectionPolicy() {
-        return new AnomalyDetectionPolicy(getContext());
-    }
-
-    @VisibleForTesting
-    BatterySipper findBatterySipperByType(List<BatterySipper> usageList, DrainType type) {
-        for (int i = 0, size = usageList.size(); i < size; i++) {
-            final BatterySipper sipper = usageList.get(i);
-            if (sipper.drainType == type) {
-                return sipper;
-            }
-        }
-        return null;
-    }
-
-    @VisibleForTesting
-    void updateScreenPreference() {
-        final BatterySipper sipper = findBatterySipperByType(
-                mStatsHelper.getUsageList(), DrainType.SCREEN);
-        final long usageTimeMs = sipper != null ? sipper.usageTimeMs : 0;
-
-        mScreenUsagePref.setSubtitle(
-            StringUtil.formatElapsedTime(getContext(), usageTimeMs, false));
-    }
-
-    @VisibleForTesting
-    void updateLastFullChargePreference(long timeMs) {
-        final CharSequence timeSequence = StringUtil.formatRelativeTime(getContext(), timeMs, false);
-        mLastFullChargePref.setSubtitle(timeSequence);
-    }
-
-    @VisibleForTesting
-    void showBothEstimates() {
-        final Context context = getContext();
-        if (context == null
-                || !mPowerFeatureProvider.isEnhancedBatteryPredictionEnabled(context)) {
-            return;
-        }
-        getLoaderManager().restartLoader(DEBUG_INFO_LOADER, Bundle.EMPTY,
-                mBatteryInfoDebugLoaderCallbacks);
-    }
-
-    @VisibleForTesting
-    double calculatePercentage(double powerUsage, double dischargeAmount) {
-        final double totalPower = mStatsHelper.getTotalPower();
-        return totalPower == 0 ? 0 :
-                ((powerUsage / totalPower) * dischargeAmount);
-    }
-
-    @VisibleForTesting
-    void setUsageSummary(Preference preference, BatterySipper sipper) {
-        // Only show summary when usage time is longer than one minute
-        final long usageTimeMs = sipper.usageTimeMs;
-        if (usageTimeMs >= DateUtils.MINUTE_IN_MILLIS) {
-            final CharSequence timeSequence =
-                    StringUtil.formatElapsedTime(getContext(), usageTimeMs, false);
-            preference.setSummary(
-                    (sipper.drainType != DrainType.APP || mBatteryUtils.shouldHideSipper(sipper))
-                            ? timeSequence
-                            : TextUtils.expandTemplate(getText(R.string.battery_used_for),
-                                    timeSequence));
-        }
-    }
-
-    @VisibleForTesting
-    String extractKeyFromSipper(BatterySipper sipper) {
-        if (sipper.uidObj != null) {
-            return extractKeyFromUid(sipper.getUid());
-        } else if (sipper.drainType == DrainType.USER) {
-            return sipper.drainType.toString() + sipper.userId;
-        } else if (sipper.drainType != DrainType.APP) {
-            return sipper.drainType.toString();
-        } else if (sipper.getPackages() != null) {
-            return TextUtils.concat(sipper.getPackages()).toString();
-        } else {
-            Log.w(TAG, "Inappropriate BatterySipper without uid and package names: " + sipper);
-            return "-1";
-        }
-    }
-
-    @VisibleForTesting
-    String extractKeyFromUid(int uid) {
-        return Integer.toString(uid);
-    }
-
-    @VisibleForTesting
-    void setBatteryLayoutPreference(LayoutPreference layoutPreference) {
-        mBatteryLayoutPref = layoutPreference;
-    }
-
-    @VisibleForTesting
-    void initFeatureProvider() {
-        final Context context = getContext();
-        mPowerFeatureProvider = FeatureFactory.getFactory(context)
-                .getPowerUsageFeatureProvider(context);
-    }
-
-    @VisibleForTesting
-    void updateAnomalySparseArray(List<Anomaly> anomalies) {
-        mAnomalySparseArray.clear();
-        for (int i = 0, size = anomalies.size(); i < size; i++) {
-            final Anomaly anomaly = anomalies.get(i);
-            if (mAnomalySparseArray.get(anomaly.uid) == null) {
-                mAnomalySparseArray.append(anomaly.uid, new ArrayList<>());
-            }
-            mAnomalySparseArray.get(anomaly.uid).add(anomaly);
-        }
-    }
-
-    @VisibleForTesting
-    void restartBatteryInfoLoader() {
-        getLoaderManager().restartLoader(BATTERY_INFO_LOADER, Bundle.EMPTY,
-                mBatteryInfoLoaderCallbacks);
-        if (mPowerFeatureProvider.isEstimateDebugEnabled()) {
-            // Unfortunately setting a long click listener on a view means it will no
-            // longer pass the regular click event to the parent, so we have to register
-            // a regular click listener as well.
-            View header = mBatteryLayoutPref.findViewById(R.id.summary1);
-            header.setOnLongClickListener(this);
-            header.setOnClickListener(this);
-        }
-    }
-
-    private static List<BatterySipper> getFakeStats() {
-        ArrayList<BatterySipper> stats = new ArrayList<>();
-        float use = 5;
-        for (DrainType type : DrainType.values()) {
-            if (type == DrainType.APP) {
-                continue;
-            }
-            stats.add(new BatterySipper(type, null, use));
-            use += 5;
-        }
-        for (int i = 0; i < 100; i++) {
-            stats.add(new BatterySipper(DrainType.APP,
-                    new FakeUid(Process.FIRST_APPLICATION_UID + i), use));
-        }
-        stats.add(new BatterySipper(DrainType.APP,
-                new FakeUid(0), use));
-
-        // Simulate dex2oat process.
-        BatterySipper sipper = new BatterySipper(DrainType.APP,
-                new FakeUid(UserHandle.getSharedAppGid(Process.FIRST_APPLICATION_UID)), 10.0f);
-        sipper.packageWithHighestDrain = "dex2oat";
-        stats.add(sipper);
-
-        sipper = new BatterySipper(DrainType.APP,
-                new FakeUid(UserHandle.getSharedAppGid(Process.FIRST_APPLICATION_UID + 1)), 10.0f);
-        sipper.packageWithHighestDrain = "dex2oat";
-        stats.add(sipper);
-
-        sipper = new BatterySipper(DrainType.APP,
-                new FakeUid(UserHandle.getSharedAppGid(Process.LOG_UID)), 9.0f);
-        stats.add(sipper);
-
-        return stats;
-    }
-
-    Handler mHandler = new Handler() {
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case BatteryEntry.MSG_UPDATE_NAME_ICON:
-                    BatteryEntry entry = (BatteryEntry) msg.obj;
-                    PowerGaugePreference pgp =
-                            (PowerGaugePreference) findPreference(
-                                    Integer.toString(entry.sipper.uidObj.getUid()));
-                    if (pgp != null) {
-                        final int userId = UserHandle.getUserId(entry.sipper.getUid());
-                        final UserHandle userHandle = new UserHandle(userId);
-                        pgp.setIcon(mUm.getBadgedIconForUser(entry.getIcon(), userHandle));
-                        pgp.setTitle(entry.name);
-                        if (entry.sipper.drainType == DrainType.APP) {
-                            pgp.setContentDescription(entry.name);
-                        }
-                    }
-                    break;
-                case BatteryEntry.MSG_REPORT_FULLY_DRAWN:
-                    Activity activity = getActivity();
-                    if (activity != null) {
-                        activity.reportFullyDrawn();
-                    }
-                    break;
-            }
-            super.handleMessage(msg);
-        }
-    };
-
-    @Override
-    public void onAnomalyHandled(Anomaly anomaly) {
-        mAnomalySummaryPreferenceController.hideHighUsagePreference();
-    }
-
-    @Override
-    public boolean onLongClick(View view) {
-        showBothEstimates();
-        view.setOnLongClickListener(null);
-        return true;
-    }
-
-    @Override
-    public void onClick(View view) {
-        performBatteryHeaderClick();
-    }
-
-    @Override
-    protected void restartBatteryStatsLoader() {
-        restartBatteryStatsLoader(true /* clearHeader */);
-    }
-
-    void restartBatteryStatsLoader(boolean clearHeader) {
-        super.restartBatteryStatsLoader();
-        if (clearHeader) {
-            mBatteryHeaderPreferenceController.quickUpdateHeaderPreference();
-        }
-    }
-
-    private static class SummaryProvider implements SummaryLoader.SummaryProvider {
-        private final Context mContext;
-        private final SummaryLoader mLoader;
-        private final BatteryBroadcastReceiver mBatteryBroadcastReceiver;
-
-        private SummaryProvider(Context context, SummaryLoader loader) {
-            mContext = context;
-            mLoader = loader;
-            mBatteryBroadcastReceiver = new BatteryBroadcastReceiver(mContext);
-            mBatteryBroadcastReceiver.setBatteryChangedListener(() -> {
-                BatteryInfo.getBatteryInfo(mContext, new BatteryInfo.Callback() {
-                    @Override
-                    public void onBatteryInfoLoaded(BatteryInfo info) {
-                        mLoader.setSummary(PowerUsageSummaryLegacy.SummaryProvider.this, info.chargeLabel);
-                    }
-                }, true /* shortString */);
-            });
-        }
-
-        @Override
-        public void setListening(boolean listening) {
-            if (listening) {
-                mBatteryBroadcastReceiver.register();
-            } else {
-                mBatteryBroadcastReceiver.unRegister();
-            }
-        }
-    }
-
-    public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY
-            = new SummaryLoader.SummaryProviderFactory() {
-        @Override
-        public SummaryLoader.SummaryProvider createSummaryProvider(Activity activity,
-                SummaryLoader summaryLoader) {
-            return new SummaryProvider(activity, summaryLoader);
-        }
-    };
-}
diff --git a/src/com/android/settings/search/SearchIndexableResourcesImpl.java b/src/com/android/settings/search/SearchIndexableResourcesImpl.java
index 61f5fec..0bc8de6 100644
--- a/src/com/android/settings/search/SearchIndexableResourcesImpl.java
+++ b/src/com/android/settings/search/SearchIndexableResourcesImpl.java
@@ -50,7 +50,6 @@
 import com.android.settings.dream.DreamSettings;
 import com.android.settings.enterprise.EnterprisePrivacySettings;
 import com.android.settings.fuelgauge.PowerUsageAdvanced;
-import com.android.settings.fuelgauge.PowerUsageAdvancedLegacy;
 import com.android.settings.fuelgauge.batterysaver.BatterySaverSettings;
 import com.android.settings.fuelgauge.PowerUsageSummary;
 import com.android.settings.fuelgauge.SmartBatterySettings;
@@ -124,7 +123,6 @@
         addIndex(ZenModeSettings.class);
         addIndex(StorageSettings.class);
         addIndex(PowerUsageAdvanced.class);
-        addIndex(PowerUsageAdvancedLegacy.class);
         addIndex(DefaultAppSettings.class);
         addIndex(ManageAssist.class);
         addIndex(SpecialAccessSettings.class);
