Merge "Use SettingsRobolectricTestRunner in settings app"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index d3acd13..c1e0c60 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -307,7 +307,7 @@
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
             <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
-                android:value="com.android.settings.wifi.SavedAccessPointsWifiSettings" />
+                android:value="com.android.settings.wifi.savedaccesspoints.SavedAccessPointsWifiSettings" />
             <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
                 android:value="true" />
         </activity>
@@ -574,6 +574,12 @@
                 android:value="true" />
         </activity>
 
+        <activity android:name=".localepicker.LocalePickerWithRegionActivity"
+                  android:excludeFromRecents="true"
+                  android:configChanges="orientation|keyboardHidden|screenSize"
+                  android:exported="false">
+        </activity>
+
         <activity
             android:name=".Settings$LanguageAndInputSettingsActivity"
             android:label="@string/language_settings"
diff --git a/res/drawable-hdpi/lock_anim_0.png b/res/drawable-hdpi/lock_anim_0.png
deleted file mode 100644
index 08732e4..0000000
--- a/res/drawable-hdpi/lock_anim_0.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/lock_anim_1.png b/res/drawable-hdpi/lock_anim_1.png
deleted file mode 100644
index 74a0628..0000000
--- a/res/drawable-hdpi/lock_anim_1.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/lock_anim_10.png b/res/drawable-hdpi/lock_anim_10.png
deleted file mode 100644
index adb981d..0000000
--- a/res/drawable-hdpi/lock_anim_10.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/lock_anim_11.png b/res/drawable-hdpi/lock_anim_11.png
deleted file mode 100644
index f8976a2..0000000
--- a/res/drawable-hdpi/lock_anim_11.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/lock_anim_12.png b/res/drawable-hdpi/lock_anim_12.png
deleted file mode 100644
index 3ccdc85..0000000
--- a/res/drawable-hdpi/lock_anim_12.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/lock_anim_13.png b/res/drawable-hdpi/lock_anim_13.png
deleted file mode 100644
index ccd38d5..0000000
--- a/res/drawable-hdpi/lock_anim_13.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/lock_anim_14.png b/res/drawable-hdpi/lock_anim_14.png
deleted file mode 100644
index 2f40d9e..0000000
--- a/res/drawable-hdpi/lock_anim_14.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/lock_anim_2.png b/res/drawable-hdpi/lock_anim_2.png
deleted file mode 100644
index 495b2da..0000000
--- a/res/drawable-hdpi/lock_anim_2.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/lock_anim_3.png b/res/drawable-hdpi/lock_anim_3.png
deleted file mode 100644
index fa37813..0000000
--- a/res/drawable-hdpi/lock_anim_3.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/lock_anim_4.png b/res/drawable-hdpi/lock_anim_4.png
deleted file mode 100644
index 8201fd9..0000000
--- a/res/drawable-hdpi/lock_anim_4.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/lock_anim_5.png b/res/drawable-hdpi/lock_anim_5.png
deleted file mode 100644
index b08932d..0000000
--- a/res/drawable-hdpi/lock_anim_5.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/lock_anim_6.png b/res/drawable-hdpi/lock_anim_6.png
deleted file mode 100644
index dac09e1..0000000
--- a/res/drawable-hdpi/lock_anim_6.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/lock_anim_7.png b/res/drawable-hdpi/lock_anim_7.png
deleted file mode 100644
index f06c9d6..0000000
--- a/res/drawable-hdpi/lock_anim_7.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/lock_anim_8.png b/res/drawable-hdpi/lock_anim_8.png
deleted file mode 100644
index 07f7e34..0000000
--- a/res/drawable-hdpi/lock_anim_8.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/lock_anim_9.png b/res/drawable-hdpi/lock_anim_9.png
deleted file mode 100644
index 551bafa..0000000
--- a/res/drawable-hdpi/lock_anim_9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/lock_anim_0.png b/res/drawable-mdpi/lock_anim_0.png
deleted file mode 100644
index afdda8b..0000000
--- a/res/drawable-mdpi/lock_anim_0.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/lock_anim_1.png b/res/drawable-mdpi/lock_anim_1.png
deleted file mode 100644
index 6cae8e5..0000000
--- a/res/drawable-mdpi/lock_anim_1.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/lock_anim_10.png b/res/drawable-mdpi/lock_anim_10.png
deleted file mode 100644
index 5de840e..0000000
--- a/res/drawable-mdpi/lock_anim_10.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/lock_anim_11.png b/res/drawable-mdpi/lock_anim_11.png
deleted file mode 100644
index 35db815..0000000
--- a/res/drawable-mdpi/lock_anim_11.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/lock_anim_12.png b/res/drawable-mdpi/lock_anim_12.png
deleted file mode 100644
index 8778d98..0000000
--- a/res/drawable-mdpi/lock_anim_12.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/lock_anim_13.png b/res/drawable-mdpi/lock_anim_13.png
deleted file mode 100644
index d0b8cf0..0000000
--- a/res/drawable-mdpi/lock_anim_13.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/lock_anim_14.png b/res/drawable-mdpi/lock_anim_14.png
deleted file mode 100644
index ea1aa31..0000000
--- a/res/drawable-mdpi/lock_anim_14.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/lock_anim_2.png b/res/drawable-mdpi/lock_anim_2.png
deleted file mode 100644
index 0542b1d..0000000
--- a/res/drawable-mdpi/lock_anim_2.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/lock_anim_3.png b/res/drawable-mdpi/lock_anim_3.png
deleted file mode 100644
index 7e2ba9a..0000000
--- a/res/drawable-mdpi/lock_anim_3.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/lock_anim_4.png b/res/drawable-mdpi/lock_anim_4.png
deleted file mode 100644
index a3ca629..0000000
--- a/res/drawable-mdpi/lock_anim_4.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/lock_anim_5.png b/res/drawable-mdpi/lock_anim_5.png
deleted file mode 100644
index 17e3839..0000000
--- a/res/drawable-mdpi/lock_anim_5.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/lock_anim_6.png b/res/drawable-mdpi/lock_anim_6.png
deleted file mode 100644
index 90205a6..0000000
--- a/res/drawable-mdpi/lock_anim_6.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/lock_anim_7.png b/res/drawable-mdpi/lock_anim_7.png
deleted file mode 100644
index 1d94a47..0000000
--- a/res/drawable-mdpi/lock_anim_7.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/lock_anim_8.png b/res/drawable-mdpi/lock_anim_8.png
deleted file mode 100644
index af7cd28..0000000
--- a/res/drawable-mdpi/lock_anim_8.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/lock_anim_9.png b/res/drawable-mdpi/lock_anim_9.png
deleted file mode 100644
index d401624..0000000
--- a/res/drawable-mdpi/lock_anim_9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/lock_anim_0.png b/res/drawable-xhdpi/lock_anim_0.png
deleted file mode 100644
index 5e8e6dc..0000000
--- a/res/drawable-xhdpi/lock_anim_0.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/lock_anim_1.png b/res/drawable-xhdpi/lock_anim_1.png
deleted file mode 100644
index 96fbd03..0000000
--- a/res/drawable-xhdpi/lock_anim_1.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/lock_anim_10.png b/res/drawable-xhdpi/lock_anim_10.png
deleted file mode 100644
index e2e83b1..0000000
--- a/res/drawable-xhdpi/lock_anim_10.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/lock_anim_11.png b/res/drawable-xhdpi/lock_anim_11.png
deleted file mode 100644
index 68de396..0000000
--- a/res/drawable-xhdpi/lock_anim_11.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/lock_anim_12.png b/res/drawable-xhdpi/lock_anim_12.png
deleted file mode 100644
index 11e51c7..0000000
--- a/res/drawable-xhdpi/lock_anim_12.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/lock_anim_13.png b/res/drawable-xhdpi/lock_anim_13.png
deleted file mode 100644
index 86a6115..0000000
--- a/res/drawable-xhdpi/lock_anim_13.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/lock_anim_14.png b/res/drawable-xhdpi/lock_anim_14.png
deleted file mode 100644
index 5bff2fa..0000000
--- a/res/drawable-xhdpi/lock_anim_14.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/lock_anim_2.png b/res/drawable-xhdpi/lock_anim_2.png
deleted file mode 100644
index 68e59c8..0000000
--- a/res/drawable-xhdpi/lock_anim_2.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/lock_anim_3.png b/res/drawable-xhdpi/lock_anim_3.png
deleted file mode 100644
index 16272ed..0000000
--- a/res/drawable-xhdpi/lock_anim_3.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/lock_anim_4.png b/res/drawable-xhdpi/lock_anim_4.png
deleted file mode 100644
index af6fbc4..0000000
--- a/res/drawable-xhdpi/lock_anim_4.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/lock_anim_5.png b/res/drawable-xhdpi/lock_anim_5.png
deleted file mode 100644
index 1e631b5..0000000
--- a/res/drawable-xhdpi/lock_anim_5.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/lock_anim_6.png b/res/drawable-xhdpi/lock_anim_6.png
deleted file mode 100644
index 93fcf39..0000000
--- a/res/drawable-xhdpi/lock_anim_6.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/lock_anim_7.png b/res/drawable-xhdpi/lock_anim_7.png
deleted file mode 100644
index b5c5277..0000000
--- a/res/drawable-xhdpi/lock_anim_7.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/lock_anim_8.png b/res/drawable-xhdpi/lock_anim_8.png
deleted file mode 100644
index bcaec0d..0000000
--- a/res/drawable-xhdpi/lock_anim_8.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/lock_anim_9.png b/res/drawable-xhdpi/lock_anim_9.png
deleted file mode 100644
index c481d1a..0000000
--- a/res/drawable-xhdpi/lock_anim_9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable/ic_menu_add_inset.xml b/res/drawable/ic_menu_add_inset.xml
deleted file mode 100644
index a4f0a65..0000000
--- a/res/drawable/ic_menu_add_inset.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<!--
-    Copyright (C) 2016 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.
--->
-<inset
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:insetLeft="5dp">
-    <vector
-        android:width="24.0dp"
-        android:height="24.0dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"
-        android:tint="?android:attr/colorAccent">
-        <path
-            android:fillColor="#FF000000"
-            android:pathData="M19.0,13.0l-6.0,0.0l0.0,6.0l-2.0,0.0l0.0,-6.0L5.0,13.0l0.0,-2.0l6.0,0.0L11.0,5.0l2.0,0.0l0.0,6.0l6.0,0.0l0.0,2.0z"/>
-    </vector>
-</inset>
diff --git a/res/drawable/lock_anim.xml b/res/drawable/lock_anim.xml
deleted file mode 100644
index 8ec31a6..0000000
--- a/res/drawable/lock_anim.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* 
-** Copyright 2008, 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.
-*/
--->
-<animation-list
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        android:oneshot="false">
-    <item android:drawable="@drawable/lock_anim_0" android:duration="200" />
-    <item android:drawable="@drawable/lock_anim_1" android:duration="200" />
-    <item android:drawable="@drawable/lock_anim_2" android:duration="200" />
-    <item android:drawable="@drawable/lock_anim_3" android:duration="200" />
-    <item android:drawable="@drawable/lock_anim_4" android:duration="200" />
-    <item android:drawable="@drawable/lock_anim_5" android:duration="200" />
-    <item android:drawable="@drawable/lock_anim_6" android:duration="200" />
-    <item android:drawable="@drawable/lock_anim_7" android:duration="200" />
-    <item android:drawable="@drawable/lock_anim_8" android:duration="200" />
-    <item android:drawable="@drawable/lock_anim_9" android:duration="200" />
-    <item android:drawable="@drawable/lock_anim_10" android:duration="200" />
-    <item android:drawable="@drawable/lock_anim_11" android:duration="200" />
-    <item android:drawable="@drawable/lock_anim_12" android:duration="200" />
-    <item android:drawable="@drawable/lock_anim_13" android:duration="200" />
-    <item android:drawable="@drawable/lock_anim_14" android:duration="200" />
-</animation-list>
diff --git a/res/layout/preference_list_fragment.xml b/res/layout/preference_list_fragment.xml
index eeea9c4..852ef6d 100644
--- a/res/layout/preference_list_fragment.xml
+++ b/res/layout/preference_list_fragment.xml
@@ -37,19 +37,6 @@
         android:paddingStart="@dimen/settings_side_margin"
         android:paddingEnd="@dimen/settings_side_margin">
 
-        <ListView android:id="@+id/backup_list"
-            style="@style/PreferenceFragmentListSinglePane"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:paddingTop="@dimen/dashboard_padding_top"
-            android:paddingBottom="@dimen/dashboard_padding_bottom"
-            android:scrollbarStyle="@*android:integer/preference_fragment_scrollbarStyle"
-            android:clipToPadding="false"
-            android:drawSelectorOnTop="false"
-            android:elevation="@dimen/dashboard_category_elevation"
-            android:visibility="gone"
-            android:scrollbarAlwaysDrawVerticalTrack="true" />
-
         <include layout="@layout/loading_container" />
 
     </FrameLayout>
@@ -74,8 +61,7 @@
             android:layout_height="wrap_content"
             android:layout_margin="5dip"
             android:layout_alignParentStart="true"
-            android:text="@*android:string/back_button_label"
-            />
+            android:text="@*android:string/back_button_label" />
 
         <LinearLayout
             android:orientation="horizontal"
@@ -89,16 +75,14 @@
                 android:layout_height="wrap_content"
                 android:layout_margin="5dip"
                 android:text="@*android:string/skip_button_label"
-                android:visibility="gone"
-                />
+                android:visibility="gone" />
 
             <Button android:id="@+id/next_button"
                 style="?android:attr/buttonBarButtonStyle"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_margin="5dip"
-                android:text="@*android:string/next_button_label"
-                />
+                android:text="@*android:string/next_button_label" />
 
         </LinearLayout>
 
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 02d3182..2341728 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -97,9 +97,6 @@
     <dimen name="dashboard_category_padding_start">0dp</dimen>
     <dimen name="dashboard_category_padding_end">0dp</dimen>
 
-    <!-- Dashboard category panel elevation -->
-    <dimen name="dashboard_category_elevation">2dp</dimen>
-
     <!-- Dashboard tile minimum height -->
     <dimen name="dashboard_tile_minimum_height">72dp</dimen>
 
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 9d9c67b..41b3a80 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -588,9 +588,6 @@
     <!-- Title for the locale picker activity -->
     <string name="language_picker_title">Languages</string>
 
-    <!-- Title for the language selection screen [CHAR LIMIT=25] -->
-    <string name="pref_title_lang_selection">Language preferences</string>
-
     <!-- Menu item in the locale menu. Will remove the selected locales. [CHAR LIMIT=30] -->
     <string name="locale_remove_menu">Remove</string>
 
@@ -2115,8 +2112,6 @@
     <string name="wifi_forget_dialog_message">All passwords for this network will be deleted</string>
 
     <!-- Wi-Fi Advanced Settings --> <skip />
-    <!-- Wi-Fi settings screen, Saved networks, settings section.  This is a header shown above Saved networks wifi settings. [CHAR LIMIT=30] -->
-    <string name="wifi_saved_access_points_titlebar">Saved networks</string>
     <!-- Wi-Fi settings screen, Saved networks summary.  This shows below the "Saved networks" item and indicates the number of networks a user has saved. -->
     <plurals name="wifi_saved_access_points_summary">
         <item quantity="one">1 network</item>
@@ -4925,11 +4920,6 @@
 
     <!-- Title for the screen usage in power use UI [CHAR_LIMIT=60] -->
     <string name="device_screen_usage">Screen usage since full charge</string>
-    <!-- Title for the screen consumption in power use UI(i.e. Screen consumption: 30% of battery usage) [CHAR_LIMIT=40] -->
-    <string name="device_screen_consumption">Screen consumption</string>
-    <!-- Title for the cellular network in power use UI(i.e. Mobile network scanning: 30% of battery usage) [CHAR_LIMIT=40] -->
-    <string name="device_cellular_network">Mobile network scanning</string>
-
     <!-- Label for list of apps using battery in power use UI. Note: ^1 should be used in all translations[CHAR_LIMIT=120] -->
     <string name="power_usage_list_summary">Battery usage since full charge</string>
     <!-- Temp string used to debug new battery estimates [DO NOT TRANSLATE] -->
@@ -5953,8 +5943,8 @@
 
     <!-- Activity title for network data usage summary. [CHAR LIMIT=25] -->
     <string name="data_usage_summary_title">Data usage</string>
-    <!-- Activity title for Appk data usage summary. [CHAR LIMIT=25] -->
-    <string name="data_usage_app_summary_title">App data usage</string>
+    <!-- Activity title Mobile data & WI-FI summary. [CHAR LIMIT=25] -->
+    <string name="data_usage_app_summary_title">Mobile data &amp; Wi\u2011Fi</string>
     <!-- Message about carrier data accounting.  [CHAR LIMIT=100] -->
     <string name="data_usage_accounting">Carrier data accounting may differ from your device.</string>
     <!-- Title for app usage. [CHAR LIMIT=40] -->
@@ -6905,6 +6895,8 @@
     <string name="app_and_notification_dashboard_title">Apps &amp; notifications</string>
     <!-- Summary for Apps & Notification settings, explaining a few important settings under it [CHAR LIMIT=NONE]-->
     <string name="app_and_notification_dashboard_summary">Permissions, default apps</string>
+    <!-- Toast text for notification settings in the work profile. This is shown when an app in the work profile attempts to open notification settings. [CHAR LIMIT=NONE] -->
+    <string name="notification_settings_work_profile">Notification access is not available for apps in the work profile.</string>
     <!-- Title for setting tile leading to account settings [CHAR LIMIT=40]-->
     <string name="account_dashboard_title">Accounts</string>
     <!-- Summary for account settings tiles when there is no accounts on device [CHAR LIMIT=NONE]-->
diff --git a/res/values/themes.xml b/res/values/themes.xml
index 2674d2f..d54f111 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -46,7 +46,7 @@
         <item name="preferenceBackgroundColor">@drawable/preference_background</item>
 
         <!-- For all androidx version of AlertDialogs -->
-        <item name="alertDialogTheme">@style/Theme.AppCompat.Light.Dialog.Alert</item>
+        <item name="alertDialogTheme">@style/Theme.AlertDialog</item>
 
         <item name="*android:lockPatternStyle">@style/LockPatternStyle.Setup</item>
 
@@ -106,11 +106,15 @@
         <item name="android:windowSoftInputMode">adjustResize</item>
     </style>
 
-    <style name="Theme.AlertDialog" parent="@*android:style/Theme.DeviceDefault.Settings.Dialog.Alert">
+    <style name="Theme.AlertDialog" parent="@style/Theme.AppCompat.DayNight.Dialog.Alert">
         <item name="android:windowSoftInputMode">adjustResize</item>
 
         <!-- Redefine the ActionBar style for contentInsetStart -->
         <item name="android:actionBarStyle">@style/Theme.ActionBar</item>
+
+        <!-- copied from Theme.DeviceDefault.Light.Dialog.Alert -->
+        <item name="colorAccent">@*android:color/accent_device_default_light</item>
+        <item name="dialogCornerRadius">@*android:dimen/config_dialogCornerRadius</item>
     </style>
 
     <style name="Theme.ConfirmDeviceCredentials" parent="Theme.SubSettings">
diff --git a/res/xml/app_info_settings.xml b/res/xml/app_info_settings.xml
index 9d77e86..684d032 100644
--- a/res/xml/app_info_settings.xml
+++ b/res/xml/app_info_settings.xml
@@ -63,7 +63,7 @@
 
     <Preference
         android:key="data_settings"
-        android:title="@string/data_usage_summary_title"
+        android:title="@string/data_usage_app_summary_title"
         android:summary="@string/summary_placeholder"
         settings:controller="com.android.settings.applications.appinfo.AppDataUsagePreferenceController" />
 
diff --git a/res/xml/wifi_display_saved_access_points.xml b/res/xml/wifi_display_saved_access_points.xml
index 81fb701..98b4dec 100644
--- a/res/xml/wifi_display_saved_access_points.xml
+++ b/res/xml/wifi_display_saved_access_points.xml
@@ -14,7 +14,15 @@
      limitations under the License.
 -->
 
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
-    android:title="@string/wifi_saved_access_points_titlebar">
+<PreferenceScreen
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
+    android:key="saved_access_points"
+    android:title="@string/wifi_saved_access_points_label">
+
+    <PreferenceCategory
+        android:key="saved_access_points_category"
+        android:layout="@layout/preference_category_no_label"
+        settings:controller="com.android.settings.wifi.savedaccesspoints.SavedAccessPointsPreferenceController"/>
 
 </PreferenceScreen>
diff --git a/res/xml/wifi_settings.xml b/res/xml/wifi_settings.xml
index 52aadcf..4ca9284 100644
--- a/res/xml/wifi_settings.xml
+++ b/res/xml/wifi_settings.xml
@@ -39,6 +39,6 @@
         <Preference
                 android:key="saved_networks"
                 android:title="@string/wifi_saved_access_points_label"
-                android:fragment="com.android.settings.wifi.SavedAccessPointsWifiSettings" />
+                android:fragment="com.android.settings.wifi.savedaccesspoints.SavedAccessPointsWifiSettings" />
     </PreferenceCategory>
 </PreferenceScreen>
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index 55ec159..9d5f96f 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -389,9 +389,7 @@
      */
     public static UserHandle getManagedProfile(UserManager userManager) {
         List<UserHandle> userProfiles = userManager.getUserProfiles();
-        final int count = userProfiles.size();
-        for (int i = 0; i < count; i++) {
-            final UserHandle profile = userProfiles.get(i);
+        for (UserHandle profile : userProfiles) {
             if (profile.getIdentifier() == userManager.getUserHandle()) {
                 continue;
             }
diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java
index b910130..22cff3e 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettings.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettings.java
@@ -633,8 +633,14 @@
                     mCategoryToPrefCategoryMap.get(CATEGORY_DISPLAY);
             experimentalCategory.removePreference(mToggleInversionPreference);
             experimentalCategory.removePreference(mDisplayDaltonizerPreferenceScreen);
-            mToggleInversionPreference.setOrder(mToggleLargePointerIconPreference.getOrder());
-            mDisplayDaltonizerPreferenceScreen.setOrder(mToggleInversionPreference.getOrder());
+            mDisplayDaltonizerPreferenceScreen.setOrder(
+                    mDisplayMagnificationPreferenceScreen.getOrder() + 1);
+            mToggleInversionPreference.setOrder(
+                    mDisplayDaltonizerPreferenceScreen.getOrder() + 1);
+            mToggleLargePointerIconPreference.setOrder(
+                    mToggleInversionPreference.getOrder() + 1);
+            mToggleDisableAnimationsPreference.setOrder(
+                    mToggleLargePointerIconPreference.getOrder() + 1);
             mToggleInversionPreference.setSummary(R.string.summary_empty);
             displayCategory.addPreference(mToggleInversionPreference);
             displayCategory.addPreference(mDisplayDaltonizerPreferenceScreen);
diff --git a/src/com/android/settings/applications/defaultapps/DefaultAppPickerFragment.java b/src/com/android/settings/applications/defaultapps/DefaultAppPickerFragment.java
index d0493e9..3838d29 100644
--- a/src/com/android/settings/applications/defaultapps/DefaultAppPickerFragment.java
+++ b/src/com/android/settings/applications/defaultapps/DefaultAppPickerFragment.java
@@ -28,6 +28,7 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+import com.android.settings.fuelgauge.BatteryUtils;
 import com.android.settings.widget.RadioButtonPickerFragment;
 import com.android.settings.widget.RadioButtonPreference;
 import com.android.settingslib.applications.DefaultAppInfo;
@@ -43,11 +44,13 @@
 public abstract class DefaultAppPickerFragment extends RadioButtonPickerFragment {
 
     protected PackageManager mPm;
+    protected BatteryUtils mBatteryUtils;
 
     @Override
     public void onAttach(Context context) {
         super.onAttach(context);
         mPm = context.getPackageManager();
+        mBatteryUtils = BatteryUtils.getInstance(context);
     }
 
     @Override
diff --git a/src/com/android/settings/applications/defaultapps/DefaultPhonePicker.java b/src/com/android/settings/applications/defaultapps/DefaultPhonePicker.java
index e462ab8..0bda2ec 100644
--- a/src/com/android/settings/applications/defaultapps/DefaultPhonePicker.java
+++ b/src/com/android/settings/applications/defaultapps/DefaultPhonePicker.java
@@ -80,6 +80,7 @@
     @Override
     protected boolean setDefaultKey(String key) {
         if (!TextUtils.isEmpty(key) && !TextUtils.equals(key, getDefaultKey())) {
+            mBatteryUtils.clearForceAppStandby(key);
             return mDefaultKeyUpdater.setDefaultDialerApplication(getContext(), key, mUserId);
         }
         return false;
diff --git a/src/com/android/settings/applications/defaultapps/DefaultSmsPicker.java b/src/com/android/settings/applications/defaultapps/DefaultSmsPicker.java
index 91f9caf..b5a2880 100644
--- a/src/com/android/settings/applications/defaultapps/DefaultSmsPicker.java
+++ b/src/com/android/settings/applications/defaultapps/DefaultSmsPicker.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.applications.defaultapps;
 
+import android.app.AppOpsManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -25,6 +26,7 @@
 import com.android.internal.telephony.SmsApplication;
 import com.android.settings.R;
 import com.android.settings.Utils;
+import com.android.settings.fuelgauge.BatteryUtils;
 import com.android.settingslib.applications.DefaultAppInfo;
 import com.android.settingslib.widget.CandidateInfo;
 
@@ -74,6 +76,7 @@
     protected boolean setDefaultKey(String key) {
         if (!TextUtils.isEmpty(key) && !TextUtils.equals(key, getDefaultKey())) {
             mDefaultKeyUpdater.setDefaultApplication(getContext(), key);
+            mBatteryUtils.clearForceAppStandby(key);
             return true;
         }
         return false;
diff --git a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java
index 6e0f915..0475734 100644
--- a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java
+++ b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java
@@ -455,10 +455,7 @@
     void unrestrictAppIfPossible(BatteryUtils batteryUtils) {
         // Unrestrict admin app if it is already been restricted
         final String packageName = mDeviceAdmin.getComponent().getPackageName();
-        final int uid = batteryUtils.getPackageUid(packageName);
-        if (batteryUtils.isForceAppStandbyEnabled(uid, packageName)) {
-            batteryUtils.setForceAppStandby(uid, packageName, AppOpsManager.MODE_ALLOWED);
-        }
+        batteryUtils.clearForceAppStandby(packageName);
     }
 
     void continueRemoveAction(CharSequence msg) {
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index 1569ff0..219c92c 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -38,7 +38,6 @@
 import com.android.settings.applications.ProcessStatsSummary;
 import com.android.settings.applications.ProcessStatsUi;
 import com.android.settings.applications.UsageAccessDetails;
-import com.android.settings.applications.specialaccess.vrlistener.VrListenerSettings;
 import com.android.settings.applications.appinfo.AppInfoDashboardFragment;
 import com.android.settings.applications.appinfo.DrawOverlayDetails;
 import com.android.settings.applications.appinfo.ExternalSourcesDetails;
@@ -50,6 +49,7 @@
 import com.android.settings.applications.specialaccess.deviceadmin.DeviceAdminSettings;
 import com.android.settings.applications.specialaccess.pictureinpicture.PictureInPictureDetails;
 import com.android.settings.applications.specialaccess.pictureinpicture.PictureInPictureSettings;
+import com.android.settings.applications.specialaccess.vrlistener.VrListenerSettings;
 import com.android.settings.backup.PrivacySettings;
 import com.android.settings.backup.ToggleBackupSettingFragment;
 import com.android.settings.bluetooth.BluetoothDeviceDetailsFragment;
@@ -127,12 +127,12 @@
 import com.android.settings.webview.WebViewAppPicker;
 import com.android.settings.wfd.WifiDisplaySettings;
 import com.android.settings.wifi.ConfigureWifiSettings;
-import com.android.settings.wifi.SavedAccessPointsWifiSettings;
 import com.android.settings.wifi.WifiAPITest;
 import com.android.settings.wifi.WifiInfo;
 import com.android.settings.wifi.WifiSettings;
 import com.android.settings.wifi.calling.WifiCallingSettings;
 import com.android.settings.wifi.p2p.WifiP2pSettings;
+import com.android.settings.wifi.savedaccesspoints.SavedAccessPointsWifiSettings;
 import com.android.settings.wifi.tether.WifiTetherSettings;
 
 public class SettingsGateway {
diff --git a/src/com/android/settings/fuelgauge/BatteryUtils.java b/src/com/android/settings/fuelgauge/BatteryUtils.java
index f92f8ad..9e920c4 100644
--- a/src/com/android/settings/fuelgauge/BatteryUtils.java
+++ b/src/com/android/settings/fuelgauge/BatteryUtils.java
@@ -407,6 +407,16 @@
                 packageName) == AppOpsManager.MODE_IGNORED;
     }
 
+    public boolean clearForceAppStandby(String packageName) {
+        final int uid = getPackageUid(packageName);
+        if (uid != UID_NULL && isForceAppStandbyEnabled(uid, packageName)) {
+            setForceAppStandby(uid, packageName, AppOpsManager.MODE_ALLOWED);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
     public void initBatteryStatsHelper(BatteryStatsHelper statsHelper, Bundle bundle,
             UserManager userManager) {
         statsHelper.create(bundle);
diff --git a/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicy.java b/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicy.java
index 22c90e3..4bd8cd7 100644
--- a/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicy.java
+++ b/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicy.java
@@ -40,6 +40,7 @@
     private static final String KEY_HIGH_USAGE_PERIOD_MS = "high_usage_period_ms";
     private static final String KEY_HIGH_USAGE_BATTERY_DRAINING = "high_usage_battery_draining";
     private static final String KEY_APP_RESTRICTION_ENABLED = "app_restriction_enabled";
+    private static final String KEY_APP_RESTRICTION_ACTIVE_HOUR = "app_restriction_active_hour";
     private static final String KEY_REDUCED_BATTERY_ENABLED = "reduced_battery_enabled";
     private static final String KEY_REDUCED_BATTERY_PERCENT = "reduced_battery_percent";
     private static final String KEY_LOW_BATTERY_ENABLED = "low_battery_enabled";
@@ -119,6 +120,15 @@
     public final boolean appRestrictionEnabled;
 
     /**
+     * Period(hour) to show anomaly apps. If it is 24 hours, it means only show anomaly apps
+     * happened in last 24 hours.
+     *
+     * @see Settings.Global#BATTERY_TIP_CONSTANTS
+     * @see #KEY_APP_RESTRICTION_ACTIVE_HOUR
+     */
+    public final int appRestrictionActiveHour;
+
+    /**
      * {@code true} if reduced battery tip is enabled
      *
      * @see Settings.Global#BATTERY_TIP_CONSTANTS
@@ -228,6 +238,7 @@
                 Duration.ofHours(2).toMillis());
         highUsageBatteryDraining = mParser.getInt(KEY_HIGH_USAGE_BATTERY_DRAINING, 25);
         appRestrictionEnabled = mParser.getBoolean(KEY_APP_RESTRICTION_ENABLED, true);
+        appRestrictionActiveHour = mParser.getInt(KEY_APP_RESTRICTION_ACTIVE_HOUR, 24);
         reducedBatteryEnabled = mParser.getBoolean(KEY_REDUCED_BATTERY_ENABLED, false);
         reducedBatteryPercent = mParser.getInt(KEY_REDUCED_BATTERY_PERCENT, 50);
         lowBatteryEnabled = mParser.getBoolean(KEY_LOW_BATTERY_ENABLED, true);
diff --git a/src/com/android/settings/fuelgauge/batterytip/BatteryTipUtils.java b/src/com/android/settings/fuelgauge/batterytip/BatteryTipUtils.java
index dfb7f97..8debf6b 100644
--- a/src/com/android/settings/fuelgauge/batterytip/BatteryTipUtils.java
+++ b/src/com/android/settings/fuelgauge/batterytip/BatteryTipUtils.java
@@ -136,8 +136,8 @@
         final List<AppInfo> highUsageApps = BatteryDatabaseManager.getInstance(context)
                 .queryAllAnomalies(timeAfterMs, AnomalyDatabaseHelper.State.NEW);
         // Remove it if it doesn't have label or been restricted
-        highUsageApps.removeIf(
-                new AppLabelPredicate(context).or(new AppRestrictionPredicate(context)));
+        highUsageApps.removeIf(AppLabelPredicate.getInstance(context)
+                .or(AppRestrictionPredicate.getInstance(context)));
 
         return highUsageApps;
     }
diff --git a/src/com/android/settings/fuelgauge/batterytip/detectors/RestrictAppDetector.java b/src/com/android/settings/fuelgauge/batterytip/detectors/RestrictAppDetector.java
index bda0073..e6c0837 100644
--- a/src/com/android/settings/fuelgauge/batterytip/detectors/RestrictAppDetector.java
+++ b/src/com/android/settings/fuelgauge/batterytip/detectors/RestrictAppDetector.java
@@ -31,6 +31,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.TimeUnit;
 
 import androidx.annotation.VisibleForTesting;
 
@@ -53,8 +54,8 @@
         mContext = context;
         mPolicy = policy;
         mBatteryDatabaseManager = BatteryDatabaseManager.getInstance(context);
-        mAppRestrictionPredicate = new AppRestrictionPredicate(context);
-        mAppLabelPredicate = new AppLabelPredicate(context);
+        mAppRestrictionPredicate = AppRestrictionPredicate.getInstance(context);
+        mAppLabelPredicate = AppLabelPredicate.getInstance(context);
     }
 
     @Override
@@ -63,8 +64,8 @@
             return getFakeData();
         }
         if (mPolicy.appRestrictionEnabled) {
-            // TODO(b/80192137): hook up the query timestamp to server side
-            final long oneDayBeforeMs = System.currentTimeMillis() - DateUtils.DAY_IN_MILLIS;
+            final long oneDayBeforeMs = System.currentTimeMillis()
+                    - TimeUnit.HOURS.toMillis(mPolicy.appRestrictionActiveHour);
             final List<AppInfo> highUsageApps = BatteryTipUtils.detectAnomalies(mContext,
                     oneDayBeforeMs);
             if (!highUsageApps.isEmpty()) {
diff --git a/src/com/android/settings/fuelgauge/batterytip/tips/AppLabelPredicate.java b/src/com/android/settings/fuelgauge/batterytip/tips/AppLabelPredicate.java
index 13a2452..1444b12 100644
--- a/src/com/android/settings/fuelgauge/batterytip/tips/AppLabelPredicate.java
+++ b/src/com/android/settings/fuelgauge/batterytip/tips/AppLabelPredicate.java
@@ -16,7 +16,6 @@
 
 package com.android.settings.fuelgauge.batterytip.tips;
 
-import android.app.AppOpsManager;
 import android.content.Context;
 
 import com.android.settings.Utils;
@@ -28,12 +27,20 @@
  * {@link Predicate} for {@link AppInfo} to check whether it has label
  */
 public class AppLabelPredicate implements Predicate<AppInfo> {
-    private Context mContext;
-    private AppOpsManager mAppOpsManager;
 
-    public AppLabelPredicate(Context context) {
+    private static AppLabelPredicate sInstance;
+    private Context mContext;
+
+    public static AppLabelPredicate getInstance(Context context) {
+        if (sInstance == null) {
+            sInstance = new AppLabelPredicate(context.getApplicationContext());
+        }
+
+        return sInstance;
+    }
+
+    private AppLabelPredicate(Context context) {
         mContext = context;
-        mAppOpsManager = context.getSystemService(AppOpsManager.class);
     }
 
     @Override
diff --git a/src/com/android/settings/fuelgauge/batterytip/tips/AppRestrictionPredicate.java b/src/com/android/settings/fuelgauge/batterytip/tips/AppRestrictionPredicate.java
index 3650fe3..43a4d90 100644
--- a/src/com/android/settings/fuelgauge/batterytip/tips/AppRestrictionPredicate.java
+++ b/src/com/android/settings/fuelgauge/batterytip/tips/AppRestrictionPredicate.java
@@ -27,9 +27,19 @@
  * {@link Predicate} for {@link AppInfo} to check whether it is restricted.
  */
 public class AppRestrictionPredicate implements Predicate<AppInfo> {
+
+    private static AppRestrictionPredicate sInstance;
     private AppOpsManager mAppOpsManager;
 
-    public AppRestrictionPredicate(Context context) {
+    public static AppRestrictionPredicate getInstance(Context context) {
+        if (sInstance == null) {
+            sInstance = new AppRestrictionPredicate(context.getApplicationContext());
+        }
+
+        return sInstance;
+    }
+
+    private AppRestrictionPredicate(Context context) {
         mAppOpsManager = context.getSystemService(AppOpsManager.class);
     }
 
diff --git a/src/com/android/settings/fuelgauge/batterytip/tips/RestrictAppTip.java b/src/com/android/settings/fuelgauge/batterytip/tips/RestrictAppTip.java
index 8a2d86d..0d91c74 100644
--- a/src/com/android/settings/fuelgauge/batterytip/tips/RestrictAppTip.java
+++ b/src/com/android/settings/fuelgauge/batterytip/tips/RestrictAppTip.java
@@ -112,7 +112,7 @@
         super.sanityCheck(context);
 
         // Set it invisible if there is no valid app
-        mRestrictAppList.removeIf(new AppLabelPredicate(context));
+        mRestrictAppList.removeIf(AppLabelPredicate.getInstance(context));
         if (mRestrictAppList.isEmpty()) {
             mState = StateType.INVISIBLE;
         }
diff --git a/src/com/android/settings/language/PhoneLanguagePreferenceController.java b/src/com/android/settings/language/PhoneLanguagePreferenceController.java
index 0f9b419..8045fc0 100644
--- a/src/com/android/settings/language/PhoneLanguagePreferenceController.java
+++ b/src/com/android/settings/language/PhoneLanguagePreferenceController.java
@@ -75,7 +75,7 @@
         new SubSettingLauncher(mContext)
                 .setDestination(LocaleListEditor.class.getName())
                 .setSourceMetricsCategory(MetricsProto.MetricsEvent.SETTINGS_LANGUAGE_CATEGORY)
-                .setTitleRes(R.string.pref_title_lang_selection)
+                .setTitleRes(R.string.language_picker_title)
                 .launch();
         return true;
     }
diff --git a/src/com/android/settings/localepicker/LocaleListEditor.java b/src/com/android/settings/localepicker/LocaleListEditor.java
index 87c19dd..cbcb1eb 100644
--- a/src/com/android/settings/localepicker/LocaleListEditor.java
+++ b/src/com/android/settings/localepicker/LocaleListEditor.java
@@ -18,8 +18,10 @@
 
 import static android.os.UserManager.DISALLOW_CONFIG_LOCALE;
 
+import android.app.Activity;
 import android.app.AlertDialog;
 import android.content.DialogInterface;
+import android.content.Intent;
 import android.os.Bundle;
 import android.os.LocaleList;
 import android.view.LayoutInflater;
@@ -40,18 +42,18 @@
 import java.util.List;
 import java.util.Locale;
 
-import androidx.fragment.app.FragmentTransaction;
 import androidx.recyclerview.widget.RecyclerView;
 
 /**
  * Drag-and-drop editor for the user-ordered locale lists.
  */
-public class LocaleListEditor extends RestrictedSettingsFragment
-        implements LocalePickerWithRegion.LocaleSelectedListener {
+public class LocaleListEditor extends RestrictedSettingsFragment {
 
+    protected static final String INTENT_LOCALE_KEY = "localeInfo";
     private static final String CFGKEY_REMOVE_MODE = "localeRemoveMode";
     private static final String CFGKEY_REMOVE_DIALOG = "showingLocaleRemoveDialog";
     private static final int MENU_ID_REMOVE = Menu.FIRST + 1;
+    private static final int REQUEST_LOCALE_PICKER = 0;
 
     private LocaleDragAndDropAdapter mAdapter;
     private Menu mMenu;
@@ -150,6 +152,19 @@
         return super.onOptionsItemSelected(menuItem);
     }
 
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (requestCode == REQUEST_LOCALE_PICKER && resultCode == Activity.RESULT_OK
+                && data != null) {
+            final LocaleStore.LocaleInfo locale =
+                    (LocaleStore.LocaleInfo) data.getSerializableExtra(
+                            INTENT_LOCALE_KEY);
+            mAdapter.addLocale(locale);
+            updateVisibilityOfRemoveMenu();
+        }
+        super.onActivityResult(requestCode, resultCode, data);
+    }
+
     private void setRemoveMode(boolean mRemoveMode) {
         this.mRemoveMode = mRemoveMode;
         mAdapter.setRemoveMode(mRemoveMode);
@@ -267,24 +282,13 @@
         mAddLanguage.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                final LocalePickerWithRegion selector = LocalePickerWithRegion.createLanguagePicker(
-                        getContext(), LocaleListEditor.this, false /* translate only */);
-                getFragmentManager()
-                        .beginTransaction()
-                        .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
-                        .replace(getId(), selector)
-                        .addToBackStack("localeListEditor")
-                        .commit();
+                final Intent intent = new Intent(getActivity(),
+                        LocalePickerWithRegionActivity.class);
+                startActivityForResult(intent, REQUEST_LOCALE_PICKER);
             }
         });
     }
 
-    @Override
-    public void onLocaleSelected(LocaleStore.LocaleInfo locale) {
-        mAdapter.addLocale(locale);
-        updateVisibilityOfRemoveMenu();
-    }
-
     // Hide the "Remove" menu if there is only one locale in the list, show it otherwise
     // This is called when the menu is first created, and then one add / remove locale
     private void updateVisibilityOfRemoveMenu() {
diff --git a/src/com/android/settings/localepicker/LocalePickerWithRegion.java b/src/com/android/settings/localepicker/LocalePickerWithRegion.java
deleted file mode 100644
index e8a91bc..0000000
--- a/src/com/android/settings/localepicker/LocalePickerWithRegion.java
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Copyright (C) 2018 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.localepicker;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.os.LocaleList;
-import android.text.TextUtils;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.ListView;
-import android.widget.SearchView;
-
-import com.android.internal.R;
-import com.android.internal.app.LocaleHelper;
-import com.android.internal.app.LocalePicker;
-import com.android.internal.app.LocaleStore;
-import com.android.internal.app.SuggestedLocaleAdapter;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Locale;
-import java.util.Set;
-
-import androidx.fragment.app.FragmentManager;
-import androidx.fragment.app.FragmentTransaction;
-import androidx.fragment.app.ListFragment;
-
-/**
- * A two-step locale picker. It shows a language, then a country.
- *
- * <p>It shows suggestions at the top, then the rest of the locales.
- * Allows the user to search for locales using both their native name and their name in the
- * default locale.</p>
- */
-public class LocalePickerWithRegion extends ListFragment implements SearchView.OnQueryTextListener {
-    private static final String PARENT_FRAGMENT_NAME = "localeListEditor";
-
-    private SuggestedLocaleAdapter mAdapter;
-    private LocaleSelectedListener mListener;
-    private Set<LocaleStore.LocaleInfo> mLocaleList;
-    private LocaleStore.LocaleInfo mParentLocale;
-    private boolean mTranslatedOnly = false;
-    private SearchView mSearchView = null;
-    private CharSequence mPreviousSearch = null;
-    private boolean mPreviousSearchHadFocus = false;
-    private int mFirstVisiblePosition = 0;
-    private int mTopDistance = 0;
-
-    /**
-     * Other classes can register to be notified when a locale was selected.
-     *
-     * <p>This is the mechanism to "return" the result of the selection.</p>
-     */
-    public interface LocaleSelectedListener {
-        /**
-         * The classes that want to retrieve the locale picked should implement this method.
-         * @param locale    the locale picked.
-         */
-        void onLocaleSelected(LocaleStore.LocaleInfo locale);
-    }
-
-    private static LocalePickerWithRegion createCountryPicker(Context context,
-            LocaleSelectedListener listener, LocaleStore.LocaleInfo parent,
-            boolean translatedOnly) {
-        LocalePickerWithRegion
-                localePicker = new LocalePickerWithRegion();
-        boolean shouldShowTheList = localePicker.setListener(context, listener, parent,
-                translatedOnly);
-        return shouldShowTheList ? localePicker : null;
-    }
-
-    public static LocalePickerWithRegion createLanguagePicker(Context context,
-            LocaleSelectedListener listener, boolean translatedOnly) {
-        LocalePickerWithRegion
-                localePicker = new LocalePickerWithRegion();
-        localePicker.setListener(context, listener, /* parent */ null, translatedOnly);
-        return localePicker;
-    }
-
-    /**
-     * Sets the listener and initializes the locale list.
-     *
-     * <p>Returns true if we need to show the list, false if not.</p>
-     *
-     * <p>Can return false because of an error, trying to show a list of countries,
-     * but no parent locale was provided.</p>
-     *
-     * <p>It can also return false if the caller tries to show the list in country mode and
-     * there is only one country available (i.e. Japanese => Japan).
-     * In this case we don't even show the list, we call the listener with that locale,
-     * "pretending" it was selected, and return false.</p>
-     */
-    private boolean setListener(Context context, LocaleSelectedListener listener,
-            LocaleStore.LocaleInfo parent, boolean translatedOnly) {
-        this.mParentLocale = parent;
-        this.mListener = listener;
-        this.mTranslatedOnly = translatedOnly;
-        setRetainInstance(true);
-
-        final HashSet<String> langTagsToIgnore = new HashSet<>();
-        if (!translatedOnly) {
-            final LocaleList userLocales = LocalePicker.getLocales();
-            final String[] langTags = userLocales.toLanguageTags().split(",");
-            Collections.addAll(langTagsToIgnore, langTags);
-        }
-
-        if (parent != null) {
-            mLocaleList = LocaleStore.getLevelLocales(context,
-                    langTagsToIgnore, parent, translatedOnly);
-            if (mLocaleList.size() <= 1) {
-                if (listener != null && (mLocaleList.size() == 1)) {
-                    listener.onLocaleSelected(mLocaleList.iterator().next());
-                }
-                return false;
-            }
-        } else {
-            mLocaleList = LocaleStore.getLevelLocales(context, langTagsToIgnore,
-                    null /* no parent */, translatedOnly);
-        }
-
-        return true;
-    }
-
-    private void returnToParentFrame() {
-        getFragmentManager().popBackStack(PARENT_FRAGMENT_NAME,
-                FragmentManager.POP_BACK_STACK_INCLUSIVE);
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setHasOptionsMenu(true);
-
-        if (mLocaleList == null) {
-            // The fragment was killed and restored by the FragmentManager.
-            // At this point we have no data, no listener. Just return, to prevend a NPE.
-            // Fixes b/28748150. Created b/29400003 for a cleaner solution.
-            returnToParentFrame();
-            return;
-        }
-
-        final boolean countryMode = mParentLocale != null;
-        final Locale sortingLocale = countryMode ? mParentLocale.getLocale() : Locale.getDefault();
-        mAdapter = new SuggestedLocaleAdapter(mLocaleList, countryMode);
-        final LocaleHelper.LocaleInfoComparator comp =
-                new LocaleHelper.LocaleInfoComparator(sortingLocale, countryMode);
-        mAdapter.sort(comp);
-        setListAdapter(mAdapter);
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem menuItem) {
-        int id = menuItem.getItemId();
-        switch (id) {
-            case android.R.id.home:
-                getFragmentManager().popBackStack();
-                return true;
-        }
-        return super.onOptionsItemSelected(menuItem);
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-
-        if (mParentLocale != null) {
-            getActivity().setTitle(mParentLocale.getFullNameNative());
-        } else {
-            getActivity().setTitle(R.string.language_selection_title);
-        }
-
-        getListView().requestFocus();
-    }
-
-    @Override
-    public void onPause() {
-        super.onPause();
-
-        // Save search status
-        if (mSearchView != null) {
-            mPreviousSearchHadFocus = mSearchView.hasFocus();
-            mPreviousSearch = mSearchView.getQuery();
-        } else {
-            mPreviousSearchHadFocus = false;
-            mPreviousSearch = null;
-        }
-
-        // Save scroll position
-        final ListView list = getListView();
-        final View firstChild = list.getChildAt(0);
-        mFirstVisiblePosition = list.getFirstVisiblePosition();
-        mTopDistance = (firstChild == null) ? 0 : (firstChild.getTop() - list.getPaddingTop());
-    }
-
-    @Override
-    public void onListItemClick(ListView l, View v, int position, long id) {
-        final LocaleStore.LocaleInfo locale =
-                (LocaleStore.LocaleInfo) getListAdapter().getItem(position);
-
-        if (locale.getParent() != null) {
-            if (mListener != null) {
-                mListener.onLocaleSelected(locale);
-            }
-            returnToParentFrame();
-        } else {
-            LocalePickerWithRegion
-                    selector = LocalePickerWithRegion.createCountryPicker(
-                    getContext(), mListener, locale, mTranslatedOnly /* translate only */);
-            if (selector != null) {
-                getFragmentManager().beginTransaction()
-                        .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
-                        .replace(getId(), selector).addToBackStack(null)
-                        .commit();
-            } else {
-                returnToParentFrame();
-            }
-        }
-    }
-
-    @Override
-    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
-        if (mParentLocale == null) {
-            inflater.inflate(R.menu.language_selection_list, menu);
-
-            final MenuItem searchMenuItem = menu.findItem(R.id.locale_search_menu);
-            mSearchView = (SearchView) searchMenuItem.getActionView();
-
-            mSearchView.setQueryHint(getText(R.string.search_language_hint));
-            mSearchView.setOnQueryTextListener(this);
-
-            // Restore previous search status
-            if (!TextUtils.isEmpty(mPreviousSearch)) {
-                searchMenuItem.expandActionView();
-                mSearchView.setIconified(false);
-                mSearchView.setActivated(true);
-                if (mPreviousSearchHadFocus) {
-                    mSearchView.requestFocus();
-                }
-                mSearchView.setQuery(mPreviousSearch, true /* submit */);
-            } else {
-                mSearchView.setQuery(null, false /* submit */);
-            }
-
-            // Restore previous scroll position
-            getListView().setSelectionFromTop(mFirstVisiblePosition, mTopDistance);
-        }
-    }
-
-    @Override
-    public boolean onQueryTextSubmit(String query) {
-        return false;
-    }
-
-    @Override
-    public boolean onQueryTextChange(String newText) {
-        if (mAdapter != null) {
-            mAdapter.getFilter().filter(newText);
-        }
-        return false;
-    }
-}
diff --git a/src/com/android/settings/localepicker/LocalePickerWithRegionActivity.java b/src/com/android/settings/localepicker/LocalePickerWithRegionActivity.java
new file mode 100644
index 0000000..6ddcf23
--- /dev/null
+++ b/src/com/android/settings/localepicker/LocalePickerWithRegionActivity.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2018 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.localepicker;
+
+import android.app.Activity;
+import android.app.FragmentTransaction;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.MenuItem;
+
+import com.android.internal.app.LocalePickerWithRegion;
+import com.android.internal.app.LocaleStore;
+
+public class LocalePickerWithRegionActivity extends Activity
+        implements LocalePickerWithRegion.LocaleSelectedListener {
+
+    private static final String PARENT_FRAGMENT_NAME = "localeListEditor";
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        getActionBar().setDisplayHomeAsUpEnabled(true);
+
+        final LocalePickerWithRegion selector = LocalePickerWithRegion.createLanguagePicker(
+                this, LocalePickerWithRegionActivity.this, false /* translate only */);
+        getFragmentManager()
+                .beginTransaction()
+                .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
+                .replace(android.R.id.content, selector)
+                .addToBackStack(PARENT_FRAGMENT_NAME)
+                .commit();
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        if (item.getItemId() == android.R.id.home) {
+            handleBackPressed();
+            return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    @Override
+    public void onLocaleSelected(LocaleStore.LocaleInfo locale) {
+        final Intent intent = new Intent();
+        intent.putExtra(LocaleListEditor.INTENT_LOCALE_KEY, locale);
+        setResult(RESULT_OK, intent);
+        finish();
+    }
+
+    @Override
+    public void onBackPressed() {
+        handleBackPressed();
+    }
+
+    private void handleBackPressed() {
+        if (getFragmentManager().getBackStackEntryCount() > 1) {
+            super.onBackPressed();
+        } else {
+            setResult(RESULT_CANCELED);
+            finish();
+        }
+    }
+}
+
diff --git a/src/com/android/settings/location/AppSettingsInjector.java b/src/com/android/settings/location/AppSettingsInjector.java
new file mode 100644
index 0000000..6b79a7e
--- /dev/null
+++ b/src/com/android/settings/location/AppSettingsInjector.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2018 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.text.TextUtils;
+
+import androidx.preference.Preference;
+
+import com.android.settings.widget.AppPreference;
+import com.android.settings.widget.RestrictedAppPreference;
+import com.android.settingslib.location.InjectedSetting;
+import com.android.settingslib.location.SettingsInjector;
+
+import java.util.List;
+
+/**
+ * Adds the preferences specified by the {@link InjectedSetting} objects to a preference group.
+ */
+public class AppSettingsInjector extends SettingsInjector {
+
+    public AppSettingsInjector(Context context) {
+        super(context);
+    }
+
+    @Override
+    protected Preference createPreference(Context prefContext, InjectedSetting setting) {
+        return TextUtils.isEmpty(setting.userRestriction)
+                ? new AppPreference(prefContext)
+                : new RestrictedAppPreference(prefContext, setting.userRestriction);
+    }
+}
diff --git a/src/com/android/settings/location/InjectedSetting.java b/src/com/android/settings/location/InjectedSetting.java
deleted file mode 100644
index 4877cb4..0000000
--- a/src/com/android/settings/location/InjectedSetting.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (C) 2013 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.Intent;
-import android.os.UserHandle;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.annotations.Immutable;
-
-import java.util.Objects;
-
-/**
- * Specifies a setting that is being injected into Settings &gt; Location &gt; Location services.
- *
- * @see android.location.SettingInjectorService
- */
-@Immutable
-class InjectedSetting {
-
-    /**
-     * Package for the subclass of {@link android.location.SettingInjectorService} and for the
-     * settings activity.
-     */
-    public final String packageName;
-
-    /**
-     * Class name for the subclass of {@link android.location.SettingInjectorService} that
-     * specifies dynamic values for the location setting.
-     */
-    public final String className;
-
-    /**
-     * The {@link androidx.preference.Preference#getTitle()} value.
-     */
-    public final String title;
-
-    /**
-     * The {@link androidx.preference.Preference#getIcon()} value.
-     */
-    public final int iconId;
-
-    /**
-     * The user/profile associated with this setting (e.g. managed profile)
-     */
-    public final UserHandle mUserHandle;
-
-    /**
-     * The activity to launch to allow the user to modify the settings value. Assumed to be in the
-     * {@link #packageName} package.
-     */
-    public final String settingsActivity;
-
-    /**
-     * The user restriction associated with this setting.
-     */
-    public final String userRestriction;
-
-    private InjectedSetting(Builder builder) {
-        this.packageName = builder.mPackageName;
-        this.className = builder.mClassName;
-        this.title = builder.mTitle;
-        this.iconId = builder.mIconId;
-        this.mUserHandle = builder.mUserHandle;
-        this.settingsActivity = builder.mSettingsActivity;
-        this.userRestriction = builder.mUserRestriction;
-    }
-
-    @Override
-    public String toString() {
-        return "InjectedSetting{" +
-                "mPackageName='" + packageName + '\'' +
-                ", mClassName='" + className + '\'' +
-                ", label=" + title +
-                ", iconId=" + iconId +
-                ", userId=" + mUserHandle.getIdentifier() +
-                ", settingsActivity='" + settingsActivity + '\'' +
-                ", userRestriction='" + userRestriction +
-                '}';
-    }
-
-    /**
-     * Returns the intent to start the {@link #className} service.
-     */
-    public Intent getServiceIntent() {
-        Intent intent = new Intent();
-        intent.setClassName(packageName, className);
-        return intent;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (!(o instanceof InjectedSetting)) return false;
-
-        InjectedSetting that = (InjectedSetting) o;
-
-        return Objects.equals(packageName, that.packageName)
-                && Objects.equals(className, that.className)
-                && Objects.equals(title, that.title)
-                && Objects.equals(iconId, that.iconId)
-                && Objects.equals(mUserHandle, that.mUserHandle)
-                && Objects.equals(settingsActivity, that.settingsActivity)
-                && Objects.equals(userRestriction, that.userRestriction);
-    }
-
-    @Override
-    public int hashCode() {
-        int result = packageName.hashCode();
-        result = 31 * result + className.hashCode();
-        result = 31 * result + title.hashCode();
-        result = 31 * result + iconId;
-        result = 31 * result + (mUserHandle == null ? 0 : mUserHandle.hashCode());
-        result = 31 * result + settingsActivity.hashCode();
-        result = 31 * result + (userRestriction == null ? 0 : userRestriction.hashCode());
-        return result;
-    }
-
-    public static class Builder {
-        private String mPackageName;
-        private String mClassName;
-        private String mTitle;
-        private int mIconId;
-        private UserHandle mUserHandle;
-        private String mSettingsActivity;
-        private String mUserRestriction;
-
-        public Builder setPackageName(String packageName) {
-            mPackageName = packageName;
-            return this;
-        }
-
-        public Builder setClassName(String className) {
-            mClassName = className;
-            return this;
-        }
-
-        public Builder setTitle(String title) {
-            mTitle = title;
-            return this;
-        }
-
-        public Builder setIconId(int iconId) {
-            mIconId = iconId;
-            return this;
-        }
-
-        public Builder setUserHandle(UserHandle userHandle) {
-            mUserHandle = userHandle;
-            return this;
-        }
-
-        public Builder setSettingsActivity(String settingsActivity) {
-            mSettingsActivity = settingsActivity;
-            return this;
-        }
-
-        public Builder setUserRestriction(String userRestriction) {
-            mUserRestriction = userRestriction;
-            return this;
-        }
-
-        public InjectedSetting build() {
-            if (mPackageName == null || mClassName == null || TextUtils.isEmpty(mTitle)
-                    || TextUtils.isEmpty(mSettingsActivity)) {
-                if (Log.isLoggable(SettingsInjector.TAG, Log.WARN)) {
-                    Log.w(SettingsInjector.TAG, "Illegal setting specification: package="
-                            + mPackageName + ", class=" + mClassName
-                            + ", title=" + mTitle + ", settingsActivity=" + mSettingsActivity);
-                }
-                return null;
-            }
-            return new InjectedSetting(this);
-        }
-    }
-}
diff --git a/src/com/android/settings/location/LocationServicePreferenceController.java b/src/com/android/settings/location/LocationServicePreferenceController.java
index 67ec152..035faad 100644
--- a/src/com/android/settings/location/LocationServicePreferenceController.java
+++ b/src/com/android/settings/location/LocationServicePreferenceController.java
@@ -47,19 +47,19 @@
 
     private PreferenceCategory mCategoryLocationServices;
     private final LocationSettings mFragment;
-    private final SettingsInjector mInjector;
+    private final AppSettingsInjector mInjector;
     /** Receives UPDATE_INTENT  */
     @VisibleForTesting
     BroadcastReceiver mInjectedSettingsReceiver;
 
     public LocationServicePreferenceController(Context context, LocationSettings fragment,
             Lifecycle lifecycle) {
-        this(context, fragment, lifecycle, new SettingsInjector(context));
+        this(context, fragment, lifecycle, new AppSettingsInjector(context));
     }
 
     @VisibleForTesting
     LocationServicePreferenceController(Context context, LocationSettings fragment,
-            Lifecycle lifecycle, SettingsInjector injector) {
+            Lifecycle lifecycle, AppSettingsInjector injector) {
         super(context, lifecycle);
         mFragment = fragment;
         mInjector = injector;
diff --git a/src/com/android/settings/location/SettingsInjector.java b/src/com/android/settings/location/SettingsInjector.java
deleted file mode 100644
index 1206e85..0000000
--- a/src/com/android/settings/location/SettingsInjector.java
+++ /dev/null
@@ -1,577 +0,0 @@
-/*
- * Copyright (C) 2013 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.ActivityManager;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageItemInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.content.res.XmlResourceParser;
-import android.graphics.drawable.Drawable;
-import android.location.SettingInjectorService;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.text.TextUtils;
-import android.util.AttributeSet;
-import android.util.IconDrawableFactory;
-import android.util.Log;
-import android.util.Xml;
-
-import com.android.settings.widget.AppPreference;
-import com.android.settings.widget.RestrictedAppPreference;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import androidx.preference.Preference;
-
-/**
- * Adds the preferences specified by the {@link InjectedSetting} objects to a preference group.
- *
- * Duplicates some code from {@link android.content.pm.RegisteredServicesCache}. We do not use that
- * class directly because it is not a good match for our use case: we do not need the caching, and
- * so do not want the additional resource hit at app install/upgrade time; and we would have to
- * suppress the tie-breaking between multiple services reporting settings with the same name.
- * Code-sharing would require extracting {@link
- * android.content.pm.RegisteredServicesCache#parseServiceAttributes(android.content.res.Resources,
- * String, android.util.AttributeSet)} into an interface, which didn't seem worth it.
- */
-class SettingsInjector {
-    static final String TAG = "SettingsInjector";
-
-    /**
-     * If reading the status of a setting takes longer than this, we go ahead and start reading
-     * the next setting.
-     */
-    private static final long INJECTED_STATUS_UPDATE_TIMEOUT_MILLIS = 1000;
-
-    /**
-     * {@link Message#what} value for starting to load status values
-     * in case we aren't already in the process of loading them.
-     */
-    private static final int WHAT_RELOAD = 1;
-
-    /**
-     * {@link Message#what} value sent after receiving a status message.
-     */
-    private static final int WHAT_RECEIVED_STATUS = 2;
-
-    /**
-     * {@link Message#what} value sent after the timeout waiting for a status message.
-     */
-    private static final int WHAT_TIMEOUT = 3;
-
-    private final Context mContext;
-
-    /**
-     * The settings that were injected
-     */
-    private final Set<Setting> mSettings;
-
-    private final Handler mHandler;
-
-    public SettingsInjector(Context context) {
-        mContext = context;
-        mSettings = new HashSet<Setting>();
-        mHandler = new StatusLoadingHandler();
-    }
-
-    /**
-     * Returns a list for a profile with one {@link InjectedSetting} object for each
-     * {@link android.app.Service} that responds to
-     * {@link SettingInjectorService#ACTION_SERVICE_INTENT} and provides the expected setting
-     * metadata.
-     *
-     * Duplicates some code from {@link android.content.pm.RegisteredServicesCache}.
-     *
-     * TODO: unit test
-     */
-    private List<InjectedSetting> getSettings(final UserHandle userHandle) {
-        PackageManager pm = mContext.getPackageManager();
-        Intent intent = new Intent(SettingInjectorService.ACTION_SERVICE_INTENT);
-
-        final int profileId = userHandle.getIdentifier();
-        List<ResolveInfo> resolveInfos =
-                pm.queryIntentServicesAsUser(intent, PackageManager.GET_META_DATA, profileId);
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.d(TAG, "Found services for profile id " + profileId + ": " + resolveInfos);
-        }
-        List<InjectedSetting> settings = new ArrayList<InjectedSetting>(resolveInfos.size());
-        for (ResolveInfo resolveInfo : resolveInfos) {
-            try {
-                InjectedSetting setting = parseServiceInfo(resolveInfo, userHandle, pm);
-                if (setting == null) {
-                    Log.w(TAG, "Unable to load service info " + resolveInfo);
-                } else {
-                    settings.add(setting);
-                }
-            } catch (XmlPullParserException e) {
-                Log.w(TAG, "Unable to load service info " + resolveInfo, e);
-            } catch (IOException e) {
-                Log.w(TAG, "Unable to load service info " + resolveInfo, e);
-            }
-        }
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.d(TAG, "Loaded settings for profile id " + profileId + ": " + settings);
-        }
-
-        return settings;
-    }
-
-    /**
-     * Returns the settings parsed from the attributes of the
-     * {@link SettingInjectorService#META_DATA_NAME} tag, or null.
-     *
-     * Duplicates some code from {@link android.content.pm.RegisteredServicesCache}.
-     */
-    private static InjectedSetting parseServiceInfo(ResolveInfo service, UserHandle userHandle,
-            PackageManager pm) throws XmlPullParserException, IOException {
-
-        ServiceInfo si = service.serviceInfo;
-        ApplicationInfo ai = si.applicationInfo;
-
-        if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
-            if (Log.isLoggable(TAG, Log.WARN)) {
-                Log.w(TAG, "Ignoring attempt to inject setting from app not in system image: "
-                        + service);
-                return null;
-            }
-        }
-
-        XmlResourceParser parser = null;
-        try {
-            parser = si.loadXmlMetaData(pm, SettingInjectorService.META_DATA_NAME);
-            if (parser == null) {
-                throw new XmlPullParserException("No " + SettingInjectorService.META_DATA_NAME
-                        + " meta-data for " + service + ": " + si);
-            }
-
-            AttributeSet attrs = Xml.asAttributeSet(parser);
-
-            int type;
-            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
-                    && type != XmlPullParser.START_TAG) {
-            }
-
-            String nodeName = parser.getName();
-            if (!SettingInjectorService.ATTRIBUTES_NAME.equals(nodeName)) {
-                throw new XmlPullParserException("Meta-data does not start with "
-                        + SettingInjectorService.ATTRIBUTES_NAME + " tag");
-            }
-
-            Resources res = pm.getResourcesForApplicationAsUser(si.packageName,
-                    userHandle.getIdentifier());
-            return parseAttributes(si.packageName, si.name, userHandle, res, attrs);
-        } catch (PackageManager.NameNotFoundException e) {
-            throw new XmlPullParserException(
-                    "Unable to load resources for package " + si.packageName);
-        } finally {
-            if (parser != null) {
-                parser.close();
-            }
-        }
-    }
-
-    /**
-     * Returns an immutable representation of the static attributes for the setting, or null.
-     */
-    private static InjectedSetting parseAttributes(String packageName, String className,
-            UserHandle userHandle, Resources res, AttributeSet attrs) {
-
-        TypedArray sa = res.obtainAttributes(attrs, android.R.styleable.SettingInjectorService);
-        try {
-            // Note that to help guard against malicious string injection, we do not allow dynamic
-            // specification of the label (setting title)
-            final String title = sa.getString(android.R.styleable.SettingInjectorService_title);
-            final int iconId =
-                    sa.getResourceId(android.R.styleable.SettingInjectorService_icon, 0);
-            final String settingsActivity =
-                    sa.getString(android.R.styleable.SettingInjectorService_settingsActivity);
-            final String userRestriction = sa.getString(
-                    android.R.styleable.SettingInjectorService_userRestriction);
-            if (Log.isLoggable(TAG, Log.DEBUG)) {
-                Log.d(TAG, "parsed title: " + title + ", iconId: " + iconId
-                        + ", settingsActivity: " + settingsActivity);
-            }
-            return new InjectedSetting.Builder()
-                    .setPackageName(packageName)
-                    .setClassName(className)
-                    .setTitle(title)
-                    .setIconId(iconId)
-                    .setUserHandle(userHandle)
-                    .setSettingsActivity(settingsActivity)
-                    .setUserRestriction(userRestriction)
-                    .build();
-        } finally {
-            sa.recycle();
-        }
-    }
-
-    /**
-     * Gets a list of preferences that other apps have injected.
-     *
-     * @param profileId Identifier of the user/profile to obtain the injected settings for or
-     *                  UserHandle.USER_CURRENT for all profiles associated with current user.
-     */
-    public List<Preference> getInjectedSettings(Context prefContext, final int profileId) {
-        final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
-        final List<UserHandle> profiles = um.getUserProfiles();
-        ArrayList<Preference> prefs = new ArrayList<>();
-        final int profileCount = profiles.size();
-        for (int i = 0; i < profileCount; ++i) {
-            final UserHandle userHandle = profiles.get(i);
-            if (profileId == UserHandle.USER_CURRENT || profileId == userHandle.getIdentifier()) {
-                Iterable<InjectedSetting> settings = getSettings(userHandle);
-                for (InjectedSetting setting : settings) {
-                    Preference pref = addServiceSetting(prefContext, prefs, setting);
-                    mSettings.add(new Setting(setting, pref));
-                }
-            }
-        }
-
-        reloadStatusMessages();
-
-        return prefs;
-    }
-
-    /**
-     * Checks wheteher there is any preference that other apps have injected.
-     *
-     * @param profileId Identifier of the user/profile to obtain the injected settings for or
-     *                  UserHandle.USER_CURRENT for all profiles associated with current user.
-     */
-    public boolean hasInjectedSettings(final int profileId) {
-        final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
-        final List<UserHandle> profiles = um.getUserProfiles();
-        final int profileCount = profiles.size();
-        for (int i = 0; i < profileCount; ++i) {
-            final UserHandle userHandle = profiles.get(i);
-            if (profileId == UserHandle.USER_CURRENT || profileId == userHandle.getIdentifier()) {
-                Iterable<InjectedSetting> settings = getSettings(userHandle);
-                for (InjectedSetting setting : settings) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Reloads the status messages for all the preference items.
-     */
-    public void reloadStatusMessages() {
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.d(TAG, "reloadingStatusMessages: " + mSettings);
-        }
-        mHandler.sendMessage(mHandler.obtainMessage(WHAT_RELOAD));
-    }
-
-    /**
-     * Adds an injected setting to the root.
-     */
-    private Preference addServiceSetting(Context prefContext, List<Preference> prefs,
-            InjectedSetting info) {
-        final PackageManager pm = mContext.getPackageManager();
-        Drawable appIcon = null;
-        try {
-            final PackageItemInfo itemInfo = new PackageItemInfo();
-            itemInfo.icon = info.iconId;
-            itemInfo.packageName = info.packageName;
-            final ApplicationInfo appInfo = pm.getApplicationInfo(info.packageName,
-                PackageManager.GET_META_DATA);
-            appIcon = IconDrawableFactory.newInstance(mContext)
-                .getBadgedIcon(itemInfo, appInfo, info.mUserHandle.getIdentifier());
-        } catch (PackageManager.NameNotFoundException e) {
-            Log.e(TAG, "Can't get ApplicationInfo for " + info.packageName, e);
-        }
-        Preference pref = TextUtils.isEmpty(info.userRestriction)
-                ? new AppPreference(prefContext)
-                : new RestrictedAppPreference(prefContext, info.userRestriction);
-        pref.setTitle(info.title);
-        pref.setSummary(null);
-        pref.setIcon(appIcon);
-        pref.setOnPreferenceClickListener(new ServiceSettingClickedListener(info));
-        prefs.add(pref);
-        return pref;
-    }
-
-    private class ServiceSettingClickedListener
-            implements Preference.OnPreferenceClickListener {
-        private InjectedSetting mInfo;
-
-        public ServiceSettingClickedListener(InjectedSetting info) {
-            mInfo = info;
-        }
-
-        @Override
-        public boolean onPreferenceClick(Preference preference) {
-            // Activity to start if they click on the preference. Must start in new task to ensure
-            // that "android.settings.LOCATION_SOURCE_SETTINGS" brings user back to
-            // Settings > Location.
-            Intent settingIntent = new Intent();
-            settingIntent.setClassName(mInfo.packageName, mInfo.settingsActivity);
-            // Sometimes the user may navigate back to "Settings" and launch another different
-            // injected setting after one injected setting has been launched.
-            //
-            // FLAG_ACTIVITY_CLEAR_TOP allows multiple Activities to stack on each other. When
-            // "back" button is clicked, the user will navigate through all the injected settings
-            // launched before. Such behavior could be quite confusing sometimes.
-            //
-            // In order to avoid such confusion, we use FLAG_ACTIVITY_CLEAR_TASK, which always clear
-            // up all existing injected settings and make sure that "back" button always brings the
-            // user back to "Settings" directly.
-            settingIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
-            mContext.startActivityAsUser(settingIntent, mInfo.mUserHandle);
-            return true;
-        }
-    }
-
-    /**
-     * Loads the setting status values one at a time. Each load starts a subclass of {@link
-     * SettingInjectorService}, so to reduce memory pressure we don't want to load too many at
-     * once.
-     */
-    private final class StatusLoadingHandler extends Handler {
-
-        /**
-         * Settings whose status values need to be loaded. A set is used to prevent redundant loads.
-         */
-        private Set<Setting> mSettingsToLoad = new HashSet<Setting>();
-
-        /**
-         * Settings that are being loaded now and haven't timed out. In practice this should have
-         * zero or one elements.
-         */
-        private Set<Setting> mSettingsBeingLoaded = new HashSet<Setting>();
-
-        /**
-         * Settings that are being loaded but have timed out. If only one setting has timed out, we
-         * will go ahead and start loading the next setting so that one slow load won't delay the
-         * load of the other settings.
-         */
-        private Set<Setting> mTimedOutSettings = new HashSet<Setting>();
-
-        private boolean mReloadRequested;
-
-        private StatusLoadingHandler() {
-            super(Looper.getMainLooper());
-        }
-        @Override
-        public void handleMessage(Message msg) {
-            if (Log.isLoggable(TAG, Log.DEBUG)) {
-                Log.d(TAG, "handleMessage start: " + msg + ", " + this);
-            }
-
-            // Update state in response to message
-            switch (msg.what) {
-                case WHAT_RELOAD:
-                    mReloadRequested = true;
-                    break;
-                case WHAT_RECEIVED_STATUS:
-                    final Setting receivedSetting = (Setting) msg.obj;
-                    receivedSetting.maybeLogElapsedTime();
-                    mSettingsBeingLoaded.remove(receivedSetting);
-                    mTimedOutSettings.remove(receivedSetting);
-                    removeMessages(WHAT_TIMEOUT, receivedSetting);
-                    break;
-                case WHAT_TIMEOUT:
-                    final Setting timedOutSetting = (Setting) msg.obj;
-                    mSettingsBeingLoaded.remove(timedOutSetting);
-                    mTimedOutSettings.add(timedOutSetting);
-                    if (Log.isLoggable(TAG, Log.WARN)) {
-                        Log.w(TAG, "Timed out after " + timedOutSetting.getElapsedTime()
-                                + " millis trying to get status for: " + timedOutSetting);
-                    }
-                    break;
-                default:
-                    Log.wtf(TAG, "Unexpected what: " + msg);
-            }
-
-            // Decide whether to load additional settings based on the new state. Start by seeing
-            // if we have headroom to load another setting.
-            if (mSettingsBeingLoaded.size() > 0 || mTimedOutSettings.size() > 1) {
-                // Don't load any more settings until one of the pending settings has completed.
-                // To reduce memory pressure, we want to be loading at most one setting (plus at
-                // most one timed-out setting) at a time. This means we'll be responsible for
-                // bringing in at most two services.
-                if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                    Log.v(TAG, "too many services already live for " + msg + ", " + this);
-                }
-                return;
-            }
-
-            if (mReloadRequested && mSettingsToLoad.isEmpty() && mSettingsBeingLoaded.isEmpty()
-                    && mTimedOutSettings.isEmpty()) {
-                if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                    Log.v(TAG, "reloading because idle and reload requesteed " + msg + ", " + this);
-                }
-                // Reload requested, so must reload all settings
-                mSettingsToLoad.addAll(mSettings);
-                mReloadRequested = false;
-            }
-
-            // Remove the next setting to load from the queue, if any
-            Iterator<Setting> iter = mSettingsToLoad.iterator();
-            if (!iter.hasNext()) {
-                if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                    Log.v(TAG, "nothing left to do for " + msg + ", " + this);
-                }
-                return;
-            }
-            Setting setting = iter.next();
-            iter.remove();
-
-            // Request the status value
-            setting.startService();
-            mSettingsBeingLoaded.add(setting);
-
-            // Ensure that if receiving the status value takes too long, we start loading the
-            // next value anyway
-            Message timeoutMsg = obtainMessage(WHAT_TIMEOUT, setting);
-            sendMessageDelayed(timeoutMsg, INJECTED_STATUS_UPDATE_TIMEOUT_MILLIS);
-
-            if (Log.isLoggable(TAG, Log.DEBUG)) {
-                Log.d(TAG, "handleMessage end " + msg + ", " + this
-                        + ", started loading " + setting);
-            }
-        }
-
-        @Override
-        public String toString() {
-            return "StatusLoadingHandler{" +
-                    "mSettingsToLoad=" + mSettingsToLoad +
-                    ", mSettingsBeingLoaded=" + mSettingsBeingLoaded +
-                    ", mTimedOutSettings=" + mTimedOutSettings +
-                    ", mReloadRequested=" + mReloadRequested +
-                    '}';
-        }
-    }
-
-    /**
-     * Represents an injected setting and the corresponding preference.
-     */
-    private final class Setting {
-
-        public final InjectedSetting setting;
-        public final Preference preference;
-        public long startMillis;
-
-        private Setting(InjectedSetting setting, Preference preference) {
-            this.setting = setting;
-            this.preference = preference;
-        }
-
-        @Override
-        public String toString() {
-            return "Setting{" +
-                    "setting=" + setting +
-                    ", preference=" + preference +
-                    '}';
-        }
-
-        /**
-         * Returns true if they both have the same {@link #setting} value. Ignores mutable
-         * {@link #preference} and {@link #startMillis} so that it's safe to use in sets.
-         */
-        @Override
-        public boolean equals(Object o) {
-            return this == o || o instanceof Setting && setting.equals(((Setting) o).setting);
-        }
-
-        @Override
-        public int hashCode() {
-            return setting.hashCode();
-        }
-
-        /**
-         * Starts the service to fetch for the current status for the setting, and updates the
-         * preference when the service replies.
-         */
-        public void startService() {
-            final ActivityManager am = (ActivityManager)
-                    mContext.getSystemService(Context.ACTIVITY_SERVICE);
-            if (!am.isUserRunning(setting.mUserHandle.getIdentifier())) {
-                if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                    Log.v(TAG, "Cannot start service as user "
-                            + setting.mUserHandle.getIdentifier() + " is not running");
-                }
-                return;
-            }
-            Handler handler = new Handler() {
-                @Override
-                public void handleMessage(Message msg) {
-                    Bundle bundle = msg.getData();
-                    boolean enabled = bundle.getBoolean(SettingInjectorService.ENABLED_KEY, true);
-                    if (Log.isLoggable(TAG, Log.DEBUG)) {
-                        Log.d(TAG, setting + ": received " + msg + ", bundle: " + bundle);
-                    }
-                    preference.setSummary(null);
-                    preference.setEnabled(enabled);
-                    mHandler.sendMessage(
-                            mHandler.obtainMessage(WHAT_RECEIVED_STATUS, Setting.this));
-                }
-            };
-            Messenger messenger = new Messenger(handler);
-
-            Intent intent = setting.getServiceIntent();
-            intent.putExtra(SettingInjectorService.MESSENGER_KEY, messenger);
-
-            if (Log.isLoggable(TAG, Log.DEBUG)) {
-                Log.d(TAG, setting + ": sending update intent: " + intent
-                        + ", handler: " + handler);
-                startMillis = SystemClock.elapsedRealtime();
-            } else {
-                startMillis = 0;
-            }
-
-            // Start the service, making sure that this is attributed to the user associated with
-            // the setting rather than the system user.
-            mContext.startServiceAsUser(intent, setting.mUserHandle);
-        }
-
-        public long getElapsedTime() {
-            long end = SystemClock.elapsedRealtime();
-            return end - startMillis;
-        }
-
-        public void maybeLogElapsedTime() {
-            if (Log.isLoggable(TAG, Log.DEBUG) && startMillis != 0) {
-                long elapsed = getElapsedTime();
-                Log.d(TAG, this + " update took " + elapsed + " millis");
-            }
-        }
-    }
-}
diff --git a/src/com/android/settings/notification/NotificationAccessSettings.java b/src/com/android/settings/notification/NotificationAccessSettings.java
index 17739f9..ad721ba 100644
--- a/src/com/android/settings/notification/NotificationAccessSettings.java
+++ b/src/com/android/settings/notification/NotificationAccessSettings.java
@@ -23,10 +23,12 @@
 import android.content.Context;
 import android.os.AsyncTask;
 import android.os.Bundle;
+import android.os.UserManager;
 import android.provider.SearchIndexableResource;
 import android.provider.Settings;
 import android.service.notification.NotificationListenerService;
 
+import android.widget.Toast;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
@@ -62,6 +64,18 @@
     private NotificationManager mNm;
 
     @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        final Context ctx = getContext();
+        if (UserManager.get(ctx).isManagedProfile()) {
+            // Apps in the work profile do not support notification listeners.
+            Toast.makeText(ctx, R.string.notification_settings_work_profile, Toast.LENGTH_SHORT)
+                .show();
+            finish();
+        }
+    }
+
+    @Override
     public int getMetricsCategory() {
         return MetricsEvent.NOTIFICATION_ACCESS;
     }
diff --git a/src/com/android/settings/print/PrintServiceSettingsFragment.java b/src/com/android/settings/print/PrintServiceSettingsFragment.java
index 4629360..1311be0 100644
--- a/src/com/android/settings/print/PrintServiceSettingsFragment.java
+++ b/src/com/android/settings/print/PrintServiceSettingsFragment.java
@@ -22,9 +22,6 @@
 import android.content.Intent;
 import android.content.IntentSender.SendIntentException;
 import android.content.pm.ResolveInfo;
-import android.database.DataSetObserver;
-import android.graphics.Color;
-import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.print.PrintManager;
@@ -44,13 +41,10 @@
 import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityManager;
-import android.widget.AdapterView;
-import android.widget.BaseAdapter;
 import android.widget.Filter;
 import android.widget.Filterable;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
-import android.widget.ListView;
 import android.widget.SearchView;
 import android.widget.Switch;
 import android.widget.TextView;
@@ -67,8 +61,11 @@
 import java.util.List;
 import java.util.Map;
 
+import androidx.annotation.NonNull;
 import androidx.loader.app.LoaderManager;
 import androidx.loader.content.Loader;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.recyclerview.widget.RecyclerView.AdapterDataObserver;
 
 /**
  * Fragment with print service settings.
@@ -77,23 +74,18 @@
         implements SwitchBar.OnSwitchChangeListener,
         LoaderManager.LoaderCallbacks<List<PrintServiceInfo>> {
 
-    private static final String LOG_TAG = "PrintServiceSettingsFragment";
+    private static final String LOG_TAG = "PrintServiceSettings";
 
     private static final int LOADER_ID_PRINTERS_LOADER = 1;
     private static final int LOADER_ID_PRINT_SERVICE_LOADER = 2;
 
-    private final DataSetObserver mDataObserver = new DataSetObserver() {
+    private final AdapterDataObserver mDataObserver = new AdapterDataObserver() {
         @Override
         public void onChanged() {
             invalidateOptionsMenuIfNeeded();
             updateEmptyView();
         }
 
-        @Override
-        public void onInvalidated() {
-            invalidateOptionsMenuIfNeeded();
-        }
-
         private void invalidateOptionsMenuIfNeeded() {
             final int unfilteredItemCount = mPrintersAdapter.getUnfilteredCount();
             if ((mLastUnfilteredItemCount <= 0 && unfilteredItemCount > 0)
@@ -173,8 +165,6 @@
         super.onViewCreated(view, savedInstanceState);
         initComponents();
         updateUiForArguments();
-        getListView().setVisibility(View.GONE);
-        getBackupListView().setVisibility(View.VISIBLE);
     }
 
     @Override
@@ -189,15 +179,11 @@
                 .setPrintServiceEnabled(mComponentName, enabled);
     }
 
-    private ListView getBackupListView() {
-        return (ListView) getView().findViewById(R.id.backup_list);
-    }
-
     private void updateEmptyView() {
         ViewGroup contentRoot = (ViewGroup) getListView().getParent();
-        View emptyView = getBackupListView().getEmptyView();
+        View emptyView = getEmptyView();
         if (!mToggleSwitch.isChecked()) {
-            if (emptyView != null && emptyView.getId() != R.id.empty_print_state) {
+            if (emptyView != null) {
                 contentRoot.removeView(emptyView);
                 emptyView = null;
             }
@@ -209,11 +195,10 @@
                 TextView textView = (TextView) emptyView.findViewById(R.id.message);
                 textView.setText(R.string.print_service_disabled);
                 contentRoot.addView(emptyView);
-                getBackupListView().setEmptyView(emptyView);
+                setEmptyView(emptyView);
             }
         } else if (mPrintersAdapter.getUnfilteredCount() <= 0) {
-            if (emptyView != null
-                    && emptyView.getId() != R.id.empty_printers_list_service_enabled) {
+            if (emptyView != null) {
                 contentRoot.removeView(emptyView);
                 emptyView = null;
             }
@@ -221,10 +206,10 @@
                 emptyView = getActivity().getLayoutInflater().inflate(
                         R.layout.empty_printers_list_service_enabled, contentRoot, false);
                 contentRoot.addView(emptyView);
-                getBackupListView().setEmptyView(emptyView);
+                setEmptyView(emptyView);
             }
-        } else if (mPrintersAdapter.getCount() <= 0) {
-            if (emptyView != null && emptyView.getId() != R.id.empty_print_state) {
+        } else if (mPrintersAdapter.getItemCount() <= 0) {
+            if (emptyView != null) {
                 contentRoot.removeView(emptyView);
                 emptyView = null;
             }
@@ -236,7 +221,11 @@
                 TextView textView = (TextView) emptyView.findViewById(R.id.message);
                 textView.setText(R.string.print_no_printers_found);
                 contentRoot.addView(emptyView);
-                getBackupListView().setEmptyView(emptyView);
+                setEmptyView(emptyView);
+            }
+        } else if (mPrintersAdapter.getItemCount() > 0) {
+            if (emptyView != null) {
+                contentRoot.removeView(emptyView);
             }
         }
     }
@@ -254,7 +243,7 @@
 
     private void initComponents() {
         mPrintersAdapter = new PrintersAdapter();
-        mPrintersAdapter.registerDataSetObserver(mDataObserver);
+        mPrintersAdapter.registerAdapterDataObserver(mDataObserver);
 
         final SettingsActivity activity = (SettingsActivity) getActivity();
 
@@ -263,31 +252,12 @@
         mSwitchBar.show();
 
         mToggleSwitch = mSwitchBar.getSwitch();
-        mToggleSwitch.setOnBeforeCheckedChangeListener(new ToggleSwitch.OnBeforeCheckedChangeListener() {
-            @Override
-            public boolean onBeforeCheckedChanged(ToggleSwitch toggleSwitch, boolean checked) {
-                onPreferenceToggled(mPreferenceKey, checked);
-                return false;
-            }
+        mToggleSwitch.setOnBeforeCheckedChangeListener((toggleSwitch, checked) -> {
+            onPreferenceToggled(mPreferenceKey, checked);
+            return false;
         });
 
-        getBackupListView().setSelector(new ColorDrawable(Color.TRANSPARENT));
-        getBackupListView().setAdapter(mPrintersAdapter);
-        getBackupListView().setOnItemClickListener(new AdapterView.OnItemClickListener() {
-            @Override
-            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-                PrinterInfo printer = (PrinterInfo) mPrintersAdapter.getItem(position);
-
-                if (printer.getInfoIntent() != null) {
-                    try {
-                        getActivity().startIntentSender(printer.getInfoIntent().getIntentSender(),
-                                null, 0, 0, 0);
-                    } catch (SendIntentException e) {
-                        Log.e(LOG_TAG, "Could not execute info intent: %s", e);
-                    }
-                }
-            }
-        });
+        getListView().setAdapter(mPrintersAdapter);
     }
 
 
@@ -446,8 +416,17 @@
         }
     }
 
-    private final class PrintersAdapter extends BaseAdapter
+    public static class ViewHolder extends RecyclerView.ViewHolder {
+
+        public ViewHolder(@NonNull View itemView) {
+            super(itemView);
+        }
+    }
+
+
+    private final class PrintersAdapter extends RecyclerView.Adapter<ViewHolder>
             implements LoaderManager.LoaderCallbacks<List<PrinterInfo>>, Filterable {
+
         private final Object mLock = new Object();
 
         private final List<PrinterInfo> mPrinters = new ArrayList<PrinterInfo>();
@@ -509,19 +488,19 @@
                         }
                     }
                     notifyDataSetChanged();
+
                 }
             };
         }
 
         @Override
-        public int getCount() {
+        public int getItemCount() {
             synchronized (mLock) {
                 return mFilteredPrinters.size();
             }
         }
 
-        @Override
-        public Object getItem(int position) {
+        private Object getItem(int position) {
             synchronized (mLock) {
                 return mFilteredPrinters.get(position);
             }
@@ -543,24 +522,27 @@
             return printer.getStatus() != PrinterInfo.STATUS_UNAVAILABLE;
         }
 
+        @NonNull
         @Override
-        public View getView(int position, View convertView, ViewGroup parent) {
-            if (convertView == null) {
-                convertView = getActivity().getLayoutInflater().inflate(
-                        R.layout.printer_dropdown_item, parent, false);
-            }
+        public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+            final View view = LayoutInflater.from(parent.getContext())
+                    .inflate(R.layout.printer_dropdown_item, parent, false);
+            return new ViewHolder(view);
+        }
 
-            convertView.setEnabled(isActionable(position));
+        @Override
+        public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
+            holder.itemView.setEnabled(isActionable(position));
 
             final PrinterInfo printer = (PrinterInfo) getItem(position);
             CharSequence title = printer.getName();
             CharSequence subtitle = printer.getDescription();
             Drawable icon = printer.loadIcon(getActivity());
 
-            TextView titleView = (TextView) convertView.findViewById(R.id.title);
+            TextView titleView = holder.itemView.findViewById(R.id.title);
             titleView.setText(title);
 
-            TextView subtitleView = (TextView) convertView.findViewById(R.id.subtitle);
+            TextView subtitleView = holder.itemView.findViewById(R.id.subtitle);
             if (!TextUtils.isEmpty(subtitle)) {
                 subtitleView.setText(subtitle);
                 subtitleView.setVisibility(View.VISIBLE);
@@ -569,7 +551,7 @@
                 subtitleView.setVisibility(View.GONE);
             }
 
-            LinearLayout moreInfoView = (LinearLayout) convertView.findViewById(R.id.more_info);
+            LinearLayout moreInfoView = holder.itemView.findViewById(R.id.more_info);
             if (printer.getInfoIntent() != null) {
                 moreInfoView.setVisibility(View.VISIBLE);
                 moreInfoView.setOnClickListener(new OnClickListener() {
@@ -587,7 +569,7 @@
                 moreInfoView.setVisibility(View.GONE);
             }
 
-            ImageView iconView = (ImageView) convertView.findViewById(R.id.icon);
+            ImageView iconView = holder.itemView.findViewById(R.id.icon);
             if (icon != null) {
                 iconView.setVisibility(View.VISIBLE);
                 if (!isActionable(position)) {
@@ -603,7 +585,18 @@
                 iconView.setVisibility(View.GONE);
             }
 
-            return convertView;
+            holder.itemView.setOnClickListener(v -> {
+                PrinterInfo pi = (PrinterInfo) getItem(position);
+
+                if (pi.getInfoIntent() != null) {
+                    try {
+                        getActivity().startIntentSender(pi.getInfoIntent().getIntentSender(),
+                                null, 0, 0, 0);
+                    } catch (SendIntentException e) {
+                        Log.e(LOG_TAG, "Could not execute info intent: %s", e);
+                    }
+                }
+            });
         }
 
         @Override
@@ -642,7 +635,7 @@
                 mFilteredPrinters.clear();
                 mLastSearchString = null;
             }
-            notifyDataSetInvalidated();
+            notifyDataSetChanged();
         }
     }
 
diff --git a/src/com/android/settings/wifi/LongPressAccessPointPreference.java b/src/com/android/settings/wifi/LongPressAccessPointPreference.java
index 579d848..85fd800 100644
--- a/src/com/android/settings/wifi/LongPressAccessPointPreference.java
+++ b/src/com/android/settings/wifi/LongPressAccessPointPreference.java
@@ -28,12 +28,6 @@
     private final Fragment mFragment;
 
     public LongPressAccessPointPreference(AccessPoint accessPoint, Context context,
-            UserBadgeCache cache, boolean forSavedNetworks, Fragment fragment) {
-        super(accessPoint, context, cache, forSavedNetworks);
-        mFragment = fragment;
-    }
-
-    public LongPressAccessPointPreference(AccessPoint accessPoint, Context context,
             UserBadgeCache cache, boolean forSavedNetworks, int iconResId, Fragment fragment) {
         super(accessPoint, context, cache, iconResId, forSavedNetworks);
         mFragment = fragment;
diff --git a/src/com/android/settings/wifi/WifiPickerActivity.java b/src/com/android/settings/wifi/WifiPickerActivity.java
index ca392ce..f7c4f79 100644
--- a/src/com/android/settings/wifi/WifiPickerActivity.java
+++ b/src/com/android/settings/wifi/WifiPickerActivity.java
@@ -21,6 +21,7 @@
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
 import com.android.settings.wifi.p2p.WifiP2pSettings;
+import com.android.settings.wifi.savedaccesspoints.SavedAccessPointsWifiSettings;
 
 import androidx.preference.PreferenceFragmentCompat;
 
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index e5ff3d9..28e10b2 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -231,7 +231,7 @@
 
         Context prefContext = getPrefContext();
         mAddPreference = new Preference(prefContext);
-        mAddPreference.setIcon(R.drawable.ic_menu_add_inset);
+        mAddPreference.setIcon(R.drawable.ic_menu_add);
         mAddPreference.setTitle(R.string.wifi_add_network);
         mStatusMessagePreference = new LinkablePreference(prefContext);
 
diff --git a/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsPreferenceController.java b/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsPreferenceController.java
new file mode 100644
index 0000000..a7c4038
--- /dev/null
+++ b/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsPreferenceController.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2018 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.wifi.savedaccesspoints;
+
+
+import android.content.Context;
+
+import com.android.settings.core.BasePreferenceController;
+
+/**
+ * Controller that manages a PrferenceGroup, which contains a list of saved access points.
+ */
+public class SavedAccessPointsPreferenceController extends BasePreferenceController {
+
+    public SavedAccessPointsPreferenceController(Context context,
+            String preferenceKey) {
+        super(context, preferenceKey);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return AVAILABLE;
+    }
+}
diff --git a/src/com/android/settings/wifi/SavedAccessPointsWifiSettings.java b/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsWifiSettings.java
similarity index 76%
rename from src/com/android/settings/wifi/SavedAccessPointsWifiSettings.java
rename to src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsWifiSettings.java
index ebb493c..930cd85 100644
--- a/src/com/android/settings/wifi/SavedAccessPointsWifiSettings.java
+++ b/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsWifiSettings.java
@@ -14,58 +14,44 @@
  * limitations under the License.
  */
 
-package com.android.settings.wifi;
+package com.android.settings.wifi.savedaccesspoints;
 
 import android.annotation.Nullable;
 import android.app.Activity;
 import android.app.Dialog;
 import android.content.Context;
-import android.icu.text.Collator;
 import android.net.wifi.WifiManager;
 import android.os.Bundle;
 import android.os.Handler;
 import android.util.Log;
 import android.widget.Toast;
 
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.search.Indexable;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.wifi.WifiConfigUiBase;
+import com.android.settings.wifi.WifiDialog;
+import com.android.settings.wifi.WifiSettings;
 import com.android.settingslib.wifi.AccessPoint;
 import com.android.settingslib.wifi.AccessPointPreference;
 import com.android.settingslib.wifi.WifiSavedConfigUtils;
 
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.List;
 
-import androidx.annotation.VisibleForTesting;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
-
 /**
  * UI to manage saved networks/access points.
- * TODO(b/64806699): convert to {@link DashboardFragment} with {@link PreferenceController}s
  */
-public class SavedAccessPointsWifiSettings extends SettingsPreferenceFragment
-        implements Indexable, WifiDialog.WifiDialogListener {
+public class SavedAccessPointsWifiSettings extends DashboardFragment
+        implements WifiDialog.WifiDialogListener {
     private static final String TAG = "SavedAccessPoints";
     @VisibleForTesting
     static final int MSG_UPDATE_PREFERENCES = 1;
-    private static final Comparator<AccessPoint> SAVED_NETWORK_COMPARATOR =
-            new Comparator<AccessPoint>() {
-        final Collator mCollator = Collator.getInstance();
-        @Override
-        public int compare(AccessPoint ap1, AccessPoint ap2) {
-            return mCollator.compare(
-                    nullToEmpty(ap1.getConfigName()), nullToEmpty(ap2.getConfigName()));
-        }
-
-        private String nullToEmpty(String string) {
-            return (string == null) ? "" : string;
-        }
-    };
 
     @VisibleForTesting
     final WifiManager.ActionListener mForgetListener = new WifiManager.ActionListener() {
@@ -95,13 +81,14 @@
         public void onSuccess() {
             postUpdatePreference();
         }
+
         @Override
         public void onFailure(int reason) {
             Activity activity = getActivity();
             if (activity != null) {
                 Toast.makeText(activity,
-                    R.string.wifi_failed_save_message,
-                    Toast.LENGTH_SHORT).show();
+                        R.string.wifi_failed_save_message,
+                        Toast.LENGTH_SHORT).show();
             }
         }
     };
@@ -111,7 +98,6 @@
     private AccessPoint mDlgAccessPoint;
     private Bundle mAccessPointSavedState;
     private AccessPoint mSelectedAccessPoint;
-    private Preference mAddNetworkPreference;
 
     private AccessPointPreference.UserBadgeCache mUserBadgeCache;
 
@@ -124,9 +110,18 @@
     }
 
     @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        addPreferencesFromResource(R.xml.wifi_display_saved_access_points);
+    protected int getPreferenceScreenResId() {
+        return R.xml.wifi_display_saved_access_points;
+    }
+
+    @Override
+    protected String getLogTag() {
+        return TAG;
+    }
+
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
         mUserBadgeCache = new AccessPointPreference.UserBadgeCache(getPackageManager());
     }
 
@@ -139,12 +134,13 @@
     @Override
     public void onActivityCreated(Bundle savedInstanceState) {
         super.onActivityCreated(savedInstanceState);
-        mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
+        mWifiManager = (WifiManager) getContext()
+                .getApplicationContext().getSystemService(Context.WIFI_SERVICE);
 
         if (savedInstanceState != null) {
             if (savedInstanceState.containsKey(SAVE_DIALOG_ACCESS_POINT_STATE)) {
                 mAccessPointSavedState =
-                    savedInstanceState.getBundle(SAVE_DIALOG_ACCESS_POINT_STATE);
+                        savedInstanceState.getBundle(SAVE_DIALOG_ACCESS_POINT_STATE);
             }
         }
     }
@@ -155,18 +151,17 @@
 
         final List<AccessPoint> accessPoints =
                 WifiSavedConfigUtils.getAllConfigs(context, mWifiManager);
-        Collections.sort(accessPoints, SAVED_NETWORK_COMPARATOR);
+        Collections.sort(accessPoints, SavedNetworkComparator.INSTANCE);
         cacheRemoveAllPrefs(preferenceScreen);
 
         final int accessPointsSize = accessPoints.size();
         for (int i = 0; i < accessPointsSize; ++i) {
             AccessPoint ap = accessPoints.get(i);
             String key = ap.getKey();
-            LongPressAccessPointPreference preference =
-                    (LongPressAccessPointPreference) getCachedPreference(key);
+            AccessPointPreference preference =
+                    (AccessPointPreference) getCachedPreference(key);
             if (preference == null) {
-                preference = new LongPressAccessPointPreference(
-                        ap, context, mUserBadgeCache, true, this);
+                preference = new AccessPointPreference(ap, context, mUserBadgeCache, true);
                 preference.setKey(key);
                 preference.setIcon(null);
                 preferenceScreen.addPreference(preference);
@@ -176,15 +171,7 @@
 
         removeCachedPrefs(preferenceScreen);
 
-        if (mAddNetworkPreference == null) {
-            mAddNetworkPreference = new Preference(getPrefContext());
-            mAddNetworkPreference.setIcon(R.drawable.ic_menu_add_inset);
-            mAddNetworkPreference.setTitle(R.string.wifi_add_network);
-        }
-        mAddNetworkPreference.setOrder(accessPointsSize);
-        preferenceScreen.addPreference(mAddNetworkPreference);
-
-        if(getPreferenceScreen().getPreferenceCount() < 1) {
+        if (getPreferenceScreen().getPreferenceCount() < 1) {
             Log.w(TAG, "Saved networks activity loaded, but there are no saved networks!");
         }
     }
@@ -195,7 +182,7 @@
         }
     }
 
-    private void showWifiDialog(@Nullable LongPressAccessPointPreference accessPoint) {
+    private void showWifiDialog(@Nullable AccessPointPreference accessPoint) {
         if (mDialog != null) {
             removeDialog(WifiSettings.WIFI_DIALOG_ID);
             mDialog = null;
@@ -290,11 +277,8 @@
 
     @Override
     public boolean onPreferenceTreeClick(Preference preference) {
-        if (preference instanceof LongPressAccessPointPreference) {
-            showWifiDialog((LongPressAccessPointPreference) preference);
-            return true;
-        } else if (preference == mAddNetworkPreference) {
-            showWifiDialog(null);
+        if (preference instanceof AccessPointPreference) {
+            showWifiDialog((AccessPointPreference) preference);
             return true;
         } else {
             return super.onPreferenceTreeClick(preference);
diff --git a/src/com/android/settings/wifi/savedaccesspoints/SavedNetworkComparator.java b/src/com/android/settings/wifi/savedaccesspoints/SavedNetworkComparator.java
new file mode 100644
index 0000000..cff4387
--- /dev/null
+++ b/src/com/android/settings/wifi/savedaccesspoints/SavedNetworkComparator.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2018 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.wifi.savedaccesspoints;
+
+import android.icu.text.Collator;
+
+import com.android.settingslib.wifi.AccessPoint;
+
+import java.util.Comparator;
+
+public final class SavedNetworkComparator {
+    public static final Comparator<AccessPoint> INSTANCE =
+            new Comparator<AccessPoint>() {
+                final Collator mCollator = Collator.getInstance();
+
+                @Override
+                public int compare(AccessPoint ap1, AccessPoint ap2) {
+                    return mCollator.compare(
+                            nullToEmpty(ap1.getConfigName()), nullToEmpty(ap2.getConfigName()));
+                }
+
+                private String nullToEmpty(String string) {
+                    return (string == null) ? "" : string;
+                }
+            };
+}
diff --git a/tests/robotests/assets/grandfather_not_implementing_index_provider b/tests/robotests/assets/grandfather_not_implementing_index_provider
index 48c9de9..37869e9 100644
--- a/tests/robotests/assets/grandfather_not_implementing_index_provider
+++ b/tests/robotests/assets/grandfather_not_implementing_index_provider
@@ -73,5 +73,5 @@
 com.android.settings.wifi.ChangeWifiStateDetails
 com.android.settings.wifi.details.WifiNetworkDetailsFragment
 com.android.settings.wifi.p2p.WifiP2pSettings
-com.android.settings.wifi.SavedAccessPointsWifiSettings
+com.android.settings.wifi.savedaccesspoints.SavedAccessPointsWifiSettings
 com.android.settings.wifi.WifiInfo
diff --git a/tests/robotests/assets/grandfather_not_implementing_instrumentable b/tests/robotests/assets/grandfather_not_implementing_instrumentable
index 27ab65c..2c8ae5d 100644
--- a/tests/robotests/assets/grandfather_not_implementing_instrumentable
+++ b/tests/robotests/assets/grandfather_not_implementing_instrumentable
@@ -5,5 +5,4 @@
 com.android.settings.password.ChooseLockPattern$SaveAndFinishWorker
 com.android.settings.RestrictedListPreference$RestrictedListPreferenceDialogFragment
 com.android.settings.password.ConfirmDeviceCredentialBaseFragment$LastTryDialog
-com.android.settings.password.CredentialCheckResultTracker
-com.android.settings.localepicker.LocalePickerWithRegion
+com.android.settings.password.CredentialCheckResultTracker
\ No newline at end of file
diff --git a/tests/robotests/res/values/themes.xml b/tests/robotests/res/values/themes.xml
index 74bdd9b..9a247f6 100644
--- a/tests/robotests/res/values/themes.xml
+++ b/tests/robotests/res/values/themes.xml
@@ -1,5 +1,8 @@
 <resources>
-    <style name="Theme.Settings" parent="@android:style/Theme.DeviceDefault.Settings" />
+    <style name="Theme.Settings" parent="@android:style/Theme.DeviceDefault.Settings">
+        <!-- For AndroidX AlertDialogs -->
+        <item name="alertDialogTheme">@style/Theme.AppCompat.DayNight.Dialog.Alert</item>
+    </style>
 
     <!-- Override the main app's style for ActionPrimaryButton to get around lack of new style
          support in robolectric  -->
diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultPhonePickerTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultPhonePickerTest.java
index f304b49..57d31cf 100644
--- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultPhonePickerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultPhonePickerTest.java
@@ -29,6 +29,7 @@
 import android.content.pm.PackageManager;
 import android.os.UserManager;
 
+import com.android.settings.fuelgauge.BatteryUtils;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
 import org.junit.Before;
@@ -53,6 +54,8 @@
     private DefaultPhonePicker.DefaultKeyUpdater mDefaultKeyUpdater;
     @Mock
     private PackageManager mPackageManager;
+    @Mock
+    private BatteryUtils mBatteryUtils;
 
     private DefaultPhonePicker mPicker;
 
@@ -66,6 +69,7 @@
 
         ReflectionHelpers.setField(mPicker, "mPm", mPackageManager);
         ReflectionHelpers.setField(mPicker, "mDefaultKeyUpdater", mDefaultKeyUpdater);
+        ReflectionHelpers.setField(mPicker, "mBatteryUtils", mBatteryUtils);
         doReturn(RuntimeEnvironment.application).when(mPicker).getContext();
     }
 
@@ -87,6 +91,14 @@
     @Test
     public void getDefaultAppKey_shouldReturnDefault() {
         mPicker.getDefaultKey();
+
         verify(mDefaultKeyUpdater).getDefaultDialerApplication(any(Context.class), anyInt());
     }
+
+    @Test
+    public void setDefaultKey_shouldUnrestrictApp() {
+        mPicker.setDefaultKey(TEST_APP_KEY);
+
+        verify(mBatteryUtils).clearForceAppStandby(TEST_APP_KEY);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultSmsPickerTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultSmsPickerTest.java
index 18bb60e..ade62a1 100644
--- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultSmsPickerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultSmsPickerTest.java
@@ -28,6 +28,7 @@
 import android.content.pm.PackageManager;
 import android.os.UserManager;
 
+import com.android.settings.fuelgauge.BatteryUtils;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
 import org.junit.Before;
@@ -52,6 +53,8 @@
     private DefaultSmsPicker.DefaultKeyUpdater mDefaultKeyUpdater;
     @Mock
     private PackageManager mPackageManager;
+    @Mock
+    private BatteryUtils mBatteryUtils;
 
     private DefaultSmsPicker mPicker;
 
@@ -64,6 +67,7 @@
 
         ReflectionHelpers.setField(mPicker, "mPm", mPackageManager);
         ReflectionHelpers.setField(mPicker, "mDefaultKeyUpdater", mDefaultKeyUpdater);
+        ReflectionHelpers.setField(mPicker, "mBatteryUtils", mBatteryUtils);
         doReturn(RuntimeEnvironment.application).when(mPicker).getContext();
     }
 
@@ -80,4 +84,11 @@
 
         verify(mDefaultKeyUpdater).getDefaultApplication(any(Context.class));
     }
+
+    @Test
+    public void setDefaultKey_shouldUnrestrictApp() {
+        mPicker.setDefaultKey(TEST_APP_KEY);
+
+        verify(mBatteryUtils).clearForceAppStandby(TEST_APP_KEY);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAddTest.java b/tests/robotests/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAddTest.java
index e85f3f6..6bc143c 100644
--- a/tests/robotests/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAddTest.java
+++ b/tests/robotests/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAddTest.java
@@ -17,9 +17,13 @@
 package com.android.settings.applications.specialaccess.deviceadmin;
 
 import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -39,6 +43,7 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.Robolectric;
+import org.robolectric.RuntimeEnvironment;
 
 @RunWith(SettingsRobolectricTestRunner.class)
 public class DeviceAdminAddTest {
@@ -47,7 +52,6 @@
 
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private DeviceAdminInfo mDeviceAdmin;
-    @Mock
     private BatteryUtils mBatteryUtils;
     private FakeFeatureFactory mFeatureFactory;
     private DeviceAdminAdd mDeviceAdminAdd;
@@ -56,6 +60,8 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
 
+        mBatteryUtils = spy(BatteryUtils.getInstance(RuntimeEnvironment.application));
+        doNothing().when(mBatteryUtils).setForceAppStandby(anyInt(), anyString(), anyInt());
         mFeatureFactory = FakeFeatureFactory.setupForTest();
         mDeviceAdminAdd = Robolectric.buildActivity(DeviceAdminAdd.class).get();
 
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
index 238a88b..df34b78 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
@@ -653,4 +653,35 @@
         assertThat(mBatteryUtils.shouldHideAnomaly(mPowerWhitelistBackend, UID,
                 mAnomalyInfo)).isTrue();
     }
+
+    @Test
+    public void clearForceAppStandby_appRestricted_clearAndReturnTrue() {
+        when(mBatteryUtils.getPackageUid(HIGH_SDK_PACKAGE)).thenReturn(UID);
+        when(mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID,
+                HIGH_SDK_PACKAGE)).thenReturn(AppOpsManager.MODE_IGNORED);
+
+        assertThat(mBatteryUtils.clearForceAppStandby(HIGH_SDK_PACKAGE)).isTrue();
+        verify(mAppOpsManager).setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID,
+                HIGH_SDK_PACKAGE, AppOpsManager.MODE_ALLOWED);
+    }
+
+    @Test
+    public void clearForceAppStandby_appInvalid_returnFalse() {
+        when(mBatteryUtils.getPackageUid(PACKAGE_NAME)).thenReturn(BatteryUtils.UID_NULL);
+
+        assertThat(mBatteryUtils.clearForceAppStandby(PACKAGE_NAME)).isFalse();
+        verify(mAppOpsManager, never()).setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID,
+                PACKAGE_NAME, AppOpsManager.MODE_ALLOWED);
+    }
+
+    @Test
+    public void clearForceAppStandby_appUnrestricted_returnFalse() {
+        when(mBatteryUtils.getPackageUid(PACKAGE_NAME)).thenReturn(UID);
+        when(mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID,
+                PACKAGE_NAME)).thenReturn(AppOpsManager.MODE_ALLOWED);
+
+        assertThat(mBatteryUtils.clearForceAppStandby(PACKAGE_NAME)).isFalse();
+        verify(mAppOpsManager, never()).setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID,
+                PACKAGE_NAME, AppOpsManager.MODE_ALLOWED);
+    }
 }
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 b0d6a7d..3ada030 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoaderTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoaderTest.java
@@ -28,9 +28,13 @@
 import com.android.internal.os.BatteryStatsHelper;
 import com.android.settings.fuelgauge.BatteryInfo;
 import com.android.settings.fuelgauge.BatteryUtils;
+import com.android.settings.fuelgauge.batterytip.tips.AppLabelPredicate;
+import com.android.settings.fuelgauge.batterytip.tips.AppRestrictionPredicate;
 import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
+import com.android.settings.testutils.BatteryTestUtils;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -77,6 +81,12 @@
         mBatteryTipLoader.mBatteryUtils = mBatteryUtils;
     }
 
+    @After
+    public void tearDown() {
+        BatteryTestUtils.clearStaticInstance(AppLabelPredicate.class, "sInstance");
+        BatteryTestUtils.clearStaticInstance(AppRestrictionPredicate.class, "sInstance");
+    }
+
     @Test
     public void testLoadBackground_containsAllTipsWithOrder() {
         final List<BatteryTip> batteryTips = mBatteryTipLoader.loadInBackground();
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicyTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicyTest.java
index 547e0eb..053a716 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicyTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicyTest.java
@@ -49,7 +49,8 @@
             + ",test_battery_saver_tip=true"
             + ",test_high_usage_tip=false"
             + ",test_smart_battery_tip=true"
-            + ",test_low_battery_tip=true";
+            + ",test_low_battery_tip=true"
+            + ",app_restriction_active_hour=6";
     private Context mContext;
 
     @Before
@@ -72,6 +73,7 @@
         assertThat(batteryTipPolicy.highUsagePeriodMs).isEqualTo(2000);
         assertThat(batteryTipPolicy.highUsageBatteryDraining).isEqualTo(30);
         assertThat(batteryTipPolicy.appRestrictionEnabled).isTrue();
+        assertThat(batteryTipPolicy.appRestrictionActiveHour).isEqualTo(6);
         assertThat(batteryTipPolicy.reducedBatteryEnabled).isTrue();
         assertThat(batteryTipPolicy.reducedBatteryPercent).isEqualTo(30);
         assertThat(batteryTipPolicy.lowBatteryEnabled).isFalse();
@@ -99,6 +101,7 @@
         assertThat(batteryTipPolicy.highUsagePeriodMs).isEqualTo(2 * DateUtils.HOUR_IN_MILLIS);
         assertThat(batteryTipPolicy.highUsageBatteryDraining).isEqualTo(25);
         assertThat(batteryTipPolicy.appRestrictionEnabled).isTrue();
+        assertThat(batteryTipPolicy.appRestrictionActiveHour).isEqualTo(24);
         assertThat(batteryTipPolicy.reducedBatteryEnabled).isFalse();
         assertThat(batteryTipPolicy.reducedBatteryPercent).isEqualTo(50);
         assertThat(batteryTipPolicy.lowBatteryEnabled).isTrue();
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipUtilsTest.java
index 459c4e2..3882e8c 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipUtilsTest.java
@@ -17,6 +17,7 @@
 package com.android.settings.fuelgauge.batterytip;
 
 import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/RestrictAppDetectorTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/RestrictAppDetectorTest.java
index 9b0007b..179f2a1 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/RestrictAppDetectorTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/RestrictAppDetectorTest.java
@@ -34,8 +34,11 @@
 import com.android.settings.fuelgauge.batterytip.AppInfo;
 import com.android.settings.fuelgauge.batterytip.BatteryDatabaseManager;
 import com.android.settings.fuelgauge.batterytip.BatteryTipPolicy;
+import com.android.settings.fuelgauge.batterytip.tips.AppLabelPredicate;
+import com.android.settings.fuelgauge.batterytip.tips.AppRestrictionPredicate;
 import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
 import com.android.settings.fuelgauge.batterytip.tips.RestrictAppTip;
+import com.android.settings.testutils.BatteryTestUtils;
 import com.android.settings.testutils.DatabaseTestUtils;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
@@ -86,6 +89,7 @@
         mContext = spy(RuntimeEnvironment.application);
         mPolicy = spy(new BatteryTipPolicy(mContext));
 
+        doReturn(mContext).when(mContext).getApplicationContext();
         doReturn(mAppOpsManager).when(mContext).getSystemService(AppOpsManager.class);
         doReturn(AppOpsManager.MODE_IGNORED).when(mAppOpsManager).checkOpNoThrow(
                 AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, RESTRICTED_UID, RESTRICTED_PACKAGE_NAME);
@@ -103,7 +107,12 @@
 
         mRestrictAppDetector = new RestrictAppDetector(mContext, mPolicy);
         mRestrictAppDetector.mBatteryDatabaseManager = mBatteryDatabaseManager;
+    }
 
+    @After
+    public void tearDown() {
+        BatteryTestUtils.clearStaticInstance(AppLabelPredicate.class, "sInstance");
+        BatteryTestUtils.clearStaticInstance(AppRestrictionPredicate.class, "sInstance");
     }
 
     @After
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/RestrictAppTipTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/RestrictAppTipTest.java
index 5c8b7d9..dd3e281 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/RestrictAppTipTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/RestrictAppTipTest.java
@@ -34,9 +34,11 @@
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
 import com.android.settings.fuelgauge.batterytip.AppInfo;
+import com.android.settings.testutils.BatteryTestUtils;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -74,6 +76,7 @@
         MockitoAnnotations.initMocks(this);
 
         mContext = spy(RuntimeEnvironment.application);
+        doReturn(mContext).when(mContext).getApplicationContext();
         doReturn(mPackageManager).when(mContext).getPackageManager();
         doReturn(mApplicationInfo).when(mPackageManager).getApplicationInfo(PACKAGE_NAME,
                 PackageManager.MATCH_DISABLED_COMPONENTS | PackageManager.MATCH_ANY_USER);
@@ -98,6 +101,12 @@
         mInvisibleBatteryTip = new RestrictAppTip(BatteryTip.StateType.INVISIBLE, new ArrayList<>());
     }
 
+    @After
+    public void tearDown() {
+        BatteryTestUtils.clearStaticInstance(AppLabelPredicate.class, "sInstance");
+        BatteryTestUtils.clearStaticInstance(AppRestrictionPredicate.class, "sInstance");
+    }
+
     @Test
     public void parcelable() {
         Parcel parcel = Parcel.obtain();
diff --git a/tests/robotests/src/com/android/settings/localepicker/LocalePickerWithRegionActivityTest.java b/tests/robotests/src/com/android/settings/localepicker/LocalePickerWithRegionActivityTest.java
new file mode 100644
index 0000000..bad3dbd
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/localepicker/LocalePickerWithRegionActivityTest.java
@@ -0,0 +1,51 @@
+package com.android.settings.localepicker;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+
+import android.app.Activity;
+
+import com.android.internal.app.LocaleStore;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
+import org.robolectric.Shadows;
+import org.robolectric.android.controller.ActivityController;
+import org.robolectric.shadows.ShadowActivity;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class LocalePickerWithRegionActivityTest {
+
+    private LocalePickerWithRegionActivity mActivity;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        final ActivityController<LocalePickerWithRegionActivity> mActivityController =
+                Robolectric.buildActivity(LocalePickerWithRegionActivity.class);
+        mActivity = spy(mActivityController.get());
+    }
+
+    @Test
+    public void onLocaleSelected_resultShouldBeOK() {
+        final ShadowActivity shadowActivity = Shadows.shadowOf(mActivity);
+        mActivity.onLocaleSelected(mock(LocaleStore.LocaleInfo.class));
+
+        assertEquals(Activity.RESULT_OK, shadowActivity.getResultCode());
+    }
+
+    @Test
+    public void onLocaleSelected_localeInfoShouldBeSentBack() {
+        final ShadowActivity shadowActivity = Shadows.shadowOf(mActivity);
+        mActivity.onLocaleSelected(mock(LocaleStore.LocaleInfo.class));
+
+        assertNotNull(shadowActivity.getResultIntent().getSerializableExtra(
+                LocaleListEditor.INTENT_LOCALE_KEY));
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/location/InjectedSettingTest.java b/tests/robotests/src/com/android/settings/location/InjectedSettingTest.java
deleted file mode 100644
index 5045837..0000000
--- a/tests/robotests/src/com/android/settings/location/InjectedSettingTest.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2018 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 static com.google.common.truth.Truth.assertThat;
-
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-public final class InjectedSettingTest {
-
-    private static final String TEST_STRING = "test";
-
-    @Test
-    public void buildWithoutPackageName_ShouldReturnNull() {
-        assertThat(((new InjectedSetting.Builder())
-                .setClassName(TEST_STRING)
-                .setTitle(TEST_STRING)
-                .setSettingsActivity(TEST_STRING).build())).isNull();
-    }
-
-    private InjectedSetting getTestSetting() {
-        return new InjectedSetting.Builder()
-                .setPackageName(TEST_STRING)
-                .setClassName(TEST_STRING)
-                .setTitle(TEST_STRING)
-                .setSettingsActivity(TEST_STRING).build();
-    }
-
-    @Test
-    public void testEquals() {
-        InjectedSetting setting1 = getTestSetting();
-        InjectedSetting setting2 = getTestSetting();
-        assertThat(setting1).isEqualTo(setting2);
-    }
-
-    @Test
-    public void testHashCode() {
-        InjectedSetting setting = getTestSetting();
-        assertThat(setting.hashCode()).isEqualTo(1225314048);
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/location/LocationServicePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/LocationServicePreferenceControllerTest.java
index ba5decc..f0904d0 100644
--- a/tests/robotests/src/com/android/settings/location/LocationServicePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/location/LocationServicePreferenceControllerTest.java
@@ -67,7 +67,7 @@
     @Mock
     private PreferenceScreen mScreen;
     @Mock
-    private SettingsInjector mSettingsInjector;
+    private AppSettingsInjector mSettingsInjector;
     @Mock
     private DevicePolicyManager mDevicePolicyManager;
 
diff --git a/tests/robotests/src/com/android/settings/password/ChooseLockTypeDialogFragmentTest.java b/tests/robotests/src/com/android/settings/password/ChooseLockTypeDialogFragmentTest.java
index f76a5ca..5068f85 100644
--- a/tests/robotests/src/com/android/settings/password/ChooseLockTypeDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/password/ChooseLockTypeDialogFragmentTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Google Inc.
+ * Copyright (C) 2017 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,38 +16,33 @@
 
 package com.android.settings.password;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
+import static com.google.common.truth.Truth.assertThat;
 import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
-import android.app.AlertDialog;
 import android.content.Context;
 
 import com.android.settings.R;
 import com.android.settings.password.ChooseLockTypeDialogFragment.OnLockTypeSelectedListener;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settings.testutils.shadow.ShadowUserManager;
-import com.android.settings.testutils.shadow.ShadowUtils;
+import com.android.settings.testutils.shadow.SettingsShadowResourcesImpl;
+import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
 import com.android.settingslib.testutils.FragmentTestUtils;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.RuntimeEnvironment;
-import org.robolectric.Shadows;
 import org.robolectric.annotation.Config;
-import org.robolectric.shadows.ShadowAlertDialog;
-import org.robolectric.shadows.ShadowDialog;
 
+import androidx.appcompat.app.AlertDialog;
 import androidx.fragment.app.Fragment;
 
 @RunWith(SettingsRobolectricTestRunner.class)
-@Config(shadows = {ShadowUserManager.class, ShadowUtils.class})
+@Config(shadows = {SettingsShadowResourcesImpl.class, ShadowAlertDialogCompat.class})
 public class ChooseLockTypeDialogFragmentTest {
 
     private Context mContext;
@@ -61,32 +56,36 @@
     }
 
     @Test
-    @Ignore("b/111247403")
     public void testThatDialog_IsShown() {
         AlertDialog latestDialog = startLockFragment();
-        assertNotNull(latestDialog);
-        ShadowDialog shadowDialog = Shadows.shadowOf(latestDialog);
+        ShadowAlertDialogCompat shadowAlertDialog = ShadowAlertDialogCompat.shadowOf(
+                latestDialog);
+
+        assertThat(latestDialog).isNotNull();
+        assertThat(latestDialog.isShowing()).isTrue();
         // verify that we are looking at the expected dialog.
-        assertEquals(shadowDialog.getTitle(),
+        assertThat(shadowAlertDialog.getTitle()).isEqualTo(
                 mContext.getString(R.string.setup_lock_settings_options_dialog_title));
     }
 
     @Test
-    @Ignore("b/111247403")
     public void testThat_OnClickListener_IsCalled() {
         mFragment.mDelegate = mock(OnLockTypeSelectedListener.class);
         AlertDialog lockDialog = startLockFragment();
-        ShadowAlertDialog shadowAlertDialog = Shadows.shadowOf(lockDialog);
+        ShadowAlertDialogCompat shadowAlertDialog = ShadowAlertDialogCompat.shadowOf(lockDialog);
+
         shadowAlertDialog.clickOnItem(0);
+
         verify(mFragment.mDelegate, times(1)).onLockTypeSelected(any(ScreenLockType.class));
     }
 
     @Test
-    @Ignore("b/111247403")
     public void testThat_OnClickListener_IsNotCalledWhenCancelled() {
         mFragment.mDelegate = mock(OnLockTypeSelectedListener.class);
         AlertDialog lockDialog = startLockFragment();
+
         lockDialog.dismiss();
+
         verify(mFragment.mDelegate, never()).onLockTypeSelected(any(ScreenLockType.class));
     }
 
@@ -94,7 +93,7 @@
         ChooseLockTypeDialogFragment chooseLockTypeDialogFragment =
                 ChooseLockTypeDialogFragment.newInstance(1234);
         chooseLockTypeDialogFragment.show(mFragment.getChildFragmentManager(), null);
-        return ShadowAlertDialog.getLatestAlertDialog();
+        return ShadowAlertDialogCompat.getLatestAlertDialog();
     }
 
     public static class TestFragment extends Fragment implements OnLockTypeSelectedListener {
diff --git a/tests/robotests/src/com/android/settings/password/ConfirmCredentialTest.java b/tests/robotests/src/com/android/settings/password/ConfirmCredentialTest.java
index 636248a..37c972a 100644
--- a/tests/robotests/src/com/android/settings/password/ConfirmCredentialTest.java
+++ b/tests/robotests/src/com/android/settings/password/ConfirmCredentialTest.java
@@ -20,25 +20,20 @@
 
 import com.android.settings.password.ConfirmDeviceCredentialBaseFragment.LastTryDialog;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settings.testutils.shadow.SettingsShadowResources;
 
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.Robolectric;
-import org.robolectric.annotation.Config;
 
 import androidx.fragment.app.FragmentActivity;
 import androidx.fragment.app.FragmentManager;
 
 @RunWith(SettingsRobolectricTestRunner.class)
-@Config(shadows = SettingsShadowResources.SettingsShadowTheme.class)
 public class ConfirmCredentialTest {
     @Test
-    @Ignore("b/111193572")
     public void testLastTryDialogShownExactlyOnce() {
         FragmentManager fm = Robolectric.buildActivity(FragmentActivity.class).
-                get().getSupportFragmentManager();
+                setup().get().getSupportFragmentManager();
 
         // Launch only one instance at a time.
         assertThat(LastTryDialog.show(
diff --git a/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java b/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java
index 2bdab27..eed2009 100644
--- a/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java
+++ b/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java
@@ -19,6 +19,8 @@
 import android.content.Intent;
 import android.os.BatteryManager;
 
+import java.lang.reflect.Field;
+
 public class BatteryTestUtils {
 
     public static Intent getChargingIntent() {
@@ -47,4 +49,15 @@
         return intent;
     }
 
+    public static void clearStaticInstance(Class clazz, String fieldName) {
+        Field instance;
+        try {
+            instance = clazz.getDeclaredField(fieldName);
+            instance.setAccessible(true);
+            instance.set(null, null);
+        } catch (Exception e) {
+            throw new RuntimeException();
+        }
+    }
+
 }
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/SettingsShadowResourcesImpl.java b/tests/robotests/src/com/android/settings/testutils/shadow/SettingsShadowResourcesImpl.java
index 9fb69a3..dd51687 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/SettingsShadowResourcesImpl.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/SettingsShadowResourcesImpl.java
@@ -43,7 +43,8 @@
         // that Robolectric isn't yet aware of.
         // TODO: Remove this once Robolectric is updated.
         if (id == R.drawable.switchbar_background
-                || id == R.color.ripple_material_light) {
+                || id == R.color.ripple_material_light
+                || id == R.color.ripple_material_dark) {
             return new ColorDrawable();
         } else if (id == R.drawable.ic_launcher_settings) {
             // ic_launcher_settings uses adaptive-icon, which is not supported by robolectric,
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/SettingsShadowTypedArray.java b/tests/robotests/src/com/android/settings/testutils/shadow/SettingsShadowTypedArray.java
new file mode 100644
index 0000000..fc3ff0c
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/SettingsShadowTypedArray.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2018 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.testutils.shadow;
+
+import static org.robolectric.shadow.api.Shadow.directlyOn;
+
+import android.content.res.ColorStateList;
+import android.content.res.TypedArray;
+import android.graphics.Color;
+
+import androidx.annotation.Nullable;
+import androidx.annotation.StyleableRes;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.RealObject;
+import org.robolectric.shadows.ShadowTypedArray;
+
+@Implements(value = TypedArray.class, inheritImplementationMethods = true)
+public class SettingsShadowTypedArray extends ShadowTypedArray {
+
+    @RealObject
+    TypedArray realTypedArray;
+
+    @Implementation
+    @Nullable
+    public ColorStateList getColorStateList(@StyleableRes int index) {
+        if (index == com.android.internal.R.styleable.TextView_textColorLink) {
+            return ColorStateList.valueOf(Color.WHITE);
+        }
+        return directlyOn(realTypedArray, TypedArray.class).getColorStateList(index);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowAlertDialogCompat.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowAlertDialogCompat.java
new file mode 100644
index 0000000..a682d85
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowAlertDialogCompat.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2018 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.testutils.shadow;
+
+import android.annotation.SuppressLint;
+import android.view.View;
+
+import org.robolectric.Shadows;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.RealObject;
+import org.robolectric.annotation.Resetter;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowDialog;
+import org.robolectric.util.ReflectionHelpers;
+
+import javax.annotation.Nullable;
+
+import androidx.appcompat.app.AlertDialog;
+
+/* Robolectric shadow for the androidx alert dialog. */
+@Implements(AlertDialog.class)
+public class ShadowAlertDialogCompat extends ShadowDialog {
+
+    @SuppressLint("StaticFieldLeak")
+    @Nullable
+    private static ShadowAlertDialogCompat latestSupportAlertDialog;
+    @RealObject
+    private AlertDialog realAlertDialog;
+
+    @Implementation
+    public void show() {
+        super.show();
+        latestSupportAlertDialog = this;
+    }
+
+    public CharSequence getMessage() {
+        final Object alertController = ReflectionHelpers.getField(realAlertDialog, "mAlert");
+        return ReflectionHelpers.getField(alertController, "mMessage");
+    }
+
+    public CharSequence getTitle() {
+        final Object alertController = ReflectionHelpers.getField(realAlertDialog, "mAlert");
+        return ReflectionHelpers.getField(alertController, "mTitle");
+    }
+
+    public View getView() {
+        final Object alertController = ReflectionHelpers.getField(realAlertDialog, "mAlert");
+        return ReflectionHelpers.getField(alertController, "mView");
+    }
+
+    @Nullable
+    public static AlertDialog getLatestAlertDialog() {
+        return latestSupportAlertDialog == null ? null : latestSupportAlertDialog.realAlertDialog;
+    }
+
+    @Resetter
+    public static void reset() {
+        latestSupportAlertDialog = null;
+    }
+
+    public static ShadowAlertDialogCompat shadowOf(AlertDialog alertDialog) {
+        return (ShadowAlertDialogCompat) Shadow.extract(alertDialog);
+    }
+
+    public void clickOnItem(int index) {
+        Shadows.shadowOf(realAlertDialog.getListView()).performItemClick(index);
+    }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiDialogActivityTest.java b/tests/robotests/src/com/android/settings/wifi/WifiDialogActivityTest.java
index 8cdecff..b40ea2e 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiDialogActivityTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiDialogActivityTest.java
@@ -17,6 +17,7 @@
 package com.android.settings.wifi;
 
 import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.Mockito.doReturn;
 
 import android.content.Intent;
@@ -25,6 +26,7 @@
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.SettingsShadowResources;
 import com.android.settings.testutils.shadow.ShadowConnectivityManager;
+import com.android.settings.testutils.shadow.SettingsShadowTypedArray;
 import com.android.settings.testutils.shadow.ShadowWifiManager;
 
 import org.junit.Before;
@@ -39,9 +41,10 @@
 
 @RunWith(SettingsRobolectricTestRunner.class)
 @Config(shadows = {
-    SettingsShadowResources.SettingsShadowTheme.class,
-    ShadowConnectivityManager.class,
-    ShadowWifiManager.class
+        SettingsShadowResources.SettingsShadowTheme.class,
+        ShadowConnectivityManager.class,
+        SettingsShadowTypedArray.class,
+        ShadowWifiManager.class
 }
 )
 public class WifiDialogActivityTest {
@@ -78,7 +81,7 @@
                 Robolectric.buildActivity(
                         WifiDialogActivity.class,
                         new Intent().putExtra(WifiDialogActivity.KEY_CONNECT_FOR_CALLER, false))
-                .setup().get();
+                        .setup().get();
         WifiDialog dialog = (WifiDialog) ShadowAlertDialog.getLatestAlertDialog();
         assertThat(dialog).isNotNull();
 
diff --git a/tests/robotests/src/com/android/settings/wifi/SavedAccessPointsWifiSettingsTest.java b/tests/robotests/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsWifiSettingsTest.java
similarity index 86%
rename from tests/robotests/src/com/android/settings/wifi/SavedAccessPointsWifiSettingsTest.java
rename to tests/robotests/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsWifiSettingsTest.java
index b4fc4cd..a988390 100644
--- a/tests/robotests/src/com/android/settings/wifi/SavedAccessPointsWifiSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsWifiSettingsTest.java
@@ -14,7 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.settings.wifi;
+package com.android.settings.wifi.savedaccesspoints;
+
+import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
@@ -27,7 +29,11 @@
 import android.net.wifi.WifiManager.ActionListener;
 import android.os.Handler;
 
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.R;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.wifi.WifiConfigController;
+import com.android.settings.wifi.WifiDialog;
 import com.android.settingslib.wifi.AccessPoint;
 
 import org.junit.Before;
@@ -105,4 +111,11 @@
         verify(mockWifiManager)
                 .forget(eq(mockWifiConfiguration.networkId), any(ActionListener.class));
     }
+
+    @Test
+    public void verifyConstants() {
+        assertThat(mSettings.getMetricsCategory()).isEqualTo(MetricsEvent.WIFI_SAVED_ACCESS_POINTS);
+        assertThat(mSettings.getPreferenceScreenResId())
+                .isEqualTo(R.xml.wifi_display_saved_access_points);
+    }
 }