Merge "[Provider Model] Replace WiFi panel to Internet panel"
diff --git a/color-check-baseline.xml b/color-check-baseline.xml
index b138082..3ebe9b1 100644
--- a/color-check-baseline.xml
+++ b/color-check-baseline.xml
@@ -921,11 +921,27 @@
         priority="4"
         summary="Using hardcoded color"
         explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+        errorLine1="    <color name="homepage_emergency_background">#F28B82</color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/values/colors.xml"
+            line="95"
+            column="5"/>
+    </issue>
+
+    <issue
+        id="HardCodedColor"
+        severity="Error"
+        message="Avoid using hardcoded color"
+        category="Correctness"
+        priority="4"
+        summary="Using hardcoded color"
+        explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.&#xA;This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
         errorLine1="    &lt;color name=&quot;homepage_system_background&quot;>#9E9E9E&lt;/color>"
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="95"
+            line="96"
             column="5"/>
     </issue>
 
@@ -941,7 +957,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="96"
+            line="97"
             column="5"/>
     </issue>
 
@@ -957,7 +973,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="97"
+            line="98"
             column="5"/>
     </issue>
 
@@ -973,7 +989,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="98"
+            line="99"
             column="5"/>
     </issue>
 
@@ -989,7 +1005,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="99"
+            line="100"
             column="5"/>
     </issue>
 
@@ -1005,7 +1021,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="100"
+            line="101"
             column="5"/>
     </issue>
 
@@ -1021,7 +1037,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="102"
+            line="103"
             column="5"/>
     </issue>
 
@@ -1037,7 +1053,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="108"
+            line="109"
             column="5"/>
     </issue>
 
@@ -1053,7 +1069,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="111"
+            line="112"
             column="5"/>
     </issue>
 
@@ -1069,7 +1085,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="112"
+            line="113"
             column="5"/>
     </issue>
 
@@ -1085,7 +1101,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="113"
+            line="114"
             column="5"/>
     </issue>
 
@@ -1101,7 +1117,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="114"
+            line="115"
             column="5"/>
     </issue>
 
@@ -1117,7 +1133,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="115"
+            line="116"
             column="5"/>
     </issue>
 
@@ -1133,7 +1149,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="116"
+            line="117"
             column="5"/>
     </issue>
 
@@ -1149,7 +1165,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="119"
+            line="120"
             column="5"/>
     </issue>
 
@@ -1165,7 +1181,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="120"
+            line="121"
             column="5"/>
     </issue>
 
@@ -1181,7 +1197,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="121"
+            line="122"
             column="5"/>
     </issue>
 
@@ -1197,7 +1213,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="122"
+            line="123"
             column="5"/>
     </issue>
 
@@ -1213,7 +1229,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="123"
+            line="124"
             column="5"/>
     </issue>
 
@@ -1229,7 +1245,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="126"
+            line="127"
             column="5"/>
     </issue>
 
@@ -1245,7 +1261,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="127"
+            line="128"
             column="5"/>
     </issue>
 
@@ -1261,7 +1277,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="128"
+            line="129"
             column="5"/>
     </issue>
 
@@ -1277,7 +1293,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="129"
+            line="130"
             column="5"/>
     </issue>
 
@@ -1293,7 +1309,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="130"
+            line="131"
             column="5"/>
     </issue>
 
@@ -1309,7 +1325,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="131"
+            line="132"
             column="5"/>
     </issue>
 
@@ -1325,7 +1341,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="138"
+            line="139"
             column="5"/>
     </issue>
 
@@ -1341,7 +1357,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="139"
+            line="140"
             column="5"/>
     </issue>
 
@@ -1357,7 +1373,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="140"
+            line="141"
             column="5"/>
     </issue>
 
@@ -1373,7 +1389,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="149"
+            line="150"
             column="5"/>
     </issue>
 
@@ -1389,7 +1405,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="151"
+            line="152"
             column="5"/>
     </issue>
 
@@ -1405,7 +1421,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="155"
+            line="156"
             column="5"/>
     </issue>
 
@@ -1421,7 +1437,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="156"
+            line="157"
             column="5"/>
     </issue>
 
@@ -1437,7 +1453,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="157"
+            line="158"
             column="5"/>
     </issue>
 
@@ -1453,7 +1469,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="158"
+            line="159"
             column="5"/>
     </issue>
 
@@ -1469,7 +1485,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="159"
+            line="160"
             column="5"/>
     </issue>
 
@@ -1485,7 +1501,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="160"
+            line="161"
             column="5"/>
     </issue>
 
@@ -1501,7 +1517,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="161"
+            line="162"
             column="5"/>
     </issue>
 
@@ -1517,7 +1533,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="162"
+            line="163"
             column="5"/>
     </issue>
 
@@ -1533,7 +1549,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="165"
+            line="166"
             column="5"/>
     </issue>
 
@@ -1549,7 +1565,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="166"
+            line="167"
             column="5"/>
     </issue>
 
@@ -1565,7 +1581,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="167"
+            line="168"
             column="5"/>
     </issue>
 
@@ -1581,7 +1597,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="168"
+            line="169"
             column="5"/>
     </issue>
 
@@ -1597,7 +1613,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="169"
+            line="170"
             column="5"/>
     </issue>
 
@@ -1613,7 +1629,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="170"
+            line="171"
             column="5"/>
     </issue>
 
@@ -1629,7 +1645,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="171"
+            line="172"
             column="5"/>
     </issue>
 
@@ -1645,7 +1661,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="172"
+            line="173"
             column="5"/>
     </issue>
 
@@ -1661,7 +1677,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="175"
+            line="176"
             column="5"/>
     </issue>
 
@@ -1677,7 +1693,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="176"
+            line="177"
             column="5"/>
     </issue>
 
@@ -1693,7 +1709,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="177"
+            line="178"
             column="5"/>
     </issue>
 
@@ -1709,7 +1725,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="178"
+            line="179"
             column="5"/>
     </issue>
 
@@ -1725,7 +1741,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="179"
+            line="180"
             column="5"/>
     </issue>
 
@@ -1741,7 +1757,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="180"
+            line="181"
             column="5"/>
     </issue>
 
@@ -1757,7 +1773,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="183"
+            line="184"
             column="5"/>
     </issue>
 
@@ -1773,7 +1789,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="184"
+            line="185"
             column="5"/>
     </issue>
 
@@ -1789,7 +1805,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="185"
+            line="186"
             column="5"/>
     </issue>
 
@@ -1805,7 +1821,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="186"
+            line="187"
             column="5"/>
     </issue>
 
@@ -1821,7 +1837,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="187"
+            line="188"
             column="5"/>
     </issue>
 
@@ -1837,7 +1853,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="188"
+            line="189"
             column="5"/>
     </issue>
 
@@ -2361,6 +2377,22 @@
         priority="4"
         summary="Using hardcoded color"
         explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.&#xA;This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+        errorLine1="            android:color=&quot;@color/homepage_emergency_background&quot; />"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/drawable/ic_homepage_emergency.xml"
+            line="24"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="HardCodedColor"
+        severity="Error"
+        message="Avoid using hardcoded color"
+        category="Correctness"
+        priority="4"
+        summary="Using hardcoded color"
+        explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.&#xA;This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
         errorLine1="            android:color=&quot;@color/homepage_location_background&quot; />"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -3069,7 +3101,7 @@
         errorLine2="                                                               ~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values-en-rAU/strings.xml"
-            line="2793"
+            line="2818"
             column="64"/>
     </issue>
 
@@ -3085,7 +3117,7 @@
         errorLine2="                                                               ~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values-en-rCA/strings.xml"
-            line="2793"
+            line="2818"
             column="64"/>
     </issue>
 
@@ -3101,7 +3133,7 @@
         errorLine2="                                                               ~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values-en-rGB/strings.xml"
-            line="2793"
+            line="2818"
             column="64"/>
     </issue>
 
@@ -3117,7 +3149,7 @@
         errorLine2="                                                               ~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values-en-rIN/strings.xml"
-            line="2793"
+            line="2818"
             column="64"/>
     </issue>
 
@@ -3133,7 +3165,7 @@
         errorLine2="                                                                                                                                                                         ~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values-en-rXC/strings.xml"
-            line="2793"
+            line="2818"
             column="170"/>
     </issue>
 
@@ -3149,7 +3181,7 @@
         errorLine2="                                   ~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/strings.xml"
-            line="6463"
+            line="6537"
             column="36"/>
     </issue>
 
@@ -3277,7 +3309,7 @@
         errorLine2="                                            ^">
         <location
             file="res/values/themes.xml"
-            line="176"
+            line="191"
             column="45"/>
     </issue>
 
@@ -3293,7 +3325,7 @@
         errorLine2="                                                ^">
         <location
             file="res/values/themes.xml"
-            line="177"
+            line="192"
             column="49"/>
     </issue>
 
@@ -3309,7 +3341,7 @@
         errorLine2="                                            ^">
         <location
             file="res/values/themes.xml"
-            line="185"
+            line="200"
             column="45"/>
     </issue>
 
@@ -3325,7 +3357,7 @@
         errorLine2="                                                ^">
         <location
             file="res/values/themes.xml"
-            line="186"
+            line="201"
             column="49"/>
     </issue>
 
@@ -3341,7 +3373,7 @@
         errorLine2="                                         ^">
         <location
             file="res/values/themes.xml"
-            line="258"
+            line="273"
             column="42"/>
     </issue>
 
diff --git a/res/drawable/ic_homepage_emergency.xml b/res/drawable/ic_homepage_emergency.xml
new file mode 100644
index 0000000..081a3fc
--- /dev/null
+++ b/res/drawable/ic_homepage_emergency.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2021 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item>
+        <com.android.settingslib.widget.AdaptiveIconShapeDrawable
+            android:width="@dimen/dashboard_tile_image_size"
+            android:height="@dimen/dashboard_tile_image_size"
+            android:color="@color/homepage_emergency_background" />
+    </item>
+
+    <item
+        android:width="@dimen/dashboard_tile_foreground_image_size"
+        android:height="@dimen/dashboard_tile_foreground_image_size"
+        android:start="@dimen/dashboard_tile_foreground_image_inset"
+        android:top="@dimen/dashboard_tile_foreground_image_inset"
+        android:drawable="@drawable/ic_settings_emergency" />
+</layer-list>
diff --git a/res/drawable/ic_settings_emergency.xml b/res/drawable/ic_settings_emergency.xml
new file mode 100644
index 0000000..f145346
--- /dev/null
+++ b/res/drawable/ic_settings_emergency.xml
@@ -0,0 +1,24 @@
+<!--
+    Copyright (C) 2021 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:pathData="M9.3207,2V7.359L4.6795,4.6795L2,9.3207L6.6412,12L2,14.6795L4.6795,19.3205L9.3207,16.641V22H14.6797V16.641L19.3207,19.3205L22.0002,14.6795L17.359,12L22.0002,9.3207L19.3207,4.6795L14.6797,7.3588V2H9.3207Z"
+        android:fillColor="?android:attr/colorPrimary"/>
+</vector>
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index f8df920..3528f9f 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -1532,4 +1532,21 @@
         <item>8</item>
         <item>12</item>
     </string-array>
+
+    <!-- Array of titles list for notification listener notification types. [DO NOT TRANSLATE] -->
+    <string-array name="notif_types_titles" translatable="false">
+        <item>@string/notif_type_ongoing</item>
+        <item>@string/notif_type_conversation</item>
+        <item>@string/notif_type_alerting</item>
+        <item>@string/notif_type_silent</item>
+    </string-array>
+
+    <!-- Values of list for notification listener notification types. Values need to match
+    android.service.notification.NotificationListenerService. [DO NOT TRANSLATE] -->
+    <string-array name="notif_types_values" translatable="false">
+        <item>8</item>
+        <item>1</item>
+        <item>2</item>
+        <item>4</item>
+    </string-array>
 </resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 58b8aa4..2ce3949 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -92,6 +92,7 @@
     <color name="homepage_security_background">#0F9D58</color>
     <color name="homepage_accounts_background">#F15B8D</color>
     <color name="homepage_accessibility_background">#5011C1</color>
+    <color name="homepage_emergency_background">#F28B82</color>
     <color name="homepage_system_background">#9E9E9E</color>
     <color name="homepage_support_background">#26459C</color>
     <color name="homepage_generic_icon_background">#1A73E8</color>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 2a63511..5301f30 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -2824,16 +2824,12 @@
     <string name="night_display_status_title">Status</string>
     <!-- Night display screen, setting the color temperature of the display. [CHAR LIMIT=30] -->
     <string name="night_display_temperature_title">Intensity</string>
-    <!-- Display settings screen, summary format of night display when off. [CHAR LIMIT=NONE] -->
-    <string name="night_display_summary_off">Off / <xliff:g name="auto_mode_summary" example="Never turn on automatically">%1$s</xliff:g></string>
     <!-- Display settings screen, summary of night display when off and will *never* turn on automatically. [CHAR LIMIT=NONE] -->
     <string name="night_display_summary_off_auto_mode_never">Will never turn on automatically</string>
          <!-- Display settings screen, summary format of night display when off and will turn on automatically at a user defined time. [CHAR LIMIT=NONE] -->
     <string name="night_display_summary_off_auto_mode_custom">Will turn on automatically at <xliff:g name="time" example="6 AM">%1$s</xliff:g></string>
     <!-- Display settings screen, summary of night display when off and will turn on automatically at sunset. [CHAR LIMIT=NONE] -->
     <string name="night_display_summary_off_auto_mode_twilight">Will turn on automatically at sunset</string>
-    <!-- Display settings screen, summary format of night display when on. [CHAR LIMIT=NONE] -->
-    <string name="night_display_summary_on">On / <xliff:g name="auto_mode_summary" example="Never turn off automatically">%1$s</xliff:g></string>
     <!-- Display settings screen, summary of night display when on and will *never* turn off automatically. [CHAR LIMIT=NONE] -->
     <string name="night_display_summary_on_auto_mode_never">Will never turn off automatically</string>
     <!-- Display settings screen, summary format of night display when on and will turn off automatically at a user defined time. [CHAR LIMIT=NONE] -->
@@ -2882,16 +2878,12 @@
     <string name="dark_ui_auto_mode_custom">Turns on at custom time</string>
     <!-- Dark UI screen, setting option name controlling the current activation status. [CHAR LIMIT=30] -->
     <string name="dark_ui_status_title">Status</string>
-    <!-- Display settings screen, summary format of Dark UI when off. [CHAR LIMIT=NONE] -->
-    <string name="dark_ui_summary_off">Off / <xliff:g name="auto_mode_summary" example="Never turn on automatically">%1$s</xliff:g></string>
     <!-- Display settings screen, summary of Dark UI when off and will *never* turn on automatically. [CHAR LIMIT=NONE] -->
     <string name="dark_ui_summary_off_auto_mode_never">Will never turn on automatically</string>
     <!-- Display settings screen, summary of Dark UI when off and will turn on automatically at sunset. [CHAR LIMIT=NONE] -->
     <string name="dark_ui_summary_off_auto_mode_auto">Will turn on automatically at sunset</string>
         <!-- Display settings screen, summary format of night display when off and will turn on automatically at a user defined time. [CHAR LIMIT=NONE] -->
     <string name="dark_ui_summary_off_auto_mode_custom">Will turn on automatically at <xliff:g name="time" example="6 AM">%1$s</xliff:g></string>
-    <!-- Display settings screen, summary format of Dark UI when on. [CHAR LIMIT=NONE] -->
-    <string name="dark_ui_summary_on">On / <xliff:g name="auto_mode_summary" example="Never turn off automatically">%1$s</xliff:g></string>
     <!-- Display settings screen, summary of Dark UI when on and will *never* turn off automatically. [CHAR LIMIT=NONE] -->
     <string name="dark_ui_summary_on_auto_mode_never">Will never turn off automatically</string>
     <!-- Display settings screen, summary of Dark UI when on and will turn off automatically at sunrise. [CHAR LIMIT=NONE] -->
@@ -4952,6 +4944,8 @@
     <string name="audio_and_captions_category_title">Audio &amp; on-screen text</string>
     <!-- Title for the accessibility preference category of display services and settings. [CHAR LIMIT=50] -->
     <string name="display_category_title">Display</string>
+    <!-- Title for the accessibility text options page. [CHAR LIMIT=50] -->
+    <string name="accessibility_text_and_display_title">Text and display</string>
     <!-- Title for the accessibility preference category of interaction control services and settings. [CHAR LIMIT=50] -->
     <string name="interaction_control_category_title">Interaction controls</string>
     <!-- Title for the accessibility preference category of services downloaded by the user. [CHAR LIMIT=50] -->
@@ -7111,13 +7105,15 @@
     <!-- Title for Guest user [CHAR LIMIT=35] -->
     <string name="user_guest">Guest</string>
     <!-- Label for item to exit guest mode [CHAR LIMIT=35] -->
-    <string name="user_exit_guest_title">Remove guest</string>
+    <string name="user_clear_guest_menu">Clear guest data</string>
+    <!-- Label for item to exit guest mode [CHAR LIMIT=35] -->
+    <string name="user_exit_guest_menu">End guest session</string>
     <!-- Title of dialog to user to confirm exiting guest. [CHAR LIMIT=50] -->
-    <string name="user_exit_guest_confirm_title">Remove guest?</string>
+    <string name="user_exit_guest_confirm_title">End guest session?</string>
     <!-- Message to user to confirm exiting guest. [CHAR LIMIT=none] -->
     <string name="user_exit_guest_confirm_message">All apps and data in this session will be deleted.</string>
     <!-- Label for button in confirmation dialog when exiting guest session [CHAR LIMIT=35] -->
-    <string name="user_exit_guest_dialog_remove">Remove</string>
+    <string name="user_exit_guest_dialog_remove">End session</string>
 
     <!-- Title of preference to enable calling[CHAR LIMIT=40] -->
     <string name="user_enable_calling">Turn on phone calls</string>
@@ -8587,7 +8583,7 @@
     <string name="recent_conversations">Recent conversations</string>
 
     <!-- [CHAR LIMIT=20] button title -->
-    <string name="conversation_settings_clear_recents">Clear recents</string>
+    <string name="conversation_settings_clear_recents">Clear all of the recent ones</string>
 
     <!-- a11y string -->
     <string name="clear">Clear</string>
@@ -8760,6 +8756,11 @@
     </string>
     <string name="notification_listener_disable_warning_confirm">Turn off</string>
     <string name="notification_listener_disable_warning_cancel">Cancel</string>
+    <string name="notification_listener_type_title">Allowed notification types</string>
+    <string name="notif_type_ongoing">Important ongoing notifications</string>
+    <string name="notif_type_conversation">Conversation notifications</string>
+    <string name="notif_type_alerting">Alerting notifications</string>
+    <string name="notif_type_silent">Silent notifications</string>
 
     <!-- Title for managing VR (virtual reality) helper services. [CHAR LIMIT=50] -->
     <string name="vr_listeners_title">VR helper services</string>
@@ -10866,7 +10867,7 @@
     <string name="dark_ui_mode">Dark theme</string>
 
     <!-- [CHAR LIMIT=60] Summary string on dark theme explaining why the toggle is disabled while the setting is still on-->
-    <string name="dark_ui_mode_disabled_summary_dark_theme_on">On / Temporarily disabled due to Battery Saver</string>
+    <string name="dark_ui_mode_disabled_summary_dark_theme_on">Temporarily disabled due to Battery Saver</string>
 
     <!-- [CHAR LIMIT=60] Summary string on dark theme explaining why the toggle is disabled while the setting is off-->
     <string name="dark_ui_mode_disabled_summary_dark_theme_off">Temporarily turned on due to Battery Saver</string>
@@ -10990,6 +10991,9 @@
     <!-- Summary for settings suggestion for swipe up to switch apps [CHAR LIMIT=60] -->
     <string name="swipe_up_to_switch_apps_suggestion_summary">Turn on the new gesture to switch apps</string>
 
+    <!-- Preference title for "Safety & emergency" settings page [CHAR LIMIT=60]-->
+    <string name="emergency_settings_preference_title">Safety &amp; emergency</string>
+
     <!-- Title text for edge to edge navigation [CHAR LIMIT=60] -->
     <string name="edge_to_edge_navigation_title">Gesture navigation</string>
     <!-- Summary text for edge to edge navigation [CHAR LIMIT=NONE] -->
@@ -12573,4 +12577,6 @@
     <string name="category_name_color">Color</string>
     <!-- Others category name [CHAR LIMIT=none] -->
     <string name="category_name_others">Others</string>
+    <!-- General category name [CHAR LIMIT=none] -->
+    <string name="category_name_general">General</string>
 </resources>
diff --git a/res/values/styles_preference.xml b/res/values/styles_preference.xml
index b88a9fb..6453458 100644
--- a/res/values/styles_preference.xml
+++ b/res/values/styles_preference.xml
@@ -25,16 +25,9 @@
         <item name="slicePreferenceStyle">@style/SlicePreference</item>
         <item name="seekBarPreferenceStyle">@style/SettingsSeekBarPreference</item>
         <item name="twoStateButtonPreferenceStyle">@style/TwoStateButtonPreference</item>
-        <item name="preferenceCategoryTitleTextAppearance">@style/TextAppearance.CategoryTitle
-        </item>
-        <item name="preferenceCategoryStyle">@style/SettingsCategoryPreference</item>
-        <!-- For preference category color -->
-        <item name="preferenceCategoryTitleTextColor">?android:attr/textColorSecondary</item>
         <item name="preferenceFragmentCompatStyle">@style/SettingsPreferenceFragmentStyle</item>
     </style>
 
-    <style name="SettingsCategoryPreference" parent="Preference.Category.Material" />
-
     <style name="PreferenceTheme.SetupWizard">
         <item name="preferenceFragmentCompatStyle">@style/SetupWizardPreferenceFragmentStyle</item>
         <item name="preferenceStyle">@style/Preference.Material</item>
diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml
index 6781e28..6efd884 100644
--- a/res/xml/accessibility_settings.xml
+++ b/res/xml/accessibility_settings.xml
@@ -45,52 +45,19 @@
         android:title="@string/display_category_title">
 
         <Preference
-            android:fragment="com.android.settings.display.ToggleFontSizePreferenceFragment"
-            android:key="font_size_preference_screen"
+            android:fragment="com.android.settings.accessibility.TextAndDisplayFragment"
+            android:key="text_and_display_preference_screen"
             android:persistent="false"
-            android:title="@string/title_font_size"
-            settings:controller="com.android.settings.display.FontSizePreferenceController"
-            settings:searchable="false"/>
+            android:title="@string/accessibility_text_and_display_title"
+            settings:searchable="true"/>
 
-     <com.android.settings.display.ScreenZoomPreference
-            android:fragment="com.android.settings.display.ScreenZoomSettings"
-            android:key="accessibility_settings_screen_zoom"
-            android:persistent="false"
-            android:title="@string/screen_zoom_title"
-            settings:searchable="false"/>
-
-       <SwitchPreference
-            android:key="dark_ui_mode_accessibility"
-            android:persistent="false"
-            android:title="@string/dark_ui_mode"
-            settings:controller="com.android.settings.display.DarkUIPreferenceController"
-            settings:searchable="false"/>
-
-       <Preference
+        <Preference
             android:fragment="com.android.settings.accessibility.MagnificationPreferenceFragment"
             android:icon="@drawable/ic_accessibility_magnification"
             android:key="magnification_preference_screen"
             android:persistent="false"
             android:title="@string/accessibility_screen_magnification_title"
             settings:controller="com.android.settings.accessibility.MagnificationPreferenceController"/>
-
-        <SwitchPreference
-            android:key="toggle_large_pointer_icon"
-            android:persistent="false"
-            android:title="@string/accessibility_toggle_large_pointer_icon_title"
-            settings:controller="com.android.settings.accessibility.LargePointerIconPreferenceController"/>
-
-        <SwitchPreference
-            android:key="toggle_disable_animations"
-            android:persistent="false"
-            android:title="@string/accessibility_disable_animations"
-            settings:controller="com.android.settings.accessibility.DisableAnimationsPreferenceController"/>
-
-        <SwitchPreference
-            android:key="toggle_force_bold_text"
-            android:persistent="false"
-            android:title="@string/force_bold_text"
-            settings:controller="com.android.settings.accessibility.FontWeightAdjustmentPreferenceController"/>
     </PreferenceCategory>
 
     <PreferenceCategory
@@ -203,42 +170,12 @@
         settings:initialExpandedChildrenCount="1">
 
         <SwitchPreference
-            android:key="toggle_high_text_contrast_preference"
-            android:persistent="false"
-            android:title="@string/accessibility_toggle_high_text_contrast_preference_title"
-            settings:controller="com.android.settings.accessibility.HighTextContrastPreferenceController"/>
-
-        <Preference
-            android:fragment="com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment"
-            android:icon="@drawable/ic_daltonizer"
-            android:key="daltonizer_preference"
-            android:persistent="false"
-            android:title="@string/accessibility_display_daltonizer_preference_title"
-            settings:controller="com.android.settings.accessibility.DaltonizerPreferenceController"/>
-
-        <Preference
-            android:fragment="com.android.settings.accessibility.ToggleColorInversionPreferenceFragment"
-            android:icon="@drawable/ic_color_inversion"
-            android:key="toggle_inversion_preference"
-            android:persistent="false"
-            android:title="@string/accessibility_display_inversion_preference_title"
-            settings:controller="com.android.settings.accessibility.ColorInversionPreferenceController"/>
-
-        <SwitchPreference
             android:key="accessibility_shortcut_preference"
             android:persistent="false"
             android:title="@string/accessibility_shortcut_service_on_lock_screen_title"
             android:summary="@string/accessibility_shortcut_description"
             settings:controller="com.android.settings.accessibility.AccessibilityShortcutPreferenceController"/>
 
-        <!--TODO(b/170973645): Get icon-->
-        <Preference
-            android:fragment="com.android.settings.accessibility.ToggleReduceBrightColorsPreferenceFragment"
-            android:key="reduce_bright_colors_preference"
-            android:persistent="false"
-            android:title="@string/reduce_bright_colors_preference_title"
-            settings:controller="com.android.settings.accessibility.ReduceBrightColorsPreferenceController"/>
-
     </PreferenceCategory>
 
 </PreferenceScreen>
diff --git a/res/xml/accessibility_text_and_display.xml b/res/xml/accessibility_text_and_display.xml
new file mode 100644
index 0000000..7dce826
--- /dev/null
+++ b/res/xml/accessibility_text_and_display.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<PreferenceScreen
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
+    android:key="accessibility_text_and_display"
+    android:persistent="false"
+    android:title="@string/accessibility_text_and_display_title">
+
+    <SwitchPreference
+        android:key="toggle_high_text_contrast_preference"
+        android:persistent="false"
+        android:title="@string/accessibility_toggle_high_text_contrast_preference_title"
+        settings:controller="com.android.settings.accessibility.HighTextContrastPreferenceController"/>
+
+    <SwitchPreference
+        android:key="dark_ui_mode_accessibility"
+        android:persistent="false"
+        android:title="@string/dark_ui_mode"
+        settings:controller="com.android.settings.display.DarkUIPreferenceController"
+        settings:searchable="false"/>
+
+    <Preference
+        android:fragment="com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment"
+        android:icon="@drawable/ic_daltonizer"
+        android:key="daltonizer_preference"
+        android:persistent="false"
+        android:title="@string/accessibility_display_daltonizer_preference_title"
+        settings:controller="com.android.settings.accessibility.DaltonizerPreferenceController"/>
+
+    <Preference
+        android:fragment="com.android.settings.accessibility.ToggleColorInversionPreferenceFragment"
+        android:icon="@drawable/ic_color_inversion"
+        android:key="toggle_inversion_preference"
+        android:persistent="false"
+        android:title="@string/accessibility_display_inversion_preference_title"
+        settings:controller="com.android.settings.accessibility.ColorInversionPreferenceController"/>
+
+    <!--TODO(b/170973645): Get icon-->
+    <Preference
+        android:fragment="com.android.settings.accessibility.ToggleReduceBrightColorsPreferenceFragment"
+        android:key="reduce_bright_colors_preference"
+        android:persistent="false"
+        android:title="@string/reduce_bright_colors_preference_title"
+        settings:controller="com.android.settings.accessibility.ReduceBrightColorsPreferenceController"/>
+
+    <SwitchPreference
+        android:key="toggle_disable_animations"
+        android:persistent="false"
+        android:title="@string/accessibility_disable_animations"
+        settings:controller="com.android.settings.accessibility.DisableAnimationsPreferenceController"/>
+
+    <com.android.settings.display.ScreenZoomPreference
+        android:fragment="com.android.settings.display.ScreenZoomSettings"
+        android:key="accessibility_settings_screen_zoom"
+        android:persistent="false"
+        android:title="@string/screen_zoom_title"
+        settings:searchable="false"/>
+
+    <Preference
+        android:fragment="com.android.settings.display.ToggleFontSizePreferenceFragment"
+        android:key="font_size_preference_screen"
+        android:persistent="false"
+        android:title="@string/title_font_size"
+        settings:controller="com.android.settings.display.FontSizePreferenceController"
+        settings:searchable="false"/>
+
+    <SwitchPreference
+        android:key="toggle_force_bold_text"
+        android:persistent="false"
+        android:title="@string/force_bold_text"
+        settings:controller="com.android.settings.accessibility.FontWeightAdjustmentPreferenceController"/>
+
+    <SwitchPreference
+        android:key="toggle_large_pointer_icon"
+        android:persistent="false"
+        android:title="@string/accessibility_toggle_large_pointer_icon_title"
+        settings:controller="com.android.settings.accessibility.LargePointerIconPreferenceController"/>
+
+    <PreferenceCategory
+        android:key="experimental_category"
+        android:persistent="false"
+        android:title="@string/experimental_category_title"
+        settings:initialExpandedChildrenCount="1">
+    </PreferenceCategory>
+</PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/display_settings_v2.xml b/res/xml/display_settings_v2.xml
index 4edc335..0b43914 100644
--- a/res/xml/display_settings_v2.xml
+++ b/res/xml/display_settings_v2.xml
@@ -33,10 +33,9 @@
             <intent android:action="com.android.intent.action.SHOW_BRIGHTNESS_DIALOG"/>
         </com.android.settingslib.RestrictedPreference>
 
-        <Preference
+        <com.android.settings.widget.PrimarySwitchPreference
             android:key="auto_brightness_entry"
             android:title="@string/auto_brightness_title"
-            android:summary="@string/summary_placeholder"
             android:fragment="com.android.settings.display.AutoBrightnessSettings"
             settings:controller="com.android.settings.display.AutoBrightnessPreferenceController"/>
     </PreferenceCategory>
@@ -103,7 +102,7 @@
     </PreferenceCategory>
 
     <PreferenceCategory
-        android:title="@string/category_name_others">
+        android:title="@string/category_name_general">
 
         <SwitchPreference
             android:key="auto_rotate"
diff --git a/res/xml/emergency_settings.xml b/res/xml/emergency_settings.xml
new file mode 100644
index 0000000..41b503e
--- /dev/null
+++ b/res/xml/emergency_settings.xml
@@ -0,0 +1,41 @@
+
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<PreferenceScreen
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
+    android:title="@string/emergency_settings_preference_title">
+    <Preference
+        android:key="emergency_info"
+        android:title="@string/emergency_info_title"
+        android:summary="@string/summary_placeholder"
+        settings:controller="com.android.settings.accounts.EmergencyInfoPreferenceController"/>
+    <Preference
+        android:key="gesture_emergency_summary"
+        android:title="@string/emergency_gesture_screen_title"
+        android:fragment="com.android.settings.gestures.EmergencyGestureSettings"
+        settings:controller="com.android.settings.gestures.EmergencyGestureEntrypointPreferenceController" />
+    <com.android.settingslib.RestrictedPreference
+        android:key="app_and_notif_cell_broadcast_settings"
+        android:title="@string/cell_broadcast_settings"
+        settings:useAdminDisabledSummary="true">
+        <intent
+            android:action="android.intent.action.MAIN"
+            android:targetPackage="@string/cell_broadcast_receiver_package"
+            android:targetClass="com.android.cellbroadcastreceiver.CellBroadcastSettings"/>
+    </com.android.settingslib.RestrictedPreference>
+</PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/notification_access_permission_details.xml b/res/xml/notification_access_permission_details.xml
index d956ce9..f7d928d 100644
--- a/res/xml/notification_access_permission_details.xml
+++ b/res/xml/notification_access_permission_details.xml
@@ -17,11 +17,35 @@
 
 <PreferenceScreen
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:key="notification_access_permission_detail_settings"
     android:title="@string/manage_notification_access_title">
 
+    <com.android.settingslib.widget.LayoutPreference
+        android:key="pref_app_header"
+        android:layout="@layout/settings_entity_header"
+        settings:controller="com.android.settings.applications.specialaccess.notificationaccess.HeaderPreferenceController"/>
+
     <com.android.settings.widget.FilterTouchesSwitchPreference
         android:key="notification_access_switch"
-        android:title="@string/notification_access_detail_switch"/>
+        android:title="@string/notification_access_detail_switch"
+        settings:controller="com.android.settings.applications.specialaccess.notificationaccess.ApprovalPreferenceController"/>
 
+    <MultiSelectListPreference
+        android:key="notification_type_filter"
+        android:title="@string/notification_listener_type_title"
+        android:entries="@array/notif_types_titles"
+        android:entryValues="@array/notif_types_values"
+        android:summary="%s"
+        android:persistent="false"
+        style="@style/SettingsMultiSelectListPreference"
+        settings:controller="com.android.settings.applications.specialaccess.notificationaccess.TypeFilterPreferenceController"/>/>
+
+    <PreferenceCategory
+        android:key="advanced"
+        android:order="50"
+        settings:initialExpandedChildrenCount="0">
+
+
+    </PreferenceCategory>
 </PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/top_level_settings.xml b/res/xml/top_level_settings.xml
index 367f426..3c65f7b 100644
--- a/res/xml/top_level_settings.xml
+++ b/res/xml/top_level_settings.xml
@@ -125,6 +125,14 @@
         android:fragment="com.android.settings.accessibility.AccessibilitySettings"
         settings:controller="com.android.settings.accessibility.TopLevelAccessibilityPreferenceController"/>
 
+        <!--    TODO(b/175158310): Enable this tile when the setting content is more flushed out-->
+        <!--    <Preference-->
+        <!--        android:key="top_level_emergency"-->
+        <!--        android:title="@string/emergency_settings_preference_title"-->
+        <!--        android:icon="@drawable/ic_homepage_emergency"-->
+        <!--        android:order="-10"-->
+        <!--        android:fragment="com.android.settings.emergency.EmergencyDashboardFragment"/>-->
+
     <Preference
         android:key="top_level_system"
         android:title="@string/header_category_system"
diff --git a/res/xml/top_level_settings_grouped.xml b/res/xml/top_level_settings_grouped.xml
index baee7b3..1ae6131 100644
--- a/res/xml/top_level_settings_grouped.xml
+++ b/res/xml/top_level_settings_grouped.xml
@@ -134,6 +134,13 @@
             android:order="-20"
             android:title="@string/security_settings_title"
             settings:controller="com.android.settings.security.TopLevelSecurityEntryPreferenceController"/>
+        <!--    TODO(b/175158310): Enable this tile when the setting content is more flushed out-->
+        <!--        <Preference-->
+        <!--            android:key="top_level_emergency"-->
+        <!--            android:title="@string/emergency_settings_preference_title"-->
+        <!--            android:icon="@drawable/ic_homepage_emergency"-->
+        <!--            android:order="-10"-->
+        <!--            android:fragment="com.android.settings.emergency.EmergencyDashboardFragment"/>-->
     </PreferenceCategory>
 
     <PreferenceCategory
diff --git a/res/xml/zen_mode_custom_rule_settings.xml b/res/xml/zen_mode_custom_rule_settings.xml
index 169a94f..8f360b9 100644
--- a/res/xml/zen_mode_custom_rule_settings.xml
+++ b/res/xml/zen_mode_custom_rule_settings.xml
@@ -22,11 +22,11 @@
 
     <PreferenceCategory
         android:key="zen_custom_rule_category">
-        <com.android.settings.notification.zen.ZenCustomRadioButtonPreference
+        <com.android.settingslib.widget.RadioButtonPreference
             android:key="zen_custom_rule_setting_default"
             android:title="@string/zen_mode_custom_behavior_summary_default"/>
 
-        <com.android.settings.notification.zen.ZenCustomRadioButtonPreference
+        <com.android.settingslib.widget.RadioButtonPreference
             android:key="zen_custom_rule_setting"
             android:title="@string/zen_mode_custom_behavior_summary" />
     </PreferenceCategory>
diff --git a/res/xml/zen_mode_restrict_notifications_settings.xml b/res/xml/zen_mode_restrict_notifications_settings.xml
index f5e7615..051c208 100644
--- a/res/xml/zen_mode_restrict_notifications_settings.xml
+++ b/res/xml/zen_mode_restrict_notifications_settings.xml
@@ -23,19 +23,19 @@
     <PreferenceCategory
         android:key="restrict_category"
         android:title="@string/zen_mode_restrict_notifications_category">
-        <com.android.settings.notification.zen.ZenCustomRadioButtonPreference
+        <com.android.settingslib.widget.RadioButtonPreference
             android:key="zen_mute_notifications"
             android:title="@string/zen_mode_restrict_notifications_mute"
             android:summary="@string/zen_mode_restrict_notifications_mute_summary"
             settings:searchable="false"/>
 
-        <com.android.settings.notification.zen.ZenCustomRadioButtonPreference
+        <com.android.settingslib.widget.RadioButtonPreference
             android:key="zen_hide_notifications"
             android:title="@string/zen_mode_restrict_notifications_hide"
             android:summary="@string/zen_mode_restrict_notifications_hide_summary"
             settings:searchable="false"/>
 
-        <com.android.settings.notification.zen.ZenCustomRadioButtonPreference
+        <com.android.settingslib.widget.RadioButtonPreference
             android:key="zen_custom"
             android:title="@string/zen_mode_restrict_notifications_custom"
             settings:searchable="false"/>
diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java
index e5bc3f5..4709c66 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettings.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettings.java
@@ -29,7 +29,6 @@
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.graphics.drawable.Drawable;
-import android.hardware.display.ColorDisplayManager;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
@@ -43,7 +42,6 @@
 import androidx.core.content.ContextCompat;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceCategory;
-import androidx.preference.SwitchPreference;
 
 import com.android.internal.accessibility.AccessibilityShortcutController;
 import com.android.internal.content.PackageMonitor;
@@ -51,7 +49,6 @@
 import com.android.settings.Utils;
 import com.android.settings.accessibility.AccessibilityUtil.AccessibilityServiceFragmentType;
 import com.android.settings.dashboard.DashboardFragment;
-import com.android.settings.display.DarkUIPreferenceController;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
 import com.android.settingslib.RestrictedLockUtilsInternal;
@@ -82,23 +79,14 @@
     private static final String CATEGORY_EXPERIMENTAL = "experimental_category";
     private static final String CATEGORY_DOWNLOADED_SERVICES = "user_installed_services_category";
 
-    private static final String[] CATEGORIES = new String[] {
+    private static final String[] CATEGORIES = new String[]{
             CATEGORY_SCREEN_READER, CATEGORY_AUDIO_AND_CAPTIONS, CATEGORY_DISPLAY,
             CATEGORY_INTERACTION_CONTROL, CATEGORY_EXPERIMENTAL, CATEGORY_DOWNLOADED_SERVICES
     };
 
     // Preferences
-    private static final String TOGGLE_INVERSION_PREFERENCE =
-            "toggle_inversion_preference";
-    private static final String TOGGLE_LARGE_POINTER_ICON =
-            "toggle_large_pointer_icon";
-    private static final String TOGGLE_DISABLE_ANIMATIONS = "toggle_disable_animations";
     private static final String DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN =
             "magnification_preference_screen";
-    private static final String DISPLAY_DALTONIZER_PREFERENCE_SCREEN =
-            "daltonizer_preference";
-    private static final String DISPLAY_REDUCE_BRIGHT_COLORS_PREFERENCE_SCREEN =
-            "reduce_bright_colors_preference";
 
     // Extras passed to sub-fragments.
     static final String EXTRA_PREFERENCE_KEY = "preference_key";
@@ -167,13 +155,7 @@
     private final Map<ComponentName, PreferenceCategory> mPreBundledServiceComponentToCategoryMap =
             new ArrayMap<>();
 
-    private SwitchPreference mToggleLargePointerIconPreference;
-    private SwitchPreference mToggleDisableAnimationsPreference;
     private Preference mDisplayMagnificationPreferenceScreen;
-    private Preference mDisplayDaltonizerPreferenceScreen;
-    private Preference mToggleInversionPreference;
-    private Preference mReduceBrightColorsPreference;
-
 
     /**
      * Check if the color transforms are color accelerated. Some transforms are experimental only
@@ -226,7 +208,6 @@
     @Override
     public void onAttach(Context context) {
         super.onAttach(context);
-        use(DarkUIPreferenceController.class).setParentFragment(this);
         use(AccessibilityHearingAidPreferenceController.class)
                 .setFragmentManager(getFragmentManager());
     }
@@ -259,8 +240,8 @@
     /**
      * Returns the summary for the current state of this accessibilityService.
      *
-     * @param context A valid context
-     * @param info The accessibilityService's info
+     * @param context        A valid context
+     * @param info           The accessibilityService's info
      * @param serviceEnabled Whether the accessibility service is enabled.
      * @return The service summary
      */
@@ -299,8 +280,8 @@
     /**
      * Returns the description for the current state of this accessibilityService.
      *
-     * @param context A valid context
-     * @param info The accessibilityService's info
+     * @param context        A valid context
+     * @param info           The accessibilityService's info
      * @param serviceEnabled Whether the accessibility service is enabled.
      * @return The service description
      */
@@ -325,24 +306,9 @@
             mCategoryToPrefCategoryMap.put(CATEGORIES[i], prefCategory);
         }
 
-        // Display inversion.
-        mToggleInversionPreference = findPreference(TOGGLE_INVERSION_PREFERENCE);
-
-        // Large pointer icon.
-        mToggleLargePointerIconPreference = findPreference(TOGGLE_LARGE_POINTER_ICON);
-
-        mToggleDisableAnimationsPreference = findPreference(TOGGLE_DISABLE_ANIMATIONS);
-
         // Display magnification.
         mDisplayMagnificationPreferenceScreen = findPreference(
                 DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN);
-
-        // Display color adjustments.
-        mDisplayDaltonizerPreferenceScreen = findPreference(DISPLAY_DALTONIZER_PREFERENCE_SCREEN);
-
-        // Reduce brightness.
-        mReduceBrightColorsPreference =
-                findPreference(DISPLAY_REDUCE_BRIGHT_COLORS_PREFERENCE_SCREEN);
     }
 
     private void updateAllPreferences() {
@@ -392,13 +358,13 @@
 
         // Update the order of all the category according to the order defined in xml file.
         updateCategoryOrderFromArray(CATEGORY_SCREEN_READER,
-            R.array.config_order_screen_reader_services);
+                R.array.config_order_screen_reader_services);
         updateCategoryOrderFromArray(CATEGORY_AUDIO_AND_CAPTIONS,
-            R.array.config_order_audio_and_caption_services);
+                R.array.config_order_audio_and_caption_services);
         updateCategoryOrderFromArray(CATEGORY_INTERACTION_CONTROL,
-            R.array.config_order_interaction_control_services);
+                R.array.config_order_interaction_control_services);
         updateCategoryOrderFromArray(CATEGORY_DISPLAY,
-            R.array.config_order_display_services);
+                R.array.config_order_display_services);
 
         // Need to check each time when updateServicePreferences() called.
         if (downloadedServicesCategory.getPreferenceCount() == 0) {
@@ -468,7 +434,7 @@
      * key with the string array of preference order which is defined in the xml.
      *
      * @param categoryKey The key of the category need to update the order
-     * @param key The key of the string array which defines the order of category
+     * @param key         The key of the string array which defines the order of category
      */
     private void updateCategoryOrderFromArray(String categoryKey, int key) {
         String[] services = getResources().getStringArray(key);
@@ -486,39 +452,11 @@
         }
     }
 
+    /**
+     * Updates preferences related to system configurations.
+     */
     protected void updateSystemPreferences() {
-        // Move color inversion and color correction preferences to Display category if device
-        // supports HWC hardware-accelerated color transform.
-        if (ColorDisplayManager.isColorTransformAccelerated(getContext())) {
-            PreferenceCategory experimentalCategory =
-                    mCategoryToPrefCategoryMap.get(CATEGORY_EXPERIMENTAL);
-            PreferenceCategory displayCategory =
-                    mCategoryToPrefCategoryMap.get(CATEGORY_DISPLAY);
-            experimentalCategory.removePreference(mToggleInversionPreference);
-            experimentalCategory.removePreference(mDisplayDaltonizerPreferenceScreen);
-            experimentalCategory.removePreference(mReduceBrightColorsPreference);
-            mDisplayMagnificationPreferenceScreen.setSummary(
-                    ToggleScreenMagnificationPreferenceFragment.getServiceSummary(getContext()));
-            mDisplayDaltonizerPreferenceScreen.setOrder(
-                    mDisplayMagnificationPreferenceScreen.getOrder() + 1);
-            mDisplayDaltonizerPreferenceScreen.setSummary(AccessibilityUtil.getSummary(
-                    getContext(), Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED));
-            mToggleInversionPreference.setOrder(
-                    mDisplayDaltonizerPreferenceScreen.getOrder() + 1);
-            mToggleLargePointerIconPreference.setOrder(
-                    mToggleInversionPreference.getOrder() + 1);
-            mToggleDisableAnimationsPreference.setOrder(
-                    mToggleLargePointerIconPreference.getOrder() + 1);
-            mToggleInversionPreference.setSummary(AccessibilityUtil.getSummary(
-                    getContext(), Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED));
-            mReduceBrightColorsPreference.setOrder(
-                    mToggleDisableAnimationsPreference.getOrder() + 1);
-            mReduceBrightColorsPreference.setSummary(AccessibilityUtil.getSummary(
-                    getContext(), Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED));
-            displayCategory.addPreference(mToggleInversionPreference);
-            displayCategory.addPreference(mDisplayDaltonizerPreferenceScreen);
-            displayCategory.addPreference(mReduceBrightColorsPreference);
-        }
+        // Do nothing.
     }
 
     public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
diff --git a/src/com/android/settings/accessibility/TextAndDisplayFragment.java b/src/com/android/settings/accessibility/TextAndDisplayFragment.java
new file mode 100644
index 0000000..b496e3d
--- /dev/null
+++ b/src/com/android/settings/accessibility/TextAndDisplayFragment.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accessibility;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.hardware.display.ColorDisplayManager;
+import android.os.Bundle;
+import android.provider.Settings;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
+import androidx.preference.SwitchPreference;
+
+import com.android.settings.R;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.display.DarkUIPreferenceController;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settingslib.search.SearchIndexable;
+
+/** Accessibility settings for text and display. */
+@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
+public class TextAndDisplayFragment extends DashboardFragment {
+
+    private static final String TAG = "TextAndDisplayFragment";
+
+    private static final String CATEGORY_EXPERIMENTAL = "experimental_category";
+
+    // Preferences
+    private static final String DISPLAY_DALTONIZER_PREFERENCE_SCREEN = "daltonizer_preference";
+    private static final String TOGGLE_INVERSION_PREFERENCE = "toggle_inversion_preference";
+    private static final String DISPLAY_REDUCE_BRIGHT_COLORS_PREFERENCE_SCREEN =
+            "reduce_bright_colors_preference";
+    private static final String TOGGLE_DISABLE_ANIMATIONS = "toggle_disable_animations";
+    private static final String TOGGLE_LARGE_POINTER_ICON = "toggle_large_pointer_icon";
+
+    private Preference mDisplayDaltonizerPreferenceScreen;
+    private Preference mToggleInversionPreference;
+    private Preference mReduceBrightColorsPreference;
+    private SwitchPreference mToggleDisableAnimationsPreference;
+    private SwitchPreference mToggleLargePointerIconPreference;
+
+    @Override
+    public int getMetricsCategory() {
+        return SettingsEnums.ACCESSIBILITY_TEXT_AND_DISPLAY;
+    }
+
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        initializeAllPreferences();
+        updateSystemPreferences();
+    }
+
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+        use(DarkUIPreferenceController.class).setParentFragment(this);
+    }
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.accessibility_text_and_display;
+    }
+
+    @Override
+    protected String getLogTag() {
+        return TAG;
+    }
+
+    private void initializeAllPreferences() {
+        // Display color adjustments.
+        mDisplayDaltonizerPreferenceScreen = findPreference(DISPLAY_DALTONIZER_PREFERENCE_SCREEN);
+
+        // Display inversion.
+        mToggleInversionPreference = findPreference(TOGGLE_INVERSION_PREFERENCE);
+
+        // Reduce brightness.
+        mReduceBrightColorsPreference =
+                findPreference(DISPLAY_REDUCE_BRIGHT_COLORS_PREFERENCE_SCREEN);
+
+        // Disable animation.
+        mToggleDisableAnimationsPreference = findPreference(TOGGLE_DISABLE_ANIMATIONS);
+
+        // Large pointer icon.
+        mToggleLargePointerIconPreference = findPreference(TOGGLE_LARGE_POINTER_ICON);
+    }
+
+    /**
+     * Updates preferences related to system configurations.
+     */
+    private void updateSystemPreferences() {
+        final PreferenceCategory experimentalCategory = getPreferenceScreen().findPreference(
+                CATEGORY_EXPERIMENTAL);
+        if (ColorDisplayManager.isColorTransformAccelerated(getContext())) {
+            mDisplayDaltonizerPreferenceScreen.setSummary(AccessibilityUtil.getSummary(
+                    getContext(), Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED));
+            mToggleInversionPreference.setSummary(AccessibilityUtil.getSummary(
+                    getContext(), Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED));
+            mReduceBrightColorsPreference.setSummary(AccessibilityUtil.getSummary(
+                    getContext(), Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED));
+            getPreferenceScreen().removePreference(experimentalCategory);
+        } else {
+            // Move following preferences to experimental category if device don't supports HWC
+            // hardware-accelerated color transform.
+            getPreferenceScreen().removePreference(mDisplayDaltonizerPreferenceScreen);
+            getPreferenceScreen().removePreference(mToggleInversionPreference);
+            getPreferenceScreen().removePreference(mReduceBrightColorsPreference);
+            getPreferenceScreen().removePreference(mToggleDisableAnimationsPreference);
+            getPreferenceScreen().removePreference(mToggleLargePointerIconPreference);
+            experimentalCategory.addPreference(mDisplayDaltonizerPreferenceScreen);
+            experimentalCategory.addPreference(mToggleInversionPreference);
+            experimentalCategory.addPreference(mReduceBrightColorsPreference);
+            experimentalCategory.addPreference(mToggleDisableAnimationsPreference);
+            experimentalCategory.addPreference(mToggleLargePointerIconPreference);
+        }
+    }
+
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+            new BaseSearchIndexProvider(R.xml.accessibility_text_and_display);
+}
diff --git a/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceController.java b/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceController.java
new file mode 100644
index 0000000..a43b9fd
--- /dev/null
+++ b/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceController.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2020 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.applications.specialaccess.notificationaccess;
+
+import android.app.NotificationManager;
+import android.app.settings.SettingsEnums;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.os.AsyncTask;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceFragmentCompat;
+import androidx.preference.SwitchPreference;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.overlay.FeatureFactory;
+
+public class ApprovalPreferenceController extends BasePreferenceController {
+
+    private static final String TAG = "ApprovalPrefController";
+
+    private PackageInfo mPkgInfo;
+    private ComponentName mCn;
+    private PreferenceFragmentCompat mParent;
+    private NotificationManager mNm;
+    private PackageManager mPm;
+
+    public ApprovalPreferenceController(Context context, String key) {
+        super(context, key);
+    }
+
+    public ApprovalPreferenceController setPkgInfo(PackageInfo pkgInfo) {
+        mPkgInfo = pkgInfo;
+        return this;
+    }
+
+    public ApprovalPreferenceController setCn(ComponentName cn) {
+        mCn = cn;
+        return this;
+    }
+
+    public ApprovalPreferenceController setParent(PreferenceFragmentCompat parent) {
+        mParent = parent;
+        return this;
+    }
+
+    public ApprovalPreferenceController setNm(NotificationManager nm) {
+        mNm = nm;
+        return this;
+    }
+
+    public ApprovalPreferenceController setPm(PackageManager pm) {
+        mPm = pm;
+        return this;
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return AVAILABLE;
+    }
+
+    @Override
+    public void updateState(Preference pref) {
+        final SwitchPreference preference = (SwitchPreference) pref;
+        final CharSequence label = mPkgInfo.applicationInfo.loadLabel(mPm);
+        preference.setChecked(isServiceEnabled(mCn));
+        preference.setOnPreferenceChangeListener((p, newValue) -> {
+            final boolean access = (Boolean) newValue;
+            if (!access) {
+                if (!isServiceEnabled(mCn)) {
+                    return true; // already disabled
+                }
+                // show a friendly dialog
+                new FriendlyWarningDialogFragment()
+                        .setServiceInfo(mCn, label, mParent)
+                        .show(mParent.getFragmentManager(), "friendlydialog");
+                return false;
+            } else {
+                if (isServiceEnabled(mCn)) {
+                    return true; // already enabled
+                }
+                // show a scary dialog
+                new ScaryWarningDialogFragment()
+                        .setServiceInfo(mCn, label, mParent)
+                        .show(mParent.getFragmentManager(), "dialog");
+                return false;
+            }
+        });
+    }
+
+    public void disable(final ComponentName cn) {
+        logSpecialPermissionChange(true, cn.getPackageName());
+        mNm.setNotificationListenerAccessGranted(cn, false);
+        AsyncTask.execute(() -> {
+            if (!mNm.isNotificationPolicyAccessGrantedForPackage(
+                    cn.getPackageName())) {
+                mNm.removeAutomaticZenRules(cn.getPackageName());
+            }
+        });
+    }
+
+    protected void enable(ComponentName cn) {
+        logSpecialPermissionChange(true, cn.getPackageName());
+        mNm.setNotificationListenerAccessGranted(cn, true);
+    }
+
+    protected boolean isServiceEnabled(ComponentName cn) {
+        return mNm.isNotificationListenerAccessGranted(cn);
+    }
+
+    @VisibleForTesting
+    void logSpecialPermissionChange(boolean enable, String packageName) {
+        final int logCategory = enable ? SettingsEnums.APP_SPECIAL_PERMISSION_NOTIVIEW_ALLOW
+                : SettingsEnums.APP_SPECIAL_PERMISSION_NOTIVIEW_DENY;
+        FeatureFactory.getFactory(mContext).getMetricsFeatureProvider().action(mContext,
+                logCategory, packageName);
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/applications/specialaccess/notificationaccess/HeaderPreferenceController.java b/src/com/android/settings/applications/specialaccess/notificationaccess/HeaderPreferenceController.java
new file mode 100644
index 0000000..94736e4
--- /dev/null
+++ b/src/com/android/settings/applications/specialaccess/notificationaccess/HeaderPreferenceController.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2020 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.applications.specialaccess.notificationaccess;
+
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.util.IconDrawableFactory;
+import android.view.View;
+
+import androidx.lifecycle.LifecycleObserver;
+import androidx.lifecycle.OnLifecycleEvent;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.widget.EntityHeaderController;
+import com.android.settingslib.applications.AppUtils;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.LayoutPreference;
+
+public class HeaderPreferenceController extends BasePreferenceController
+        implements PreferenceControllerMixin, LifecycleObserver {
+
+    private DashboardFragment mFragment;
+    private EntityHeaderController mHeaderController;
+    private PackageInfo mPackageInfo;
+    private PackageManager mPm;
+    private CharSequence mServiceName;
+
+    public HeaderPreferenceController(Context context, String key) {
+        super(context, key);
+    }
+
+    public HeaderPreferenceController setFragment(DashboardFragment fragment) {
+        mFragment = fragment;
+        return this;
+    }
+
+    public HeaderPreferenceController setPackageInfo(PackageInfo packageInfo) {
+        mPackageInfo = packageInfo;
+        return this;
+    }
+
+    public HeaderPreferenceController setPm(PackageManager pm) {
+        mPm = pm;
+        return this;
+    }
+
+    public HeaderPreferenceController setServiceName(CharSequence serviceName) {
+        mServiceName = serviceName;
+        return this;
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return AVAILABLE;
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        if (mFragment == null) {
+            return;
+        }
+        LayoutPreference pref = screen.findPreference(getPreferenceKey());
+        mHeaderController = EntityHeaderController.newInstance(
+                mFragment.getActivity(), mFragment, pref.findViewById(R.id.entity_header));
+        pref = mHeaderController
+                .setRecyclerView(mFragment.getListView(), mFragment.getSettingsLifecycle())
+                .setIcon(IconDrawableFactory.newInstance(mFragment.getActivity())
+                        .getBadgedIcon(mPackageInfo.applicationInfo))
+                .setLabel(mPackageInfo.applicationInfo.loadLabel(mPm))
+                .setSummary(mServiceName)
+                .setIsInstantApp(AppUtils.isInstant(mPackageInfo.applicationInfo))
+                .setPackageName(mPackageInfo.packageName)
+                .setUid(mPackageInfo.applicationInfo.uid)
+                .setHasAppInfoLink(true)
+                .setButtonActions(EntityHeaderController.ActionType.ACTION_NONE,
+                        EntityHeaderController.ActionType.ACTION_NONE)
+                .done(mFragment.getActivity(), mContext);
+        pref.findViewById(R.id.entity_header).setVisibility(View.VISIBLE);
+    }
+
+    @OnLifecycleEvent(Lifecycle.Event.ON_START)
+    public void onStart() {
+        if (mHeaderController != null) {
+            mHeaderController.styleActionBar(mFragment.getActivity());
+        }
+    }
+}
diff --git a/src/com/android/settings/applications/specialaccess/notificationaccess/NotificationAccessDetails.java b/src/com/android/settings/applications/specialaccess/notificationaccess/NotificationAccessDetails.java
index 58a6d7f..9f4b693 100644
--- a/src/com/android/settings/applications/specialaccess/notificationaccess/NotificationAccessDetails.java
+++ b/src/com/android/settings/applications/specialaccess/notificationaccess/NotificationAccessDetails.java
@@ -16,52 +16,55 @@
 
 package com.android.settings.applications.specialaccess.notificationaccess;
 
+import static com.android.settings.applications.AppInfoBase.ARG_PACKAGE_NAME;
+
 import android.app.Activity;
 import android.app.NotificationManager;
 import android.app.settings.SettingsEnums;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
-import android.os.AsyncTask;
 import android.os.Bundle;
+import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
 import android.service.notification.NotificationListenerService;
-import android.util.IconDrawableFactory;
 import android.util.Log;
 import android.util.Slog;
 
-import androidx.annotation.VisibleForTesting;
-import androidx.appcompat.app.AlertDialog;
-import androidx.preference.Preference;
-import androidx.preference.SwitchPreference;
+import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
-import com.android.settings.applications.AppInfoBase;
-import com.android.settings.overlay.FeatureFactory;
-import com.android.settings.widget.EntityHeaderController;
-import com.android.settingslib.applications.AppUtils;
+import com.android.settings.SettingsActivity;
+import com.android.settings.applications.manageapplications.ManageApplications;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.notification.NotificationBackend;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
 
 import java.util.List;
 import java.util.Objects;
 
-public class NotificationAccessDetails extends AppInfoBase {
+public class NotificationAccessDetails extends DashboardFragment {
     private static final String TAG = "NotifAccessDetails";
-    private static final String SWITCH_PREF_KEY = "notification_access_switch";
 
-    private boolean mCreated;
     private ComponentName mComponentName;
     private CharSequence mServiceName;
+    protected PackageInfo mPackageInfo;
+    protected int mUserId;
+    protected String mPackageName;
+    protected RestrictedLockUtils.EnforcedAdmin mAppsControlDisallowedAdmin;
+    protected boolean mAppsControlDisallowedBySystem;
     private boolean mIsNls;
-
-    private NotificationManager mNm;
     private PackageManager mPm;
 
     @Override
-    public void onCreate(Bundle savedInstanceState) {
+    public void onAttach(Context context) {
+        super.onAttach(context);
         final Intent intent = getIntent();
         if (mComponentName == null && intent != null) {
             String cn = intent.getStringExtra(Settings.EXTRA_NOTIFICATION_LISTENER_COMPONENT_NAME);
@@ -73,38 +76,24 @@
                 }
             }
         }
-        super.onCreate(savedInstanceState);
-        mNm = getContext().getSystemService(NotificationManager.class);
         mPm = getPackageManager();
-        addPreferencesFromResource(R.xml.notification_access_permission_details);
-    }
-
-    @Override
-    public void onActivityCreated(Bundle savedInstanceState) {
-        super.onActivityCreated(savedInstanceState);
-        if (mCreated) {
-            Log.w(TAG, "onActivityCreated: ignoring duplicate call");
-            return;
-        }
-        mCreated = true;
-        if (mPackageInfo == null) return;
+        retrieveAppEntry();
         loadNotificationListenerService();
-        final Activity activity = getActivity();
-        final Preference pref = EntityHeaderController
-                .newInstance(activity, this, null /* header */)
-                .setRecyclerView(getListView(), getSettingsLifecycle())
-                .setIcon(IconDrawableFactory.newInstance(getContext())
-                        .getBadgedIcon(mPackageInfo.applicationInfo))
-                .setLabel(mPackageInfo.applicationInfo.loadLabel(mPm))
-                .setSummary(mServiceName)
-                .setIsInstantApp(AppUtils.isInstant(mPackageInfo.applicationInfo))
-                .setPackageName(mPackageName)
-                .setUid(mPackageInfo.applicationInfo.uid)
-                .setHasAppInfoLink(true)
-                .setButtonActions(EntityHeaderController.ActionType.ACTION_NONE,
-                        EntityHeaderController.ActionType.ACTION_NONE)
-                .done(activity, getPrefContext());
-        getPreferenceScreen().addPreference(pref);
+        use(ApprovalPreferenceController.class)
+                .setPkgInfo(mPackageInfo)
+                .setCn(mComponentName)
+                .setNm(context.getSystemService(NotificationManager.class))
+                .setPm(context.getPackageManager())
+                .setParent(this);
+        use(HeaderPreferenceController.class)
+                .setFragment(this)
+                .setPackageInfo(mPackageInfo)
+                .setPm(context.getPackageManager())
+                .setServiceName(mServiceName);
+        use(TypeFilterPreferenceController.class)
+                .setNm(new NotificationBackend())
+                .setCn(mComponentName)
+                .setUserId(mUserId);
     }
 
     @Override
@@ -112,9 +101,7 @@
         return SettingsEnums.NOTIFICATION_ACCESS_DETAIL;
     }
 
-    @Override
     protected boolean refreshUi() {
-        final Context context = getContext();
         if (mComponentName == null) {
             // No service given
             Slog.d(TAG, "No component name provided");
@@ -130,72 +117,78 @@
             Slog.d(TAG, "NLSes aren't allowed in work profiles");
             return false;
         }
-        updatePreference(findPreference(SWITCH_PREF_KEY));
         return true;
     }
 
     @Override
-    protected AlertDialog createDialog(int id, int errorCode) {
-        return null;
+    public void onResume() {
+        super.onResume();
+        mAppsControlDisallowedAdmin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
+                getActivity(), UserManager.DISALLOW_APPS_CONTROL, mUserId);
+        mAppsControlDisallowedBySystem = RestrictedLockUtilsInternal.hasBaseUserRestriction(
+                getActivity(), UserManager.DISALLOW_APPS_CONTROL, mUserId);
+
+        if (!refreshUi()) {
+            setIntentAndFinish(true /* appChanged */);
+        }
     }
 
-    public void updatePreference(SwitchPreference preference) {
-        final CharSequence label = mPackageInfo.applicationInfo.loadLabel(mPm);
-        preference.setChecked(isServiceEnabled(mComponentName));
-        preference.setOnPreferenceChangeListener((p, newValue) -> {
-            final boolean access = (Boolean) newValue;
-            if (!access) {
-                if (!isServiceEnabled(mComponentName)) {
-                    return true; // already disabled
-                }
-                // show a friendly dialog
-                new FriendlyWarningDialogFragment()
-                        .setServiceInfo(mComponentName, label, this)
-                        .show(getFragmentManager(), "friendlydialog");
-                return false;
-            } else {
-                if (isServiceEnabled(mComponentName)) {
-                    return true; // already enabled
-                }
-                // show a scary dialog
-                new ScaryWarningDialogFragment()
-                        .setServiceInfo(mComponentName, label, this)
-                        .show(getFragmentManager(), "dialog");
-                return false;
+    protected void setIntentAndFinish(boolean appChanged) {
+        Log.i(TAG, "appChanged=" + appChanged);
+        Intent intent = new Intent();
+        intent.putExtra(ManageApplications.APP_CHG, appChanged);
+        SettingsActivity sa = (SettingsActivity) getActivity();
+        sa.finishPreferencePanel(Activity.RESULT_OK, intent);
+    }
+
+    protected void retrieveAppEntry() {
+        final Bundle args = getArguments();
+        mPackageName = (args != null) ? args.getString(ARG_PACKAGE_NAME) : null;
+        Intent intent = (args == null) ?
+                getIntent() : (Intent) args.getParcelable("intent");
+        if (mPackageName == null) {
+            if (intent != null && intent.getData() != null) {
+                mPackageName = intent.getData().getSchemeSpecificPart();
             }
-        });
+        }
+        if (intent != null && intent.hasExtra(Intent.EXTRA_USER_HANDLE)) {
+            mUserId = ((UserHandle) intent.getParcelableExtra(
+                    Intent.EXTRA_USER_HANDLE)).getIdentifier();
+        } else {
+            mUserId = UserHandle.myUserId();
+        }
+
+        try {
+            mPackageInfo = mPm.getPackageInfoAsUser(mPackageName,
+                    PackageManager.MATCH_DISABLED_COMPONENTS |
+                            PackageManager.GET_SIGNING_CERTIFICATES |
+                            PackageManager.GET_PERMISSIONS, mUserId);
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.e(TAG, "Exception when retrieving package:" + mPackageName, e);
+        }
     }
 
-    @VisibleForTesting
-    void logSpecialPermissionChange(boolean enable, String packageName) {
-        int logCategory = enable ? SettingsEnums.APP_SPECIAL_PERMISSION_NOTIVIEW_ALLOW
-                : SettingsEnums.APP_SPECIAL_PERMISSION_NOTIVIEW_DENY;
-        FeatureFactory.getFactory(getContext()).getMetricsFeatureProvider().action(getContext(),
-                logCategory, packageName);
-    }
-
+    // Dialogs only have access to the parent fragment, not the controller, so pass the information
+    // along to keep business logic out of this file
     public void disable(final ComponentName cn) {
-        logSpecialPermissionChange(true, cn.getPackageName());
-        mNm.setNotificationListenerAccessGranted(cn, false);
-        AsyncTask.execute(() -> {
-            if (!mNm.isNotificationPolicyAccessGrantedForPackage(
-                    cn.getPackageName())) {
-                mNm.removeAutomaticZenRules(cn.getPackageName());
-            }
-        });
-        refreshUi();
+        final PreferenceScreen screen = getPreferenceScreen();
+        ApprovalPreferenceController controller = use(ApprovalPreferenceController.class);
+        controller.disable(cn);
+        controller.updateState(screen.findPreference(controller.getPreferenceKey()));
+        TypeFilterPreferenceController dependent1 = use(TypeFilterPreferenceController.class);
+        dependent1.updateState(screen.findPreference(dependent1.getPreferenceKey()));
     }
 
     protected void enable(ComponentName cn) {
-        logSpecialPermissionChange(true, cn.getPackageName());
-        mNm.setNotificationListenerAccessGranted(cn, true);
-        refreshUi();
+        final PreferenceScreen screen = getPreferenceScreen();
+        ApprovalPreferenceController controller = use(ApprovalPreferenceController.class);
+        controller.enable(cn);
+        controller.updateState(screen.findPreference(controller.getPreferenceKey()));
+        TypeFilterPreferenceController dependent1 = use(TypeFilterPreferenceController.class);
+        dependent1.updateState(screen.findPreference(dependent1.getPreferenceKey()));
     }
 
-    protected boolean isServiceEnabled(ComponentName cn) {
-        return mNm.isNotificationListenerAccessGranted(cn);
-    }
-
+    // To save binder calls, load this in the fragment rather than each preference controller
     protected void loadNotificationListenerService() {
         mIsNls = false;
 
@@ -218,4 +211,14 @@
             }
         }
     }
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.notification_access_permission_details;
+    }
+
+    @Override
+    protected String getLogTag() {
+        return TAG;
+    }
 }
\ No newline at end of file
diff --git a/src/com/android/settings/applications/specialaccess/notificationaccess/TypeFilterPreferenceController.java b/src/com/android/settings/applications/specialaccess/notificationaccess/TypeFilterPreferenceController.java
new file mode 100644
index 0000000..9d7fcc1
--- /dev/null
+++ b/src/com/android/settings/applications/specialaccess/notificationaccess/TypeFilterPreferenceController.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.applications.specialaccess.notificationaccess;
+
+import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ALERTING;
+import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_CONVERSATIONS;
+import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ONGOING;
+import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_SILENT;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.service.notification.NotificationListenerFilter;
+
+import androidx.preference.MultiSelectListPreference;
+import androidx.preference.Preference;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.notification.NotificationBackend;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class TypeFilterPreferenceController extends BasePreferenceController implements
+        PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
+
+    private static final String TAG = "TypeFilterPrefCntlr";
+
+    private ComponentName mCn;
+    private int mUserId;
+    private NotificationBackend mNm;
+    private NotificationListenerFilter mNlf;
+
+    public TypeFilterPreferenceController(Context context, String key) {
+        super(context, key);
+    }
+
+    public TypeFilterPreferenceController setCn(ComponentName cn) {
+        mCn = cn;
+        return this;
+    }
+
+    public TypeFilterPreferenceController setUserId(int userId) {
+        mUserId = userId;
+        return this;
+    }
+
+    public TypeFilterPreferenceController setNm(NotificationBackend nm) {
+        mNm = nm;
+        return this;
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        if (mNm.isNotificationListenerAccessGranted(mCn)) {
+            return AVAILABLE;
+        } else {
+            return DISABLED_DEPENDENT_SETTING;
+        }
+    }
+
+    @Override
+    public void updateState(Preference pref) {
+        mNlf = mNm.getListenerFilter(mCn, mUserId);
+        Set<String> values = new HashSet<>();
+        Set<String> entries = new HashSet<>();
+
+        if (hasFlag(mNlf.getTypes(), FLAG_FILTER_TYPE_ONGOING)) {
+            values.add(String.valueOf(FLAG_FILTER_TYPE_ONGOING));
+            entries.add(mContext.getString(R.string.notif_type_ongoing));
+        }
+        if (hasFlag(mNlf.getTypes(), FLAG_FILTER_TYPE_CONVERSATIONS)) {
+            values.add(String.valueOf(FLAG_FILTER_TYPE_CONVERSATIONS));
+            entries.add(mContext.getString(R.string.notif_type_conversation));
+        }
+        if (hasFlag(mNlf.getTypes(), FLAG_FILTER_TYPE_ALERTING)) {
+            values.add(String.valueOf(FLAG_FILTER_TYPE_ALERTING));
+            entries.add(mContext.getString(R.string.notif_type_alerting));
+        }
+        if (hasFlag(mNlf.getTypes(), FLAG_FILTER_TYPE_SILENT)) {
+            values.add(String.valueOf(FLAG_FILTER_TYPE_SILENT));
+            entries.add(mContext.getString(R.string.notif_type_silent));
+        }
+
+        final MultiSelectListPreference preference = (MultiSelectListPreference) pref;
+        preference.setValues(values);
+        super.updateState(preference);
+        pref.setEnabled(getAvailabilityStatus() == AVAILABLE);
+    }
+
+    private boolean hasFlag(int value, int flag) {
+        return (value & flag) != 0;
+    }
+
+    public CharSequence getSummary() {
+        Set<String> entries = new HashSet<>();
+        if (hasFlag(mNlf.getTypes(), FLAG_FILTER_TYPE_ONGOING)) {
+            entries.add(mContext.getString(R.string.notif_type_ongoing));
+        }
+        if (hasFlag(mNlf.getTypes(), FLAG_FILTER_TYPE_CONVERSATIONS)) {
+            entries.add(mContext.getString(R.string.notif_type_conversation));
+        }
+        if (hasFlag(mNlf.getTypes(), FLAG_FILTER_TYPE_ALERTING)) {
+            entries.add(mContext.getString(R.string.notif_type_alerting));
+        }
+        if (hasFlag(mNlf.getTypes(), FLAG_FILTER_TYPE_SILENT)) {
+            entries.add(mContext.getString(R.string.notif_type_silent));
+        }
+        return String.join(System.lineSeparator(), entries);
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        // retrieve latest in case the package filter has changed
+        mNlf = mNm.getListenerFilter(mCn, mUserId);
+
+        Set<String> set = (Set<String>) newValue;
+
+        int newFilter = 0;
+        for (String filterType : set) {
+            newFilter |= Integer.parseInt(filterType);
+        }
+        mNlf.setTypes(newFilter);
+        preference.setSummary(getSummary());
+        mNm.setListenerFilter(mCn, mUserId, mNlf);
+        return true;
+    }
+
+}
\ No newline at end of file
diff --git a/src/com/android/settings/dashboard/DashboardFragmentRegistry.java b/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
index f8a4f39..2e326b0 100644
--- a/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
+++ b/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
@@ -29,6 +29,7 @@
 import com.android.settings.deviceinfo.StorageDashboardFragment;
 import com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment;
 import com.android.settings.display.NightDisplaySettings;
+import com.android.settings.emergency.EmergencyDashboardFragment;
 import com.android.settings.enterprise.EnterprisePrivacySettings;
 import com.android.settings.fuelgauge.PowerUsageSummary;
 import com.android.settings.fuelgauge.SmartBatterySettings;
@@ -81,6 +82,8 @@
                 CategoryKey.CATEGORY_BATTERY);
         PARENT_TO_CATEGORY_KEY_MAP.put(DisplaySettings.class.getName(),
                 CategoryKey.CATEGORY_DISPLAY);
+        PARENT_TO_CATEGORY_KEY_MAP.put(EmergencyDashboardFragment.class.getName(),
+                CategoryKey.CATEGORY_EMERGENCY);
         PARENT_TO_CATEGORY_KEY_MAP.put(SoundSettings.class.getName(),
                 CategoryKey.CATEGORY_SOUND);
         PARENT_TO_CATEGORY_KEY_MAP.put(StorageDashboardFragment.class.getName(),
diff --git a/src/com/android/settings/display/NightDisplayPreferenceController.java b/src/com/android/settings/display/NightDisplayPreferenceController.java
index 0198007..003373c 100644
--- a/src/com/android/settings/display/NightDisplayPreferenceController.java
+++ b/src/com/android/settings/display/NightDisplayPreferenceController.java
@@ -17,6 +17,7 @@
 import android.hardware.display.ColorDisplayManager;
 import android.hardware.display.NightDisplayListener;
 
+import androidx.preference.Preference;
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
@@ -32,6 +33,7 @@
 
     private final ColorDisplayManager mColorDisplayManager;
     private final NightDisplayListener mNightDisplayListener;
+    private final NightDisplayTimeFormatter mTimeFormatter;
     private PrimarySwitchPreference mPreference;
 
     public NightDisplayPreferenceController(Context context, String key) {
@@ -39,6 +41,7 @@
 
         mColorDisplayManager = context.getSystemService(ColorDisplayManager.class);
         mNightDisplayListener = new NightDisplayListener(context);
+        mTimeFormatter = new NightDisplayTimeFormatter(context);
     }
 
     public static boolean isSuggestionComplete(Context context) {
@@ -87,6 +90,12 @@
     }
 
     @Override
+    public void updateState(Preference preference) {
+        super.updateState(preference);
+        preference.setSummary(mTimeFormatter.getAutoModeSummary(mContext, mColorDisplayManager));
+    }
+
+    @Override
     public void onActivated(boolean activated) {
         updateState(mPreference);
     }
diff --git a/src/com/android/settings/display/NightDisplayTimeFormatter.java b/src/com/android/settings/display/NightDisplayTimeFormatter.java
index 1449ac1..aa715de 100644
--- a/src/com/android/settings/display/NightDisplayTimeFormatter.java
+++ b/src/com/android/settings/display/NightDisplayTimeFormatter.java
@@ -17,8 +17,8 @@
 package com.android.settings.display;
 
 import android.content.Context;
-
 import android.hardware.display.ColorDisplayManager;
+
 import com.android.settings.R;
 
 import java.text.DateFormat;
@@ -45,13 +45,6 @@
         return mTimeFormatter.format(c.getTime());
     }
 
-    public String getAutoModeTimeSummary(Context context, ColorDisplayManager manager) {
-        final int summaryFormatResId =
-                manager.isNightDisplayActivated() ? R.string.night_display_summary_on
-                        : R.string.night_display_summary_off;
-        return context.getString(summaryFormatResId, getAutoModeSummary(context, manager));
-    }
-
     public String getAutoModeSummary(Context context, ColorDisplayManager manager) {
         final boolean isActivated = manager.isNightDisplayActivated();
         final int autoMode = manager.getNightDisplayAutoMode();
diff --git a/src/com/android/settings/display/ScreenTimeoutSettings.java b/src/com/android/settings/display/ScreenTimeoutSettings.java
index 83f904a..a90c886 100644
--- a/src/com/android/settings/display/ScreenTimeoutSettings.java
+++ b/src/com/android/settings/display/ScreenTimeoutSettings.java
@@ -37,13 +37,13 @@
 import com.android.settings.support.actionbar.HelpMenuController;
 import com.android.settings.support.actionbar.HelpResourceProvider;
 import com.android.settings.widget.RadioButtonPickerFragment;
-import com.android.settings.widget.RadioButtonPreferenceWithExtraWidget;
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.settingslib.RestrictedLockUtilsInternal;
 import com.android.settingslib.search.SearchIndexable;
 import com.android.settingslib.search.SearchIndexableRaw;
 import com.android.settingslib.widget.CandidateInfo;
 import com.android.settingslib.widget.FooterPreference;
+import com.android.settingslib.widget.RadioButtonPreference;
 
 import com.google.common.annotations.VisibleForTesting;
 
@@ -152,8 +152,8 @@
         }
 
         for (CandidateInfo info : candidateList) {
-            RadioButtonPreferenceWithExtraWidget pref =
-                    new RadioButtonPreferenceWithExtraWidget(getPrefContext());
+            RadioButtonPreference pref =
+                    new RadioButtonPreference(getPrefContext());
             bindPreference(pref, info.getKey(), info, defaultKey);
             screen.addPreference(pref);
         }
diff --git a/src/com/android/settings/display/darkmode/DarkModePreference.java b/src/com/android/settings/display/darkmode/DarkModePreference.java
index baaa1f7..c69bb01 100644
--- a/src/com/android/settings/display/darkmode/DarkModePreference.java
+++ b/src/com/android/settings/display/darkmode/DarkModePreference.java
@@ -74,10 +74,10 @@
             return;
         }
         final int mode = mUiModeManager.getNightMode();
-        String detail;
+        String summary;
 
         if (mode == UiModeManager.MODE_NIGHT_AUTO) {
-            detail = getContext().getString(active
+            summary = getContext().getString(active
                     ? R.string.dark_ui_summary_on_auto_mode_auto
                     : R.string.dark_ui_summary_off_auto_mode_auto);
         } else if (mode == UiModeManager.MODE_NIGHT_CUSTOM) {
@@ -85,17 +85,14 @@
                     ? mUiModeManager.getCustomNightModeEnd()
                     : mUiModeManager.getCustomNightModeStart();
             final String timeStr = mFormat.of(time);
-            detail = getContext().getString(active
+            summary = getContext().getString(active
                     ? R.string.dark_ui_summary_on_auto_mode_custom
                     : R.string.dark_ui_summary_off_auto_mode_custom, timeStr);
         } else {
-            detail = getContext().getString(active
+            summary = getContext().getString(active
                     ? R.string.dark_ui_summary_on_auto_mode_never
                     : R.string.dark_ui_summary_off_auto_mode_never);
         }
-        String summary = getContext().getString(active
-                ? R.string.dark_ui_summary_on
-                : R.string.dark_ui_summary_off, detail);
 
         setSummary(summary);
     }
diff --git a/src/com/android/settings/emergency/EmergencyDashboardFragment.java b/src/com/android/settings/emergency/EmergencyDashboardFragment.java
new file mode 100644
index 0000000..c786767
--- /dev/null
+++ b/src/com/android/settings/emergency/EmergencyDashboardFragment.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.emergency;
+
+import android.app.settings.SettingsEnums;
+
+import com.android.settings.R;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settingslib.search.SearchIndexable;
+
+
+/**
+ * {@link DashboardFragment} that hosts emergency/safety related settings.
+ */
+@SearchIndexable
+public class EmergencyDashboardFragment extends DashboardFragment {
+
+    private static final String TAG = "EmergencyDashboard";
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.emergency_settings;
+    }
+
+    @Override
+    protected String getLogTag() {
+        return TAG;
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        return SettingsEnums.EMERGENCY_SOS_GESTURE_SETTINGS;
+    }
+
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+            new BaseSearchIndexProvider(R.xml.emergency_settings);
+}
diff --git a/src/com/android/settings/emergency/OWNERS b/src/com/android/settings/emergency/OWNERS
new file mode 100644
index 0000000..5707f87
--- /dev/null
+++ b/src/com/android/settings/emergency/OWNERS
@@ -0,0 +1 @@
+zhfan@google.com
\ No newline at end of file
diff --git a/src/com/android/settings/gestures/SystemNavigationGestureSettings.java b/src/com/android/settings/gestures/SystemNavigationGestureSettings.java
index bed14a8..ddcdd59 100644
--- a/src/com/android/settings/gestures/SystemNavigationGestureSettings.java
+++ b/src/com/android/settings/gestures/SystemNavigationGestureSettings.java
@@ -21,9 +21,6 @@
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY;
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY;
 
-import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_GONE;
-import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_SETTING;
-
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.content.Intent;
@@ -49,7 +46,6 @@
 import com.android.settings.support.actionbar.HelpResourceProvider;
 import com.android.settings.utils.CandidateInfoExtra;
 import com.android.settings.widget.RadioButtonPickerFragment;
-import com.android.settings.widget.RadioButtonPreferenceWithExtraWidget;
 import com.android.settings.widget.VideoPreference;
 import com.android.settingslib.search.SearchIndexable;
 import com.android.settingslib.widget.CandidateInfo;
@@ -119,8 +115,8 @@
             return;
         }
         for (CandidateInfo info : candidateList) {
-            RadioButtonPreferenceWithExtraWidget pref =
-                    new RadioButtonPreferenceWithExtraWidget(getPrefContext());
+            RadioButtonPreference pref =
+                    new RadioButtonPreference(getPrefContext());
             bindPreference(pref, info.getKey(), info, defaultKey);
             bindPreferenceExtra(pref, info.getKey(), info, defaultKey, systemDefaultKey);
             screen.addPreference(pref);
@@ -131,20 +127,15 @@
     @Override
     public void bindPreferenceExtra(RadioButtonPreference pref,
             String key, CandidateInfo info, String defaultKey, String systemDefaultKey) {
-        if (!(info instanceof CandidateInfoExtra)
-                || !(pref instanceof RadioButtonPreferenceWithExtraWidget)) {
+        if (!(info instanceof CandidateInfoExtra)) {
             return;
         }
 
         pref.setSummary(((CandidateInfoExtra) info).loadSummary());
 
-        RadioButtonPreferenceWithExtraWidget p = (RadioButtonPreferenceWithExtraWidget) pref;
         if (info.getKey() == KEY_SYSTEM_NAV_GESTURAL) {
-            p.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_SETTING);
-            p.setExtraWidgetOnClickListener((v) -> startActivity(new Intent(
+            pref.setExtraWidgetOnClickListener((v) -> startActivity(new Intent(
                     GestureNavigationSettingsFragment.GESTURE_NAVIGATION_SETTINGS)));
-        } else {
-            p.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_GONE);
         }
     }
 
diff --git a/src/com/android/settings/network/NetworkMobileProviderController.java b/src/com/android/settings/network/NetworkMobileProviderController.java
index 4c29256..5dc6c0d 100644
--- a/src/com/android/settings/network/NetworkMobileProviderController.java
+++ b/src/com/android/settings/network/NetworkMobileProviderController.java
@@ -24,6 +24,7 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.core.BasePreferenceController;
+import com.android.settings.wifi.WifiPickerTrackerHelper;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 
 /**
@@ -115,4 +116,10 @@
         }
         mPreferenceCategory.setVisible(available);
     }
+
+    public void setWifiPickerTrackerHelper(WifiPickerTrackerHelper helper) {
+        if (mSubscriptionsController != null) {
+            mSubscriptionsController.setWifiPickerTrackerHelper(helper);
+        }
+    }
 }
diff --git a/src/com/android/settings/network/NetworkProviderSettings.java b/src/com/android/settings/network/NetworkProviderSettings.java
index c2881ac..c4c767b 100644
--- a/src/com/android/settings/network/NetworkProviderSettings.java
+++ b/src/com/android/settings/network/NetworkProviderSettings.java
@@ -27,19 +27,12 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
-import android.net.ConnectivityManager;
-import android.net.NetworkScoreManager;
 import android.net.NetworkTemplate;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiManager;
 import android.os.Bundle;
 import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
 import android.os.PowerManager;
-import android.os.Process;
-import android.os.SimpleClock;
-import android.os.SystemClock;
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.FeatureFlagUtils;
@@ -74,6 +67,7 @@
 import com.android.settings.wifi.WifiConfigUiBase2;
 import com.android.settings.wifi.WifiConnectListener;
 import com.android.settings.wifi.WifiDialog2;
+import com.android.settings.wifi.WifiPickerTrackerHelper;
 import com.android.settings.wifi.WifiUtils;
 import com.android.settings.wifi.details2.WifiNetworkDetailsFragment2;
 import com.android.settings.wifi.dpp.WifiDppUtils;
@@ -88,8 +82,6 @@
 import com.android.wifitrackerlib.WifiEntry.ConnectCallback;
 import com.android.wifitrackerlib.WifiPickerTracker;
 
-import java.time.Clock;
-import java.time.ZoneOffset;
 import java.util.List;
 import java.util.Optional;
 
@@ -115,11 +107,6 @@
     static final int MENU_ID_FORGET = Menu.FIRST + 3;
     static final int MENU_ID_MODIFY = Menu.FIRST + 4;
 
-    // Max age of tracked WifiEntries
-    private static final long MAX_SCAN_AGE_MILLIS = 15_000;
-    // Interval between initiating WifiPickerTracker scans
-    private static final long SCAN_INTERVAL_MILLIS = 10_000;
-
     @VisibleForTesting
     static final int ADD_NETWORK_REQUEST = 2;
     static final int CONFIG_NETWORK_REQUEST = 3;
@@ -187,11 +174,9 @@
      */
     private boolean mIsRestricted;
 
-    // Worker thread used for WifiPickerTracker work
-    private HandlerThread mWorkerThread;
-
     @VisibleForTesting
     WifiPickerTracker mWifiPickerTracker;
+    private WifiPickerTrackerHelper mWifiPickerTrackerHelper;
 
     private WifiDialog2 mDialog;
 
@@ -279,27 +264,9 @@
     public void onActivityCreated(Bundle savedInstanceState) {
         super.onActivityCreated(savedInstanceState);
 
-        final Context context = getContext();
-        mWorkerThread = new HandlerThread(TAG
-                + "{" + Integer.toHexString(System.identityHashCode(this)) + "}",
-                Process.THREAD_PRIORITY_BACKGROUND);
-        mWorkerThread.start();
-        final Clock elapsedRealtimeClock = new SimpleClock(ZoneOffset.UTC) {
-            @Override
-            public long millis() {
-                return SystemClock.elapsedRealtime();
-            }
-        };
-        mWifiPickerTracker = new WifiPickerTracker(getSettingsLifecycle(), context,
-                context.getSystemService(WifiManager.class),
-                context.getSystemService(ConnectivityManager.class),
-                context.getSystemService(NetworkScoreManager.class),
-                new Handler(Looper.getMainLooper()),
-                mWorkerThread.getThreadHandler(),
-                elapsedRealtimeClock,
-                MAX_SCAN_AGE_MILLIS,
-                SCAN_INTERVAL_MILLIS,
-                this);
+        mWifiPickerTrackerHelper =
+                new WifiPickerTrackerHelper(getSettingsLifecycle(), getContext(), this);
+        mWifiPickerTracker = mWifiPickerTrackerHelper.getWifiPickerTracker();
 
         final Activity activity = getActivity();
 
@@ -356,6 +323,10 @@
         if (intent.hasExtra(EXTRA_START_CONNECT_SSID)) {
             mOpenSsid = intent.getStringExtra(EXTRA_START_CONNECT_SSID);
         }
+
+        if (mNetworkMobileProviderController != null) {
+            mNetworkMobileProviderController.setWifiPickerTrackerHelper(mWifiPickerTrackerHelper);
+        }
     }
 
     @Override
@@ -365,13 +336,6 @@
     }
 
     @Override
-    public void onDestroyView() {
-        mWorkerThread.quit();
-
-        super.onDestroyView();
-    }
-
-    @Override
     public void onStart() {
         super.onStart();
 
diff --git a/src/com/android/settings/network/SubscriptionsPreferenceController.java b/src/com/android/settings/network/SubscriptionsPreferenceController.java
index a17fc60..6e67543 100644
--- a/src/com/android/settings/network/SubscriptionsPreferenceController.java
+++ b/src/com/android/settings/network/SubscriptionsPreferenceController.java
@@ -50,6 +50,7 @@
 import com.android.settings.network.telephony.MobileNetworkUtils;
 import com.android.settings.network.telephony.SignalStrengthListener;
 import com.android.settings.widget.GearPreference;
+import com.android.settings.wifi.WifiPickerTrackerHelper;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.net.SignalStrengthUtil;
 
@@ -84,6 +85,7 @@
     private MobileDataEnabledListener mDataEnabledListener;
     private DataConnectivityListener mConnectivityListener;
     private SignalStrengthListener mSignalStrengthListener;
+    private WifiPickerTrackerHelper mWifiPickerTrackerHelper;
 
     @VisibleForTesting
     final BroadcastReceiver mDataSubscriptionChangedReceiver = new BroadcastReceiver() {
@@ -215,7 +217,7 @@
             mPreferenceGroup.removeAll();
             mSubsGearPref = new GearPreference(mContext, null);
             mSubsGearPref.setOnPreferenceClickListener(preference -> {
-                //TODO(b/176141379) Wait for wifiManager#selectCarrier(int subscriptionId)
+                connectCarrierNetwork();
                 return true;
             });
             mSubsGearPref.setOnGearClickListener(p ->
@@ -466,6 +468,20 @@
                 ProxySubscriptionManager.getInstance(context), subId) != null);
     }
 
+    public void setWifiPickerTrackerHelper(WifiPickerTrackerHelper helper) {
+        mWifiPickerTrackerHelper = helper;
+    }
+
+    @VisibleForTesting
+    public void connectCarrierNetwork() {
+        if (mTelephonyManager == null || !mTelephonyManager.isDataEnabled()) {
+            return;
+        }
+        if (mWifiPickerTrackerHelper != null) {
+            mWifiPickerTrackerHelper.connectCarrierNetwork(null /* ConnectCallback */);
+        }
+    }
+
     SubsPrefCtrlInjector createSubsPrefCtrlInjector() {
         return new SubsPrefCtrlInjector();
     }
diff --git a/src/com/android/settings/network/telephony/MobileDataDialogFragment.java b/src/com/android/settings/network/telephony/MobileDataDialogFragment.java
index c8a1e98..180d503 100644
--- a/src/com/android/settings/network/telephony/MobileDataDialogFragment.java
+++ b/src/com/android/settings/network/telephony/MobileDataDialogFragment.java
@@ -28,6 +28,7 @@
 
 import com.android.settings.R;
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+import com.android.settings.wifi.WifiPickerTrackerHelper;
 
 
 /**
@@ -50,6 +51,8 @@
     private int mType;
     private int mSubId;
 
+    private WifiPickerTrackerHelper mWifiPickerTrackerHelper;
+
     public static MobileDataDialogFragment newInstance(int type, int subId) {
         final MobileDataDialogFragment dialogFragment = new MobileDataDialogFragment();
 
@@ -65,6 +68,8 @@
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         mSubscriptionManager = getContext().getSystemService(SubscriptionManager.class);
+        mWifiPickerTrackerHelper = new WifiPickerTrackerHelper(getSettingsLifecycle(), getContext(),
+                null /* WifiPickerTrackerCallback */);
     }
 
     @Override
@@ -124,11 +129,17 @@
             case TYPE_DISABLE_DIALOG:
                 MobileNetworkUtils.setMobileDataEnabled(getContext(), mSubId, false /* enabled */,
                         false /* disableOtherSubscriptions */);
+                if (mWifiPickerTrackerHelper != null) {
+                    mWifiPickerTrackerHelper.setCarrierNetworkEnabled(false);
+                }
                 break;
             case TYPE_MULTI_SIM_DIALOG:
                 mSubscriptionManager.setDefaultDataSubId(mSubId);
                 MobileNetworkUtils.setMobileDataEnabled(getContext(), mSubId, true /* enabled */,
                         true /* disableOtherSubscriptions */);
+                if (mWifiPickerTrackerHelper != null) {
+                    mWifiPickerTrackerHelper.setCarrierNetworkEnabled(true);
+                }
                 break;
             default:
                 throw new IllegalArgumentException("unknown type " + mType);
diff --git a/src/com/android/settings/network/telephony/MobileDataPreferenceController.java b/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
index 91c46df..78bc0a0 100644
--- a/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
+++ b/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
@@ -32,6 +32,7 @@
 
 import com.android.settings.R;
 import com.android.settings.network.MobileDataContentObserver;
+import com.android.settings.wifi.WifiPickerTrackerHelper;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnStart;
 import com.android.settingslib.core.lifecycle.events.OnStop;
@@ -54,6 +55,8 @@
     @VisibleForTesting
     boolean mNeedDialog;
 
+    private WifiPickerTrackerHelper mWifiPickerTrackerHelper;
+
     public MobileDataPreferenceController(Context context, String key) {
         super(context, key);
         mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
@@ -107,6 +110,9 @@
         if (!mNeedDialog) {
             // Update data directly if we don't need dialog
             MobileNetworkUtils.setMobileDataEnabled(mContext, mSubId, isChecked, false);
+            if (mWifiPickerTrackerHelper != null) {
+                mWifiPickerTrackerHelper.setCarrierNetworkEnabled(isChecked);
+            }
             return true;
         }
 
@@ -149,6 +155,10 @@
                 .createForSubscriptionId(mSubId);
     }
 
+    public void setWifiPickerTrackerHelper(WifiPickerTrackerHelper helper) {
+        mWifiPickerTrackerHelper = helper;
+    }
+
     @VisibleForTesting
     boolean isDialogNeeded() {
         final boolean enableData = !isChecked();
diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettings.java b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
index 2a11521..7c45949 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkSettings.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
@@ -43,6 +43,7 @@
 import com.android.settings.network.telephony.gsm.AutoSelectPreferenceController;
 import com.android.settings.network.telephony.gsm.OpenNetworkSelectPagePreferenceController;
 import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.wifi.WifiPickerTrackerHelper;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.search.SearchIndexable;
 import com.android.settingslib.utils.ThreadUtils;
@@ -147,6 +148,9 @@
         use(DisableSimFooterPreferenceController.class).init(mSubId);
         use(NrDisabledInDsdsFooterPreferenceController.class).init(mSubId);
         use(MobileDataPreferenceController.class).init(getFragmentManager(), mSubId);
+        use(MobileDataPreferenceController.class).setWifiPickerTrackerHelper(
+                new WifiPickerTrackerHelper(getSettingsLifecycle(), context,
+                        null /* WifiPickerTrackerCallback */));
         use(RoamingPreferenceController.class).init(getFragmentManager(), mSubId);
         use(ApnPreferenceController.class).init(mSubId);
         use(CarrierPreferenceController.class).init(mSubId);
diff --git a/src/com/android/settings/notification/NotificationBackend.java b/src/com/android/settings/notification/NotificationBackend.java
index 6d51eb3..43d1700 100644
--- a/src/com/android/settings/notification/NotificationBackend.java
+++ b/src/com/android/settings/notification/NotificationBackend.java
@@ -45,6 +45,7 @@
 import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.service.notification.ConversationChannelWrapper;
+import android.service.notification.NotificationListenerFilter;
 import android.text.format.DateUtils;
 import android.util.IconDrawableFactory;
 import android.util.Log;
@@ -593,6 +594,32 @@
         }
     }
 
+    public NotificationListenerFilter getListenerFilter(ComponentName cn, int userId) {
+        try {
+            return sINM.getListenerFilter(cn, userId);
+        } catch (Exception e) {
+            Log.w(TAG, "Error calling NoMan", e);
+        }
+        return new NotificationListenerFilter();
+    }
+
+    public void setListenerFilter(ComponentName cn, int userId, NotificationListenerFilter nlf) {
+        try {
+            sINM.setListenerFilter(cn, userId, nlf);
+        } catch (Exception e) {
+            Log.w(TAG, "Error calling NoMan", e);
+        }
+    }
+
+    public boolean isNotificationListenerAccessGranted(ComponentName cn) {
+        try {
+            return sINM.isNotificationListenerAccessGranted(cn);
+        } catch (Exception e) {
+            Log.w(TAG, "Error calling NoMan", e);
+        }
+        return false;
+    }
+
     /**
      * NotificationsSentState contains how often an app sends notifications and how recently it sent
      * one.
diff --git a/src/com/android/settings/notification/zen/ZenCustomRadioButtonPreference.java b/src/com/android/settings/notification/zen/ZenCustomRadioButtonPreference.java
deleted file mode 100644
index 57f4891..0000000
--- a/src/com/android/settings/notification/zen/ZenCustomRadioButtonPreference.java
+++ /dev/null
@@ -1,144 +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.notification.zen;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.RadioButton;
-
-import androidx.preference.PreferenceViewHolder;
-
-import com.android.settings.R;
-import com.android.settingslib.TwoTargetPreference;
-
-/**
- * A radio button preference with a divider and a settings icon that links to another screen.
- */
-public class ZenCustomRadioButtonPreference extends TwoTargetPreference
-        implements View.OnClickListener {
-
-    private RadioButton mButton;
-    private boolean mChecked;
-
-    private OnGearClickListener mOnGearClickListener;
-    private OnRadioButtonClickListener mOnRadioButtonClickListener;
-
-    public ZenCustomRadioButtonPreference(Context context, AttributeSet attrs,
-            int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        setLayoutResource(R.layout.preference_two_target_radio);
-    }
-
-    public ZenCustomRadioButtonPreference(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        setLayoutResource(R.layout.preference_two_target_radio);
-    }
-
-    public ZenCustomRadioButtonPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        setLayoutResource(R.layout.preference_two_target_radio);
-    }
-
-    public ZenCustomRadioButtonPreference(Context context) {
-        super(context);
-        setLayoutResource(R.layout.preference_two_target_radio);
-    }
-
-    @Override
-    protected int getSecondTargetResId() {
-        return R.layout.preference_widget_gear;
-    }
-
-    public void setOnGearClickListener(OnGearClickListener l) {
-        mOnGearClickListener = l;
-        notifyChanged();
-    }
-
-    public void setOnRadioButtonClickListener(OnRadioButtonClickListener l) {
-        mOnRadioButtonClickListener = l;
-        notifyChanged();
-    }
-
-    @Override
-    public void onBindViewHolder(PreferenceViewHolder holder) {
-        super.onBindViewHolder(holder);
-        View buttonFrame = holder.findViewById(R.id.checkbox_frame);
-        if (buttonFrame != null) {
-            buttonFrame.setOnClickListener(this);
-        }
-        mButton = (RadioButton) holder.findViewById(android.R.id.checkbox);
-        if (mButton != null) {
-            mButton.setChecked(mChecked);
-        }
-
-        final View gear = holder.findViewById(android.R.id.widget_frame);
-        final View divider = holder.findViewById(R.id.two_target_divider);
-        if (mOnGearClickListener != null) {
-            divider.setVisibility(View.VISIBLE);
-            gear.setVisibility(View.VISIBLE);
-            gear.setOnClickListener(this);
-        } else {
-            divider.setVisibility(View.GONE);
-            gear.setVisibility(View.GONE);
-            gear.setOnClickListener(null);
-        }
-    }
-
-    public boolean isChecked() {
-        return mButton != null && mChecked;
-    }
-
-    public void setChecked(boolean checked) {
-        mChecked = checked;
-        if (mButton != null) {
-            mButton.setChecked(checked);
-        }
-    }
-
-    public RadioButton getRadioButton() {
-        return mButton;
-    }
-
-    @Override
-    public void onClick() {
-        if (mOnRadioButtonClickListener != null) {
-            mOnRadioButtonClickListener.onRadioButtonClick(this);
-        }
-    }
-
-    @Override
-    public void onClick(View v) {
-        if (v.getId() == android.R.id.widget_frame) {
-            if (mOnGearClickListener != null) {
-                mOnGearClickListener.onGearClick(this);
-            }
-        } else if (v.getId() == R.id.checkbox_frame) {
-            if (mOnRadioButtonClickListener != null) {
-                mOnRadioButtonClickListener.onRadioButtonClick(this);
-            }
-        }
-    }
-
-    public interface OnGearClickListener {
-        void onGearClick(ZenCustomRadioButtonPreference p);
-    }
-
-    public interface OnRadioButtonClickListener {
-        void onRadioButtonClick(ZenCustomRadioButtonPreference p);
-    }
-}
diff --git a/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceController.java b/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceController.java
index e77f4ea..5afe0b6 100644
--- a/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceController.java
+++ b/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceController.java
@@ -16,9 +16,6 @@
 
 package com.android.settings.notification.zen;
 
-import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_GONE;
-import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_SETTING;
-
 import android.app.NotificationManager;
 import android.app.settings.SettingsEnums;
 import android.content.Context;
@@ -37,7 +34,6 @@
 import com.android.settings.core.SubSettingLauncher;
 import com.android.settings.notification.NotificationBackend;
 import com.android.settings.notification.app.ConversationListSettings;
-import com.android.settings.widget.RadioButtonPreferenceWithExtraWidget;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.widget.RadioButtonPreference;
 
@@ -186,13 +182,10 @@
     }
 
     private RadioButtonPreference makeRadioPreference(String key, int titleId) {
-        RadioButtonPreferenceWithExtraWidget pref =
-                new RadioButtonPreferenceWithExtraWidget(mPreferenceCategory.getContext());
+        final RadioButtonPreference pref =
+                new RadioButtonPreference(mPreferenceCategory.getContext());
         if (KEY_ALL.equals(key) || KEY_IMPORTANT.equals(key)) {
             pref.setExtraWidgetOnClickListener(mConversationSettingsWidgetClickListener);
-            pref.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_SETTING);
-        } else {
-            pref.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_GONE);
         }
         pref.setKey(key);
         pref.setTitle(titleId);
diff --git a/src/com/android/settings/notification/zen/ZenModePrioritySendersPreferenceController.java b/src/com/android/settings/notification/zen/ZenModePrioritySendersPreferenceController.java
index abf2ced..482865c 100644
--- a/src/com/android/settings/notification/zen/ZenModePrioritySendersPreferenceController.java
+++ b/src/com/android/settings/notification/zen/ZenModePrioritySendersPreferenceController.java
@@ -19,9 +19,6 @@
 import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CALLS;
 import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES;
 
-import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_GONE;
-import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_SETTING;
-
 import android.app.NotificationManager;
 import android.content.Context;
 import android.content.Intent;
@@ -35,7 +32,6 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
-import com.android.settings.widget.RadioButtonPreferenceWithExtraWidget;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.widget.RadioButtonPreference;
 
@@ -67,7 +63,7 @@
     private final boolean mIsMessages; // if this is false, then this preference is for calls
 
     private PreferenceCategory mPreferenceCategory;
-    private List<RadioButtonPreferenceWithExtraWidget> mRadioButtonPreferences = new ArrayList<>();
+    private List<RadioButtonPreference> mRadioButtonPreferences = new ArrayList<>();
 
     public ZenModePrioritySendersPreferenceController(Context context, String key,
             Lifecycle lifecycle, boolean isMessages) {
@@ -114,7 +110,7 @@
     public void updateState(Preference preference) {
         final int currSetting = getPrioritySenders();
 
-        for (RadioButtonPreferenceWithExtraWidget pref : mRadioButtonPreferences) {
+        for (RadioButtonPreference pref : mRadioButtonPreferences) {
             pref.setChecked(keyToSetting(pref.getKey()) == currSetting);
         }
     }
@@ -126,7 +122,7 @@
     }
 
     private void updateSummaries() {
-        for (RadioButtonPreferenceWithExtraWidget pref : mRadioButtonPreferences) {
+        for (RadioButtonPreference pref : mRadioButtonPreferences) {
             pref.setSummary(getSummary(pref.getKey()));
         }
     }
@@ -169,9 +165,9 @@
         }
     }
 
-    private RadioButtonPreferenceWithExtraWidget makeRadioPreference(String key, int titleId) {
-        RadioButtonPreferenceWithExtraWidget pref =
-                new RadioButtonPreferenceWithExtraWidget(mPreferenceCategory.getContext());
+    private RadioButtonPreference makeRadioPreference(String key, int titleId) {
+        final RadioButtonPreference pref =
+                new RadioButtonPreference(mPreferenceCategory.getContext());
         pref.setKey(key);
         pref.setTitle(titleId);
         pref.setOnClickListener(mRadioButtonClickListener);
@@ -179,9 +175,6 @@
         View.OnClickListener widgetClickListener = getWidgetClickListener(key);
         if (widgetClickListener != null) {
             pref.setExtraWidgetOnClickListener(widgetClickListener);
-            pref.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_SETTING);
-        } else {
-            pref.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_GONE);
         }
 
         mPreferenceCategory.addPreference(pref);
diff --git a/src/com/android/settings/notification/zen/ZenModeVisEffectsAllPreferenceController.java b/src/com/android/settings/notification/zen/ZenModeVisEffectsAllPreferenceController.java
index f729be8..735ce79 100644
--- a/src/com/android/settings/notification/zen/ZenModeVisEffectsAllPreferenceController.java
+++ b/src/com/android/settings/notification/zen/ZenModeVisEffectsAllPreferenceController.java
@@ -24,12 +24,13 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
 
 public class ZenModeVisEffectsAllPreferenceController
         extends AbstractZenModePreferenceController
-        implements ZenCustomRadioButtonPreference.OnRadioButtonClickListener {
+        implements RadioButtonPreference.OnClickListener {
 
-    private ZenCustomRadioButtonPreference mPreference;
+    private RadioButtonPreference mPreference;
 
     protected static final int EFFECTS = Policy.SUPPRESSED_EFFECT_SCREEN_OFF
             | Policy.SUPPRESSED_EFFECT_SCREEN_ON
@@ -50,7 +51,7 @@
     public void displayPreference(PreferenceScreen screen) {
         super.displayPreference(screen);
         mPreference = screen.findPreference(getPreferenceKey());
-        mPreference.setOnRadioButtonClickListener(this);
+        mPreference.setOnClickListener(this);
     }
 
     @Override
@@ -68,7 +69,7 @@
     }
 
     @Override
-    public void onRadioButtonClick(ZenCustomRadioButtonPreference p) {
+    public void onRadioButtonClicked(RadioButtonPreference p) {
         mMetricsFeatureProvider.action(mContext,
                 SettingsEnums.ACTION_ZEN_SOUND_AND_VIS_EFFECTS, true);
         mBackend.saveVisualEffectsPolicy(EFFECTS, true);
diff --git a/src/com/android/settings/notification/zen/ZenModeVisEffectsCustomPreferenceController.java b/src/com/android/settings/notification/zen/ZenModeVisEffectsCustomPreferenceController.java
index a772eb5..535dca3 100644
--- a/src/com/android/settings/notification/zen/ZenModeVisEffectsCustomPreferenceController.java
+++ b/src/com/android/settings/notification/zen/ZenModeVisEffectsCustomPreferenceController.java
@@ -26,11 +26,12 @@
 import com.android.settings.R;
 import com.android.settings.core.SubSettingLauncher;
 import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
 
 public class ZenModeVisEffectsCustomPreferenceController
         extends AbstractZenModePreferenceController {
 
-    private ZenCustomRadioButtonPreference mPreference;
+    private RadioButtonPreference mPreference;
 
     protected static final int INTERRUPTIVE_EFFECTS =
             NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT
@@ -53,12 +54,11 @@
         super.displayPreference(screen);
         mPreference = screen.findPreference(getPreferenceKey());
 
-        mPreference.setOnGearClickListener(p -> {
+        mPreference.setExtraWidgetOnClickListener(p -> {
             launchCustomSettings();
-
         });
 
-        mPreference.setOnRadioButtonClickListener(p -> {
+        mPreference.setOnClickListener(p -> {
             launchCustomSettings();
         });
     }
diff --git a/src/com/android/settings/notification/zen/ZenModeVisEffectsNonePreferenceController.java b/src/com/android/settings/notification/zen/ZenModeVisEffectsNonePreferenceController.java
index 84037b9..8723ea8 100644
--- a/src/com/android/settings/notification/zen/ZenModeVisEffectsNonePreferenceController.java
+++ b/src/com/android/settings/notification/zen/ZenModeVisEffectsNonePreferenceController.java
@@ -24,12 +24,13 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
 
 public class ZenModeVisEffectsNonePreferenceController
         extends AbstractZenModePreferenceController
-        implements ZenCustomRadioButtonPreference.OnRadioButtonClickListener {
+        implements RadioButtonPreference.OnClickListener {
 
-    private ZenCustomRadioButtonPreference mPreference;
+    private RadioButtonPreference mPreference;
 
     protected static final int EFFECTS = Policy.SUPPRESSED_EFFECT_SCREEN_OFF
             | Policy.SUPPRESSED_EFFECT_SCREEN_ON
@@ -50,7 +51,7 @@
     public void displayPreference(PreferenceScreen screen) {
         super.displayPreference(screen);
         mPreference = screen.findPreference(getPreferenceKey());
-        mPreference.setOnRadioButtonClickListener(this);
+        mPreference.setOnClickListener(this);
     }
 
     @Override
@@ -67,7 +68,7 @@
     }
 
     @Override
-    public void onRadioButtonClick(ZenCustomRadioButtonPreference preference) {
+    public void onRadioButtonClicked(RadioButtonPreference preference) {
         mMetricsFeatureProvider.action(mContext,
                 SettingsEnums.ACTION_ZEN_SOUND_ONLY, true);
         mBackend.saveVisualEffectsPolicy(EFFECTS, false);
diff --git a/src/com/android/settings/notification/zen/ZenRuleCustomPolicyPreferenceController.java b/src/com/android/settings/notification/zen/ZenRuleCustomPolicyPreferenceController.java
index 56b98ff..2cf8679 100644
--- a/src/com/android/settings/notification/zen/ZenRuleCustomPolicyPreferenceController.java
+++ b/src/com/android/settings/notification/zen/ZenRuleCustomPolicyPreferenceController.java
@@ -25,11 +25,12 @@
 
 import com.android.settings.core.SubSettingLauncher;
 import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
 
 public class ZenRuleCustomPolicyPreferenceController extends
         AbstractZenCustomRulePreferenceController {
 
-    private ZenCustomRadioButtonPreference mPreference;
+    private RadioButtonPreference mPreference;
 
     public ZenRuleCustomPolicyPreferenceController(Context context, Lifecycle lifecycle,
             String key) {
@@ -41,13 +42,12 @@
         super.displayPreference(screen);
         mPreference = screen.findPreference(getPreferenceKey());
 
-        mPreference.setOnGearClickListener(p -> {
+        mPreference.setExtraWidgetOnClickListener(p -> {
             setCustomPolicy();
             launchCustomSettings();
-
         });
 
-        mPreference.setOnRadioButtonClickListener(p -> {
+        mPreference.setOnClickListener(p -> {
             setCustomPolicy();
             launchCustomSettings();
         });
diff --git a/src/com/android/settings/notification/zen/ZenRuleDefaultPolicyPreferenceController.java b/src/com/android/settings/notification/zen/ZenRuleDefaultPolicyPreferenceController.java
index 268156b..372f152 100644
--- a/src/com/android/settings/notification/zen/ZenRuleDefaultPolicyPreferenceController.java
+++ b/src/com/android/settings/notification/zen/ZenRuleDefaultPolicyPreferenceController.java
@@ -26,11 +26,12 @@
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.core.PreferenceControllerMixin;
 import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
 
 public class ZenRuleDefaultPolicyPreferenceController extends
         AbstractZenCustomRulePreferenceController implements PreferenceControllerMixin {
 
-    private ZenCustomRadioButtonPreference mPreference;
+    private RadioButtonPreference mPreference;
 
     public ZenRuleDefaultPolicyPreferenceController(Context context, Lifecycle lifecycle,
             String key) {
@@ -42,7 +43,7 @@
         super.displayPreference(screen);
         mPreference = screen.findPreference(getPreferenceKey());
 
-        mPreference.setOnRadioButtonClickListener(p -> {
+        mPreference.setOnClickListener(p -> {
             mRule.setZenPolicy(null);
             mBackend.updateZenRule(mId, mRule);
         });
diff --git a/src/com/android/settings/notification/zen/ZenRuleVisEffectsAllPreferenceController.java b/src/com/android/settings/notification/zen/ZenRuleVisEffectsAllPreferenceController.java
index fb46209..6e9152f 100644
--- a/src/com/android/settings/notification/zen/ZenRuleVisEffectsAllPreferenceController.java
+++ b/src/com/android/settings/notification/zen/ZenRuleVisEffectsAllPreferenceController.java
@@ -27,11 +27,12 @@
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.core.PreferenceControllerMixin;
 import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
 
 public class ZenRuleVisEffectsAllPreferenceController extends
         AbstractZenCustomRulePreferenceController implements PreferenceControllerMixin {
 
-    private ZenCustomRadioButtonPreference mPreference;
+    private RadioButtonPreference mPreference;
 
     public ZenRuleVisEffectsAllPreferenceController(Context context, Lifecycle lifecycle,
             String key) {
@@ -43,7 +44,7 @@
         super.displayPreference(screen);
         mPreference = screen.findPreference(getPreferenceKey());
 
-        mPreference.setOnRadioButtonClickListener(p -> {
+        mPreference.setOnClickListener(p -> {
             mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_ZEN_SOUND_ONLY,
                     Pair.create(MetricsProto.MetricsEvent.FIELD_ZEN_RULE_ID, mId));
             mRule.setZenPolicy(new ZenPolicy.Builder(mRule.getZenPolicy())
diff --git a/src/com/android/settings/notification/zen/ZenRuleVisEffectsCustomPreferenceController.java b/src/com/android/settings/notification/zen/ZenRuleVisEffectsCustomPreferenceController.java
index 68ab818..d7c5f86 100644
--- a/src/com/android/settings/notification/zen/ZenRuleVisEffectsCustomPreferenceController.java
+++ b/src/com/android/settings/notification/zen/ZenRuleVisEffectsCustomPreferenceController.java
@@ -27,11 +27,12 @@
 import com.android.settings.core.PreferenceControllerMixin;
 import com.android.settings.core.SubSettingLauncher;
 import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
 
 public class ZenRuleVisEffectsCustomPreferenceController extends
         AbstractZenCustomRulePreferenceController implements PreferenceControllerMixin {
 
-    private ZenCustomRadioButtonPreference mPreference;
+    private RadioButtonPreference mPreference;
 
     public ZenRuleVisEffectsCustomPreferenceController(Context context, Lifecycle lifecycle,
             String key) {
@@ -43,12 +44,12 @@
         super.displayPreference(screen);
         mPreference = screen.findPreference(getPreferenceKey());
 
-        mPreference.setOnGearClickListener(p -> {
+        mPreference.setOnClickListener(p -> {
             launchCustomSettings();
 
         });
 
-        mPreference.setOnRadioButtonClickListener(p -> {
+        mPreference.setExtraWidgetOnClickListener(p -> {
             launchCustomSettings();
         });
     }
diff --git a/src/com/android/settings/notification/zen/ZenRuleVisEffectsNonePreferenceController.java b/src/com/android/settings/notification/zen/ZenRuleVisEffectsNonePreferenceController.java
index cb3e690..5484ed5 100644
--- a/src/com/android/settings/notification/zen/ZenRuleVisEffectsNonePreferenceController.java
+++ b/src/com/android/settings/notification/zen/ZenRuleVisEffectsNonePreferenceController.java
@@ -27,11 +27,12 @@
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.core.PreferenceControllerMixin;
 import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
 
 public class ZenRuleVisEffectsNonePreferenceController extends
         AbstractZenCustomRulePreferenceController implements PreferenceControllerMixin {
 
-    private ZenCustomRadioButtonPreference mPreference;
+    private RadioButtonPreference mPreference;
 
     public ZenRuleVisEffectsNonePreferenceController(Context context, Lifecycle lifecycle,
             String key) {
@@ -43,7 +44,7 @@
         super.displayPreference(screen);
         mPreference = screen.findPreference(getPreferenceKey());
 
-        mPreference.setOnRadioButtonClickListener(p -> {
+        mPreference.setOnClickListener(p -> {
             mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_ZEN_SOUND_AND_VIS_EFFECTS,
                     Pair.create(MetricsProto.MetricsEvent.FIELD_ZEN_RULE_ID, mId));
             mRule.setZenPolicy(new ZenPolicy.Builder(mRule.getZenPolicy())
diff --git a/src/com/android/settings/overlay/FeatureFactory.java b/src/com/android/settings/overlay/FeatureFactory.java
index b9aa68a..a15075e 100644
--- a/src/com/android/settings/overlay/FeatureFactory.java
+++ b/src/com/android/settings/overlay/FeatureFactory.java
@@ -41,6 +41,7 @@
 import com.android.settings.security.SecurityFeatureProvider;
 import com.android.settings.slices.SlicesFeatureProvider;
 import com.android.settings.users.UserFeatureProvider;
+import com.android.settings.wifi.WifiTrackerLibProvider;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 /**
@@ -143,6 +144,11 @@
 
     public abstract FaceFeatureProvider getFaceFeatureProvider();
 
+    /**
+     * Gets implementation for the WifiTrackerLib.
+     */
+    public abstract WifiTrackerLibProvider getWifiTrackerLibProvider();
+
     public static final class FactoryNotFoundException extends RuntimeException {
         public FactoryNotFoundException(Throwable throwable) {
             super("Unable to create factory. Did you misconfigure Proguard?", throwable);
diff --git a/src/com/android/settings/overlay/FeatureFactoryImpl.java b/src/com/android/settings/overlay/FeatureFactoryImpl.java
index d4d396f..ebbe87c 100644
--- a/src/com/android/settings/overlay/FeatureFactoryImpl.java
+++ b/src/com/android/settings/overlay/FeatureFactoryImpl.java
@@ -62,6 +62,8 @@
 import com.android.settings.slices.SlicesFeatureProviderImpl;
 import com.android.settings.users.UserFeatureProvider;
 import com.android.settings.users.UserFeatureProviderImpl;
+import com.android.settings.wifi.WifiTrackerLibProvider;
+import com.android.settings.wifi.WifiTrackerLibProviderImpl;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 /**
@@ -90,6 +92,7 @@
     private BluetoothFeatureProvider mBluetoothFeatureProvider;
     private AwareFeatureProvider mAwareFeatureProvider;
     private FaceFeatureProvider mFaceFeatureProvider;
+    private WifiTrackerLibProvider mWifiTrackerLibProvider;
 
     @Override
     public SupportFeatureProvider getSupportFeatureProvider(Context context) {
@@ -278,4 +281,12 @@
         }
         return mFaceFeatureProvider;
     }
+
+    @Override
+    public WifiTrackerLibProvider getWifiTrackerLibProvider() {
+        if (mWifiTrackerLibProvider == null) {
+            mWifiTrackerLibProvider = new WifiTrackerLibProviderImpl();
+        }
+        return mWifiTrackerLibProvider;
+    }
 }
diff --git a/src/com/android/settings/slices/SettingsSliceProvider.java b/src/com/android/settings/slices/SettingsSliceProvider.java
index 0c6205f..7c487ba 100644
--- a/src/com/android/settings/slices/SettingsSliceProvider.java
+++ b/src/com/android/settings/slices/SettingsSliceProvider.java
@@ -343,7 +343,7 @@
         final Intent settingsIntent = new Intent(Settings.ACTION_SETTINGS)
                 .setPackage(Utils.SETTINGS_PACKAGE_NAME);
         final PendingIntent noOpIntent = PendingIntent.getActivity(getContext(),
-                0 /* requestCode */, settingsIntent, 0 /* flags */);
+                0 /* requestCode */, settingsIntent, PendingIntent.FLAG_IMMUTABLE);
         return noOpIntent;
     }
 
diff --git a/src/com/android/settings/users/UserDetailsSettings.java b/src/com/android/settings/users/UserDetailsSettings.java
index 53d9849..5005399 100644
--- a/src/com/android/settings/users/UserDetailsSettings.java
+++ b/src/com/android/settings/users/UserDetailsSettings.java
@@ -243,7 +243,7 @@
                 mDefaultGuestRestrictions = mUserManager.getDefaultGuestRestrictions();
                 mPhonePref.setChecked(
                         !mDefaultGuestRestrictions.getBoolean(UserManager.DISALLOW_OUTGOING_CALLS));
-                mRemoveUserPref.setTitle(R.string.user_exit_guest_title);
+                mRemoveUserPref.setTitle(R.string.user_exit_guest_menu);
             } else {
                 mPhonePref.setChecked(!mUserManager.hasUserRestriction(
                         UserManager.DISALLOW_OUTGOING_CALLS, new UserHandle(userId)));
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index 63ccb6b..8ba5432 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -31,6 +31,7 @@
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.graphics.PorterDuff;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.AsyncTask;
@@ -164,6 +165,7 @@
     private final Object mUserLock = new Object();
     private UserManager mUserManager;
     private static SparseArray<Bitmap> sDarkDefaultUserBitmapCache = new SparseArray<>();
+    private static Bitmap sRemoveGuestBitmap = null;
 
     private MultiUserSwitchBarController mSwitchBarController;
     private EditUserInfoController mEditUserInfoController =
@@ -177,6 +179,7 @@
 
     // A place to cache the generated default avatar
     private Drawable mDefaultIconDrawable;
+    private Drawable mRemoveGuestIconDrawable;
 
     // TODO:   Replace current Handler solution to something that doesn't leak memory and works
     // TODO:   during a configuration change
@@ -383,8 +386,8 @@
     private void loadProfile() {
         if (isCurrentUserGuest()) {
             // No need to load profile information
-            mMePreference.setIcon(getEncircledDefaultIcon());
-            mMePreference.setTitle(R.string.user_exit_guest_title);
+            mMePreference.setIcon(getEncircledRemoveGuestIcon());
+            mMePreference.setTitle(R.string.user_clear_guest_menu);
             mMePreference.setSelectable(true);
             // removing a guest will result in switching back to the admin user
             mMePreference.setEnabled(canSwitchUserNow());
@@ -899,7 +902,7 @@
                 } else {
                     setPhotoId(pref, user);
                 }
-            } else {
+            } else if (!user.isGuest()) {
                 // Icon not available yet, print a placeholder
                 pref.setIcon(getEncircledDefaultIcon());
             }
@@ -1044,6 +1047,14 @@
         return mDefaultIconDrawable;
     }
 
+    private Drawable getEncircledRemoveGuestIcon() {
+        if (mRemoveGuestIconDrawable == null) {
+            mRemoveGuestIconDrawable = encircle(
+                    getRemoveGuestIconAsBitmap(getContext().getResources()));
+        }
+        return mRemoveGuestIconDrawable;
+    }
+
     private void setPhotoId(Preference pref, UserInfo user) {
         Bitmap bitmap = mUserIcons.get(user.id);
         if (bitmap != null) {
@@ -1123,6 +1134,23 @@
     }
 
     /**
+     * Returns a remove guest icon (as a {@link Bitmap})
+     *
+     * @param resources resources object to fetch the remove guest icon.
+     */
+    private static Bitmap getRemoveGuestIconAsBitmap(Resources resources) {
+        if (sRemoveGuestBitmap == null) {
+            Drawable icon = resources.getDrawable(R.drawable.ic_delete, null).mutate();
+            icon.setColorFilter(
+                    resources.getColor(com.android.internal.R.color.user_icon_default_gray, null),
+                    PorterDuff.Mode.SRC_IN);
+            icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight());
+            sRemoveGuestBitmap = UserIcons.convertToBitmap(icon);
+        }
+        return sRemoveGuestBitmap;
+    }
+
+    /**
      * Assign the default photo to user with {@paramref userId}
      *
      * @param context used to get the {@link UserManager}
diff --git a/src/com/android/settings/widget/RadioButtonPreferenceWithExtraWidget.java b/src/com/android/settings/widget/RadioButtonPreferenceWithExtraWidget.java
deleted file mode 100644
index 2b28ec1..0000000
--- a/src/com/android/settings/widget/RadioButtonPreferenceWithExtraWidget.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2019 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.widget;
-
-import android.content.Context;
-import android.view.View;
-import android.widget.ImageView;
-
-import androidx.preference.PreferenceViewHolder;
-
-import com.android.settings.R;
-import com.android.settingslib.widget.RadioButtonPreference;
-
-public class RadioButtonPreferenceWithExtraWidget extends RadioButtonPreference {
-    public static final int EXTRA_WIDGET_VISIBILITY_GONE = 0;
-    public static final int EXTRA_WIDGET_VISIBILITY_INFO = 1;
-    public static final int EXTRA_WIDGET_VISIBILITY_SETTING = 2;
-
-    private View mExtraWidgetDivider;
-    private ImageView mExtraWidget;
-
-    private int mExtraWidgetVisibility = EXTRA_WIDGET_VISIBILITY_GONE;
-    private View.OnClickListener mExtraWidgetOnClickListener;
-
-    public RadioButtonPreferenceWithExtraWidget(Context context) {
-        super(context, null);
-        setLayoutResource(R.layout.preference_radio_with_extra_widget);
-    }
-
-    @Override
-    public void onBindViewHolder(PreferenceViewHolder view) {
-        super.onBindViewHolder(view);
-
-        mExtraWidget = (ImageView) view.findViewById(R.id.radio_extra_widget);
-        mExtraWidgetDivider = view.findViewById(R.id.radio_extra_widget_divider);
-        setExtraWidgetVisibility(mExtraWidgetVisibility);
-
-        if (mExtraWidgetOnClickListener != null) {
-            setExtraWidgetOnClickListener(mExtraWidgetOnClickListener);
-        }
-    }
-
-    public void setExtraWidgetVisibility(int visibility) {
-        mExtraWidgetVisibility = visibility;
-        if (mExtraWidget == null || mExtraWidgetDivider == null) {
-            return;
-        }
-
-        if (visibility == EXTRA_WIDGET_VISIBILITY_GONE) {
-            mExtraWidget.setClickable(false);
-            mExtraWidget.setVisibility(View.GONE);
-            mExtraWidgetDivider.setVisibility(View.GONE);
-        } else {
-            mExtraWidget.setClickable(true);
-            mExtraWidget.setVisibility(View.VISIBLE);
-            mExtraWidgetDivider.setVisibility(View.VISIBLE);
-            if (mExtraWidgetVisibility == EXTRA_WIDGET_VISIBILITY_INFO) {
-                mExtraWidget.setImageResource(R.drawable.ic_settings_about);
-                mExtraWidget.setContentDescription(
-                        getContext().getResources().getText(R.string.information_label));
-            } else if (mExtraWidgetVisibility == EXTRA_WIDGET_VISIBILITY_SETTING) {
-                mExtraWidget.setImageResource(R.drawable.ic_settings_accent);
-                mExtraWidget.setContentDescription(
-                        getContext().getResources().getText(R.string.settings_label));
-            }
-        }
-    }
-
-    public void setExtraWidgetOnClickListener(View.OnClickListener listener) {
-        mExtraWidgetOnClickListener = listener;
-        if (mExtraWidget != null) {
-            mExtraWidget.setEnabled(true);
-            mExtraWidget.setOnClickListener(listener);
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/settings/wifi/ConfigureWifiEntryFragment.java b/src/com/android/settings/wifi/ConfigureWifiEntryFragment.java
index 881aaea..c36a298 100644
--- a/src/com/android/settings/wifi/ConfigureWifiEntryFragment.java
+++ b/src/com/android/settings/wifi/ConfigureWifiEntryFragment.java
@@ -21,9 +21,6 @@
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.content.Intent;
-import android.net.ConnectivityManager;
-import android.net.NetworkScoreManager;
-import android.net.wifi.WifiManager;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -40,6 +37,7 @@
 
 import com.android.settings.R;
 import com.android.settings.core.InstrumentedFragment;
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.wifi.details2.WifiNetworkDetailsFragment2;
 import com.android.wifitrackerlib.NetworkDetailsTracker;
 import com.android.wifitrackerlib.WifiEntry;
@@ -222,17 +220,17 @@
             }
         };
 
-        mNetworkDetailsTracker = NetworkDetailsTracker.createNetworkDetailsTracker(
-                getSettingsLifecycle(),
-                context,
-                context.getSystemService(WifiManager.class),
-                context.getSystemService(ConnectivityManager.class),
-                context.getSystemService(NetworkScoreManager.class),
-                new Handler(Looper.getMainLooper()),
-                mWorkerThread.getThreadHandler(),
-                elapsedRealtimeClock,
-                MAX_SCAN_AGE_MILLIS,
-                SCAN_INTERVAL_MILLIS,
-                getArguments().getString(WifiNetworkDetailsFragment2.KEY_CHOSEN_WIFIENTRY_KEY));
+        mNetworkDetailsTracker = FeatureFactory.getFactory(context)
+                .getWifiTrackerLibProvider()
+                .createNetworkDetailsTracker(
+                        getSettingsLifecycle(),
+                        context,
+                        new Handler(Looper.getMainLooper()),
+                        mWorkerThread.getThreadHandler(),
+                        elapsedRealtimeClock,
+                        MAX_SCAN_AGE_MILLIS,
+                        SCAN_INTERVAL_MILLIS,
+                        getArguments().getString(
+                                WifiNetworkDetailsFragment2.KEY_CHOSEN_WIFIENTRY_KEY));
     }
 }
diff --git a/src/com/android/settings/wifi/NetworkRequestDialogFragment.java b/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
index 887f09f..11f3612 100644
--- a/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
+++ b/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
@@ -24,11 +24,8 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.graphics.drawable.Drawable;
-import android.net.ConnectivityManager;
-import android.net.NetworkScoreManager;
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiManager;
 import android.net.wifi.WifiManager.NetworkRequestMatchCallback;
 import android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback;
 import android.os.Bundle;
@@ -54,6 +51,7 @@
 import androidx.preference.internal.PreferenceImageView;
 
 import com.android.settings.R;
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.Utils;
 import com.android.wifitrackerlib.WifiEntry;
 import com.android.wifitrackerlib.WifiPickerTracker;
@@ -113,16 +111,15 @@
             }
         };
         final Context context = getContext();
-        mWifiPickerTracker = new WifiPickerTracker(getSettingsLifecycle(), context,
-                context.getSystemService(WifiManager.class),
-                context.getSystemService(ConnectivityManager.class),
-                context.getSystemService(NetworkScoreManager.class),
-                new Handler(Looper.getMainLooper()),
-                mWorkerThread.getThreadHandler(),
-                elapsedRealtimeClock,
-                MAX_SCAN_AGE_MILLIS,
-                SCAN_INTERVAL_MILLIS,
-                this);
+        mWifiPickerTracker = FeatureFactory.getFactory(context)
+                .getWifiTrackerLibProvider()
+                .createWifiPickerTracker(getSettingsLifecycle(), context,
+                        new Handler(Looper.getMainLooper()),
+                        mWorkerThread.getThreadHandler(),
+                        elapsedRealtimeClock,
+                        MAX_SCAN_AGE_MILLIS,
+                        SCAN_INTERVAL_MILLIS,
+                        this);
     }
 
     @Override
diff --git a/src/com/android/settings/wifi/WifiConnectionPreferenceController.java b/src/com/android/settings/wifi/WifiConnectionPreferenceController.java
index 13d5082..3b2669c 100644
--- a/src/com/android/settings/wifi/WifiConnectionPreferenceController.java
+++ b/src/com/android/settings/wifi/WifiConnectionPreferenceController.java
@@ -17,9 +17,6 @@
 package com.android.settings.wifi;
 
 import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.NetworkScoreManager;
-import android.net.wifi.WifiManager;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -36,6 +33,7 @@
 
 import com.android.settings.R;
 import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.wifi.details2.WifiNetworkDetailsFragment2;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.core.lifecycle.Lifecycle;
@@ -115,16 +113,15 @@
                 return SystemClock.elapsedRealtime();
             }
         };
-        mWifiPickerTracker = new WifiPickerTracker(lifecycle, context,
-                context.getSystemService(WifiManager.class),
-                context.getSystemService(ConnectivityManager.class),
-                context.getSystemService(NetworkScoreManager.class),
-                new Handler(Looper.getMainLooper()),
-                mWorkerThread.getThreadHandler(),
-                elapsedRealtimeClock,
-                MAX_SCAN_AGE_MILLIS,
-                SCAN_INTERVAL_MILLIS,
-                this);
+        mWifiPickerTracker = FeatureFactory.getFactory(context)
+                .getWifiTrackerLibProvider()
+                .createWifiPickerTracker(lifecycle, context,
+                        new Handler(Looper.getMainLooper()),
+                        mWorkerThread.getThreadHandler(),
+                        elapsedRealtimeClock,
+                        MAX_SCAN_AGE_MILLIS,
+                        SCAN_INTERVAL_MILLIS,
+                        this);
     }
 
     /**
diff --git a/src/com/android/settings/wifi/WifiDialogActivity.java b/src/com/android/settings/wifi/WifiDialogActivity.java
index 000ed3e..1c5a8ed 100644
--- a/src/com/android/settings/wifi/WifiDialogActivity.java
+++ b/src/com/android/settings/wifi/WifiDialogActivity.java
@@ -18,9 +18,7 @@
 
 import android.content.DialogInterface;
 import android.content.Intent;
-import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
-import android.net.NetworkScoreManager;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiManager;
 import android.net.wifi.WifiManager.ActionListener;
@@ -38,6 +36,7 @@
 
 import com.android.settings.R;
 import com.android.settings.SetupWizardUtils;
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.wifi.dpp.WifiDppUtils;
 import com.android.settingslib.core.lifecycle.ObservableActivity;
 import com.android.settingslib.wifi.AccessPoint;
@@ -124,18 +123,17 @@
                     return SystemClock.elapsedRealtime();
                 }
             };
-            mNetworkDetailsTracker = NetworkDetailsTracker.createNetworkDetailsTracker(
-                    getLifecycle(),
-                    this,
-                    getSystemService(WifiManager.class),
-                    getSystemService(ConnectivityManager.class),
-                    getSystemService(NetworkScoreManager.class),
-                    new Handler(Looper.getMainLooper()),
-                    mWorkerThread.getThreadHandler(),
-                    elapsedRealtimeClock,
-                    MAX_SCAN_AGE_MILLIS,
-                    SCAN_INTERVAL_MILLIS,
-                    mIntent.getStringExtra(KEY_CHOSEN_WIFIENTRY_KEY));
+            mNetworkDetailsTracker = FeatureFactory.getFactory(this)
+                    .getWifiTrackerLibProvider()
+                    .createNetworkDetailsTracker(
+                            getLifecycle(),
+                            this,
+                            new Handler(Looper.getMainLooper()),
+                            mWorkerThread.getThreadHandler(),
+                            elapsedRealtimeClock,
+                            MAX_SCAN_AGE_MILLIS,
+                            SCAN_INTERVAL_MILLIS,
+                            mIntent.getStringExtra(KEY_CHOSEN_WIFIENTRY_KEY));
         } else {
             final Bundle accessPointState = mIntent.getBundleExtra(KEY_ACCESS_POINT_STATE);
             if (accessPointState != null) {
diff --git a/src/com/android/settings/wifi/WifiPickerTrackerHelper.java b/src/com/android/settings/wifi/WifiPickerTrackerHelper.java
new file mode 100644
index 0000000..c20f355
--- /dev/null
+++ b/src/com/android/settings/wifi/WifiPickerTrackerHelper.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.wifi;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Process;
+import android.os.SimpleClock;
+import android.os.SystemClock;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleObserver;
+import androidx.lifecycle.OnLifecycleEvent;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.wifitrackerlib.MergedCarrierEntry;
+import com.android.wifitrackerlib.WifiEntry;
+import com.android.wifitrackerlib.WifiPickerTracker;
+
+import java.time.Clock;
+import java.time.ZoneOffset;
+
+public class WifiPickerTrackerHelper implements LifecycleObserver {
+
+    private static final String TAG = "WifiPickerTrackerHelper";
+
+    // Max age of tracked WifiEntries
+    private static final long MAX_SCAN_AGE_MILLIS = 15_000;
+    // Interval between initiating WifiPickerTracker scans
+    private static final long SCAN_INTERVAL_MILLIS = 10_000;
+    // Clock used for evaluating the age of scans
+    private static final Clock ELAPSED_REALTIME_CLOCK = new SimpleClock(ZoneOffset.UTC) {
+        @Override
+        public long millis() {
+            return SystemClock.elapsedRealtime();
+        }
+    };
+
+    private WifiPickerTracker mWifiPickerTracker;
+    // Worker thread used for WifiPickerTracker work
+    private HandlerThread mWorkerThread;
+
+    public WifiPickerTrackerHelper(@NonNull Lifecycle lifecycle, @NonNull Context context,
+            @Nullable WifiPickerTracker.WifiPickerTrackerCallback listener) {
+        if (lifecycle == null) {
+            throw new IllegalArgumentException("lifecycle must be non-null.");
+        }
+        lifecycle.addObserver(this);
+        mWorkerThread = new HandlerThread(TAG
+                + "{" + Integer.toHexString(System.identityHashCode(this)) + "}",
+                Process.THREAD_PRIORITY_BACKGROUND);
+        mWorkerThread.start();
+
+        mWifiPickerTracker =  FeatureFactory.getFactory(context)
+                .getWifiTrackerLibProvider()
+                .createWifiPickerTracker(lifecycle, context,
+                new Handler(Looper.getMainLooper()),
+                mWorkerThread.getThreadHandler(),
+                ELAPSED_REALTIME_CLOCK,
+                MAX_SCAN_AGE_MILLIS,
+                SCAN_INTERVAL_MILLIS,
+                listener);
+
+    }
+
+    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
+    public void onDestroy() {
+        mWorkerThread.quit();
+    }
+
+    public @NonNull WifiPickerTracker getWifiPickerTracker() {
+        return mWifiPickerTracker;
+    }
+
+    public boolean setCarrierNetworkEnabled(boolean enable) {
+        final MergedCarrierEntry mergedCarrierEntry = mWifiPickerTracker.getMergedCarrierEntry();
+        if (mergedCarrierEntry == null) {
+            return false;
+        }
+        mergedCarrierEntry.setEnabled(enable);
+        return true;
+    }
+
+    public boolean connectCarrierNetwork(@Nullable WifiEntry.ConnectCallback callback) {
+        final MergedCarrierEntry mergedCarrierEntry = mWifiPickerTracker.getMergedCarrierEntry();
+        if (mergedCarrierEntry == null || !mergedCarrierEntry.canConnect()) {
+            return false;
+        }
+        mergedCarrierEntry.connect(callback);
+        return true;
+    }
+
+    @VisibleForTesting
+    void setWifiPickerTracker(@NonNull WifiPickerTracker wifiPickerTracker) {
+        mWifiPickerTracker = wifiPickerTracker;
+    }
+
+    @VisibleForTesting
+    void setWorkerThread(@NonNull HandlerThread workerThread) {
+        mWorkerThread = workerThread;
+    }
+}
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index 2804393..cf8242b 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -27,8 +27,6 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
-import android.net.ConnectivityManager;
-import android.net.NetworkScoreManager;
 import android.net.NetworkTemplate;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiManager;
@@ -66,6 +64,7 @@
 import com.android.settings.datausage.DataUsagePreference;
 import com.android.settings.datausage.DataUsageUtils;
 import com.android.settings.location.ScanningSettings;
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.widget.SwitchBarController;
 import com.android.settings.wifi.details2.WifiNetworkDetailsFragment2;
@@ -283,16 +282,15 @@
                 return SystemClock.elapsedRealtime();
             }
         };
-        mWifiPickerTracker = new WifiPickerTracker(getSettingsLifecycle(), context,
-                context.getSystemService(WifiManager.class),
-                context.getSystemService(ConnectivityManager.class),
-                context.getSystemService(NetworkScoreManager.class),
-                new Handler(Looper.getMainLooper()),
-                mWorkerThread.getThreadHandler(),
-                elapsedRealtimeClock,
-                MAX_SCAN_AGE_MILLIS,
-                SCAN_INTERVAL_MILLIS,
-                this);
+        mWifiPickerTracker = FeatureFactory.getFactory(context)
+                .getWifiTrackerLibProvider()
+                .createWifiPickerTracker(getSettingsLifecycle(), context,
+                        new Handler(Looper.getMainLooper()),
+                        mWorkerThread.getThreadHandler(),
+                        elapsedRealtimeClock,
+                        MAX_SCAN_AGE_MILLIS,
+                        SCAN_INTERVAL_MILLIS,
+                        this);
 
         final Activity activity = getActivity();
 
diff --git a/src/com/android/settings/wifi/WifiTrackerLibProvider.java b/src/com/android/settings/wifi/WifiTrackerLibProvider.java
new file mode 100644
index 0000000..10b3373
--- /dev/null
+++ b/src/com/android/settings/wifi/WifiTrackerLibProvider.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2020 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;
+
+import android.content.Context;
+import android.os.Handler;
+
+import androidx.lifecycle.Lifecycle;
+
+import com.android.wifitrackerlib.NetworkDetailsTracker;
+import com.android.wifitrackerlib.WifiPickerTracker;
+
+import java.time.Clock;
+
+/**
+ * Provides the objects instances from the AOSP WifiTrackerLib.
+ */
+public interface WifiTrackerLibProvider {
+
+    /** Create a new instance of WifiPickerTracker */
+    WifiPickerTracker createWifiPickerTracker(
+            Lifecycle lifecycle, Context context,
+            Handler mainHandler, Handler workerHandler, Clock clock,
+            long maxScanAgeMillis, long scanIntervalMillis,
+            WifiPickerTracker.WifiPickerTrackerCallback listener);
+
+    /** Create a new instance of NetworkDetailsTracker */
+    NetworkDetailsTracker createNetworkDetailsTracker(
+            Lifecycle lifecycle, Context context,
+            Handler mainHandler, Handler workerHandler, Clock clock,
+            long maxScanAgeMillis, long scanIntervalMillis,
+            String key);
+
+}
diff --git a/src/com/android/settings/wifi/WifiTrackerLibProviderImpl.java b/src/com/android/settings/wifi/WifiTrackerLibProviderImpl.java
new file mode 100644
index 0000000..f835409
--- /dev/null
+++ b/src/com/android/settings/wifi/WifiTrackerLibProviderImpl.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2020 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;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkScoreManager;
+import android.net.wifi.WifiManager;
+import android.os.Handler;
+
+import androidx.lifecycle.Lifecycle;
+
+import com.android.wifitrackerlib.NetworkDetailsTracker;
+import com.android.wifitrackerlib.WifiPickerTracker;
+
+import java.time.Clock;
+
+/**
+ * Implementation of AOSP WifiTrackerLibProvider.
+ */
+public class WifiTrackerLibProviderImpl implements WifiTrackerLibProvider {
+
+    /**
+     * Create an instance of WifiPickerTracker.
+     */
+    @Override
+    public WifiPickerTracker createWifiPickerTracker(
+            Lifecycle lifecycle, Context context,
+            Handler mainHandler, Handler workerHandler, Clock clock,
+            long maxScanAgeMillis, long scanIntervalMillis,
+            WifiPickerTracker.WifiPickerTrackerCallback listener) {
+        return new WifiPickerTracker(
+                lifecycle, context,
+                context.getSystemService(WifiManager.class),
+                context.getSystemService(ConnectivityManager.class),
+                context.getSystemService(NetworkScoreManager.class),
+                mainHandler, workerHandler, clock,
+                maxScanAgeMillis, scanIntervalMillis,
+                listener);
+    }
+
+    /**
+     * Create an instance of NetworkDetailsTracker.
+     */
+    @Override
+    public NetworkDetailsTracker createNetworkDetailsTracker(
+            Lifecycle lifecycle, Context context,
+            Handler mainHandler, Handler workerHandler, Clock clock,
+            long maxScanAgeMillis, long scanIntervalMillis,
+            String key) {
+        return NetworkDetailsTracker.createNetworkDetailsTracker(
+                lifecycle, context,
+                context.getSystemService(WifiManager.class),
+                context.getSystemService(ConnectivityManager.class),
+                context.getSystemService(NetworkScoreManager.class),
+                mainHandler, workerHandler, clock,
+                maxScanAgeMillis, scanIntervalMillis,
+                key);
+    }
+}
diff --git a/src/com/android/settings/wifi/addappnetworks/AddAppNetworksFragment.java b/src/com/android/settings/wifi/addappnetworks/AddAppNetworksFragment.java
index 3921488..46f4414 100644
--- a/src/com/android/settings/wifi/addappnetworks/AddAppNetworksFragment.java
+++ b/src/com/android/settings/wifi/addappnetworks/AddAppNetworksFragment.java
@@ -24,8 +24,6 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.graphics.drawable.Drawable;
-import android.net.ConnectivityManager;
-import android.net.NetworkScoreManager;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiConfiguration.KeyMgmt;
 import android.net.wifi.WifiManager;
@@ -60,6 +58,7 @@
 import com.android.settings.R;
 import com.android.settings.Utils;
 import com.android.settings.core.InstrumentedFragment;
+import com.android.settings.overlay.FeatureFactory;
 import com.android.wifitrackerlib.WifiEntry;
 import com.android.wifitrackerlib.WifiPickerTracker;
 
@@ -191,16 +190,15 @@
                 return SystemClock.elapsedRealtime();
             }
         };
-        mWifiPickerTracker = new WifiPickerTracker(getSettingsLifecycle(), mActivity,
-                mActivity.getSystemService(WifiManager.class),
-                mActivity.getSystemService(ConnectivityManager.class),
-                mActivity.getSystemService(NetworkScoreManager.class),
-                new Handler(Looper.getMainLooper()),
-                mWorkerThread.getThreadHandler(),
-                elapsedRealtimeClock,
-                MAX_SCAN_AGE_MILLIS,
-                SCAN_INTERVAL_MILLIS,
-                this);
+        mWifiPickerTracker = FeatureFactory.getFactory(mActivity.getApplicationContext())
+                .getWifiTrackerLibProvider()
+                .createWifiPickerTracker(getSettingsLifecycle(), mActivity,
+                        new Handler(Looper.getMainLooper()),
+                        mWorkerThread.getThreadHandler(),
+                        elapsedRealtimeClock,
+                        MAX_SCAN_AGE_MILLIS,
+                        SCAN_INTERVAL_MILLIS,
+                        this);
         return inflater.inflate(R.layout.wifi_add_app_networks, container, false);
     }
 
diff --git a/src/com/android/settings/wifi/details2/WifiNetworkDetailsFragment2.java b/src/com/android/settings/wifi/details2/WifiNetworkDetailsFragment2.java
index d0708ea..b154a9b 100644
--- a/src/com/android/settings/wifi/details2/WifiNetworkDetailsFragment2.java
+++ b/src/com/android/settings/wifi/details2/WifiNetworkDetailsFragment2.java
@@ -22,7 +22,6 @@
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.net.ConnectivityManager;
-import android.net.NetworkScoreManager;
 import android.net.wifi.WifiManager;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -42,6 +41,7 @@
 import com.android.settings.R;
 import com.android.settings.Utils;
 import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.wifi.WifiConfigUiBase2;
 import com.android.settings.wifi.WifiDialog2;
 import com.android.settingslib.RestrictedLockUtils;
@@ -239,18 +239,17 @@
             }
         };
 
-        mNetworkDetailsTracker = NetworkDetailsTracker.createNetworkDetailsTracker(
-                getSettingsLifecycle(),
-                context,
-                context.getSystemService(WifiManager.class),
-                context.getSystemService(ConnectivityManager.class),
-                context.getSystemService(NetworkScoreManager.class),
-                new Handler(Looper.getMainLooper()),
-                mWorkerThread.getThreadHandler(),
-                elapsedRealtimeClock,
-                MAX_SCAN_AGE_MILLIS,
-                SCAN_INTERVAL_MILLIS,
-                getArguments().getString(KEY_CHOSEN_WIFIENTRY_KEY));
+        mNetworkDetailsTracker = FeatureFactory.getFactory(context)
+                .getWifiTrackerLibProvider()
+                .createNetworkDetailsTracker(
+                        getSettingsLifecycle(),
+                        context,
+                        new Handler(Looper.getMainLooper()),
+                        mWorkerThread.getThreadHandler(),
+                        elapsedRealtimeClock,
+                        MAX_SCAN_AGE_MILLIS,
+                        SCAN_INTERVAL_MILLIS,
+                        getArguments().getString(KEY_CHOSEN_WIFIENTRY_KEY));
     }
 
     /**
diff --git a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
index cee3ccd..5c80024 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
@@ -25,8 +25,6 @@
 import android.graphics.Matrix;
 import android.graphics.Rect;
 import android.graphics.SurfaceTexture;
-import android.net.ConnectivityManager;
-import android.net.NetworkScoreManager;
 import android.net.wifi.EasyConnectStatusCallback;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiManager;
@@ -57,6 +55,7 @@
 import androidx.lifecycle.ViewModelProviders;
 
 import com.android.settings.R;
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.wifi.qrcode.QrCamera;
 import com.android.settings.wifi.qrcode.QrDecorateView;
 import com.android.wifitrackerlib.WifiEntry;
@@ -363,16 +362,15 @@
             }
         };
         final Context context = getContext();
-        mWifiPickerTracker = new WifiPickerTracker(getSettingsLifecycle(), context,
-                context.getSystemService(WifiManager.class),
-                context.getSystemService(ConnectivityManager.class),
-                context.getSystemService(NetworkScoreManager.class),
-                new Handler(Looper.getMainLooper()),
-                mWorkerThread.getThreadHandler(),
-                elapsedRealtimeClock,
-                MAX_SCAN_AGE_MILLIS,
-                SCAN_INTERVAL_MILLIS,
-                null /* listener */);
+        mWifiPickerTracker = FeatureFactory.getFactory(context)
+                .getWifiTrackerLibProvider()
+                .createWifiPickerTracker(getSettingsLifecycle(), context,
+                        new Handler(Looper.getMainLooper()),
+                        mWorkerThread.getThreadHandler(),
+                        elapsedRealtimeClock,
+                        MAX_SCAN_AGE_MILLIS,
+                        SCAN_INTERVAL_MILLIS,
+                        null /* listener */);
 
         // setTitle for TalkBack
         if (mIsConfiguratorMode) {
diff --git a/src/com/android/settings/wifi/slice/WifiScanWorker.java b/src/com/android/settings/wifi/slice/WifiScanWorker.java
index a87b36a..78b0d33 100644
--- a/src/com/android/settings/wifi/slice/WifiScanWorker.java
+++ b/src/com/android/settings/wifi/slice/WifiScanWorker.java
@@ -19,8 +19,6 @@
 import static com.android.settings.wifi.slice.WifiSlice.DEFAULT_EXPANDED_ROW_COUNT;
 
 import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.NetworkScoreManager;
 import android.net.Uri;
 import android.net.wifi.WifiManager;
 import android.os.HandlerThread;
@@ -34,6 +32,7 @@
 import androidx.lifecycle.LifecycleOwner;
 import androidx.lifecycle.LifecycleRegistry;
 
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.slices.SliceBackgroundWorker;
 import com.android.settingslib.utils.ThreadUtils;
 import com.android.wifitrackerlib.MergedCarrierEntry;
@@ -79,16 +78,15 @@
                 return SystemClock.elapsedRealtime();
             }
         };
-        mWifiPickerTracker = new WifiPickerTracker(getLifecycle(), context,
-                context.getSystemService(WifiManager.class),
-                context.getSystemService(ConnectivityManager.class),
-                context.getSystemService(NetworkScoreManager.class),
-                ThreadUtils.getUiThreadHandler(),
-                mWorkerThread.getThreadHandler(),
-                elapsedRealtimeClock,
-                MAX_SCAN_AGE_MILLIS,
-                SCAN_INTERVAL_MILLIS,
-                this);
+        mWifiPickerTracker = FeatureFactory.getFactory(context)
+                .getWifiTrackerLibProvider()
+                .createWifiPickerTracker(getLifecycle(), context,
+                        ThreadUtils.getUiThreadHandler(),
+                        mWorkerThread.getThreadHandler(),
+                        elapsedRealtimeClock,
+                        MAX_SCAN_AGE_MILLIS,
+                        SCAN_INTERVAL_MILLIS,
+                        this);
 
         mLifecycleRegistry.markState(Lifecycle.State.INITIALIZED);
         mLifecycleRegistry.markState(Lifecycle.State.CREATED);
diff --git a/tests/robotests/src/com/android/settings/accessibility/RingVibrationIntensityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/RingVibrationIntensityPreferenceControllerTest.java
new file mode 100644
index 0000000..0eaf008
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/RingVibrationIntensityPreferenceControllerTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accessibility;
+
+import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+import android.os.Vibrator;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+
+/** Tests for {@link RingVibrationIntensityPreferenceController}. */
+@RunWith(RobolectricTestRunner.class)
+public class RingVibrationIntensityPreferenceControllerTest {
+    @Mock
+    private Vibrator mVibrator;
+
+    private RingVibrationIntensityPreferenceController mController;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        final Context mContext = spy(ApplicationProvider.getApplicationContext());
+        doReturn(mVibrator).when(mContext).getSystemService(Vibrator.class);
+        mController = new RingVibrationIntensityPreferenceController(mContext);
+    }
+
+    @Test
+    public void getAvailabilityStatus_available() {
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+    }
+
+    @Test
+    public void getDefaultIntensity_success() {
+        doReturn(/* toBeReturned= */ 5).when(mVibrator).getDefaultRingVibrationIntensity();
+
+        assertThat(mController.getDefaultIntensity()).isEqualTo(/* expected= */ 5);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/TextAndDisplayFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/TextAndDisplayFragmentTest.java
new file mode 100644
index 0000000..96756ecd
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/TextAndDisplayFragmentTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accessibility;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.R;
+import com.android.settings.testutils.XmlTestUtils;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+import java.util.List;
+
+@RunWith(RobolectricTestRunner.class)
+public class TextAndDisplayFragmentTest {
+
+    private Context mContext = ApplicationProvider.getApplicationContext();
+
+    @Test
+    public void getNonIndexableKeys_existInXmlLayout() {
+        final List<String> niks = TextAndDisplayFragment.SEARCH_INDEX_DATA_PROVIDER
+                .getNonIndexableKeys(mContext);
+        final List<String> keys =
+                XmlTestUtils.getKeysFromPreferenceXml(mContext,
+                        R.xml.accessibility_text_and_display);
+
+        assertThat(keys).containsAtLeastElementsIn(niks);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/applications/specialaccess/notificationaccess/NotificationAccessDetailsTest.java b/tests/robotests/src/com/android/settings/applications/specialaccess/notificationaccess/NotificationAccessDetailsTest.java
deleted file mode 100644
index 26a78d0..0000000
--- a/tests/robotests/src/com/android/settings/applications/specialaccess/notificationaccess/NotificationAccessDetailsTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2019 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.applications.specialaccess.notificationaccess;
-
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.testutils.FakeFeatureFactory;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-
-@RunWith(RobolectricTestRunner.class)
-public class NotificationAccessDetailsTest {
-
-    private Context mContext;
-    private FakeFeatureFactory mFeatureFactory;
-    private NotificationAccessDetails mFragment;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mFeatureFactory = FakeFeatureFactory.setupForTest();
-        mFragment = spy(new NotificationAccessDetails());
-        mContext = RuntimeEnvironment.application;
-        doReturn(mContext).when(mFragment).getContext();
-
-    }
-
-    @Test
-    public void logSpecialPermissionChange() {
-        mFragment.logSpecialPermissionChange(true, "app");
-        verify(mFeatureFactory.metricsFeatureProvider).action(
-                mContext,
-                MetricsProto.MetricsEvent.APP_SPECIAL_PERMISSION_NOTIVIEW_ALLOW,
-                "app");
-
-        mFragment.logSpecialPermissionChange(false, "app");
-        verify(mFeatureFactory.metricsFeatureProvider).action(
-                mContext,
-                MetricsProto.MetricsEvent.APP_SPECIAL_PERMISSION_NOTIVIEW_DENY,
-                "app");
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenCustomRadioButtonPreferenceTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenCustomRadioButtonPreferenceTest.java
deleted file mode 100644
index f6e51cd..0000000
--- a/tests/robotests/src/com/android/settings/notification/zen/ZenCustomRadioButtonPreferenceTest.java
+++ /dev/null
@@ -1,110 +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.notification.zen;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.RadioButton;
-
-import androidx.preference.PreferenceViewHolder;
-
-import com.android.settings.R;
-import com.android.settings.notification.zen.ZenCustomRadioButtonPreference;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-
-@RunWith(RobolectricTestRunner.class)
-public class ZenCustomRadioButtonPreferenceTest {
-
-    private Context mContext;
-
-    @Before
-    public void setUp() {
-        mContext = RuntimeEnvironment.application;
-    }
-
-    @Test
-    public void createNewPreference_shouldSetLayout() {
-        final ZenCustomRadioButtonPreference preference
-                = new ZenCustomRadioButtonPreference(mContext);
-
-        assertThat(preference.getLayoutResource()).isEqualTo(R.layout.preference_two_target_radio);
-        assertThat(preference.getWidgetLayoutResource())
-                .isEqualTo(R.layout.preference_widget_gear);
-    }
-
-    @Test
-    public void setChecked_shouldUpdateButtonCheckedState() {
-        final ZenCustomRadioButtonPreference preference =
-                new ZenCustomRadioButtonPreference(mContext);
-        final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
-                LayoutInflater.from(mContext).inflate(
-                  R.layout.preference_two_target_radio, null));
-        final RadioButton toggle = (RadioButton) holder.findViewById(android.R.id.checkbox);
-        preference.onBindViewHolder(holder);
-
-        preference.setChecked(true);
-        assertThat(toggle.isChecked()).isTrue();
-
-        preference.setChecked(false);
-        assertThat(toggle.isChecked()).isFalse();
-    }
-
-    @Test
-    public void clickRadioButton_shouldNotifyRadioButtonClicked() {
-        final ZenCustomRadioButtonPreference preference
-                = new ZenCustomRadioButtonPreference(mContext);
-        final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
-                LayoutInflater.from(mContext).inflate(R.layout.preference_two_target_radio, null));
-        final View toggle = holder.findViewById(R.id.checkbox_frame);
-
-        ZenCustomRadioButtonPreference.OnRadioButtonClickListener l = mock(
-                ZenCustomRadioButtonPreference.OnRadioButtonClickListener.class);
-        preference.setOnRadioButtonClickListener(l);
-        preference.onBindViewHolder(holder);
-
-        toggle.performClick();
-        verify(l).onRadioButtonClick(preference);
-    }
-
-    @Test
-    public void clickWidgetView_shouldNotifyWidgetClicked() {
-        final ZenCustomRadioButtonPreference preference =
-                new ZenCustomRadioButtonPreference(mContext);
-        final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
-                LayoutInflater.from(mContext).inflate(R.layout.preference_two_target_radio, null));
-        final View widgetView = holder.findViewById(android.R.id.widget_frame);
-
-        ZenCustomRadioButtonPreference.OnGearClickListener l = mock(
-                ZenCustomRadioButtonPreference.OnGearClickListener.class);
-        preference.setOnGearClickListener(l);
-        preference.onBindViewHolder(holder);
-
-        widgetView.performClick();
-        verify(l).onGearClick(preference);
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenModeVisEffectsAllPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenModeVisEffectsAllPreferenceControllerTest.java
index 05537f3..45a40d3 100644
--- a/tests/robotests/src/com/android/settings/notification/zen/ZenModeVisEffectsAllPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/zen/ZenModeVisEffectsAllPreferenceControllerTest.java
@@ -40,11 +40,9 @@
 
 import androidx.preference.PreferenceScreen;
 
-import com.android.settings.notification.zen.ZenCustomRadioButtonPreference;
-import com.android.settings.notification.zen.ZenModeBackend;
-import com.android.settings.notification.zen.ZenModeVisEffectsAllPreferenceController;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -63,7 +61,7 @@
     @Mock
     private ZenModeBackend mBackend;
     @Mock
-    private ZenCustomRadioButtonPreference mockPref;
+    private RadioButtonPreference mPref;
     private Context mContext;
     private FakeFeatureFactory mFeatureFactory;
     @Mock
@@ -86,7 +84,7 @@
                 mContext, mock(Lifecycle.class), PREF_KEY);
         ReflectionHelpers.setField(mController, "mBackend", mBackend);
 
-        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
+        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPref);
         mController.displayPreference(mScreen);
     }
 
@@ -98,9 +96,9 @@
     @Test
     public void updateState_notChecked() {
         mBackend.mPolicy = new NotificationManager.Policy(0, 0, 0, 1);
-        mController.updateState(mockPref);
+        mController.updateState(mPref);
 
-        verify(mockPref).setChecked(false);
+        verify(mPref).setChecked(false);
     }
 
     @Test
@@ -115,9 +113,9 @@
                 | SUPPRESSED_EFFECT_PEEK
                 | SUPPRESSED_EFFECT_NOTIFICATION_LIST;
         mBackend.mPolicy = new NotificationManager.Policy(0, 0, 0, allSuppressed);
-        mController.updateState(mockPref);
+        mController.updateState(mPref);
 
-        verify(mockPref).setChecked(true);
+        verify(mPref).setChecked(true);
     }
 
     @Test
@@ -132,7 +130,7 @@
                 | SUPPRESSED_EFFECT_PEEK
                 | SUPPRESSED_EFFECT_NOTIFICATION_LIST;
         mBackend.mPolicy = new NotificationManager.Policy(0, 0, 0, 1);
-        mController.onRadioButtonClick(mockPref);
+        mController.onRadioButtonClicked(mPref);
         verify(mBackend).saveVisualEffectsPolicy(allSuppressed, true);
         verify(mFeatureFactory.metricsFeatureProvider).action(eq(mContext),
                 eq(ACTION_ZEN_SOUND_AND_VIS_EFFECTS),
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenModeVisEffectsCustomPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenModeVisEffectsCustomPreferenceControllerTest.java
index baea9ef..88c2c50 100644
--- a/tests/robotests/src/com/android/settings/notification/zen/ZenModeVisEffectsCustomPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/zen/ZenModeVisEffectsCustomPreferenceControllerTest.java
@@ -38,11 +38,9 @@
 
 import androidx.preference.PreferenceScreen;
 
-import com.android.settings.notification.zen.ZenCustomRadioButtonPreference;
-import com.android.settings.notification.zen.ZenModeBackend;
-import com.android.settings.notification.zen.ZenModeVisEffectsCustomPreferenceController;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -61,7 +59,7 @@
     @Mock
     private ZenModeBackend mBackend;
     @Mock
-    private ZenCustomRadioButtonPreference mockPref;
+    private RadioButtonPreference mPref;
     private Context mContext;
     @Mock
     private PreferenceScreen mScreen;
@@ -83,7 +81,7 @@
                 mContext, mock(Lifecycle.class), PREF_KEY);
         ReflectionHelpers.setField(mController, "mBackend", mBackend);
 
-        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
+        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPref);
         mController.displayPreference(mScreen);
     }
 
@@ -102,9 +100,9 @@
     @Test
     public void updateState_notChecked_noVisEffects() {
         mBackend.mPolicy = new NotificationManager.Policy(0, 0, 0, 0);
-        mController.updateState(mockPref);
+        mController.updateState(mPref);
 
-        verify(mockPref).setChecked(false);
+        verify(mPref).setChecked(false);
     }
 
     @Test
@@ -119,25 +117,25 @@
                 | SUPPRESSED_EFFECT_PEEK
                 | SUPPRESSED_EFFECT_NOTIFICATION_LIST;
         mBackend.mPolicy = new NotificationManager.Policy(0, 0, 0, allSuppressed);
-        mController.updateState(mockPref);
+        mController.updateState(mPref);
 
-        verify(mockPref).setChecked(false);
+        verify(mPref).setChecked(false);
     }
 
     @Test
     public void updateState_checked() {
         mBackend.mPolicy = new NotificationManager.Policy(0, 0, 0, 2);
-        mController.updateState(mockPref);
+        mController.updateState(mPref);
 
-        verify(mockPref).setChecked(true);
+        verify(mPref).setChecked(true);
     }
 
     @Test
     public void updateState_listeners() {
         mBackend.mPolicy = new NotificationManager.Policy(0, 0, 0, 2);
-        mController.updateState(mockPref);
+        mController.updateState(mPref);
 
-        verify(mockPref).setOnGearClickListener(any());
-        verify(mockPref).setOnRadioButtonClickListener(any());
+        verify(mPref).setExtraWidgetOnClickListener(any());
+        verify(mPref).setOnClickListener(any());
     }
 }
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenModeVisEffectsNonePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenModeVisEffectsNonePreferenceControllerTest.java
index aacb109..79c6cb8 100644
--- a/tests/robotests/src/com/android/settings/notification/zen/ZenModeVisEffectsNonePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/zen/ZenModeVisEffectsNonePreferenceControllerTest.java
@@ -40,11 +40,9 @@
 
 import androidx.preference.PreferenceScreen;
 
-import com.android.settings.notification.zen.ZenCustomRadioButtonPreference;
-import com.android.settings.notification.zen.ZenModeBackend;
-import com.android.settings.notification.zen.ZenModeVisEffectsNonePreferenceController;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -63,7 +61,7 @@
     @Mock
     private ZenModeBackend mBackend;
     @Mock
-    private ZenCustomRadioButtonPreference mockPref;
+    private RadioButtonPreference mMockPref;
     private Context mContext;
     private FakeFeatureFactory mFeatureFactory;
     @Mock
@@ -86,7 +84,7 @@
                 mContext, mock(Lifecycle.class), PREF_KEY);
         ReflectionHelpers.setField(mController, "mBackend", mBackend);
 
-        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
+        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mMockPref);
         mController.displayPreference(mScreen);
     }
 
@@ -98,17 +96,17 @@
     @Test
     public void updateState_notChecked() {
         mBackend.mPolicy = new NotificationManager.Policy(0, 0, 0, 1);
-        mController.updateState(mockPref);
+        mController.updateState(mMockPref);
 
-        verify(mockPref).setChecked(false);
+        verify(mMockPref).setChecked(false);
     }
 
     @Test
     public void updateState_checked() {
         mBackend.mPolicy = new NotificationManager.Policy(0, 0, 0, 0);
-        mController.updateState(mockPref);
+        mController.updateState(mMockPref);
 
-        verify(mockPref).setChecked(true);
+        verify(mMockPref).setChecked(true);
     }
 
     @Test
@@ -123,7 +121,7 @@
                 | SUPPRESSED_EFFECT_PEEK
                 | SUPPRESSED_EFFECT_NOTIFICATION_LIST;
         mBackend.mPolicy = new NotificationManager.Policy(0, 0, 0, 1);
-        mController.onRadioButtonClick(mockPref);
+        mController.onRadioButtonClicked(mMockPref);
         verify(mBackend).saveVisualEffectsPolicy(allSuppressed, false);
         verify(mFeatureFactory.metricsFeatureProvider).action(nullable(Context.class),
                 eq(ACTION_ZEN_SOUND_ONLY),
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenRuleCustomPolicyPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenRuleCustomPolicyPreferenceControllerTest.java
index f6fa5b7..f149541 100644
--- a/tests/robotests/src/com/android/settings/notification/zen/ZenRuleCustomPolicyPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/zen/ZenRuleCustomPolicyPreferenceControllerTest.java
@@ -27,6 +27,7 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -47,7 +48,7 @@
     @Mock
     private NotificationManager mNotificationManager;
     @Mock
-    private ZenCustomRadioButtonPreference mockPref;
+    private RadioButtonPreference mMockPref;
     @Mock
     private PreferenceScreen mScreen;
 
@@ -70,21 +71,21 @@
                 PREF_KEY);
         ReflectionHelpers.setField(mController, "mBackend", mBackend);
         when(mBackend.getAutomaticZenRule(RULE_ID)).thenReturn(mRule);
-        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
+        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mMockPref);
         mController.displayPreference(mScreen);
     }
 
     @Test
     public void updateState_nullZenPolicy() {
         updateControllerZenPolicy(null);
-        mController.updateState(mockPref);
-        verify(mockPref).setChecked(false);
+        mController.updateState(mMockPref);
+        verify(mMockPref).setChecked(false);
     }
 
     @Test
     public void updateState_hasZenPolicy() {
         updateControllerZenPolicy(new ZenPolicy.Builder().build());
-        mController.updateState(mockPref);
-        verify(mockPref).setChecked(true);
+        mController.updateState(mMockPref);
+        verify(mMockPref).setChecked(true);
     }
 }
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenRuleDefaultPolicyPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenRuleDefaultPolicyPreferenceControllerTest.java
index 7091ceb..c0258e4 100644
--- a/tests/robotests/src/com/android/settings/notification/zen/ZenRuleDefaultPolicyPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/zen/ZenRuleDefaultPolicyPreferenceControllerTest.java
@@ -27,6 +27,7 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -47,7 +48,7 @@
     @Mock
     private NotificationManager mNotificationManager;
     @Mock
-    private ZenCustomRadioButtonPreference mockPref;
+    private RadioButtonPreference mMockPref;
     @Mock
     private PreferenceScreen mScreen;
 
@@ -70,21 +71,21 @@
                 PREF_KEY);
         ReflectionHelpers.setField(mController, "mBackend", mBackend);
         when(mBackend.getAutomaticZenRule(RULE_ID)).thenReturn(mRule);
-        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
+        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mMockPref);
         mController.displayPreference(mScreen);
     }
 
     @Test
     public void updateState_nullZenPolicy() {
         updateControllerZenPolicy(null);
-        mController.updateState(mockPref);
-        verify(mockPref).setChecked(true);
+        mController.updateState(mMockPref);
+        verify(mMockPref).setChecked(true);
     }
 
     @Test
     public void updateState_hasZenPolicy() {
         updateControllerZenPolicy(new ZenPolicy.Builder().build());
-        mController.updateState(mockPref);
-        verify(mockPref).setChecked(false);
+        mController.updateState(mMockPref);
+        verify(mMockPref).setChecked(false);
     }
 }
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenRulePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenRulePreferenceControllerTest.java
index 13963db..e3fef19 100644
--- a/tests/robotests/src/com/android/settings/notification/zen/ZenRulePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/zen/ZenRulePreferenceControllerTest.java
@@ -28,10 +28,8 @@
 
 import androidx.preference.PreferenceScreen;
 
-import com.android.settings.notification.zen.AbstractZenCustomRulePreferenceController;
-import com.android.settings.notification.zen.ZenCustomRadioButtonPreference;
-import com.android.settings.notification.zen.ZenModeBackend;
 import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -51,7 +49,7 @@
     @Mock
     private NotificationManager mNotificationManager;
     @Mock
-    private ZenCustomRadioButtonPreference mockPref;
+    private RadioButtonPreference mMockPref;
     @Mock
     private PreferenceScreen mScreen;
 
@@ -67,7 +65,7 @@
         mContext = RuntimeEnvironment.application;
         mController = new TestablePreferenceController(mContext,"test", mock(Lifecycle.class));
         ReflectionHelpers.setField(mController, "mBackend", mBackend);
-        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
+        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mMockPref);
         mController.displayPreference(mScreen);
     }
 
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenRuleVisEffectsAllPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenRuleVisEffectsAllPreferenceControllerTest.java
index f30587f..edbcd06 100644
--- a/tests/robotests/src/com/android/settings/notification/zen/ZenRuleVisEffectsAllPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/zen/ZenRuleVisEffectsAllPreferenceControllerTest.java
@@ -27,6 +27,7 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -47,7 +48,7 @@
     @Mock
     private NotificationManager mNotificationManager;
     @Mock
-    private ZenCustomRadioButtonPreference mockPref;
+    private RadioButtonPreference mMockPref;
     @Mock
     private PreferenceScreen mScreen;
 
@@ -69,7 +70,7 @@
                 PREF_KEY);
         ReflectionHelpers.setField(mController, "mBackend", mBackend);
         when(mBackend.getAutomaticZenRule(RULE_ID)).thenReturn(mRule);
-        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
+        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mMockPref);
         mController.displayPreference(mScreen);
     }
 
@@ -78,8 +79,8 @@
         updateControllerZenPolicy(new ZenPolicy.Builder()
                 .hideAllVisualEffects()
                 .build());
-        mController.updateState(mockPref);
-        verify(mockPref).setChecked(false);
+        mController.updateState(mMockPref);
+        verify(mMockPref).setChecked(false);
     }
 
     @Test
@@ -87,8 +88,8 @@
         updateControllerZenPolicy(new ZenPolicy.Builder()
                 .showAllVisualEffects()
                 .build());
-        mController.updateState(mockPref);
-        verify(mockPref).setChecked(true);
+        mController.updateState(mMockPref);
+        verify(mMockPref).setChecked(true);
     }
 
     @Test
@@ -97,8 +98,8 @@
                 .showPeeking(true)
                 .showBadges(false)
                 .build());
-        mController.updateState(mockPref);
+        mController.updateState(mMockPref);
 
-        verify(mockPref).setChecked(false);
+        verify(mMockPref).setChecked(false);
     }
 }
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenRuleVisEffectsCustomPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenRuleVisEffectsCustomPreferenceControllerTest.java
index 99b76ce..ece5d5f 100644
--- a/tests/robotests/src/com/android/settings/notification/zen/ZenRuleVisEffectsCustomPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/zen/ZenRuleVisEffectsCustomPreferenceControllerTest.java
@@ -27,6 +27,7 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -47,7 +48,7 @@
     @Mock
     private NotificationManager mNotificationManager;
     @Mock
-    private ZenCustomRadioButtonPreference mockPref;
+    private RadioButtonPreference mMockPref;
     @Mock
     private PreferenceScreen mScreen;
 
@@ -69,7 +70,7 @@
                 PREF_KEY);
         ReflectionHelpers.setField(mController, "mBackend", mBackend);
         when(mBackend.getAutomaticZenRule(RULE_ID)).thenReturn(mRule);
-        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
+        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mMockPref);
         mController.displayPreference(mScreen);
     }
 
@@ -78,8 +79,8 @@
         updateControllerZenPolicy(new ZenPolicy.Builder()
                 .hideAllVisualEffects()
                 .build());
-        mController.updateState(mockPref);
-        verify(mockPref).setChecked(false);
+        mController.updateState(mMockPref);
+        verify(mMockPref).setChecked(false);
     }
 
     @Test
@@ -87,8 +88,8 @@
         updateControllerZenPolicy(new ZenPolicy.Builder()
                 .showAllVisualEffects()
                 .build());
-        mController.updateState(mockPref);
-        verify(mockPref).setChecked(false);
+        mController.updateState(mMockPref);
+        verify(mMockPref).setChecked(false);
     }
 
     @Test
@@ -97,8 +98,8 @@
                 .showPeeking(true)
                 .showBadges(false)
                 .build());
-        mController.updateState(mockPref);
+        mController.updateState(mMockPref);
 
-        verify(mockPref).setChecked(true);
+        verify(mMockPref).setChecked(true);
     }
 }
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenRuleVisEffectsNonePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenRuleVisEffectsNonePreferenceControllerTest.java
index 510da5f..2daf4fb 100644
--- a/tests/robotests/src/com/android/settings/notification/zen/ZenRuleVisEffectsNonePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/zen/ZenRuleVisEffectsNonePreferenceControllerTest.java
@@ -27,6 +27,7 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -47,7 +48,7 @@
     @Mock
     private NotificationManager mNotificationManager;
     @Mock
-    private ZenCustomRadioButtonPreference mockPref;
+    private RadioButtonPreference mMockPref;
     @Mock
     private PreferenceScreen mScreen;
 
@@ -69,7 +70,7 @@
                 PREF_KEY);
         ReflectionHelpers.setField(mController, "mBackend", mBackend);
         when(mBackend.getAutomaticZenRule(RULE_ID)).thenReturn(mRule);
-        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
+        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mMockPref);
         mController.displayPreference(mScreen);
     }
 
@@ -78,8 +79,8 @@
         updateControllerZenPolicy(new ZenPolicy.Builder()
                 .hideAllVisualEffects()
                 .build());
-        mController.updateState(mockPref);
-        verify(mockPref).setChecked(true);
+        mController.updateState(mMockPref);
+        verify(mMockPref).setChecked(true);
     }
 
     @Test
@@ -87,8 +88,8 @@
         updateControllerZenPolicy(new ZenPolicy.Builder()
                 .showAllVisualEffects()
                 .build());
-        mController.updateState(mockPref);
-        verify(mockPref).setChecked(false);
+        mController.updateState(mMockPref);
+        verify(mMockPref).setChecked(false);
     }
 
     @Test
@@ -97,8 +98,8 @@
                 .showPeeking(true)
                 .showBadges(false)
                 .build());
-        mController.updateState(mockPref);
+        mController.updateState(mMockPref);
 
-        verify(mockPref).setChecked(false);
+        verify(mMockPref).setChecked(false);
     }
 }
diff --git a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
index b5c6c44..c2c67e3 100644
--- a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
@@ -565,7 +565,8 @@
         final Intent settingsIntent = new Intent(Settings.ACTION_SETTINGS)
                 .setPackage(Utils.SETTINGS_PACKAGE_NAME);
         PendingIntent settingsPendingIntent =
-                PendingIntent.getActivity(mContext, 0, settingsIntent, 0);
+                PendingIntent.getActivity(mContext, 0, settingsIntent,
+                        PendingIntent.FLAG_IMMUTABLE);
 
         assertThat(pendingIntent).isEqualTo(settingsPendingIntent);
     }
diff --git a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
index 2c68269..6fb2eae 100644
--- a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
+++ b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
@@ -43,6 +43,7 @@
 import com.android.settings.security.SecurityFeatureProvider;
 import com.android.settings.slices.SlicesFeatureProvider;
 import com.android.settings.users.UserFeatureProvider;
+import com.android.settings.wifi.WifiTrackerLibProvider;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import org.mockito.Answers;
@@ -77,6 +78,8 @@
     public SearchFeatureProvider searchFeatureProvider;
     public ContextualCardFeatureProvider mContextualCardFeatureProvider;
 
+    public WifiTrackerLibProvider wifiTrackerLibProvider;
+
     /**
      * Call this in {@code @Before} method of the test class to use fake factory.
      */
@@ -120,6 +123,7 @@
         mBluetoothFeatureProvider = mock(BluetoothFeatureProvider.class);
         mAwareFeatureProvider = mock(AwareFeatureProvider.class);
         mFaceFeatureProvider = mock(FaceFeatureProvider.class);
+        wifiTrackerLibProvider = mock(WifiTrackerLibProvider.class);
     }
 
     @Override
@@ -231,4 +235,9 @@
     public FaceFeatureProvider getFaceFeatureProvider() {
         return mFaceFeatureProvider;
     }
+
+    @Override
+    public WifiTrackerLibProvider getWifiTrackerLibProvider() {
+        return wifiTrackerLibProvider;
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/users/UserDetailsSettingsTest.java b/tests/robotests/src/com/android/settings/users/UserDetailsSettingsTest.java
index 90c9172..50ddd2a 100644
--- a/tests/robotests/src/com/android/settings/users/UserDetailsSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/users/UserDetailsSettingsTest.java
@@ -363,7 +363,7 @@
         mFragment.initialize(mActivity, mArguments);
 
         verify(mRemoveUserPref).setOnPreferenceClickListener(mFragment);
-        verify(mRemoveUserPref).setTitle(R.string.user_exit_guest_title);
+        verify(mRemoveUserPref).setTitle(R.string.user_exit_guest_menu);
         verify(mFragment, never()).removePreference(KEY_REMOVE_USER);
     }
 
diff --git a/tests/robotests/src/com/android/settings/widget/RadioButtonPreferenceWithExtraWidgetTest.java b/tests/robotests/src/com/android/settings/widget/RadioButtonPreferenceWithExtraWidgetTest.java
deleted file mode 100644
index 2e2d786..0000000
--- a/tests/robotests/src/com/android/settings/widget/RadioButtonPreferenceWithExtraWidgetTest.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2019 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.widget;
-
-import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_GONE;
-import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_INFO;
-import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_SETTING;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assert.assertEquals;
-
-import android.app.Application;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import androidx.preference.PreferenceViewHolder;
-
-import com.android.settings.R;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-
-@RunWith(RobolectricTestRunner.class)
-public class RadioButtonPreferenceWithExtraWidgetTest {
-
-    private Application mContext;
-    private RadioButtonPreferenceWithExtraWidget mPreference;
-
-    private TextView mSummary;
-    private ImageView mExtraWidget;
-    private View mExtraWidgetDivider;
-
-    private boolean mIsClickListenerCalled = false;
-    private View.OnClickListener mClickListener = new View.OnClickListener() {
-        @Override
-        public void onClick(View v) {
-            mIsClickListenerCalled = true;
-        }
-    };
-
-    @Before
-    public void setUp() {
-        mContext = RuntimeEnvironment.application;
-        mPreference = new RadioButtonPreferenceWithExtraWidget(mContext);
-        mPreference.setSummary("test summary");
-
-        View view = LayoutInflater.from(mContext)
-                .inflate(R.layout.preference_radio_with_extra_widget, null);
-        PreferenceViewHolder preferenceViewHolder =
-                PreferenceViewHolder.createInstanceForTests(view);
-        mPreference.onBindViewHolder(preferenceViewHolder);
-
-        mSummary = view.findViewById(android.R.id.summary);
-        mExtraWidget = view.findViewById(R.id.radio_extra_widget);
-        mExtraWidgetDivider = view.findViewById(R.id.radio_extra_widget_divider);
-    }
-
-    @Test
-    public void shouldHaveRadioPreferenceWithExtraWidgetLayout() {
-        assertThat(mPreference.getLayoutResource())
-                .isEqualTo(R.layout.preference_radio_with_extra_widget);
-    }
-
-    @Test
-    public void iconSpaceReservedShouldBeFalse() {
-        assertThat(mPreference.isIconSpaceReserved()).isFalse();
-    }
-
-    @Test
-    public void summaryShouldBeVisible() {
-        assertEquals(View.VISIBLE, mSummary.getVisibility());
-    }
-
-    @Test
-    public void testSetExtraWidgetVisibility_gone() {
-        mPreference.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_GONE);
-        assertEquals(View.GONE, mExtraWidget.getVisibility());
-        assertEquals(View.GONE, mExtraWidgetDivider.getVisibility());
-        assertThat(mExtraWidget.isClickable()).isFalse();
-    }
-
-    @Test
-    public void testSetExtraWidgetVisibility_info() {
-        mPreference.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_INFO);
-        assertEquals(View.VISIBLE, mExtraWidget.getVisibility());
-        assertEquals(View.VISIBLE, mExtraWidgetDivider.getVisibility());
-        assertThat(mExtraWidget.isClickable()).isTrue();
-        assertEquals(mContext.getResources().getText(R.string.information_label),
-                mExtraWidget.getContentDescription());
-    }
-
-    @Test
-    public void testSetExtraWidgetVisibility_setting() {
-        mPreference.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_SETTING);
-        assertEquals(View.VISIBLE, mExtraWidget.getVisibility());
-        assertEquals(View.VISIBLE, mExtraWidgetDivider.getVisibility());
-        assertThat(mExtraWidget.isClickable()).isTrue();
-        assertEquals(mContext.getResources().getText(R.string.settings_label),
-                mExtraWidget.getContentDescription());
-    }
-
-    @Test
-    public void testSetExtraWidgetOnClickListener() {
-        mPreference.setExtraWidgetOnClickListener(mClickListener);
-
-        assertThat(mIsClickListenerCalled).isFalse();
-        mExtraWidget.callOnClick();
-        assertThat(mIsClickListenerCalled).isTrue();
-    }
-
-    @Test
-    public void extraWidgetStaysEnabledWhenPreferenceIsDisabled() {
-        mPreference.setEnabled(false);
-        mExtraWidget.setEnabled(false);
-
-        assertThat(mExtraWidget.isEnabled()).isFalse();
-        mPreference.setExtraWidgetOnClickListener(mClickListener);
-        assertThat(mExtraWidget.isEnabled()).isTrue();
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/wifi/addappnetworks/AddAppNetworksFragmentTest.java b/tests/robotests/src/com/android/settings/wifi/addappnetworks/AddAppNetworksFragmentTest.java
index 70c7810..24d4c47 100644
--- a/tests/robotests/src/com/android/settings/wifi/addappnetworks/AddAppNetworksFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/addappnetworks/AddAppNetworksFragmentTest.java
@@ -20,6 +20,7 @@
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
@@ -41,6 +42,7 @@
 import androidx.fragment.app.FragmentActivity;
 
 import com.android.settings.R;
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.wifitrackerlib.WifiEntry;
 import com.android.wifitrackerlib.WifiPickerTracker;
 
@@ -82,6 +84,8 @@
     @Mock
     private WifiEntry mWifiEntry;
 
+    private FakeFeatureFactory mFakeFeatureFactory;
+
     @Mock
     private WifiPickerTracker mWifiPickerTracker;
 
@@ -106,6 +110,8 @@
         mSavedWpaConfigurationEntry = generateRegularWifiConfiguration(FAKE_NEW_SAVED_WPA_SSID,
                 WifiConfiguration.KeyMgmt.WPA_PSK, "\"1234567890\"");
 
+        mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
+
         mAddAppNetworksFragment.mWifiPickerTracker = mWifiPickerTracker;
         setUpOneScannedNetworkWithScanedLevel4();
     }
@@ -485,6 +491,9 @@
     }
 
     private void setupFragment() {
+        when(mFakeFeatureFactory.wifiTrackerLibProvider.createWifiPickerTracker(
+                any(), any(), any(), any(), any(), anyLong(), anyLong(), any()))
+                .thenReturn(mWifiPickerTracker);
         FragmentController.setupFragment(mAddAppNetworksFragment);
     }
 
diff --git a/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceControllerTest.java b/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceControllerTest.java
new file mode 100644
index 0000000..064f813
--- /dev/null
+++ b/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceControllerTest.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2020 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.applications.specialaccess.notificationaccess;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+
+import androidx.preference.SwitchPreference;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.testutils.FakeFeatureFactory;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+public class ApprovalPreferenceControllerTest {
+
+    private Context mContext;
+    private FakeFeatureFactory mFeatureFactory;
+    @Mock
+    private NotificationAccessDetails mFragment;
+    private ApprovalPreferenceController mController;
+    @Mock
+    NotificationManager mNm;
+    @Mock
+    PackageManager mPm;
+    PackageInfo mPkgInfo;
+    ComponentName mCn = new ComponentName("a", "b");
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mFeatureFactory = FakeFeatureFactory.setupForTest();
+        mContext = spy(ApplicationProvider.getApplicationContext());
+        doReturn(mContext).when(mFragment).getContext();
+
+        mPkgInfo = new PackageInfo();
+        mPkgInfo.applicationInfo = mock(ApplicationInfo.class);
+        when(mPkgInfo.applicationInfo.loadLabel(mPm)).thenReturn("LABEL");
+
+        mController = new ApprovalPreferenceController(mContext, "key");
+        mController.setCn(mCn);
+        mController.setNm(mNm);
+        mController.setParent(mFragment);
+        mController.setPkgInfo(mPkgInfo);
+    }
+
+    @Test
+    public void updateState_checked() {
+        when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
+        SwitchPreference pref = new SwitchPreference(mContext);
+
+        mController.updateState(pref);
+        assertThat(pref.isChecked()).isTrue();
+    }
+
+    @Test
+    public void enable() {
+        mController.enable(mCn);
+        verify(mFeatureFactory.metricsFeatureProvider).action(
+                mContext,
+                MetricsProto.MetricsEvent.APP_SPECIAL_PERMISSION_NOTIVIEW_ALLOW,
+                "a");
+
+        verify(mNm).setNotificationListenerAccessGranted(mCn, true);
+    }
+
+    @Test
+    public void disable() {
+        mController.disable(mCn);
+        verify(mFeatureFactory.metricsFeatureProvider).action(
+                mContext,
+                MetricsProto.MetricsEvent.APP_SPECIAL_PERMISSION_NOTIVIEW_ALLOW,
+                "a");
+
+        verify(mNm).setNotificationListenerAccessGranted(mCn, false);
+    }
+}
diff --git a/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/TypeFilterPreferenceControllerTest.java b/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/TypeFilterPreferenceControllerTest.java
new file mode 100644
index 0000000..3014066
--- /dev/null
+++ b/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/TypeFilterPreferenceControllerTest.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.applications.specialaccess.notificationaccess;
+
+import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_CONVERSATIONS;
+import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ONGOING;
+import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_SILENT;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.service.notification.NotificationListenerFilter;
+import android.util.ArraySet;
+
+import androidx.preference.MultiSelectListPreference;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.settings.notification.NotificationBackend;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Set;
+
+@RunWith(AndroidJUnit4.class)
+public class TypeFilterPreferenceControllerTest {
+
+    private Context mContext;
+    private TypeFilterPreferenceController mController;
+    @Mock
+    NotificationBackend mNm;
+    ComponentName mCn = new ComponentName("a", "b");
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = ApplicationProvider.getApplicationContext();
+
+        mController = new TypeFilterPreferenceController(mContext, "key");
+        mController.setCn(mCn);
+        mController.setNm(mNm);
+        mController.setUserId(0);
+    }
+
+    @Test
+    public void updateState_enabled() {
+        when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
+        when(mNm.getListenerFilter(mCn, 0)).thenReturn(new NotificationListenerFilter());
+        MultiSelectListPreference pref = new MultiSelectListPreference(mContext);
+
+        mController.updateState(pref);
+        assertThat(pref.isEnabled()).isTrue();
+    }
+
+    @Test
+    public void updateState_disabled() {
+        when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(false);
+        when(mNm.getListenerFilter(mCn, 0)).thenReturn(new NotificationListenerFilter());
+        MultiSelectListPreference pref = new MultiSelectListPreference(mContext);
+
+        mController.updateState(pref);
+        assertThat(pref.isEnabled()).isFalse();
+    }
+
+    @Test
+    public void updateState() {
+        NotificationListenerFilter nlf = new NotificationListenerFilter(FLAG_FILTER_TYPE_ONGOING
+                | FLAG_FILTER_TYPE_SILENT, new ArraySet<>());
+        when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
+        when(mNm.getListenerFilter(mCn, 0)).thenReturn(nlf);
+
+        MultiSelectListPreference pref = new MultiSelectListPreference(mContext);
+        mController.updateState(pref);
+
+        assertThat(pref.getValues()).containsExactlyElementsIn(
+                new String[] {String.valueOf(FLAG_FILTER_TYPE_ONGOING),
+                        String.valueOf(FLAG_FILTER_TYPE_SILENT)});
+        assertThat(pref.getSummary()).isNotNull();
+    }
+
+    @Test
+    public void getSummary() {
+        NotificationListenerFilter nlf = new NotificationListenerFilter(FLAG_FILTER_TYPE_ONGOING
+                | FLAG_FILTER_TYPE_CONVERSATIONS, new ArraySet<>());
+        when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
+        when(mNm.getListenerFilter(mCn, 0)).thenReturn(nlf);
+
+        MultiSelectListPreference pref = new MultiSelectListPreference(mContext);
+        mController.updateState(pref);
+
+        assertThat(mController.getSummary().toString()).ignoringCase().contains("ongoing");
+        assertThat(mController.getSummary().toString()).ignoringCase().contains("conversation");
+    }
+
+    @Test
+    public void onPreferenceChange() {
+        NotificationListenerFilter nlf = new NotificationListenerFilter(FLAG_FILTER_TYPE_ONGOING
+                | FLAG_FILTER_TYPE_CONVERSATIONS, new ArraySet<>());
+        when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
+        when(mNm.getListenerFilter(mCn, 0)).thenReturn(nlf);
+
+        MultiSelectListPreference pref = new MultiSelectListPreference(mContext);
+
+        mController.onPreferenceChange(pref, Set.of("8", "1", "4"));
+
+        ArgumentCaptor<NotificationListenerFilter> captor =
+                ArgumentCaptor.forClass(NotificationListenerFilter.class);
+        verify(mNm).setListenerFilter(eq(mCn), eq(0), captor.capture());
+        assertThat(captor.getValue().getTypes()).isEqualTo(FLAG_FILTER_TYPE_CONVERSATIONS
+                | FLAG_FILTER_TYPE_SILENT | FLAG_FILTER_TYPE_ONGOING);
+    }
+}
diff --git a/tests/unit/src/com/android/settings/network/ProviderModelSliceTest.java b/tests/unit/src/com/android/settings/network/ProviderModelSliceTest.java
index f9450db..076ce2b 100644
--- a/tests/unit/src/com/android/settings/network/ProviderModelSliceTest.java
+++ b/tests/unit/src/com/android/settings/network/ProviderModelSliceTest.java
@@ -22,6 +22,7 @@
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -50,9 +51,11 @@
 
 import com.android.settings.Utils;
 import com.android.settings.network.telephony.NetworkProviderWorker;
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.ResourcesUtils;
 import com.android.settings.wifi.slice.WifiSliceItem;
 import com.android.wifitrackerlib.WifiEntry;
+import com.android.wifitrackerlib.WifiPickerTracker;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -100,12 +103,22 @@
     @Mock
     GridRowBuilder mMockGridRowBuilderAllNetworkUnavailable;
 
+    private FakeFeatureFactory mFeatureFactory;
+    @Mock
+    private WifiPickerTracker mWifiPickerTracker;
+
     @Before
     @UiThreadTest
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mContext = spy(ApplicationProvider.getApplicationContext());
 
+        mFeatureFactory = FakeFeatureFactory.setupForTest();
+        when(mFeatureFactory.wifiTrackerLibProvider
+                .createWifiPickerTracker(
+                        any(), any(), any(), any(), any(), anyLong(), anyLong(), any()))
+                .thenReturn(mWifiPickerTracker);
+
         when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager);
         when(mContext.getSystemService(ConnectivityManager.class)).thenReturn(mConnectivityManager);
         when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
diff --git a/tests/unit/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java b/tests/unit/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java
index 5ee4c42..27dd2aa 100644
--- a/tests/unit/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java
@@ -28,6 +28,7 @@
 import static org.mockito.ArgumentMatchers.eq;;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -59,6 +60,7 @@
 import com.android.settings.Utils;
 import com.android.settings.network.SubscriptionsPreferenceController.SubsPrefCtrlInjector;
 import com.android.settings.testutils.ResourcesUtils;
+import com.android.settings.wifi.WifiPickerTrackerHelper;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 
 import org.junit.After;
@@ -90,6 +92,8 @@
     private Lifecycle mLifecycle;
     @Mock
     private LifecycleOwner mLifecycleOwner;
+    @Mock
+    private WifiPickerTrackerHelper mWifiPickerTrackerHelper;
     private LifecycleRegistry mLifecycleRegistry;
     private int mOnChildUpdatedCount;
     private Context mContext;
@@ -529,6 +533,26 @@
         assertThat(icon).isEqualTo(actualIcon);
     }
 
+    @Test
+    public void connectCarrierNetwork_isDataEnabled_helperConnect() {
+        when(mTelephonyManager.isDataEnabled()).thenReturn(true);
+        mController.setWifiPickerTrackerHelper(mWifiPickerTrackerHelper);
+
+        mController.connectCarrierNetwork();
+
+        verify(mWifiPickerTrackerHelper).connectCarrierNetwork(any());
+    }
+
+    @Test
+    public void connectCarrierNetwork_isNotDataEnabled_helperNeverConnect() {
+        when(mTelephonyManager.isDataEnabled()).thenReturn(false);
+        mController.setWifiPickerTrackerHelper(mWifiPickerTrackerHelper);
+
+        mController.connectCarrierNetwork();
+
+        verify(mWifiPickerTrackerHelper, never()).connectCarrierNetwork(any());
+    }
+
     private void setupGetIconConditions(int subId, boolean isActiveCellularNetwork,
             boolean isDataEnable, int dataState, int servicestate) {
         doReturn(mTelephonyManagerForSub).when(mTelephonyManager).createForSubscriptionId(subId);
diff --git a/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java
index 47851b9..d20fc12 100644
--- a/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java
+++ b/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java
@@ -41,6 +41,7 @@
 import com.android.settings.security.SecurityFeatureProvider;
 import com.android.settings.slices.SlicesFeatureProvider;
 import com.android.settings.users.UserFeatureProvider;
+import com.android.settings.wifi.WifiTrackerLibProvider;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 /**
@@ -72,6 +73,8 @@
     public SearchFeatureProvider searchFeatureProvider;
     public ContextualCardFeatureProvider mContextualCardFeatureProvider;
 
+    public WifiTrackerLibProvider wifiTrackerLibProvider;
+
     /**
      * Call this in {@code @Before} method of the test class to use fake factory.
      */
@@ -106,6 +109,7 @@
         mBluetoothFeatureProvider = mock(BluetoothFeatureProvider.class);
         mAwareFeatureProvider = mock(AwareFeatureProvider.class);
         mFaceFeatureProvider = mock(FaceFeatureProvider.class);
+        wifiTrackerLibProvider = mock(WifiTrackerLibProvider.class);
     }
 
     @Override
@@ -217,4 +221,9 @@
     public FaceFeatureProvider getFaceFeatureProvider() {
         return mFaceFeatureProvider;
     }
+
+    @Override
+    public WifiTrackerLibProvider getWifiTrackerLibProvider() {
+        return wifiTrackerLibProvider;
+    }
 }
diff --git a/tests/unit/src/com/android/settings/wifi/WifiPickerTrackerHelperTest.java b/tests/unit/src/com/android/settings/wifi/WifiPickerTrackerHelperTest.java
new file mode 100644
index 0000000..2991550
--- /dev/null
+++ b/tests/unit/src/com/android/settings/wifi/WifiPickerTrackerHelperTest.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.wifi;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.os.HandlerThread;
+
+import androidx.lifecycle.Lifecycle;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.wifitrackerlib.MergedCarrierEntry;
+import com.android.wifitrackerlib.WifiEntry;
+import com.android.wifitrackerlib.WifiPickerTracker;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+@RunWith(AndroidJUnit4.class)
+public class WifiPickerTrackerHelperTest {
+
+    @Rule
+    public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+    @Mock
+    public WifiPickerTracker mWifiPickerTracker;
+    @Mock
+    public MergedCarrierEntry mMergedCarrierEntry;
+    @Mock
+    public WifiEntry.ConnectCallback mConnectCallback;
+
+    private WifiPickerTrackerHelper mWifiPickerTrackerHelper;
+
+    private FakeFeatureFactory mFeatureFactory;
+
+    @Before
+    public void setUp() {
+        mFeatureFactory = FakeFeatureFactory.setupForTest();
+        when(mFeatureFactory.wifiTrackerLibProvider
+                .createWifiPickerTracker(
+                        any(), any(), any(), any(), any(), anyLong(), anyLong(), any()))
+                .thenReturn(mWifiPickerTracker);
+        mWifiPickerTrackerHelper = new WifiPickerTrackerHelper(mock(Lifecycle.class),
+                ApplicationProvider.getApplicationContext(), null);
+    }
+
+    @Test
+    public void getWifiPickerTracker_returnNonNull() {
+        assertThat(mWifiPickerTrackerHelper.getWifiPickerTracker()).isNotNull();
+    }
+
+    @Test
+    public void onDestroy_workerThreadQuit() {
+        final HandlerThread workerThread = mock(HandlerThread.class);
+        mWifiPickerTrackerHelper.setWorkerThread(workerThread);
+
+        mWifiPickerTrackerHelper.onDestroy();
+
+        verify(workerThread).quit();
+    }
+
+    @Test
+    public void setCarrierNetworkEnabled_returnTrueAndSetEnabled() {
+        mWifiPickerTrackerHelper.setWifiPickerTracker(mWifiPickerTracker);
+        when(mWifiPickerTracker.getMergedCarrierEntry()).thenReturn(mMergedCarrierEntry);
+
+        assertThat(mWifiPickerTrackerHelper.setCarrierNetworkEnabled(true)).isTrue();
+        verify(mMergedCarrierEntry).setEnabled(true);
+
+        assertThat(mWifiPickerTrackerHelper.setCarrierNetworkEnabled(false)).isTrue();
+        verify(mMergedCarrierEntry).setEnabled(false);
+    }
+
+    @Test
+    public void setCarrierNetworkEnabled_mergedCarrierEntryIsNull_returnFalse() {
+        mWifiPickerTrackerHelper.setWifiPickerTracker(mWifiPickerTracker);
+        when(mWifiPickerTracker.getMergedCarrierEntry()).thenReturn(null);
+
+        assertThat(mWifiPickerTrackerHelper.setCarrierNetworkEnabled(true)).isFalse();
+        assertThat(mWifiPickerTrackerHelper.setCarrierNetworkEnabled(false)).isFalse();
+    }
+
+    @Test
+    public void connectCarrierNetwork_returnTrueAndConnect() {
+        mWifiPickerTrackerHelper.setWifiPickerTracker(mWifiPickerTracker);
+        when(mWifiPickerTracker.getMergedCarrierEntry()).thenReturn(mMergedCarrierEntry);
+        when(mMergedCarrierEntry.canConnect()).thenReturn(true);
+
+        assertThat(mWifiPickerTrackerHelper.connectCarrierNetwork(mConnectCallback)).isTrue();
+        verify(mMergedCarrierEntry).connect(mConnectCallback);
+    }
+
+    @Test
+    public void connectCarrierNetwork_mergedCarrierEntryIsNull_returnFalse() {
+        mWifiPickerTrackerHelper.setWifiPickerTracker(mWifiPickerTracker);
+        when(mWifiPickerTracker.getMergedCarrierEntry()).thenReturn(null);
+
+        assertThat(mWifiPickerTrackerHelper.connectCarrierNetwork(mConnectCallback)).isFalse();
+    }
+
+    @Test
+    public void connectCarrierNetwork_canConnectIsFalse_returnFalseAndNeverConnect() {
+        mWifiPickerTrackerHelper.setWifiPickerTracker(mWifiPickerTracker);
+        when(mWifiPickerTracker.getMergedCarrierEntry()).thenReturn(mMergedCarrierEntry);
+        when(mMergedCarrierEntry.canConnect()).thenReturn(false);
+
+        assertThat(mWifiPickerTrackerHelper.connectCarrierNetwork(mConnectCallback)).isFalse();
+        verify(mMergedCarrierEntry, never()).connect(mConnectCallback);
+    }
+}