Merge "Remove the non-translatable tags from MainSwitch titles." into sc-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 1632e7e..30f181a 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -2820,8 +2820,13 @@
         </activity>
 
         <!-- Show channel-level notification settings (channel passed in as extras) -->
-        <activity android:name="Settings$ChannelNotificationSettingsActivity"
+        <activity android:name=".notification.app.ChannelPanelActivity"
                   android:label="@string/notification_channel_title"
+                  android:theme="@style/Theme.Panel"
+                  android:launchMode="singleInstance"
+                  android:excludeFromRecents="true"
+                  android:noHistory="true"
+                  android:configChanges="orientation|keyboardHidden|screenSize"
                   android:exported="true">
             <intent-filter android:priority="1">
                 <action android:name="android.settings.CHANNEL_NOTIFICATION_SETTINGS" />
diff --git a/color-check-baseline.xml b/color-check-baseline.xml
index b94da0d..9c79bab 100644
--- a/color-check-baseline.xml
+++ b/color-check-baseline.xml
@@ -4013,4 +4013,36 @@
             column="5"/>
     </issue>
 
+    <issue
+        id="HardCodedColor"
+        severity="Error"
+        message="Avoid using hardcoded color"
+        category="Correctness"
+        priority="4"
+        summary="Using hardcoded color"
+        explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.&#xA;This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+        errorLine1="          &lt;item android:offset=&quot;0&quot; android:color=&quot;#FF4285F4&quot;/>"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/drawable/one_handed_guideline.xml"
+            line="34"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="HardCodedColor"
+        severity="Error"
+        message="Avoid using hardcoded color"
+        category="Correctness"
+        priority="4"
+        summary="Using hardcoded color"
+        explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.&#xA;This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+        errorLine1="          &lt;item android:offset=&quot;1&quot; android:color=&quot;#004385F5&quot;/>"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/drawable/one_handed_guideline.xml"
+            line="35"
+            column="36"/>
+    </issue>
+
 </issues>
diff --git a/res/layout/notification_channel_panel.xml b/res/layout/notification_channel_panel.xml
new file mode 100644
index 0000000..49cd95c
--- /dev/null
+++ b/res/layout/notification_channel_panel.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 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.
+-->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/main_content"
+    android:layout_height="@dimen/output_switcher_slice_max_height"
+    android:background="@drawable/settings_panel_background"
+    android:orientation="vertical"
+    android:layout_width="match_parent">
+
+    <FrameLayout
+        android:id="@android:id/list_container"
+        android:layout_height="0px"
+        android:layout_weight="1"
+        android:layout_width="match_parent"/>
+
+    <View
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/footer_divider"
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/horizontal_divider_height"
+        android:background="?android:attr/dividerHorizontal"/>
+
+    <LinearLayout
+        android:id="@+id/footer"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:paddingTop="8dp"
+        android:paddingBottom="8dp">
+
+        <Button
+            android:id="@+id/see_more"
+            style="@android:style/Widget.DeviceDefault.Button.Borderless.Colored"
+            android:layout_width="wrap_content"
+            android:layout_height="48dp"
+            android:layout_marginStart="12dp"
+            android:text="@string/see_more"/>
+
+        <Space
+            android:layout_weight="1"
+            android:layout_width="0dp"
+            android:layout_height="match_parent" />
+
+        <Button
+            android:id="@+id/done"
+            style="@android:style/Widget.DeviceDefault.Button.Borderless.Colored"
+            android:layout_width="wrap_content"
+            android:layout_height="48dp"
+            android:layout_marginEnd="12dp"
+            android:text="@string/done"/>
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 99ec087..7e10006 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -3188,6 +3188,10 @@
     <string name="status_prl_version">PRL version</string>
     <!-- About phone screen, title for MEID for multi-sim devices -->
     <string name="meid_multi_sim">MEID (sim slot %1$d)</string>
+    <!-- The status text when (Wi-Fi or Bluetooth) scanning is on. [CHAR LIMIT=100] -->
+    <string name="scanning_status_text_on">On</string>
+    <!-- The status text when (Wi-Fi or Bluetooth) scanning is off. [CHAR LIMIT=100] -->
+    <string name="scanning_status_text_off">Off</string>
     <!-- The status text when both Wi-Fi scanning and Bluetooth scanning are on. [CHAR LIMIT=100] -->
     <string name="scanning_status_text_wifi_on_ble_on">Both Wi\u2011Fi and Bluetooth scanning are on</string>
     <!-- The status text when Wi-Fi scanning is on and Bluetooth scanning are off. [CHAR LIMIT=100] -->
@@ -5027,27 +5031,27 @@
     <!-- Title for the accessibility preference screen to enable screen magnification. [CHAR LIMIT=35] -->
     <string name="accessibility_screen_magnification_title">Magnification</string>
     <!-- Title for the accessibility preference screen to edit magnification area. [CHAR LIMIT=35] -->
-    <string name="accessibility_magnification_mode_title">Magnification area</string>
+    <string name="accessibility_magnification_mode_title">Choose how to magnify</string>
     <!-- Message for the accessibility preference screen to edit magnification area dialog. [CHAR LIMIT=none] -->
-    <string name="accessibility_magnification_area_settings_message">Choose the magnification area(s) you want to use when magnifying the screen</string>
+    <string name="accessibility_magnification_area_settings_message">Magnify your full screen, a specific area, or switch between both options</string>
     <!-- Summary for the accessibility preference screen to edit full screen. [CHAR LIMIT=none] -->
     <string name="accessibility_magnification_area_settings_full_screen_summary">Full screen</string>
-    <!-- Summary for the accessibility preference screen to edit window screen. [CHAR LIMIT=none] -->
-    <string name="accessibility_magnification_area_settings_window_screen_summary">Part of screen</string>
-    <!-- Summary for the accessibility preference screen to edit entire screen. [CHAR LIMIT=none] -->
-    <string name="accessibility_magnification_area_settings_all_summary">Full screen &amp; part of screen</string>
-    <!-- Message for the accessibility preference screen to edit entire screen. [CHAR LIMIT=none] -->
-    <string name="accessibility_magnification_area_settings_full_screen">Magnify entire screen</string>
+    <!-- Summary for the accessibility preference screen to edit partial screen. [CHAR LIMIT=none] -->
+    <string name="accessibility_magnification_area_settings_window_screen_summary">Partial screen</string>
+    <!-- Summary for the accessibility preference screen to edit full and partial screen. [CHAR LIMIT=none] -->
+    <string name="accessibility_magnification_area_settings_all_summary">Switch between full and partial screen</string>
+    <!-- Message for the accessibility preference screen to edit the full screen. [CHAR LIMIT=none] -->
+    <string name="accessibility_magnification_area_settings_full_screen">Magnify full screen</string>
     <!-- Message for the accessibility preference screen to edit part of screen. [CHAR LIMIT=none] -->
     <string name="accessibility_magnification_area_settings_window_screen">Magnify part of screen</string>
     <!-- Title for the accessibility magnification switch shortcut dialog. [CHAR LIMIT=48] -->
     <string name="accessibility_magnification_switch_shortcut_title">Switch to accessibility button?</string>
     <!-- Message for the accessibility magnification switch shortcut dialog. [CHAR LIMIT=none] -->
-    <string name="accessibility_magnification_switch_shortcut_message">Using triple tap to magnify part of the screen will cause typing and other actions to be delayed.\n\nDo you want to switch to using accessibility button to magnify?</string>
+    <string name="accessibility_magnification_switch_shortcut_message">Using triple-tap to magnify part of the screen causes typing and other delays.\n\nThe accessibility button floats on your screen over other apps. Tap it to magnify.</string>
     <!-- Title for the switch shortcut button in accessibility switch shortcut dialog to change the config shortcut value. [CHAR LIMIT=45] -->
     <string name="accessibility_magnification_switch_shortcut_positive_button">Switch to accessibility button</string>
     <!-- Title for the cancel button in accessibility switch shortcut dialog to keep the config shortcut value. [CHAR LIMIT=54] -->
-    <string name="accessibility_magnification_switch_shortcut_negative_button">Keep triple tap to magnify</string>
+    <string name="accessibility_magnification_switch_shortcut_negative_button">Use triple-tap</string>
     <!-- Title for the accessibility preference screen to enable screen magnification settings. [CHAR LIMIT=35] -->
     <string name="accessibility_magnification_service_settings_title">Magnification settings</string>
     <!-- Title for the accessibility preference screen to enable triple-tap gesture screen magnification. [CHAR LIMIT=35] -->
@@ -5068,7 +5072,7 @@
     <string name="accessibility_screen_magnification_navbar_short_summary">Tap a button to zoom</string>
     <!-- Summary for the accessibility preference screen to enable screen magnification gestures. [CHAR LIMIT=none] -->
     <string name="accessibility_screen_magnification_summary">
-        <![CDATA[Quickly zoom in on the screen to display content more clearly.<br/><br/>
+        <![CDATA[Quickly zoom in on the screen to make content larger.<br/><br/>
         <b>To zoom in:</b><br/>
         1. Use shortcut to start magnification<br/>
         2. Tap the screen<br/>
diff --git a/res/xml/channel_notification_settings.xml b/res/xml/channel_notification_settings.xml
index 707cae9..95f7944 100644
--- a/res/xml/channel_notification_settings.xml
+++ b/res/xml/channel_notification_settings.xml
@@ -65,56 +65,56 @@
         android:summary="@string/promote_conversation_summary"
         settings:allowDividerAbove="true"/>
 
-        <!-- Default ringtone -->
-        <com.android.settings.notification.app.NotificationSoundPreference
-            android:key="ringtone"
-            android:title="@string/notification_channel_sound_title"
-            android:dialogTitle="@string/notification_channel_sound_title"
-            android:order="11"
-            android:showSilent="true"
-            android:showDefault="true"/>
+    <!-- Default ringtone -->
+    <com.android.settings.notification.app.NotificationSoundPreference
+        android:key="ringtone"
+        android:title="@string/notification_channel_sound_title"
+        android:dialogTitle="@string/notification_channel_sound_title"
+        android:order="11"
+        android:showSilent="true"
+        android:showDefault="true"/>
 
-        <!-- Vibration -->
-        <com.android.settingslib.RestrictedSwitchPreference
-            android:key="vibrate"
-            android:order="12"
-            android:title="@string/notification_vibrate_title"
-            settings:useAdditionalSummary="true" />
+    <!-- Vibration -->
+    <com.android.settingslib.RestrictedSwitchPreference
+        android:key="vibrate"
+        android:order="12"
+        android:title="@string/notification_vibrate_title"
+        settings:useAdditionalSummary="true" />
 
-        <!-- Visibility Override -->
-        <com.android.settings.RestrictedListPreference
-            android:key="visibility_override"
-            android:order="13"
-            android:title="@string/app_notification_visibility_override_title"/>
+    <!-- Visibility Override -->
+    <com.android.settings.RestrictedListPreference
+        android:key="visibility_override"
+        android:order="13"
+        android:title="@string/app_notification_visibility_override_title"/>
 
-        <!-- Lights -->
-        <com.android.settingslib.RestrictedSwitchPreference
-            android:key="lights"
-            android:order="14"
-            android:title="@string/notification_show_lights_title"
-            settings:useAdditionalSummary="true"/>
+    <!-- Lights -->
+    <com.android.settingslib.RestrictedSwitchPreference
+        android:key="lights"
+        android:order="14"
+        android:title="@string/notification_show_lights_title"
+        settings:useAdditionalSummary="true"/>
 
-        <!-- Show badge -->
-        <com.android.settingslib.RestrictedSwitchPreference
-            android:key="badge"
-            android:order="15"
-            android:title="@string/notification_channel_badge_title"
-            settings:useAdditionalSummary="true"
-            settings:restrictedSwitchSummary="@string/enabled_by_admin"/>
+    <!-- Show badge -->
+    <com.android.settingslib.RestrictedSwitchPreference
+        android:key="badge"
+        android:order="15"
+        android:title="@string/notification_channel_badge_title"
+        settings:useAdditionalSummary="true"
+        settings:restrictedSwitchSummary="@string/enabled_by_admin"/>
 
-        <!-- Bypass DND -->
-        <com.android.settingslib.RestrictedSwitchPreference
-            android:key="bypass_dnd"
-            android:order="17"
-            android:title="@string/app_notification_override_dnd_title"
-            android:summary="@string/app_notification_override_dnd_summary"
-            settings:useAdditionalSummary="true"/>
+    <!-- Bypass DND -->
+    <com.android.settingslib.RestrictedSwitchPreference
+        android:key="bypass_dnd"
+        android:order="17"
+        android:title="@string/app_notification_override_dnd_title"
+        android:summary="@string/app_notification_override_dnd_summary"
+        settings:useAdditionalSummary="true"/>
 
-        <Preference
-            android:key="app_link"
-            android:order="18"
-            android:title="@string/app_settings_link"
-            settings:allowDividerAbove="true"/>
+    <Preference
+        android:key="app_link"
+        android:order="18"
+        android:title="@string/app_settings_link"
+        settings:allowDividerAbove="true"/>
 
     <com.android.settings.notification.app.NotificationFooterPreference
         android:key="desc"
diff --git a/res/xml/conversation_notification_settings.xml b/res/xml/conversation_notification_settings.xml
index 65fdee5..ea555c2 100644
--- a/res/xml/conversation_notification_settings.xml
+++ b/res/xml/conversation_notification_settings.xml
@@ -62,10 +62,6 @@
         android:key="block_desc"
         settings:allowDividerAbove="false"/>
 
-    <PreferenceCategory
-        android:key="channel_advanced"
-        android:order="50"
-        settings:initialExpandedChildrenCount="0">
 
         <!-- peeking -->
         <com.android.settingslib.RestrictedSwitchPreference
@@ -107,6 +103,5 @@
             android:icon="@drawable/ic_volume_ringer_vibrate"
             android:title="@string/notification_vibrate_title"
             settings:useAdditionalSummary="true" />
-    </PreferenceCategory>
 
 </PreferenceScreen>
diff --git a/res/xml/location_services.xml b/res/xml/location_services.xml
index ef94886..516491c 100644
--- a/res/xml/location_services.xml
+++ b/res/xml/location_services.xml
@@ -18,21 +18,21 @@
                   xmlns:settings="http://schemas.android.com/apk/res-auto"
         android:title="@string/location_services_screen_title">
 
-        <SwitchPreference
-            android:title="@string/location_scanning_wifi_always_scanning_title"
-            android:summary="@string/location_scanning_wifi_always_scanning_description"
-            android:defaultValue="true"
-            android:key="wifi_always_scanning" />
-
-        <SwitchPreference
-            android:title="@string/location_scanning_bluetooth_always_scanning_title"
-            android:summary="@string/location_scanning_bluetooth_always_scanning_description"
-            android:defaultValue="true"
-            android:key="bluetooth_always_scanning" />
-
         <PreferenceCategory
             android:key="location_services"
             android:layout="@layout/preference_category_no_label"
             settings:controller="com.android.settings.location.LocationInjectedServicesPreferenceController"/>
 
+        <Preference
+            android:fragment="com.android.settings.location.WifiScanningFragment"
+            android:key="location_services_wifi_scanning"
+            android:title="@string/location_scanning_wifi_always_scanning_title"
+            settings:controller="com.android.settings.location.LocationServicesWifiScanningPreferenceController"/>
+
+        <Preference
+            android:fragment="com.android.settings.location.BluetoothScanningFragment"
+            android:key="location_services_bluetooth_scanning"
+            android:title="@string/location_scanning_bluetooth_always_scanning_title"
+            settings:controller="com.android.settings.location.LocationServicesBluetoothScanningPreferenceController"/>
+
 </PreferenceScreen>
diff --git a/res/xml/location_services_bluetooth_scanning.xml b/res/xml/location_services_bluetooth_scanning.xml
new file mode 100644
index 0000000..fb522f0
--- /dev/null
+++ b/res/xml/location_services_bluetooth_scanning.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 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.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+                  xmlns:settings="http://schemas.android.com/apk/res-auto"
+        android:title="@string/location_scanning_bluetooth_always_scanning_title">
+
+        <com.android.settingslib.widget.MainSwitchPreference
+            android:key="bluetooth_always_scanning_switch"
+            android:title="@string/location_scanning_bluetooth_always_scanning_title"
+            settings:controller="com.android.settings.location.BluetoothScanningMainSwitchPreferenceController"/>
+
+        <com.android.settingslib.widget.FooterPreference
+            android:key="bluetooth_always_scanning_footer"
+            android:title="@string/location_scanning_bluetooth_always_scanning_description"
+            android:selectable="false"
+            settings:searchable="false"/>
+
+</PreferenceScreen>
diff --git a/res/xml/location_services_wifi_scanning.xml b/res/xml/location_services_wifi_scanning.xml
new file mode 100644
index 0000000..a436fac
--- /dev/null
+++ b/res/xml/location_services_wifi_scanning.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 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.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+                  xmlns:settings="http://schemas.android.com/apk/res-auto"
+        android:title="@string/location_scanning_wifi_always_scanning_title">
+
+        <com.android.settingslib.widget.MainSwitchPreference
+            android:key="wifi_always_scanning_switch"
+            android:title="@string/location_scanning_wifi_always_scanning_title"
+            settings:controller="com.android.settings.location.WifiScanningMainSwitchPreferenceController"/>
+
+        <com.android.settingslib.widget.FooterPreference
+            android:key="wifi_always_scanning_footer"
+            android:title="@string/location_scanning_wifi_always_scanning_description"
+            android:selectable="false"
+            settings:searchable="false"/>
+
+</PreferenceScreen>
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/applications/assist/DefaultVoiceInputPicker.java b/src/com/android/settings/applications/assist/DefaultVoiceInputPicker.java
index e5953db..d4ea4a9 100644
--- a/src/com/android/settings/applications/assist/DefaultVoiceInputPicker.java
+++ b/src/com/android/settings/applications/assist/DefaultVoiceInputPicker.java
@@ -24,7 +24,6 @@
 import android.provider.Settings;
 import android.text.TextUtils;
 
-import com.android.internal.app.AssistUtils;
 import com.android.settings.R;
 import com.android.settings.applications.defaultapps.DefaultAppPickerFragment;
 import com.android.settingslib.applications.DefaultAppInfo;
@@ -35,8 +34,6 @@
 public class DefaultVoiceInputPicker extends DefaultAppPickerFragment {
 
     private VoiceInputHelper mHelper;
-    private AssistUtils mAssistUtils;
-    private String mAssistRestrict;
 
     @Override
     public int getMetricsCategory() {
@@ -46,13 +43,8 @@
     @Override
     public void onAttach(Context context) {
         super.onAttach(context);
-        mAssistUtils = new AssistUtils(context);
         mHelper = new VoiceInputHelper(context);
         mHelper.buildUi();
-        final ComponentName assist = getCurrentAssist();
-        if (isCurrentAssistVoiceService(assist, getCurrentService(mHelper))) {
-            mAssistRestrict = assist.flattenToShortString();
-        }
     }
 
     @Override
@@ -64,16 +56,9 @@
     protected List<VoiceInputDefaultAppInfo> getCandidates() {
         final List<VoiceInputDefaultAppInfo> candidates = new ArrayList<>();
         final Context context = getContext();
-        boolean hasEnabled = true;
-        for (VoiceInputHelper.InteractionInfo info : mHelper.mAvailableInteractionInfos) {
-            final boolean enabled = TextUtils.equals(info.key, mAssistRestrict);
-            hasEnabled |= enabled;
-            candidates.add(new VoiceInputDefaultAppInfo(context, mPm, mUserId, info, enabled));
-        }
 
-        final boolean assistIsService = !hasEnabled;
         for (VoiceInputHelper.RecognizerInfo info : mHelper.mAvailableRecognizerInfos) {
-            final boolean enabled = !assistIsService;
+            final boolean enabled = true;
             candidates.add(new VoiceInputDefaultAppInfo(context, mPm, mUserId, info, enabled));
         }
         return candidates;
@@ -90,24 +75,9 @@
 
     @Override
     protected boolean setDefaultKey(String value) {
-        for (VoiceInputHelper.InteractionInfo info : mHelper.mAvailableInteractionInfos) {
-            if (TextUtils.equals(value, info.key)) {
-                Settings.Secure.putString(getContext().getContentResolver(),
-                        Settings.Secure.VOICE_INTERACTION_SERVICE, value);
-                Settings.Secure.putString(getContext().getContentResolver(),
-                        Settings.Secure.VOICE_RECOGNITION_SERVICE,
-                        new ComponentName(info.service.packageName,
-                                info.serviceInfo.getRecognitionService())
-                                .flattenToShortString());
-                return true;
-            }
-        }
-
         for (VoiceInputHelper.RecognizerInfo info : mHelper.mAvailableRecognizerInfos) {
             if (TextUtils.equals(value, info.key)) {
                 Settings.Secure.putString(getContext().getContentResolver(),
-                        Settings.Secure.VOICE_INTERACTION_SERVICE, "");
-                Settings.Secure.putString(getContext().getContentResolver(),
                         Settings.Secure.VOICE_RECOGNITION_SERVICE, value);
                 return true;
             }
@@ -116,23 +86,7 @@
     }
 
     public static ComponentName getCurrentService(VoiceInputHelper helper) {
-        if (helper.mCurrentVoiceInteraction != null) {
-            return helper.mCurrentVoiceInteraction;
-        } else if (helper.mCurrentRecognizer != null) {
-            return helper.mCurrentRecognizer;
-        } else {
-            return null;
-        }
-    }
-
-    private ComponentName getCurrentAssist() {
-        return mAssistUtils.getAssistComponentForUser(mUserId);
-    }
-
-    public static boolean isCurrentAssistVoiceService(ComponentName currentAssist,
-            ComponentName currentVoiceService) {
-        return currentAssist == null && currentVoiceService == null ||
-                currentAssist != null && currentAssist.equals(currentVoiceService);
+        return helper.mCurrentRecognizer;
     }
 
     public static class VoiceInputDefaultAppInfo extends DefaultAppInfo {
@@ -152,11 +106,7 @@
 
         @Override
         public CharSequence loadLabel() {
-            if (mInfo instanceof VoiceInputHelper.InteractionInfo) {
-                return mInfo.appLabel;
-            } else {
-                return mInfo.label;
-            }
+            return mInfo.label;
         }
 
         public Intent getSettingIntent() {
diff --git a/src/com/android/settings/applications/assist/DefaultVoiceInputPreferenceController.java b/src/com/android/settings/applications/assist/DefaultVoiceInputPreferenceController.java
index e53334d..59f5731 100644
--- a/src/com/android/settings/applications/assist/DefaultVoiceInputPreferenceController.java
+++ b/src/com/android/settings/applications/assist/DefaultVoiceInputPreferenceController.java
@@ -26,7 +26,6 @@
 import androidx.preference.Preference;
 import androidx.preference.PreferenceScreen;
 
-import com.android.internal.app.AssistUtils;
 import com.android.settings.applications.defaultapps.DefaultAppPreferenceController;
 import com.android.settingslib.applications.DefaultAppInfo;
 import com.android.settingslib.core.lifecycle.Lifecycle;
@@ -42,17 +41,13 @@
     private static final String KEY_VOICE_INPUT = "voice_input_settings";
 
     private VoiceInputHelper mHelper;
-    private AssistUtils mAssistUtils;
     private PreferenceScreen mScreen;
     private Preference mPreference;
-    private SettingObserver mSettingObserver;
     private Context mContext;
 
     public DefaultVoiceInputPreferenceController(Context context, Lifecycle lifecycle) {
         super(context);
         mContext = context;
-        mSettingObserver = new SettingObserver();
-        mAssistUtils = new AssistUtils(context);
         mHelper = new VoiceInputHelper(context);
         mHelper.buildUi();
         if (lifecycle != null) {
@@ -80,7 +75,6 @@
 
     @Override
     public void onResume() {
-        mSettingObserver.register(mContext.getContentResolver(), true);
         updatePreference();
     }
 
@@ -91,9 +85,7 @@
     }
 
     @Override
-    public void onPause() {
-        mSettingObserver.register(mContext.getContentResolver(), false);
-    }
+    public void onPause() {}
 
     @Override
     protected DefaultAppInfo getDefaultAppInfo() {
@@ -101,12 +93,6 @@
         if (defaultKey == null) {
             return null;
         }
-        for (VoiceInputHelper.InteractionInfo info : mHelper.mAvailableInteractionInfos) {
-            if (TextUtils.equals(defaultKey, info.key)) {
-                return new DefaultVoiceInputPicker.VoiceInputDefaultAppInfo(mContext,
-                        mPackageManager, mUserId, info, true /* enabled */);
-            }
-        }
 
         for (VoiceInputHelper.RecognizerInfo info : mHelper.mAvailableRecognizerInfos) {
             if (TextUtils.equals(defaultKey, info.key)) {
@@ -149,16 +135,4 @@
         }
         return currentService.flattenToShortString();
     }
-
-    class SettingObserver extends AssistSettingObserver {
-        @Override
-        protected List<Uri> getSettingUris() {
-            return null;
-        }
-
-        @Override
-        public void onSettingChange() {
-            updatePreference();
-        }
-    }
 }
diff --git a/src/com/android/settings/applications/assist/VoiceInputHelper.java b/src/com/android/settings/applications/assist/VoiceInputHelper.java
index fb60090..285f4f7 100644
--- a/src/com/android/settings/applications/assist/VoiceInputHelper.java
+++ b/src/com/android/settings/applications/assist/VoiceInputHelper.java
@@ -26,10 +26,7 @@
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
 import android.provider.Settings;
-import android.service.voice.VoiceInteractionService;
-import android.service.voice.VoiceInteractionServiceInfo;
 import android.speech.RecognitionService;
-import android.util.ArraySet;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.Xml;
@@ -46,9 +43,9 @@
     static final String TAG = "VoiceInputHelper";
     final Context mContext;
 
-    final List<ResolveInfo> mAvailableVoiceInteractions;
     final List<ResolveInfo> mAvailableRecognition;
 
+    // TODO: Remove this superclass as we only have 1 class now (RecognizerInfo).
     static public class BaseInfo implements Comparable {
         public final ServiceInfo service;
         public final ComponentName componentName;
@@ -75,15 +72,6 @@
         }
     }
 
-    static public class InteractionInfo extends BaseInfo {
-        public final VoiceInteractionServiceInfo serviceInfo;
-
-        public InteractionInfo(PackageManager pm, VoiceInteractionServiceInfo _service) {
-            super(pm, _service.getServiceInfo(), _service.getSettingsActivity());
-            serviceInfo = _service;
-        }
-    }
-
     static public class RecognizerInfo extends BaseInfo {
         public final boolean mSelectableAsDefault;
 
@@ -96,56 +84,21 @@
         }
     }
 
-    final ArrayList<InteractionInfo> mAvailableInteractionInfos = new ArrayList<>();
     final ArrayList<RecognizerInfo> mAvailableRecognizerInfos = new ArrayList<>();
 
-    ComponentName mCurrentVoiceInteraction;
     ComponentName mCurrentRecognizer;
 
     public VoiceInputHelper(Context context) {
         mContext = context;
 
-        mAvailableVoiceInteractions = mContext.getPackageManager().queryIntentServices(
-                new Intent(VoiceInteractionService.SERVICE_INTERFACE),
-                PackageManager.GET_META_DATA);
         mAvailableRecognition = mContext.getPackageManager().queryIntentServices(
                 new Intent(RecognitionService.SERVICE_INTERFACE),
                 PackageManager.GET_META_DATA);
     }
 
     public void buildUi() {
-        // Get the currently selected interactor from the secure setting.
-        String currentSetting = Settings.Secure.getString(
-                mContext.getContentResolver(), Settings.Secure.VOICE_INTERACTION_SERVICE);
-        if (currentSetting != null && !currentSetting.isEmpty()) {
-            mCurrentVoiceInteraction = ComponentName.unflattenFromString(currentSetting);
-        } else {
-            mCurrentVoiceInteraction = null;
-        }
-
-        ArraySet<ComponentName> interactorRecognizers = new ArraySet<>();
-
-        // Iterate through all the available interactors and load up their info to show
-        // in the preference.
-        int size = mAvailableVoiceInteractions.size();
-        for (int i = 0; i < size; i++) {
-            ResolveInfo resolveInfo = mAvailableVoiceInteractions.get(i);
-            VoiceInteractionServiceInfo info = new VoiceInteractionServiceInfo(
-                    mContext.getPackageManager(), resolveInfo.serviceInfo);
-            if (info.getParseError() != null) {
-                Log.w("VoiceInteractionService", "Error in VoiceInteractionService "
-                        + resolveInfo.serviceInfo.packageName + "/"
-                        + resolveInfo.serviceInfo.name + ": " + info.getParseError());
-                continue;
-            }
-            mAvailableInteractionInfos.add(new InteractionInfo(mContext.getPackageManager(), info));
-            interactorRecognizers.add(new ComponentName(resolveInfo.serviceInfo.packageName,
-                    info.getRecognitionService()));
-        }
-        Collections.sort(mAvailableInteractionInfos);
-
         // Get the currently selected recognizer from the secure setting.
-        currentSetting = Settings.Secure.getString(
+        String currentSetting = Settings.Secure.getString(
                 mContext.getContentResolver(), Settings.Secure.VOICE_RECOGNITION_SERVICE);
         if (currentSetting != null && !currentSetting.isEmpty()) {
             mCurrentRecognizer = ComponentName.unflattenFromString(currentSetting);
@@ -155,14 +108,11 @@
 
         // Iterate through all the available recognizers and load up their info to show
         // in the preference.
-        size = mAvailableRecognition.size();
+        int size = mAvailableRecognition.size();
         for (int i = 0; i < size; i++) {
             ResolveInfo resolveInfo = mAvailableRecognition.get(i);
             ComponentName comp = new ComponentName(resolveInfo.serviceInfo.packageName,
                     resolveInfo.serviceInfo.name);
-            if (interactorRecognizers.contains(comp)) {
-                //continue;
-            }
             ServiceInfo si = resolveInfo.serviceInfo;
             String settingsActivity = null;
             // Always show in voice input settings unless specifically set to False.
diff --git a/src/com/android/settings/bluetooth/BluetoothPermissionActivity.java b/src/com/android/settings/bluetooth/BluetoothPermissionActivity.java
index e40e30d..cd36ce8 100644
--- a/src/com/android/settings/bluetooth/BluetoothPermissionActivity.java
+++ b/src/com/android/settings/bluetooth/BluetoothPermissionActivity.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.bluetooth;
 
+import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+
 import android.bluetooth.BluetoothDevice;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -23,6 +25,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.os.Bundle;
+import android.text.TextUtils;
 import android.util.Log;
 import android.view.View;
 import android.widget.Button;
@@ -30,11 +33,14 @@
 
 import androidx.preference.Preference;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.AlertActivity;
 import com.android.internal.app.AlertController;
 import com.android.settings.R;
-
-import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+import com.android.settings.password.PasswordUtils;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
 
 /**
  * BluetoothPermissionActivity shows a dialog for accepting incoming
@@ -51,8 +57,13 @@
     private TextView messageView;
     private Button mOkButton;
     private BluetoothDevice mDevice;
-    private String mReturnPackage = null;
-    private String mReturnClass = null;
+
+    @VisibleForTesting
+    String mReturnPackage = null;
+    @VisibleForTesting
+    String mReturnClass = null;
+    @VisibleForTesting
+    String mCallingAppPackageName;
 
     private int mRequestType = 0;
     private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@@ -80,6 +91,7 @@
 
         getWindow().addPrivateFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
         Intent i = getIntent();
+        mCallingAppPackageName = PasswordUtils.getCallingAppPackageName(getActivityToken());
         String action = i.getAction();
         if (!action.equals(BluetoothDevice.ACTION_CONNECTION_ACCESS_REQUEST)) {
             Log.e(TAG, "Error: this activity may be started only with intent "
@@ -94,6 +106,22 @@
         mRequestType = i.getIntExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE,
                                      BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS);
 
+        // Even if the user has already made the choice, Bluetooth still may not know that if
+        // the user preference data have not been migrated from Settings app's shared
+        // preferences to Bluetooth app's. In that case, Bluetooth app broadcasts an
+        // ACTION_CONNECTION_ACCESS_REQUEST intent to ask to Settings app.
+        //
+        // If that happens, 'checkUserChoice()' here will do migration because it finds or
+        // creates a 'CachedBluetoothDevice' object for the device.
+        //
+        // After migration is done, 'checkUserChoice()' replies to the request by sending an
+        // ACTION_CONNECTION_ACCESS_REPLY intent. And we don't need to start permission activity
+        // dialog or notification.
+        if (checkUserChoice()) {
+            finish();
+            return;
+        }
+
         if(DEBUG) Log.i(TAG, "onCreate() Request type: " + mRequestType);
 
         if (mRequestType == BluetoothDevice.REQUEST_TYPE_PROFILE_CONNECTION) {
@@ -202,7 +230,14 @@
         sendReplyIntentToReceiver(false, true);
     }
 
-    private void sendReplyIntentToReceiver(final boolean allowed, final boolean always) {
+    @VisibleForTesting
+    void sendReplyIntentToReceiver(final boolean allowed, final boolean always) {
+        if (!TextUtils.equals(mCallingAppPackageName, mReturnPackage)) {
+            Log.w(TAG, "sendReplyIntentToReceiver() return package name is not equivalent"
+                    + " to calling package name!");
+            return;
+        }
+
         Intent intent = new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY);
 
         if (mReturnPackage != null && mReturnClass != null) {
@@ -246,4 +281,76 @@
     public boolean onPreferenceChange(Preference preference, Object newValue) {
         return true;
     }
+
+    /**
+     * @return true user had made a choice, this method replies to the request according
+     *              to user's previous decision
+     *         false user hadnot made any choice on this device
+     */
+    private boolean checkUserChoice() {
+        boolean processed = false;
+
+        // ignore if it is something else than phonebook/message settings it wants us to remember
+        if (mRequestType != BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS
+                && mRequestType != BluetoothDevice.REQUEST_TYPE_MESSAGE_ACCESS
+                && mRequestType != BluetoothDevice.REQUEST_TYPE_SIM_ACCESS) {
+            Log.d(TAG, "checkUserChoice(): Unknown RequestType " + mRequestType);
+            return processed;
+        }
+
+        final LocalBluetoothManager bluetoothManager = Utils.getLocalBtManager(this);
+        final CachedBluetoothDeviceManager cachedDeviceManager =
+                bluetoothManager.getCachedDeviceManager();
+        CachedBluetoothDevice cachedDevice = cachedDeviceManager.findDevice(mDevice);
+        if (cachedDevice == null) {
+            cachedDevice = cachedDeviceManager.addDevice(mDevice);
+        }
+
+        if (mRequestType == BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS) {
+            final int phonebookPermission = mDevice.getPhonebookAccessPermission();
+
+            if (phonebookPermission == BluetoothDevice.ACCESS_UNKNOWN) {
+                // Leave 'processed' as false.
+            } else if (phonebookPermission == BluetoothDevice.ACCESS_ALLOWED) {
+                sendReplyIntentToReceiver(true, true);
+                processed = true;
+            } else if (phonebookPermission == BluetoothDevice.ACCESS_REJECTED) {
+                sendReplyIntentToReceiver(false, true);
+                processed = true;
+            } else {
+                Log.e(TAG, "Bad phonebookPermission: " + phonebookPermission);
+            }
+        } else if (mRequestType == BluetoothDevice.REQUEST_TYPE_MESSAGE_ACCESS) {
+            final int messagePermission = mDevice.getMessageAccessPermission();
+
+            if (messagePermission == BluetoothDevice.ACCESS_UNKNOWN) {
+                // Leave 'processed' as false.
+            } else if (messagePermission == BluetoothDevice.ACCESS_ALLOWED) {
+                sendReplyIntentToReceiver(true, true);
+                processed = true;
+            } else if (messagePermission == BluetoothDevice.ACCESS_REJECTED) {
+                sendReplyIntentToReceiver(false, true);
+                processed = true;
+            } else {
+                Log.e(TAG, "Bad messagePermission: " + messagePermission);
+            }
+        } else if (mRequestType == BluetoothDevice.REQUEST_TYPE_SIM_ACCESS) {
+            final int simPermission = mDevice.getSimAccessPermission();
+
+            if (simPermission == BluetoothDevice.ACCESS_UNKNOWN) {
+                // Leave 'processed' as false.
+            } else if (simPermission == BluetoothDevice.ACCESS_ALLOWED) {
+                sendReplyIntentToReceiver(true, true);
+                processed = true;
+            } else if (simPermission == BluetoothDevice.ACCESS_REJECTED) {
+                sendReplyIntentToReceiver(false, true);
+                processed = true;
+            } else {
+                Log.e(TAG, "Bad simPermission: " + simPermission);
+            }
+        }
+
+        Log.d(TAG, "checkUserChoice(): returning " + processed);
+        return processed;
+    }
 }
diff --git a/src/com/android/settings/bluetooth/BluetoothPermissionRequest.java b/src/com/android/settings/bluetooth/BluetoothPermissionRequest.java
index 7fac4991c..c606e31 100644
--- a/src/com/android/settings/bluetooth/BluetoothPermissionRequest.java
+++ b/src/com/android/settings/bluetooth/BluetoothPermissionRequest.java
@@ -29,9 +29,6 @@
 import android.util.Log;
 
 import com.android.settings.R;
-import com.android.settingslib.bluetooth.CachedBluetoothDevice;
-import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
-import com.android.settingslib.bluetooth.LocalBluetoothManager;
 
 /**
  * BluetoothPermissionRequest is a receiver to receive Bluetooth connection
@@ -83,21 +80,6 @@
             if (DEBUG) Log.d(TAG, "onReceive request type: " + mRequestType + " return "
                     + mReturnPackage + "," + mReturnClass);
 
-            // Even if the user has already made the choice, Bluetooth still may not know that if
-            // the user preference data have not been migrated from Settings app's shared
-            // preferences to Bluetooth app's. In that case, Bluetooth app broadcasts an
-            // ACTION_CONNECTION_ACCESS_REQUEST intent to ask to Settings app.
-            //
-            // If that happens, 'checkUserChoice()' here will do migration because it finds or
-            // creates a 'CachedBluetoothDevice' object for the device.
-            //
-            // After migration is done, 'checkUserChoice()' replies to the request by sending an
-            // ACTION_CONNECTION_ACCESS_REPLY intent. And we don't need to start permission activity
-            // dialog or notification.
-            if (checkUserChoice()) {
-                return;
-            }
-
             Intent connectionAccessIntent = new Intent(action);
             connectionAccessIntent.setClass(context, BluetoothPermissionActivity.class);
             // We use the FLAG_ACTIVITY_MULTIPLE_TASK since we can have multiple concurrent access
@@ -212,92 +194,4 @@
         }
         return null;
     }
-
-    /**
-     * @return true user had made a choice, this method replies to the request according
-     *              to user's previous decision
-     *         false user hadnot made any choice on this device
-     */
-    private boolean checkUserChoice() {
-        boolean processed = false;
-
-        // ignore if it is something else than phonebook/message settings it wants us to remember
-        if (mRequestType != BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS
-                && mRequestType != BluetoothDevice.REQUEST_TYPE_MESSAGE_ACCESS
-                && mRequestType != BluetoothDevice.REQUEST_TYPE_SIM_ACCESS) {
-            if (DEBUG) Log.d(TAG, "checkUserChoice(): Unknown RequestType " + mRequestType);
-            return processed;
-        }
-
-        LocalBluetoothManager bluetoothManager = Utils.getLocalBtManager(mContext);
-        CachedBluetoothDeviceManager cachedDeviceManager =
-            bluetoothManager.getCachedDeviceManager();
-        CachedBluetoothDevice cachedDevice = cachedDeviceManager.findDevice(mDevice);
-        if (cachedDevice == null) {
-            cachedDevice = cachedDeviceManager.addDevice(mDevice);
-        }
-
-        String intentName = BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY;
-
-        if (mRequestType == BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS) {
-            int phonebookPermission = mDevice.getPhonebookAccessPermission();
-
-            if (phonebookPermission == BluetoothDevice.ACCESS_UNKNOWN) {
-                // Leave 'processed' as false.
-            } else if (phonebookPermission == BluetoothDevice.ACCESS_ALLOWED) {
-                sendReplyIntentToReceiver(true);
-                processed = true;
-            } else if (phonebookPermission == BluetoothDevice.ACCESS_REJECTED) {
-                sendReplyIntentToReceiver(false);
-                processed = true;
-            } else {
-                Log.e(TAG, "Bad phonebookPermission: " + phonebookPermission);
-            }
-        } else if (mRequestType == BluetoothDevice.REQUEST_TYPE_MESSAGE_ACCESS) {
-            int messagePermission = mDevice.getMessageAccessPermission();
-
-            if (messagePermission == BluetoothDevice.ACCESS_UNKNOWN) {
-                // Leave 'processed' as false.
-            } else if (messagePermission == BluetoothDevice.ACCESS_ALLOWED) {
-                sendReplyIntentToReceiver(true);
-                processed = true;
-            } else if (messagePermission == BluetoothDevice.ACCESS_REJECTED) {
-                sendReplyIntentToReceiver(false);
-                processed = true;
-            } else {
-                Log.e(TAG, "Bad messagePermission: " + messagePermission);
-            }
-        } else if(mRequestType == BluetoothDevice.REQUEST_TYPE_SIM_ACCESS) {
-            int simPermission = mDevice.getSimAccessPermission();
-
-            if (simPermission == BluetoothDevice.ACCESS_UNKNOWN) {
-                // Leave 'processed' as false.
-            } else if (simPermission == BluetoothDevice.ACCESS_ALLOWED) {
-                sendReplyIntentToReceiver(true);
-                processed = true;
-            } else if (simPermission == BluetoothDevice.ACCESS_REJECTED) {
-                sendReplyIntentToReceiver(false);
-                processed = true;
-            } else {
-                Log.e(TAG, "Bad simPermission: " + simPermission);
-            }
-        }
-        if (DEBUG) Log.d(TAG,"checkUserChoice(): returning " + processed);
-        return processed;
-    }
-
-    private void sendReplyIntentToReceiver(final boolean allowed) {
-        Intent intent = new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY);
-
-        if (mReturnPackage != null && mReturnClass != null) {
-            intent.setClassName(mReturnPackage, mReturnClass);
-        }
-
-        intent.putExtra(BluetoothDevice.EXTRA_CONNECTION_ACCESS_RESULT,
-                        allowed ? BluetoothDevice.CONNECTION_ACCESS_YES
-                                : BluetoothDevice.CONNECTION_ACCESS_NO);
-        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice);
-        intent.putExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, mRequestType);
-        mContext.sendBroadcast(intent, android.Manifest.permission.BLUETOOTH_ADMIN);
-    }
 }
diff --git a/src/com/android/settings/bluetooth/DevicePickerFragment.java b/src/com/android/settings/bluetooth/DevicePickerFragment.java
index ab8eea5..214c590 100644
--- a/src/com/android/settings/bluetooth/DevicePickerFragment.java
+++ b/src/com/android/settings/bluetooth/DevicePickerFragment.java
@@ -27,12 +27,15 @@
 import android.content.Intent;
 import android.os.Bundle;
 import android.os.UserManager;
+import android.text.TextUtils;
+import android.util.Log;
 import android.view.Menu;
 import android.view.MenuInflater;
 
 import androidx.annotation.VisibleForTesting;
 
 import com.android.settings.R;
+import com.android.settings.password.PasswordUtils;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.settingslib.core.AbstractPreferenceController;
 
@@ -48,10 +51,16 @@
 
     @VisibleForTesting
     BluetoothProgressCategory mAvailableDevicesCategory;
+    @VisibleForTesting
+    String mLaunchPackage;
+    @VisibleForTesting
+    String mLaunchClass;
+    @VisibleForTesting
+    String mCallingAppPackageName;
+    @VisibleForTesting
+    Context mContext;
 
     private boolean mNeedAuth;
-    private String mLaunchPackage;
-    private String mLaunchClass;
     private boolean mScanAllowed;
 
     public DevicePickerFragment() {
@@ -85,6 +94,9 @@
         getActivity().setTitle(getString(R.string.device_picker));
         UserManager um = (UserManager) getSystemService(Context.USER_SERVICE);
         mScanAllowed = !um.hasUserRestriction(DISALLOW_CONFIG_BLUETOOTH);
+        mCallingAppPackageName = PasswordUtils.getCallingAppPackageName(
+                getActivity().getActivityToken());
+        mContext = getContext();
         setHasOptionsMenu(true);
     }
 
@@ -188,11 +200,17 @@
     }
 
     private void sendDevicePickedIntent(BluetoothDevice device) {
+        if (!TextUtils.equals(mCallingAppPackageName, mLaunchPackage)) {
+            Log.w(TAG, "sendDevicePickedIntent() launch package name is not equivalent to"
+                    + " calling package name!");
+            return;
+        }
+
         Intent intent = new Intent(BluetoothDevicePicker.ACTION_DEVICE_SELECTED);
         intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
         if (mLaunchPackage != null && mLaunchClass != null) {
             intent.setClassName(mLaunchPackage, mLaunchClass);
         }
-        getActivity().sendBroadcast(intent, Manifest.permission.BLUETOOTH_ADMIN);
+        mContext.sendBroadcast(intent, Manifest.permission.BLUETOOTH_ADMIN);
     }
 }
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/FakeUid.java b/src/com/android/settings/fuelgauge/FakeUid.java
index e1fc7f4..4bb98ed 100644
--- a/src/com/android/settings/fuelgauge/FakeUid.java
+++ b/src/com/android/settings/fuelgauge/FakeUid.java
@@ -361,6 +361,11 @@
     }
 
     @Override
+    public long getCpuMeasuredBatteryConsumptionUC() {
+        return 0;
+    }
+
+    @Override
     public long[] getCustomConsumerMeasuredBatteryConsumptionUC() {
         return null;
     }
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/src/com/android/settings/location/BluetoothScanningFragment.java b/src/com/android/settings/location/BluetoothScanningFragment.java
new file mode 100644
index 0000000..553f975
--- /dev/null
+++ b/src/com/android/settings/location/BluetoothScanningFragment.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2021 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.location;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+
+import com.android.settings.R;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.search.SearchIndexable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A page that configures the Bluetooth scanning setting.
+ */
+@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
+public class BluetoothScanningFragment extends DashboardFragment {
+    private static final String TAG = "BluetoothScanningFragment";
+
+    @Override
+    public int getMetricsCategory() {
+        return SettingsEnums.LOCATION_SERVICES;
+    }
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.location_services_bluetooth_scanning;
+    }
+
+    @Override
+    protected String getLogTag() {
+        return TAG;
+    }
+
+    @Override
+    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+        return buildPreferenceControllers(context);
+    }
+
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+    }
+
+    private static List<AbstractPreferenceController> buildPreferenceControllers(Context context) {
+        final List<AbstractPreferenceController> controllers = new ArrayList<>();
+        controllers.add(new BluetoothScanningPreferenceController(context));
+        return controllers;
+    }
+
+    /**
+     * For Search.
+     */
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+            new BaseSearchIndexProvider(R.xml.location_services_bluetooth_scanning) {
+
+                @Override
+                public List<AbstractPreferenceController> createPreferenceControllers(Context
+                        context) {
+                    return buildPreferenceControllers(context);
+                }
+            };
+}
diff --git a/src/com/android/settings/location/BluetoothScanningMainSwitchPreferenceController.java b/src/com/android/settings/location/BluetoothScanningMainSwitchPreferenceController.java
new file mode 100644
index 0000000..051fd8d
--- /dev/null
+++ b/src/com/android/settings/location/BluetoothScanningMainSwitchPreferenceController.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2021 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.location;
+
+import android.content.Context;
+import android.provider.Settings;
+import android.widget.Switch;
+
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.core.TogglePreferenceController;
+import com.android.settingslib.widget.MainSwitchPreference;
+import com.android.settingslib.widget.OnMainSwitchChangeListener;
+
+/**
+ * Preference controller for Bluetooth scanning main switch.
+ */
+public class BluetoothScanningMainSwitchPreferenceController extends TogglePreferenceController
+        implements OnMainSwitchChangeListener {
+
+    private static final String KEY_BLUETOOTH_SCANNING_SWITCH = "bluetooth_always_scanning_switch";
+
+    public BluetoothScanningMainSwitchPreferenceController(Context context) {
+        super(context, KEY_BLUETOOTH_SCANNING_SWITCH);
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        MainSwitchPreference pref = screen.findPreference(getPreferenceKey());
+        pref.addOnSwitchChangeListener(this);
+        pref.updateStatus(isChecked());
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return mContext.getResources().getBoolean(R.bool.config_show_location_scanning)
+                ? AVAILABLE
+                : UNSUPPORTED_ON_DEVICE;
+    }
+
+    @Override
+    public boolean isChecked() {
+        return Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE, 0) == 1;
+    }
+
+    @Override
+    public boolean setChecked(boolean isChecked) {
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE, isChecked ? 1 : 0);
+        // Returning true means the underlying setting is updated.
+        return true;
+    }
+
+    @Override
+    public void onSwitchChanged(Switch switchView, boolean isChecked) {
+        if (isChecked != isChecked()) {
+            setChecked(isChecked);
+        }
+    }
+}
diff --git a/src/com/android/settings/location/LocationServicesBluetoothScanningPreferenceController.java b/src/com/android/settings/location/LocationServicesBluetoothScanningPreferenceController.java
new file mode 100644
index 0000000..9913848
--- /dev/null
+++ b/src/com/android/settings/location/LocationServicesBluetoothScanningPreferenceController.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2021 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.location;
+
+import android.content.Context;
+import android.provider.Settings;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+
+/**
+ * Preference controller for Bluetooth scanning in Location Services.
+ */
+public class LocationServicesBluetoothScanningPreferenceController extends
+        BasePreferenceController {
+
+    public LocationServicesBluetoothScanningPreferenceController(Context context, String key) {
+        super(context, key);
+    }
+
+    @Override
+    public CharSequence getSummary() {
+        final boolean bleScanOn = Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE, 0) == 1;
+        int resId =
+                bleScanOn ? R.string.scanning_status_text_on : R.string.scanning_status_text_off;
+        return mContext.getString(resId);
+    }
+
+    @AvailabilityStatus
+    public int getAvailabilityStatus() {
+        return mContext.getResources().getBoolean(R.bool.config_show_location_scanning)
+                ? AVAILABLE
+                : UNSUPPORTED_ON_DEVICE;
+    }
+}
diff --git a/src/com/android/settings/location/LocationServicesWifiScanningPreferenceController.java b/src/com/android/settings/location/LocationServicesWifiScanningPreferenceController.java
new file mode 100644
index 0000000..080a023
--- /dev/null
+++ b/src/com/android/settings/location/LocationServicesWifiScanningPreferenceController.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2021 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.location;
+
+import android.content.Context;
+import android.net.wifi.WifiManager;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+
+/**
+ * Preference controller for Wi-Fi scanning in Location Services.
+ */
+public class LocationServicesWifiScanningPreferenceController extends BasePreferenceController {
+
+    private final WifiManager mWifiManager;
+
+    public LocationServicesWifiScanningPreferenceController(Context context, String key) {
+        super(context, key);
+        mWifiManager = context.getSystemService(WifiManager.class);
+    }
+
+    @Override
+    public CharSequence getSummary() {
+        final boolean wifiScanOn = mWifiManager.isScanAlwaysAvailable();
+        int resId =
+                wifiScanOn ? R.string.scanning_status_text_on : R.string.scanning_status_text_off;
+        return mContext.getString(resId);
+    }
+
+    @AvailabilityStatus
+    public int getAvailabilityStatus() {
+        return mContext.getResources().getBoolean(R.bool.config_show_location_scanning)
+                ? AVAILABLE
+                : UNSUPPORTED_ON_DEVICE;
+    }
+}
diff --git a/src/com/android/settings/location/WifiScanningFragment.java b/src/com/android/settings/location/WifiScanningFragment.java
new file mode 100644
index 0000000..f5cb0ae
--- /dev/null
+++ b/src/com/android/settings/location/WifiScanningFragment.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2021 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.location;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+
+import com.android.settings.R;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.search.SearchIndexable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A page that configures the Wi-Fi scanning setting.
+ */
+@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
+public class WifiScanningFragment extends DashboardFragment {
+    private static final String TAG = "WifiScanningFragment";
+
+    @Override
+    public int getMetricsCategory() {
+        return SettingsEnums.LOCATION_SERVICES;
+    }
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.location_services_wifi_scanning;
+    }
+
+    @Override
+    protected String getLogTag() {
+        return TAG;
+    }
+
+    @Override
+    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+        return buildPreferenceControllers(context);
+    }
+
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+    }
+
+    private static List<AbstractPreferenceController> buildPreferenceControllers(Context context) {
+        final List<AbstractPreferenceController> controllers = new ArrayList<>();
+        controllers.add(new WifiScanningPreferenceController(context));
+        return controllers;
+    }
+
+    /**
+     * For Search.
+     */
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+            new BaseSearchIndexProvider(R.xml.location_services_wifi_scanning) {
+
+                @Override
+                public List<AbstractPreferenceController> createPreferenceControllers(Context
+                        context) {
+                    return buildPreferenceControllers(context);
+                }
+            };
+}
diff --git a/src/com/android/settings/location/WifiScanningMainSwitchPreferenceController.java b/src/com/android/settings/location/WifiScanningMainSwitchPreferenceController.java
new file mode 100644
index 0000000..a69fdb8
--- /dev/null
+++ b/src/com/android/settings/location/WifiScanningMainSwitchPreferenceController.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2021 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.location;
+
+import android.content.Context;
+import android.net.wifi.WifiManager;
+import android.widget.Switch;
+
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.core.TogglePreferenceController;
+import com.android.settingslib.widget.MainSwitchPreference;
+import com.android.settingslib.widget.OnMainSwitchChangeListener;
+
+/**
+ * Preference controller for Wi-Fi scanning main switch.
+ */
+public class WifiScanningMainSwitchPreferenceController extends TogglePreferenceController
+        implements OnMainSwitchChangeListener {
+
+    private static final String KEY_WIFI_SCANNING_SWITCH = "wifi_always_scanning_switch";
+    private final WifiManager mWifiManager;
+
+    public WifiScanningMainSwitchPreferenceController(Context context) {
+        super(context, KEY_WIFI_SCANNING_SWITCH);
+        mWifiManager = context.getSystemService(WifiManager.class);
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+
+        MainSwitchPreference pref = screen.findPreference(getPreferenceKey());
+        pref.addOnSwitchChangeListener(this);
+        pref.updateStatus(isChecked());
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return mContext.getResources().getBoolean(R.bool.config_show_location_scanning)
+                ? AVAILABLE
+                : UNSUPPORTED_ON_DEVICE;
+    }
+
+    @Override
+    public boolean isChecked() {
+        return mWifiManager.isScanAlwaysAvailable();
+    }
+
+    @Override
+    public boolean setChecked(boolean isChecked) {
+        mWifiManager.setScanAlwaysAvailable(isChecked);
+        // Returning true means the underlying setting is updated.
+        return true;
+    }
+
+    @Override
+    public void onSwitchChanged(Switch switchView, boolean isChecked) {
+        if (isChecked != isChecked()) {
+            setChecked(isChecked);
+        }
+    }
+}
diff --git a/src/com/android/settings/network/AllowedNetworkTypesListener.java b/src/com/android/settings/network/AllowedNetworkTypesListener.java
index a9ed8be..ecc1d9c 100644
--- a/src/com/android/settings/network/AllowedNetworkTypesListener.java
+++ b/src/com/android/settings/network/AllowedNetworkTypesListener.java
@@ -24,7 +24,6 @@
 
 import androidx.annotation.VisibleForTesting;
 
-import java.util.Map;
 import java.util.concurrent.Executor;
 
 
@@ -72,9 +71,10 @@
     }
 
     @Override
-    public void onAllowedNetworkTypesChanged(Map<Integer, Long> allowedNetworkTypesList) {
-        long newAllowedNetworkType = allowedNetworkTypesList.get(
-                TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER);
+    public void onAllowedNetworkTypesChanged(int reason, long newAllowedNetworkType) {
+        if (reason != TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER) {
+            return;
+        }
         if (mListener != null && mAllowedNetworkType != newAllowedNetworkType) {
             mListener.onAllowedNetworkTypesChanged();
             Log.d(LOG_TAG, "onAllowedNetworkChanged: " + mAllowedNetworkType);
diff --git a/src/com/android/settings/network/PrivateDnsModeDialogPreference.java b/src/com/android/settings/network/PrivateDnsModeDialogPreference.java
index 4878f31..ea29a1d 100644
--- a/src/com/android/settings/network/PrivateDnsModeDialogPreference.java
+++ b/src/com/android/settings/network/PrivateDnsModeDialogPreference.java
@@ -15,7 +15,6 @@
  */
 package com.android.settings.network;
 
-import static android.net.ConnectivityManager.PRIVATE_DNS_DEFAULT_MODE_FALLBACK;
 import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF;
 import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
 import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
@@ -28,6 +27,7 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
+import android.net.ConnectivityManager;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
@@ -84,14 +84,6 @@
     @VisibleForTesting
     static final String HOSTNAME_KEY = Settings.Global.PRIVATE_DNS_SPECIFIER;
 
-    public static String getModeFromSettings(ContentResolver cr) {
-        String mode = Settings.Global.getString(cr, MODE_KEY);
-        if (!PRIVATE_DNS_MAP.containsKey(mode)) {
-            mode = Settings.Global.getString(cr, Settings.Global.PRIVATE_DNS_DEFAULT_MODE);
-        }
-        return PRIVATE_DNS_MAP.containsKey(mode) ? mode : PRIVATE_DNS_DEFAULT_MODE_FALLBACK;
-    }
-
     public static String getHostnameFromSettings(ContentResolver cr) {
         return Settings.Global.getString(cr, HOSTNAME_KEY);
     }
@@ -168,7 +160,7 @@
         final Context context = getContext();
         final ContentResolver contentResolver = context.getContentResolver();
 
-        mMode = getModeFromSettings(context.getContentResolver());
+        mMode = ConnectivityManager.getPrivateDnsMode(contentResolver);
 
         mEditText = view.findViewById(R.id.private_dns_mode_provider_hostname);
         mEditText.addTextChangedListener(this);
diff --git a/src/com/android/settings/network/PrivateDnsPreferenceController.java b/src/com/android/settings/network/PrivateDnsPreferenceController.java
index 84cae88..3136040 100644
--- a/src/com/android/settings/network/PrivateDnsPreferenceController.java
+++ b/src/com/android/settings/network/PrivateDnsPreferenceController.java
@@ -118,7 +118,7 @@
     public CharSequence getSummary() {
         final Resources res = mContext.getResources();
         final ContentResolver cr = mContext.getContentResolver();
-        final String mode = PrivateDnsModeDialogPreference.getModeFromSettings(cr);
+        final String mode = ConnectivityManager.getPrivateDnsMode(cr);
         final LinkProperties lp = mLatestLinkProperties;
         final List<InetAddress> dnses = (lp == null) ? null : lp.getValidatedPrivateDnsServers();
         final boolean dnsesResolved = !ArrayUtils.isEmpty(dnses);
diff --git a/src/com/android/settings/network/telephony/NetworkProviderWifiCallingGroup.java b/src/com/android/settings/network/telephony/NetworkProviderWifiCallingGroup.java
index 44fd029..c16dbc9 100644
--- a/src/com/android/settings/network/telephony/NetworkProviderWifiCallingGroup.java
+++ b/src/com/android/settings/network/telephony/NetworkProviderWifiCallingGroup.java
@@ -217,7 +217,12 @@
             pref.setEnabled(getTelephonyManagerForSubscriptionId(subId).getCallState()
                     == TelephonyManager.CALL_STATE_IDLE);
             pref.setOrder(order++);
-            pref.setSummary(R.string.calls_sms_wfc_summary);
+
+            int resId = com.android.internal.R.string.wifi_calling_off_summary;
+            if (queryImsState(subId).isEnabledByUser()) {
+                resId = R.string.calls_sms_wfc_summary;
+            }
+            pref.setSummary(resId);
 
             mWifiCallingForSubPreferences.put(subId, pref);
         }
diff --git a/src/com/android/settings/notification/ConfigureNotificationSettings.java b/src/com/android/settings/notification/ConfigureNotificationSettings.java
index 0f3695a..dcba273 100644
--- a/src/com/android/settings/notification/ConfigureNotificationSettings.java
+++ b/src/com/android/settings/notification/ConfigureNotificationSettings.java
@@ -127,20 +127,23 @@
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
-        final PreferenceScreen screen = getPreferenceScreen();
-        final Bundle arguments = getArguments();
+        // TODO(b/182237530): This method should be removed when this flag is deprecated.
+        if (!FeatureFlagUtils.isEnabled(getContext(), FeatureFlags.SILKY_HOME)) {
+            final PreferenceScreen screen = getPreferenceScreen();
+            final Bundle arguments = getArguments();
 
-        if (screen == null) {
-            return;
-        }
-        if (arguments != null) {
-            final String highlightKey = arguments.getString(EXTRA_FRAGMENT_ARG_KEY);
-            if (!TextUtils.isEmpty(highlightKey)) {
-                final PreferenceCategory advancedCategory =
-                        screen.findPreference(KEY_ADVANCED_CATEGORY);
-                // Has highlight row - expand everything
-                advancedCategory.setInitialExpandedChildrenCount(Integer.MAX_VALUE);
-                scrollToPreference(advancedCategory);
+            if (screen == null) {
+                return;
+            }
+            if (arguments != null) {
+                final String highlightKey = arguments.getString(EXTRA_FRAGMENT_ARG_KEY);
+                if (!TextUtils.isEmpty(highlightKey)) {
+                    final PreferenceCategory advancedCategory =
+                            screen.findPreference(KEY_ADVANCED_CATEGORY);
+                    // Has highlight row - expand everything
+                    advancedCategory.setInitialExpandedChildrenCount(Integer.MAX_VALUE);
+                    scrollToPreference(advancedCategory);
+                }
             }
         }
     }
diff --git a/src/com/android/settings/notification/app/ChannelNotificationSettings.java b/src/com/android/settings/notification/app/ChannelNotificationSettings.java
index bdea30d..296863c 100644
--- a/src/com/android/settings/notification/app/ChannelNotificationSettings.java
+++ b/src/com/android/settings/notification/app/ChannelNotificationSettings.java
@@ -68,12 +68,16 @@
 
         if (mChannel != null && !TextUtils.isEmpty(mChannel.getConversationId())
             && !mChannel.isDemoted()) {
-            startActivity(new SubSettingLauncher(mContext)
+            Intent intent = new SubSettingLauncher(mContext)
                     .setDestination(ConversationNotificationSettings.class.getName())
                     .setArguments(getArguments())
                     .setExtras(getIntent() != null ? getIntent().getExtras(): null)
                     .setSourceMetricsCategory(SettingsEnums.NOTIFICATION_TOPIC_NOTIFICATION)
-                    .toIntent());
+                    .toIntent();
+            if (mPreferenceFilter != null) {
+                intent.setClass(mContext, ChannelPanelActivity.class);
+            }
+            startActivity(intent);
             finish();
             return;
         }
@@ -84,6 +88,7 @@
             controller.displayPreference(getPreferenceScreen());
         }
         updatePreferenceStates();
+        animatePanel();
     }
 
     @Override
diff --git a/src/com/android/settings/notification/app/ChannelPanelActivity.java b/src/com/android/settings/notification/app/ChannelPanelActivity.java
new file mode 100644
index 0000000..3ba118e
--- /dev/null
+++ b/src/com/android/settings/notification/app/ChannelPanelActivity.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2021 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.notification.app;
+
+import android.app.settings.SettingsEnums;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.Window;
+import android.view.WindowManager;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.FragmentActivity;
+import androidx.fragment.app.FragmentManager;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.settings.R;
+import com.android.settings.core.HideNonSystemOverlayMixin;
+import com.android.settings.core.SubSettingLauncher;
+
+/**
+ * Dialog Activity to host channel settings
+ */
+public class ChannelPanelActivity extends FragmentActivity {
+
+    private static final String TAG = "ChannelPanelActivity";
+
+    final Bundle mBundle = new Bundle();
+    NotificationSettings mPanelFragment;
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        if (!getIntent().hasExtra(Settings.EXTRA_CHANNEL_FILTER_LIST)) {
+            launchFullSettings();
+        }
+
+        getApplicationContext().getTheme().rebase();
+        createOrUpdatePanel();
+        getLifecycle().addObserver(new HideNonSystemOverlayMixin(this));
+    }
+
+    @Override
+    protected void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
+        setIntent(intent);
+        createOrUpdatePanel();
+    }
+
+    @Override
+    public void onConfigurationChanged(@NonNull Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+    }
+
+    private void launchFullSettings() {
+        Bundle extras = getIntent().getExtras();
+        extras.remove(Settings.EXTRA_CHANNEL_FILTER_LIST);
+        startActivity(new SubSettingLauncher(this)
+                .setDestination(ChannelNotificationSettings.class.getName())
+                .setExtras(extras)
+                .setSourceMetricsCategory(SettingsEnums.NOTIFICATION_TOPIC_NOTIFICATION)
+                .toIntent());
+        finish();
+    }
+
+    private void createOrUpdatePanel() {
+        final Intent callingIntent = getIntent();
+        if (callingIntent == null) {
+            Log.e(TAG, "Null intent, closing Panel Activity");
+            finish();
+            return;
+        }
+
+        final FragmentManager fragmentManager = getSupportFragmentManager();
+        setContentView(R.layout.notification_channel_panel);
+
+        // Move the window to the bottom of screen, and make it take up the entire screen width.
+        final Window window = getWindow();
+        window.setGravity(Gravity.BOTTOM);
+        window.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
+                WindowManager.LayoutParams.WRAP_CONTENT);
+
+        findViewById(R.id.done).setOnClickListener(v -> finish());
+        findViewById(R.id.see_more).setOnClickListener(v -> launchFullSettings());
+
+        mPanelFragment = callingIntent.hasExtra(Settings.EXTRA_CONVERSATION_ID)
+                ? new ConversationNotificationSettings()
+                : new ChannelNotificationSettings();
+        mPanelFragment.setArguments(new Bundle(mBundle));
+        fragmentManager.beginTransaction().replace(
+                android.R.id.list_container, mPanelFragment).commit();
+    }
+}
diff --git a/src/com/android/settings/notification/app/ConversationHeaderPreferenceController.java b/src/com/android/settings/notification/app/ConversationHeaderPreferenceController.java
index 313b387..73659b8 100644
--- a/src/com/android/settings/notification/app/ConversationHeaderPreferenceController.java
+++ b/src/com/android/settings/notification/app/ConversationHeaderPreferenceController.java
@@ -93,6 +93,7 @@
                     .done(activity, mContext);
 
             pref.findViewById(R.id.entity_header).setVisibility(View.VISIBLE);
+            pref.findViewById(R.id.entity_header).setBackground(null);
         }
     }
 
diff --git a/src/com/android/settings/notification/app/ConversationNotificationSettings.java b/src/com/android/settings/notification/app/ConversationNotificationSettings.java
index 819ba83..d712c84 100644
--- a/src/com/android/settings/notification/app/ConversationNotificationSettings.java
+++ b/src/com/android/settings/notification/app/ConversationNotificationSettings.java
@@ -49,10 +49,11 @@
 
         for (NotificationPreferenceController controller : mControllers) {
             controller.onResume(mAppRow, mChannel, mChannelGroup, mConversationDrawable,
-                    mConversationInfo, mSuspendedAppsAdmin, null);
+                    mConversationInfo, mSuspendedAppsAdmin, mPreferenceFilter);
             controller.displayPreference(getPreferenceScreen());
         }
         updatePreferenceStates();
+        animatePanel();
     }
 
     @Override
diff --git a/src/com/android/settings/notification/app/HeaderPreferenceController.java b/src/com/android/settings/notification/app/HeaderPreferenceController.java
index 6482943..4e9c039 100644
--- a/src/com/android/settings/notification/app/HeaderPreferenceController.java
+++ b/src/com/android/settings/notification/app/HeaderPreferenceController.java
@@ -92,6 +92,7 @@
                     .setRecyclerView(mFragment.getListView(), mFragment.getSettingsLifecycle())
                     .done(activity, mContext);
             pref.findViewById(R.id.entity_header).setVisibility(View.VISIBLE);
+            pref.findViewById(R.id.entity_header).setBackground(null);
         }
     }
 
diff --git a/src/com/android/settings/notification/app/NotificationSettings.java b/src/com/android/settings/notification/app/NotificationSettings.java
index 44c735a..99f067d 100644
--- a/src/com/android/settings/notification/app/NotificationSettings.java
+++ b/src/com/android/settings/notification/app/NotificationSettings.java
@@ -18,6 +18,9 @@
 
 import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
 
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.NotificationChannelGroup;
@@ -39,8 +42,13 @@
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.view.animation.DecelerateInterpolator;
 import android.widget.Toast;
 
+import androidx.annotation.NonNull;
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
@@ -85,6 +93,20 @@
     protected Intent mIntent;
     protected Bundle mArgs;
 
+    private ViewGroup mLayoutView;
+    private static final int DURATION_ANIMATE_PANEL_EXPAND_MS = 250;
+
+    private final ViewTreeObserver.OnGlobalLayoutListener mOnGlobalLayoutListener =
+            new ViewTreeObserver.OnGlobalLayoutListener() {
+                @Override
+                public void onGlobalLayout() {
+                    animateIn();
+                    if (mLayoutView != null) {
+                        mLayoutView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+                    }
+                }
+            };
+
     @Override
     public void onAttach(Context context) {
         super.onAttach(context);
@@ -187,6 +209,50 @@
         collectConfigActivities();
     }
 
+    protected void animatePanel() {
+        if (mPreferenceFilter != null) {
+            mLayoutView = getActivity().findViewById(R.id.main_content);
+            mLayoutView.getViewTreeObserver().addOnGlobalLayoutListener(mOnGlobalLayoutListener);
+        }
+    }
+
+    /**
+     * Animate a Panel onto the screen.
+     * <p>
+     * Takes the entire panel and animates in from behind the navigation bar.
+     * <p>
+     * Relies on the Panel being having a fixed height to begin the animation.
+     */
+    private void animateIn() {
+        final AnimatorSet animatorSet = buildAnimatorSet(mLayoutView,
+                mLayoutView.getHeight() /* startY */, 0.0f /* endY */,
+                0.0f /* startAlpha */, 1.0f /* endAlpha */,
+                DURATION_ANIMATE_PANEL_EXPAND_MS);
+        final ValueAnimator animator = new ValueAnimator();
+        animator.setFloatValues(0.0f, 1.0f);
+        animatorSet.play(animator);
+        animatorSet.start();
+    }
+
+    /**
+     * Build an {@link AnimatorSet} to animate the Panel, {@param parentView} in or out of the
+     * screen, based on the positional parameters {@param startY}, {@param endY}, the parameters
+     * for alpha changes {@param startAlpha}, {@param endAlpha}, and the {@param duration} in
+     * milliseconds.
+     */
+    @NonNull
+    private static AnimatorSet buildAnimatorSet(@NonNull View targetView,
+            float startY, float endY,
+            float startAlpha, float endAlpha, int duration) {
+        final AnimatorSet animatorSet = new AnimatorSet();
+        animatorSet.setDuration(duration);
+        animatorSet.setInterpolator(new DecelerateInterpolator());
+        animatorSet.playTogether(
+                ObjectAnimator.ofFloat(targetView, View.TRANSLATION_Y, startY, endY),
+                ObjectAnimator.ofFloat(targetView, View.ALPHA, startAlpha, endAlpha));
+        return animatorSet;
+    }
+
     private void loadPreferencesFilter() {
         Intent intent = getActivity().getIntent();
         mPreferenceFilter = intent != null
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothPermissionActivityTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothPermissionActivityTest.java
new file mode 100644
index 0000000..4dd568b
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothPermissionActivityTest.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2021 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.bluetooth;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.content.Intent;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(RobolectricTestRunner.class)
+public class BluetoothPermissionActivityTest {
+
+    private BluetoothPermissionActivity mActivity;
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(RuntimeEnvironment.application);
+        mActivity = new BluetoothPermissionActivity();
+    }
+
+    @Test
+    public void callingPackageIsEqualToReturnPackage_sendBroadcastToReturnPackage() {
+        mActivity.mReturnPackage = "com.android.settings";
+        mActivity.mReturnClass = "com.android.settings.bluetooth.BluetoothPermissionActivity";
+        mActivity.mCallingAppPackageName = "com.android.settings";
+        final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        ReflectionHelpers.setField(mActivity, "mBase", mContext);
+
+        mActivity.sendReplyIntentToReceiver(true, true);
+
+        verify(mContext).sendBroadcast(intentCaptor.capture(),
+                eq("android.permission.BLUETOOTH_ADMIN"));
+        assertThat(intentCaptor.getValue().getComponent().getPackageName())
+                .isEqualTo("com.android.settings");
+    }
+
+    @Test
+    public void callingPackageIsNotEqualToReturnPackage_broadcastNotSend() {
+        mActivity.mReturnPackage = "com.fake.settings";
+        mActivity.mReturnClass = "com.android.settings.bluetooth.BluetoothPermissionActivity";
+        mActivity.mCallingAppPackageName = "com.android.settings";
+        final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        ReflectionHelpers.setField(mActivity, "mBase", mContext);
+
+        mActivity.sendReplyIntentToReceiver(true, true);
+
+        verify(mContext, never()).sendBroadcast(intentCaptor.capture(),
+                eq("android.permission.BLUETOOTH_ADMIN"));
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/bluetooth/DevicePickerFragmentTest.java b/tests/robotests/src/com/android/settings/bluetooth/DevicePickerFragmentTest.java
index feaf683..f5635a9 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/DevicePickerFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/DevicePickerFragmentTest.java
@@ -16,28 +16,46 @@
 
 package com.android.settings.bluetooth;
 
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.bluetooth.BluetoothDevice;
+import android.content.Context;
+import android.content.Intent;
+
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
 
 @RunWith(RobolectricTestRunner.class)
 public class DevicePickerFragmentTest {
 
     @Mock
     private BluetoothProgressCategory mAvailableDevicesCategory;
+
     private DevicePickerFragment mFragment;
+    private Context mContext;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
 
         mFragment = new DevicePickerFragment();
-
+        mContext = spy(RuntimeEnvironment.application);
+        mFragment.mContext = mContext;
         mFragment.mAvailableDevicesCategory = mAvailableDevicesCategory;
     }
 
@@ -49,4 +67,40 @@
 
         verify(mAvailableDevicesCategory).setProgress(true);
     }
+
+    @Test
+    public void callingPackageIsEqualToLaunchPackage_sendBroadcastToLaunchPackage() {
+        final CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class);
+        final BluetoothDevice bluetoothDevice = mock(BluetoothDevice.class);
+        final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        when(cachedDevice.getDevice()).thenReturn(bluetoothDevice);
+        mFragment.mSelectedDevice = bluetoothDevice;
+        mFragment.mLaunchPackage = "com.android.settings";
+        mFragment.mLaunchClass = "com.android.settings.bluetooth.BluetoothPermissionActivity";
+        mFragment.mCallingAppPackageName = "com.android.settings";
+
+        mFragment.onDeviceBondStateChanged(cachedDevice, BluetoothDevice.BOND_BONDED);
+
+        verify(mContext).sendBroadcast(intentCaptor.capture(),
+                eq("android.permission.BLUETOOTH_ADMIN"));
+        assertThat(intentCaptor.getValue().getComponent().getPackageName())
+                .isEqualTo(mFragment.mLaunchPackage);
+    }
+
+    @Test
+    public void callingPackageIsNotEqualToLaunchPackage_broadcastNotSend() {
+        final CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class);
+        final BluetoothDevice bluetoothDevice = mock(BluetoothDevice.class);
+        final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        when(cachedDevice.getDevice()).thenReturn(bluetoothDevice);
+        mFragment.mSelectedDevice = bluetoothDevice;
+        mFragment.mLaunchPackage = "com.fake.settings";
+        mFragment.mLaunchClass = "com.android.settings.bluetooth.BluetoothPermissionActivity";
+        mFragment.mCallingAppPackageName = "com.android.settings";
+
+        mFragment.onDeviceBondStateChanged(cachedDevice, BluetoothDevice.BOND_BONDED);
+
+        verify(mContext, never()).sendBroadcast(intentCaptor.capture(),
+                eq("android.permission.BLUETOOTH_ADMIN"));
+    }
 }
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();
diff --git a/tests/unit/src/com/android/settings/network/AllowedNetworkTypesListenerTest.java b/tests/unit/src/com/android/settings/network/AllowedNetworkTypesListenerTest.java
index d8f3c78..e89a257 100644
--- a/tests/unit/src/com/android/settings/network/AllowedNetworkTypesListenerTest.java
+++ b/tests/unit/src/com/android/settings/network/AllowedNetworkTypesListenerTest.java
@@ -40,9 +40,6 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-import java.util.HashMap;
-import java.util.Map;
-
 @RunWith(AndroidJUnit4.class)
 public class AllowedNetworkTypesListenerTest {
 
@@ -73,12 +70,11 @@
     @Test
     public void onChange_shouldCallListener() {
         mAllowedNetworkTypesListener.mListener = mListener;
-        Map<Integer, Long> allowedNetworkTypesList = new HashMap<>();
         long networkType = (long) RadioAccessFamily.getRafFromNetworkType(
                 TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO);
-        allowedNetworkTypesList.put(TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER,
-                networkType);
-        mAllowedNetworkTypesListener.onAllowedNetworkTypesChanged(allowedNetworkTypesList);
+
+        mAllowedNetworkTypesListener.onAllowedNetworkTypesChanged(
+                TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER, networkType);
 
         verify(mListener).onAllowedNetworkTypesChanged();
     }