Merge "Bump string length limits"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 2d2f584..7689b11 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -114,13 +114,6 @@
         <uses-library android:name="org.apache.http.legacy" />
         <!-- Settings -->
 
-        <activity android:name="SettingsActivity"
-                android:label="@string/settings_label_launcher"
-                android:launchMode="singleTask">
-            <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
-                android:value="true" />
-        </activity>
-
         <activity android:name=".homepage.SettingsHomepageActivity"
                   android:label="@string/settings_label_launcher"
                   android:theme="@style/Theme.Settings.Home"
@@ -2585,6 +2578,18 @@
             </intent-filter>
         </activity>
 
+        <activity
+            android:name=".wifi.NetworkRequestDialogActivity"
+            android:theme="@style/Transparent"
+            android:excludeFromRecents="true"
+            android:exported="true"
+            android:permission="android.permission.NETWORK_SETTINGS">
+            <intent-filter>
+                <action android:name="com.android.settings.wifi.NETWORK_REQUEST" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
         <activity android:name=".sim.SimDialogActivity"
                 android:theme="@style/Theme.AlertDialog"
                 android:label="@string/sim_settings_title"
@@ -2959,6 +2964,17 @@
                        android:value="true" />
         </activity>
 
+        <activity android:name=".panel.SettingsPanelActivity"
+            android:label="@string/settings_panel_title"
+            android:theme="@style/Theme.BottomDialog"
+            android:excludeFromRecents="true"
+            android:launchMode="singleTask">
+                 <intent-filter>
+                     <action android:name="android.settings.SETTINGSPANEL" />
+                     <category android:name="android.intent.category.DEFAULT" />
+                 </intent-filter>
+        </activity>
+
         <provider android:name=".slices.SettingsSliceProvider"
                   android:authorities="com.android.settings.slices;android.settings.slices"
                   android:exported="true"
@@ -3021,6 +3037,9 @@
 
         <activity
             android:name=".wifi.dpp.WifiDppConfiguratorActivity"/>
+
+        <activity android:name=".homepage.contextualcards.ContextualCardFeedbackDialog"
+                  android:theme="@android:style/Theme.DeviceDefault.Light.Dialog.Alert" />
         <!-- This is the longest AndroidManifest.xml ever. -->
     </application>
 </manifest>
diff --git a/color-check-baseline.xml b/color-check-baseline.xml
index 0ae001d..312e5c9 100644
--- a/color-check-baseline.xml
+++ b/color-check-baseline.xml
@@ -169,12 +169,12 @@
         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;material_empty_color_light&quot;>#FFCED7DB&lt;/color>"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        errorLine1="  &lt;color name=&quot;homepage_accessibility_background&quot;>#783BE5&lt;/color>"
+        errorLine2="  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="res/values/colors.xml"
+            file="res/values-night/colors.xml"
             line="22"
-            column="5"/>
+            column="3"/>
     </issue>
 
     <issue
@@ -189,7 +189,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="24"
+            line="22"
             column="5"/>
     </issue>
 
@@ -201,11 +201,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.&#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_support_background&quot;>#3F5FBD&lt;/color>"
+        errorLine2="  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/values-night/colors.xml"
+            line="23"
+            column="3"/>
+    </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;crypt_keeper_clock_background&quot;>#ff9a9a9a&lt;/color>"
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="26"
+            line="24"
             column="5"/>
     </issue>
 
@@ -221,7 +237,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="27"
+            line="25"
             column="5"/>
     </issue>
 
@@ -237,7 +253,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="28"
+            line="26"
             column="5"/>
     </issue>
 
@@ -253,7 +269,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="29"
+            line="27"
             column="5"/>
     </issue>
 
@@ -269,23 +285,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="31"
-            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;setup_lock_pattern_view_regular_color_dark&quot;>#ffbdbdbd&lt;/color>"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/values/colors.xml"
-            line="33"
+            line="29"
             column="5"/>
     </issue>
 
@@ -301,7 +301,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="35"
+            line="32"
             column="5"/>
     </issue>
 
@@ -317,7 +317,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="37"
+            line="34"
             column="5"/>
     </issue>
 
@@ -333,7 +333,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="38"
+            line="35"
             column="5"/>
     </issue>
 
@@ -349,7 +349,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="39"
+            line="36"
             column="5"/>
     </issue>
 
@@ -365,7 +365,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="41"
+            line="38"
             column="5"/>
     </issue>
 
@@ -381,7 +381,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="42"
+            line="39"
             column="5"/>
     </issue>
 
@@ -397,7 +397,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="44"
+            line="41"
             column="5"/>
     </issue>
 
@@ -413,7 +413,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="49"
+            line="46"
             column="5"/>
     </issue>
 
@@ -429,7 +429,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="50"
+            line="47"
             column="5"/>
     </issue>
 
@@ -445,7 +445,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="52"
+            line="49"
             column="5"/>
     </issue>
 
@@ -461,23 +461,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="53"
-            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;wifi_divider&quot;>#ffe0e0e0&lt;/color>"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/values/colors.xml"
-            line="55"
+            line="50"
             column="5"/>
     </issue>
 
@@ -493,103 +477,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="58"
-            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;voice_interaction_highlight&quot;>#33b5e5&lt;/color>"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/values/colors.xml"
-            line="59"
-            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;memory_normal&quot;>#ff009587&lt;/color>"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/values/colors.xml"
-            line="61"
-            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;memory_moderate&quot;>#ffF3B300&lt;/color>"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/values/colors.xml"
-            line="62"
-            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;memory_low&quot;>#ffff9700&lt;/color>"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/values/colors.xml"
-            line="63"
-            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;memory_critical&quot;>#ffff5621&lt;/color>"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/values/colors.xml"
-            line="64"
-            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;memory_avg_use&quot;>#ff384248&lt;/color>"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/values/colors.xml"
-            line="66"
+            line="54"
             column="5"/>
     </issue>
 
@@ -605,39 +493,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="69"
-            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;importance_icon_tint&quot;>#8a000000&lt;/color>"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/values/colors.xml"
-            line="71"
-            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;importance_disabled_tint&quot;>#4d000000&lt;/color>"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/values/colors.xml"
-            line="72"
+            line="57"
             column="5"/>
     </issue>
 
@@ -653,7 +509,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="75"
+            line="60"
             column="5"/>
     </issue>
 
@@ -669,7 +525,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="76"
+            line="61"
             column="5"/>
     </issue>
 
@@ -685,7 +541,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="77"
+            line="62"
             column="5"/>
     </issue>
 
@@ -701,7 +557,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="78"
+            line="63"
             column="5"/>
     </issue>
 
@@ -717,7 +573,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="79"
+            line="64"
             column="5"/>
     </issue>
 
@@ -733,7 +589,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="82"
+            line="66"
             column="5"/>
     </issue>
 
@@ -749,7 +605,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="83"
+            line="67"
             column="5"/>
     </issue>
 
@@ -765,7 +621,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="84"
+            line="68"
             column="5"/>
     </issue>
 
@@ -781,7 +637,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="85"
+            line="69"
             column="5"/>
     </issue>
 
@@ -797,7 +653,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="86"
+            line="70"
             column="5"/>
     </issue>
 
@@ -813,7 +669,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="87"
+            line="71"
             column="5"/>
     </issue>
 
@@ -829,7 +685,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="88"
+            line="72"
             column="5"/>
     </issue>
 
@@ -845,7 +701,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="89"
+            line="73"
             column="5"/>
     </issue>
 
@@ -861,7 +717,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="90"
+            line="74"
             column="5"/>
     </issue>
 
@@ -877,7 +733,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="91"
+            line="75"
             column="5"/>
     </issue>
 
@@ -893,7 +749,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="92"
+            line="76"
             column="5"/>
     </issue>
 
@@ -909,7 +765,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="94"
+            line="78"
             column="5"/>
     </issue>
 
@@ -925,23 +781,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="97"
-            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;status_bar_color&quot;>#3c3c3c&lt;/color>"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/values/colors.xml"
-            line="99"
+            line="81"
             column="5"/>
     </issue>
 
@@ -957,7 +797,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="102"
+            line="84"
             column="5"/>
     </issue>
 
@@ -973,55 +813,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="105"
-            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;fallback_tintColor&quot;>#89000000&lt;/color>"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/values/colors.xml"
-            line="108"
-            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;suggestion_condition_background&quot;>#f2f2f2&lt;/color>"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/values/colors.xml"
-            line="111"
-            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;condition_card_background&quot;>#f8f8f8&lt;/color>"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/values/colors.xml"
-            line="112"
+            line="87"
             column="5"/>
     </issue>
 
@@ -1037,7 +829,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="115"
+            line="90"
             column="5"/>
     </issue>
 
@@ -1053,7 +845,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="116"
+            line="91"
             column="5"/>
     </issue>
 
@@ -1069,7 +861,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="117"
+            line="92"
             column="5"/>
     </issue>
 
@@ -1085,7 +877,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="118"
+            line="93"
             column="5"/>
     </issue>
 
@@ -1101,7 +893,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="119"
+            line="94"
             column="5"/>
     </issue>
 
@@ -1117,7 +909,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="120"
+            line="95"
             column="5"/>
     </issue>
 
@@ -1133,7 +925,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="121"
+            line="96"
             column="5"/>
     </issue>
 
@@ -1149,7 +941,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="122"
+            line="97"
             column="5"/>
     </issue>
 
@@ -1165,7 +957,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="123"
+            line="98"
             column="5"/>
     </issue>
 
@@ -1181,7 +973,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="124"
+            line="99"
             column="5"/>
     </issue>
 
@@ -1197,7 +989,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="125"
+            line="100"
             column="5"/>
     </issue>
 
@@ -1213,7 +1005,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="126"
+            line="101"
             column="5"/>
     </issue>
 
@@ -1229,7 +1021,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="127"
+            line="102"
             column="5"/>
     </issue>
 
@@ -1245,7 +1037,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="128"
+            line="103"
             column="5"/>
     </issue>
 
@@ -1261,7 +1053,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="129"
+            line="104"
             column="5"/>
     </issue>
 
@@ -1277,7 +1069,23 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="130"
+            line="105"
+            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_card_stroke_color&quot;>#1f000000&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/values/colors.xml"
+            line="106"
             column="5"/>
     </issue>
 
@@ -1293,7 +1101,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="134"
+            line="110"
             column="5"/>
     </issue>
 
@@ -1309,7 +1117,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="139"
+            line="115"
             column="5"/>
     </issue>
 
@@ -1325,7 +1133,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="140"
+            line="116"
             column="5"/>
     </issue>
 
@@ -1341,7 +1149,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="141"
+            line="117"
             column="5"/>
     </issue>
 
@@ -1357,7 +1165,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="142"
+            line="118"
             column="5"/>
     </issue>
 
@@ -1373,7 +1181,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="143"
+            line="119"
             column="5"/>
     </issue>
 
@@ -1389,7 +1197,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="144"
+            line="120"
             column="5"/>
     </issue>
 
@@ -1405,7 +1213,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="147"
+            line="123"
             column="5"/>
     </issue>
 
@@ -1421,7 +1229,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="148"
+            line="124"
             column="5"/>
     </issue>
 
@@ -1437,7 +1245,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="149"
+            line="125"
             column="5"/>
     </issue>
 
@@ -1453,7 +1261,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="150"
+            line="126"
             column="5"/>
     </issue>
 
@@ -1469,7 +1277,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="151"
+            line="127"
             column="5"/>
     </issue>
 
@@ -1801,6 +1609,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_accessibility_background&quot; />"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/drawable/ic_homepage_accessibility.xml"
+            line="23"
+            column="17"/>
+    </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_accounts_background&quot; />"
         errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -2009,6 +1833,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_support_background&quot; />"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/drawable/ic_homepage_support.xml"
+            line="23"
+            column="17"/>
+    </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_system_background&quot; />"
         errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -2621,7 +2461,7 @@
         errorLine2="                                   ~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/strings.xml"
-            line="5902"
+            line="5805"
             column="36"/>
     </issue>
 
@@ -2637,7 +2477,7 @@
         errorLine2="                                        ^">
         <location
             file="res/values/styles.xml"
-            line="179"
+            line="174"
             column="41"/>
     </issue>
 
@@ -2653,7 +2493,7 @@
         errorLine2="                                           ^">
         <location
             file="res/values/styles.xml"
-            line="448"
+            line="422"
             column="44"/>
     </issue>
 
@@ -2669,7 +2509,7 @@
         errorLine2="                                           ^">
         <location
             file="res/values/styles.xml"
-            line="454"
+            line="428"
             column="44"/>
     </issue>
 
@@ -2685,7 +2525,7 @@
         errorLine2="                                           ^">
         <location
             file="res/values/styles.xml"
-            line="455"
+            line="429"
             column="44"/>
     </issue>
 
@@ -2697,6 +2537,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="        &lt;item name=&quot;strokeColor&quot;>@color/homepage_card_stroke_color&lt;/item>"
+        errorLine2="                                 ^">
+        <location
+            file="res/values/styles.xml"
+            line="464"
+            column="34"/>
+    </issue>
+
+    <issue
+        id="HardCodedColor"
+        severity="Error"
+        message="Avoid using hardcoded color"
+        category="Correctness"
+        priority="4"
+        summary="Using hardcoded color"
+        explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.&#xA;This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
         errorLine1="        &lt;item name=&quot;batteryGoodColor&quot;>@color/battery_good_color_light&lt;/item>"
         errorLine2="                                      ^">
         <location
@@ -3089,68 +2945,4 @@
             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="            android:background=&quot;@color/divider_color&quot;"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/layout-sw600dp-land/wifi_settings_for_setup_wizard_xl.xml"
-            line="71"
-            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:background=&quot;@color/divider_color&quot;"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/layout-sw600dp/wifi_settings_for_setup_wizard_xl.xml"
-            line="71"
-            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:background=&quot;@color/divider_color&quot; />  &lt;!-- TODO: fix this -->"
-        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/layout-sw600dp-land/wifi_settings_for_setup_wizard_xl.xml"
-            line="178"
-            column="9"/>
-    </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:background=&quot;@color/divider_color&quot; />  &lt;!-- TODO: fix this -->"
-        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/layout-sw600dp/wifi_settings_for_setup_wizard_xl.xml"
-            line="178"
-            column="9"/>
-    </issue>
-
 </issues>
diff --git a/res/drawable/ic_launcher_settings.xml b/res/drawable/ic_launcher_settings.xml
index cdf9e35..9ede59d 100644
--- a/res/drawable/ic_launcher_settings.xml
+++ b/res/drawable/ic_launcher_settings.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
-    <background android:drawable="@*android:color/accent_device_default_light"/>
+    <background android:drawable="@color/icon_launcher_setting_color"/>
     <foreground android:drawable="@mipmap/ic_launcher_settings"/>
 </adaptive-icon>
diff --git a/res/layout/layout_preference_frame.xml b/res/drawable/settings_panel_background.xml
similarity index 61%
copy from res/layout/layout_preference_frame.xml
copy to res/drawable/settings_panel_background.xml
index eec3d7a..36c58e0 100644
--- a/res/layout/layout_preference_frame.xml
+++ b/res/drawable/settings_panel_background.xml
@@ -1,5 +1,5 @@
-<!--
-     Copyright (C) 2015 The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
@@ -13,6 +13,10 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content" />
+
+<inset xmlns:android="http://schemas.android.com/apk/res/android" android:inset="4dp">
+    <shape android:shape="rectangle">
+        <corners android:radius="8dp" />
+        <solid android:color="?android:attr/colorBackground" />
+    </shape>
+</inset>
\ No newline at end of file
diff --git a/res/layout-sw600dp-land/wifi_settings_for_setup_wizard_xl.xml b/res/layout-sw600dp-land/wifi_settings_for_setup_wizard_xl.xml
deleted file mode 100644
index 70d868a..0000000
--- a/res/layout-sw600dp-land/wifi_settings_for_setup_wizard_xl.xml
+++ /dev/null
@@ -1,228 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 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.
-  -->
-
-<RelativeLayout
-    android:id="@+id/layout_root"
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="horizontal"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent"
-    android:paddingTop="60dip"
-    android:paddingStart="@dimen/screen_margin_sides"
-    android:paddingEnd="@dimen/screen_margin_sides"
-    android:paddingBottom="0dip" >
-
-    <FrameLayout
-        android:id="@+id/top_padding_layout"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_alignParentTop="true">
-        <!-- Set to gone when software keyboard appears -->
-        <View
-             android:id="@+id/top_padding"
-             android:layout_width="match_parent"
-             android:layout_height="94dip" />
-    </FrameLayout>
-
-    <TextView
-        android:id="@+id/wifi_setup_title"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:minHeight="48dip"
-        android:layout_alignParentStart="true"
-        android:layout_centerVertical="true"
-        android:layout_marginStart="16dip"
-        android:layout_below="@id/top_padding_layout"
-        android:textSize="32dip"
-        android:textColor="@color/title_color"
-        android:text="@string/wifi_setup_title"
-        android:gravity="bottom"/>
-
-    <!-- Divider -->
-    <FrameLayout
-        android:id="@+id/top_divider"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/wifi_setup_title">
-        <ProgressBar
-            android:id="@+id/scanning_progress_bar"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            style="?android:attr/progressBarStyleHorizontal" />
-        <View
-            android:id="@+id/top_divider_no_progress"
-            android:layout_width="match_parent"
-            android:layout_height="3dip"
-            android:layout_marginTop="6dip"
-            android:layout_marginBottom="0dip"
-            android:background="@color/divider_color"
-            android:visibility="gone" />
-    </FrameLayout>
-
-    <!-- Dummy view to have the left edge of following Views.
-         @id/content needs to have layout_width="match_parent" to accommodate
-         every views inside @id/wifi_config_ui while sometimes config ui becomes
-         very wide. -->
-    <View
-        android:id="@+id/dummy_for_left_edge"
-        android:layout_width="716dip"
-        android:layout_height="0dip"
-        android:layout_below="@id/top_divider"
-        android:layout_centerHorizontal="true" />
-
-    <RelativeLayout
-        android:id="@+id/content"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/top_divider"
-        android:layout_alignStart="@id/dummy_for_left_edge"
-        android:layout_centerHorizontal="true">
-
-        <!-- Padding for @id/content shown when keyboard isn't available -->
-        <View
-            android:id="@+id/content_padding"
-            android:layout_width="match_parent"
-            android:layout_height="370dip"
-            android:visibility="gone" />
-
-        <FrameLayout
-            android:id="@+id/wifi_settings_fragment_layout"
-            android:layout_width="716dip"
-            android:layout_height="370dip">
-            <fragment
-                class="com.android.settings.wifi.WifiSettings"
-                android:id="@+id/wifi_setup_fragment"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content" />
-        </FrameLayout>
-        <FrameLayout
-            android:id="@+id/wifi_config_ui"
-            android:layout_width="wrap_content"
-            android:minWidth="406dip"
-            android:layout_height="wrap_content"
-            android:minHeight="160dip"
-            android:layout_marginTop="10dip"
-            android:layout_alignParentStart="true"
-            android:visibility="gone" />
-        <LinearLayout
-            android:id="@+id/connecting_status_layout"
-            android:layout_width="716dip"
-            android:layout_height="360dip"
-            android:layout_marginTop="10dip"
-            android:visibility="gone">
-            <TextView
-                android:id="@+id/connecting_status"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:lineSpacingExtra="10dip"
-                android:textAppearance="?android:attr/textAppearanceMedium"
-                android:textSize="20sp" />
-        </LinearLayout>
-
-    </RelativeLayout>
-
-    <!-- Shown when @id/top_divider is using View instead of ProgressBar.
-         We need this padding to place @id/bottom_divider at the same position
-         regardless of @id/top_divider state.
-
-         Detail:
-         When ProgressBar is used in @id/top_divider, we have 7dip implicit
-         padding inside the ProgressBar object, while we don't have the
-         padding when View is used. As a result, all the objects below it
-         including @id/bottom_divider moves up/down in 7dip between those
-         two states. It is WAI for @id/content, but not for the others.
-
-         Note that we cannot let bottom dividers/buttons align with parent's
-         bottom edge using layout_alignParentBottom="true", since we'd like
-         to control bottom margin between @id/bottom_buttons and the edge
-         depending on software keyboard is shown/hidden.
-
-         We need to enclose @id/bottom_padding with @id/bottom_padding_layout
-         to let @id/bottom_divider use android:layout_below.
-         android:visibility="gone" really let the object go away,
-         causing @id/bottom_divider to lose the target for android:layout_below.
-      -->
-    <FrameLayout
-        android:id="@+id/bottom_padding_layout"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/content">
-        <View
-             android:id="@+id/bottom_padding"
-             android:layout_width="match_parent"
-             android:layout_height="7dip"
-             android:visibility="gone" />
-    </FrameLayout>
-
-    <!-- Divider -->
-    <View
-        android:id="@+id/bottom_divider"
-        android:layout_width="match_parent"
-        android:layout_height="3dip"
-        android:layout_marginBottom="16dip"
-        android:layout_below="@id/bottom_padding_layout"
-        android:layout_alignStart="@id/content"
-        android:background="@color/divider_color" />  <!-- TODO: fix this -->
-
-    <RelativeLayout
-        android:id="@+id/bottom_buttons"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/bottom_divider"
-        android:layout_alignStart="@id/bottom_divider"
-        android:layout_alignParentEnd="true"
-        android:layout_alignParentBottom="true">
-
-        <Button
-            android:id="@+id/wifi_setup_add_network"
-            style="@style/setup_wizard_button"
-            android:layout_alignParentStart="true"
-            android:text="@string/wifi_setup_add_network"
-            android:enabled="false" />
-
-        <LinearLayout
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_alignParentEnd="true"
-            android:orientation="horizontal">
-
-            <!-- This misleading name is for keeping consistency between non-XL
-                 layouts -->
-            <Button android:id="@+id/wifi_setup_cancel"
-                    style="@style/setup_wizard_button"
-                    android:text="@string/wifi_setup_back"
-                    android:visibility="gone" />
-
-            <Button android:id="@+id/wifi_setup_connect"
-                    style="@style/setup_wizard_button"
-                    android:layout_marginStart="16dip"
-                    android:text="@string/wifi_setup_connect"
-                    android:enabled="false"
-                    android:visibility="gone" />
-
-            <Button android:id="@+id/wifi_setup_refresh_list"
-                    style="@style/setup_wizard_button"
-                    android:layout_marginStart="16dip"
-                    android:text="@string/wifi_setup_refresh_list"
-                    android:enabled="false" />
-
-            <Button android:id="@+id/wifi_setup_skip_or_next"
-                    style="@style/setup_wizard_button"
-                    android:layout_marginStart="16dip"
-                    android:text="@string/wifi_setup_skip" />
-        </LinearLayout>
-    </RelativeLayout>
-</RelativeLayout>
diff --git a/res/layout-sw600dp/wifi_settings_for_setup_wizard_xl.xml b/res/layout-sw600dp/wifi_settings_for_setup_wizard_xl.xml
deleted file mode 100644
index 94833e8..0000000
--- a/res/layout-sw600dp/wifi_settings_for_setup_wizard_xl.xml
+++ /dev/null
@@ -1,238 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 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.
-  -->
-
-<RelativeLayout
-    android:id="@+id/layout_root"
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="horizontal"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent"
-    android:paddingTop="60dip"
-    android:paddingStart="@dimen/screen_margin_sides"
-    android:paddingEnd="@dimen/screen_margin_sides"
-    android:paddingBottom="0dip" >
-
-    <FrameLayout
-        android:id="@+id/top_padding_layout"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_alignParentTop="true">
-        <!-- Set to gone when software keyboard appears -->
-        <View
-             android:id="@+id/top_padding"
-             android:layout_width="match_parent"
-             android:layout_height="94dip" />
-    </FrameLayout>
-
-    <TextView
-        android:id="@+id/wifi_setup_title"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:minHeight="48dip"
-        android:layout_alignParentStart="true"
-        android:layout_centerVertical="true"
-        android:layout_marginStart="16dip"
-        android:layout_below="@id/top_padding_layout"
-        android:textSize="32dip"
-        android:textColor="@color/title_color"
-        android:text="@string/wifi_setup_title"
-        android:gravity="bottom"/>
-
-    <!-- Divider -->
-    <FrameLayout
-        android:id="@+id/top_divider"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/wifi_setup_title">
-        <ProgressBar
-            android:id="@+id/scanning_progress_bar"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            style="?android:attr/progressBarStyleHorizontal" />
-        <View
-            android:id="@+id/top_divider_no_progress"
-            android:layout_width="match_parent"
-            android:layout_height="3dip"
-            android:layout_marginTop="6dip"
-            android:layout_marginBottom="0dip"
-            android:background="@color/divider_color"
-            android:visibility="gone" />
-    </FrameLayout>
-
-    <!-- Dummy view to have the left edge of following Views.
-         @id/content needs to have layout_width="match_parent" to accommodate
-         every views inside @id/wifi_config_ui while sometimes config ui becomes
-         very wide. -->
-    <View
-        android:id="@+id/dummy_for_left_edge"
-        android:layout_width="716dip"
-        android:layout_height="0dip"
-        android:layout_below="@id/top_divider"
-        android:layout_centerHorizontal="true" />
-
-    <RelativeLayout
-        android:id="@+id/content"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/top_divider"
-        android:layout_alignStart="@id/dummy_for_left_edge"
-        android:layout_centerHorizontal="true">
-
-        <!-- Padding for @id/content shown when keyboard isn't available -->
-        <View
-            android:id="@+id/content_padding"
-            android:layout_width="match_parent"
-            android:layout_height="370dip"
-            android:visibility="gone" />
-
-        <FrameLayout
-            android:id="@+id/wifi_settings_fragment_layout"
-            android:layout_width="716dip"
-            android:layout_height="377dip">
-            <fragment
-                class="com.android.settings.wifi.WifiSettings"
-                android:id="@+id/wifi_setup_fragment"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content" />
-        </FrameLayout>
-        <FrameLayout
-            android:id="@+id/wifi_config_ui"
-            android:layout_width="wrap_content"
-            android:minWidth="406dip"
-            android:layout_height="wrap_content"
-            android:minHeight="160dip"
-            android:layout_marginTop="10dip"
-            android:layout_alignParentStart="true"
-            android:visibility="gone" />
-        <LinearLayout
-            android:id="@+id/connecting_status_layout"
-            android:layout_width="716dip"
-            android:layout_height="360dip"
-            android:layout_marginTop="10dip"
-            android:visibility="gone">
-            <TextView
-                android:id="@+id/connecting_status"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:lineSpacingExtra="10dip"
-                android:textAppearance="?android:attr/textAppearanceMedium"
-                android:textSize="20sp" />
-        </LinearLayout>
-
-    </RelativeLayout>
-
-    <!-- Shown when @id/top_divider is using View instead of ProgressBar.
-         We need this padding to place @id/bottom_divider at the same position
-         regardless of @id/top_divider state.
-
-         Detail:
-         When ProgressBar is used in @id/top_divider, we have 7dip implicit
-         padding inside the ProgressBar object, while we don't have the
-         padding when View is used. As a result, all the objects below it
-         including @id/bottom_divider moves up/down in 7dip between those
-         two states. It is WAI for @id/content, but not for the others.
-
-         Note that we cannot let bottom dividers/buttons align with parent's
-         bottom edge using layout_alignParentBottom="true", since we'd like
-         to control bottom margin between @id/bottom_buttons and the edge
-         depending on software keyboard is shown/hidden.
-
-         We need to enclose @id/bottom_padding with @id/bottom_padding_layout
-         to let @id/bottom_divider use android:layout_below.
-         android:visibility="gone" really let the object go away,
-         causing @id/bottom_divider to lose the target for android:layout_below.
-      -->
-    <FrameLayout
-        android:id="@+id/bottom_padding_layout"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/content">
-        <View
-             android:id="@+id/bottom_padding"
-             android:layout_width="match_parent"
-             android:layout_height="7dip"
-             android:visibility="gone" />
-    </FrameLayout>
-
-    <!-- Divider -->
-    <View
-        android:id="@+id/bottom_divider"
-        android:layout_width="match_parent"
-        android:layout_height="3dip"
-        android:layout_marginBottom="16dip"
-        android:layout_below="@id/bottom_padding_layout"
-        android:layout_alignStart="@id/content"
-        android:background="@color/divider_color" />  <!-- TODO: fix this -->
-
-    <LinearLayout
-        android:id="@+id/bottom_buttons"
-        android:orientation="vertical"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/bottom_divider"
-        android:layout_alignStart="@id/bottom_divider">
-
-        <RelativeLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_below="@id/bottom_divider"
-            android:layout_alignStart="@id/bottom_divider"
-            android:layout_alignParentEnd="true"
-            android:layout_alignParentBottom="true">
-
-            <Button
-                android:id="@+id/wifi_setup_add_network"
-                style="@style/setup_wizard_button"
-                android:layout_alignParentStart="true"
-                android:text="@string/wifi_setup_add_network"
-                android:enabled="false" />
-
-            <LinearLayout
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_alignParentEnd="true"
-                android:orientation="horizontal">
-
-                <!-- This misleading name is for keeping consistency between non-XL
-                     layouts -->
-                <Button android:id="@+id/wifi_setup_cancel"
-                        style="@style/setup_wizard_button"
-                        android:text="@string/wifi_setup_back"
-                        android:visibility="gone" />
-
-                <Button android:id="@+id/wifi_setup_connect"
-                        style="@style/setup_wizard_button"
-                        android:layout_marginStart="16dip"
-                        android:text="@string/wifi_setup_connect"
-                        android:enabled="false"
-                        android:visibility="gone" />
-
-                <Button android:id="@+id/wifi_setup_skip_or_next"
-                        style="@style/setup_wizard_button"
-                        android:layout_marginStart="16dip"
-                        android:text="@string/wifi_setup_skip" />
-            </LinearLayout>
-
-        </RelativeLayout>
-
-        <Button android:id="@+id/wifi_setup_refresh_list"
-                style="@style/setup_wizard_button"
-                android:layout_alignParentEnd="true"
-                android:text="@string/wifi_setup_refresh_list"
-                android:enabled="false" />
-
-    </LinearLayout>
-</RelativeLayout>
diff --git a/res/layout/homepage_condition_full_tile.xml b/res/layout/homepage_condition_full_tile.xml
index 415defc..4b12625 100644
--- a/res/layout/homepage_condition_full_tile.xml
+++ b/res/layout/homepage_condition_full_tile.xml
@@ -15,7 +15,7 @@
      limitations under the License.
 -->
 
-<androidx.cardview.widget.CardView
+<com.google.android.material.card.MaterialCardView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
@@ -71,4 +71,4 @@
 
     </LinearLayout>
 
-</androidx.cardview.widget.CardView>
+</com.google.android.material.card.MaterialCardView>
diff --git a/res/layout/homepage_condition_half_tile.xml b/res/layout/homepage_condition_half_tile.xml
index 0b7eec7..fb83389 100644
--- a/res/layout/homepage_condition_half_tile.xml
+++ b/res/layout/homepage_condition_half_tile.xml
@@ -15,7 +15,7 @@
      limitations under the License.
 -->
 
-<androidx.cardview.widget.CardView
+<com.google.android.material.card.MaterialCardView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="@dimen/homepage_condition_half_card_height"
@@ -65,4 +65,4 @@
 
     </LinearLayout>
 
-</androidx.cardview.widget.CardView>
\ No newline at end of file
+</com.google.android.material.card.MaterialCardView>
\ No newline at end of file
diff --git a/res/layout/homepage_condition_header.xml b/res/layout/homepage_condition_header.xml
index a440d7f..8f3a92c 100644
--- a/res/layout/homepage_condition_header.xml
+++ b/res/layout/homepage_condition_header.xml
@@ -15,7 +15,7 @@
   limitations under the License.
   -->
 
-<androidx.cardview.widget.CardView
+<com.google.android.material.card.MaterialCardView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
@@ -49,4 +49,4 @@
 
     </LinearLayout>
 
-</androidx.cardview.widget.CardView>
\ No newline at end of file
+</com.google.android.material.card.MaterialCardView>
\ No newline at end of file
diff --git a/res/layout/homepage_slice_tile.xml b/res/layout/homepage_slice_tile.xml
index dbdb91b..9165abc 100644
--- a/res/layout/homepage_slice_tile.xml
+++ b/res/layout/homepage_slice_tile.xml
@@ -15,7 +15,7 @@
      limitations under the License.
 -->
 
-<androidx.cardview.widget.CardView
+<com.google.android.material.card.MaterialCardView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
@@ -30,8 +30,6 @@
             android:id="@+id/slice_view"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_marginBottom="@dimen/homepage_card_vertical_margin"
-            android:layout_marginTop="@dimen/homepage_card_vertical_margin"
             android:paddingStart="@dimen/homepage_card_padding_start"
             android:paddingEnd="@dimen/homepage_card_padding_end"/>
 
@@ -72,4 +70,4 @@
             </LinearLayout>
         </LinearLayout>
     </ViewFlipper>
-</androidx.cardview.widget.CardView>
\ No newline at end of file
+</com.google.android.material.card.MaterialCardView>
\ No newline at end of file
diff --git a/res/layout/homepage_suggestion_tile.xml b/res/layout/homepage_suggestion_tile.xml
index 36ad45c..5d3a79c 100644
--- a/res/layout/homepage_suggestion_tile.xml
+++ b/res/layout/homepage_suggestion_tile.xml
@@ -15,7 +15,7 @@
   limitations under the License.
   -->
 
-<androidx.cardview.widget.CardView
+<com.google.android.material.card.MaterialCardView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/suggestion_card"
     android:layout_width="match_parent"
@@ -67,4 +67,4 @@
 
     </LinearLayout>
 
-</androidx.cardview.widget.CardView>
\ No newline at end of file
+</com.google.android.material.card.MaterialCardView>
\ No newline at end of file
diff --git a/res/layout/panel_layout.xml b/res/layout/panel_layout.xml
new file mode 100644
index 0000000..cbdd53f
--- /dev/null
+++ b/res/layout/panel_layout.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    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
+  -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/panel_parent_layout"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingLeft="24dp"
+        android:paddingRight="24dp"
+        android:paddingBottom="8dp"
+        android:layout_margin="4dp"
+        android:orientation="vertical">
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/two_action_buttons.xml b/res/layout/settings_action_buttons.xml
similarity index 71%
rename from res/layout/two_action_buttons.xml
rename to res/layout/settings_action_buttons.xml
index 2b4aa5d..56e1a36 100644
--- a/res/layout/two_action_buttons.xml
+++ b/res/layout/settings_action_buttons.xml
@@ -20,7 +20,6 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:paddingStart="8dp"
-    android:paddingEnd="8dp"
     android:orientation="horizontal">
 
     <Button
@@ -28,19 +27,26 @@
         style="@style/SettingsActionButton"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
-        android:layout_weight="1"
-        android:paddingTop="20dp"
-        android:paddingBottom="20dp"/>
-    <Space
-        android:layout_width="8dp"
-        android:layout_height="wrap_content" />
+        android:layout_weight="1"/>
 
     <Button
         android:id="@+id/button2"
         style="@style/SettingsActionButton"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
-        android:layout_weight="1"
-        android:paddingTop="20dp"
-        android:paddingBottom="20dp"/>
+        android:layout_weight="1"/>
+
+    <Button
+        android:id="@+id/button3"
+        style="@style/SettingsActionButton"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"/>
+
+    <Button
+        android:id="@+id/button4"
+        style="@style/SettingsActionButton"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"/>
 </LinearLayout>
\ No newline at end of file
diff --git a/res/layout/settings_entity_header.xml b/res/layout/settings_entity_header.xml
deleted file mode 100644
index 5f5fe00..0000000
--- a/res/layout/settings_entity_header.xml
+++ /dev/null
@@ -1,105 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2017 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-
-<!-- Entity header -->
-<RelativeLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/entity_header"
-    style="@style/EntityHeader"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:orientation="horizontal">
-
-    <LinearLayout
-        android:id="@+id/entity_header_content"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_centerHorizontal="true"
-        android:gravity="center_horizontal"
-        android:orientation="vertical">
-
-        <ImageView
-            android:id="@+id/entity_header_icon"
-            android:layout_width="48dp"
-            android:layout_height="48dp"
-            android:scaleType="fitXY"
-            android:antialias="true"/>
-
-        <TextView
-            android:id="@+id/entity_header_title"
-            style="@style/TextAppearance.EntityHeaderTitle"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:singleLine="false"
-            android:ellipsize="marquee"
-            android:textDirection="locale"
-            android:layout_marginTop="8dp"/>
-
-        <TextView
-            android:id="@+id/install_type"
-            style="@style/TextAppearance.EntityHeaderSummary"
-            android:visibility="gone"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="2dp"/>
-
-        <TextView
-            android:id="@+id/entity_header_summary"
-            style="@style/TextAppearance.EntityHeaderSummary"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="2dp"/>
-
-        <TextView
-            android:id="@+id/entity_header_second_summary"
-            style="@style/TextAppearance.EntityHeaderSummary"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content" />
-
-    </LinearLayout>
-
-    <LinearLayout
-        android:id="@+id/entity_header_links"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:layout_centerVertical="true"
-        android:layout_alignParentEnd="true"
-        android:orientation="vertical">
-
-        <ImageButton
-            android:id="@android:id/button1"
-            style="?android:attr/actionOverflowButtonStyle"
-            android:layout_width="wrap_content"
-            android:layout_weight="1"
-            android:layout_height="0dp"
-            android:minWidth="@dimen/min_tap_target_size"
-            android:src="@null"
-            android:tint="?android:attr/colorAccent" />
-
-        <ImageButton
-            android:id="@android:id/button2"
-            style="?android:attr/actionOverflowButtonStyle"
-            android:layout_width="wrap_content"
-            android:layout_weight="1"
-            android:layout_height="0dp"
-            android:minWidth="@dimen/min_tap_target_size"
-            android:src="@null"
-            android:tint="?android:attr/colorAccent" />
-
-    </LinearLayout>
-
-</RelativeLayout>
diff --git a/res/layout/settings_homepage_container.xml b/res/layout/settings_homepage_container.xml
index 7a84e32..0223573 100644
--- a/res/layout/settings_homepage_container.xml
+++ b/res/layout/settings_homepage_container.xml
@@ -29,6 +29,7 @@
 
 
     <androidx.core.widget.NestedScrollView
+        android:id="@+id/main_content_scrollable_container"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         app:layout_behavior="@string/appbar_scrolling_view_behavior">
@@ -42,7 +43,9 @@
             <FrameLayout
                 android:id="@+id/contextual_cards_content"
                 android:layout_width="match_parent"
-                android:layout_height="wrap_content"/>
+                android:layout_height="wrap_content"
+                android:layout_marginStart="@dimen/homepage_card_side_margin"
+                android:layout_marginEnd="@dimen/homepage_card_side_margin"/>
 
             <FrameLayout
                 android:id="@+id/main_content"
diff --git a/res/layout/settings_main_dashboard.xml b/res/layout/settings_main_dashboard.xml
deleted file mode 100644
index 3994092..0000000
--- a/res/layout/settings_main_dashboard.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2014, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical">
-
-    <include layout="@layout/search_bar" />
-
-    <FrameLayout
-        android:id="@+id/main_content"
-        android:layout_height="match_parent"
-        android:layout_width="match_parent" />
-</LinearLayout>
diff --git a/res/layout/layout_preference_frame.xml b/res/layout/settings_panel.xml
similarity index 75%
rename from res/layout/layout_preference_frame.xml
rename to res/layout/settings_panel.xml
index eec3d7a..aec898c 100644
--- a/res/layout/layout_preference_frame.xml
+++ b/res/layout/settings_panel.xml
@@ -1,5 +1,5 @@
-<!--
-     Copyright (C) 2015 The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
@@ -14,5 +14,6 @@
      limitations under the License.
 -->
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content" />
+    android:id="@+id/main_content"
+    android:layout_height="match_parent"
+    android:layout_width="match_parent"/>
\ No newline at end of file
diff --git a/res/layout/wifi_dpp_add_device_fragment.xml b/res/layout/wifi_dpp_add_device_fragment.xml
new file mode 100644
index 0000000..03add62
--- /dev/null
+++ b/res/layout/wifi_dpp_add_device_fragment.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     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.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/root"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <include layout="@layout/wifi_dpp_fragment_header"/>
+
+    <ProgressBar
+      android:id="@+id/progress_bar"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:indeterminate="true"/>
+
+    <ImageView
+        android:id="@+id/wifi_ap_picture_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_gravity="center"/>
+
+    <TextView android:id="@+id/choose_different_network"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"/>
+
+    <include layout="@layout/wifi_dpp_fragment_footer"
+        android:gravity="center|bottom"/>
+
+</LinearLayout>
+
diff --git a/res/layout/wifi_dpp_choose_saved_wifi_network_fragment.xml b/res/layout/wifi_dpp_choose_saved_wifi_network_fragment.xml
new file mode 100644
index 0000000..a65cf3e
--- /dev/null
+++ b/res/layout/wifi_dpp_choose_saved_wifi_network_fragment.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     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.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/root"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <include layout="@layout/wifi_dpp_fragment_header"/>
+
+    <ListView android:id="@+id/saved_wifi_network_list"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"/>
+
+    <include layout="@layout/wifi_dpp_fragment_footer"
+        android:gravity="center|bottom"/>
+
+</LinearLayout>
+
diff --git a/res/layout/wifi_dpp_qrcode_generator_fragment.xml b/res/layout/wifi_dpp_qrcode_generator_fragment.xml
new file mode 100644
index 0000000..789b3a3
--- /dev/null
+++ b/res/layout/wifi_dpp_qrcode_generator_fragment.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     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.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/root"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <include layout="@layout/wifi_dpp_fragment_header"/>
+
+    <ImageView
+        android:id="@+id/barcode_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_gravity="center"/>
+
+</LinearLayout>
+
diff --git a/res/layout/wifi_dpp_qrcode_scanner_fragment.xml b/res/layout/wifi_dpp_qrcode_scanner_fragment.xml
index 130bb6d..a864f51 100644
--- a/res/layout/wifi_dpp_qrcode_scanner_fragment.xml
+++ b/res/layout/wifi_dpp_qrcode_scanner_fragment.xml
@@ -17,7 +17,6 @@
 
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:id="@+id/root"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
diff --git a/res/layout/zen_onboarding.xml b/res/layout/zen_onboarding.xml
index 33cdbdd..35b992d 100644
--- a/res/layout/zen_onboarding.xml
+++ b/res/layout/zen_onboarding.xml
@@ -47,7 +47,8 @@
                 android:id="@+id/zen_onboarding_new_setting_button"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:paddingHorizontal="8dp" />
+                android:paddingHorizontal="8dp"
+                android:minHeight="48dp"/>
 
             <LinearLayout
                 android:layout_width="match_parent"
@@ -83,7 +84,8 @@
                 android:id="@+id/zen_onboarding_current_setting_button"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:paddingHorizontal="8dp" />
+                android:paddingHorizontal="8dp"
+                android:minHeight="48dp"/>
 
             <LinearLayout
                 android:layout_width="match_parent"
diff --git a/res/values-night/colors.xml b/res/values-night/colors.xml
index 595f429..bc06f47 100644
--- a/res/values-night/colors.xml
+++ b/res/values-night/colors.xml
@@ -19,5 +19,7 @@
   <color name="switch_bar_background">#dadce0</color>
   <color name="switchbar_switch_track_tint">#82000000</color>
   <color name="switchbar_switch_thumb_tint">@android:color/black</color>
+  <color name="homepage_accessibility_background">#783BE5</color>
+  <color name="homepage_support_background">#3F5FBD</color>
 </resources>
 
diff --git a/res/values-sw600dp/styles.xml b/res/values-sw600dp/styles.xml
index b132f9f..27b31be 100644
--- a/res/values-sw600dp/styles.xml
+++ b/res/values-sw600dp/styles.xml
@@ -20,12 +20,4 @@
         <item name="android:windowNoTitle">true</item>
     </style>
 
-    <style name="setup_wizard_button">
-        <item name="android:layout_width">wrap_content</item>
-        <item name="android:minWidth">208dip</item>
-        <item name="android:layout_height">48dip</item>
-        <item name="android:textAppearance">?android:attr/textAppearanceMedium</item>
-        <item name="android:textSize">20sp</item>
-    </style>
-
 </resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 34885b4..d10cb5f 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -19,8 +19,6 @@
     <color name="red">#F00</color>
     <color name="blue">#00F</color>
 
-    <color name="material_empty_color_light">#FFCED7DB</color>
-
     <color name="bluetooth_dialog_text_color">#8a000000</color>
 
     <color name="crypt_keeper_clock_background">#ff9a9a9a</color>
@@ -30,7 +28,6 @@
 
     <color name="divider_color">#20ffffff</color>
     <color name="title_color">@android:color/holo_blue_light</color>
-    <color name="setup_lock_pattern_view_regular_color_dark">#ffbdbdbd</color>
     <color name="setup_lock_pattern_view_regular_color_light">@color/lock_pattern_view_regular_color</color>
     <color name="setup_lock_pattern_view_success_color_dark">#ff84ffff</color>
     <color name="setup_lock_pattern_view_success_color_light">@color/suw_color_accent_light</color>
@@ -52,25 +49,13 @@
     <color name="running_processes_system_ram">#ff384248</color>
     <color name="running_processes_free_ram">#ffced7db</color>
 
-    <color name="wifi_divider">#ffe0e0e0</color>
     <color name="sim_noitification">@*android:color/accent_device_default_light</color>
 
     <color name="confirm_device_credential_transparent_black">#60000000</color>
-    <color name="voice_interaction_highlight">#33b5e5</color>
-
-    <color name="memory_normal">#ff009587</color>
-    <color name="memory_moderate">#ffF3B300</color>
-    <color name="memory_low">#ffff9700</color>
-    <color name="memory_critical">#ffff5621</color>
-
-    <color name="memory_avg_use">#ff384248</color>
 
     <!-- Accent color that matches the settings launcher icon -->
     <color name="icon_accent">#ffabffec</color>
 
-    <color name="importance_icon_tint">#8a000000</color>
-    <color name="importance_disabled_tint">#4d000000</color>
-
     <!-- Accessibility SUW colors -->
     <color name="material_blue_500">#4285F4</color>
     <color name="material_blue_700">#3367D6</color>
@@ -78,7 +63,6 @@
     <color name="material_grey_200">#ffffff</color>
     <color name="switch_bar_background">#ff80868B</color>
 
-
     <color name="message_text_incoming">#ffffffff</color>
     <color name="message_text_outgoing">#ff323232</color>
     <color name="timestamp_text_outgoing">#99323232</color>
@@ -96,21 +80,12 @@
     <!-- Gestures settings -->
     <color name="gestures_setting_background_color">#ffffff</color>
 
-    <color name="status_bar_color">#3c3c3c</color>
-
     <!-- Color for the background of the shortcut icons.-->
     <color name="shortcut_background">#fff5f5f5</color>
 
     <!-- Color for preference icons on the Wifi Network Details page -->
     <color name="wifi_details_icon_color">#8A000000</color>
 
-    <!-- The fallback color for tinting icons. Only used when colorControlNormal is unavailable -->
-    <color name="fallback_tintColor">#89000000</color>
-
-    <!-- Suggestion/condition colors -->
-    <color name="suggestion_condition_background">#f2f2f2</color>
-    <color name="condition_card_background">#f8f8f8</color>
-
     <!-- Dashboard/homepage icon background colors -->
     <color name="homepage_network_background">#2196F3</color>
     <color name="homepage_connected_device_background">#72B70F</color>
@@ -128,6 +103,7 @@
     <color name="homepage_location_background">#2EC7DC</color>
     <color name="homepage_about_background">#9FA8DA</color>
     <color name="homepage_privacy_background">#5E97F6</color>
+    <color name="homepage_card_stroke_color">#1f000000</color>
     <!-- End of dashboard/homepage icon background colors -->
 
     <color name="switchbar_text_color">@android:color/white</color>
@@ -149,5 +125,8 @@
     <color name="face_anim_particle_color_3">#ff4caf50</color> <!-- Material Green 500 -->
     <color name="face_anim_particle_color_4">#fffdd835</color> <!-- Material Yellow 600 -->
     <color name="face_anim_particle_error">#ff9e9e9e</color> <!-- Material Gray 500 -->
+
+    <!-- launcher icon color -->
+    <color name="icon_launcher_setting_color">@*android:color/accent_device_default_light</color>
 </resources>
 
diff --git a/res/values/config.xml b/res/values/config.xml
index d487f46..edd948f7 100755
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -150,4 +150,19 @@
     <string name="config_settingsintelligence_package_name" translatable="false">
         com.android.settings.intelligence
     </string>
+
+    <!-- Settings intelligence interaction log intent action -->
+    <string name="config_settingsintelligence_log_action" translatable="false"></string>
+
+    <!-- Emergency app package name -->
+    <string name="config_emergency_package_name" translatable="false">
+        com.android.emergency
+    </string>
+    <!-- Emergency app intent action -->
+    <string name="config_emergency_intent_action" translatable="false">
+        android.settings.EDIT_EMERGENCY_INFO
+    </string>
+
+    <!-- Email address for the homepage contextual cards feedback -->
+    <string name="config_contextual_card_feedback_email" translatable="false"></string>
 </resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 8f44c69..f55ef10 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -327,10 +327,8 @@
 
     <!-- Homepage cards size and padding -->
     <dimen name="homepage_card_icon_size">24dp</dimen>
-    <dimen name="homepage_card_corner_radius">8dp</dimen>
-    <dimen name="homepage_card_elevation">2dp</dimen>
-    <dimen name="homepage_card_vertical_margin">4dp</dimen>
-    <dimen name="homepage_card_side_margin">8dp</dimen>
+    <dimen name="homepage_card_vertical_margin">8dp</dimen>
+    <dimen name="homepage_card_side_margin">4dp</dimen>
     <dimen name="homepage_card_padding_start">16dp</dimen>
     <dimen name="homepage_card_padding_end">16dp</dimen>
 
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 830aa82..ceed0fe 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -4131,7 +4131,6 @@
     <!-- Manage applications, text for move error messages -->
     <string name="insufficient_storage">Not enough storage space.</string>
     <string name="does_not_exist">App doesn\u2019t exist.</string>
-    <string name="app_forward_locked">App is copy-protected.</string>
     <string name="invalid_location">Install location isn\u2019t valid.</string>
     <string name="system_package">System updates can\u2019t be installed on external media.</string>
     <!-- Error message shown when trying to move device administrators to external disks, such as SD card [CHAR_LIMIT=none] -->
@@ -4578,22 +4577,24 @@
     <!-- Summary for the accessibility preference for master mono. [CHAR LIMIT=50] -->
     <string name="accessibility_toggle_master_mono_summary">Combine channels when playing audio</string>
 
-    <!-- Title for accessibility preference to accessibility timeout. [CHAR LIMIT=35] -->
+    <!-- Option heading to leave the timeout requirement for accessibility users at its default level. [CHAR LIMIT=35] -->
     <string name="accessibility_timeout_default">Default</string>
-    <!-- Title for accessibility preference to accessibility timeout. [CHAR LIMIT=35] -->
+    <!-- Option heading to leave the timeout requirement for accessibility users at 10 secs. [CHAR LIMIT=35] -->
     <string name="accessibility_timeout_10secs">10 seconds</string>
-    <!-- Title for accessibility preference to accessibility timeout. [CHAR LIMIT=35] -->
+    <!-- Option heading to leave the timeout requirement for accessibility users at 30 secs. [CHAR LIMIT=35] -->
     <string name="accessibility_timeout_30secs">30 seconds</string>
-    <!-- Title for accessibility preference to accessibility timeout. [CHAR LIMIT=35] -->
+    <!-- Option heading to leave the timeout requirement for accessibility users at 1 min. [CHAR LIMIT=35] -->
     <string name="accessibility_timeout_1min">1 minute</string>
-    <!-- Title for accessibility preference to accessibility timeout. [CHAR LIMIT=35] -->
+    <!-- Option heading to leave the timeout requirement for accessibility users at 2 mins. [CHAR LIMIT=35] -->
     <string name="accessibility_timeout_2mins">2 minutes</string>
-    <!-- Title for accessibility preference to accessibility message_timeout. [CHAR LIMIT=35] -->
-    <string name="accessibility_accessibility_content_timeout_preference_title">Content Timeout</string>
-    <!-- Title for accessibility preference to accessibility message_timeout. [CHAR LIMIT=35] -->
-    <string name="accessibility_accessibility_control_timeout_preference_title">Control Timeout</string>
-    <!-- Title for accessibility preference to accessibility message_timeout. [CHAR LIMIT=NONE] -->
-    <string name="accessibility_accessibility_timeout_preference_summary">Choose how long it takes before automatically disappearing messages go away.\nSome apps may not support this setting yet.</string>
+    <!-- Title for accessibility preference to accessibility timeout. [CHAR LIMIT=35] -->
+    <string name="accessibility_content_timeout_preference_title">Time to read</string>
+    <!-- Title for accessibility preference to accessibility timeout. [CHAR LIMIT=35] -->
+    <string name="accessibility_control_timeout_preference_title">Time to take action</string>
+    <!-- Descriptive text for accessibility preference to accessibility content timeout. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_content_timeout_preference_summary">Choose how much time you want to read and take action on messages that automatically go away.\n\nSupport for this setting is up to each app.</string>
+    <!-- Descriptive text for accessibility preference to accessibility control timeout. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_control_timeout_preference_summary">Choose how long to show messages that ask you to take action, but are visible only temporarily.\n\nNot all apps support this setting.</string>
 
     <!-- Title for accessibility preference to choose long-press delay i.e. timeout before it is detected. [CHAR LIMIT=35] -->
     <string name="accessibility_long_press_timeout_preference_title">Touch &amp; hold delay</string>
@@ -5424,9 +5425,9 @@
     <string name="battery_saver_turn_on_automatically_pct">at <xliff:g id="percent">%1$s</xliff:g> battery</string>
 
     <!-- [CHAR_LIMIT=40] Battery percentage: Title -->
-    <string name="battery_percentage">Battery percentage</string>
+    <string name="battery_info">Battery Information</string>
     <!-- [CHAR_LIMIT=NONE] Battery percentage: Description for preference -->
-    <string name="battery_percentage_description">Show battery percentage in status bar</string>
+    <string name="battery_info_description">Show percentage and time left before charge is needed</string>
 
     <!-- Process Stats strings -->
     <skip />
@@ -5720,116 +5721,14 @@
     <!-- Message displayed to let the user know that some of the options are disabled by admin. [CHAR LIMIT=NONE] -->
     <string name="admin_disabled_other_options">Other options are disabled by your admin</string>
     <string name="admin_more_details">More details</string>
-
-    <string name="sound_category_sound_title">General</string>
     <string name="notification_log_title">Notification log</string>
 
     <!-- Category title for phone call's ringtone and vibration settings in the Sound Setting.
          [CHAR LIMIT=40] -->
     <string name="sound_category_call_ringtone_vibrate_title">Call ringtone &amp; vibrate</string>
-
-    <!-- Category title for system-wide notification and feedback settings in the Sound Setting.
-         [CHAR LIMIT=40] -->
-    <string name="sound_category_system_title">System</string>
-
-    <!-- Wifi Setup For Setup Wizard with XL screen -->
-    <!-- Title shown in Wifi Setup Wizard with XL screen -->
-    <string name="wifi_setup_title">Wi\u2011Fi setup</string>
-    <!-- Title shown in Wifi Setup Wizard with XL screen when
-         a user is configuring password for a network.
-         The argument should be the name of the network.
-         [CHAR LIMIT=50] -->
-    <string name="wifi_setup_title_editing_network">Connect to Wi\u2011Fi network <xliff:g id="network_name" example="Happy Mobile">%s</xliff:g></string>
-    <!-- Title shown in Wifi Setup For Setup Wizard with XL screen when
-         the device is connecting a network the user specified.
-         The argument should be the name of the network.
-         [CHAR LIMIT=50] -->
-    <string name="wifi_setup_title_connecting_network">Connecting to Wi\u2011Fi network <xliff:g id="network_name" example="Happy Mobile">%s</xliff:g>\u2026</string>
-    <!-- Title shown in Wifi Setup For Setup Wizard with XL screen when
-         the device successfully connected to a network the user specified.
-         The argument should be the name of the network.
-         [CHAR LIMIT=50] -->
-    <string name="wifi_setup_title_connected_network">Connected to Wi\u2011Fi network <xliff:g id="network_name" example="Happy Mobile">%s</xliff:g></string>
-    <!-- Title shown in Wifi Setup For Setup Wizard with XL screen when
-         a user is adding a network.
-         [CHAR LIMIT=50] -->
-    <string name="wifi_setup_title_add_network">Add a network</string>
-    <!-- Text message shown when Wifi is not connected.
-         Used in Wifi Setup For Setup Wizard with XL screen. -->
-    <string name="wifi_setup_not_connected">Not connected</string>
-    <!-- Button message shown on the button adding manual setting.
-         Used in Wifi Setup For Setup Wizard with XL screen. -->
-    <string name="wifi_setup_add_network">Add network</string>
-    <!-- Button message shown on the button refreshing a list of network.
-         Used in Wifi Setup For Setup Wizard with XL screen. -->
-    <string name="wifi_setup_refresh_list">Refresh list</string>
-    <!-- Button message shown on the button enabling users skip Wifi Setup.
-         Used in Wifi Setup For Setup Wizard with XL screen. [CHAR LIMIT=10] -->
-    <string name="wifi_setup_skip">Skip</string>
-    <!-- Button message shown on the button enabling users go the next step.
-         Used in Wifi Setup For Setup Wizard with XL screen. [CHAR LIMIT=10] -->
-    <string name="wifi_setup_next">Next</string>
-    <!-- Button label to go back to previous screen. Used in SetupWizard for
-      XLarge screen [CHAR LIMIT=10] -->
-    <string name="wifi_setup_back">Back</string>
     <!-- Button label to show detailed dialog for a selected Wi-Fi settings.
          Used in SetupWizard for XLarge screen [CHAR LIMIT=20] -->
     <string name="wifi_setup_detail">Network details</string>
-    <!-- Button label to connect to a Wi-Fi network.
-         Used in SetupWizard for XLarge screen [CHAR LIMIT=10] -->
-    <string name="wifi_setup_connect">Connect</string>
-    <!-- Button label to delete a Wi-Fi network.
-         Used in SetupWizard for XLarge screen [CHAR LIMIT=10] -->
-    <string name="wifi_setup_forget">Forget</string>
-    <!-- Button label to save a Wi-Fi network configuration.
-         Used in SetupWizard for XLarge screen [CHAR LIMIT=10] -->
-    <string name="wifi_setup_save">Save</string>
-    <!-- Button label to dismiss the dialog.
-         Used in SetupWizard for XLarge screen [CHAR LIMIT=10] -->
-    <string name="wifi_setup_cancel">Cancel</string>
-
-    <!-- The message shown above available networks when the device is scanning
-         available networks [CHAR LIMIT=35] -->
-    <string name="wifi_setup_status_scanning">Scanning networks\u2026</string>
-    <!-- Message shown above available network when there's no connected network.
-         Used in Wifi Setup For Setup Wizard with XL screen. -->
-    <string name="wifi_setup_status_select_network">Tap a network to connect to it</string>
-    <!-- Message shown above available networks when a user clicked one of available
-         networks and the UI is showing one possible existing network.
-         Used in Wifi Setup. -->
-    <string name="wifi_setup_status_existing_network">Connect to existing network</string>
-    <!-- Message shown above available networks when a user clicked one of available
-         networks and the network doesn't require configuration (e.g. password)
-         Used in Wifi Setup with XL screen. [CHAR LIMIT=35] -->
-    <string name="wifi_setup_status_unsecured_network">Connect to unsecured network</string>
-    <!-- Message shown above available networks when a user clicked one of available
-         networks and the UI is prompting the user to edit the network configuration
-         if needed. Used in Wifi Setup with XL screen. [CHAR LIMIT=35] -->
-    <string name="wifi_setup_status_edit_network">Type network configuration</string>
-    <!-- The message shown above available networks when a user clicked "Add network"
-         button. Used in Wifi Setup For Setup Wizard with XL screen. [CHAR LIMIT=35] -->
-    <string name="wifi_setup_status_new_network">Connect to new network</string>
-    <!-- The message shown above available networks when a user clicked one of available
-         networks or created another profile and he/she is waiting for the connection
-         is established.
-         Used in Wifi Setup For Setup Wizard with XL screen. [CHAR LIMIT=35] -->
-    <string name="wifi_setup_status_connecting">Connecting\u2026</string>
-    <!-- The message shown above available networks when connection is established,
-         letting a user to proceed to the next step of the SetupWizard.
-         Used in Wifi Setup For Setup Wizard with XL screen. [CHAR LIMIT=35] -->
-    <string name="wifi_setup_status_proceed_to_next">Go to the next step</string>
-    <!-- The message shown above available networks when a user clicked a network secured by
-         EAP. We don't allow the user to connect it.
-         Used in Wifi Setup For Setup Wizard with XL screen. [CHAR LIMIT=35] -->
-    <string name="wifi_setup_status_eap_not_supported">EAP isn\u2019t supported.</string>
-    <!-- Message shown when users select EAP in Wi-Fi settings for SetupWizard,
-         saying EAP can't be configured in SetupWizard flow.
-         [CHAR LIMIT=NONE] -->
-    <string name="wifi_setup_eap_not_supported">You can\u2019t configure an EAP Wi\u2011Fi connection during setup. After setup, you can do that in Settings &gt; Wireless &amp; networks.</string>
-    <!-- Message shown when the device is connecting a network [CHAR LIMIT=NONE] -->
-    <string name="wifi_setup_description_connecting">Connecting can take a few minutes\u2026</string>
-    <!-- Message shown when the device is connected to a network [CHAR LIMIT=NONE] -->
-    <string name="wifi_setup_description_connected">Tap <b>Next</b> to continue with setup.\n\nTap <b>Back</b> to connect to a different Wi\u2011Fi network.</string>
 
     <!-- Do not translate. This is a stub which will be removed soon. -->
     <string name="time_zone_auto_stub" translatable="false">Select Time Zone</string>
@@ -9032,25 +8931,28 @@
     <string name="condition_expand_hide">Hide</string>
 
     <!-- Title of condition that hotspot is on [CHAR LIMIT=30] -->
-    <string name="condition_hotspot_title">Hotspot is on</string>
+    <string name="condition_hotspot_title">Hotspot</string>
 
     <!-- Summary of condition that hotspot is on [CHAR LIMIT=NONE] -->
-    <string name="condition_hotspot_summary">Portable Wi-Fi hotspot <xliff:g name="ap_name" example="AndroidAP">%1$s</xliff:g> is active, Wi-Fi for this device is turned off.</string>
+    <string name="condition_hotspot_summary"><xliff:g name="ap_name" example="AndroidAP">%1$s</xliff:g> on</string>
 
     <!-- Title of condition that airplane mode is on [CHAR LIMIT=30] -->
     <string name="condition_airplane_title">Airplane mode is on</string>
 
     <!-- Summary of condition that airplane mode is on [CHAR LIMIT=NONE] -->
-    <string name="condition_airplane_summary">When airplane mode is turned on, Wi\u2011Fi, Bluetooth, and mobile network are turned off. Wi\u2011Fi and Bluetooth can be turned back on.</string>
+    <string name="condition_airplane_summary">Networks unavailable</string>
 
     <!-- Title of condition that do not disturb is on [CHAR LIMIT=36] -->
     <string name="condition_zen_title">Do Not Disturb is on</string>
 
+    <!-- Summary of condition that do not disturb is on [CHAR LIMIT=36] -->
+    <string name="condition_zen_summary">Impacts what you hear and see</string>
+
     <!-- Title of condition that battery saver is on [CHAR LIMIT=30] -->
     <string name="condition_battery_title">Battery Saver is on</string>
 
     <!-- Summary of condition that battery saver is on [CHAR LIMIT=NONE] -->
-    <string name="condition_battery_summary">Battery Saver turns off some device features and restricts apps</string>
+    <string name="condition_battery_summary">Features restricted</string>
 
     <!-- Title of condition that cellular data is off [CHAR LIMIT=50] -->
     <string name="condition_cellular_title">Mobile data is off</string>
@@ -9059,10 +8961,10 @@
     <string name="condition_cellular_summary">Internet is available only via Wi-Fi</string>
 
     <!-- Title of condition that background data is off [CHAR LIMIT=30] -->
-    <string name="condition_bg_data_title">Data Saver is on</string>
+    <string name="condition_bg_data_title">Data Saver</string>
 
     <!-- Summary of condition that background data is off [CHAR LIMIT=NONE] -->
-    <string name="condition_bg_data_summary">Background data is only available via Wi-Fi. This may affect some apps or services when Wi-Fi is not available.</string>
+    <string name="condition_bg_data_summary">Features restricted</string>
 
     <!-- Title of condition that work mode is off [CHAR LIMIT=30] -->
     <string name="condition_work_title">Work profile is off</string>
@@ -9077,22 +8979,22 @@
     <string name="condition_device_muted_title" product="tablet">Device is muted</string>
 
     <!-- Title of condition that indicates device is muted [CHAR LIMIT=50] -->
-    <string name="condition_device_muted_title" product="default">Phone is muted</string>
+    <string name="condition_device_muted_title" product="default">Phone muted</string>
 
     <!-- Summary of condition that indicates device is muted -->
-    <string name="condition_device_muted_summary">Calls and notifications will be muted</string>
+    <string name="condition_device_muted_summary">For calls &amp; notifications</string>
 
     <!-- Title of condition that indicates device is set to vibrate [CHAR LIMIT=50] -->
     <string name="condition_device_vibrate_title" product="tablet">Device is set to vibrate</string>
 
     <!-- Title of condition that indicates device is muted [CHAR LIMIT=50] -->
-    <string name="condition_device_vibrate_title" product="default">Phone is set to vibrate</string>
+    <string name="condition_device_vibrate_title" product="default">Vibration only</string>
 
     <!-- Summary of condition that indicates device is set to vibrate -->
     <string name="condition_device_vibrate_summary" product="tablet">Calls and notifications will vibrate device</string>
 
     <!-- Summary of condition that indicates device is set to vibrate -->
-    <string name="condition_device_vibrate_summary" product="default">Calls and notifications will vibrate phone</string>
+    <string name="condition_device_vibrate_summary" product="default">For calls &amp; notifications</string>
 
     <!--  Night display: Title for the night display option Suggestion (renamed "Night Light" with title caps). [CHAR LIMIT=46] -->
     <string name="night_display_suggestion_title">Set Night Light schedule</string>
@@ -9104,7 +9006,7 @@
     <string name="condition_night_display_title">Night Light is on</string>
 
     <!-- Summary of condition that night display is on (renamed "Night Light" with title caps). [CHAR LIMIT=NONE] -->
-    <string name="condition_night_display_summary">Screen is tinted amber. This may help you fall asleep.</string>
+    <string name="condition_night_display_summary">Screen tinted amber</string>
 
     <!-- Summary for the condition section on the dashboard, representing number of conditions. [CHAR LIMIT=10] -->
     <string name="condition_summary" translatable="false"><xliff:g name="count" example="3">%1$d</xliff:g></string>
@@ -9990,6 +9892,11 @@
     <!-- UI debug setting: preference summary - describes the behavior of forcing full raw GNSS satellite measurements [CHAR LIMIT=NONE] -->
     <string name="enable_gnss_raw_meas_full_tracking_summary">Track all GNSS constellations and frequencies with no duty cycling</string>
 
+    <!-- UI debug setting: preference title - allow background activity starts [CHAR LIMIT=60] -->
+    <string name="allow_background_activity_starts">Allow background activity starts</string>
+    <!-- UI debug setting: preference summary - describes the behavior of allowing background activity starts [CHAR LIMIT=NONE] -->
+    <string name="allow_background_activity_starts_summary">Allows all background activity starts</string>
+
     <!-- UI debug setting: preference title - show all crash dialogs [CHAR LIMIT=60] -->
     <string name="show_first_crash_dialog">Always show crash dialog</string>
     <!-- UI debug setting: preference summary - describes the behavior of showing a dialog every time an app crashes [CHAR LIMIT=NONE] -->
@@ -10079,6 +9986,9 @@
     <!-- Title for HFP(hands free profile) output switch button in settings. -->
     <string name="take_call_on_title">Take call on</string>
 
+    <!-- Toast that appears when users tap an APN for which parameters cannot be viewed. [CHAR LIMIT=NONE] -->
+    <string name="cannot_change_apn_toast">This APN cannot be changed.</string>
+
     <!--  Title for battery Suggestion. (tablet) [CHAR LIMIT=46] -->
     <string name="battery_suggestion_title" product="tablet" >Improve tablet\'s battery life</string>
     <!--  Title for battery Suggestion. (device) [CHAR LIMIT=46] -->
@@ -10294,8 +10204,8 @@
     <!-- Available networks screen, summary when button disallowed due to permanent automatic mode [CHAR LIMIT=NONE] -->
     <string name="manual_mode_disallowed_summary">Unavailable when connected to <xliff:g id="carrier" example="verizon">%1$s</xliff:g></string>
 
-    <!-- Used for EmergencyInfoSlice slice helper class -->
-    <string name="emergency_info_contextual_card_summary" translatable="false">Medical info, emergency contacts</string>
+    <!-- Used for EmergencyInfoSlice slice helper class [CHAR LIMIT=NONE]-->
+    <string name="emergency_info_contextual_card_summary">Medical info, emergency contacts</string>
 
     <!-- See more items in contextual homepage [CHAR LIMIT=30]-->
     <string name="see_more">See more</string>
@@ -10317,6 +10227,12 @@
     <!-- Title for no connected devices in connected device slice. [CHAR LIMIT=NONE] -->
     <string name="no_connected_devices">No connected devices</string>
 
+    <!-- Default title for the settings panel [CHAR LIMIT=NONE] -->
+    <string name="settings_panel_title">Settings Panel</string>
+
+    <!-- Title for the Internet Connectivity dialog (settings panel) with Internet related settings [CHAR LIMIT=50] -->
+    <string name="internet_connectivity_panel_title">Internet Connectivity</string>
+
     <!-- UI debug setting: force desktop mode [CHAR LIMIT=50] -->
     <string name="force_desktop_mode">Force desktop mode</string>
     <!-- UI debug setting: force desktop mode summary [CHAR LIMIT=NONE] -->
@@ -10341,4 +10257,9 @@
 
     <!-- Summary for low storage slice. [CHAR LIMIT=NONE] -->
     <string name="low_storage_summary">Storage is low. <xliff:g id="percentage" example="54%">%1$s</xliff:g> used - <xliff:g id="free_space" example="32GB">%2$s</xliff:g> free</string>
-</resources>
\ No newline at end of file
+
+    <!-- Label for button in contextual card feedback dialog for users to send feedback [CHAR LIMIT=30] -->
+    <string name="contextual_card_feedback_send">Send feedback</string>
+    <!-- String for contextual card feedback dialog [CHAR LIMIT=NONE] -->
+    <string name="contextual_card_feedback_confirm_message">Would you like to give us feedback on this suggestion?</string>
+</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index cfc5fd3..1b311aa 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -164,11 +164,6 @@
         <item name="android:orientation">vertical</item>
     </style>
 
-    <style name="setup_wizard_button">
-        <item name="android:layout_width">wrap_content</item>
-        <item name="android:layout_height">wrap_content</item>
-    </style>
-
     <style name="ConfirmDeviceCredentialsAnimationStyle"
            parent="@*android:style/Animation.Material.Activity">
         <item name="android:activityOpenEnterAnimation">@anim/confirm_credential_open_enter</item>
@@ -331,23 +326,6 @@
         <item name="android:textColor">?android:attr/textColorSecondary</item>
     </style>
 
-    <style name="TextAppearance.EntityHeaderTitle"
-           parent="@android:style/TextAppearance.Material.Subhead">
-        <item name="android:fontFamily">@*android:string/config_headlineFontFamilyMedium</item>
-        <item name="android:textColor">?android:attr/textColorPrimary</item>
-        <item name="android:textSize">20sp</item>
-    </style>
-
-    <style name="TextAppearance.EntityHeaderSummary"
-           parent="@android:style/TextAppearance.Material.Body1">
-        <item name="android:textAlignment">viewStart</item>
-        <item name="android:textColor">?android:attr/textColorSecondary</item>
-        <item name="android:gravity">start</item>
-        <item name="android:singleLine">true</item>
-        <item name="android:ellipsize">marquee</item>
-        <item name="android:textSize">14sp</item>
-    </style>
-
     <style name="TextAppearance.ZenOnboardingButton">
         <item name="android:fontFamily">sans-serif-medium</item>
         <item name="android:textSize">14sp</item>
@@ -418,13 +396,6 @@
         <item name="android:progressDrawable">@drawable/ring_progress</item>
     </style>
 
-    <style name="EntityHeader">
-        <item name="android:background">?android:attr/colorPrimaryDark</item>
-        <item name="android:paddingTop">24dp</item>
-        <item name="android:paddingBottom">16dp</item>
-        <item name="android:paddingEnd">16dp</item>
-    </style>
-
     <style name="ActionPrimaryButton" parent="android:Widget.DeviceDefault.Button.Colored"/>
 
     <style name="ActionSecondaryButton" parent="android:Widget.DeviceDefault.Button"/>
@@ -432,6 +403,9 @@
     <style name="SettingsActionButton" parent="android:Widget.DeviceDefault.Button.Borderless.Colored">
         <item name="android:drawablePadding">4dp</item>
         <item name="android:drawableTint">@*android:color/btn_colored_borderless_text_material</item>
+        <item name="android:layout_marginEnd">8dp</item>
+        <item name="android:paddingTop">20dp</item>
+        <item name="android:paddingBottom">20dp</item>
     </style>
 
     <style name="LockPatternContainerStyle">
@@ -482,12 +456,13 @@
     </style>
 
     <style name="ContextualCardStyle">
-        <item name="android:layout_marginTop">@dimen/homepage_card_vertical_margin</item>
         <item name="android:layout_marginBottom">@dimen/homepage_card_vertical_margin</item>
         <item name="android:layout_marginStart">@dimen/homepage_card_side_margin</item>
         <item name="android:layout_marginEnd">@dimen/homepage_card_side_margin</item>
-        <item name="cardCornerRadius">@dimen/homepage_card_corner_radius</item>
-        <item name="cardElevation">@dimen/homepage_card_elevation</item>
+        <item name="cardCornerRadius">8dp</item>
+        <item name="cardElevation">0dp</item>
+        <item name="strokeColor">@color/homepage_card_stroke_color</item>
+        <item name="strokeWidth">1dp</item>
     </style>
 
     <style name="ConditionCardBorderlessButton"
diff --git a/res/values/themes.xml b/res/values/themes.xml
index b280482..873216d 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -200,4 +200,8 @@
         <item name="cardBackgroundColor">?android:attr/colorBackground</item>
     </style>
 
+    <style name="Theme.BottomDialog" parent="@*android:style/Theme.DeviceDefault.Settings.Dialog">
+        <item name="android:windowBackground">@drawable/settings_panel_background</item>
+    </style>
+
 </resources>
diff --git a/res/xml/accessibility_content_timeout_settings.xml b/res/xml/accessibility_content_timeout_settings.xml
index 51573c9..d450449 100644
--- a/res/xml/accessibility_content_timeout_settings.xml
+++ b/res/xml/accessibility_content_timeout_settings.xml
@@ -19,7 +19,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:key="accessibility_content_timeout_preference"
-    android:title="@string/accessibility_accessibility_content_timeout_preference_title"
+    android:title="@string/accessibility_content_timeout_preference_title"
     android:persistent="false" >
 
     <com.android.settings.widget.VideoPreference
@@ -32,7 +32,7 @@
         android:key="accessibility_content_timeout_summary"
         android:selectable="false"
         android:enabled="true"
-        android:summary="@string/accessibility_accessibility_timeout_preference_summary"
+        android:summary="@string/accessibility_content_timeout_preference_summary"
         android:persistent="false" />
 
     <com.android.settings.widget.RadioButtonPreference
diff --git a/res/xml/accessibility_control_timeout_settings.xml b/res/xml/accessibility_control_timeout_settings.xml
index 4559650..6d8e1d0 100644
--- a/res/xml/accessibility_control_timeout_settings.xml
+++ b/res/xml/accessibility_control_timeout_settings.xml
@@ -19,7 +19,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:key="accessibility_control_timeout_preference"
-    android:title="@string/accessibility_accessibility_control_timeout_preference_title"
+    android:title="@string/accessibility_control_timeout_preference_title"
     android:persistent="false" >
 
     <com.android.settings.widget.VideoPreference
@@ -32,7 +32,7 @@
         android:key="accessibility_control_timeout_summary"
         android:selectable="false"
         android:enabled="true"
-        android:summary="@string/accessibility_accessibility_timeout_preference_summary"
+        android:summary="@string/accessibility_control_timeout_preference_summary"
         android:persistent="false" />
 
     <com.android.settings.widget.RadioButtonPreference
diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml
index 1cd4a48..cc07ce1 100644
--- a/res/xml/accessibility_settings.xml
+++ b/res/xml/accessibility_settings.xml
@@ -75,8 +75,7 @@
         <Preference
             android:fragment="com.android.settings.accessibility.AccessibilityContentTimeoutPreferenceFragment"
             android:key="accessibility_content_timeout_preference_fragment"
-            android:title="@string/accessibility_accessibility_content_timeout_preference_title"
-            android:icon="@drawable/ic_accessibility_generic"
+            android:title="@string/accessibility_content_timeout_preference_title"
             android:persistent="false" />
 
     </PreferenceCategory>
@@ -111,8 +110,7 @@
         <Preference
             android:fragment="com.android.settings.accessibility.AccessibilityControlTimeoutPreferenceFragment"
             android:key="accessibility_control_timeout_preference_fragment"
-            android:title="@string/accessibility_accessibility_control_timeout_preference_title"
-            android:icon="@drawable/ic_accessibility_generic"
+            android:title="@string/accessibility_control_timeout_preference_title"
             android:persistent="false" />
 
         <Preference
diff --git a/res/xml/account_type_settings.xml b/res/xml/account_type_settings.xml
index 29f92ea..98a5e8b 100644
--- a/res/xml/account_type_settings.xml
+++ b/res/xml/account_type_settings.xml
@@ -19,7 +19,7 @@
         android:title="@string/account_settings_title"
         settings:keywords="@string/keywords_accounts">
 
-    <com.android.settings.applications.LayoutPreference
+    <com.android.settingslib.widget.LayoutPreference
         android:key="account_header"
         android:layout="@layout/settings_entity_header"
         android:selectable="false"
@@ -35,7 +35,7 @@
         android:icon="@drawable/ic_sync"
         android:order="200"/>
 
-    <com.android.settings.applications.LayoutPreference
+    <com.android.settingslib.widget.LayoutPreference
       android:key="remove_account"
       android:layout="@layout/remove_account_button"
       android:order="1000"
diff --git a/res/xml/app_info_settings.xml b/res/xml/app_info_settings.xml
index 1e320e4..8f99ce1 100644
--- a/res/xml/app_info_settings.xml
+++ b/res/xml/app_info_settings.xml
@@ -21,14 +21,14 @@
     android:key="installed_app_detail_settings_screen"
     settings:initialExpandedChildrenCount="6">
 
-    <com.android.settings.applications.LayoutPreference
+    <com.android.settingslib.widget.LayoutPreference
         android:key="header_view"
         android:layout="@layout/settings_entity_header"
         android:selectable="false"
         android:order="-10000"
         settings:allowDividerBelow="true"/>
 
-    <com.android.settings.applications.LayoutPreference
+    <com.android.settingslib.widget.LayoutPreference
         android:key="instant_app_buttons"
         android:layout="@layout/instant_app_buttons"
         android:selectable="false"
@@ -182,6 +182,7 @@
         android:selectable="false"
         android:order="9999"
         settings:controller="com.android.settings.applications.appinfo.AppVersionPreferenceController"
-        settings:allowDividerAbove="true" />
+        settings:allowDividerAbove="true"
+        settings:enableCopying="true"/>
 
 </PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/app_notification_settings.xml b/res/xml/app_notification_settings.xml
index 0056ef2..49d64a9 100644
--- a/res/xml/app_notification_settings.xml
+++ b/res/xml/app_notification_settings.xml
@@ -18,11 +18,11 @@
         xmlns:settings="http://schemas.android.com/apk/res-auto"
         android:key="app_notifications">
 
-    <com.android.settings.applications.LayoutPreference
+    <com.android.settingslib.widget.LayoutPreference
         android:key="pref_app_header"
         android:layout="@layout/settings_entity_header" />
 
-    <com.android.settings.applications.LayoutPreference
+    <com.android.settingslib.widget.LayoutPreference
         android:key="block"
         android:layout="@layout/styled_switch_bar" />
 
diff --git a/res/xml/app_storage_settings.xml b/res/xml/app_storage_settings.xml
index 14ad180..7036d27 100644
--- a/res/xml/app_storage_settings.xml
+++ b/res/xml/app_storage_settings.xml
@@ -34,7 +34,7 @@
         android:selectable="false"
         android:layout="@layout/horizontal_preference" />
 
-    <com.android.settings.applications.LayoutPreference
+    <com.android.settingslib.widget.LayoutPreference
         android:key="change_storage_button"
         android:selectable="false"
         android:layout="@layout/single_button_panel" />
@@ -78,7 +78,7 @@
         android:layout="@layout/preference_category_no_label"
         settings:allowDividerAbove="false"
         settings:allowDividerBelow="false">
-        <com.android.settings.applications.LayoutPreference
+        <com.android.settingslib.widget.LayoutPreference
             android:key="clear_uri_button"
             android:layout="@layout/single_button_panel"
             android:selectable="false" />
diff --git a/res/xml/bluetooth_device_details_fragment.xml b/res/xml/bluetooth_device_details_fragment.xml
index 01114b6..6449e4b 100644
--- a/res/xml/bluetooth_device_details_fragment.xml
+++ b/res/xml/bluetooth_device_details_fragment.xml
@@ -19,7 +19,7 @@
     xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:title="@string/device_details_title">
 
-    <com.android.settings.applications.LayoutPreference
+    <com.android.settingslib.widget.LayoutPreference
         android:key="bluetooth_device_header"
         android:layout="@layout/settings_entity_header"
         android:selectable="false"
diff --git a/res/xml/channel_notification_settings.xml b/res/xml/channel_notification_settings.xml
index 5afc70d..9e9e7a9 100644
--- a/res/xml/channel_notification_settings.xml
+++ b/res/xml/channel_notification_settings.xml
@@ -20,12 +20,12 @@
     android:key="channel_settings"
     android:title="@string/notification_channel_title" >
 
-    <com.android.settings.applications.LayoutPreference
+    <com.android.settingslib.widget.LayoutPreference
         android:key="pref_app_header"
         android:order="1"
         android:layout="@layout/settings_entity_header" />
 
-    <com.android.settings.applications.LayoutPreference
+    <com.android.settingslib.widget.LayoutPreference
         android:key="block"
         android:order="2"
         android:layout="@layout/styled_switch_bar" />
diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml
index cc724b8..a0f019d 100644
--- a/res/xml/development_settings.xml
+++ b/res/xml/development_settings.xml
@@ -485,6 +485,11 @@
             android:title="@string/background_check_pref" />
 
         <SwitchPreference
+            android:key="allow_background_activity_starts"
+            android:title="@string/allow_background_activity_starts"
+            android:summary="@string/allow_background_activity_starts_summary" />
+
+        <SwitchPreference
             android:key="show_first_crash_dialog"
             android:title="@string/show_first_crash_dialog"
             android:summary="@string/show_first_crash_dialog_summary" />
diff --git a/res/xml/display_settings.xml b/res/xml/display_settings.xml
index b0e362c..50a5649 100644
--- a/res/xml/display_settings.xml
+++ b/res/xml/display_settings.xml
@@ -44,7 +44,6 @@
         android:title="@string/auto_brightness_title"
         android:summary="@string/summary_placeholder"
         android:fragment="com.android.settings.display.AutoBrightnessSettings"
-        settings:searchable="false"
         settings:controller="com.android.settings.display.AutoBrightnessPreferenceController" />
 
     <com.android.settingslib.RestrictedPreference
diff --git a/res/xml/dream_fragment_overview.xml b/res/xml/dream_fragment_overview.xml
index a6214d1..e4c2eb5 100644
--- a/res/xml/dream_fragment_overview.xml
+++ b/res/xml/dream_fragment_overview.xml
@@ -35,7 +35,7 @@
     <!-- Layout preference doesn't obey allowDividerAbove, so put it in a PreferenceCategory -->
     <PreferenceCategory
         android:key="dream_start_now_category">
-        <com.android.settings.applications.LayoutPreference
+        <com.android.settingslib.widget.LayoutPreference
             android:key="dream_start_now_button_container"
             android:selectable="false"
             android:layout="@layout/dream_start_button" />
diff --git a/res/xml/my_device_info.xml b/res/xml/my_device_info.xml
index 7165218..950c2da 100644
--- a/res/xml/my_device_info.xml
+++ b/res/xml/my_device_info.xml
@@ -21,7 +21,7 @@
     android:key="my_device_info_pref_screen"
     android:title="@string/about_settings">
 
-    <com.android.settings.applications.LayoutPreference
+    <com.android.settingslib.widget.LayoutPreference
         android:key="my_device_info_header"
         android:order="0"
         android:layout="@layout/settings_entity_header"
@@ -32,7 +32,8 @@
         android:key="device_name"
         android:order="1"
         android:title="@string/my_device_info_device_name_preference_title"
-        android:summary="@string/summary_placeholder"/>
+        android:summary="@string/summary_placeholder"
+        settings:enableCopying="true" />
 
     <!-- Account name -->
     <Preference
@@ -50,7 +51,8 @@
         android:selectable="false"
         settings:allowDynamicSummaryInSlice="true"
         settings:controller=
-            "com.android.settings.deviceinfo.PhoneNumberPreferenceController" />
+            "com.android.settings.deviceinfo.PhoneNumberPreferenceController"
+        settings:enableCopying="true" />
 
     <Preference
         android:key="emergency_info"
@@ -129,7 +131,8 @@
         android:title="@string/wifi_ip_address"
         android:summary="@string/summary_placeholder"
         android:selectable="false"
-        settings:allowDividerAbove="true"/>
+        settings:allowDividerAbove="true"
+        settings:enableCopying="true" />
 
     <!-- Wi-Fi MAC address -->
     <Preference
@@ -137,7 +140,8 @@
         android:order="35"
         android:title="@string/status_wifi_mac_address"
         android:summary="@string/summary_placeholder"
-        android:selectable="false"/>
+        android:selectable="false"
+        settings:enableCopying="true" />
 
     <!-- Bluetooth address -->
     <Preference
@@ -145,7 +149,8 @@
         android:order="36"
         android:title="@string/status_bt_address"
         android:summary="@string/summary_placeholder"
-        android:selectable="false"/>
+        android:selectable="false"
+        settings:enableCopying="true" />
 
     <!-- Device up time -->
     <Preference
@@ -183,6 +188,7 @@
         android:order="43"
         android:title="@string/build_number"
         android:summary="@string/summary_placeholder"
-        settings:allowDividerAbove="true"/>
+        settings:allowDividerAbove="true"
+        settings:enableCopying="true" />
 
-</PreferenceScreen>
\ No newline at end of file
+</PreferenceScreen>
diff --git a/res/xml/network_and_internet.xml b/res/xml/network_and_internet.xml
index 8e36e91..c218869 100644
--- a/res/xml/network_and_internet.xml
+++ b/res/xml/network_and_internet.xml
@@ -64,7 +64,7 @@
         settings:useAdminDisabledSummary="true" />
 
     <com.android.settingslib.RestrictedSwitchPreference
-        android:key="toggle_airplane"
+        android:key="airplane_mode"
         android:title="@string/airplane_mode"
         android:icon="@drawable/ic_airplanemode_active"
         android:disableDependentsState="true"
diff --git a/res/xml/night_display_settings.xml b/res/xml/night_display_settings.xml
index 12c8bc7..b6f6251 100644
--- a/res/xml/night_display_settings.xml
+++ b/res/xml/night_display_settings.xml
@@ -43,7 +43,7 @@
         settings:keywords="@string/keywords_display_night_display"
         settings:controller="com.android.settings.display.NightDisplayIntensityPreferenceController" />
 
-    <com.android.settings.applications.LayoutPreference
+    <com.android.settingslib.widget.LayoutPreference
         android:key="night_display_activated"
         android:title="@string/night_display_title"
         android:selectable="false"
diff --git a/res/xml/notification_group_settings.xml b/res/xml/notification_group_settings.xml
index 0d4184d..7192f90 100644
--- a/res/xml/notification_group_settings.xml
+++ b/res/xml/notification_group_settings.xml
@@ -17,11 +17,11 @@
 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
         xmlns:settings="http://schemas.android.com/apk/res-auto">
 
-    <com.android.settings.applications.LayoutPreference
+    <com.android.settingslib.widget.LayoutPreference
         android:key="pref_app_header"
         android:layout="@layout/settings_entity_header" />
 
-    <com.android.settings.applications.LayoutPreference
+    <com.android.settingslib.widget.LayoutPreference
         android:key="block"
         android:layout="@layout/styled_switch_bar" />
 
diff --git a/res/xml/power_usage_detail.xml b/res/xml/power_usage_detail.xml
index c854f77..12c7e21 100644
--- a/res/xml/power_usage_detail.xml
+++ b/res/xml/power_usage_detail.xml
@@ -19,7 +19,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:settings="http://schemas.android.com/apk/res-auto">
 
-    <com.android.settings.applications.LayoutPreference
+    <com.android.settingslib.widget.LayoutPreference
         android:key="header_view"
         android:layout="@layout/settings_entity_header"
         android:selectable="false"
diff --git a/res/xml/power_usage_details.xml b/res/xml/power_usage_details.xml
index 85a2ce7..8c79116 100644
--- a/res/xml/power_usage_details.xml
+++ b/res/xml/power_usage_details.xml
@@ -17,7 +17,7 @@
 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:settings="http://schemas.android.com/apk/res-auto">
 
-        <com.android.settings.applications.LayoutPreference
+        <com.android.settingslib.widget.LayoutPreference
             android:key="two_buttons"
             android:layout="@layout/two_buttons_panel"
             android:selectable="false" />
diff --git a/res/xml/power_usage_summary.xml b/res/xml/power_usage_summary.xml
index b4db4ed..14d8eda 100644
--- a/res/xml/power_usage_summary.xml
+++ b/res/xml/power_usage_summary.xml
@@ -21,7 +21,7 @@
     android:title="@string/power_usage_summary_title"
     settings:keywords="@string/keywords_battery">
 
-    <com.android.settings.applications.LayoutPreference
+    <com.android.settingslib.widget.LayoutPreference
         android:key="battery_header"
         android:title="@string/summary_placeholder"
         android:selectable="false"
@@ -50,8 +50,8 @@
 
     <SwitchPreference
         android:key="battery_percentage"
-        android:title="@string/battery_percentage"
-        android:summary="@string/battery_percentage_description"
+        android:title="@string/battery_info"
+        android:summary="@string/battery_info_description"
         settings:controller="com.android.settings.display.BatteryPercentagePreferenceController" />
 
 
diff --git a/res/xml/privacy_dashboard_settings.xml b/res/xml/privacy_dashboard_settings.xml
index 5d11936..79e2e71 100644
--- a/res/xml/privacy_dashboard_settings.xml
+++ b/res/xml/privacy_dashboard_settings.xml
@@ -21,6 +21,7 @@
     android:key="privacy_dashboard_page"
     android:title="@string/privacy_dashboard_title">
 
+    <!-- App permissions -->
     <Preference
         android:key="privacy_manage_perms"
         android:title="@string/app_permissions"
@@ -29,6 +30,14 @@
         <intent android:action="android.intent.action.MANAGE_PERMISSIONS"/>
     </Preference>
 
+    <!-- On lock screen notifications -->
+    <com.android.settings.RestrictedListPreference
+        android:key="privacy_lock_screen_notifications"
+        android:title="@string/lock_screen_notifications_title"
+        android:summary="@string/summary_placeholder"
+        settings:searchable="false"/>
+
+    <!-- Show passwords -->
     <SwitchPreference
         android:key="show_password"
         android:title="@string/show_password"
@@ -42,4 +51,20 @@
     <PreferenceCategory
         android:key="dashboard_tile_placeholder"/>
 
+    <!-- Work profile settings are at the bottom with high order value to avoid users thinking that
+         any of the above settings (including dynamic) are specific to the work profile. -->
+    <PreferenceCategory
+        android:key="privacy_work_profile_notifications_category"
+        android:title="@string/profile_section_header"
+        android:order="998"
+        settings:searchable="false">
+
+        <com.android.settings.RestrictedListPreference
+            android:key="privacy_lock_screen_work_profile_notifications"
+            android:title="@string/locked_work_profile_notification_title"
+            android:summary="@string/summary_placeholder"
+            android:order="999"
+            settings:searchable="false"/>
+    </PreferenceCategory>
+
 </PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/security_settings_face.xml b/res/xml/security_settings_face.xml
index 2bdfdc8..c202a6c 100644
--- a/res/xml/security_settings_face.xml
+++ b/res/xml/security_settings_face.xml
@@ -55,7 +55,7 @@
             android:title="@string/security_settings_face_settings_improve_face">
         </Preference>
 
-        <com.android.settings.applications.LayoutPreference
+        <com.android.settingslib.widget.LayoutPreference
             android:key="security_settings_face_delete_faces_container"
             android:selectable="false"
             android:layout="@layout/face_remove_button" />
diff --git a/res/xml/usb_details_fragment.xml b/res/xml/usb_details_fragment.xml
index 5c1efcf..4a6cefa 100644
--- a/res/xml/usb_details_fragment.xml
+++ b/res/xml/usb_details_fragment.xml
@@ -20,7 +20,7 @@
     android:title="@string/usb_preference"
     android:key="usb_details_fragment">
 
-    <com.android.settings.applications.LayoutPreference
+    <com.android.settingslib.widget.LayoutPreference
         android:key="usb_device_header"
         android:layout="@layout/settings_entity_header"
         android:selectable="false"/>
diff --git a/res/xml/wifi_network_details_fragment.xml b/res/xml/wifi_network_details_fragment.xml
index 4198b76..8b027e2 100644
--- a/res/xml/wifi_network_details_fragment.xml
+++ b/res/xml/wifi_network_details_fragment.xml
@@ -19,7 +19,7 @@
     xmlns:settings="http://schemas.android.com/apk/res-auto"
     settings:initialExpandedChildrenCount="5">
 
-    <com.android.settings.applications.LayoutPreference
+    <com.android.settingslib.widget.LayoutPreference
         android:key="connection_header"
         android:layout="@layout/settings_entity_header"
         android:selectable="false"
@@ -34,18 +34,18 @@
     <!-- General Details Category -->
     <PreferenceCategory
             android:key="general_details_category" >
-        <com.android.settings.wifi.WifiDetailPreference
+        <Preference
                 android:key="signal_strength"
                 android:title="@string/wifi_signal"
                 android:selectable="false"/>
 
-        <com.android.settings.wifi.WifiDetailPreference
+        <Preference
                 android:key="frequency"
                 android:icon="@drawable/ic_frequency_antenna"
                 android:title="@string/wifi_frequency"
                 android:selectable="false"/>
 
-        <com.android.settings.wifi.WifiDetailPreference
+        <Preference
                 android:key="security"
                 android:icon="@drawable/ic_security_lock_24dp"
                 android:title="@string/wifi_security"
@@ -69,30 +69,36 @@
     <PreferenceCategory
             android:key="ip_details_category"
             android:title="@string/wifi_setup_detail">
-        <com.android.settings.wifi.WifiDetailPreference
-            android:key="mac_address"
-            android:title="@string/wifi_advanced_mac_address_title"
-            android:selectable="false"/>
-        <com.android.settings.wifi.WifiDetailPreference
+        <Preference
+                android:key="mac_address"
+                android:title="@string/wifi_advanced_mac_address_title"
+                android:selectable="false"
+                settings:enableCopying="true"/>
+        <Preference
                 android:key="ip_address"
                 android:title="@string/wifi_ip_address"
-                android:selectable="false"/>
-        <com.android.settings.wifi.WifiDetailPreference
+                android:selectable="false"
+                settings:enableCopying="true"/>
+        <Preference
                 android:key="gateway"
                 android:title="@string/wifi_gateway"
-                android:selectable="false"/>
-        <com.android.settings.wifi.WifiDetailPreference
+                android:selectable="false"
+                settings:enableCopying="true"/>
+        <Preference
                 android:key="subnet_mask"
                 android:title="@string/wifi_details_subnet_mask"
-                android:selectable="false"/>
-        <com.android.settings.wifi.WifiDetailPreference
+                android:selectable="false"
+                settings:enableCopying="true"/>
+        <Preference
                 android:key="dns"
                 android:title="@string/wifi_details_dns"
-                android:selectable="false"/>
-        <com.android.settings.wifi.WifiDetailPreference
+                android:selectable="false"
+                settings:enableCopying="true"/>
+        <Preference
                 android:key="link_speed"
                 android:title="@string/wifi_speed"
-                android:selectable="false"/>
+                android:selectable="false"
+                settings:enableCopying="true"/>
     </PreferenceCategory>
 
     <!-- IPv6 Details -->
@@ -102,6 +108,7 @@
             android:selectable="false">
         <Preference
                 android:key="ipv6_addresses"
-                android:selectable="false"/>
+                android:selectable="false"
+                settings:enableCopying="true"/>
     </PreferenceCategory>
 </PreferenceScreen>
diff --git a/res/xml/zen_mode_event_rule_settings.xml b/res/xml/zen_mode_event_rule_settings.xml
index ea37855..c871fe1 100644
--- a/res/xml/zen_mode_event_rule_settings.xml
+++ b/res/xml/zen_mode_event_rule_settings.xml
@@ -20,11 +20,11 @@
     android:key="zen_mode_event_rule_settings"
     android:title="@string/zen_mode_automatic_rule_settings_page_title">
 
-    <com.android.settings.applications.LayoutPreference
+    <com.android.settingslib.widget.LayoutPreference
         android:key="pref_app_header"
         android:layout="@layout/settings_entity_header" />
 
-    <com.android.settings.applications.LayoutPreference
+    <com.android.settingslib.widget.LayoutPreference
         android:key="zen_automatic_rule_switch"
         android:layout="@layout/styled_switch_bar" />
 
diff --git a/res/xml/zen_mode_schedule_rule_settings.xml b/res/xml/zen_mode_schedule_rule_settings.xml
index e201b87..d05bbd2 100644
--- a/res/xml/zen_mode_schedule_rule_settings.xml
+++ b/res/xml/zen_mode_schedule_rule_settings.xml
@@ -20,11 +20,11 @@
     android:key="zen_mode_schedule_rule_settings"
     android:title="@string/zen_mode_automatic_rule_settings_page_title">
 
-    <com.android.settings.applications.LayoutPreference
+    <com.android.settingslib.widget.LayoutPreference
         android:key="pref_app_header"
         android:layout="@layout/settings_entity_header" />
 
-    <com.android.settings.applications.LayoutPreference
+    <com.android.settingslib.widget.LayoutPreference
         android:key="zen_automatic_rule_switch"
         android:layout="@layout/styled_switch_bar" />
 
diff --git a/res/xml/zen_mode_settings.xml b/res/xml/zen_mode_settings.xml
index 1966484..832150a 100644
--- a/res/xml/zen_mode_settings.xml
+++ b/res/xml/zen_mode_settings.xml
@@ -37,11 +37,6 @@
             android:title="@string/zen_mode_messages_title"
             android:fragment="com.android.settings.notification.ZenModeMessagesSettings" />
 
-        <!-- Alarms -->
-        <SwitchPreference
-            android:key="zen_mode_behavior_alarms"
-            android:title="@string/zen_mode_alarms"/>
-
         <!-- All sounds -->
         <Preference
             android:key="zen_sound_vibration_settings"
@@ -70,7 +65,7 @@
         android:fragment="com.android.settings.notification.ZenModeAutomationSettings"/>
 
     <!-- Turn on DND button -->
-    <com.android.settings.applications.LayoutPreference
+    <com.android.settingslib.widget.LayoutPreference
         android:key="zen_mode_settings_button_container"
         android:selectable="false"
         android:layout="@layout/zen_mode_settings_button"
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index 8ed368c..222c18c 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -38,7 +38,6 @@
 import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.widget.Button;
-import android.widget.Toolbar;
 
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
@@ -133,15 +132,10 @@
             ":settings:show_fragment_title_res_package_name";
     public static final String EXTRA_SHOW_FRAGMENT_TITLE_RESID =
             ":settings:show_fragment_title_resid";
-    public static final String EXTRA_SHOW_FRAGMENT_AS_SHORTCUT =
-            ":settings:show_fragment_as_shortcut";
 
     public static final String EXTRA_SHOW_FRAGMENT_AS_SUBSETTING =
             ":settings:show_fragment_as_subsetting";
 
-    @Deprecated
-    public static final String EXTRA_HIDE_DRAWER = ":settings:hide_drawer";
-
     public static final String META_DATA_KEY_FRAGMENT_CLASS =
             "com.android.settings.FRAGMENT_CLASS";
 
@@ -174,8 +168,6 @@
 
     private Button mNextButton;
 
-    private boolean mIsShowingDashboard;
-
     private ViewGroup mContent;
 
     // Categories
@@ -246,9 +238,6 @@
         // Getting Intent properties can only be done after the super.onCreate(...)
         final String initialFragmentName = intent.getStringExtra(EXTRA_SHOW_FRAGMENT);
 
-        mIsShowingDashboard = TextUtils.equals(
-                SettingsActivity.class.getName(), intent.getComponent().getClassName());
-
         // This is a "Sub Settings" when:
         // - this is a real SubSettings
         // - or :settings:show_fragment_as_subsetting is passed to the Intent
@@ -261,8 +250,7 @@
             setTheme(R.style.Theme_SubSettings);
         }
 
-        setContentView(mIsShowingDashboard ?
-                R.layout.settings_main_dashboard : R.layout.settings_main_prefs);
+        setContentView(R.layout.settings_main_prefs);
 
         mContent = findViewById(R.id.main_content);
 
@@ -281,25 +269,16 @@
                 setTitleFromBackStack();
             }
         } else {
-            launchSettingFragment(initialFragmentName, isSubSettings, intent);
+            launchSettingFragment(initialFragmentName, intent);
         }
 
         final boolean deviceProvisioned = Utils.isDeviceProvisioned(this);
-        if (mIsShowingDashboard) {
-            findViewById(R.id.search_bar).setVisibility(
-                    deviceProvisioned ? View.VISIBLE : View.INVISIBLE);
-            findViewById(R.id.action_bar).setVisibility(View.GONE);
-            final Toolbar toolbar = findViewById(R.id.search_action_bar);
-            setActionBar(toolbar);
-            FeatureFactory.getFactory(this).getSearchFeatureProvider()
-                    .initSearchToolbar(this, toolbar);
-        }
 
         ActionBar actionBar = getActionBar();
         if (actionBar != null) {
             actionBar.setDisplayHomeAsUpEnabled(deviceProvisioned);
             actionBar.setHomeButtonEnabled(deviceProvisioned);
-            actionBar.setDisplayShowTitleEnabled(!mIsShowingDashboard);
+            actionBar.setDisplayShowTitleEnabled(true);
         }
         mSwitchBar = findViewById(R.id.switch_bar);
         if (mSwitchBar != null) {
@@ -377,8 +356,8 @@
     }
 
     @VisibleForTesting
-    void launchSettingFragment(String initialFragmentName, boolean isSubSettings, Intent intent) {
-        if (!mIsShowingDashboard && initialFragmentName != null) {
+    void launchSettingFragment(String initialFragmentName, Intent intent) {
+        if (initialFragmentName != null) {
             setTitleFromIntent(intent);
 
             Bundle initialArguments = intent.getBundleExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS);
diff --git a/src/com/android/settings/SettingsPreferenceFragment.java b/src/com/android/settings/SettingsPreferenceFragment.java
index 5cfe218..6b29b2e 100644
--- a/src/com/android/settings/SettingsPreferenceFragment.java
+++ b/src/com/android/settings/SettingsPreferenceFragment.java
@@ -42,7 +42,6 @@
 import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
 
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.core.InstrumentedPreferenceFragment;
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
 import com.android.settings.search.Indexable;
@@ -55,6 +54,7 @@
 import com.android.settingslib.CustomEditTextPreferenceCompat;
 import com.android.settingslib.core.instrumentation.Instrumentable;
 import com.android.settingslib.widget.FooterPreferenceMixinCompat;
+import com.android.settingslib.widget.LayoutPreference;
 
 import java.util.UUID;
 
@@ -155,13 +155,14 @@
         checkAvailablePrefs(getPreferenceScreen());
     }
 
-    private void checkAvailablePrefs(PreferenceGroup preferenceGroup) {
+    @VisibleForTesting
+    void checkAvailablePrefs(PreferenceGroup preferenceGroup) {
         if (preferenceGroup == null) return;
         for (int i = 0; i < preferenceGroup.getPreferenceCount(); i++) {
             Preference pref = preferenceGroup.getPreference(i);
             if (pref instanceof SelfAvailablePreference
                     && !((SelfAvailablePreference) pref).isAvailable(getContext())) {
-                preferenceGroup.removePreference(pref);
+                pref.setVisible(false);
             } else if (pref instanceof PreferenceGroup) {
                 checkAvailablePrefs((PreferenceGroup) pref);
             }
diff --git a/src/com/android/settings/accounts/AccountHeaderPreferenceController.java b/src/com/android/settings/accounts/AccountHeaderPreferenceController.java
index 36a7021..d762095 100644
--- a/src/com/android/settings/accounts/AccountHeaderPreferenceController.java
+++ b/src/com/android/settings/accounts/AccountHeaderPreferenceController.java
@@ -29,7 +29,6 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.core.PreferenceControllerMixin;
 import com.android.settings.widget.EntityHeaderController;
 import com.android.settingslib.accounts.AuthenticatorHelper;
@@ -37,6 +36,7 @@
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnResume;
+import com.android.settingslib.widget.LayoutPreference;
 
 public class AccountHeaderPreferenceController extends AbstractPreferenceController
         implements PreferenceControllerMixin, LifecycleObserver, OnResume {
diff --git a/src/com/android/settings/accounts/EmergencyInfoPreferenceController.java b/src/com/android/settings/accounts/EmergencyInfoPreferenceController.java
index 31e5613..408db09 100644
--- a/src/com/android/settings/accounts/EmergencyInfoPreferenceController.java
+++ b/src/com/android/settings/accounts/EmergencyInfoPreferenceController.java
@@ -22,6 +22,7 @@
 import android.content.res.Resources;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.util.FeatureFlagUtils;
 
 import androidx.preference.Preference;
 
@@ -63,7 +64,7 @@
     @Override
     public boolean handlePreferenceTreeClick(Preference preference) {
         if (KEY_EMERGENCY_INFO.equals(preference.getKey())) {
-            Intent intent = new Intent(ACTION_EDIT_EMERGENCY_INFO);
+            Intent intent = new Intent(getIntentAction(mContext));
             intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
             mContext.startActivity(intent);
             return true;
@@ -73,7 +74,7 @@
 
     @Override
     public boolean isAvailable() {
-        Intent intent = new Intent(ACTION_EDIT_EMERGENCY_INFO).setPackage(PACKAGE_NAME_EMERGENCY);
+        Intent intent = new Intent(getIntentAction(mContext)).setPackage(getPackageName(mContext));
         List<ResolveInfo> infos = mContext.getPackageManager().queryIntentActivities(intent, 0);
         return infos != null && !infos.isEmpty();
     }
@@ -82,4 +83,20 @@
     public String getPreferenceKey() {
         return KEY_EMERGENCY_INFO;
     }
+
+    private String getIntentAction(Context context) {
+        if (FeatureFlagUtils.isEnabled(context, FeatureFlagUtils.SAFETY_HUB)) {
+            return context.getResources().getString(R.string.config_emergency_intent_action);
+        }
+
+        return ACTION_EDIT_EMERGENCY_INFO;
+    }
+
+    private String getPackageName(Context context) {
+        if (FeatureFlagUtils.isEnabled(context, FeatureFlagUtils.SAFETY_HUB)) {
+            return context.getResources().getString(R.string.config_emergency_package_name);
+        }
+
+        return PACKAGE_NAME_EMERGENCY;
+    }
 }
diff --git a/src/com/android/settings/accounts/RemoveAccountPreferenceController.java b/src/com/android/settings/accounts/RemoveAccountPreferenceController.java
index 9770332..06eddd3 100644
--- a/src/com/android/settings/accounts/RemoveAccountPreferenceController.java
+++ b/src/com/android/settings/accounts/RemoveAccountPreferenceController.java
@@ -39,13 +39,13 @@
 
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.core.PreferenceControllerMixin;
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
 import com.android.settingslib.RestrictedLockUtilsInternal;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.widget.LayoutPreference;
 
 import java.io.IOException;
 
diff --git a/src/com/android/settings/applications/AppStorageSettings.java b/src/com/android/settings/applications/AppStorageSettings.java
index 841fb51..61ce33d 100644
--- a/src/com/android/settings/applications/AppStorageSettings.java
+++ b/src/com/android/settings/applications/AppStorageSettings.java
@@ -58,6 +58,7 @@
 import com.android.settingslib.applications.ApplicationsState.Callbacks;
 import com.android.settingslib.applications.StorageStatsSource;
 import com.android.settingslib.applications.StorageStatsSource.AppStorageStats;
+import com.android.settingslib.widget.LayoutPreference;
 
 import java.util.Collections;
 import java.util.List;
diff --git a/src/com/android/settings/applications/LayoutPreference.java b/src/com/android/settings/applications/LayoutPreference.java
deleted file mode 100644
index 9c3cfaf..0000000
--- a/src/com/android/settings/applications/LayoutPreference.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2015 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;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.util.AttributeSet;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-
-import androidx.core.content.res.TypedArrayUtils;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceViewHolder;
-
-import com.android.settings.R;
-import com.android.settings.Utils;
-
-public class LayoutPreference extends Preference {
-
-    private final View.OnClickListener mClickListener = v -> performClick(v);
-    private boolean mAllowDividerAbove;
-    private boolean mAllowDividerBelow;
-    private View mRootView;
-
-    public LayoutPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        init(context, attrs, 0 /* defStyleAttr */);
-    }
-
-    public LayoutPreference(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        init(context, attrs, defStyleAttr);
-    }
-
-    public LayoutPreference(Context context, int resource) {
-        this(context, LayoutInflater.from(context).inflate(resource, null, false));
-    }
-
-    public LayoutPreference(Context context, View view) {
-        super(context);
-        setView(view);
-    }
-
-    private void init(Context context, AttributeSet attrs, int defStyleAttr) {
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Preference);
-        mAllowDividerAbove = TypedArrayUtils.getBoolean(a, R.styleable.Preference_allowDividerAbove,
-                R.styleable.Preference_allowDividerAbove, false);
-        mAllowDividerBelow = TypedArrayUtils.getBoolean(a, R.styleable.Preference_allowDividerBelow,
-                R.styleable.Preference_allowDividerBelow, false);
-        a.recycle();
-
-        a = context.obtainStyledAttributes(
-                attrs, com.android.internal.R.styleable.Preference, defStyleAttr, 0);
-        int layoutResource = a.getResourceId(com.android.internal.R.styleable.Preference_layout,
-                0);
-        if (layoutResource == 0) {
-            throw new IllegalArgumentException("LayoutPreference requires a layout to be defined");
-        }
-        a.recycle();
-
-        // Need to create view now so that findViewById can be called immediately.
-        final View view = LayoutInflater.from(getContext())
-                .inflate(layoutResource, null, false);
-        setView(view);
-    }
-
-    private void setView(View view) {
-        setLayoutResource(R.layout.layout_preference_frame);
-        final ViewGroup allDetails = view.findViewById(R.id.all_details);
-        if (allDetails != null) {
-            Utils.forceCustomPadding(allDetails, true /* additive padding */);
-        }
-        mRootView = view;
-        setShouldDisableView(false);
-    }
-
-    @Override
-    public void onBindViewHolder(PreferenceViewHolder holder) {
-        holder.itemView.setOnClickListener(mClickListener);
-
-        final boolean selectable = isSelectable();
-        holder.itemView.setFocusable(selectable);
-        holder.itemView.setClickable(selectable);
-        holder.setDividerAllowedAbove(mAllowDividerAbove);
-        holder.setDividerAllowedBelow(mAllowDividerBelow);
-
-        FrameLayout layout = (FrameLayout) holder.itemView;
-        layout.removeAllViews();
-        ViewGroup parent = (ViewGroup) mRootView.getParent();
-        if (parent != null) {
-            parent.removeView(mRootView);
-        }
-        layout.addView(mRootView);
-    }
-
-    public <T extends View> T findViewById(int id) {
-        return mRootView.findViewById(id);
-    }
-
-    public void setAllowDividerBelow(boolean allowed) {
-        mAllowDividerBelow = allowed;
-    }
-
-    public boolean isAllowDividerBelow() {
-        return mAllowDividerBelow;
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/settings/applications/appinfo/AppHeaderViewPreferenceController.java b/src/com/android/settings/applications/appinfo/AppHeaderViewPreferenceController.java
index 5f41ae0..f65bb9b 100644
--- a/src/com/android/settings/applications/appinfo/AppHeaderViewPreferenceController.java
+++ b/src/com/android/settings/applications/appinfo/AppHeaderViewPreferenceController.java
@@ -23,8 +23,6 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
-import com.android.settings.Utils;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.widget.EntityHeaderController;
 import com.android.settingslib.applications.AppUtils;
@@ -32,6 +30,7 @@
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnStart;
+import com.android.settingslib.widget.LayoutPreference;
 
 public class AppHeaderViewPreferenceController extends BasePreferenceController
         implements AppInfoDashboardFragment.Callback, LifecycleObserver, OnStart {
diff --git a/src/com/android/settings/applications/appinfo/InstantAppButtonsPreferenceController.java b/src/com/android/settings/applications/appinfo/InstantAppButtonsPreferenceController.java
index f710f2e..23c0121 100644
--- a/src/com/android/settings/applications/appinfo/InstantAppButtonsPreferenceController.java
+++ b/src/com/android/settings/applications/appinfo/InstantAppButtonsPreferenceController.java
@@ -34,7 +34,6 @@
 
 import com.android.settings.R;
 import com.android.settings.applications.AppStoreUtil;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.core.BasePreferenceController;
 import com.android.settingslib.applications.AppUtils;
 import com.android.settingslib.core.lifecycle.Lifecycle;
@@ -42,6 +41,7 @@
 import com.android.settingslib.core.lifecycle.events.OnCreateOptionsMenu;
 import com.android.settingslib.core.lifecycle.events.OnOptionsItemSelected;
 import com.android.settingslib.core.lifecycle.events.OnPrepareOptionsMenu;
+import com.android.settingslib.widget.LayoutPreference;
 
 import java.util.List;
 
diff --git a/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java
index d1fdc48..8e41eff 100644
--- a/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java
+++ b/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java
@@ -23,8 +23,8 @@
 import androidx.preference.Preference;
 
 import com.android.settings.R;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.widget.LayoutPreference;
 
 /**
  * Controller for the remove button.
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsButtonsController.java b/src/com/android/settings/bluetooth/BluetoothDetailsButtonsController.java
index 563a06a..4bb2103 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsButtonsController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsButtonsController.java
@@ -76,7 +76,7 @@
             if (!mConnectButtonInitialized || previouslyConnected) {
                 mActionButtons
                         .setButton2Text(R.string.bluetooth_device_context_connect)
-                        // TODO (b/119646923) Icon is not ready.
+                        .setButton2Icon(R.drawable.ic_add_24dp)
                         .setButton2OnClickListener(
                                 view -> mCachedDevice.connect(true /* connectAllProfiles */));
                 mConnectButtonInitialized = true;
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsHeaderController.java b/src/com/android/settings/bluetooth/BluetoothDetailsHeaderController.java
index 1795c07..11bd174 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsHeaderController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsHeaderController.java
@@ -25,13 +25,13 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.widget.EntityHeaderController;
 import com.android.settingslib.bluetooth.BluetoothUtils;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.LayoutPreference;
 
 /**
  * This class adds a header with device name and status (connected/disconnected, etc.).
diff --git a/src/com/android/settings/bluetooth/BluetoothSliceBuilder.java b/src/com/android/settings/bluetooth/BluetoothSliceBuilder.java
index 1462f91..0a2e8ce 100644
--- a/src/com/android/settings/bluetooth/BluetoothSliceBuilder.java
+++ b/src/com/android/settings/bluetooth/BluetoothSliceBuilder.java
@@ -20,7 +20,6 @@
 import android.annotation.ColorInt;
 import android.app.PendingIntent;
 import android.bluetooth.BluetoothAdapter;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -37,6 +36,7 @@
 import com.android.settings.R;
 import com.android.settings.SubSettings;
 import com.android.settings.connecteddevice.BluetoothDashboardFragment;
+import com.android.settings.slices.CustomSliceRegistry;
 import com.android.settings.slices.SliceBroadcastReceiver;
 import com.android.settings.slices.SliceBuilderUtils;
 
@@ -48,16 +48,6 @@
     private static final String TAG = "BluetoothSliceBuilder";
 
     /**
-     * Backing Uri for the Bluetooth Slice.
-     */
-    public static final Uri BLUETOOTH_URI = new Uri.Builder()
-            .scheme(ContentResolver.SCHEME_CONTENT)
-            .authority(SettingsSlicesContract.AUTHORITY)
-            .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
-            .appendPath(SettingsSlicesContract.KEY_BLUETOOTH)
-            .build();
-
-    /**
      * Action notifying a change on the BluetoothSlice.
      */
     public static final String ACTION_BLUETOOTH_SLICE_CHANGED =
@@ -74,7 +64,7 @@
     }
 
     /**
-     * Return a Bluetooth Slice bound to {@link #BLUETOOTH_URI}.
+     * Return a Bluetooth Slice bound to {@link CustomSliceRegistry#BLUETOOTH_URI}.
      * <p>
      * Note that you should register a listener for {@link #INTENT_FILTER} to get changes for
      * Bluetooth.
@@ -92,7 +82,7 @@
         final SliceAction toggleSliceAction = new SliceAction(toggleAction, null /* actionTitle */,
                 isBluetoothEnabled);
 
-        return new ListBuilder(context, BLUETOOTH_URI, ListBuilder.INFINITY)
+        return new ListBuilder(context, CustomSliceRegistry.BLUETOOTH_URI, ListBuilder.INFINITY)
                 .setAccentColor(color)
                 .addRow(new RowBuilder()
                         .setTitle(title)
diff --git a/src/com/android/settings/connecteddevice/usb/UsbDetailsHeaderController.java b/src/com/android/settings/connecteddevice/usb/UsbDetailsHeaderController.java
index 0e1811d..26b21a1 100644
--- a/src/com/android/settings/connecteddevice/usb/UsbDetailsHeaderController.java
+++ b/src/com/android/settings/connecteddevice/usb/UsbDetailsHeaderController.java
@@ -21,8 +21,8 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.widget.EntityHeaderController;
+import com.android.settingslib.widget.LayoutPreference;
 
 /**
  * This class adds a header with device name.
diff --git a/src/com/android/settings/core/SubSettingLauncher.java b/src/com/android/settings/core/SubSettingLauncher.java
index fb730b8..39ecd78 100644
--- a/src/com/android/settings/core/SubSettingLauncher.java
+++ b/src/com/android/settings/core/SubSettingLauncher.java
@@ -84,11 +84,6 @@
         return this;
     }
 
-    public SubSettingLauncher setIsShortCut(boolean isShortCut) {
-        mLaunchRequest.isShortCut = isShortCut;
-        return this;
-    }
-
     public SubSettingLauncher setArguments(Bundle arguments) {
         mLaunchRequest.arguments = arguments;
         return this;
@@ -159,8 +154,6 @@
         intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE_RESID,
                 mLaunchRequest.titleResId);
         intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE, mLaunchRequest.title);
-        intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_AS_SHORTCUT,
-                mLaunchRequest.isShortCut);
         intent.addFlags(mLaunchRequest.flags);
         return intent;
     }
@@ -195,7 +188,6 @@
         int titleResId;
         String titleResPackageName;
         CharSequence title;
-        boolean isShortCut;
         int sourceMetricsCategory = -100;
         int flags;
         Fragment mResultListener;
diff --git a/src/com/android/settings/development/AllowBackgroundActivityStartsPreferenceController.java b/src/com/android/settings/development/AllowBackgroundActivityStartsPreferenceController.java
new file mode 100644
index 0000000..ea47f35
--- /dev/null
+++ b/src/com/android/settings/development/AllowBackgroundActivityStartsPreferenceController.java
@@ -0,0 +1,68 @@
+/*
+ * 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.development;
+
+import android.content.Context;
+import android.provider.Settings;
+
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.development.DeveloperOptionsPreferenceController;
+
+import androidx.preference.Preference;
+import androidx.preference.SwitchPreference;
+
+public class AllowBackgroundActivityStartsPreferenceController
+        extends DeveloperOptionsPreferenceController
+        implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin {
+
+    private static final String BACKGROUND_ACTIVITY_STARTS_ENABLED_KEY
+            = "allow_background_activity_starts";
+
+    public AllowBackgroundActivityStartsPreferenceController(Context context) {
+        super(context);
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return BACKGROUND_ACTIVITY_STARTS_ENABLED_KEY;
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        writeSetting((boolean) newValue);
+        return true;
+    }
+
+    private void writeSetting(boolean isEnabled) {
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED, isEnabled ? 1 : 0);
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        final int mode = Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED, 1);
+        ((SwitchPreference) mPreference).setChecked(mode != 0);
+    }
+
+    @Override
+    protected void onDeveloperOptionsSwitchDisabled() {
+        super.onDeveloperOptionsSwitchDisabled();
+        writeSetting(false);
+        ((SwitchPreference) mPreference).setChecked(false);
+    }
+}
diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
index 932c0c7..762686a 100644
--- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
+++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
@@ -454,6 +454,7 @@
         controllers.add(new ProfileGpuRenderingPreferenceController(context));
         controllers.add(new KeepActivitiesPreferenceController(context));
         controllers.add(new BackgroundProcessLimitPreferenceController(context));
+        controllers.add(new AllowBackgroundActivityStartsPreferenceController(context));
         controllers.add(new ShowFirstCrashDialogPreferenceController(context));
         controllers.add(new AppsNotRespondingPreferenceController(context));
         controllers.add(new NotificationChannelWarningsPreferenceController(context));
diff --git a/src/com/android/settings/deviceinfo/StorageWizardMoveProgress.java b/src/com/android/settings/deviceinfo/StorageWizardMoveProgress.java
index 7a2f0c1..27fa9be 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardMoveProgress.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardMoveProgress.java
@@ -88,8 +88,6 @@
                 return getString(R.string.move_error_device_admin);
             case PackageManager.MOVE_FAILED_DOESNT_EXIST:
                 return getString(R.string.does_not_exist);
-            case PackageManager.MOVE_FAILED_FORWARD_LOCKED:
-                return getString(R.string.app_forward_locked);
             case PackageManager.MOVE_FAILED_INVALID_LOCATION:
                 return getString(R.string.invalid_location);
             case PackageManager.MOVE_FAILED_SYSTEM_PACKAGE:
diff --git a/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java b/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java
index 8c6c5ae..8b21f0d 100644
--- a/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java
+++ b/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java
@@ -29,9 +29,7 @@
 import com.android.settings.R;
 import com.android.settings.Utils;
 import com.android.settings.accounts.EmergencyInfoPreferenceController;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.dashboard.DashboardFragment;
-import com.android.settings.dashboard.SummaryLoader;
 import com.android.settings.deviceinfo.BluetoothAddressPreferenceController;
 import com.android.settings.deviceinfo.BrandedAccountPreferenceController;
 import com.android.settings.deviceinfo.BuildNumberPreferenceController;
@@ -53,6 +51,7 @@
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.search.SearchIndexable;
+import com.android.settingslib.widget.LayoutPreference;
 
 import java.util.ArrayList;
 import java.util.Arrays;
diff --git a/src/com/android/settings/display/AutoBrightnessPreferenceController.java b/src/com/android/settings/display/AutoBrightnessPreferenceController.java
index 3f5f2b0..3b53fa8 100644
--- a/src/com/android/settings/display/AutoBrightnessPreferenceController.java
+++ b/src/com/android/settings/display/AutoBrightnessPreferenceController.java
@@ -52,7 +52,7 @@
     public int getAvailabilityStatus() {
         return mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_automatic_brightness_available)
-                ? AVAILABLE_UNSEARCHABLE
+                ? AVAILABLE
                 : UNSUPPORTED_ON_DEVICE;
     }
 
@@ -67,4 +67,4 @@
                 ? R.string.auto_brightness_summary_on
                 : R.string.auto_brightness_summary_off);
     }
-}
\ No newline at end of file
+}
diff --git a/src/com/android/settings/display/ColorModePreferenceFragment.java b/src/com/android/settings/display/ColorModePreferenceFragment.java
index bf307b6..2a21379 100644
--- a/src/com/android/settings/display/ColorModePreferenceFragment.java
+++ b/src/com/android/settings/display/ColorModePreferenceFragment.java
@@ -23,12 +23,12 @@
 import com.android.internal.app.ColorDisplayController;
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.search.Indexable;
 import com.android.settings.widget.RadioButtonPickerFragment;
 import com.android.settingslib.search.SearchIndexable;
 import com.android.settingslib.widget.CandidateInfo;
+import com.android.settingslib.widget.LayoutPreference;
 
 import java.util.ArrayList;
 import java.util.Arrays;
diff --git a/src/com/android/settings/display/NightDisplayActivationPreferenceController.java b/src/com/android/settings/display/NightDisplayActivationPreferenceController.java
index 706ac85..35cb5ed 100644
--- a/src/com/android/settings/display/NightDisplayActivationPreferenceController.java
+++ b/src/com/android/settings/display/NightDisplayActivationPreferenceController.java
@@ -28,8 +28,8 @@
 
 import com.android.internal.app.ColorDisplayController;
 import com.android.settings.R;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.core.TogglePreferenceController;
+import com.android.settingslib.widget.LayoutPreference;
 
 public class NightDisplayActivationPreferenceController extends TogglePreferenceController {
 
diff --git a/src/com/android/settings/dream/StartNowPreferenceController.java b/src/com/android/settings/dream/StartNowPreferenceController.java
index 5519a0e..9e45ea3 100644
--- a/src/com/android/settings/dream/StartNowPreferenceController.java
+++ b/src/com/android/settings/dream/StartNowPreferenceController.java
@@ -23,10 +23,10 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.core.PreferenceControllerMixin;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.dream.DreamBackend;
+import com.android.settingslib.widget.LayoutPreference;
 
 public class StartNowPreferenceController extends AbstractPreferenceController implements
         PreferenceControllerMixin {
diff --git a/src/com/android/settings/flashlight/FlashlightSliceBuilder.java b/src/com/android/settings/flashlight/FlashlightSliceBuilder.java
index d21739e..57d99ef 100644
--- a/src/com/android/settings/flashlight/FlashlightSliceBuilder.java
+++ b/src/com/android/settings/flashlight/FlashlightSliceBuilder.java
@@ -22,17 +22,14 @@
 
 import android.annotation.ColorInt;
 import android.app.PendingIntent;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.hardware.camera2.CameraAccessException;
 import android.hardware.camera2.CameraCharacteristics;
 import android.hardware.camera2.CameraManager;
-import android.net.Uri;
 import android.provider.Settings;
 import android.provider.Settings.Secure;
-import android.provider.SettingsSlicesContract;
 import android.util.Log;
 
 import androidx.core.graphics.drawable.IconCompat;
@@ -43,7 +40,7 @@
 
 import com.android.settings.R;
 import com.android.settings.Utils;
-import com.android.settings.slices.SettingsSliceProvider;
+import com.android.settings.slices.CustomSliceRegistry;
 import com.android.settings.slices.SliceBroadcastReceiver;
 
 
@@ -54,37 +51,23 @@
 
     private static final String TAG = "FlashlightSliceBuilder";
 
-    public static final String KEY_FLASHLIGHT = "flashlight";
-
-    /**
-     * Backing Uri for the Flashlight Slice.
-     */
-    public static final Uri FLASHLIGHT_URI = new Uri.Builder()
-        .scheme(ContentResolver.SCHEME_CONTENT)
-        .authority(SettingsSliceProvider.SLICE_AUTHORITY)
-        .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
-        .appendPath(KEY_FLASHLIGHT)
-        .build();
-
     /**
      * Action notifying a change on the Flashlight Slice.
      */
     public static final String ACTION_FLASHLIGHT_SLICE_CHANGED =
-        "com.android.settings.flashlight.action.FLASHLIGHT_SLICE_CHANGED";
+            "com.android.settings.flashlight.action.FLASHLIGHT_SLICE_CHANGED";
 
     /**
      * Action broadcasting a change on whether flashlight is on or off.
      */
     public static final String ACTION_FLASHLIGHT_CHANGED =
-        "com.android.settings.flashlight.action.FLASHLIGHT_CHANGED";
+            "com.android.settings.flashlight.action.FLASHLIGHT_CHANGED";
 
     public static final IntentFilter INTENT_FILTER = new IntentFilter(ACTION_FLASHLIGHT_CHANGED);
 
-    private FlashlightSliceBuilder() {}
+    private FlashlightSliceBuilder() {
+    }
 
-    /**
-     * Return a Flashlight Slice bound to {@link #FLASHLIGHT_URI}.
-     */
     public static Slice getSlice(Context context) {
         if (!isFlashlightAvailable(context)) {
             return null;
@@ -93,14 +76,15 @@
         @ColorInt final int color = Utils.getColorAccentDefaultColor(context);
         final IconCompat icon =
                 IconCompat.createWithResource(context, R.drawable.ic_signal_flashlight);
-        return new ListBuilder(context, FLASHLIGHT_URI, ListBuilder.INFINITY)
-            .setAccentColor(color)
-            .addRow(new RowBuilder()
-                .setTitle(context.getText(R.string.power_flashlight))
-                .setTitleItem(icon, ICON_IMAGE)
-                .setPrimaryAction(
-                        new SliceAction(toggleAction, null, isFlashlightEnabled(context))))
-            .build();
+        return new ListBuilder(context, CustomSliceRegistry.FLASHLIGHT_SLICE_URI,
+                ListBuilder.INFINITY)
+                .setAccentColor(color)
+                .addRow(new RowBuilder()
+                        .setTitle(context.getText(R.string.power_flashlight))
+                        .setTitleItem(icon, ICON_IMAGE)
+                        .setPrimaryAction(
+                                new SliceAction(toggleAction, null, isFlashlightEnabled(context))))
+                .build();
     }
 
     /**
@@ -119,7 +103,7 @@
         } catch (CameraAccessException e) {
             Log.e(TAG, "Camera couldn't set torch mode.", e);
         }
-        context.getContentResolver().notifyChange(FLASHLIGHT_URI, null);
+        context.getContentResolver().notifyChange(CustomSliceRegistry.FLASHLIGHT_SLICE_URI, null);
     }
 
     private static String getCameraId(Context context) throws CameraAccessException {
@@ -130,7 +114,7 @@
             Boolean flashAvailable = c.get(CameraCharacteristics.FLASH_INFO_AVAILABLE);
             Integer lensFacing = c.get(CameraCharacteristics.LENS_FACING);
             if (flashAvailable != null && flashAvailable
-                  && lensFacing != null && lensFacing == CameraCharacteristics.LENS_FACING_BACK) {
+                    && lensFacing != null && lensFacing == CameraCharacteristics.LENS_FACING_BACK) {
                 return id;
             }
         }
@@ -141,16 +125,16 @@
         final Intent intent = new Intent(ACTION_FLASHLIGHT_SLICE_CHANGED);
         intent.setClass(context, SliceBroadcastReceiver.class);
         return PendingIntent.getBroadcast(context, 0 /* requestCode */, intent,
-            PendingIntent.FLAG_CANCEL_CURRENT);
+                PendingIntent.FLAG_CANCEL_CURRENT);
     }
 
     private static boolean isFlashlightAvailable(Context context) {
         return Settings.Secure.getInt(
-            context.getContentResolver(), Secure.FLASHLIGHT_AVAILABLE, 0) == 1;
+                context.getContentResolver(), Secure.FLASHLIGHT_AVAILABLE, 0) == 1;
     }
 
     private static boolean isFlashlightEnabled(Context context) {
         return Settings.Secure.getInt(
-            context.getContentResolver(), Secure.FLASHLIGHT_ENABLED, 0) == 1;
+                context.getContentResolver(), Secure.FLASHLIGHT_ENABLED, 0) == 1;
     }
 }
diff --git a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
index ce9cabc..6ad50a9 100644
--- a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
+++ b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
@@ -39,7 +39,6 @@
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
 import com.android.settings.Utils;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.applications.appinfo.AppButtonsPreferenceController;
 import com.android.settings.applications.appinfo.ButtonActionDialogFragment;
 import com.android.settings.core.InstrumentedPreferenceFragment;
@@ -52,6 +51,7 @@
 import com.android.settingslib.applications.ApplicationsState;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.utils.StringUtil;
+import com.android.settingslib.widget.LayoutPreference;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java b/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java
index e5a2e5e..48f4cc1 100644
--- a/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java
@@ -30,7 +30,6 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.core.PreferenceControllerMixin;
 import com.android.settings.widget.EntityHeaderController;
@@ -38,6 +37,7 @@
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnStart;
+import com.android.settingslib.widget.LayoutPreference;
 
 /**
  * Controller that update the battery header view
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
index f7c31e5..85aa915 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
@@ -39,7 +39,6 @@
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
 import com.android.settings.Utils;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.core.SubSettingLauncher;
 import com.android.settings.fuelgauge.batterytip.BatteryTipLoader;
 import com.android.settings.fuelgauge.batterytip.BatteryTipPreferenceController;
@@ -49,6 +48,7 @@
 import com.android.settingslib.search.SearchIndexable;
 import com.android.settingslib.utils.PowerUtil;
 import com.android.settingslib.utils.StringUtil;
+import com.android.settingslib.widget.LayoutPreference;
 
 import java.util.Collections;
 import java.util.List;
diff --git a/src/com/android/settings/fuelgauge/batterytip/BatteryTipPreferenceController.java b/src/com/android/settings/fuelgauge/batterytip/BatteryTipPreferenceController.java
index eac2bf5..0d9b1c4 100644
--- a/src/com/android/settings/fuelgauge/batterytip/BatteryTipPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/batterytip/BatteryTipPreferenceController.java
@@ -42,6 +42,9 @@
  * Controller in charge of the battery tip group
  */
 public class BatteryTipPreferenceController extends BasePreferenceController {
+
+    public static final String PREF_NAME = "battery_tip";
+
     private static final String TAG = "BatteryTipPreferenceController";
     private static final int REQUEST_ANOMALY_ACTION = 0;
     private static final String KEY_BATTERY_TIPS = "key_battery_tips";
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCard.java b/src/com/android/settings/homepage/contextualcards/ContextualCard.java
index 4e4e34f..ca5555b 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCard.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCard.java
@@ -33,13 +33,16 @@
     /**
      * Flags indicating the type of the ContextualCard.
      */
-    @IntDef({CardType.DEFAULT, CardType.SLICE, CardType.LEGACY_SUGGESTION, CardType.CONDITIONAL})
+    @IntDef({CardType.DEFAULT, CardType.SLICE, CardType.LEGACY_SUGGESTION, CardType.CONDITIONAL,
+            CardType.CONDITIONAL_HEADER, CardType.CONDITIONAL_FOOTER})
     @Retention(RetentionPolicy.SOURCE)
     public @interface CardType {
         int DEFAULT = 0;
         int SLICE = 1;
         int LEGACY_SUGGESTION = 2;
         int CONDITIONAL = 3;
+        int CONDITIONAL_HEADER = 4;
+        int CONDITIONAL_FOOTER = 5;
     }
 
     private final Builder mBuilder;
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProvider.java b/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProvider.java
new file mode 100644
index 0000000..8583f38
--- /dev/null
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProvider.java
@@ -0,0 +1,39 @@
+/*
+ * 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.homepage.contextualcards;
+
+import android.content.Context;
+
+import java.util.List;
+
+/** Feature provider for the contextual card feature. */
+public interface ContextualCardFeatureProvider {
+
+    /** Homepage displays. */
+    public void logHomepageDisplay(Context context, Long latency);
+
+    /** When user clicks dismiss in contextual card */
+    public void logContextualCardDismiss(Context context, ContextualCard card);
+
+    /** After ContextualCardManager decides which cards will be displayed/hidden */
+    public void logContextualCardDisplay(Context context, List<ContextualCard> showedCards,
+            List<ContextualCard> hiddenCards);
+
+    /** When user clicks toggle/title area of a contextual card. */
+    public void logContextualCardClick(Context context, ContextualCard card, int row,
+            int tapTarget);
+}
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProviderImpl.java b/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProviderImpl.java
new file mode 100644
index 0000000..e437e2b
--- /dev/null
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProviderImpl.java
@@ -0,0 +1,136 @@
+/*
+ * 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.homepage.contextualcards;
+
+import android.content.Context;
+import android.content.Intent;
+import android.text.TextUtils;
+import android.util.Log;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.slice.widget.EventInfo;
+
+import com.android.settings.R;
+
+import java.util.List;
+
+public class ContextualCardFeatureProviderImpl implements ContextualCardFeatureProvider {
+    private static final String TAG = "ContextualCardFeature";
+
+    // Contextual card interaction logs
+    // Settings Homepage shows
+    private static final int CONTEXTUAL_HOME_SHOW = 38;
+
+    // Contextual card shows, log card name and rank
+    private static final int CONTEXTUAL_CARD_SHOW = 39;
+
+    // Contextual card is eligible to be shown, but doesn't rank high
+    // enough, log card name and score
+    private static final int CONTEXTUAL_CARD_NOT_SHOW = 40;
+
+    // Contextual card is dismissed, log card name
+    private static final int CONTEXTUAL_CARD_DISMISS = 41;
+
+    // Contextual card is clicked , log card name, score, tap area
+    private static final int CONTEXTUAL_CARD_CLICK = 42;
+
+    // SettingsLogBroadcastReceiver contracts
+    // contextual card name
+    private static final String EXTRA_CONTEXTUALCARD_NAME = "name";
+
+    // contextual card score
+    private static final String EXTRA_CONTEXTUALCARD_SCORE = "score";
+
+    // contextual card clicked row
+    private static final String EXTRA_CONTEXTUALCARD_ROW = "row";
+
+    // contextual card tap target
+    private static final String EXTRA_CONTEXTUALCARD_TAP_TARGET = "target";
+
+    // contextual homepage display latency
+    private static final String EXTRA_LATENCY = "latency";
+
+    // log type
+    private static final String EXTRA_CONTEXTUALCARD_ACTION_TYPE = "type";
+
+
+    // Contextual card tap target
+    private static final int TARGET_DEFAULT = 0;
+
+    // Click title area
+    private static final int TARGET_TITLE = 1;
+
+    // Click toggle
+    private static final int TARGET_TOGGLE = 2;
+
+    // Click slider
+    private static final int TARGET_SLIDER = 3;
+
+    @Override
+    public void logHomepageDisplay(Context context, Long latency) {
+    }
+
+    @Override
+    public void logContextualCardDismiss(Context context, ContextualCard card) {
+        final Intent intent = new Intent();
+        intent.putExtra(EXTRA_CONTEXTUALCARD_ACTION_TYPE, CONTEXTUAL_CARD_DISMISS);
+        intent.putExtra(EXTRA_CONTEXTUALCARD_NAME, card.getName());
+        intent.putExtra(EXTRA_CONTEXTUALCARD_SCORE, card.getRankingScore());
+        sendBroadcast(context, intent);
+    }
+
+    @Override
+    public void logContextualCardDisplay(Context context, List<ContextualCard> showCards,
+            List<ContextualCard> hiddenCards) {
+    }
+
+    @Override
+    public void logContextualCardClick(Context context, ContextualCard card, int row,
+            int actionType) {
+        final Intent intent = new Intent();
+        intent.putExtra(EXTRA_CONTEXTUALCARD_ACTION_TYPE, CONTEXTUAL_CARD_CLICK);
+        intent.putExtra(EXTRA_CONTEXTUALCARD_NAME, card.getName());
+        intent.putExtra(EXTRA_CONTEXTUALCARD_SCORE, card.getRankingScore());
+        intent.putExtra(EXTRA_CONTEXTUALCARD_ROW, row);
+        intent.putExtra(EXTRA_CONTEXTUALCARD_TAP_TARGET, actionTypeToTapTarget(actionType));
+        sendBroadcast(context, intent);
+    }
+
+    @VisibleForTesting
+    void sendBroadcast(final Context context, final Intent intent) {
+        intent.setPackage(context.getString(R.string.config_settingsintelligence_package_name));
+        final String action = context.getString(R.string.config_settingsintelligence_log_action);
+        if (!TextUtils.isEmpty(action)) {
+            intent.setAction(action);
+            context.sendBroadcast(intent);
+        }
+    }
+
+    private int actionTypeToTapTarget(int actionType) {
+        switch (actionType) {
+            case EventInfo.ACTION_TYPE_CONTENT:
+                return TARGET_TITLE;
+            case EventInfo.ACTION_TYPE_TOGGLE:
+                return TARGET_TOGGLE;
+            case EventInfo.ACTION_TYPE_SLIDER:
+                return TARGET_SLIDER;
+            default:
+                Log.w(TAG, "unknown type " + actionType);
+                return TARGET_DEFAULT;
+        }
+    }
+}
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardFeedbackDialog.java b/src/com/android/settings/homepage/contextualcards/ContextualCardFeedbackDialog.java
new file mode 100644
index 0000000..0d5b275
--- /dev/null
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCardFeedbackDialog.java
@@ -0,0 +1,66 @@
+/*
+ * 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.homepage.contextualcards;
+
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.Log;
+
+import com.android.internal.app.AlertActivity;
+import com.android.internal.app.AlertController;
+import com.android.settings.R;
+
+public class ContextualCardFeedbackDialog extends AlertActivity implements
+        DialogInterface.OnClickListener {
+
+    public static final String EXTRA_CARD_NAME = "card_name";
+    public static final String EXTRA_FEEDBACK_EMAIL = "feedback_email";
+
+    private static final String TAG = "CardFeedbackDialog";
+    private static final String SUBJECT = "Settings Contextual Card Feedback - ";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        final AlertController.AlertParams alertParams = mAlertParams;
+        alertParams.mMessage = getText(R.string.contextual_card_feedback_confirm_message);
+        alertParams.mPositiveButtonText = getText(R.string.contextual_card_feedback_send);
+        alertParams.mPositiveButtonListener = this;
+        alertParams.mNegativeButtonText = getText(R.string.skip_label);
+
+        setupAlert();
+    }
+
+    @Override
+    public void onClick(DialogInterface dialog, int which) {
+        final String cardName = getIntent().getStringExtra(EXTRA_CARD_NAME);
+        final String email = getIntent().getStringExtra(EXTRA_FEEDBACK_EMAIL);
+        final Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:" + email));
+        intent.putExtra(Intent.EXTRA_SUBJECT, SUBJECT + cardName);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+        try {
+            startActivity(intent);
+        } catch (Exception e) {
+            Log.e(TAG, "Send feedback failed.", e);
+        }
+        finish();
+    }
+}
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardLoader.java b/src/com/android/settings/homepage/contextualcards/ContextualCardLoader.java
index c723cfd..3ef4653 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCardLoader.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCardLoader.java
@@ -23,7 +23,6 @@
 import android.content.ContentProviderClient;
 import android.content.ContentResolver;
 import android.content.Context;
-import android.content.pm.PackageManager;
 import android.database.ContentObserver;
 import android.database.Cursor;
 import android.net.Uri;
@@ -35,9 +34,7 @@
 import androidx.annotation.VisibleForTesting;
 import androidx.slice.Slice;
 
-import com.android.settings.homepage.contextualcards.deviceinfo.BatterySlice;
-import com.android.settings.homepage.contextualcards.slices.ConnectedDeviceSlice;
-import com.android.settings.wifi.WifiSlice;
+import com.android.settings.slices.CustomSliceRegistry;
 import com.android.settingslib.utils.AsyncLoaderCompat;
 
 import java.util.ArrayList;
@@ -52,11 +49,17 @@
 
     private static final String TAG = "ContextualCardLoader";
 
-    private Context mContext;
+    private final ContentObserver mObserver = new ContentObserver(
+            new Handler(Looper.getMainLooper())) {
+        @Override
+        public void onChange(boolean selfChange) {
+            if (isStarted()) {
+                forceLoad();
+            }
+        }
+    };
 
-    public interface CardContentLoaderListener {
-        void onFinishCardLoading(List<ContextualCard> contextualCards);
-    }
+    private Context mContext;
 
     ContextualCardLoader(Context context) {
         super(context);
@@ -86,9 +89,7 @@
     public List<ContextualCard> loadInBackground() {
         final List<ContextualCard> result = new ArrayList<>();
         try (Cursor cursor = getContextualCardsFromProvider()) {
-            if (cursor.getCount() == 0) {
-                result.addAll(createStaticCards());
-            } else {
+            if (cursor.getCount() > 0) {
                 for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
                     final ContextualCard card = new ContextualCard(cursor);
                     if (card.isCustomCard()) {
@@ -131,24 +132,6 @@
     }
 
     @VisibleForTesting
-    List<ContextualCard> createStaticCards() {
-        final long appVersionCode = getAppVersionCode();
-        final String packageName = mContext.getPackageName();
-        final double rankingScore = 0.0;
-        final List<ContextualCard> result = new ArrayList();
-        result.add(new ContextualCard.Builder()
-                .setSliceUri(BatterySlice.BATTERY_CARD_URI)
-                .setName(BatterySlice.PATH_BATTERY_INFO)
-                .setPackageName(packageName)
-                .setRankingScore(rankingScore)
-                .setAppVersion(appVersionCode)
-                .setCardType(ContextualCard.CardType.SLICE)
-                .setIsHalfWidth(false)
-                .build());
-        return result;
-    }
-
-    @VisibleForTesting
     List<ContextualCard> filterEligibleCards(List<ContextualCard> candidates) {
         return candidates.stream().filter(card -> isCardEligibleToDisplay(card))
                 .collect(Collectors.toList());
@@ -186,28 +169,12 @@
 
     private int getNumberOfLargeCard(List<ContextualCard> cards) {
         return (int) cards.stream()
-                .filter(card -> card.getSliceUri().equals(WifiSlice.WIFI_URI)
-                        || card.getSliceUri().equals(ConnectedDeviceSlice.CONNECTED_DEVICE_URI))
+                .filter(card -> card.getSliceUri().equals(CustomSliceRegistry.WIFI_SLICE_URI)
+                        || card.getSliceUri().equals(CustomSliceRegistry.CONNECTED_DEVICE_SLICE_URI))
                 .count();
     }
 
-    private long getAppVersionCode() {
-        try {
-            return mContext.getPackageManager().getPackageInfo(mContext.getPackageName(),
-                    0 /* flags */).getLongVersionCode();
-        } catch (PackageManager.NameNotFoundException e) {
-            Log.e(TAG, "Invalid package name for context", e);
-        }
-        return -1L;
+    public interface CardContentLoaderListener {
+        void onFinishCardLoading(List<ContextualCard> contextualCards);
     }
-
-    private final ContentObserver mObserver = new ContentObserver(
-            new Handler(Looper.getMainLooper())) {
-        @Override
-        public void onChange(boolean selfChange) {
-            if (isStarted()) {
-                forceLoad();
-            }
-        }
-    };
-}
+}
\ No newline at end of file
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardLookupTable.java b/src/com/android/settings/homepage/contextualcards/ContextualCardLookupTable.java
index dabc88c..a4a8419 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCardLookupTable.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCardLookupTable.java
@@ -24,10 +24,14 @@
 import com.android.settings.homepage.contextualcards.ContextualCard.CardType;
 import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardController;
 import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardRenderer;
+import com.android.settings.homepage.contextualcards.conditional
+        .ConditionHeaderContextualCardRenderer;
 import com.android.settings.homepage.contextualcards.legacysuggestion
         .LegacySuggestionContextualCardController;
 import com.android.settings.homepage.contextualcards.legacysuggestion
         .LegacySuggestionContextualCardRenderer;
+import com.android.settings.homepage.contextualcards.conditional
+        .ConditionFooterContextualCardRenderer;
 import com.android.settings.homepage.contextualcards.slices.SliceContextualCardController;
 import com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer;
 
@@ -83,6 +87,14 @@
                         SliceContextualCardRenderer.VIEW_TYPE,
                         SliceContextualCardController.class,
                         SliceContextualCardRenderer.class));
+                add(new ControllerRendererMapping(CardType.CONDITIONAL_FOOTER,
+                        ConditionFooterContextualCardRenderer.VIEW_TYPE,
+                        ConditionContextualCardController.class,
+                        ConditionFooterContextualCardRenderer.class));
+                add(new ControllerRendererMapping(CardType.CONDITIONAL_HEADER,
+                        ConditionHeaderContextualCardRenderer.VIEW_TYPE,
+                        ConditionContextualCardController.class,
+                        ConditionHeaderContextualCardRenderer.class));
             }};
 
     public static Class<? extends ContextualCardController> getCardControllerClass(
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardManager.java b/src/com/android/settings/homepage/contextualcards/ContextualCardManager.java
index 30eae29..5f397d7 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCardManager.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCardManager.java
@@ -40,6 +40,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.TreeSet;
 import java.util.stream.Collectors;
 
 /**
@@ -132,8 +133,13 @@
         // except Conditional cards, all other cards are from the database. So when the map sent
         // here is empty, we only keep Conditional cards.
         if (cardTypes.isEmpty()) {
+            final Set<Integer> conditionalCardTypes = new TreeSet() {{
+                add(ContextualCard.CardType.CONDITIONAL);
+                add(ContextualCard.CardType.CONDITIONAL_HEADER);
+                add(ContextualCard.CardType.CONDITIONAL_FOOTER);
+            }};
             cardsToKeep = mContextualCards.stream()
-                    .filter(card -> card.getCardType() == ContextualCard.CardType.CONDITIONAL)
+                    .filter(card -> conditionalCardTypes.contains(card.getCardType()))
                     .collect(Collectors.toList());
         } else {
             cardsToKeep = mContextualCards.stream()
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardsAdapter.java b/src/com/android/settings/homepage/contextualcards/ContextualCardsAdapter.java
index 0a8749d..13b509d 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCardsAdapter.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCardsAdapter.java
@@ -99,7 +99,6 @@
                 @Override
                 public int getSpanSize(int position) {
                     final ContextualCard card = mContextualCards.get(position);
-                    //TODO(b/114009676): may use another field to make decision. still under review.
                     if (card.isHalfWidth()) {
                         return HALF_WIDTH;
                     }
@@ -129,5 +128,7 @@
             // Adding items to empty list, should animate.
             mRecyclerView.scheduleLayoutAnimation();
         }
+
+        //TODO(b/119465242): flickering conditional cards after collapsing/expanding
     }
 }
diff --git a/src/com/android/settings/homepage/contextualcards/ControllerRendererPool.java b/src/com/android/settings/homepage/contextualcards/ControllerRendererPool.java
index 931bfb7..992d4c9 100644
--- a/src/com/android/settings/homepage/contextualcards/ControllerRendererPool.java
+++ b/src/com/android/settings/homepage/contextualcards/ControllerRendererPool.java
@@ -26,10 +26,14 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardController;
 import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardRenderer;
+import com.android.settings.homepage.contextualcards.conditional
+        .ConditionHeaderContextualCardRenderer;
 import com.android.settings.homepage.contextualcards.legacysuggestion
         .LegacySuggestionContextualCardController;
 import com.android.settings.homepage.contextualcards.legacysuggestion
         .LegacySuggestionContextualCardRenderer;
+import com.android.settings.homepage.contextualcards.conditional
+        .ConditionFooterContextualCardRenderer;
 import com.android.settings.homepage.contextualcards.slices.SliceContextualCardController;
 import com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer;
 
@@ -131,6 +135,12 @@
         } else if (LegacySuggestionContextualCardRenderer.class == clz) {
             return new LegacySuggestionContextualCardRenderer(context,
                     this /* controllerRendererPool */);
+        } else if (ConditionFooterContextualCardRenderer.class == clz) {
+            return new ConditionFooterContextualCardRenderer(context,
+                    this /*controllerRendererPool*/);
+        } else if (ConditionHeaderContextualCardRenderer.class == clz) {
+            return new ConditionHeaderContextualCardRenderer(context,
+                    this /*controllerRendererPool*/);
         }
         return null;
     }
diff --git a/src/com/android/settings/homepage/contextualcards/SettingsContextualCardProvider.java b/src/com/android/settings/homepage/contextualcards/SettingsContextualCardProvider.java
index db3fddc..376bb83 100644
--- a/src/com/android/settings/homepage/contextualcards/SettingsContextualCardProvider.java
+++ b/src/com/android/settings/homepage/contextualcards/SettingsContextualCardProvider.java
@@ -16,17 +16,11 @@
 
 package com.android.settings.homepage.contextualcards;
 
-import static android.provider.SettingsSlicesContract.KEY_WIFI;
-
 import android.annotation.Nullable;
 
-import com.android.settings.homepage.contextualcards.deviceinfo.BatterySlice;
-import com.android.settings.homepage.contextualcards.slices.BatteryFixSlice;
-import com.android.settings.homepage.contextualcards.slices.ConnectedDeviceSlice;
-import com.android.settings.homepage.contextualcards.slices.LowStorageSlice;
 import com.android.settings.intelligence.ContextualCardProto.ContextualCard;
 import com.android.settings.intelligence.ContextualCardProto.ContextualCardList;
-import com.android.settings.wifi.WifiSlice;
+import com.android.settings.slices.CustomSliceRegistry;
 
 import com.google.android.settings.intelligence.libs.contextualcards.ContextualCardProvider;
 
@@ -40,37 +34,30 @@
     public ContextualCardList getContextualCards() {
         final ContextualCard wifiCard =
                 ContextualCard.newBuilder()
-                        .setSliceUri(WifiSlice.WIFI_URI.toString())
-                        .setCardName(KEY_WIFI)
+                        .setSliceUri(CustomSliceRegistry.WIFI_SLICE_URI.toString())
+                        .setCardName(CustomSliceRegistry.WIFI_SLICE_URI.toString())
                         .setCardCategory(ContextualCard.Category.IMPORTANT)
                         .build();
-        final ContextualCard batteryInfoCard =
-                ContextualCard.newBuilder()
-                        .setSliceUri(BatterySlice.BATTERY_CARD_URI.toString())
-                        .setCardName(BatterySlice.PATH_BATTERY_INFO)
-                        .setCardCategory(ContextualCard.Category.DEFAULT)
-                        .build();
         final ContextualCard connectedDeviceCard =
                 ContextualCard.newBuilder()
-                        .setSliceUri(ConnectedDeviceSlice.CONNECTED_DEVICE_URI.toString())
-                        .setCardName(ConnectedDeviceSlice.PATH_CONNECTED_DEVICE)
+                        .setSliceUri(CustomSliceRegistry.CONNECTED_DEVICE_SLICE_URI.toString())
+                        .setCardName(CustomSliceRegistry.CONNECTED_DEVICE_SLICE_URI.toString())
                         .setCardCategory(ContextualCard.Category.IMPORTANT)
                         .build();
         final ContextualCard lowStorageCard =
                 ContextualCard.newBuilder()
-                        .setSliceUri(LowStorageSlice.LOW_STORAGE_URI.toString())
-                        .setCardName(LowStorageSlice.PATH_LOW_STORAGE)
+                        .setSliceUri(CustomSliceRegistry.LOW_STORAGE_SLICE_URI.toString())
+                        .setCardName(CustomSliceRegistry.LOW_STORAGE_SLICE_URI.toString())
                         .setCardCategory(ContextualCard.Category.IMPORTANT)
                         .build();
         final ContextualCard batteryFixCard =
                 ContextualCard.newBuilder()
-                        .setSliceUri(BatteryFixSlice.BATTERY_FIX_URI.toString())
-                        .setCardName(BatteryFixSlice.PATH_BATTERY_FIX)
+                        .setSliceUri(CustomSliceRegistry.BATTERY_FIX_SLICE_URI.toString())
+                        .setCardName(CustomSliceRegistry.BATTERY_FIX_SLICE_URI.toString())
                         .setCardCategory(ContextualCard.Category.IMPORTANT)
                         .build();
         final ContextualCardList cards = ContextualCardList.newBuilder()
                 .addCard(wifiCard)
-                .addCard(batteryInfoCard)
                 .addCard(connectedDeviceCard)
                 .addCard(lowStorageCard)
                 .addCard(batteryFixCard)
@@ -78,4 +65,4 @@
 
         return cards;
     }
-}
+}
\ No newline at end of file
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardController.java b/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardController.java
index 6fcc636..02854c2 100644
--- a/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardController.java
+++ b/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardController.java
@@ -19,6 +19,8 @@
 import android.content.Context;
 import android.util.ArrayMap;
 
+import androidx.annotation.VisibleForTesting;
+
 import com.android.settings.homepage.contextualcards.ContextualCard;
 import com.android.settings.homepage.contextualcards.ContextualCardController;
 import com.android.settings.homepage.contextualcards.ContextualCardUpdateListener;
@@ -26,8 +28,11 @@
 import com.android.settingslib.core.lifecycle.events.OnStart;
 import com.android.settingslib.core.lifecycle.events.OnStop;
 
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * This controller triggers the loading of conditional cards and monitors state changes to
@@ -35,13 +40,18 @@
  */
 public class ConditionContextualCardController implements ContextualCardController,
         ConditionListener, LifecycleObserver, OnStart, OnStop {
+    public static final int EXPANDING_THRESHOLD = 2;
 
+    private static final double UNSUPPORTED_RANKING = -99999.0;
     private static final String TAG = "ConditionCtxCardCtrl";
+    private static final String CONDITION_FOOTER = "condition_footer";
+    private static final String CONDITION_HEADER = "condition_header";
 
     private final Context mContext;
     private final ConditionManager mConditionManager;
 
     private ContextualCardUpdateListener mListener;
+    private boolean mIsExpanded;
 
     public ConditionContextualCardController(Context context) {
         mContext = context;
@@ -49,6 +59,10 @@
         mConditionManager.startMonitoringStateChange();
     }
 
+    public void setIsExpanded(boolean isExpanded) {
+        mIsExpanded = isExpanded;
+    }
+
     @Override
     public void setCardUpdateListener(ContextualCardUpdateListener listener) {
         mListener = listener;
@@ -88,20 +102,102 @@
 
     @Override
     public void onConditionsChanged() {
+        if (mListener == null) {
+            return;
+        }
         final List<ContextualCard> conditionCards = mConditionManager.getDisplayableCards();
+        final Map<Integer, List<ContextualCard>> conditionalCards =
+                buildConditionalCardsWithFooterOrHeader(conditionCards);
+        mListener.onContextualCardUpdated(conditionalCards);
 
-        final boolean isOddNumber = conditionCards.size() % 2 == 1;
+    }
+
+    /**
+     * According to conditional cards, build a map that includes conditional cards, header card and
+     * footer card.
+     *
+     * Rules:
+     * - The last one of conditional cards will be displayed as a full-width card if the size of
+     * conditional cards is odd number. The rest will be displayed as a half-width card.
+     * - By default conditional cards will be collapsed if there are more than TWO cards.
+     *
+     * For examples:
+     * - Only one conditional card: Returns a map that contains a full-width conditional card,
+     * no header card and no footer card.
+     * <p>Map{(CONDITIONAL, conditionCards), (CONDITIONAL_FOOTER, EMPTY_LIST), (CONDITIONAL_HEADER,
+     * EMPTY_LIST)}</p>
+     * - Two conditional cards: Returns a map that contains two half-width conditional cards,
+     * no header card and no footer card.
+     * <p>Map{(CONDITIONAL, conditionCards), (CONDITIONAL_FOOTER, EMPTY_LIST), (CONDITIONAL_HEADER,
+     * EMPTY_LIST)}</p>
+     * - Three conditional cards or above: By default, returns a map that contains no conditional
+     * card, one header card and no footer card. If conditional cards are expanded, will returns a
+     * map that contains three conditional cards, no header card and one footer card.
+     * If expanding conditional cards:
+     * <p>Map{(CONDITIONAL, conditionCards), (CONDITIONAL_FOOTER, footerCards), (CONDITIONAL_HEADER,
+     * EMPTY_LIST)}</p>
+     * If collapsing conditional cards:
+     * <p>Map{(CONDITIONAL, EMPTY_LIST), (CONDITIONAL_FOOTER, EMPTY_LIST), (CONDITIONAL_HEADER,
+     * headerCards)}</p>
+     *
+     * @param conditionCards A list of conditional cards that are from {@link
+     * ConditionManager#getDisplayableCards}
+     * @return A map contained three types of lists
+     */
+    @VisibleForTesting
+    Map<Integer, List<ContextualCard>> buildConditionalCardsWithFooterOrHeader(
+            List<ContextualCard> conditionCards) {
+        final Map<Integer, List<ContextualCard>> conditionalCards = new ArrayMap<>();
+        conditionalCards.put(ContextualCard.CardType.CONDITIONAL,
+                getExpandedConditionalCards(conditionCards));
+        conditionalCards.put(ContextualCard.CardType.CONDITIONAL_FOOTER,
+                getConditionalFooterCard(conditionCards));
+        conditionalCards.put(ContextualCard.CardType.CONDITIONAL_HEADER,
+                getConditionalHeaderCard(conditionCards));
+        return conditionalCards;
+    }
+
+    private List<ContextualCard> getExpandedConditionalCards(List<ContextualCard> conditionCards) {
+        if (conditionCards.isEmpty() || (conditionCards.size() > EXPANDING_THRESHOLD
+                && !mIsExpanded)) {
+            return Collections.EMPTY_LIST;
+        }
+        final List<ContextualCard> expandedCards = conditionCards.stream().collect(
+                Collectors.toList());
+        final boolean isOddNumber = expandedCards.size() % 2 == 1;
         if (isOddNumber) {
-            final int lastIndex = conditionCards.size() - 1;
-            final ConditionalContextualCard card = (ConditionalContextualCard) conditionCards
-                    .get(lastIndex);
-            conditionCards.set(lastIndex, card.mutate().setIsHalfWidth(false).build());
+            final int lastIndex = expandedCards.size() - 1;
+            final ConditionalContextualCard card =
+                    (ConditionalContextualCard) expandedCards.get(lastIndex);
+            expandedCards.set(lastIndex, card.mutate().setIsHalfWidth(false).build());
         }
+        return expandedCards;
+    }
 
-        if (mListener != null) {
-            final Map<Integer, List<ContextualCard>> conditionalCards = new ArrayMap<>();
-            conditionalCards.put(ContextualCard.CardType.CONDITIONAL, conditionCards);
-            mListener.onContextualCardUpdated(conditionalCards);
+    private List<ContextualCard> getConditionalFooterCard(List<ContextualCard> conditionCards) {
+        if (!conditionCards.isEmpty() && mIsExpanded
+                && conditionCards.size() > EXPANDING_THRESHOLD) {
+            final List<ContextualCard> footerCards = new ArrayList<>();
+            footerCards.add(new ConditionFooterContextualCard.Builder()
+                    .setName(CONDITION_FOOTER)
+                    .setRankingScore(UNSUPPORTED_RANKING)
+                    .build());
+            return footerCards;
         }
+        return Collections.EMPTY_LIST;
+    }
+
+    private List<ContextualCard> getConditionalHeaderCard(List<ContextualCard> conditionCards) {
+        if (!conditionCards.isEmpty() && !mIsExpanded
+                && conditionCards.size() > EXPANDING_THRESHOLD) {
+            final List<ContextualCard> headerCards = new ArrayList<>();
+            headerCards.add(new ConditionHeaderContextualCard.Builder()
+                    .setConditionalCards(conditionCards)
+                    .setName(CONDITION_HEADER)
+                    .setRankingScore(UNSUPPORTED_RANKING)
+                    .build());
+            return headerCards;
+        }
+        return Collections.EMPTY_LIST;
     }
 }
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/ConditionFooterContextualCard.java b/src/com/android/settings/homepage/contextualcards/conditional/ConditionFooterContextualCard.java
new file mode 100644
index 0000000..17a5bfa
--- /dev/null
+++ b/src/com/android/settings/homepage/contextualcards/conditional/ConditionFooterContextualCard.java
@@ -0,0 +1,50 @@
+/*
+ * 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.homepage.contextualcards.conditional;
+
+import com.android.settings.homepage.contextualcards.ContextualCard;
+
+/**
+ * Data class representing a condition footer {@link ContextualCard}.
+ *
+ * Use this class for {@link ConditionFooterContextualCardRenderer} and
+ * {@link ConditionContextualCardController}.
+ */
+public class ConditionFooterContextualCard extends ContextualCard {
+
+    private ConditionFooterContextualCard(Builder builder) {
+        super(builder);
+    }
+
+    @Override
+    public int getCardType() {
+        return CardType.CONDITIONAL_FOOTER;
+    }
+
+    public static class Builder extends ContextualCard.Builder {
+
+        @Override
+        public Builder setCardType(int cardType) {
+            throw new IllegalArgumentException(
+                    "Cannot change card type for " + getClass().getName());
+        }
+
+        public ConditionFooterContextualCard build() {
+            return new ConditionFooterContextualCard(this);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/ConditionFooterContextualCardRenderer.java b/src/com/android/settings/homepage/contextualcards/conditional/ConditionFooterContextualCardRenderer.java
new file mode 100644
index 0000000..2465ca4
--- /dev/null
+++ b/src/com/android/settings/homepage/contextualcards/conditional/ConditionFooterContextualCardRenderer.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.homepage.contextualcards.conditional;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.view.View;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settings.homepage.contextualcards.ContextualCard;
+import com.android.settings.homepage.contextualcards.ContextualCardRenderer;
+import com.android.settings.homepage.contextualcards.ControllerRendererPool;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+
+public class ConditionFooterContextualCardRenderer implements ContextualCardRenderer {
+    public static final int VIEW_TYPE = R.layout.homepage_condition_footer;
+    private static final String TAG = "ConditionFooterRenderer";
+
+    private final Context mContext;
+    private final ControllerRendererPool mControllerRendererPool;
+
+    public ConditionFooterContextualCardRenderer(Context context,
+            ControllerRendererPool controllerRendererPool) {
+        mContext = context;
+        mControllerRendererPool = controllerRendererPool;
+    }
+
+    @Override
+    public int getViewType(boolean isHalfWidth) {
+        return VIEW_TYPE;
+    }
+
+    @Override
+    public RecyclerView.ViewHolder createViewHolder(View view) {
+        return new ConditionFooterCardHolder(view);
+    }
+
+    @Override
+    public void bindView(RecyclerView.ViewHolder holder, ContextualCard card) {
+        final MetricsFeatureProvider metricsFeatureProvider = FeatureFactory.getFactory(
+                mContext).getMetricsFeatureProvider();
+        holder.itemView.setOnClickListener(v -> {
+            metricsFeatureProvider.action(SettingsEnums.PAGE_UNKNOWN,
+                    MetricsProto.MetricsEvent.ACTION_SETTINGS_CONDITION_EXPAND,
+                    SettingsEnums.SETTINGS_HOMEPAGE,
+                    null /* key */,
+                    0 /* false */);
+            final ConditionContextualCardController controller =
+                    mControllerRendererPool.getController(mContext,
+                            ContextualCard.CardType.CONDITIONAL_FOOTER);
+            controller.setIsExpanded(false);
+            controller.onConditionsChanged();
+        });
+    }
+
+    public static class ConditionFooterCardHolder extends RecyclerView.ViewHolder {
+        public ConditionFooterCardHolder(View itemView) {
+            super(itemView);
+        }
+    }
+}
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/ConditionHeaderContextualCard.java b/src/com/android/settings/homepage/contextualcards/conditional/ConditionHeaderContextualCard.java
new file mode 100644
index 0000000..b72f9f7
--- /dev/null
+++ b/src/com/android/settings/homepage/contextualcards/conditional/ConditionHeaderContextualCard.java
@@ -0,0 +1,88 @@
+/*
+ * 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.homepage.contextualcards.conditional;
+
+import android.text.TextUtils;
+
+import com.android.settings.homepage.contextualcards.ContextualCard;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Data class representing a condition header {@link ContextualCard}.
+ *
+ * Use this class to store additional attributes on top of {@link ContextualCard} for
+ * {@link ConditionHeaderContextualCardRenderer} and {@link ConditionContextualCardController}.
+ */
+public class ConditionHeaderContextualCard extends ContextualCard {
+
+    private final List<ContextualCard> mConditionalCards;
+
+    private ConditionHeaderContextualCard(Builder builder) {
+        super(builder);
+        mConditionalCards = builder.mConditionalCards;
+    }
+
+    @Override
+    public int getCardType() {
+        return CardType.CONDITIONAL_HEADER;
+    }
+
+    public List<ContextualCard> getConditionalCards() {
+        return mConditionalCards;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getName(), mConditionalCards);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof ConditionHeaderContextualCard)) {
+            return false;
+        }
+        final ConditionHeaderContextualCard that = (ConditionHeaderContextualCard) obj;
+
+        return TextUtils.equals(getName(), that.getName()) && mConditionalCards.equals(
+                that.mConditionalCards);
+    }
+
+    public static class Builder extends ContextualCard.Builder {
+
+        private List<ContextualCard> mConditionalCards;
+
+        public Builder setConditionalCards(List<ContextualCard> conditionalCards) {
+            mConditionalCards = conditionalCards;
+            return this;
+        }
+
+        @Override
+        public Builder setCardType(int cardType) {
+            throw new IllegalArgumentException(
+                    "Cannot change card type for " + getClass().getName());
+        }
+
+        public ConditionHeaderContextualCard build() {
+            return new ConditionHeaderContextualCard(this);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/ConditionHeaderContextualCardRenderer.java b/src/com/android/settings/homepage/contextualcards/conditional/ConditionHeaderContextualCardRenderer.java
new file mode 100644
index 0000000..a98c82d
--- /dev/null
+++ b/src/com/android/settings/homepage/contextualcards/conditional/ConditionHeaderContextualCardRenderer.java
@@ -0,0 +1,97 @@
+/*
+ * 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.homepage.contextualcards.conditional;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settings.homepage.contextualcards.ContextualCard;
+import com.android.settings.homepage.contextualcards.ContextualCardRenderer;
+import com.android.settings.homepage.contextualcards.ControllerRendererPool;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+
+public class ConditionHeaderContextualCardRenderer implements ContextualCardRenderer {
+    public static final int VIEW_TYPE = R.layout.homepage_condition_header;
+    private static final String TAG = "ConditionHeaderRenderer";
+
+    private final Context mContext;
+    private final ControllerRendererPool mControllerRendererPool;
+
+    public ConditionHeaderContextualCardRenderer(Context context,
+            ControllerRendererPool controllerRendererPool) {
+        mContext = context;
+        mControllerRendererPool = controllerRendererPool;
+    }
+
+    @Override
+    public int getViewType(boolean isHalfWidth) {
+        return VIEW_TYPE;
+    }
+
+    @Override
+    public RecyclerView.ViewHolder createViewHolder(View view) {
+        return new ConditionHeaderCardHolder(view);
+    }
+
+    @Override
+    public void bindView(RecyclerView.ViewHolder holder, ContextualCard contextualCard) {
+        final ConditionHeaderContextualCard headerCard =
+                (ConditionHeaderContextualCard) contextualCard;
+        final ConditionHeaderCardHolder view = (ConditionHeaderCardHolder) holder;
+        final MetricsFeatureProvider metricsFeatureProvider = FeatureFactory.getFactory(
+                mContext).getMetricsFeatureProvider();
+        view.icons.removeAllViews();
+        headerCard.getConditionalCards().stream().forEach(card -> {
+            final ImageView icon = (ImageView) LayoutInflater.from(mContext).inflate(
+                    R.layout.homepage_condition_header_icon, view.icons, false);
+            icon.setImageDrawable(card.getIconDrawable());
+            view.icons.addView(icon);
+        });
+        view.itemView.setOnClickListener(v -> {
+            metricsFeatureProvider.action(SettingsEnums.PAGE_UNKNOWN,
+                    MetricsProto.MetricsEvent.ACTION_SETTINGS_CONDITION_EXPAND,
+                    SettingsEnums.SETTINGS_HOMEPAGE,
+                    null /* key */,
+                    1 /* true */);
+            final ConditionContextualCardController controller =
+                    mControllerRendererPool.getController(mContext,
+                            ContextualCard.CardType.CONDITIONAL_HEADER);
+            controller.setIsExpanded(true);
+            controller.onConditionsChanged();
+        });
+    }
+
+    public static class ConditionHeaderCardHolder extends RecyclerView.ViewHolder {
+        public final LinearLayout icons;
+        public final ImageView expandIndicator;
+
+        public ConditionHeaderCardHolder(View itemView) {
+            super(itemView);
+            icons = itemView.findViewById(R.id.header_icons_container);
+            expandIndicator = itemView.findViewById(R.id.expand_indicator);
+        }
+    }
+}
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/DndConditionCardController.java b/src/com/android/settings/homepage/contextualcards/conditional/DndConditionCardController.java
index 706b50e..cf91157 100644
--- a/src/com/android/settings/homepage/contextualcards/conditional/DndConditionCardController.java
+++ b/src/com/android/settings/homepage/contextualcards/conditional/DndConditionCardController.java
@@ -98,25 +98,12 @@
                 .setName(mAppContext.getPackageName() + "/"
                         + mAppContext.getText(R.string.condition_zen_title))
                 .setTitleText(mAppContext.getText(R.string.condition_zen_title).toString())
-                .setSummaryText(getSummary().toString())
+                .setSummaryText(mAppContext.getText(R.string.condition_zen_summary).toString())
                 .setIconDrawable(mAppContext.getDrawable(R.drawable.ic_do_not_disturb_on_24dp))
                 .setIsHalfWidth(true)
                 .build();
     }
 
-    public CharSequence getSummary() {
-        final int zen = mNotificationManager.getZenMode();
-        final ZenModeConfig config;
-        boolean zenModeEnabled = zen != Settings.Global.ZEN_MODE_OFF;
-        if (zenModeEnabled) {
-            config = mNotificationManager.getZenModeConfig();
-        } else {
-            config = null;
-        }
-        return ZenModeConfig.getDescription(mAppContext, zen != Settings.Global.ZEN_MODE_OFF,
-                config, true);
-    }
-
     public class Receiver extends BroadcastReceiver {
         @Override
         public void onReceive(Context context, Intent intent) {
diff --git a/src/com/android/settings/homepage/contextualcards/deviceinfo/BatterySlice.java b/src/com/android/settings/homepage/contextualcards/deviceinfo/BatterySlice.java
index 873b942..222e9dd 100644
--- a/src/com/android/settings/homepage/contextualcards/deviceinfo/BatterySlice.java
+++ b/src/com/android/settings/homepage/contextualcards/deviceinfo/BatterySlice.java
@@ -16,8 +16,9 @@
 
 package com.android.settings.homepage.contextualcards.deviceinfo;
 
+import static com.android.settings.slices.CustomSliceRegistry.BATTERY_INFO_SLICE_URI;
+
 import android.app.PendingIntent;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -37,7 +38,6 @@
 import com.android.settings.fuelgauge.BatteryInfo;
 import com.android.settings.fuelgauge.PowerUsageSummary;
 import com.android.settings.slices.CustomSliceable;
-import com.android.settings.slices.SettingsSliceProvider;
 import com.android.settings.slices.SliceBuilderUtils;
 
 /**
@@ -46,20 +46,6 @@
 public class BatterySlice implements CustomSliceable {
     private static final String TAG = "BatterySlice";
 
-    /**
-     * The path denotes the unique name of battery slice.
-     */
-    public static final String PATH_BATTERY_INFO = "battery_card";
-
-    /**
-     * Backing Uri for the Battery Slice.
-     */
-    public static final Uri BATTERY_CARD_URI = new Uri.Builder()
-            .scheme(ContentResolver.SCHEME_CONTENT)
-            .authority(SettingsSliceProvider.SLICE_AUTHORITY)
-            .appendPath(PATH_BATTERY_INFO)
-            .build();
-
     private final Context mContext;
 
     private BatteryInfo mBatteryInfo;
@@ -69,9 +55,6 @@
         mContext = context;
     }
 
-    /**
-     * Return a {@link BatterySlice} bound to {@link #BATTERY_CARD_URI}
-     */
     @Override
     public Slice getSlice() {
         if (mBatteryInfo == null) {
@@ -82,7 +65,7 @@
                 R.drawable.ic_settings_battery);
         final CharSequence title = mContext.getText(R.string.power_usage_summary_title);
         final SliceAction primarySliceAction = new SliceAction(getPrimaryAction(), icon, title);
-        final Slice slice = new ListBuilder(mContext, BATTERY_CARD_URI, ListBuilder.INFINITY)
+        final Slice slice = new ListBuilder(mContext, BATTERY_INFO_SLICE_URI, ListBuilder.INFINITY)
                 .setAccentColor(Utils.getColorAccentDefaultColor(mContext))
                 .setHeader(new ListBuilder.HeaderBuilder().setTitle(title))
                 .addRow(new ListBuilder.RowBuilder()
@@ -97,7 +80,7 @@
 
     @Override
     public Uri getUri() {
-        return BATTERY_CARD_URI;
+        return BATTERY_INFO_SLICE_URI;
     }
 
     @Override
@@ -108,12 +91,10 @@
     @Override
     public Intent getIntent() {
         final String screenTitle = mContext.getText(R.string.power_usage_summary_title).toString();
-        final Uri contentUri = new Uri.Builder().appendPath(PATH_BATTERY_INFO).build();
         return SliceBuilderUtils.buildSearchResultPageIntent(mContext,
-                PowerUsageSummary.class.getName(), PATH_BATTERY_INFO, screenTitle,
+                PowerUsageSummary.class.getName(), "" /* key */, screenTitle,
                 MetricsProto.MetricsEvent.SLICE)
-                .setClassName(mContext.getPackageName(), SubSettings.class.getName())
-                .setData(contentUri);
+                .setClassName(mContext.getPackageName(), SubSettings.class.getName());
     }
 
     @Override
diff --git a/src/com/android/settings/homepage/contextualcards/deviceinfo/DataUsageSlice.java b/src/com/android/settings/homepage/contextualcards/deviceinfo/DataUsageSlice.java
index 6296b1e..9be4b61 100644
--- a/src/com/android/settings/homepage/contextualcards/deviceinfo/DataUsageSlice.java
+++ b/src/com/android/settings/homepage/contextualcards/deviceinfo/DataUsageSlice.java
@@ -17,7 +17,6 @@
 package com.android.settings.homepage.contextualcards.deviceinfo;
 
 import android.app.PendingIntent;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.net.Uri;
@@ -39,8 +38,8 @@
 import com.android.settings.Utils;
 import com.android.settings.datausage.DataUsageSummary;
 import com.android.settings.datausage.DataUsageUtils;
+import com.android.settings.slices.CustomSliceRegistry;
 import com.android.settings.slices.CustomSliceable;
-import com.android.settings.slices.SettingsSliceProvider;
 import com.android.settings.slices.SliceBuilderUtils;
 import com.android.settingslib.net.DataUsageController;
 
@@ -50,19 +49,6 @@
     private static final String TAG = "DataUsageSlice";
     private static final long MILLIS_IN_A_DAY = TimeUnit.DAYS.toMillis(1);
 
-    /**
-     * The path denotes the unique name of data usage slice.
-     */
-    public static final String PATH_DATA_USAGE = "data_usage_card";
-
-    /**
-     * Backing Uri for the Data usage Slice.
-     */
-    public static final Uri DATA_USAGE_CARD_URI = new Uri.Builder()
-            .scheme(ContentResolver.SCHEME_CONTENT)
-            .authority(SettingsSliceProvider.SLICE_AUTHORITY)
-            .appendPath(PATH_DATA_USAGE)
-            .build();
 
     private final Context mContext;
 
@@ -72,12 +58,9 @@
 
     @Override
     public Uri getUri() {
-        return DATA_USAGE_CARD_URI;
+        return CustomSliceRegistry.DATA_USAGE_SLICE_URI;
     }
 
-    /**
-     * Return a Data usage Slice bound to {@link #DATA_USAGE_CARD_URI}
-     */
     @Override
     public Slice getSlice() {
         final IconCompat icon = IconCompat.createWithResource(mContext,
@@ -87,7 +70,8 @@
         final DataUsageController dataUsageController = new DataUsageController(mContext);
         final DataUsageController.DataUsageInfo info = dataUsageController.getDataUsageInfo();
         final ListBuilder listBuilder =
-                new ListBuilder(mContext, DATA_USAGE_CARD_URI, ListBuilder.INFINITY)
+                new ListBuilder(mContext, CustomSliceRegistry.DATA_USAGE_SLICE_URI,
+                        ListBuilder.INFINITY)
                         .setAccentColor(Utils.getColorAccentDefaultColor(mContext))
                         .setHeader(new ListBuilder.HeaderBuilder().setTitle(title));
         if (DataUsageUtils.hasSim(mContext)) {
@@ -106,12 +90,10 @@
     @Override
     public Intent getIntent() {
         final String screenTitle = mContext.getText(R.string.data_usage_wifi_title).toString();
-        final Uri contentUri = new Uri.Builder().appendPath(PATH_DATA_USAGE).build();
         return SliceBuilderUtils.buildSearchResultPageIntent(mContext,
-                DataUsageSummary.class.getName(), PATH_DATA_USAGE, screenTitle,
+                DataUsageSummary.class.getName(), "" /* key */, screenTitle,
                 MetricsProto.MetricsEvent.SLICE)
-                .setClassName(mContext.getPackageName(), SubSettings.class.getName())
-                .setData(contentUri);
+                .setClassName(mContext.getPackageName(), SubSettings.class.getName());
     }
 
     private PendingIntent getPrimaryAction() {
diff --git a/src/com/android/settings/homepage/contextualcards/deviceinfo/DeviceInfoSlice.java b/src/com/android/settings/homepage/contextualcards/deviceinfo/DeviceInfoSlice.java
index b8751f8..b7c662e 100644
--- a/src/com/android/settings/homepage/contextualcards/deviceinfo/DeviceInfoSlice.java
+++ b/src/com/android/settings/homepage/contextualcards/deviceinfo/DeviceInfoSlice.java
@@ -17,7 +17,6 @@
 package com.android.settings.homepage.contextualcards.deviceinfo;
 
 import android.app.PendingIntent;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.net.Uri;
@@ -39,8 +38,8 @@
 import com.android.settings.Utils;
 import com.android.settings.deviceinfo.DeviceModelPreferenceController;
 import com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment;
+import com.android.settings.slices.CustomSliceRegistry;
 import com.android.settings.slices.CustomSliceable;
-import com.android.settings.slices.SettingsSliceProvider;
 import com.android.settings.slices.SliceBuilderUtils;
 import com.android.settingslib.DeviceInfoUtils;
 
@@ -49,20 +48,6 @@
 public class DeviceInfoSlice implements CustomSliceable {
     private static final String TAG = "DeviceInfoSlice";
 
-    /**
-     * The path denotes the unique name of device info slice
-     */
-    public static final String PATH_DEVICE_INFO = "device_info_card";
-
-    /**
-     * Backing Uri for the Device info Slice.
-     */
-    public static final Uri DEVICE_INFO_CARD_URI = new Uri.Builder()
-            .scheme(ContentResolver.SCHEME_CONTENT)
-            .authority(SettingsSliceProvider.SLICE_AUTHORITY)
-            .appendPath(PATH_DEVICE_INFO)
-            .build();
-
     private final Context mContext;
     private final SubscriptionManager mSubscriptionManager;
 
@@ -71,16 +56,14 @@
         mSubscriptionManager = mContext.getSystemService(SubscriptionManager.class);
     }
 
-    /**
-     * Return a device info slice bound to {@Link #DEVICE_INFO_CARD_URI}
-     */
     @Override
     public Slice getSlice() {
         final IconCompat icon = IconCompat.createWithResource(mContext,
                 R.drawable.ic_info_outline_24dp);
         final String title = mContext.getString(R.string.device_info_label);
         final SliceAction primaryAction = new SliceAction(getPrimaryAction(), icon, title);
-        return new ListBuilder(mContext, DEVICE_INFO_CARD_URI, ListBuilder.INFINITY)
+        return new ListBuilder(mContext, CustomSliceRegistry.DEVICE_INFO_SLICE_URI,
+                ListBuilder.INFINITY)
                 .setAccentColor((Utils.getColorAccentDefaultColor(mContext)))
                 .setHeader(new ListBuilder.HeaderBuilder().setTitle(title))
                 .addRow(new ListBuilder.RowBuilder()
@@ -92,18 +75,16 @@
 
     @Override
     public Uri getUri() {
-        return DEVICE_INFO_CARD_URI;
+        return CustomSliceRegistry.DEVICE_INFO_SLICE_URI;
     }
 
     @Override
     public Intent getIntent() {
         final String screenTitle = mContext.getText(R.string.device_info_label).toString();
-        final Uri contentUri = new Uri.Builder().appendPath(PATH_DEVICE_INFO).build();
         return SliceBuilderUtils.buildSearchResultPageIntent(mContext,
-                MyDeviceInfoFragment.class.getName(), PATH_DEVICE_INFO, screenTitle,
+                MyDeviceInfoFragment.class.getName(), "" /* key */, screenTitle,
                 MetricsProto.MetricsEvent.SLICE)
-                .setClassName(mContext.getPackageName(), SubSettings.class.getName())
-                .setData(contentUri);
+                .setClassName(mContext.getPackageName(), SubSettings.class.getName());
     }
 
     private PendingIntent getPrimaryAction() {
diff --git a/src/com/android/settings/homepage/contextualcards/deviceinfo/EmergencyInfoSlice.java b/src/com/android/settings/homepage/contextualcards/deviceinfo/EmergencyInfoSlice.java
index aff34f4..dfadc72 100644
--- a/src/com/android/settings/homepage/contextualcards/deviceinfo/EmergencyInfoSlice.java
+++ b/src/com/android/settings/homepage/contextualcards/deviceinfo/EmergencyInfoSlice.java
@@ -17,10 +17,8 @@
 package com.android.settings.homepage.contextualcards.deviceinfo;
 
 import android.app.PendingIntent;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
-import android.net.Uri;
 
 import androidx.core.graphics.drawable.IconCompat;
 import androidx.slice.Slice;
@@ -28,39 +26,27 @@
 import androidx.slice.builders.SliceAction;
 
 import com.android.settings.R;
-import com.android.settings.slices.SettingsSliceProvider;
+import com.android.settings.slices.CustomSliceRegistry;
 
 // This is a slice helper class for EmergencyInfo
 public class EmergencyInfoSlice {
-    /**
-     * The path denotes the unique name of emergency info slice.
-     */
-    public static final String PATH_EMERGENCY_INFO_CARD = "emergency_info_card";
-
-    /**
-     * Backing Uri for the Emergency Info Slice.
-     */
-    public static final Uri EMERGENCY_INFO_CARD_URI = new Uri.Builder()
-            .scheme(ContentResolver.SCHEME_CONTENT)
-            .authority(SettingsSliceProvider.SLICE_AUTHORITY)
-            .appendPath(PATH_EMERGENCY_INFO_CARD)
-            .build();
 
     private static final String ACTION_EDIT_EMERGENCY_INFO = "android.settings.EDIT_EMERGENCY_INFO";
 
     public static Slice getSlice(Context context) {
-        final ListBuilder listBuilder = new ListBuilder(context, EMERGENCY_INFO_CARD_URI,
+        final ListBuilder listBuilder = new ListBuilder(context,
+                CustomSliceRegistry.EMERGENCY_INFO_SLICE_URI,
                 ListBuilder.INFINITY);
         listBuilder.addRow(
                 new ListBuilder.RowBuilder()
                         .setTitle(context.getText(R.string.emergency_info_title))
                         .setSubtitle(
                                 context.getText(R.string.emergency_info_contextual_card_summary))
-                        .setPrimaryAction(generatePrimaryAction(context)));
+                        .setPrimaryAction(createPrimaryAction(context)));
         return listBuilder.build();
     }
 
-    private static SliceAction generatePrimaryAction(Context context) {
+    private static SliceAction createPrimaryAction(Context context) {
         PendingIntent pendingIntent =
                 PendingIntent.getActivity(
                         context,
diff --git a/src/com/android/settings/homepage/contextualcards/deviceinfo/StorageSlice.java b/src/com/android/settings/homepage/contextualcards/deviceinfo/StorageSlice.java
index c61a8a0..1e07f7a 100644
--- a/src/com/android/settings/homepage/contextualcards/deviceinfo/StorageSlice.java
+++ b/src/com/android/settings/homepage/contextualcards/deviceinfo/StorageSlice.java
@@ -17,7 +17,6 @@
 package com.android.settings.homepage.contextualcards.deviceinfo;
 
 import android.app.PendingIntent;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.net.Uri;
@@ -36,8 +35,8 @@
 import com.android.settings.Utils;
 import com.android.settings.deviceinfo.StorageDashboardFragment;
 import com.android.settings.deviceinfo.storage.StorageSummaryDonutPreferenceController;
+import com.android.settings.slices.CustomSliceRegistry;
 import com.android.settings.slices.CustomSliceable;
-import com.android.settings.slices.SettingsSliceProvider;
 import com.android.settings.slices.SliceBuilderUtils;
 import com.android.settingslib.deviceinfo.PrivateStorageInfo;
 import com.android.settingslib.deviceinfo.StorageManagerVolumeProvider;
@@ -45,20 +44,6 @@
 public class StorageSlice implements CustomSliceable {
     private static final String TAG = "StorageSlice";
 
-    /**
-     * The path denotes the unique name of storage slicel
-     */
-    public static final String PATH_STORAGE_INFO = "storage_card";
-
-    /**
-     * Backing Uri for the storage slice.
-     */
-    public static final Uri STORAGE_CARD_URI = new Uri.Builder()
-            .scheme(ContentResolver.SCHEME_CONTENT)
-            .authority(SettingsSliceProvider.SLICE_AUTHORITY)
-            .appendPath(PATH_STORAGE_INFO)
-            .build();
-
     private final Context mContext;
 
     public StorageSlice(Context context) {
@@ -67,12 +52,9 @@
 
     @Override
     public Uri getUri() {
-        return STORAGE_CARD_URI;
+        return CustomSliceRegistry.STORAGE_SLICE_URI;
     }
 
-    /**
-     * Return a storage slice bound to {@link #STORAGE_CARD_URI}
-     */
     @Override
     public Slice getSlice() {
         final IconCompat icon = IconCompat.createWithResource(mContext,
@@ -80,7 +62,8 @@
         final String title = mContext.getString(R.string.storage_label);
         final SliceAction primaryAction = new SliceAction(getPrimaryAction(), icon, title);
         final PrivateStorageInfo info = getPrivateStorageInfo();
-        return new ListBuilder(mContext, STORAGE_CARD_URI, ListBuilder.INFINITY)
+        return new ListBuilder(mContext, CustomSliceRegistry.STORAGE_SLICE_URI,
+                ListBuilder.INFINITY)
                 .setAccentColor(Utils.getColorAccentDefaultColor(mContext))
                 .setHeader(new ListBuilder.HeaderBuilder().setTitle(title))
                 .addRow(new ListBuilder.RowBuilder()
@@ -93,12 +76,10 @@
     @Override
     public Intent getIntent() {
         final String screenTitle = mContext.getText(R.string.storage_label).toString();
-        final Uri contentUri = new Uri.Builder().appendPath(PATH_STORAGE_INFO).build();
         return SliceBuilderUtils.buildSearchResultPageIntent(mContext,
-                StorageDashboardFragment.class.getName(), PATH_STORAGE_INFO, screenTitle,
+                StorageDashboardFragment.class.getName(), "" /* key */, screenTitle,
                 MetricsProto.MetricsEvent.SLICE)
-                .setClassName(mContext.getPackageName(), SubSettings.class.getName())
-                .setData(contentUri);
+                .setClassName(mContext.getPackageName(), SubSettings.class.getName());
     }
 
     private PendingIntent getPrimaryAction() {
diff --git a/src/com/android/settings/homepage/contextualcards/slices/BatteryFixSlice.java b/src/com/android/settings/homepage/contextualcards/slices/BatteryFixSlice.java
index 23ff172..cae222a 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/BatteryFixSlice.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/BatteryFixSlice.java
@@ -19,7 +19,6 @@
 import static android.content.Context.MODE_PRIVATE;
 
 import android.app.PendingIntent;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
@@ -34,7 +33,6 @@
 import androidx.slice.builders.SliceAction;
 
 import com.android.internal.logging.nano.MetricsProto;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.os.BatteryStatsHelper;
 import com.android.settings.R;
 import com.android.settings.SubSettings;
@@ -42,9 +40,10 @@
 import com.android.settings.fuelgauge.BatteryStatsHelperLoader;
 import com.android.settings.fuelgauge.PowerUsageSummary;
 import com.android.settings.fuelgauge.batterytip.BatteryTipLoader;
+import com.android.settings.fuelgauge.batterytip.BatteryTipPreferenceController;
 import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
+import com.android.settings.slices.CustomSliceRegistry;
 import com.android.settings.slices.CustomSliceable;
-import com.android.settings.slices.SettingsSliceProvider;
 import com.android.settings.slices.SliceBackgroundWorker;
 import com.android.settings.slices.SliceBuilderUtils;
 import com.android.settingslib.utils.ThreadUtils;
@@ -53,20 +52,6 @@
 
 public class BatteryFixSlice implements CustomSliceable {
 
-    /**
-     * Unique name of Battery Fix Slice.
-     */
-    public static final String PATH_BATTERY_FIX = "battery_fix";
-
-    /**
-     * Uri for Battery Fix Slice.
-     */
-    public static final Uri BATTERY_FIX_URI = new Uri.Builder()
-            .scheme(ContentResolver.SCHEME_CONTENT)
-            .authority(SettingsSliceProvider.SLICE_AUTHORITY)
-            .appendPath(PATH_BATTERY_FIX)
-            .build();
-
     @VisibleForTesting
     static final String PREFS = "battery_fix_prefs";
     @VisibleForTesting
@@ -82,12 +67,9 @@
 
     @Override
     public Uri getUri() {
-        return BATTERY_FIX_URI;
+        return CustomSliceRegistry.BATTERY_FIX_SLICE_URI;
     }
 
-    /**
-     * Return a Slice bound to {@link #BATTERY_FIX_URI}.
-     */
     @Override
     public Slice getSlice() {
         IconCompat icon;
@@ -109,7 +91,8 @@
                     primaryAction = new SliceAction(getPrimaryAction(),
                             icon,
                             batteryTip.getTitle(mContext));
-                    slice = new ListBuilder(mContext, BATTERY_FIX_URI, ListBuilder.INFINITY)
+                    slice = new ListBuilder(mContext, CustomSliceRegistry.BATTERY_FIX_SLICE_URI,
+                            ListBuilder.INFINITY)
                             .setAccentColor(Utils.getColorAccentDefaultColor(mContext))
                             .addRow(new RowBuilder()
                                     .setTitle(batteryTip.getTitle(mContext))
@@ -125,7 +108,8 @@
                     R.drawable.ic_battery_status_good_24dp);
             final String title = mContext.getString(R.string.power_usage_summary_title);
             primaryAction = new SliceAction(getPrimaryAction(), icon, title);
-            slice = new ListBuilder(mContext, BATTERY_FIX_URI, ListBuilder.INFINITY)
+            slice = new ListBuilder(mContext, CustomSliceRegistry.BATTERY_FIX_SLICE_URI,
+                    ListBuilder.INFINITY)
                     .setAccentColor(Utils.getColorAccentDefaultColor(mContext))
                     .addRow(new RowBuilder()
                             .setTitle(title)
@@ -140,10 +124,11 @@
     public Intent getIntent() {
         final String screenTitle = mContext.getText(R.string.power_usage_summary_title)
                 .toString();
-        final Uri contentUri = new Uri.Builder().appendPath(PATH_BATTERY_FIX).build();
+        final Uri contentUri = new Uri.Builder()
+                .appendPath(BatteryTipPreferenceController.PREF_NAME).build();
 
         return SliceBuilderUtils.buildSearchResultPageIntent(mContext,
-                PowerUsageSummary.class.getName(), PATH_BATTERY_FIX,
+                PowerUsageSummary.class.getName(), BatteryTipPreferenceController.PREF_NAME,
                 screenTitle,
                 MetricsProto.MetricsEvent.SLICE)
                 .setClassName(mContext.getPackageName(), SubSettings.class.getName())
diff --git a/src/com/android/settings/homepage/contextualcards/slices/ConnectedDeviceSlice.java b/src/com/android/settings/homepage/contextualcards/slices/ConnectedDeviceSlice.java
index ef7c1bd..fe907f3 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/ConnectedDeviceSlice.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/ConnectedDeviceSlice.java
@@ -18,7 +18,6 @@
 
 import android.app.PendingIntent;
 import android.bluetooth.BluetoothAdapter;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Bitmap;
@@ -43,8 +42,8 @@
 import com.android.settings.bluetooth.BluetoothDeviceDetailsFragment;
 import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment;
 import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.slices.CustomSliceRegistry;
 import com.android.settings.slices.CustomSliceable;
-import com.android.settings.slices.SettingsSliceProvider;
 import com.android.settings.slices.SliceBuilderUtils;
 import com.android.settingslib.bluetooth.BluetoothUtils;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
@@ -68,20 +67,6 @@
 public class ConnectedDeviceSlice implements CustomSliceable {
 
     /**
-     * The path denotes the unique name of Connected device Slice.
-     */
-    public static final String PATH_CONNECTED_DEVICE = "connected_device";
-
-    /**
-     * Backing Uri for Connected device Slice.
-     */
-    public static final Uri CONNECTED_DEVICE_URI = new Uri.Builder()
-            .scheme(ContentResolver.SCHEME_CONTENT)
-            .authority(SettingsSliceProvider.SLICE_AUTHORITY)
-            .appendPath(PATH_CONNECTED_DEVICE)
-            .build();
-
-    /**
      * To sort the Bluetooth devices by {@link CachedBluetoothDevice}.
      * Refer compareTo method from {@link com.android.settings.bluetooth.BluetoothDevicePreference}.
      */
@@ -109,12 +94,9 @@
 
     @Override
     public Uri getUri() {
-        return CONNECTED_DEVICE_URI;
+        return CustomSliceRegistry.CONNECTED_DEVICE_SLICE_URI;
     }
 
-    /**
-     * Return a Connected Device Slice bound to {@link #CONNECTED_DEVICE_URI}.
-     */
     @Override
     public Slice getSlice() {
         final IconCompat icon = IconCompat.createWithResource(mContext,
@@ -127,7 +109,8 @@
         final SliceAction primarySliceAction = new SliceAction(primaryActionIntent, icon,
                 title);
         final ListBuilder listBuilder =
-                new ListBuilder(mContext, CONNECTED_DEVICE_URI, ListBuilder.INFINITY)
+                new ListBuilder(mContext, CustomSliceRegistry.CONNECTED_DEVICE_SLICE_URI,
+                        ListBuilder.INFINITY)
                         .setAccentColor(Utils.getColorAccentDefaultColor(mContext));
 
         // Get row builders by connected devices, e.g. Bluetooth.
@@ -159,14 +142,12 @@
     public Intent getIntent() {
         final String screenTitle = mContext.getText(R.string.connected_devices_dashboard_title)
                 .toString();
-        final Uri contentUri = new Uri.Builder().appendPath(PATH_CONNECTED_DEVICE).build();
 
         return SliceBuilderUtils.buildSearchResultPageIntent(mContext,
-                ConnectedDeviceDashboardFragment.class.getName(), PATH_CONNECTED_DEVICE,
+                ConnectedDeviceDashboardFragment.class.getName(), "" /* key */,
                 screenTitle,
                 MetricsProto.MetricsEvent.SLICE)
-                .setClassName(mContext.getPackageName(), SubSettings.class.getName())
-                .setData(contentUri);
+                .setClassName(mContext.getPackageName(), SubSettings.class.getName());
     }
 
     @Override
diff --git a/src/com/android/settings/homepage/contextualcards/slices/LowStorageSlice.java b/src/com/android/settings/homepage/contextualcards/slices/LowStorageSlice.java
index 7f6efcc..b3b0b0a 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/LowStorageSlice.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/LowStorageSlice.java
@@ -17,7 +17,6 @@
 package com.android.settings.homepage.contextualcards.slices;
 
 import android.app.PendingIntent;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.net.Uri;
@@ -36,8 +35,8 @@
 import com.android.settings.SubSettings;
 import com.android.settings.Utils;
 import com.android.settings.deviceinfo.StorageSettings;
+import com.android.settings.slices.CustomSliceRegistry;
 import com.android.settings.slices.CustomSliceable;
-import com.android.settings.slices.SettingsSliceProvider;
 import com.android.settings.slices.SliceBuilderUtils;
 import com.android.settingslib.deviceinfo.PrivateStorageInfo;
 import com.android.settingslib.deviceinfo.StorageManagerVolumeProvider;
@@ -46,20 +45,6 @@
 
 public class LowStorageSlice implements CustomSliceable {
 
-    /**
-     * The path denotes the unique name of Low storage Slice.
-     */
-    public static final String PATH_LOW_STORAGE = "low_storage";
-
-    /**
-     * Backing Uri for Low storage Slice.
-     */
-    public static final Uri LOW_STORAGE_URI = new Uri.Builder()
-            .scheme(ContentResolver.SCHEME_CONTENT)
-            .authority(SettingsSliceProvider.SLICE_AUTHORITY)
-            .appendPath(PATH_LOW_STORAGE)
-            .build();
-
     private static final String TAG = "LowStorageSlice";
 
     /**
@@ -73,9 +58,6 @@
         mContext = context;
     }
 
-    /**
-     * Return a Low storage Slice bound to {@link #LOW_STORAGE_URI}
-     */
     @Override
     public Slice getSlice() {
         // Get current storage percentage from StorageManager.
@@ -108,7 +90,8 @@
          * Slices doesn't support "Icon on the left" in header. Now we intend to start with Icon
          * right aligned. Will update the icon to left until Slices support it.
          */
-        return new ListBuilder(mContext, LOW_STORAGE_URI, ListBuilder.INFINITY)
+        return new ListBuilder(mContext, CustomSliceRegistry.LOW_STORAGE_SLICE_URI,
+                ListBuilder.INFINITY)
                 .setAccentColor(Utils.getColorAccentDefaultColor(mContext))
                 .addRow(new RowBuilder()
                         .setTitle(title)
@@ -120,7 +103,7 @@
 
     @Override
     public Uri getUri() {
-        return LOW_STORAGE_URI;
+        return CustomSliceRegistry.LOW_STORAGE_SLICE_URI;
     }
 
     @Override
@@ -132,13 +115,11 @@
     public Intent getIntent() {
         final String screenTitle = mContext.getText(R.string.storage_label)
                 .toString();
-        final Uri contentUri = new Uri.Builder().appendPath(PATH_LOW_STORAGE).build();
 
         return SliceBuilderUtils.buildSearchResultPageIntent(mContext,
-                StorageSettings.class.getName(), PATH_LOW_STORAGE,
+                StorageSettings.class.getName(), "" /* key */,
                 screenTitle,
                 MetricsProto.MetricsEvent.SLICE)
-                .setClassName(mContext.getPackageName(), SubSettings.class.getName())
-                .setData(contentUri);
+                .setClassName(mContext.getPackageName(), SubSettings.class.getName());
     }
 }
\ No newline at end of file
diff --git a/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardController.java b/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardController.java
index f1fbc9c..4378be3 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardController.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardController.java
@@ -17,12 +17,19 @@
 package com.android.settings.homepage.contextualcards.slices;
 
 import android.content.Context;
+import android.content.Intent;
+import android.text.TextUtils;
 
-import com.android.settings.homepage.contextualcards.CardContentProvider;
+import androidx.annotation.VisibleForTesting;
+
+import com.android.settings.R;
 import com.android.settings.homepage.contextualcards.CardDatabaseHelper;
 import com.android.settings.homepage.contextualcards.ContextualCard;
 import com.android.settings.homepage.contextualcards.ContextualCardController;
+import com.android.settings.homepage.contextualcards.ContextualCardFeatureProvider;
+import com.android.settings.homepage.contextualcards.ContextualCardFeedbackDialog;
 import com.android.settings.homepage.contextualcards.ContextualCardUpdateListener;
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.utils.ThreadUtils;
 
 /**
@@ -32,7 +39,8 @@
 
     private static final String TAG = "SliceCardController";
 
-    private Context mContext;
+    private final Context mContext;
+
     private ContextualCardUpdateListener mCardUpdateListener;
 
     public SliceContextualCardController(Context context) {
@@ -51,7 +59,7 @@
 
     @Override
     public void onActionClick(ContextualCard card) {
-        //TODO(b/113783548): Implement feedback mechanism
+
     }
 
     @Override
@@ -60,10 +68,33 @@
             final CardDatabaseHelper dbHelper = CardDatabaseHelper.getInstance(mContext);
             dbHelper.markContextualCardAsDismissed(mContext, card.getName());
         });
+        showFeedbackDialog(card);
+        final ContextualCardFeatureProvider contexualCardFeatureProvider =
+                FeatureFactory.getFactory(mContext).getContextualCardFeatureProvider();
+        contexualCardFeatureProvider.logContextualCardDismiss(mContext, card);
     }
 
     @Override
     public void setCardUpdateListener(ContextualCardUpdateListener listener) {
         mCardUpdateListener = listener;
     }
+
+    @VisibleForTesting
+    void showFeedbackDialog(ContextualCard card) {
+        final String email = mContext.getString(R.string.config_contextual_card_feedback_email);
+        if (TextUtils.isEmpty(email)) {
+            return;
+        }
+        final Intent feedbackIntent = new Intent(mContext, ContextualCardFeedbackDialog.class);
+        feedbackIntent.putExtra(ContextualCardFeedbackDialog.EXTRA_CARD_NAME,
+                getSimpleCardName(card));
+        feedbackIntent.putExtra(ContextualCardFeedbackDialog.EXTRA_FEEDBACK_EMAIL, email);
+        feedbackIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivity(feedbackIntent);
+    }
+
+    private String getSimpleCardName(ContextualCard card) {
+        final String[] split = card.getName().split("/");
+        return split[split.length - 1];
+    }
 }
diff --git a/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java b/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java
index 74f25eb..a2d6e2b 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.net.Uri;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.Log;
 import android.view.View;
 import android.widget.Button;
@@ -38,10 +39,13 @@
 
 import com.android.settings.R;
 import com.android.settings.homepage.contextualcards.ContextualCard;
+import com.android.settings.homepage.contextualcards.ContextualCardFeatureProvider;
 import com.android.settings.homepage.contextualcards.ContextualCardRenderer;
 import com.android.settings.homepage.contextualcards.ControllerRendererPool;
+import com.android.settings.overlay.FeatureFactory;
 
 import java.util.Map;
+import java.util.Set;
 
 /**
  * Card renderer for {@link ContextualCard} built as slices.
@@ -58,6 +62,7 @@
     private final Context mContext;
     private final LifecycleOwner mLifecycleOwner;
     private final ControllerRendererPool mControllerRendererPool;
+    private final Set<ContextualCard> mCardSet;
 
     public SliceContextualCardRenderer(Context context, LifecycleOwner lifecycleOwner,
             ControllerRendererPool controllerRendererPool) {
@@ -65,6 +70,7 @@
         mLifecycleOwner = lifecycleOwner;
         mSliceLiveDataMap = new ArrayMap<>();
         mControllerRendererPool = controllerRendererPool;
+        mCardSet = new ArraySet<>();
     }
 
     @Override
@@ -99,6 +105,7 @@
             sliceLiveData = SliceLiveData.fromUri(mContext, uri);
             mSliceLiveDataMap.put(uri.toString(), sliceLiveData);
         }
+        mCardSet.add(card);
 
         sliceLiveData.removeObservers(mLifecycleOwner);
         sliceLiveData.observe(mLifecycleOwner, slice -> {
@@ -128,14 +135,27 @@
 
         final Button btnRemove = cardHolder.itemView.findViewById(R.id.remove);
         btnRemove.setOnClickListener(v -> {
-            mControllerRendererPool.getController(mContext, card.getCardType()).onDismissed(
-                    card);
+            mControllerRendererPool.getController(mContext, card.getCardType()).onDismissed(card);
         });
     }
 
     @Override
     public void onSliceAction(@NonNull EventInfo eventInfo, @NonNull SliceItem sliceItem) {
         //TODO(b/79698338): Log user interaction
+
+        // sliceItem.getSlice().getUri() is like
+        // content://android.settings.slices/action/wifi/_gen/0/_gen/0
+        // contextualCard.getSliceUri() is prefix of sliceItem.getSlice().getUri()
+        for (ContextualCard card : mCardSet) {
+            if (sliceItem.getSlice().getUri().toString().startsWith(
+                    card.getSliceUri().toString())) {
+                ContextualCardFeatureProvider contexualCardFeatureProvider =
+                        FeatureFactory.getFactory(mContext).getContextualCardFeatureProvider();
+                contexualCardFeatureProvider.logContextualCardClick(mContext, card,
+                        eventInfo.rowIndex, eventInfo.actionType);
+                break;
+            }
+        }
     }
 
     public static class SliceViewHolder extends RecyclerView.ViewHolder {
diff --git a/src/com/android/settings/location/LocationSliceBuilder.java b/src/com/android/settings/location/LocationSliceBuilder.java
index 56cf676..1d79ada 100644
--- a/src/com/android/settings/location/LocationSliceBuilder.java
+++ b/src/com/android/settings/location/LocationSliceBuilder.java
@@ -23,11 +23,9 @@
 
 import android.annotation.ColorInt;
 import android.app.PendingIntent;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.net.Uri;
-import android.provider.SettingsSlicesContract;
 
 import androidx.core.graphics.drawable.IconCompat;
 import androidx.slice.Slice;
@@ -39,6 +37,7 @@
 import com.android.settings.R;
 import com.android.settings.SubSettings;
 import com.android.settings.Utils;
+import com.android.settings.slices.CustomSliceRegistry;
 import com.android.settings.slices.SliceBuilderUtils;
 
 /**
@@ -46,21 +45,11 @@
  */
 public class LocationSliceBuilder {
 
-    /**
-     * Backing Uri for the Location Slice.
-     */
-    public static final Uri LOCATION_URI = new Uri.Builder()
-            .scheme(ContentResolver.SCHEME_CONTENT)
-            .authority(SettingsSlicesContract.AUTHORITY)
-            .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
-            .appendPath(KEY_LOCATION)
-            .build();
-
     private LocationSliceBuilder() {
     }
 
     /**
-     * Return a Location Slice bound to {@link #LOCATION_URI}.
+     * Return a Location Slice bound to {@link CustomSliceRegistry#LOCATION_SLICE_URI}.
      */
     public static Slice getSlice(Context context) {
         final IconCompat icon = IconCompat.createWithResource(context,
@@ -70,7 +59,8 @@
         final PendingIntent primaryAction = getPrimaryAction(context);
         final SliceAction primarySliceAction = new SliceAction(primaryAction, icon, title);
 
-        return new ListBuilder(context, LOCATION_URI, ListBuilder.INFINITY)
+        return new ListBuilder(context, CustomSliceRegistry.LOCATION_SLICE_URI,
+                ListBuilder.INFINITY)
                 .setAccentColor(color)
                 .addRow(new RowBuilder()
                         .setTitle(title)
diff --git a/src/com/android/settings/network/AirplaneModePreferenceController.java b/src/com/android/settings/network/AirplaneModePreferenceController.java
index 80cca2c..1c4e351 100644
--- a/src/com/android/settings/network/AirplaneModePreferenceController.java
+++ b/src/com/android/settings/network/AirplaneModePreferenceController.java
@@ -93,7 +93,7 @@
 
     @Override
     public boolean isSliceable() {
-        return TextUtils.equals(getPreferenceKey(), "toggle_airplane");
+        return true;
     }
 
     @Override
diff --git a/src/com/android/settings/network/ApnPreference.java b/src/com/android/settings/network/ApnPreference.java
index a7fbb6e..f039539 100755
--- a/src/com/android/settings/network/ApnPreference.java
+++ b/src/com/android/settings/network/ApnPreference.java
@@ -27,6 +27,7 @@
 import android.view.View;
 import android.widget.CompoundButton;
 import android.widget.RadioButton;
+import android.widget.Toast;
 
 import androidx.preference.Preference;
 import androidx.preference.PreferenceViewHolder;
@@ -54,6 +55,7 @@
     private static CompoundButton mCurrentChecked = null;
     private boolean mProtectFromCheckedChange = false;
     private boolean mSelectable = true;
+    private boolean mHideDetails = false;
 
     @Override
     public void onBindViewHolder(PreferenceViewHolder view) {
@@ -113,6 +115,11 @@
         super.onClick();
         Context context = getContext();
         if (context != null) {
+            if (mHideDetails) {
+                Toast.makeText(context, context.getString(
+                        R.string.cannot_change_apn_toast), Toast.LENGTH_LONG).show();
+                return;
+            }
             int pos = Integer.parseInt(getKey());
             Uri url = ContentUris.withAppendedId(Telephony.Carriers.CONTENT_URI, pos);
             Intent editIntent = new Intent(Intent.ACTION_EDIT, url);
@@ -132,4 +139,8 @@
     public void setSubId(int subId) {
         mSubId = subId;
     }
+
+    public void setHideDetails() {
+        mHideDetails = true;
+    }
 }
diff --git a/src/com/android/settings/network/ApnSettings.java b/src/com/android/settings/network/ApnSettings.java
index a71dfaa..4bd964e 100755
--- a/src/com/android/settings/network/ApnSettings.java
+++ b/src/com/android/settings/network/ApnSettings.java
@@ -40,7 +40,6 @@
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
-import android.telephony.data.ApnSetting;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.Menu;
@@ -55,8 +54,6 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.TelephonyIntents;
-import com.android.internal.telephony.dataconnection.ApnSettingUtils;
-import com.android.internal.telephony.uicc.IccRecords;
 import com.android.internal.telephony.uicc.UiccController;
 import com.android.settings.R;
 import com.android.settings.RestrictedSettingsFragment;
@@ -78,12 +75,23 @@
     public static final String MVNO_TYPE = "mvno_type";
     public static final String MVNO_MATCH_DATA = "mvno_match_data";
 
+    private static final String[] CARRIERS_PROJECTION = new String[] {
+            Telephony.Carriers._ID,
+            Telephony.Carriers.NAME,
+            Telephony.Carriers.APN,
+            Telephony.Carriers.TYPE,
+            Telephony.Carriers.MVNO_TYPE,
+            Telephony.Carriers.MVNO_MATCH_DATA,
+            Telephony.Carriers.EDITED,
+    };
+
     private static final int ID_INDEX = 0;
     private static final int NAME_INDEX = 1;
     private static final int APN_INDEX = 2;
     private static final int TYPES_INDEX = 3;
     private static final int MVNO_TYPE_INDEX = 4;
     private static final int MVNO_MATCH_DATA_INDEX = 5;
+    private static final int EDITED_INDEX = 6;
 
     private static final int MENU_NEW = Menu.FIRST;
     private static final int MENU_RESTORE = Menu.FIRST + 1;
@@ -116,6 +124,7 @@
 
     private boolean mHideImsApn;
     private boolean mAllowAddingApns;
+    private boolean mHidePresetApnDetails;
 
     public ApnSettings() {
         super(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS);
@@ -196,6 +205,7 @@
                 mAllowAddingApns = false;
             }
         }
+        mHidePresetApnDetails = b.getBoolean(CarrierConfigManager.KEY_HIDE_PRESET_APN_DETAILS_BOOL);
         mUserManager = UserManager.get(activity);
     }
 
@@ -265,35 +275,27 @@
     }
 
     private void fillList() {
-        final TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
         final int subId = mSubscriptionInfo != null ? mSubscriptionInfo.getSubscriptionId()
                 : SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-        final String mccmnc = mSubscriptionInfo == null ? "" : tm.getSimOperator(subId);
-        Log.d(TAG, "mccmnc = " + mccmnc);
-        StringBuilder where = new StringBuilder("numeric=\"" + mccmnc +
-                "\" AND NOT (type='ia' AND (apn=\"\" OR apn IS NULL)) AND user_visible!=0");
+        final Uri simApnUri = Uri.withAppendedPath(Telephony.Carriers.SIM_APN_LIST,
+                String.valueOf(subId));
+        StringBuilder where = new StringBuilder("NOT (type='ia' AND (apn=\"\" OR apn IS NULL)) AND "
+                + "user_visible!=0");
 
         if (mHideImsApn) {
             where.append(" AND NOT (type='ims')");
         }
 
-        Cursor cursor = getContentResolver().query(Telephony.Carriers.CONTENT_URI, new String[] {
-                "_id", "name", "apn", "type", "mvno_type", "mvno_match_data"}, where.toString(),
-                null, Telephony.Carriers.DEFAULT_SORT_ORDER);
+        Cursor cursor = getContentResolver().query(simApnUri,
+                CARRIERS_PROJECTION, where.toString(), null,
+                Telephony.Carriers.DEFAULT_SORT_ORDER);
 
         if (cursor != null) {
-            IccRecords r = null;
-            if (mUiccController != null && mSubscriptionInfo != null) {
-                r = mUiccController.getIccRecords(
-                        SubscriptionManager.getPhoneId(subId), UiccController.APP_FAM_3GPP);
-            }
-            PreferenceGroup apnList = (PreferenceGroup) findPreference("apn_list");
-            apnList.removeAll();
+            PreferenceGroup apnPrefList = (PreferenceGroup) findPreference("apn_list");
+            apnPrefList.removeAll();
 
-            ArrayList<ApnPreference> mnoApnList = new ArrayList<ApnPreference>();
-            ArrayList<ApnPreference> mvnoApnList = new ArrayList<ApnPreference>();
-            ArrayList<ApnPreference> mnoMmsApnList = new ArrayList<ApnPreference>();
-            ArrayList<ApnPreference> mvnoMmsApnList = new ArrayList<ApnPreference>();
+            ArrayList<ApnPreference> apnList = new ArrayList<ApnPreference>();
+            ArrayList<ApnPreference> mmsApnList = new ArrayList<ApnPreference>();
 
             mSelectedKey = getSelectedApnKey();
             cursor.moveToFirst();
@@ -302,16 +304,21 @@
                 String apn = cursor.getString(APN_INDEX);
                 String key = cursor.getString(ID_INDEX);
                 String type = cursor.getString(TYPES_INDEX);
-                String mvnoType = cursor.getString(MVNO_TYPE_INDEX);
-                String mvnoMatchData = cursor.getString(MVNO_MATCH_DATA_INDEX);
+                int edited = cursor.getInt(EDITED_INDEX);
+                mMvnoType = cursor.getString(MVNO_TYPE_INDEX);
+                mMvnoMatchData = cursor.getString(MVNO_MATCH_DATA_INDEX);
 
                 ApnPreference pref = new ApnPreference(getPrefContext());
 
                 pref.setKey(key);
                 pref.setTitle(name);
-                pref.setSummary(apn);
                 pref.setPersistent(false);
                 pref.setSubId(subId);
+                if (mHidePresetApnDetails && edited == Telephony.Carriers.UNEDITED) {
+                    pref.setHideDetails();
+                } else {
+                    pref.setSummary(apn);
+                }
 
                 boolean selectable = ((type == null) || !type.equals("mms"));
                 pref.setSelectable(selectable);
@@ -319,43 +326,20 @@
                     if ((mSelectedKey != null) && mSelectedKey.equals(key)) {
                         pref.setChecked();
                     }
-                    addApnToList(pref, mnoApnList, mvnoApnList, r, mvnoType, mvnoMatchData);
+                    apnList.add(pref);
                 } else {
-                    addApnToList(pref, mnoMmsApnList, mvnoMmsApnList, r, mvnoType, mvnoMatchData);
+                    mmsApnList.add(pref);
                 }
                 cursor.moveToNext();
             }
             cursor.close();
 
-            if (!mvnoApnList.isEmpty()) {
-                mnoApnList = mvnoApnList;
-                mnoMmsApnList = mvnoMmsApnList;
-
-                // Also save the mvno info
+            for (Preference preference : apnList) {
+                apnPrefList.addPreference(preference);
             }
-
-            for (Preference preference : mnoApnList) {
-                apnList.addPreference(preference);
+            for (Preference preference : mmsApnList) {
+                apnPrefList.addPreference(preference);
             }
-            for (Preference preference : mnoMmsApnList) {
-                apnList.addPreference(preference);
-            }
-        }
-    }
-
-    private void addApnToList(ApnPreference pref, ArrayList<ApnPreference> mnoList,
-                              ArrayList<ApnPreference> mvnoList, IccRecords r, String mvnoType,
-                              String mvnoMatchData) {
-        if (r != null && !TextUtils.isEmpty(mvnoType) && !TextUtils.isEmpty(mvnoMatchData)) {
-            if (ApnSettingUtils.mvnoMatches(r, ApnSetting.getMvnoTypeIntFromString(mvnoType),
-                    mvnoMatchData)) {
-                mvnoList.add(pref);
-                // Since adding to mvno list, save mvno info
-                mMvnoType = mvnoType;
-                mMvnoMatchData = mvnoMatchData;
-            }
-        } else {
-            mnoList.add(pref);
         }
     }
 
diff --git a/src/com/android/settings/network/telephony/Enhanced4gLteSliceHelper.java b/src/com/android/settings/network/telephony/Enhanced4gLteSliceHelper.java
index b198f92..aff1211 100644
--- a/src/com/android/settings/network/telephony/Enhanced4gLteSliceHelper.java
+++ b/src/com/android/settings/network/telephony/Enhanced4gLteSliceHelper.java
@@ -19,7 +19,6 @@
 import static android.app.slice.Slice.EXTRA_TOGGLE_STATE;
 
 import android.app.PendingIntent;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -40,9 +39,8 @@
 import com.android.ims.ImsManager;
 import com.android.settings.R;
 import com.android.settings.Utils;
-import com.android.settings.slices.SettingsSliceProvider;
+import com.android.settings.slices.CustomSliceRegistry;
 import com.android.settings.slices.SliceBroadcastReceiver;
-import com.android.settings.slices.SliceBuilderUtils;
 
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
@@ -57,12 +55,7 @@
  */
 public class Enhanced4gLteSliceHelper {
 
-    private static final String TAG = "Enhanced4gLteSliceHelper";
-
-    /**
-     * Settings slice path to enhanced 4g LTE setting.
-     */
-    public static final String PATH_ENHANCED_4G_LTE = "enhanced_4g_lte";
+    private static final String TAG = "Enhanced4gLteSlice";
 
     /**
      * Action passed for changes to enhanced 4g LTE slice (toggle).
@@ -71,14 +64,6 @@
             "com.android.settings.mobilenetwork.action.ENHANCED_4G_LTE_CHANGED";
 
     /**
-     * Slice Uri for Enhanced 4G slice
-     */
-    public static final Uri SLICE_URI = new Uri.Builder()
-            .scheme(ContentResolver.SCHEME_CONTENT)
-            .authority(SettingsSliceProvider.SLICE_AUTHORITY)
-            .appendPath(PATH_ENHANCED_4G_LTE)
-            .build();
-    /**
      * Action for mobile network settings activity which
      * allows setting configuration for Enhanced 4G LTE
      * related settings
@@ -225,8 +210,7 @@
         }
         // notify change in slice in any case to get re-queried. This would result in displaying
         // appropriate message with the updated setting.
-        final Uri uri = SliceBuilderUtils.getUri(PATH_ENHANCED_4G_LTE, false /*isPlatformSlice*/);
-        mContext.getContentResolver().notifyChange(uri, null);
+        mContext.getContentResolver().notifyChange(CustomSliceRegistry.ENHANCED_4G_SLICE_URI, null);
     }
 
     private CharSequence getEnhanced4glteModeTitle(int subId) {
diff --git a/src/com/android/settings/notification/BlockPreferenceController.java b/src/com/android/settings/notification/BlockPreferenceController.java
index bee32f5..960526c 100644
--- a/src/com/android/settings/notification/BlockPreferenceController.java
+++ b/src/com/android/settings/notification/BlockPreferenceController.java
@@ -27,9 +27,9 @@
 import androidx.preference.Preference;
 
 import com.android.settings.R;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.core.PreferenceControllerMixin;
 import com.android.settings.widget.SwitchBar;
+import com.android.settingslib.widget.LayoutPreference;
 
 public class BlockPreferenceController extends NotificationPreferenceController
         implements PreferenceControllerMixin, SwitchBar.OnSwitchChangeListener {
diff --git a/src/com/android/settings/notification/HeaderPreferenceController.java b/src/com/android/settings/notification/HeaderPreferenceController.java
index f0c860f..0c091b4 100644
--- a/src/com/android/settings/notification/HeaderPreferenceController.java
+++ b/src/com/android/settings/notification/HeaderPreferenceController.java
@@ -31,10 +31,10 @@
 import androidx.preference.PreferenceFragmentCompat;
 
 import com.android.settings.R;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.core.PreferenceControllerMixin;
 import com.android.settings.widget.EntityHeaderController;
 import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.LayoutPreference;
 
 public class HeaderPreferenceController extends NotificationPreferenceController
         implements PreferenceControllerMixin, LifecycleObserver {
diff --git a/src/com/android/settings/notification/NotificationSwitchBarPreference.java b/src/com/android/settings/notification/NotificationSwitchBarPreference.java
index ff42987..01c4f6a 100644
--- a/src/com/android/settings/notification/NotificationSwitchBarPreference.java
+++ b/src/com/android/settings/notification/NotificationSwitchBarPreference.java
@@ -22,9 +22,9 @@
 
 import androidx.preference.PreferenceViewHolder;
 
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.widget.ToggleSwitch;
 import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.widget.LayoutPreference;
 
 public class NotificationSwitchBarPreference extends LayoutPreference {
     private ToggleSwitch mSwitch;
diff --git a/src/com/android/settings/notification/ZenAutomaticRuleHeaderPreferenceController.java b/src/com/android/settings/notification/ZenAutomaticRuleHeaderPreferenceController.java
index 41eb111..72bb0e3 100644
--- a/src/com/android/settings/notification/ZenAutomaticRuleHeaderPreferenceController.java
+++ b/src/com/android/settings/notification/ZenAutomaticRuleHeaderPreferenceController.java
@@ -28,17 +28,17 @@
 import android.util.Slog;
 import android.view.View;
 
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.applications.LayoutPreference;
-import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.widget.EntityHeaderController;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-
 import androidx.fragment.app.Fragment;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceFragmentCompat;
 
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.widget.EntityHeaderController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.LayoutPreference;
+
 public class ZenAutomaticRuleHeaderPreferenceController extends AbstractZenModePreferenceController
         implements PreferenceControllerMixin {
 
diff --git a/src/com/android/settings/notification/ZenAutomaticRuleSwitchPreferenceController.java b/src/com/android/settings/notification/ZenAutomaticRuleSwitchPreferenceController.java
index d411402..f38deb3 100644
--- a/src/com/android/settings/notification/ZenAutomaticRuleSwitchPreferenceController.java
+++ b/src/com/android/settings/notification/ZenAutomaticRuleSwitchPreferenceController.java
@@ -25,9 +25,9 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.widget.SwitchBar;
 import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.LayoutPreference;
 
 public class ZenAutomaticRuleSwitchPreferenceController extends
         AbstractZenModeAutomaticRulePreferenceController implements
diff --git a/src/com/android/settings/notification/ZenModeButtonPreferenceController.java b/src/com/android/settings/notification/ZenModeButtonPreferenceController.java
index 3e45899..8ebc6b8 100644
--- a/src/com/android/settings/notification/ZenModeButtonPreferenceController.java
+++ b/src/com/android/settings/notification/ZenModeButtonPreferenceController.java
@@ -26,9 +26,9 @@
 
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.core.PreferenceControllerMixin;
 import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.LayoutPreference;
 
 public class ZenModeButtonPreferenceController extends AbstractZenModePreferenceController
         implements PreferenceControllerMixin {
diff --git a/src/com/android/settings/notification/ZenModePreferenceController.java b/src/com/android/settings/notification/ZenModePreferenceController.java
index 44ad2ff..22eb0c0 100644
--- a/src/com/android/settings/notification/ZenModePreferenceController.java
+++ b/src/com/android/settings/notification/ZenModePreferenceController.java
@@ -35,6 +35,9 @@
 public class ZenModePreferenceController extends BasePreferenceController
         implements LifecycleObserver, OnResume, OnPause {
 
+
+    public static final String ZEN_MODE_KEY = "zen_mode";
+
     private SettingObserver mSettingObserver;
     private ZenModeSettings.SummaryBuilder mSummaryBuilder;
 
diff --git a/src/com/android/settings/notification/ZenModeSettings.java b/src/com/android/settings/notification/ZenModeSettings.java
index 3a270d2..293c429 100644
--- a/src/com/android/settings/notification/ZenModeSettings.java
+++ b/src/com/android/settings/notification/ZenModeSettings.java
@@ -86,8 +86,6 @@
                 "zen_mode_behavior_calls"));
         controllers.add(new ZenModeMessagesPreferenceController(context, lifecycle,
                 "zen_mode_behavior_messages"));
-        controllers.add(new ZenModeAlarmsPreferenceController(context, lifecycle,
-                "zen_mode_behavior_alarms"));
         controllers.add(new ZenModeBlockedEffectsPreferenceController(context, lifecycle));
         controllers.add(new ZenModeDurationPreferenceController(context, lifecycle));
         controllers.add(new ZenModeAutomationPreferenceController(context));
diff --git a/src/com/android/settings/notification/ZenModeSliceBuilder.java b/src/com/android/settings/notification/ZenModeSliceBuilder.java
index bd6ad0b..f5208c1 100644
--- a/src/com/android/settings/notification/ZenModeSliceBuilder.java
+++ b/src/com/android/settings/notification/ZenModeSliceBuilder.java
@@ -18,16 +18,16 @@
 
 import static android.app.slice.Slice.EXTRA_TOGGLE_STATE;
 
+import static com.android.settings.notification.ZenModePreferenceController.ZEN_MODE_KEY;
+
 import android.annotation.ColorInt;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.net.Uri;
 import android.provider.Settings;
-import android.provider.SettingsSlicesContract;
 
 import androidx.core.graphics.drawable.IconCompat;
 import androidx.slice.Slice;
@@ -39,7 +39,7 @@
 import com.android.settings.R;
 import com.android.settings.SubSettings;
 import com.android.settings.Utils;
-import com.android.settings.slices.SettingsSliceProvider;
+import com.android.settings.slices.CustomSliceRegistry;
 import com.android.settings.slices.SliceBroadcastReceiver;
 import com.android.settings.slices.SliceBuilderUtils;
 
@@ -47,18 +47,6 @@
 
     private static final String TAG = "ZenModeSliceBuilder";
 
-    private static final String ZEN_MODE_KEY = "zen_mode";
-
-    /**
-     * Backing Uri for the Zen Mode Slice.
-     */
-    public static final Uri ZEN_MODE_URI = new Uri.Builder()
-            .scheme(ContentResolver.SCHEME_CONTENT)
-            .authority(SettingsSliceProvider.SLICE_AUTHORITY)
-            .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
-            .appendPath(ZEN_MODE_KEY)
-            .build();
-
     /**
      * Action notifying a change on the Zen Mode Slice.
      */
@@ -77,7 +65,7 @@
     }
 
     /**
-     * Return a ZenMode Slice bound to {@link #ZEN_MODE_URI}.
+     * Return a ZenMode Slice bound to {@link CustomSliceRegistry#ZEN_MODE_URI}.
      * <p>
      * Note that you should register a listener for {@link #INTENT_FILTER} to get changes for
      * ZenMode.
@@ -93,7 +81,8 @@
         final SliceAction toggleSliceAction = new SliceAction(toggleAction, null /* actionTitle */,
                 isZenModeEnabled);
 
-        return new ListBuilder(context, ZEN_MODE_URI, ListBuilder.INFINITY)
+        return new ListBuilder(context, CustomSliceRegistry.ZEN_MODE_SLICE_URI,
+                ListBuilder.INFINITY)
                 .setAccentColor(color)
                 .addRow(new RowBuilder()
                         .setTitle(title)
diff --git a/src/com/android/settings/overlay/FeatureFactory.java b/src/com/android/settings/overlay/FeatureFactory.java
index 38d48c8..a52619b 100644
--- a/src/com/android/settings/overlay/FeatureFactory.java
+++ b/src/com/android/settings/overlay/FeatureFactory.java
@@ -28,7 +28,9 @@
 import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider;
 import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
 import com.android.settings.gestures.AssistGestureFeatureProvider;
+import com.android.settings.homepage.contextualcards.ContextualCardFeatureProvider;
 import com.android.settings.localepicker.LocaleFeatureProvider;
+import com.android.settings.panel.PanelFeatureProvider;
 import com.android.settings.search.SearchFeatureProvider;
 import com.android.settings.security.SecurityFeatureProvider;
 import com.android.settings.slices.SlicesFeatureProvider;
@@ -105,6 +107,10 @@
 
     public abstract AccountFeatureProvider getAccountFeatureProvider();
 
+    public abstract PanelFeatureProvider getPanelFeatureProvider();
+
+    public abstract ContextualCardFeatureProvider getContextualCardFeatureProvider();
+
     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 f74043f..3515ac0 100644
--- a/src/com/android/settings/overlay/FeatureFactoryImpl.java
+++ b/src/com/android/settings/overlay/FeatureFactoryImpl.java
@@ -40,8 +40,12 @@
 import com.android.settings.fuelgauge.PowerUsageFeatureProviderImpl;
 import com.android.settings.gestures.AssistGestureFeatureProvider;
 import com.android.settings.gestures.AssistGestureFeatureProviderImpl;
+import com.android.settings.homepage.contextualcards.ContextualCardFeatureProvider;
+import com.android.settings.homepage.contextualcards.ContextualCardFeatureProviderImpl;
 import com.android.settings.localepicker.LocaleFeatureProvider;
 import com.android.settings.localepicker.LocaleFeatureProviderImpl;
+import com.android.settings.panel.PanelFeatureProvider;
+import com.android.settings.panel.PanelFeatureProviderImpl;
 import com.android.settings.search.SearchFeatureProvider;
 import com.android.settings.search.SearchFeatureProviderImpl;
 import com.android.settings.security.SecurityFeatureProvider;
@@ -72,6 +76,8 @@
     private UserFeatureProvider mUserFeatureProvider;
     private SlicesFeatureProvider mSlicesFeatureProvider;
     private AccountFeatureProvider mAccountFeatureProvider;
+    private PanelFeatureProvider mPanelFeatureProvider;
+    private ContextualCardFeatureProvider mContextualCardFeatureProvider;
 
     @Override
     public SupportFeatureProvider getSupportFeatureProvider(Context context) {
@@ -209,4 +215,19 @@
         }
         return mAccountFeatureProvider;
     }
+
+    @Override
+    public PanelFeatureProvider getPanelFeatureProvider() {
+        if (mPanelFeatureProvider == null) {
+            mPanelFeatureProvider = new PanelFeatureProviderImpl();
+        }
+        return mPanelFeatureProvider;
+    }
+
+    public ContextualCardFeatureProvider getContextualCardFeatureProvider() {
+        if (mContextualCardFeatureProvider == null) {
+            mContextualCardFeatureProvider = new ContextualCardFeatureProviderImpl();
+        }
+        return mContextualCardFeatureProvider;
+    }
 }
diff --git a/src/com/android/settings/panel/InternetConnectivityPanel.java b/src/com/android/settings/panel/InternetConnectivityPanel.java
new file mode 100644
index 0000000..1e01e71
--- /dev/null
+++ b/src/com/android/settings/panel/InternetConnectivityPanel.java
@@ -0,0 +1,65 @@
+/*
+ * 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.panel;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+
+import com.android.settings.R;
+import com.android.settings.slices.CustomSliceRegistry;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents the Internet Connectivity Panel.
+ *
+ * <p>
+ * Displays Wifi (full Slice) and Airplane mode.
+ * </p>
+ */
+public class InternetConnectivityPanel implements PanelContent {
+
+    private final Context mContext;
+
+    public static InternetConnectivityPanel create(Context context) {
+        return new InternetConnectivityPanel(context);
+    }
+
+    private InternetConnectivityPanel(Context context) {
+        mContext = context.getApplicationContext();
+    }
+
+    @Override
+    public String getTitle() {
+        return (String) mContext.getText(R.string.internet_connectivity_panel_title);
+    }
+
+    @Override
+    public List<Uri> getSlices() {
+        final List<Uri> uris = new ArrayList<>();
+        uris.add(CustomSliceRegistry.WIFI_SLICE_URI);
+        uris.add(CustomSliceRegistry.AIRPLANE_URI);
+        return uris;
+    }
+
+    @Override
+    public Intent getSeeMoreIntent() {
+        return null;
+    }
+}
diff --git a/src/com/android/settings/panel/PanelContent.java b/src/com/android/settings/panel/PanelContent.java
new file mode 100644
index 0000000..bd84c2f
--- /dev/null
+++ b/src/com/android/settings/panel/PanelContent.java
@@ -0,0 +1,49 @@
+/*
+ * 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.panel;
+
+import android.content.Intent;
+import android.net.Uri;
+
+import java.util.List;
+
+/**
+ * Represents the data class needed to create a Settings Panel. See {@link PanelFragment}.
+ */
+public interface PanelContent {
+
+    /**
+     * @return a string for the title of the Panel.
+     */
+    CharSequence getTitle();
+
+    /**
+     * @return an ordered list of the Slices to be displayed in the Panel. The first item in the
+     * list is shown on top of the Panel.
+     */
+    List<Uri> getSlices();
+
+
+    /**
+     * @return an {@link Intent} to the full content in Settings that is summarized by the Panel.
+     *
+     * <p>
+     *     For example, for the connectivity panel you would intent to the Network & Internet page.
+     * </p>
+     */
+    Intent getSeeMoreIntent();
+}
diff --git a/src/com/android/settings/panel/PanelFeatureProvider.java b/src/com/android/settings/panel/PanelFeatureProvider.java
new file mode 100644
index 0000000..7d6c558
--- /dev/null
+++ b/src/com/android/settings/panel/PanelFeatureProvider.java
@@ -0,0 +1,27 @@
+/*
+ * 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.panel;
+
+import android.content.Context;
+
+public interface PanelFeatureProvider {
+
+    /**
+     * Returns {@link PanelContent} as specified by the {@param panelType}.
+     */
+    PanelContent getPanel(Context context, String panelType);
+}
diff --git a/src/com/android/settings/panel/PanelFeatureProviderImpl.java b/src/com/android/settings/panel/PanelFeatureProviderImpl.java
new file mode 100644
index 0000000..2e84078
--- /dev/null
+++ b/src/com/android/settings/panel/PanelFeatureProviderImpl.java
@@ -0,0 +1,32 @@
+/*
+ * 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.panel;
+
+import android.content.Context;
+
+public class PanelFeatureProviderImpl implements PanelFeatureProvider {
+
+    @Override
+    public PanelContent getPanel(Context context, String panelType) {
+        switch (panelType) {
+            case SettingsPanelActivity.PANEL_TYPE_WIFI:
+                return InternetConnectivityPanel.create(context);
+        }
+
+        throw new IllegalStateException("No matching panel for: "  + panelType);
+    }
+}
diff --git a/src/com/android/settings/panel/PanelFragment.java b/src/com/android/settings/panel/PanelFragment.java
new file mode 100644
index 0000000..bbdaec3
--- /dev/null
+++ b/src/com/android/settings/panel/PanelFragment.java
@@ -0,0 +1,88 @@
+/*
+ * 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.panel;
+
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import android.widget.LinearLayout;
+
+import androidx.lifecycle.LiveData;
+import androidx.slice.Slice;
+import androidx.slice.widget.SliceLiveData;
+import androidx.slice.widget.SliceView;
+
+import com.android.settings.R;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentActivity;
+
+import com.android.settings.overlay.FeatureFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PanelFragment extends Fragment {
+
+    private static final String TAG = "PanelFragment";
+
+    private List<SliceView> mSliceViewList;
+    private List<LiveData<Slice>> mSliceDataList;
+    private LinearLayout mPanelLayout;
+
+    public PanelFragment() {
+        mSliceViewList = new ArrayList<>();
+        mSliceDataList = new ArrayList<>();
+    }
+
+    @Nullable
+    @Override
+    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
+            @Nullable Bundle savedInstanceState) {
+        final FragmentActivity activity = getActivity();
+        final View view = inflater.inflate(R.layout.panel_layout, container, false);
+
+        mPanelLayout = view.findViewById(R.id.panel_parent_layout);
+        final Bundle arguments = getArguments();
+
+        final String panelType = arguments.getString(SettingsPanelActivity.KEY_PANEL_TYPE_ARGUMENT);
+
+        final PanelContent panel = FeatureFactory.getFactory(activity)
+                .getPanelFeatureProvider()
+                .getPanel(activity, panelType);
+
+        activity.setTitle(panel.getTitle());
+
+
+        for (Uri uri : panel.getSlices()) {
+            final SliceView sliceView = new SliceView(activity);
+            mPanelLayout.addView(sliceView);
+            final LiveData<Slice> liveData = SliceLiveData.fromUri(activity, uri);
+            liveData.observe(this /* lifecycleOwner */, sliceView);
+
+            mSliceDataList.add(liveData);
+            mSliceViewList.add(sliceView);
+        }
+
+        return view;
+    }
+}
diff --git a/src/com/android/settings/panel/SettingsPanelActivity.java b/src/com/android/settings/panel/SettingsPanelActivity.java
new file mode 100644
index 0000000..db1f60d
--- /dev/null
+++ b/src/com/android/settings/panel/SettingsPanelActivity.java
@@ -0,0 +1,103 @@
+/*
+ * 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.panel;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.os.Bundle;
+
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.Window;
+import android.view.WindowManager;
+
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentActivity;
+import androidx.fragment.app.FragmentManager;
+
+import com.android.settings.R;
+
+/**
+ * Dialog Activity to host Settings Slices.
+ *
+ * TODO link to action / framework API
+ */
+public class SettingsPanelActivity extends FragmentActivity {
+
+    private final String TAG = "panel_activity";
+
+    /**
+     * Key specifying which Panel the app is requesting.
+     */
+    public static final String KEY_PANEL_TYPE_ARGUMENT = "PANEL_TYPE_ARGUMENT";
+
+
+    // TODO (b/117804442) move to framework
+    public static final String EXTRA_PANEL_TYPE = "com.android.settings.panel.extra";
+
+    // TODO (b/117804442) move to framework
+    public static final String PANEL_TYPE_WIFI = "wifi_panel";
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        final ComponentName callingActivityName = getCallingActivity();
+
+        if (callingActivityName == null) {
+            Log.e(TAG, "Must start with startActivityForResult. Closing.");
+            finish();
+            return;
+        }
+
+        final Intent callingIntent = getIntent();
+        if (callingIntent == null) {
+            Log.e(TAG, "Null intent, closing Panel Activity");
+            finish();
+            return;
+        }
+
+        final String typeExtra = callingIntent.getStringExtra(EXTRA_PANEL_TYPE);
+        if (TextUtils.isEmpty(typeExtra)) {
+            Log.e(TAG, "No intent passed, closing Panel Activity");
+            return;
+        }
+
+        setContentView(R.layout.settings_panel);
+
+        // Move the window to the bottom of screen, and make it take up the entire screen width.
+        final Window window = getWindow();
+        window.setGravity(Gravity.BOTTOM);
+        window.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
+                WindowManager.LayoutParams.WRAP_CONTENT);
+
+
+        final Bundle bundle = new Bundle();
+        bundle.putString(KEY_PANEL_TYPE_ARGUMENT, typeExtra);
+
+        final PanelFragment panelFragment = new PanelFragment();
+        panelFragment.setArguments(bundle);
+
+        final FragmentManager fragmentManager = getSupportFragmentManager();
+        final Fragment fragment = fragmentManager.findFragmentById(R.id.main_content);
+        if (fragment == null) {
+            fragmentManager.beginTransaction().add(R.id.main_content, panelFragment).commit();
+        }
+    }
+}
diff --git a/src/com/android/settings/password/ChooseLockGeneric.java b/src/com/android/settings/password/ChooseLockGeneric.java
index 14a918e..cbb3593 100644
--- a/src/com/android/settings/password/ChooseLockGeneric.java
+++ b/src/com/android/settings/password/ChooseLockGeneric.java
@@ -19,8 +19,7 @@
 import static android.app.admin.DevicePolicyManager.ACTION_SET_NEW_PARENT_PROFILE_PASSWORD;
 import static android.app.admin.DevicePolicyManager.ACTION_SET_NEW_PASSWORD;
 
-import static com.android.settings.password.ChooseLockPassword.ChooseLockPasswordFragment
-        .RESULT_FINISHED;
+import static com.android.settings.password.ChooseLockPassword.ChooseLockPasswordFragment.RESULT_FINISHED;
 
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.app.Activity;
@@ -77,12 +76,6 @@
     public Intent getIntent() {
         Intent modIntent = new Intent(super.getIntent());
         modIntent.putExtra(EXTRA_SHOW_FRAGMENT, getFragmentClass().getName());
-
-        String action = modIntent.getAction();
-        if (ACTION_SET_NEW_PASSWORD.equals(action)
-                || ACTION_SET_NEW_PARENT_PROFILE_PASSWORD.equals(action)) {
-            modIntent.putExtra(EXTRA_HIDE_DRAWER, true);
-        }
         return modIntent;
     }
 
@@ -154,7 +147,6 @@
         private FingerprintManager mFingerprintManager;
         private FaceManager mFaceManager;
         private int mUserId;
-        private boolean mHideDrawer = false;
         private ManagedLockPasswordProvider mManagedPasswordProvider;
         private boolean mIsSetNewPassword = false;
         private UserManager mUserManager;
@@ -194,7 +186,6 @@
                 mUserPassword = getActivity().getIntent().getStringExtra(
                         ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
             }
-            mHideDrawer = getActivity().getIntent().getBooleanExtra(EXTRA_HIDE_DRAWER, false);
 
             mHasChallenge = getActivity().getIntent().getBooleanExtra(
                     ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false);
@@ -345,7 +336,6 @@
                         mForFingerprint);
                 intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE,
                         mForFace);
-                intent.putExtra(EXTRA_HIDE_DRAWER, mHideDrawer);
                 startActivityForResult(
                         intent,
                         mIsSetNewPassword && mHasChallenge
@@ -748,9 +738,6 @@
             } else if (quality == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) {
                 intent = getLockPatternIntent();
             }
-            if (intent != null) {
-                intent.putExtra(EXTRA_HIDE_DRAWER, mHideDrawer);
-            }
             return intent;
         }
 
diff --git a/src/com/android/settings/password/ChooseLockPassword.java b/src/com/android/settings/password/ChooseLockPassword.java
index cd04193..1ef95da 100644
--- a/src/com/android/settings/password/ChooseLockPassword.java
+++ b/src/com/android/settings/password/ChooseLockPassword.java
@@ -190,7 +190,6 @@
         private int mPasswordMinNonLetter = 0;
         private int mPasswordMinLengthToFulfillAllPolicies = 0;
         protected int mUserId;
-        private boolean mHideDrawer = false;
         private byte[] mPasswordHistoryHashFactor;
         /**
          * Password requirements that we need to verify.
@@ -375,7 +374,6 @@
             mForFace = intent.getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE, false);
             processPasswordRequirements(intent);
             mChooseLockSettingsHelper = new ChooseLockSettingsHelper(getActivity());
-            mHideDrawer = getActivity().getIntent().getBooleanExtra(EXTRA_HIDE_DRAWER, false);
 
             if (intent.getBooleanExtra(
                     ChooseLockSettingsHelper.EXTRA_KEY_FOR_CHANGE_CRED_REQUIRED_FOR_BOOT, false)) {
@@ -975,7 +973,6 @@
             if (!wasSecureBefore) {
                 Intent intent = getRedactionInterstitialIntent(getActivity());
                 if (intent != null) {
-                    intent.putExtra(EXTRA_HIDE_DRAWER, mHideDrawer);
                     startActivity(intent);
                 }
             }
diff --git a/src/com/android/settings/password/ChooseLockPattern.java b/src/com/android/settings/password/ChooseLockPattern.java
index 4e4730f..0d06ed8 100644
--- a/src/com/android/settings/password/ChooseLockPattern.java
+++ b/src/com/android/settings/password/ChooseLockPattern.java
@@ -196,7 +196,6 @@
         private TextView mFooterLeftButton;
         private TextView mFooterRightButton;
         protected List<LockPatternView.Cell> mChosenPattern = null;
-        private boolean mHideDrawer = false;
         private ColorStateList mDefaultHeaderColorList;
 
         // ScrollView that contains title and header, only exist in land mode
@@ -464,7 +463,6 @@
                 w.start(mChooseLockSettingsHelper.utils(), required,
                         false, 0, LockPatternUtils.stringToPattern(current), current, mUserId);
             }
-            mHideDrawer = getActivity().getIntent().getBooleanExtra(EXTRA_HIDE_DRAWER, false);
             mForFingerprint = intent.getBooleanExtra(
                     ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false);
             mForFace = intent.getBooleanExtra(
@@ -808,7 +806,6 @@
             if (!wasSecureBefore) {
                 Intent intent = getRedactionInterstitialIntent(getActivity());
                 if (intent != null) {
-                    intent.putExtra(EXTRA_HIDE_DRAWER, mHideDrawer);
                     startActivity(intent);
                 }
             }
diff --git a/src/com/android/settings/password/ChooseLockSettingsHelper.java b/src/com/android/settings/password/ChooseLockSettingsHelper.java
index d5182b3..938dec4 100644
--- a/src/com/android/settings/password/ChooseLockSettingsHelper.java
+++ b/src/com/android/settings/password/ChooseLockSettingsHelper.java
@@ -391,8 +391,6 @@
         intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_RETURN_CREDENTIALS, returnCredentials);
         intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, hasChallenge);
         intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge);
-        // we should never have a drawer when confirming device credentials.
-        intent.putExtra(SettingsActivity.EXTRA_HIDE_DRAWER, true);
         intent.putExtra(Intent.EXTRA_USER_ID, userId);
         intent.putExtra(KeyguardManager.EXTRA_ALTERNATE_BUTTON_LABEL, alternateButton);
         if (extras != null) {
diff --git a/src/com/android/settings/privacy/PrivacyDashboardFragment.java b/src/com/android/settings/privacy/PrivacyDashboardFragment.java
index dd4c8fa..91e85b3 100644
--- a/src/com/android/settings/privacy/PrivacyDashboardFragment.java
+++ b/src/com/android/settings/privacy/PrivacyDashboardFragment.java
@@ -22,7 +22,10 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.notification.LockScreenNotificationPreferenceController;
 import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.search.SearchIndexable;
 
 import java.util.ArrayList;
@@ -31,6 +34,11 @@
 @SearchIndexable
 public class PrivacyDashboardFragment extends DashboardFragment {
     private static final String TAG = "PrivacyDashboardFragment";
+    private static final String KEY_LOCK_SCREEN_NOTIFICATIONS = "privacy_lock_screen_notifications";
+    private static final String KEY_WORK_PROFILE_CATEGORY =
+            "privacy_work_profile_notifications_category";
+    private static final String KEY_NOTIFICATION_WORK_PROFILE_NOTIFICATIONS =
+            "privacy_lock_screen_work_profile_notifications";
 
     @Override
     public int getMetricsCategory() {
@@ -52,6 +60,28 @@
         return R.string.help_url_privacy_dashboard;
     }
 
+    @Override
+    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+        return buildPreferenceControllers(context, getSettingsLifecycle());
+    }
+
+    private static List<AbstractPreferenceController> buildPreferenceControllers(
+            Context context, Lifecycle lifecycle) {
+        final List<AbstractPreferenceController> controllers = new ArrayList<>();
+        final LockScreenNotificationPreferenceController notificationController =
+                new LockScreenNotificationPreferenceController(context,
+                        KEY_LOCK_SCREEN_NOTIFICATIONS,
+                        KEY_WORK_PROFILE_CATEGORY,
+                        KEY_NOTIFICATION_WORK_PROFILE_NOTIFICATIONS);
+        if (lifecycle != null) {
+            lifecycle.addObserver(notificationController);
+        }
+        controllers.add(notificationController);
+
+        return controllers;
+
+    }
+
     public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
@@ -64,5 +94,11 @@
                     result.add(sir);
                     return result;
                 }
+
+                @Override
+                public List<AbstractPreferenceController> createPreferenceControllers(
+                        Context context) {
+                    return buildPreferenceControllers(context, null);
+                }
             };
 }
diff --git a/src/com/android/settings/search/SearchFeatureProvider.java b/src/com/android/settings/search/SearchFeatureProvider.java
index 3c1c62b..34f8629 100644
--- a/src/com/android/settings/search/SearchFeatureProvider.java
+++ b/src/com/android/settings/search/SearchFeatureProvider.java
@@ -68,8 +68,10 @@
         if (activity == null || toolbar == null) {
             return;
         }
-        if (!Utils.isPackageEnabled(activity, getSettingsIntelligencePkgName(activity))) {
-            final ViewGroup parent = (ViewGroup)toolbar.getParent();
+
+        if (!Utils.isDeviceProvisioned(activity) ||
+                !Utils.isPackageEnabled(activity, getSettingsIntelligencePkgName(activity))) {
+            final ViewGroup parent = (ViewGroup) toolbar.getParent();
             if (parent != null) {
                 parent.setVisibility(View.GONE);
             }
diff --git a/src/com/android/settings/slices/CustomSliceManager.java b/src/com/android/settings/slices/CustomSliceManager.java
index 99e22a1..bef72b7 100644
--- a/src/com/android/settings/slices/CustomSliceManager.java
+++ b/src/com/android/settings/slices/CustomSliceManager.java
@@ -101,13 +101,13 @@
     }
 
     private void addSlices() {
-        mUriMap.put(WifiSlice.WIFI_URI, WifiSlice.class);
-        mUriMap.put(DataUsageSlice.DATA_USAGE_CARD_URI, DataUsageSlice.class);
-        mUriMap.put(DeviceInfoSlice.DEVICE_INFO_CARD_URI, DeviceInfoSlice.class);
-        mUriMap.put(StorageSlice.STORAGE_CARD_URI, StorageSlice.class);
-        mUriMap.put(BatterySlice.BATTERY_CARD_URI, BatterySlice.class);
-        mUriMap.put(ConnectedDeviceSlice.CONNECTED_DEVICE_URI, ConnectedDeviceSlice.class);
-        mUriMap.put(LowStorageSlice.LOW_STORAGE_URI, LowStorageSlice.class);
-        mUriMap.put(BatteryFixSlice.BATTERY_FIX_URI, BatteryFixSlice.class);
+        mUriMap.put(CustomSliceRegistry.BATTERY_FIX_SLICE_URI, BatteryFixSlice.class);
+        mUriMap.put(CustomSliceRegistry.BATTERY_INFO_SLICE_URI, BatterySlice.class);
+        mUriMap.put(CustomSliceRegistry.CONNECTED_DEVICE_SLICE_URI, ConnectedDeviceSlice.class);
+        mUriMap.put(CustomSliceRegistry.DATA_USAGE_SLICE_URI, DataUsageSlice.class);
+        mUriMap.put(CustomSliceRegistry.DEVICE_INFO_SLICE_URI, DeviceInfoSlice.class);
+        mUriMap.put(CustomSliceRegistry.LOW_STORAGE_SLICE_URI, LowStorageSlice.class);
+        mUriMap.put(CustomSliceRegistry.STORAGE_SLICE_URI, StorageSlice.class);
+        mUriMap.put(CustomSliceRegistry.WIFI_SLICE_URI, WifiSlice.class);
     }
 }
diff --git a/src/com/android/settings/slices/CustomSliceRegistry.java b/src/com/android/settings/slices/CustomSliceRegistry.java
new file mode 100644
index 0000000..f2b3299
--- /dev/null
+++ b/src/com/android/settings/slices/CustomSliceRegistry.java
@@ -0,0 +1,184 @@
+/*
+ * 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.slices;
+
+import static android.provider.SettingsSlicesContract.KEY_LOCATION;
+import static android.provider.SettingsSlicesContract.KEY_WIFI;
+
+import static com.android.settings.notification.ZenModePreferenceController.ZEN_MODE_KEY;
+
+import android.content.ContentResolver;
+import android.net.Uri;
+import android.provider.SettingsSlicesContract;
+
+import com.android.settings.fuelgauge.batterytip.BatteryTipPreferenceController;
+import com.android.settings.wifi.calling.WifiCallingSliceHelper;
+
+/**
+ * A registry of custom slice Uris.
+ */
+public class CustomSliceRegistry {
+
+    /**
+     * Uri for Airplane mode Slice.
+     */
+    public static final Uri AIRPLANE_URI = new Uri.Builder()
+            .scheme(ContentResolver.SCHEME_CONTENT)
+            .authority(SettingsSlicesContract.AUTHORITY)
+            .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+            .appendPath(SettingsSlicesContract.KEY_AIRPLANE_MODE)
+            .build();
+
+    /**
+     * Uri for Battery Fix Slice.
+     */
+    public static final Uri BATTERY_FIX_SLICE_URI = new Uri.Builder()
+            .scheme(ContentResolver.SCHEME_CONTENT)
+            .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+            .appendEncodedPath(SettingsSlicesContract.PATH_SETTING_INTENT)
+            .appendPath(BatteryTipPreferenceController.PREF_NAME)
+            .build();
+    /**
+     * Backing Uri for the Battery info Slice.
+     */
+    public static final Uri BATTERY_INFO_SLICE_URI = new Uri.Builder()
+            .scheme(ContentResolver.SCHEME_CONTENT)
+            .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+            .appendEncodedPath(SettingsSlicesContract.PATH_SETTING_INTENT)
+            .appendPath("battery_card")
+            .build();
+    /**
+     * Backing Uri for the Bluetooth Slice.
+     */
+    public static final Uri BLUETOOTH_URI = new Uri.Builder()
+            .scheme(ContentResolver.SCHEME_CONTENT)
+            .authority(SettingsSlicesContract.AUTHORITY)
+            .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+            .appendPath(SettingsSlicesContract.KEY_BLUETOOTH)
+            .build();
+
+    /**
+     * Backing Uri for Connected device Slice.
+     */
+    public static final Uri CONNECTED_DEVICE_SLICE_URI = new Uri.Builder()
+            .scheme(ContentResolver.SCHEME_CONTENT)
+            .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+            .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+            .appendPath("connected_device")
+            .build();
+    /**
+     * Backing Uri for the Data usage Slice.
+     */
+    public static final Uri DATA_USAGE_SLICE_URI = new Uri.Builder()
+            .scheme(ContentResolver.SCHEME_CONTENT)
+            .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+            .appendPath("data_usage_card")
+            .build();
+    /**
+     * Backing Uri for the Device info Slice.
+     */
+    public static final Uri DEVICE_INFO_SLICE_URI = new Uri.Builder()
+            .scheme(ContentResolver.SCHEME_CONTENT)
+            .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+            .appendPath("device_info_card")
+            .build();
+    /**
+     * Backing Uri for the Emergency Info Slice.
+     */
+    public static final Uri EMERGENCY_INFO_SLICE_URI = new Uri.Builder()
+            .scheme(ContentResolver.SCHEME_CONTENT)
+            .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+            .appendPath("emergency_info_card")
+            .build();
+    /**
+     * Slice Uri for Enhanced 4G slice
+     */
+    public static final Uri ENHANCED_4G_SLICE_URI = new Uri.Builder()
+            .scheme(ContentResolver.SCHEME_CONTENT)
+            .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+            .appendPath("enhanced_4g_lte")
+            .build();
+    /**
+     * Backing Uri for the Flashlight Slice.
+     */
+    public static final Uri FLASHLIGHT_SLICE_URI = new Uri.Builder()
+            .scheme(ContentResolver.SCHEME_CONTENT)
+            .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+            .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+            .appendPath("flashlight")
+            .build();
+    /**
+     * Backing Uri for the Location Slice.
+     */
+    public static final Uri LOCATION_SLICE_URI = new Uri.Builder()
+            .scheme(ContentResolver.SCHEME_CONTENT)
+            .authority(SettingsSlicesContract.AUTHORITY)
+            .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+            .appendPath(KEY_LOCATION)
+            .build();
+    /**
+     * Backing Uri for Low storage Slice.
+     */
+    public static final Uri LOW_STORAGE_SLICE_URI = new Uri.Builder()
+            .scheme(ContentResolver.SCHEME_CONTENT)
+            .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+            .appendEncodedPath(SettingsSlicesContract.PATH_SETTING_INTENT)
+            .appendPath("low_storage")
+            .build();
+    /**
+     * Backing Uri for the storage slice.
+     */
+    public static final Uri STORAGE_SLICE_URI = new Uri.Builder()
+            .scheme(ContentResolver.SCHEME_CONTENT)
+            .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+            .appendPath("storage_card")
+            .build();
+    /**
+     * Full {@link Uri} for the Wifi Calling Slice.
+     */
+    public static final Uri WIFI_CALLING_URI = new Uri.Builder()
+            .scheme(ContentResolver.SCHEME_CONTENT)
+            .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+            .appendPath(WifiCallingSliceHelper.PATH_WIFI_CALLING)
+            .build();
+    /**
+     * Full {@link Uri} for the Wifi Calling Preference Slice.
+     */
+    public static final Uri WIFI_CALLING_PREFERENCE_URI = new Uri.Builder()
+            .scheme(ContentResolver.SCHEME_CONTENT)
+            .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+            .appendPath(WifiCallingSliceHelper.PATH_WIFI_CALLING_PREFERENCE)
+            .build();
+    /**
+     * Backing Uri for the Wifi Slice.
+     */
+    public static final Uri WIFI_SLICE_URI = new Uri.Builder()
+            .scheme(ContentResolver.SCHEME_CONTENT)
+            .authority(SettingsSlicesContract.AUTHORITY)
+            .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+            .appendPath(KEY_WIFI)
+            .build();
+    /**
+     * Backing Uri for the Zen Mode Slice.
+     */
+    public static final Uri ZEN_MODE_SLICE_URI = new Uri.Builder()
+            .scheme(ContentResolver.SCHEME_CONTENT)
+            .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+            .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+            .appendPath(ZEN_MODE_KEY)
+            .build();
+}
diff --git a/src/com/android/settings/slices/SettingsSliceProvider.java b/src/com/android/settings/slices/SettingsSliceProvider.java
index fa669bb..109f02e 100644
--- a/src/com/android/settings/slices/SettingsSliceProvider.java
+++ b/src/com/android/settings/slices/SettingsSliceProvider.java
@@ -44,11 +44,8 @@
 import com.android.settings.flashlight.FlashlightSliceBuilder;
 import com.android.settings.homepage.contextualcards.deviceinfo.EmergencyInfoSlice;
 import com.android.settings.location.LocationSliceBuilder;
-import com.android.settings.network.telephony.Enhanced4gLteSliceHelper;
 import com.android.settings.notification.ZenModeSliceBuilder;
 import com.android.settings.overlay.FeatureFactory;
-import com.android.settings.wifi.WifiSlice;
-import com.android.settings.wifi.calling.WifiCallingSliceHelper;
 import com.android.settingslib.SliceBroadcastRelay;
 import com.android.settingslib.utils.ThreadUtils;
 
@@ -175,23 +172,21 @@
             if (filter != null) {
                 registerIntentToUri(filter, sliceUri);
             }
-            ThreadUtils.postOnMainThread(() -> {
-                startBackgroundWorker(sliceable);
-            });
+            ThreadUtils.postOnMainThread(() -> startBackgroundWorker(sliceable));
             return;
         }
 
-        if (ZenModeSliceBuilder.ZEN_MODE_URI.equals(sliceUri)) {
+        if (CustomSliceRegistry.ZEN_MODE_SLICE_URI.equals(sliceUri)) {
             registerIntentToUri(ZenModeSliceBuilder.INTENT_FILTER, sliceUri);
             return;
-        } else if (BluetoothSliceBuilder.BLUETOOTH_URI.equals(sliceUri)) {
+        } else if (CustomSliceRegistry.BLUETOOTH_URI.equals(sliceUri)) {
             registerIntentToUri(BluetoothSliceBuilder.INTENT_FILTER, sliceUri);
             return;
-        } else if (FlashlightSliceBuilder.FLASHLIGHT_URI.equals(sliceUri)) {
+        } else if (CustomSliceRegistry.FLASHLIGHT_SLICE_URI.equals(sliceUri)) {
             registerIntentToUri(FlashlightSliceBuilder.INTENT_FILTER, sliceUri);
             mRegisteredUris.add(sliceUri);
             return;
-        } else if (EmergencyInfoSlice.EMERGENCY_INFO_CARD_URI.equals(sliceUri)) {
+        } else if (CustomSliceRegistry.EMERGENCY_INFO_SLICE_URI.equals(sliceUri)) {
             return;
         }
 
@@ -236,30 +231,30 @@
                 return sliceable.getSlice();
             }
 
-            if (WifiCallingSliceHelper.WIFI_CALLING_URI.equals(sliceUri)) {
+            if (CustomSliceRegistry.WIFI_CALLING_URI.equals(sliceUri)) {
                 return FeatureFactory.getFactory(getContext())
                         .getSlicesFeatureProvider()
                         .getNewWifiCallingSliceHelper(getContext())
                         .createWifiCallingSlice(sliceUri);
-            } else if (ZenModeSliceBuilder.ZEN_MODE_URI.equals(sliceUri)) {
+            } else if (CustomSliceRegistry.ZEN_MODE_SLICE_URI.equals(sliceUri)) {
                 return ZenModeSliceBuilder.getSlice(getContext());
-            } else if (BluetoothSliceBuilder.BLUETOOTH_URI.equals(sliceUri)) {
+            } else if (CustomSliceRegistry.BLUETOOTH_URI.equals(sliceUri)) {
                 return BluetoothSliceBuilder.getSlice(getContext());
-            } else if (LocationSliceBuilder.LOCATION_URI.equals(sliceUri)) {
+            } else if (CustomSliceRegistry.LOCATION_SLICE_URI.equals(sliceUri)) {
                 return LocationSliceBuilder.getSlice(getContext());
-            } else if (Enhanced4gLteSliceHelper.SLICE_URI.equals(sliceUri)) {
+            } else if (CustomSliceRegistry.ENHANCED_4G_SLICE_URI.equals(sliceUri)) {
                 return FeatureFactory.getFactory(getContext())
                         .getSlicesFeatureProvider()
                         .getNewEnhanced4gLteSliceHelper(getContext())
                         .createEnhanced4gLteSlice(sliceUri);
-            } else if (WifiCallingSliceHelper.WIFI_CALLING_PREFERENCE_URI.equals(sliceUri)) {
+            } else if (CustomSliceRegistry.WIFI_CALLING_PREFERENCE_URI.equals(sliceUri)) {
                 return FeatureFactory.getFactory(getContext())
                         .getSlicesFeatureProvider()
                         .getNewWifiCallingSliceHelper(getContext())
                         .createWifiCallingPreferenceSlice(sliceUri);
-            } else if (FlashlightSliceBuilder.FLASHLIGHT_URI.equals(sliceUri)) {
+            } else if (CustomSliceRegistry.FLASHLIGHT_SLICE_URI.equals(sliceUri)) {
                 return FlashlightSliceBuilder.getSlice(getContext());
-            } else if (EmergencyInfoSlice.EMERGENCY_INFO_CARD_URI.equals(sliceUri)) {
+            } else if (CustomSliceRegistry.EMERGENCY_INFO_SLICE_URI.equals(sliceUri)) {
                 return EmergencyInfoSlice.getSlice(getContext());
             }
 
@@ -427,7 +422,7 @@
         try {
             sliceData = mSlicesDatabaseAccessor.getSliceDataFromUri(uri);
         } catch (IllegalStateException e) {
-            Log.d(TAG, "Could not create slicedata for uri: " + uri);
+            Log.d(TAG, "Could not create slicedata for uri: " + uri, e);
             return;
         }
 
@@ -476,16 +471,16 @@
 
     private List<Uri> getSpecialCasePlatformUris() {
         return Arrays.asList(
-                WifiSlice.WIFI_URI,
-                BluetoothSliceBuilder.BLUETOOTH_URI,
-                LocationSliceBuilder.LOCATION_URI
+                CustomSliceRegistry.WIFI_SLICE_URI,
+                CustomSliceRegistry.BLUETOOTH_URI,
+                CustomSliceRegistry.LOCATION_SLICE_URI
         );
     }
 
     private List<Uri> getSpecialCaseOemUris() {
         return Arrays.asList(
-                ZenModeSliceBuilder.ZEN_MODE_URI,
-                FlashlightSliceBuilder.FLASHLIGHT_URI
+                CustomSliceRegistry.ZEN_MODE_SLICE_URI,
+                CustomSliceRegistry.FLASHLIGHT_SLICE_URI
         );
     }
 
diff --git a/src/com/android/settings/slices/SliceDeepLinkSpringBoard.java b/src/com/android/settings/slices/SliceDeepLinkSpringBoard.java
index 7531778..01708af 100644
--- a/src/com/android/settings/slices/SliceDeepLinkSpringBoard.java
+++ b/src/com/android/settings/slices/SliceDeepLinkSpringBoard.java
@@ -62,11 +62,11 @@
                     final CustomSliceable sliceable =
                             customSliceManager.getSliceableFromUri(sliceUri);
                     launchIntent = sliceable.getIntent();
-                } else if (ZenModeSliceBuilder.ZEN_MODE_URI.equals(sliceUri)) {
+                } else if (CustomSliceRegistry.ZEN_MODE_SLICE_URI.equals(sliceUri)) {
                     launchIntent = ZenModeSliceBuilder.getIntent(this /* context */);
-                } else if (BluetoothSliceBuilder.BLUETOOTH_URI.equals(sliceUri)) {
+                } else if (CustomSliceRegistry.BLUETOOTH_URI.equals(sliceUri)) {
                     launchIntent = BluetoothSliceBuilder.getIntent(this /* context */);
-                } else if (LocationSliceBuilder.LOCATION_URI.equals(sliceUri)) {
+                } else if (CustomSliceRegistry.LOCATION_SLICE_URI.equals(sliceUri)) {
                     launchIntent = LocationSliceBuilder.getIntent(this /* context */);
                 } else {
                     final SlicesDatabaseAccessor slicesDatabaseAccessor =
diff --git a/src/com/android/settings/slices/SlicesFeatureProviderImpl.java b/src/com/android/settings/slices/SlicesFeatureProviderImpl.java
index 39d385e..508eb1c 100644
--- a/src/com/android/settings/slices/SlicesFeatureProviderImpl.java
+++ b/src/com/android/settings/slices/SlicesFeatureProviderImpl.java
@@ -1,3 +1,19 @@
+/*
+ * 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.slices;
 
 import android.content.Context;
diff --git a/src/com/android/settings/widget/ActionButtonPreference.java b/src/com/android/settings/widget/ActionButtonPreference.java
index 7ce84bd..a34d735 100644
--- a/src/com/android/settings/widget/ActionButtonPreference.java
+++ b/src/com/android/settings/widget/ActionButtonPreference.java
@@ -32,11 +32,30 @@
 
 import com.android.settings.R;
 
+/**
+ * This preference provides a four buttons layout with Settings style.
+ * It looks like below
+ *
+ * --------------------------------------------------
+ *  button1     | button2   | button3   | button4   |
+ * --------------------------------------------------
+ *
+ * User can set title / icon / click listener for each button.
+ *
+ * By default, four buttons are visible.
+ * However, there are two cases which button should be invisible(View.GONE).
+ *
+ * 1. User sets invisible for button. ex: ActionButtonPreference.setButton1Visible(false)
+ * 2. User doesn't set any title or icon for button.
+ *
+ */
 public class ActionButtonPreference extends Preference {
 
     private final String TAG = "ActionButtonPreference";
     private final ButtonInfo mButton1Info = new ButtonInfo();
     private final ButtonInfo mButton2Info = new ButtonInfo();
+    private final ButtonInfo mButton3Info = new ButtonInfo();
+    private final ButtonInfo mButton4Info = new ButtonInfo();
 
     public ActionButtonPreference(Context context, AttributeSet attrs,
             int defStyleAttr, int defStyleRes) {
@@ -60,7 +79,7 @@
     }
 
     private void init() {
-        setLayoutResource(R.layout.two_action_buttons);
+        setLayoutResource(R.layout.settings_action_buttons);
         setSelectable(false);
     }
 
@@ -72,9 +91,21 @@
 
         mButton1Info.mButton = (Button) holder.findViewById(R.id.button1);
         mButton2Info.mButton = (Button) holder.findViewById(R.id.button2);
+        mButton3Info.mButton = (Button) holder.findViewById(R.id.button3);
+        mButton4Info.mButton = (Button) holder.findViewById(R.id.button4);
 
         mButton1Info.setUpButton();
         mButton2Info.setUpButton();
+        mButton3Info.setUpButton();
+        mButton4Info.setUpButton();
+    }
+
+    public ActionButtonPreference setButton1Visible(boolean isVisible) {
+        if (isVisible != mButton1Info.mIsVisible) {
+            mButton1Info.mIsVisible = isVisible;
+            notifyChanged();
+        }
+        return this;
     }
 
     public ActionButtonPreference setButton1Text(@StringRes int textResId) {
@@ -110,6 +141,22 @@
         return this;
     }
 
+    public ActionButtonPreference setButton1OnClickListener(View.OnClickListener listener) {
+        if (listener != mButton1Info.mListener) {
+            mButton1Info.mListener = listener;
+            notifyChanged();
+        }
+        return this;
+    }
+
+    public ActionButtonPreference setButton2Visible(boolean isVisible) {
+        if (isVisible != mButton2Info.mIsVisible) {
+            mButton2Info.mIsVisible = isVisible;
+            notifyChanged();
+        }
+        return this;
+    }
+
     public ActionButtonPreference setButton2Text(@StringRes int textResId) {
         final String newText = getContext().getString(textResId);
         if (!TextUtils.equals(newText, mButton2Info.mText)) {
@@ -143,14 +190,6 @@
         return this;
     }
 
-    public ActionButtonPreference setButton1OnClickListener(View.OnClickListener listener) {
-        if (listener != mButton1Info.mListener) {
-            mButton1Info.mListener = listener;
-            notifyChanged();
-        }
-        return this;
-    }
-
     public ActionButtonPreference setButton2OnClickListener(View.OnClickListener listener) {
         if (listener != mButton2Info.mListener) {
             mButton2Info.mListener = listener;
@@ -159,17 +198,99 @@
         return this;
     }
 
-    public ActionButtonPreference setButton1Visible(boolean isVisible) {
-        if (isVisible != mButton1Info.mIsVisible) {
-            mButton1Info.mIsVisible = isVisible;
+    public ActionButtonPreference setButton3Visible(boolean isVisible) {
+        if (isVisible != mButton3Info.mIsVisible) {
+            mButton3Info.mIsVisible = isVisible;
             notifyChanged();
         }
         return this;
     }
 
-    public ActionButtonPreference setButton2Visible(boolean isVisible) {
-        if (isVisible != mButton2Info.mIsVisible) {
-            mButton2Info.mIsVisible = isVisible;
+    public ActionButtonPreference setButton3Text(@StringRes int textResId) {
+        final String newText = getContext().getString(textResId);
+        if (!TextUtils.equals(newText, mButton3Info.mText)) {
+            mButton3Info.mText = newText;
+            notifyChanged();
+        }
+        return this;
+    }
+
+    public ActionButtonPreference setButton3Icon(@DrawableRes int iconResId) {
+        if (iconResId == 0) {
+            return this;
+        }
+
+        final Drawable icon;
+        try {
+            icon = getContext().getDrawable(iconResId);
+            mButton3Info.mIcon = icon;
+            notifyChanged();
+        } catch (Resources.NotFoundException exception) {
+            Log.e(TAG, "Resource does not exist: " + iconResId);
+        }
+        return this;
+    }
+
+    public ActionButtonPreference setButton3Enabled(boolean isEnabled) {
+        if (isEnabled != mButton3Info.mIsEnabled) {
+            mButton3Info.mIsEnabled = isEnabled;
+            notifyChanged();
+        }
+        return this;
+    }
+
+    public ActionButtonPreference setButton3OnClickListener(View.OnClickListener listener) {
+        if (listener != mButton3Info.mListener) {
+            mButton3Info.mListener = listener;
+            notifyChanged();
+        }
+        return this;
+    }
+
+    public ActionButtonPreference setButton4Visible(boolean isVisible) {
+        if (isVisible != mButton4Info.mIsVisible) {
+            mButton4Info.mIsVisible = isVisible;
+            notifyChanged();
+        }
+        return this;
+    }
+
+    public ActionButtonPreference setButton4Text(@StringRes int textResId) {
+        final String newText = getContext().getString(textResId);
+        if (!TextUtils.equals(newText, mButton4Info.mText)) {
+            mButton4Info.mText = newText;
+            notifyChanged();
+        }
+        return this;
+    }
+
+    public ActionButtonPreference setButton4Icon(@DrawableRes int iconResId) {
+        if (iconResId == 0) {
+            return this;
+        }
+
+        final Drawable icon;
+        try {
+            icon = getContext().getDrawable(iconResId);
+            mButton4Info.mIcon = icon;
+            notifyChanged();
+        } catch (Resources.NotFoundException exception) {
+            Log.e(TAG, "Resource does not exist: " + iconResId);
+        }
+        return this;
+    }
+
+    public ActionButtonPreference setButton4Enabled(boolean isEnabled) {
+        if (isEnabled != mButton4Info.mIsEnabled) {
+            mButton4Info.mIsEnabled = isEnabled;
+            notifyChanged();
+        }
+        return this;
+    }
+
+    public ActionButtonPreference setButton4OnClickListener(View.OnClickListener listener) {
+        if (listener != mButton4Info.mListener) {
+            mButton4Info.mListener = listener;
             notifyChanged();
         }
         return this;
@@ -189,11 +310,24 @@
             mButton.setEnabled(mIsEnabled);
             mButton.setCompoundDrawablesWithIntrinsicBounds(
                     null /* left */, mIcon /* top */, null /* right */, null /* bottom */);
-            if (mIsVisible) {
+
+            if (shouldBeVisible()) {
                 mButton.setVisibility(View.VISIBLE);
             } else {
                 mButton.setVisibility(View.GONE);
             }
         }
+
+        /**
+         * By default, four buttons are visible.
+         * However, there are two cases which button should be invisible.
+         *
+         * 1. User set invisible for this button. ex: mIsVisible = false.
+         * 2. User didn't set any title or icon.
+         *
+         */
+        private boolean shouldBeVisible() {
+            return mIsVisible && (!TextUtils.isEmpty(mText) || mIcon != null);
+        }
     }
 }
\ No newline at end of file
diff --git a/src/com/android/settings/widget/EntityHeaderController.java b/src/com/android/settings/widget/EntityHeaderController.java
index 267838c..056f6b4 100644
--- a/src/com/android/settings/widget/EntityHeaderController.java
+++ b/src/com/android/settings/widget/EntityHeaderController.java
@@ -16,8 +16,7 @@
 
 package com.android.settings.widget;
 
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent
-        .ACTION_OPEN_APP_NOTIFICATION_SETTING;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_OPEN_APP_NOTIFICATION_SETTING;
 
 import android.annotation.IdRes;
 import android.annotation.UserIdInt;
@@ -48,11 +47,11 @@
 import com.android.settings.R;
 import com.android.settings.Utils;
 import com.android.settings.applications.AppInfoBase;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.applications.appinfo.AppInfoDashboardFragment;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.applications.ApplicationsState;
 import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.LayoutPreference;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
diff --git a/src/com/android/settings/widget/TwoStateButtonPreference.java b/src/com/android/settings/widget/TwoStateButtonPreference.java
index b154fb4..eeee65d 100644
--- a/src/com/android/settings/widget/TwoStateButtonPreference.java
+++ b/src/com/android/settings/widget/TwoStateButtonPreference.java
@@ -26,7 +26,7 @@
 import androidx.core.content.res.TypedArrayUtils;
 
 import com.android.settings.R;
-import com.android.settings.applications.LayoutPreference;
+import com.android.settingslib.widget.LayoutPreference;
 
 /**
  * Preference that presents a button with two states(On vs Off)
diff --git a/src/com/android/settings/wifi/NetworkRequestDialogActivity.java b/src/com/android/settings/wifi/NetworkRequestDialogActivity.java
new file mode 100644
index 0000000..5d89f77
--- /dev/null
+++ b/src/com/android/settings/wifi/NetworkRequestDialogActivity.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.wifi;
+
+import android.os.Bundle;
+
+import androidx.annotation.Nullable;
+import androidx.fragment.app.FragmentActivity;
+
+/**
+ * When other applications request to have a wifi connection, framework will bring up this activity
+ * to let user select which wifi ap wanna to connect. This activity is just a door for framework
+ * call, and main functional process is at {@code NetworkRequestDialogFragment}.
+ */
+public class NetworkRequestDialogActivity extends FragmentActivity {
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        final NetworkRequestDialogFragment fragment = NetworkRequestDialogFragment.newInstance();
+        fragment.show(getSupportFragmentManager(), "NetworkRequestDialogFragment");
+    }
+}
diff --git a/src/com/android/settings/wifi/NetworkRequestDialogFragment.java b/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
index 7078ae0..a1d8620 100644
--- a/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
+++ b/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
@@ -28,9 +28,11 @@
 import android.os.Handler;
 import android.os.Message;
 import android.widget.BaseAdapter;
+
 import androidx.annotation.NonNull;
 import androidx.appcompat.app.AlertDialog;
 import androidx.preference.internal.PreferenceImageView;
+
 import android.os.Bundle;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -38,257 +40,276 @@
 import android.widget.ArrayAdapter;
 import android.widget.ProgressBar;
 import android.widget.TextView;
+
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
 import com.android.settingslib.Utils;
 import com.android.settingslib.wifi.AccessPoint;
+
 import java.util.ArrayList;
 import java.util.List;
 
 public class NetworkRequestDialogFragment extends InstrumentedDialogFragment implements
-    DialogInterface.OnClickListener, NetworkRequestMatchCallback {
+        DialogInterface.OnClickListener, NetworkRequestMatchCallback {
 
-  /** Message sent to us to stop scanning wifi and pop up timeout dialog. */
-  private static final int MESSAGE_STOP_SCAN_WIFI_LIST = 0;
+    /** Message sent to us to stop scanning wifi and pop up timeout dialog. */
+    private static final int MESSAGE_STOP_SCAN_WIFI_LIST = 0;
 
-  /** Delayed time to stop scanning wifi. */
-  private static final int DELAY_TIME_STOP_SCAN_MS = 30 * 1000;
+    /** Delayed time to stop scanning wifi. */
+    private static final int DELAY_TIME_STOP_SCAN_MS = 30 * 1000;
 
-  private List<AccessPoint> mAccessPointList;
-  private AccessPointAdapter mDialogAdapter;
-  private NetworkRequestUserSelectionCallback mUserSelectionCallback;
+    private List<AccessPoint> mAccessPointList;
+    private AccessPointAdapter mDialogAdapter;
+    private NetworkRequestUserSelectionCallback mUserSelectionCallback;
 
-  public static NetworkRequestDialogFragment newInstance() {
-    NetworkRequestDialogFragment dialogFragment = new NetworkRequestDialogFragment();
-    return dialogFragment;
-  }
-
-  @Override
-  public Dialog onCreateDialog(Bundle savedInstanceState) {
-    final Context context = getContext();
-
-    // Prepares title.
-    final LayoutInflater inflater = LayoutInflater.from(context);
-    final View customTitle = inflater.inflate(R.layout.network_request_dialog_title, null);
-
-    final TextView title = customTitle.findViewById(R.id.network_request_title_text);
-    title.setText(R.string.network_connection_request_dialog_title);
-    final ProgressBar progressBar = customTitle.findViewById(R.id.network_request_title_progress);
-    progressBar.setVisibility(View.VISIBLE);
-
-    // Prepares adapter.
-    mDialogAdapter = new AccessPointAdapter(context,
-        R.layout.preference_access_point, getAccessPointList());
-
-    final AlertDialog.Builder builder = new AlertDialog.Builder(context)
-        .setCustomTitle(customTitle)
-        .setAdapter(mDialogAdapter, this)
-        .setPositiveButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
-    return builder.create();
-  }
-
-  @NonNull
-  List<AccessPoint> getAccessPointList() {
-    // Initials list for adapter, in case of display crashing.
-    if (mAccessPointList == null) {
-      mAccessPointList = new ArrayList<>();
-    }
-    return mAccessPointList;
-  }
-
-  private BaseAdapter getDialogAdapter() {
-    return mDialogAdapter;
-  }
-
-  @Override
-  public void onClick(DialogInterface dialog, int which) {
-    final List<AccessPoint> accessPointList = getAccessPointList();
-    if (accessPointList.size() == 0) {
-      return;  // Invalid values.
-    }
-    if (mUserSelectionCallback == null) {
-      return; // Callback is missing or not ready.
-    }
-
-    if (which < accessPointList.size()) {
-      WifiConfiguration wifiConfig = accessPointList.get(which).getConfig();
-      mUserSelectionCallback.select(wifiConfig);
-    }
-  }
-
-  @Override
-  public void onPause() {
-    super.onPause();
-
-    mHandler.removeMessages(MESSAGE_STOP_SCAN_WIFI_LIST);
-    final WifiManager wifiManager = getContext().getApplicationContext()
-        .getSystemService(WifiManager.class);
-    if (wifiManager != null) {
-      wifiManager.unregisterNetworkRequestMatchCallback(this);
-    }
-  }
-
-  @Override
-  public void onResume() {
-    super.onResume();
-
-    final WifiManager wifiManager = getContext().getApplicationContext()
-        .getSystemService(WifiManager.class);
-    if (wifiManager != null) {
-      wifiManager.registerNetworkRequestMatchCallback(this, mHandler);
-    }
-    // Sets time-out to stop scanning.
-    mHandler.sendEmptyMessageDelayed(MESSAGE_STOP_SCAN_WIFI_LIST, DELAY_TIME_STOP_SCAN_MS);
-  }
-
-  private final Handler mHandler = new Handler() {
-    @Override
-    public void handleMessage(Message msg) {
-      switch (msg.what) {
-        case MESSAGE_STOP_SCAN_WIFI_LIST:
-          removeMessages(MESSAGE_STOP_SCAN_WIFI_LIST);
-          stopScanningAndPopTimeoutDialog();
-          break;
-        default:
-          // Do nothing.
-          break;
-      }
-    }
-  };
-
-  protected void stopScanningAndPopTimeoutDialog() {
-    // Dismisses current dialog.
-    dismiss();
-
-    // Throws new timeout dialog.
-    final NetworkRequestTimeoutDialogFragment fragment = NetworkRequestTimeoutDialogFragment
-        .newInstance();
-    fragment.show(getActivity().getSupportFragmentManager(), null);
-  }
-
-  @Override
-  public int getMetricsCategory() {
-    return MetricsProto.MetricsEvent.WIFI_SCANNING_NEEDED_DIALOG;
-  }
-
-  private class AccessPointAdapter extends ArrayAdapter<AccessPoint> {
-
-    private final int mResourceId;
-    private final LayoutInflater mInflater;
-
-    public AccessPointAdapter(Context context, int resourceId, List<AccessPoint> objects) {
-      super(context, resourceId, objects);
-      mResourceId = resourceId;
-      mInflater = LayoutInflater.from(context);
+    public static NetworkRequestDialogFragment newInstance() {
+        NetworkRequestDialogFragment dialogFragment = new NetworkRequestDialogFragment();
+        return dialogFragment;
     }
 
     @Override
-    public View getView(int position, View view, ViewGroup parent) {
-      if (view == null) {
-        view = mInflater.inflate(mResourceId, parent, false);
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        final Context context = getContext();
 
-        final View divider = view.findViewById(com.android.settingslib.R.id.two_target_divider);
-        divider.setVisibility(View.GONE);
-      }
+        // Prepares title.
+        final LayoutInflater inflater = LayoutInflater.from(context);
+        final View customTitle = inflater.inflate(R.layout.network_request_dialog_title, null);
 
-      final AccessPoint accessPoint = getItem(position);
+        final TextView title = customTitle.findViewById(R.id.network_request_title_text);
+        title.setText(R.string.network_connection_request_dialog_title);
+        final ProgressBar progressBar = customTitle.findViewById(
+                R.id.network_request_title_progress);
+        progressBar.setVisibility(View.VISIBLE);
 
-      final TextView titleView = view.findViewById(android.R.id.title);
-      if (titleView != null) {
-        titleView.setText(accessPoint.getSsidStr());
-      }
+        // Prepares adapter.
+        mDialogAdapter = new AccessPointAdapter(context,
+                R.layout.preference_access_point, getAccessPointList());
 
-      final TextView summary = view.findViewById(android.R.id.summary);
-      if (summary != null) {
-        summary.setText(accessPoint.getSettingsSummary());
-      }
+        final AlertDialog.Builder builder = new AlertDialog.Builder(context)
+                .setCustomTitle(customTitle)
+                .setAdapter(mDialogAdapter, this)
+                .setPositiveButton(R.string.cancel, (dialog, which) -> getActivity().finish());
 
-      final PreferenceImageView imageView = view.findViewById(android.R.id.icon);
-      final int level = accessPoint.getLevel();
-      if (imageView != null) {
-        final Drawable drawable = getContext().getDrawable(Utils.getWifiIconResource(level));
-        drawable.setTintList(Utils.getColorAttr(getContext(), android.R.attr.colorControlNormal));
-        imageView.setImageDrawable(drawable);
-      }
-
-      return view;
-    }
-  }
-
-  @Override
-  public void onAbort() {
-    // TODO(b/117399926): We should have a UI notify user here.
-  }
-
-  @Override
-  public void onUserSelectionCallbackRegistration(
-      NetworkRequestUserSelectionCallback userSelectionCallback) {
-    mUserSelectionCallback = userSelectionCallback;
-  }
-
-  @Override
-  public void onMatch(List<ScanResult> scanResults) {
-    // TODO(b/119846365): Checks if we could escalate the converting effort.
-    // Converts ScanResult to WifiConfiguration.
-    List<WifiConfiguration> wifiConfigurations = null;
-    final WifiManager wifiManager = getContext().getApplicationContext()
-        .getSystemService(WifiManager.class);
-    if (wifiManager != null) {
-      wifiConfigurations = wifiManager.getAllMatchingWifiConfigs(scanResults);
+        // Clicking list item is to connect wifi ap.
+        final AlertDialog dialog = builder.create();
+        dialog.getListView()
+                .setOnItemClickListener(
+                        (parent, view, position, id) -> this.onClick(dialog, position));
+        return dialog;
     }
 
-    setUpAccessPointList(wifiConfigurations);
-
-    if (getDialogAdapter() != null) {
-      getDialogAdapter().notifyDataSetChanged();
-    }
-  }
-
-  @Override
-  public void onUserSelectionConnectSuccess(WifiConfiguration wificonfiguration) {
-    if (getDialogAdapter() != null) {
-      updateAccessPointListItem(wificonfiguration);
-      getDialogAdapter().notifyDataSetChanged();
-    }
-  }
-
-  @Override
-  public void onUserSelectionConnectFailure(WifiConfiguration wificonfiguration) {
-    if (mDialogAdapter != null) {
-      updateAccessPointListItem(wificonfiguration);
-      getDialogAdapter().notifyDataSetChanged();
-    }
-  }
-
-  private void updateAccessPointListItem(WifiConfiguration wificonfiguration) {
-    if (wificonfiguration == null) {
-      return;
+    @NonNull
+    List<AccessPoint> getAccessPointList() {
+        // Initials list for adapter, in case of display crashing.
+        if (mAccessPointList == null) {
+            mAccessPointList = new ArrayList<>();
+        }
+        return mAccessPointList;
     }
 
-    final List<AccessPoint> accessPointList = getAccessPointList();
-    final int accessPointListSize = accessPointList.size();
-
-    for (int i = 0; i < accessPointListSize; i++) {
-      AccessPoint accessPoint = accessPointList.get(i);
-      // It is the same AccessPoint SSID, and should be replaced to update latest properties.
-      if (accessPoint.matches(wificonfiguration)) {
-        accessPointList.set(i, new AccessPoint(getContext(), wificonfiguration));
-        break;
-      }
-    }
-  }
-
-  private void setUpAccessPointList(List<WifiConfiguration> wifiConfigurations) {
-    // Grants for zero size input, since maybe current wifi is off or somethings are wrong.
-    if (wifiConfigurations == null) {
-      return;
+    private BaseAdapter getDialogAdapter() {
+        return mDialogAdapter;
     }
 
-    final List<AccessPoint> accessPointList = getAccessPointList();
-    accessPointList.clear();
-    for (WifiConfiguration config : wifiConfigurations) {
-      accessPointList.add(new AccessPoint(getContext(), config));
+    @Override
+    public void onClick(DialogInterface dialog, int which) {
+        final List<AccessPoint> accessPointList = getAccessPointList();
+        if (accessPointList.size() == 0) {
+            return;  // Invalid values.
+        }
+        if (mUserSelectionCallback == null) {
+            return; // Callback is missing or not ready.
+        }
+
+        if (which < accessPointList.size()) {
+            WifiConfiguration wifiConfig = accessPointList.get(which).getConfig();
+            mUserSelectionCallback.select(wifiConfig);
+        }
     }
-  }
-}
\ No newline at end of file
+
+    @Override
+    public void onCancel(@NonNull DialogInterface dialog) {
+        super.onCancel(dialog);
+        // Finishes activity when user clicks back key or outside of dialog.
+        getActivity().finish();
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+
+        mHandler.removeMessages(MESSAGE_STOP_SCAN_WIFI_LIST);
+        final WifiManager wifiManager = getContext().getApplicationContext()
+                .getSystemService(WifiManager.class);
+        if (wifiManager != null) {
+            wifiManager.unregisterNetworkRequestMatchCallback(this);
+        }
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+
+        final WifiManager wifiManager = getContext().getApplicationContext()
+                .getSystemService(WifiManager.class);
+        if (wifiManager != null) {
+            wifiManager.registerNetworkRequestMatchCallback(this, mHandler);
+        }
+        // Sets time-out to stop scanning.
+        mHandler.sendEmptyMessageDelayed(MESSAGE_STOP_SCAN_WIFI_LIST, DELAY_TIME_STOP_SCAN_MS);
+    }
+
+    private final Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MESSAGE_STOP_SCAN_WIFI_LIST:
+                    removeMessages(MESSAGE_STOP_SCAN_WIFI_LIST);
+                    stopScanningAndPopTimeoutDialog();
+                    break;
+                default:
+                    // Do nothing.
+                    break;
+            }
+        }
+    };
+
+    protected void stopScanningAndPopTimeoutDialog() {
+        // Dismisses current dialog.
+        dismiss();
+
+        // Throws new timeout dialog.
+        final NetworkRequestTimeoutDialogFragment fragment = NetworkRequestTimeoutDialogFragment
+                .newInstance();
+        fragment.show(getActivity().getSupportFragmentManager(), null);
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        return MetricsProto.MetricsEvent.WIFI_SCANNING_NEEDED_DIALOG;
+    }
+
+    private class AccessPointAdapter extends ArrayAdapter<AccessPoint> {
+
+        private final int mResourceId;
+        private final LayoutInflater mInflater;
+
+        public AccessPointAdapter(Context context, int resourceId, List<AccessPoint> objects) {
+            super(context, resourceId, objects);
+            mResourceId = resourceId;
+            mInflater = LayoutInflater.from(context);
+        }
+
+        @Override
+        public View getView(int position, View view, ViewGroup parent) {
+            if (view == null) {
+                view = mInflater.inflate(mResourceId, parent, false);
+
+                final View divider = view.findViewById(
+                        com.android.settingslib.R.id.two_target_divider);
+                divider.setVisibility(View.GONE);
+            }
+
+            final AccessPoint accessPoint = getItem(position);
+
+            final TextView titleView = view.findViewById(android.R.id.title);
+            if (titleView != null) {
+                titleView.setText(accessPoint.getSsidStr());
+            }
+
+            final TextView summary = view.findViewById(android.R.id.summary);
+            if (summary != null) {
+                summary.setText(accessPoint.getSettingsSummary());
+            }
+
+            final PreferenceImageView imageView = view.findViewById(android.R.id.icon);
+            final int level = accessPoint.getLevel();
+            if (imageView != null) {
+                final Drawable drawable = getContext().getDrawable(
+                        Utils.getWifiIconResource(level));
+                drawable.setTintList(
+                        Utils.getColorAttr(getContext(), android.R.attr.colorControlNormal));
+                imageView.setImageDrawable(drawable);
+            }
+
+            return view;
+        }
+    }
+
+    @Override
+    public void onAbort() {
+        // TODO(b/117399926): We should have a UI notify user here.
+    }
+
+    @Override
+    public void onUserSelectionCallbackRegistration(
+            NetworkRequestUserSelectionCallback userSelectionCallback) {
+        mUserSelectionCallback = userSelectionCallback;
+    }
+
+    @Override
+    public void onMatch(List<ScanResult> scanResults) {
+        // TODO(b/119846365): Checks if we could escalate the converting effort.
+        // Converts ScanResult to WifiConfiguration.
+        List<WifiConfiguration> wifiConfigurations = null;
+        final WifiManager wifiManager = getContext().getApplicationContext()
+                .getSystemService(WifiManager.class);
+        if (wifiManager != null) {
+            wifiConfigurations = wifiManager.getAllMatchingWifiConfigs(scanResults);
+        }
+
+        setUpAccessPointList(wifiConfigurations);
+
+        if (getDialogAdapter() != null) {
+            getDialogAdapter().notifyDataSetChanged();
+        }
+    }
+
+    @Override
+    public void onUserSelectionConnectSuccess(WifiConfiguration wificonfiguration) {
+        if (getDialogAdapter() != null) {
+            updateAccessPointListItem(wificonfiguration);
+            getDialogAdapter().notifyDataSetChanged();
+        }
+    }
+
+    @Override
+    public void onUserSelectionConnectFailure(WifiConfiguration wificonfiguration) {
+        if (mDialogAdapter != null) {
+            updateAccessPointListItem(wificonfiguration);
+            getDialogAdapter().notifyDataSetChanged();
+        }
+    }
+
+    private void updateAccessPointListItem(WifiConfiguration wificonfiguration) {
+        if (wificonfiguration == null) {
+            return;
+        }
+
+        final List<AccessPoint> accessPointList = getAccessPointList();
+        final int accessPointListSize = accessPointList.size();
+
+        for (int i = 0; i < accessPointListSize; i++) {
+            AccessPoint accessPoint = accessPointList.get(i);
+            // It is the same AccessPoint SSID, and should be replaced to update latest properties.
+            if (accessPoint.matches(wificonfiguration)) {
+                accessPointList.set(i, new AccessPoint(getContext(), wificonfiguration));
+                break;
+            }
+        }
+    }
+
+    private void setUpAccessPointList(List<WifiConfiguration> wifiConfigurations) {
+        // Grants for zero size input, since maybe current wifi is off or somethings are wrong.
+        if (wifiConfigurations == null) {
+            return;
+        }
+
+        final List<AccessPoint> accessPointList = getAccessPointList();
+        accessPointList.clear();
+        for (WifiConfiguration config : wifiConfigurations) {
+            accessPointList.add(new AccessPoint(getContext(), config));
+        }
+    }
+}
diff --git a/src/com/android/settings/wifi/WifiDetailPreference.java b/src/com/android/settings/wifi/WifiDetailPreference.java
deleted file mode 100644
index 2567a42..0000000
--- a/src/com/android/settings/wifi/WifiDetailPreference.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.wifi;
-
-import android.content.Context;
-import android.text.TextUtils;
-import android.util.AttributeSet;
-import android.widget.TextView;
-
-import androidx.preference.Preference;
-import androidx.preference.PreferenceViewHolder;
-
-import com.android.settings.R;
-
-/**
- * A Preference to be used with the Wifi Network Detail Fragment that allows a summary text to be
- * set inside the widget resource
- */
-public class WifiDetailPreference extends Preference {
-    private String mDetailText;
-
-    public WifiDetailPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        setWidgetLayoutResource(R.layout.preference_widget_summary);
-    }
-
-    public void setDetailText(String text) {
-        if (TextUtils.equals(mDetailText, text)) return;
-        mDetailText = text;
-        notifyChanged();
-    }
-
-    @Override
-    public void onBindViewHolder(PreferenceViewHolder view) {
-        super.onBindViewHolder(view);
-        TextView textView = ((TextView) view.findViewById(R.id.widget_summary));
-        textView.setText(mDetailText);
-        textView.setPadding(0, 0, 10, 0);
-    }
-}
diff --git a/src/com/android/settings/wifi/WifiSlice.java b/src/com/android/settings/wifi/WifiSlice.java
index d06d830..0dbbfd5 100644
--- a/src/com/android/settings/wifi/WifiSlice.java
+++ b/src/com/android/settings/wifi/WifiSlice.java
@@ -19,9 +19,10 @@
 import static android.app.slice.Slice.EXTRA_TOGGLE_STATE;
 import static android.provider.SettingsSlicesContract.KEY_WIFI;
 
+import static com.android.settings.slices.CustomSliceRegistry.WIFI_SLICE_URI;
+
 import android.annotation.ColorInt;
 import android.app.PendingIntent;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -30,7 +31,6 @@
 import android.net.wifi.WifiManager;
 import android.net.wifi.WifiSsid;
 import android.os.Bundle;
-import android.provider.SettingsSlicesContract;
 import android.text.TextUtils;
 
 import androidx.annotation.VisibleForTesting;
@@ -60,16 +60,6 @@
  */
 public class WifiSlice implements CustomSliceable {
 
-    /**
-     * Backing Uri for the Wifi Slice.
-     */
-    public static final Uri WIFI_URI = new Uri.Builder()
-            .scheme(ContentResolver.SCHEME_CONTENT)
-            .authority(SettingsSlicesContract.AUTHORITY)
-            .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
-            .appendPath(KEY_WIFI)
-            .build();
-
     @VisibleForTesting
     static final int DEFAULT_EXPANDED_ROW_COUNT = 3;
 
@@ -81,7 +71,7 @@
 
     @Override
     public Uri getUri() {
-        return WIFI_URI;
+        return WIFI_SLICE_URI;
     }
 
     @Override
@@ -92,9 +82,6 @@
         return filter;
     }
 
-    /**
-     * Return a Wifi Slice bound to {@link #WIFI_URI}.
-     */
     @Override
     public Slice getSlice() {
         final boolean isWifiEnabled = isWifiEnabled();
@@ -109,7 +96,8 @@
         final SliceAction toggleSliceAction = new SliceAction(toggleAction, null /* actionTitle */,
                 isWifiEnabled);
 
-        final ListBuilder listBuilder = new ListBuilder(mContext, WIFI_URI, ListBuilder.INFINITY)
+        final ListBuilder listBuilder = new ListBuilder(mContext, WIFI_SLICE_URI,
+                ListBuilder.INFINITY)
                 .setAccentColor(color)
                 .addRow(new RowBuilder()
                         .setTitle(title)
diff --git a/src/com/android/settings/wifi/calling/WifiCallingSliceHelper.java b/src/com/android/settings/wifi/calling/WifiCallingSliceHelper.java
index 0629ad3..65012fc 100644
--- a/src/com/android/settings/wifi/calling/WifiCallingSliceHelper.java
+++ b/src/com/android/settings/wifi/calling/WifiCallingSliceHelper.java
@@ -18,9 +18,11 @@
 
 import static android.app.slice.Slice.EXTRA_TOGGLE_STATE;
 
+import static com.android.settings.slices.CustomSliceRegistry.WIFI_CALLING_PREFERENCE_URI;
+import static com.android.settings.slices.CustomSliceRegistry.WIFI_CALLING_URI;
+
 import android.app.PendingIntent;
 import android.content.ComponentName;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.net.Uri;
@@ -42,9 +44,7 @@
 import com.android.ims.ImsManager;
 import com.android.settings.R;
 import com.android.settings.Utils;
-import com.android.settings.slices.SettingsSliceProvider;
 import com.android.settings.slices.SliceBroadcastReceiver;
-import com.android.settings.slices.SliceBuilderUtils;
 
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
@@ -104,24 +104,6 @@
             "android.settings.WIFI_CALLING_SETTINGS";
 
     /**
-     * Full {@link Uri} for the Wifi Calling Slice.
-     */
-    public static final Uri WIFI_CALLING_URI = new Uri.Builder()
-            .scheme(ContentResolver.SCHEME_CONTENT)
-            .authority(SettingsSliceProvider.SLICE_AUTHORITY)
-            .appendPath(PATH_WIFI_CALLING)
-            .build();
-
-    /**
-     * Full {@link Uri} for the Wifi Calling Preference Slice.
-     */
-    public static final Uri WIFI_CALLING_PREFERENCE_URI = new Uri.Builder()
-            .scheme(ContentResolver.SCHEME_CONTENT)
-            .authority(SettingsSliceProvider.SLICE_AUTHORITY)
-            .appendPath(PATH_WIFI_CALLING_PREFERENCE)
-            .build();
-
-    /**
      * Timeout for querying wifi calling setting from ims manager.
      */
     private static final int TIMEOUT_MILLIS = 2000;
@@ -246,7 +228,7 @@
         }
 
         final boolean isWifiCallingPrefEditable = isCarrierConfigManagerKeyEnabled(
-                CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL, subId,false);
+                CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL, subId, false);
         final boolean isWifiOnlySupported = isCarrierConfigManagerKeyEnabled(
                 CarrierConfigManager.KEY_CARRIER_WFC_SUPPORTS_WIFI_ONLY_BOOL, subId, true);
         final ImsManager imsManager = getImsManager(subId);
@@ -287,8 +269,8 @@
      * Returns actionable wifi calling preference slice.
      *
      * @param isWifiOnlySupported adds row for wifi only if this is true
-     * @param currentWfcPref current Preference {@link ImsConfig}
-     * @param sliceUri sliceUri
+     * @param currentWfcPref      current Preference {@link ImsConfig}
+     * @param sliceUri            sliceUri
      * @return Slice for actionable wifi calling preference settings
      */
     private Slice getWifiCallingPreferenceSlice(boolean isWifiOnlySupported,
@@ -299,12 +281,12 @@
         ListBuilder listBuilder = new ListBuilder(mContext, sliceUri, ListBuilder.INFINITY)
                 .setAccentColor(Utils.getColorAccentDefaultColor(mContext));
         listBuilder.setHeader(new ListBuilder.HeaderBuilder()
-                        .setTitle(mContext.getText(R.string.wifi_calling_mode_title))
-                        .setSubtitle(getWifiCallingPreferenceSummary(currentWfcPref))
-                        .setPrimaryAction(new SliceAction(
-                                getActivityIntent(ACTION_WIFI_CALLING_SETTINGS_ACTIVITY),
-                                icon,
-                                mContext.getText(R.string.wifi_calling_mode_title))));
+                .setTitle(mContext.getText(R.string.wifi_calling_mode_title))
+                .setSubtitle(getWifiCallingPreferenceSummary(currentWfcPref))
+                .setPrimaryAction(new SliceAction(
+                        getActivityIntent(ACTION_WIFI_CALLING_SETTINGS_ACTIVITY),
+                        icon,
+                        mContext.getText(R.string.wifi_calling_mode_title))));
 
         if (isWifiOnlySupported) {
             listBuilder.addRow(wifiPreferenceRowBuilder(listBuilder,
@@ -329,9 +311,9 @@
     /**
      * Returns RowBuilder for a new row containing specific wifi calling preference.
      *
-     * @param listBuilder ListBuilder that will be the parent for this RowBuilder
+     * @param listBuilder          ListBuilder that will be the parent for this RowBuilder
      * @param preferenceTitleResId resource Id for the preference row title
-     * @param action action to be added for the row
+     * @param action               action to be added for the row
      * @return RowBuilder for the row
      */
     private RowBuilder wifiPreferenceRowBuilder(ListBuilder listBuilder,
@@ -414,8 +396,7 @@
         }
         // notify change in slice in any case to get re-queried. This would result in displaying
         // appropriate message with the updated setting.
-        final Uri uri = SliceBuilderUtils.getUri(PATH_WIFI_CALLING, false /*isPlatformSlice*/);
-        mContext.getContentResolver().notifyChange(uri, null);
+        mContext.getContentResolver().notifyChange(WIFI_CALLING_URI, null);
     }
 
     /**
@@ -433,7 +414,7 @@
 
         if (subId > SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
             final boolean isWifiCallingPrefEditable = isCarrierConfigManagerKeyEnabled(
-                    CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL, subId,false);
+                    CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL, subId, false);
             final boolean isWifiOnlySupported = isCarrierConfigManagerKeyEnabled(
                     CarrierConfigManager.KEY_CARRIER_WFC_SUPPORTS_WIFI_ONLY_BOOL, subId, true);
 
@@ -470,15 +451,13 @@
 
         // notify change in slice in any case to get re-queried. This would result in displaying
         // appropriate message.
-        final Uri uri = SliceBuilderUtils.getUri(PATH_WIFI_CALLING_PREFERENCE,
-                false /*isPlatformSlice*/);
-        mContext.getContentResolver().notifyChange(uri, null);
+        mContext.getContentResolver().notifyChange(WIFI_CALLING_PREFERENCE_URI, null);
     }
 
     /**
      * Returns Slice with the title and subtitle provided as arguments with wifi signal Icon.
      *
-     * @param title Title of the slice
+     * @param title    Title of the slice
      * @param subtitle Subtitle of the slice
      * @param sliceUri slice uri
      * @return Slice with title and subtitle
diff --git a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
index 3bf38a7..48446c9 100644
--- a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
+++ b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
@@ -54,11 +54,9 @@
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
 import com.android.settings.Utils;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.core.PreferenceControllerMixin;
 import com.android.settings.widget.ActionButtonPreference;
 import com.android.settings.widget.EntityHeaderController;
-import com.android.settings.wifi.WifiDetailPreference;
 import com.android.settings.wifi.WifiDialog;
 import com.android.settings.wifi.WifiDialog.WifiDialogListener;
 import com.android.settings.wifi.WifiUtils;
@@ -68,6 +66,7 @@
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnPause;
 import com.android.settingslib.core.lifecycle.events.OnResume;
+import com.android.settingslib.widget.LayoutPreference;
 import com.android.settingslib.wifi.AccessPoint;
 
 import java.net.Inet4Address;
@@ -133,15 +132,15 @@
     // UI elements - in order of appearance
     private ActionButtonPreference mButtonsPref;
     private EntityHeaderController mEntityHeaderController;
-    private WifiDetailPreference mSignalStrengthPref;
-    private WifiDetailPreference mLinkSpeedPref;
-    private WifiDetailPreference mFrequencyPref;
-    private WifiDetailPreference mSecurityPref;
-    private WifiDetailPreference mMacAddressPref;
-    private WifiDetailPreference mIpAddressPref;
-    private WifiDetailPreference mGatewayPref;
-    private WifiDetailPreference mSubnetPref;
-    private WifiDetailPreference mDnsPref;
+    private Preference mSignalStrengthPref;
+    private Preference mLinkSpeedPref;
+    private Preference mFrequencyPref;
+    private Preference mSecurityPref;
+    private Preference mMacAddressPref;
+    private Preference mIpAddressPref;
+    private Preference mGatewayPref;
+    private Preference mSubnetPref;
+    private Preference mDnsPref;
     private PreferenceCategory mIpv6Category;
     private Preference mIpv6AddressPref;
 
@@ -283,22 +282,21 @@
                 .setButton2Text(R.string.wifi_sign_in_button_text)
                 .setButton2OnClickListener(view -> signIntoNetwork());
 
-        mSignalStrengthPref =
-                (WifiDetailPreference) screen.findPreference(KEY_SIGNAL_STRENGTH_PREF);
-        mLinkSpeedPref = (WifiDetailPreference) screen.findPreference(KEY_LINK_SPEED);
-        mFrequencyPref = (WifiDetailPreference) screen.findPreference(KEY_FREQUENCY_PREF);
-        mSecurityPref = (WifiDetailPreference) screen.findPreference(KEY_SECURITY_PREF);
+        mSignalStrengthPref = screen.findPreference(KEY_SIGNAL_STRENGTH_PREF);
+        mLinkSpeedPref = screen.findPreference(KEY_LINK_SPEED);
+        mFrequencyPref = screen.findPreference(KEY_FREQUENCY_PREF);
+        mSecurityPref = screen.findPreference(KEY_SECURITY_PREF);
 
-        mMacAddressPref = (WifiDetailPreference) screen.findPreference(KEY_MAC_ADDRESS_PREF);
-        mIpAddressPref = (WifiDetailPreference) screen.findPreference(KEY_IP_ADDRESS_PREF);
-        mGatewayPref = (WifiDetailPreference) screen.findPreference(KEY_GATEWAY_PREF);
-        mSubnetPref = (WifiDetailPreference) screen.findPreference(KEY_SUBNET_MASK_PREF);
-        mDnsPref = (WifiDetailPreference) screen.findPreference(KEY_DNS_PREF);
+        mMacAddressPref = screen.findPreference(KEY_MAC_ADDRESS_PREF);
+        mIpAddressPref = screen.findPreference(KEY_IP_ADDRESS_PREF);
+        mGatewayPref = screen.findPreference(KEY_GATEWAY_PREF);
+        mSubnetPref = screen.findPreference(KEY_SUBNET_MASK_PREF);
+        mDnsPref = screen.findPreference(KEY_DNS_PREF);
 
         mIpv6Category = (PreferenceCategory) screen.findPreference(KEY_IPV6_CATEGORY);
         mIpv6AddressPref = screen.findPreference(KEY_IPV6_ADDRESSES_PREF);
 
-        mSecurityPref.setDetailText(mAccessPoint.getSecurityString(false /* concise */));
+        mSecurityPref.setSummary(mAccessPoint.getSecurityString(false /* concise */));
     }
 
     private void setupEntityHeader(PreferenceScreen screen) {
@@ -359,12 +357,12 @@
         refreshRssiViews();
 
         // MAC Address Pref
-        mMacAddressPref.setDetailText(mWifiInfo.getMacAddress());
+        mMacAddressPref.setSummary(mWifiInfo.getMacAddress());
 
         // Link Speed Pref
         int linkSpeedMbps = mWifiInfo.getLinkSpeed();
         mLinkSpeedPref.setVisible(linkSpeedMbps >= 0);
-        mLinkSpeedPref.setDetailText(mContext.getString(
+        mLinkSpeedPref.setSummary(mContext.getString(
                 R.string.link_speed, mWifiInfo.getLinkSpeed()));
 
         // Frequency Pref
@@ -379,7 +377,7 @@
         } else {
             Log.e(TAG, "Unexpected frequency " + frequency);
         }
-        mFrequencyPref.setDetailText(band);
+        mFrequencyPref.setSummary(band);
 
         updateIpLayerInfo();
     }
@@ -414,12 +412,12 @@
                 R.color.wifi_details_icon_color, mContext.getTheme()));
         mSignalStrengthPref.setIcon(wifiIconDark);
 
-        mSignalStrengthPref.setDetailText(mSignalStr[mRssiSignalLevel]);
+        mSignalStrengthPref.setSummary(mSignalStr[mRssiSignalLevel]);
     }
 
-    private void updatePreference(WifiDetailPreference pref, String detailText) {
+    private void updatePreference(Preference pref, String detailText) {
         if (!TextUtils.isEmpty(detailText)) {
-            pref.setDetailText(detailText);
+            pref.setSummary(detailText);
             pref.setVisible(true);
         } else {
             pref.setVisible(false);
diff --git a/src/com/android/settings/wifi/dpp/WifiDppAddDeviceFragment.java b/src/com/android/settings/wifi/dpp/WifiDppAddDeviceFragment.java
new file mode 100644
index 0000000..177e79d
--- /dev/null
+++ b/src/com/android/settings/wifi/dpp/WifiDppAddDeviceFragment.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.wifi.dpp;
+
+import android.os.Bundle;
+
+import com.android.settings.R;
+
+/**
+ * After getting Wi-Fi network information and(or) QR code, this fragment config a device to connect
+ * to the Wi-Fi network.
+ */
+public class WifiDppAddDeviceFragment extends WifiDppQrCodeBaseFragment {
+    @Override
+    protected int getLayout() {
+        return R.layout.wifi_dpp_add_device_fragment;
+    }
+
+    @Override
+    public void onActivityCreated (Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+    }
+}
diff --git a/src/com/android/settings/wifi/dpp/WifiDppChooseSavedWifiNetworkFragment.java b/src/com/android/settings/wifi/dpp/WifiDppChooseSavedWifiNetworkFragment.java
new file mode 100644
index 0000000..7d031c1
--- /dev/null
+++ b/src/com/android/settings/wifi/dpp/WifiDppChooseSavedWifiNetworkFragment.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.wifi.dpp;
+
+import android.os.Bundle;
+
+import com.android.settings.R;
+
+/**
+ * After a camera APP scanned a Wi-Fi DPP QR code, it can trigger
+ * {@code WifiDppConfiguratorActivity} to start with this fragment to choose a saved Wi-Fi network.
+ */
+public class WifiDppChooseSavedWifiNetworkFragment extends WifiDppQrCodeBaseFragment {
+    @Override
+    protected int getLayout() {
+        return R.layout.wifi_dpp_choose_saved_wifi_network_fragment;
+    }
+
+    @Override
+    public void onActivityCreated (Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+    }
+}
diff --git a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
index bccb53a..e631c84 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
@@ -67,25 +67,48 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.wifi_dpp_activity);
 
-        // Hide action bar
-        ActionBar action = getActionBar();
-        if (action != null) {
-            action.hide();
-        }
-
         mFragmentManager = getSupportFragmentManager();
         mFragmentTransaction = getSupportFragmentManager().beginTransaction();
 
         final int launchMode = getIntent().getIntExtra(EXTRA_LAUNCH_MODE,
             LaunchMode.LAUNCH_MODE_NOT_DEFINED.getMode());
         if (launchMode == LaunchMode.LAUNCH_MODE_QR_CODE_SCANNER.getMode()) {
-            WifiDppQrCodeScannerFragment scanFragment = new WifiDppQrCodeScannerFragment();
-            mFragmentTransaction.add(R.id.fragment_container, scanFragment);
-            mFragmentTransaction.commit();
+            addQrCodeScannerFragment();
+        } else if (launchMode == LaunchMode.LAUNCH_MODE_QR_CODE_GENERATOR.getMode()) {
+            addQrCodeGeneratorFragment();
+        } else if (launchMode == LaunchMode.LAUNCH_MODE_CHOOSE_SAVED_WIFI_NETWORK.getMode()) {
+            addChooseSavedWifiNetworkFragment();
         } else {
             Log.e(TAG, "Launch with an invalid mode extra");
             setResult(Activity.RESULT_CANCELED);
             finish();
         }
     }
+
+    private void addQrCodeScannerFragment() {
+        WifiDppQrCodeScannerFragment fragment = new WifiDppQrCodeScannerFragment();
+        mFragmentTransaction.add(R.id.fragment_container, fragment);
+        mFragmentTransaction.addToBackStack(null);
+        mFragmentTransaction.commit();
+    }
+
+    private void addQrCodeGeneratorFragment() {
+        WifiDppQrCodeGeneratorFragment fragment = new WifiDppQrCodeGeneratorFragment();
+        mFragmentTransaction.add(R.id.fragment_container, fragment);
+        mFragmentTransaction.addToBackStack(null);
+        mFragmentTransaction.commit();
+    }
+
+    private void addChooseSavedWifiNetworkFragment() {
+        ActionBar action = getActionBar();
+        if (action != null) {
+            action.hide();
+        }
+
+        WifiDppChooseSavedWifiNetworkFragment fragment =
+                new WifiDppChooseSavedWifiNetworkFragment();
+        mFragmentTransaction.add(R.id.fragment_container, fragment);
+        mFragmentTransaction.addToBackStack(null);
+        mFragmentTransaction.commit();
+    }
 }
diff --git a/src/com/android/settings/wifi/dpp/WifiDppQrCodeBaseFragment.java b/src/com/android/settings/wifi/dpp/WifiDppQrCodeBaseFragment.java
index 004cb18..0d30a79 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppQrCodeBaseFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppQrCodeBaseFragment.java
@@ -22,6 +22,9 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.ProgressBar;
 import android.widget.TextView;
 
 import com.android.internal.logging.nano.MetricsProto;
@@ -29,13 +32,37 @@
 import com.android.settings.core.InstrumentedFragment;
 import com.android.settings.R;
 
+/**
+ * There are below 4 fragments for Wi-Fi DPP UI flow, to reduce redundant code of UI components,
+ * this parent fragment instantiates all UI components and provides setting APIs for them.
+ *
+ * {@code WifiDppQrCodeScannerFragment}
+ * {@code WifiDppQrCodeGeneratorFragment}
+ * {@code WifiDppChooseSavedWifiNetworkFragment}
+ * {@code WifiDppAddDeviceFragment}
+ */
 public abstract class WifiDppQrCodeBaseFragment extends InstrumentedFragment {
     private TextView mTitle;
     private TextView mDescription;
-    private SurfaceView mPreviewView;
-    private TextView mErrorMessage; //optional, view used to surface connectivity errors to the user
-    private Button mButtonLeft;
-    private Button mButtonRight;
+
+    private SurfaceView mPreviewView;       //optional, for WifiDppQrCodeScannerFragment
+    private ImageView mDecorateViiew;       //optional, for WifiDppQrCodeScannerFragment
+    private TextView mErrorMessage;         //optional, for WifiDppQrCodeScannerFragment
+
+    private ImageView mBarcodeView;         //optional, for WifiDppQrCodeGeneratorFragment
+
+    private ListView mSavedWifiNetworkList; //optional, for WifiDppChooseSavedWifiNetworkFragment
+
+    private ProgressBar mProgressBar;       //optional, for WifiDppAddDeviceFragment
+    private ImageView mWifiApPictureView;   //optional, for WifiDppAddDeviceFragment
+    private TextView mChooseDifferentNetwork;//optional, for WifiDppAddDeviceFragment
+
+    private Button mButtonLeft;             //optional, for WifiDppQrCodeScannerFragment,
+                                            //              WifiDppChooseSavedWifiNetworkFragment,
+                                            //              WifiDppAddDeviceFragment
+    private Button mButtonRight;            //optional, for WifiDppQrCodeScannerFragment,
+                                            //              WifiDppChooseSavedWifiNetworkFragment,
+                                            //              WifiDppAddDeviceFragment
 
     abstract protected int getLayout();
 
@@ -61,8 +88,19 @@
     private void initView(View view) {
         mTitle = view.findViewById(R.id.title);
         mDescription = view.findViewById(R.id.description);
+
         mPreviewView = view.findViewById(R.id.preview_view);
+        mDecorateViiew = view.findViewById(R.id.decorate_view);
         mErrorMessage = view.findViewById(R.id.error_message);
+
+        mBarcodeView = view.findViewById(R.id.barcode_view);
+
+        mSavedWifiNetworkList = view.findViewById(R.id.saved_wifi_network_list);
+
+        mProgressBar = view.findViewById(R.id.progress_bar);
+        mWifiApPictureView = view.findViewById(R.id.wifi_ap_picture_view);
+        mChooseDifferentNetwork = view.findViewById(R.id.choose_different_network);
+
         mButtonLeft = view.findViewById(R.id.button_left);
         mButtonRight = view.findViewById(R.id.button_right);
     }
@@ -75,33 +113,76 @@
         mDescription.setText(description);
     }
 
+    /** optional, for WifiDppQrCodeScannerFragment */
     protected void setErrorMessage(String errorMessage) {
         if (mErrorMessage != null) {
             mErrorMessage.setText(errorMessage);
         }
     }
 
+    /**
+     * optional, for WifiDppQrCodeScannerFragment,
+     *               WifiDppChooseSavedWifiNetworkFragment,
+     *               WifiDppAddDeviceFragment
+     */
     protected void setLeftButtonText(String text) {
-        mButtonLeft.setText(text);
+        if (mButtonLeft != null) {
+            mButtonLeft.setText(text);
+        }
     }
 
+    /**
+     * optional, for WifiDppQrCodeScannerFragment,
+     *               WifiDppChooseSavedWifiNetworkFragment,
+     *               WifiDppAddDeviceFragment
+     */
     protected void setRightButtonText(String text) {
-        mButtonRight.setText(text);
+        if (mButtonRight != null) {
+            mButtonRight.setText(text);
+        }
     }
 
+    /**
+     * optional, for WifiDppQrCodeScannerFragment,
+     *               WifiDppChooseSavedWifiNetworkFragment,
+     *               WifiDppAddDeviceFragment
+     */
     protected void hideLeftButton() {
-        mButtonLeft.setVisibility(View.INVISIBLE);
+        if (mButtonLeft != null) {
+            mButtonLeft.setVisibility(View.INVISIBLE);
+        }
     }
 
+    /**
+     * optional, for WifiDppQrCodeScannerFragment,
+     *               WifiDppChooseSavedWifiNetworkFragment,
+     *               WifiDppAddDeviceFragment
+     */
     protected void hideRightButton() {
-        mButtonRight.setVisibility(View.INVISIBLE);
+        if (mButtonRight != null) {
+            mButtonRight.setVisibility(View.INVISIBLE);
+        }
     }
 
+    /**
+     * optional, for WifiDppQrCodeScannerFragment,
+     *               WifiDppChooseSavedWifiNetworkFragment,
+     *               WifiDppAddDeviceFragment
+     */
     protected void setLeftButtonOnClickListener(View.OnClickListener listener) {
-        mButtonLeft.setOnClickListener(listener);
+        if (mButtonLeft != null) {
+            mButtonLeft.setOnClickListener(listener);
+        }
     }
 
+    /**
+     * optional, for WifiDppQrCodeScannerFragment,
+     *               WifiDppChooseSavedWifiNetworkFragment,
+     *               WifiDppAddDeviceFragment
+     */
     protected void setRightButtonOnClickListener(View.OnClickListener listener) {
-        mButtonRight.setOnClickListener(listener);
+        if (mButtonRight != null) {
+            mButtonRight.setOnClickListener(listener);
+        }
     }
 }
diff --git a/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java b/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java
new file mode 100644
index 0000000..9935bf2
--- /dev/null
+++ b/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.wifi.dpp;
+
+import android.os.Bundle;
+
+import com.android.settings.R;
+
+/**
+ * After sharing a saved Wi-Fi network, {@code WifiDppConfiguratorActivity} start with this fragment
+ * to generate a Wi-Fi DPP QR code for other device to initiate as an enrollee.
+ */
+public class WifiDppQrCodeGeneratorFragment extends WifiDppQrCodeBaseFragment {
+    @Override
+    protected int getLayout() {
+        return R.layout.wifi_dpp_qrcode_generator_fragment;
+    }
+
+    @Override
+    public void onActivityCreated (Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+    }
+}
diff --git a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
index 0ee8434..cbaa5d5 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
@@ -19,10 +19,7 @@
 import android.app.Activity;
 import android.content.Intent;
 import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
 
-import android.view.ViewGroup;
 import com.android.settings.R;
 
 public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment {
diff --git a/tests/robotests/assets/grandfather_not_implementing_instrumentable b/tests/robotests/assets/grandfather_not_implementing_instrumentable
index 625d9ff..04ef0ef 100644
--- a/tests/robotests/assets/grandfather_not_implementing_instrumentable
+++ b/tests/robotests/assets/grandfather_not_implementing_instrumentable
@@ -6,4 +6,5 @@
 com.android.settings.RestrictedListPreference$RestrictedListPreferenceDialogFragment
 com.android.settings.password.ConfirmDeviceCredentialBaseFragment$LastTryDialog
 com.android.settings.password.CredentialCheckResultTracker
-com.android.settings.dashboard.profileselector.ProfileSelectDialog
\ No newline at end of file
+com.android.settings.dashboard.profileselector.ProfileSelectDialog
+com.android.settings.panel.PanelFragment
\ No newline at end of file
diff --git a/tests/robotests/res/values-mcc999/config.xml b/tests/robotests/res/values-mcc999/config.xml
index 73d2264..c5c552e 100644
--- a/tests/robotests/res/values-mcc999/config.xml
+++ b/tests/robotests/res/values-mcc999/config.xml
@@ -73,8 +73,16 @@
         <item>fake_package/fake_service</item>
     </string-array>
 
+    <!-- Settings intelligence interaction log intent action -->
+    <string name="config_settingsintelligence_log_action" translatable="false">
+        aaa.bbb.ccc
+    </string>
+
     <!-- List of packages that should be whitelisted for slice uri access. Do not translate -->
     <string-array name="slice_whitelist_package_names" translatable="false">
         <item>com.android.settings.slice_whitelist_package</item>
     </string-array>
+
+    <!-- Email address for the homepage contextual cards feedback -->
+    <string name="config_contextual_card_feedback_email" translatable="false">test@test.test</string>
 </resources>
diff --git a/tests/robotests/src/com/android/settings/SettingsActivityTest.java b/tests/robotests/src/com/android/settings/SettingsActivityTest.java
index 2c98f70..aa41464 100644
--- a/tests/robotests/src/com/android/settings/SettingsActivityTest.java
+++ b/tests/robotests/src/com/android/settings/SettingsActivityTest.java
@@ -28,9 +28,6 @@
 import android.app.ActivityManager;
 import android.content.Context;
 import android.content.Intent;
-import android.os.Bundle;
-import android.provider.Settings.Global;
-import android.view.View;
 
 import androidx.fragment.app.Fragment;
 import androidx.fragment.app.FragmentManager;
@@ -38,16 +35,13 @@
 
 import com.android.settings.core.OnActivityResultListener;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settings.testutils.shadow.ShadowUtils;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.Robolectric;
 import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -71,29 +65,6 @@
     }
 
     @Test
-    @Config(shadows = ShadowUtils.class)
-    public void onCreate_deviceNotProvisioned_shouldDisableSearch() {
-        Global.putInt(mContext.getContentResolver(), Global.DEVICE_PROVISIONED, 0);
-        final SettingsActivity activity = Robolectric.buildActivity(SettingsActivity.class)
-                .create(Bundle.EMPTY)
-                .get();
-
-        assertThat(activity.findViewById(R.id.search_bar).getVisibility())
-                .isEqualTo(View.INVISIBLE);
-    }
-
-    @Test
-    @Config(shadows = ShadowUtils.class)
-    public void onCreate_deviceProvisioned_shouldEnableSearch() {
-        Global.putInt(mContext.getContentResolver(), Global.DEVICE_PROVISIONED, 1);
-        final SettingsActivity activity = Robolectric.buildActivity(SettingsActivity.class)
-                .create(Bundle.EMPTY)
-                .get();
-
-        assertThat(activity.findViewById(R.id.search_bar).getVisibility()).isEqualTo(View.VISIBLE);
-    }
-
-    @Test
     public void launchSettingFragment_nullExtraShowFragment_shouldNotCrash() {
         when(mActivity.getSupportFragmentManager()).thenReturn(mFragmentManager);
         doReturn(mContext.getContentResolver()).when(mActivity).getContentResolver();
@@ -101,7 +72,7 @@
 
         doReturn(RuntimeEnvironment.application.getClassLoader()).when(mActivity).getClassLoader();
 
-        mActivity.launchSettingFragment(null, true, mock(Intent.class));
+        mActivity.launchSettingFragment(null, mock(Intent.class));
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/SettingsPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/SettingsPreferenceFragmentTest.java
index 2fc3dcb..76f7043 100644
--- a/tests/robotests/src/com/android/settings/SettingsPreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/SettingsPreferenceFragmentTest.java
@@ -18,8 +18,10 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Matchers.any;
 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;
@@ -37,6 +39,7 @@
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.SettingsShadowResources;
+import com.android.settings.widget.WorkOnlyCategory;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -174,6 +177,20 @@
         // no crash
     }
 
+    @Test
+    public void checkAvailablePrefs_selfAvialbalePreferenceNotAvailable_shouldHidePreference() {
+        doReturn(mPreferenceScreen).when(mFragment).getPreferenceScreen();
+        final WorkOnlyCategory workOnlyCategory = mock(WorkOnlyCategory.class);
+        when(mPreferenceScreen.getPreferenceCount()).thenReturn(1);
+        when(mPreferenceScreen.getPreference(0)).thenReturn(workOnlyCategory);
+        when(workOnlyCategory.isAvailable(any(Context.class))).thenReturn(false);
+
+        mFragment.checkAvailablePrefs(mPreferenceScreen);
+
+        verify(mPreferenceScreen, never()).removePreference(workOnlyCategory);
+        verify(workOnlyCategory).setVisible(false);
+    }
+
     public static class TestFragment extends SettingsPreferenceFragment {
 
         @Override
diff --git a/tests/robotests/src/com/android/settings/accounts/AccountHeaderPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/AccountHeaderPreferenceControllerTest.java
index 19a140c..aeb5f54 100644
--- a/tests/robotests/src/com/android/settings/accounts/AccountHeaderPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/AccountHeaderPreferenceControllerTest.java
@@ -35,11 +35,11 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settingslib.accounts.AuthenticatorHelper;
 import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.LayoutPreference;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/tests/robotests/src/com/android/settings/accounts/RemoveAccountPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/RemoveAccountPreferenceControllerTest.java
index 3bebd66..83ea218 100644
--- a/tests/robotests/src/com/android/settings/accounts/RemoveAccountPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/RemoveAccountPreferenceControllerTest.java
@@ -51,12 +51,12 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.ShadowAccountManager;
 import com.android.settings.testutils.shadow.ShadowContentResolver;
 import com.android.settings.testutils.shadow.ShadowDevicePolicyManager;
 import com.android.settings.testutils.shadow.ShadowUserManager;
+import com.android.settingslib.widget.LayoutPreference;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/tests/robotests/src/com/android/settings/applications/AppInfoWithHeaderTest.java b/tests/robotests/src/com/android/settings/applications/AppInfoWithHeaderTest.java
index ddcbf85..3031f5b 100644
--- a/tests/robotests/src/com/android/settings/applications/AppInfoWithHeaderTest.java
+++ b/tests/robotests/src/com/android/settings/applications/AppInfoWithHeaderTest.java
@@ -44,6 +44,7 @@
 import com.android.settingslib.applications.AppUtils;
 import com.android.settingslib.applications.ApplicationsState;
 import com.android.settingslib.applications.instantapps.InstantAppDataProvider;
+import com.android.settingslib.widget.LayoutPreference;
 
 import org.junit.After;
 import org.junit.Before;
diff --git a/tests/robotests/src/com/android/settings/applications/LayoutPreferenceTest.java b/tests/robotests/src/com/android/settings/applications/LayoutPreferenceTest.java
deleted file mode 100644
index 899d4cb..0000000
--- a/tests/robotests/src/com/android/settings/applications/LayoutPreferenceTest.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.applications;
-
-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 androidx.preference.Preference.OnPreferenceClickListener;
-import androidx.preference.PreferenceViewHolder;
-
-import com.android.settings.R;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RuntimeEnvironment;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-public class LayoutPreferenceTest {
-
-    private Context mContext;
-    private LayoutPreference mPreference;
-    private PreferenceViewHolder mHolder;
-
-    @Before
-    public void setUp() {
-        mContext = RuntimeEnvironment.application;
-        mPreference = new LayoutPreference(mContext, R.layout.two_action_buttons);
-        mHolder = PreferenceViewHolder.createInstanceForTests(LayoutInflater.from(mContext)
-                .inflate(R.layout.layout_preference_frame, null, false));
-    }
-
-    @Test
-    public void setOnClickListener_shouldAttachToRootView() {
-        final OnPreferenceClickListener listener = mock(OnPreferenceClickListener.class);
-
-        mPreference.setOnPreferenceClickListener(listener);
-        mPreference.onBindViewHolder(mHolder);
-
-        mHolder.itemView.callOnClick();
-
-        verify(listener).onPreferenceClick(mPreference);
-        assertThat(mHolder.itemView.isFocusable()).isTrue();
-        assertThat(mHolder.itemView.isClickable()).isTrue();
-    }
-
-    @Test
-    public void setNonSelectable_viewShouldNotBeSelectable() {
-        mPreference.setSelectable(false);
-        mPreference.onBindViewHolder(mHolder);
-
-        assertThat(mHolder.itemView.isFocusable()).isFalse();
-        assertThat(mHolder.itemView.isClickable()).isFalse();
-    }
-
-    @Test
-    public void disableSomeView_shouldMaintainStateAfterBind() {
-        mPreference.findViewById(R.id.button1).setEnabled(false);
-        mPreference.findViewById(R.id.button2).setEnabled(true);
-
-        mPreference.onBindViewHolder(mHolder);
-
-        assertThat(mPreference.findViewById(R.id.button1).isEnabled()).isFalse();
-        assertThat(mPreference.findViewById(R.id.button2).isEnabled()).isTrue();
-    }
-
-    @Test
-    public void allowDividerBelow_shouldSaveCorrectDividerStatus() {
-        mPreference.setAllowDividerBelow(true);
-
-        assertThat(mPreference.isAllowDividerBelow()).isTrue();
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java
index 6ff0dba..3d3a05a 100644
--- a/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java
@@ -51,7 +51,6 @@
 
 import com.android.settings.R;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settings.testutils.shadow.ShadowPowerManager;
 import com.android.settingslib.applications.AppUtils;
 import com.android.settingslib.applications.ApplicationsState;
 import com.android.settingslib.applications.instantapps.InstantAppDataProvider;
@@ -93,6 +92,8 @@
     private ApplicationsState.AppEntry mAppEntry;
     @Mock
     private ApplicationInfo mApplicationInfo;
+    @Mock
+    private PowerManager mPowerManager;
 
     private Context mContext;
     private RecentAppsPreferenceController mController;
@@ -104,6 +105,7 @@
         doReturn(mUsageStatsManager).when(mContext).getSystemService(Context.USAGE_STATS_SERVICE);
         doReturn(mUserManager).when(mContext).getSystemService(Context.USER_SERVICE);
         doReturn(mPackageManager).when(mContext).getPackageManager();
+        doReturn(mPowerManager).when(mContext).getSystemService(PowerManager.class);
 
         mController = new RecentAppsPreferenceController(mContext, mAppState, null);
         when(mScreen.findPreference(anyString())).thenReturn(mCategory);
@@ -174,15 +176,15 @@
 
         // stat1, stat2 are valid apps. stat3 is invalid.
         when(mAppState.getEntry(stat1.mPackageName, UserHandle.myUserId()))
-            .thenReturn(mAppEntry);
+                .thenReturn(mAppEntry);
         when(mAppState.getEntry(stat2.mPackageName, UserHandle.myUserId()))
-            .thenReturn(mAppEntry);
+                .thenReturn(mAppEntry);
         when(mAppState.getEntry(stat3.mPackageName, UserHandle.myUserId()))
-            .thenReturn(null);
+                .thenReturn(null);
         when(mPackageManager.resolveActivity(any(Intent.class), anyInt()))
-            .thenReturn(new ResolveInfo());
+                .thenReturn(new ResolveInfo());
         when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong()))
-            .thenReturn(stats);
+                .thenReturn(stats);
         mAppEntry.info = mApplicationInfo;
 
         mController.displayPreference(mScreen);
@@ -199,7 +201,7 @@
 
     @Test
     public void display_powerSaverMode_showNoRecents() {
-        mContext.getSystemService(PowerManager.class).setPowerSaveMode(true);
+        when(mPowerManager.isPowerSaveMode()).thenReturn(true);
 
         final List<UsageStats> stats = new ArrayList<>();
         final UsageStats stat1 = new UsageStats();
@@ -251,7 +253,7 @@
 
         // Only the regular app stat1 should have its intent resolve.
         when(mPackageManager.resolveActivity(argThat(intentMatcher(stat1.mPackageName)), anyInt()))
-            .thenReturn(new ResolveInfo());
+                .thenReturn(new ResolveInfo());
 
         when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong()))
                 .thenReturn(stats);
@@ -311,13 +313,13 @@
 
         // stat1, stat2 are not displayable
         when(mAppState.getEntry(stat1.mPackageName, UserHandle.myUserId()))
-            .thenReturn(mock(ApplicationsState.AppEntry.class));
+                .thenReturn(mock(ApplicationsState.AppEntry.class));
         when(mAppState.getEntry(stat2.mPackageName, UserHandle.myUserId()))
-            .thenReturn(mock(ApplicationsState.AppEntry.class));
+                .thenReturn(mock(ApplicationsState.AppEntry.class));
         when(mPackageManager.resolveActivity(any(Intent.class), anyInt()))
-            .thenReturn(new ResolveInfo());
+                .thenReturn(new ResolveInfo());
         when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong()))
-            .thenReturn(stats);
+                .thenReturn(stats);
 
         mController.displayPreference(mScreen);
 
@@ -336,11 +338,11 @@
         stats.add(stat1);
 
         when(mAppState.getEntry(stat1.mPackageName, UserHandle.myUserId()))
-            .thenReturn(mAppEntry);
+                .thenReturn(mAppEntry);
         when(mPackageManager.resolveActivity(any(Intent.class), anyInt()))
-            .thenReturn(new ResolveInfo());
+                .thenReturn(new ResolveInfo());
         when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong()))
-            .thenReturn(stats);
+                .thenReturn(stats);
         mAppEntry.info = mApplicationInfo;
 
         mController.displayPreference(mScreen);
diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppHeaderViewPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppHeaderViewPreferenceControllerTest.java
index d3e00c3..67702f1 100644
--- a/tests/robotests/src/com/android/settings/applications/appinfo/AppHeaderViewPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppHeaderViewPreferenceControllerTest.java
@@ -42,10 +42,10 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settingslib.applications.ApplicationsState;
 import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.LayoutPreference;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/InstantAppButtonsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/InstantAppButtonsPreferenceControllerTest.java
index 5d8c842..6879b7d 100644
--- a/tests/robotests/src/com/android/settings/applications/appinfo/InstantAppButtonsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/appinfo/InstantAppButtonsPreferenceControllerTest.java
@@ -48,11 +48,11 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settingslib.applications.AppUtils;
 import com.android.settingslib.applications.instantapps.InstantAppDataProvider;
+import com.android.settingslib.widget.LayoutPreference;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsButtonsControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsButtonsControllerTest.java
index 6c555dd..094ec80 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsButtonsControllerTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsButtonsControllerTest.java
@@ -55,7 +55,8 @@
     public void setUp() {
         super.setUp();
         final View buttons = View.inflate(
-                RuntimeEnvironment.application, R.layout.two_action_buttons, null /* parent */);
+                RuntimeEnvironment.application, R.layout.settings_action_buttons,
+                null /* parent */);
         mConnectButton = buttons.findViewById(R.id.button2);
         mForgetButton = buttons.findViewById(R.id.button1);
         mController =
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsHeaderControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsHeaderControllerTest.java
index 0430e0f..e62e338 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsHeaderControllerTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsHeaderControllerTest.java
@@ -33,7 +33,6 @@
 import androidx.fragment.app.FragmentTransaction;
 
 import com.android.settings.R;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.SettingsShadowBluetoothDevice;
@@ -41,6 +40,7 @@
 import com.android.settings.widget.EntityHeaderController;
 import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.widget.LayoutPreference;
 
 import org.junit.After;
 import org.junit.Test;
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/usb/UsbDetailsHeaderControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/usb/UsbDetailsHeaderControllerTest.java
index ec697ad..2aa38d7 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/usb/UsbDetailsHeaderControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/usb/UsbDetailsHeaderControllerTest.java
@@ -31,12 +31,12 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
 import com.android.settings.widget.EntityHeaderController;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.testutils.DrawableTestHelper;
+import com.android.settingslib.widget.LayoutPreference;
 
 import org.junit.After;
 import org.junit.Before;
diff --git a/tests/robotests/src/com/android/settings/development/AllowBackgroundActivityStartsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/AllowBackgroundActivityStartsPreferenceControllerTest.java
new file mode 100644
index 0000000..8b9b14f
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/development/AllowBackgroundActivityStartsPreferenceControllerTest.java
@@ -0,0 +1,110 @@
+/*
+ * 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.development;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.provider.Settings;
+
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+
+import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class AllowBackgroundActivityStartsPreferenceControllerTest {
+
+    @Mock
+    private SwitchPreference mPreference;
+    @Mock
+    private PreferenceScreen mPreferenceScreen;
+
+    private Context mContext;
+    private AllowBackgroundActivityStartsPreferenceController mController;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+        mController = new AllowBackgroundActivityStartsPreferenceController(mContext);
+        when(mPreferenceScreen.findPreference(mController.getPreferenceKey()))
+            .thenReturn(mPreference);
+        mController.displayPreference(mPreferenceScreen);
+    }
+
+    @Test
+    public void onPreferenceChange_settingEnabled_allowBackgroundActivityStartsShouldBeOn() {
+        mController.onPreferenceChange(mPreference, true /* new value */);
+
+        final int mode = Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED, 1 /* default */);
+
+        assertThat(mode).isEqualTo(1);
+    }
+
+    @Test
+    public void onPreferenceChange_settingDisabled_allowBackgroundActivityStartsShouldBeOff() {
+        mController.onPreferenceChange(mPreference, false /* new value */);
+
+        final int mode = Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED, 1 /* default */);
+
+        assertThat(mode).isEqualTo(0);
+    }
+
+    @Test
+    public void updateState_settingDisabled_preferenceShouldNotBeChecked() {
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED, 0);
+        mController.updateState(mPreference);
+
+        verify(mPreference).setChecked(false);
+    }
+
+    @Test
+    public void updateState_settingEnabled_preferenceShouldBeChecked() {
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED, 1);
+        mController.updateState(mPreference);
+
+        verify(mPreference).setChecked(true);
+    }
+
+    @Test
+    public void onDeveloperOptionsSwitchDisabled_shouldDisablePreference() {
+        mController.onDeveloperOptionsSwitchDisabled();
+
+        final int mode = Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED, 1 /* default */);
+
+        assertThat(mode).isEqualTo(0);
+        verify(mPreference).setChecked(false);
+        verify(mPreference).setEnabled(false);
+    }
+}
+
diff --git a/tests/robotests/src/com/android/settings/display/ColorModePreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/display/ColorModePreferenceFragmentTest.java
index 3aae145..859912a 100644
--- a/tests/robotests/src/com/android/settings/display/ColorModePreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/display/ColorModePreferenceFragmentTest.java
@@ -34,10 +34,10 @@
 import com.android.internal.app.ColorDisplayController;
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.SettingsShadowResources;
 import com.android.settingslib.widget.CandidateInfo;
+import com.android.settingslib.widget.LayoutPreference;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/tests/robotests/src/com/android/settings/display/NightDisplayActivationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/NightDisplayActivationPreferenceControllerTest.java
index 30dedb6..84d184d 100644
--- a/tests/robotests/src/com/android/settings/display/NightDisplayActivationPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/NightDisplayActivationPreferenceControllerTest.java
@@ -26,9 +26,9 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.SettingsShadowResources;
+import com.android.settingslib.widget.LayoutPreference;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/tests/robotests/src/com/android/settings/dream/StartNowPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/dream/StartNowPreferenceControllerTest.java
index fc7edc2..21cb9f1 100644
--- a/tests/robotests/src/com/android/settings/dream/StartNowPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/dream/StartNowPreferenceControllerTest.java
@@ -28,9 +28,9 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settingslib.dream.DreamBackend;
+import com.android.settingslib.widget.LayoutPreference;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
index 1a8d58d..c9086ab 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
@@ -51,7 +51,6 @@
 import com.android.internal.os.BatteryStatsHelper;
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.ShadowActivityManager;
@@ -61,6 +60,7 @@
 import com.android.settingslib.applications.ApplicationsState;
 import com.android.settingslib.applications.instantapps.InstantAppDataProvider;
 import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.LayoutPreference;
 
 import org.junit.After;
 import org.junit.Before;
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java
index 5541654..7797a78 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java
@@ -42,7 +42,6 @@
 import androidx.recyclerview.widget.RecyclerView;
 
 import com.android.settings.R;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.SettingsShadowResources;
@@ -50,6 +49,7 @@
 import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
 import com.android.settings.widget.EntityHeaderController;
 import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.LayoutPreference;
 
 import org.junit.After;
 import org.junit.Before;
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
index cf1a5f3..14caf2c 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
@@ -48,12 +48,12 @@
 import com.android.internal.os.BatteryStatsHelper;
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.fuelgauge.batterytip.BatteryTipPreferenceController;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.XmlTestUtils;
 import com.android.settings.testutils.shadow.SettingsShadowResources;
+import com.android.settingslib.widget.LayoutPreference;
 
 import org.junit.Before;
 import org.junit.BeforeClass;
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceControllerTest.java
index c09af2b..051ef39 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceControllerTest.java
@@ -21,6 +21,8 @@
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.os.PowerManager;
@@ -37,22 +39,20 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-import org.robolectric.shadows.ShadowPowerManager;
 import org.robolectric.util.ReflectionHelpers;
 
 @RunWith(SettingsRobolectricTestRunner.class)
-@Config(shadows = ShadowPowerManager.class)
 public class BatterySaverButtonPreferenceControllerTest {
 
     private BatterySaverButtonPreferenceController mController;
     private Context mContext;
     private Button mButtonOn;
     private Button mButtonOff;
-    private PowerManager mPowerManager;
     private TwoStateButtonPreference mPreference;
 
     @Mock
+    private PowerManager mPowerManager;
+    @Mock
     private PreferenceScreen mPreferenceScreen;
 
     @Before
@@ -61,10 +61,11 @@
         mContext = spy(RuntimeEnvironment.application);
         mButtonOn = new Button(mContext);
         mButtonOff = new Button(mContext);
-        mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
         mPreference = spy(new TwoStateButtonPreference(mContext, null /* AttributeSet */));
         ReflectionHelpers.setField(mPreference, "mButtonOn", mButtonOn);
         ReflectionHelpers.setField(mPreference, "mButtonOff", mButtonOff);
+
+        doReturn(mPowerManager).when(mContext).getSystemService(Context.POWER_SERVICE);
         doReturn(mPreference).when(mPreferenceScreen).findPreference(anyString());
 
         mController = new BatterySaverButtonPreferenceController(mContext, "test_key");
@@ -73,7 +74,7 @@
 
     @Test
     public void updateState_lowPowerOn_preferenceIsChecked() {
-        mPowerManager.setPowerSaveMode(true);
+        when(mPowerManager.isPowerSaveMode()).thenReturn(true);
 
         mController.updateState(mPreference);
 
@@ -82,7 +83,7 @@
 
     @Test
     public void testUpdateState_lowPowerOff_preferenceIsUnchecked() {
-        mPowerManager.setPowerSaveMode(false);
+        when(mPowerManager.isPowerSaveMode()).thenReturn(false);
 
         mController.updateState(mPreference);
 
@@ -93,13 +94,13 @@
     public void setChecked_on_setPowerSaveMode() {
         mController.setChecked(true);
 
-        assertThat(mPowerManager.isPowerSaveMode()).isTrue();
+        verify(mPowerManager).setPowerSaveMode(true);
     }
 
     @Test
     public void setChecked_off_unsetPowerSaveMode() {
         mController.setChecked(false);
 
-        assertThat(mPowerManager.isPowerSaveMode()).isFalse();
+        verify(mPowerManager).setPowerSaveMode(false);
     }
 }
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProviderImplTest.java
new file mode 100644
index 0000000..08631f7
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProviderImplTest.java
@@ -0,0 +1,62 @@
+/*
+ * 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.homepage.contextualcards;
+
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.content.Intent;
+
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class ContextualCardFeatureProviderImplTest {
+
+    private Context mContext;
+    private ContextualCardFeatureProviderImpl mImpl;
+
+    @Before
+    public void setUp() {
+        mContext = spy(RuntimeEnvironment.application);
+        mImpl = new ContextualCardFeatureProviderImpl();
+    }
+
+    @Test
+    public void sendBroadcast_emptyAction_notSendBroadcast() {
+        final Intent intent = new Intent();
+        mImpl.sendBroadcast(mContext, intent);
+
+        verify(mContext, never()).sendBroadcast(intent);
+    }
+
+    @Test
+    @Config(qualifiers = "mcc999")
+    public void sendBroadcast_hasAction_sendBroadcast() {
+        final Intent intent = new Intent();
+        mImpl.sendBroadcast(mContext, intent);
+
+        verify(mContext).sendBroadcast(intent);
+    }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardLoaderTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardLoaderTest.java
index f9eda49..4f50197 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardLoaderTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardLoaderTest.java
@@ -27,11 +27,9 @@
 import android.content.Context;
 import android.net.Uri;
 
-import com.android.settings.homepage.contextualcards.deviceinfo.BatterySlice;
-import com.android.settings.homepage.contextualcards.slices.ConnectedDeviceSlice;
+import com.android.settings.slices.CustomSliceRegistry;
 import com.android.settings.slices.SettingsSliceProvider;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settings.wifi.WifiSlice;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -40,7 +38,6 @@
 import org.robolectric.shadows.ShadowContentResolver;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -61,17 +58,6 @@
     }
 
     @Test
-    public void createStaticCards_shouldContainCorrectCards() {
-        final Uri batteryInfo = BatterySlice.BATTERY_CARD_URI;
-        final List<Uri> expectedUris = Arrays.asList(batteryInfo);
-
-        final List<Uri> actualCardUris = mContextualCardLoader.createStaticCards().stream().map(
-                ContextualCard::getSliceUri).collect(Collectors.toList());
-
-        assertThat(actualCardUris).containsExactlyElementsIn(expectedUris);
-    }
-
-    @Test
     public void isCardEligibleToDisplay_customCard_returnTrue() {
         final ContextualCard customCard = new ContextualCard.Builder()
                 .setName("custom_card")
@@ -165,7 +151,7 @@
         cards.add(new ContextualCard.Builder()
                 .setName("test_wifi")
                 .setCardType(ContextualCard.CardType.SLICE)
-                .setSliceUri(WifiSlice.WIFI_URI)
+                .setSliceUri(CustomSliceRegistry.WIFI_SLICE_URI)
                 .build());
         cards.add(new ContextualCard.Builder()
                 .setName("test_flashlight")
@@ -176,7 +162,7 @@
         cards.add(new ContextualCard.Builder()
                 .setName("test_connected")
                 .setCardType(ContextualCard.CardType.SLICE)
-                .setSliceUri(ConnectedDeviceSlice.CONNECTED_DEVICE_URI)
+                .setSliceUri(CustomSliceRegistry.CONNECTED_DEVICE_SLICE_URI)
                 .build());
         cards.add(new ContextualCard.Builder()
                 .setName("test_gesture")
@@ -187,7 +173,7 @@
         cards.add(new ContextualCard.Builder()
                 .setName("test_battery")
                 .setCardType(ContextualCard.CardType.SLICE)
-                .setSliceUri(BatterySlice.BATTERY_CARD_URI)
+                .setSliceUri(CustomSliceRegistry.BATTERY_INFO_SLICE_URI)
                 .build());
         return cards;
     }
@@ -220,8 +206,8 @@
         cards.add(new ContextualCard.Builder()
                 .setName("test_battery")
                 .setCardType(ContextualCard.CardType.SLICE)
-                .setSliceUri(BatterySlice.BATTERY_CARD_URI)
+                .setSliceUri(CustomSliceRegistry.BATTERY_INFO_SLICE_URI)
                 .build());
         return cards;
     }
-}
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardManagerTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardManagerTest.java
index 8287672..64a7c9c 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardManagerTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardManagerTest.java
@@ -18,13 +18,12 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.ArgumentMatchers.anyMap;
-import static org.mockito.Mockito.doNothing;
-
 import android.content.Context;
 import android.net.Uri;
 import android.util.ArrayMap;
 
+import com.android.settings.homepage.contextualcards.conditional.ConditionFooterContextualCard;
+import com.android.settings.homepage.contextualcards.conditional.ConditionHeaderContextualCard;
 import com.android.settings.homepage.contextualcards.conditional.ConditionalContextualCard;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
@@ -70,7 +69,7 @@
     }
 
     @Test
-    public void onContextualCardUpdated_emtpyMapWithExistingCards_shouldOnlyKeepConditionalCard() {
+    public void onContextualCardUpdated_emptyMapWithExistingCards_shouldOnlyKeepConditionalCard() {
         mManager.mContextualCards.add(new ConditionalContextualCard.Builder().build());
         mManager.mContextualCards.add(
                 buildContextualCard(TEST_SLICE_URI));
@@ -84,6 +83,31 @@
                 .isEqualTo(ContextualCard.CardType.CONDITIONAL);
     }
 
+    @Test
+    public void onContextualCardUpdated_hasEmptyMap_shouldKeepConditionalHeaderCard() {
+        mManager.mContextualCards.add(new ConditionHeaderContextualCard.Builder().build());
+        mManager.setListener(mListener);
+
+        mManager.onContextualCardUpdated(new ArrayMap<>());
+
+        assertThat(mManager.mContextualCards).hasSize(1);
+        assertThat(mManager.mContextualCards.get(0).getCardType())
+                .isEqualTo(ContextualCard.CardType.CONDITIONAL_HEADER);
+    }
+
+    @Test
+    public void onContextualCardUpdated_hasEmptyMap_shouldKeepConditionalFooterCard() {
+        mManager.mContextualCards.add(new ConditionFooterContextualCard.Builder().build());
+        mManager.setListener(mListener);
+
+        mManager.onContextualCardUpdated(new ArrayMap<>());
+
+        assertThat(mManager.mContextualCards).hasSize(1);
+        assertThat(mManager.mContextualCards.get(0).getCardType())
+                .isEqualTo(ContextualCard.CardType.CONDITIONAL_FOOTER);
+    }
+
+
     private ContextualCard buildContextualCard(String sliceUri) {
         return new ContextualCard.Builder()
                 .setName("test_name")
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/SettingsContextualCardProviderTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/SettingsContextualCardProviderTest.java
index 6b1f8b1..4b0b085 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/SettingsContextualCardProviderTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/SettingsContextualCardProviderTest.java
@@ -23,15 +23,13 @@
 import static org.mockito.Mockito.spy;
 
 import android.app.slice.SliceManager;
-import android.content.ContentResolver;
 import android.content.Context;
-import android.net.Uri;
 import android.os.Bundle;
 
 import com.android.settings.intelligence.ContextualCardProto.ContextualCard;
 import com.android.settings.intelligence.ContextualCardProto.ContextualCardList;
+import com.android.settings.slices.CustomSliceRegistry;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settings.wifi.WifiSlice;
 
 import com.google.android.settings.intelligence.libs.contextualcards.ContextualCardProvider;
 
@@ -48,18 +46,11 @@
 
     @Mock
     private SliceManager mSliceManager;
-    private ContentResolver mResolver;
-    private Uri mUri;
     private SettingsContextualCardProvider mProvider;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mResolver = RuntimeEnvironment.application.getContentResolver();
-        mUri = new Uri.Builder()
-                .scheme(ContentResolver.SCHEME_CONTENT)
-                .authority(SettingsContextualCardProvider.CARD_AUTHORITY)
-                .build();
         mProvider = spy(Robolectric.setupContentProvider(SettingsContextualCardProvider.class));
         final Context context = spy(RuntimeEnvironment.application);
         doReturn(mSliceManager).when(context).getSystemService(SliceManager.class);
@@ -83,7 +74,7 @@
         final ContextualCardList cards = mProvider.getContextualCards();
         ContextualCard wifiCard = null;
         for (ContextualCard card : cards.getCardList()) {
-            if (card.getSliceUri().equals(WifiSlice.WIFI_URI.toString())) {
+            if (card.getSliceUri().equals(CustomSliceRegistry.WIFI_SLICE_URI.toString())) {
                 wifiCard = card;
             }
         }
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardControllerTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardControllerTest.java
index ab82a54..688e94c 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardControllerTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardControllerTest.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.homepage.contextualcards.conditional;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
@@ -25,6 +27,7 @@
 import android.content.Context;
 
 import com.android.settings.homepage.contextualcards.ContextualCard;
+import com.android.settings.homepage.contextualcards.ContextualCard.CardType;
 import com.android.settings.homepage.contextualcards.ContextualCardUpdateListener;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
@@ -38,6 +41,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 @RunWith(SettingsRobolectricTestRunner.class)
 public class ConditionContextualCardControllerTest {
@@ -95,4 +99,81 @@
 
         verify(mListener, never()).onContextualCardUpdated(any());
     }
+
+    @Test
+    public void getConditionalCards_hasEmptyConditionCards_shouldReturnThreeEmptyList() {
+        final Map<Integer, List<ContextualCard>> conditionalCards =
+                mController.buildConditionalCardsWithFooterOrHeader(generateConditionCards(0));
+
+        assertThat(conditionalCards).hasSize(3);
+        for (@CardType int cardType : conditionalCards.keySet()) {
+            assertThat(conditionalCards.get(cardType)).isEmpty();
+        }
+    }
+
+    @Test
+    public void getConditionalCards_hasOneConditionCard_shouldGetOneFullWidthCard() {
+        final Map<Integer, List<ContextualCard>> conditionalCards =
+                mController.buildConditionalCardsWithFooterOrHeader(generateConditionCards(1));
+
+        assertThat(conditionalCards).hasSize(3);
+        assertThat(conditionalCards.get(CardType.CONDITIONAL)).hasSize(1);
+        assertThat(conditionalCards.get(CardType.CONDITIONAL).get(0).isHalfWidth()).isFalse();
+        assertThat(conditionalCards.get(CardType.CONDITIONAL_HEADER)).isEmpty();
+        assertThat(conditionalCards.get(CardType.CONDITIONAL_FOOTER)).isEmpty();
+    }
+
+    @Test
+    public void getConditionalCards_hasTwoConditionCards_shouldGetTwoHalfWidthCards() {
+        final Map<Integer, List<ContextualCard>> conditionalCards =
+                mController.buildConditionalCardsWithFooterOrHeader(generateConditionCards(2));
+
+        assertThat(conditionalCards).hasSize(3);
+        assertThat(conditionalCards.get(CardType.CONDITIONAL)).hasSize(2);
+        for (ContextualCard card : conditionalCards.get(CardType.CONDITIONAL)) {
+            assertThat(card.isHalfWidth()).isTrue();
+        }
+        assertThat(conditionalCards.get(CardType.CONDITIONAL_HEADER)).isEmpty();
+        assertThat(conditionalCards.get(CardType.CONDITIONAL_FOOTER)).isEmpty();
+    }
+
+    @Test
+    public void getConditionalCards_hasThreeCardsAndExpanded_shouldGetThreeCardsWithFooter() {
+        mController.setIsExpanded(true);
+        final Map<Integer, List<ContextualCard>> conditionalCards =
+                mController.buildConditionalCardsWithFooterOrHeader(generateConditionCards(3));
+
+        assertThat(conditionalCards).hasSize(3);
+        assertThat(conditionalCards.get(CardType.CONDITIONAL)).hasSize(3);
+        assertThat(conditionalCards.get(CardType.CONDITIONAL_HEADER)).isEmpty();
+        assertThat(conditionalCards.get(CardType.CONDITIONAL_FOOTER)).isNotEmpty();
+    }
+
+    @Test
+    public void getConditionalCards_hasThreeCardsAndCollapsed_shouldGetOneConditionalHeader() {
+        mController.setIsExpanded(false);
+        final Map<Integer, List<ContextualCard>> conditionalCards =
+                mController.buildConditionalCardsWithFooterOrHeader(generateConditionCards(3));
+
+        assertThat(conditionalCards).hasSize(3);
+        assertThat(conditionalCards.get(CardType.CONDITIONAL)).isEmpty();
+        assertThat(conditionalCards.get(CardType.CONDITIONAL_HEADER)).isNotEmpty();
+        assertThat(conditionalCards.get(CardType.CONDITIONAL_FOOTER)).isEmpty();
+    }
+
+    private List<ContextualCard> generateConditionCards(int numberOfCondition) {
+        final List<ContextualCard> conditionCards = new ArrayList<>();
+        for (int i = 0; i < numberOfCondition; i++) {
+            conditionCards.add(new ConditionalContextualCard.Builder()
+                    .setConditionId(123 + i)
+                    .setMetricsConstant(1)
+                    .setActionText("test_action" + i)
+                    .setName("test_name" + i)
+                    .setTitleText("test_title" + i)
+                    .setSummaryText("test_summary" + i)
+                    .setIsHalfWidth(true)
+                    .build());
+        }
+        return conditionCards;
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardRendererTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardRendererTest.java
index 376042d..bb61c7d 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardRendererTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardRendererTest.java
@@ -19,11 +19,10 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.content.Context;
+import android.app.Activity;
 import android.view.LayoutInflater;
 import android.view.View;
 
@@ -40,7 +39,8 @@
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RuntimeEnvironment;
+import org.robolectric.Robolectric;
+import org.robolectric.android.controller.ActivityController;
 
 @RunWith(SettingsRobolectricTestRunner.class)
 public class ConditionContextualCardRendererTest {
@@ -49,25 +49,29 @@
     private ControllerRendererPool mControllerRendererPool;
     @Mock
     private ConditionContextualCardController mController;
-    private Context mContext;
+    private Activity mActivity;
     private ConditionContextualCardRenderer mRenderer;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mContext = spy(RuntimeEnvironment.application);
-        mRenderer = new ConditionContextualCardRenderer(mContext, mControllerRendererPool);
+        final ActivityController<Activity> activityController = Robolectric.buildActivity(
+                Activity.class);
+        mActivity = activityController.get();
+        mActivity.setTheme(R.style.Theme_AppCompat);
+        activityController.create();
+        mRenderer = new ConditionContextualCardRenderer(mActivity, mControllerRendererPool);
     }
 
     @Test
     public void bindView_shouldSetListener() {
         final int viewType = mRenderer.getViewType(false /* isHalfWidth */);
-        final RecyclerView recyclerView = new RecyclerView(mContext);
-        recyclerView.setLayoutManager(new LinearLayoutManager(mContext));
-        final View view = LayoutInflater.from(mContext).inflate(viewType, recyclerView, false);
+        final RecyclerView recyclerView = new RecyclerView(mActivity);
+        recyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
+        final View view = LayoutInflater.from(mActivity).inflate(viewType, recyclerView, false);
         final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(view);
         final View card = view.findViewById(R.id.content);
-        when(mControllerRendererPool.getController(mContext,
+        when(mControllerRendererPool.getController(mActivity,
                 ContextualCard.CardType.CONDITIONAL)).thenReturn(mController);
 
         mRenderer.bindView(viewHolder, buildConditionContextualCard());
@@ -79,12 +83,12 @@
     @Test
     public void viewClick_shouldInvokeControllerPrimaryClick() {
         final int viewType = mRenderer.getViewType(false /* isHalfWidth */);
-        final RecyclerView recyclerView = new RecyclerView(mContext);
-        recyclerView.setLayoutManager(new LinearLayoutManager(mContext));
-        final View view = LayoutInflater.from(mContext).inflate(viewType, recyclerView, false);
+        final RecyclerView recyclerView = new RecyclerView(mActivity);
+        recyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
+        final View view = LayoutInflater.from(mActivity).inflate(viewType, recyclerView, false);
         final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(view);
         final View card = view.findViewById(R.id.content);
-        when(mControllerRendererPool.getController(mContext,
+        when(mControllerRendererPool.getController(mActivity,
                 ContextualCard.CardType.CONDITIONAL)).thenReturn(mController);
 
         mRenderer.bindView(viewHolder, buildConditionContextualCard());
@@ -103,7 +107,7 @@
                 .setName("test_name")
                 .setTitleText("test_title")
                 .setSummaryText("test_summary")
-                .setIconDrawable(mContext.getDrawable(R.drawable.ic_do_not_disturb_on_24dp))
+                .setIconDrawable(mActivity.getDrawable(R.drawable.ic_do_not_disturb_on_24dp))
                 .setIsHalfWidth(true)
                 .build();
     }
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionFooterContextualCardRendererTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionFooterContextualCardRendererTest.java
new file mode 100644
index 0000000..524a690
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionFooterContextualCardRendererTest.java
@@ -0,0 +1,101 @@
+/*
+ * 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.homepage.contextualcards.conditional;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.settings.homepage.contextualcards.ContextualCard;
+import com.android.settings.homepage.contextualcards.ControllerRendererPool;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class ConditionFooterContextualCardRendererTest {
+
+    @Mock
+    private ControllerRendererPool mControllerRendererPool;
+    @Mock
+    private ConditionContextualCardController mController;
+    private Context mContext;
+    private ConditionFooterContextualCardRenderer mRenderer;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(RuntimeEnvironment.application);
+        mRenderer = new ConditionFooterContextualCardRenderer(mContext, mControllerRendererPool);
+    }
+
+    @Test
+    public void bindView_shouldSetClickListener() {
+        final int viewType = mRenderer.getViewType(false /* isHalfWidth */);
+        final RecyclerView recyclerView = new RecyclerView(mContext);
+        recyclerView.setLayoutManager(new LinearLayoutManager(mContext));
+        final View view = LayoutInflater.from(mContext).inflate(viewType, recyclerView, false);
+        final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(view);
+        when(mControllerRendererPool.getController(mContext,
+                ContextualCard.CardType.CONDITIONAL_FOOTER)).thenReturn(mController);
+
+        mRenderer.bindView(viewHolder, generateConditionFooterContextualCard());
+
+        assertThat(viewHolder.itemView).isNotNull();
+        assertThat(viewHolder.itemView.hasOnClickListeners()).isTrue();
+    }
+
+    @Test
+    public void bindView_clickView_shouldSetTrueToIsConditionExpanded() {
+        final int viewType = mRenderer.getViewType(false /* isHalfWidth */);
+        final RecyclerView recyclerView = new RecyclerView(mContext);
+        recyclerView.setLayoutManager(new LinearLayoutManager(mContext));
+        final View view = LayoutInflater.from(mContext).inflate(viewType, recyclerView, false);
+        final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(view);
+        when(mControllerRendererPool.getController(mContext,
+                ContextualCard.CardType.CONDITIONAL_FOOTER)).thenReturn(mController);
+
+        mRenderer.bindView(viewHolder, generateConditionFooterContextualCard());
+
+        assertThat(viewHolder.itemView).isNotNull();
+        viewHolder.itemView.performClick();
+
+        verify(mController).setIsExpanded(false);
+        verify(mController).onConditionsChanged();
+    }
+
+    private ContextualCard generateConditionFooterContextualCard() {
+        return new ConditionFooterContextualCard.Builder()
+                .setName("test_condition_footer")
+                .setRankingScore(-9999.0)
+                .build();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionFooterContextualCardTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionFooterContextualCardTest.java
new file mode 100644
index 0000000..783ae9f
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionFooterContextualCardTest.java
@@ -0,0 +1,42 @@
+/*
+ * 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.homepage.contextualcards.conditional;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.android.settings.homepage.contextualcards.ContextualCard;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class ConditionFooterContextualCardTest {
+
+    @Test(expected = IllegalArgumentException.class)
+    public void newInstance_changeCardType_shouldCrash() {
+        new ConditionFooterContextualCard.Builder()
+                .setCardType(ContextualCard.CardType.LEGACY_SUGGESTION)
+                .build();
+    }
+
+    @Test
+    public void getCardType_shouldAlwaysBeConditionalFooter() {
+        assertThat(new ConditionFooterContextualCard.Builder().build().getCardType())
+                .isEqualTo(ContextualCard.CardType.CONDITIONAL_FOOTER);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionHeaderContextualCardRendererTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionHeaderContextualCardRendererTest.java
new file mode 100644
index 0000000..d0b5a24
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionHeaderContextualCardRendererTest.java
@@ -0,0 +1,126 @@
+/*
+ * 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.homepage.contextualcards.conditional;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Activity;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.settings.R;
+import com.android.settings.homepage.contextualcards.ContextualCard;
+import com.android.settings.homepage.contextualcards.ControllerRendererPool;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
+import org.robolectric.android.controller.ActivityController;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class ConditionHeaderContextualCardRendererTest {
+
+    @Mock
+    private ControllerRendererPool mControllerRendererPool;
+    @Mock
+    private ConditionContextualCardController mController;
+    private Activity mActivity;
+    private ConditionHeaderContextualCardRenderer mRenderer;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        final ActivityController<Activity> activityController = Robolectric.buildActivity(
+                Activity.class);
+        mActivity = activityController.get();
+        mActivity.setTheme(R.style.Theme_AppCompat);
+        activityController.create();
+        mRenderer = new ConditionHeaderContextualCardRenderer(mActivity, mControllerRendererPool);
+    }
+
+    @Test
+    public void bindView_shouldSetClickListener() {
+        final int viewType = mRenderer.getViewType(false /* isHalfWidth */);
+        final RecyclerView recyclerView = new RecyclerView(mActivity);
+        recyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
+        final View view = LayoutInflater.from(mActivity).inflate(viewType, recyclerView, false);
+        final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(view);
+        when(mControllerRendererPool.getController(mActivity,
+                ContextualCard.CardType.CONDITIONAL_HEADER)).thenReturn(mController);
+
+        mRenderer.bindView(viewHolder, generateConditionHeaderContextualCard());
+
+        assertThat(viewHolder.itemView).isNotNull();
+        assertThat(viewHolder.itemView.hasOnClickListeners()).isTrue();
+    }
+
+    @Test
+    public void bindView_clickView_shouldSetTrueToIsConditionExpanded() {
+        final int viewType = mRenderer.getViewType(false /* isHalfWidth */);
+        final RecyclerView recyclerView = new RecyclerView(mActivity);
+        recyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
+        final View view = LayoutInflater.from(mActivity).inflate(viewType, recyclerView, false);
+        final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(view);
+        when(mControllerRendererPool.getController(mActivity,
+                ContextualCard.CardType.CONDITIONAL_HEADER)).thenReturn(mController);
+
+        mRenderer.bindView(viewHolder, generateConditionHeaderContextualCard());
+
+        assertThat(viewHolder.itemView).isNotNull();
+        viewHolder.itemView.performClick();
+
+        verify(mController).setIsExpanded(true);
+        verify(mController).onConditionsChanged();
+    }
+
+    private ContextualCard generateConditionHeaderContextualCard() {
+        return new ConditionHeaderContextualCard.Builder()
+                .setConditionalCards(generateConditionCards(3))
+                .setName("test_condition_header")
+                .setRankingScore(-9999.0)
+                .build();
+    }
+
+    private List<ContextualCard> generateConditionCards(int numberOfCondition) {
+        final List<ContextualCard> conditionCards = new ArrayList<>();
+        for (int i = 0; i < numberOfCondition; i++) {
+            conditionCards.add(new ConditionalContextualCard.Builder()
+                    .setConditionId(123 + i)
+                    .setMetricsConstant(1)
+                    .setActionText("test_action" + i)
+                    .setName("test_name" + i)
+                    .setTitleText("test_title" + i)
+                    .setSummaryText("test_summary" + i)
+                    .setIsHalfWidth(true)
+                    .build());
+        }
+        return conditionCards;
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionHeaderContextualCardTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionHeaderContextualCardTest.java
new file mode 100644
index 0000000..767adad
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionHeaderContextualCardTest.java
@@ -0,0 +1,42 @@
+/*
+ * 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.homepage.contextualcards.conditional;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.android.settings.homepage.contextualcards.ContextualCard;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class ConditionHeaderContextualCardTest {
+
+    @Test(expected = IllegalArgumentException.class)
+    public void newInstance_changeCardType_shouldCrash() {
+        new ConditionHeaderContextualCard.Builder()
+                .setCardType(ContextualCard.CardType.LEGACY_SUGGESTION)
+                .build();
+    }
+
+    @Test
+    public void getCardType_shouldAlwaysBeConditionalHeader() {
+        assertThat(new ConditionHeaderContextualCard.Builder().build().getCardType())
+                .isEqualTo(ContextualCard.CardType.CONDITIONAL_HEADER);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRendererTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRendererTest.java
index 20f1b7b..2618e1b 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRendererTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRendererTest.java
@@ -23,7 +23,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.content.Context;
+import android.app.Activity;
 import android.view.LayoutInflater;
 import android.view.View;
 
@@ -40,7 +40,8 @@
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RuntimeEnvironment;
+import org.robolectric.Robolectric;
+import org.robolectric.android.controller.ActivityController;
 
 @RunWith(SettingsRobolectricTestRunner.class)
 public class LegacySuggestionContextualCardRendererTest {
@@ -48,26 +49,31 @@
     private ControllerRendererPool mControllerRendererPool;
     @Mock
     private LegacySuggestionContextualCardController mController;
-    private Context mContext;
+    private Activity mActivity;
     private LegacySuggestionContextualCardRenderer mRenderer;
 
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mContext = RuntimeEnvironment.application;
-        mRenderer = new LegacySuggestionContextualCardRenderer(mContext, mControllerRendererPool);
+        final ActivityController<Activity> activityController = Robolectric.buildActivity(
+                Activity.class);
+        mActivity = activityController.get();
+        mActivity.setTheme(R.style.Theme_AppCompat);
+        activityController.create();
+
+        mRenderer = new LegacySuggestionContextualCardRenderer(mActivity, mControllerRendererPool);
     }
 
     @Test
     public void bindView_shouldSetListener() {
         final int viewType = mRenderer.getViewType(true /* isHalfWidth */);
-        final RecyclerView recyclerView = new RecyclerView(mContext);
-        recyclerView.setLayoutManager(new LinearLayoutManager(mContext));
-        final View card = LayoutInflater.from(mContext).inflate(viewType, recyclerView, false);
+        final RecyclerView recyclerView = new RecyclerView(mActivity);
+        recyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
+        final View card = LayoutInflater.from(mActivity).inflate(viewType, recyclerView, false);
         final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(card);
 
-        when(mControllerRendererPool.getController(mContext,
+        when(mControllerRendererPool.getController(mActivity,
                 ContextualCard.CardType.LEGACY_SUGGESTION)).thenReturn(mController);
 
         mRenderer.bindView(viewHolder, buildContextualCard());
@@ -79,11 +85,11 @@
     @Test
     public void viewClick_shouldInvokeControllerPrimaryClick() {
         final int viewType = mRenderer.getViewType(true /* isHalfWidth */);
-        final RecyclerView recyclerView = new RecyclerView(mContext);
-        recyclerView.setLayoutManager(new LinearLayoutManager(mContext));
-        final View card = LayoutInflater.from(mContext).inflate(viewType, recyclerView, false);
+        final RecyclerView recyclerView = new RecyclerView(mActivity);
+        recyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
+        final View card = LayoutInflater.from(mActivity).inflate(viewType, recyclerView, false);
         final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(card);
-        when(mControllerRendererPool.getController(mContext,
+        when(mControllerRendererPool.getController(mActivity,
                 ContextualCard.CardType.LEGACY_SUGGESTION)).thenReturn(mController);
 
         mRenderer.bindView(viewHolder, buildContextualCard());
@@ -99,7 +105,7 @@
                 .setName("test_name")
                 .setTitleText("test_title")
                 .setSummaryText("test_summary")
-                .setIconDrawable(mContext.getDrawable(R.drawable.ic_do_not_disturb_on_24dp))
+                .setIconDrawable(mActivity.getDrawable(R.drawable.ic_do_not_disturb_on_24dp))
                 .build();
     }
 }
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardControllerTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardControllerTest.java
index 362e1f5..af3b2e8 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardControllerTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardControllerTest.java
@@ -18,6 +18,11 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
 import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
@@ -27,14 +32,22 @@
 import com.android.settings.homepage.contextualcards.CardContentProvider;
 import com.android.settings.homepage.contextualcards.CardDatabaseHelper;
 import com.android.settings.homepage.contextualcards.ContextualCard;
+import com.android.settings.homepage.contextualcards.ContextualCardFeedbackDialog;
+import com.android.settings.homepage.contextualcards.ContextualCardsFragment;
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
 import org.robolectric.Robolectric;
 import org.robolectric.RuntimeEnvironment;
+import org.robolectric.Shadows;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowActivity;
 import org.robolectric.shadows.ShadowContentResolver;
+import org.robolectric.shadows.androidx.fragment.FragmentController;
 
 @RunWith(SettingsRobolectricTestRunner.class)
 public class SliceContextualCardControllerTest {
@@ -46,27 +59,27 @@
     private CardContentProvider mProvider;
     private ContentResolver mResolver;
     private SliceContextualCardController mController;
+    private FakeFeatureFactory mFeatureFactory;
 
     @Before
     public void setUp() {
+        MockitoAnnotations.initMocks(this);
         mContext = RuntimeEnvironment.application;
         mProvider = Robolectric.setupContentProvider(CardContentProvider.class);
         ShadowContentResolver.registerProviderInternal(CardContentProvider.CARD_AUTHORITY,
                 mProvider);
         mResolver = mContext.getContentResolver();
-        mController = new SliceContextualCardController(mContext);
+        mController = spy(new SliceContextualCardController(mContext));
+        mFeatureFactory = FakeFeatureFactory.setupForTest();
     }
 
     @Test
     public void onDismissed_cardShouldBeMarkedAsDismissed() {
         final Uri providerUri = CardContentProvider.URI;
-        final ContextualCard card = new ContextualCard.Builder()
-                .setName(TEST_CARD_NAME)
-                .setCardType(ContextualCard.CardType.SLICE)
-                .setSliceUri(Uri.parse(TEST_SLICE_URI))
-                .build();
         mResolver.insert(providerUri, generateOneRow());
+        doNothing().when(mController).showFeedbackDialog(any(ContextualCard.class));
 
+        final ContextualCard card = getTestSliceCard();
         mController.onDismissed(card);
 
         final String[] columns = {CardDatabaseHelper.CardColumns.CARD_DISMISSED};
@@ -78,6 +91,34 @@
         cr.close();
 
         assertThat(qryDismissed).isEqualTo(1);
+        verify(mFeatureFactory.mContextualCardFeatureProvider).logContextualCardDismiss(
+                mContext, card);
+    }
+
+    @Test
+    public void onDismissed_noFeedbackEmail_shouldNotShowFeedbackDialog() {
+        mResolver.insert(CardContentProvider.URI, generateOneRow());
+        final ContextualCardsFragment fragment =
+                FragmentController.of(new ContextualCardsFragment()).create().get();
+        final ShadowActivity shadowActivity = Shadows.shadowOf(fragment.getActivity());
+
+        mController.onDismissed(getTestSliceCard());
+
+        assertThat(shadowActivity.getNextStartedActivity()).isNull();
+    }
+
+    @Test
+    @Config(qualifiers = "mcc999")
+    public void onDismissed_hasFeedbackEmail_shouldShowFeedbackDialog() {
+        mResolver.insert(CardContentProvider.URI, generateOneRow());
+        final ContextualCardsFragment fragment =
+                FragmentController.of(new ContextualCardsFragment()).create().get();
+        final ShadowActivity shadowActivity = Shadows.shadowOf(fragment.getActivity());
+
+        mController.onDismissed(getTestSliceCard());
+
+        assertThat(shadowActivity.getNextStartedActivity().getComponent().getClassName())
+                .isEqualTo(ContextualCardFeedbackDialog.class.getName());
     }
 
     private ContentValues generateOneRow() {
@@ -93,4 +134,12 @@
 
         return values;
     }
+
+    private ContextualCard getTestSliceCard() {
+        return new ContextualCard.Builder()
+                .setName(TEST_CARD_NAME)
+                .setCardType(ContextualCard.CardType.SLICE)
+                .setSliceUri(Uri.parse(TEST_SLICE_URI))
+                .build();
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRendererTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRendererTest.java
index 1ba329c..abfddbb 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRendererTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRendererTest.java
@@ -20,7 +20,7 @@
 
 import static org.mockito.Mockito.verify;
 
-import android.content.Context;
+import android.app.Activity;
 import android.net.Uri;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -45,7 +45,8 @@
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RuntimeEnvironment;
+import org.robolectric.Robolectric;
+import org.robolectric.android.controller.ActivityController;
 
 @RunWith(SettingsRobolectricTestRunner.class)
 public class SliceContextualCardRendererTest {
@@ -54,19 +55,21 @@
     private LiveData<Slice> mSliceLiveData;
     @Mock
     private ControllerRendererPool mControllerRendererPool;
-    @Mock
-    private SliceContextualCardController mController;
 
-    private Context mContext;
+    private Activity mActivity;
     private SliceContextualCardRenderer mRenderer;
     private LifecycleOwner mLifecycleOwner;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mContext = RuntimeEnvironment.application;
+        final ActivityController<Activity> activityController = Robolectric.buildActivity(
+                Activity.class);
+        mActivity = activityController.get();
+        mActivity.setTheme(R.style.Theme_AppCompat);
+        activityController.create();
         mLifecycleOwner = new ContextualCardsFragment();
-        mRenderer = new SliceContextualCardRenderer(mContext, mLifecycleOwner,
+        mRenderer = new SliceContextualCardRenderer(mActivity, mLifecycleOwner,
                 mControllerRendererPool);
     }
 
@@ -156,9 +159,9 @@
 
     private RecyclerView.ViewHolder getSliceViewHolder() {
         final int viewType = mRenderer.getViewType(false /* isHalfWidth */);
-        final RecyclerView recyclerView = new RecyclerView(mContext);
-        recyclerView.setLayoutManager(new LinearLayoutManager(mContext));
-        final View view = LayoutInflater.from(mContext).inflate(viewType, recyclerView, false);
+        final RecyclerView recyclerView = new RecyclerView(mActivity);
+        recyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
+        final View view = LayoutInflater.from(mActivity).inflate(viewType, recyclerView, false);
 
         return mRenderer.createViewHolder(view);
     }
diff --git a/tests/robotests/src/com/android/settings/network/AirplaneModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/AirplaneModePreferenceControllerTest.java
index 91a545c..46d177f 100644
--- a/tests/robotests/src/com/android/settings/network/AirplaneModePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/AirplaneModePreferenceControllerTest.java
@@ -187,11 +187,4 @@
                 new AirplaneModePreferenceController(mContext,"toggle_airplane");
         assertThat(controller.isSliceable()).isTrue();
     }
-
-    @Test
-    public void isSliceableIncorrectKey_returnsFalse() {
-        final AirplaneModePreferenceController controller =
-                new AirplaneModePreferenceController(mContext, "bad_key");
-        assertThat(controller.isSliceable()).isFalse();
-    }
 }
diff --git a/tests/robotests/src/com/android/settings/network/telephony/Enhanced4gLteSliceHelperTest.java b/tests/robotests/src/com/android/settings/network/telephony/Enhanced4gLteSliceHelperTest.java
index d260a97..5269dd7 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/Enhanced4gLteSliceHelperTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/Enhanced4gLteSliceHelperTest.java
@@ -44,6 +44,7 @@
 import com.android.ims.ImsManager;
 import com.android.settings.R;
 import com.android.settings.slices.CustomSliceManager;
+import com.android.settings.slices.CustomSliceRegistry;
 import com.android.settings.slices.SettingsSliceProvider;
 import com.android.settings.slices.SliceBroadcastReceiver;
 import com.android.settings.slices.SlicesFeatureProvider;
@@ -107,7 +108,7 @@
         mEnhanced4gLteSliceHelper.setDefaultVoiceSubId(-1);
 
         final Slice slice = mEnhanced4gLteSliceHelper.createEnhanced4gLteSlice(
-                Enhanced4gLteSliceHelper.SLICE_URI);
+                CustomSliceRegistry.ENHANCED_4G_SLICE_URI);
 
         assertThat(slice).isNull();
     }
@@ -117,7 +118,7 @@
         when(mMockImsManager.isVolteEnabledByPlatform()).thenReturn(false);
 
         final Slice slice = mEnhanced4gLteSliceHelper.createEnhanced4gLteSlice(
-                Enhanced4gLteSliceHelper.SLICE_URI);
+                CustomSliceRegistry.ENHANCED_4G_SLICE_URI);
 
         assertThat(mEnhanced4gLteSliceHelper.getDefaultVoiceSubId()).isEqualTo(1);
         assertThat(slice).isNull();
@@ -132,7 +133,7 @@
         when(mMockCarrierConfigManager.getConfigForSubId(1)).thenReturn(null);
 
         final Slice slice = mEnhanced4gLteSliceHelper.createEnhanced4gLteSlice(
-                Enhanced4gLteSliceHelper.SLICE_URI);
+                CustomSliceRegistry.ENHANCED_4G_SLICE_URI);
 
         assertThat(mEnhanced4gLteSliceHelper.getDefaultVoiceSubId()).isEqualTo(1);
         testEnhanced4gLteSettingsToggleSlice(slice);
@@ -148,7 +149,7 @@
         when(mSlicesFeatureProvider.getNewEnhanced4gLteSliceHelper(mContext))
                 .thenReturn(mEnhanced4gLteSliceHelper);
 
-        final Slice slice = mProvider.onBindSlice(Enhanced4gLteSliceHelper.SLICE_URI);
+        final Slice slice = mProvider.onBindSlice(CustomSliceRegistry.ENHANCED_4G_SLICE_URI);
 
         assertThat(mEnhanced4gLteSliceHelper.getDefaultVoiceSubId()).isEqualTo(1);
         testEnhanced4gLteSettingsToggleSlice(slice);
diff --git a/tests/robotests/src/com/android/settings/notification/BlockPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/BlockPreferenceControllerTest.java
index 06ef601..0ebcaef 100644
--- a/tests/robotests/src/com/android/settings/notification/BlockPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/BlockPreferenceControllerTest.java
@@ -45,9 +45,9 @@
 import android.os.UserManager;
 
 import com.android.settings.R;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.widget.SwitchBar;
+import com.android.settingslib.widget.LayoutPreference;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/tests/robotests/src/com/android/settings/notification/HeaderPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/HeaderPreferenceControllerTest.java
index 57c8712..04dac26 100644
--- a/tests/robotests/src/com/android/settings/notification/HeaderPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/HeaderPreferenceControllerTest.java
@@ -37,7 +37,7 @@
 import androidx.fragment.app.FragmentActivity;
 import androidx.preference.PreferenceFragmentCompat;
 
-import com.android.settings.applications.LayoutPreference;
+import com.android.settingslib.widget.LayoutPreference;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
 import org.junit.Before;
diff --git a/tests/robotests/src/com/android/settings/panel/InternetConnectivityPanelTest.java b/tests/robotests/src/com/android/settings/panel/InternetConnectivityPanelTest.java
new file mode 100644
index 0000000..243c19b
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/panel/InternetConnectivityPanelTest.java
@@ -0,0 +1,52 @@
+/*
+ * 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.panel;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.net.Uri;
+
+import com.android.settings.slices.CustomSliceRegistry;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+
+import java.util.List;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+
+public class InternetConnectivityPanelTest {
+
+    private InternetConnectivityPanel mPanel;
+
+    @Before
+    public void setUp() {
+        mPanel = InternetConnectivityPanel.create(RuntimeEnvironment.application);
+    }
+
+    @Test
+    public void getSlices_containsNecessarySlices() {
+        final List<Uri> uris = mPanel.getSlices();
+
+        assertThat(uris).containsExactly(CustomSliceRegistry.WIFI_SLICE_URI,
+                CustomSliceRegistry.AIRPLANE_URI);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/panel/PanelFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/panel/PanelFeatureProviderImplTest.java
new file mode 100644
index 0000000..050fd0c
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/panel/PanelFeatureProviderImplTest.java
@@ -0,0 +1,52 @@
+/*
+ * 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.panel;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class PanelFeatureProviderImplTest {
+
+    private Context mContext;
+    private PanelFeatureProviderImpl mProvider;
+
+    @Before
+    public void setUp() {
+        mContext = RuntimeEnvironment.application;
+        mProvider = new PanelFeatureProviderImpl();
+    }
+
+    @Test
+    public void getPanel_internetConnectivityKey_returnsCorrectPanel() {
+        final PanelContent panel = mProvider.getPanel(mContext,
+                SettingsPanelActivity.PANEL_TYPE_WIFI);
+
+        assertThat(panel).isInstanceOf(InternetConnectivityPanel.class);
+    }
+
+}
diff --git a/tests/robotests/src/com/android/settings/search/SearchFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/search/SearchFeatureProviderImplTest.java
index b0e4025..37fd888 100644
--- a/tests/robotests/src/com/android/settings/search/SearchFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/search/SearchFeatureProviderImplTest.java
@@ -53,6 +53,8 @@
         mActivity = Robolectric.setupActivity(Activity.class);
         mProvider = new SearchFeatureProviderImpl();
         mPackageManager = Shadows.shadowOf(mActivity.getPackageManager());
+        Settings.Global.putInt(mActivity.getContentResolver(),
+                Settings.Global.DEVICE_PROVISIONED, 1);
     }
 
     @Test
@@ -82,7 +84,7 @@
 
     @Test
     @Config(shadows = ShadowUtils.class)
-    public void initSearchToolbar_NotHaveResolvedInfo_shouldNotStartActivity() {
+    public void initSearchToolbar_noResolvedInfo_shouldNotStartActivity() {
         final Toolbar toolbar = new Toolbar(mActivity);
         // This ensures navigationView is created.
         toolbar.setNavigationContentDescription("test");
@@ -90,9 +92,21 @@
 
         toolbar.performClick();
 
-        final Intent launchIntent = Shadows.shadowOf(mActivity).getNextStartedActivity();
+        assertThat(Shadows.shadowOf(mActivity).getNextStartedActivity()).isNull();
+    }
 
-        assertThat(launchIntent).isNull();
+    @Test
+    public void initSearchToolbar_deviceNotProvisioned_shouldNotCreateSearchBar() {
+        final Toolbar toolbar = new Toolbar(mActivity);
+        // This ensures navigationView is created.
+        toolbar.setNavigationContentDescription("test");
+
+        Settings.Global.putInt(mActivity.getContentResolver(),
+                Settings.Global.DEVICE_PROVISIONED, 0);
+
+        toolbar.performClick();
+
+        assertThat(Shadows.shadowOf(mActivity).getNextStartedActivity()).isNull();
     }
 
     @Test(expected = IllegalArgumentException.class)
diff --git a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
index 3c2cbdb..8e3c1c8 100644
--- a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
@@ -48,10 +48,6 @@
 import androidx.slice.widget.SliceLiveData;
 
 import com.android.settings.R;
-import com.android.settings.bluetooth.BluetoothSliceBuilder;
-import com.android.settings.flashlight.FlashlightSliceBuilder;
-import com.android.settings.location.LocationSliceBuilder;
-import com.android.settings.notification.ZenModeSliceBuilder;
 import com.android.settings.testutils.DatabaseTestUtils;
 import com.android.settings.testutils.FakeToggleController;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
@@ -113,14 +109,14 @@
     private SliceManager mManager;
 
     private static final List<Uri> SPECIAL_CASE_PLATFORM_URIS = Arrays.asList(
-            WifiSlice.WIFI_URI,
-            BluetoothSliceBuilder.BLUETOOTH_URI,
-            LocationSliceBuilder.LOCATION_URI
+            CustomSliceRegistry.WIFI_SLICE_URI,
+            CustomSliceRegistry.BLUETOOTH_URI,
+            CustomSliceRegistry.LOCATION_SLICE_URI
     );
 
     private static final List<Uri> SPECIAL_CASE_OEM_URIS = Arrays.asList(
-            ZenModeSliceBuilder.ZEN_MODE_URI,
-            FlashlightSliceBuilder.FLASHLIGHT_URI
+            CustomSliceRegistry.ZEN_MODE_SLICE_URI,
+            CustomSliceRegistry.FLASHLIGHT_SLICE_URI
     );
 
     @Before
@@ -472,9 +468,9 @@
 
     @Test
     public void bindSlice_wifiSlice_returnsWifiSlice() {
-        final Slice wifiSlice = mProvider.onBindSlice(WifiSlice.WIFI_URI);
+        final Slice wifiSlice = mProvider.onBindSlice(CustomSliceRegistry.WIFI_SLICE_URI);
 
-        assertThat(wifiSlice.getUri()).isEqualTo(WifiSlice.WIFI_URI);
+        assertThat(wifiSlice.getUri()).isEqualTo(CustomSliceRegistry.WIFI_SLICE_URI);
     }
 
     @Test
@@ -482,9 +478,10 @@
         Settings.Secure.putInt(
                 mContext.getContentResolver(), Settings.Secure.FLASHLIGHT_AVAILABLE, 1);
 
-        final Slice flashlightSlice = mProvider.onBindSlice(FlashlightSliceBuilder.FLASHLIGHT_URI);
+        final Slice flashlightSlice = mProvider.onBindSlice(
+                CustomSliceRegistry.FLASHLIGHT_SLICE_URI);
 
-        assertThat(flashlightSlice.getUri()).isEqualTo(FlashlightSliceBuilder.FLASHLIGHT_URI);
+        assertThat(flashlightSlice.getUri()).isEqualTo(CustomSliceRegistry.FLASHLIGHT_SLICE_URI);
     }
 
     @Test
@@ -526,22 +523,22 @@
 
     @Test
     public void onSlicePinned_backgroundWorker_started() {
-        mProvider.onSlicePinned(WifiSlice.WIFI_URI);
+        mProvider.onSlicePinned(CustomSliceRegistry.WIFI_SLICE_URI);
 
         verify(ShadowWifiScanWorker.getWifiTracker()).onStart();
     }
 
     @Test
     public void onSlicePinned_backgroundWorker_stopped() {
-        mProvider.onSlicePinned(WifiSlice.WIFI_URI);
-        mProvider.onSliceUnpinned(WifiSlice.WIFI_URI);
+        mProvider.onSlicePinned(CustomSliceRegistry.WIFI_SLICE_URI);
+        mProvider.onSliceUnpinned(CustomSliceRegistry.WIFI_SLICE_URI);
 
         verify(ShadowWifiScanWorker.getWifiTracker()).onStop();
     }
 
     @Test
     public void shutdown_backgroundWorker_closed() {
-        mProvider.onSlicePinned(WifiSlice.WIFI_URI);
+        mProvider.onSlicePinned(CustomSliceRegistry.WIFI_SLICE_URI);
         mProvider.shutdown();
 
         verify(ShadowWifiScanWorker.getWifiTracker()).onDestroy();
diff --git a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
index 24db829..978dd7d 100644
--- a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
+++ b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
@@ -28,11 +28,13 @@
 import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider;
 import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
 import com.android.settings.gestures.AssistGestureFeatureProvider;
+import com.android.settings.homepage.contextualcards.ContextualCardFeatureProvider;
 import com.android.settings.localepicker.LocaleFeatureProvider;
 import com.android.settings.overlay.DockUpdaterFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.overlay.SupportFeatureProvider;
 import com.android.settings.overlay.SurveyFeatureProvider;
+import com.android.settings.panel.PanelFeatureProvider;
 import com.android.settings.search.SearchFeatureProvider;
 import com.android.settings.security.SecurityFeatureProvider;
 import com.android.settings.slices.SlicesFeatureProvider;
@@ -61,6 +63,8 @@
     public final UserFeatureProvider userFeatureProvider;
     public final AssistGestureFeatureProvider assistGestureFeatureProvider;
     public final AccountFeatureProvider mAccountFeatureProvider;
+    public final PanelFeatureProvider mPanelFeatureProvider;
+    public final ContextualCardFeatureProvider mContextualCardFeatureProvider;
 
     public SlicesFeatureProvider slicesFeatureProvider;
     public SearchFeatureProvider searchFeatureProvider;
@@ -102,6 +106,8 @@
         assistGestureFeatureProvider = mock(AssistGestureFeatureProvider.class);
         slicesFeatureProvider = mock(SlicesFeatureProvider.class);
         mAccountFeatureProvider = mock(AccountFeatureProvider.class);
+        mPanelFeatureProvider = mock(PanelFeatureProvider.class);
+        mContextualCardFeatureProvider = mock(ContextualCardFeatureProvider.class);
     }
 
     @Override
@@ -183,4 +189,13 @@
     public AccountFeatureProvider getAccountFeatureProvider() {
         return mAccountFeatureProvider;
     }
+
+    @Override
+    public PanelFeatureProvider getPanelFeatureProvider() {
+        return mPanelFeatureProvider;
+    }
+
+    public ContextualCardFeatureProvider getContextualCardFeatureProvider() {
+        return mContextualCardFeatureProvider;
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/testutils/SettingsRobolectricTestRunner.java b/tests/robotests/src/com/android/settings/testutils/SettingsRobolectricTestRunner.java
index 5e5410c..9417e9c 100644
--- a/tests/robotests/src/com/android/settings/testutils/SettingsRobolectricTestRunner.java
+++ b/tests/robotests/src/com/android/settings/testutils/SettingsRobolectricTestRunner.java
@@ -84,6 +84,8 @@
             paths.add(new ResourcePath(null,
                     Fs.fromURL(new URL("file:frameworks/base/packages/SettingsLib/SearchWidget/res/")), null));
             paths.add(new ResourcePath(null,
+                    Fs.fromURL(new URL("file:frameworks/base/packages/SettingsLib/SettingsLayoutPreference/res")), null));
+            paths.add(new ResourcePath(null,
                 Fs.fromURL(new URL("file:frameworks/base/core/res/res")), null));
             paths.add(new ResourcePath(null,
                 Fs.fromURL(new URL("file:frameworks/opt/setupwizard/library/main/res")), null));
diff --git a/tests/robotests/src/com/android/settings/widget/ActionButtonPreferenceTest.java b/tests/robotests/src/com/android/settings/widget/ActionButtonPreferenceTest.java
index 2a15127..34a9872 100644
--- a/tests/robotests/src/com/android/settings/widget/ActionButtonPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/widget/ActionButtonPreferenceTest.java
@@ -50,52 +50,175 @@
     @Before
     public void setUp() {
         mContext = RuntimeEnvironment.application;
-        mRootView = View.inflate(mContext, R.layout.two_action_buttons, null /* parent */);
+        mRootView = View.inflate(mContext, R.layout.settings_action_buttons, null /* parent */);
         mHolder = PreferenceViewHolder.createInstanceForTests(mRootView);
         mPref = new ActionButtonPreference(mContext);
     }
 
     @Test
-    public void setVisibility_shouldUpdateButtonVisibility() {
-        mPref.setButton1Visible(false).setButton2Visible(false);
-        mPref.onBindViewHolder(mHolder);
+    public void onBindViewHolder_setTitle_shouldShowButtonByDefault() {
+        mPref.setButton1Text(R.string.settings_label);
+        mPref.setButton2Text(R.string.settings_label);
+        mPref.setButton3Text(R.string.settings_label);
+        mPref.setButton4Text(R.string.settings_label);
 
-        assertThat(mRootView.findViewById(R.id.button1).getVisibility())
-                .isEqualTo(View.GONE);
-        assertThat(mRootView.findViewById(R.id.button2).getVisibility())
-                .isEqualTo(View.GONE);
-
-        mPref.setButton1Visible(true).setButton2Visible(true);
         mPref.onBindViewHolder(mHolder);
 
         assertThat(mRootView.findViewById(R.id.button1).getVisibility())
                 .isEqualTo(View.VISIBLE);
         assertThat(mRootView.findViewById(R.id.button2).getVisibility())
                 .isEqualTo(View.VISIBLE);
+        assertThat(mRootView.findViewById(R.id.button3).getVisibility())
+                .isEqualTo(View.VISIBLE);
+        assertThat(mRootView.findViewById(R.id.button4).getVisibility())
+                .isEqualTo(View.VISIBLE);
     }
 
     @Test
-    public void setEnabled_shouldEnableButton() {
-        mPref.setButton1Enabled(true).setButton2Enabled(false);
+    public void onBindViewHolder_setIcon_shouldShowButtonByDefault() {
+        mPref.setButton1Icon(R.drawable.ic_settings);
+        mPref.setButton2Icon(R.drawable.ic_settings);
+        mPref.setButton3Icon(R.drawable.ic_settings);
+        mPref.setButton4Icon(R.drawable.ic_settings);
+
+        mPref.onBindViewHolder(mHolder);
+
+        assertThat(mRootView.findViewById(R.id.button1).getVisibility())
+                .isEqualTo(View.VISIBLE);
+        assertThat(mRootView.findViewById(R.id.button2).getVisibility())
+                .isEqualTo(View.VISIBLE);
+        assertThat(mRootView.findViewById(R.id.button3).getVisibility())
+                .isEqualTo(View.VISIBLE);
+        assertThat(mRootView.findViewById(R.id.button4).getVisibility())
+                .isEqualTo(View.VISIBLE);
+    }
+
+    @Test
+    public void onBindViewHolder_notSetTitleOrIcon_shouldNotShowButtonByDefault() {
+        mPref.onBindViewHolder(mHolder);
+
+        assertThat(mRootView.findViewById(R.id.button1).getVisibility())
+                .isEqualTo(View.GONE);
+        assertThat(mRootView.findViewById(R.id.button2).getVisibility())
+                .isEqualTo(View.GONE);
+        assertThat(mRootView.findViewById(R.id.button3).getVisibility())
+                .isEqualTo(View.GONE);
+        assertThat(mRootView.findViewById(R.id.button4).getVisibility())
+                .isEqualTo(View.GONE);
+    }
+
+    @Test
+    public void onBindViewHolder_setVisibleIsGoneAndSetTitle_shouldNotShowButton() {
+        mPref.setButton1Text(R.string.settings_label).setButton1Visible(false);
+        mPref.setButton2Text(R.string.settings_label).setButton2Visible(false);
+        mPref.setButton3Text(R.string.settings_label).setButton3Visible(false);
+        mPref.setButton4Text(R.string.settings_label).setButton4Visible(false);
+
+        mPref.onBindViewHolder(mHolder);
+
+        assertThat(mRootView.findViewById(R.id.button1).getVisibility())
+                .isEqualTo(View.GONE);
+        assertThat(mRootView.findViewById(R.id.button2).getVisibility())
+                .isEqualTo(View.GONE);
+        assertThat(mRootView.findViewById(R.id.button3).getVisibility())
+                .isEqualTo(View.GONE);
+        assertThat(mRootView.findViewById(R.id.button4).getVisibility())
+                .isEqualTo(View.GONE);
+    }
+
+    @Test
+    public void onBindViewHolder_setVisibleIsGoneAndSetIcon_shouldNotShowButton() {
+        mPref.setButton1Icon(R.drawable.ic_settings).setButton1Visible(false);
+        mPref.setButton2Icon(R.drawable.ic_settings).setButton2Visible(false);
+        mPref.setButton3Icon(R.drawable.ic_settings).setButton3Visible(false);
+        mPref.setButton4Icon(R.drawable.ic_settings).setButton4Visible(false);
+
+        mPref.onBindViewHolder(mHolder);
+
+        assertThat(mRootView.findViewById(R.id.button1).getVisibility())
+                .isEqualTo(View.GONE);
+        assertThat(mRootView.findViewById(R.id.button2).getVisibility())
+                .isEqualTo(View.GONE);
+        assertThat(mRootView.findViewById(R.id.button3).getVisibility())
+                .isEqualTo(View.GONE);
+        assertThat(mRootView.findViewById(R.id.button4).getVisibility())
+                .isEqualTo(View.GONE);
+    }
+
+    @Test
+    public void onBindViewHolder_setVisibility_shouldUpdateButtonVisibility() {
+        mPref.setButton1Text(R.string.settings_label).setButton1Visible(false);
+        mPref.setButton2Text(R.string.settings_label).setButton2Visible(false);
+        mPref.setButton3Text(R.string.settings_label).setButton3Visible(false);
+        mPref.setButton4Text(R.string.settings_label).setButton4Visible(false);
+
+        mPref.onBindViewHolder(mHolder);
+
+        assertThat(mRootView.findViewById(R.id.button1).getVisibility())
+                .isEqualTo(View.GONE);
+        assertThat(mRootView.findViewById(R.id.button2).getVisibility())
+                .isEqualTo(View.GONE);
+        assertThat(mRootView.findViewById(R.id.button3).getVisibility())
+                .isEqualTo(View.GONE);
+        assertThat(mRootView.findViewById(R.id.button4).getVisibility())
+                .isEqualTo(View.GONE);
+
+        mPref.setButton1Visible(true);
+        mPref.setButton2Visible(true);
+        mPref.setButton3Visible(true);
+        mPref.setButton4Visible(true);
+
+        mPref.onBindViewHolder(mHolder);
+
+        assertThat(mRootView.findViewById(R.id.button1).getVisibility())
+                .isEqualTo(View.VISIBLE);
+        assertThat(mRootView.findViewById(R.id.button2).getVisibility())
+                .isEqualTo(View.VISIBLE);
+        assertThat(mRootView.findViewById(R.id.button3).getVisibility())
+                .isEqualTo(View.VISIBLE);
+        assertThat(mRootView.findViewById(R.id.button4).getVisibility())
+                .isEqualTo(View.VISIBLE);
+    }
+
+    @Test
+    public void onBindViewHolder_setEnabled_shouldEnableButton() {
+        mPref.setButton1Enabled(true);
+        mPref.setButton2Enabled(false);
+        mPref.setButton3Enabled(true);
+        mPref.setButton4Enabled(false);
+
         mPref.onBindViewHolder(mHolder);
 
         assertThat(mRootView.findViewById(R.id.button1).isEnabled()).isTrue();
         assertThat(mRootView.findViewById(R.id.button2).isEnabled()).isFalse();
+        assertThat(mRootView.findViewById(R.id.button3).isEnabled()).isTrue();
+        assertThat(mRootView.findViewById(R.id.button4).isEnabled()).isFalse();
     }
 
     @Test
-    public void setText_shouldShowSameText() {
+    public void onBindViewHolder_setText_shouldShowSameText() {
         mPref.setButton1Text(R.string.settings_label);
+        mPref.setButton2Text(R.string.settings_label);
+        mPref.setButton3Text(R.string.settings_label);
+        mPref.setButton4Text(R.string.settings_label);
+
         mPref.onBindViewHolder(mHolder);
 
         assertThat(((Button) mRootView.findViewById(R.id.button1)).getText())
                 .isEqualTo(mContext.getText(R.string.settings_label));
+        assertThat(((Button) mRootView.findViewById(R.id.button2)).getText())
+                .isEqualTo(mContext.getText(R.string.settings_label));
+        assertThat(((Button) mRootView.findViewById(R.id.button3)).getText())
+                .isEqualTo(mContext.getText(R.string.settings_label));
+        assertThat(((Button) mRootView.findViewById(R.id.button4)).getText())
+                .isEqualTo(mContext.getText(R.string.settings_label));
     }
 
     @Test
-    public void setButtonIcon_iconMustDisplayAboveText() {
+    public void onBindViewHolder_setButtonIcon_iconMustDisplayAboveText() {
         mPref.setButton1Text(R.string.settings_label);
         mPref.setButton1Icon(R.drawable.ic_settings);
+
         mPref.onBindViewHolder(mHolder);
         final Drawable[] drawablesAroundText =
                 ((Button) mRootView.findViewById(R.id.button1))
@@ -108,6 +231,7 @@
     public void setButtonIcon_iconResourceIdIsZero_shouldNotDisplayIcon() {
         mPref.setButton1Text(R.string.settings_label);
         mPref.setButton1Icon(0);
+
         mPref.onBindViewHolder(mHolder);
         final Drawable[] drawablesAroundText =
                 ((Button) mRootView.findViewById(R.id.button1))
@@ -142,6 +266,18 @@
         when(pref.setButton2Enabled(anyBoolean())).thenReturn(pref);
         when(pref.setButton2Visible(anyBoolean())).thenReturn(pref);
         when(pref.setButton2OnClickListener(any(View.OnClickListener.class))).thenReturn(pref);
+
+        when(pref.setButton3Text(anyInt())).thenReturn(pref);
+        when(pref.setButton3Icon(anyInt())).thenReturn(pref);
+        when(pref.setButton3Enabled(anyBoolean())).thenReturn(pref);
+        when(pref.setButton3Visible(anyBoolean())).thenReturn(pref);
+        when(pref.setButton3OnClickListener(any(View.OnClickListener.class))).thenReturn(pref);
+
+        when(pref.setButton4Text(anyInt())).thenReturn(pref);
+        when(pref.setButton4Icon(anyInt())).thenReturn(pref);
+        when(pref.setButton4Enabled(anyBoolean())).thenReturn(pref);
+        when(pref.setButton4Visible(anyBoolean())).thenReturn(pref);
+        when(pref.setButton4OnClickListener(any(View.OnClickListener.class))).thenReturn(pref);
         return pref;
     }
 }
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/widget/EntityHeaderControllerTest.java b/tests/robotests/src/com/android/settings/widget/EntityHeaderControllerTest.java
index 5d60810..5639549 100644
--- a/tests/robotests/src/com/android/settings/widget/EntityHeaderControllerTest.java
+++ b/tests/robotests/src/com/android/settings/widget/EntityHeaderControllerTest.java
@@ -46,10 +46,10 @@
 import androidx.preference.Preference;
 
 import com.android.settings.R;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.ShadowIconDrawableFactory;
 import com.android.settingslib.applications.ApplicationsState;
+import com.android.settingslib.widget.LayoutPreference;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/tests/robotests/src/com/android/settings/widget/RoundedHomepageIconTest.java b/tests/robotests/src/com/android/settings/widget/RoundedHomepageIconTest.java
index aaffa93..5bc8dda 100644
--- a/tests/robotests/src/com/android/settings/widget/RoundedHomepageIconTest.java
+++ b/tests/robotests/src/com/android/settings/widget/RoundedHomepageIconTest.java
@@ -101,7 +101,7 @@
     public void onBindTile_externalTileWithBackgroundColorHint_shouldUpdateIcon() {
         final Tile tile = spy(new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE));
         mActivityInfo.metaData.putInt(META_DATA_PREFERENCE_ICON_BACKGROUND_HINT,
-                R.color.memory_critical);
+                R.color.material_blue_500);
         doReturn(Icon.createWithResource(mContext, R.drawable.ic_settings))
                 .when(tile).getIcon(mContext);
 
@@ -110,7 +110,7 @@
         icon.setBackgroundColor(mContext, tile);
 
         assertThat(icon.mBackgroundColor)
-                .isEqualTo(mContext.getColor(R.color.memory_critical));
+                .isEqualTo(mContext.getColor(R.color.material_blue_500));
     }
 
 }
diff --git a/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogActivityTest.java b/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogActivityTest.java
new file mode 100644
index 0000000..4889c83
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogActivityTest.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.settings.wifi;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.appcompat.app.AlertDialog;
+
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.SettingsShadowResourcesImpl;
+import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(shadows = {
+        ShadowAlertDialogCompat.class,
+        SettingsShadowResourcesImpl.class
+})
+public class NetworkRequestDialogActivityTest {
+
+    @Test
+    public void LaunchActivity_shouldShowNetworkRequestDialog() {
+        NetworkRequestDialogActivity activity = Robolectric
+                .setupActivity(NetworkRequestDialogActivity.class);
+
+        AlertDialog alertDialog = ShadowAlertDialogCompat.getLatestAlertDialog();
+
+        assertThat(alertDialog.isShowing()).isTrue();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSliceHelperTest.java b/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSliceHelperTest.java
index ae4c753..11dd56e 100644
--- a/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSliceHelperTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSliceHelperTest.java
@@ -49,6 +49,7 @@
 import com.android.ims.ImsManager;
 import com.android.settings.R;
 import com.android.settings.slices.CustomSliceManager;
+import com.android.settings.slices.CustomSliceRegistry;
 import com.android.settings.slices.SettingsSliceProvider;
 import com.android.settings.slices.SliceBroadcastReceiver;
 import com.android.settings.slices.SliceData;
@@ -113,7 +114,7 @@
         mWfcSliceHelper.setDefaultVoiceSubId(-1);
 
         final Slice slice = mWfcSliceHelper.createWifiCallingSlice(
-                WifiCallingSliceHelper.WIFI_CALLING_URI);
+                CustomSliceRegistry.WIFI_CALLING_URI);
 
         assertThat(slice).isNull();
     }
@@ -123,7 +124,7 @@
         when(mMockImsManager.isWfcEnabledByPlatform()).thenReturn(false);
 
         final Slice slice = mWfcSliceHelper.createWifiCallingSlice(
-                WifiCallingSliceHelper.WIFI_CALLING_URI);
+                CustomSliceRegistry.WIFI_CALLING_URI);
 
         assertThat(mWfcSliceHelper.getDefaultVoiceSubId()).isEqualTo(1);
         assertThat(slice).isNull();
@@ -144,7 +145,7 @@
         mWfcSliceHelper.setActivationAppIntent(new Intent()); // dummy Intent
 
         final Slice slice  = mWfcSliceHelper.createWifiCallingSlice(
-                WifiCallingSliceHelper.WIFI_CALLING_URI);
+                CustomSliceRegistry.WIFI_CALLING_URI);
 
         assertThat(mWfcSliceHelper.getDefaultVoiceSubId()).isEqualTo(1);
         testWifiCallingSettingsUnavailableSlice(slice, null,
@@ -161,7 +162,7 @@
         when(mMockCarrierConfigManager.getConfigForSubId(1)).thenReturn(null);
 
         final Slice slice = mWfcSliceHelper.createWifiCallingSlice(
-                WifiCallingSliceHelper.WIFI_CALLING_URI);
+                CustomSliceRegistry.WIFI_CALLING_URI);
 
         assertThat(mWfcSliceHelper.getDefaultVoiceSubId()).isEqualTo(1);
         testWifiCallingSettingsToggleSlice(slice, null);
@@ -177,7 +178,7 @@
         when(mSlicesFeatureProvider.getNewWifiCallingSliceHelper(mContext))
                 .thenReturn(mWfcSliceHelper);
 
-        final Slice slice = mProvider.onBindSlice(WifiCallingSliceHelper.WIFI_CALLING_URI);
+        final Slice slice = mProvider.onBindSlice(CustomSliceRegistry.WIFI_CALLING_URI);
 
         assertThat(mWfcSliceHelper.getDefaultVoiceSubId()).isEqualTo(1);
         testWifiCallingSettingsToggleSlice(slice, null);
@@ -217,7 +218,7 @@
         mWfcSliceHelper.setIsWifiCallingPrefEditable(false);
 
         final Slice slice = mWfcSliceHelper.createWifiCallingPreferenceSlice(
-                WifiCallingSliceHelper.WIFI_CALLING_PREFERENCE_URI);
+                CustomSliceRegistry.WIFI_CALLING_PREFERENCE_URI);
 
         assertThat(mWfcSliceHelper.getDefaultVoiceSubId()).isEqualTo(1);
         assertThat(slice).isNull();
@@ -232,7 +233,7 @@
         mWfcSliceHelper.setIsWifiCallingPrefEditable(true);
 
         final Slice slice = mWfcSliceHelper.createWifiCallingPreferenceSlice(
-                WifiCallingSliceHelper.WIFI_CALLING_PREFERENCE_URI);
+                CustomSliceRegistry.WIFI_CALLING_PREFERENCE_URI);
 
         assertThat(mWfcSliceHelper.getDefaultVoiceSubId()).isEqualTo(1);
         testWifiCallingSettingsUnavailableSlice(slice, null,
@@ -251,7 +252,7 @@
         mWfcSliceHelper.setIsWifiCallingPrefEditable(true);
 
         final Slice slice = mWfcSliceHelper.createWifiCallingPreferenceSlice(
-                WifiCallingSliceHelper.WIFI_CALLING_PREFERENCE_URI);
+                CustomSliceRegistry.WIFI_CALLING_PREFERENCE_URI);
 
         assertThat(mWfcSliceHelper.getDefaultVoiceSubId()).isEqualTo(1);
         testWifiCallingPreferenceSlice(slice, null,
@@ -271,7 +272,7 @@
         mWfcSliceHelper.setIsWifiCallingPrefEditable(true);
 
         final Slice slice = mProvider.onBindSlice(
-                WifiCallingSliceHelper.WIFI_CALLING_PREFERENCE_URI);
+                CustomSliceRegistry.WIFI_CALLING_PREFERENCE_URI);
 
         assertThat(mWfcSliceHelper.getDefaultVoiceSubId()).isEqualTo(1);
         testWifiCallingPreferenceSlice(slice, null,
diff --git a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
index 59e6287..d39b55f 100644
--- a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
@@ -57,12 +57,12 @@
 
 import androidx.fragment.app.FragmentActivity;
 import androidx.lifecycle.LifecycleOwner;
+import androidx.preference.Preference;
 import androidx.preference.PreferenceCategory;
 import androidx.preference.PreferenceScreen;
 
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.ShadowBidiFormatter;
 import com.android.settings.testutils.shadow.ShadowDevicePolicyManager;
@@ -70,9 +70,9 @@
 import com.android.settings.widget.ActionButtonPreference;
 import com.android.settings.widget.ActionButtonPreferenceTest;
 import com.android.settings.widget.EntityHeaderController;
-import com.android.settings.wifi.WifiDetailPreference;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.LayoutPreference;
 import com.android.settingslib.wifi.AccessPoint;
 
 import org.junit.Before;
@@ -144,27 +144,27 @@
     @Mock
     private ActionButtonPreference mockButtonsPref;
     @Mock
-    private WifiDetailPreference mockSignalStrengthPref;
+    private Preference mockSignalStrengthPref;
     @Mock
-    private WifiDetailPreference mockLinkSpeedPref;
+    private Preference mockLinkSpeedPref;
     @Mock
-    private WifiDetailPreference mockFrequencyPref;
+    private Preference mockFrequencyPref;
     @Mock
-    private WifiDetailPreference mockSecurityPref;
+    private Preference mockSecurityPref;
     @Mock
-    private WifiDetailPreference mockMacAddressPref;
+    private Preference mockMacAddressPref;
     @Mock
-    private WifiDetailPreference mockIpAddressPref;
+    private Preference mockIpAddressPref;
     @Mock
-    private WifiDetailPreference mockGatewayPref;
+    private Preference mockGatewayPref;
     @Mock
-    private WifiDetailPreference mockSubnetPref;
+    private Preference mockSubnetPref;
     @Mock
-    private WifiDetailPreference mockDnsPref;
+    private Preference mockDnsPref;
     @Mock
     private PreferenceCategory mockIpv6Category;
     @Mock
-    private WifiDetailPreference mockIpv6AddressesPref;
+    private Preference mockIpv6AddressesPref;
     @Mock
     private PackageManager mockPackageManager;
 
@@ -336,7 +336,7 @@
     public void securityPreference_stringShouldBeSet() {
         displayAndResume();
 
-        verify(mockSecurityPref).setDetailText(SECURITY);
+        verify(mockSecurityPref).setSummary(SECURITY);
     }
 
     @Test
@@ -413,7 +413,7 @@
 
         displayAndResume();
 
-        verify(mockSignalStrengthPref).setDetailText(expectedStrength);
+        verify(mockSignalStrengthPref).setSummary(expectedStrength);
     }
 
     @Test
@@ -422,7 +422,7 @@
 
         displayAndResume();
 
-        verify(mockLinkSpeedPref).setDetailText(expectedLinkSpeed);
+        verify(mockLinkSpeedPref).setSummary(expectedLinkSpeed);
     }
 
     @Test
@@ -438,7 +438,7 @@
     public void macAddressPref_shouldHaveDetailTextSet() {
         displayAndResume();
 
-        verify(mockMacAddressPref).setDetailText(MAC_ADDRESS);
+        verify(mockMacAddressPref).setSummary(MAC_ADDRESS);
     }
 
     @Test
@@ -447,7 +447,7 @@
 
         displayAndResume();
 
-        verify(mockIpAddressPref).setDetailText(Constants.IPV4_ADDR.getAddress().getHostAddress());
+        verify(mockIpAddressPref).setSummary(Constants.IPV4_ADDR.getAddress().getHostAddress());
     }
 
     @Test
@@ -458,8 +458,8 @@
 
         displayAndResume();
 
-        verify(mockSubnetPref).setDetailText("255.255.255.128");
-        verify(mockGatewayPref).setDetailText("192.0.2.127");
+        verify(mockSubnetPref).setSummary("255.255.255.128");
+        verify(mockGatewayPref).setSummary("192.0.2.127");
     }
 
     @Test
@@ -470,7 +470,7 @@
 
         displayAndResume();
 
-        verify(mockDnsPref).setDetailText(
+        verify(mockDnsPref).setSummary(
                 "8.8.4.4\n" +
                         "8.8.8.8\n" +
                         Constants.IPV6_DNS.getHostAddress());
@@ -551,15 +551,15 @@
 
         lp.addRoute(Constants.IPV4_DEFAULT);
         updateLinkProperties(lp);
-        inOrder.verify(mockGatewayPref).setDetailText(Constants.IPV4_GATEWAY.getHostAddress());
+        inOrder.verify(mockGatewayPref).setSummary(Constants.IPV4_GATEWAY.getHostAddress());
         inOrder.verify(mockGatewayPref).setVisible(true);
 
         lp.addLinkAddress(Constants.IPV4_ADDR);
         lp.addRoute(Constants.IPV4_SUBNET);
         updateLinkProperties(lp);
-        inOrder.verify(mockIpAddressPref).setDetailText(asString(Constants.IPV4_ADDR));
+        inOrder.verify(mockIpAddressPref).setSummary(asString(Constants.IPV4_ADDR));
         inOrder.verify(mockIpAddressPref).setVisible(true);
-        inOrder.verify(mockSubnetPref).setDetailText("255.255.255.128");
+        inOrder.verify(mockSubnetPref).setSummary("255.255.255.128");
         inOrder.verify(mockSubnetPref).setVisible(true);
 
         lp.addLinkAddress(Constants.IPV6_GLOBAL1);
@@ -578,13 +578,13 @@
 
         lp.addDnsServer(Constants.IPV6_DNS);
         updateLinkProperties(lp);
-        inOrder.verify(mockDnsPref).setDetailText(Constants.IPV6_DNS.getHostAddress());
+        inOrder.verify(mockDnsPref).setSummary(Constants.IPV6_DNS.getHostAddress());
         inOrder.verify(mockDnsPref).setVisible(true);
 
         lp.addDnsServer(Constants.IPV4_DNS1);
         lp.addDnsServer(Constants.IPV4_DNS2);
         updateLinkProperties(lp);
-        inOrder.verify(mockDnsPref).setDetailText(
+        inOrder.verify(mockDnsPref).setSummary(
                 Constants.IPV6_DNS.getHostAddress() + "\n" +
                         Constants.IPV4_DNS1.getHostAddress() + "\n" +
                         Constants.IPV4_DNS2.getHostAddress());
diff --git a/tests/unit/src/com/android/settings/slices/SliceDeepLinkSpringBoardTest.java b/tests/unit/src/com/android/settings/slices/SliceDeepLinkSpringBoardTest.java
index 81f1fac..bd8649d 100644
--- a/tests/unit/src/com/android/settings/slices/SliceDeepLinkSpringBoardTest.java
+++ b/tests/unit/src/com/android/settings/slices/SliceDeepLinkSpringBoardTest.java
@@ -26,11 +26,6 @@
 import android.support.test.filters.MediumTest;
 import android.support.test.runner.AndroidJUnit4;
 
-import com.android.settings.bluetooth.BluetoothSliceBuilder;
-import com.android.settings.location.LocationSliceBuilder;
-import com.android.settings.notification.ZenModeSliceBuilder;
-import com.android.settings.wifi.WifiSlice;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -57,7 +52,8 @@
     @Test
     @Presubmit
     public void launchesDeepLinkIntent_wifiSlice_shouldNotCrash() {
-        final Intent deepLinkIntent = getSpringboardIntent(WifiSlice.WIFI_URI.toString());
+        final Intent deepLinkIntent = getSpringboardIntent(
+                CustomSliceRegistry.WIFI_SLICE_URI.toString());
 
         mContext.startActivity(deepLinkIntent);
     }
@@ -66,7 +62,7 @@
     @Presubmit
     public void launchesDeepLinkIntent_bluetoothSlice_shouldNotCrash() {
         final Intent deepLinkIntent = getSpringboardIntent(
-                BluetoothSliceBuilder.BLUETOOTH_URI.toString());
+                CustomSliceRegistry.BLUETOOTH_URI.toString());
 
         mContext.startActivity(deepLinkIntent);
     }
@@ -75,7 +71,7 @@
     @Presubmit
     public void launchesDeepLinkIntent_dndSlice_shouldNotCrash() {
         final Intent deepLinkIntent = getSpringboardIntent(
-                ZenModeSliceBuilder.ZEN_MODE_URI.toString());
+                CustomSliceRegistry.ZEN_MODE_SLICE_URI.toString());
 
         mContext.startActivity(deepLinkIntent);
     }
@@ -84,7 +80,7 @@
     @Presubmit
     public void launchesDeepLinkIntent_locationSlice_shouldNotCrash() {
         final Intent deepLinkIntent = getSpringboardIntent(
-                LocationSliceBuilder.LOCATION_URI.toString());
+                CustomSliceRegistry.LOCATION_SLICE_URI.toString());
 
         mContext.startActivity(deepLinkIntent);
     }
diff --git a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java
index d101c92..208c344 100644
--- a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java
+++ b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java
@@ -35,18 +35,38 @@
             new ActivityTestRule<>(WifiDppConfiguratorActivity.class);
 
     @Test
-    public void testLaunchModeQrCodeScanner_shouldNotAutoFinish() {
+    public void launchActivity_modeQrCodeScanner_shouldNotAutoFinish() {
         Intent intent = new Intent();
         intent.putExtra(WifiDppConfiguratorActivity.EXTRA_LAUNCH_MODE,
                 WifiDppConfiguratorActivity.LaunchMode.LAUNCH_MODE_QR_CODE_SCANNER.getMode());
         mActivityRule.launchActivity(intent);
 
         assertThat(mActivityRule.getActivity().isFinishing()).isEqualTo(false);
-        mActivityRule.finishActivity();
     }
 
     @Test
-    public void testNoLaunchMode_shouldFinishActivityWithResultCodeCanceled() {
+    public void launchActivity_modeQrCodeGenerator_shouldNotAutoFinish() {
+        Intent intent = new Intent();
+        intent.putExtra(WifiDppConfiguratorActivity.EXTRA_LAUNCH_MODE,
+                WifiDppConfiguratorActivity.LaunchMode.LAUNCH_MODE_QR_CODE_GENERATOR.getMode());
+        mActivityRule.launchActivity(intent);
+
+        assertThat(mActivityRule.getActivity().isFinishing()).isEqualTo(false);
+    }
+
+    @Test
+    public void launchActivity_modeChooseSavedWifiNetwork_shouldNotAutoFinish() {
+        Intent intent = new Intent();
+        intent.putExtra(WifiDppConfiguratorActivity.EXTRA_LAUNCH_MODE,
+                WifiDppConfiguratorActivity.LaunchMode
+                .LAUNCH_MODE_CHOOSE_SAVED_WIFI_NETWORK.getMode());
+        mActivityRule.launchActivity(intent);
+
+        assertThat(mActivityRule.getActivity().isFinishing()).isEqualTo(false);
+    }
+
+    @Test
+    public void launchActivity_noLaunchMode_shouldFinishActivityWithResultCodeCanceled() {
         // If we do not specify launch mode, the activity will finish itself right away
         Intent intent = new Intent();
         mActivityRule.launchActivity(intent);
diff --git a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragmentTest.java b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragmentTest.java
index 58fa61f..0f4bfd9 100644
--- a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragmentTest.java
+++ b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragmentTest.java
@@ -47,8 +47,9 @@
     }
 
     @Test
-    public void testLeftButton_shouldFinishActivityWithResultCodeCanceled() {
+    public void leftButton_shouldFinishActivityWithResultCodeCanceled() {
         onView(withText("Cancel")).perform(click());
+
         assertThat(mActivityRule.getActivityResult().getResultCode()).
                 isEqualTo(Activity.RESULT_CANCELED);
     }